1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 88, 89, 92-96, 1997 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
27 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
28 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
29 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
30 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
32 ;; -mlive-g0 is *not* supported for TARGET_ARCH64, so we don't bother to
33 ;; test TARGET_LIVE_G0 if we have TARGET_ARCH64.
35 ;; Attribute for cpu type.
36 ;; These must match the values for enum processor_type in sparc.h.
37 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v8plus,v9,ultrasparc"
38 (const (symbol_ref "sparc_cpu_attr")))
40 ;; Attribute for the instruction set.
41 ;; At present we only need to distinguish v9/!v9, but for clarity we
42 ;; test TARGET_V8 too.
43 (define_attr "isa" "v6,v8,v9,sparclet"
45 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
46 (symbol_ref "TARGET_V8") (const_string "v8")
47 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
48 (const_string "v6"))))
51 (define_attr "arch" "arch32bit,arch64bit"
53 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
54 (const_string "arch32bit"))))
56 ;; Whether -mlive-g0 is in effect.
57 (define_attr "live_g0" "no,yes"
59 (cond [(symbol_ref "TARGET_LIVE_G0") (const_string "yes")]
60 (const_string "no"))))
62 ;; Insn type. Used to default other attribute values.
64 ;; type "unary" insns have one input operand (1) and one output operand (0)
65 ;; type "binary" insns have two input operands (1,2) and one output (0)
66 ;; type "compare" insns have one or two input operands (0,1) and no output
67 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
70 "move,unary,binary,compare,load,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc"
71 (const_string "binary"))
73 ;; Set true if insn uses call-clobbered intermediate register.
74 (define_attr "use_clobbered" "false,true"
75 (if_then_else (and (eq_attr "type" "address")
76 (match_operand 0 "clobbered_register" ""))
78 (const_string "false")))
80 ;; Length (in # of insns).
81 (define_attr "length" ""
82 (cond [(eq_attr "type" "load,fpload")
83 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
84 (const_int 2) (const_int 1))
86 (eq_attr "type" "store,fpstore")
87 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
88 (const_int 2) (const_int 1))
90 (eq_attr "type" "address") (const_int 2)
92 (eq_attr "type" "binary")
93 (if_then_else (ior (match_operand 2 "arith_operand" "")
94 (match_operand 2 "arith_double_operand" ""))
95 (const_int 1) (const_int 3))
97 (eq_attr "type" "multi") (const_int 2)
99 (eq_attr "type" "move,unary")
100 (if_then_else (ior (match_operand 1 "arith_operand" "")
101 (match_operand 1 "arith_double_operand" ""))
102 (const_int 1) (const_int 2))]
106 (define_asm_attributes
107 [(set_attr "length" "1")
108 (set_attr "type" "multi")])
110 ;; Attributes for instruction and branch scheduling
112 (define_attr "in_call_delay" "false,true"
113 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
114 (const_string "false")
115 (eq_attr "type" "load,fpload,store,fpstore")
116 (if_then_else (eq_attr "length" "1")
117 (const_string "true")
118 (const_string "false"))
119 (eq_attr "type" "address")
120 (if_then_else (eq_attr "use_clobbered" "false")
121 (const_string "true")
122 (const_string "false"))]
123 (if_then_else (eq_attr "length" "1")
124 (const_string "true")
125 (const_string "false"))))
127 (define_delay (eq_attr "type" "call")
128 [(eq_attr "in_call_delay" "true") (nil) (nil)])
130 ;; ??? Should implement the notion of predelay slots for floating point
131 ;; branches. This would allow us to remove the nop always inserted before
132 ;; a floating point branch.
134 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
135 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
136 ;; This is because doing so will add several pipeline stalls to the path
137 ;; that the load/store did not come from. Unfortunately, there is no way
138 ;; to prevent fill_eager_delay_slots from using load/store without completely
139 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
140 ;; because it prevents us from moving back the final store of inner loops.
142 (define_attr "in_branch_delay" "false,true"
143 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
144 (eq_attr "length" "1"))
145 (const_string "true")
146 (const_string "false")))
148 (define_attr "in_uncond_branch_delay" "false,true"
149 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
150 (eq_attr "length" "1"))
151 (const_string "true")
152 (const_string "false")))
154 (define_attr "in_annul_branch_delay" "false,true"
155 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
156 (eq_attr "length" "1"))
157 (const_string "true")
158 (const_string "false")))
160 (define_delay (eq_attr "type" "branch")
161 [(eq_attr "in_branch_delay" "true")
162 (nil) (eq_attr "in_annul_branch_delay" "true")])
164 (define_delay (eq_attr "type" "uncond_branch")
165 [(eq_attr "in_uncond_branch_delay" "true")
168 ;; Function units of the SPARC
170 ;; (define_function_unit {name} {num-units} {n-users} {test}
171 ;; {ready-delay} {issue-delay} [{conflict-list}])
174 ;; (Noted only for documentation; units that take one cycle do not need to
177 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
180 ;; (define_function_unit "alu" 1 0
181 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
183 ;; ---- cypress CY7C602 scheduling:
184 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
185 (define_function_unit "memory" 1 0
186 (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2)
188 ;; SPARC has two floating-point units: the FP ALU,
189 ;; and the FP MUL/DIV/SQRT unit.
190 ;; Instruction timings on the CY7C602 are as follows
204 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
205 ;; More insns cause the chip to stall.
207 (define_function_unit "fp_alu" 1 0
208 (and (eq_attr "type" "fp") (eq_attr "cpu" "cypress")) 5 5)
209 (define_function_unit "fp_mds" 1 0
210 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "cypress")) 7 7)
211 (define_function_unit "fp_mds" 1 0
212 (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37)
213 (define_function_unit "fp_mds" 1 0
214 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "cypress")) 63 63)
216 ;; ----- The TMS390Z55 scheduling
217 ;; The Supersparc can issue 1 - 3 insns per cycle; here we assume
218 ;; three insns/cycle, and hence multiply all costs by three.
219 ;; Combinations up to two integer, one ld/st, one fp.
220 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
221 (define_function_unit "memory" 1 0
222 (and (eq_attr "type" "load") (eq_attr "cpu" "supersparc")) 3 3)
223 (define_function_unit "memory" 1 0
224 (and (eq_attr "type" "fpload") (eq_attr "cpu" "supersparc")) 1 3)
225 ;; at least one in three instructions can be a mem opt.
226 (define_function_unit "memory" 1 0
227 (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3)
228 ;; at least one in three instructions can be a shift op.
229 (define_function_unit "shift" 1 0
230 (and (eq_attr "type" "shift") (eq_attr "cpu" "supersparc")) 1 3)
232 ;; There are only two write ports to the integer register file
233 ;; A store also uses a write port
234 (define_function_unit "iwport" 2 0
235 (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3)
237 ;; Timings; throughput/latency
238 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
246 (define_function_unit "fp_alu" 1 0
247 (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3)
248 (define_function_unit "fp_mds" 1 0
249 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "supersparc")) 9 3)
250 (define_function_unit "fp_mds" 1 0
251 (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "supersparc")) 18 12)
252 (define_function_unit "fp_mds" 1 0
253 (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "supersparc")) 27 21)
254 (define_function_unit "fp_mds" 1 0
255 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "supersparc")) 36 30)
256 (define_function_unit "fp_mds" 1 0
257 (and (eq_attr "type" "imul") (eq_attr "cpu" "supersparc")) 12 12)
259 ;; ----- sparclet tsc701 scheduling
260 ;; The tsc701 issues 1 insn per cycle.
261 ;; Results may be written back out of order.
263 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
264 (define_function_unit "tsc701_load" 4 1
265 (and (eq_attr "type" "load") (eq_attr "cpu" "tsc701")) 3 1)
266 ;; Stores take 2(?) extra cycles to complete.
267 ;; It is desirable to not have any memory operation in the following 2 cycles.
268 ;; (??? or 2 memory ops in the case of std).
269 (define_function_unit "tsc701_store" 1 0
270 (and (eq_attr "type" "store") (eq_attr "cpu" "tsc701")) 3 3
271 [(eq_attr "type" "load,store")])
272 ;; The multiply unit has a latency of 5.
273 (define_function_unit "tsc701_mul" 1 0
274 (and (eq_attr "type" "imul") (eq_attr "cpu" "tsc701")) 5 5)
276 ;; ----- The UltraSPARC-1 scheduling
277 ;; The Ultrasparc can issue 1 - 4 insns per cycle; here we assume
278 ;; four insns/cycle, and hence multiply all costs by four.
280 ;; Memory delivers its result in three cycles to IU, three cycles to FP
281 (define_function_unit "memory" 1 0
282 (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "ultrasparc")) 12 4)
283 (define_function_unit "memory" 1 0
284 (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "ultrasparc")) 4 4)
285 (define_function_unit "ieu" 1 0
286 (and (eq_attr "type" "ialu") (eq_attr "cpu" "ultrasparc")) 1 2)
287 (define_function_unit "ieu" 1 0
288 (and (eq_attr "type" "shift") (eq_attr "cpu" "ultrasparc")) 1 4)
289 (define_function_unit "ieu" 1 0
290 (and (eq_attr "type" "cmove") (eq_attr "cpu" "ultrasparc")) 8 4)
292 ;; Timings; throughput/latency
293 ;; ?? FADD 1/3 add/sub, format conv, compar, abs, neg
300 (define_function_unit "fp" 1 0
301 (and (eq_attr "type" "fp") (eq_attr "cpu" "ultrasparc")) 12 2)
302 (define_function_unit "fp" 1 0
303 (and (eq_attr "type" "fpcmp") (eq_attr "cpu" "ultrasparc")) 8 2)
304 (define_function_unit "fp" 1 0
305 (and (eq_attr "type" "fpmul") (eq_attr "cpu" "ultrasparc")) 12 2)
306 (define_function_unit "fp" 1 0
307 (and (eq_attr "type" "fpdivs") (eq_attr "cpu" "ultrasparc")) 48 2)
308 (define_function_unit "fp" 1 0
309 (and (eq_attr "type" "fpdivd") (eq_attr "cpu" "ultrasparc")) 88 2)
310 (define_function_unit "fp" 1 0
311 (and (eq_attr "type" "fpsqrt") (eq_attr "cpu" "ultrasparc")) 48 2)
313 ;; Compare instructions.
314 ;; This controls RTL generation and register allocation.
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.
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
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.
329 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
331 (define_expand "cmpsi"
333 (compare:CC (match_operand:SI 0 "register_operand" "")
334 (match_operand:SI 1 "arith_operand" "")))]
338 sparc_compare_op0 = operands[0];
339 sparc_compare_op1 = operands[1];
343 (define_expand "cmpdi"
345 (compare:CCX (match_operand:DI 0 "register_operand" "")
346 (match_operand:DI 1 "arith_double_operand" "")))]
350 sparc_compare_op0 = operands[0];
351 sparc_compare_op1 = operands[1];
355 (define_expand "cmpsf"
356 ;; The 96 here isn't ever used by anyone.
358 (compare:CCFP (match_operand:SF 0 "register_operand" "")
359 (match_operand:SF 1 "register_operand" "")))]
363 sparc_compare_op0 = operands[0];
364 sparc_compare_op1 = operands[1];
368 (define_expand "cmpdf"
369 ;; The 96 here isn't ever used by anyone.
371 (compare:CCFP (match_operand:DF 0 "register_operand" "")
372 (match_operand:DF 1 "register_operand" "")))]
376 sparc_compare_op0 = operands[0];
377 sparc_compare_op1 = operands[1];
381 (define_expand "cmptf"
382 ;; The 96 here isn't ever used by anyone.
384 (compare:CCFP (match_operand:TF 0 "register_operand" "")
385 (match_operand:TF 1 "register_operand" "")))]
389 sparc_compare_op0 = operands[0];
390 sparc_compare_op1 = operands[1];
394 ;; Now the compare DEFINE_INSNs.
396 (define_insn "*cmpsi_insn"
398 (compare:CC (match_operand:SI 0 "register_operand" "r")
399 (match_operand:SI 1 "arith_operand" "rI")))]
402 [(set_attr "type" "compare")])
404 (define_insn "*cmpdi_sp64"
406 (compare:CCX (match_operand:DI 0 "register_operand" "r")
407 (match_operand:DI 1 "arith_double_operand" "rHI")))]
410 [(set_attr "type" "compare")])
412 (define_insn "*cmpsf_fpe"
413 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
414 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
415 (match_operand:SF 2 "register_operand" "f")))]
420 return \"fcmpes %0,%1,%2\";
421 return \"fcmpes %1,%2\";
423 [(set_attr "type" "fpcmp")])
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")))]
433 return \"fcmped %0,%1,%2\";
434 return \"fcmped %1,%2\";
436 [(set_attr "type" "fpcmp")])
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"
446 return \"fcmpeq %0,%1,%2\";
447 return \"fcmpeq %1,%2\";
449 [(set_attr "type" "fpcmp")])
451 (define_insn "*cmpsf_fp"
452 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
453 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
454 (match_operand:SF 2 "register_operand" "f")))]
459 return \"fcmps %0,%1,%2\";
460 return \"fcmps %1,%2\";
462 [(set_attr "type" "fpcmp")])
464 (define_insn "*cmpdf_fp"
465 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
466 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
467 (match_operand:DF 2 "register_operand" "e")))]
472 return \"fcmpd %0,%1,%2\";
473 return \"fcmpd %1,%2\";
475 [(set_attr "type" "fpcmp")])
477 (define_insn "*cmptf_fp"
478 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
479 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
480 (match_operand:TF 2 "register_operand" "e")))]
481 "TARGET_FPU && TARGET_HARD_QUAD"
485 return \"fcmpq %0,%1,%2\";
486 return \"fcmpq %1,%2\";
488 [(set_attr "type" "fpcmp")])
490 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
491 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
492 ;; the same code as v8 (the addx/subx method has more applications). The
493 ;; exception to this is "reg != 0" which can be done in one instruction on v9
494 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
497 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
498 ;; generate addcc/subcc instructions.
500 (define_expand "seqsi_special"
502 (xor:SI (match_operand:SI 1 "register_operand" "")
503 (match_operand:SI 2 "register_operand" "")))
504 (parallel [(set (match_operand:SI 0 "register_operand" "")
505 (eq:SI (match_dup 3) (const_int 0)))
506 (clobber (reg:CC 100))])]
508 "{ operands[3] = gen_reg_rtx (SImode); }")
510 (define_expand "seqdi_special"
512 (xor:DI (match_operand:DI 1 "register_operand" "")
513 (match_operand:DI 2 "register_operand" "")))
514 (set (match_operand:DI 0 "register_operand" "")
515 (eq:DI (match_dup 3) (const_int 0)))]
517 "{ operands[3] = gen_reg_rtx (DImode); }")
519 (define_expand "snesi_special"
521 (xor:SI (match_operand:SI 1 "register_operand" "")
522 (match_operand:SI 2 "register_operand" "")))
523 (parallel [(set (match_operand:SI 0 "register_operand" "")
524 (ne:SI (match_dup 3) (const_int 0)))
525 (clobber (reg:CC 100))])]
527 "{ operands[3] = gen_reg_rtx (SImode); }")
529 (define_expand "snedi_special"
531 (xor:DI (match_operand:DI 1 "register_operand" "")
532 (match_operand:DI 2 "register_operand" "")))
533 (set (match_operand:DI 0 "register_operand" "")
534 (ne:DI (match_dup 3) (const_int 0)))]
536 "{ operands[3] = gen_reg_rtx (DImode); }")
538 (define_expand "seqdi_special_trunc"
540 (xor:DI (match_operand:DI 1 "register_operand" "")
541 (match_operand:DI 2 "register_operand" "")))
542 (set (match_operand:SI 0 "register_operand" "")
543 (eq:DI (match_dup 3) (const_int 0)))]
545 "{ operands[3] = gen_reg_rtx (DImode); }")
547 (define_expand "snedi_special_trunc"
549 (xor:DI (match_operand:DI 1 "register_operand" "")
550 (match_operand:DI 2 "register_operand" "")))
551 (set (match_operand:SI 0 "register_operand" "")
552 (ne:DI (match_dup 3) (const_int 0)))]
554 "{ operands[3] = gen_reg_rtx (DImode); }")
556 (define_expand "seqsi_special_extend"
558 (xor:SI (match_operand:SI 1 "register_operand" "")
559 (match_operand:SI 2 "register_operand" "")))
560 (parallel [(set (match_operand:DI 0 "register_operand" "")
561 (eq:SI (match_dup 3) (const_int 0)))
562 (clobber (reg:CC 100))])]
564 "{ operands[3] = gen_reg_rtx (SImode); }")
566 (define_expand "snesi_special_extend"
568 (xor:SI (match_operand:SI 1 "register_operand" "")
569 (match_operand:SI 2 "register_operand" "")))
570 (parallel [(set (match_operand:DI 0 "register_operand" "")
571 (ne:SI (match_dup 3) (const_int 0)))
572 (clobber (reg:CC 100))])]
574 "{ operands[3] = gen_reg_rtx (SImode); }")
576 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
577 ;; However, the code handles both SImode and DImode.
579 [(set (match_operand:SI 0 "intreg_operand" "")
580 (eq:SI (match_dup 1) (const_int 0)))]
584 if (GET_MODE (sparc_compare_op0) == SImode)
588 if (GET_MODE (operands[0]) == SImode)
589 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
591 else if (! TARGET_ARCH64)
594 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
599 else if (GET_MODE (sparc_compare_op0) == DImode)
605 else if (GET_MODE (operands[0]) == SImode)
606 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
609 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
614 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
616 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
617 emit_insn (gen_sne (operands[0]));
622 if (gen_v9_scc (EQ, operands))
626 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
629 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
630 ;; However, the code handles both SImode and DImode.
632 [(set (match_operand:SI 0 "intreg_operand" "")
633 (ne:SI (match_dup 1) (const_int 0)))]
637 if (GET_MODE (sparc_compare_op0) == SImode)
641 if (GET_MODE (operands[0]) == SImode)
642 pat = gen_snesi_special (operands[0], sparc_compare_op0,
644 else if (! TARGET_ARCH64)
647 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
652 else if (GET_MODE (sparc_compare_op0) == DImode)
658 else if (GET_MODE (operands[0]) == SImode)
659 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
662 pat = gen_snedi_special (operands[0], sparc_compare_op0,
667 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
669 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
670 emit_insn (gen_sne (operands[0]));
675 if (gen_v9_scc (NE, operands))
679 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
683 [(set (match_operand:SI 0 "intreg_operand" "")
684 (gt:SI (match_dup 1) (const_int 0)))]
688 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
690 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
691 emit_insn (gen_sne (operands[0]));
696 if (gen_v9_scc (GT, operands))
700 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
704 [(set (match_operand:SI 0 "intreg_operand" "")
705 (lt:SI (match_dup 1) (const_int 0)))]
709 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
711 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
712 emit_insn (gen_sne (operands[0]));
717 if (gen_v9_scc (LT, operands))
721 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
725 [(set (match_operand:SI 0 "intreg_operand" "")
726 (ge:SI (match_dup 1) (const_int 0)))]
730 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
732 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
733 emit_insn (gen_sne (operands[0]));
738 if (gen_v9_scc (GE, operands))
742 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
746 [(set (match_operand:SI 0 "intreg_operand" "")
747 (le:SI (match_dup 1) (const_int 0)))]
751 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
753 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
754 emit_insn (gen_sne (operands[0]));
759 if (gen_v9_scc (LE, operands))
763 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
766 (define_expand "sgtu"
767 [(set (match_operand:SI 0 "intreg_operand" "")
768 (gtu:SI (match_dup 1) (const_int 0)))]
776 /* We can do ltu easily, so if both operands are registers, swap them and
778 if ((GET_CODE (sparc_compare_op0) == REG
779 || GET_CODE (sparc_compare_op0) == SUBREG)
780 && (GET_CODE (sparc_compare_op1) == REG
781 || GET_CODE (sparc_compare_op1) == SUBREG))
783 tem = sparc_compare_op0;
784 sparc_compare_op0 = sparc_compare_op1;
785 sparc_compare_op1 = tem;
786 emit_insn (gen_sltu (operands[0]));
792 if (gen_v9_scc (GTU, operands))
795 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
798 (define_expand "sltu"
799 [(set (match_operand:SI 0 "intreg_operand" "")
800 (ltu:SI (match_dup 1) (const_int 0)))]
806 if (gen_v9_scc (LTU, operands))
809 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
812 (define_expand "sgeu"
813 [(set (match_operand:SI 0 "intreg_operand" "")
814 (geu:SI (match_dup 1) (const_int 0)))]
820 if (gen_v9_scc (GEU, operands))
823 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
826 (define_expand "sleu"
827 [(set (match_operand:SI 0 "intreg_operand" "")
828 (leu:SI (match_dup 1) (const_int 0)))]
836 /* We can do geu easily, so if both operands are registers, swap them and
838 if ((GET_CODE (sparc_compare_op0) == REG
839 || GET_CODE (sparc_compare_op0) == SUBREG)
840 && (GET_CODE (sparc_compare_op1) == REG
841 || GET_CODE (sparc_compare_op1) == SUBREG))
843 tem = sparc_compare_op0;
844 sparc_compare_op0 = sparc_compare_op1;
845 sparc_compare_op1 = tem;
846 emit_insn (gen_sgeu (operands[0]));
852 if (gen_v9_scc (LEU, operands))
855 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
858 ;; Now the DEFINE_INSNs for the scc cases.
860 ;; The SEQ and SNE patterns are special because they can be done
861 ;; without any branching and do not involve a COMPARE.
863 (define_insn "*snesi_zero"
864 [(set (match_operand:SI 0 "register_operand" "=r")
865 (ne:SI (match_operand:SI 1 "register_operand" "r")
867 (clobber (reg:CC 100))]
869 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
870 [(set_attr "type" "unary")
871 (set_attr "length" "2")])
873 (define_insn "*neg_snesi_zero"
874 [(set (match_operand:SI 0 "register_operand" "=r")
875 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
877 (clobber (reg:CC 100))]
879 "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
880 [(set_attr "type" "unary")
881 (set_attr "length" "2")])
883 (define_insn "*snesi_zero_extend"
884 [(set (match_operand:DI 0 "register_operand" "=r")
885 (ne:SI (match_operand:SI 1 "register_operand" "r")
887 (clobber (reg:CC 100))]
889 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
890 [(set_attr "type" "unary")
891 (set_attr "length" "2")])
893 (define_insn "*snedi_zero"
894 [(set (match_operand:DI 0 "register_operand" "=&r")
895 (ne:DI (match_operand:DI 1 "register_operand" "r")
898 "mov 0,%0\;movrnz %1,1,%0"
899 [(set_attr "type" "unary")
900 (set_attr "length" "2")])
902 (define_insn "*neg_snedi_zero"
903 [(set (match_operand:DI 0 "register_operand" "=&r")
904 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
907 "mov 0,%0\;movrnz %1,-1,%0"
908 [(set_attr "type" "unary")
909 (set_attr "length" "2")])
911 (define_insn "*snedi_zero_trunc"
912 [(set (match_operand:SI 0 "register_operand" "=&r")
913 (ne:DI (match_operand:DI 1 "register_operand" "r")
916 "mov 0,%0\;movrnz %1,1,%0"
917 [(set_attr "type" "unary")
918 (set_attr "length" "2")])
920 (define_insn "*seqsi_zero"
921 [(set (match_operand:SI 0 "register_operand" "=r")
922 (eq:SI (match_operand:SI 1 "register_operand" "r")
924 (clobber (reg:CC 100))]
926 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
927 [(set_attr "type" "unary")
928 (set_attr "length" "2")])
930 (define_insn "*neg_seqsi_zero"
931 [(set (match_operand:SI 0 "register_operand" "=r")
932 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
934 (clobber (reg:CC 100))]
936 "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
937 [(set_attr "type" "unary")
938 (set_attr "length" "2")])
940 (define_insn "*seqsi_zero_extend"
941 [(set (match_operand:DI 0 "register_operand" "=r")
942 (eq:SI (match_operand:SI 1 "register_operand" "r")
944 (clobber (reg:CC 100))]
946 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
947 [(set_attr "type" "unary")
948 (set_attr "length" "2")])
950 (define_insn "*seqdi_zero"
951 [(set (match_operand:DI 0 "register_operand" "=&r")
952 (eq:DI (match_operand:DI 1 "register_operand" "r")
955 "mov 0,%0\;movrz %1,1,%0"
956 [(set_attr "type" "unary")
957 (set_attr "length" "2")])
959 (define_insn "*neg_seqdi_zero"
960 [(set (match_operand:DI 0 "register_operand" "=&r")
961 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
964 "mov 0,%0\;movrz %1,-1,%0"
965 [(set_attr "type" "unary")
966 (set_attr "length" "2")])
968 (define_insn "*seqdi_zero_trunc"
969 [(set (match_operand:SI 0 "register_operand" "=&r")
970 (eq:DI (match_operand:DI 1 "register_operand" "r")
973 "mov 0,%0\;movrz %1,1,%0"
974 [(set_attr "type" "unary")
975 (set_attr "length" "2")])
977 ;; We can also do (x + (i == 0)) and related, so put them in.
978 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
981 (define_insn "*x_plus_i_ne_0"
982 [(set (match_operand:SI 0 "register_operand" "=r")
983 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
985 (match_operand:SI 2 "register_operand" "r")))
986 (clobber (reg:CC 100))]
988 "subcc %%g0,%1,%%g0\;addx %2,0,%0"
989 [(set_attr "length" "2")])
991 (define_insn "*x_minus_i_ne_0"
992 [(set (match_operand:SI 0 "register_operand" "=r")
993 (minus:SI (match_operand:SI 2 "register_operand" "r")
994 (ne:SI (match_operand:SI 1 "register_operand" "r")
996 (clobber (reg:CC 100))]
998 "subcc %%g0,%1,%%g0\;subx %2,0,%0"
999 [(set_attr "length" "2")])
1001 (define_insn "*x_plus_i_eq_0"
1002 [(set (match_operand:SI 0 "register_operand" "=r")
1003 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1005 (match_operand:SI 2 "register_operand" "r")))
1006 (clobber (reg:CC 100))]
1008 "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
1009 [(set_attr "length" "2")])
1011 (define_insn "*x_minus_i_eq_0"
1012 [(set (match_operand:SI 0 "register_operand" "=r")
1013 (minus:SI (match_operand:SI 2 "register_operand" "r")
1014 (eq:SI (match_operand:SI 1 "register_operand" "r")
1016 (clobber (reg:CC 100))]
1018 "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
1019 [(set_attr "length" "2")])
1021 ;; We can also do GEU and LTU directly, but these operate after a compare.
1022 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1025 (define_insn "*sltu_insn"
1026 [(set (match_operand:SI 0 "register_operand" "=r")
1027 (ltu:SI (reg:CC 100) (const_int 0)))]
1030 [(set_attr "type" "misc")])
1032 (define_insn "*neg_sltu_insn"
1033 [(set (match_operand:SI 0 "register_operand" "=r")
1034 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1037 [(set_attr "type" "misc")])
1039 ;; ??? Combine should canonicalize these next two to the same pattern.
1040 (define_insn "*neg_sltu_minus_x"
1041 [(set (match_operand:SI 0 "register_operand" "=r")
1042 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1043 (match_operand:SI 1 "arith_operand" "rI")))]
1046 [(set_attr "type" "unary")])
1048 (define_insn "*neg_sltu_plus_x"
1049 [(set (match_operand:SI 0 "register_operand" "=r")
1050 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1051 (match_operand:SI 1 "arith_operand" "rI"))))]
1054 [(set_attr "type" "unary")])
1056 (define_insn "*sgeu_insn"
1057 [(set (match_operand:SI 0 "register_operand" "=r")
1058 (geu:SI (reg:CC 100) (const_int 0)))]
1061 [(set_attr "type" "misc")])
1063 (define_insn "*neg_sgeu_insn"
1064 [(set (match_operand:SI 0 "register_operand" "=r")
1065 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1068 [(set_attr "type" "misc")])
1070 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1071 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1074 (define_insn "*sltu_plus_x"
1075 [(set (match_operand:SI 0 "register_operand" "=r")
1076 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1077 (match_operand:SI 1 "arith_operand" "rI")))]
1080 [(set_attr "type" "unary")])
1082 (define_insn "*sltu_plus_x_plus_y"
1083 [(set (match_operand:SI 0 "register_operand" "=r")
1084 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1085 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1086 (match_operand:SI 2 "arith_operand" "rI"))))]
1090 (define_insn "*x_minus_sltu"
1091 [(set (match_operand:SI 0 "register_operand" "=r")
1092 (minus:SI (match_operand:SI 1 "register_operand" "r")
1093 (ltu:SI (reg:CC 100) (const_int 0))))]
1096 [(set_attr "type" "unary")])
1098 ;; ??? Combine should canonicalize these next two to the same pattern.
1099 (define_insn "*x_minus_y_minus_sltu"
1100 [(set (match_operand:SI 0 "register_operand" "=r")
1101 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1102 (match_operand:SI 2 "arith_operand" "rI"))
1103 (ltu:SI (reg:CC 100) (const_int 0))))]
1107 (define_insn "*x_minus_sltu_plus_y"
1108 [(set (match_operand:SI 0 "register_operand" "=r")
1109 (minus:SI (match_operand:SI 1 "register_operand" "r")
1110 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1111 (match_operand:SI 2 "arith_operand" "rI"))))]
1115 (define_insn "*sgeu_plus_x"
1116 [(set (match_operand:SI 0 "register_operand" "=r")
1117 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1118 (match_operand:SI 1 "register_operand" "r")))]
1121 [(set_attr "type" "unary")])
1123 (define_insn "*x_minus_sgeu"
1124 [(set (match_operand:SI 0 "register_operand" "=r")
1125 (minus:SI (match_operand:SI 1 "register_operand" "r")
1126 (geu:SI (reg:CC 100) (const_int 0))))]
1129 [(set_attr "type" "unary")])
1131 ;; Now we have the generic scc insns.
1132 ;; !v9: These will be done using a jump.
1133 ;; v9: Use conditional moves which are defined elsewhere.
1134 ;; We have to exclude the cases above, since we will not want combine to
1135 ;; turn something that does not require a jump into something that does.
1137 (define_insn "*scc_si"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (match_operator:SI 2 "noov_compare_op"
1140 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1143 "* return output_scc_insn (operands, insn); "
1144 [(set_attr "type" "multi")
1145 (set_attr "length" "3")])
1147 (define_insn "*scc_di"
1148 [(set (match_operand:DI 0 "register_operand" "=r")
1149 (match_operator:DI 2 "noov_compare_op"
1150 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1153 "* return output_scc_insn (operands, insn); "
1154 [(set_attr "type" "multi")
1155 (set_attr "length" "3")])
1157 ;; These control RTL generation for conditional jump insns
1159 ;; The quad-word fp compare library routines all return nonzero to indicate
1160 ;; true, which is different from the equivalent libgcc routines, so we must
1161 ;; handle them specially here.
1163 (define_expand "beq"
1165 (if_then_else (eq (match_dup 1) (const_int 0))
1166 (label_ref (match_operand 0 "" ""))
1171 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1172 && GET_CODE (sparc_compare_op0) == REG
1173 && GET_MODE (sparc_compare_op0) == DImode)
1175 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1178 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1180 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1181 emit_jump_insn (gen_bne (operands[0]));
1184 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1187 (define_expand "bne"
1189 (if_then_else (ne (match_dup 1) (const_int 0))
1190 (label_ref (match_operand 0 "" ""))
1195 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1196 && GET_CODE (sparc_compare_op0) == REG
1197 && GET_MODE (sparc_compare_op0) == DImode)
1199 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1202 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1204 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1205 emit_jump_insn (gen_bne (operands[0]));
1208 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1211 (define_expand "bgt"
1213 (if_then_else (gt (match_dup 1) (const_int 0))
1214 (label_ref (match_operand 0 "" ""))
1219 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1220 && GET_CODE (sparc_compare_op0) == REG
1221 && GET_MODE (sparc_compare_op0) == DImode)
1223 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1226 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1228 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1229 emit_jump_insn (gen_bne (operands[0]));
1232 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1235 (define_expand "bgtu"
1237 (if_then_else (gtu (match_dup 1) (const_int 0))
1238 (label_ref (match_operand 0 "" ""))
1242 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1245 (define_expand "blt"
1247 (if_then_else (lt (match_dup 1) (const_int 0))
1248 (label_ref (match_operand 0 "" ""))
1253 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1254 && GET_CODE (sparc_compare_op0) == REG
1255 && GET_MODE (sparc_compare_op0) == DImode)
1257 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1260 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1262 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1263 emit_jump_insn (gen_bne (operands[0]));
1266 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1269 (define_expand "bltu"
1271 (if_then_else (ltu (match_dup 1) (const_int 0))
1272 (label_ref (match_operand 0 "" ""))
1276 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1279 (define_expand "bge"
1281 (if_then_else (ge (match_dup 1) (const_int 0))
1282 (label_ref (match_operand 0 "" ""))
1287 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1288 && GET_CODE (sparc_compare_op0) == REG
1289 && GET_MODE (sparc_compare_op0) == DImode)
1291 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1294 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1296 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1297 emit_jump_insn (gen_bne (operands[0]));
1300 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1303 (define_expand "bgeu"
1305 (if_then_else (geu (match_dup 1) (const_int 0))
1306 (label_ref (match_operand 0 "" ""))
1310 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1313 (define_expand "ble"
1315 (if_then_else (le (match_dup 1) (const_int 0))
1316 (label_ref (match_operand 0 "" ""))
1321 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1322 && GET_CODE (sparc_compare_op0) == REG
1323 && GET_MODE (sparc_compare_op0) == DImode)
1325 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1328 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1330 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1331 emit_jump_insn (gen_bne (operands[0]));
1334 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1337 (define_expand "bleu"
1339 (if_then_else (leu (match_dup 1) (const_int 0))
1340 (label_ref (match_operand 0 "" ""))
1344 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1347 ;; Now match both normal and inverted jump.
1349 (define_insn "*normal_branch"
1351 (if_then_else (match_operator 0 "noov_compare_op"
1352 [(reg 100) (const_int 0)])
1353 (label_ref (match_operand 1 "" ""))
1358 return output_cbranch (operands[0], 1, 0,
1359 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1362 [(set_attr "type" "branch")])
1364 (define_insn "*inverted_branch"
1366 (if_then_else (match_operator 0 "noov_compare_op"
1367 [(reg 100) (const_int 0)])
1369 (label_ref (match_operand 1 "" ""))))]
1373 return output_cbranch (operands[0], 1, 1,
1374 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1377 [(set_attr "type" "branch")])
1379 (define_insn "*normal_fp_branch"
1381 (if_then_else (match_operator 1 "comparison_operator"
1382 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1384 (label_ref (match_operand 2 "" ""))
1389 return output_cbranch (operands[1], 2, 0,
1390 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1393 [(set_attr "type" "branch")])
1395 (define_insn "*inverted_fp_branch"
1397 (if_then_else (match_operator 1 "comparison_operator"
1398 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1401 (label_ref (match_operand 2 "" ""))))]
1405 return output_cbranch (operands[1], 2, 1,
1406 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1409 [(set_attr "type" "branch")])
1411 (define_insn "*normal_fpe_branch"
1413 (if_then_else (match_operator 1 "comparison_operator"
1414 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1416 (label_ref (match_operand 2 "" ""))
1421 return output_cbranch (operands[1], 2, 0,
1422 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1425 [(set_attr "type" "branch")])
1427 (define_insn "*inverted_fpe_branch"
1429 (if_then_else (match_operator 1 "comparison_operator"
1430 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1433 (label_ref (match_operand 2 "" ""))))]
1437 return output_cbranch (operands[1], 2, 1,
1438 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1441 [(set_attr "type" "branch")])
1443 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1444 ;; in the architecture.
1446 ;; There are no 32 bit brreg insns.
1448 (define_insn "*normal_int_branch_sp64"
1450 (if_then_else (match_operator 0 "v9_regcmp_op"
1451 [(match_operand:DI 1 "register_operand" "r")
1453 (label_ref (match_operand 2 "" ""))
1458 return output_v9branch (operands[0], 1, 2, 0,
1459 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1462 [(set_attr "type" "branch")])
1464 (define_insn "*inverted_int_branch_sp64"
1466 (if_then_else (match_operator 0 "v9_regcmp_op"
1467 [(match_operand:DI 1 "register_operand" "r")
1470 (label_ref (match_operand 2 "" ""))))]
1474 return output_v9branch (operands[0], 1, 2, 1,
1475 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1478 [(set_attr "type" "branch")])
1480 ;; Esoteric move insns (lo_sum, high, pic).
1482 (define_insn "*lo_sum_si"
1483 [(set (match_operand:SI 0 "register_operand" "=r")
1484 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1485 (match_operand:SI 2 "immediate_operand" "in")))]
1487 ;; V9 needs "add" because of the code models. We still use "or" for v8
1488 ;; so we can compare the old compiler with the new.
1489 "* return TARGET_ARCH64 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1490 ;; Need to set length for this arith insn because operand2
1491 ;; is not an "arith_operand".
1492 [(set_attr "length" "1")])
1494 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1495 ;; confuse them with real addresses.
1496 (define_insn "pic_lo_sum_si"
1497 [(set (match_operand:SI 0 "register_operand" "=r")
1498 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1499 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1501 ;; V9 needs "add" because of the code models. We still use "or" for v8
1502 ;; so we can compare the old compiler with the new.
1503 "* return TARGET_ARCH64 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1504 ;; Need to set length for this arith insn because operand2
1505 ;; is not an "arith_operand".
1506 [(set_attr "length" "1")])
1508 ;; The PIC version of sethi must appear before the non-pic case so that
1509 ;; the unspec will not be matched as part of the operand.
1510 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1511 ;; confuse them with real addresses.
1512 (define_insn "pic_sethi_si"
1513 [(set (match_operand:SI 0 "register_operand" "=r")
1514 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1515 "flag_pic && check_pic (1)"
1516 "sethi %%hi(%a1),%0"
1517 [(set_attr "type" "move")
1518 (set_attr "length" "1")])
1520 (define_insn "*sethi_si"
1521 [(set (match_operand:SI 0 "register_operand" "=r")
1522 (high:SI (match_operand 1 "" "")))]
1524 "sethi %%hi(%a1),%0"
1525 [(set_attr "type" "move")
1526 (set_attr "length" "1")])
1528 (define_insn "*sethi_hi"
1529 [(set (match_operand:HI 0 "register_operand" "=r")
1530 (high:HI (match_operand 1 "" "")))]
1532 "sethi %%hi(%a1),%0"
1533 [(set_attr "type" "move")
1534 (set_attr "length" "1")])
1536 (define_insn "get_pc_via_call"
1537 [(set (pc) (label_ref (match_operand 0 "" "")))
1538 (set (reg:SI 15) (label_ref (match_operand 1 "" "")))]
1541 [(set_attr "type" "uncond_branch")])
1543 (define_insn "get_pc_via_rdpc"
1544 [(set (match_operand:DI 0 "register_operand" "=r") (pc))]
1547 [(set_attr "type" "move")])
1549 ;; Special pic pattern, for loading the address of a label into a register.
1550 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
1551 ;; there. The pic tablejump pattern also uses this.
1553 (define_insn "move_pic_label_si"
1554 [(set (match_operand:SI 0 "register_operand" "=r")
1555 ; This was previously (label_ref:SI (match_operand 1 "" "")) but that
1556 ; loses the volatil and other flags of the original label_ref.
1557 (match_operand:SI 1 "label_ref_operand" ""))
1558 (set (reg:SI 15) (pc))]
1562 if (get_attr_length (insn) == 2)
1563 return \"\\n1:\;call 2f\;add %%o7,%%lo(%l1-1b),%0\\n2:\";
1565 return \"\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0\";
1567 [(set_attr "type" "multi")
1568 ; 960 = 4096 bytes / 4 bytes/insn - 64 (for not always perfect length calcs)
1569 (set (attr "length") (if_then_else (ltu (minus (match_dup 1) (pc))
1574 ;; Special sparc64 pattern for loading the address of a label into a register.
1575 ;; The pic and non-pic cases are the same since it's the most efficient way.
1577 ;; ??? The non-pic case doesn't need to use %o7, we could use a scratch
1578 ;; instead. But the pic case doesn't need to use %o7 either. We handle them
1579 ;; both here so that when this is fixed, they can both be fixed together.
1580 ;; Don't forget that the pic jump table stuff uses %o7 (that will need to be
1583 (define_insn "move_label_di"
1584 [(set (match_operand:DI 0 "register_operand" "=r")
1585 ; This was previously (label_ref:DI (match_operand 1 "" "")) but that
1586 ; loses the volatil and other flags of the original label_ref.
1587 (match_operand:DI 1 "label_ref_operand" ""))
1588 (set (reg:DI 15) (pc))]
1592 if (get_attr_length (insn) == 2)
1593 return \"\\n1:\;rd %%pc,%%o7\;add %%o7,%l1-1b,%0\";
1595 return \"\\n1:\;rd %%pc,%%o7\;sethi %%hi(%l1-1b),%0\;add %0,%%lo(%l1-1b),%0\;sra %0,0,%0\;add %0,%%o7,%0\";
1597 [(set_attr "type" "multi")
1598 ; 960 = 4096 bytes / 4 bytes/insn - 64 (for not always perfect length calcs)
1599 (set (attr "length") (if_then_else (ltu (minus (match_dup 1) (pc))
1604 (define_insn "*lo_sum_di_sp32"
1605 [(set (match_operand:DI 0 "register_operand" "=r")
1606 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1607 (match_operand:DI 2 "immediate_operand" "in")))]
1611 /* Don't output a 64 bit constant, since we can't trust the assembler to
1612 handle it correctly. */
1613 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1614 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
1615 else if (GET_CODE (operands[2]) == CONST_INT
1616 && HOST_BITS_PER_WIDE_INT > 32
1617 && INTVAL (operands[2]) > 0xffffffff)
1618 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
1620 return \"or %L1,%%lo(%a2),%L0\";
1622 ;; Need to set length for this arith insn because operand2
1623 ;; is not an "arith_operand".
1624 [(set_attr "length" "1")])
1626 ;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add?
1628 (define_insn "*lo_sum_di_sp64"
1629 [(set (match_operand:DI 0 "register_operand" "=r")
1630 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1631 (match_operand:DI 2 "immediate_operand" "in")))]
1635 /* Don't output a 64 bit constant, since we can't trust the assembler to
1636 handle it correctly. */
1637 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1638 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
1639 else if (GET_CODE (operands[2]) == CONST_INT
1640 && HOST_BITS_PER_WIDE_INT > 32
1641 && INTVAL (operands[2]) > 0xffffffff)
1642 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
1644 /* Note that we use add here. This is important because Medium/Anywhere
1645 code model support depends on it. */
1646 return \"add %1,%%lo(%a2),%0\";
1648 ;; Need to set length for this arith insn because operand2
1649 ;; is not an "arith_operand".
1650 [(set_attr "length" "1")])
1652 (define_insn "*sethi_di_sp32"
1653 [(set (match_operand:DI 0 "register_operand" "=r")
1654 (high:DI (match_operand 1 "" "")))]
1655 "! TARGET_ARCH64 && check_pic (1)"
1658 rtx op0 = operands[0];
1659 rtx op1 = operands[1];
1661 if (GET_CODE (op1) == CONST_INT)
1663 operands[0] = operand_subword (op0, 1, 0, DImode);
1664 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1666 operands[0] = operand_subword (op0, 0, 0, DImode);
1667 if (INTVAL (op1) < 0)
1668 return \"mov -1,%0\";
1670 return \"mov 0,%0\";
1672 else if (GET_CODE (op1) == CONST_DOUBLE)
1674 operands[0] = operand_subword (op0, 1, 0, DImode);
1675 operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
1676 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1678 operands[0] = operand_subword (op0, 0, 0, DImode);
1679 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
1680 return singlemove_string (operands);
1686 [(set_attr "type" "move")
1687 (set_attr "length" "2")])
1689 ;;; ??? This pattern originally clobbered a scratch register. However, this
1690 ;;; is invalid, the movdi pattern may not use a temp register because it
1691 ;;; may be called from reload to reload a DImode value. In that case, we
1692 ;;; end up with a scratch register that never gets allocated. To avoid this,
1693 ;;; we use global register 1 which is never otherwise used by gcc as a temp.
1694 ;;; The correct solution here might be to force DImode constants to memory,
1695 ;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg
1696 ;;; 1 will then no longer need to be considered a fixed reg.
1698 (define_expand "sethi_di_sp64"
1700 [(set (match_operand:DI 0 "register_operand" "")
1701 (high:DI (match_operand 1 "general_operand" "")))
1702 (clobber (reg:DI 1))])]
1706 (define_insn "*sethi_di_sp64_const"
1707 [(set (match_operand:DI 0 "register_operand" "=r")
1708 (high:DI (match_operand 1 "const_double_operand" "")))
1709 (clobber (reg:DI 1))]
1710 "TARGET_ARCH64 && check_pic (1)"
1713 #if HOST_BITS_PER_WIDE_INT == 32
1716 split_double (operands[1], &high, &low);
1718 if (high == const0_rtx)
1721 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1726 output_asm_insn (singlemove_string (operands), operands);
1729 output_asm_insn (\"sllx %0,32,%0\", operands);
1730 if (low != const0_rtx)
1731 output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
1734 rtx op = operands[1];
1736 if (! SPARC_SETHI_P (INTVAL(op)))
1738 operands[1] = GEN_INT (INTVAL (op) >> 32);
1739 output_asm_insn (singlemove_string (operands), operands);
1741 output_asm_insn (\"sllx %0,32,%0\", operands);
1742 if (INTVAL (op) & 0xffffffff)
1744 operands[1] = GEN_INT (INTVAL (op) & 0xffffffff);
1745 output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
1750 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1756 [(set_attr "type" "move")
1757 (set_attr "length" "5")])
1759 ;; Most of the required support for the various code models is here.
1760 ;; We can do this because sparcs need the high insn to load the address. We
1761 ;; just need to get high to do the right thing for each code model. Then each
1762 ;; uses the same "%X+%lo(...)" in the load/store insn.
1764 ;; When TARGET_MEDLOW, assume that the upper 32 bits of symbol addresses are
1766 ;; When TARGET_MEDANY, the text and data segments have a maximum size of 32
1767 ;; bits and may be located anywhere. MEDANY_BASE_REG contains the start
1768 ;; address of the data segment, currently %g4.
1769 ;; When TARGET_FULLANY, symbolic addresses are 64 bits.
1771 (define_insn "*sethi_di_medlow"
1772 [(set (match_operand:DI 0 "register_operand" "=r")
1773 (high:DI (match_operand 1 "" "")))
1774 ;; The clobber is here because emit_move_sequence assumes the worst case.
1775 (clobber (reg:DI 1))]
1776 "TARGET_MEDLOW && check_pic (1)"
1777 "sethi %%hi(%a1),%0"
1778 [(set_attr "type" "move")
1779 (set_attr "length" "1")])
1781 (define_insn "*sethi_di_medium_pic"
1782 [(set (match_operand:DI 0 "register_operand" "=r")
1783 (high:DI (match_operand 1 "sp64_medium_pic_operand" "")))]
1784 "(TARGET_MEDLOW || TARGET_MEDANY) && check_pic (1)"
1785 "sethi %%hi(%a1),%0"
1786 [(set_attr "type" "move")
1787 (set_attr "length" "1")])
1789 ;; WARNING: %0 gets %hi(%1)+%g4.
1790 ;; You cannot OR in %lo(%1), it must be added in.
1792 (define_insn "*sethi_di_medany_data"
1793 [(set (match_operand:DI 0 "register_operand" "=r")
1794 (high:DI (match_operand 1 "data_segment_operand" "")))
1795 ;; The clobber is here because emit_move_sequence assumes the worst case.
1796 (clobber (reg:DI 1))]
1797 "TARGET_MEDANY && check_pic (1)"
1798 "sethi %%hi(%a1),%0; add %0,%%g4,%0"
1799 [(set_attr "type" "move")
1800 (set_attr "length" "2")])
1802 (define_insn "*sethi_di_medany_text"
1803 [(set (match_operand:DI 0 "register_operand" "=r")
1804 (high:DI (match_operand 1 "text_segment_operand" "")))
1805 ;; The clobber is here because emit_move_sequence assumes the worst case.
1806 (clobber (reg:DI 1))]
1807 "TARGET_MEDANY && check_pic (1)"
1808 "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
1809 [(set_attr "type" "move")
1810 (set_attr "length" "5")])
1812 (define_insn "*sethi_di_fullany"
1813 [(set (match_operand:DI 0 "register_operand" "=r")
1814 (high:DI (match_operand 1 "" "")))
1815 (clobber (reg:DI 1))]
1816 "TARGET_FULLANY && check_pic (1)"
1817 "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
1818 [(set_attr "type" "move")
1819 (set_attr "length" "5")])
1821 ;; Move instructions
1823 (define_expand "movqi"
1824 [(set (match_operand:QI 0 "general_operand" "")
1825 (match_operand:QI 1 "general_operand" ""))]
1829 if (emit_move_sequence (operands, QImode))
1833 (define_insn "*movqi_insn"
1834 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1835 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1837 && (register_operand (operands[0], QImode)
1838 || register_operand (operands[1], QImode)
1839 || operands[1] == const0_rtx)"
1845 [(set_attr "type" "move,move,load,store")
1846 (set_attr "length" "1")])
1848 (define_insn "*movqi_insn_liveg0"
1849 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q")
1850 (match_operand:QI 1 "move_operand" "r,J,I,K,Q,r"))]
1852 && (register_operand (operands[0], QImode)
1853 || register_operand (operands[1], QImode))"
1857 and %0,0,%0\;or %0,%1,%0
1861 [(set_attr "type" "move,move,move,move,load,store")
1862 (set_attr "length" "1,1,2,1,1,1")])
1864 (define_insn "*lo_sum_qi"
1865 [(set (match_operand:QI 0 "register_operand" "=r")
1866 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1867 (match_operand 2 "immediate_operand" "in")) 0))]
1869 "or %1,%%lo(%a2),%0"
1870 [(set_attr "length" "1")])
1872 (define_insn "*store_qi"
1873 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1874 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1875 (clobber (match_scratch:SI 2 "=&r"))]
1876 "(reload_completed || reload_in_progress)
1878 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1879 [(set_attr "type" "store")
1880 (set_attr "length" "2")])
1882 (define_expand "movhi"
1883 [(set (match_operand:HI 0 "general_operand" "")
1884 (match_operand:HI 1 "general_operand" ""))]
1888 if (emit_move_sequence (operands, HImode))
1892 (define_insn "*movhi_insn"
1893 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1894 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
1896 && (register_operand (operands[0], HImode)
1897 || register_operand (operands[1], HImode)
1898 || operands[1] == const0_rtx)"
1904 [(set_attr "type" "move,move,load,store")
1905 (set_attr "length" "1")])
1907 (define_insn "*movhi_insn_liveg0"
1908 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q")
1909 (match_operand:HI 1 "move_operand" "r,J,I,K,Q,r"))]
1911 && (register_operand (operands[0], HImode)
1912 || register_operand (operands[1], HImode))"
1916 and %0,0,%0\;or %0,%1,%0
1920 [(set_attr "type" "move,move,move,move,load,store")
1921 (set_attr "length" "1,1,2,1,1,1")])
1923 (define_insn "*lo_sum_hi"
1924 [(set (match_operand:HI 0 "register_operand" "=r")
1925 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1926 (match_operand 2 "immediate_operand" "in")))]
1928 "or %1,%%lo(%a2),%0"
1929 [(set_attr "length" "1")])
1931 (define_insn "*store_hi"
1932 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
1933 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
1934 (clobber (match_scratch:SI 2 "=&r"))]
1935 "(reload_completed || reload_in_progress)
1937 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
1938 [(set_attr "type" "store")
1939 (set_attr "length" "2")])
1941 (define_expand "movsi"
1942 [(set (match_operand:SI 0 "general_operand" "")
1943 (match_operand:SI 1 "general_operand" ""))]
1947 if (emit_move_sequence (operands, SImode))
1951 ;; We must support both 'r' and 'f' registers here, because combine may
1952 ;; convert SFmode hard registers to SImode hard registers when simplifying
1955 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
1956 ;; problems with register allocation. Reload might try to put an integer
1957 ;; in an fp register, or an fp number is an integer register.
1959 (define_insn "*movsi_insn"
1960 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
1961 (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
1963 && (register_operand (operands[0], SImode)
1964 || register_operand (operands[1], SImode)
1965 || operands[1] == const0_rtx)"
1974 [(set_attr "type" "move,fp,move,load,fpload,store,fpstore")
1975 (set_attr "length" "1")])
1977 (define_insn "*movsi_insn_liveg0"
1978 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,r,r,f,Q,Q")
1979 (match_operand:SI 1 "move_operand" "r,J,I,!f,K,Q,!Q,r,!f"))]
1981 && (register_operand (operands[0], SImode)
1982 || register_operand (operands[1], SImode))"
1986 and %0,0,%0\;or %0,%1,%0
1993 [(set_attr "type" "move,move,move,fp,move,load,fpload,store,fpstore")
1994 (set_attr "length" "1,1,2,1,1,1,1,1,1")])
1996 (define_insn "*store_si"
1997 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
1998 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1999 (clobber (match_scratch:SI 2 "=&r"))]
2000 "(reload_completed || reload_in_progress)
2002 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
2003 [(set_attr "type" "store")
2004 (set_attr "length" "2")])
2006 (define_expand "movdi"
2007 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2008 (match_operand:DI 1 "general_operand" ""))]
2012 if (emit_move_sequence (operands, DImode))
2016 (define_insn "*movdi_sp32_insn"
2017 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q")
2018 (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))]
2020 && (register_operand (operands[0], DImode)
2021 || register_operand (operands[1], DImode)
2022 || operands[1] == const0_rtx)"
2025 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2026 return output_fp_move_double (operands);
2027 return output_move_double (operands);
2029 [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore")
2030 (set_attr "length" "2,1,1,3,3,3,2,3,3")])
2032 ;;; ??? The trick used below can be extended to load any negative 32 bit
2033 ;;; constant in two instructions. Currently the compiler will use HIGH/LO_SUM
2034 ;;; for anything not matching the HIK constraints, which results in 5
2035 ;;; instructions. Positive 32 bit constants can be loaded in the obvious way
2036 ;;; with sethi/ori. To extend the trick, in the xor instruction, use
2037 ;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0
2038 ;;; This needs the original value of operands[1], not the inverted value.
2040 (define_insn "*movdi_sp64_insn"
2041 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q")
2042 (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))]
2044 && (register_operand (operands[0], DImode)
2045 || register_operand (operands[1], DImode)
2046 || operands[1] == const0_rtx)"
2049 switch (which_alternative)
2052 return \"mov %1,%0\";
2054 /* Sethi does not sign extend, so we must use a little trickery
2055 to use it for negative numbers. Invert the constant before
2056 loading it in, then use a xor immediate to invert the loaded bits
2057 (along with the upper 32 bits) to the desired constant. This
2058 works because the sethi and immediate fields overlap. */
2060 if ((INTVAL (operands[1]) & 0x80000000) == 0)
2061 return \"sethi %%hi(%a1),%0\";
2064 operands[1] = GEN_INT (~INTVAL (operands[1]));
2065 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
2066 /* The low 10 bits are already zero, but invert the rest.
2067 Assemblers don't accept 0x1c00, so use -0x400 instead. */
2068 return \"xor %0,-0x400,%0\";
2071 return \"ldx %1,%0\";
2073 return \"stx %r1,%0\";
2075 return \"mov %1,%0\";
2077 return \"ldd %1,%0\";
2079 return \"std %1,%0\";
2082 [(set_attr "type" "move,move,load,store,fp,fpload,fpstore")
2083 (set_attr "length" "1,2,1,1,1,1,1")])
2085 ;; ??? There's no symbolic (set (mem:DI ...) ...).
2086 ;; Experimentation with v9 suggested one isn't needed.
2088 ;; Block move insns.
2090 ;; ??? We get better code without it. See output_block_move in sparc.c.
2092 ;; The definition of this insn does not really explain what it does,
2093 ;; but it should suffice
2094 ;; that anything generated as this insn will be recognized as one
2095 ;; and that it will not successfully combine with anything.
2096 ;(define_expand "movstrsi"
2097 ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
2098 ; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
2099 ; (use (match_operand:SI 2 "nonmemory_operand" ""))
2100 ; (use (match_operand:SI 3 "immediate_operand" ""))
2101 ; (clobber (match_dup 0))
2102 ; (clobber (match_dup 1))
2103 ; (clobber (match_scratch:SI 4 ""))
2104 ; (clobber (reg:SI 100))
2105 ; (clobber (reg:SI 1))])]
2109 ; /* If the size isn't known, don't emit inline code. output_block_move
2110 ; would output code that's much slower than the library function.
2111 ; Also don't output code for large blocks. */
2112 ; if (GET_CODE (operands[2]) != CONST_INT
2113 ; || GET_CODE (operands[3]) != CONST_INT
2114 ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
2117 ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2118 ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2119 ; operands[2] = force_not_mem (operands[2]);
2122 ;(define_insn "*block_move_insn"
2123 ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
2124 ; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
2125 ; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
2126 ; (use (match_operand:SI 3 "immediate_operand" "i"))
2127 ; (clobber (match_dup 0))
2128 ; (clobber (match_dup 1))
2129 ; (clobber (match_scratch:SI 4 "=&r"))
2130 ; (clobber (reg:SI 100))
2131 ; (clobber (reg:SI 1))]
2133 ; "* return output_block_move (operands);"
2134 ; [(set_attr "type" "multi")
2135 ; (set_attr "length" "6")])
2137 ;; Floating point move insns
2139 ;; This pattern forces (set (reg:SF ...) (const_double ...))
2140 ;; to be reloaded by putting the constant into memory.
2141 ;; It must come before the more general movsf pattern.
2142 (define_insn "*movsf_const_insn"
2143 [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
2144 (match_operand:SF 1 "" "?F,m,G"))]
2145 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2148 switch (which_alternative)
2151 return singlemove_string (operands);
2153 return \"ld %1,%0\";
2155 return \"st %%g0,%0\";
2158 [(set_attr "type" "load,fpload,store")
2159 (set_attr "length" "2,1,1")])
2161 (define_expand "movsf"
2162 [(set (match_operand:SF 0 "general_operand" "")
2163 (match_operand:SF 1 "general_operand" ""))]
2167 if (emit_move_sequence (operands, SFmode))
2171 (define_insn "*movsf_insn"
2172 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
2173 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
2175 && (register_operand (operands[0], SFmode)
2176 || register_operand (operands[1], SFmode))"
2184 [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
2186 ;; Exactly the same as above, except that all `f' cases are deleted.
2187 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2190 (define_insn "*movsf_no_f_insn"
2191 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
2192 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
2194 && (register_operand (operands[0], SFmode)
2195 || register_operand (operands[1], SFmode))"
2200 [(set_attr "type" "move,load,store")])
2202 (define_insn "*store_sf"
2203 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
2204 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
2205 (clobber (match_scratch:SI 2 "=&r"))]
2206 "(reload_completed || reload_in_progress)
2208 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
2209 [(set_attr "type" "store")
2210 (set_attr "length" "2")])
2212 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2213 ;; to be reloaded by putting the constant into memory.
2214 ;; It must come before the more general movdf pattern.
2216 (define_insn "*movdf_const_insn"
2217 [(set (match_operand:DF 0 "general_operand" "=?r,e,o")
2218 (match_operand:DF 1 "" "?F,m,G"))]
2219 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2222 switch (which_alternative)
2225 return output_move_double (operands);
2227 return output_fp_move_double (operands);
2231 return \"stx %%g0,%0\";
2235 operands[1] = adj_offsettable_operand (operands[0], 4);
2236 return \"st %%g0,%0\;st %%g0,%1\";
2240 [(set_attr "type" "load,fpload,store")
2241 (set_attr "length" "3,3,3")])
2243 (define_expand "movdf"
2244 [(set (match_operand:DF 0 "general_operand" "")
2245 (match_operand:DF 1 "general_operand" ""))]
2249 if (emit_move_sequence (operands, DFmode))
2253 (define_insn "*movdf_insn"
2254 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r")
2255 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))]
2257 && (register_operand (operands[0], DFmode)
2258 || register_operand (operands[1], DFmode))"
2261 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2262 return output_fp_move_double (operands);
2263 return output_move_double (operands);
2265 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
2266 (set_attr "length" "1,1,2,2,3,3,3,3")])
2268 ;; Exactly the same as above, except that all `e' cases are deleted.
2269 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2272 (define_insn "*movdf_no_e_insn"
2273 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
2274 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
2276 && (register_operand (operands[0], DFmode)
2277 || register_operand (operands[1], DFmode))"
2278 "* return output_move_double (operands);"
2279 [(set_attr "type" "store,load,move,store,load")
2280 (set_attr "length" "1,1,2,3,3")])
2282 ;; Must handle overlapping registers here, since parameters can be unaligned
2286 [(set (match_operand:DF 0 "register_operand" "")
2287 (match_operand:DF 1 "register_operand" ""))]
2288 "! TARGET_ARCH64 && reload_completed
2289 && REGNO (operands[0]) < SPARC_FIRST_V9_FP_REG
2290 && REGNO (operands[1]) < SPARC_FIRST_V9_FP_REG"
2291 [(set (match_dup 2) (match_dup 3))
2292 (set (match_dup 4) (match_dup 5))]
2295 rtx first_set = operand_subword (operands[0], 0, 0, DFmode);
2296 rtx second_use = operand_subword (operands[1], 1, 0, DFmode);
2298 if (REGNO (first_set) == REGNO (second_use))
2300 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
2301 operands[3] = second_use;
2302 operands[4] = first_set;
2303 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
2307 operands[2] = first_set;
2308 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2309 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2310 operands[5] = second_use;
2314 (define_insn "*store_df"
2315 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
2316 (match_operand:DF 1 "reg_or_0_operand" "re,G"))
2317 (clobber (match_scratch:SI 2 "=&r,&r"))]
2318 "(reload_completed || reload_in_progress)
2322 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2323 if (which_alternative == 0)
2324 return \"std %1,[%2+%%lo(%a0)]\";
2326 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
2328 [(set_attr "type" "store")
2329 (set_attr "length" "3")])
2331 ;; This pattern forces (set (reg:TF ...) (const_double ...))
2332 ;; to be reloaded by putting the constant into memory.
2333 ;; It must come before the more general movtf pattern.
2334 (define_insn "*movtf_const_insn"
2335 [(set (match_operand:TF 0 "general_operand" "=?r,e,o")
2336 (match_operand:TF 1 "" "?F,m,G"))]
2337 "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2340 switch (which_alternative)
2343 return output_move_quad (operands);
2345 return output_fp_move_quad (operands);
2349 operands[1] = adj_offsettable_operand (operands[0], 8);
2350 return \"stx %%g0,%0\;stx %%g0,%1\";
2354 /* ??? Do we run off the end of the array here? */
2355 operands[1] = adj_offsettable_operand (operands[0], 4);
2356 operands[2] = adj_offsettable_operand (operands[0], 8);
2357 operands[3] = adj_offsettable_operand (operands[0], 12);
2358 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
2362 [(set_attr "type" "load,fpload,store")
2363 (set_attr "length" "5,5,5")])
2365 (define_expand "movtf"
2366 [(set (match_operand:TF 0 "general_operand" "")
2367 (match_operand:TF 1 "general_operand" ""))]
2371 if (emit_move_sequence (operands, TFmode))
2375 (define_insn "*movtf_insn"
2376 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r")
2377 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))]
2379 && (register_operand (operands[0], TFmode)
2380 || register_operand (operands[1], TFmode))"
2383 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2384 return output_fp_move_quad (operands);
2385 return output_move_quad (operands);
2387 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
2388 (set_attr "length" "4,4,5,5,5,5")])
2390 ;; Exactly the same as above, except that all `e' cases are deleted.
2391 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2394 (define_insn "*movtf_no_e_insn"
2395 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
2396 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
2398 && (register_operand (operands[0], TFmode)
2399 || register_operand (operands[1], TFmode))"
2402 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2403 return output_fp_move_quad (operands);
2404 return output_move_quad (operands);
2406 [(set_attr "type" "move,store,load")
2407 (set_attr "length" "4,5,5")])
2409 ;; This is disabled because it does not work. Long doubles have only 8
2410 ;; byte alignment. Adding an offset of 8 or 12 to an 8 byte aligned %lo may
2411 ;; cause it to overflow. See also GO_IF_LEGITIMATE_ADDRESS.
2412 (define_insn "*store_tf"
2413 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
2414 (match_operand:TF 1 "reg_or_0_operand" "re,G"))
2415 (clobber (match_scratch:SI 2 "=&r,&r"))]
2416 "0 && (reload_completed || reload_in_progress)
2420 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2421 if (which_alternative == 0)
2422 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
2424 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
2426 [(set_attr "type" "store")
2427 (set_attr "length" "5")])
2429 ;; Sparc V9 conditional move instructions.
2431 ;; We can handle larger constants here for some flavors, but for now we keep
2432 ;; it simple and only allow those constants supported by all flavours.
2433 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2434 ;; 3 contains the constant if one is present, but we handle either for
2435 ;; generality (sparc.c puts a constant in operand 2).
2437 (define_expand "movqicc"
2438 [(set (match_operand:QI 0 "register_operand" "")
2439 (if_then_else:QI (match_operand 1 "comparison_operator" "")
2440 (match_operand:QI 2 "arith10_operand" "")
2441 (match_operand:QI 3 "arith10_operand" "")))]
2445 enum rtx_code code = GET_CODE (operands[1]);
2447 if (GET_MODE (sparc_compare_op0) == DImode
2451 if (sparc_compare_op1 == const0_rtx
2452 && GET_CODE (sparc_compare_op0) == REG
2453 && GET_MODE (sparc_compare_op0) == DImode
2454 && v9_regcmp_p (code))
2456 operands[1] = gen_rtx (code, DImode,
2457 sparc_compare_op0, sparc_compare_op1);
2461 rtx cc_reg = gen_compare_reg (code,
2462 sparc_compare_op0, sparc_compare_op1);
2463 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2467 (define_expand "movhicc"
2468 [(set (match_operand:HI 0 "register_operand" "")
2469 (if_then_else:HI (match_operand 1 "comparison_operator" "")
2470 (match_operand:HI 2 "arith10_operand" "")
2471 (match_operand:HI 3 "arith10_operand" "")))]
2475 enum rtx_code code = GET_CODE (operands[1]);
2477 if (GET_MODE (sparc_compare_op0) == DImode
2481 if (sparc_compare_op1 == const0_rtx
2482 && GET_CODE (sparc_compare_op0) == REG
2483 && GET_MODE (sparc_compare_op0) == DImode
2484 && v9_regcmp_p (code))
2486 operands[1] = gen_rtx (code, DImode,
2487 sparc_compare_op0, sparc_compare_op1);
2491 rtx cc_reg = gen_compare_reg (code,
2492 sparc_compare_op0, sparc_compare_op1);
2493 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2497 (define_expand "movsicc"
2498 [(set (match_operand:SI 0 "register_operand" "")
2499 (if_then_else:SI (match_operand 1 "comparison_operator" "")
2500 (match_operand:SI 2 "arith10_operand" "")
2501 (match_operand:SI 3 "arith10_operand" "")))]
2505 enum rtx_code code = GET_CODE (operands[1]);
2507 if (GET_MODE (sparc_compare_op0) == DImode
2511 if (sparc_compare_op1 == const0_rtx
2512 && GET_CODE (sparc_compare_op0) == REG
2513 && GET_MODE (sparc_compare_op0) == DImode
2514 && v9_regcmp_p (code))
2516 operands[1] = gen_rtx (code, DImode,
2517 sparc_compare_op0, sparc_compare_op1);
2521 rtx cc_reg = gen_compare_reg (code,
2522 sparc_compare_op0, sparc_compare_op1);
2523 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2527 (define_expand "movdicc"
2528 [(set (match_operand:DI 0 "register_operand" "")
2529 (if_then_else:DI (match_operand 1 "comparison_operator" "")
2530 (match_operand:DI 2 "arith10_double_operand" "")
2531 (match_operand:DI 3 "arith10_double_operand" "")))]
2535 enum rtx_code code = GET_CODE (operands[1]);
2537 if (sparc_compare_op1 == const0_rtx
2538 && GET_CODE (sparc_compare_op0) == REG
2539 && GET_MODE (sparc_compare_op0) == DImode
2540 && v9_regcmp_p (code))
2542 operands[1] = gen_rtx (code, DImode,
2543 sparc_compare_op0, sparc_compare_op1);
2547 rtx cc_reg = gen_compare_reg (code,
2548 sparc_compare_op0, sparc_compare_op1);
2549 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2553 (define_expand "movsfcc"
2554 [(set (match_operand:SF 0 "register_operand" "")
2555 (if_then_else:SF (match_operand 1 "comparison_operator" "")
2556 (match_operand:SF 2 "register_operand" "")
2557 (match_operand:SF 3 "register_operand" "")))]
2558 "TARGET_V9 && TARGET_FPU"
2561 enum rtx_code code = GET_CODE (operands[1]);
2563 if (GET_MODE (sparc_compare_op0) == DImode
2567 if (sparc_compare_op1 == const0_rtx
2568 && GET_CODE (sparc_compare_op0) == REG
2569 && GET_MODE (sparc_compare_op0) == DImode
2570 && v9_regcmp_p (code))
2572 operands[1] = gen_rtx (code, DImode,
2573 sparc_compare_op0, sparc_compare_op1);
2577 rtx cc_reg = gen_compare_reg (code,
2578 sparc_compare_op0, sparc_compare_op1);
2579 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2583 (define_expand "movdfcc"
2584 [(set (match_operand:DF 0 "register_operand" "")
2585 (if_then_else:DF (match_operand 1 "comparison_operator" "")
2586 (match_operand:DF 2 "register_operand" "")
2587 (match_operand:DF 3 "register_operand" "")))]
2588 "TARGET_V9 && TARGET_FPU"
2591 enum rtx_code code = GET_CODE (operands[1]);
2593 if (GET_MODE (sparc_compare_op0) == DImode
2597 if (sparc_compare_op1 == const0_rtx
2598 && GET_CODE (sparc_compare_op0) == REG
2599 && GET_MODE (sparc_compare_op0) == DImode
2600 && v9_regcmp_p (code))
2602 operands[1] = gen_rtx (code, DImode,
2603 sparc_compare_op0, sparc_compare_op1);
2607 rtx cc_reg = gen_compare_reg (code,
2608 sparc_compare_op0, sparc_compare_op1);
2609 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2613 (define_expand "movtfcc"
2614 [(set (match_operand:TF 0 "register_operand" "")
2615 (if_then_else:TF (match_operand 1 "comparison_operator" "")
2616 (match_operand:TF 2 "register_operand" "")
2617 (match_operand:TF 3 "register_operand" "")))]
2618 "TARGET_V9 && TARGET_FPU"
2621 enum rtx_code code = GET_CODE (operands[1]);
2623 if (GET_MODE (sparc_compare_op0) == DImode
2627 if (sparc_compare_op1 == const0_rtx
2628 && GET_CODE (sparc_compare_op0) == REG
2629 && GET_MODE (sparc_compare_op0) == DImode
2630 && v9_regcmp_p (code))
2632 operands[1] = gen_rtx (code, DImode,
2633 sparc_compare_op0, sparc_compare_op1);
2637 rtx cc_reg = gen_compare_reg (code,
2638 sparc_compare_op0, sparc_compare_op1);
2639 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2643 ;; Conditional move define_insns.
2645 (define_insn "*movqi_cc_sp64"
2646 [(set (match_operand:QI 0 "register_operand" "=r,r")
2647 (if_then_else:QI (match_operator 1 "comparison_operator"
2648 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2650 (match_operand:QI 3 "arith11_operand" "rL,0")
2651 (match_operand:QI 4 "arith11_operand" "0,rL")))]
2656 [(set_attr "type" "cmove")])
2658 (define_insn "*movhi_cc_sp64"
2659 [(set (match_operand:HI 0 "register_operand" "=r,r")
2660 (if_then_else:HI (match_operator 1 "comparison_operator"
2661 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2663 (match_operand:HI 3 "arith11_operand" "rL,0")
2664 (match_operand:HI 4 "arith11_operand" "0,rL")))]
2669 [(set_attr "type" "cmove")])
2671 (define_insn "*movsi_cc_sp64"
2672 [(set (match_operand:SI 0 "register_operand" "=r,r")
2673 (if_then_else:SI (match_operator 1 "comparison_operator"
2674 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2676 (match_operand:SI 3 "arith11_operand" "rL,0")
2677 (match_operand:SI 4 "arith11_operand" "0,rL")))]
2682 [(set_attr "type" "cmove")])
2684 ;; ??? The constraints of operands 3,4 need work.
2685 (define_insn "*movdi_cc_sp64"
2686 [(set (match_operand:DI 0 "register_operand" "=r,r")
2687 (if_then_else:DI (match_operator 1 "comparison_operator"
2688 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2690 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
2691 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
2696 [(set_attr "type" "cmove")])
2698 (define_insn "*movsf_cc_sp64"
2699 [(set (match_operand:SF 0 "register_operand" "=f,f")
2700 (if_then_else:SF (match_operator 1 "comparison_operator"
2701 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2703 (match_operand:SF 3 "register_operand" "f,0")
2704 (match_operand:SF 4 "register_operand" "0,f")))]
2705 "TARGET_V9 && TARGET_FPU"
2709 [(set_attr "type" "cmove")])
2711 (define_insn "*movdf_cc_sp64"
2712 [(set (match_operand:DF 0 "register_operand" "=e,e")
2713 (if_then_else:DF (match_operator 1 "comparison_operator"
2714 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2716 (match_operand:DF 3 "register_operand" "e,0")
2717 (match_operand:DF 4 "register_operand" "0,e")))]
2718 "TARGET_V9 && TARGET_FPU"
2722 [(set_attr "type" "cmove")])
2724 (define_insn "*movtf_cc_sp64"
2725 [(set (match_operand:TF 0 "register_operand" "=e,e")
2726 (if_then_else:TF (match_operator 1 "comparison_operator"
2727 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2729 (match_operand:TF 3 "register_operand" "e,0")
2730 (match_operand:TF 4 "register_operand" "0,e")))]
2731 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2735 [(set_attr "type" "cmove")])
2737 (define_insn "*movqi_cc_reg_sp64"
2738 [(set (match_operand:QI 0 "register_operand" "=r,r")
2739 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
2740 [(match_operand:DI 2 "register_operand" "r,r")
2742 (match_operand:QI 3 "arith10_operand" "rM,0")
2743 (match_operand:QI 4 "arith10_operand" "0,rM")))]
2748 [(set_attr "type" "cmove")])
2750 (define_insn "*movhi_cc_reg_sp64"
2751 [(set (match_operand:HI 0 "register_operand" "=r,r")
2752 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
2753 [(match_operand:DI 2 "register_operand" "r,r")
2755 (match_operand:HI 3 "arith10_operand" "rM,0")
2756 (match_operand:HI 4 "arith10_operand" "0,rM")))]
2761 [(set_attr "type" "cmove")])
2763 (define_insn "*movsi_cc_reg_sp64"
2764 [(set (match_operand:SI 0 "register_operand" "=r,r")
2765 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
2766 [(match_operand:DI 2 "register_operand" "r,r")
2768 (match_operand:SI 3 "arith10_operand" "rM,0")
2769 (match_operand:SI 4 "arith10_operand" "0,rM")))]
2774 [(set_attr "type" "cmove")])
2776 ;; ??? The constraints of operands 3,4 need work.
2777 (define_insn "*movdi_cc_reg_sp64"
2778 [(set (match_operand:DI 0 "register_operand" "=r,r")
2779 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
2780 [(match_operand:DI 2 "register_operand" "r,r")
2782 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
2783 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
2788 [(set_attr "type" "cmove")])
2790 (define_insn "*movsf_cc_reg_sp64"
2791 [(set (match_operand:SF 0 "register_operand" "=f,f")
2792 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
2793 [(match_operand:DI 2 "register_operand" "r,r")
2795 (match_operand:SF 3 "register_operand" "f,0")
2796 (match_operand:SF 4 "register_operand" "0,f")))]
2797 "TARGET_ARCH64 && TARGET_FPU"
2801 [(set_attr "type" "cmove")])
2803 (define_insn "*movdf_cc_reg_sp64"
2804 [(set (match_operand:DF 0 "register_operand" "=e,e")
2805 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
2806 [(match_operand:DI 2 "register_operand" "r,r")
2808 (match_operand:DF 3 "register_operand" "e,0")
2809 (match_operand:DF 4 "register_operand" "0,e")))]
2810 "TARGET_ARCH64 && TARGET_FPU"
2814 [(set_attr "type" "cmove")])
2816 (define_insn "*movtf_cc_reg_sp64"
2817 [(set (match_operand:TF 0 "register_operand" "=e,e")
2818 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
2819 [(match_operand:DI 2 "register_operand" "r,r")
2821 (match_operand:TF 3 "register_operand" "e,0")
2822 (match_operand:TF 4 "register_operand" "0,e")))]
2823 "TARGET_ARCH64 && TARGET_FPU"
2827 [(set_attr "type" "cmove")])
2829 ;;- zero extension instructions
2831 ;; These patterns originally accepted general_operands, however, slightly
2832 ;; better code is generated by only accepting register_operands, and then
2833 ;; letting combine generate the ldu[hb] insns.
2835 (define_expand "zero_extendhisi2"
2836 [(set (match_operand:SI 0 "register_operand" "")
2837 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2841 rtx temp = gen_reg_rtx (SImode);
2842 rtx shift_16 = GEN_INT (16);
2843 int op1_subword = 0;
2845 if (GET_CODE (operand1) == SUBREG)
2847 op1_subword = SUBREG_WORD (operand1);
2848 operand1 = XEXP (operand1, 0);
2851 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2854 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2858 (define_insn "*zero_extendhisi2_insn"
2859 [(set (match_operand:SI 0 "register_operand" "=r")
2860 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2863 [(set_attr "type" "load")])
2865 (define_expand "zero_extendqihi2"
2866 [(set (match_operand:HI 0 "register_operand" "")
2867 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2871 (define_insn "*zero_extendqihi2_insn"
2872 [(set (match_operand:HI 0 "register_operand" "=r,r")
2873 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2874 "GET_CODE (operands[1]) != CONST_INT"
2878 [(set_attr "type" "unary,load")
2879 (set_attr "length" "1")])
2881 (define_expand "zero_extendqisi2"
2882 [(set (match_operand:SI 0 "register_operand" "")
2883 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2887 (define_insn "*zero_extendqisi2_insn"
2888 [(set (match_operand:SI 0 "register_operand" "=r,r")
2889 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2890 "GET_CODE (operands[1]) != CONST_INT"
2894 [(set_attr "type" "unary,load")
2895 (set_attr "length" "1")])
2897 (define_expand "zero_extendqidi2"
2898 [(set (match_operand:DI 0 "register_operand" "")
2899 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2903 (define_insn "*zero_extendqidi2_insn"
2904 [(set (match_operand:DI 0 "register_operand" "=r,r")
2905 (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2906 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2910 [(set_attr "type" "unary,load")
2911 (set_attr "length" "1")])
2913 (define_expand "zero_extendhidi2"
2914 [(set (match_operand:DI 0 "register_operand" "")
2915 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2919 rtx temp = gen_reg_rtx (DImode);
2920 rtx shift_48 = GEN_INT (48);
2921 int op1_subword = 0;
2923 if (GET_CODE (operand1) == SUBREG)
2925 op1_subword = SUBREG_WORD (operand1);
2926 operand1 = XEXP (operand1, 0);
2929 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2932 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2936 (define_insn "*zero_extendhidi2_insn"
2937 [(set (match_operand:DI 0 "register_operand" "=r")
2938 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2941 [(set_attr "type" "load")])
2943 ;; ??? Write truncdisi pattern using sra?
2945 (define_expand "zero_extendsidi2"
2946 [(set (match_operand:DI 0 "register_operand" "")
2947 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2951 (define_insn "*zero_extendsidi2_insn"
2952 [(set (match_operand:DI 0 "register_operand" "=r,r")
2953 (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
2954 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2958 [(set_attr "type" "unary,load")
2959 (set_attr "length" "1")])
2961 ;; Simplify comparisons of extended values.
2963 (define_insn "*cmp_zero_extendqisi2"
2965 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2968 "andcc %0,0xff,%%g0"
2969 [(set_attr "type" "compare")])
2971 (define_insn "*cmp_zero_extendqisi2_set"
2973 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2975 (set (match_operand:SI 0 "register_operand" "=r")
2976 (zero_extend:SI (match_dup 1)))]
2979 [(set_attr "type" "unary")])
2981 ;; Similarly, handle SI->QI mode truncation followed by a compare.
2983 (define_insn "*cmp_siqi_trunc"
2985 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
2988 "andcc %0,0xff,%%g0"
2989 [(set_attr "type" "compare")])
2991 (define_insn "*cmp_siqi_trunc_set"
2993 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
2995 (set (match_operand:QI 0 "register_operand" "=r")
2999 [(set_attr "type" "unary")])
3001 ;;- sign extension instructions
3003 ;; These patterns originally accepted general_operands, however, slightly
3004 ;; better code is generated by only accepting register_operands, and then
3005 ;; letting combine generate the lds[hb] insns.
3007 (define_expand "extendhisi2"
3008 [(set (match_operand:SI 0 "register_operand" "")
3009 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3013 rtx temp = gen_reg_rtx (SImode);
3014 rtx shift_16 = GEN_INT (16);
3015 int op1_subword = 0;
3017 if (GET_CODE (operand1) == SUBREG)
3019 op1_subword = SUBREG_WORD (operand1);
3020 operand1 = XEXP (operand1, 0);
3023 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
3026 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3030 (define_insn "*sign_extendhisi2_insn"
3031 [(set (match_operand:SI 0 "register_operand" "=r")
3032 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3035 [(set_attr "type" "load")])
3037 (define_expand "extendqihi2"
3038 [(set (match_operand:HI 0 "register_operand" "")
3039 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3043 rtx temp = gen_reg_rtx (SImode);
3044 rtx shift_24 = GEN_INT (24);
3045 int op1_subword = 0;
3046 int op0_subword = 0;
3048 if (GET_CODE (operand1) == SUBREG)
3050 op1_subword = SUBREG_WORD (operand1);
3051 operand1 = XEXP (operand1, 0);
3053 if (GET_CODE (operand0) == SUBREG)
3055 op0_subword = SUBREG_WORD (operand0);
3056 operand0 = XEXP (operand0, 0);
3058 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
3061 if (GET_MODE (operand0) != SImode)
3062 operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
3063 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3067 (define_insn "*sign_extendqihi2_insn"
3068 [(set (match_operand:HI 0 "register_operand" "=r")
3069 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3072 [(set_attr "type" "load")])
3074 (define_expand "extendqisi2"
3075 [(set (match_operand:SI 0 "register_operand" "")
3076 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3080 rtx temp = gen_reg_rtx (SImode);
3081 rtx shift_24 = GEN_INT (24);
3082 int op1_subword = 0;
3084 if (GET_CODE (operand1) == SUBREG)
3086 op1_subword = SUBREG_WORD (operand1);
3087 operand1 = XEXP (operand1, 0);
3090 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
3093 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3097 (define_insn "*sign_extendqisi2_insn"
3098 [(set (match_operand:SI 0 "register_operand" "=r")
3099 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3102 [(set_attr "type" "load")])
3104 (define_expand "extendqidi2"
3105 [(set (match_operand:DI 0 "register_operand" "")
3106 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3110 rtx temp = gen_reg_rtx (DImode);
3111 rtx shift_56 = GEN_INT (56);
3112 int op1_subword = 0;
3114 if (GET_CODE (operand1) == SUBREG)
3116 op1_subword = SUBREG_WORD (operand1);
3117 operand1 = XEXP (operand1, 0);
3120 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
3123 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3127 (define_insn "*sign_extendqidi2_insn"
3128 [(set (match_operand:DI 0 "register_operand" "=r")
3129 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3132 [(set_attr "type" "load")])
3134 (define_expand "extendhidi2"
3135 [(set (match_operand:DI 0 "register_operand" "")
3136 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3140 rtx temp = gen_reg_rtx (DImode);
3141 rtx shift_48 = GEN_INT (48);
3142 int op1_subword = 0;
3144 if (GET_CODE (operand1) == SUBREG)
3146 op1_subword = SUBREG_WORD (operand1);
3147 operand1 = XEXP (operand1, 0);
3150 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
3153 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3157 (define_insn "*sign_extendhidi2_insn"
3158 [(set (match_operand:DI 0 "register_operand" "=r")
3159 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3162 [(set_attr "type" "load")])
3164 (define_expand "extendsidi2"
3165 [(set (match_operand:DI 0 "register_operand" "")
3166 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3170 (define_insn "*sign_extendsidi2_insn"
3171 [(set (match_operand:DI 0 "register_operand" "=r,r")
3172 (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
3177 [(set_attr "type" "unary,load")
3178 (set_attr "length" "1")])
3180 ;; Special pattern for optimizing bit-field compares. This is needed
3181 ;; because combine uses this as a canonical form.
3183 (define_insn "*cmp_zero_extract"
3186 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3187 (match_operand:SI 1 "small_int" "n")
3188 (match_operand:SI 2 "small_int" "n"))
3190 "INTVAL (operands[2]) > 19"
3193 int len = INTVAL (operands[1]);
3194 int pos = 32 - INTVAL (operands[2]) - len;
3195 unsigned mask = ((1 << len) - 1) << pos;
3197 operands[1] = GEN_INT (mask);
3198 return \"andcc %0,%1,%%g0\";
3201 (define_insn "*cmp_zero_extract_sp64"
3204 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3205 (match_operand:SI 1 "small_int" "n")
3206 (match_operand:SI 2 "small_int" "n"))
3208 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3211 int len = INTVAL (operands[1]);
3212 int pos = 64 - INTVAL (operands[2]) - len;
3213 unsigned HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3215 operands[1] = GEN_INT (mask);
3216 return \"andcc %0,%1,%%g0\";
3219 ;; Conversions between float, double and long double.
3221 (define_insn "extendsfdf2"
3222 [(set (match_operand:DF 0 "register_operand" "=e")
3224 (match_operand:SF 1 "register_operand" "f")))]
3227 [(set_attr "type" "fp")])
3229 (define_insn "extendsftf2"
3230 [(set (match_operand:TF 0 "register_operand" "=e")
3232 (match_operand:SF 1 "register_operand" "f")))]
3233 "TARGET_FPU && TARGET_HARD_QUAD"
3235 [(set_attr "type" "fp")])
3237 (define_insn "extenddftf2"
3238 [(set (match_operand:TF 0 "register_operand" "=e")
3240 (match_operand:DF 1 "register_operand" "e")))]
3241 "TARGET_FPU && TARGET_HARD_QUAD"
3243 [(set_attr "type" "fp")])
3245 (define_insn "truncdfsf2"
3246 [(set (match_operand:SF 0 "register_operand" "=f")
3248 (match_operand:DF 1 "register_operand" "e")))]
3251 [(set_attr "type" "fp")])
3253 (define_insn "trunctfsf2"
3254 [(set (match_operand:SF 0 "register_operand" "=f")
3256 (match_operand:TF 1 "register_operand" "e")))]
3257 "TARGET_FPU && TARGET_HARD_QUAD"
3259 [(set_attr "type" "fp")])
3261 (define_insn "trunctfdf2"
3262 [(set (match_operand:DF 0 "register_operand" "=e")
3264 (match_operand:TF 1 "register_operand" "e")))]
3265 "TARGET_FPU && TARGET_HARD_QUAD"
3267 [(set_attr "type" "fp")])
3269 ;; Conversion between fixed point and floating point.
3271 (define_insn "floatsisf2"
3272 [(set (match_operand:SF 0 "register_operand" "=f")
3273 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3276 [(set_attr "type" "fp")])
3278 (define_insn "floatsidf2"
3279 [(set (match_operand:DF 0 "register_operand" "=e")
3280 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3283 [(set_attr "type" "fp")])
3285 (define_insn "floatsitf2"
3286 [(set (match_operand:TF 0 "register_operand" "=e")
3287 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3288 "TARGET_FPU && TARGET_HARD_QUAD"
3290 [(set_attr "type" "fp")])
3292 ;; Now the same for 64 bit sources.
3293 ;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2).
3295 (define_expand "floatdisf2"
3296 [(parallel [(set (match_operand:SF 0 "register_operand" "")
3297 (float:SF (match_operand:DI 1 "general_operand" "")))
3298 (clobber (match_dup 2))
3299 (clobber (match_dup 3))])]
3300 "TARGET_ARCH64 && TARGET_FPU"
3303 operands[2] = gen_reg_rtx (DFmode);
3304 operands[3] = sparc64_fpconv_stack_temp ();
3307 (define_expand "floatdidf2"
3308 [(parallel [(set (match_operand:DF 0 "register_operand" "")
3309 (float:DF (match_operand:DI 1 "general_operand" "")))
3310 (clobber (match_dup 2))
3311 (clobber (match_dup 3))])]
3312 "TARGET_ARCH64 && TARGET_FPU"
3315 operands[2] = gen_reg_rtx (DFmode);
3316 operands[3] = sparc64_fpconv_stack_temp ();
3319 (define_expand "floatditf2"
3320 [(parallel [(set (match_operand:TF 0 "register_operand" "")
3321 (float:TF (match_operand:DI 1 "general_operand" "")))
3322 (clobber (match_dup 2))
3323 (clobber (match_dup 3))])]
3324 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3327 operands[2] = gen_reg_rtx (DFmode);
3328 operands[3] = sparc64_fpconv_stack_temp ();
3331 (define_insn "*floatdisf2_insn"
3332 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
3333 (float:SF (match_operand:DI 1 "general_operand" "rm")))
3334 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3335 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3336 "TARGET_ARCH64 && TARGET_FPU"
3339 if (GET_CODE (operands[1]) == MEM)
3340 output_asm_insn (\"ldd %1,%2\", operands);
3342 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3343 return \"fxtos %2,%0\";
3345 [(set_attr "type" "fp")
3346 (set_attr "length" "3")])
3348 (define_insn "*floatdidf2_insn"
3349 [(parallel [(set (match_operand:DF 0 "register_operand" "=e")
3350 (float:DF (match_operand:DI 1 "general_operand" "rm")))
3351 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3352 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3353 "TARGET_ARCH64 && TARGET_FPU"
3356 if (GET_CODE (operands[1]) == MEM)
3357 output_asm_insn (\"ldd %1,%2\", operands);
3359 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3360 return \"fxtod %2,%0\";
3362 [(set_attr "type" "fp")
3363 (set_attr "length" "3")])
3365 (define_insn "*floatditf2_insn"
3366 [(parallel [(set (match_operand:TF 0 "register_operand" "=e")
3367 (float:TF (match_operand:DI 1 "general_operand" "rm")))
3368 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3369 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3370 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3373 if (GET_CODE (operands[1]) == MEM)
3374 output_asm_insn (\"ldd %1,%2\", operands);
3376 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3377 return \"fxtoq %2,%0\";
3379 [(set_attr "type" "fp")
3380 (set_attr "length" "3")])
3382 ;; ??? Ideally, these are what we would like to use.
3384 (define_insn "floatdisf2_sp64"
3385 [(set (match_operand:SF 0 "register_operand" "=f")
3386 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3387 "0 && TARGET_ARCH64 && TARGET_FPU"
3389 [(set_attr "type" "fp")])
3391 (define_insn "floatdidf2_sp64"
3392 [(set (match_operand:DF 0 "register_operand" "=e")
3393 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3394 "0 && TARGET_ARCH64 && TARGET_FPU"
3396 [(set_attr "type" "fp")])
3398 (define_insn "floatditf2_sp64"
3399 [(set (match_operand:TF 0 "register_operand" "=e")
3400 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3401 "0 && TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3403 [(set_attr "type" "fp")])
3405 ;; Convert a float to an actual integer.
3406 ;; Truncation is performed as part of the conversion.
3408 (define_insn "fix_truncsfsi2"
3409 [(set (match_operand:SI 0 "register_operand" "=f")
3410 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3413 [(set_attr "type" "fp")])
3415 (define_insn "fix_truncdfsi2"
3416 [(set (match_operand:SI 0 "register_operand" "=f")
3417 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3420 [(set_attr "type" "fp")])
3422 (define_insn "fix_trunctfsi2"
3423 [(set (match_operand:SI 0 "register_operand" "=f")
3424 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3425 "TARGET_FPU && TARGET_HARD_QUAD"
3427 [(set_attr "type" "fp")])
3429 ;; Now the same, for 64-bit targets
3430 ;; ??? We try to work around an interesting problem.
3431 ;; If gcc tries to do a subreg on the result it will get the wrong answer:
3432 ;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as
3433 ;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change
3434 ;; the "0" to a "1". One could enhance alter_subreg but it is not clear how to
3437 (define_expand "fix_truncsfdi2"
3438 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3439 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
3440 (clobber (match_dup 2))
3441 (clobber (match_dup 3))])]
3442 "TARGET_ARCH64 && TARGET_FPU"
3445 operands[2] = gen_reg_rtx (DFmode);
3446 operands[3] = sparc64_fpconv_stack_temp ();
3449 (define_expand "fix_truncdfdi2"
3450 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3451 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
3452 (clobber (match_dup 2))
3453 (clobber (match_dup 3))])]
3454 "TARGET_ARCH64 && TARGET_FPU"
3457 operands[2] = gen_reg_rtx (DFmode);
3458 operands[3] = sparc64_fpconv_stack_temp ();
3461 (define_expand "fix_trunctfdi2"
3462 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3463 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" ""))))
3464 (clobber (match_dup 2))
3465 (clobber (match_dup 3))])]
3466 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3469 operands[2] = gen_reg_rtx (DFmode);
3470 operands[3] = sparc64_fpconv_stack_temp ();
3473 (define_insn "*fix_truncsfdi2_insn"
3474 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3475 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
3476 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3477 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3478 "TARGET_ARCH64 && TARGET_FPU"
3481 output_asm_insn (\"fstox %1,%2\", operands);
3482 if (GET_CODE (operands[0]) == MEM)
3483 return \"std %2,%0\";
3485 return \"std %2,%3\;ldx %3,%0\";
3487 [(set_attr "type" "fp")
3488 (set_attr "length" "3")])
3490 (define_insn "*fix_truncdfdi2_insn"
3491 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3492 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))
3493 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3494 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3495 "TARGET_ARCH64 && TARGET_FPU"
3498 output_asm_insn (\"fdtox %1,%2\", operands);
3499 if (GET_CODE (operands[0]) == MEM)
3500 return \"std %2,%0\";
3502 return \"std %2,%3\;ldx %3,%0\";
3504 [(set_attr "type" "fp")
3505 (set_attr "length" "3")])
3507 (define_insn "*fix_trunctfdi2_insn"
3508 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3509 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))
3510 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3511 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3512 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3515 output_asm_insn (\"fqtox %1,%2\", operands);
3516 if (GET_CODE (operands[0]) == MEM)
3517 return \"std %2,%0\";
3519 return \"std %2,%3\;ldx %3,%0\";
3521 [(set_attr "type" "fp")
3522 (set_attr "length" "3")])
3524 ;; ??? Ideally, these are what we would like to use.
3526 (define_insn "fix_truncsfdi2_sp64"
3527 [(set (match_operand:DI 0 "register_operand" "=e")
3528 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3529 "0 && TARGET_ARCH64 && TARGET_FPU"
3531 [(set_attr "type" "fp")])
3533 (define_insn "fix_truncdfdi2_sp64"
3534 [(set (match_operand:DI 0 "register_operand" "=e")
3535 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3536 "0 && TARGET_ARCH64 && TARGET_FPU"
3538 [(set_attr "type" "fp")])
3540 (define_insn "fix_trunctfdi2_sp64"
3541 [(set (match_operand:DI 0 "register_operand" "=e")
3542 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3543 "0 && TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3545 [(set_attr "type" "fp")])
3547 ;;- arithmetic instructions
3549 (define_expand "adddi3"
3550 [(set (match_operand:DI 0 "register_operand" "=r")
3551 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3552 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3556 if (! TARGET_ARCH64)
3558 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3559 gen_rtx (SET, VOIDmode, operands[0],
3560 gen_rtx (PLUS, DImode, operands[1],
3562 gen_rtx (CLOBBER, VOIDmode,
3563 gen_rtx (REG, SImode, SPARC_ICC_REG)))));
3568 (define_insn "*adddi3_sp32"
3569 [(set (match_operand:DI 0 "register_operand" "=r")
3570 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3571 (match_operand:DI 2 "arith_double_operand" "rHI")))
3572 (clobber (reg:SI 100))]
3576 rtx op2 = operands[2];
3578 if (GET_CODE (op2) == CONST_INT
3579 || GET_CODE (op2) == CONST_DOUBLE)
3582 xoperands[0] = operands[0];
3583 xoperands[1] = operands[1];
3584 if (WORDS_BIG_ENDIAN)
3585 split_double (op2, &xoperands[2], &xoperands[3]);
3587 split_double (op2, &xoperands[3], &xoperands[2]);
3588 if (xoperands[3] == const0_rtx && xoperands[0] == xoperands[1])
3589 output_asm_insn (\"add %H1,%2,%H0\", xoperands);
3591 output_asm_insn (\"addcc %L1,%3,%L0\;addx %H1,%2,%H0\", xoperands);
3594 return \"addcc %L1,%L2,%L0\;addx %H1,%H2,%H0\";
3596 [(set_attr "length" "2")])
3598 (define_insn "*adddi3_sp64"
3599 [(set (match_operand:DI 0 "register_operand" "=r")
3600 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3601 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3605 (define_insn "addsi3"
3606 [(set (match_operand:SI 0 "register_operand" "=r")
3607 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3608 (match_operand:SI 2 "arith_operand" "rI")))]
3611 [(set_attr "type" "ialu")])
3613 (define_insn "*cmp_cc_plus"
3614 [(set (reg:CC_NOOV 100)
3615 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3616 (match_operand:SI 1 "arith_operand" "rI"))
3620 [(set_attr "type" "compare")])
3622 (define_insn "*cmp_ccx_plus"
3623 [(set (reg:CCX_NOOV 100)
3624 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
3625 (match_operand:DI 1 "arith_double_operand" "rHI"))
3629 [(set_attr "type" "compare")])
3631 (define_insn "*cmp_cc_plus_set"
3632 [(set (reg:CC_NOOV 100)
3633 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3634 (match_operand:SI 2 "arith_operand" "rI"))
3636 (set (match_operand:SI 0 "register_operand" "=r")
3637 (plus:SI (match_dup 1) (match_dup 2)))]
3641 (define_insn "*cmp_ccx_plus_set"
3642 [(set (reg:CCX_NOOV 100)
3643 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3644 (match_operand:DI 2 "arith_double_operand" "rHI"))
3646 (set (match_operand:DI 0 "register_operand" "=r")
3647 (plus:DI (match_dup 1) (match_dup 2)))]
3651 (define_expand "subdi3"
3652 [(set (match_operand:DI 0 "register_operand" "=r")
3653 (minus:DI (match_operand:DI 1 "register_operand" "r")
3654 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3658 if (! TARGET_ARCH64)
3660 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3661 gen_rtx (SET, VOIDmode, operands[0],
3662 gen_rtx (MINUS, DImode, operands[1],
3664 gen_rtx (CLOBBER, VOIDmode,
3665 gen_rtx (REG, SImode, SPARC_ICC_REG)))));
3670 (define_insn "*subdi3_sp32"
3671 [(set (match_operand:DI 0 "register_operand" "=r")
3672 (minus:DI (match_operand:DI 1 "register_operand" "r")
3673 (match_operand:DI 2 "arith_double_operand" "rHI")))
3674 (clobber (reg:SI 100))]
3678 rtx op2 = operands[2];
3680 if (GET_CODE (op2) == CONST_INT
3681 || GET_CODE (op2) == CONST_DOUBLE)
3684 xoperands[0] = operands[0];
3685 xoperands[1] = operands[1];
3686 if (WORDS_BIG_ENDIAN)
3687 split_double (op2, &xoperands[2], &xoperands[3]);
3689 split_double (op2, &xoperands[3], &xoperands[2]);
3690 if (xoperands[3] == const0_rtx && xoperands[0] == xoperands[1])
3691 output_asm_insn (\"sub %H1,%2,%H0\", xoperands);
3693 output_asm_insn (\"subcc %L1,%3,%L0\;subx %H1,%2,%H0\", xoperands);
3696 return \"subcc %L1,%L2,%L0\;subx %H1,%H2,%H0\";
3698 [(set_attr "length" "2")])
3700 (define_insn "*subdi3_sp64"
3701 [(set (match_operand:DI 0 "register_operand" "=r")
3702 (minus:DI (match_operand:DI 1 "register_operand" "r")
3703 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3707 (define_insn "subsi3"
3708 [(set (match_operand:SI 0 "register_operand" "=r")
3709 (minus:SI (match_operand:SI 1 "register_operand" "r")
3710 (match_operand:SI 2 "arith_operand" "rI")))]
3713 [(set_attr "type" "ialu")])
3715 (define_insn "*cmp_minus_cc"
3716 [(set (reg:CC_NOOV 100)
3717 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
3718 (match_operand:SI 1 "arith_operand" "rI"))
3722 [(set_attr "type" "compare")])
3724 (define_insn "*cmp_minus_ccx"
3725 [(set (reg:CCX_NOOV 100)
3726 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3727 (match_operand:DI 1 "arith_double_operand" "rHI"))
3731 [(set_attr "type" "compare")])
3733 (define_insn "*cmp_minus_cc_set"
3734 [(set (reg:CC_NOOV 100)
3735 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
3736 (match_operand:SI 2 "arith_operand" "rI"))
3738 (set (match_operand:SI 0 "register_operand" "=r")
3739 (minus:SI (match_dup 1) (match_dup 2)))]
3743 (define_insn "*cmp_minus_ccx_set"
3744 [(set (reg:CCX_NOOV 100)
3745 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3746 (match_operand:DI 2 "arith_double_operand" "rHI"))
3748 (set (match_operand:DI 0 "register_operand" "=r")
3749 (minus:DI (match_dup 1) (match_dup 2)))]
3753 ;; Integer Multiply/Divide.
3755 ;; The 32 bit multiply/divide instructions are deprecated on v9 and shouldn't
3756 ;; we used. We still use them in 32 bit v9 compilers.
3757 ;; The 64 bit v9 compiler will (/should) widen the args and use muldi3.
3759 (define_insn "mulsi3"
3760 [(set (match_operand:SI 0 "register_operand" "=r")
3761 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3762 (match_operand:SI 2 "arith_operand" "rI")))]
3763 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3765 [(set_attr "type" "imul")])
3767 (define_insn "muldi3"
3768 [(set (match_operand:DI 0 "register_operand" "=r")
3769 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
3770 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3774 ;; It is not known whether this will match.
3776 (define_insn "*cmp_mul_set"
3777 [(set (match_operand:SI 0 "register_operand" "=r")
3778 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3779 (match_operand:SI 2 "arith_operand" "rI")))
3780 (set (reg:CC_NOOV 100)
3781 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
3783 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3785 [(set_attr "type" "imul")])
3787 (define_expand "mulsidi3"
3788 [(set (match_operand:DI 0 "register_operand" "")
3789 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3790 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3791 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3794 if (CONSTANT_P (operands[2]))
3796 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
3801 (define_insn "*mulsidi3_sp32"
3802 [(set (match_operand:DI 0 "register_operand" "=r")
3803 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3804 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3805 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3808 return TARGET_SPARCLET ? \"smuld %1,%2,%L0\" : \"smul %1,%2,%L0\;rd %%y,%H0\";
3810 [(set (attr "length")
3811 (if_then_else (eq_attr "isa" "sparclet")
3812 (const_int 1) (const_int 2)))])
3814 ;; Extra pattern, because sign_extend of a constant isn't valid.
3816 (define_insn "const_mulsidi3"
3817 [(set (match_operand:DI 0 "register_operand" "=r")
3818 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3819 (match_operand:SI 2 "small_int" "I")))]
3820 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3823 return TARGET_SPARCLET ? \"smuld %1,%2,%L0\" : \"smul %1,%2,%L0\;rd %%y,%H0\";
3825 [(set (attr "length")
3826 (if_then_else (eq_attr "isa" "sparclet")
3827 (const_int 1) (const_int 2)))])
3829 (define_expand "smulsi3_highpart"
3830 [(set (match_operand:SI 0 "register_operand" "")
3832 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3833 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
3835 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3838 if (CONSTANT_P (operands[2]))
3840 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
3845 (define_insn "*smulsidi3_highpart_sp32"
3846 [(set (match_operand:SI 0 "register_operand" "=r")
3848 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3849 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
3851 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3852 "smul %1,%2,%%g0\;rd %%y,%0"
3853 [(set_attr "length" "2")])
3855 (define_insn "const_smulsi3_highpart"
3856 [(set (match_operand:SI 0 "register_operand" "=r")
3858 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3859 (match_operand:SI 2 "register_operand" "r"))
3861 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3862 "smul %1,%2,%%g0\;rd %%y,%0"
3863 [(set_attr "length" "2")])
3865 (define_expand "umulsidi3"
3866 [(set (match_operand:DI 0 "register_operand" "")
3867 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3868 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
3869 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3872 if (CONSTANT_P (operands[2]))
3874 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
3879 (define_insn "*umulsidi3_sp32"
3880 [(set (match_operand:DI 0 "register_operand" "=r")
3881 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3882 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3883 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3886 return TARGET_SPARCLET ? \"umuld %1,%2,%L0\" : \"umul %1,%2,%L0\;rd %%y,%H0\";
3888 [(set (attr "length")
3889 (if_then_else (eq_attr "isa" "sparclet")
3890 (const_int 1) (const_int 2)))])
3892 ;; Extra pattern, because sign_extend of a constant isn't valid.
3894 (define_insn "const_umulsidi3"
3895 [(set (match_operand:DI 0 "register_operand" "=r")
3896 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3897 (match_operand:SI 2 "uns_small_int" "")))]
3898 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3901 return TARGET_SPARCLET ? \"umuld %1,%2,%L0\" : \"umul %1,%2,%L0\;rd %%y,%H0\";
3903 [(set (attr "length")
3904 (if_then_else (eq_attr "isa" "sparclet")
3905 (const_int 1) (const_int 2)))])
3907 (define_expand "umulsi3_highpart"
3908 [(set (match_operand:SI 0 "register_operand" "")
3910 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3911 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
3913 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3916 if (CONSTANT_P (operands[2]))
3918 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
3923 (define_insn "*umulsidi3_highpart_sp32"
3924 [(set (match_operand:SI 0 "register_operand" "=r")
3926 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3927 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
3929 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3930 "umul %1,%2,%%g0\;rd %%y,%0"
3931 [(set_attr "length" "2")])
3933 (define_insn "const_umulsi3_highpart"
3934 [(set (match_operand:SI 0 "register_operand" "=r")
3936 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3937 (match_operand:SI 2 "uns_small_int" ""))
3939 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
3940 "umul %1,%2,%%g0\;rd %%y,%0"
3941 [(set_attr "length" "2")])
3943 ;; The v8 architecture specifies that there must be 3 instructions between
3944 ;; a y register write and a use of it for correct results.
3946 (define_insn "divsi3"
3947 [(set (match_operand:SI 0 "register_operand" "=r")
3948 (div:SI (match_operand:SI 1 "register_operand" "r")
3949 (match_operand:SI 2 "arith_operand" "rI")))
3950 (clobber (match_scratch:SI 3 "=&r"))]
3951 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
3955 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdiv %1,%2,%0\";
3957 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0\";
3959 [(set (attr "length")
3960 (if_then_else (eq_attr "isa" "v9")
3961 (const_int 3) (const_int 6)))])
3963 (define_insn "divdi3"
3964 [(set (match_operand:DI 0 "register_operand" "=r")
3965 (div:DI (match_operand:DI 1 "register_operand" "r")
3966 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3970 ;; It is not known whether this will match.
3972 (define_insn "*cmp_sdiv_cc_set"
3973 [(set (match_operand:SI 0 "register_operand" "=r")
3974 (div:SI (match_operand:SI 1 "register_operand" "r")
3975 (match_operand:SI 2 "arith_operand" "rI")))
3977 (compare:CC (div:SI (match_dup 1) (match_dup 2))
3979 (clobber (match_scratch:SI 3 "=&r"))]
3980 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
3984 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdivcc %1,%2,%0\";
3986 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0\";
3988 [(set (attr "length")
3989 (if_then_else (eq_attr "isa" "v9")
3990 (const_int 3) (const_int 6)))])
3992 (define_insn "udivsi3"
3993 [(set (match_operand:SI 0 "register_operand" "=r")
3994 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3995 (match_operand:SI 2 "arith_operand" "rI")))]
3996 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4000 return \"wr %%g0,%%g0,%%y\;udiv %1,%2,%0\";
4002 return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0\";
4004 [(set (attr "length")
4005 (if_then_else (eq_attr "isa" "v9")
4006 (const_int 2) (const_int 5)))])
4008 (define_insn "udivdi3"
4009 [(set (match_operand:DI 0 "register_operand" "=r")
4010 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4011 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4015 ;; It is not known whether this will match.
4017 (define_insn "*cmp_udiv_cc_set"
4018 [(set (match_operand:SI 0 "register_operand" "=r")
4019 (udiv:SI (match_operand:SI 1 "register_operand" "r")
4020 (match_operand:SI 2 "arith_operand" "rI")))
4022 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
4024 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4028 return \"wr %%g0,%%g0,%%y\;udivcc %1,%2,%0\";
4030 return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0\";
4032 [(set (attr "length")
4033 (if_then_else (eq_attr "isa" "v9")
4034 (const_int 2) (const_int 5)))])
4036 ; sparclet multiply/accumulate insns
4038 (define_insn "*smacsi"
4039 [(set (match_operand:SI 0 "register_operand" "=r")
4040 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4041 (match_operand:SI 2 "arith_operand" "rI"))
4042 (match_operand:SI 3 "register_operand" "0")))]
4045 [(set_attr "type" "imul")])
4047 (define_insn "*smacdi"
4048 [(set (match_operand:DI 0 "register_operand" "=r")
4049 (plus:DI (mult:DI (sign_extend:DI
4050 (match_operand:SI 1 "register_operand" "%r"))
4052 (match_operand:SI 2 "register_operand" "r")))
4053 (match_operand:DI 3 "register_operand" "0")))]
4056 [(set_attr "type" "imul")])
4058 (define_insn "*umacdi"
4059 [(set (match_operand:DI 0 "register_operand" "=r")
4060 (plus:DI (mult:DI (zero_extend:DI
4061 (match_operand:SI 1 "register_operand" "%r"))
4063 (match_operand:SI 2 "register_operand" "r")))
4064 (match_operand:DI 3 "register_operand" "0")))]
4067 [(set_attr "type" "imul")])
4069 ;;- Boolean instructions
4070 ;; We define DImode `and' so with DImode `not' we can get
4071 ;; DImode `andn'. Other combinations are possible.
4073 (define_expand "anddi3"
4074 [(set (match_operand:DI 0 "register_operand" "")
4075 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4076 (match_operand:DI 2 "arith_double_operand" "")))]
4080 (define_insn "*anddi3_sp32"
4081 [(set (match_operand:DI 0 "register_operand" "=r")
4082 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4083 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4087 rtx op2 = operands[2];
4089 if (GET_CODE (op2) == CONST_INT
4090 || GET_CODE (op2) == CONST_DOUBLE)
4093 xoperands[0] = operands[0];
4094 xoperands[1] = operands[1];
4095 if (WORDS_BIG_ENDIAN)
4096 split_double (op2, &xoperands[2], &xoperands[3]);
4098 split_double (op2, &xoperands[3], &xoperands[2]);
4099 output_asm_insn (\"and %L1,%3,%L0\;and %H1,%2,%H0\", xoperands);
4102 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
4104 [(set_attr "length" "2")])
4106 (define_insn "*anddi3_sp64"
4107 [(set (match_operand:DI 0 "register_operand" "=r")
4108 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4109 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4113 (define_insn "andsi3"
4114 [(set (match_operand:SI 0 "register_operand" "=r")
4115 (and:SI (match_operand:SI 1 "arith_operand" "%r")
4116 (match_operand:SI 2 "arith_operand" "rI")))]
4119 [(set_attr "type" "ialu")])
4122 [(set (match_operand:SI 0 "register_operand" "")
4123 (and:SI (match_operand:SI 1 "register_operand" "")
4124 (match_operand:SI 2 "" "")))
4125 (clobber (match_operand:SI 3 "register_operand" ""))]
4126 "GET_CODE (operands[2]) == CONST_INT
4127 && !SMALL_INT (operands[2])
4128 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4129 [(set (match_dup 3) (match_dup 4))
4130 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4133 operands[4] = GEN_INT (~INTVAL (operands[2]));
4136 (define_insn "*and_not_di_sp32"
4137 [(set (match_operand:DI 0 "register_operand" "=r")
4138 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4139 (match_operand:DI 2 "register_operand" "r")))]
4141 "andn %2,%1,%0\;andn %R2,%R1,%R0"
4142 [(set_attr "length" "2")])
4144 (define_insn "*and_not_di_sp64"
4145 [(set (match_operand:DI 0 "register_operand" "=r")
4146 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4147 (match_operand:DI 2 "register_operand" "r")))]
4151 (define_insn "*and_not_si"
4152 [(set (match_operand:SI 0 "register_operand" "=r")
4153 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4154 (match_operand:SI 2 "register_operand" "r")))]
4157 [(set_attr "type" "ialu")])
4159 (define_expand "iordi3"
4160 [(set (match_operand:DI 0 "register_operand" "")
4161 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4162 (match_operand:DI 2 "arith_double_operand" "")))]
4166 (define_insn "*iordi3_sp32"
4167 [(set (match_operand:DI 0 "register_operand" "=r")
4168 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4169 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4173 rtx op2 = operands[2];
4175 if (GET_CODE (op2) == CONST_INT
4176 || GET_CODE (op2) == CONST_DOUBLE)
4179 xoperands[0] = operands[0];
4180 xoperands[1] = operands[1];
4181 if (WORDS_BIG_ENDIAN)
4182 split_double (op2, &xoperands[2], &xoperands[3]);
4184 split_double (op2, &xoperands[3], &xoperands[2]);
4185 output_asm_insn (\"or %L1,%3,%L0\;or %H1,%2,%H0\", xoperands);
4188 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
4190 [(set_attr "length" "2")])
4192 (define_insn "*iordi3_sp64"
4193 [(set (match_operand:DI 0 "register_operand" "=r")
4194 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4195 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4199 (define_insn "iorsi3"
4200 [(set (match_operand:SI 0 "register_operand" "=r")
4201 (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4202 (match_operand:SI 2 "arith_operand" "rI")))]
4205 [(set_attr "type" "ialu")])
4208 [(set (match_operand:SI 0 "register_operand" "")
4209 (ior:SI (match_operand:SI 1 "register_operand" "")
4210 (match_operand:SI 2 "" "")))
4211 (clobber (match_operand:SI 3 "register_operand" ""))]
4212 "GET_CODE (operands[2]) == CONST_INT
4213 && !SMALL_INT (operands[2])
4214 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4215 [(set (match_dup 3) (match_dup 4))
4216 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4219 operands[4] = GEN_INT (~INTVAL (operands[2]));
4222 (define_insn "*or_not_di_sp32"
4223 [(set (match_operand:DI 0 "register_operand" "=r")
4224 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4225 (match_operand:DI 2 "register_operand" "r")))]
4227 "orn %2,%1,%0\;orn %R2,%R1,%R0"
4228 [(set_attr "length" "2")])
4230 (define_insn "*or_not_di_sp64"
4231 [(set (match_operand:DI 0 "register_operand" "=r")
4232 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4233 (match_operand:DI 2 "register_operand" "r")))]
4237 (define_insn "*or_not_si"
4238 [(set (match_operand:SI 0 "register_operand" "=r")
4239 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4240 (match_operand:SI 2 "register_operand" "r")))]
4243 [(set_attr "type" "ialu")])
4245 (define_expand "xordi3"
4246 [(set (match_operand:DI 0 "register_operand" "")
4247 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4248 (match_operand:DI 2 "arith_double_operand" "")))]
4252 (define_insn "*xorsi3_sp32"
4253 [(set (match_operand:DI 0 "register_operand" "=r")
4254 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4255 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4259 rtx op2 = operands[2];
4261 if (GET_CODE (op2) == CONST_INT
4262 || GET_CODE (op2) == CONST_DOUBLE)
4265 xoperands[0] = operands[0];
4266 xoperands[1] = operands[1];
4267 if (WORDS_BIG_ENDIAN)
4268 split_double (op2, &xoperands[2], &xoperands[3]);
4270 split_double (op2, &xoperands[3], &xoperands[2]);
4271 output_asm_insn (\"xor %L1,%3,%L0\;xor %H1,%2,%H0\", xoperands);
4274 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
4276 [(set_attr "length" "2")])
4278 (define_insn "*xordi3_sp64"
4279 [(set (match_operand:DI 0 "register_operand" "=r")
4280 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ")
4281 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4285 (define_insn "xorsi3"
4286 [(set (match_operand:SI 0 "register_operand" "=r")
4287 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4288 (match_operand:SI 2 "arith_operand" "rI")))]
4291 [(set_attr "type" "ialu")])
4294 [(set (match_operand:SI 0 "register_operand" "")
4295 (xor:SI (match_operand:SI 1 "register_operand" "")
4296 (match_operand:SI 2 "" "")))
4297 (clobber (match_operand:SI 3 "register_operand" ""))]
4298 "GET_CODE (operands[2]) == CONST_INT
4299 && !SMALL_INT (operands[2])
4300 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4301 [(set (match_dup 3) (match_dup 4))
4302 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4305 operands[4] = GEN_INT (~INTVAL (operands[2]));
4309 [(set (match_operand:SI 0 "register_operand" "")
4310 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4311 (match_operand:SI 2 "" ""))))
4312 (clobber (match_operand:SI 3 "register_operand" ""))]
4313 "GET_CODE (operands[2]) == CONST_INT
4314 && !SMALL_INT (operands[2])
4315 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4316 [(set (match_dup 3) (match_dup 4))
4317 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4320 operands[4] = GEN_INT (~INTVAL (operands[2]));
4323 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4324 ;; Combine now canonicalizes to the rightmost expression.
4325 (define_insn "*xor_not_di_sp32"
4326 [(set (match_operand:DI 0 "register_operand" "=r")
4327 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4328 (match_operand:DI 2 "register_operand" "r"))))]
4330 "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
4331 [(set_attr "length" "2")])
4333 (define_insn "*xor_not_di_sp64"
4334 [(set (match_operand:DI 0 "register_operand" "=r")
4335 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
4336 (match_operand:DI 2 "arith_double_operand" "rHI"))))]
4340 (define_insn "*xor_not_si"
4341 [(set (match_operand:SI 0 "register_operand" "=r")
4342 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4343 (match_operand:SI 2 "arith_operand" "rI"))))]
4346 [(set_attr "type" "ialu")])
4348 ;; These correspond to the above in the case where we also (or only)
4349 ;; want to set the condition code.
4351 (define_insn "*cmp_cc_arith_op"
4354 (match_operator:SI 2 "cc_arithop"
4355 [(match_operand:SI 0 "arith_operand" "%r")
4356 (match_operand:SI 1 "arith_operand" "rI")])
4360 [(set_attr "type" "compare")])
4362 (define_insn "*cmp_ccx_arith_op"
4365 (match_operator:DI 2 "cc_arithop"
4366 [(match_operand:DI 0 "arith_double_operand" "%r")
4367 (match_operand:DI 1 "arith_double_operand" "rHI")])
4371 [(set_attr "type" "compare")])
4373 (define_insn "*cmp_cc_arith_op_set"
4376 (match_operator:SI 3 "cc_arithop"
4377 [(match_operand:SI 1 "arith_operand" "%r")
4378 (match_operand:SI 2 "arith_operand" "rI")])
4380 (set (match_operand:SI 0 "register_operand" "=r")
4385 (define_insn "*cmp_ccx_arith_op_set"
4388 (match_operator:DI 3 "cc_arithop"
4389 [(match_operand:DI 1 "arith_double_operand" "%r")
4390 (match_operand:DI 2 "arith_double_operand" "rHI")])
4392 (set (match_operand:DI 0 "register_operand" "=r")
4397 (define_insn "*cmp_cc_xor_not"
4400 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
4401 (match_operand:SI 1 "arith_operand" "rI")))
4404 "xnorcc %r0,%1,%%g0"
4405 [(set_attr "type" "compare")])
4407 (define_insn "*cmp_ccx_xor_not"
4410 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
4411 (match_operand:DI 1 "arith_double_operand" "rHI")))
4414 "xnorcc %r0,%1,%%g0"
4415 [(set_attr "type" "compare")])
4417 (define_insn "*cmp_cc_xor_not_set"
4420 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4421 (match_operand:SI 2 "arith_operand" "rI")))
4423 (set (match_operand:SI 0 "register_operand" "=r")
4424 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4428 (define_insn "*cmp_ccx_xor_not_set"
4431 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
4432 (match_operand:DI 2 "arith_double_operand" "rHI")))
4434 (set (match_operand:DI 0 "register_operand" "=r")
4435 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4439 (define_insn "*cmp_cc_arith_op_not"
4442 (match_operator:SI 2 "cc_arithopn"
4443 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4444 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
4448 [(set_attr "type" "compare")])
4450 (define_insn "*cmp_ccx_arith_op_not"
4453 (match_operator:DI 2 "cc_arithopn"
4454 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4455 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
4459 [(set_attr "type" "compare")])
4461 (define_insn "*cmp_cc_arith_op_not_set"
4464 (match_operator:SI 3 "cc_arithopn"
4465 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4466 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
4468 (set (match_operand:SI 0 "register_operand" "=r")
4473 (define_insn "*cmp_ccx_arith_op_not_set"
4476 (match_operator:DI 3 "cc_arithopn"
4477 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4478 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
4480 (set (match_operand:DI 0 "register_operand" "=r")
4485 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4486 ;; does not know how to make it work for constants.
4488 (define_expand "negdi2"
4489 [(set (match_operand:DI 0 "register_operand" "=r")
4490 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4494 if (! TARGET_ARCH64)
4496 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4497 gen_rtx (SET, VOIDmode, operand0,
4498 gen_rtx (NEG, DImode, operand1)),
4499 gen_rtx (CLOBBER, VOIDmode,
4500 gen_rtx (REG, SImode, SPARC_ICC_REG)))));
4505 (define_insn "*negdi2_sp32"
4506 [(set (match_operand:DI 0 "register_operand" "=r")
4507 (neg:DI (match_operand:DI 1 "register_operand" "r")))
4508 (clobber (reg:SI 100))]
4513 output_asm_insn (\"and %%g0,0,%%g0\", operands);
4514 return \"subcc %%g0,%L1,%L0\;subx %%g0,%H1,%H0\";
4516 [(set_attr "type" "unary")
4517 ;; ??? This is wrong for TARGET_LIVE_G0 but it's not critical.
4518 (set_attr "length" "2")])
4520 (define_insn "*negdi2_sp64"
4521 [(set (match_operand:DI 0 "register_operand" "=r")
4522 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4525 [(set_attr "type" "unary")
4526 (set_attr "length" "1")])
4528 (define_insn "negsi2"
4529 [(set (match_operand:SI 0 "register_operand" "=r")
4530 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
4535 return \"and %%g0,0,%%g0\;sub %%g0,%1,%0\";
4536 return \"sub %%g0,%1,%0\";
4538 [(set_attr "type" "unary")
4539 (set (attr "length")
4540 (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1)))])
4542 (define_insn "*cmp_cc_neg"
4543 [(set (reg:CC_NOOV 100)
4544 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
4547 "subcc %%g0,%0,%%g0"
4548 [(set_attr "type" "compare")])
4550 (define_insn "*cmp_ccx_neg"
4551 [(set (reg:CCX_NOOV 100)
4552 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4555 "subcc %%g0,%0,%%g0"
4556 [(set_attr "type" "compare")])
4558 (define_insn "*cmp_cc_set_neg"
4559 [(set (reg:CC_NOOV 100)
4560 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
4562 (set (match_operand:SI 0 "register_operand" "=r")
4563 (neg:SI (match_dup 1)))]
4566 [(set_attr "type" "unary")])
4568 (define_insn "*cmp_ccx_set_neg"
4569 [(set (reg:CCX_NOOV 100)
4570 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4572 (set (match_operand:DI 0 "register_operand" "=r")
4573 (neg:DI (match_dup 1)))]
4576 [(set_attr "type" "unary")])
4578 ;; We cannot use the "not" pseudo insn because the Sun assembler
4579 ;; does not know how to make it work for constants.
4580 (define_expand "one_cmpldi2"
4581 [(set (match_operand:DI 0 "register_operand" "")
4582 (not:DI (match_operand:DI 1 "register_operand" "")))]
4586 (define_insn "*one_cmpldi2_sp32"
4587 [(set (match_operand:DI 0 "register_operand" "=r")
4588 (not:DI (match_operand:DI 1 "register_operand" "r")))]
4590 "xnor %1,0,%0\;xnor %R1,0,%R0"
4591 [(set_attr "type" "unary")
4592 (set_attr "length" "2")])
4594 (define_insn "*one_cmpldi2_sp64"
4595 [(set (match_operand:DI 0 "register_operand" "=r")
4596 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
4599 [(set_attr "type" "unary")])
4601 (define_insn "one_cmplsi2"
4602 [(set (match_operand:SI 0 "register_operand" "=r,r")
4603 (not:SI (match_operand:SI 1 "arith_operand" "r,I")))]
4607 if (which_alternative == 0)
4608 return \"xnor %1,0,%0\";
4610 output_asm_insn (\"and %%g0,0,%%g0\", operands);
4611 return \"xnor %%g0,%1,%0\";
4613 [(set_attr "type" "unary")
4614 (set_attr_alternative "length"
4616 (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1))])])
4618 (define_insn "*cmp_cc_not"
4620 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
4623 "xnorcc %%g0,%0,%%g0"
4624 [(set_attr "type" "compare")])
4626 (define_insn "*cmp_ccx_not"
4628 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4631 "xnorcc %%g0,%0,%%g0"
4632 [(set_attr "type" "compare")])
4634 (define_insn "*cmp_cc_set_not"
4636 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
4638 (set (match_operand:SI 0 "register_operand" "=r")
4639 (not:SI (match_dup 1)))]
4642 [(set_attr "type" "unary")])
4644 (define_insn "*cmp_ccx_set_not"
4646 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4648 (set (match_operand:DI 0 "register_operand" "=r")
4649 (not:DI (match_dup 1)))]
4652 [(set_attr "type" "unary")])
4654 ;; Floating point arithmetic instructions.
4656 (define_insn "addtf3"
4657 [(set (match_operand:TF 0 "register_operand" "=e")
4658 (plus:TF (match_operand:TF 1 "register_operand" "e")
4659 (match_operand:TF 2 "register_operand" "e")))]
4660 "TARGET_FPU && TARGET_HARD_QUAD"
4662 [(set_attr "type" "fp")])
4664 (define_insn "adddf3"
4665 [(set (match_operand:DF 0 "register_operand" "=e")
4666 (plus:DF (match_operand:DF 1 "register_operand" "e")
4667 (match_operand:DF 2 "register_operand" "e")))]
4670 [(set_attr "type" "fp")])
4672 (define_insn "addsf3"
4673 [(set (match_operand:SF 0 "register_operand" "=f")
4674 (plus:SF (match_operand:SF 1 "register_operand" "f")
4675 (match_operand:SF 2 "register_operand" "f")))]
4678 [(set_attr "type" "fp")])
4680 (define_insn "subtf3"
4681 [(set (match_operand:TF 0 "register_operand" "=e")
4682 (minus:TF (match_operand:TF 1 "register_operand" "e")
4683 (match_operand:TF 2 "register_operand" "e")))]
4684 "TARGET_FPU && TARGET_HARD_QUAD"
4686 [(set_attr "type" "fp")])
4688 (define_insn "subdf3"
4689 [(set (match_operand:DF 0 "register_operand" "=e")
4690 (minus:DF (match_operand:DF 1 "register_operand" "e")
4691 (match_operand:DF 2 "register_operand" "e")))]
4694 [(set_attr "type" "fp")])
4696 (define_insn "subsf3"
4697 [(set (match_operand:SF 0 "register_operand" "=f")
4698 (minus:SF (match_operand:SF 1 "register_operand" "f")
4699 (match_operand:SF 2 "register_operand" "f")))]
4702 [(set_attr "type" "fp")])
4704 (define_insn "multf3"
4705 [(set (match_operand:TF 0 "register_operand" "=e")
4706 (mult:TF (match_operand:TF 1 "register_operand" "e")
4707 (match_operand:TF 2 "register_operand" "e")))]
4708 "TARGET_FPU && TARGET_HARD_QUAD"
4710 [(set_attr "type" "fpmul")])
4712 (define_insn "muldf3"
4713 [(set (match_operand:DF 0 "register_operand" "=e")
4714 (mult:DF (match_operand:DF 1 "register_operand" "e")
4715 (match_operand:DF 2 "register_operand" "e")))]
4718 [(set_attr "type" "fpmul")])
4720 (define_insn "mulsf3"
4721 [(set (match_operand:SF 0 "register_operand" "=f")
4722 (mult:SF (match_operand:SF 1 "register_operand" "f")
4723 (match_operand:SF 2 "register_operand" "f")))]
4726 [(set_attr "type" "fpmul")])
4728 (define_insn "*muldf3_extend"
4729 [(set (match_operand:DF 0 "register_operand" "=e")
4730 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
4731 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
4732 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4734 [(set_attr "type" "fpmul")])
4736 (define_insn "*multf3_extend"
4737 [(set (match_operand:TF 0 "register_operand" "=e")
4738 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
4739 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
4740 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
4742 [(set_attr "type" "fpmul")])
4744 ;; don't have timing for quad-prec. divide.
4745 (define_insn "divtf3"
4746 [(set (match_operand:TF 0 "register_operand" "=e")
4747 (div:TF (match_operand:TF 1 "register_operand" "e")
4748 (match_operand:TF 2 "register_operand" "e")))]
4749 "TARGET_FPU && TARGET_HARD_QUAD"
4751 [(set_attr "type" "fpdivd")])
4753 (define_insn "divdf3"
4754 [(set (match_operand:DF 0 "register_operand" "=e")
4755 (div:DF (match_operand:DF 1 "register_operand" "e")
4756 (match_operand:DF 2 "register_operand" "e")))]
4759 [(set_attr "type" "fpdivd")])
4761 (define_insn "divsf3"
4762 [(set (match_operand:SF 0 "register_operand" "=f")
4763 (div:SF (match_operand:SF 1 "register_operand" "f")
4764 (match_operand:SF 2 "register_operand" "f")))]
4767 [(set_attr "type" "fpdivs")])
4769 (define_insn "negtf2"
4770 [(set (match_operand:TF 0 "register_operand" "=e,e")
4771 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
4772 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
4776 /* v9: can't use fnegs, won't work with upper regs. */
4777 if (which_alternative == 0)
4778 return TARGET_V9 ? \"fnegd %0,%0\" : \"fnegs %0,%0\";
4780 return TARGET_V9 ? \"fnegd %1,%0\;fmovd %S1,%S0\"
4781 : \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4783 [(set_attr "type" "fp")
4784 (set_attr_alternative "length"
4786 (if_then_else (eq_attr "isa" "v9") (const_int 2) (const_int 4))])])
4788 (define_insn "negdf2"
4789 [(set (match_operand:DF 0 "register_operand" "=e,e")
4790 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
4795 return \"fnegd %1,%0\";
4796 else if (which_alternative == 0)
4797 return \"fnegs %0,%0\";
4799 return \"fnegs %1,%0\;fmovs %R1,%R0\";
4801 [(set_attr "type" "fp")
4802 (set_attr_alternative "length"
4804 (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])])
4806 (define_insn "negsf2"
4807 [(set (match_operand:SF 0 "register_operand" "=f")
4808 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
4811 [(set_attr "type" "fp")])
4813 (define_insn "abstf2"
4814 [(set (match_operand:TF 0 "register_operand" "=e,e")
4815 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
4816 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
4820 /* v9: can't use fabss, won't work with upper regs. */
4821 if (which_alternative == 0)
4822 return TARGET_V9 ? \"fabsd %0,%0\" : \"fabss %0,%0\";
4824 return TARGET_V9 ? \"fabsd %1,%0\;fmovd %S1,%S0\"
4825 : \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4827 [(set_attr "type" "fp")
4828 (set_attr_alternative "length"
4830 (if_then_else (eq_attr "isa" "v9") (const_int 2) (const_int 4))])])
4832 (define_insn "absdf2"
4833 [(set (match_operand:DF 0 "register_operand" "=e,e")
4834 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
4839 return \"fabsd %1,%0\";
4840 else if (which_alternative == 0)
4841 return \"fabss %0,%0\";
4843 return \"fabss %1,%0\;fmovs %R1,%R0\";
4845 [(set_attr "type" "fp")
4846 (set_attr_alternative "length"
4848 (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])])
4850 (define_insn "abssf2"
4851 [(set (match_operand:SF 0 "register_operand" "=f")
4852 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
4855 [(set_attr "type" "fp")])
4857 (define_insn "sqrttf2"
4858 [(set (match_operand:TF 0 "register_operand" "=e")
4859 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
4860 "TARGET_FPU && TARGET_HARD_QUAD"
4862 [(set_attr "type" "fpsqrt")])
4864 (define_insn "sqrtdf2"
4865 [(set (match_operand:DF 0 "register_operand" "=e")
4866 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
4869 [(set_attr "type" "fpsqrt")])
4871 (define_insn "sqrtsf2"
4872 [(set (match_operand:SF 0 "register_operand" "=f")
4873 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
4876 [(set_attr "type" "fpsqrt")])
4878 ;;- arithmetic shift instructions
4880 (define_insn "ashlsi3"
4881 [(set (match_operand:SI 0 "register_operand" "=r")
4882 (ashift:SI (match_operand:SI 1 "register_operand" "r")
4883 (match_operand:SI 2 "arith_operand" "rI")))]
4887 if (GET_CODE (operands[2]) == CONST_INT
4888 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
4889 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4891 return \"sll %1,%2,%0\";
4893 [(set_attr "type" "shift")])
4895 (define_insn "ashldi3"
4896 [(set (match_operand:DI 0 "register_operand" "=r")
4897 (ashift:DI (match_operand:DI 1 "register_operand" "r")
4898 (match_operand:SI 2 "arith_operand" "rI")))]
4902 if (GET_CODE (operands[2]) == CONST_INT
4903 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
4904 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4906 return \"sllx %1,%2,%0\";
4909 (define_insn "*cmp_cc_ashift_1"
4910 [(set (reg:CC_NOOV 100)
4911 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
4916 [(set_attr "type" "compare")])
4918 (define_insn "*cmp_cc_set_ashift_1"
4919 [(set (reg:CC_NOOV 100)
4920 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
4923 (set (match_operand:SI 0 "register_operand" "=r")
4924 (ashift:SI (match_dup 1) (const_int 1)))]
4928 (define_insn "ashrsi3"
4929 [(set (match_operand:SI 0 "register_operand" "=r")
4930 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4931 (match_operand:SI 2 "arith_operand" "rI")))]
4935 if (GET_CODE (operands[2]) == CONST_INT
4936 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
4937 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4939 return \"sra %1,%2,%0\";
4941 [(set_attr "type" "shift")])
4943 (define_insn "ashrdi3"
4944 [(set (match_operand:DI 0 "register_operand" "=r")
4945 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
4946 (match_operand:SI 2 "arith_operand" "rI")))]
4950 if (GET_CODE (operands[2]) == CONST_INT
4951 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
4952 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4954 return \"srax %1,%2,%0\";
4957 (define_insn "lshrsi3"
4958 [(set (match_operand:SI 0 "register_operand" "=r")
4959 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4960 (match_operand:SI 2 "arith_operand" "rI")))]
4964 if (GET_CODE (operands[2]) == CONST_INT
4965 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
4966 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4968 return \"srl %1,%2,%0\";
4970 [(set_attr "type" "shift")])
4972 (define_insn "lshrdi3"
4973 [(set (match_operand:DI 0 "register_operand" "=r")
4974 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
4975 (match_operand:SI 2 "arith_operand" "rI")))]
4979 if (GET_CODE (operands[2]) == CONST_INT
4980 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
4981 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4983 return \"srlx %1,%2,%0\";
4986 ;; Unconditional and other jump instructions
4987 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
4988 ;; following insn is never executed. This saves us a nop. Dbx does not
4989 ;; handle such branches though, so we only use them when optimizing.
4991 [(set (pc) (label_ref (match_operand 0 "" "")))]
4994 [(set_attr "type" "uncond_branch")])
4996 (define_expand "tablejump"
4997 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
4998 (use (label_ref (match_operand 1 "" "")))])]
5002 if (GET_MODE (operands[0]) != Pmode)
5005 /* We need to use the PC value in %o7 that was set up when the address
5006 of the label was loaded into a register, so we need different RTL. */
5010 emit_jump_insn (gen_pic_tablejump_32 (operands[0], operands[1]));
5012 emit_jump_insn (gen_pic_tablejump_64 (operands[0], operands[1]));
5017 (define_insn "pic_tablejump_32"
5018 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
5019 (use (label_ref (match_operand 1 "" "")))
5023 [(set_attr "type" "uncond_branch")])
5025 (define_insn "pic_tablejump_64"
5026 [(set (pc) (match_operand:DI 0 "register_operand" "r"))
5027 (use (label_ref (match_operand 1 "" "")))
5031 [(set_attr "type" "uncond_branch")])
5033 (define_insn "*tablejump_sp32"
5034 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5035 (use (label_ref (match_operand 1 "" "")))]
5038 [(set_attr "type" "uncond_branch")])
5040 (define_insn "*tablejump_sp64"
5041 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5042 (use (label_ref (match_operand 1 "" "")))]
5045 [(set_attr "type" "uncond_branch")])
5047 ;; This pattern recognizes the "instruction" that appears in
5048 ;; a function call that wants a structure value,
5049 ;; to inform the called function if compiled with Sun CC.
5050 ;(define_insn "*unimp_insn"
5051 ; [(match_operand:SI 0 "immediate_operand" "")]
5052 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
5054 ; [(set_attr "type" "marker")])
5056 ;;- jump to subroutine
5057 (define_expand "call"
5058 ;; Note that this expression is not used for generating RTL.
5059 ;; All the RTL is generated explicitly below.
5060 [(call (match_operand 0 "call_operand" "")
5061 (match_operand 3 "" "i"))]
5062 ;; operands[2] is next_arg_register
5063 ;; operands[3] is struct_value_size_rtx.
5067 rtx fn_rtx, nregs_rtx;
5069 if (GET_MODE (operands[0]) != FUNCTION_MODE)
5072 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5074 /* This is really a PIC sequence. We want to represent
5075 it as a funny jump so it's delay slots can be filled.
5077 ??? But if this really *is* a CALL, will not it clobber the
5078 call-clobbered registers? We lose this if it is a JUMP_INSN.
5079 Why cannot we have delay slots filled if it were a CALL? */
5081 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5083 (gen_rtx (PARALLEL, VOIDmode,
5085 gen_rtx (SET, VOIDmode, pc_rtx,
5086 XEXP (operands[0], 0)),
5087 GEN_INT (INTVAL (operands[3]) & 0xfff),
5088 gen_rtx (CLOBBER, VOIDmode,
5089 gen_rtx (REG, Pmode, 15)))));
5092 (gen_rtx (PARALLEL, VOIDmode,
5094 gen_rtx (SET, VOIDmode, pc_rtx,
5095 XEXP (operands[0], 0)),
5096 gen_rtx (CLOBBER, VOIDmode,
5097 gen_rtx (REG, Pmode, 15)))));
5101 fn_rtx = operands[0];
5103 /* Count the number of parameter registers being used by this call.
5104 if that argument is NULL, it means we are using them all, which
5105 means 6 on the sparc. */
5108 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
5110 nregs_rtx = GEN_INT (6);
5112 nregs_rtx = const0_rtx;
5115 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5117 (gen_rtx (PARALLEL, VOIDmode,
5118 gen_rtvec (3, gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
5119 GEN_INT (INTVAL (operands[3]) & 0xfff),
5120 gen_rtx (CLOBBER, VOIDmode,
5121 gen_rtx (REG, Pmode, 15)))));
5124 (gen_rtx (PARALLEL, VOIDmode,
5125 gen_rtvec (2, gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
5126 gen_rtx (CLOBBER, VOIDmode,
5127 gen_rtx (REG, Pmode, 15)))));
5131 /* If this call wants a structure value,
5132 emit an unimp insn to let the called function know about this. */
5133 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
5135 rtx insn = emit_insn (operands[3]);
5136 SCHED_GROUP_P (insn) = 1;
5143 ;; We can't use the same pattern for these two insns, because then registers
5144 ;; in the address may not be properly reloaded.
5146 (define_insn "*call_address_sp32"
5147 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5148 (match_operand 1 "" ""))
5149 (clobber (reg:SI 15))]
5150 ;;- Do not use operand 1 for most machines.
5153 [(set_attr "type" "call")])
5155 (define_insn "*call_symbolic_sp32"
5156 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5157 (match_operand 1 "" ""))
5158 (clobber (reg:SI 15))]
5159 ;;- Do not use operand 1 for most machines.
5162 [(set_attr "type" "call")])
5164 (define_insn "*call_address_sp64"
5165 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
5166 (match_operand 1 "" ""))
5167 (clobber (reg:DI 15))]
5168 ;;- Do not use operand 1 for most machines.
5171 [(set_attr "type" "call")])
5173 (define_insn "*call_symbolic_sp64"
5174 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
5175 (match_operand 1 "" ""))
5176 (clobber (reg:DI 15))]
5177 ;;- Do not use operand 1 for most machines.
5180 [(set_attr "type" "call")])
5182 ;; This is a call that wants a structure value.
5183 ;; There is no such critter for v9 (??? we may need one anyway).
5184 (define_insn "*call_address_struct_value_sp32"
5185 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5186 (match_operand 1 "" ""))
5187 (match_operand 2 "immediate_operand" "")
5188 (clobber (reg:SI 15))]
5189 ;;- Do not use operand 1 for most machines.
5190 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
5191 "call %a0,%1\;nop\;unimp %2"
5192 [(set_attr "type" "call_no_delay_slot")])
5194 ;; This is a call that wants a structure value.
5195 ;; There is no such critter for v9 (??? we may need one anyway).
5196 (define_insn "*call_symbolic_struct_value_sp32"
5197 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5198 (match_operand 1 "" ""))
5199 (match_operand 2 "immediate_operand" "")
5200 (clobber (reg:SI 15))]
5201 ;;- Do not use operand 1 for most machines.
5202 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
5203 "call %a0,%1\;nop\;unimp %2"
5204 [(set_attr "type" "call_no_delay_slot")])
5206 ;; This is a call that may want a structure value. This is used for
5208 (define_insn "*call_address_untyped_struct_value_sp32"
5209 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5210 (match_operand 1 "" ""))
5211 (match_operand 2 "immediate_operand" "")
5212 (clobber (reg:SI 15))]
5213 ;;- Do not use operand 1 for most machines.
5214 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
5215 "call %a0,%1\;nop\;nop"
5216 [(set_attr "type" "call_no_delay_slot")])
5218 ;; This is a call that wants a structure value.
5219 (define_insn "*call_symbolic_untyped_struct_value_sp32"
5220 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5221 (match_operand 1 "" ""))
5222 (match_operand 2 "immediate_operand" "")
5223 (clobber (reg:SI 15))]
5224 ;;- Do not use operand 1 for most machines.
5225 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
5226 "call %a0,%1\;nop\;nop"
5227 [(set_attr "type" "call_no_delay_slot")])
5229 (define_expand "call_value"
5230 ;; Note that this expression is not used for generating RTL.
5231 ;; All the RTL is generated explicitly below.
5232 [(set (match_operand 0 "register_operand" "=rf")
5233 (call (match_operand:SI 1 "" "")
5234 (match_operand 4 "" "")))]
5235 ;; operand 2 is stack_size_rtx
5236 ;; operand 3 is next_arg_register
5240 rtx fn_rtx, nregs_rtx;
5243 if (GET_MODE (operands[1]) != FUNCTION_MODE)
5246 fn_rtx = operands[1];
5250 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
5252 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
5254 nregs_rtx = const0_rtx;
5258 gen_rtx (SET, VOIDmode, operands[0],
5259 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
5260 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 15)));
5262 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
5267 (define_insn "*call_value_address_sp32"
5268 [(set (match_operand 0 "" "=rf")
5269 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
5270 (match_operand 2 "" "")))
5271 (clobber (reg:SI 15))]
5272 ;;- Do not use operand 2 for most machines.
5275 [(set_attr "type" "call")])
5277 (define_insn "*call_value_symbolic_sp32"
5278 [(set (match_operand 0 "" "=rf")
5279 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
5280 (match_operand 2 "" "")))
5281 (clobber (reg:SI 15))]
5282 ;;- Do not use operand 2 for most machines.
5285 [(set_attr "type" "call")])
5287 (define_insn "*call_value_address_sp64"
5288 [(set (match_operand 0 "" "=rf")
5289 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
5290 (match_operand 2 "" "")))
5291 (clobber (reg:DI 15))]
5292 ;;- Do not use operand 2 for most machines.
5295 [(set_attr "type" "call")])
5297 (define_insn "*call_value_symbolic_sp64"
5298 [(set (match_operand 0 "" "=rf")
5299 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
5300 (match_operand 2 "" "")))
5301 (clobber (reg:DI 15))]
5302 ;;- Do not use operand 2 for most machines.
5305 [(set_attr "type" "call")])
5307 (define_expand "untyped_call"
5308 [(parallel [(call (match_operand 0 "" "")
5310 (match_operand 1 "" "")
5311 (match_operand 2 "" "")])]
5317 /* Pass constm1 to indicate that it may expect a structure value, but
5318 we don't know what size it is. */
5319 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
5321 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5323 rtx set = XVECEXP (operands[2], 0, i);
5324 emit_move_insn (SET_DEST (set), SET_SRC (set));
5327 /* The optimizer does not know that the call sets the function value
5328 registers we stored in the result block. We avoid problems by
5329 claiming that all hard registers are used and clobbered at this
5331 emit_insn (gen_blockage ());
5336 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
5337 ;; all of memory. This blocks insns from being moved across this point.
5339 (define_insn "blockage"
5340 [(unspec_volatile [(const_int 0)] 0)]
5344 ;; Prepare to return any type including a structure value.
5346 (define_expand "untyped_return"
5347 [(match_operand:BLK 0 "memory_operand" "")
5348 (match_operand 1 "" "")]
5352 rtx valreg1 = gen_rtx (REG, DImode, 24);
5353 rtx valreg2 = gen_rtx (REG, TARGET_ARCH64 ? TFmode : DFmode, 32);
5354 rtx result = operands[0];
5356 if (! TARGET_ARCH64)
5358 rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
5359 rtx value = gen_reg_rtx (SImode);
5361 /* Fetch the instruction where we will return to and see if it's an unimp
5362 instruction (the most significant 10 bits will be zero). If so,
5363 update the return address to skip the unimp instruction. */
5364 emit_move_insn (value,
5365 gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
5366 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
5367 emit_insn (gen_update_return (rtnreg, value));
5370 /* Reload the function value registers. */
5371 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
5372 emit_move_insn (valreg2,
5373 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
5374 plus_constant (XEXP (result, 0), 8)));
5376 /* Put USE insns before the return. */
5377 emit_insn (gen_rtx (USE, VOIDmode, valreg1));
5378 emit_insn (gen_rtx (USE, VOIDmode, valreg2));
5380 /* Construct the return. */
5381 expand_null_return ();
5386 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
5387 ;; and parts of the compiler don't want to believe that the add is needed.
5389 (define_insn "update_return"
5390 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
5391 (match_operand:SI 1 "register_operand" "r")] 0)]
5393 "cmp %1,0\;be,a .+8\;add %0,4,%0"
5394 [(set_attr "type" "multi")])
5396 (define_insn "return"
5400 "* return output_return (operands);"
5401 [(set_attr "type" "multi")])
5408 (define_expand "indirect_jump"
5409 [(set (pc) (match_operand 0 "address_operand" "p"))]
5413 (define_insn "*branch_sp32"
5414 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
5417 [(set_attr "type" "uncond_branch")])
5419 (define_insn "*branch_sp64"
5420 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
5423 [(set_attr "type" "uncond_branch")])
5425 ;; ??? Doesn't work with -mflat.
5426 (define_expand "nonlocal_goto"
5427 [(match_operand:SI 0 "general_operand" "")
5428 (match_operand:SI 1 "general_operand" "")
5429 (match_operand:SI 2 "general_operand" "")
5430 (match_operand:SI 3 "" "")]
5434 /* Trap instruction to flush all the register windows. */
5435 emit_insn (gen_flush_register_windows ());
5436 /* Load the fp value for the containing fn into %fp.
5437 This is needed because operands[2] refers to %fp.
5438 Virtual register instantiation fails if the virtual %fp isn't set from a
5439 register. Thus we must copy operands[0] into a register if it isn't
5441 if (GET_CODE (operands[0]) != REG)
5442 operands[0] = force_reg (Pmode, operands[0]);
5443 emit_move_insn (virtual_stack_vars_rtx, operands[0]);
5444 /* Find the containing function's current nonlocal goto handler,
5445 which will do any cleanups and then jump to the label. */
5446 emit_move_insn (gen_rtx (REG, Pmode, 8), operands[1]);
5447 /* Restore %fp from stack pointer value for containing function.
5448 The restore insn that follows will move this to %sp,
5449 and reload the appropriate value into %fp. */
5450 emit_move_insn (frame_pointer_rtx, operands[2]);
5451 /* Put in the static chain register the nonlocal label address. */
5452 emit_move_insn (static_chain_rtx, operands[3]);
5453 /* USE of frame_pointer_rtx added for consistency; not clear if
5455 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
5456 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
5457 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
5458 /* Return, restoring reg window and jumping to goto handler. */
5459 emit_insn (gen_goto_handler_and_restore ());
5464 ;; Special trap insn to flush register windows.
5465 (define_insn "flush_register_windows"
5466 [(unspec_volatile [(const_int 0)] 1)]
5468 ;; ??? Use TARGET_V9 instead?
5469 "* return TARGET_ARCH64 ? \"flushw\" : \"ta 3\";"
5470 [(set_attr "type" "misc")])
5472 (define_insn "goto_handler_and_restore"
5473 [(unspec_volatile [(const_int 0)] 2)
5476 "jmp %%o0+0\;restore"
5477 [(set_attr "type" "misc")
5478 (set_attr "length" "2")])
5480 ;; Pattern for use after a setjmp to store FP and the return register
5481 ;; into the stack area.
5483 (define_expand "setjmp"
5489 emit_insn (gen_setjmp_64 ());
5491 emit_insn (gen_setjmp_32 ());
5496 (define_expand "setjmp_32"
5497 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
5498 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
5501 { operands[0] = frame_pointer_rtx; }")
5503 (define_expand "setjmp_64"
5504 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
5505 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
5508 { operands[0] = frame_pointer_rtx; }")
5510 ;; Special pattern for the FLUSH instruction.
5512 (define_insn "flush"
5513 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 3)]
5515 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
5516 [(set_attr "type" "misc")])
5520 ;; The scan instruction searches from the most significant bit while ffs
5521 ;; searches from the least significant bit. The bit index and treatment of
5522 ;; zero also differ. It takes at least 7 instructions to get the proper
5523 ;; result. Here is an obvious 8 instruction sequence.
5525 (define_insn "ffssi2"
5526 [(set (match_operand:SI 0 "register_operand" "=&r")
5527 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
5528 (clobber (match_scratch:SI 2 "=&r"))]
5529 "TARGET_SPARCLITE || TARGET_SPARCLET"
5533 output_asm_insn (\"and %%g0,0,%%g0\", operands);
5534 return \"sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0\";
5536 [(set_attr "type" "multi")
5537 (set_attr "length" "8")])
5539 ;; ??? This should be a define expand, so that the extra instruction have
5540 ;; a chance of being optimized away.
5542 (define_insn "ffsdi2"
5543 [(set (match_operand:DI 0 "register_operand" "=&r")
5544 (ffs:DI (match_operand:DI 1 "register_operand" "r")))
5545 (clobber (match_scratch:DI 2 "=&r"))]
5547 "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,0,%0"
5548 [(set_attr "type" "multi")
5549 (set_attr "length" "5")])
5551 ;; Split up troublesome insns for better scheduling. */
5553 ;; The following patterns are straightforward. They can be applied
5554 ;; either before or after register allocation.
5557 [(set (match_operand 0 "splittable_symbolic_memory_operand" "")
5558 (match_operand 1 "reg_or_0_operand" ""))
5559 (clobber (match_operand:SI 2 "register_operand" ""))]
5561 [(set (match_dup 2) (high:SI (match_dup 3)))
5562 (set (match_dup 4) (match_dup 1))]
5565 operands[3] = XEXP (operands[0], 0);
5566 operands[4] = gen_rtx (MEM, GET_MODE (operands[0]),
5567 gen_rtx (LO_SUM, SImode, operands[2], operands[3]));
5568 MEM_IN_STRUCT_P (operands[4]) = MEM_IN_STRUCT_P (operands[0]);
5569 MEM_VOLATILE_P (operands[4]) = MEM_VOLATILE_P (operands[0]);
5570 RTX_UNCHANGING_P (operands[4]) = RTX_UNCHANGING_P (operands[0]);
5574 [(set (match_operand 0 "splittable_immediate_memory_operand" "")
5575 (match_operand 1 "general_operand" ""))
5576 (clobber (match_operand:SI 2 "register_operand" ""))]
5578 [(set (match_dup 3) (match_dup 1))]
5581 rtx addr = legitimize_pic_address (XEXP (operands[0], 0),
5582 GET_MODE (operands[0]),
5584 operands[3] = gen_rtx (MEM, GET_MODE (operands[0]), addr);
5585 MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[0]);
5586 MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[0]);
5587 RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[0]);
5591 [(set (match_operand 0 "register_operand" "")
5592 (match_operand 1 "splittable_immediate_memory_operand" ""))]
5594 [(set (match_dup 0) (match_dup 2))]
5597 rtx addr = legitimize_pic_address (XEXP (operands[1], 0),
5598 GET_MODE (operands[1]),
5600 operands[2] = gen_rtx (MEM, GET_MODE (operands[1]), addr);
5601 MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]);
5602 MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]);
5603 RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
5606 ;; Sign- and Zero-extend operations can have symbolic memory operands.
5609 [(set (match_operand 0 "register_operand" "")
5610 (match_operator 1 "extend_op" [(match_operand 2 "splittable_immediate_memory_operand" "")]))]
5612 [(set (match_dup 0) (match_op_dup 1 [(match_dup 3)]))]
5615 rtx addr = legitimize_pic_address (XEXP (operands[2], 0),
5616 GET_MODE (operands[2]),
5618 operands[3] = gen_rtx (MEM, GET_MODE (operands[2]), addr);
5619 MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[2]);
5620 MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[2]);
5621 RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[2]);
5625 [(set (match_operand:SI 0 "register_operand" "")
5626 (match_operand:SI 1 "immediate_operand" ""))]
5627 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5628 || GET_CODE (operands[1]) == CONST
5629 || GET_CODE (operands[1]) == LABEL_REF)"
5630 [(set (match_dup 0) (high:SI (match_dup 1)))
5632 (lo_sum:SI (match_dup 0) (match_dup 1)))]
5635 ;; LABEL_REFs are not modified by `legitimize_pic_address'
5636 ;; so do not recurse infinitely in the PIC case.
5638 [(set (match_operand:SI 0 "register_operand" "")
5639 (match_operand:SI 1 "immediate_operand" ""))]
5640 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5641 || GET_CODE (operands[1]) == CONST)"
5642 [(set (match_dup 0) (match_dup 1))]
5645 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
5648 ;; These split sne/seq insns. The forms of the resulting insns are
5649 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
5650 ;; Nothing will look at these in detail after splitting has occurred.
5652 ;; ??? v9 DImode versions are missing because addc and subc use %icc.
5655 [(set (match_operand:SI 0 "register_operand" "")
5656 (ne:SI (match_operand:SI 1 "register_operand" "")
5658 (clobber (reg:CC 100))]
5660 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5662 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
5666 [(set (match_operand:SI 0 "register_operand" "")
5667 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5669 (clobber (reg:CC 100))]
5671 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5673 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
5677 [(set (match_operand:SI 0 "register_operand" "")
5678 (eq:SI (match_operand:SI 1 "register_operand" "")
5680 (clobber (reg:CC 100))]
5682 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5684 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
5688 [(set (match_operand:SI 0 "register_operand" "")
5689 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5691 (clobber (reg:CC 100))]
5693 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5695 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
5699 [(set (match_operand:SI 0 "register_operand" "")
5700 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5702 (match_operand:SI 2 "register_operand" "")))
5703 (clobber (reg:CC 100))]
5705 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5707 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
5712 [(set (match_operand:SI 0 "register_operand" "")
5713 (minus:SI (match_operand:SI 2 "register_operand" "")
5714 (ne:SI (match_operand:SI 1 "register_operand" "")
5716 (clobber (reg:CC 100))]
5718 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5720 (set (match_dup 0) (minus:SI (match_dup 2)
5721 (ltu:SI (reg:CC 100) (const_int 0))))]
5725 [(set (match_operand:SI 0 "register_operand" "")
5726 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5728 (match_operand:SI 2 "register_operand" "")))
5729 (clobber (reg:CC 100))]
5731 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5733 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
5738 [(set (match_operand:SI 0 "register_operand" "")
5739 (minus:SI (match_operand:SI 2 "register_operand" "")
5740 (eq:SI (match_operand:SI 1 "register_operand" "")
5742 (clobber (reg:CC 100))]
5744 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5746 (set (match_dup 0) (minus:SI (match_dup 2)
5747 (geu:SI (reg:CC 100) (const_int 0))))]
5750 ;; Peepholes go at the end.
5752 ;; Optimize consecutive loads or stores into ldd and std when possible.
5753 ;; The conditions in which we do this are very restricted and are
5754 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
5757 [(set (match_operand:SI 0 "register_operand" "=rf")
5758 (match_operand:SI 1 "memory_operand" ""))
5759 (set (match_operand:SI 2 "register_operand" "=rf")
5760 (match_operand:SI 3 "memory_operand" ""))]
5762 && registers_ok_for_ldd_peep (operands[0], operands[2])
5763 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5764 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5768 [(set (match_operand:SI 0 "memory_operand" "")
5769 (match_operand:SI 1 "register_operand" "rf"))
5770 (set (match_operand:SI 2 "memory_operand" "")
5771 (match_operand:SI 3 "register_operand" "rf"))]
5773 && registers_ok_for_ldd_peep (operands[1], operands[3])
5774 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5775 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5779 [(set (match_operand:SF 0 "register_operand" "=fr")
5780 (match_operand:SF 1 "memory_operand" ""))
5781 (set (match_operand:SF 2 "register_operand" "=fr")
5782 (match_operand:SF 3 "memory_operand" ""))]
5784 && registers_ok_for_ldd_peep (operands[0], operands[2])
5785 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5786 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5790 [(set (match_operand:SF 0 "memory_operand" "")
5791 (match_operand:SF 1 "register_operand" "fr"))
5792 (set (match_operand:SF 2 "memory_operand" "")
5793 (match_operand:SF 3 "register_operand" "fr"))]
5795 && registers_ok_for_ldd_peep (operands[1], operands[3])
5796 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5797 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5801 [(set (match_operand:SI 0 "register_operand" "=rf")
5802 (match_operand:SI 1 "memory_operand" ""))
5803 (set (match_operand:SI 2 "register_operand" "=rf")
5804 (match_operand:SI 3 "memory_operand" ""))]
5806 && registers_ok_for_ldd_peep (operands[2], operands[0])
5807 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5808 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5812 [(set (match_operand:SI 0 "memory_operand" "")
5813 (match_operand:SI 1 "register_operand" "rf"))
5814 (set (match_operand:SI 2 "memory_operand" "")
5815 (match_operand:SI 3 "register_operand" "rf"))]
5817 && registers_ok_for_ldd_peep (operands[3], operands[1])
5818 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5819 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5823 [(set (match_operand:SF 0 "register_operand" "=fr")
5824 (match_operand:SF 1 "memory_operand" ""))
5825 (set (match_operand:SF 2 "register_operand" "=fr")
5826 (match_operand:SF 3 "memory_operand" ""))]
5828 && registers_ok_for_ldd_peep (operands[2], operands[0])
5829 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5830 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5834 [(set (match_operand:SF 0 "memory_operand" "")
5835 (match_operand:SF 1 "register_operand" "fr"))
5836 (set (match_operand:SF 2 "memory_operand" "")
5837 (match_operand:SF 3 "register_operand" "fr"))]
5839 && registers_ok_for_ldd_peep (operands[3], operands[1])
5840 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5841 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5844 ;; Optimize the case of following a reg-reg move with a test
5845 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
5846 ;; This can result from a float to fix conversion.
5849 [(set (match_operand:SI 0 "register_operand" "=r")
5850 (match_operand:SI 1 "register_operand" "r"))
5852 (compare:CC (match_operand:SI 2 "register_operand" "r")
5854 "(rtx_equal_p (operands[2], operands[0])
5855 || rtx_equal_p (operands[2], operands[1]))
5856 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5860 [(set (match_operand:DI 0 "register_operand" "=r")
5861 (match_operand:DI 1 "register_operand" "r"))
5863 (compare:CCX (match_operand:DI 2 "register_operand" "r")
5866 && (rtx_equal_p (operands[2], operands[0])
5867 || rtx_equal_p (operands[2], operands[1]))
5868 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5871 ;; Do {sign,zero}-extended compares somewhat more efficiently.
5872 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
5873 ;; eventually have some impact here?
5876 [(set (match_operand:HI 0 "register_operand" "")
5877 (match_operand:HI 1 "memory_operand" ""))
5878 (set (match_operand:SI 2 "register_operand" "")
5879 (sign_extend:SI (match_dup 0)))
5881 (compare:CC (match_dup 2)
5884 "ldsh %1,%0\;orcc %0,0,%2")
5887 [(set (match_operand:HI 0 "register_operand" "")
5888 (match_operand:HI 1 "memory_operand" ""))
5889 (set (match_operand:DI 2 "register_operand" "")
5890 (sign_extend:DI (match_dup 0)))
5892 (compare:CCX (match_dup 2)
5895 "ldsh %1,%0\;orcc %0,0,%2")
5898 [(set (match_operand:QI 0 "register_operand" "")
5899 (match_operand:QI 1 "memory_operand" ""))
5900 (set (match_operand:SI 2 "register_operand" "")
5901 (sign_extend:SI (match_dup 0)))
5903 (compare:CC (match_dup 2)
5906 "ldsb %1,%0\;orcc %0,0,%2")
5909 [(set (match_operand:QI 0 "register_operand" "")
5910 (match_operand:QI 1 "memory_operand" ""))
5911 (set (match_operand:DI 2 "register_operand" "")
5912 (sign_extend:DI (match_dup 0)))
5914 (compare:CCX (match_dup 2)
5917 "ldsb %1,%0\;orcc %0,0,%2")
5919 ;; Floating-point move peepholes
5920 ;; ??? v9: Do we want similar ones?
5923 [(set (match_operand:SI 0 "register_operand" "=r")
5924 (lo_sum:SI (match_dup 0)
5925 (match_operand:SI 1 "immediate_operand" "i")))
5926 (set (match_operand:DF 2 "register_operand" "=er")
5927 (mem:DF (match_dup 0)))]
5928 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5931 /* Go by way of output_move_double in case the register in operand 2
5932 is not properly aligned for ldd. */
5933 operands[1] = gen_rtx (MEM, DFmode,
5934 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
5935 operands[0] = operands[2];
5936 return output_move_double (operands);
5940 [(set (match_operand:SI 0 "register_operand" "=r")
5941 (lo_sum:SI (match_dup 0)
5942 (match_operand:SI 1 "immediate_operand" "i")))
5943 (set (match_operand:SF 2 "register_operand" "=fr")
5944 (mem:SF (match_dup 0)))]
5945 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5946 "ld [%0+%%lo(%a1)],%2")
5948 ;; Return peepholes. First the "normal" ones.
5949 ;; These are necessary to catch insns ending up in the epilogue delay list.
5951 (define_insn "*return_qi"
5952 [(set (match_operand:QI 0 "restore_operand" "")
5953 (match_operand:QI 1 "arith_operand" "rI"))
5955 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
5958 if (! TARGET_ARCH64 && current_function_returns_struct)
5959 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5961 return \"ret\;restore %%g0,%1,%Y0\";
5963 [(set_attr "type" "multi")])
5965 (define_insn "*return_hi"
5966 [(set (match_operand:HI 0 "restore_operand" "")
5967 (match_operand:HI 1 "arith_operand" "rI"))
5969 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
5972 if (! TARGET_ARCH64 && current_function_returns_struct)
5973 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5975 return \"ret\;restore %%g0,%1,%Y0\";
5977 [(set_attr "type" "multi")])
5979 (define_insn "*return_si"
5980 [(set (match_operand:SI 0 "restore_operand" "")
5981 (match_operand:SI 1 "arith_operand" "rI"))
5983 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
5986 if (! TARGET_ARCH64 && current_function_returns_struct)
5987 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5989 return \"ret\;restore %%g0,%1,%Y0\";
5991 [(set_attr "type" "multi")])
5993 ;; The following pattern is only generated by delayed-branch scheduling,
5994 ;; when the insn winds up in the epilogue. This can only happen when
5995 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
5996 (define_insn "*return_sf_no_fpu"
5997 [(set (match_operand:SF 0 "restore_operand" "r")
5998 (match_operand:SF 1 "register_operand" "r"))
6000 "! TARGET_FPU && ! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
6003 if (! TARGET_ARCH64 && current_function_returns_struct)
6004 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
6006 return \"ret\;restore %%g0,%1,%Y0\";
6008 [(set_attr "type" "multi")])
6010 (define_insn "*return_addsi"
6011 [(set (match_operand:SI 0 "restore_operand" "")
6012 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
6013 (match_operand:SI 2 "arith_operand" "rI")))
6015 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0
6016 && (register_operand (operands[1], SImode)
6017 || register_operand (operands[2], SImode))"
6020 if (! TARGET_ARCH64 && current_function_returns_struct)
6021 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
6023 return \"ret\;restore %r1,%2,%Y0\";
6025 [(set_attr "type" "multi")])
6027 (define_insn "*return_di"
6028 [(set (match_operand:DI 0 "restore_operand" "")
6029 (match_operand:DI 1 "arith_double_operand" "rHI"))
6031 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
6032 "ret\;restore %%g0,%1,%Y0"
6033 [(set_attr "type" "multi")])
6035 (define_insn "*return_adddi"
6036 [(set (match_operand:DI 0 "restore_operand" "")
6037 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
6038 (match_operand:DI 2 "arith_double_operand" "rHI")))
6040 "TARGET_ARCH64 && ! TARGET_EPILOGUE
6041 && (register_operand (operands[1], DImode)
6042 || register_operand (operands[2], DImode))"
6043 "ret\;restore %r1,%2,%Y0"
6044 [(set_attr "type" "multi")])
6046 (define_insn "*return_subsi"
6047 [(set (match_operand:SI 0 "restore_operand" "")
6048 (minus:SI (match_operand:SI 1 "register_operand" "r")
6049 (match_operand:SI 2 "small_int" "I")))
6051 "! TARGET_EPILOGUE && INTVAL (operands[2]) != -4096"
6052 "ret\;restore %1,%n2,%Y0"
6053 [(set_attr "type" "multi")])
6055 ;; The following pattern is only generated by delayed-branch scheduling,
6056 ;; when the insn winds up in the epilogue.
6057 (define_insn "*return_sf"
6059 (match_operand:SF 0 "register_operand" "f"))
6062 "ret\;fmovs %0,%%f0"
6063 [(set_attr "type" "multi")])
6065 ;; Now peepholes to do a call followed by a jump.
6068 [(parallel [(set (match_operand 0 "" "")
6069 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
6070 (match_operand 2 "" "")))
6071 (clobber (reg:SI 15))])
6072 (set (pc) (label_ref (match_operand 3 "" "")))]
6073 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
6074 "call %a1,%2\;add %%o7,(%l3-.-4),%%o7")
6077 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
6078 (match_operand 1 "" ""))
6079 (clobber (reg:SI 15))])
6080 (set (pc) (label_ref (match_operand 2 "" "")))]
6081 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
6084 return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
6088 [(parallel [(set (match_operand 0 "" "")
6089 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
6090 (match_operand 2 "" "")))
6091 (clobber (reg:DI 15))])
6092 (set (pc) (label_ref (match_operand 3 "" "")))]
6093 "TARGET_ARCH64 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
6094 "call %a1,%2\;add %%o7,(%l3-.-4),%%o7")
6097 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
6098 (match_operand 1 "" ""))
6099 (clobber (reg:DI 15))])
6100 (set (pc) (label_ref (match_operand 2 "" "")))]
6101 "TARGET_ARCH64 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
6102 "call %a0,%1\;add %%o7,(%l2-.-4),%%o7")
6104 ;; Other miscellaneous peepholes.
6106 ;; (reg:SI 100) is created by the {add,neg,sub}di patterns.
6108 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
6109 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6111 (clobber (reg:CC 100))])
6112 (set (reg:CC 100) (compare (match_dup 0) (const_int 0)))]