]>
Commit | Line | Data |
---|---|---|
3276910d | 1 | ;- Machine description for SPARC chip for GNU C compiler |
4592bdcb | 2 | ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
3276910d | 3 | ;; 1999, 2000, 2001 Free Software Foundation, Inc. |
8dffbc60 RK |
4 | ;; Contributed by Michael Tiemann (tiemann@cygnus.com) |
5 | ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, | |
6 | ;; at Cygnus Support. | |
7a768814 RS |
7 | |
8 | ;; This file is part of GNU CC. | |
9 | ||
10 | ;; GNU CC is free software; you can redistribute it and/or modify | |
11 | ;; it under the terms of the GNU General Public License as published by | |
12 | ;; the Free Software Foundation; either version 2, or (at your option) | |
13 | ;; any later version. | |
14 | ||
15 | ;; GNU CC is distributed in the hope that it will be useful, | |
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ;; GNU General Public License for more details. | |
19 | ||
20 | ;; You should have received a copy of the GNU General Public License | |
21 | ;; along with GNU CC; see the file COPYING. If not, write to | |
3f63df56 RK |
22 | ;; the Free Software Foundation, 59 Temple Place - Suite 330, |
23 | ;; Boston, MA 02111-1307, USA. | |
7a768814 | 24 | |
7a768814 RS |
25 | ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. |
26 | ||
e0d80184 DM |
27 | ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file: |
28 | ;; | |
29 | ;; UNSPEC: 0 movsi_{lo_sum,high}_pic | |
30 | ;; pic_lo_sum_di | |
31 | ;; pic_sethi_di | |
32 | ;; 1 update_return | |
33 | ;; 2 get_pc | |
34 | ;; 5 movsi_{,lo_sum_,high_}pic_label_ref | |
35 | ;; 6 seth44 | |
36 | ;; 7 setm44 | |
37 | ;; 8 setl44 | |
38 | ;; 9 sethh | |
39 | ;; 10 setlm | |
40 | ;; 11 embmedany_sethi, embmedany_brsum | |
41 | ;; 13 embmedany_textuhi | |
42 | ;; 14 embmedany_texthi | |
43 | ;; 15 embmedany_textulo | |
44 | ;; 16 embmedany_textlo | |
45 | ;; 18 sethm | |
46 | ;; 19 setlo | |
47 | ;; | |
48 | ;; UNSPEC_VOLATILE: 0 blockage | |
49 | ;; 1 flush_register_windows | |
50 | ;; 2 goto_handler_and_restore | |
51 | ;; 3 goto_handler_and_restore_v9* | |
52 | ;; 4 flush | |
f36d6244 | 53 | ;; 5 do_builtin_setjmp_setup |
e0d80184 DM |
54 | ;; |
55 | ||
b6d3c4ba JW |
56 | ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this |
57 | ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name | |
58 | ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding | |
59 | ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of | |
60 | ;; 'f' for all DF/TFmode values, including those that are specific to the v8. | |
61 | ||
0f1f080e | 62 | ;; Attribute for cpu type. |
6cab8731 | 63 | ;; These must match the values for enum processor_type in sparc.h. |
8947065c | 64 | (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc" |
6cab8731 | 65 | (const (symbol_ref "sparc_cpu_attr"))) |
0f1f080e | 66 | |
eb582c5d DE |
67 | ;; Attribute for the instruction set. |
68 | ;; At present we only need to distinguish v9/!v9, but for clarity we | |
69 | ;; test TARGET_V8 too. | |
6d29fc41 | 70 | (define_attr "isa" "v6,v8,v9,sparclet" |
eb582c5d DE |
71 | (const |
72 | (cond [(symbol_ref "TARGET_V9") (const_string "v9") | |
6d29fc41 DE |
73 | (symbol_ref "TARGET_V8") (const_string "v8") |
74 | (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")] | |
eb582c5d DE |
75 | (const_string "v6")))) |
76 | ||
77 | ;; Architecture size. | |
c180bd1e | 78 | (define_attr "arch" "arch32bit,arch64bit" |
eb582c5d DE |
79 | (const |
80 | (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")] | |
81 | (const_string "arch32bit")))) | |
c180bd1e | 82 | |
7a768814 RS |
83 | ;; Insn type. Used to default other attribute values. |
84 | ||
85 | ;; type "unary" insns have one input operand (1) and one output operand (0) | |
86 | ;; type "binary" insns have two input operands (1,2) and one output (0) | |
87 | ;; type "compare" insns have one or two input operands (0,1) and no output | |
88 | ;; type "call_no_delay_slot" is a call followed by an unimp instruction. | |
89 | ||
90 | (define_attr "type" | |
7d167afd | 91 | "move,unary,binary,compare,load,sload,store,ialu,shift,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,address,imul,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc" |
7a768814 RS |
92 | (const_string "binary")) |
93 | ||
94 | ;; Set true if insn uses call-clobbered intermediate register. | |
95 | (define_attr "use_clobbered" "false,true" | |
96 | (if_then_else (and (eq_attr "type" "address") | |
97 | (match_operand 0 "clobbered_register" "")) | |
98 | (const_string "true") | |
99 | (const_string "false"))) | |
100 | ||
101 | ;; Length (in # of insns). | |
102 | (define_attr "length" "" | |
bfd6bc60 | 103 | (cond [(eq_attr "type" "load,sload,fpload") |
7a768814 RS |
104 | (if_then_else (match_operand 1 "symbolic_memory_operand" "") |
105 | (const_int 2) (const_int 1)) | |
106 | ||
107 | (eq_attr "type" "store,fpstore") | |
108 | (if_then_else (match_operand 0 "symbolic_memory_operand" "") | |
109 | (const_int 2) (const_int 1)) | |
110 | ||
111 | (eq_attr "type" "address") (const_int 2) | |
112 | ||
113 | (eq_attr "type" "binary") | |
114 | (if_then_else (ior (match_operand 2 "arith_operand" "") | |
115 | (match_operand 2 "arith_double_operand" "")) | |
116 | (const_int 1) (const_int 3)) | |
117 | ||
b4ac57ab RS |
118 | (eq_attr "type" "multi") (const_int 2) |
119 | ||
7a768814 RS |
120 | (eq_attr "type" "move,unary") |
121 | (if_then_else (ior (match_operand 1 "arith_operand" "") | |
122 | (match_operand 1 "arith_double_operand" "")) | |
123 | (const_int 1) (const_int 2))] | |
124 | ||
125 | (const_int 1))) | |
126 | ||
127 | (define_asm_attributes | |
128 | [(set_attr "length" "1") | |
129 | (set_attr "type" "multi")]) | |
130 | ||
131 | ;; Attributes for instruction and branch scheduling | |
132 | ||
133 | (define_attr "in_call_delay" "false,true" | |
7d167afd | 134 | (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi") |
7a768814 RS |
135 | (const_string "false") |
136 | (eq_attr "type" "load,fpload,store,fpstore") | |
137 | (if_then_else (eq_attr "length" "1") | |
138 | (const_string "true") | |
139 | (const_string "false")) | |
140 | (eq_attr "type" "address") | |
141 | (if_then_else (eq_attr "use_clobbered" "false") | |
142 | (const_string "true") | |
143 | (const_string "false"))] | |
144 | (if_then_else (eq_attr "length" "1") | |
145 | (const_string "true") | |
146 | (const_string "false")))) | |
147 | ||
148 | (define_delay (eq_attr "type" "call") | |
149 | [(eq_attr "in_call_delay" "true") (nil) (nil)]) | |
150 | ||
7d167afd | 151 | (define_attr "eligible_for_sibcall_delay" "false,true" |
3276910d | 152 | (symbol_ref "eligible_for_sibcall_delay (insn)")) |
7d167afd JJ |
153 | |
154 | (define_delay (eq_attr "type" "sibcall") | |
155 | [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)]) | |
156 | ||
284d86e9 | 157 | (define_attr "leaf_function" "false,true" |
54ff41b7 | 158 | (const (symbol_ref "current_function_uses_only_leaf_regs"))) |
284d86e9 | 159 | |
1c57c60c | 160 | (define_attr "eligible_for_return_delay" "false,true" |
3276910d | 161 | (symbol_ref "eligible_for_return_delay (insn)")) |
1c57c60c | 162 | |
284d86e9 JC |
163 | (define_attr "in_return_delay" "false,true" |
164 | (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu") | |
165 | (eq_attr "length" "1")) | |
166 | (eq_attr "leaf_function" "false")) | |
1c57c60c | 167 | (eq_attr "eligible_for_return_delay" "false")) |
284d86e9 JC |
168 | (const_string "true") |
169 | (const_string "false"))) | |
170 | ||
171 | (define_delay (and (eq_attr "type" "return") | |
172 | (eq_attr "isa" "v9")) | |
173 | [(eq_attr "in_return_delay" "true") (nil) (nil)]) | |
174 | ||
7a768814 RS |
175 | ;; ??? Should implement the notion of predelay slots for floating point |
176 | ;; branches. This would allow us to remove the nop always inserted before | |
177 | ;; a floating point branch. | |
178 | ||
cab55461 JW |
179 | ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions |
180 | ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so. | |
181 | ;; This is because doing so will add several pipeline stalls to the path | |
182 | ;; that the load/store did not come from. Unfortunately, there is no way | |
183 | ;; to prevent fill_eager_delay_slots from using load/store without completely | |
184 | ;; disabling them. For the SPEC benchmark set, this is a serious lose, | |
185 | ;; because it prevents us from moving back the final store of inner loops. | |
e8d6096c | 186 | |
7a768814 | 187 | (define_attr "in_branch_delay" "false,true" |
7d167afd | 188 | (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi") |
e8d6096c JL |
189 | (eq_attr "length" "1")) |
190 | (const_string "true") | |
191 | (const_string "false"))) | |
192 | ||
193 | (define_attr "in_uncond_branch_delay" "false,true" | |
7d167afd | 194 | (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi") |
e8d6096c JL |
195 | (eq_attr "length" "1")) |
196 | (const_string "true") | |
197 | (const_string "false"))) | |
198 | ||
199 | (define_attr "in_annul_branch_delay" "false,true" | |
7d167afd | 200 | (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi") |
7a768814 RS |
201 | (eq_attr "length" "1")) |
202 | (const_string "true") | |
203 | (const_string "false"))) | |
204 | ||
205 | (define_delay (eq_attr "type" "branch") | |
206 | [(eq_attr "in_branch_delay" "true") | |
e8d6096c | 207 | (nil) (eq_attr "in_annul_branch_delay" "true")]) |
7a768814 | 208 | |
e8d6096c JL |
209 | (define_delay (eq_attr "type" "uncond_branch") |
210 | [(eq_attr "in_uncond_branch_delay" "true") | |
211 | (nil) (nil)]) | |
212 | ||
7a768814 RS |
213 | ;; Function units of the SPARC |
214 | ||
215 | ;; (define_function_unit {name} {num-units} {n-users} {test} | |
af93f7bf | 216 | ;; {ready-delay} {issue-delay} [{conflict-list}]) |
7a768814 RS |
217 | |
218 | ;; The integer ALU. | |
219 | ;; (Noted only for documentation; units that take one cycle do not need to | |
220 | ;; be specified.) | |
221 | ||
114b9aa4 JW |
222 | ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on |
223 | ;; the inputs. | |
224 | ||
7a768814 RS |
225 | ;; (define_function_unit "alu" 1 0 |
226 | ;; (eq_attr "type" "unary,binary,move,address") 1 0) | |
227 | ||
c180bd1e | 228 | ;; ---- cypress CY7C602 scheduling: |
7a768814 | 229 | ;; Memory with load-delay of 1 (i.e., 2 cycle load). |
bfd6bc60 | 230 | |
c180bd1e | 231 | (define_function_unit "memory" 1 0 |
bfd6bc60 JC |
232 | (and (eq_attr "cpu" "cypress") |
233 | (eq_attr "type" "load,sload,fpload")) | |
234 | 2 2) | |
7a768814 RS |
235 | |
236 | ;; SPARC has two floating-point units: the FP ALU, | |
237 | ;; and the FP MUL/DIV/SQRT unit. | |
238 | ;; Instruction timings on the CY7C602 are as follows | |
239 | ;; FABSs 4 | |
240 | ;; FADDs/d 5/5 | |
241 | ;; FCMPs/d 4/4 | |
242 | ;; FDIVs/d 23/37 | |
243 | ;; FMOVs 4 | |
244 | ;; FMULs/d 5/7 | |
245 | ;; FNEGs 4 | |
246 | ;; FSQRTs/d 34/63 | |
247 | ;; FSUBs/d 5/5 | |
248 | ;; FdTOi/s 5/5 | |
249 | ;; FsTOi/d 5/5 | |
250 | ;; FiTOs/d 9/5 | |
251 | ||
252 | ;; The CY7C602 can only support 2 fp isnsn simultaneously. | |
ead69aea JW |
253 | ;; More insns cause the chip to stall. |
254 | ||
c180bd1e | 255 | (define_function_unit "fp_alu" 1 0 |
bfd6bc60 JC |
256 | (and (eq_attr "cpu" "cypress") |
257 | (eq_attr "type" "fp,fpmove")) | |
258 | 5 5) | |
259 | ||
c180bd1e | 260 | (define_function_unit "fp_mds" 1 0 |
bfd6bc60 JC |
261 | (and (eq_attr "cpu" "cypress") |
262 | (eq_attr "type" "fpmul")) | |
263 | 7 7) | |
264 | ||
c180bd1e | 265 | (define_function_unit "fp_mds" 1 0 |
bfd6bc60 JC |
266 | (and (eq_attr "cpu" "cypress") |
267 | (eq_attr "type" "fpdivs,fpdivd")) | |
268 | 37 37) | |
269 | ||
c180bd1e | 270 | (define_function_unit "fp_mds" 1 0 |
bfd6bc60 | 271 | (and (eq_attr "cpu" "cypress") |
c0ec7a75 | 272 | (eq_attr "type" "fpsqrts,fpsqrtd")) |
bfd6bc60 | 273 | 63 63) |
c180bd1e JW |
274 | |
275 | ;; ----- The TMS390Z55 scheduling | |
bfd6bc60 JC |
276 | ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer, |
277 | ;; one ld/st, one fp. | |
c180bd1e | 278 | ;; Memory delivers its result in one cycle to IU, zero cycles to FP |
bfd6bc60 | 279 | |
c180bd1e | 280 | (define_function_unit "memory" 1 0 |
bfd6bc60 JC |
281 | (and (eq_attr "cpu" "supersparc") |
282 | (eq_attr "type" "load,sload")) | |
283 | 1 1) | |
284 | ||
c180bd1e | 285 | (define_function_unit "memory" 1 0 |
bfd6bc60 JC |
286 | (and (eq_attr "cpu" "supersparc") |
287 | (eq_attr "type" "fpload")) | |
288 | 0 1) | |
289 | ||
c180bd1e | 290 | (define_function_unit "memory" 1 0 |
bfd6bc60 JC |
291 | (and (eq_attr "cpu" "supersparc") |
292 | (eq_attr "type" "store,fpstore")) | |
293 | 1 1) | |
294 | ||
c180bd1e | 295 | (define_function_unit "shift" 1 0 |
bfd6bc60 JC |
296 | (and (eq_attr "cpu" "supersparc") |
297 | (eq_attr "type" "shift")) | |
298 | 1 1) | |
c180bd1e JW |
299 | |
300 | ;; There are only two write ports to the integer register file | |
301 | ;; A store also uses a write port | |
bfd6bc60 | 302 | |
c180bd1e | 303 | (define_function_unit "iwport" 2 0 |
bfd6bc60 JC |
304 | (and (eq_attr "cpu" "supersparc") |
305 | (eq_attr "type" "load,sload,store,shift,ialu")) | |
306 | 1 1) | |
c180bd1e JW |
307 | |
308 | ;; Timings; throughput/latency | |
309 | ;; FADD 1/3 add/sub, format conv, compar, abs, neg | |
310 | ;; FMUL 1/3 | |
311 | ;; FDIVs 4/6 | |
312 | ;; FDIVd 7/9 | |
313 | ;; FSQRTs 6/8 | |
314 | ;; FSQRTd 10/12 | |
315 | ;; IMUL 4/4 | |
316 | ||
317 | (define_function_unit "fp_alu" 1 0 | |
bfd6bc60 JC |
318 | (and (eq_attr "cpu" "supersparc") |
319 | (eq_attr "type" "fp,fpmove,fpcmp")) | |
320 | 3 1) | |
321 | ||
c180bd1e | 322 | (define_function_unit "fp_mds" 1 0 |
bfd6bc60 JC |
323 | (and (eq_attr "cpu" "supersparc") |
324 | (eq_attr "type" "fpmul")) | |
325 | 3 1) | |
326 | ||
c180bd1e | 327 | (define_function_unit "fp_mds" 1 0 |
bfd6bc60 JC |
328 | (and (eq_attr "cpu" "supersparc") |
329 | (eq_attr "type" "fpdivs")) | |
330 | 6 4) | |
331 | ||
c180bd1e | 332 | (define_function_unit "fp_mds" 1 0 |
bfd6bc60 JC |
333 | (and (eq_attr "cpu" "supersparc") |
334 | (eq_attr "type" "fpdivd")) | |
335 | 9 7) | |
336 | ||
c180bd1e | 337 | (define_function_unit "fp_mds" 1 0 |
bfd6bc60 | 338 | (and (eq_attr "cpu" "supersparc") |
c0ec7a75 | 339 | (eq_attr "type" "fpsqrts,fpsqrtd")) |
bfd6bc60 JC |
340 | 12 10) |
341 | ||
c180bd1e | 342 | (define_function_unit "fp_mds" 1 0 |
bfd6bc60 JC |
343 | (and (eq_attr "cpu" "supersparc") |
344 | (eq_attr "type" "imul")) | |
345 | 4 4) | |
967ba98d | 346 | |
8947065c RH |
347 | ;; ----- hypersparc/sparclite86x scheduling |
348 | ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are: | |
349 | ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB | |
350 | ;; II/FF case is only when loading a 32 bit hi/lo constant | |
351 | ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp | |
352 | ;; Memory delivers its result in one cycle to IU | |
353 | ||
354 | (define_function_unit "memory" 1 0 | |
355 | (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) | |
356 | (eq_attr "type" "load,sload,fpload")) | |
357 | 1 1) | |
358 | ||
359 | (define_function_unit "memory" 1 0 | |
360 | (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) | |
361 | (eq_attr "type" "store,fpstore")) | |
362 | 2 1) | |
363 | ||
c219ddf7 BK |
364 | (define_function_unit "sparclite86x_branch" 1 0 |
365 | (and (eq_attr "cpu" "sparclite86x") | |
366 | (eq_attr "type" "branch")) | |
367 | 1 1) | |
368 | ||
369 | ;; integer multiply insns | |
370 | (define_function_unit "sparclite86x_shift" 1 0 | |
371 | (and (eq_attr "cpu" "sparclite86x") | |
372 | (eq_attr "type" "shift")) | |
373 | 1 1) | |
374 | ||
8947065c RH |
375 | (define_function_unit "fp_alu" 1 0 |
376 | (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) | |
377 | (eq_attr "type" "fp,fpmove,fpcmp")) | |
378 | 1 1) | |
379 | ||
380 | (define_function_unit "fp_mds" 1 0 | |
381 | (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) | |
382 | (eq_attr "type" "fpmul")) | |
383 | 1 1) | |
384 | ||
385 | (define_function_unit "fp_mds" 1 0 | |
386 | (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) | |
387 | (eq_attr "type" "fpdivs")) | |
388 | 8 6) | |
389 | ||
390 | (define_function_unit "fp_mds" 1 0 | |
391 | (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) | |
392 | (eq_attr "type" "fpdivd")) | |
393 | 12 10) | |
394 | ||
395 | (define_function_unit "fp_mds" 1 0 | |
396 | (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) | |
c0ec7a75 | 397 | (eq_attr "type" "fpsqrts,fpsqrtd")) |
8947065c RH |
398 | 17 15) |
399 | ||
400 | (define_function_unit "fp_mds" 1 0 | |
401 | (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) | |
402 | (eq_attr "type" "imul")) | |
403 | 17 15) | |
404 | ||
3f79ef9b DE |
405 | ;; ----- sparclet tsc701 scheduling |
406 | ;; The tsc701 issues 1 insn per cycle. | |
967ba98d DE |
407 | ;; Results may be written back out of order. |
408 | ||
409 | ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time. | |
bfd6bc60 | 410 | |
3f79ef9b | 411 | (define_function_unit "tsc701_load" 4 1 |
bfd6bc60 JC |
412 | (and (eq_attr "cpu" "tsc701") |
413 | (eq_attr "type" "load,sload")) | |
414 | 3 1) | |
415 | ||
967ba98d DE |
416 | ;; Stores take 2(?) extra cycles to complete. |
417 | ;; It is desirable to not have any memory operation in the following 2 cycles. | |
418 | ;; (??? or 2 memory ops in the case of std). | |
bfd6bc60 | 419 | |
3f79ef9b | 420 | (define_function_unit "tsc701_store" 1 0 |
bfd6bc60 JC |
421 | (and (eq_attr "cpu" "tsc701") |
422 | (eq_attr "type" "store")) | |
423 | 3 3 | |
424 | [(eq_attr "type" "load,sload,store")]) | |
425 | ||
967ba98d | 426 | ;; The multiply unit has a latency of 5. |
3f79ef9b | 427 | (define_function_unit "tsc701_mul" 1 0 |
bfd6bc60 JC |
428 | (and (eq_attr "cpu" "tsc701") |
429 | (eq_attr "type" "imul")) | |
430 | 5 5) | |
770a0113 CK |
431 | |
432 | ;; ----- The UltraSPARC-1 scheduling | |
bfd6bc60 JC |
433 | ;; UltraSPARC has two integer units. Shift instructions can only execute |
434 | ;; on IE0. Condition code setting instructions, call, and jmpl (including | |
435 | ;; the ret and retl pseudo-instructions) can only execute on IE1. | |
436 | ;; Branch on register uses IE1, but branch on condition code does not. | |
437 | ;; Conditional moves take 2 cycles. No other instruction can issue in the | |
438 | ;; same cycle as a conditional move. | |
439 | ;; Multiply and divide take many cycles during which no other instructions | |
440 | ;; can issue. | |
441 | ;; Memory delivers its result in two cycles (except for signed loads, | |
442 | ;; which take one cycle more). One memory instruction can be issued per | |
443 | ;; cycle. | |
770a0113 | 444 | |
770a0113 | 445 | (define_function_unit "memory" 1 0 |
bfd6bc60 JC |
446 | (and (eq_attr "cpu" "ultrasparc") |
447 | (eq_attr "type" "load,fpload")) | |
448 | 2 1) | |
449 | ||
770a0113 | 450 | (define_function_unit "memory" 1 0 |
bfd6bc60 JC |
451 | (and (eq_attr "cpu" "ultrasparc") |
452 | (eq_attr "type" "sload")) | |
453 | 3 1) | |
454 | ||
455 | (define_function_unit "memory" 1 0 | |
456 | (and (eq_attr "cpu" "ultrasparc") | |
457 | (eq_attr "type" "store,fpstore")) | |
458 | 1 1) | |
459 | ||
3bc8b61e | 460 | (define_function_unit "ieuN" 2 0 |
bfd6bc60 | 461 | (and (eq_attr "cpu" "ultrasparc") |
7d167afd | 462 | (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch")) |
bfd6bc60 JC |
463 | 1 1) |
464 | ||
e0d80184 | 465 | (define_function_unit "ieu0" 1 0 |
bfd6bc60 JC |
466 | (and (eq_attr "cpu" "ultrasparc") |
467 | (eq_attr "type" "shift")) | |
468 | 1 1) | |
469 | ||
e0d80184 | 470 | (define_function_unit "ieu0" 1 0 |
bfd6bc60 JC |
471 | (and (eq_attr "cpu" "ultrasparc") |
472 | (eq_attr "type" "cmove")) | |
473 | 2 1) | |
770a0113 | 474 | |
e0d80184 DM |
475 | (define_function_unit "ieu1" 1 0 |
476 | (and (eq_attr "cpu" "ultrasparc") | |
7d167afd | 477 | (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch")) |
3bc8b61e DM |
478 | 1 1) |
479 | ||
480 | (define_function_unit "cti" 1 0 | |
481 | (and (eq_attr "cpu" "ultrasparc") | |
482 | (eq_attr "type" "branch")) | |
e0d80184 DM |
483 | 1 1) |
484 | ||
770a0113 | 485 | ;; Timings; throughput/latency |
284d86e9 JC |
486 | ;; FMOV 1/1 fmov, fabs, fneg |
487 | ;; FMOVcc 1/2 | |
c0ec7a75 DM |
488 | ;; FADD 1/3 add/sub, format conv, compar |
489 | ;; FMUL 1/3 | |
284d86e9 JC |
490 | ;; FDIVs 12/12 |
491 | ;; FDIVd 22/22 | |
492 | ;; FSQRTs 12/12 | |
493 | ;; FSQRTd 22/22 | |
494 | ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move. | |
e0d80184 | 495 | ;; |
c0ec7a75 DM |
496 | ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only |
497 | ;; use the FPM multiplier for final rounding 3 cycles before the | |
498 | ;; end of their latency and we have no real way to model that. | |
499 | ;; | |
e0d80184 DM |
500 | ;; ??? This is really bogus because the timings really depend upon |
501 | ;; who uses the result. We should record who the user is with | |
502 | ;; more descriptive 'type' attribute names and account for these | |
503 | ;; issues in ultrasparc_adjust_cost. | |
770a0113 | 504 | |
bfd6bc60 JC |
505 | (define_function_unit "fadd" 1 0 |
506 | (and (eq_attr "cpu" "ultrasparc") | |
507 | (eq_attr "type" "fpmove")) | |
508 | 1 1) | |
509 | ||
510 | (define_function_unit "fadd" 1 0 | |
511 | (and (eq_attr "cpu" "ultrasparc") | |
512 | (eq_attr "type" "fpcmove")) | |
513 | 2 1) | |
514 | ||
515 | (define_function_unit "fadd" 1 0 | |
516 | (and (eq_attr "cpu" "ultrasparc") | |
517 | (eq_attr "type" "fp")) | |
c0ec7a75 | 518 | 3 1) |
bfd6bc60 JC |
519 | |
520 | (define_function_unit "fadd" 1 0 | |
521 | (and (eq_attr "cpu" "ultrasparc") | |
522 | (eq_attr "type" "fpcmp")) | |
523 | 2 1) | |
524 | ||
525 | (define_function_unit "fmul" 1 0 | |
526 | (and (eq_attr "cpu" "ultrasparc") | |
527 | (eq_attr "type" "fpmul")) | |
c0ec7a75 | 528 | 3 1) |
bfd6bc60 JC |
529 | |
530 | (define_function_unit "fadd" 1 0 | |
531 | (and (eq_attr "cpu" "ultrasparc") | |
532 | (eq_attr "type" "fpcmove")) | |
533 | 2 1) | |
534 | ||
c0ec7a75 | 535 | (define_function_unit "fdiv" 1 0 |
bfd6bc60 JC |
536 | (and (eq_attr "cpu" "ultrasparc") |
537 | (eq_attr "type" "fpdivs")) | |
538 | 12 12) | |
539 | ||
c0ec7a75 | 540 | (define_function_unit "fdiv" 1 0 |
bfd6bc60 JC |
541 | (and (eq_attr "cpu" "ultrasparc") |
542 | (eq_attr "type" "fpdivd")) | |
543 | 22 22) | |
544 | ||
c0ec7a75 | 545 | (define_function_unit "fdiv" 1 0 |
bfd6bc60 | 546 | (and (eq_attr "cpu" "ultrasparc") |
c0ec7a75 | 547 | (eq_attr "type" "fpsqrts")) |
bfd6bc60 | 548 | 12 12) |
c0ec7a75 DM |
549 | |
550 | (define_function_unit "fdiv" 1 0 | |
551 | (and (eq_attr "cpu" "ultrasparc") | |
552 | (eq_attr "type" "fpsqrtd")) | |
553 | 22 22) | |
7a768814 RS |
554 | \f |
555 | ;; Compare instructions. | |
556 | ;; This controls RTL generation and register allocation. | |
557 | ||
558 | ;; We generate RTL for comparisons and branches by having the cmpxx | |
559 | ;; patterns store away the operands. Then, the scc and bcc patterns | |
560 | ;; emit RTL for both the compare and the branch. | |
561 | ;; | |
562 | ;; We do this because we want to generate different code for an sne and | |
563 | ;; seq insn. In those cases, if the second operand of the compare is not | |
564 | ;; const0_rtx, we want to compute the xor of the two operands and test | |
565 | ;; it against zero. | |
566 | ;; | |
a8d2b752 | 567 | ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match |
7a768814 RS |
568 | ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc |
569 | ;; insns that actually require more than one machine instruction. | |
570 | ||
571 | ;; Put cmpsi first among compare insns so it matches two CONST_INT operands. | |
572 | ||
573 | (define_expand "cmpsi" | |
c4ce6853 | 574 | [(set (reg:CC 100) |
7a768814 RS |
575 | (compare:CC (match_operand:SI 0 "register_operand" "") |
576 | (match_operand:SI 1 "arith_operand" "")))] | |
577 | "" | |
578 | " | |
579 | { | |
580 | sparc_compare_op0 = operands[0]; | |
581 | sparc_compare_op1 = operands[1]; | |
582 | DONE; | |
583 | }") | |
584 | ||
a8d2b752 | 585 | (define_expand "cmpdi" |
c4ce6853 | 586 | [(set (reg:CCX 100) |
a8d2b752 DE |
587 | (compare:CCX (match_operand:DI 0 "register_operand" "") |
588 | (match_operand:DI 1 "arith_double_operand" "")))] | |
e0d80184 | 589 | "TARGET_ARCH64" |
a8d2b752 DE |
590 | " |
591 | { | |
592 | sparc_compare_op0 = operands[0]; | |
593 | sparc_compare_op1 = operands[1]; | |
594 | DONE; | |
595 | }") | |
596 | ||
7a768814 | 597 | (define_expand "cmpsf" |
c4ce6853 DE |
598 | ;; The 96 here isn't ever used by anyone. |
599 | [(set (reg:CCFP 96) | |
7a768814 RS |
600 | (compare:CCFP (match_operand:SF 0 "register_operand" "") |
601 | (match_operand:SF 1 "register_operand" "")))] | |
ab5519b7 | 602 | "TARGET_FPU" |
7a768814 RS |
603 | " |
604 | { | |
605 | sparc_compare_op0 = operands[0]; | |
606 | sparc_compare_op1 = operands[1]; | |
607 | DONE; | |
608 | }") | |
609 | ||
610 | (define_expand "cmpdf" | |
c4ce6853 DE |
611 | ;; The 96 here isn't ever used by anyone. |
612 | [(set (reg:CCFP 96) | |
7a768814 RS |
613 | (compare:CCFP (match_operand:DF 0 "register_operand" "") |
614 | (match_operand:DF 1 "register_operand" "")))] | |
ab5519b7 | 615 | "TARGET_FPU" |
7a768814 RS |
616 | " |
617 | { | |
618 | sparc_compare_op0 = operands[0]; | |
619 | sparc_compare_op1 = operands[1]; | |
620 | DONE; | |
621 | }") | |
622 | ||
795068a4 | 623 | (define_expand "cmptf" |
c4ce6853 DE |
624 | ;; The 96 here isn't ever used by anyone. |
625 | [(set (reg:CCFP 96) | |
795068a4 JW |
626 | (compare:CCFP (match_operand:TF 0 "register_operand" "") |
627 | (match_operand:TF 1 "register_operand" "")))] | |
5c5c34a4 | 628 | "TARGET_FPU" |
795068a4 JW |
629 | " |
630 | { | |
631 | sparc_compare_op0 = operands[0]; | |
632 | sparc_compare_op1 = operands[1]; | |
633 | DONE; | |
634 | }") | |
635 | ||
967ba98d DE |
636 | ;; Now the compare DEFINE_INSNs. |
637 | ||
2a01c939 | 638 | (define_insn "*cmpsi_insn" |
c4ce6853 | 639 | [(set (reg:CC 100) |
967ba98d DE |
640 | (compare:CC (match_operand:SI 0 "register_operand" "r") |
641 | (match_operand:SI 1 "arith_operand" "rI")))] | |
2a01c939 | 642 | "" |
e0d80184 | 643 | "cmp\\t%0, %1" |
967ba98d DE |
644 | [(set_attr "type" "compare")]) |
645 | ||
967ba98d | 646 | (define_insn "*cmpdi_sp64" |
c4ce6853 | 647 | [(set (reg:CCX 100) |
967ba98d DE |
648 | (compare:CCX (match_operand:DI 0 "register_operand" "r") |
649 | (match_operand:DI 1 "arith_double_operand" "rHI")))] | |
650 | "TARGET_ARCH64" | |
e0d80184 | 651 | "cmp\\t%0, %1" |
967ba98d DE |
652 | [(set_attr "type" "compare")]) |
653 | ||
c4ce6853 DE |
654 | (define_insn "*cmpsf_fpe" |
655 | [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") | |
967ba98d DE |
656 | (compare:CCFPE (match_operand:SF 1 "register_operand" "f") |
657 | (match_operand:SF 2 "register_operand" "f")))] | |
c4ce6853 DE |
658 | "TARGET_FPU" |
659 | "* | |
660 | { | |
661 | if (TARGET_V9) | |
e0d80184 DM |
662 | return \"fcmpes\\t%0, %1, %2\"; |
663 | return \"fcmpes\\t%1, %2\"; | |
c4ce6853 | 664 | }" |
967ba98d DE |
665 | [(set_attr "type" "fpcmp")]) |
666 | ||
c4ce6853 DE |
667 | (define_insn "*cmpdf_fpe" |
668 | [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") | |
967ba98d DE |
669 | (compare:CCFPE (match_operand:DF 1 "register_operand" "e") |
670 | (match_operand:DF 2 "register_operand" "e")))] | |
c4ce6853 DE |
671 | "TARGET_FPU" |
672 | "* | |
673 | { | |
674 | if (TARGET_V9) | |
e0d80184 DM |
675 | return \"fcmped\\t%0, %1, %2\"; |
676 | return \"fcmped\\t%1, %2\"; | |
c4ce6853 | 677 | }" |
967ba98d DE |
678 | [(set_attr "type" "fpcmp")]) |
679 | ||
c4ce6853 DE |
680 | (define_insn "*cmptf_fpe" |
681 | [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") | |
967ba98d DE |
682 | (compare:CCFPE (match_operand:TF 1 "register_operand" "e") |
683 | (match_operand:TF 2 "register_operand" "e")))] | |
c4ce6853 DE |
684 | "TARGET_FPU && TARGET_HARD_QUAD" |
685 | "* | |
686 | { | |
687 | if (TARGET_V9) | |
e0d80184 DM |
688 | return \"fcmpeq\\t%0, %1, %2\"; |
689 | return \"fcmpeq\\t%1, %2\"; | |
c4ce6853 | 690 | }" |
967ba98d DE |
691 | [(set_attr "type" "fpcmp")]) |
692 | ||
c4ce6853 DE |
693 | (define_insn "*cmpsf_fp" |
694 | [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c") | |
967ba98d DE |
695 | (compare:CCFP (match_operand:SF 1 "register_operand" "f") |
696 | (match_operand:SF 2 "register_operand" "f")))] | |
c4ce6853 DE |
697 | "TARGET_FPU" |
698 | "* | |
699 | { | |
700 | if (TARGET_V9) | |
e0d80184 DM |
701 | return \"fcmps\\t%0, %1, %2\"; |
702 | return \"fcmps\\t%1, %2\"; | |
c4ce6853 | 703 | }" |
967ba98d DE |
704 | [(set_attr "type" "fpcmp")]) |
705 | ||
c4ce6853 DE |
706 | (define_insn "*cmpdf_fp" |
707 | [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c") | |
967ba98d DE |
708 | (compare:CCFP (match_operand:DF 1 "register_operand" "e") |
709 | (match_operand:DF 2 "register_operand" "e")))] | |
c4ce6853 DE |
710 | "TARGET_FPU" |
711 | "* | |
712 | { | |
713 | if (TARGET_V9) | |
e0d80184 DM |
714 | return \"fcmpd\\t%0, %1, %2\"; |
715 | return \"fcmpd\\t%1, %2\"; | |
c4ce6853 | 716 | }" |
967ba98d DE |
717 | [(set_attr "type" "fpcmp")]) |
718 | ||
c4ce6853 DE |
719 | (define_insn "*cmptf_fp" |
720 | [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c") | |
967ba98d DE |
721 | (compare:CCFP (match_operand:TF 1 "register_operand" "e") |
722 | (match_operand:TF 2 "register_operand" "e")))] | |
c4ce6853 DE |
723 | "TARGET_FPU && TARGET_HARD_QUAD" |
724 | "* | |
725 | { | |
726 | if (TARGET_V9) | |
e0d80184 DM |
727 | return \"fcmpq\\t%0, %1, %2\"; |
728 | return \"fcmpq\\t%1, %2\"; | |
c4ce6853 | 729 | }" |
967ba98d DE |
730 | [(set_attr "type" "fpcmp")]) |
731 | \f | |
7a768814 | 732 | ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this |
a8d2b752 DE |
733 | ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use |
734 | ;; the same code as v8 (the addx/subx method has more applications). The | |
735 | ;; exception to this is "reg != 0" which can be done in one instruction on v9 | |
736 | ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do | |
737 | ;; branches. | |
738 | ||
739 | ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they | |
7a768814 RS |
740 | ;; generate addcc/subcc instructions. |
741 | ||
a8d2b752 DE |
742 | (define_expand "seqsi_special" |
743 | [(set (match_dup 3) | |
744 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
745 | (match_operand:SI 2 "register_operand" ""))) | |
7a768814 RS |
746 | (parallel [(set (match_operand:SI 0 "register_operand" "") |
747 | (eq:SI (match_dup 3) (const_int 0))) | |
c4ce6853 | 748 | (clobber (reg:CC 100))])] |
e6c1be7e | 749 | "" |
7a768814 RS |
750 | "{ operands[3] = gen_reg_rtx (SImode); }") |
751 | ||
a8d2b752 DE |
752 | (define_expand "seqdi_special" |
753 | [(set (match_dup 3) | |
754 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
755 | (match_operand:DI 2 "register_operand" ""))) | |
b0967cad DE |
756 | (set (match_operand:DI 0 "register_operand" "") |
757 | (eq:DI (match_dup 3) (const_int 0)))] | |
fa0f39e4 | 758 | "TARGET_ARCH64" |
a8d2b752 DE |
759 | "{ operands[3] = gen_reg_rtx (DImode); }") |
760 | ||
761 | (define_expand "snesi_special" | |
762 | [(set (match_dup 3) | |
763 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
764 | (match_operand:SI 2 "register_operand" ""))) | |
7a768814 RS |
765 | (parallel [(set (match_operand:SI 0 "register_operand" "") |
766 | (ne:SI (match_dup 3) (const_int 0))) | |
c4ce6853 | 767 | (clobber (reg:CC 100))])] |
e6c1be7e | 768 | "" |
7a768814 RS |
769 | "{ operands[3] = gen_reg_rtx (SImode); }") |
770 | ||
a8d2b752 DE |
771 | (define_expand "snedi_special" |
772 | [(set (match_dup 3) | |
773 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
774 | (match_operand:DI 2 "register_operand" ""))) | |
b0967cad DE |
775 | (set (match_operand:DI 0 "register_operand" "") |
776 | (ne:DI (match_dup 3) (const_int 0)))] | |
fa0f39e4 | 777 | "TARGET_ARCH64" |
a8d2b752 DE |
778 | "{ operands[3] = gen_reg_rtx (DImode); }") |
779 | ||
780 | (define_expand "seqdi_special_trunc" | |
781 | [(set (match_dup 3) | |
782 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
783 | (match_operand:DI 2 "register_operand" ""))) | |
b0967cad | 784 | (set (match_operand:SI 0 "register_operand" "") |
638e8b1f | 785 | (eq:SI (match_dup 3) (const_int 0)))] |
fa0f39e4 | 786 | "TARGET_ARCH64" |
a8d2b752 DE |
787 | "{ operands[3] = gen_reg_rtx (DImode); }") |
788 | ||
789 | (define_expand "snedi_special_trunc" | |
790 | [(set (match_dup 3) | |
791 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
792 | (match_operand:DI 2 "register_operand" ""))) | |
b0967cad | 793 | (set (match_operand:SI 0 "register_operand" "") |
638e8b1f | 794 | (ne:SI (match_dup 3) (const_int 0)))] |
fa0f39e4 | 795 | "TARGET_ARCH64" |
a8d2b752 DE |
796 | "{ operands[3] = gen_reg_rtx (DImode); }") |
797 | ||
798 | (define_expand "seqsi_special_extend" | |
44965bad | 799 | [(set (match_dup 3) |
a8d2b752 DE |
800 | (xor:SI (match_operand:SI 1 "register_operand" "") |
801 | (match_operand:SI 2 "register_operand" ""))) | |
802 | (parallel [(set (match_operand:DI 0 "register_operand" "") | |
638e8b1f | 803 | (eq:DI (match_dup 3) (const_int 0))) |
c4ce6853 | 804 | (clobber (reg:CC 100))])] |
fa0f39e4 | 805 | "TARGET_ARCH64" |
44965bad | 806 | "{ operands[3] = gen_reg_rtx (SImode); }") |
a8d2b752 DE |
807 | |
808 | (define_expand "snesi_special_extend" | |
44965bad | 809 | [(set (match_dup 3) |
a8d2b752 DE |
810 | (xor:SI (match_operand:SI 1 "register_operand" "") |
811 | (match_operand:SI 2 "register_operand" ""))) | |
812 | (parallel [(set (match_operand:DI 0 "register_operand" "") | |
638e8b1f | 813 | (ne:DI (match_dup 3) (const_int 0))) |
c4ce6853 | 814 | (clobber (reg:CC 100))])] |
fa0f39e4 | 815 | "TARGET_ARCH64" |
44965bad | 816 | "{ operands[3] = gen_reg_rtx (SImode); }") |
a8d2b752 DE |
817 | |
818 | ;; ??? v9: Operand 0 needs a mode, so SImode was chosen. | |
819 | ;; However, the code handles both SImode and DImode. | |
7a768814 | 820 | (define_expand "seq" |
a8d2b752 | 821 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 822 | (eq:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 823 | "" |
7a768814 | 824 | " |
387fd02d JW |
825 | { |
826 | if (GET_MODE (sparc_compare_op0) == SImode) | |
7a768814 | 827 | { |
a8d2b752 DE |
828 | rtx pat; |
829 | ||
830 | if (GET_MODE (operands[0]) == SImode) | |
831 | pat = gen_seqsi_special (operands[0], sparc_compare_op0, | |
832 | sparc_compare_op1); | |
fa0f39e4 | 833 | else if (! TARGET_ARCH64) |
a8d2b752 DE |
834 | FAIL; |
835 | else | |
836 | pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0, | |
837 | sparc_compare_op1); | |
838 | emit_insn (pat); | |
839 | DONE; | |
840 | } | |
841 | else if (GET_MODE (sparc_compare_op0) == DImode) | |
842 | { | |
843 | rtx pat; | |
844 | ||
fa0f39e4 DE |
845 | if (! TARGET_ARCH64) |
846 | FAIL; | |
847 | else if (GET_MODE (operands[0]) == SImode) | |
a8d2b752 DE |
848 | pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0, |
849 | sparc_compare_op1); | |
a8d2b752 DE |
850 | else |
851 | pat = gen_seqdi_special (operands[0], sparc_compare_op0, | |
852 | sparc_compare_op1); | |
853 | emit_insn (pat); | |
7a768814 RS |
854 | DONE; |
855 | } | |
5c5c34a4 | 856 | else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
857 | { |
858 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); | |
859 | emit_jump_insn (gen_sne (operands[0])); | |
860 | DONE; | |
861 | } | |
a8d2b752 DE |
862 | else if (TARGET_V9) |
863 | { | |
864 | if (gen_v9_scc (EQ, operands)) | |
865 | DONE; | |
866 | /* fall through */ | |
867 | } | |
e0d80184 | 868 | FAIL; |
7a768814 RS |
869 | }") |
870 | ||
a8d2b752 DE |
871 | ;; ??? v9: Operand 0 needs a mode, so SImode was chosen. |
872 | ;; However, the code handles both SImode and DImode. | |
7a768814 | 873 | (define_expand "sne" |
a8d2b752 | 874 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 875 | (ne:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 876 | "" |
7a768814 | 877 | " |
387fd02d JW |
878 | { |
879 | if (GET_MODE (sparc_compare_op0) == SImode) | |
7a768814 | 880 | { |
a8d2b752 DE |
881 | rtx pat; |
882 | ||
883 | if (GET_MODE (operands[0]) == SImode) | |
884 | pat = gen_snesi_special (operands[0], sparc_compare_op0, | |
885 | sparc_compare_op1); | |
fa0f39e4 | 886 | else if (! TARGET_ARCH64) |
a8d2b752 DE |
887 | FAIL; |
888 | else | |
889 | pat = gen_snesi_special_extend (operands[0], sparc_compare_op0, | |
890 | sparc_compare_op1); | |
891 | emit_insn (pat); | |
892 | DONE; | |
893 | } | |
894 | else if (GET_MODE (sparc_compare_op0) == DImode) | |
895 | { | |
896 | rtx pat; | |
897 | ||
fa0f39e4 DE |
898 | if (! TARGET_ARCH64) |
899 | FAIL; | |
900 | else if (GET_MODE (operands[0]) == SImode) | |
a8d2b752 DE |
901 | pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0, |
902 | sparc_compare_op1); | |
a8d2b752 DE |
903 | else |
904 | pat = gen_snedi_special (operands[0], sparc_compare_op0, | |
905 | sparc_compare_op1); | |
906 | emit_insn (pat); | |
7a768814 RS |
907 | DONE; |
908 | } | |
5c5c34a4 | 909 | else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
910 | { |
911 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE); | |
912 | emit_jump_insn (gen_sne (operands[0])); | |
913 | DONE; | |
914 | } | |
a8d2b752 DE |
915 | else if (TARGET_V9) |
916 | { | |
917 | if (gen_v9_scc (NE, operands)) | |
918 | DONE; | |
919 | /* fall through */ | |
920 | } | |
e0d80184 | 921 | FAIL; |
7a768814 RS |
922 | }") |
923 | ||
924 | (define_expand "sgt" | |
a8d2b752 | 925 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 926 | (gt:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 927 | "" |
7a768814 | 928 | " |
387fd02d | 929 | { |
5c5c34a4 | 930 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
931 | { |
932 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT); | |
933 | emit_jump_insn (gen_sne (operands[0])); | |
934 | DONE; | |
935 | } | |
936 | else if (TARGET_V9) | |
a8d2b752 DE |
937 | { |
938 | if (gen_v9_scc (GT, operands)) | |
939 | DONE; | |
940 | /* fall through */ | |
941 | } | |
e0d80184 | 942 | FAIL; |
387fd02d | 943 | }") |
7a768814 RS |
944 | |
945 | (define_expand "slt" | |
a8d2b752 | 946 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 947 | (lt:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 948 | "" |
7a768814 | 949 | " |
387fd02d | 950 | { |
5c5c34a4 | 951 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
952 | { |
953 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT); | |
954 | emit_jump_insn (gen_sne (operands[0])); | |
955 | DONE; | |
956 | } | |
957 | else if (TARGET_V9) | |
a8d2b752 DE |
958 | { |
959 | if (gen_v9_scc (LT, operands)) | |
960 | DONE; | |
961 | /* fall through */ | |
962 | } | |
e0d80184 | 963 | FAIL; |
387fd02d | 964 | }") |
7a768814 RS |
965 | |
966 | (define_expand "sge" | |
a8d2b752 | 967 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 968 | (ge:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 969 | "" |
7a768814 | 970 | " |
387fd02d | 971 | { |
5c5c34a4 | 972 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
973 | { |
974 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE); | |
975 | emit_jump_insn (gen_sne (operands[0])); | |
976 | DONE; | |
977 | } | |
978 | else if (TARGET_V9) | |
a8d2b752 DE |
979 | { |
980 | if (gen_v9_scc (GE, operands)) | |
981 | DONE; | |
982 | /* fall through */ | |
983 | } | |
e0d80184 | 984 | FAIL; |
387fd02d | 985 | }") |
7a768814 RS |
986 | |
987 | (define_expand "sle" | |
a8d2b752 | 988 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 989 | (le:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 990 | "" |
7a768814 | 991 | " |
387fd02d | 992 | { |
5c5c34a4 | 993 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
994 | { |
995 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE); | |
996 | emit_jump_insn (gen_sne (operands[0])); | |
997 | DONE; | |
998 | } | |
999 | else if (TARGET_V9) | |
a8d2b752 DE |
1000 | { |
1001 | if (gen_v9_scc (LE, operands)) | |
1002 | DONE; | |
1003 | /* fall through */ | |
1004 | } | |
e0d80184 | 1005 | FAIL; |
387fd02d | 1006 | }") |
7a768814 RS |
1007 | |
1008 | (define_expand "sgtu" | |
a8d2b752 | 1009 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 1010 | (gtu:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 1011 | "" |
7a768814 RS |
1012 | " |
1013 | { | |
a8d2b752 | 1014 | if (! TARGET_V9) |
7a768814 | 1015 | { |
e0d80184 | 1016 | rtx tem, pat; |
a8d2b752 DE |
1017 | |
1018 | /* We can do ltu easily, so if both operands are registers, swap them and | |
1019 | do a LTU. */ | |
1020 | if ((GET_CODE (sparc_compare_op0) == REG | |
1021 | || GET_CODE (sparc_compare_op0) == SUBREG) | |
1022 | && (GET_CODE (sparc_compare_op1) == REG | |
1023 | || GET_CODE (sparc_compare_op1) == SUBREG)) | |
1024 | { | |
1025 | tem = sparc_compare_op0; | |
1026 | sparc_compare_op0 = sparc_compare_op1; | |
1027 | sparc_compare_op1 = tem; | |
e0d80184 DM |
1028 | pat = gen_sltu (operands[0]); |
1029 | if (pat == NULL_RTX) | |
1030 | FAIL; | |
1031 | emit_insn (pat); | |
a8d2b752 DE |
1032 | DONE; |
1033 | } | |
7a768814 | 1034 | } |
a8d2b752 DE |
1035 | else |
1036 | { | |
1037 | if (gen_v9_scc (GTU, operands)) | |
1038 | DONE; | |
1039 | } | |
e0d80184 | 1040 | FAIL; |
7a768814 RS |
1041 | }") |
1042 | ||
1043 | (define_expand "sltu" | |
a8d2b752 | 1044 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 1045 | (ltu:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 1046 | "" |
7a768814 | 1047 | " |
a8d2b752 DE |
1048 | { |
1049 | if (TARGET_V9) | |
1050 | { | |
1051 | if (gen_v9_scc (LTU, operands)) | |
1052 | DONE; | |
1053 | } | |
45120407 | 1054 | operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); |
7a768814 RS |
1055 | }") |
1056 | ||
1057 | (define_expand "sgeu" | |
a8d2b752 | 1058 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 1059 | (geu:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 1060 | "" |
7a768814 | 1061 | " |
a8d2b752 DE |
1062 | { |
1063 | if (TARGET_V9) | |
1064 | { | |
1065 | if (gen_v9_scc (GEU, operands)) | |
1066 | DONE; | |
1067 | } | |
45120407 | 1068 | operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); |
7a768814 RS |
1069 | }") |
1070 | ||
1071 | (define_expand "sleu" | |
a8d2b752 | 1072 | [(set (match_operand:SI 0 "intreg_operand" "") |
7a768814 | 1073 | (leu:SI (match_dup 1) (const_int 0)))] |
e6c1be7e | 1074 | "" |
7a768814 RS |
1075 | " |
1076 | { | |
a8d2b752 | 1077 | if (! TARGET_V9) |
7a768814 | 1078 | { |
e0d80184 | 1079 | rtx tem, pat; |
a8d2b752 DE |
1080 | |
1081 | /* We can do geu easily, so if both operands are registers, swap them and | |
1082 | do a GEU. */ | |
1083 | if ((GET_CODE (sparc_compare_op0) == REG | |
1084 | || GET_CODE (sparc_compare_op0) == SUBREG) | |
1085 | && (GET_CODE (sparc_compare_op1) == REG | |
1086 | || GET_CODE (sparc_compare_op1) == SUBREG)) | |
1087 | { | |
1088 | tem = sparc_compare_op0; | |
1089 | sparc_compare_op0 = sparc_compare_op1; | |
1090 | sparc_compare_op1 = tem; | |
e0d80184 DM |
1091 | pat = gen_sgeu (operands[0]); |
1092 | if (pat == NULL_RTX) | |
1093 | FAIL; | |
1094 | emit_insn (pat); | |
a8d2b752 DE |
1095 | DONE; |
1096 | } | |
1097 | } | |
1098 | else | |
1099 | { | |
1100 | if (gen_v9_scc (LEU, operands)) | |
1101 | DONE; | |
7a768814 | 1102 | } |
e0d80184 | 1103 | FAIL; |
7a768814 RS |
1104 | }") |
1105 | ||
967ba98d | 1106 | ;; Now the DEFINE_INSNs for the scc cases. |
a8d2b752 | 1107 | |
7a768814 | 1108 | ;; The SEQ and SNE patterns are special because they can be done |
e0d80184 DM |
1109 | ;; without any branching and do not involve a COMPARE. We want |
1110 | ;; them to always use the splitz below so the results can be | |
1111 | ;; scheduled. | |
7a768814 | 1112 | |
c8b3b7d6 | 1113 | (define_insn "*snesi_zero" |
7a768814 | 1114 | [(set (match_operand:SI 0 "register_operand" "=r") |
a8d2b752 DE |
1115 | (ne:SI (match_operand:SI 1 "register_operand" "r") |
1116 | (const_int 0))) | |
c4ce6853 | 1117 | (clobber (reg:CC 100))] |
e6c1be7e | 1118 | "" |
e0d80184 DM |
1119 | "#" |
1120 | [(set_attr "length" "2")]) | |
1121 | ||
1122 | (define_split | |
1123 | [(set (match_operand:SI 0 "register_operand" "") | |
1124 | (ne:SI (match_operand:SI 1 "register_operand" "") | |
1125 | (const_int 0))) | |
1126 | (clobber (reg:CC 100))] | |
1127 | "" | |
1128 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) | |
1129 | (const_int 0))) | |
1130 | (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))] | |
1131 | "") | |
7a768814 | 1132 | |
c8b3b7d6 | 1133 | (define_insn "*neg_snesi_zero" |
7a768814 RS |
1134 | [(set (match_operand:SI 0 "register_operand" "=r") |
1135 | (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") | |
1136 | (const_int 0)))) | |
c4ce6853 | 1137 | (clobber (reg:CC 100))] |
e6c1be7e | 1138 | "" |
e0d80184 DM |
1139 | "#" |
1140 | [(set_attr "length" "2")]) | |
1141 | ||
1142 | (define_split | |
1143 | [(set (match_operand:SI 0 "register_operand" "") | |
1144 | (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "") | |
1145 | (const_int 0)))) | |
1146 | (clobber (reg:CC 100))] | |
1147 | "" | |
1148 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) | |
1149 | (const_int 0))) | |
1150 | (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] | |
1151 | "") | |
7a768814 | 1152 | |
44965bad JW |
1153 | (define_insn "*snesi_zero_extend" |
1154 | [(set (match_operand:DI 0 "register_operand" "=r") | |
638e8b1f | 1155 | (ne:DI (match_operand:SI 1 "register_operand" "r") |
44965bad | 1156 | (const_int 0))) |
c4ce6853 | 1157 | (clobber (reg:CC 100))] |
fa0f39e4 | 1158 | "TARGET_ARCH64" |
e0d80184 | 1159 | "#" |
44965bad JW |
1160 | [(set_attr "type" "unary") |
1161 | (set_attr "length" "2")]) | |
1162 | ||
e0d80184 DM |
1163 | (define_split |
1164 | [(set (match_operand:DI 0 "register_operand" "") | |
638e8b1f | 1165 | (ne:DI (match_operand:SI 1 "register_operand" "") |
e0d80184 DM |
1166 | (const_int 0))) |
1167 | (clobber (reg:CC 100))] | |
71648202 | 1168 | "TARGET_ARCH64" |
638e8b1f | 1169 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1)) |
e0d80184 | 1170 | (const_int 0))) |
f710f868 DM |
1171 | (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0) |
1172 | (const_int 0)) | |
1173 | (ltu:SI (reg:CC_NOOV 100) | |
1174 | (const_int 0)))))] | |
e0d80184 DM |
1175 | "") |
1176 | ||
c8b3b7d6 | 1177 | (define_insn "*snedi_zero" |
2808652a | 1178 | [(set (match_operand:DI 0 "register_operand" "=&r") |
a8d2b752 | 1179 | (ne:DI (match_operand:DI 1 "register_operand" "r") |
b0967cad | 1180 | (const_int 0)))] |
fa0f39e4 | 1181 | "TARGET_ARCH64" |
e0d80184 | 1182 | "#" |
284d86e9 | 1183 | [(set_attr "type" "cmove") |
a8d2b752 DE |
1184 | (set_attr "length" "2")]) |
1185 | ||
e0d80184 DM |
1186 | (define_split |
1187 | [(set (match_operand:DI 0 "register_operand" "") | |
1188 | (ne:DI (match_operand:DI 1 "register_operand" "") | |
1189 | (const_int 0)))] | |
5deb91a4 JJ |
1190 | "TARGET_ARCH64 |
1191 | && ! reg_overlap_mentioned_p (operands[1], operands[0])" | |
e0d80184 DM |
1192 | [(set (match_dup 0) (const_int 0)) |
1193 | (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1) | |
1194 | (const_int 0)) | |
1195 | (const_int 1) | |
1196 | (match_dup 0)))] | |
1197 | "") | |
1198 | ||
c8b3b7d6 | 1199 | (define_insn "*neg_snedi_zero" |
2808652a | 1200 | [(set (match_operand:DI 0 "register_operand" "=&r") |
a8d2b752 | 1201 | (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r") |
b0967cad | 1202 | (const_int 0))))] |
fa0f39e4 | 1203 | "TARGET_ARCH64" |
e0d80184 | 1204 | "#" |
284d86e9 | 1205 | [(set_attr "type" "cmove") |
a8d2b752 DE |
1206 | (set_attr "length" "2")]) |
1207 | ||
e0d80184 DM |
1208 | (define_split |
1209 | [(set (match_operand:DI 0 "register_operand" "") | |
1210 | (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "") | |
1211 | (const_int 0))))] | |
5deb91a4 JJ |
1212 | "TARGET_ARCH64 |
1213 | && ! reg_overlap_mentioned_p (operands[1], operands[0])" | |
e0d80184 DM |
1214 | [(set (match_dup 0) (const_int 0)) |
1215 | (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1) | |
1216 | (const_int 0)) | |
1217 | (const_int -1) | |
1218 | (match_dup 0)))] | |
1219 | "") | |
1220 | ||
b0967cad | 1221 | (define_insn "*snedi_zero_trunc" |
2808652a | 1222 | [(set (match_operand:SI 0 "register_operand" "=&r") |
638e8b1f | 1223 | (ne:SI (match_operand:DI 1 "register_operand" "r") |
b0967cad | 1224 | (const_int 0)))] |
fa0f39e4 | 1225 | "TARGET_ARCH64" |
e0d80184 | 1226 | "#" |
284d86e9 | 1227 | [(set_attr "type" "cmove") |
44965bad JW |
1228 | (set_attr "length" "2")]) |
1229 | ||
e0d80184 DM |
1230 | (define_split |
1231 | [(set (match_operand:SI 0 "register_operand" "") | |
638e8b1f | 1232 | (ne:SI (match_operand:DI 1 "register_operand" "") |
e0d80184 | 1233 | (const_int 0)))] |
5deb91a4 JJ |
1234 | "TARGET_ARCH64 |
1235 | && ! reg_overlap_mentioned_p (operands[1], operands[0])" | |
e0d80184 | 1236 | [(set (match_dup 0) (const_int 0)) |
638e8b1f | 1237 | (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1) |
e0d80184 DM |
1238 | (const_int 0)) |
1239 | (const_int 1) | |
1240 | (match_dup 0)))] | |
1241 | "") | |
1242 | ||
c8b3b7d6 | 1243 | (define_insn "*seqsi_zero" |
7a768814 | 1244 | [(set (match_operand:SI 0 "register_operand" "=r") |
a8d2b752 DE |
1245 | (eq:SI (match_operand:SI 1 "register_operand" "r") |
1246 | (const_int 0))) | |
c4ce6853 | 1247 | (clobber (reg:CC 100))] |
e6c1be7e | 1248 | "" |
e0d80184 DM |
1249 | "#" |
1250 | [(set_attr "length" "2")]) | |
1251 | ||
1252 | (define_split | |
1253 | [(set (match_operand:SI 0 "register_operand" "") | |
1254 | (eq:SI (match_operand:SI 1 "register_operand" "") | |
1255 | (const_int 0))) | |
1256 | (clobber (reg:CC 100))] | |
1257 | "" | |
1258 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) | |
1259 | (const_int 0))) | |
1260 | (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))] | |
1261 | "") | |
7a768814 | 1262 | |
c8b3b7d6 | 1263 | (define_insn "*neg_seqsi_zero" |
7a768814 RS |
1264 | [(set (match_operand:SI 0 "register_operand" "=r") |
1265 | (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") | |
1266 | (const_int 0)))) | |
c4ce6853 | 1267 | (clobber (reg:CC 100))] |
e6c1be7e | 1268 | "" |
e0d80184 DM |
1269 | "#" |
1270 | [(set_attr "length" "2")]) | |
1271 | ||
1272 | (define_split | |
1273 | [(set (match_operand:SI 0 "register_operand" "") | |
1274 | (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "") | |
1275 | (const_int 0)))) | |
1276 | (clobber (reg:CC 100))] | |
1277 | "" | |
1278 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) | |
1279 | (const_int 0))) | |
1280 | (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] | |
1281 | "") | |
7a768814 | 1282 | |
44965bad JW |
1283 | (define_insn "*seqsi_zero_extend" |
1284 | [(set (match_operand:DI 0 "register_operand" "=r") | |
638e8b1f | 1285 | (eq:DI (match_operand:SI 1 "register_operand" "r") |
44965bad | 1286 | (const_int 0))) |
c4ce6853 | 1287 | (clobber (reg:CC 100))] |
fa0f39e4 | 1288 | "TARGET_ARCH64" |
e0d80184 | 1289 | "#" |
44965bad JW |
1290 | [(set_attr "type" "unary") |
1291 | (set_attr "length" "2")]) | |
1292 | ||
e0d80184 DM |
1293 | (define_split |
1294 | [(set (match_operand:DI 0 "register_operand" "") | |
638e8b1f | 1295 | (eq:DI (match_operand:SI 1 "register_operand" "") |
e0d80184 DM |
1296 | (const_int 0))) |
1297 | (clobber (reg:CC 100))] | |
1298 | "TARGET_ARCH64" | |
1299 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1)) | |
1300 | (const_int 0))) | |
638e8b1f DM |
1301 | (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0) |
1302 | (const_int -1)) | |
1303 | (ltu:SI (reg:CC_NOOV 100) | |
1304 | (const_int 0)))))] | |
e0d80184 DM |
1305 | "") |
1306 | ||
c8b3b7d6 | 1307 | (define_insn "*seqdi_zero" |
2808652a | 1308 | [(set (match_operand:DI 0 "register_operand" "=&r") |
a8d2b752 | 1309 | (eq:DI (match_operand:DI 1 "register_operand" "r") |
b0967cad | 1310 | (const_int 0)))] |
fa0f39e4 | 1311 | "TARGET_ARCH64" |
e0d80184 | 1312 | "#" |
284d86e9 | 1313 | [(set_attr "type" "cmove") |
a8d2b752 DE |
1314 | (set_attr "length" "2")]) |
1315 | ||
e0d80184 DM |
1316 | (define_split |
1317 | [(set (match_operand:DI 0 "register_operand" "") | |
1318 | (eq:DI (match_operand:DI 1 "register_operand" "") | |
1319 | (const_int 0)))] | |
5deb91a4 JJ |
1320 | "TARGET_ARCH64 |
1321 | && ! reg_overlap_mentioned_p (operands[1], operands[0])" | |
e0d80184 DM |
1322 | [(set (match_dup 0) (const_int 0)) |
1323 | (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1) | |
1324 | (const_int 0)) | |
1325 | (const_int 1) | |
1326 | (match_dup 0)))] | |
1327 | "") | |
1328 | ||
c8b3b7d6 | 1329 | (define_insn "*neg_seqdi_zero" |
2808652a | 1330 | [(set (match_operand:DI 0 "register_operand" "=&r") |
a8d2b752 | 1331 | (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r") |
b0967cad | 1332 | (const_int 0))))] |
fa0f39e4 | 1333 | "TARGET_ARCH64" |
e0d80184 | 1334 | "#" |
284d86e9 | 1335 | [(set_attr "type" "cmove") |
a8d2b752 DE |
1336 | (set_attr "length" "2")]) |
1337 | ||
e0d80184 DM |
1338 | (define_split |
1339 | [(set (match_operand:DI 0 "register_operand" "") | |
1340 | (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "") | |
1341 | (const_int 0))))] | |
5deb91a4 JJ |
1342 | "TARGET_ARCH64 |
1343 | && ! reg_overlap_mentioned_p (operands[1], operands[0])" | |
e0d80184 DM |
1344 | [(set (match_dup 0) (const_int 0)) |
1345 | (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1) | |
1346 | (const_int 0)) | |
1347 | (const_int -1) | |
1348 | (match_dup 0)))] | |
1349 | "") | |
1350 | ||
b0967cad | 1351 | (define_insn "*seqdi_zero_trunc" |
2808652a | 1352 | [(set (match_operand:SI 0 "register_operand" "=&r") |
638e8b1f | 1353 | (eq:SI (match_operand:DI 1 "register_operand" "r") |
b0967cad | 1354 | (const_int 0)))] |
fa0f39e4 | 1355 | "TARGET_ARCH64" |
e0d80184 | 1356 | "#" |
284d86e9 | 1357 | [(set_attr "type" "cmove") |
44965bad JW |
1358 | (set_attr "length" "2")]) |
1359 | ||
e0d80184 DM |
1360 | (define_split |
1361 | [(set (match_operand:SI 0 "register_operand" "") | |
638e8b1f | 1362 | (eq:SI (match_operand:DI 1 "register_operand" "") |
e0d80184 | 1363 | (const_int 0)))] |
5deb91a4 JJ |
1364 | "TARGET_ARCH64 |
1365 | && ! reg_overlap_mentioned_p (operands[1], operands[0])" | |
e0d80184 | 1366 | [(set (match_dup 0) (const_int 0)) |
638e8b1f | 1367 | (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1) |
e0d80184 DM |
1368 | (const_int 0)) |
1369 | (const_int 1) | |
1370 | (match_dup 0)))] | |
1371 | "") | |
1372 | ||
7a768814 | 1373 | ;; We can also do (x + (i == 0)) and related, so put them in. |
a8d2b752 DE |
1374 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode |
1375 | ;; versions for v9. | |
7a768814 | 1376 | |
c8b3b7d6 | 1377 | (define_insn "*x_plus_i_ne_0" |
7a768814 RS |
1378 | [(set (match_operand:SI 0 "register_operand" "=r") |
1379 | (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r") | |
1380 | (const_int 0)) | |
1381 | (match_operand:SI 2 "register_operand" "r"))) | |
c4ce6853 | 1382 | (clobber (reg:CC 100))] |
e6c1be7e | 1383 | "" |
e0d80184 | 1384 | "#" |
7a768814 RS |
1385 | [(set_attr "length" "2")]) |
1386 | ||
e0d80184 DM |
1387 | (define_split |
1388 | [(set (match_operand:SI 0 "register_operand" "") | |
1389 | (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "") | |
1390 | (const_int 0)) | |
1391 | (match_operand:SI 2 "register_operand" ""))) | |
1392 | (clobber (reg:CC 100))] | |
e6c1be7e | 1393 | "" |
e0d80184 DM |
1394 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) |
1395 | (const_int 0))) | |
1396 | (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) | |
1397 | (match_dup 2)))] | |
1398 | "") | |
1399 | ||
c8b3b7d6 | 1400 | (define_insn "*x_minus_i_ne_0" |
7a768814 RS |
1401 | [(set (match_operand:SI 0 "register_operand" "=r") |
1402 | (minus:SI (match_operand:SI 2 "register_operand" "r") | |
1403 | (ne:SI (match_operand:SI 1 "register_operand" "r") | |
1404 | (const_int 0)))) | |
c4ce6853 | 1405 | (clobber (reg:CC 100))] |
e6c1be7e | 1406 | "" |
e0d80184 | 1407 | "#" |
7a768814 RS |
1408 | [(set_attr "length" "2")]) |
1409 | ||
e0d80184 DM |
1410 | (define_split |
1411 | [(set (match_operand:SI 0 "register_operand" "") | |
1412 | (minus:SI (match_operand:SI 2 "register_operand" "") | |
1413 | (ne:SI (match_operand:SI 1 "register_operand" "") | |
1414 | (const_int 0)))) | |
1415 | (clobber (reg:CC 100))] | |
e6c1be7e | 1416 | "" |
e0d80184 DM |
1417 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) |
1418 | (const_int 0))) | |
1419 | (set (match_dup 0) (minus:SI (match_dup 2) | |
1420 | (ltu:SI (reg:CC 100) (const_int 0))))] | |
1421 | "") | |
1422 | ||
c8b3b7d6 | 1423 | (define_insn "*x_plus_i_eq_0" |
7a768814 RS |
1424 | [(set (match_operand:SI 0 "register_operand" "=r") |
1425 | (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") | |
1426 | (const_int 0)) | |
1427 | (match_operand:SI 2 "register_operand" "r"))) | |
c4ce6853 | 1428 | (clobber (reg:CC 100))] |
e6c1be7e | 1429 | "" |
e0d80184 | 1430 | "#" |
7a768814 RS |
1431 | [(set_attr "length" "2")]) |
1432 | ||
e0d80184 DM |
1433 | (define_split |
1434 | [(set (match_operand:SI 0 "register_operand" "") | |
1435 | (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "") | |
1436 | (const_int 0)) | |
1437 | (match_operand:SI 2 "register_operand" ""))) | |
1438 | (clobber (reg:CC 100))] | |
e6c1be7e | 1439 | "" |
e0d80184 DM |
1440 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) |
1441 | (const_int 0))) | |
1442 | (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0)) | |
1443 | (match_dup 2)))] | |
1444 | "") | |
1445 | ||
c8b3b7d6 | 1446 | (define_insn "*x_minus_i_eq_0" |
7a768814 RS |
1447 | [(set (match_operand:SI 0 "register_operand" "=r") |
1448 | (minus:SI (match_operand:SI 2 "register_operand" "r") | |
1449 | (eq:SI (match_operand:SI 1 "register_operand" "r") | |
1450 | (const_int 0)))) | |
c4ce6853 | 1451 | (clobber (reg:CC 100))] |
e6c1be7e | 1452 | "" |
e0d80184 | 1453 | "#" |
b4ac57ab | 1454 | [(set_attr "length" "2")]) |
7a768814 | 1455 | |
e0d80184 DM |
1456 | (define_split |
1457 | [(set (match_operand:SI 0 "register_operand" "") | |
1458 | (minus:SI (match_operand:SI 2 "register_operand" "") | |
1459 | (eq:SI (match_operand:SI 1 "register_operand" "") | |
1460 | (const_int 0)))) | |
1461 | (clobber (reg:CC 100))] | |
e6c1be7e | 1462 | "" |
e0d80184 DM |
1463 | [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) |
1464 | (const_int 0))) | |
1465 | (set (match_dup 0) (minus:SI (match_dup 2) | |
1466 | (geu:SI (reg:CC 100) (const_int 0))))] | |
1467 | "") | |
1468 | ||
a8d2b752 DE |
1469 | ;; We can also do GEU and LTU directly, but these operate after a compare. |
1470 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode | |
1471 | ;; versions for v9. | |
7a768814 | 1472 | |
c8b3b7d6 | 1473 | (define_insn "*sltu_insn" |
7a768814 | 1474 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1475 | (ltu:SI (reg:CC 100) (const_int 0)))] |
e6c1be7e | 1476 | "" |
e0d80184 DM |
1477 | "addx\\t%%g0, 0, %0" |
1478 | [(set_attr "type" "misc") | |
1479 | (set_attr "length" "1")]) | |
7a768814 | 1480 | |
c8b3b7d6 | 1481 | (define_insn "*neg_sltu_insn" |
7a768814 | 1482 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1483 | (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] |
e6c1be7e | 1484 | "" |
e0d80184 DM |
1485 | "subx\\t%%g0, 0, %0" |
1486 | [(set_attr "type" "misc") | |
1487 | (set_attr "length" "1")]) | |
7a768814 RS |
1488 | |
1489 | ;; ??? Combine should canonicalize these next two to the same pattern. | |
c8b3b7d6 | 1490 | (define_insn "*neg_sltu_minus_x" |
7a768814 | 1491 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1492 | (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0))) |
7a768814 | 1493 | (match_operand:SI 1 "arith_operand" "rI")))] |
e6c1be7e | 1494 | "" |
e0d80184 | 1495 | "subx\\t%%g0, %1, %0" |
3bc8b61e | 1496 | [(set_attr "type" "misc") |
e0d80184 | 1497 | (set_attr "length" "1")]) |
7a768814 | 1498 | |
c8b3b7d6 | 1499 | (define_insn "*neg_sltu_plus_x" |
7a768814 | 1500 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1501 | (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) |
7a768814 | 1502 | (match_operand:SI 1 "arith_operand" "rI"))))] |
e6c1be7e | 1503 | "" |
e0d80184 | 1504 | "subx\\t%%g0, %1, %0" |
3bc8b61e | 1505 | [(set_attr "type" "misc") |
e0d80184 | 1506 | (set_attr "length" "1")]) |
7a768814 | 1507 | |
c8b3b7d6 | 1508 | (define_insn "*sgeu_insn" |
7a768814 | 1509 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1510 | (geu:SI (reg:CC 100) (const_int 0)))] |
e6c1be7e | 1511 | "" |
e0d80184 DM |
1512 | "subx\\t%%g0, -1, %0" |
1513 | [(set_attr "type" "misc") | |
1514 | (set_attr "length" "1")]) | |
7a768814 | 1515 | |
c8b3b7d6 | 1516 | (define_insn "*neg_sgeu_insn" |
7a768814 | 1517 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1518 | (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] |
e6c1be7e | 1519 | "" |
e0d80184 DM |
1520 | "addx\\t%%g0, -1, %0" |
1521 | [(set_attr "type" "misc") | |
1522 | (set_attr "length" "1")]) | |
7a768814 RS |
1523 | |
1524 | ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. | |
a8d2b752 DE |
1525 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode |
1526 | ;; versions for v9. | |
7a768814 | 1527 | |
c8b3b7d6 | 1528 | (define_insn "*sltu_plus_x" |
7a768814 | 1529 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1530 | (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) |
7a768814 | 1531 | (match_operand:SI 1 "arith_operand" "rI")))] |
e6c1be7e | 1532 | "" |
e0d80184 | 1533 | "addx\\t%%g0, %1, %0" |
3bc8b61e | 1534 | [(set_attr "type" "misc") |
e0d80184 | 1535 | (set_attr "length" "1")]) |
7a768814 | 1536 | |
c8b3b7d6 | 1537 | (define_insn "*sltu_plus_x_plus_y" |
7a768814 | 1538 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1539 | (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) |
7a768814 RS |
1540 | (plus:SI (match_operand:SI 1 "arith_operand" "%r") |
1541 | (match_operand:SI 2 "arith_operand" "rI"))))] | |
1542 | "" | |
e0d80184 | 1543 | "addx\\t%1, %2, %0" |
3bc8b61e | 1544 | [(set_attr "type" "misc") |
e0d80184 | 1545 | (set_attr "length" "1")]) |
7a768814 | 1546 | |
c8b3b7d6 | 1547 | (define_insn "*x_minus_sltu" |
7a768814 RS |
1548 | [(set (match_operand:SI 0 "register_operand" "=r") |
1549 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
c4ce6853 | 1550 | (ltu:SI (reg:CC 100) (const_int 0))))] |
7a768814 | 1551 | "" |
e0d80184 | 1552 | "subx\\t%1, 0, %0" |
3bc8b61e | 1553 | [(set_attr "type" "misc") |
e0d80184 | 1554 | (set_attr "length" "1")]) |
7a768814 RS |
1555 | |
1556 | ;; ??? Combine should canonicalize these next two to the same pattern. | |
c8b3b7d6 | 1557 | (define_insn "*x_minus_y_minus_sltu" |
7a768814 | 1558 | [(set (match_operand:SI 0 "register_operand" "=r") |
e0d80184 | 1559 | (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") |
7a768814 | 1560 | (match_operand:SI 2 "arith_operand" "rI")) |
c4ce6853 | 1561 | (ltu:SI (reg:CC 100) (const_int 0))))] |
7a768814 | 1562 | "" |
e0d80184 | 1563 | "subx\\t%r1, %2, %0" |
3bc8b61e | 1564 | [(set_attr "type" "misc") |
e0d80184 | 1565 | (set_attr "length" "1")]) |
7a768814 | 1566 | |
c8b3b7d6 | 1567 | (define_insn "*x_minus_sltu_plus_y" |
7a768814 | 1568 | [(set (match_operand:SI 0 "register_operand" "=r") |
e0d80184 | 1569 | (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") |
c4ce6853 | 1570 | (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) |
7a768814 RS |
1571 | (match_operand:SI 2 "arith_operand" "rI"))))] |
1572 | "" | |
e0d80184 | 1573 | "subx\\t%r1, %2, %0" |
3bc8b61e | 1574 | [(set_attr "type" "misc") |
e0d80184 | 1575 | (set_attr "length" "1")]) |
7a768814 | 1576 | |
c8b3b7d6 | 1577 | (define_insn "*sgeu_plus_x" |
7a768814 | 1578 | [(set (match_operand:SI 0 "register_operand" "=r") |
c4ce6853 | 1579 | (plus:SI (geu:SI (reg:CC 100) (const_int 0)) |
7a768814 RS |
1580 | (match_operand:SI 1 "register_operand" "r")))] |
1581 | "" | |
e0d80184 | 1582 | "subx\\t%1, -1, %0" |
3bc8b61e | 1583 | [(set_attr "type" "misc") |
e0d80184 | 1584 | (set_attr "length" "1")]) |
7a768814 | 1585 | |
c8b3b7d6 | 1586 | (define_insn "*x_minus_sgeu" |
7a768814 RS |
1587 | [(set (match_operand:SI 0 "register_operand" "=r") |
1588 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
c4ce6853 | 1589 | (geu:SI (reg:CC 100) (const_int 0))))] |
7a768814 | 1590 | "" |
e0d80184 | 1591 | "addx\\t%1, -1, %0" |
3bc8b61e | 1592 | [(set_attr "type" "misc") |
e0d80184 | 1593 | (set_attr "length" "1")]) |
a8d2b752 | 1594 | |
c6b0465b JC |
1595 | (define_split |
1596 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1597 | (match_operator:SI 2 "noov_compare_op" | |
1598 | [(match_operand 1 "icc_or_fcc_reg_operand" "") | |
1599 | (const_int 0)]))] | |
1600 | ;; 32 bit LTU/GEU are better implemented using addx/subx | |
1601 | "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG | |
1602 | && (GET_MODE (operands[1]) == CCXmode | |
1603 | || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))" | |
1604 | [(set (match_dup 0) (const_int 0)) | |
1605 | (set (match_dup 0) | |
1606 | (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)]) | |
1607 | (const_int 1) | |
1608 | (match_dup 0)))] | |
1609 | "") | |
1610 | ||
7a768814 RS |
1611 | \f |
1612 | ;; These control RTL generation for conditional jump insns | |
1613 | ||
ef903eca JW |
1614 | ;; The quad-word fp compare library routines all return nonzero to indicate |
1615 | ;; true, which is different from the equivalent libgcc routines, so we must | |
1616 | ;; handle them specially here. | |
1617 | ||
7a768814 RS |
1618 | (define_expand "beq" |
1619 | [(set (pc) | |
1620 | (if_then_else (eq (match_dup 1) (const_int 0)) | |
1621 | (label_ref (match_operand 0 "" "")) | |
1622 | (pc)))] | |
1623 | "" | |
1624 | " | |
ef903eca | 1625 | { |
fa0f39e4 | 1626 | if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
a8d2b752 DE |
1627 | && GET_CODE (sparc_compare_op0) == REG |
1628 | && GET_MODE (sparc_compare_op0) == DImode) | |
1629 | { | |
1630 | emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]); | |
1631 | DONE; | |
1632 | } | |
5c5c34a4 | 1633 | else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
1634 | { |
1635 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ); | |
1636 | emit_jump_insn (gen_bne (operands[0])); | |
1637 | DONE; | |
1638 | } | |
ef903eca JW |
1639 | operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); |
1640 | }") | |
7a768814 RS |
1641 | |
1642 | (define_expand "bne" | |
1643 | [(set (pc) | |
1644 | (if_then_else (ne (match_dup 1) (const_int 0)) | |
1645 | (label_ref (match_operand 0 "" "")) | |
1646 | (pc)))] | |
1647 | "" | |
1648 | " | |
ef903eca | 1649 | { |
fa0f39e4 | 1650 | if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
a8d2b752 DE |
1651 | && GET_CODE (sparc_compare_op0) == REG |
1652 | && GET_MODE (sparc_compare_op0) == DImode) | |
1653 | { | |
1654 | emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]); | |
1655 | DONE; | |
1656 | } | |
5c5c34a4 | 1657 | else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
1658 | { |
1659 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE); | |
1660 | emit_jump_insn (gen_bne (operands[0])); | |
1661 | DONE; | |
1662 | } | |
ef903eca JW |
1663 | operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); |
1664 | }") | |
7a768814 RS |
1665 | |
1666 | (define_expand "bgt" | |
1667 | [(set (pc) | |
1668 | (if_then_else (gt (match_dup 1) (const_int 0)) | |
1669 | (label_ref (match_operand 0 "" "")) | |
1670 | (pc)))] | |
1671 | "" | |
1672 | " | |
ef903eca | 1673 | { |
fa0f39e4 | 1674 | if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
a8d2b752 DE |
1675 | && GET_CODE (sparc_compare_op0) == REG |
1676 | && GET_MODE (sparc_compare_op0) == DImode) | |
1677 | { | |
1678 | emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]); | |
1679 | DONE; | |
1680 | } | |
5c5c34a4 | 1681 | else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
1682 | { |
1683 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT); | |
1684 | emit_jump_insn (gen_bne (operands[0])); | |
1685 | DONE; | |
1686 | } | |
ef903eca JW |
1687 | operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); |
1688 | }") | |
7a768814 RS |
1689 | |
1690 | (define_expand "bgtu" | |
1691 | [(set (pc) | |
1692 | (if_then_else (gtu (match_dup 1) (const_int 0)) | |
1693 | (label_ref (match_operand 0 "" "")) | |
1694 | (pc)))] | |
1695 | "" | |
1696 | " | |
1697 | { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1); | |
1698 | }") | |
1699 | ||
1700 | (define_expand "blt" | |
1701 | [(set (pc) | |
1702 | (if_then_else (lt (match_dup 1) (const_int 0)) | |
1703 | (label_ref (match_operand 0 "" "")) | |
1704 | (pc)))] | |
1705 | "" | |
1706 | " | |
ef903eca | 1707 | { |
fa0f39e4 | 1708 | if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
a8d2b752 DE |
1709 | && GET_CODE (sparc_compare_op0) == REG |
1710 | && GET_MODE (sparc_compare_op0) == DImode) | |
1711 | { | |
1712 | emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]); | |
1713 | DONE; | |
1714 | } | |
5c5c34a4 | 1715 | else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
1716 | { |
1717 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT); | |
1718 | emit_jump_insn (gen_bne (operands[0])); | |
1719 | DONE; | |
1720 | } | |
ef903eca JW |
1721 | operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); |
1722 | }") | |
7a768814 RS |
1723 | |
1724 | (define_expand "bltu" | |
1725 | [(set (pc) | |
1726 | (if_then_else (ltu (match_dup 1) (const_int 0)) | |
1727 | (label_ref (match_operand 0 "" "")) | |
1728 | (pc)))] | |
1729 | "" | |
1730 | " | |
1731 | { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1); | |
1732 | }") | |
1733 | ||
1734 | (define_expand "bge" | |
1735 | [(set (pc) | |
1736 | (if_then_else (ge (match_dup 1) (const_int 0)) | |
1737 | (label_ref (match_operand 0 "" "")) | |
1738 | (pc)))] | |
1739 | "" | |
1740 | " | |
ef903eca | 1741 | { |
fa0f39e4 | 1742 | if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
a8d2b752 DE |
1743 | && GET_CODE (sparc_compare_op0) == REG |
1744 | && GET_MODE (sparc_compare_op0) == DImode) | |
1745 | { | |
1746 | emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]); | |
1747 | DONE; | |
1748 | } | |
5c5c34a4 | 1749 | else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
1750 | { |
1751 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE); | |
1752 | emit_jump_insn (gen_bne (operands[0])); | |
1753 | DONE; | |
1754 | } | |
ef903eca JW |
1755 | operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); |
1756 | }") | |
7a768814 RS |
1757 | |
1758 | (define_expand "bgeu" | |
1759 | [(set (pc) | |
1760 | (if_then_else (geu (match_dup 1) (const_int 0)) | |
1761 | (label_ref (match_operand 0 "" "")) | |
1762 | (pc)))] | |
1763 | "" | |
1764 | " | |
1765 | { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1); | |
1766 | }") | |
1767 | ||
1768 | (define_expand "ble" | |
1769 | [(set (pc) | |
1770 | (if_then_else (le (match_dup 1) (const_int 0)) | |
1771 | (label_ref (match_operand 0 "" "")) | |
1772 | (pc)))] | |
1773 | "" | |
1774 | " | |
ef903eca | 1775 | { |
fa0f39e4 | 1776 | if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx |
a8d2b752 DE |
1777 | && GET_CODE (sparc_compare_op0) == REG |
1778 | && GET_MODE (sparc_compare_op0) == DImode) | |
1779 | { | |
1780 | emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]); | |
1781 | DONE; | |
1782 | } | |
5c5c34a4 | 1783 | else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
47ac041c JJ |
1784 | { |
1785 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE); | |
1786 | emit_jump_insn (gen_bne (operands[0])); | |
1787 | DONE; | |
1788 | } | |
ef903eca JW |
1789 | operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); |
1790 | }") | |
7a768814 RS |
1791 | |
1792 | (define_expand "bleu" | |
1793 | [(set (pc) | |
1794 | (if_then_else (leu (match_dup 1) (const_int 0)) | |
1795 | (label_ref (match_operand 0 "" "")) | |
1796 | (pc)))] | |
1797 | "" | |
1798 | " | |
1799 | { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); | |
1800 | }") | |
e267e177 RH |
1801 | |
1802 | (define_expand "bunordered" | |
1803 | [(set (pc) | |
1804 | (if_then_else (unordered (match_dup 1) (const_int 0)) | |
1805 | (label_ref (match_operand 0 "" "")) | |
1806 | (pc)))] | |
1807 | "" | |
1808 | " | |
1809 | { | |
5c5c34a4 | 1810 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
e267e177 RH |
1811 | { |
1812 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, | |
1813 | UNORDERED); | |
5c5c34a4 | 1814 | emit_jump_insn (gen_beq (operands[0])); |
e267e177 RH |
1815 | DONE; |
1816 | } | |
1817 | operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0, | |
1818 | sparc_compare_op1); | |
1819 | }") | |
1820 | ||
1821 | (define_expand "bordered" | |
1822 | [(set (pc) | |
1823 | (if_then_else (ordered (match_dup 1) (const_int 0)) | |
1824 | (label_ref (match_operand 0 "" "")) | |
1825 | (pc)))] | |
1826 | "" | |
1827 | " | |
1828 | { | |
5c5c34a4 | 1829 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
e267e177 RH |
1830 | { |
1831 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED); | |
1832 | emit_jump_insn (gen_bne (operands[0])); | |
1833 | DONE; | |
1834 | } | |
1835 | operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0, | |
1836 | sparc_compare_op1); | |
1837 | }") | |
1838 | ||
1839 | (define_expand "bungt" | |
1840 | [(set (pc) | |
1841 | (if_then_else (ungt (match_dup 1) (const_int 0)) | |
1842 | (label_ref (match_operand 0 "" "")) | |
1843 | (pc)))] | |
1844 | "" | |
1845 | " | |
1846 | { | |
5c5c34a4 | 1847 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
e267e177 RH |
1848 | { |
1849 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT); | |
5c5c34a4 | 1850 | emit_jump_insn (gen_bgt (operands[0])); |
e267e177 RH |
1851 | DONE; |
1852 | } | |
1853 | operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1); | |
1854 | }") | |
1855 | ||
1856 | (define_expand "bunlt" | |
1857 | [(set (pc) | |
1858 | (if_then_else (unlt (match_dup 1) (const_int 0)) | |
1859 | (label_ref (match_operand 0 "" "")) | |
1860 | (pc)))] | |
1861 | "" | |
1862 | " | |
1863 | { | |
5c5c34a4 | 1864 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
e267e177 RH |
1865 | { |
1866 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT); | |
1867 | emit_jump_insn (gen_bne (operands[0])); | |
1868 | DONE; | |
1869 | } | |
1870 | operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1); | |
1871 | }") | |
1872 | ||
1873 | (define_expand "buneq" | |
1874 | [(set (pc) | |
1875 | (if_then_else (uneq (match_dup 1) (const_int 0)) | |
1876 | (label_ref (match_operand 0 "" "")) | |
1877 | (pc)))] | |
1878 | "" | |
1879 | " | |
1880 | { | |
5c5c34a4 | 1881 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
e267e177 RH |
1882 | { |
1883 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ); | |
5c5c34a4 | 1884 | emit_jump_insn (gen_beq (operands[0])); |
e267e177 RH |
1885 | DONE; |
1886 | } | |
1887 | operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1); | |
1888 | }") | |
1889 | ||
1890 | (define_expand "bunge" | |
1891 | [(set (pc) | |
1892 | (if_then_else (unge (match_dup 1) (const_int 0)) | |
1893 | (label_ref (match_operand 0 "" "")) | |
1894 | (pc)))] | |
1895 | "" | |
1896 | " | |
1897 | { | |
5c5c34a4 | 1898 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
e267e177 RH |
1899 | { |
1900 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE); | |
1901 | emit_jump_insn (gen_bne (operands[0])); | |
1902 | DONE; | |
1903 | } | |
1904 | operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1); | |
1905 | }") | |
1906 | ||
1907 | (define_expand "bunle" | |
1908 | [(set (pc) | |
1909 | (if_then_else (unle (match_dup 1) (const_int 0)) | |
1910 | (label_ref (match_operand 0 "" "")) | |
1911 | (pc)))] | |
1912 | "" | |
1913 | " | |
1914 | { | |
5c5c34a4 | 1915 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
e267e177 RH |
1916 | { |
1917 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE); | |
1918 | emit_jump_insn (gen_bne (operands[0])); | |
1919 | DONE; | |
1920 | } | |
1921 | operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1); | |
1922 | }") | |
7913f3d0 RH |
1923 | |
1924 | (define_expand "bltgt" | |
1925 | [(set (pc) | |
1926 | (if_then_else (ltgt (match_dup 1) (const_int 0)) | |
1927 | (label_ref (match_operand 0 "" "")) | |
1928 | (pc)))] | |
1929 | "" | |
1930 | " | |
1931 | { | |
5c5c34a4 | 1932 | if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) |
7913f3d0 RH |
1933 | { |
1934 | sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT); | |
1935 | emit_jump_insn (gen_bne (operands[0])); | |
1936 | DONE; | |
1937 | } | |
1938 | operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1); | |
1939 | }") | |
7a768814 RS |
1940 | \f |
1941 | ;; Now match both normal and inverted jump. | |
1942 | ||
e0d80184 | 1943 | ;; XXX fpcmp nop braindamage |
c8b3b7d6 | 1944 | (define_insn "*normal_branch" |
7a768814 RS |
1945 | [(set (pc) |
1946 | (if_then_else (match_operator 0 "noov_compare_op" | |
c4ce6853 | 1947 | [(reg 100) (const_int 0)]) |
7a768814 RS |
1948 | (label_ref (match_operand 1 "" "")) |
1949 | (pc)))] | |
1950 | "" | |
1951 | "* | |
1952 | { | |
c4ce6853 | 1953 | return output_cbranch (operands[0], 1, 0, |
7a768814 | 1954 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
c6b0465b | 1955 | ! final_sequence, insn); |
7a768814 RS |
1956 | }" |
1957 | [(set_attr "type" "branch")]) | |
1958 | ||
e0d80184 | 1959 | ;; XXX fpcmp nop braindamage |
c8b3b7d6 | 1960 | (define_insn "*inverted_branch" |
7a768814 RS |
1961 | [(set (pc) |
1962 | (if_then_else (match_operator 0 "noov_compare_op" | |
c4ce6853 | 1963 | [(reg 100) (const_int 0)]) |
7a768814 RS |
1964 | (pc) |
1965 | (label_ref (match_operand 1 "" ""))))] | |
1966 | "" | |
1967 | "* | |
1968 | { | |
c4ce6853 | 1969 | return output_cbranch (operands[0], 1, 1, |
7a768814 | 1970 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
c6b0465b | 1971 | ! final_sequence, insn); |
7a768814 RS |
1972 | }" |
1973 | [(set_attr "type" "branch")]) | |
7a768814 | 1974 | |
e0d80184 | 1975 | ;; XXX fpcmp nop braindamage |
c4ce6853 | 1976 | (define_insn "*normal_fp_branch" |
a8d2b752 | 1977 | [(set (pc) |
c4ce6853 DE |
1978 | (if_then_else (match_operator 1 "comparison_operator" |
1979 | [(match_operand:CCFP 0 "fcc_reg_operand" "c") | |
a8d2b752 DE |
1980 | (const_int 0)]) |
1981 | (label_ref (match_operand 2 "" "")) | |
1982 | (pc)))] | |
c4ce6853 | 1983 | "" |
a8d2b752 | 1984 | "* |
6a4bb1fa | 1985 | { |
c4ce6853 | 1986 | return output_cbranch (operands[1], 2, 0, |
a8d2b752 | 1987 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
c6b0465b | 1988 | ! final_sequence, insn); |
a8d2b752 DE |
1989 | }" |
1990 | [(set_attr "type" "branch")]) | |
6a4bb1fa | 1991 | |
e0d80184 | 1992 | ;; XXX fpcmp nop braindamage |
c4ce6853 | 1993 | (define_insn "*inverted_fp_branch" |
a8d2b752 | 1994 | [(set (pc) |
c4ce6853 DE |
1995 | (if_then_else (match_operator 1 "comparison_operator" |
1996 | [(match_operand:CCFP 0 "fcc_reg_operand" "c") | |
a8d2b752 DE |
1997 | (const_int 0)]) |
1998 | (pc) | |
1999 | (label_ref (match_operand 2 "" ""))))] | |
c4ce6853 | 2000 | "" |
a8d2b752 DE |
2001 | "* |
2002 | { | |
c4ce6853 | 2003 | return output_cbranch (operands[1], 2, 1, |
a8d2b752 | 2004 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
c6b0465b | 2005 | ! final_sequence, insn); |
a8d2b752 DE |
2006 | }" |
2007 | [(set_attr "type" "branch")]) | |
6a4bb1fa | 2008 | |
e0d80184 | 2009 | ;; XXX fpcmp nop braindamage |
c4ce6853 | 2010 | (define_insn "*normal_fpe_branch" |
a8d2b752 | 2011 | [(set (pc) |
c4ce6853 DE |
2012 | (if_then_else (match_operator 1 "comparison_operator" |
2013 | [(match_operand:CCFPE 0 "fcc_reg_operand" "c") | |
a8d2b752 DE |
2014 | (const_int 0)]) |
2015 | (label_ref (match_operand 2 "" "")) | |
2016 | (pc)))] | |
c4ce6853 | 2017 | "" |
a8d2b752 DE |
2018 | "* |
2019 | { | |
c4ce6853 | 2020 | return output_cbranch (operands[1], 2, 0, |
a8d2b752 | 2021 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
c6b0465b | 2022 | ! final_sequence, insn); |
a8d2b752 DE |
2023 | }" |
2024 | [(set_attr "type" "branch")]) | |
6a4bb1fa | 2025 | |
e0d80184 | 2026 | ;; XXX fpcmp nop braindamage |
c4ce6853 | 2027 | (define_insn "*inverted_fpe_branch" |
a8d2b752 | 2028 | [(set (pc) |
c4ce6853 DE |
2029 | (if_then_else (match_operator 1 "comparison_operator" |
2030 | [(match_operand:CCFPE 0 "fcc_reg_operand" "c") | |
a8d2b752 DE |
2031 | (const_int 0)]) |
2032 | (pc) | |
2033 | (label_ref (match_operand 2 "" ""))))] | |
c4ce6853 | 2034 | "" |
a8d2b752 DE |
2035 | "* |
2036 | { | |
c4ce6853 | 2037 | return output_cbranch (operands[1], 2, 1, |
a8d2b752 | 2038 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
c6b0465b | 2039 | ! final_sequence, insn); |
a8d2b752 DE |
2040 | }" |
2041 | [(set_attr "type" "branch")]) | |
6a4bb1fa | 2042 | |
a8d2b752 DE |
2043 | ;; Sparc V9-specific jump insns. None of these are guaranteed to be |
2044 | ;; in the architecture. | |
2045 | ||
2046 | ;; There are no 32 bit brreg insns. | |
2047 | ||
e0d80184 | 2048 | ;; XXX |
c8b3b7d6 | 2049 | (define_insn "*normal_int_branch_sp64" |
a8d2b752 DE |
2050 | [(set (pc) |
2051 | (if_then_else (match_operator 0 "v9_regcmp_op" | |
2052 | [(match_operand:DI 1 "register_operand" "r") | |
2053 | (const_int 0)]) | |
2054 | (label_ref (match_operand 2 "" "")) | |
2055 | (pc)))] | |
fa0f39e4 | 2056 | "TARGET_ARCH64" |
a8d2b752 | 2057 | "* |
6a4bb1fa | 2058 | { |
a8d2b752 DE |
2059 | return output_v9branch (operands[0], 1, 2, 0, |
2060 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), | |
e0d80184 | 2061 | ! final_sequence, insn); |
a8d2b752 DE |
2062 | }" |
2063 | [(set_attr "type" "branch")]) | |
6a4bb1fa | 2064 | |
e0d80184 | 2065 | ;; XXX |
c8b3b7d6 | 2066 | (define_insn "*inverted_int_branch_sp64" |
a8d2b752 DE |
2067 | [(set (pc) |
2068 | (if_then_else (match_operator 0 "v9_regcmp_op" | |
2069 | [(match_operand:DI 1 "register_operand" "r") | |
2070 | (const_int 0)]) | |
2071 | (pc) | |
2072 | (label_ref (match_operand 2 "" ""))))] | |
fa0f39e4 | 2073 | "TARGET_ARCH64" |
a8d2b752 DE |
2074 | "* |
2075 | { | |
2076 | return output_v9branch (operands[0], 1, 2, 1, | |
2077 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), | |
e0d80184 | 2078 | ! final_sequence, insn); |
a8d2b752 DE |
2079 | }" |
2080 | [(set_attr "type" "branch")]) | |
2081 | \f | |
e0d80184 | 2082 | ;; Load program counter insns. |
6a4bb1fa | 2083 | |
e0d80184 DM |
2084 | (define_insn "get_pc" |
2085 | [(clobber (reg:SI 15)) | |
2086 | (set (match_operand 0 "register_operand" "=r") | |
2087 | (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))] | |
2088 | "flag_pic && REGNO (operands[0]) == 23" | |
2089 | "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0" | |
2090 | [(set_attr "length" "3")]) | |
6a4bb1fa | 2091 | |
e0d80184 DM |
2092 | ;; Currently unused... |
2093 | ;; (define_insn "get_pc_via_rdpc" | |
2094 | ;; [(set (match_operand 0 "register_operand" "=r") (pc))] | |
2095 | ;; "TARGET_V9" | |
2096 | ;; "rd\\t%%pc, %0" | |
2097 | ;; [(set_attr "type" "move")]) | |
7a768814 | 2098 | |
e0d80184 DM |
2099 | \f |
2100 | ;; Move instructions | |
7a768814 | 2101 | |
e0d80184 DM |
2102 | (define_expand "movqi" |
2103 | [(set (match_operand:QI 0 "general_operand" "") | |
2104 | (match_operand:QI 1 "general_operand" ""))] | |
2105 | "" | |
2106 | " | |
2107 | { | |
2108 | /* Working with CONST_INTs is easier, so convert | |
2109 | a double if needed. */ | |
2110 | if (GET_CODE (operands[1]) == CONST_DOUBLE) | |
2111 | { | |
2112 | operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff); | |
2113 | } | |
2114 | else if (GET_CODE (operands[1]) == CONST_INT) | |
2115 | { | |
2116 | /* And further, we know for all QI cases that only the | |
2117 | low byte is significant, which we can always process | |
2118 | in a single insn. So mask it now. */ | |
2119 | operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); | |
2120 | } | |
7e37212e | 2121 | |
e0d80184 DM |
2122 | /* Handle sets of MEM first. */ |
2123 | if (GET_CODE (operands[0]) == MEM) | |
2124 | { | |
e0d80184 DM |
2125 | if (reg_or_0_operand (operands[1], QImode)) |
2126 | goto movqi_is_ok; | |
7e37212e | 2127 | |
e0d80184 DM |
2128 | if (! reload_in_progress) |
2129 | { | |
2130 | operands[0] = validize_mem (operands[0]); | |
2131 | operands[1] = force_reg (QImode, operands[1]); | |
2132 | } | |
2133 | } | |
7a768814 | 2134 | |
e0d80184 DM |
2135 | /* Fixup PIC cases. */ |
2136 | if (flag_pic) | |
2137 | { | |
2138 | if (CONSTANT_P (operands[1]) | |
2139 | && pic_address_needs_scratch (operands[1])) | |
2140 | operands[1] = legitimize_pic_address (operands[1], QImode, 0); | |
7a768814 | 2141 | |
e0d80184 DM |
2142 | if (symbolic_operand (operands[1], QImode)) |
2143 | { | |
2144 | operands[1] = legitimize_pic_address (operands[1], | |
2145 | QImode, | |
2146 | (reload_in_progress ? | |
2147 | operands[0] : | |
2148 | NULL_RTX)); | |
2149 | goto movqi_is_ok; | |
2150 | } | |
2151 | } | |
7a768814 | 2152 | |
e0d80184 | 2153 | /* All QI constants require only one insn, so proceed. */ |
a8d2b752 | 2154 | |
e0d80184 | 2155 | movqi_is_ok: |
5f78aa30 | 2156 | ; |
e0d80184 DM |
2157 | }") |
2158 | ||
2159 | (define_insn "*movqi_insn" | |
db7eb3e8 | 2160 | [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m") |
e0d80184 DM |
2161 | (match_operand:QI 1 "input_operand" "rI,m,rJ"))] |
2162 | "(register_operand (operands[0], QImode) | |
2163 | || reg_or_0_operand (operands[1], QImode))" | |
2164 | "@ | |
2165 | mov\\t%1, %0 | |
2166 | ldub\\t%1, %0 | |
2167 | stb\\t%r1, %0" | |
2168 | [(set_attr "type" "move,load,store") | |
2169 | (set_attr "length" "1")]) | |
2170 | ||
2171 | (define_expand "movhi" | |
2172 | [(set (match_operand:HI 0 "general_operand" "") | |
2173 | (match_operand:HI 1 "general_operand" ""))] | |
2174 | "" | |
2175 | " | |
95726648 | 2176 | { |
e0d80184 DM |
2177 | /* Working with CONST_INTs is easier, so convert |
2178 | a double if needed. */ | |
2179 | if (GET_CODE (operands[1]) == CONST_DOUBLE) | |
2180 | operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); | |
2181 | ||
2182 | /* Handle sets of MEM first. */ | |
2183 | if (GET_CODE (operands[0]) == MEM) | |
2184 | { | |
e0d80184 DM |
2185 | if (reg_or_0_operand (operands[1], HImode)) |
2186 | goto movhi_is_ok; | |
2187 | ||
2188 | if (! reload_in_progress) | |
2189 | { | |
2190 | operands[0] = validize_mem (operands[0]); | |
2191 | operands[1] = force_reg (HImode, operands[1]); | |
2192 | } | |
2193 | } | |
2194 | ||
2195 | /* Fixup PIC cases. */ | |
2196 | if (flag_pic) | |
2197 | { | |
2198 | if (CONSTANT_P (operands[1]) | |
2199 | && pic_address_needs_scratch (operands[1])) | |
2200 | operands[1] = legitimize_pic_address (operands[1], HImode, 0); | |
2201 | ||
2202 | if (symbolic_operand (operands[1], HImode)) | |
2203 | { | |
2204 | operands[1] = legitimize_pic_address (operands[1], | |
2205 | HImode, | |
2206 | (reload_in_progress ? | |
2207 | operands[0] : | |
2208 | NULL_RTX)); | |
2209 | goto movhi_is_ok; | |
2210 | } | |
2211 | } | |
2212 | ||
2213 | /* This makes sure we will not get rematched due to splittage. */ | |
2214 | if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode)) | |
2215 | ; | |
2216 | else if (CONSTANT_P (operands[1]) | |
2217 | && GET_CODE (operands[1]) != HIGH | |
2218 | && GET_CODE (operands[1]) != LO_SUM) | |
2219 | { | |
2220 | sparc_emit_set_const32 (operands[0], operands[1]); | |
2221 | DONE; | |
2222 | } | |
2223 | movhi_is_ok: | |
5f78aa30 | 2224 | ; |
e0d80184 | 2225 | }") |
a8d2b752 | 2226 | |
71648202 DM |
2227 | (define_insn "*movhi_const64_special" |
2228 | [(set (match_operand:HI 0 "register_operand" "=r") | |
2229 | (match_operand:HI 1 "const64_high_operand" ""))] | |
2230 | "TARGET_ARCH64" | |
2231 | "sethi\\t%%hi(%a1), %0" | |
2232 | [(set_attr "type" "move") | |
2233 | (set_attr "length" "1")]) | |
2234 | ||
e0d80184 | 2235 | (define_insn "*movhi_insn" |
db7eb3e8 | 2236 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") |
e0d80184 DM |
2237 | (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))] |
2238 | "(register_operand (operands[0], HImode) | |
2239 | || reg_or_0_operand (operands[1], HImode))" | |
2240 | "@ | |
2241 | mov\\t%1, %0 | |
2242 | sethi\\t%%hi(%a1), %0 | |
2243 | lduh\\t%1, %0 | |
2244 | sth\\t%r1, %0" | |
2245 | [(set_attr "type" "move,move,load,store") | |
2246 | (set_attr "length" "1")]) | |
2247 | ||
71648202 | 2248 | ;; We always work with constants here. |
e0d80184 | 2249 | (define_insn "*movhi_lo_sum" |
200d7a32 | 2250 | [(set (match_operand:HI 0 "register_operand" "=r") |
9d09e0d1 DM |
2251 | (ior:HI (match_operand:HI 1 "arith_operand" "%r") |
2252 | (match_operand:HI 2 "arith_operand" "I")))] | |
e0d80184 | 2253 | "" |
71648202 | 2254 | "or\\t%1, %2, %0" |
e0d80184 | 2255 | [(set_attr "type" "ialu") |
200d7a32 DE |
2256 | (set_attr "length" "1")]) |
2257 | ||
e0d80184 DM |
2258 | (define_expand "movsi" |
2259 | [(set (match_operand:SI 0 "general_operand" "") | |
2260 | (match_operand:SI 1 "general_operand" ""))] | |
2261 | "" | |
2262 | " | |
a8d2b752 | 2263 | { |
e0d80184 DM |
2264 | /* Working with CONST_INTs is easier, so convert |
2265 | a double if needed. */ | |
2266 | if (GET_CODE (operands[1]) == CONST_DOUBLE) | |
2267 | operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); | |
a8d2b752 | 2268 | |
e0d80184 DM |
2269 | /* Handle sets of MEM first. */ |
2270 | if (GET_CODE (operands[0]) == MEM) | |
2271 | { | |
e0d80184 DM |
2272 | if (reg_or_0_operand (operands[1], SImode)) |
2273 | goto movsi_is_ok; | |
a8d2b752 | 2274 | |
e0d80184 DM |
2275 | if (! reload_in_progress) |
2276 | { | |
2277 | operands[0] = validize_mem (operands[0]); | |
2278 | operands[1] = force_reg (SImode, operands[1]); | |
2279 | } | |
2280 | } | |
7a768814 | 2281 | |
e0d80184 DM |
2282 | /* Fixup PIC cases. */ |
2283 | if (flag_pic) | |
7a768814 | 2284 | { |
e0d80184 DM |
2285 | if (CONSTANT_P (operands[1]) |
2286 | && pic_address_needs_scratch (operands[1])) | |
2287 | operands[1] = legitimize_pic_address (operands[1], SImode, 0); | |
7a768814 | 2288 | |
e0d80184 DM |
2289 | if (GET_CODE (operands[1]) == LABEL_REF) |
2290 | { | |
2291 | /* shit */ | |
2292 | emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1])); | |
2293 | DONE; | |
2294 | } | |
2295 | ||
2296 | if (symbolic_operand (operands[1], SImode)) | |
2297 | { | |
2298 | operands[1] = legitimize_pic_address (operands[1], | |
2299 | SImode, | |
2300 | (reload_in_progress ? | |
2301 | operands[0] : | |
2302 | NULL_RTX)); | |
2303 | goto movsi_is_ok; | |
2304 | } | |
7a768814 | 2305 | } |
7a768814 | 2306 | |
e0d80184 DM |
2307 | /* If we are trying to toss an integer constant into the |
2308 | FPU registers, force it into memory. */ | |
2309 | if (GET_CODE (operands[0]) == REG | |
2310 | && REGNO (operands[0]) >= SPARC_FIRST_FP_REG | |
2311 | && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG | |
2312 | && CONSTANT_P (operands[1])) | |
2313 | operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), | |
2314 | operands[1])); | |
2315 | ||
2316 | /* This makes sure we will not get rematched due to splittage. */ | |
2317 | if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode)) | |
2318 | ; | |
2319 | else if (CONSTANT_P (operands[1]) | |
2320 | && GET_CODE (operands[1]) != HIGH | |
2321 | && GET_CODE (operands[1]) != LO_SUM) | |
2322 | { | |
2323 | sparc_emit_set_const32 (operands[0], operands[1]); | |
2324 | DONE; | |
7a768814 | 2325 | } |
e0d80184 | 2326 | movsi_is_ok: |
5f78aa30 | 2327 | ; |
e0d80184 DM |
2328 | }") |
2329 | ||
71648202 DM |
2330 | ;; This is needed to show CSE exactly which bits are set |
2331 | ;; in a 64-bit register by sethi instructions. | |
2332 | (define_insn "*movsi_const64_special" | |
2333 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2334 | (match_operand:SI 1 "const64_high_operand" ""))] | |
2335 | "TARGET_ARCH64" | |
2336 | "sethi\\t%%hi(%a1), %0" | |
2337 | [(set_attr "type" "move") | |
2338 | (set_attr "length" "1")]) | |
2339 | ||
e0d80184 | 2340 | (define_insn "*movsi_insn" |
db7eb3e8 | 2341 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d") |
e0d80184 DM |
2342 | (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))] |
2343 | "(register_operand (operands[0], SImode) | |
2344 | || reg_or_0_operand (operands[1], SImode))" | |
2345 | "@ | |
2346 | mov\\t%1, %0 | |
2347 | fmovs\\t%1, %0 | |
2348 | sethi\\t%%hi(%a1), %0 | |
2349 | clr\\t%0 | |
2350 | ld\\t%1, %0 | |
2351 | ld\\t%1, %0 | |
2352 | st\\t%r1, %0 | |
2353 | st\\t%1, %0 | |
f952a238 | 2354 | fzeros\\t%0" |
e0d80184 DM |
2355 | [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove") |
2356 | (set_attr "length" "1")]) | |
2357 | ||
2358 | (define_insn "*movsi_lo_sum" | |
2359 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2360 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
2361 | (match_operand:SI 2 "immediate_operand" "in")))] | |
2362 | "" | |
2363 | "or\\t%1, %%lo(%a2), %0" | |
2364 | [(set_attr "type" "ialu") | |
2365 | (set_attr "length" "1")]) | |
2366 | ||
2367 | (define_insn "*movsi_high" | |
2368 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2369 | (high:SI (match_operand:SI 1 "immediate_operand" "in")))] | |
2370 | "" | |
2371 | "sethi\\t%%hi(%a1), %0" | |
7a768814 | 2372 | [(set_attr "type" "move") |
e0d80184 | 2373 | (set_attr "length" "1")]) |
7a768814 | 2374 | |
e0d80184 DM |
2375 | ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC |
2376 | ;; so that CSE won't optimize the address computation away. | |
2377 | (define_insn "movsi_lo_sum_pic" | |
2378 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2379 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
2380 | (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))] | |
2381 | "flag_pic" | |
2382 | "or\\t%1, %%lo(%a2), %0" | |
3bc8b61e DM |
2383 | [(set_attr "type" "ialu") |
2384 | (set_attr "length" "1")]) | |
a8d2b752 | 2385 | |
e0d80184 DM |
2386 | (define_insn "movsi_high_pic" |
2387 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2388 | (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] | |
2389 | "flag_pic && check_pic (1)" | |
2390 | "sethi\\t%%hi(%a1), %0" | |
2391 | [(set_attr "type" "move") | |
2392 | (set_attr "length" "1")]) | |
2393 | ||
2394 | (define_expand "movsi_pic_label_ref" | |
2395 | [(set (match_dup 3) (high:SI | |
2396 | (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") | |
2397 | (match_dup 2)] 5))) | |
2398 | (set (match_dup 4) (lo_sum:SI (match_dup 3) | |
2399 | (unspec:SI [(match_dup 1) (match_dup 2)] 5))) | |
2400 | (set (match_operand:SI 0 "register_operand" "=r") | |
2401 | (minus:SI (match_dup 5) (match_dup 4)))] | |
2402 | "flag_pic" | |
2403 | " | |
a8d2b752 | 2404 | { |
e0d80184 DM |
2405 | current_function_uses_pic_offset_table = 1; |
2406 | operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\"); | |
7652adb5 JJ |
2407 | if (no_new_pseudos) |
2408 | { | |
2409 | operands[3] = operands[0]; | |
2410 | operands[4] = operands[0]; | |
2411 | } | |
2412 | else | |
2413 | { | |
2414 | operands[3] = gen_reg_rtx (SImode); | |
2415 | operands[4] = gen_reg_rtx (SImode); | |
2416 | } | |
e0d80184 DM |
2417 | operands[5] = pic_offset_table_rtx; |
2418 | }") | |
a8d2b752 | 2419 | |
e0d80184 DM |
2420 | (define_insn "*movsi_high_pic_label_ref" |
2421 | [(set (match_operand:SI 0 "register_operand" "=r") | |
2422 | (high:SI | |
2423 | (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") | |
2424 | (match_operand:SI 2 "" "")] 5)))] | |
2425 | "flag_pic" | |
2426 | "sethi\\t%%hi(%a2-(%a1-.)), %0" | |
2427 | [(set_attr "type" "move") | |
2428 | (set_attr "length" "1")]) | |
2429 | ||
2430 | (define_insn "*movsi_lo_sum_pic_label_ref" | |
2431 | [(set (match_operand:SI 0 "register_operand" "=r") | |
67111044 | 2432 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") |
e0d80184 DM |
2433 | (unspec:SI [(match_operand:SI 2 "label_ref_operand" "") |
2434 | (match_operand:SI 3 "" "")] 5)))] | |
2435 | "flag_pic" | |
2436 | "or\\t%1, %%lo(%a3-(%a2-.)), %0" | |
3bc8b61e DM |
2437 | [(set_attr "type" "ialu") |
2438 | (set_attr "length" "1")]) | |
e0d80184 DM |
2439 | |
2440 | (define_expand "movdi" | |
2441 | [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") | |
2442 | (match_operand:DI 1 "general_operand" ""))] | |
2443 | "" | |
2444 | " | |
2445 | { | |
2446 | /* Where possible, convert CONST_DOUBLE into a CONST_INT. */ | |
2447 | if (GET_CODE (operands[1]) == CONST_DOUBLE | |
3bb5de61 | 2448 | #if HOST_BITS_PER_WIDE_INT == 32 |
e0d80184 DM |
2449 | && ((CONST_DOUBLE_HIGH (operands[1]) == 0 |
2450 | && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0) | |
3bb5de61 | 2451 | || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff |
e0d80184 DM |
2452 | && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0)) |
2453 | #endif | |
2454 | ) | |
2455 | operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); | |
2456 | ||
2457 | /* Handle MEM cases first. */ | |
2458 | if (GET_CODE (operands[0]) == MEM) | |
a8d2b752 | 2459 | { |
e0d80184 DM |
2460 | /* If it's a REG, we can always do it. |
2461 | The const zero case is more complex, on v9 | |
2462 | we can always perform it. */ | |
2463 | if (register_operand (operands[1], DImode) | |
2464 | || (TARGET_ARCH64 | |
2465 | && (operands[1] == const0_rtx))) | |
2466 | goto movdi_is_ok; | |
2467 | ||
2468 | if (! reload_in_progress) | |
2469 | { | |
2470 | operands[0] = validize_mem (operands[0]); | |
2471 | operands[1] = force_reg (DImode, operands[1]); | |
2472 | } | |
a8d2b752 | 2473 | } |
a8d2b752 | 2474 | |
e0d80184 | 2475 | if (flag_pic) |
5d4f5e87 | 2476 | { |
e0d80184 DM |
2477 | if (CONSTANT_P (operands[1]) |
2478 | && pic_address_needs_scratch (operands[1])) | |
2479 | operands[1] = legitimize_pic_address (operands[1], DImode, 0); | |
5d4f5e87 | 2480 | |
56420c2c DM |
2481 | if (GET_CODE (operands[1]) == LABEL_REF) |
2482 | { | |
2483 | if (! TARGET_ARCH64) | |
2484 | abort (); | |
2485 | emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); | |
2486 | DONE; | |
2487 | } | |
2488 | ||
e0d80184 | 2489 | if (symbolic_operand (operands[1], DImode)) |
5d4f5e87 | 2490 | { |
e0d80184 DM |
2491 | operands[1] = legitimize_pic_address (operands[1], |
2492 | DImode, | |
2493 | (reload_in_progress ? | |
2494 | operands[0] : | |
2495 | NULL_RTX)); | |
2496 | goto movdi_is_ok; | |
5d4f5e87 DE |
2497 | } |
2498 | } | |
e0d80184 DM |
2499 | |
2500 | /* If we are trying to toss an integer constant into the | |
2501 | FPU registers, force it into memory. */ | |
2502 | if (GET_CODE (operands[0]) == REG | |
2503 | && REGNO (operands[0]) >= SPARC_FIRST_FP_REG | |
2504 | && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG | |
2505 | && CONSTANT_P (operands[1])) | |
2506 | operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), | |
2507 | operands[1])); | |
2508 | ||
2509 | /* This makes sure we will not get rematched due to splittage. */ | |
2510 | if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode)) | |
2511 | ; | |
2512 | else if (TARGET_ARCH64 | |
2513 | && CONSTANT_P (operands[1]) | |
2514 | && GET_CODE (operands[1]) != HIGH | |
2515 | && GET_CODE (operands[1]) != LO_SUM) | |
5d4f5e87 | 2516 | { |
e0d80184 DM |
2517 | sparc_emit_set_const64 (operands[0], operands[1]); |
2518 | DONE; | |
5d4f5e87 | 2519 | } |
b7d9c418 | 2520 | |
e0d80184 | 2521 | movdi_is_ok: |
5f78aa30 | 2522 | ; |
e0d80184 DM |
2523 | }") |
2524 | ||
2525 | ;; Be careful, fmovd does not exist when !arch64. | |
2526 | ;; We match MEM moves directly when we have correct even | |
2527 | ;; numbered registers, but fall into splits otherwise. | |
2528 | ;; The constraint ordering here is really important to | |
2529 | ;; avoid insane problems in reload, especially for patterns | |
2530 | ;; of the form: | |
2531 | ;; | |
2532 | ;; (set (mem:DI (plus:SI (reg:SI 30 %fp) | |
2533 | ;; (const_int -5016))) | |
2534 | ;; (reg:DI 2 %g2)) | |
2535 | ;; | |
2536 | (define_insn "*movdi_insn_sp32" | |
db7eb3e8 | 2537 | [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f") |
e0d80184 DM |
2538 | (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))] |
2539 | "! TARGET_ARCH64 && | |
2540 | (register_operand (operands[0], DImode) | |
2541 | || register_operand (operands[1], DImode))" | |
2542 | "@ | |
2543 | std\\t%1, %0 | |
2544 | ldd\\t%1, %0 | |
2545 | # | |
2546 | # | |
2547 | # | |
2548 | # | |
2549 | std\\t%1, %0 | |
2550 | ldd\\t%1, %0 | |
2551 | # | |
2552 | # | |
2553 | #" | |
2554 | [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*") | |
2555 | (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")]) | |
2556 | ||
f710f868 | 2557 | ;; The following are generated by sparc_emit_set_const64 |
9208e4b2 DM |
2558 | (define_insn "*movdi_sp64_dbl" |
2559 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2560 | (match_operand:DI 1 "const64_operand" ""))] | |
2561 | "(TARGET_ARCH64 | |
2562 | && HOST_BITS_PER_WIDE_INT != 64)" | |
2563 | "mov\\t%1, %0" | |
2564 | [(set_attr "type" "move") | |
2565 | (set_attr "length" "1")]) | |
2566 | ||
f710f868 DM |
2567 | ;; This is needed to show CSE exactly which bits are set |
2568 | ;; in a 64-bit register by sethi instructions. | |
9208e4b2 DM |
2569 | (define_insn "*movdi_const64_special" |
2570 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2571 | (match_operand:DI 1 "const64_high_operand" ""))] | |
f710f868 | 2572 | "TARGET_ARCH64" |
9208e4b2 DM |
2573 | "sethi\\t%%hi(%a1), %0" |
2574 | [(set_attr "type" "move") | |
2575 | (set_attr "length" "1")]) | |
2576 | ||
a5774a7d JJ |
2577 | (define_insn "*movdi_insn_sp64_novis" |
2578 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m") | |
2579 | (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))] | |
7a2bf7af RK |
2580 | "TARGET_ARCH64 && ! TARGET_VIS |
2581 | && (register_operand (operands[0], DImode) | |
2582 | || reg_or_0_operand (operands[1], DImode))" | |
a5774a7d JJ |
2583 | "@ |
2584 | mov\\t%1, %0 | |
2585 | sethi\\t%%hi(%a1), %0 | |
2586 | clr\\t%0 | |
2587 | ldx\\t%1, %0 | |
2588 | stx\\t%r1, %0 | |
2589 | fmovd\\t%1, %0 | |
2590 | ldd\\t%1, %0 | |
2591 | std\\t%1, %0" | |
2592 | [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore") | |
2593 | (set_attr "length" "1")]) | |
2594 | ||
2595 | (define_insn "*movdi_insn_sp64_vis" | |
db7eb3e8 | 2596 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b") |
f952a238 | 2597 | (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))] |
a5774a7d | 2598 | "TARGET_ARCH64 && TARGET_VIS && |
e0d80184 DM |
2599 | (register_operand (operands[0], DImode) |
2600 | || reg_or_0_operand (operands[1], DImode))" | |
2601 | "@ | |
2602 | mov\\t%1, %0 | |
2603 | sethi\\t%%hi(%a1), %0 | |
2604 | clr\\t%0 | |
2605 | ldx\\t%1, %0 | |
2606 | stx\\t%r1, %0 | |
2607 | fmovd\\t%1, %0 | |
2608 | ldd\\t%1, %0 | |
f952a238 JJ |
2609 | std\\t%1, %0 |
2610 | fzero\\t%0" | |
2611 | [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove") | |
e0d80184 DM |
2612 | (set_attr "length" "1")]) |
2613 | ||
56420c2c DM |
2614 | (define_expand "movdi_pic_label_ref" |
2615 | [(set (match_dup 3) (high:DI | |
2616 | (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") | |
2617 | (match_dup 2)] 5))) | |
2618 | (set (match_dup 4) (lo_sum:DI (match_dup 3) | |
2619 | (unspec:DI [(match_dup 1) (match_dup 2)] 5))) | |
2620 | (set (match_operand:DI 0 "register_operand" "=r") | |
2621 | (minus:DI (match_dup 5) (match_dup 4)))] | |
2622 | "TARGET_ARCH64 && flag_pic" | |
2623 | " | |
e0d80184 | 2624 | { |
56420c2c DM |
2625 | current_function_uses_pic_offset_table = 1; |
2626 | operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\"); | |
7652adb5 JJ |
2627 | if (no_new_pseudos) |
2628 | { | |
2629 | operands[3] = operands[0]; | |
2630 | operands[4] = operands[0]; | |
2631 | } | |
2632 | else | |
2633 | { | |
2634 | operands[3] = gen_reg_rtx (DImode); | |
2635 | operands[4] = gen_reg_rtx (DImode); | |
2636 | } | |
56420c2c DM |
2637 | operands[5] = pic_offset_table_rtx; |
2638 | }") | |
2639 | ||
2640 | (define_insn "*movdi_high_pic_label_ref" | |
2641 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2642 | (high:DI | |
2643 | (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") | |
2644 | (match_operand:DI 2 "" "")] 5)))] | |
2645 | "TARGET_ARCH64 && flag_pic" | |
2646 | "sethi\\t%%hi(%a2-(%a1-.)), %0" | |
2647 | [(set_attr "type" "move") | |
2648 | (set_attr "length" "1")]) | |
2649 | ||
2650 | (define_insn "*movdi_lo_sum_pic_label_ref" | |
2651 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2652 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
2653 | (unspec:DI [(match_operand:DI 2 "label_ref_operand" "") | |
2654 | (match_operand:DI 3 "" "")] 5)))] | |
2655 | "TARGET_ARCH64 && flag_pic" | |
2656 | "or\\t%1, %%lo(%a3-(%a2-.)), %0" | |
2657 | [(set_attr "type" "ialu") | |
2658 | (set_attr "length" "1")]) | |
a8d2b752 | 2659 | |
e0d80184 DM |
2660 | ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64 |
2661 | ;; in sparc.c to see what is going on here... PIC stuff comes first. | |
2662 | ||
be3f1ff5 | 2663 | (define_insn "movdi_lo_sum_pic" |
e0d80184 | 2664 | [(set (match_operand:DI 0 "register_operand" "=r") |
638e8b1f DM |
2665 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
2666 | (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))] | |
e0d80184 DM |
2667 | "TARGET_ARCH64 && flag_pic" |
2668 | "or\\t%1, %%lo(%a2), %0" | |
3bc8b61e DM |
2669 | [(set_attr "type" "ialu") |
2670 | (set_attr "length" "1")]) | |
e0d80184 | 2671 | |
be3f1ff5 | 2672 | (define_insn "movdi_high_pic" |
e0d80184 | 2673 | [(set (match_operand:DI 0 "register_operand" "=r") |
638e8b1f | 2674 | (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))] |
e0d80184 DM |
2675 | "TARGET_ARCH64 && flag_pic && check_pic (1)" |
2676 | "sethi\\t%%hi(%a1), %0" | |
2677 | [(set_attr "type" "move") | |
2678 | (set_attr "length" "1")]) | |
2679 | ||
2680 | (define_insn "*sethi_di_medlow_embmedany_pic" | |
2681 | [(set (match_operand:DI 0 "register_operand" "=r") | |
e1a2f7ae | 2682 | (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))] |
e0d80184 | 2683 | "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)" |
1cb36a98 | 2684 | "sethi\\t%%hi(%a1), %0" |
e0d80184 DM |
2685 | [(set_attr "type" "move") |
2686 | (set_attr "length" "1")]) | |
b4ac57ab | 2687 | |
c8b3b7d6 | 2688 | (define_insn "*sethi_di_medlow" |
a8d2b752 | 2689 | [(set (match_operand:DI 0 "register_operand" "=r") |
e1a2f7ae | 2690 | (high:DI (match_operand:DI 1 "symbolic_operand" "")))] |
a0a301fc | 2691 | "TARGET_CM_MEDLOW && check_pic (1)" |
e0d80184 | 2692 | "sethi\\t%%hi(%a1), %0" |
7a768814 RS |
2693 | [(set_attr "type" "move") |
2694 | (set_attr "length" "1")]) | |
2695 | ||
e0d80184 | 2696 | (define_insn "*losum_di_medlow" |
95726648 | 2697 | [(set (match_operand:DI 0 "register_operand" "=r") |
e0d80184 | 2698 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
f710f868 | 2699 | (match_operand:DI 2 "symbolic_operand" "")))] |
e0d80184 DM |
2700 | "TARGET_CM_MEDLOW" |
2701 | "or\\t%1, %%lo(%a2), %0" | |
3bc8b61e DM |
2702 | [(set_attr "type" "ialu") |
2703 | (set_attr "length" "1")]) | |
e0d80184 DM |
2704 | |
2705 | (define_insn "seth44" | |
2706 | [(set (match_operand:DI 0 "register_operand" "=r") | |
9208e4b2 | 2707 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))] |
e0d80184 DM |
2708 | "TARGET_CM_MEDMID" |
2709 | "sethi\\t%%h44(%a1), %0" | |
95726648 DE |
2710 | [(set_attr "type" "move") |
2711 | (set_attr "length" "1")]) | |
2712 | ||
e0d80184 DM |
2713 | (define_insn "setm44" |
2714 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2715 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
9208e4b2 | 2716 | (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))] |
e0d80184 DM |
2717 | "TARGET_CM_MEDMID" |
2718 | "or\\t%1, %%m44(%a2), %0" | |
2719 | [(set_attr "type" "move") | |
2720 | (set_attr "length" "1")]) | |
a8d2b752 | 2721 | |
e0d80184 | 2722 | (define_insn "setl44" |
a8d2b752 | 2723 | [(set (match_operand:DI 0 "register_operand" "=r") |
e0d80184 DM |
2724 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
2725 | (match_operand:DI 2 "symbolic_operand" "")))] | |
2726 | "TARGET_CM_MEDMID" | |
2727 | "or\\t%1, %%l44(%a2), %0" | |
3bc8b61e DM |
2728 | [(set_attr "type" "ialu") |
2729 | (set_attr "length" "1")]) | |
e0d80184 DM |
2730 | |
2731 | (define_insn "sethh" | |
2732 | [(set (match_operand:DI 0 "register_operand" "=r") | |
9208e4b2 | 2733 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))] |
e0d80184 DM |
2734 | "TARGET_CM_MEDANY" |
2735 | "sethi\\t%%hh(%a1), %0" | |
a8d2b752 | 2736 | [(set_attr "type" "move") |
e0d80184 | 2737 | (set_attr "length" "1")]) |
a8d2b752 | 2738 | |
e0d80184 | 2739 | (define_insn "setlm" |
a8d2b752 | 2740 | [(set (match_operand:DI 0 "register_operand" "=r") |
9208e4b2 | 2741 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))] |
e0d80184 DM |
2742 | "TARGET_CM_MEDANY" |
2743 | "sethi\\t%%lm(%a1), %0" | |
a8d2b752 | 2744 | [(set_attr "type" "move") |
e0d80184 | 2745 | (set_attr "length" "1")]) |
a8d2b752 | 2746 | |
e0d80184 DM |
2747 | (define_insn "sethm" |
2748 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2749 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
f710f868 | 2750 | (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))] |
e0d80184 DM |
2751 | "TARGET_CM_MEDANY" |
2752 | "or\\t%1, %%hm(%a2), %0" | |
3bc8b61e DM |
2753 | [(set_attr "type" "ialu") |
2754 | (set_attr "length" "1")]) | |
a8d2b752 | 2755 | |
e0d80184 DM |
2756 | (define_insn "setlo" |
2757 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2758 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
f710f868 | 2759 | (match_operand:DI 2 "symbolic_operand" "")))] |
e0d80184 DM |
2760 | "TARGET_CM_MEDANY" |
2761 | "or\\t%1, %%lo(%a2), %0" | |
3bc8b61e DM |
2762 | [(set_attr "type" "ialu") |
2763 | (set_attr "length" "1")]) | |
e0d80184 DM |
2764 | |
2765 | (define_insn "embmedany_sethi" | |
2766 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2767 | (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))] | |
2768 | "TARGET_CM_EMBMEDANY && check_pic (1)" | |
2769 | "sethi\\t%%hi(%a1), %0" | |
2770 | [(set_attr "type" "move") | |
04e1602e | 2771 | (set_attr "length" "1")]) |
a8d2b752 | 2772 | |
e0d80184 DM |
2773 | (define_insn "embmedany_losum" |
2774 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2775 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
2776 | (match_operand:DI 2 "data_segment_operand" "")))] | |
2777 | "TARGET_CM_EMBMEDANY" | |
2778 | "add\\t%1, %%lo(%a2), %0" | |
3bc8b61e DM |
2779 | [(set_attr "type" "ialu") |
2780 | (set_attr "length" "1")]) | |
a8d2b752 | 2781 | |
e0d80184 DM |
2782 | (define_insn "embmedany_brsum" |
2783 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2784 | (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))] | |
2785 | "TARGET_CM_EMBMEDANY" | |
2786 | "add\\t%1, %_, %0" | |
2787 | [(set_attr "length" "1")]) | |
a8d2b752 | 2788 | |
e0d80184 DM |
2789 | (define_insn "embmedany_textuhi" |
2790 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2791 | (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))] | |
2792 | "TARGET_CM_EMBMEDANY && check_pic (1)" | |
2793 | "sethi\\t%%uhi(%a1), %0" | |
2794 | [(set_attr "type" "move") | |
2795 | (set_attr "length" "1")]) | |
a8d2b752 | 2796 | |
e0d80184 DM |
2797 | (define_insn "embmedany_texthi" |
2798 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2799 | (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))] | |
2800 | "TARGET_CM_EMBMEDANY && check_pic (1)" | |
2801 | "sethi\\t%%hi(%a1), %0" | |
2802 | [(set_attr "type" "move") | |
04e1602e | 2803 | (set_attr "length" "1")]) |
a8d2b752 | 2804 | |
e0d80184 DM |
2805 | (define_insn "embmedany_textulo" |
2806 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2807 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
2808 | (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))] | |
2809 | "TARGET_CM_EMBMEDANY" | |
2810 | "or\\t%1, %%ulo(%a2), %0" | |
3bc8b61e DM |
2811 | [(set_attr "type" "ialu") |
2812 | (set_attr "length" "1")]) | |
b4ac57ab | 2813 | |
e0d80184 DM |
2814 | (define_insn "embmedany_textlo" |
2815 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2816 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
2817 | (match_operand:DI 2 "text_segment_operand" "")))] | |
2818 | "TARGET_CM_EMBMEDANY" | |
2819 | "or\\t%1, %%lo(%a2), %0" | |
3bc8b61e DM |
2820 | [(set_attr "type" "ialu") |
2821 | (set_attr "length" "1")]) | |
a8d2b752 | 2822 | |
e0d80184 DM |
2823 | ;; Now some patterns to help reload out a bit. |
2824 | (define_expand "reload_indi" | |
2825 | [(parallel [(match_operand:DI 0 "register_operand" "=r") | |
2826 | (match_operand:DI 1 "immediate_operand" "") | |
2827 | (match_operand:TI 2 "register_operand" "=&r")])] | |
2828 | "(TARGET_CM_MEDANY | |
2829 | || TARGET_CM_EMBMEDANY) | |
2830 | && ! flag_pic" | |
a8d2b752 DE |
2831 | " |
2832 | { | |
e0d80184 DM |
2833 | sparc_emit_set_symbolic_const64 (operands[0], operands[1], |
2834 | gen_rtx_REG (DImode, REGNO (operands[2]))); | |
2835 | DONE; | |
a8d2b752 DE |
2836 | }") |
2837 | ||
e0d80184 DM |
2838 | (define_expand "reload_outdi" |
2839 | [(parallel [(match_operand:DI 0 "register_operand" "=r") | |
2840 | (match_operand:DI 1 "immediate_operand" "") | |
2841 | (match_operand:TI 2 "register_operand" "=&r")])] | |
2842 | "(TARGET_CM_MEDANY | |
2843 | || TARGET_CM_EMBMEDANY) | |
2844 | && ! flag_pic" | |
7a768814 RS |
2845 | " |
2846 | { | |
e0d80184 DM |
2847 | sparc_emit_set_symbolic_const64 (operands[0], operands[1], |
2848 | gen_rtx_REG (DImode, REGNO (operands[2]))); | |
2849 | DONE; | |
7a768814 RS |
2850 | }") |
2851 | ||
e0d80184 DM |
2852 | ;; Split up putting CONSTs and REGs into DI regs when !arch64 |
2853 | (define_split | |
2854 | [(set (match_operand:DI 0 "register_operand" "") | |
2855 | (match_operand:DI 1 "const_int_operand" ""))] | |
2856 | "! TARGET_ARCH64 && reload_completed" | |
2857 | [(clobber (const_int 0))] | |
2858 | " | |
bfd6bc60 | 2859 | { |
93b7b953 | 2860 | #if HOST_BITS_PER_WIDE_INT == 32 |
e0d80184 DM |
2861 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), |
2862 | (INTVAL (operands[1]) < 0) ? | |
2863 | constm1_rtx : | |
2864 | const0_rtx)); | |
2865 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
2866 | operands[1])); | |
93b7b953 JJ |
2867 | #else |
2868 | unsigned int low, high; | |
2869 | ||
2870 | low = INTVAL (operands[1]) & 0xffffffff; | |
2871 | high = (INTVAL (operands[1]) >> 32) & 0xffffffff; | |
2872 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high))); | |
2873 | ||
2874 | /* Slick... but this trick loses if this subreg constant part | |
2875 | can be done in one insn. */ | |
2876 | if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000) | |
2877 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
2878 | gen_highpart (SImode, operands[0]))); | |
2879 | else | |
2880 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low))); | |
2881 | #endif | |
e0d80184 DM |
2882 | DONE; |
2883 | }") | |
bfd6bc60 | 2884 | |
bfd6bc60 | 2885 | (define_split |
e0d80184 DM |
2886 | [(set (match_operand:DI 0 "register_operand" "") |
2887 | (match_operand:DI 1 "const_double_operand" ""))] | |
2888 | "! TARGET_ARCH64 && reload_completed" | |
2889 | [(clobber (const_int 0))] | |
2890 | " | |
6a4bb1fa | 2891 | { |
e0d80184 DM |
2892 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), |
2893 | GEN_INT (CONST_DOUBLE_HIGH (operands[1])))); | |
2894 | ||
2895 | /* Slick... but this trick loses if this subreg constant part | |
2896 | can be done in one insn. */ | |
2897 | if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1]) | |
2898 | && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1])) | |
2899 | || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))) | |
a8d2b752 | 2900 | { |
e0d80184 DM |
2901 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), |
2902 | gen_highpart (SImode, operands[0]))); | |
a8d2b752 | 2903 | } |
e0d80184 DM |
2904 | else |
2905 | { | |
2906 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
2907 | GEN_INT (CONST_DOUBLE_LOW (operands[1])))); | |
2908 | } | |
2909 | DONE; | |
2910 | }") | |
7a768814 | 2911 | |
e0d80184 DM |
2912 | (define_split |
2913 | [(set (match_operand:DI 0 "register_operand" "") | |
2914 | (match_operand:DI 1 "register_operand" ""))] | |
2915 | "! TARGET_ARCH64 && reload_completed" | |
2916 | [(clobber (const_int 0))] | |
2917 | " | |
2918 | { | |
2919 | rtx set_dest = operands[0]; | |
2920 | rtx set_src = operands[1]; | |
2921 | rtx dest1, dest2; | |
2922 | rtx src1, src2; | |
7a768814 | 2923 | |
e0d80184 DM |
2924 | if (GET_CODE (set_dest) == SUBREG) |
2925 | set_dest = alter_subreg (set_dest); | |
2926 | if (GET_CODE (set_src) == SUBREG) | |
2927 | set_src = alter_subreg (set_src); | |
2928 | ||
2929 | dest1 = gen_highpart (SImode, set_dest); | |
2930 | dest2 = gen_lowpart (SImode, set_dest); | |
2931 | src1 = gen_highpart (SImode, set_src); | |
2932 | src2 = gen_lowpart (SImode, set_src); | |
2933 | ||
2934 | /* Now emit using the real source and destination we found, swapping | |
2935 | the order if we detect overlap. */ | |
0e64f197 | 2936 | if (reg_overlap_mentioned_p (dest1, src2)) |
e0d80184 DM |
2937 | { |
2938 | emit_insn (gen_movsi (dest2, src2)); | |
2939 | emit_insn (gen_movsi (dest1, src1)); | |
2940 | } | |
2941 | else | |
2942 | { | |
2943 | emit_insn (gen_movsi (dest1, src1)); | |
2944 | emit_insn (gen_movsi (dest2, src2)); | |
2945 | } | |
2946 | DONE; | |
2947 | }") | |
2948 | ||
2949 | ;; Now handle the cases of memory moves from/to non-even | |
2950 | ;; DI mode register pairs. | |
2951 | (define_split | |
2952 | [(set (match_operand:DI 0 "register_operand" "") | |
2953 | (match_operand:DI 1 "memory_operand" ""))] | |
2954 | "(! TARGET_ARCH64 | |
2955 | && reload_completed | |
2956 | && sparc_splitdi_legitimate (operands[0], operands[1]))" | |
2957 | [(clobber (const_int 0))] | |
2958 | " | |
795068a4 | 2959 | { |
f4ef873c | 2960 | rtx word0 = adjust_address (operands[1], SImode, 0); |
ed8908e7 | 2961 | rtx word1 = adjust_address (operands[1], SImode, 4); |
e0d80184 DM |
2962 | rtx high_part = gen_highpart (SImode, operands[0]); |
2963 | rtx low_part = gen_lowpart (SImode, operands[0]); | |
e0d80184 | 2964 | |
06424989 | 2965 | if (reg_overlap_mentioned_p (high_part, word1)) |
795068a4 | 2966 | { |
e0d80184 DM |
2967 | emit_insn (gen_movsi (low_part, word1)); |
2968 | emit_insn (gen_movsi (high_part, word0)); | |
795068a4 | 2969 | } |
e0d80184 DM |
2970 | else |
2971 | { | |
2972 | emit_insn (gen_movsi (high_part, word0)); | |
2973 | emit_insn (gen_movsi (low_part, word1)); | |
2974 | } | |
2975 | DONE; | |
2976 | }") | |
2977 | ||
2978 | (define_split | |
2979 | [(set (match_operand:DI 0 "memory_operand" "") | |
2980 | (match_operand:DI 1 "register_operand" ""))] | |
2981 | "(! TARGET_ARCH64 | |
2982 | && reload_completed | |
2983 | && sparc_splitdi_legitimate (operands[1], operands[0]))" | |
2984 | [(clobber (const_int 0))] | |
2985 | " | |
2986 | { | |
ed8908e7 RK |
2987 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), |
2988 | gen_highpart (SImode, operands[1]))); | |
2989 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), | |
2990 | gen_lowpart (SImode, operands[1]))); | |
e0d80184 DM |
2991 | DONE; |
2992 | }") | |
2993 | ||
2994 | \f | |
2995 | ;; Floating point move insns | |
795068a4 | 2996 | |
e6c1be7e | 2997 | (define_insn "*movsf_insn_novis" |
62190128 DM |
2998 | [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m") |
2999 | (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))] | |
e6c1be7e | 3000 | "(TARGET_FPU && ! TARGET_VIS) |
62190128 DM |
3001 | && (register_operand (operands[0], SFmode) |
3002 | || register_operand (operands[1], SFmode) | |
7ce86678 | 3003 | || fp_zero_operand (operands[1], SFmode))" |
45120407 DM |
3004 | "* |
3005 | { | |
62190128 DM |
3006 | if (GET_CODE (operands[1]) == CONST_DOUBLE |
3007 | && (which_alternative == 2 | |
3008 | || which_alternative == 3 | |
3009 | || which_alternative == 4)) | |
3010 | { | |
3011 | REAL_VALUE_TYPE r; | |
3012 | long i; | |
45120407 | 3013 | |
62190128 DM |
3014 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); |
3015 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
3016 | operands[1] = GEN_INT (i); | |
3017 | } | |
45120407 | 3018 | |
62190128 | 3019 | switch (which_alternative) |
45120407 | 3020 | { |
62190128 DM |
3021 | case 0: |
3022 | return \"fmovs\\t%1, %0\"; | |
3023 | case 1: | |
3024 | return \"clr\\t%0\"; | |
3025 | case 2: | |
3026 | return \"sethi\\t%%hi(%a1), %0\"; | |
3027 | case 3: | |
3028 | return \"mov\\t%1, %0\"; | |
3029 | case 4: | |
3030 | return \"#\"; | |
3031 | case 5: | |
3032 | case 6: | |
3033 | return \"ld\\t%1, %0\"; | |
3034 | case 7: | |
3035 | case 8: | |
3036 | return \"st\\t%r1, %0\"; | |
fbd039b2 KG |
3037 | default: |
3038 | abort(); | |
62190128 DM |
3039 | } |
3040 | }" | |
3041 | [(set_attr "type" "fpmove,move,move,move,*,load,fpload,fpstore,store") | |
3042 | (set_attr "length" "1")]) | |
3043 | ||
3044 | (define_insn "*movsf_insn_vis" | |
3045 | [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m") | |
3046 | (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))] | |
3047 | "(TARGET_FPU && TARGET_VIS) | |
3048 | && (register_operand (operands[0], SFmode) | |
3049 | || register_operand (operands[1], SFmode) | |
7ce86678 | 3050 | || fp_zero_operand (operands[1], SFmode))" |
62190128 DM |
3051 | "* |
3052 | { | |
3053 | if (GET_CODE (operands[1]) == CONST_DOUBLE | |
3054 | && (which_alternative == 3 | |
3055 | || which_alternative == 4 | |
3056 | || which_alternative == 5)) | |
3057 | { | |
3058 | REAL_VALUE_TYPE r; | |
3059 | long i; | |
3060 | ||
3061 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
3062 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
45120407 | 3063 | operands[1] = GEN_INT (i); |
45120407 | 3064 | } |
62190128 DM |
3065 | |
3066 | switch (which_alternative) | |
3067 | { | |
3068 | case 0: | |
3069 | return \"fmovs\\t%1, %0\"; | |
3070 | case 1: | |
3071 | return \"fzeros\\t%0\"; | |
3072 | case 2: | |
3073 | return \"clr\\t%0\"; | |
3074 | case 3: | |
3075 | return \"sethi\\t%%hi(%a1), %0\"; | |
3076 | case 4: | |
3077 | return \"mov\\t%1, %0\"; | |
3078 | case 5: | |
3079 | return \"#\"; | |
3080 | case 6: | |
3081 | case 7: | |
3082 | return \"ld\\t%1, %0\"; | |
3083 | case 8: | |
3084 | case 9: | |
3085 | return \"st\\t%r1, %0\"; | |
fbd039b2 KG |
3086 | default: |
3087 | abort(); | |
62190128 | 3088 | } |
45120407 | 3089 | }" |
62190128 | 3090 | [(set_attr "type" "fpmove,fpmove,move,move,move,*,load,fpload,fpstore,store") |
45120407 DM |
3091 | (set_attr "length" "1")]) |
3092 | ||
fd2c87bd GK |
3093 | ;; Exactly the same as above, except that all `f' cases are deleted. |
3094 | ;; This is necessary to prevent reload from ever trying to use a `f' reg | |
3095 | ;; when -mno-fpu. | |
3096 | ||
3097 | (define_insn "*movsf_no_f_insn" | |
3098 | [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m") | |
3099 | (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))] | |
3100 | "! TARGET_FPU | |
3101 | && (register_operand (operands[0], SFmode) | |
3102 | || register_operand (operands[1], SFmode) | |
3103 | || fp_zero_operand (operands[1], SFmode))" | |
3104 | "* | |
3105 | { | |
3106 | if (GET_CODE (operands[1]) == CONST_DOUBLE | |
3107 | && (which_alternative == 1 | |
3108 | || which_alternative == 2 | |
3109 | || which_alternative == 3)) | |
3110 | { | |
3111 | REAL_VALUE_TYPE r; | |
3112 | long i; | |
3113 | ||
3114 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
3115 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
3116 | operands[1] = GEN_INT (i); | |
3117 | } | |
3118 | ||
3119 | switch (which_alternative) | |
3120 | { | |
3121 | case 0: | |
3122 | return \"clr\\t%0\"; | |
3123 | case 1: | |
3124 | return \"sethi\\t%%hi(%a1), %0\"; | |
3125 | case 2: | |
3126 | return \"mov\\t%1, %0\"; | |
3127 | case 3: | |
3128 | return \"#\"; | |
3129 | case 4: | |
3130 | return \"ld\\t%1, %0\"; | |
3131 | case 5: | |
3132 | return \"st\\t%r1, %0\"; | |
3133 | default: | |
3134 | abort(); | |
3135 | } | |
3136 | }" | |
3137 | [(set_attr "type" "move,move,move,*,load,store") | |
3138 | (set_attr "length" "1")]) | |
3139 | ||
62190128 | 3140 | (define_insn "*movsf_lo_sum" |
fd2c87bd GK |
3141 | [(set (match_operand:SF 0 "register_operand" "=r") |
3142 | (lo_sum:SF (match_operand:SF 1 "register_operand" "r") | |
3143 | (match_operand:SF 2 "const_double_operand" "S")))] | |
3144 | "fp_high_losum_p (operands[2])" | |
62190128 DM |
3145 | "* |
3146 | { | |
3147 | REAL_VALUE_TYPE r; | |
3148 | long i; | |
3149 | ||
3150 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); | |
3151 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
3152 | operands[2] = GEN_INT (i); | |
3153 | return \"or\\t%1, %%lo(%a2), %0\"; | |
3154 | }" | |
3155 | [(set_attr "type" "ialu") | |
45120407 DM |
3156 | (set_attr "length" "1")]) |
3157 | ||
62190128 | 3158 | (define_insn "*movsf_high" |
fd2c87bd GK |
3159 | [(set (match_operand:SF 0 "register_operand" "=r") |
3160 | (high:SF (match_operand:SF 1 "const_double_operand" "S")))] | |
3161 | "fp_high_losum_p (operands[1])" | |
62190128 | 3162 | "* |
45120407 DM |
3163 | { |
3164 | REAL_VALUE_TYPE r; | |
3165 | long i; | |
3166 | ||
3167 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
3168 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
3169 | operands[1] = GEN_INT (i); | |
62190128 DM |
3170 | return \"sethi\\t%%hi(%1), %0\"; |
3171 | }" | |
3172 | [(set_attr "type" "move") | |
3173 | (set_attr "length" "1")]) | |
3174 | ||
3175 | (define_split | |
3176 | [(set (match_operand:SF 0 "register_operand" "") | |
3177 | (match_operand:SF 1 "const_double_operand" ""))] | |
fd2c87bd | 3178 | "fp_high_losum_p (operands[1]) |
62190128 DM |
3179 | && (GET_CODE (operands[0]) == REG |
3180 | && REGNO (operands[0]) < 32)" | |
3181 | [(set (match_dup 0) (high:SF (match_dup 1))) | |
3182 | (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))]) | |
3183 | ||
6a4bb1fa DE |
3184 | (define_expand "movsf" |
3185 | [(set (match_operand:SF 0 "general_operand" "") | |
3186 | (match_operand:SF 1 "general_operand" ""))] | |
795068a4 JW |
3187 | "" |
3188 | " | |
3189 | { | |
e0d80184 DM |
3190 | /* Force SFmode constants into memory. */ |
3191 | if (GET_CODE (operands[0]) == REG | |
3192 | && CONSTANT_P (operands[1])) | |
3193 | { | |
3194 | /* emit_group_store will send such bogosity to us when it is | |
3195 | not storing directly into memory. So fix this up to avoid | |
3196 | crashes in output_constant_pool. */ | |
3197 | if (operands [1] == const0_rtx) | |
3198 | operands[1] = CONST0_RTX (SFmode); | |
a5774a7d JJ |
3199 | |
3200 | if (TARGET_VIS && fp_zero_operand (operands[1], SFmode)) | |
3201 | goto movsf_is_ok; | |
3202 | ||
3203 | /* We are able to build any SF constant in integer registers | |
3204 | with at most 2 instructions. */ | |
3205 | if (REGNO (operands[0]) < 32) | |
3206 | goto movsf_is_ok; | |
3207 | ||
e0d80184 DM |
3208 | operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), |
3209 | operands[1])); | |
3210 | } | |
3211 | ||
3212 | /* Handle sets of MEM first. */ | |
3213 | if (GET_CODE (operands[0]) == MEM) | |
3214 | { | |
62190128 | 3215 | if (register_operand (operands[1], SFmode) |
e6c1be7e | 3216 | || fp_zero_operand (operands[1], SFmode)) |
e0d80184 DM |
3217 | goto movsf_is_ok; |
3218 | ||
3219 | if (! reload_in_progress) | |
3220 | { | |
3221 | operands[0] = validize_mem (operands[0]); | |
3222 | operands[1] = force_reg (SFmode, operands[1]); | |
3223 | } | |
3224 | } | |
3225 | ||
3226 | /* Fixup PIC cases. */ | |
3227 | if (flag_pic) | |
3228 | { | |
3229 | if (CONSTANT_P (operands[1]) | |
3230 | && pic_address_needs_scratch (operands[1])) | |
3231 | operands[1] = legitimize_pic_address (operands[1], SFmode, 0); | |
3232 | ||
3233 | if (symbolic_operand (operands[1], SFmode)) | |
3234 | { | |
3235 | operands[1] = legitimize_pic_address (operands[1], | |
3236 | SFmode, | |
3237 | (reload_in_progress ? | |
3238 | operands[0] : | |
3239 | NULL_RTX)); | |
3240 | } | |
3241 | } | |
3242 | ||
3243 | movsf_is_ok: | |
5f78aa30 | 3244 | ; |
795068a4 JW |
3245 | }") |
3246 | ||
7a768814 RS |
3247 | (define_expand "movdf" |
3248 | [(set (match_operand:DF 0 "general_operand" "") | |
3249 | (match_operand:DF 1 "general_operand" ""))] | |
3250 | "" | |
3251 | " | |
3252 | { | |
e0d80184 DM |
3253 | /* Force DFmode constants into memory. */ |
3254 | if (GET_CODE (operands[0]) == REG | |
3255 | && CONSTANT_P (operands[1])) | |
3256 | { | |
3257 | /* emit_group_store will send such bogosity to us when it is | |
3258 | not storing directly into memory. So fix this up to avoid | |
3259 | crashes in output_constant_pool. */ | |
3260 | if (operands [1] == const0_rtx) | |
3261 | operands[1] = CONST0_RTX (DFmode); | |
a5774a7d JJ |
3262 | |
3263 | if ((TARGET_VIS || REGNO (operands[0]) < 32) | |
3264 | && fp_zero_operand (operands[1], DFmode)) | |
3265 | goto movdf_is_ok; | |
3266 | ||
e0d80184 DM |
3267 | operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), |
3268 | operands[1])); | |
3269 | } | |
3270 | ||
3271 | /* Handle MEM cases first. */ | |
3272 | if (GET_CODE (operands[0]) == MEM) | |
3273 | { | |
a5774a7d JJ |
3274 | if (register_operand (operands[1], DFmode) |
3275 | || fp_zero_operand (operands[1], DFmode)) | |
e0d80184 DM |
3276 | goto movdf_is_ok; |
3277 | ||
3278 | if (! reload_in_progress) | |
3279 | { | |
3280 | operands[0] = validize_mem (operands[0]); | |
3281 | operands[1] = force_reg (DFmode, operands[1]); | |
3282 | } | |
3283 | } | |
3284 | ||
3285 | /* Fixup PIC cases. */ | |
3286 | if (flag_pic) | |
3287 | { | |
3288 | if (CONSTANT_P (operands[1]) | |
3289 | && pic_address_needs_scratch (operands[1])) | |
3290 | operands[1] = legitimize_pic_address (operands[1], DFmode, 0); | |
3291 | ||
3292 | if (symbolic_operand (operands[1], DFmode)) | |
3293 | { | |
3294 | operands[1] = legitimize_pic_address (operands[1], | |
3295 | DFmode, | |
3296 | (reload_in_progress ? | |
3297 | operands[0] : | |
3298 | NULL_RTX)); | |
3299 | } | |
3300 | } | |
3301 | ||
3302 | movdf_is_ok: | |
5f78aa30 | 3303 | ; |
7a768814 RS |
3304 | }") |
3305 | ||
71648202 | 3306 | ;; Be careful, fmovd does not exist when !v9. |
e0d80184 | 3307 | (define_insn "*movdf_insn_sp32" |
a5774a7d JJ |
3308 | [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o") |
3309 | (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))] | |
ab5519b7 | 3310 | "TARGET_FPU |
71648202 | 3311 | && ! TARGET_V9 |
ab5519b7 | 3312 | && (register_operand (operands[0], DFmode) |
a5774a7d JJ |
3313 | || register_operand (operands[1], DFmode) |
3314 | || fp_zero_operand (operands[1], DFmode))" | |
e0d80184 DM |
3315 | "@ |
3316 | ldd\\t%1, %0 | |
3317 | std\\t%1, %0 | |
3318 | ldd\\t%1, %0 | |
3319 | std\\t%1, %0 | |
3320 | # | |
3321 | # | |
3322 | # | |
3323 | # | |
3324 | # | |
3325 | #" | |
3326 | [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*") | |
3327 | (set_attr "length" "1,1,1,1,2,2,2,2,2,2")]) | |
3328 | ||
3329 | (define_insn "*movdf_no_e_insn_sp32" | |
a5774a7d JJ |
3330 | [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o") |
3331 | (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))] | |
ab5519b7 | 3332 | "! TARGET_FPU |
a5774a7d | 3333 | && ! TARGET_V9 |
e0d80184 DM |
3334 | && ! TARGET_ARCH64 |
3335 | && (register_operand (operands[0], DFmode) | |
a5774a7d JJ |
3336 | || register_operand (operands[1], DFmode) |
3337 | || fp_zero_operand (operands[1], DFmode))" | |
e0d80184 DM |
3338 | "@ |
3339 | ldd\\t%1, %0 | |
3340 | std\\t%1, %0 | |
3341 | # | |
3342 | # | |
3343 | #" | |
3344 | [(set_attr "type" "load,store,*,*,*") | |
3345 | (set_attr "length" "1,1,2,2,2")]) | |
3346 | ||
a5774a7d JJ |
3347 | (define_insn "*movdf_no_e_insn_v9_sp32" |
3348 | [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o") | |
3349 | (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))] | |
3350 | "! TARGET_FPU | |
3351 | && TARGET_V9 | |
3352 | && ! TARGET_ARCH64 | |
3353 | && (register_operand (operands[0], DFmode) | |
3354 | || register_operand (operands[1], DFmode) | |
3355 | || fp_zero_operand (operands[1], DFmode))" | |
3356 | "@ | |
3357 | ldd\\t%1, %0 | |
3358 | std\\t%1, %0 | |
3359 | stx\\t%r1, %0 | |
3360 | # | |
3361 | #" | |
3362 | [(set_attr "type" "load,store,store,*,*") | |
3363 | (set_attr "length" "1,1,1,2,2")]) | |
3364 | ||
71648202 | 3365 | ;; We have available v9 double floats but not 64-bit |
a5774a7d JJ |
3366 | ;; integer registers and no VIS. |
3367 | (define_insn "*movdf_insn_v9only_novis" | |
3368 | [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o") | |
3369 | (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))] | |
71648202 DM |
3370 | "TARGET_FPU |
3371 | && TARGET_V9 | |
a5774a7d JJ |
3372 | && ! TARGET_VIS |
3373 | && ! TARGET_ARCH64 | |
3374 | && (register_operand (operands[0], DFmode) | |
3375 | || register_operand (operands[1], DFmode) | |
3376 | || fp_zero_operand (operands[1], DFmode))" | |
3377 | "@ | |
3378 | fmovd\\t%1, %0 | |
3379 | ldd\\t%1, %0 | |
3380 | stx\\t%r1, %0 | |
3381 | std\\t%1, %0 | |
3382 | ldd\\t%1, %0 | |
3383 | std\\t%1, %0 | |
3384 | # | |
3385 | # | |
3386 | #" | |
3387 | [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*") | |
3388 | (set_attr "length" "1,1,1,1,1,1,2,2,2")]) | |
3389 | ||
3390 | ;; We have available v9 double floats but not 64-bit | |
3391 | ;; integer registers but we have VIS. | |
3392 | (define_insn "*movdf_insn_v9only_vis" | |
3393 | [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o") | |
3394 | (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))] | |
3395 | "TARGET_FPU | |
3396 | && TARGET_VIS | |
71648202 DM |
3397 | && ! TARGET_ARCH64 |
3398 | && (register_operand (operands[0], DFmode) | |
a5774a7d JJ |
3399 | || register_operand (operands[1], DFmode) |
3400 | || fp_zero_operand (operands[1], DFmode))" | |
71648202 | 3401 | "@ |
1f046771 | 3402 | fzero\\t%0 |
71648202 DM |
3403 | fmovd\\t%1, %0 |
3404 | ldd\\t%1, %0 | |
a5774a7d | 3405 | stx\\t%r1, %0 |
71648202 DM |
3406 | std\\t%1, %0 |
3407 | ldd\\t%1, %0 | |
3408 | std\\t%1, %0 | |
3409 | # | |
3410 | # | |
3411 | #" | |
a5774a7d JJ |
3412 | [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*") |
3413 | (set_attr "length" "1,1,1,1,1,1,1,2,2,2")]) | |
71648202 DM |
3414 | |
3415 | ;; We have available both v9 double floats and 64-bit | |
a5774a7d JJ |
3416 | ;; integer registers. No VIS though. |
3417 | (define_insn "*movdf_insn_sp64_novis" | |
3418 | [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r") | |
3419 | (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))] | |
e0d80184 | 3420 | "TARGET_FPU |
a5774a7d | 3421 | && ! TARGET_VIS |
e0d80184 | 3422 | && TARGET_ARCH64 |
ab5519b7 | 3423 | && (register_operand (operands[0], DFmode) |
a5774a7d JJ |
3424 | || register_operand (operands[1], DFmode) |
3425 | || fp_zero_operand (operands[1], DFmode))" | |
e0d80184 DM |
3426 | "@ |
3427 | fmovd\\t%1, %0 | |
3428 | ldd\\t%1, %0 | |
3429 | std\\t%1, %0 | |
a5774a7d | 3430 | mov\\t%r1, %0 |
e0d80184 | 3431 | ldx\\t%1, %0 |
a5774a7d JJ |
3432 | stx\\t%r1, %0 |
3433 | #" | |
3434 | [(set_attr "type" "fpmove,load,store,move,load,store,*") | |
3435 | (set_attr "length" "1,1,1,1,1,1,2")]) | |
3436 | ||
3437 | ;; We have available both v9 double floats and 64-bit | |
3438 | ;; integer registers. And we have VIS. | |
3439 | (define_insn "*movdf_insn_sp64_vis" | |
3440 | [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r") | |
3441 | (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))] | |
3442 | "TARGET_FPU | |
3443 | && TARGET_VIS | |
3444 | && TARGET_ARCH64 | |
3445 | && (register_operand (operands[0], DFmode) | |
3446 | || register_operand (operands[1], DFmode) | |
3447 | || fp_zero_operand (operands[1], DFmode))" | |
3448 | "@ | |
3449 | fzero\\t%0 | |
3450 | fmovd\\t%1, %0 | |
3451 | ldd\\t%1, %0 | |
3452 | std\\t%1, %0 | |
3453 | mov\\t%r1, %0 | |
3454 | ldx\\t%1, %0 | |
3455 | stx\\t%r1, %0 | |
3456 | #" | |
3457 | [(set_attr "type" "fpmove,fpmove,load,store,move,load,store,*") | |
3458 | (set_attr "length" "1,1,1,1,1,1,1,2")]) | |
ab5519b7 | 3459 | |
e0d80184 | 3460 | (define_insn "*movdf_no_e_insn_sp64" |
db7eb3e8 | 3461 | [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m") |
a5774a7d | 3462 | (match_operand:DF 1 "input_operand" "r,m,rG"))] |
e0d80184 DM |
3463 | "! TARGET_FPU |
3464 | && TARGET_ARCH64 | |
3465 | && (register_operand (operands[0], DFmode) | |
a5774a7d JJ |
3466 | || register_operand (operands[1], DFmode) |
3467 | || fp_zero_operand (operands[1], DFmode))" | |
e0d80184 DM |
3468 | "@ |
3469 | mov\\t%1, %0 | |
3470 | ldx\\t%1, %0 | |
a5774a7d | 3471 | stx\\t%r1, %0" |
e0d80184 DM |
3472 | [(set_attr "type" "move,load,store") |
3473 | (set_attr "length" "1")]) | |
9ad2334b | 3474 | |
a5774a7d JJ |
3475 | (define_split |
3476 | [(set (match_operand:DF 0 "register_operand" "") | |
3477 | (match_operand:DF 1 "const_double_operand" ""))] | |
3478 | "TARGET_FPU | |
3479 | && (GET_CODE (operands[0]) == REG | |
3480 | && REGNO (operands[0]) < 32) | |
3481 | && ! fp_zero_operand(operands[1], DFmode) | |
3482 | && reload_completed" | |
3483 | [(clobber (const_int 0))] | |
3484 | " | |
3485 | { | |
3486 | REAL_VALUE_TYPE r; | |
3487 | long l[2]; | |
3488 | ||
3489 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
3490 | REAL_VALUE_TO_TARGET_DOUBLE (r, l); | |
3491 | if (GET_CODE (operands[0]) == SUBREG) | |
3492 | operands[0] = alter_subreg (operands[0]); | |
3493 | operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0])); | |
3494 | ||
3495 | if (TARGET_ARCH64) | |
3496 | { | |
3497 | #if HOST_BITS_PER_WIDE_INT == 64 | |
3498 | HOST_WIDE_INT val; | |
3499 | ||
3500 | val = ((HOST_WIDE_INT)(unsigned long)l[1] | | |
3501 | ((HOST_WIDE_INT)(unsigned long)l[0] << 32)); | |
3502 | emit_insn (gen_movdi (operands[0], GEN_INT (val))); | |
3503 | #else | |
3504 | emit_insn (gen_movdi (operands[0], | |
3505 | gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx, | |
3506 | l[1], l[0]))); | |
3507 | #endif | |
3508 | } | |
3509 | else | |
3510 | { | |
3511 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), | |
3512 | GEN_INT (l[0]))); | |
3513 | ||
3514 | /* Slick... but this trick loses if this subreg constant part | |
3515 | can be done in one insn. */ | |
3516 | if (l[1] == l[0] | |
3517 | && !(SPARC_SETHI_P (l[0]) | |
3518 | || SPARC_SIMM13_P (l[0]))) | |
3519 | { | |
3520 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
3521 | gen_highpart (SImode, operands[0]))); | |
3522 | } | |
3523 | else | |
3524 | { | |
3525 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
3526 | GEN_INT (l[1]))); | |
3527 | } | |
3528 | } | |
3529 | DONE; | |
3530 | }") | |
3531 | ||
e0d80184 DM |
3532 | ;; Ok, now the splits to handle all the multi insn and |
3533 | ;; mis-aligned memory address cases. | |
71648202 DM |
3534 | ;; In these splits please take note that we must be |
3535 | ;; careful when V9 but not ARCH64 because the integer | |
3536 | ;; register DFmode cases must be handled. | |
ae0cab49 JW |
3537 | (define_split |
3538 | [(set (match_operand:DF 0 "register_operand" "") | |
e0d80184 | 3539 | (match_operand:DF 1 "register_operand" ""))] |
71648202 DM |
3540 | "(! TARGET_V9 |
3541 | || (! TARGET_ARCH64 | |
e61c29e9 DM |
3542 | && ((GET_CODE (operands[0]) == REG |
3543 | && REGNO (operands[0]) < 32) | |
3544 | || (GET_CODE (operands[0]) == SUBREG | |
3545 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
3546 | && REGNO (SUBREG_REG (operands[0])) < 32)))) | |
71648202 | 3547 | && reload_completed" |
e0d80184 | 3548 | [(clobber (const_int 0))] |
ae0cab49 | 3549 | " |
63f7136f | 3550 | { |
e0d80184 DM |
3551 | rtx set_dest = operands[0]; |
3552 | rtx set_src = operands[1]; | |
3553 | rtx dest1, dest2; | |
3554 | rtx src1, src2; | |
3555 | ||
3556 | if (GET_CODE (set_dest) == SUBREG) | |
3557 | set_dest = alter_subreg (set_dest); | |
3558 | if (GET_CODE (set_src) == SUBREG) | |
3559 | set_src = alter_subreg (set_src); | |
63f7136f | 3560 | |
e0d80184 DM |
3561 | dest1 = gen_highpart (SFmode, set_dest); |
3562 | dest2 = gen_lowpart (SFmode, set_dest); | |
3563 | src1 = gen_highpart (SFmode, set_src); | |
3564 | src2 = gen_lowpart (SFmode, set_src); | |
3565 | ||
3566 | /* Now emit using the real source and destination we found, swapping | |
3567 | the order if we detect overlap. */ | |
0e64f197 | 3568 | if (reg_overlap_mentioned_p (dest1, src2)) |
63f7136f | 3569 | { |
e0d80184 DM |
3570 | emit_insn (gen_movsf (dest2, src2)); |
3571 | emit_insn (gen_movsf (dest1, src1)); | |
63f7136f JW |
3572 | } |
3573 | else | |
3574 | { | |
e0d80184 DM |
3575 | emit_insn (gen_movsf (dest1, src1)); |
3576 | emit_insn (gen_movsf (dest2, src2)); | |
63f7136f | 3577 | } |
e0d80184 | 3578 | DONE; |
63f7136f | 3579 | }") |
ae0cab49 | 3580 | |
e0d80184 DM |
3581 | (define_split |
3582 | [(set (match_operand:DF 0 "register_operand" "") | |
3583 | (match_operand:DF 1 "memory_operand" ""))] | |
a5774a7d JJ |
3584 | "reload_completed |
3585 | && ! TARGET_ARCH64 | |
3586 | && (((REGNO (operands[0]) % 2) != 0) | |
3587 | || ! mem_min_alignment (operands[1], 8)) | |
3588 | && offsettable_memref_p (operands[1])" | |
e0d80184 DM |
3589 | [(clobber (const_int 0))] |
3590 | " | |
7a768814 | 3591 | { |
f4ef873c | 3592 | rtx word0 = adjust_address (operands[1], SFmode, 0); |
ed8908e7 | 3593 | rtx word1 = adjust_address (operands[1], SFmode, 4); |
e0d80184 | 3594 | |
03ad6f4d DM |
3595 | if (GET_CODE (operands[0]) == SUBREG) |
3596 | operands[0] = alter_subreg (operands[0]); | |
3597 | ||
06424989 | 3598 | if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1)) |
e0d80184 DM |
3599 | { |
3600 | emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]), | |
3601 | word1)); | |
3602 | emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]), | |
3603 | word0)); | |
3604 | } | |
7a768814 | 3605 | else |
2b9a9aea | 3606 | { |
e0d80184 DM |
3607 | emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]), |
3608 | word0)); | |
3609 | emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]), | |
3610 | word1)); | |
2b9a9aea | 3611 | } |
e0d80184 DM |
3612 | DONE; |
3613 | }") | |
3614 | ||
3615 | (define_split | |
3616 | [(set (match_operand:DF 0 "memory_operand" "") | |
3617 | (match_operand:DF 1 "register_operand" ""))] | |
a5774a7d JJ |
3618 | "reload_completed |
3619 | && ! TARGET_ARCH64 | |
3620 | && (((REGNO (operands[1]) % 2) != 0) | |
3621 | || ! mem_min_alignment (operands[0], 8)) | |
3622 | && offsettable_memref_p (operands[0])" | |
e0d80184 DM |
3623 | [(clobber (const_int 0))] |
3624 | " | |
3625 | { | |
f4ef873c | 3626 | rtx word0 = adjust_address (operands[0], SFmode, 0); |
ed8908e7 | 3627 | rtx word1 = adjust_address (operands[0], SFmode, 4); |
e0d80184 | 3628 | |
03ad6f4d DM |
3629 | if (GET_CODE (operands[1]) == SUBREG) |
3630 | operands[1] = alter_subreg (operands[1]); | |
e0d80184 DM |
3631 | emit_insn (gen_movsf (word0, |
3632 | gen_highpart (SFmode, operands[1]))); | |
3633 | emit_insn (gen_movsf (word1, | |
3634 | gen_lowpart (SFmode, operands[1]))); | |
3635 | DONE; | |
3636 | }") | |
2b9a9aea | 3637 | |
0f63333c | 3638 | (define_split |
a5774a7d JJ |
3639 | [(set (match_operand:DF 0 "memory_operand" "") |
3640 | (match_operand:DF 1 "fp_zero_operand" ""))] | |
3641 | "reload_completed | |
3642 | && (! TARGET_V9 | |
3643 | || (! TARGET_ARCH64 | |
3644 | && ! mem_min_alignment (operands[0], 8))) | |
3645 | && offsettable_memref_p (operands[0])" | |
3646 | [(clobber (const_int 0))] | |
0f63333c JJ |
3647 | " |
3648 | { | |
a5774a7d | 3649 | rtx dest1, dest2; |
0f63333c | 3650 | |
f4ef873c | 3651 | dest1 = adjust_address (operands[0], SFmode, 0); |
ed8908e7 RK |
3652 | dest2 = adjust_address (operands[0], SFmode, 4); |
3653 | ||
a5774a7d JJ |
3654 | emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode))); |
3655 | emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode))); | |
3656 | DONE; | |
3657 | }") | |
0f63333c JJ |
3658 | |
3659 | (define_split | |
a5774a7d JJ |
3660 | [(set (match_operand:DF 0 "register_operand" "") |
3661 | (match_operand:DF 1 "fp_zero_operand" ""))] | |
3662 | "reload_completed | |
3663 | && ! TARGET_ARCH64 | |
3664 | && ((GET_CODE (operands[0]) == REG | |
3665 | && REGNO (operands[0]) < 32) | |
3666 | || (GET_CODE (operands[0]) == SUBREG | |
3667 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
3668 | && REGNO (SUBREG_REG (operands[0])) < 32))" | |
3669 | [(clobber (const_int 0))] | |
0f63333c JJ |
3670 | " |
3671 | { | |
a5774a7d JJ |
3672 | rtx set_dest = operands[0]; |
3673 | rtx dest1, dest2; | |
3674 | ||
3675 | if (GET_CODE (set_dest) == SUBREG) | |
3676 | set_dest = alter_subreg (set_dest); | |
3677 | dest1 = gen_highpart (SFmode, set_dest); | |
3678 | dest2 = gen_lowpart (SFmode, set_dest); | |
3679 | emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode))); | |
3680 | emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode))); | |
3681 | DONE; | |
3682 | }") | |
0f63333c | 3683 | |
6a4bb1fa DE |
3684 | (define_expand "movtf" |
3685 | [(set (match_operand:TF 0 "general_operand" "") | |
3686 | (match_operand:TF 1 "general_operand" ""))] | |
7a768814 RS |
3687 | "" |
3688 | " | |
3689 | { | |
e0d80184 DM |
3690 | /* Force TFmode constants into memory. */ |
3691 | if (GET_CODE (operands[0]) == REG | |
3692 | && CONSTANT_P (operands[1])) | |
3693 | { | |
3694 | /* emit_group_store will send such bogosity to us when it is | |
3695 | not storing directly into memory. So fix this up to avoid | |
3696 | crashes in output_constant_pool. */ | |
3697 | if (operands [1] == const0_rtx) | |
3698 | operands[1] = CONST0_RTX (TFmode); | |
a5774a7d JJ |
3699 | |
3700 | if (TARGET_VIS && fp_zero_operand (operands[1], TFmode)) | |
3701 | goto movtf_is_ok; | |
3702 | ||
e0d80184 DM |
3703 | operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), |
3704 | operands[1])); | |
3705 | } | |
3706 | ||
03ad6f4d DM |
3707 | /* Handle MEM cases first, note that only v9 guarentees |
3708 | full 16-byte alignment for quads. */ | |
e0d80184 DM |
3709 | if (GET_CODE (operands[0]) == MEM) |
3710 | { | |
a5774a7d JJ |
3711 | if (register_operand (operands[1], TFmode) |
3712 | || fp_zero_operand (operands[1], TFmode)) | |
3713 | goto movtf_is_ok; | |
e0d80184 DM |
3714 | |
3715 | if (! reload_in_progress) | |
3716 | { | |
3717 | operands[0] = validize_mem (operands[0]); | |
3718 | operands[1] = force_reg (TFmode, operands[1]); | |
3719 | } | |
3720 | } | |
3721 | ||
3722 | /* Fixup PIC cases. */ | |
3723 | if (flag_pic) | |
3724 | { | |
3725 | if (CONSTANT_P (operands[1]) | |
3726 | && pic_address_needs_scratch (operands[1])) | |
3727 | operands[1] = legitimize_pic_address (operands[1], TFmode, 0); | |
3728 | ||
3729 | if (symbolic_operand (operands[1], TFmode)) | |
3730 | { | |
3731 | operands[1] = legitimize_pic_address (operands[1], | |
3732 | TFmode, | |
3733 | (reload_in_progress ? | |
3734 | operands[0] : | |
3735 | NULL_RTX)); | |
3736 | } | |
3737 | } | |
3738 | ||
5f78aa30 JC |
3739 | movtf_is_ok: |
3740 | ; | |
7a768814 RS |
3741 | }") |
3742 | ||
e0d80184 DM |
3743 | ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so |
3744 | ;; we must split them all. :-( | |
3745 | (define_insn "*movtf_insn_sp32" | |
1573b933 JJ |
3746 | [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r") |
3747 | (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))] | |
ab5519b7 | 3748 | "TARGET_FPU |
a5774a7d | 3749 | && ! TARGET_VIS |
e0d80184 | 3750 | && ! TARGET_ARCH64 |
6a4bb1fa | 3751 | && (register_operand (operands[0], TFmode) |
a5774a7d JJ |
3752 | || register_operand (operands[1], TFmode) |
3753 | || fp_zero_operand (operands[1], TFmode))" | |
3754 | "#" | |
3755 | [(set_attr "length" "4")]) | |
3756 | ||
3757 | (define_insn "*movtf_insn_vis_sp32" | |
1573b933 JJ |
3758 | [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r") |
3759 | (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))] | |
a5774a7d JJ |
3760 | "TARGET_FPU |
3761 | && TARGET_VIS | |
3762 | && ! TARGET_ARCH64 | |
3763 | && (register_operand (operands[0], TFmode) | |
3764 | || register_operand (operands[1], TFmode) | |
3765 | || fp_zero_operand (operands[1], TFmode))" | |
e0d80184 DM |
3766 | "#" |
3767 | [(set_attr "length" "4")]) | |
7a768814 | 3768 | |
b6d3c4ba JW |
3769 | ;; Exactly the same as above, except that all `e' cases are deleted. |
3770 | ;; This is necessary to prevent reload from ever trying to use a `e' reg | |
ab5519b7 JW |
3771 | ;; when -mno-fpu. |
3772 | ||
e0d80184 | 3773 | (define_insn "*movtf_no_e_insn_sp32" |
a5774a7d | 3774 | [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o") |
1573b933 | 3775 | (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))] |
ab5519b7 | 3776 | "! TARGET_FPU |
e0d80184 | 3777 | && ! TARGET_ARCH64 |
6a4bb1fa | 3778 | && (register_operand (operands[0], TFmode) |
a5774a7d JJ |
3779 | || register_operand (operands[1], TFmode) |
3780 | || fp_zero_operand (operands[1], TFmode))" | |
e0d80184 DM |
3781 | "#" |
3782 | [(set_attr "length" "4")]) | |
3783 | ||
3784 | ;; Now handle the float reg cases directly when arch64, | |
3785 | ;; hard_quad, and proper reg number alignment are all true. | |
3786 | (define_insn "*movtf_insn_hq_sp64" | |
1573b933 JJ |
3787 | [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r") |
3788 | (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))] | |
e0d80184 | 3789 | "TARGET_FPU |
a5774a7d | 3790 | && ! TARGET_VIS |
e0d80184 | 3791 | && TARGET_ARCH64 |
e0d80184 DM |
3792 | && TARGET_HARD_QUAD |
3793 | && (register_operand (operands[0], TFmode) | |
a5774a7d JJ |
3794 | || register_operand (operands[1], TFmode) |
3795 | || fp_zero_operand (operands[1], TFmode))" | |
3796 | "@ | |
3797 | fmovq\\t%1, %0 | |
3798 | ldq\\t%1, %0 | |
3799 | stq\\t%1, %0 | |
3800 | # | |
a5774a7d | 3801 | #" |
1573b933 JJ |
3802 | [(set_attr "type" "fpmove,fpload,fpstore,*,*") |
3803 | (set_attr "length" "1,1,1,2,2")]) | |
a5774a7d JJ |
3804 | |
3805 | (define_insn "*movtf_insn_hq_vis_sp64" | |
3806 | [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o") | |
1573b933 | 3807 | (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))] |
a5774a7d JJ |
3808 | "TARGET_FPU |
3809 | && TARGET_VIS | |
3810 | && TARGET_ARCH64 | |
3811 | && TARGET_HARD_QUAD | |
3812 | && (register_operand (operands[0], TFmode) | |
3813 | || register_operand (operands[1], TFmode) | |
3814 | || fp_zero_operand (operands[1], TFmode))" | |
e0d80184 DM |
3815 | "@ |
3816 | fmovq\\t%1, %0 | |
3817 | ldq\\t%1, %0 | |
3818 | stq\\t%1, %0 | |
3819 | # | |
3820 | # | |
3821 | #" | |
3822 | [(set_attr "type" "fpmove,fpload,fpstore,*,*,*") | |
3823 | (set_attr "length" "1,1,1,2,2,2")]) | |
3824 | ||
3825 | ;; Now we allow the integer register cases even when | |
3826 | ;; only arch64 is true. | |
3827 | (define_insn "*movtf_insn_sp64" | |
1573b933 JJ |
3828 | [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r") |
3829 | (match_operand:TF 1 "input_operand" "oe,Ger,orG"))] | |
a5774a7d JJ |
3830 | "TARGET_FPU |
3831 | && ! TARGET_VIS | |
3832 | && TARGET_ARCH64 | |
3833 | && ! TARGET_HARD_QUAD | |
3834 | && (register_operand (operands[0], TFmode) | |
3835 | || register_operand (operands[1], TFmode) | |
3836 | || fp_zero_operand (operands[1], TFmode))" | |
3837 | "#" | |
3838 | [(set_attr "length" "2")]) | |
3839 | ||
3840 | (define_insn "*movtf_insn_vis_sp64" | |
1573b933 JJ |
3841 | [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r") |
3842 | (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))] | |
e0d80184 | 3843 | "TARGET_FPU |
a5774a7d | 3844 | && TARGET_VIS |
e0d80184 DM |
3845 | && TARGET_ARCH64 |
3846 | && ! TARGET_HARD_QUAD | |
3847 | && (register_operand (operands[0], TFmode) | |
a5774a7d JJ |
3848 | || register_operand (operands[1], TFmode) |
3849 | || fp_zero_operand (operands[1], TFmode))" | |
e0d80184 DM |
3850 | "#" |
3851 | [(set_attr "length" "2")]) | |
3852 | ||
3853 | (define_insn "*movtf_no_e_insn_sp64" | |
a5774a7d | 3854 | [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o") |
1573b933 | 3855 | (match_operand:TF 1 "input_operand" "orG,rG"))] |
e0d80184 DM |
3856 | "! TARGET_FPU |
3857 | && TARGET_ARCH64 | |
3858 | && (register_operand (operands[0], TFmode) | |
a5774a7d JJ |
3859 | || register_operand (operands[1], TFmode) |
3860 | || fp_zero_operand (operands[1], TFmode))" | |
e0d80184 DM |
3861 | "#" |
3862 | [(set_attr "length" "2")]) | |
3863 | ||
3864 | ;; Now all the splits to handle multi-insn TF mode moves. | |
3865 | (define_split | |
3866 | [(set (match_operand:TF 0 "register_operand" "") | |
3867 | (match_operand:TF 1 "register_operand" ""))] | |
3868 | "reload_completed | |
3869 | && (! TARGET_ARCH64 | |
3870 | || (TARGET_FPU | |
3871 | && ! TARGET_HARD_QUAD))" | |
3872 | [(clobber (const_int 0))] | |
3873 | " | |
6a4bb1fa | 3874 | { |
e0d80184 DM |
3875 | rtx set_dest = operands[0]; |
3876 | rtx set_src = operands[1]; | |
3877 | rtx dest1, dest2; | |
3878 | rtx src1, src2; | |
3879 | ||
3880 | if (GET_CODE (set_dest) == SUBREG) | |
3881 | set_dest = alter_subreg (set_dest); | |
3882 | if (GET_CODE (set_src) == SUBREG) | |
3883 | set_src = alter_subreg (set_src); | |
3884 | ||
7b1ac798 JJ |
3885 | dest1 = gen_df_reg (set_dest, 0); |
3886 | dest2 = gen_df_reg (set_dest, 1); | |
3887 | src1 = gen_df_reg (set_src, 0); | |
3888 | src2 = gen_df_reg (set_src, 1); | |
e0d80184 DM |
3889 | |
3890 | /* Now emit using the real source and destination we found, swapping | |
3891 | the order if we detect overlap. */ | |
0e64f197 | 3892 | if (reg_overlap_mentioned_p (dest1, src2)) |
e0d80184 DM |
3893 | { |
3894 | emit_insn (gen_movdf (dest2, src2)); | |
3895 | emit_insn (gen_movdf (dest1, src1)); | |
3896 | } | |
6a4bb1fa | 3897 | else |
e0d80184 DM |
3898 | { |
3899 | emit_insn (gen_movdf (dest1, src1)); | |
3900 | emit_insn (gen_movdf (dest2, src2)); | |
3901 | } | |
3902 | DONE; | |
3903 | }") | |
3904 | ||
a5774a7d JJ |
3905 | (define_split |
3906 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
3907 | (match_operand:TF 1 "fp_zero_operand" ""))] | |
3908 | "reload_completed" | |
3909 | [(clobber (const_int 0))] | |
3910 | " | |
3911 | { | |
3912 | rtx set_dest = operands[0]; | |
3913 | rtx dest1, dest2; | |
3914 | ||
3915 | switch (GET_CODE (set_dest)) | |
3916 | { | |
3917 | case SUBREG: | |
3918 | set_dest = alter_subreg (set_dest); | |
3919 | /* FALLTHROUGH */ | |
3920 | case REG: | |
3921 | dest1 = gen_df_reg (set_dest, 0); | |
3922 | dest2 = gen_df_reg (set_dest, 1); | |
3923 | break; | |
3924 | case MEM: | |
f4ef873c | 3925 | dest1 = adjust_address (set_dest, DFmode, 0); |
ed8908e7 | 3926 | dest2 = adjust_address (set_dest, DFmode, 8); |
a5774a7d JJ |
3927 | break; |
3928 | default: | |
3929 | abort (); | |
3930 | } | |
3931 | ||
3932 | emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode))); | |
3933 | emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode))); | |
3934 | DONE; | |
3935 | }") | |
3936 | ||
e0d80184 DM |
3937 | (define_split |
3938 | [(set (match_operand:TF 0 "register_operand" "") | |
3939 | (match_operand:TF 1 "memory_operand" ""))] | |
3940 | "(reload_completed | |
3941 | && offsettable_memref_p (operands[1]))" | |
3942 | [(clobber (const_int 0))] | |
3943 | " | |
3944 | { | |
f4ef873c | 3945 | rtx word0 = adjust_address (operands[1], DFmode, 0); |
ed8908e7 | 3946 | rtx word1 = adjust_address (operands[1], DFmode, 8); |
ccd61a80 DM |
3947 | rtx set_dest, dest1, dest2; |
3948 | ||
3949 | set_dest = operands[0]; | |
3950 | if (GET_CODE (set_dest) == SUBREG) | |
3951 | set_dest = alter_subreg (set_dest); | |
e0d80184 | 3952 | |
7b1ac798 JJ |
3953 | dest1 = gen_df_reg (set_dest, 0); |
3954 | dest2 = gen_df_reg (set_dest, 1); | |
994099bb DM |
3955 | |
3956 | /* Now output, ordering such that we don't clobber any registers | |
3957 | mentioned in the address. */ | |
06424989 JW |
3958 | if (reg_overlap_mentioned_p (dest1, word1)) |
3959 | ||
994099bb DM |
3960 | { |
3961 | emit_insn (gen_movdf (dest2, word1)); | |
3962 | emit_insn (gen_movdf (dest1, word0)); | |
3963 | } | |
3964 | else | |
3965 | { | |
3966 | emit_insn (gen_movdf (dest1, word0)); | |
3967 | emit_insn (gen_movdf (dest2, word1)); | |
3968 | } | |
e0d80184 DM |
3969 | DONE; |
3970 | }") | |
3971 | ||
3972 | (define_split | |
3973 | [(set (match_operand:TF 0 "memory_operand" "") | |
3974 | (match_operand:TF 1 "register_operand" ""))] | |
3975 | "(reload_completed | |
3976 | && offsettable_memref_p (operands[0]))" | |
3977 | [(clobber (const_int 0))] | |
3978 | " | |
3979 | { | |
ed8908e7 | 3980 | rtx set_src = operands[1]; |
ccd61a80 DM |
3981 | if (GET_CODE (set_src) == SUBREG) |
3982 | set_src = alter_subreg (set_src); | |
3983 | ||
ed8908e7 RK |
3984 | emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0), |
3985 | gen_df_reg (set_src, 0))); | |
3986 | emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8), | |
3987 | gen_df_reg (set_src, 1))); | |
e0d80184 DM |
3988 | DONE; |
3989 | }") | |
7a768814 | 3990 | \f |
a8d2b752 DE |
3991 | ;; Sparc V9 conditional move instructions. |
3992 | ||
57b7e1bf DE |
3993 | ;; We can handle larger constants here for some flavors, but for now we keep |
3994 | ;; it simple and only allow those constants supported by all flavours. | |
304b7a23 DE |
3995 | ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand |
3996 | ;; 3 contains the constant if one is present, but we handle either for | |
3997 | ;; generality (sparc.c puts a constant in operand 2). | |
3998 | ||
3999 | (define_expand "movqicc" | |
4000 | [(set (match_operand:QI 0 "register_operand" "") | |
4001 | (if_then_else:QI (match_operand 1 "comparison_operator" "") | |
4002 | (match_operand:QI 2 "arith10_operand" "") | |
4003 | (match_operand:QI 3 "arith10_operand" "")))] | |
4004 | "TARGET_V9" | |
4005 | " | |
4006 | { | |
4007 | enum rtx_code code = GET_CODE (operands[1]); | |
4008 | ||
4009 | if (GET_MODE (sparc_compare_op0) == DImode | |
4010 | && ! TARGET_ARCH64) | |
4011 | FAIL; | |
4012 | ||
4013 | if (sparc_compare_op1 == const0_rtx | |
4014 | && GET_CODE (sparc_compare_op0) == REG | |
4015 | && GET_MODE (sparc_compare_op0) == DImode | |
4016 | && v9_regcmp_p (code)) | |
4017 | { | |
254110c2 | 4018 | operands[1] = gen_rtx_fmt_ee (code, DImode, |
304b7a23 DE |
4019 | sparc_compare_op0, sparc_compare_op1); |
4020 | } | |
4021 | else | |
4022 | { | |
4023 | rtx cc_reg = gen_compare_reg (code, | |
4024 | sparc_compare_op0, sparc_compare_op1); | |
254110c2 | 4025 | operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); |
304b7a23 DE |
4026 | } |
4027 | }") | |
4028 | ||
4029 | (define_expand "movhicc" | |
4030 | [(set (match_operand:HI 0 "register_operand" "") | |
4031 | (if_then_else:HI (match_operand 1 "comparison_operator" "") | |
4032 | (match_operand:HI 2 "arith10_operand" "") | |
4033 | (match_operand:HI 3 "arith10_operand" "")))] | |
4034 | "TARGET_V9" | |
4035 | " | |
4036 | { | |
4037 | enum rtx_code code = GET_CODE (operands[1]); | |
4038 | ||
4039 | if (GET_MODE (sparc_compare_op0) == DImode | |
4040 | && ! TARGET_ARCH64) | |
4041 | FAIL; | |
4042 | ||
4043 | if (sparc_compare_op1 == const0_rtx | |
4044 | && GET_CODE (sparc_compare_op0) == REG | |
4045 | && GET_MODE (sparc_compare_op0) == DImode | |
4046 | && v9_regcmp_p (code)) | |
4047 | { | |
254110c2 | 4048 | operands[1] = gen_rtx_fmt_ee (code, DImode, |
304b7a23 DE |
4049 | sparc_compare_op0, sparc_compare_op1); |
4050 | } | |
4051 | else | |
4052 | { | |
4053 | rtx cc_reg = gen_compare_reg (code, | |
4054 | sparc_compare_op0, sparc_compare_op1); | |
254110c2 | 4055 | operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); |
304b7a23 DE |
4056 | } |
4057 | }") | |
cd5fb1ee DE |
4058 | |
4059 | (define_expand "movsicc" | |
4060 | [(set (match_operand:SI 0 "register_operand" "") | |
304b7a23 DE |
4061 | (if_then_else:SI (match_operand 1 "comparison_operator" "") |
4062 | (match_operand:SI 2 "arith10_operand" "") | |
4063 | (match_operand:SI 3 "arith10_operand" "")))] | |
4064 | "TARGET_V9" | |
cd5fb1ee DE |
4065 | " |
4066 | { | |
4067 | enum rtx_code code = GET_CODE (operands[1]); | |
284d86e9 | 4068 | enum machine_mode op0_mode = GET_MODE (sparc_compare_op0); |
304b7a23 | 4069 | |
cd5fb1ee DE |
4070 | if (sparc_compare_op1 == const0_rtx |
4071 | && GET_CODE (sparc_compare_op0) == REG | |
e0d80184 | 4072 | && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code))) |
cd5fb1ee | 4073 | { |
284d86e9 | 4074 | operands[1] = gen_rtx_fmt_ee (code, op0_mode, |
cd5fb1ee DE |
4075 | sparc_compare_op0, sparc_compare_op1); |
4076 | } | |
4077 | else | |
4078 | { | |
4079 | rtx cc_reg = gen_compare_reg (code, | |
4080 | sparc_compare_op0, sparc_compare_op1); | |
284d86e9 JC |
4081 | operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), |
4082 | cc_reg, const0_rtx); | |
cd5fb1ee DE |
4083 | } |
4084 | }") | |
4085 | ||
4086 | (define_expand "movdicc" | |
4087 | [(set (match_operand:DI 0 "register_operand" "") | |
304b7a23 DE |
4088 | (if_then_else:DI (match_operand 1 "comparison_operator" "") |
4089 | (match_operand:DI 2 "arith10_double_operand" "") | |
4090 | (match_operand:DI 3 "arith10_double_operand" "")))] | |
fa0f39e4 | 4091 | "TARGET_ARCH64" |
cd5fb1ee DE |
4092 | " |
4093 | { | |
4094 | enum rtx_code code = GET_CODE (operands[1]); | |
4095 | ||
4096 | if (sparc_compare_op1 == const0_rtx | |
4097 | && GET_CODE (sparc_compare_op0) == REG | |
4098 | && GET_MODE (sparc_compare_op0) == DImode | |
4099 | && v9_regcmp_p (code)) | |
4100 | { | |
284d86e9 | 4101 | operands[1] = gen_rtx_fmt_ee (code, DImode, |
cd5fb1ee DE |
4102 | sparc_compare_op0, sparc_compare_op1); |
4103 | } | |
4104 | else | |
4105 | { | |
4106 | rtx cc_reg = gen_compare_reg (code, | |
4107 | sparc_compare_op0, sparc_compare_op1); | |
284d86e9 JC |
4108 | operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), |
4109 | cc_reg, const0_rtx); | |
cd5fb1ee DE |
4110 | } |
4111 | }") | |
4112 | ||
4113 | (define_expand "movsfcc" | |
4114 | [(set (match_operand:SF 0 "register_operand" "") | |
304b7a23 DE |
4115 | (if_then_else:SF (match_operand 1 "comparison_operator" "") |
4116 | (match_operand:SF 2 "register_operand" "") | |
4117 | (match_operand:SF 3 "register_operand" "")))] | |
4118 | "TARGET_V9 && TARGET_FPU" | |
cd5fb1ee DE |
4119 | " |
4120 | { | |
4121 | enum rtx_code code = GET_CODE (operands[1]); | |
4122 | ||
304b7a23 DE |
4123 | if (GET_MODE (sparc_compare_op0) == DImode |
4124 | && ! TARGET_ARCH64) | |
4125 | FAIL; | |
4126 | ||
cd5fb1ee DE |
4127 | if (sparc_compare_op1 == const0_rtx |
4128 | && GET_CODE (sparc_compare_op0) == REG | |
4129 | && GET_MODE (sparc_compare_op0) == DImode | |
4130 | && v9_regcmp_p (code)) | |
4131 | { | |
254110c2 | 4132 | operands[1] = gen_rtx_fmt_ee (code, DImode, |
cd5fb1ee DE |
4133 | sparc_compare_op0, sparc_compare_op1); |
4134 | } | |
4135 | else | |
4136 | { | |
4137 | rtx cc_reg = gen_compare_reg (code, | |
4138 | sparc_compare_op0, sparc_compare_op1); | |
254110c2 | 4139 | operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); |
cd5fb1ee DE |
4140 | } |
4141 | }") | |
4142 | ||
4143 | (define_expand "movdfcc" | |
4144 | [(set (match_operand:DF 0 "register_operand" "") | |
304b7a23 DE |
4145 | (if_then_else:DF (match_operand 1 "comparison_operator" "") |
4146 | (match_operand:DF 2 "register_operand" "") | |
4147 | (match_operand:DF 3 "register_operand" "")))] | |
4148 | "TARGET_V9 && TARGET_FPU" | |
cd5fb1ee DE |
4149 | " |
4150 | { | |
4151 | enum rtx_code code = GET_CODE (operands[1]); | |
4152 | ||
304b7a23 DE |
4153 | if (GET_MODE (sparc_compare_op0) == DImode |
4154 | && ! TARGET_ARCH64) | |
4155 | FAIL; | |
4156 | ||
cd5fb1ee DE |
4157 | if (sparc_compare_op1 == const0_rtx |
4158 | && GET_CODE (sparc_compare_op0) == REG | |
4159 | && GET_MODE (sparc_compare_op0) == DImode | |
4160 | && v9_regcmp_p (code)) | |
4161 | { | |
254110c2 | 4162 | operands[1] = gen_rtx_fmt_ee (code, DImode, |
cd5fb1ee DE |
4163 | sparc_compare_op0, sparc_compare_op1); |
4164 | } | |
4165 | else | |
4166 | { | |
4167 | rtx cc_reg = gen_compare_reg (code, | |
4168 | sparc_compare_op0, sparc_compare_op1); | |
254110c2 | 4169 | operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); |
cd5fb1ee DE |
4170 | } |
4171 | }") | |
4172 | ||
4173 | (define_expand "movtfcc" | |
4174 | [(set (match_operand:TF 0 "register_operand" "") | |
304b7a23 DE |
4175 | (if_then_else:TF (match_operand 1 "comparison_operator" "") |
4176 | (match_operand:TF 2 "register_operand" "") | |
4177 | (match_operand:TF 3 "register_operand" "")))] | |
4178 | "TARGET_V9 && TARGET_FPU" | |
cd5fb1ee DE |
4179 | " |
4180 | { | |
4181 | enum rtx_code code = GET_CODE (operands[1]); | |
4182 | ||
304b7a23 DE |
4183 | if (GET_MODE (sparc_compare_op0) == DImode |
4184 | && ! TARGET_ARCH64) | |
4185 | FAIL; | |
4186 | ||
cd5fb1ee DE |
4187 | if (sparc_compare_op1 == const0_rtx |
4188 | && GET_CODE (sparc_compare_op0) == REG | |
4189 | && GET_MODE (sparc_compare_op0) == DImode | |
4190 | && v9_regcmp_p (code)) | |
4191 | { | |
254110c2 | 4192 | operands[1] = gen_rtx_fmt_ee (code, DImode, |
cd5fb1ee DE |
4193 | sparc_compare_op0, sparc_compare_op1); |
4194 | } | |
4195 | else | |
4196 | { | |
4197 | rtx cc_reg = gen_compare_reg (code, | |
4198 | sparc_compare_op0, sparc_compare_op1); | |
254110c2 | 4199 | operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); |
cd5fb1ee DE |
4200 | } |
4201 | }") | |
4202 | ||
304b7a23 | 4203 | ;; Conditional move define_insns. |
b1e74255 | 4204 | |
304b7a23 DE |
4205 | (define_insn "*movqi_cc_sp64" |
4206 | [(set (match_operand:QI 0 "register_operand" "=r,r") | |
4207 | (if_then_else:QI (match_operator 1 "comparison_operator" | |
4208 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
4209 | (const_int 0)]) | |
638e8b1f DM |
4210 | (match_operand:QI 3 "arith11_operand" "rL,0") |
4211 | (match_operand:QI 4 "arith11_operand" "0,rL")))] | |
a8d2b752 | 4212 | "TARGET_V9" |
304b7a23 | 4213 | "@ |
e0d80184 DM |
4214 | mov%C1\\t%x2, %3, %0 |
4215 | mov%c1\\t%x2, %4, %0" | |
4216 | [(set_attr "type" "cmove") | |
4217 | (set_attr "length" "1")]) | |
a8d2b752 | 4218 | |
304b7a23 DE |
4219 | (define_insn "*movhi_cc_sp64" |
4220 | [(set (match_operand:HI 0 "register_operand" "=r,r") | |
4221 | (if_then_else:HI (match_operator 1 "comparison_operator" | |
4222 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
4223 | (const_int 0)]) | |
638e8b1f DM |
4224 | (match_operand:HI 3 "arith11_operand" "rL,0") |
4225 | (match_operand:HI 4 "arith11_operand" "0,rL")))] | |
304b7a23 DE |
4226 | "TARGET_V9" |
4227 | "@ | |
e0d80184 DM |
4228 | mov%C1\\t%x2, %3, %0 |
4229 | mov%c1\\t%x2, %4, %0" | |
4230 | [(set_attr "type" "cmove") | |
4231 | (set_attr "length" "1")]) | |
a8d2b752 | 4232 | |
304b7a23 DE |
4233 | (define_insn "*movsi_cc_sp64" |
4234 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
4235 | (if_then_else:SI (match_operator 1 "comparison_operator" | |
4236 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
4237 | (const_int 0)]) | |
638e8b1f DM |
4238 | (match_operand:SI 3 "arith11_operand" "rL,0") |
4239 | (match_operand:SI 4 "arith11_operand" "0,rL")))] | |
304b7a23 DE |
4240 | "TARGET_V9" |
4241 | "@ | |
e0d80184 DM |
4242 | mov%C1\\t%x2, %3, %0 |
4243 | mov%c1\\t%x2, %4, %0" | |
4244 | [(set_attr "type" "cmove") | |
4245 | (set_attr "length" "1")]) | |
a8d2b752 | 4246 | |
57b7e1bf | 4247 | ;; ??? The constraints of operands 3,4 need work. |
304b7a23 DE |
4248 | (define_insn "*movdi_cc_sp64" |
4249 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
4250 | (if_then_else:DI (match_operator 1 "comparison_operator" | |
4251 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
4252 | (const_int 0)]) | |
638e8b1f DM |
4253 | (match_operand:DI 3 "arith11_double_operand" "rLH,0") |
4254 | (match_operand:DI 4 "arith11_double_operand" "0,rLH")))] | |
fa0f39e4 | 4255 | "TARGET_ARCH64" |
304b7a23 | 4256 | "@ |
e0d80184 DM |
4257 | mov%C1\\t%x2, %3, %0 |
4258 | mov%c1\\t%x2, %4, %0" | |
4259 | [(set_attr "type" "cmove") | |
4260 | (set_attr "length" "1")]) | |
4261 | ||
4262 | (define_insn "*movdi_cc_sp64_trunc" | |
4263 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
638e8b1f | 4264 | (if_then_else:SI (match_operator 1 "comparison_operator" |
e0d80184 DM |
4265 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") |
4266 | (const_int 0)]) | |
638e8b1f DM |
4267 | (match_operand:SI 3 "arith11_double_operand" "rLH,0") |
4268 | (match_operand:SI 4 "arith11_double_operand" "0,rLH")))] | |
e0d80184 DM |
4269 | "TARGET_ARCH64" |
4270 | "@ | |
4271 | mov%C1\\t%x2, %3, %0 | |
4272 | mov%c1\\t%x2, %4, %0" | |
4273 | [(set_attr "type" "cmove") | |
4274 | (set_attr "length" "1")]) | |
a8d2b752 | 4275 | |
304b7a23 DE |
4276 | (define_insn "*movsf_cc_sp64" |
4277 | [(set (match_operand:SF 0 "register_operand" "=f,f") | |
4278 | (if_then_else:SF (match_operator 1 "comparison_operator" | |
4279 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
a8d2b752 | 4280 | (const_int 0)]) |
638e8b1f DM |
4281 | (match_operand:SF 3 "register_operand" "f,0") |
4282 | (match_operand:SF 4 "register_operand" "0,f")))] | |
304b7a23 DE |
4283 | "TARGET_V9 && TARGET_FPU" |
4284 | "@ | |
e0d80184 DM |
4285 | fmovs%C1\\t%x2, %3, %0 |
4286 | fmovs%c1\\t%x2, %4, %0" | |
4287 | [(set_attr "type" "fpcmove") | |
4288 | (set_attr "length" "1")]) | |
a8d2b752 | 4289 | |
ccd61a80 | 4290 | (define_insn "movdf_cc_sp64" |
304b7a23 DE |
4291 | [(set (match_operand:DF 0 "register_operand" "=e,e") |
4292 | (if_then_else:DF (match_operator 1 "comparison_operator" | |
4293 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
a8d2b752 | 4294 | (const_int 0)]) |
638e8b1f DM |
4295 | (match_operand:DF 3 "register_operand" "e,0") |
4296 | (match_operand:DF 4 "register_operand" "0,e")))] | |
304b7a23 DE |
4297 | "TARGET_V9 && TARGET_FPU" |
4298 | "@ | |
e0d80184 DM |
4299 | fmovd%C1\\t%x2, %3, %0 |
4300 | fmovd%c1\\t%x2, %4, %0" | |
4301 | [(set_attr "type" "fpcmove") | |
4302 | (set_attr "length" "1")]) | |
a8d2b752 | 4303 | |
ccd61a80 | 4304 | (define_insn "*movtf_cc_hq_sp64" |
304b7a23 DE |
4305 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
4306 | (if_then_else:TF (match_operator 1 "comparison_operator" | |
4307 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
a8d2b752 | 4308 | (const_int 0)]) |
638e8b1f DM |
4309 | (match_operand:TF 3 "register_operand" "e,0") |
4310 | (match_operand:TF 4 "register_operand" "0,e")))] | |
5d4f5e87 | 4311 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
304b7a23 | 4312 | "@ |
e0d80184 DM |
4313 | fmovq%C1\\t%x2, %3, %0 |
4314 | fmovq%c1\\t%x2, %4, %0" | |
4315 | [(set_attr "type" "fpcmove") | |
4316 | (set_attr "length" "1")]) | |
304b7a23 | 4317 | |
ccd61a80 DM |
4318 | (define_insn "*movtf_cc_sp64" |
4319 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
4320 | (if_then_else:TF (match_operator 1 "comparison_operator" | |
4321 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
4322 | (const_int 0)]) | |
4323 | (match_operand:TF 3 "register_operand" "e,0") | |
4324 | (match_operand:TF 4 "register_operand" "0,e")))] | |
4325 | "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" | |
4326 | "#" | |
4327 | [(set_attr "type" "fpcmove") | |
4328 | (set_attr "length" "2")]) | |
4329 | ||
4330 | (define_split | |
4331 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
4332 | (if_then_else:TF (match_operator 1 "comparison_operator" | |
4333 | [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") | |
4334 | (const_int 0)]) | |
4335 | (match_operand:TF 3 "register_operand" "e,0") | |
4336 | (match_operand:TF 4 "register_operand" "0,e")))] | |
4337 | "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" | |
4338 | [(clobber (const_int 0))] | |
4339 | " | |
4340 | { | |
4341 | rtx set_dest = operands[0]; | |
4342 | rtx set_srca = operands[3]; | |
4343 | rtx set_srcb = operands[4]; | |
4344 | int third = rtx_equal_p (set_dest, set_srca); | |
4345 | rtx dest1, dest2; | |
4346 | rtx srca1, srca2, srcb1, srcb2; | |
4347 | ||
4348 | if (GET_CODE (set_dest) == SUBREG) | |
4349 | set_dest = alter_subreg (set_dest); | |
4350 | if (GET_CODE (set_srca) == SUBREG) | |
4351 | set_srca = alter_subreg (set_srca); | |
4352 | if (GET_CODE (set_srcb) == SUBREG) | |
4353 | set_srcb = alter_subreg (set_srcb); | |
4354 | ||
7b1ac798 JJ |
4355 | dest1 = gen_df_reg (set_dest, 0); |
4356 | dest2 = gen_df_reg (set_dest, 1); | |
4357 | srca1 = gen_df_reg (set_srca, 0); | |
4358 | srca2 = gen_df_reg (set_srca, 1); | |
4359 | srcb1 = gen_df_reg (set_srcb, 0); | |
4360 | srcb2 = gen_df_reg (set_srcb, 1); | |
ccd61a80 DM |
4361 | |
4362 | /* Now emit using the real source and destination we found, swapping | |
4363 | the order if we detect overlap. */ | |
4364 | if ((third && reg_overlap_mentioned_p (dest1, srcb2)) | |
4365 | || (!third && reg_overlap_mentioned_p (dest1, srca2))) | |
4366 | { | |
4367 | emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); | |
4368 | emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); | |
4369 | } | |
4370 | else | |
4371 | { | |
4372 | emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); | |
4373 | emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); | |
4374 | } | |
4375 | DONE; | |
4376 | }") | |
4377 | ||
304b7a23 DE |
4378 | (define_insn "*movqi_cc_reg_sp64" |
4379 | [(set (match_operand:QI 0 "register_operand" "=r,r") | |
4380 | (if_then_else:QI (match_operator 1 "v9_regcmp_op" | |
4381 | [(match_operand:DI 2 "register_operand" "r,r") | |
4382 | (const_int 0)]) | |
638e8b1f DM |
4383 | (match_operand:QI 3 "arith10_operand" "rM,0") |
4384 | (match_operand:QI 4 "arith10_operand" "0,rM")))] | |
fa0f39e4 | 4385 | "TARGET_ARCH64" |
304b7a23 | 4386 | "@ |
e0d80184 DM |
4387 | movr%D1\\t%2, %r3, %0 |
4388 | movr%d1\\t%2, %r4, %0" | |
4389 | [(set_attr "type" "cmove") | |
4390 | (set_attr "length" "1")]) | |
a8d2b752 | 4391 | |
304b7a23 DE |
4392 | (define_insn "*movhi_cc_reg_sp64" |
4393 | [(set (match_operand:HI 0 "register_operand" "=r,r") | |
4394 | (if_then_else:HI (match_operator 1 "v9_regcmp_op" | |
4395 | [(match_operand:DI 2 "register_operand" "r,r") | |
a8d2b752 | 4396 | (const_int 0)]) |
638e8b1f DM |
4397 | (match_operand:HI 3 "arith10_operand" "rM,0") |
4398 | (match_operand:HI 4 "arith10_operand" "0,rM")))] | |
fa0f39e4 | 4399 | "TARGET_ARCH64" |
304b7a23 | 4400 | "@ |
e0d80184 DM |
4401 | movr%D1\\t%2, %r3, %0 |
4402 | movr%d1\\t%2, %r4, %0" | |
4403 | [(set_attr "type" "cmove") | |
4404 | (set_attr "length" "1")]) | |
a8d2b752 | 4405 | |
c8b3b7d6 | 4406 | (define_insn "*movsi_cc_reg_sp64" |
304b7a23 DE |
4407 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
4408 | (if_then_else:SI (match_operator 1 "v9_regcmp_op" | |
4409 | [(match_operand:DI 2 "register_operand" "r,r") | |
a8d2b752 | 4410 | (const_int 0)]) |
638e8b1f DM |
4411 | (match_operand:SI 3 "arith10_operand" "rM,0") |
4412 | (match_operand:SI 4 "arith10_operand" "0,rM")))] | |
fa0f39e4 | 4413 | "TARGET_ARCH64" |
304b7a23 | 4414 | "@ |
e0d80184 DM |
4415 | movr%D1\\t%2, %r3, %0 |
4416 | movr%d1\\t%2, %r4, %0" | |
284d86e9 | 4417 | [(set_attr "type" "cmove") |
e0d80184 | 4418 | (set_attr "length" "1")]) |
284d86e9 | 4419 | |
57b7e1bf | 4420 | ;; ??? The constraints of operands 3,4 need work. |
c8b3b7d6 | 4421 | (define_insn "*movdi_cc_reg_sp64" |
304b7a23 DE |
4422 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
4423 | (if_then_else:DI (match_operator 1 "v9_regcmp_op" | |
4424 | [(match_operand:DI 2 "register_operand" "r,r") | |
a8d2b752 | 4425 | (const_int 0)]) |
638e8b1f DM |
4426 | (match_operand:DI 3 "arith10_double_operand" "rMH,0") |
4427 | (match_operand:DI 4 "arith10_double_operand" "0,rMH")))] | |
fa0f39e4 | 4428 | "TARGET_ARCH64" |
304b7a23 | 4429 | "@ |
e0d80184 DM |
4430 | movr%D1\\t%2, %r3, %0 |
4431 | movr%d1\\t%2, %r4, %0" | |
4432 | [(set_attr "type" "cmove") | |
4433 | (set_attr "length" "1")]) | |
4434 | ||
4435 | (define_insn "*movdi_cc_reg_sp64_trunc" | |
4436 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
638e8b1f | 4437 | (if_then_else:SI (match_operator 1 "v9_regcmp_op" |
e0d80184 DM |
4438 | [(match_operand:DI 2 "register_operand" "r,r") |
4439 | (const_int 0)]) | |
638e8b1f DM |
4440 | (match_operand:SI 3 "arith10_double_operand" "rMH,0") |
4441 | (match_operand:SI 4 "arith10_double_operand" "0,rMH")))] | |
e0d80184 DM |
4442 | "TARGET_ARCH64" |
4443 | "@ | |
4444 | movr%D1\\t%2, %r3, %0 | |
4445 | movr%d1\\t%2, %r4, %0" | |
4446 | [(set_attr "type" "cmove") | |
4447 | (set_attr "length" "1")]) | |
a8d2b752 | 4448 | |
c8b3b7d6 | 4449 | (define_insn "*movsf_cc_reg_sp64" |
304b7a23 DE |
4450 | [(set (match_operand:SF 0 "register_operand" "=f,f") |
4451 | (if_then_else:SF (match_operator 1 "v9_regcmp_op" | |
4452 | [(match_operand:DI 2 "register_operand" "r,r") | |
a8d2b752 | 4453 | (const_int 0)]) |
638e8b1f DM |
4454 | (match_operand:SF 3 "register_operand" "f,0") |
4455 | (match_operand:SF 4 "register_operand" "0,f")))] | |
fa0f39e4 | 4456 | "TARGET_ARCH64 && TARGET_FPU" |
304b7a23 | 4457 | "@ |
e0d80184 DM |
4458 | fmovrs%D1\\t%2, %3, %0 |
4459 | fmovrs%d1\\t%2, %4, %0" | |
4460 | [(set_attr "type" "fpcmove") | |
4461 | (set_attr "length" "1")]) | |
a8d2b752 | 4462 | |
ccd61a80 | 4463 | (define_insn "movdf_cc_reg_sp64" |
304b7a23 DE |
4464 | [(set (match_operand:DF 0 "register_operand" "=e,e") |
4465 | (if_then_else:DF (match_operator 1 "v9_regcmp_op" | |
4466 | [(match_operand:DI 2 "register_operand" "r,r") | |
a8d2b752 | 4467 | (const_int 0)]) |
638e8b1f DM |
4468 | (match_operand:DF 3 "register_operand" "e,0") |
4469 | (match_operand:DF 4 "register_operand" "0,e")))] | |
fa0f39e4 | 4470 | "TARGET_ARCH64 && TARGET_FPU" |
304b7a23 | 4471 | "@ |
e0d80184 DM |
4472 | fmovrd%D1\\t%2, %3, %0 |
4473 | fmovrd%d1\\t%2, %4, %0" | |
4474 | [(set_attr "type" "fpcmove") | |
4475 | (set_attr "length" "1")]) | |
a8d2b752 | 4476 | |
ccd61a80 | 4477 | (define_insn "*movtf_cc_reg_hq_sp64" |
304b7a23 DE |
4478 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
4479 | (if_then_else:TF (match_operator 1 "v9_regcmp_op" | |
4480 | [(match_operand:DI 2 "register_operand" "r,r") | |
a8d2b752 | 4481 | (const_int 0)]) |
638e8b1f DM |
4482 | (match_operand:TF 3 "register_operand" "e,0") |
4483 | (match_operand:TF 4 "register_operand" "0,e")))] | |
ccd61a80 | 4484 | "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" |
304b7a23 | 4485 | "@ |
e0d80184 DM |
4486 | fmovrq%D1\\t%2, %3, %0 |
4487 | fmovrq%d1\\t%2, %4, %0" | |
4488 | [(set_attr "type" "fpcmove") | |
4489 | (set_attr "length" "1")]) | |
ccd61a80 DM |
4490 | |
4491 | (define_insn "*movtf_cc_reg_sp64" | |
4492 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
4493 | (if_then_else:TF (match_operator 1 "v9_regcmp_op" | |
4494 | [(match_operand:DI 2 "register_operand" "r,r") | |
4495 | (const_int 0)]) | |
4496 | (match_operand:TF 3 "register_operand" "e,0") | |
4497 | (match_operand:TF 4 "register_operand" "0,e")))] | |
4498 | "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD" | |
4499 | "#" | |
4500 | [(set_attr "type" "fpcmove") | |
4501 | (set_attr "length" "2")]) | |
4502 | ||
4503 | (define_split | |
4504 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
4505 | (if_then_else:TF (match_operator 1 "v9_regcmp_op" | |
4506 | [(match_operand:DI 2 "register_operand" "r,r") | |
4507 | (const_int 0)]) | |
4508 | (match_operand:TF 3 "register_operand" "e,0") | |
4509 | (match_operand:TF 4 "register_operand" "0,e")))] | |
4510 | "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD" | |
4511 | [(clobber (const_int 0))] | |
4512 | " | |
4513 | { | |
4514 | rtx set_dest = operands[0]; | |
4515 | rtx set_srca = operands[3]; | |
4516 | rtx set_srcb = operands[4]; | |
4517 | int third = rtx_equal_p (set_dest, set_srca); | |
4518 | rtx dest1, dest2; | |
4519 | rtx srca1, srca2, srcb1, srcb2; | |
4520 | ||
4521 | if (GET_CODE (set_dest) == SUBREG) | |
4522 | set_dest = alter_subreg (set_dest); | |
4523 | if (GET_CODE (set_srca) == SUBREG) | |
4524 | set_srca = alter_subreg (set_srca); | |
4525 | if (GET_CODE (set_srcb) == SUBREG) | |
4526 | set_srcb = alter_subreg (set_srcb); | |
4527 | ||
7b1ac798 JJ |
4528 | dest1 = gen_df_reg (set_dest, 0); |
4529 | dest2 = gen_df_reg (set_dest, 1); | |
4530 | srca1 = gen_df_reg (set_srca, 0); | |
4531 | srca2 = gen_df_reg (set_srca, 1); | |
4532 | srcb1 = gen_df_reg (set_srcb, 0); | |
4533 | srcb2 = gen_df_reg (set_srcb, 1); | |
ccd61a80 DM |
4534 | |
4535 | /* Now emit using the real source and destination we found, swapping | |
4536 | the order if we detect overlap. */ | |
4537 | if ((third && reg_overlap_mentioned_p (dest1, srcb2)) | |
4538 | || (!third && reg_overlap_mentioned_p (dest1, srca2))) | |
4539 | { | |
4540 | emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); | |
4541 | emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); | |
4542 | } | |
4543 | else | |
4544 | { | |
4545 | emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); | |
4546 | emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); | |
4547 | } | |
4548 | DONE; | |
4549 | }") | |
4550 | ||
a8d2b752 | 4551 | \f |
7a768814 RS |
4552 | ;;- zero extension instructions |
4553 | ||
4554 | ;; These patterns originally accepted general_operands, however, slightly | |
4555 | ;; better code is generated by only accepting register_operands, and then | |
4556 | ;; letting combine generate the ldu[hb] insns. | |
4557 | ||
4558 | (define_expand "zero_extendhisi2" | |
4559 | [(set (match_operand:SI 0 "register_operand" "") | |
4560 | (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] | |
4561 | "" | |
4562 | " | |
4563 | { | |
4564 | rtx temp = gen_reg_rtx (SImode); | |
5d4f5e87 | 4565 | rtx shift_16 = GEN_INT (16); |
ddef6bc7 | 4566 | int op1_subbyte = 0; |
7a768814 RS |
4567 | |
4568 | if (GET_CODE (operand1) == SUBREG) | |
053e4cac | 4569 | { |
ddef6bc7 JJ |
4570 | op1_subbyte = SUBREG_BYTE (operand1); |
4571 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
4572 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
053e4cac JW |
4573 | operand1 = XEXP (operand1, 0); |
4574 | } | |
7a768814 | 4575 | |
ddef6bc7 | 4576 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
7a768814 RS |
4577 | shift_16)); |
4578 | emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); | |
4579 | DONE; | |
4580 | }") | |
4581 | ||
c8b3b7d6 | 4582 | (define_insn "*zero_extendhisi2_insn" |
7a768814 RS |
4583 | [(set (match_operand:SI 0 "register_operand" "=r") |
4584 | (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
4585 | "" | |
e0d80184 DM |
4586 | "lduh\\t%1, %0" |
4587 | [(set_attr "type" "load") | |
4588 | (set_attr "length" "1")]) | |
7a768814 RS |
4589 | |
4590 | (define_expand "zero_extendqihi2" | |
4591 | [(set (match_operand:HI 0 "register_operand" "") | |
4592 | (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] | |
4593 | "" | |
4594 | "") | |
4595 | ||
c8b3b7d6 | 4596 | (define_insn "*zero_extendqihi2_insn" |
b67bfdf7 | 4597 | [(set (match_operand:HI 0 "register_operand" "=r,r") |
e0d80184 | 4598 | (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))] |
7a768814 RS |
4599 | "GET_CODE (operands[1]) != CONST_INT" |
4600 | "@ | |
e0d80184 DM |
4601 | and\\t%1, 0xff, %0 |
4602 | ldub\\t%1, %0" | |
b67bfdf7 | 4603 | [(set_attr "type" "unary,load") |
7a768814 RS |
4604 | (set_attr "length" "1")]) |
4605 | ||
4606 | (define_expand "zero_extendqisi2" | |
4607 | [(set (match_operand:SI 0 "register_operand" "") | |
4608 | (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] | |
4609 | "" | |
4610 | "") | |
4611 | ||
c8b3b7d6 | 4612 | (define_insn "*zero_extendqisi2_insn" |
b67bfdf7 | 4613 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
e0d80184 | 4614 | (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))] |
7a768814 RS |
4615 | "GET_CODE (operands[1]) != CONST_INT" |
4616 | "@ | |
e0d80184 DM |
4617 | and\\t%1, 0xff, %0 |
4618 | ldub\\t%1, %0" | |
b67bfdf7 | 4619 | [(set_attr "type" "unary,load") |
7a768814 RS |
4620 | (set_attr "length" "1")]) |
4621 | ||
a8d2b752 DE |
4622 | (define_expand "zero_extendqidi2" |
4623 | [(set (match_operand:DI 0 "register_operand" "") | |
4624 | (zero_extend:DI (match_operand:QI 1 "register_operand" "")))] | |
fa0f39e4 | 4625 | "TARGET_ARCH64" |
a8d2b752 DE |
4626 | "") |
4627 | ||
c8b3b7d6 | 4628 | (define_insn "*zero_extendqidi2_insn" |
a8d2b752 | 4629 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
e0d80184 | 4630 | (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))] |
fa0f39e4 | 4631 | "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT" |
a8d2b752 | 4632 | "@ |
e0d80184 DM |
4633 | and\\t%1, 0xff, %0 |
4634 | ldub\\t%1, %0" | |
a8d2b752 DE |
4635 | [(set_attr "type" "unary,load") |
4636 | (set_attr "length" "1")]) | |
4637 | ||
4638 | (define_expand "zero_extendhidi2" | |
4639 | [(set (match_operand:DI 0 "register_operand" "") | |
4640 | (zero_extend:DI (match_operand:HI 1 "register_operand" "")))] | |
fa0f39e4 | 4641 | "TARGET_ARCH64" |
a8d2b752 DE |
4642 | " |
4643 | { | |
4644 | rtx temp = gen_reg_rtx (DImode); | |
5d4f5e87 | 4645 | rtx shift_48 = GEN_INT (48); |
ddef6bc7 | 4646 | int op1_subbyte = 0; |
a8d2b752 DE |
4647 | |
4648 | if (GET_CODE (operand1) == SUBREG) | |
4649 | { | |
ddef6bc7 JJ |
4650 | op1_subbyte = SUBREG_BYTE (operand1); |
4651 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
4652 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
a8d2b752 DE |
4653 | operand1 = XEXP (operand1, 0); |
4654 | } | |
4655 | ||
ddef6bc7 | 4656 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
a8d2b752 DE |
4657 | shift_48)); |
4658 | emit_insn (gen_lshrdi3 (operand0, temp, shift_48)); | |
4659 | DONE; | |
4660 | }") | |
4661 | ||
c8b3b7d6 | 4662 | (define_insn "*zero_extendhidi2_insn" |
a8d2b752 DE |
4663 | [(set (match_operand:DI 0 "register_operand" "=r") |
4664 | (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] | |
fa0f39e4 | 4665 | "TARGET_ARCH64" |
e0d80184 DM |
4666 | "lduh\\t%1, %0" |
4667 | [(set_attr "type" "load") | |
4668 | (set_attr "length" "1")]) | |
a8d2b752 | 4669 | |
284d86e9 | 4670 | |
a8d2b752 DE |
4671 | ;; ??? Write truncdisi pattern using sra? |
4672 | ||
4673 | (define_expand "zero_extendsidi2" | |
4674 | [(set (match_operand:DI 0 "register_operand" "") | |
4675 | (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] | |
2a01c939 | 4676 | "" |
a8d2b752 DE |
4677 | "") |
4678 | ||
2a01c939 | 4679 | (define_insn "*zero_extendsidi2_insn_sp64" |
a8d2b752 | 4680 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
e0d80184 | 4681 | (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))] |
fa0f39e4 | 4682 | "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT" |
a8d2b752 | 4683 | "@ |
e0d80184 DM |
4684 | srl\\t%1, 0, %0 |
4685 | lduw\\t%1, %0" | |
3bc8b61e | 4686 | [(set_attr "type" "shift,load") |
a8d2b752 DE |
4687 | (set_attr "length" "1")]) |
4688 | ||
2a01c939 DM |
4689 | (define_insn "*zero_extendsidi2_insn_sp32" |
4690 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4691 | (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] | |
4692 | "! TARGET_ARCH64" | |
4693 | "#" | |
4694 | [(set_attr "type" "unary") | |
4695 | (set_attr "length" "2")]) | |
4696 | ||
4697 | (define_split | |
4698 | [(set (match_operand:DI 0 "register_operand" "") | |
4699 | (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] | |
4700 | "! TARGET_ARCH64 && reload_completed" | |
4701 | [(set (match_dup 2) (match_dup 3)) | |
4702 | (set (match_dup 4) (match_dup 5))] | |
4703 | " | |
4704 | { | |
4705 | rtx dest1, dest2; | |
4706 | ||
4707 | if (GET_CODE (operands[0]) == SUBREG) | |
4708 | operands[0] = alter_subreg (operands[0]); | |
4709 | ||
4710 | dest1 = gen_highpart (SImode, operands[0]); | |
4711 | dest2 = gen_lowpart (SImode, operands[0]); | |
4712 | ||
4713 | /* Swap the order in case of overlap. */ | |
4714 | if (REGNO (dest1) == REGNO (operands[1])) | |
4715 | { | |
4716 | operands[2] = dest2; | |
4717 | operands[3] = operands[1]; | |
4718 | operands[4] = dest1; | |
4719 | operands[5] = const0_rtx; | |
4720 | } | |
4721 | else | |
4722 | { | |
4723 | operands[2] = dest1; | |
4724 | operands[3] = const0_rtx; | |
4725 | operands[4] = dest2; | |
4726 | operands[5] = operands[1]; | |
4727 | } | |
4728 | }") | |
4729 | ||
a8d2b752 DE |
4730 | ;; Simplify comparisons of extended values. |
4731 | ||
c8b3b7d6 | 4732 | (define_insn "*cmp_zero_extendqisi2" |
c4ce6853 | 4733 | [(set (reg:CC 100) |
7a768814 RS |
4734 | (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) |
4735 | (const_int 0)))] | |
e6c1be7e | 4736 | "" |
e0d80184 DM |
4737 | "andcc\\t%0, 0xff, %%g0" |
4738 | [(set_attr "type" "compare") | |
4739 | (set_attr "length" "1")]) | |
7a768814 | 4740 | |
ce1531ab JJ |
4741 | (define_insn "*cmp_zero_qi" |
4742 | [(set (reg:CC 100) | |
4743 | (compare:CC (match_operand:QI 0 "register_operand" "r") | |
4744 | (const_int 0)))] | |
e6c1be7e | 4745 | "" |
ce1531ab JJ |
4746 | "andcc\\t%0, 0xff, %%g0" |
4747 | [(set_attr "type" "compare") | |
4748 | (set_attr "length" "1")]) | |
4749 | ||
c8b3b7d6 | 4750 | (define_insn "*cmp_zero_extendqisi2_set" |
c4ce6853 | 4751 | [(set (reg:CC 100) |
7a768814 RS |
4752 | (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) |
4753 | (const_int 0))) | |
4754 | (set (match_operand:SI 0 "register_operand" "=r") | |
4755 | (zero_extend:SI (match_dup 1)))] | |
4756 | "" | |
e0d80184 DM |
4757 | "andcc\\t%1, 0xff, %0" |
4758 | [(set_attr "type" "compare") | |
4759 | (set_attr "length" "1")]) | |
4760 | ||
ce1531ab JJ |
4761 | (define_insn "*cmp_zero_extendqisi2_andcc_set" |
4762 | [(set (reg:CC 100) | |
4763 | (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r") | |
4764 | (const_int 255)) | |
4765 | (const_int 0))) | |
4766 | (set (match_operand:SI 0 "register_operand" "=r") | |
4767 | (zero_extend:SI (subreg:QI (match_dup 1) 0)))] | |
4768 | "" | |
4769 | "andcc\\t%1, 0xff, %0" | |
4770 | [(set_attr "type" "compare") | |
4771 | (set_attr "length" "1")]) | |
4772 | ||
e0d80184 DM |
4773 | (define_insn "*cmp_zero_extendqidi2" |
4774 | [(set (reg:CCX 100) | |
4775 | (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r")) | |
4776 | (const_int 0)))] | |
4777 | "TARGET_ARCH64" | |
4778 | "andcc\\t%0, 0xff, %%g0" | |
4779 | [(set_attr "type" "compare") | |
4780 | (set_attr "length" "1")]) | |
4781 | ||
ce1531ab JJ |
4782 | (define_insn "*cmp_zero_qi_sp64" |
4783 | [(set (reg:CCX 100) | |
4784 | (compare:CCX (match_operand:QI 0 "register_operand" "r") | |
4785 | (const_int 0)))] | |
4786 | "TARGET_ARCH64" | |
4787 | "andcc\\t%0, 0xff, %%g0" | |
4788 | [(set_attr "type" "compare") | |
4789 | (set_attr "length" "1")]) | |
4790 | ||
e0d80184 DM |
4791 | (define_insn "*cmp_zero_extendqidi2_set" |
4792 | [(set (reg:CCX 100) | |
4793 | (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) | |
4794 | (const_int 0))) | |
4795 | (set (match_operand:DI 0 "register_operand" "=r") | |
4796 | (zero_extend:DI (match_dup 1)))] | |
4797 | "TARGET_ARCH64" | |
4798 | "andcc\\t%1, 0xff, %0" | |
4799 | [(set_attr "type" "compare") | |
4800 | (set_attr "length" "1")]) | |
d21a353d | 4801 | |
ce1531ab JJ |
4802 | (define_insn "*cmp_zero_extendqidi2_andcc_set" |
4803 | [(set (reg:CCX 100) | |
4804 | (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r") | |
4805 | (const_int 255)) | |
4806 | (const_int 0))) | |
4807 | (set (match_operand:DI 0 "register_operand" "=r") | |
4808 | (zero_extend:DI (subreg:QI (match_dup 1) 0)))] | |
4809 | "TARGET_ARCH64" | |
4810 | "andcc\\t%1, 0xff, %0" | |
4811 | [(set_attr "type" "compare") | |
4812 | (set_attr "length" "1")]) | |
4813 | ||
e0d80184 | 4814 | ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare. |
d21a353d | 4815 | |
c8b3b7d6 | 4816 | (define_insn "*cmp_siqi_trunc" |
c4ce6853 | 4817 | [(set (reg:CC 100) |
ddef6bc7 | 4818 | (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3) |
d21a353d | 4819 | (const_int 0)))] |
e6c1be7e | 4820 | "" |
e0d80184 DM |
4821 | "andcc\\t%0, 0xff, %%g0" |
4822 | [(set_attr "type" "compare") | |
4823 | (set_attr "length" "1")]) | |
d21a353d | 4824 | |
c8b3b7d6 | 4825 | (define_insn "*cmp_siqi_trunc_set" |
c4ce6853 | 4826 | [(set (reg:CC 100) |
ddef6bc7 | 4827 | (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3) |
d21a353d JW |
4828 | (const_int 0))) |
4829 | (set (match_operand:QI 0 "register_operand" "=r") | |
ddef6bc7 | 4830 | (subreg:QI (match_dup 1) 3))] |
d21a353d | 4831 | "" |
e0d80184 DM |
4832 | "andcc\\t%1, 0xff, %0" |
4833 | [(set_attr "type" "compare") | |
4834 | (set_attr "length" "1")]) | |
4835 | ||
4836 | (define_insn "*cmp_diqi_trunc" | |
4837 | [(set (reg:CC 100) | |
ddef6bc7 | 4838 | (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7) |
e0d80184 DM |
4839 | (const_int 0)))] |
4840 | "TARGET_ARCH64" | |
4841 | "andcc\\t%0, 0xff, %%g0" | |
4842 | [(set_attr "type" "compare") | |
4843 | (set_attr "length" "1")]) | |
4844 | ||
4845 | (define_insn "*cmp_diqi_trunc_set" | |
4846 | [(set (reg:CC 100) | |
ddef6bc7 | 4847 | (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7) |
e0d80184 DM |
4848 | (const_int 0))) |
4849 | (set (match_operand:QI 0 "register_operand" "=r") | |
ddef6bc7 | 4850 | (subreg:QI (match_dup 1) 7))] |
e0d80184 DM |
4851 | "TARGET_ARCH64" |
4852 | "andcc\\t%1, 0xff, %0" | |
4853 | [(set_attr "type" "compare") | |
4854 | (set_attr "length" "1")]) | |
7a768814 RS |
4855 | \f |
4856 | ;;- sign extension instructions | |
4857 | ||
4858 | ;; These patterns originally accepted general_operands, however, slightly | |
4859 | ;; better code is generated by only accepting register_operands, and then | |
4860 | ;; letting combine generate the lds[hb] insns. | |
4861 | ||
4862 | (define_expand "extendhisi2" | |
4863 | [(set (match_operand:SI 0 "register_operand" "") | |
4864 | (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] | |
4865 | "" | |
4866 | " | |
4867 | { | |
4868 | rtx temp = gen_reg_rtx (SImode); | |
5d4f5e87 | 4869 | rtx shift_16 = GEN_INT (16); |
ddef6bc7 | 4870 | int op1_subbyte = 0; |
7a768814 RS |
4871 | |
4872 | if (GET_CODE (operand1) == SUBREG) | |
053e4cac | 4873 | { |
ddef6bc7 JJ |
4874 | op1_subbyte = SUBREG_BYTE (operand1); |
4875 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
4876 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
053e4cac JW |
4877 | operand1 = XEXP (operand1, 0); |
4878 | } | |
7a768814 | 4879 | |
ddef6bc7 | 4880 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
7a768814 RS |
4881 | shift_16)); |
4882 | emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); | |
4883 | DONE; | |
4884 | }") | |
4885 | ||
c8b3b7d6 | 4886 | (define_insn "*sign_extendhisi2_insn" |
7a768814 RS |
4887 | [(set (match_operand:SI 0 "register_operand" "=r") |
4888 | (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
4889 | "" | |
e0d80184 DM |
4890 | "ldsh\\t%1, %0" |
4891 | [(set_attr "type" "sload") | |
4892 | (set_attr "length" "1")]) | |
7a768814 | 4893 | |
a8d2b752 DE |
4894 | (define_expand "extendqihi2" |
4895 | [(set (match_operand:HI 0 "register_operand" "") | |
4896 | (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] | |
4897 | "" | |
4898 | " | |
4899 | { | |
4900 | rtx temp = gen_reg_rtx (SImode); | |
5d4f5e87 | 4901 | rtx shift_24 = GEN_INT (24); |
ddef6bc7 JJ |
4902 | int op1_subbyte = 0; |
4903 | int op0_subbyte = 0; | |
a8d2b752 DE |
4904 | |
4905 | if (GET_CODE (operand1) == SUBREG) | |
4906 | { | |
ddef6bc7 JJ |
4907 | op1_subbyte = SUBREG_BYTE (operand1); |
4908 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
4909 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
a8d2b752 DE |
4910 | operand1 = XEXP (operand1, 0); |
4911 | } | |
4912 | if (GET_CODE (operand0) == SUBREG) | |
4913 | { | |
ddef6bc7 JJ |
4914 | op0_subbyte = SUBREG_BYTE (operand0); |
4915 | op0_subbyte /= GET_MODE_SIZE (SImode); | |
4916 | op0_subbyte *= GET_MODE_SIZE (SImode); | |
a8d2b752 DE |
4917 | operand0 = XEXP (operand0, 0); |
4918 | } | |
ddef6bc7 | 4919 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
a8d2b752 DE |
4920 | shift_24)); |
4921 | if (GET_MODE (operand0) != SImode) | |
ddef6bc7 | 4922 | operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte); |
a8d2b752 DE |
4923 | emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); |
4924 | DONE; | |
4925 | }") | |
4926 | ||
c8b3b7d6 | 4927 | (define_insn "*sign_extendqihi2_insn" |
a8d2b752 DE |
4928 | [(set (match_operand:HI 0 "register_operand" "=r") |
4929 | (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] | |
4930 | "" | |
e0d80184 DM |
4931 | "ldsb\\t%1, %0" |
4932 | [(set_attr "type" "sload") | |
4933 | (set_attr "length" "1")]) | |
a8d2b752 DE |
4934 | |
4935 | (define_expand "extendqisi2" | |
4936 | [(set (match_operand:SI 0 "register_operand" "") | |
4937 | (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] | |
4938 | "" | |
4939 | " | |
4940 | { | |
4941 | rtx temp = gen_reg_rtx (SImode); | |
5d4f5e87 | 4942 | rtx shift_24 = GEN_INT (24); |
ddef6bc7 | 4943 | int op1_subbyte = 0; |
a8d2b752 DE |
4944 | |
4945 | if (GET_CODE (operand1) == SUBREG) | |
4946 | { | |
ddef6bc7 JJ |
4947 | op1_subbyte = SUBREG_BYTE (operand1); |
4948 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
4949 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
a8d2b752 DE |
4950 | operand1 = XEXP (operand1, 0); |
4951 | } | |
4952 | ||
ddef6bc7 | 4953 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
a8d2b752 DE |
4954 | shift_24)); |
4955 | emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); | |
4956 | DONE; | |
4957 | }") | |
4958 | ||
c8b3b7d6 | 4959 | (define_insn "*sign_extendqisi2_insn" |
a8d2b752 DE |
4960 | [(set (match_operand:SI 0 "register_operand" "=r") |
4961 | (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] | |
4962 | "" | |
e0d80184 DM |
4963 | "ldsb\\t%1, %0" |
4964 | [(set_attr "type" "sload") | |
4965 | (set_attr "length" "1")]) | |
a8d2b752 DE |
4966 | |
4967 | (define_expand "extendqidi2" | |
4968 | [(set (match_operand:DI 0 "register_operand" "") | |
4969 | (sign_extend:DI (match_operand:QI 1 "register_operand" "")))] | |
fa0f39e4 | 4970 | "TARGET_ARCH64" |
7a768814 RS |
4971 | " |
4972 | { | |
a8d2b752 | 4973 | rtx temp = gen_reg_rtx (DImode); |
5d4f5e87 | 4974 | rtx shift_56 = GEN_INT (56); |
ddef6bc7 | 4975 | int op1_subbyte = 0; |
7a768814 RS |
4976 | |
4977 | if (GET_CODE (operand1) == SUBREG) | |
053e4cac | 4978 | { |
ddef6bc7 JJ |
4979 | op1_subbyte = SUBREG_BYTE (operand1); |
4980 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
4981 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
053e4cac JW |
4982 | operand1 = XEXP (operand1, 0); |
4983 | } | |
a8d2b752 | 4984 | |
ddef6bc7 | 4985 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
a8d2b752 DE |
4986 | shift_56)); |
4987 | emit_insn (gen_ashrdi3 (operand0, temp, shift_56)); | |
7a768814 RS |
4988 | DONE; |
4989 | }") | |
4990 | ||
c8b3b7d6 | 4991 | (define_insn "*sign_extendqidi2_insn" |
a8d2b752 DE |
4992 | [(set (match_operand:DI 0 "register_operand" "=r") |
4993 | (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] | |
fa0f39e4 | 4994 | "TARGET_ARCH64" |
e0d80184 DM |
4995 | "ldsb\\t%1, %0" |
4996 | [(set_attr "type" "sload") | |
4997 | (set_attr "length" "1")]) | |
7a768814 | 4998 | |
a8d2b752 DE |
4999 | (define_expand "extendhidi2" |
5000 | [(set (match_operand:DI 0 "register_operand" "") | |
5001 | (sign_extend:DI (match_operand:HI 1 "register_operand" "")))] | |
fa0f39e4 | 5002 | "TARGET_ARCH64" |
7a768814 RS |
5003 | " |
5004 | { | |
a8d2b752 | 5005 | rtx temp = gen_reg_rtx (DImode); |
5d4f5e87 | 5006 | rtx shift_48 = GEN_INT (48); |
ddef6bc7 | 5007 | int op1_subbyte = 0; |
7a768814 RS |
5008 | |
5009 | if (GET_CODE (operand1) == SUBREG) | |
053e4cac | 5010 | { |
ddef6bc7 JJ |
5011 | op1_subbyte = SUBREG_BYTE (operand1); |
5012 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
5013 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
053e4cac JW |
5014 | operand1 = XEXP (operand1, 0); |
5015 | } | |
5016 | ||
ddef6bc7 | 5017 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
a8d2b752 DE |
5018 | shift_48)); |
5019 | emit_insn (gen_ashrdi3 (operand0, temp, shift_48)); | |
7a768814 RS |
5020 | DONE; |
5021 | }") | |
5022 | ||
c8b3b7d6 | 5023 | (define_insn "*sign_extendhidi2_insn" |
a8d2b752 DE |
5024 | [(set (match_operand:DI 0 "register_operand" "=r") |
5025 | (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] | |
fa0f39e4 | 5026 | "TARGET_ARCH64" |
e0d80184 | 5027 | "ldsh\\t%1, %0" |
3bc8b61e | 5028 | [(set_attr "type" "sload") |
e0d80184 | 5029 | (set_attr "length" "1")]) |
a8d2b752 DE |
5030 | |
5031 | (define_expand "extendsidi2" | |
5032 | [(set (match_operand:DI 0 "register_operand" "") | |
5033 | (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] | |
fa0f39e4 | 5034 | "TARGET_ARCH64" |
a8d2b752 DE |
5035 | "") |
5036 | ||
c8b3b7d6 | 5037 | (define_insn "*sign_extendsidi2_insn" |
a8d2b752 | 5038 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
e0d80184 | 5039 | (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))] |
fa0f39e4 | 5040 | "TARGET_ARCH64" |
a8d2b752 | 5041 | "@ |
e0d80184 DM |
5042 | sra\\t%1, 0, %0 |
5043 | ldsw\\t%1, %0" | |
3bc8b61e | 5044 | [(set_attr "type" "shift,sload") |
a8d2b752 | 5045 | (set_attr "length" "1")]) |
7a768814 | 5046 | \f |
b4ac57ab RS |
5047 | ;; Special pattern for optimizing bit-field compares. This is needed |
5048 | ;; because combine uses this as a canonical form. | |
5049 | ||
c8b3b7d6 | 5050 | (define_insn "*cmp_zero_extract" |
c4ce6853 | 5051 | [(set (reg:CC 100) |
b4ac57ab RS |
5052 | (compare:CC |
5053 | (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
e0d80184 DM |
5054 | (match_operand:SI 1 "small_int_or_double" "n") |
5055 | (match_operand:SI 2 "small_int_or_double" "n")) | |
b4ac57ab | 5056 | (const_int 0)))] |
e6c1be7e JJ |
5057 | "(GET_CODE (operands[2]) == CONST_INT |
5058 | && INTVAL (operands[2]) > 19) | |
5059 | || (GET_CODE (operands[2]) == CONST_DOUBLE | |
5060 | && CONST_DOUBLE_LOW (operands[2]) > 19)" | |
b4ac57ab RS |
5061 | "* |
5062 | { | |
e0d80184 DM |
5063 | int len = (GET_CODE (operands[1]) == CONST_INT |
5064 | ? INTVAL (operands[1]) | |
5065 | : CONST_DOUBLE_LOW (operands[1])); | |
5066 | int pos = 32 - | |
5067 | (GET_CODE (operands[2]) == CONST_INT | |
5068 | ? INTVAL (operands[2]) | |
5069 | : CONST_DOUBLE_LOW (operands[2])) - len; | |
f710f868 | 5070 | HOST_WIDE_INT mask = ((1 << len) - 1) << pos; |
b4ac57ab | 5071 | |
5d4f5e87 | 5072 | operands[1] = GEN_INT (mask); |
e0d80184 DM |
5073 | return \"andcc\\t%0, %1, %%g0\"; |
5074 | }" | |
5075 | [(set_attr "type" "compare") | |
5076 | (set_attr "length" "1")]) | |
a8d2b752 | 5077 | |
c8b3b7d6 | 5078 | (define_insn "*cmp_zero_extract_sp64" |
c4ce6853 | 5079 | [(set (reg:CCX 100) |
a8d2b752 DE |
5080 | (compare:CCX |
5081 | (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
e0d80184 DM |
5082 | (match_operand:SI 1 "small_int_or_double" "n") |
5083 | (match_operand:SI 2 "small_int_or_double" "n")) | |
a8d2b752 | 5084 | (const_int 0)))] |
e0d80184 DM |
5085 | "TARGET_ARCH64 |
5086 | && ((GET_CODE (operands[2]) == CONST_INT | |
5087 | && INTVAL (operands[2]) > 51) | |
5088 | || (GET_CODE (operands[2]) == CONST_DOUBLE | |
5089 | && CONST_DOUBLE_LOW (operands[2]) > 51))" | |
a8d2b752 DE |
5090 | "* |
5091 | { | |
e0d80184 DM |
5092 | int len = (GET_CODE (operands[1]) == CONST_INT |
5093 | ? INTVAL (operands[1]) | |
5094 | : CONST_DOUBLE_LOW (operands[1])); | |
5095 | int pos = 64 - | |
5096 | (GET_CODE (operands[2]) == CONST_INT | |
5097 | ? INTVAL (operands[2]) | |
5098 | : CONST_DOUBLE_LOW (operands[2])) - len; | |
f710f868 | 5099 | HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos; |
a8d2b752 | 5100 | |
5d4f5e87 | 5101 | operands[1] = GEN_INT (mask); |
e0d80184 DM |
5102 | return \"andcc\\t%0, %1, %%g0\"; |
5103 | }" | |
5104 | [(set_attr "type" "compare") | |
5105 | (set_attr "length" "1")]) | |
b4ac57ab | 5106 | \f |
795068a4 | 5107 | ;; Conversions between float, double and long double. |
7a768814 RS |
5108 | |
5109 | (define_insn "extendsfdf2" | |
b6d3c4ba | 5110 | [(set (match_operand:DF 0 "register_operand" "=e") |
7a768814 RS |
5111 | (float_extend:DF |
5112 | (match_operand:SF 1 "register_operand" "f")))] | |
ab5519b7 | 5113 | "TARGET_FPU" |
e0d80184 DM |
5114 | "fstod\\t%1, %0" |
5115 | [(set_attr "type" "fp") | |
5116 | (set_attr "length" "1")]) | |
7a768814 | 5117 | |
47ac041c JJ |
5118 | (define_expand "extendsftf2" |
5119 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5120 | (float_extend:TF | |
5121 | (match_operand:SF 1 "register_operand" "f")))] | |
5122 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
5123 | " | |
5124 | { | |
5125 | if (! TARGET_HARD_QUAD) | |
5126 | { | |
5127 | rtx slot0; | |
5128 | ||
5129 | if (GET_CODE (operands[0]) != MEM) | |
5130 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5131 | else | |
5132 | slot0 = operands[0]; | |
5133 | ||
5134 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0, | |
5135 | VOIDmode, 2, | |
5136 | XEXP (slot0, 0), Pmode, | |
5137 | operands[1], SFmode); | |
5138 | ||
5139 | if (GET_CODE (operands[0]) != MEM) | |
5140 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
5141 | DONE; | |
5142 | } | |
5143 | }") | |
5144 | ||
5145 | (define_insn "*extendsftf2_hq" | |
b6d3c4ba | 5146 | [(set (match_operand:TF 0 "register_operand" "=e") |
795068a4 JW |
5147 | (float_extend:TF |
5148 | (match_operand:SF 1 "register_operand" "f")))] | |
ef903eca | 5149 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
5150 | "fstoq\\t%1, %0" |
5151 | [(set_attr "type" "fp") | |
5152 | (set_attr "length" "1")]) | |
795068a4 | 5153 | |
47ac041c JJ |
5154 | (define_expand "extenddftf2" |
5155 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5156 | (float_extend:TF | |
5157 | (match_operand:DF 1 "register_operand" "e")))] | |
5158 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
5159 | " | |
5160 | { | |
5161 | if (! TARGET_HARD_QUAD) | |
5162 | { | |
5163 | rtx slot0; | |
5164 | ||
5165 | if (GET_CODE (operands[0]) != MEM) | |
5166 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5167 | else | |
5168 | slot0 = operands[0]; | |
5169 | ||
5170 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0, | |
5171 | VOIDmode, 2, | |
5172 | XEXP (slot0, 0), Pmode, | |
5173 | operands[1], DFmode); | |
5174 | ||
5175 | if (GET_CODE (operands[0]) != MEM) | |
5176 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
5177 | DONE; | |
5178 | } | |
5179 | }") | |
5180 | ||
5181 | (define_insn "*extenddftf2_hq" | |
b6d3c4ba | 5182 | [(set (match_operand:TF 0 "register_operand" "=e") |
795068a4 | 5183 | (float_extend:TF |
b6d3c4ba | 5184 | (match_operand:DF 1 "register_operand" "e")))] |
ef903eca | 5185 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
5186 | "fdtoq\\t%1, %0" |
5187 | [(set_attr "type" "fp") | |
5188 | (set_attr "length" "1")]) | |
795068a4 | 5189 | |
7a768814 RS |
5190 | (define_insn "truncdfsf2" |
5191 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5192 | (float_truncate:SF | |
b6d3c4ba | 5193 | (match_operand:DF 1 "register_operand" "e")))] |
ab5519b7 | 5194 | "TARGET_FPU" |
e0d80184 DM |
5195 | "fdtos\\t%1, %0" |
5196 | [(set_attr "type" "fp") | |
5197 | (set_attr "length" "1")]) | |
795068a4 | 5198 | |
47ac041c JJ |
5199 | (define_expand "trunctfsf2" |
5200 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5201 | (float_truncate:SF | |
5202 | (match_operand:TF 1 "register_operand" "e")))] | |
5203 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
5204 | " | |
5205 | { | |
5206 | if (! TARGET_HARD_QUAD) | |
5207 | { | |
5208 | rtx slot0; | |
5209 | ||
5210 | if (GET_CODE (operands[1]) != MEM) | |
5211 | { | |
5212 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5213 | emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); | |
5214 | } | |
5215 | else | |
5216 | slot0 = operands[1]; | |
5217 | ||
5218 | emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"), | |
5219 | operands[0], 0, SFmode, 1, | |
5220 | XEXP (slot0, 0), Pmode); | |
5221 | DONE; | |
5222 | } | |
5223 | }") | |
5224 | ||
5225 | (define_insn "*trunctfsf2_hq" | |
795068a4 JW |
5226 | [(set (match_operand:SF 0 "register_operand" "=f") |
5227 | (float_truncate:SF | |
b6d3c4ba | 5228 | (match_operand:TF 1 "register_operand" "e")))] |
ef903eca | 5229 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
5230 | "fqtos\\t%1, %0" |
5231 | [(set_attr "type" "fp") | |
5232 | (set_attr "length" "1")]) | |
795068a4 | 5233 | |
47ac041c JJ |
5234 | (define_expand "trunctfdf2" |
5235 | [(set (match_operand:DF 0 "register_operand" "=f") | |
5236 | (float_truncate:DF | |
5237 | (match_operand:TF 1 "register_operand" "e")))] | |
5238 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
5239 | " | |
5240 | { | |
5241 | if (! TARGET_HARD_QUAD) | |
5242 | { | |
5243 | rtx slot0; | |
5244 | ||
5245 | if (GET_CODE (operands[1]) != MEM) | |
5246 | { | |
5247 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5248 | emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); | |
5249 | } | |
5250 | else | |
5251 | slot0 = operands[1]; | |
5252 | ||
5253 | emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"), | |
5254 | operands[0], 0, DFmode, 1, | |
5255 | XEXP (slot0, 0), Pmode); | |
5256 | DONE; | |
5257 | } | |
5258 | }") | |
5259 | ||
5260 | (define_insn "*trunctfdf2_hq" | |
b6d3c4ba | 5261 | [(set (match_operand:DF 0 "register_operand" "=e") |
795068a4 | 5262 | (float_truncate:DF |
b6d3c4ba | 5263 | (match_operand:TF 1 "register_operand" "e")))] |
ef903eca | 5264 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
5265 | "fqtod\\t%1, %0" |
5266 | [(set_attr "type" "fp") | |
5267 | (set_attr "length" "1")]) | |
7a768814 RS |
5268 | \f |
5269 | ;; Conversion between fixed point and floating point. | |
5270 | ||
5271 | (define_insn "floatsisf2" | |
ec08cf0a JW |
5272 | [(set (match_operand:SF 0 "register_operand" "=f") |
5273 | (float:SF (match_operand:SI 1 "register_operand" "f")))] | |
ab5519b7 | 5274 | "TARGET_FPU" |
e0d80184 DM |
5275 | "fitos\\t%1, %0" |
5276 | [(set_attr "type" "fp") | |
5277 | (set_attr "length" "1")]) | |
7a768814 RS |
5278 | |
5279 | (define_insn "floatsidf2" | |
b6d3c4ba | 5280 | [(set (match_operand:DF 0 "register_operand" "=e") |
ec08cf0a | 5281 | (float:DF (match_operand:SI 1 "register_operand" "f")))] |
ab5519b7 | 5282 | "TARGET_FPU" |
e0d80184 DM |
5283 | "fitod\\t%1, %0" |
5284 | [(set_attr "type" "fp") | |
5285 | (set_attr "length" "1")]) | |
7a768814 | 5286 | |
47ac041c JJ |
5287 | (define_expand "floatsitf2" |
5288 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5289 | (float:TF (match_operand:SI 1 "register_operand" "f")))] | |
5290 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
5291 | " | |
5292 | { | |
5293 | if (! TARGET_HARD_QUAD) | |
5294 | { | |
5295 | rtx slot0; | |
5296 | ||
5297 | if (GET_CODE (operands[1]) != MEM) | |
5298 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5299 | else | |
5300 | slot0 = operands[1]; | |
5301 | ||
5302 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0, | |
5303 | VOIDmode, 2, | |
5304 | XEXP (slot0, 0), Pmode, | |
5305 | operands[1], SImode); | |
5306 | ||
5307 | if (GET_CODE (operands[0]) != MEM) | |
5308 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
5309 | DONE; | |
5310 | } | |
5311 | }") | |
5312 | ||
5313 | (define_insn "*floatsitf2_hq" | |
b6d3c4ba | 5314 | [(set (match_operand:TF 0 "register_operand" "=e") |
ec08cf0a | 5315 | (float:TF (match_operand:SI 1 "register_operand" "f")))] |
ef903eca | 5316 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
5317 | "fitoq\\t%1, %0" |
5318 | [(set_attr "type" "fp") | |
5319 | (set_attr "length" "1")]) | |
795068a4 | 5320 | |
47ac041c JJ |
5321 | (define_expand "floatunssitf2" |
5322 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5323 | (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))] | |
5324 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" | |
5325 | " | |
5326 | { | |
5327 | rtx slot0; | |
5328 | ||
5329 | if (GET_CODE (operands[1]) != MEM) | |
5330 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5331 | else | |
5332 | slot0 = operands[1]; | |
5333 | ||
5334 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0, | |
5335 | VOIDmode, 2, | |
5336 | XEXP (slot0, 0), Pmode, | |
5337 | operands[1], SImode); | |
5338 | ||
5339 | if (GET_CODE (operands[0]) != MEM) | |
5340 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
5341 | DONE; | |
5342 | }") | |
5343 | ||
a8d2b752 | 5344 | ;; Now the same for 64 bit sources. |
a8d2b752 | 5345 | |
284d86e9 | 5346 | (define_insn "floatdisf2" |
a8d2b752 | 5347 | [(set (match_operand:SF 0 "register_operand" "=f") |
b6d3c4ba | 5348 | (float:SF (match_operand:DI 1 "register_operand" "e")))] |
284d86e9 | 5349 | "TARGET_V9 && TARGET_FPU" |
e0d80184 DM |
5350 | "fxtos\\t%1, %0" |
5351 | [(set_attr "type" "fp") | |
5352 | (set_attr "length" "1")]) | |
a8d2b752 | 5353 | |
284d86e9 | 5354 | (define_insn "floatdidf2" |
b6d3c4ba JW |
5355 | [(set (match_operand:DF 0 "register_operand" "=e") |
5356 | (float:DF (match_operand:DI 1 "register_operand" "e")))] | |
284d86e9 | 5357 | "TARGET_V9 && TARGET_FPU" |
e0d80184 DM |
5358 | "fxtod\\t%1, %0" |
5359 | [(set_attr "type" "fp") | |
5360 | (set_attr "length" "1")]) | |
a8d2b752 | 5361 | |
47ac041c JJ |
5362 | (define_expand "floatditf2" |
5363 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5364 | (float:TF (match_operand:DI 1 "register_operand" "e")))] | |
5365 | "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
5366 | " | |
5367 | { | |
5368 | if (! TARGET_HARD_QUAD) | |
5369 | { | |
5370 | rtx slot0; | |
5371 | ||
5372 | if (GET_CODE (operands[1]) != MEM) | |
5373 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5374 | else | |
5375 | slot0 = operands[1]; | |
5376 | ||
5377 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0, | |
5378 | VOIDmode, 2, | |
5379 | XEXP (slot0, 0), Pmode, | |
5380 | operands[1], DImode); | |
5381 | ||
5382 | if (GET_CODE (operands[0]) != MEM) | |
5383 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
5384 | DONE; | |
5385 | } | |
5386 | }") | |
5387 | ||
5388 | (define_insn "*floatditf2_hq" | |
b6d3c4ba JW |
5389 | [(set (match_operand:TF 0 "register_operand" "=e") |
5390 | (float:TF (match_operand:DI 1 "register_operand" "e")))] | |
284d86e9 | 5391 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
5392 | "fxtoq\\t%1, %0" |
5393 | [(set_attr "type" "fp") | |
5394 | (set_attr "length" "1")]) | |
a8d2b752 | 5395 | |
47ac041c JJ |
5396 | (define_expand "floatunsditf2" |
5397 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5398 | (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))] | |
5399 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" | |
5400 | " | |
5401 | { | |
5402 | rtx slot0; | |
5403 | ||
5404 | if (GET_CODE (operands[1]) != MEM) | |
5405 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5406 | else | |
5407 | slot0 = operands[1]; | |
5408 | ||
5409 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0, | |
5410 | VOIDmode, 2, | |
5411 | XEXP (slot0, 0), Pmode, | |
5412 | operands[1], DImode); | |
5413 | ||
5414 | if (GET_CODE (operands[0]) != MEM) | |
5415 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
5416 | DONE; | |
5417 | }") | |
5418 | ||
7a768814 RS |
5419 | ;; Convert a float to an actual integer. |
5420 | ;; Truncation is performed as part of the conversion. | |
5421 | ||
5422 | (define_insn "fix_truncsfsi2" | |
ec08cf0a JW |
5423 | [(set (match_operand:SI 0 "register_operand" "=f") |
5424 | (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] | |
ab5519b7 | 5425 | "TARGET_FPU" |
e0d80184 DM |
5426 | "fstoi\\t%1, %0" |
5427 | [(set_attr "type" "fp") | |
5428 | (set_attr "length" "1")]) | |
7a768814 RS |
5429 | |
5430 | (define_insn "fix_truncdfsi2" | |
ec08cf0a | 5431 | [(set (match_operand:SI 0 "register_operand" "=f") |
b6d3c4ba | 5432 | (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] |
ab5519b7 | 5433 | "TARGET_FPU" |
e0d80184 DM |
5434 | "fdtoi\\t%1, %0" |
5435 | [(set_attr "type" "fp") | |
5436 | (set_attr "length" "1")]) | |
a3ee5899 | 5437 | |
47ac041c JJ |
5438 | (define_expand "fix_trunctfsi2" |
5439 | [(set (match_operand:SI 0 "register_operand" "=f") | |
5440 | (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] | |
5441 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
5442 | " | |
5443 | { | |
5444 | if (! TARGET_HARD_QUAD) | |
5445 | { | |
5446 | rtx slot0; | |
5447 | ||
5448 | if (GET_CODE (operands[1]) != MEM) | |
5449 | { | |
5450 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5451 | emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); | |
5452 | } | |
5453 | else | |
5454 | slot0 = operands[1]; | |
5455 | ||
5456 | emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"), | |
5457 | operands[0], 0, SImode, 1, | |
5458 | XEXP (slot0, 0), Pmode); | |
5459 | DONE; | |
5460 | } | |
5461 | }") | |
5462 | ||
5463 | (define_insn "*fix_trunctfsi2_hq" | |
ec08cf0a | 5464 | [(set (match_operand:SI 0 "register_operand" "=f") |
b6d3c4ba | 5465 | (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] |
ef903eca | 5466 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
5467 | "fqtoi\\t%1, %0" |
5468 | [(set_attr "type" "fp") | |
5469 | (set_attr "length" "1")]) | |
a8d2b752 | 5470 | |
47ac041c JJ |
5471 | (define_expand "fixuns_trunctfsi2" |
5472 | [(set (match_operand:SI 0 "register_operand" "=f") | |
5473 | (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] | |
5474 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" | |
5475 | " | |
5476 | { | |
5477 | rtx slot0; | |
5478 | ||
5479 | if (GET_CODE (operands[1]) != MEM) | |
5480 | { | |
5481 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5482 | emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); | |
5483 | } | |
5484 | else | |
5485 | slot0 = operands[1]; | |
5486 | ||
5487 | emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"), | |
5488 | operands[0], 0, SImode, 1, | |
5489 | XEXP (slot0, 0), Pmode); | |
5490 | DONE; | |
5491 | }") | |
5492 | ||
284d86e9 | 5493 | ;; Now the same, for V9 targets |
a8d2b752 | 5494 | |
284d86e9 | 5495 | (define_insn "fix_truncsfdi2" |
b6d3c4ba | 5496 | [(set (match_operand:DI 0 "register_operand" "=e") |
a8d2b752 | 5497 | (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] |
284d86e9 | 5498 | "TARGET_V9 && TARGET_FPU" |
e0d80184 DM |
5499 | "fstox\\t%1, %0" |
5500 | [(set_attr "type" "fp") | |
5501 | (set_attr "length" "1")]) | |
a8d2b752 | 5502 | |
284d86e9 | 5503 | (define_insn "fix_truncdfdi2" |
b6d3c4ba JW |
5504 | [(set (match_operand:DI 0 "register_operand" "=e") |
5505 | (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] | |
284d86e9 | 5506 | "TARGET_V9 && TARGET_FPU" |
e0d80184 DM |
5507 | "fdtox\\t%1, %0" |
5508 | [(set_attr "type" "fp") | |
5509 | (set_attr "length" "1")]) | |
a8d2b752 | 5510 | |
47ac041c JJ |
5511 | (define_expand "fix_trunctfdi2" |
5512 | [(set (match_operand:DI 0 "register_operand" "=e") | |
5513 | (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] | |
5514 | "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
5515 | " | |
5516 | { | |
5517 | if (! TARGET_HARD_QUAD) | |
5518 | { | |
5519 | rtx slot0; | |
5520 | ||
5521 | if (GET_CODE (operands[1]) != MEM) | |
5522 | { | |
5523 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5524 | emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); | |
5525 | } | |
5526 | else | |
5527 | slot0 = operands[1]; | |
5528 | ||
5529 | emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"), | |
5530 | operands[0], 0, DImode, 1, | |
5531 | XEXP (slot0, 0), Pmode); | |
5532 | DONE; | |
5533 | } | |
5534 | }") | |
5535 | ||
5536 | (define_insn "*fix_trunctfdi2_hq" | |
b6d3c4ba JW |
5537 | [(set (match_operand:DI 0 "register_operand" "=e") |
5538 | (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] | |
284d86e9 | 5539 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
5540 | "fqtox\\t%1, %0" |
5541 | [(set_attr "type" "fp") | |
5542 | (set_attr "length" "1")]) | |
47ac041c JJ |
5543 | |
5544 | (define_expand "fixuns_trunctfdi2" | |
5545 | [(set (match_operand:DI 0 "register_operand" "=f") | |
5546 | (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] | |
5547 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" | |
5548 | " | |
5549 | { | |
5550 | rtx slot0; | |
5551 | ||
5552 | if (GET_CODE (operands[1]) != MEM) | |
5553 | { | |
5554 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
5555 | emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1])); | |
5556 | } | |
5557 | else | |
5558 | slot0 = operands[1]; | |
5559 | ||
5560 | emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"), | |
5561 | operands[0], 0, DImode, 1, | |
5562 | XEXP (slot0, 0), Pmode); | |
5563 | DONE; | |
5564 | }") | |
5565 | ||
7a768814 RS |
5566 | \f |
5567 | ;;- arithmetic instructions | |
5568 | ||
a8d2b752 DE |
5569 | (define_expand "adddi3" |
5570 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5571 | (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
5d6d3339 | 5572 | (match_operand:DI 2 "arith_double_add_operand" "rHI")))] |
a8d2b752 DE |
5573 | "" |
5574 | " | |
5575 | { | |
8b1c5fd0 JJ |
5576 | HOST_WIDE_INT i; |
5577 | ||
fa0f39e4 | 5578 | if (! TARGET_ARCH64) |
a8d2b752 | 5579 | { |
5b8e7fa3 DM |
5580 | emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, |
5581 | gen_rtx_SET (VOIDmode, operands[0], | |
5582 | gen_rtx_PLUS (DImode, operands[1], | |
5583 | operands[2])), | |
5584 | gen_rtx_CLOBBER (VOIDmode, | |
c6b0465b | 5585 | gen_rtx_REG (CCmode, SPARC_ICC_REG))))); |
a8d2b752 DE |
5586 | DONE; |
5587 | } | |
5d6d3339 JJ |
5588 | if (arith_double_4096_operand(operands[2], DImode)) |
5589 | { | |
8b1c5fd0 JJ |
5590 | switch (GET_CODE (operands[1])) |
5591 | { | |
5592 | case CONST_INT: i = INTVAL (operands[1]); break; | |
5593 | case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break; | |
5594 | default: | |
5595 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
5596 | gen_rtx_MINUS (DImode, operands[1], | |
5597 | GEN_INT(-4096)))); | |
5598 | DONE; | |
5599 | } | |
5600 | emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096))); | |
5d6d3339 JJ |
5601 | DONE; |
5602 | } | |
a8d2b752 DE |
5603 | }") |
5604 | ||
e0d80184 | 5605 | (define_insn "adddi3_insn_sp32" |
7a768814 RS |
5606 | [(set (match_operand:DI 0 "register_operand" "=r") |
5607 | (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
5608 | (match_operand:DI 2 "arith_double_operand" "rHI"))) | |
c6b0465b | 5609 | (clobber (reg:CC 100))] |
fa0f39e4 | 5610 | "! TARGET_ARCH64" |
e0d80184 | 5611 | "#" |
7a768814 RS |
5612 | [(set_attr "length" "2")]) |
5613 | ||
284d86e9 JC |
5614 | (define_split |
5615 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5616 | (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
5617 | (match_operand:DI 2 "arith_double_operand" "rHI"))) | |
c6b0465b | 5618 | (clobber (reg:CC 100))] |
284d86e9 JC |
5619 | "! TARGET_ARCH64 && reload_completed" |
5620 | [(parallel [(set (reg:CC_NOOV 100) | |
5621 | (compare:CC_NOOV (plus:SI (match_dup 4) | |
5622 | (match_dup 5)) | |
5623 | (const_int 0))) | |
5624 | (set (match_dup 3) | |
5625 | (plus:SI (match_dup 4) (match_dup 5)))]) | |
5626 | (set (match_dup 6) | |
5627 | (plus:SI (plus:SI (match_dup 7) | |
5628 | (match_dup 8)) | |
5629 | (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] | |
1c44748c DM |
5630 | " |
5631 | { | |
5632 | operands[3] = gen_lowpart (SImode, operands[0]); | |
5633 | operands[4] = gen_lowpart (SImode, operands[1]); | |
5634 | operands[5] = gen_lowpart (SImode, operands[2]); | |
5635 | operands[6] = gen_highpart (SImode, operands[0]); | |
5636 | operands[7] = gen_highpart (SImode, operands[1]); | |
93b7b953 | 5637 | #if HOST_BITS_PER_WIDE_INT == 32 |
1c44748c DM |
5638 | if (GET_CODE (operands[2]) == CONST_INT) |
5639 | { | |
5640 | if (INTVAL (operands[2]) < 0) | |
5641 | operands[8] = constm1_rtx; | |
5642 | else | |
5643 | operands[8] = const0_rtx; | |
5644 | } | |
5645 | else | |
93b7b953 | 5646 | #endif |
1c44748c DM |
5647 | operands[8] = gen_highpart (SImode, operands[2]); |
5648 | }") | |
284d86e9 JC |
5649 | |
5650 | (define_split | |
5651 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5652 | (minus:DI (match_operand:DI 1 "arith_double_operand" "r") | |
5653 | (match_operand:DI 2 "arith_double_operand" "rHI"))) | |
c6b0465b | 5654 | (clobber (reg:CC 100))] |
284d86e9 JC |
5655 | "! TARGET_ARCH64 && reload_completed" |
5656 | [(parallel [(set (reg:CC_NOOV 100) | |
5657 | (compare:CC_NOOV (minus:SI (match_dup 4) | |
5658 | (match_dup 5)) | |
5659 | (const_int 0))) | |
5660 | (set (match_dup 3) | |
5661 | (minus:SI (match_dup 4) (match_dup 5)))]) | |
5662 | (set (match_dup 6) | |
5663 | (minus:SI (minus:SI (match_dup 7) | |
5664 | (match_dup 8)) | |
5665 | (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] | |
1c44748c DM |
5666 | " |
5667 | { | |
5668 | operands[3] = gen_lowpart (SImode, operands[0]); | |
5669 | operands[4] = gen_lowpart (SImode, operands[1]); | |
5670 | operands[5] = gen_lowpart (SImode, operands[2]); | |
5671 | operands[6] = gen_highpart (SImode, operands[0]); | |
5672 | operands[7] = gen_highpart (SImode, operands[1]); | |
93b7b953 | 5673 | #if HOST_BITS_PER_WIDE_INT == 32 |
1c44748c DM |
5674 | if (GET_CODE (operands[2]) == CONST_INT) |
5675 | { | |
5676 | if (INTVAL (operands[2]) < 0) | |
5677 | operands[8] = constm1_rtx; | |
5678 | else | |
5679 | operands[8] = const0_rtx; | |
5680 | } | |
5681 | else | |
93b7b953 | 5682 | #endif |
1c44748c DM |
5683 | operands[8] = gen_highpart (SImode, operands[2]); |
5684 | }") | |
284d86e9 JC |
5685 | |
5686 | ;; LTU here means "carry set" | |
e0d80184 | 5687 | (define_insn "addx" |
284d86e9 JC |
5688 | [(set (match_operand:SI 0 "register_operand" "=r") |
5689 | (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r") | |
5690 | (match_operand:SI 2 "arith_operand" "rI")) | |
5691 | (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] | |
5692 | "" | |
e0d80184 DM |
5693 | "addx\\t%1, %2, %0" |
5694 | [(set_attr "type" "unary") | |
5695 | (set_attr "length" "1")]) | |
5696 | ||
16cf8119 | 5697 | (define_insn "*addx_extend_sp32" |
e0d80184 | 5698 | [(set (match_operand:DI 0 "register_operand" "=r") |
638e8b1f DM |
5699 | (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") |
5700 | (match_operand:SI 2 "arith_operand" "rI")) | |
5701 | (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] | |
16cf8119 DM |
5702 | "! TARGET_ARCH64" |
5703 | "#" | |
5704 | [(set_attr "type" "unary") | |
5705 | (set_attr "length" "2")]) | |
5706 | ||
5707 | (define_split | |
5708 | [(set (match_operand:DI 0 "register_operand" "") | |
638e8b1f DM |
5709 | (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") |
5710 | (match_operand:SI 2 "arith_operand" "")) | |
5711 | (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] | |
16cf8119 DM |
5712 | "! TARGET_ARCH64 && reload_completed" |
5713 | [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2)) | |
5714 | (ltu:SI (reg:CC_NOOV 100) (const_int 0)))) | |
5715 | (set (match_dup 4) (const_int 0))] | |
5716 | "operands[3] = gen_lowpart (SImode, operands[0]); | |
5717 | operands[4] = gen_highpart (SImode, operands[1]);") | |
5718 | ||
5719 | (define_insn "*addx_extend_sp64" | |
5720 | [(set (match_operand:DI 0 "register_operand" "=r") | |
638e8b1f DM |
5721 | (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") |
5722 | (match_operand:SI 2 "arith_operand" "rI")) | |
5723 | (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] | |
16cf8119 | 5724 | "TARGET_ARCH64" |
e0d80184 | 5725 | "addx\\t%r1, %2, %0" |
3bc8b61e | 5726 | [(set_attr "type" "misc") |
e0d80184 | 5727 | (set_attr "length" "1")]) |
284d86e9 | 5728 | |
e0d80184 | 5729 | (define_insn "subx" |
284d86e9 | 5730 | [(set (match_operand:SI 0 "register_operand" "=r") |
e0d80184 DM |
5731 | (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") |
5732 | (match_operand:SI 2 "arith_operand" "rI")) | |
5733 | (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] | |
5734 | "" | |
5735 | "subx\\t%r1, %2, %0" | |
3bc8b61e | 5736 | [(set_attr "type" "misc") |
e0d80184 DM |
5737 | (set_attr "length" "1")]) |
5738 | ||
16cf8119 | 5739 | (define_insn "*subx_extend_sp64" |
e0d80184 | 5740 | [(set (match_operand:DI 0 "register_operand" "=r") |
638e8b1f DM |
5741 | (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") |
5742 | (match_operand:SI 2 "arith_operand" "rI")) | |
5743 | (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] | |
16cf8119 | 5744 | "TARGET_ARCH64" |
e0d80184 | 5745 | "subx\\t%r1, %2, %0" |
3bc8b61e | 5746 | [(set_attr "type" "misc") |
e0d80184 DM |
5747 | (set_attr "length" "1")]) |
5748 | ||
16cf8119 DM |
5749 | (define_insn "*subx_extend" |
5750 | [(set (match_operand:DI 0 "register_operand" "=r") | |
638e8b1f DM |
5751 | (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") |
5752 | (match_operand:SI 2 "arith_operand" "rI")) | |
5753 | (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] | |
16cf8119 DM |
5754 | "! TARGET_ARCH64" |
5755 | "#" | |
5756 | [(set_attr "type" "unary") | |
5757 | (set_attr "length" "2")]) | |
5758 | ||
5759 | (define_split | |
5760 | [(set (match_operand:DI 0 "register_operand" "=r") | |
638e8b1f DM |
5761 | (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") |
5762 | (match_operand:SI 2 "arith_operand" "rI")) | |
5763 | (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] | |
16cf8119 DM |
5764 | "! TARGET_ARCH64 && reload_completed" |
5765 | [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2)) | |
5766 | (ltu:SI (reg:CC_NOOV 100) (const_int 0)))) | |
5767 | (set (match_dup 4) (const_int 0))] | |
5768 | "operands[3] = gen_lowpart (SImode, operands[0]); | |
5769 | operands[4] = gen_highpart (SImode, operands[0]);") | |
5770 | ||
bfd6bc60 JC |
5771 | (define_insn "" |
5772 | [(set (match_operand:DI 0 "register_operand" "=r") | |
16cf8119 DM |
5773 | (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) |
5774 | (match_operand:DI 2 "register_operand" "r"))) | |
c6b0465b | 5775 | (clobber (reg:CC 100))] |
bfd6bc60 | 5776 | "! TARGET_ARCH64" |
e0d80184 DM |
5777 | "#" |
5778 | [(set_attr "type" "multi") | |
5779 | (set_attr "length" "2")]) | |
5780 | ||
5781 | (define_split | |
5782 | [(set (match_operand:DI 0 "register_operand" "") | |
5783 | (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | |
5784 | (match_operand:DI 2 "register_operand" ""))) | |
5785 | (clobber (reg:CC 100))] | |
71648202 | 5786 | "! TARGET_ARCH64 && reload_completed" |
16cf8119 DM |
5787 | [(parallel [(set (reg:CC_NOOV 100) |
5788 | (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1)) | |
5789 | (const_int 0))) | |
5790 | (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))]) | |
5791 | (set (match_dup 6) | |
e0d80184 DM |
5792 | (plus:SI (plus:SI (match_dup 4) (const_int 0)) |
5793 | (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] | |
5794 | "operands[3] = gen_lowpart (SImode, operands[2]); | |
16cf8119 DM |
5795 | operands[4] = gen_highpart (SImode, operands[2]); |
5796 | operands[5] = gen_lowpart (SImode, operands[0]); | |
5797 | operands[6] = gen_highpart (SImode, operands[0]);") | |
bfd6bc60 | 5798 | |
c8b3b7d6 | 5799 | (define_insn "*adddi3_sp64" |
a8d2b752 DE |
5800 | [(set (match_operand:DI 0 "register_operand" "=r") |
5801 | (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
5802 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
fa0f39e4 | 5803 | "TARGET_ARCH64" |
3bc8b61e DM |
5804 | "add\\t%1, %2, %0" |
5805 | [(set_attr "type" "binary") | |
5806 | (set_attr "length" "1")]) | |
a8d2b752 | 5807 | |
5d6d3339 JJ |
5808 | (define_expand "addsi3" |
5809 | [(set (match_operand:SI 0 "register_operand" "=r,d") | |
5810 | (plus:SI (match_operand:SI 1 "arith_operand" "%r,d") | |
5811 | (match_operand:SI 2 "arith_add_operand" "rI,d")))] | |
5812 | "" | |
5813 | " | |
5814 | { | |
8b1c5fd0 | 5815 | if (arith_4096_operand(operands[2], SImode)) |
5d6d3339 | 5816 | { |
8b1c5fd0 JJ |
5817 | if (GET_CODE (operands[1]) == CONST_INT) |
5818 | emit_insn (gen_movsi (operands[0], | |
5819 | GEN_INT (INTVAL (operands[1]) + 4096))); | |
5820 | else | |
5821 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
5822 | gen_rtx_MINUS (SImode, operands[1], | |
5823 | GEN_INT(-4096)))); | |
5d6d3339 JJ |
5824 | DONE; |
5825 | } | |
5826 | }") | |
5827 | ||
5828 | (define_insn "*addsi3" | |
bfd6bc60 JC |
5829 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
5830 | (plus:SI (match_operand:SI 1 "arith_operand" "%r,d") | |
5831 | (match_operand:SI 2 "arith_operand" "rI,d")))] | |
7a768814 | 5832 | "" |
bfd6bc60 | 5833 | "@ |
e0d80184 DM |
5834 | add\\t%1, %2, %0 |
5835 | fpadd32s\\t%1, %2, %0" | |
5836 | [(set_attr "type" "ialu,fp") | |
5837 | (set_attr "length" "1")]) | |
7a768814 | 5838 | |
c8b3b7d6 | 5839 | (define_insn "*cmp_cc_plus" |
c4ce6853 | 5840 | [(set (reg:CC_NOOV 100) |
7a768814 RS |
5841 | (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") |
5842 | (match_operand:SI 1 "arith_operand" "rI")) | |
5843 | (const_int 0)))] | |
e6c1be7e | 5844 | "" |
e0d80184 DM |
5845 | "addcc\\t%0, %1, %%g0" |
5846 | [(set_attr "type" "compare") | |
5847 | (set_attr "length" "1")]) | |
7a768814 | 5848 | |
c8b3b7d6 | 5849 | (define_insn "*cmp_ccx_plus" |
c4ce6853 | 5850 | [(set (reg:CCX_NOOV 100) |
a8d2b752 DE |
5851 | (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r") |
5852 | (match_operand:DI 1 "arith_double_operand" "rHI")) | |
5853 | (const_int 0)))] | |
fa0f39e4 | 5854 | "TARGET_ARCH64" |
e0d80184 DM |
5855 | "addcc\\t%0, %1, %%g0" |
5856 | [(set_attr "type" "compare") | |
5857 | (set_attr "length" "1")]) | |
a8d2b752 | 5858 | |
c8b3b7d6 | 5859 | (define_insn "*cmp_cc_plus_set" |
c4ce6853 | 5860 | [(set (reg:CC_NOOV 100) |
7a768814 RS |
5861 | (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r") |
5862 | (match_operand:SI 2 "arith_operand" "rI")) | |
5863 | (const_int 0))) | |
5864 | (set (match_operand:SI 0 "register_operand" "=r") | |
5865 | (plus:SI (match_dup 1) (match_dup 2)))] | |
5866 | "" | |
e0d80184 DM |
5867 | "addcc\\t%1, %2, %0" |
5868 | [(set_attr "type" "compare") | |
5869 | (set_attr "length" "1")]) | |
7a768814 | 5870 | |
c8b3b7d6 | 5871 | (define_insn "*cmp_ccx_plus_set" |
c4ce6853 | 5872 | [(set (reg:CCX_NOOV 100) |
a8d2b752 DE |
5873 | (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") |
5874 | (match_operand:DI 2 "arith_double_operand" "rHI")) | |
5875 | (const_int 0))) | |
5876 | (set (match_operand:DI 0 "register_operand" "=r") | |
5877 | (plus:DI (match_dup 1) (match_dup 2)))] | |
fa0f39e4 | 5878 | "TARGET_ARCH64" |
e0d80184 DM |
5879 | "addcc\\t%1, %2, %0" |
5880 | [(set_attr "type" "compare") | |
5881 | (set_attr "length" "1")]) | |
a8d2b752 DE |
5882 | |
5883 | (define_expand "subdi3" | |
5884 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5885 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
5d6d3339 | 5886 | (match_operand:DI 2 "arith_double_add_operand" "rHI")))] |
a8d2b752 DE |
5887 | "" |
5888 | " | |
5889 | { | |
fa0f39e4 | 5890 | if (! TARGET_ARCH64) |
a8d2b752 | 5891 | { |
5b8e7fa3 DM |
5892 | emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, |
5893 | gen_rtx_SET (VOIDmode, operands[0], | |
5894 | gen_rtx_MINUS (DImode, operands[1], | |
5895 | operands[2])), | |
5896 | gen_rtx_CLOBBER (VOIDmode, | |
c6b0465b | 5897 | gen_rtx_REG (CCmode, SPARC_ICC_REG))))); |
a8d2b752 DE |
5898 | DONE; |
5899 | } | |
5d6d3339 JJ |
5900 | if (arith_double_4096_operand(operands[2], DImode)) |
5901 | { | |
5902 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
5903 | gen_rtx_PLUS (DImode, operands[1], | |
5904 | GEN_INT(-4096)))); | |
5905 | DONE; | |
5906 | } | |
a8d2b752 DE |
5907 | }") |
5908 | ||
c8b3b7d6 | 5909 | (define_insn "*subdi3_sp32" |
7a768814 RS |
5910 | [(set (match_operand:DI 0 "register_operand" "=r") |
5911 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
5912 | (match_operand:DI 2 "arith_double_operand" "rHI"))) | |
c6b0465b | 5913 | (clobber (reg:CC 100))] |
fa0f39e4 | 5914 | "! TARGET_ARCH64" |
e0d80184 DM |
5915 | "#" |
5916 | [(set_attr "length" "2")]) | |
5917 | ||
5918 | (define_split | |
5919 | [(set (match_operand:DI 0 "register_operand" "") | |
5920 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
5921 | (match_operand:DI 2 "arith_double_operand" ""))) | |
5922 | (clobber (reg:CC 100))] | |
5923 | "! TARGET_ARCH64 | |
5924 | && reload_completed | |
5925 | && (GET_CODE (operands[2]) == CONST_INT | |
5926 | || GET_CODE (operands[2]) == CONST_DOUBLE)" | |
5927 | [(clobber (const_int 0))] | |
5928 | " | |
7a768814 | 5929 | { |
e0d80184 | 5930 | rtx highp, lowp; |
7a768814 | 5931 | |
e0d80184 DM |
5932 | highp = gen_highpart (SImode, operands[2]); |
5933 | lowp = gen_lowpart (SImode, operands[2]); | |
5934 | if ((lowp == const0_rtx) | |
5935 | && (operands[0] == operands[1])) | |
7a768814 | 5936 | { |
9208e4b2 | 5937 | emit_insn (gen_rtx_SET (VOIDmode, |
e0d80184 DM |
5938 | gen_highpart (SImode, operands[0]), |
5939 | gen_rtx_MINUS (SImode, | |
5940 | gen_highpart (SImode, operands[1]), | |
5941 | highp))); | |
7a768814 | 5942 | } |
e0d80184 DM |
5943 | else |
5944 | { | |
5945 | emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]), | |
5946 | gen_lowpart (SImode, operands[1]), | |
5947 | lowp)); | |
5948 | emit_insn (gen_subx (gen_highpart (SImode, operands[0]), | |
5949 | gen_highpart (SImode, operands[1]), | |
5950 | highp)); | |
5951 | } | |
5952 | DONE; | |
5953 | }") | |
5954 | ||
5955 | (define_split | |
5956 | [(set (match_operand:DI 0 "register_operand" "") | |
5957 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
5958 | (match_operand:DI 2 "register_operand" ""))) | |
5959 | (clobber (reg:CC 100))] | |
5960 | "! TARGET_ARCH64 | |
5961 | && reload_completed" | |
5962 | [(clobber (const_int 0))] | |
5963 | " | |
5964 | { | |
5965 | emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]), | |
5966 | gen_lowpart (SImode, operands[1]), | |
5967 | gen_lowpart (SImode, operands[2]))); | |
5968 | emit_insn (gen_subx (gen_highpart (SImode, operands[0]), | |
5969 | gen_highpart (SImode, operands[1]), | |
5970 | gen_highpart (SImode, operands[2]))); | |
5971 | DONE; | |
5972 | }") | |
7a768814 | 5973 | |
bfd6bc60 JC |
5974 | (define_insn "" |
5975 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5976 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
5977 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))) | |
c6b0465b | 5978 | (clobber (reg:CC 100))] |
bfd6bc60 | 5979 | "! TARGET_ARCH64" |
e0d80184 DM |
5980 | "#" |
5981 | [(set_attr "type" "multi") | |
5982 | (set_attr "length" "2")]) | |
5983 | ||
5984 | (define_split | |
5985 | [(set (match_operand:DI 0 "register_operand" "") | |
5986 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
5987 | (zero_extend:DI (match_operand:SI 2 "register_operand" "")))) | |
5988 | (clobber (reg:CC 100))] | |
71648202 | 5989 | "! TARGET_ARCH64 && reload_completed" |
16cf8119 DM |
5990 | [(parallel [(set (reg:CC_NOOV 100) |
5991 | (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2)) | |
5992 | (const_int 0))) | |
5993 | (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))]) | |
5994 | (set (match_dup 6) | |
5995 | (minus:SI (minus:SI (match_dup 4) (const_int 0)) | |
5996 | (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] | |
e0d80184 | 5997 | "operands[3] = gen_lowpart (SImode, operands[1]); |
16cf8119 DM |
5998 | operands[4] = gen_highpart (SImode, operands[1]); |
5999 | operands[5] = gen_lowpart (SImode, operands[0]); | |
6000 | operands[6] = gen_highpart (SImode, operands[0]);") | |
bfd6bc60 | 6001 | |
c8b3b7d6 | 6002 | (define_insn "*subdi3_sp64" |
a8d2b752 DE |
6003 | [(set (match_operand:DI 0 "register_operand" "=r") |
6004 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
6005 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
fa0f39e4 | 6006 | "TARGET_ARCH64" |
e0d80184 DM |
6007 | "sub\\t%1, %2, %0" |
6008 | [(set_attr "type" "binary") | |
6009 | (set_attr "length" "1")]) | |
a8d2b752 | 6010 | |
5d6d3339 JJ |
6011 | (define_expand "subsi3" |
6012 | [(set (match_operand:SI 0 "register_operand" "=r,d") | |
6013 | (minus:SI (match_operand:SI 1 "register_operand" "r,d") | |
6014 | (match_operand:SI 2 "arith_add_operand" "rI,d")))] | |
6015 | "" | |
6016 | " | |
6017 | { | |
8b1c5fd0 | 6018 | if (arith_4096_operand(operands[2], SImode)) |
5d6d3339 JJ |
6019 | { |
6020 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
6021 | gen_rtx_PLUS (SImode, operands[1], | |
6022 | GEN_INT(-4096)))); | |
6023 | DONE; | |
6024 | } | |
6025 | }") | |
6026 | ||
6027 | (define_insn "*subsi3" | |
bfd6bc60 JC |
6028 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
6029 | (minus:SI (match_operand:SI 1 "register_operand" "r,d") | |
6030 | (match_operand:SI 2 "arith_operand" "rI,d")))] | |
7a768814 | 6031 | "" |
bfd6bc60 | 6032 | "@ |
e0d80184 DM |
6033 | sub\\t%1, %2, %0 |
6034 | fpsub32s\\t%1, %2, %0" | |
6035 | [(set_attr "type" "ialu,fp") | |
6036 | (set_attr "length" "1")]) | |
7a768814 | 6037 | |
c8b3b7d6 | 6038 | (define_insn "*cmp_minus_cc" |
c4ce6853 | 6039 | [(set (reg:CC_NOOV 100) |
e0d80184 | 6040 | (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ") |
7a768814 RS |
6041 | (match_operand:SI 1 "arith_operand" "rI")) |
6042 | (const_int 0)))] | |
e6c1be7e | 6043 | "" |
e0d80184 DM |
6044 | "subcc\\t%r0, %1, %%g0" |
6045 | [(set_attr "type" "compare") | |
6046 | (set_attr "length" "1")]) | |
7a768814 | 6047 | |
c8b3b7d6 | 6048 | (define_insn "*cmp_minus_ccx" |
c4ce6853 | 6049 | [(set (reg:CCX_NOOV 100) |
a8d2b752 DE |
6050 | (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r") |
6051 | (match_operand:DI 1 "arith_double_operand" "rHI")) | |
6052 | (const_int 0)))] | |
fa0f39e4 | 6053 | "TARGET_ARCH64" |
e0d80184 DM |
6054 | "subcc\\t%0, %1, %%g0" |
6055 | [(set_attr "type" "compare") | |
6056 | (set_attr "length" "1")]) | |
a8d2b752 | 6057 | |
e0d80184 | 6058 | (define_insn "cmp_minus_cc_set" |
c4ce6853 | 6059 | [(set (reg:CC_NOOV 100) |
e0d80184 | 6060 | (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") |
7a768814 RS |
6061 | (match_operand:SI 2 "arith_operand" "rI")) |
6062 | (const_int 0))) | |
6063 | (set (match_operand:SI 0 "register_operand" "=r") | |
6064 | (minus:SI (match_dup 1) (match_dup 2)))] | |
6065 | "" | |
e0d80184 DM |
6066 | "subcc\\t%r1, %2, %0" |
6067 | [(set_attr "type" "compare") | |
6068 | (set_attr "length" "1")]) | |
7a768814 | 6069 | |
c8b3b7d6 | 6070 | (define_insn "*cmp_minus_ccx_set" |
c4ce6853 | 6071 | [(set (reg:CCX_NOOV 100) |
a8d2b752 DE |
6072 | (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r") |
6073 | (match_operand:DI 2 "arith_double_operand" "rHI")) | |
6074 | (const_int 0))) | |
6075 | (set (match_operand:DI 0 "register_operand" "=r") | |
6076 | (minus:DI (match_dup 1) (match_dup 2)))] | |
fa0f39e4 | 6077 | "TARGET_ARCH64" |
e0d80184 DM |
6078 | "subcc\\t%1, %2, %0" |
6079 | [(set_attr "type" "compare") | |
6080 | (set_attr "length" "1")]) | |
eb582c5d DE |
6081 | \f |
6082 | ;; Integer Multiply/Divide. | |
a8d2b752 | 6083 | |
5cb01b65 JJ |
6084 | ;; The 32 bit multiply/divide instructions are deprecated on v9, but at |
6085 | ;; least in UltraSPARC I, II and IIi it is a win tick-wise. | |
a8d2b752 | 6086 | |
77a02b01 JW |
6087 | (define_insn "mulsi3" |
6088 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6089 | (mult:SI (match_operand:SI 1 "arith_operand" "%r") | |
6090 | (match_operand:SI 2 "arith_operand" "rI")))] | |
bfd6bc60 | 6091 | "TARGET_HARD_MUL" |
e0d80184 DM |
6092 | "smul\\t%1, %2, %0" |
6093 | [(set_attr "type" "imul") | |
6094 | (set_attr "length" "1")]) | |
77a02b01 | 6095 | |
284d86e9 JC |
6096 | (define_expand "muldi3" |
6097 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6098 | (mult:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
6099 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
6100 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
6101 | " | |
6102 | { | |
6103 | if (TARGET_V8PLUS) | |
6104 | { | |
6105 | emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2])); | |
6106 | DONE; | |
6107 | } | |
6108 | }") | |
6109 | ||
6110 | (define_insn "*muldi3_sp64" | |
a8d2b752 DE |
6111 | [(set (match_operand:DI 0 "register_operand" "=r") |
6112 | (mult:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
6113 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
fa0f39e4 | 6114 | "TARGET_ARCH64" |
e0d80184 DM |
6115 | "mulx\\t%1, %2, %0" |
6116 | [(set_attr "type" "imul") | |
6117 | (set_attr "length" "1")]) | |
a8d2b752 | 6118 | |
284d86e9 | 6119 | ;; V8plus wide multiply. |
e0d80184 | 6120 | ;; XXX |
284d86e9 JC |
6121 | (define_insn "muldi3_v8plus" |
6122 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
6123 | (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0") | |
4df1190a | 6124 | (match_operand:DI 2 "arith_double_operand" "rI,rI"))) |
284d86e9 JC |
6125 | (clobber (match_scratch:SI 3 "=&h,X")) |
6126 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
6127 | "TARGET_V8PLUS" | |
6128 | "* | |
6129 | { | |
6130 | if (sparc_check_64 (operands[1], insn) <= 0) | |
e0d80184 | 6131 | output_asm_insn (\"srl\\t%L1, 0, %L1\", operands); |
284d86e9 | 6132 | if (which_alternative == 1) |
e0d80184 | 6133 | output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands); |
4df1190a JJ |
6134 | if (GET_CODE (operands[2]) == CONST_INT) |
6135 | { | |
6136 | if (which_alternative == 1) | |
6137 | return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\"; | |
6138 | else | |
6139 | return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\"; | |
6140 | } | |
284d86e9 | 6141 | if (sparc_check_64 (operands[2], insn) <= 0) |
e0d80184 | 6142 | output_asm_insn (\"srl\\t%L2, 0, %L2\", operands); |
284d86e9 | 6143 | if (which_alternative == 1) |
e0d80184 | 6144 | return \"or\\t%L1, %H1, %H1\\n\\tsllx\\t%H2, 32, %L1\\n\\tor\\t%L2, %L1, %L1\\n\\tmulx\\t%H1, %L1, %L0\;srlx\\t%L0, 32, %H0\"; |
284d86e9 | 6145 | else |
e0d80184 | 6146 | return \"sllx\\t%H1, 32, %3\\n\\tsllx\\t%H2, 32, %4\\n\\tor\\t%L1, %3, %3\\n\\tor\\t%L2, %4, %4\\n\\tmulx\\t%3, %4, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\"; |
284d86e9 JC |
6147 | }" |
6148 | [(set_attr "length" "9,8")]) | |
6149 | ||
c8b3b7d6 | 6150 | (define_insn "*cmp_mul_set" |
5cb01b65 JJ |
6151 | [(set (reg:CC 100) |
6152 | (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r") | |
6153 | (match_operand:SI 2 "arith_operand" "rI")) | |
6154 | (const_int 0))) | |
6155 | (set (match_operand:SI 0 "register_operand" "=r") | |
6156 | (mult:SI (match_dup 1) (match_dup 2)))] | |
eb582c5d | 6157 | "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" |
e0d80184 DM |
6158 | "smulcc\\t%1, %2, %0" |
6159 | [(set_attr "type" "imul") | |
6160 | (set_attr "length" "1")]) | |
77a02b01 | 6161 | |
ab5519b7 JW |
6162 | (define_expand "mulsidi3" |
6163 | [(set (match_operand:DI 0 "register_operand" "") | |
6164 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) | |
6165 | (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))] | |
bfd6bc60 | 6166 | "TARGET_HARD_MUL" |
ab5519b7 JW |
6167 | " |
6168 | { | |
6169 | if (CONSTANT_P (operands[2])) | |
6170 | { | |
2cea586a | 6171 | if (TARGET_V8PLUS) |
5cb01b65 JJ |
6172 | emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1], |
6173 | operands[2])); | |
6174 | else | |
6175 | emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1], | |
6176 | operands[2])); | |
ab5519b7 JW |
6177 | DONE; |
6178 | } | |
2cea586a JW |
6179 | if (TARGET_V8PLUS) |
6180 | { | |
6181 | emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2])); | |
6182 | DONE; | |
6183 | } | |
ab5519b7 JW |
6184 | }") |
6185 | ||
284d86e9 JC |
6186 | ;; V9 puts the 64 bit product in a 64 bit register. Only out or global |
6187 | ;; registers can hold 64 bit values in the V8plus environment. | |
e0d80184 | 6188 | ;; XXX |
2cea586a | 6189 | (define_insn "mulsidi3_v8plus" |
284d86e9 JC |
6190 | [(set (match_operand:DI 0 "register_operand" "=h,r") |
6191 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
6192 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) | |
6193 | (clobber (match_scratch:SI 3 "=X,&h"))] | |
6194 | "TARGET_V8PLUS" | |
6195 | "@ | |
e0d80184 DM |
6196 | smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0 |
6197 | smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0" | |
284d86e9 JC |
6198 | [(set_attr "length" "2,3")]) |
6199 | ||
e0d80184 | 6200 | ;; XXX |
2cea586a | 6201 | (define_insn "const_mulsidi3_v8plus" |
284d86e9 JC |
6202 | [(set (match_operand:DI 0 "register_operand" "=h,r") |
6203 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
6204 | (match_operand:SI 2 "small_int" "I,I"))) | |
6205 | (clobber (match_scratch:SI 3 "=X,&h"))] | |
6206 | "TARGET_V8PLUS" | |
6207 | "@ | |
e0d80184 DM |
6208 | smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0 |
6209 | smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0" | |
284d86e9 JC |
6210 | [(set_attr "length" "2,3")]) |
6211 | ||
e0d80184 | 6212 | ;; XXX |
c8b3b7d6 | 6213 | (define_insn "*mulsidi3_sp32" |
77a02b01 | 6214 | [(set (match_operand:DI 0 "register_operand" "=r") |
ab5519b7 JW |
6215 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) |
6216 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
284d86e9 | 6217 | "TARGET_HARD_MUL32" |
6d29fc41 DE |
6218 | "* |
6219 | { | |
e0d80184 | 6220 | return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\"; |
6d29fc41 DE |
6221 | }" |
6222 | [(set (attr "length") | |
6223 | (if_then_else (eq_attr "isa" "sparclet") | |
6224 | (const_int 1) (const_int 2)))]) | |
77a02b01 | 6225 | |
5cb01b65 JJ |
6226 | (define_insn "*mulsidi3_sp64" |
6227 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6228 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6229 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
6230 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
6231 | "smul\\t%1, %2, %0" | |
6232 | [(set_attr "length" "1")]) | |
6233 | ||
3826a3da | 6234 | ;; Extra pattern, because sign_extend of a constant isn't valid. |
ab5519b7 | 6235 | |
e0d80184 | 6236 | ;; XXX |
5cb01b65 | 6237 | (define_insn "const_mulsidi3_sp32" |
77a02b01 | 6238 | [(set (match_operand:DI 0 "register_operand" "=r") |
ab5519b7 JW |
6239 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) |
6240 | (match_operand:SI 2 "small_int" "I")))] | |
5cb01b65 | 6241 | "TARGET_HARD_MUL32" |
6d29fc41 DE |
6242 | "* |
6243 | { | |
e0d80184 | 6244 | return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\"; |
6d29fc41 DE |
6245 | }" |
6246 | [(set (attr "length") | |
6247 | (if_then_else (eq_attr "isa" "sparclet") | |
6248 | (const_int 1) (const_int 2)))]) | |
ab5519b7 | 6249 | |
5cb01b65 JJ |
6250 | (define_insn "const_mulsidi3_sp64" |
6251 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6252 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6253 | (match_operand:SI 2 "small_int" "I")))] | |
6254 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
6255 | "smul\\t%1, %2, %0" | |
6256 | [(set_attr "length" "1")]) | |
6257 | ||
e783e4c2 JW |
6258 | (define_expand "smulsi3_highpart" |
6259 | [(set (match_operand:SI 0 "register_operand" "") | |
6260 | (truncate:SI | |
6261 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) | |
6262 | (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))) | |
6263 | (const_int 32))))] | |
5cb01b65 | 6264 | "TARGET_HARD_MUL && TARGET_ARCH32" |
e783e4c2 JW |
6265 | " |
6266 | { | |
6267 | if (CONSTANT_P (operands[2])) | |
6268 | { | |
2cea586a JW |
6269 | if (TARGET_V8PLUS) |
6270 | { | |
6271 | emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0], | |
6272 | operands[1], | |
6273 | operands[2], | |
6274 | GEN_INT (32))); | |
6275 | DONE; | |
6276 | } | |
e783e4c2 JW |
6277 | emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2])); |
6278 | DONE; | |
6279 | } | |
284d86e9 JC |
6280 | if (TARGET_V8PLUS) |
6281 | { | |
2cea586a JW |
6282 | emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1], |
6283 | operands[2], GEN_INT (32))); | |
284d86e9 JC |
6284 | DONE; |
6285 | } | |
e783e4c2 JW |
6286 | }") |
6287 | ||
e0d80184 | 6288 | ;; XXX |
2cea586a | 6289 | (define_insn "smulsi3_highpart_v8plus" |
284d86e9 JC |
6290 | [(set (match_operand:SI 0 "register_operand" "=h,r") |
6291 | (truncate:SI | |
6292 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
6293 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
6294 | (match_operand:SI 3 "const_int_operand" "i,i")))) | |
6295 | (clobber (match_scratch:SI 4 "=X,&h"))] | |
6296 | "TARGET_V8PLUS" | |
6297 | "@ | |
9ea2bda9 JJ |
6298 | smul\\t%1, %2, %0\;srlx\\t%0, %3, %0 |
6299 | smul\\t%1, %2, %4\;srlx\\t%4, %3, %0" | |
284d86e9 JC |
6300 | [(set_attr "length" "2")]) |
6301 | ||
c6b0465b | 6302 | ;; The combiner changes TRUNCATE in the previous pattern to SUBREG. |
e0d80184 | 6303 | ;; XXX |
c6b0465b JC |
6304 | (define_insn "" |
6305 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
6306 | (subreg:SI | |
6307 | (lshiftrt:DI | |
6308 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
6309 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
6310 | (match_operand:SI 3 "const_int_operand" "i,i")) | |
ddef6bc7 | 6311 | 4)) |
c6b0465b JC |
6312 | (clobber (match_scratch:SI 4 "=X,&h"))] |
6313 | "TARGET_V8PLUS" | |
6314 | "@ | |
e0d80184 DM |
6315 | smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0 |
6316 | smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0" | |
c6b0465b JC |
6317 | [(set_attr "length" "2")]) |
6318 | ||
e0d80184 | 6319 | ;; XXX |
2cea586a JW |
6320 | (define_insn "const_smulsi3_highpart_v8plus" |
6321 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
6322 | (truncate:SI | |
6323 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
c6b0465b | 6324 | (match_operand 2 "small_int" "i,i")) |
2cea586a JW |
6325 | (match_operand:SI 3 "const_int_operand" "i,i")))) |
6326 | (clobber (match_scratch:SI 4 "=X,&h"))] | |
6327 | "TARGET_V8PLUS" | |
6328 | "@ | |
e0d80184 DM |
6329 | smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0 |
6330 | smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0" | |
2cea586a JW |
6331 | [(set_attr "length" "2")]) |
6332 | ||
e0d80184 | 6333 | ;; XXX |
2cea586a | 6334 | (define_insn "*smulsi3_highpart_sp32" |
e783e4c2 JW |
6335 | [(set (match_operand:SI 0 "register_operand" "=r") |
6336 | (truncate:SI | |
6337 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6338 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) | |
6339 | (const_int 32))))] | |
e6c1be7e | 6340 | "TARGET_HARD_MUL32" |
e0d80184 | 6341 | "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0" |
e783e4c2 JW |
6342 | [(set_attr "length" "2")]) |
6343 | ||
e0d80184 | 6344 | ;; XXX |
e783e4c2 JW |
6345 | (define_insn "const_smulsi3_highpart" |
6346 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6347 | (truncate:SI | |
6348 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6349 | (match_operand:SI 2 "register_operand" "r")) | |
6350 | (const_int 32))))] | |
e6c1be7e | 6351 | "TARGET_HARD_MUL32" |
e0d80184 | 6352 | "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0" |
e783e4c2 JW |
6353 | [(set_attr "length" "2")]) |
6354 | ||
ab5519b7 JW |
6355 | (define_expand "umulsidi3" |
6356 | [(set (match_operand:DI 0 "register_operand" "") | |
6357 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | |
13a7eb33 | 6358 | (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))] |
bfd6bc60 | 6359 | "TARGET_HARD_MUL" |
ab5519b7 JW |
6360 | " |
6361 | { | |
6362 | if (CONSTANT_P (operands[2])) | |
6363 | { | |
2cea586a | 6364 | if (TARGET_V8PLUS) |
5cb01b65 JJ |
6365 | emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1], |
6366 | operands[2])); | |
6367 | else | |
6368 | emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1], | |
6369 | operands[2])); | |
ab5519b7 JW |
6370 | DONE; |
6371 | } | |
284d86e9 JC |
6372 | if (TARGET_V8PLUS) |
6373 | { | |
6374 | emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2])); | |
6375 | DONE; | |
6376 | } | |
ab5519b7 JW |
6377 | }") |
6378 | ||
e0d80184 | 6379 | ;; XXX |
284d86e9 JC |
6380 | (define_insn "umulsidi3_v8plus" |
6381 | [(set (match_operand:DI 0 "register_operand" "=h,r") | |
6382 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
6383 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) | |
6384 | (clobber (match_scratch:SI 3 "=X,&h"))] | |
6385 | "TARGET_V8PLUS" | |
6386 | "@ | |
e0d80184 DM |
6387 | umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0 |
6388 | umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0" | |
284d86e9 JC |
6389 | [(set_attr "length" "2,3")]) |
6390 | ||
e0d80184 | 6391 | ;; XXX |
c8b3b7d6 | 6392 | (define_insn "*umulsidi3_sp32" |
ab5519b7 JW |
6393 | [(set (match_operand:DI 0 "register_operand" "=r") |
6394 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6395 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
284d86e9 | 6396 | "TARGET_HARD_MUL32" |
6d29fc41 DE |
6397 | "* |
6398 | { | |
e0d80184 | 6399 | return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\"; |
6d29fc41 DE |
6400 | }" |
6401 | [(set (attr "length") | |
6402 | (if_then_else (eq_attr "isa" "sparclet") | |
6403 | (const_int 1) (const_int 2)))]) | |
ab5519b7 | 6404 | |
5cb01b65 JJ |
6405 | (define_insn "*umulsidi3_sp64" |
6406 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6407 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6408 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
6409 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
6410 | "umul\\t%1, %2, %0" | |
6411 | [(set_attr "length" "1")]) | |
6412 | ||
3826a3da | 6413 | ;; Extra pattern, because sign_extend of a constant isn't valid. |
ab5519b7 | 6414 | |
e0d80184 | 6415 | ;; XXX |
5cb01b65 | 6416 | (define_insn "const_umulsidi3_sp32" |
ab5519b7 JW |
6417 | [(set (match_operand:DI 0 "register_operand" "=r") |
6418 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
13a7eb33 | 6419 | (match_operand:SI 2 "uns_small_int" "")))] |
284d86e9 | 6420 | "TARGET_HARD_MUL32" |
6d29fc41 DE |
6421 | "* |
6422 | { | |
e0d80184 | 6423 | return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\"; |
6d29fc41 DE |
6424 | }" |
6425 | [(set (attr "length") | |
6426 | (if_then_else (eq_attr "isa" "sparclet") | |
6427 | (const_int 1) (const_int 2)))]) | |
77a02b01 | 6428 | |
5cb01b65 JJ |
6429 | (define_insn "const_umulsidi3_sp64" |
6430 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6431 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6432 | (match_operand:SI 2 "uns_small_int" "")))] | |
6433 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
6434 | "umul\\t%1, %2, %0" | |
6435 | [(set_attr "length" "1")]) | |
6436 | ||
e0d80184 | 6437 | ;; XXX |
284d86e9 JC |
6438 | (define_insn "const_umulsidi3_v8plus" |
6439 | [(set (match_operand:DI 0 "register_operand" "=h,r") | |
6440 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
6441 | (match_operand:SI 2 "uns_small_int" ""))) | |
6442 | (clobber (match_scratch:SI 3 "=X,h"))] | |
6443 | "TARGET_V8PLUS" | |
6444 | "@ | |
e0d80184 DM |
6445 | umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0 |
6446 | umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0" | |
284d86e9 JC |
6447 | [(set_attr "length" "2,3")]) |
6448 | ||
e783e4c2 JW |
6449 | (define_expand "umulsi3_highpart" |
6450 | [(set (match_operand:SI 0 "register_operand" "") | |
6451 | (truncate:SI | |
6452 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | |
6453 | (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))) | |
6454 | (const_int 32))))] | |
5cb01b65 | 6455 | "TARGET_HARD_MUL && TARGET_ARCH32" |
e783e4c2 JW |
6456 | " |
6457 | { | |
2cea586a | 6458 | if (CONSTANT_P (operands[2])) |
284d86e9 | 6459 | { |
2cea586a JW |
6460 | if (TARGET_V8PLUS) |
6461 | { | |
6462 | emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0], | |
6463 | operands[1], | |
6464 | operands[2], | |
6465 | GEN_INT (32))); | |
6466 | DONE; | |
6467 | } | |
6468 | emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2])); | |
284d86e9 JC |
6469 | DONE; |
6470 | } | |
2cea586a | 6471 | if (TARGET_V8PLUS) |
e783e4c2 | 6472 | { |
2cea586a JW |
6473 | emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1], |
6474 | operands[2], GEN_INT (32))); | |
e783e4c2 JW |
6475 | DONE; |
6476 | } | |
6477 | }") | |
6478 | ||
e0d80184 | 6479 | ;; XXX |
2cea586a | 6480 | (define_insn "umulsi3_highpart_v8plus" |
284d86e9 JC |
6481 | [(set (match_operand:SI 0 "register_operand" "=h,r") |
6482 | (truncate:SI | |
6483 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
6484 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
6485 | (match_operand:SI 3 "const_int_operand" "i,i")))) | |
6486 | (clobber (match_scratch:SI 4 "=X,h"))] | |
6487 | "TARGET_V8PLUS" | |
6488 | "@ | |
e0d80184 DM |
6489 | umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0 |
6490 | umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0" | |
284d86e9 JC |
6491 | [(set_attr "length" "2")]) |
6492 | ||
e0d80184 | 6493 | ;; XXX |
284d86e9 JC |
6494 | (define_insn "const_umulsi3_highpart_v8plus" |
6495 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
6496 | (truncate:SI | |
6497 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
6498 | (match_operand:SI 2 "uns_small_int" "")) | |
6499 | (match_operand:SI 3 "const_int_operand" "i,i")))) | |
6500 | (clobber (match_scratch:SI 4 "=X,h"))] | |
6501 | "TARGET_V8PLUS" | |
6502 | "@ | |
e0d80184 DM |
6503 | umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0 |
6504 | umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0" | |
284d86e9 JC |
6505 | [(set_attr "length" "2")]) |
6506 | ||
e0d80184 | 6507 | ;; XXX |
2cea586a | 6508 | (define_insn "*umulsi3_highpart_sp32" |
e783e4c2 JW |
6509 | [(set (match_operand:SI 0 "register_operand" "=r") |
6510 | (truncate:SI | |
6511 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6512 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) | |
6513 | (const_int 32))))] | |
e6c1be7e | 6514 | "TARGET_HARD_MUL32" |
e0d80184 | 6515 | "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0" |
e783e4c2 JW |
6516 | [(set_attr "length" "2")]) |
6517 | ||
e0d80184 | 6518 | ;; XXX |
e783e4c2 JW |
6519 | (define_insn "const_umulsi3_highpart" |
6520 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6521 | (truncate:SI | |
6522 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
6523 | (match_operand:SI 2 "uns_small_int" "")) | |
6524 | (const_int 32))))] | |
e6c1be7e | 6525 | "TARGET_HARD_MUL32" |
e0d80184 | 6526 | "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0" |
e783e4c2 JW |
6527 | [(set_attr "length" "2")]) |
6528 | ||
eb582c5d | 6529 | ;; The v8 architecture specifies that there must be 3 instructions between |
77a02b01 JW |
6530 | ;; a y register write and a use of it for correct results. |
6531 | ||
5cb01b65 JJ |
6532 | (define_expand "divsi3" |
6533 | [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r") | |
6534 | (div:SI (match_operand:SI 1 "register_operand" "r,r") | |
6535 | (match_operand:SI 2 "input_operand" "rI,m"))) | |
6536 | (clobber (match_scratch:SI 3 "=&r,&r"))])] | |
6537 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" | |
6538 | " | |
6539 | { | |
6540 | if (TARGET_ARCH64) | |
6541 | { | |
6542 | operands[3] = gen_reg_rtx(SImode); | |
6543 | emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31))); | |
6544 | emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2], | |
6545 | operands[3])); | |
6546 | DONE; | |
6547 | } | |
6548 | }") | |
6549 | ||
6550 | (define_insn "divsi3_sp32" | |
284d86e9 JC |
6551 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
6552 | (div:SI (match_operand:SI 1 "register_operand" "r,r") | |
e0d80184 | 6553 | (match_operand:SI 2 "input_operand" "rI,m"))) |
284d86e9 | 6554 | (clobber (match_scratch:SI 3 "=&r,&r"))] |
5cb01b65 JJ |
6555 | "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) |
6556 | && TARGET_ARCH32" | |
eb582c5d DE |
6557 | "* |
6558 | { | |
284d86e9 | 6559 | if (which_alternative == 0) |
5cb01b65 JJ |
6560 | if (TARGET_V9) |
6561 | return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\"; | |
6562 | else | |
6563 | return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\"; | |
284d86e9 JC |
6564 | else |
6565 | if (TARGET_V9) | |
5cb01b65 | 6566 | return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\"; |
284d86e9 | 6567 | else |
5cb01b65 | 6568 | return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\"; |
eb582c5d DE |
6569 | }" |
6570 | [(set (attr "length") | |
6571 | (if_then_else (eq_attr "isa" "v9") | |
284d86e9 | 6572 | (const_int 4) (const_int 7)))]) |
77a02b01 | 6573 | |
5cb01b65 JJ |
6574 | (define_insn "divsi3_sp64" |
6575 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6576 | (div:SI (match_operand:SI 1 "register_operand" "r") | |
6577 | (match_operand:SI 2 "input_operand" "rI"))) | |
6578 | (use (match_operand:SI 3 "register_operand" "r"))] | |
6579 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
6580 | "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0" | |
6581 | [(set_attr "length" "2")]) | |
6582 | ||
a8d2b752 DE |
6583 | (define_insn "divdi3" |
6584 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6585 | (div:DI (match_operand:DI 1 "register_operand" "r") | |
6586 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
fa0f39e4 | 6587 | "TARGET_ARCH64" |
e0d80184 | 6588 | "sdivx\\t%1, %2, %0") |
a8d2b752 | 6589 | |
c8b3b7d6 | 6590 | (define_insn "*cmp_sdiv_cc_set" |
5cb01b65 JJ |
6591 | [(set (reg:CC 100) |
6592 | (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r") | |
6593 | (match_operand:SI 2 "arith_operand" "rI")) | |
77a02b01 | 6594 | (const_int 0))) |
5cb01b65 JJ |
6595 | (set (match_operand:SI 0 "register_operand" "=r") |
6596 | (div:SI (match_dup 1) (match_dup 2))) | |
77a02b01 | 6597 | (clobber (match_scratch:SI 3 "=&r"))] |
5cb01b65 | 6598 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
eb582c5d DE |
6599 | "* |
6600 | { | |
6601 | if (TARGET_V9) | |
5cb01b65 | 6602 | return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\"; |
eb582c5d | 6603 | else |
5cb01b65 | 6604 | return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\"; |
eb582c5d DE |
6605 | }" |
6606 | [(set (attr "length") | |
6607 | (if_then_else (eq_attr "isa" "v9") | |
6608 | (const_int 3) (const_int 6)))]) | |
77a02b01 | 6609 | |
e0d80184 | 6610 | ;; XXX |
5cb01b65 JJ |
6611 | (define_expand "udivsi3" |
6612 | [(set (match_operand:SI 0 "register_operand" "") | |
6613 | (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "") | |
6614 | (match_operand:SI 2 "input_operand" "")))] | |
e6c1be7e | 6615 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
5cb01b65 JJ |
6616 | "") |
6617 | ||
6618 | (define_insn "udivsi3_sp32" | |
284d86e9 JC |
6619 | [(set (match_operand:SI 0 "register_operand" "=r,&r,&r") |
6620 | (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m") | |
e0d80184 DM |
6621 | (match_operand:SI 2 "input_operand" "rI,m,r")))] |
6622 | "(TARGET_V8 | |
6623 | || TARGET_DEPRECATED_V8_INSNS) | |
e6c1be7e | 6624 | && TARGET_ARCH32" |
eb582c5d DE |
6625 | "* |
6626 | { | |
e0d80184 | 6627 | output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands); |
284d86e9 JC |
6628 | switch (which_alternative) |
6629 | { | |
6630 | default: | |
e0d80184 | 6631 | return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\"; |
284d86e9 | 6632 | case 1: |
e0d80184 | 6633 | return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\"; |
284d86e9 | 6634 | case 2: |
e0d80184 | 6635 | return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\"; |
284d86e9 | 6636 | } |
eb582c5d | 6637 | }" |
5cb01b65 JJ |
6638 | [(set_attr "length" "5")]) |
6639 | ||
6640 | (define_insn "udivsi3_sp64" | |
6641 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6642 | (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r") | |
6643 | (match_operand:SI 2 "input_operand" "rI")))] | |
6644 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
6645 | "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0" | |
6646 | [(set_attr "length" "2")]) | |
77a02b01 | 6647 | |
a8d2b752 DE |
6648 | (define_insn "udivdi3" |
6649 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6650 | (udiv:DI (match_operand:DI 1 "register_operand" "r") | |
6651 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
fa0f39e4 | 6652 | "TARGET_ARCH64" |
e0d80184 | 6653 | "udivx\\t%1, %2, %0") |
a8d2b752 | 6654 | |
c8b3b7d6 | 6655 | (define_insn "*cmp_udiv_cc_set" |
5cb01b65 JJ |
6656 | [(set (reg:CC 100) |
6657 | (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r") | |
6658 | (match_operand:SI 2 "arith_operand" "rI")) | |
6659 | (const_int 0))) | |
6660 | (set (match_operand:SI 0 "register_operand" "=r") | |
6661 | (udiv:SI (match_dup 1) (match_dup 2)))] | |
e6c1be7e JJ |
6662 | "TARGET_V8 |
6663 | || TARGET_DEPRECATED_V8_INSNS" | |
eb582c5d DE |
6664 | "* |
6665 | { | |
6666 | if (TARGET_V9) | |
e0d80184 | 6667 | return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\"; |
eb582c5d | 6668 | else |
e0d80184 | 6669 | return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\"; |
eb582c5d DE |
6670 | }" |
6671 | [(set (attr "length") | |
6672 | (if_then_else (eq_attr "isa" "v9") | |
6673 | (const_int 2) (const_int 5)))]) | |
967ba98d DE |
6674 | |
6675 | ; sparclet multiply/accumulate insns | |
6676 | ||
6677 | (define_insn "*smacsi" | |
637166fe | 6678 | [(set (match_operand:SI 0 "register_operand" "=r") |
967ba98d DE |
6679 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r") |
6680 | (match_operand:SI 2 "arith_operand" "rI")) | |
6d29fc41 | 6681 | (match_operand:SI 3 "register_operand" "0")))] |
967ba98d | 6682 | "TARGET_SPARCLET" |
e0d80184 DM |
6683 | "smac\\t%1, %2, %0" |
6684 | [(set_attr "type" "imul") | |
6685 | (set_attr "length" "1")]) | |
967ba98d DE |
6686 | |
6687 | (define_insn "*smacdi" | |
637166fe | 6688 | [(set (match_operand:DI 0 "register_operand" "=r") |
967ba98d DE |
6689 | (plus:DI (mult:DI (sign_extend:DI |
6690 | (match_operand:SI 1 "register_operand" "%r")) | |
6691 | (sign_extend:DI | |
6692 | (match_operand:SI 2 "register_operand" "r"))) | |
6d29fc41 | 6693 | (match_operand:DI 3 "register_operand" "0")))] |
967ba98d | 6694 | "TARGET_SPARCLET" |
e0d80184 DM |
6695 | "smacd\\t%1, %2, %L0" |
6696 | [(set_attr "type" "imul") | |
6697 | (set_attr "length" "1")]) | |
967ba98d DE |
6698 | |
6699 | (define_insn "*umacdi" | |
637166fe | 6700 | [(set (match_operand:DI 0 "register_operand" "=r") |
967ba98d DE |
6701 | (plus:DI (mult:DI (zero_extend:DI |
6702 | (match_operand:SI 1 "register_operand" "%r")) | |
6703 | (zero_extend:DI | |
6704 | (match_operand:SI 2 "register_operand" "r"))) | |
6d29fc41 | 6705 | (match_operand:DI 3 "register_operand" "0")))] |
967ba98d | 6706 | "TARGET_SPARCLET" |
e0d80184 DM |
6707 | "umacd\\t%1, %2, %L0" |
6708 | [(set_attr "type" "imul") | |
6709 | (set_attr "length" "1")]) | |
6a4bb1fa DE |
6710 | \f |
6711 | ;;- Boolean instructions | |
967ba98d DE |
6712 | ;; We define DImode `and' so with DImode `not' we can get |
6713 | ;; DImode `andn'. Other combinations are possible. | |
7a768814 RS |
6714 | |
6715 | (define_expand "anddi3" | |
6716 | [(set (match_operand:DI 0 "register_operand" "") | |
6717 | (and:DI (match_operand:DI 1 "arith_double_operand" "") | |
6718 | (match_operand:DI 2 "arith_double_operand" "")))] | |
6719 | "" | |
6720 | "") | |
6721 | ||
c8b3b7d6 | 6722 | (define_insn "*anddi3_sp32" |
bfd6bc60 JC |
6723 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6724 | (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b") | |
6725 | (match_operand:DI 2 "arith_double_operand" "rHI,b")))] | |
fa0f39e4 | 6726 | "! TARGET_ARCH64" |
e0d80184 DM |
6727 | "@ |
6728 | # | |
6729 | fand\\t%1, %2, %0" | |
6730 | [(set_attr "type" "ialu,fp") | |
6731 | (set_attr "length" "2,1")]) | |
7a768814 | 6732 | |
c8b3b7d6 | 6733 | (define_insn "*anddi3_sp64" |
e0d80184 DM |
6734 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6735 | (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b") | |
6736 | (match_operand:DI 2 "arith_double_operand" "rHI,b")))] | |
fa0f39e4 | 6737 | "TARGET_ARCH64" |
e0d80184 DM |
6738 | "@ |
6739 | and\\t%1, %2, %0 | |
6740 | fand\\t%1, %2, %0" | |
6741 | [(set_attr "type" "ialu,fp") | |
6742 | (set_attr "length" "1,1")]) | |
a8d2b752 | 6743 | |
7a768814 | 6744 | (define_insn "andsi3" |
bfd6bc60 JC |
6745 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
6746 | (and:SI (match_operand:SI 1 "arith_operand" "%r,d") | |
6747 | (match_operand:SI 2 "arith_operand" "rI,d")))] | |
7a768814 | 6748 | "" |
bfd6bc60 | 6749 | "@ |
e0d80184 DM |
6750 | and\\t%1, %2, %0 |
6751 | fands\\t%1, %2, %0" | |
6752 | [(set_attr "type" "ialu,fp") | |
6753 | (set_attr "length" "1,1")]) | |
7a768814 | 6754 | |
95edfef2 JW |
6755 | (define_split |
6756 | [(set (match_operand:SI 0 "register_operand" "") | |
6757 | (and:SI (match_operand:SI 1 "register_operand" "") | |
5584677e JW |
6758 | (match_operand:SI 2 "" ""))) |
6759 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
95edfef2 | 6760 | "GET_CODE (operands[2]) == CONST_INT |
284d86e9 | 6761 | && !SMALL_INT32 (operands[2]) |
95edfef2 | 6762 | && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" |
5584677e JW |
6763 | [(set (match_dup 3) (match_dup 4)) |
6764 | (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))] | |
95edfef2 JW |
6765 | " |
6766 | { | |
284d86e9 | 6767 | operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff); |
95edfef2 JW |
6768 | }") |
6769 | ||
c6b0465b JC |
6770 | ;; Split DImode logical operations requiring two instructions. |
6771 | (define_split | |
6772 | [(set (match_operand:DI 0 "register_operand" "") | |
6773 | (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR | |
6774 | [(match_operand:DI 2 "register_operand" "") | |
6775 | (match_operand:DI 3 "arith_double_operand" "")]))] | |
e0d80184 DM |
6776 | "! TARGET_ARCH64 |
6777 | && reload_completed | |
e61c29e9 DM |
6778 | && ((GET_CODE (operands[0]) == REG |
6779 | && REGNO (operands[0]) < 32) | |
6780 | || (GET_CODE (operands[0]) == SUBREG | |
6781 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
6782 | && REGNO (SUBREG_REG (operands[0])) < 32))" | |
c6b0465b JC |
6783 | [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)])) |
6784 | (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))] | |
1c44748c DM |
6785 | " |
6786 | { | |
e61c29e9 DM |
6787 | if (GET_CODE (operands[0]) == SUBREG) |
6788 | operands[0] = alter_subreg (operands[0]); | |
1c44748c DM |
6789 | operands[4] = gen_highpart (SImode, operands[0]); |
6790 | operands[5] = gen_lowpart (SImode, operands[0]); | |
6791 | operands[6] = gen_highpart (SImode, operands[2]); | |
6792 | operands[7] = gen_lowpart (SImode, operands[2]); | |
93b7b953 | 6793 | #if HOST_BITS_PER_WIDE_INT == 32 |
1c44748c DM |
6794 | if (GET_CODE (operands[3]) == CONST_INT) |
6795 | { | |
6796 | if (INTVAL (operands[3]) < 0) | |
6797 | operands[8] = constm1_rtx; | |
6798 | else | |
6799 | operands[8] = const0_rtx; | |
6800 | } | |
6801 | else | |
93b7b953 | 6802 | #endif |
1c44748c DM |
6803 | operands[8] = gen_highpart (SImode, operands[3]); |
6804 | operands[9] = gen_lowpart (SImode, operands[3]); | |
6805 | }") | |
c6b0465b | 6806 | |
c8b3b7d6 | 6807 | (define_insn "*and_not_di_sp32" |
bfd6bc60 JC |
6808 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6809 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b")) | |
6810 | (match_operand:DI 2 "register_operand" "r,b")))] | |
fa0f39e4 | 6811 | "! TARGET_ARCH64" |
bfd6bc60 | 6812 | "@ |
e0d80184 DM |
6813 | # |
6814 | fandnot1\\t%1, %2, %0" | |
6815 | [(set_attr "type" "ialu,fp") | |
6816 | (set_attr "length" "2,1")]) | |
6817 | ||
6818 | (define_split | |
6819 | [(set (match_operand:DI 0 "register_operand" "") | |
6820 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "")) | |
6821 | (match_operand:DI 2 "register_operand" "")))] | |
6822 | "! TARGET_ARCH64 | |
6823 | && reload_completed | |
e61c29e9 DM |
6824 | && ((GET_CODE (operands[0]) == REG |
6825 | && REGNO (operands[0]) < 32) | |
6826 | || (GET_CODE (operands[0]) == SUBREG | |
6827 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
6828 | && REGNO (SUBREG_REG (operands[0])) < 32))" | |
e0d80184 DM |
6829 | [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5))) |
6830 | (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))] | |
e61c29e9 DM |
6831 | "if (GET_CODE (operands[0]) == SUBREG) |
6832 | operands[0] = alter_subreg (operands[0]); | |
6833 | operands[3] = gen_highpart (SImode, operands[0]); | |
e0d80184 DM |
6834 | operands[4] = gen_highpart (SImode, operands[1]); |
6835 | operands[5] = gen_highpart (SImode, operands[2]); | |
6836 | operands[6] = gen_lowpart (SImode, operands[0]); | |
6837 | operands[7] = gen_lowpart (SImode, operands[1]); | |
6838 | operands[8] = gen_lowpart (SImode, operands[2]);") | |
7a768814 | 6839 | |
c8b3b7d6 | 6840 | (define_insn "*and_not_di_sp64" |
e0d80184 DM |
6841 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6842 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b")) | |
6843 | (match_operand:DI 2 "register_operand" "r,b")))] | |
fa0f39e4 | 6844 | "TARGET_ARCH64" |
e0d80184 DM |
6845 | "@ |
6846 | andn\\t%2, %1, %0 | |
6847 | fandnot1\\t%1, %2, %0" | |
6848 | [(set_attr "type" "ialu,fp") | |
6849 | (set_attr "length" "1,1")]) | |
a8d2b752 | 6850 | |
c8b3b7d6 | 6851 | (define_insn "*and_not_si" |
bfd6bc60 JC |
6852 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
6853 | (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d")) | |
6854 | (match_operand:SI 2 "register_operand" "r,d")))] | |
7a768814 | 6855 | "" |
bfd6bc60 | 6856 | "@ |
e0d80184 DM |
6857 | andn\\t%2, %1, %0 |
6858 | fandnot1s\\t%1, %2, %0" | |
6859 | [(set_attr "type" "ialu,fp") | |
6860 | (set_attr "length" "1,1")]) | |
7a768814 RS |
6861 | |
6862 | (define_expand "iordi3" | |
6863 | [(set (match_operand:DI 0 "register_operand" "") | |
6864 | (ior:DI (match_operand:DI 1 "arith_double_operand" "") | |
6865 | (match_operand:DI 2 "arith_double_operand" "")))] | |
6866 | "" | |
6867 | "") | |
6868 | ||
c8b3b7d6 | 6869 | (define_insn "*iordi3_sp32" |
bfd6bc60 JC |
6870 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6871 | (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b") | |
6872 | (match_operand:DI 2 "arith_double_operand" "rHI,b")))] | |
fa0f39e4 | 6873 | "! TARGET_ARCH64" |
e0d80184 DM |
6874 | "@ |
6875 | # | |
6876 | for\\t%1, %2, %0" | |
6877 | [(set_attr "type" "ialu,fp") | |
6878 | (set_attr "length" "2,1")]) | |
7a768814 | 6879 | |
c8b3b7d6 | 6880 | (define_insn "*iordi3_sp64" |
e0d80184 DM |
6881 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6882 | (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b") | |
6883 | (match_operand:DI 2 "arith_double_operand" "rHI,b")))] | |
fa0f39e4 | 6884 | "TARGET_ARCH64" |
e0d80184 DM |
6885 | "@ |
6886 | or\\t%1, %2, %0 | |
6887 | for\\t%1, %2, %0" | |
6888 | [(set_attr "type" "ialu,fp") | |
6889 | (set_attr "length" "1,1")]) | |
a8d2b752 | 6890 | |
7a768814 | 6891 | (define_insn "iorsi3" |
bfd6bc60 JC |
6892 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
6893 | (ior:SI (match_operand:SI 1 "arith_operand" "%r,d") | |
6894 | (match_operand:SI 2 "arith_operand" "rI,d")))] | |
7a768814 | 6895 | "" |
bfd6bc60 | 6896 | "@ |
e0d80184 DM |
6897 | or\\t%1, %2, %0 |
6898 | fors\\t%1, %2, %0" | |
6899 | [(set_attr "type" "ialu,fp") | |
6900 | (set_attr "length" "1,1")]) | |
7a768814 | 6901 | |
95edfef2 JW |
6902 | (define_split |
6903 | [(set (match_operand:SI 0 "register_operand" "") | |
6904 | (ior:SI (match_operand:SI 1 "register_operand" "") | |
5584677e JW |
6905 | (match_operand:SI 2 "" ""))) |
6906 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
95edfef2 | 6907 | "GET_CODE (operands[2]) == CONST_INT |
284d86e9 | 6908 | && !SMALL_INT32 (operands[2]) |
95edfef2 | 6909 | && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" |
5584677e JW |
6910 | [(set (match_dup 3) (match_dup 4)) |
6911 | (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))] | |
95edfef2 JW |
6912 | " |
6913 | { | |
284d86e9 | 6914 | operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff); |
95edfef2 JW |
6915 | }") |
6916 | ||
c8b3b7d6 | 6917 | (define_insn "*or_not_di_sp32" |
bfd6bc60 JC |
6918 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6919 | (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b")) | |
6920 | (match_operand:DI 2 "register_operand" "r,b")))] | |
fa0f39e4 | 6921 | "! TARGET_ARCH64" |
bfd6bc60 | 6922 | "@ |
e0d80184 DM |
6923 | # |
6924 | fornot1\\t%1, %2, %0" | |
6925 | [(set_attr "type" "ialu,fp") | |
6926 | (set_attr "length" "2,1")]) | |
6927 | ||
6928 | (define_split | |
6929 | [(set (match_operand:DI 0 "register_operand" "") | |
6930 | (ior:DI (not:DI (match_operand:DI 1 "register_operand" "")) | |
6931 | (match_operand:DI 2 "register_operand" "")))] | |
6932 | "! TARGET_ARCH64 | |
6933 | && reload_completed | |
e61c29e9 DM |
6934 | && ((GET_CODE (operands[0]) == REG |
6935 | && REGNO (operands[0]) < 32) | |
6936 | || (GET_CODE (operands[0]) == SUBREG | |
6937 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
6938 | && REGNO (SUBREG_REG (operands[0])) < 32))" | |
e0d80184 DM |
6939 | [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5))) |
6940 | (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))] | |
e61c29e9 DM |
6941 | "if (GET_CODE (operands[0]) == SUBREG) |
6942 | operands[0] = alter_subreg (operands[0]); | |
6943 | operands[3] = gen_highpart (SImode, operands[0]); | |
e0d80184 DM |
6944 | operands[4] = gen_highpart (SImode, operands[1]); |
6945 | operands[5] = gen_highpart (SImode, operands[2]); | |
6946 | operands[6] = gen_lowpart (SImode, operands[0]); | |
6947 | operands[7] = gen_lowpart (SImode, operands[1]); | |
6948 | operands[8] = gen_lowpart (SImode, operands[2]);") | |
7a768814 | 6949 | |
c8b3b7d6 | 6950 | (define_insn "*or_not_di_sp64" |
e0d80184 DM |
6951 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6952 | (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b")) | |
6953 | (match_operand:DI 2 "register_operand" "r,b")))] | |
fa0f39e4 | 6954 | "TARGET_ARCH64" |
e0d80184 DM |
6955 | "@ |
6956 | orn\\t%2, %1, %0 | |
6957 | fornot1\\t%1, %2, %0" | |
6958 | [(set_attr "type" "ialu,fp") | |
6959 | (set_attr "length" "1,1")]) | |
a8d2b752 | 6960 | |
c8b3b7d6 | 6961 | (define_insn "*or_not_si" |
bfd6bc60 JC |
6962 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
6963 | (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d")) | |
6964 | (match_operand:SI 2 "register_operand" "r,d")))] | |
7a768814 | 6965 | "" |
bfd6bc60 | 6966 | "@ |
e0d80184 DM |
6967 | orn\\t%2, %1, %0 |
6968 | fornot1s\\t%1, %2, %0" | |
6969 | [(set_attr "type" "ialu,fp") | |
6970 | (set_attr "length" "1,1")]) | |
7a768814 RS |
6971 | |
6972 | (define_expand "xordi3" | |
6973 | [(set (match_operand:DI 0 "register_operand" "") | |
6974 | (xor:DI (match_operand:DI 1 "arith_double_operand" "") | |
6975 | (match_operand:DI 2 "arith_double_operand" "")))] | |
6976 | "" | |
6977 | "") | |
6978 | ||
284d86e9 | 6979 | (define_insn "*xordi3_sp32" |
bfd6bc60 JC |
6980 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6981 | (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b") | |
6982 | (match_operand:DI 2 "arith_double_operand" "rHI,b")))] | |
fa0f39e4 | 6983 | "! TARGET_ARCH64" |
e0d80184 DM |
6984 | "@ |
6985 | # | |
6986 | fxor\\t%1, %2, %0" | |
284d86e9 JC |
6987 | [(set_attr "length" "2,1") |
6988 | (set_attr "type" "ialu,fp")]) | |
7a768814 | 6989 | |
c8b3b7d6 | 6990 | (define_insn "*xordi3_sp64" |
e0d80184 DM |
6991 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
6992 | (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b") | |
6993 | (match_operand:DI 2 "arith_double_operand" "rHI,b")))] | |
fa0f39e4 | 6994 | "TARGET_ARCH64" |
e0d80184 DM |
6995 | "@ |
6996 | xor\\t%r1, %2, %0 | |
6997 | fxor\\t%1, %2, %0" | |
6998 | [(set_attr "type" "ialu,fp") | |
6999 | (set_attr "length" "1,1")]) | |
7000 | ||
7001 | (define_insn "*xordi3_sp64_dbl" | |
7002 | [(set (match_operand:DI 0 "register_operand" "=r") | |
f710f868 | 7003 | (xor:DI (match_operand:DI 1 "register_operand" "r") |
89e65674 | 7004 | (match_operand:DI 2 "const64_operand" "")))] |
9208e4b2 DM |
7005 | "(TARGET_ARCH64 |
7006 | && HOST_BITS_PER_WIDE_INT != 64)" | |
89e65674 | 7007 | "xor\\t%1, %2, %0" |
e0d80184 DM |
7008 | [(set_attr "type" "ialu") |
7009 | (set_attr "length" "1")]) | |
a8d2b752 | 7010 | |
7a768814 | 7011 | (define_insn "xorsi3" |
bfd6bc60 JC |
7012 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
7013 | (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d") | |
7014 | (match_operand:SI 2 "arith_operand" "rI,d")))] | |
7a768814 | 7015 | "" |
bfd6bc60 | 7016 | "@ |
e0d80184 DM |
7017 | xor\\t%r1, %2, %0 |
7018 | fxors\\t%1, %2, %0" | |
7019 | [(set_attr "type" "ialu,fp") | |
7020 | (set_attr "length" "1,1")]) | |
7a768814 | 7021 | |
95edfef2 JW |
7022 | (define_split |
7023 | [(set (match_operand:SI 0 "register_operand" "") | |
7024 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
5584677e JW |
7025 | (match_operand:SI 2 "" ""))) |
7026 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
95edfef2 | 7027 | "GET_CODE (operands[2]) == CONST_INT |
284d86e9 | 7028 | && !SMALL_INT32 (operands[2]) |
95edfef2 | 7029 | && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" |
5584677e JW |
7030 | [(set (match_dup 3) (match_dup 4)) |
7031 | (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))] | |
95edfef2 JW |
7032 | " |
7033 | { | |
284d86e9 | 7034 | operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff); |
95edfef2 JW |
7035 | }") |
7036 | ||
7037 | (define_split | |
7038 | [(set (match_operand:SI 0 "register_operand" "") | |
7039 | (not:SI (xor:SI (match_operand:SI 1 "register_operand" "") | |
5584677e JW |
7040 | (match_operand:SI 2 "" "")))) |
7041 | (clobber (match_operand:SI 3 "register_operand" ""))] | |
95edfef2 | 7042 | "GET_CODE (operands[2]) == CONST_INT |
284d86e9 | 7043 | && !SMALL_INT32 (operands[2]) |
95edfef2 | 7044 | && (INTVAL (operands[2]) & 0x3ff) == 0x3ff" |
5584677e JW |
7045 | [(set (match_dup 3) (match_dup 4)) |
7046 | (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))] | |
95edfef2 JW |
7047 | " |
7048 | { | |
284d86e9 | 7049 | operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff); |
95edfef2 JW |
7050 | }") |
7051 | ||
7a768814 RS |
7052 | ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b). |
7053 | ;; Combine now canonicalizes to the rightmost expression. | |
c8b3b7d6 | 7054 | (define_insn "*xor_not_di_sp32" |
bfd6bc60 JC |
7055 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
7056 | (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b") | |
7057 | (match_operand:DI 2 "register_operand" "r,b"))))] | |
fa0f39e4 | 7058 | "! TARGET_ARCH64" |
bfd6bc60 | 7059 | "@ |
e0d80184 DM |
7060 | # |
7061 | fxnor\\t%1, %2, %0" | |
bfd6bc60 JC |
7062 | [(set_attr "length" "2,1") |
7063 | (set_attr "type" "ialu,fp")]) | |
7a768814 | 7064 | |
e0d80184 DM |
7065 | (define_split |
7066 | [(set (match_operand:DI 0 "register_operand" "") | |
7067 | (not:DI (xor:DI (match_operand:DI 1 "register_operand" "") | |
7068 | (match_operand:DI 2 "register_operand" ""))))] | |
7069 | "! TARGET_ARCH64 | |
7070 | && reload_completed | |
e61c29e9 DM |
7071 | && ((GET_CODE (operands[0]) == REG |
7072 | && REGNO (operands[0]) < 32) | |
7073 | || (GET_CODE (operands[0]) == SUBREG | |
7074 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
7075 | && REGNO (SUBREG_REG (operands[0])) < 32))" | |
e0d80184 DM |
7076 | [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5)))) |
7077 | (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))] | |
e61c29e9 DM |
7078 | "if (GET_CODE (operands[0]) == SUBREG) |
7079 | operands[0] = alter_subreg (operands[0]); | |
7080 | operands[3] = gen_highpart (SImode, operands[0]); | |
e0d80184 DM |
7081 | operands[4] = gen_highpart (SImode, operands[1]); |
7082 | operands[5] = gen_highpart (SImode, operands[2]); | |
7083 | operands[6] = gen_lowpart (SImode, operands[0]); | |
7084 | operands[7] = gen_lowpart (SImode, operands[1]); | |
7085 | operands[8] = gen_lowpart (SImode, operands[2]);") | |
7086 | ||
c8b3b7d6 | 7087 | (define_insn "*xor_not_di_sp64" |
e0d80184 DM |
7088 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
7089 | (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b") | |
7090 | (match_operand:DI 2 "arith_double_operand" "rHI,b"))))] | |
fa0f39e4 | 7091 | "TARGET_ARCH64" |
e0d80184 DM |
7092 | "@ |
7093 | xnor\\t%r1, %2, %0 | |
7094 | fxnor\\t%1, %2, %0" | |
7095 | [(set_attr "type" "ialu,fp") | |
7096 | (set_attr "length" "1,1")]) | |
a8d2b752 | 7097 | |
c8b3b7d6 | 7098 | (define_insn "*xor_not_si" |
bfd6bc60 JC |
7099 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
7100 | (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d") | |
7101 | (match_operand:SI 2 "arith_operand" "rI,d"))))] | |
7a768814 | 7102 | "" |
bfd6bc60 | 7103 | "@ |
e0d80184 DM |
7104 | xnor\\t%r1, %2, %0 |
7105 | fxnors\\t%1, %2, %0" | |
7106 | [(set_attr "type" "ialu,fp") | |
7107 | (set_attr "length" "1,1")]) | |
7a768814 RS |
7108 | |
7109 | ;; These correspond to the above in the case where we also (or only) | |
7110 | ;; want to set the condition code. | |
7111 | ||
c8b3b7d6 | 7112 | (define_insn "*cmp_cc_arith_op" |
c4ce6853 | 7113 | [(set (reg:CC 100) |
7a768814 RS |
7114 | (compare:CC |
7115 | (match_operator:SI 2 "cc_arithop" | |
7116 | [(match_operand:SI 0 "arith_operand" "%r") | |
7117 | (match_operand:SI 1 "arith_operand" "rI")]) | |
7118 | (const_int 0)))] | |
e6c1be7e | 7119 | "" |
e0d80184 DM |
7120 | "%A2cc\\t%0, %1, %%g0" |
7121 | [(set_attr "type" "compare") | |
7122 | (set_attr "length" "1")]) | |
7a768814 | 7123 | |
c8b3b7d6 | 7124 | (define_insn "*cmp_ccx_arith_op" |
c4ce6853 | 7125 | [(set (reg:CCX 100) |
a8d2b752 DE |
7126 | (compare:CCX |
7127 | (match_operator:DI 2 "cc_arithop" | |
7128 | [(match_operand:DI 0 "arith_double_operand" "%r") | |
7129 | (match_operand:DI 1 "arith_double_operand" "rHI")]) | |
7130 | (const_int 0)))] | |
fa0f39e4 | 7131 | "TARGET_ARCH64" |
e0d80184 DM |
7132 | "%A2cc\\t%0, %1, %%g0" |
7133 | [(set_attr "type" "compare") | |
7134 | (set_attr "length" "1")]) | |
a8d2b752 | 7135 | |
c8b3b7d6 | 7136 | (define_insn "*cmp_cc_arith_op_set" |
c4ce6853 | 7137 | [(set (reg:CC 100) |
7a768814 RS |
7138 | (compare:CC |
7139 | (match_operator:SI 3 "cc_arithop" | |
7140 | [(match_operand:SI 1 "arith_operand" "%r") | |
7141 | (match_operand:SI 2 "arith_operand" "rI")]) | |
7142 | (const_int 0))) | |
7143 | (set (match_operand:SI 0 "register_operand" "=r") | |
1b9ea8eb RH |
7144 | (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))] |
7145 | "GET_CODE (operands[3]) == GET_CODE (operands[4])" | |
e0d80184 DM |
7146 | "%A3cc\\t%1, %2, %0" |
7147 | [(set_attr "type" "compare") | |
7148 | (set_attr "length" "1")]) | |
a8d2b752 | 7149 | |
c8b3b7d6 | 7150 | (define_insn "*cmp_ccx_arith_op_set" |
c4ce6853 | 7151 | [(set (reg:CCX 100) |
a8d2b752 DE |
7152 | (compare:CCX |
7153 | (match_operator:DI 3 "cc_arithop" | |
7154 | [(match_operand:DI 1 "arith_double_operand" "%r") | |
7155 | (match_operand:DI 2 "arith_double_operand" "rHI")]) | |
7156 | (const_int 0))) | |
7157 | (set (match_operand:DI 0 "register_operand" "=r") | |
1b9ea8eb RH |
7158 | (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))] |
7159 | "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])" | |
e0d80184 DM |
7160 | "%A3cc\\t%1, %2, %0" |
7161 | [(set_attr "type" "compare") | |
7162 | (set_attr "length" "1")]) | |
7a768814 | 7163 | |
c8b3b7d6 | 7164 | (define_insn "*cmp_cc_xor_not" |
c4ce6853 | 7165 | [(set (reg:CC 100) |
7a768814 RS |
7166 | (compare:CC |
7167 | (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ") | |
7168 | (match_operand:SI 1 "arith_operand" "rI"))) | |
7169 | (const_int 0)))] | |
e6c1be7e | 7170 | "" |
e0d80184 DM |
7171 | "xnorcc\\t%r0, %1, %%g0" |
7172 | [(set_attr "type" "compare") | |
7173 | (set_attr "length" "1")]) | |
7a768814 | 7174 | |
c8b3b7d6 | 7175 | (define_insn "*cmp_ccx_xor_not" |
c4ce6853 | 7176 | [(set (reg:CCX 100) |
a8d2b752 DE |
7177 | (compare:CCX |
7178 | (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ") | |
7179 | (match_operand:DI 1 "arith_double_operand" "rHI"))) | |
7180 | (const_int 0)))] | |
fa0f39e4 | 7181 | "TARGET_ARCH64" |
e0d80184 DM |
7182 | "xnorcc\\t%r0, %1, %%g0" |
7183 | [(set_attr "type" "compare") | |
7184 | (set_attr "length" "1")]) | |
a8d2b752 | 7185 | |
c8b3b7d6 | 7186 | (define_insn "*cmp_cc_xor_not_set" |
c4ce6853 | 7187 | [(set (reg:CC 100) |
7a768814 RS |
7188 | (compare:CC |
7189 | (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") | |
7190 | (match_operand:SI 2 "arith_operand" "rI"))) | |
7191 | (const_int 0))) | |
7192 | (set (match_operand:SI 0 "register_operand" "=r") | |
7193 | (not:SI (xor:SI (match_dup 1) (match_dup 2))))] | |
7194 | "" | |
e0d80184 DM |
7195 | "xnorcc\\t%r1, %2, %0" |
7196 | [(set_attr "type" "compare") | |
7197 | (set_attr "length" "1")]) | |
7a768814 | 7198 | |
c8b3b7d6 | 7199 | (define_insn "*cmp_ccx_xor_not_set" |
c4ce6853 | 7200 | [(set (reg:CCX 100) |
a8d2b752 DE |
7201 | (compare:CCX |
7202 | (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") | |
7203 | (match_operand:DI 2 "arith_double_operand" "rHI"))) | |
7204 | (const_int 0))) | |
7205 | (set (match_operand:DI 0 "register_operand" "=r") | |
7206 | (not:DI (xor:DI (match_dup 1) (match_dup 2))))] | |
fa0f39e4 | 7207 | "TARGET_ARCH64" |
e0d80184 DM |
7208 | "xnorcc\\t%r1, %2, %0" |
7209 | [(set_attr "type" "compare") | |
7210 | (set_attr "length" "1")]) | |
a8d2b752 | 7211 | |
c8b3b7d6 | 7212 | (define_insn "*cmp_cc_arith_op_not" |
c4ce6853 | 7213 | [(set (reg:CC 100) |
7a768814 RS |
7214 | (compare:CC |
7215 | (match_operator:SI 2 "cc_arithopn" | |
7216 | [(not:SI (match_operand:SI 0 "arith_operand" "rI")) | |
7217 | (match_operand:SI 1 "reg_or_0_operand" "rJ")]) | |
7218 | (const_int 0)))] | |
e6c1be7e | 7219 | "" |
e0d80184 DM |
7220 | "%B2cc\\t%r1, %0, %%g0" |
7221 | [(set_attr "type" "compare") | |
7222 | (set_attr "length" "1")]) | |
7a768814 | 7223 | |
c8b3b7d6 | 7224 | (define_insn "*cmp_ccx_arith_op_not" |
c4ce6853 | 7225 | [(set (reg:CCX 100) |
a8d2b752 DE |
7226 | (compare:CCX |
7227 | (match_operator:DI 2 "cc_arithopn" | |
7228 | [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI")) | |
7229 | (match_operand:DI 1 "reg_or_0_operand" "rJ")]) | |
7230 | (const_int 0)))] | |
fa0f39e4 | 7231 | "TARGET_ARCH64" |
e0d80184 DM |
7232 | "%B2cc\\t%r1, %0, %%g0" |
7233 | [(set_attr "type" "compare") | |
7234 | (set_attr "length" "1")]) | |
a8d2b752 | 7235 | |
c8b3b7d6 | 7236 | (define_insn "*cmp_cc_arith_op_not_set" |
c4ce6853 | 7237 | [(set (reg:CC 100) |
7a768814 RS |
7238 | (compare:CC |
7239 | (match_operator:SI 3 "cc_arithopn" | |
7240 | [(not:SI (match_operand:SI 1 "arith_operand" "rI")) | |
7241 | (match_operand:SI 2 "reg_or_0_operand" "rJ")]) | |
7242 | (const_int 0))) | |
7243 | (set (match_operand:SI 0 "register_operand" "=r") | |
1b9ea8eb RH |
7244 | (match_operator:SI 4 "cc_arithopn" |
7245 | [(not:SI (match_dup 1)) (match_dup 2)]))] | |
7246 | "GET_CODE (operands[3]) == GET_CODE (operands[4])" | |
e0d80184 DM |
7247 | "%B3cc\\t%r2, %1, %0" |
7248 | [(set_attr "type" "compare") | |
7249 | (set_attr "length" "1")]) | |
7a768814 | 7250 | |
c8b3b7d6 | 7251 | (define_insn "*cmp_ccx_arith_op_not_set" |
c4ce6853 | 7252 | [(set (reg:CCX 100) |
a8d2b752 DE |
7253 | (compare:CCX |
7254 | (match_operator:DI 3 "cc_arithopn" | |
7255 | [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI")) | |
7256 | (match_operand:DI 2 "reg_or_0_operand" "rJ")]) | |
7257 | (const_int 0))) | |
7258 | (set (match_operand:DI 0 "register_operand" "=r") | |
1b9ea8eb RH |
7259 | (match_operator:DI 4 "cc_arithopn" |
7260 | [(not:DI (match_dup 1)) (match_dup 2)]))] | |
7261 | "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])" | |
e0d80184 DM |
7262 | "%B3cc\\t%r2, %1, %0" |
7263 | [(set_attr "type" "compare") | |
7264 | (set_attr "length" "1")]) | |
a8d2b752 | 7265 | |
7a768814 RS |
7266 | ;; We cannot use the "neg" pseudo insn because the Sun assembler |
7267 | ;; does not know how to make it work for constants. | |
7268 | ||
a8d2b752 DE |
7269 | (define_expand "negdi2" |
7270 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7271 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
7272 | "" | |
7273 | " | |
7274 | { | |
fa0f39e4 | 7275 | if (! TARGET_ARCH64) |
a8d2b752 | 7276 | { |
c5c76735 JL |
7277 | emit_insn (gen_rtx_PARALLEL |
7278 | (VOIDmode, | |
7279 | gen_rtvec (2, | |
7280 | gen_rtx_SET (VOIDmode, operand0, | |
7281 | gen_rtx_NEG (DImode, operand1)), | |
7282 | gen_rtx_CLOBBER (VOIDmode, | |
7283 | gen_rtx_REG (CCmode, | |
7284 | SPARC_ICC_REG))))); | |
a8d2b752 DE |
7285 | DONE; |
7286 | } | |
7287 | }") | |
7288 | ||
c8b3b7d6 | 7289 | (define_insn "*negdi2_sp32" |
7a768814 RS |
7290 | [(set (match_operand:DI 0 "register_operand" "=r") |
7291 | (neg:DI (match_operand:DI 1 "register_operand" "r"))) | |
c6b0465b | 7292 | (clobber (reg:CC 100))] |
e6c1be7e | 7293 | "TARGET_ARCH32" |
e0d80184 | 7294 | "#" |
7a768814 RS |
7295 | [(set_attr "type" "unary") |
7296 | (set_attr "length" "2")]) | |
7297 | ||
e0d80184 DM |
7298 | (define_split |
7299 | [(set (match_operand:DI 0 "register_operand" "") | |
7300 | (neg:DI (match_operand:DI 1 "register_operand" ""))) | |
7301 | (clobber (reg:CC 100))] | |
e6c1be7e | 7302 | "TARGET_ARCH32 |
e0d80184 DM |
7303 | && reload_completed" |
7304 | [(parallel [(set (reg:CC_NOOV 100) | |
7305 | (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5)) | |
7306 | (const_int 0))) | |
7307 | (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))]) | |
7308 | (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) | |
7309 | (ltu:SI (reg:CC 100) (const_int 0))))] | |
7310 | "operands[2] = gen_highpart (SImode, operands[0]); | |
7311 | operands[3] = gen_highpart (SImode, operands[1]); | |
7312 | operands[4] = gen_lowpart (SImode, operands[0]); | |
7313 | operands[5] = gen_lowpart (SImode, operands[1]);") | |
7314 | ||
c8b3b7d6 | 7315 | (define_insn "*negdi2_sp64" |
a8d2b752 DE |
7316 | [(set (match_operand:DI 0 "register_operand" "=r") |
7317 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
fa0f39e4 | 7318 | "TARGET_ARCH64" |
e0d80184 | 7319 | "sub\\t%%g0, %1, %0" |
a8d2b752 DE |
7320 | [(set_attr "type" "unary") |
7321 | (set_attr "length" "1")]) | |
7322 | ||
e6c1be7e | 7323 | (define_insn "negsi2" |
e0d80184 | 7324 | [(set (match_operand:SI 0 "register_operand" "=r") |
e6c1be7e JJ |
7325 | (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] |
7326 | "" | |
e0d80184 | 7327 | "sub\\t%%g0, %1, %0" |
c4ce6853 | 7328 | [(set_attr "type" "unary") |
e0d80184 | 7329 | (set_attr "length" "1")]) |
7a768814 | 7330 | |
c8b3b7d6 | 7331 | (define_insn "*cmp_cc_neg" |
c4ce6853 | 7332 | [(set (reg:CC_NOOV 100) |
7a768814 RS |
7333 | (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) |
7334 | (const_int 0)))] | |
e6c1be7e | 7335 | "" |
e0d80184 DM |
7336 | "subcc\\t%%g0, %0, %%g0" |
7337 | [(set_attr "type" "compare") | |
7338 | (set_attr "length" "1")]) | |
7a768814 | 7339 | |
c8b3b7d6 | 7340 | (define_insn "*cmp_ccx_neg" |
c4ce6853 | 7341 | [(set (reg:CCX_NOOV 100) |
a8d2b752 DE |
7342 | (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI")) |
7343 | (const_int 0)))] | |
fa0f39e4 | 7344 | "TARGET_ARCH64" |
e0d80184 DM |
7345 | "subcc\\t%%g0, %0, %%g0" |
7346 | [(set_attr "type" "compare") | |
7347 | (set_attr "length" "1")]) | |
a8d2b752 | 7348 | |
c8b3b7d6 | 7349 | (define_insn "*cmp_cc_set_neg" |
c4ce6853 | 7350 | [(set (reg:CC_NOOV 100) |
7a768814 RS |
7351 | (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) |
7352 | (const_int 0))) | |
7353 | (set (match_operand:SI 0 "register_operand" "=r") | |
7354 | (neg:SI (match_dup 1)))] | |
e6c1be7e | 7355 | "" |
e0d80184 DM |
7356 | "subcc\\t%%g0, %1, %0" |
7357 | [(set_attr "type" "compare") | |
7358 | (set_attr "length" "1")]) | |
7a768814 | 7359 | |
c8b3b7d6 | 7360 | (define_insn "*cmp_ccx_set_neg" |
c4ce6853 | 7361 | [(set (reg:CCX_NOOV 100) |
a8d2b752 DE |
7362 | (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI")) |
7363 | (const_int 0))) | |
7364 | (set (match_operand:DI 0 "register_operand" "=r") | |
7365 | (neg:DI (match_dup 1)))] | |
fa0f39e4 | 7366 | "TARGET_ARCH64" |
e0d80184 DM |
7367 | "subcc\\t%%g0, %1, %0" |
7368 | [(set_attr "type" "compare") | |
7369 | (set_attr "length" "1")]) | |
a8d2b752 | 7370 | |
7a768814 RS |
7371 | ;; We cannot use the "not" pseudo insn because the Sun assembler |
7372 | ;; does not know how to make it work for constants. | |
7373 | (define_expand "one_cmpldi2" | |
ae526227 JW |
7374 | [(set (match_operand:DI 0 "register_operand" "") |
7375 | (not:DI (match_operand:DI 1 "register_operand" "")))] | |
7a768814 RS |
7376 | "" |
7377 | "") | |
7378 | ||
c8b3b7d6 | 7379 | (define_insn "*one_cmpldi2_sp32" |
bfd6bc60 JC |
7380 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
7381 | (not:DI (match_operand:DI 1 "register_operand" "r,b")))] | |
fa0f39e4 | 7382 | "! TARGET_ARCH64" |
bfd6bc60 | 7383 | "@ |
e0d80184 DM |
7384 | # |
7385 | fnot1\\t%1, %0" | |
bfd6bc60 JC |
7386 | [(set_attr "type" "unary,fp") |
7387 | (set_attr "length" "2,1")]) | |
7a768814 | 7388 | |
e0d80184 DM |
7389 | (define_split |
7390 | [(set (match_operand:DI 0 "register_operand" "") | |
7391 | (not:DI (match_operand:DI 1 "register_operand" "")))] | |
7392 | "! TARGET_ARCH64 | |
7393 | && reload_completed | |
e61c29e9 DM |
7394 | && ((GET_CODE (operands[0]) == REG |
7395 | && REGNO (operands[0]) < 32) | |
7396 | || (GET_CODE (operands[0]) == SUBREG | |
7397 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
7398 | && REGNO (SUBREG_REG (operands[0])) < 32))" | |
e0d80184 DM |
7399 | [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0)))) |
7400 | (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))] | |
e61c29e9 DM |
7401 | "if (GET_CODE (operands[0]) == SUBREG) |
7402 | operands[0] = alter_subreg (operands[0]); | |
7403 | operands[2] = gen_highpart (SImode, operands[0]); | |
e0d80184 DM |
7404 | operands[3] = gen_highpart (SImode, operands[1]); |
7405 | operands[4] = gen_lowpart (SImode, operands[0]); | |
7406 | operands[5] = gen_lowpart (SImode, operands[1]);") | |
7407 | ||
c8b3b7d6 | 7408 | (define_insn "*one_cmpldi2_sp64" |
f952a238 JJ |
7409 | [(set (match_operand:DI 0 "register_operand" "=r,b") |
7410 | (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))] | |
fa0f39e4 | 7411 | "TARGET_ARCH64" |
f952a238 JJ |
7412 | "@ |
7413 | xnor\\t%%g0, %1, %0 | |
7414 | fnot1\\t%1, %0" | |
7415 | [(set_attr "type" "unary,fp") | |
e0d80184 | 7416 | (set_attr "length" "1")]) |
a8d2b752 | 7417 | |
e6c1be7e | 7418 | (define_insn "one_cmplsi2" |
f710f868 DM |
7419 | [(set (match_operand:SI 0 "register_operand" "=r,d") |
7420 | (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))] | |
e6c1be7e | 7421 | "" |
e0d80184 | 7422 | "@ |
e0d80184 DM |
7423 | xnor\\t%%g0, %1, %0 |
7424 | fnot1s\\t%1, %0" | |
f710f868 DM |
7425 | [(set_attr "type" "unary,fp") |
7426 | (set_attr "length" "1,1")]) | |
e0d80184 | 7427 | |
c8b3b7d6 | 7428 | (define_insn "*cmp_cc_not" |
c4ce6853 | 7429 | [(set (reg:CC 100) |
7a768814 RS |
7430 | (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) |
7431 | (const_int 0)))] | |
e6c1be7e | 7432 | "" |
e0d80184 DM |
7433 | "xnorcc\\t%%g0, %0, %%g0" |
7434 | [(set_attr "type" "compare") | |
7435 | (set_attr "length" "1")]) | |
7a768814 | 7436 | |
c8b3b7d6 | 7437 | (define_insn "*cmp_ccx_not" |
c4ce6853 | 7438 | [(set (reg:CCX 100) |
a8d2b752 DE |
7439 | (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI")) |
7440 | (const_int 0)))] | |
fa0f39e4 | 7441 | "TARGET_ARCH64" |
e0d80184 DM |
7442 | "xnorcc\\t%%g0, %0, %%g0" |
7443 | [(set_attr "type" "compare") | |
7444 | (set_attr "length" "1")]) | |
a8d2b752 | 7445 | |
c8b3b7d6 | 7446 | (define_insn "*cmp_cc_set_not" |
c4ce6853 | 7447 | [(set (reg:CC 100) |
7a768814 RS |
7448 | (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) |
7449 | (const_int 0))) | |
7450 | (set (match_operand:SI 0 "register_operand" "=r") | |
7451 | (not:SI (match_dup 1)))] | |
e6c1be7e | 7452 | "" |
e0d80184 DM |
7453 | "xnorcc\\t%%g0, %1, %0" |
7454 | [(set_attr "type" "compare") | |
7455 | (set_attr "length" "1")]) | |
a8d2b752 | 7456 | |
c8b3b7d6 | 7457 | (define_insn "*cmp_ccx_set_not" |
c4ce6853 | 7458 | [(set (reg:CCX 100) |
a8d2b752 DE |
7459 | (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")) |
7460 | (const_int 0))) | |
7461 | (set (match_operand:DI 0 "register_operand" "=r") | |
7462 | (not:DI (match_dup 1)))] | |
fa0f39e4 | 7463 | "TARGET_ARCH64" |
e0d80184 DM |
7464 | "xnorcc\\t%%g0, %1, %0" |
7465 | [(set_attr "type" "compare") | |
7466 | (set_attr "length" "1")]) | |
7a768814 RS |
7467 | \f |
7468 | ;; Floating point arithmetic instructions. | |
7469 | ||
47ac041c JJ |
7470 | (define_expand "addtf3" |
7471 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
7472 | (plus:TF (match_operand:TF 1 "general_operand" "") | |
7473 | (match_operand:TF 2 "general_operand" "")))] | |
7474 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
7475 | " | |
7476 | { | |
7477 | if (! TARGET_HARD_QUAD) | |
7478 | { | |
7479 | rtx slot0, slot1, slot2; | |
7480 | ||
7481 | if (GET_CODE (operands[0]) != MEM) | |
7482 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7483 | else | |
7484 | slot0 = operands[0]; | |
7485 | if (GET_CODE (operands[1]) != MEM) | |
7486 | { | |
7487 | slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7488 | emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); | |
7489 | } | |
7490 | else | |
7491 | slot1 = operands[1]; | |
7492 | if (GET_CODE (operands[2]) != MEM) | |
7493 | { | |
7494 | slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7495 | emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2])); | |
7496 | } | |
7497 | else | |
7498 | slot2 = operands[2]; | |
7499 | ||
7500 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0, | |
7501 | VOIDmode, 3, | |
7502 | XEXP (slot0, 0), Pmode, | |
7503 | XEXP (slot1, 0), Pmode, | |
7504 | XEXP (slot2, 0), Pmode); | |
7505 | ||
7506 | if (GET_CODE (operands[0]) != MEM) | |
7507 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
7508 | DONE; | |
7509 | } | |
7510 | }") | |
7511 | ||
7512 | (define_insn "*addtf3_hq" | |
b6d3c4ba JW |
7513 | [(set (match_operand:TF 0 "register_operand" "=e") |
7514 | (plus:TF (match_operand:TF 1 "register_operand" "e") | |
7515 | (match_operand:TF 2 "register_operand" "e")))] | |
ef903eca | 7516 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
7517 | "faddq\\t%1, %2, %0" |
7518 | [(set_attr "type" "fp") | |
7519 | (set_attr "length" "1")]) | |
795068a4 | 7520 | |
7a768814 | 7521 | (define_insn "adddf3" |
b6d3c4ba JW |
7522 | [(set (match_operand:DF 0 "register_operand" "=e") |
7523 | (plus:DF (match_operand:DF 1 "register_operand" "e") | |
7524 | (match_operand:DF 2 "register_operand" "e")))] | |
ab5519b7 | 7525 | "TARGET_FPU" |
e0d80184 DM |
7526 | "faddd\\t%1, %2, %0" |
7527 | [(set_attr "type" "fp") | |
7528 | (set_attr "length" "1")]) | |
7a768814 RS |
7529 | |
7530 | (define_insn "addsf3" | |
7531 | [(set (match_operand:SF 0 "register_operand" "=f") | |
7532 | (plus:SF (match_operand:SF 1 "register_operand" "f") | |
7533 | (match_operand:SF 2 "register_operand" "f")))] | |
ab5519b7 | 7534 | "TARGET_FPU" |
e0d80184 DM |
7535 | "fadds\\t%1, %2, %0" |
7536 | [(set_attr "type" "fp") | |
7537 | (set_attr "length" "1")]) | |
7a768814 | 7538 | |
47ac041c JJ |
7539 | (define_expand "subtf3" |
7540 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
7541 | (minus:TF (match_operand:TF 1 "general_operand" "") | |
7542 | (match_operand:TF 2 "general_operand" "")))] | |
7543 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
7544 | " | |
7545 | { | |
7546 | if (! TARGET_HARD_QUAD) | |
7547 | { | |
7548 | rtx slot0, slot1, slot2; | |
7549 | ||
7550 | if (GET_CODE (operands[0]) != MEM) | |
7551 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7552 | else | |
7553 | slot0 = operands[0]; | |
7554 | if (GET_CODE (operands[1]) != MEM) | |
7555 | { | |
7556 | slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7557 | emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); | |
7558 | } | |
7559 | else | |
7560 | slot1 = operands[1]; | |
7561 | if (GET_CODE (operands[2]) != MEM) | |
7562 | { | |
7563 | slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7564 | emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2])); | |
7565 | } | |
7566 | else | |
7567 | slot2 = operands[2]; | |
7568 | ||
7569 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0, | |
7570 | VOIDmode, 3, | |
7571 | XEXP (slot0, 0), Pmode, | |
7572 | XEXP (slot1, 0), Pmode, | |
7573 | XEXP (slot2, 0), Pmode); | |
7574 | ||
7575 | if (GET_CODE (operands[0]) != MEM) | |
7576 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
7577 | DONE; | |
7578 | } | |
7579 | }") | |
7580 | ||
7581 | (define_insn "*subtf3_hq" | |
b6d3c4ba JW |
7582 | [(set (match_operand:TF 0 "register_operand" "=e") |
7583 | (minus:TF (match_operand:TF 1 "register_operand" "e") | |
7584 | (match_operand:TF 2 "register_operand" "e")))] | |
ef903eca | 7585 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
7586 | "fsubq\\t%1, %2, %0" |
7587 | [(set_attr "type" "fp") | |
7588 | (set_attr "length" "1")]) | |
795068a4 | 7589 | |
7a768814 | 7590 | (define_insn "subdf3" |
b6d3c4ba JW |
7591 | [(set (match_operand:DF 0 "register_operand" "=e") |
7592 | (minus:DF (match_operand:DF 1 "register_operand" "e") | |
7593 | (match_operand:DF 2 "register_operand" "e")))] | |
ab5519b7 | 7594 | "TARGET_FPU" |
e0d80184 DM |
7595 | "fsubd\\t%1, %2, %0" |
7596 | [(set_attr "type" "fp") | |
7597 | (set_attr "length" "1")]) | |
7a768814 RS |
7598 | |
7599 | (define_insn "subsf3" | |
7600 | [(set (match_operand:SF 0 "register_operand" "=f") | |
7601 | (minus:SF (match_operand:SF 1 "register_operand" "f") | |
7602 | (match_operand:SF 2 "register_operand" "f")))] | |
ab5519b7 | 7603 | "TARGET_FPU" |
e0d80184 DM |
7604 | "fsubs\\t%1, %2, %0" |
7605 | [(set_attr "type" "fp") | |
7606 | (set_attr "length" "1")]) | |
7a768814 | 7607 | |
47ac041c JJ |
7608 | (define_expand "multf3" |
7609 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
7610 | (mult:TF (match_operand:TF 1 "general_operand" "") | |
7611 | (match_operand:TF 2 "general_operand" "")))] | |
7612 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
7613 | " | |
7614 | { | |
7615 | if (! TARGET_HARD_QUAD) | |
7616 | { | |
7617 | rtx slot0, slot1, slot2; | |
7618 | ||
7619 | if (GET_CODE (operands[0]) != MEM) | |
7620 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7621 | else | |
7622 | slot0 = operands[0]; | |
7623 | if (GET_CODE (operands[1]) != MEM) | |
7624 | { | |
7625 | slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7626 | emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); | |
7627 | } | |
7628 | else | |
7629 | slot1 = operands[1]; | |
7630 | if (GET_CODE (operands[2]) != MEM) | |
7631 | { | |
7632 | slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7633 | emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2])); | |
7634 | } | |
7635 | else | |
7636 | slot2 = operands[2]; | |
7637 | ||
7638 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0, | |
7639 | VOIDmode, 3, | |
7640 | XEXP (slot0, 0), Pmode, | |
7641 | XEXP (slot1, 0), Pmode, | |
7642 | XEXP (slot2, 0), Pmode); | |
7643 | ||
7644 | if (GET_CODE (operands[0]) != MEM) | |
7645 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
7646 | DONE; | |
7647 | } | |
7648 | }") | |
7649 | ||
7650 | (define_insn "*multf3_hq" | |
b6d3c4ba JW |
7651 | [(set (match_operand:TF 0 "register_operand" "=e") |
7652 | (mult:TF (match_operand:TF 1 "register_operand" "e") | |
7653 | (match_operand:TF 2 "register_operand" "e")))] | |
ef903eca | 7654 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
7655 | "fmulq\\t%1, %2, %0" |
7656 | [(set_attr "type" "fpmul") | |
7657 | (set_attr "length" "1")]) | |
795068a4 | 7658 | |
7a768814 | 7659 | (define_insn "muldf3" |
b6d3c4ba JW |
7660 | [(set (match_operand:DF 0 "register_operand" "=e") |
7661 | (mult:DF (match_operand:DF 1 "register_operand" "e") | |
7662 | (match_operand:DF 2 "register_operand" "e")))] | |
ab5519b7 | 7663 | "TARGET_FPU" |
e0d80184 DM |
7664 | "fmuld\\t%1, %2, %0" |
7665 | [(set_attr "type" "fpmul") | |
7666 | (set_attr "length" "1")]) | |
7a768814 RS |
7667 | |
7668 | (define_insn "mulsf3" | |
7669 | [(set (match_operand:SF 0 "register_operand" "=f") | |
7670 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
7671 | (match_operand:SF 2 "register_operand" "f")))] | |
ab5519b7 | 7672 | "TARGET_FPU" |
e0d80184 DM |
7673 | "fmuls\\t%1, %2, %0" |
7674 | [(set_attr "type" "fpmul") | |
7675 | (set_attr "length" "1")]) | |
7a768814 | 7676 | |
c8b3b7d6 | 7677 | (define_insn "*muldf3_extend" |
b6d3c4ba | 7678 | [(set (match_operand:DF 0 "register_operand" "=e") |
8d2f4374 JW |
7679 | (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f")) |
7680 | (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))] | |
a8d2b752 | 7681 | "(TARGET_V8 || TARGET_V9) && TARGET_FPU" |
e0d80184 DM |
7682 | "fsmuld\\t%1, %2, %0" |
7683 | [(set_attr "type" "fpmul") | |
7684 | (set_attr "length" "1")]) | |
8d2f4374 | 7685 | |
c8b3b7d6 | 7686 | (define_insn "*multf3_extend" |
b6d3c4ba JW |
7687 | [(set (match_operand:TF 0 "register_operand" "=e") |
7688 | (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e")) | |
7689 | (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))] | |
fa0f39e4 | 7690 | "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
7691 | "fdmulq\\t%1, %2, %0" |
7692 | [(set_attr "type" "fpmul") | |
7693 | (set_attr "length" "1")]) | |
8d2f4374 | 7694 | |
47ac041c JJ |
7695 | (define_expand "divtf3" |
7696 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
7697 | (div:TF (match_operand:TF 1 "general_operand" "") | |
7698 | (match_operand:TF 2 "general_operand" "")))] | |
7699 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
7700 | " | |
7701 | { | |
7702 | if (! TARGET_HARD_QUAD) | |
7703 | { | |
7704 | rtx slot0, slot1, slot2; | |
7705 | ||
7706 | if (GET_CODE (operands[0]) != MEM) | |
7707 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7708 | else | |
7709 | slot0 = operands[0]; | |
7710 | if (GET_CODE (operands[1]) != MEM) | |
7711 | { | |
7712 | slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7713 | emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); | |
7714 | } | |
7715 | else | |
7716 | slot1 = operands[1]; | |
7717 | if (GET_CODE (operands[2]) != MEM) | |
7718 | { | |
7719 | slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
7720 | emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2])); | |
7721 | } | |
7722 | else | |
7723 | slot2 = operands[2]; | |
7724 | ||
7725 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0, | |
7726 | VOIDmode, 3, | |
7727 | XEXP (slot0, 0), Pmode, | |
7728 | XEXP (slot1, 0), Pmode, | |
7729 | XEXP (slot2, 0), Pmode); | |
7730 | ||
7731 | if (GET_CODE (operands[0]) != MEM) | |
7732 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
7733 | DONE; | |
7734 | } | |
7735 | }") | |
7736 | ||
c180bd1e | 7737 | ;; don't have timing for quad-prec. divide. |
47ac041c | 7738 | (define_insn "*divtf3_hq" |
b6d3c4ba JW |
7739 | [(set (match_operand:TF 0 "register_operand" "=e") |
7740 | (div:TF (match_operand:TF 1 "register_operand" "e") | |
7741 | (match_operand:TF 2 "register_operand" "e")))] | |
ef903eca | 7742 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 DM |
7743 | "fdivq\\t%1, %2, %0" |
7744 | [(set_attr "type" "fpdivd") | |
7745 | (set_attr "length" "1")]) | |
795068a4 | 7746 | |
7a768814 | 7747 | (define_insn "divdf3" |
b6d3c4ba JW |
7748 | [(set (match_operand:DF 0 "register_operand" "=e") |
7749 | (div:DF (match_operand:DF 1 "register_operand" "e") | |
7750 | (match_operand:DF 2 "register_operand" "e")))] | |
ab5519b7 | 7751 | "TARGET_FPU" |
e0d80184 DM |
7752 | "fdivd\\t%1, %2, %0" |
7753 | [(set_attr "type" "fpdivd") | |
7754 | (set_attr "length" "1")]) | |
7a768814 RS |
7755 | |
7756 | (define_insn "divsf3" | |
7757 | [(set (match_operand:SF 0 "register_operand" "=f") | |
7758 | (div:SF (match_operand:SF 1 "register_operand" "f") | |
7759 | (match_operand:SF 2 "register_operand" "f")))] | |
ab5519b7 | 7760 | "TARGET_FPU" |
e0d80184 DM |
7761 | "fdivs\\t%1, %2, %0" |
7762 | [(set_attr "type" "fpdivs") | |
7763 | (set_attr "length" "1")]) | |
7a768814 | 7764 | |
45120407 | 7765 | (define_expand "negtf2" |
b6d3c4ba JW |
7766 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
7767 | (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
ab5519b7 | 7768 | "TARGET_FPU" |
45120407 DM |
7769 | "") |
7770 | ||
7771 | (define_insn "*negtf2_notv9" | |
7772 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
7773 | (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
7774 | ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. | |
7775 | "TARGET_FPU | |
7776 | && ! TARGET_V9" | |
7777 | "@ | |
7778 | fnegs\\t%0, %0 | |
7779 | #" | |
bfd6bc60 | 7780 | [(set_attr "type" "fpmove") |
45120407 | 7781 | (set_attr "length" "1,2")]) |
795068a4 | 7782 | |
45120407 DM |
7783 | (define_split |
7784 | [(set (match_operand:TF 0 "register_operand" "") | |
7785 | (neg:TF (match_operand:TF 1 "register_operand" "")))] | |
7786 | "TARGET_FPU | |
7787 | && ! TARGET_V9 | |
d5e8c40c JL |
7788 | && reload_completed |
7789 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" | |
031fec00 | 7790 | [(set (match_dup 2) (neg:SF (match_dup 3))) |
45120407 DM |
7791 | (set (match_dup 4) (match_dup 5)) |
7792 | (set (match_dup 6) (match_dup 7))] | |
e61c29e9 DM |
7793 | "if (GET_CODE (operands[0]) == SUBREG) |
7794 | operands[0] = alter_subreg (operands[0]); | |
7795 | if (GET_CODE (operands[1]) == SUBREG) | |
7796 | operands[1] = alter_subreg (operands[1]); | |
7797 | operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); | |
45120407 DM |
7798 | operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); |
7799 | operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); | |
7800 | operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1); | |
06424989 JW |
7801 | operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); |
7802 | operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);") | |
45120407 DM |
7803 | |
7804 | (define_insn "*negtf2_v9" | |
7805 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
7806 | (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
7807 | ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. | |
7808 | "TARGET_FPU && TARGET_V9" | |
7809 | "@ | |
7810 | fnegd\\t%0, %0 | |
7811 | #" | |
7812 | [(set_attr "type" "fpmove") | |
7813 | (set_attr "length" "1,2")]) | |
7814 | ||
7815 | (define_split | |
7816 | [(set (match_operand:TF 0 "register_operand" "") | |
7817 | (neg:TF (match_operand:TF 1 "register_operand" "")))] | |
7818 | "TARGET_FPU | |
7819 | && TARGET_V9 | |
d5e8c40c JL |
7820 | && reload_completed |
7821 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" | |
45120407 DM |
7822 | [(set (match_dup 2) (neg:DF (match_dup 3))) |
7823 | (set (match_dup 4) (match_dup 5))] | |
e61c29e9 DM |
7824 | "if (GET_CODE (operands[0]) == SUBREG) |
7825 | operands[0] = alter_subreg (operands[0]); | |
7826 | if (GET_CODE (operands[1]) == SUBREG) | |
7827 | operands[1] = alter_subreg (operands[1]); | |
7828 | operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0])); | |
45120407 DM |
7829 | operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1])); |
7830 | operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); | |
7831 | operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);") | |
7832 | ||
7833 | (define_expand "negdf2" | |
7834 | [(set (match_operand:DF 0 "register_operand" "") | |
7835 | (neg:DF (match_operand:DF 1 "register_operand" "")))] | |
7836 | "TARGET_FPU" | |
7837 | "") | |
7838 | ||
7839 | (define_insn "*negdf2_notv9" | |
b6d3c4ba JW |
7840 | [(set (match_operand:DF 0 "register_operand" "=e,e") |
7841 | (neg:DF (match_operand:DF 1 "register_operand" "0,e")))] | |
45120407 DM |
7842 | "TARGET_FPU && ! TARGET_V9" |
7843 | "@ | |
7844 | fnegs\\t%0, %0 | |
7845 | #" | |
bfd6bc60 | 7846 | [(set_attr "type" "fpmove") |
45120407 DM |
7847 | (set_attr "length" "1,2")]) |
7848 | ||
7849 | (define_split | |
7850 | [(set (match_operand:DF 0 "register_operand" "") | |
7851 | (neg:DF (match_operand:DF 1 "register_operand" "")))] | |
7852 | "TARGET_FPU | |
7853 | && ! TARGET_V9 | |
d5e8c40c JL |
7854 | && reload_completed |
7855 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" | |
45120407 DM |
7856 | [(set (match_dup 2) (neg:SF (match_dup 3))) |
7857 | (set (match_dup 4) (match_dup 5))] | |
e61c29e9 DM |
7858 | "if (GET_CODE (operands[0]) == SUBREG) |
7859 | operands[0] = alter_subreg (operands[0]); | |
7860 | if (GET_CODE (operands[1]) == SUBREG) | |
7861 | operands[1] = alter_subreg (operands[1]); | |
7862 | operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); | |
45120407 DM |
7863 | operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); |
7864 | operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); | |
7865 | operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);") | |
7866 | ||
7867 | (define_insn "*negdf2_v9" | |
7868 | [(set (match_operand:DF 0 "register_operand" "=e") | |
7869 | (neg:DF (match_operand:DF 1 "register_operand" "e")))] | |
7870 | "TARGET_FPU && TARGET_V9" | |
031fec00 | 7871 | "fnegd\\t%1, %0" |
45120407 DM |
7872 | [(set_attr "type" "fpmove") |
7873 | (set_attr "length" "1")]) | |
7a768814 | 7874 | |
7a768814 RS |
7875 | (define_insn "negsf2" |
7876 | [(set (match_operand:SF 0 "register_operand" "=f") | |
7877 | (neg:SF (match_operand:SF 1 "register_operand" "f")))] | |
ab5519b7 | 7878 | "TARGET_FPU" |
e0d80184 DM |
7879 | "fnegs\\t%1, %0" |
7880 | [(set_attr "type" "fpmove") | |
7881 | (set_attr "length" "1")]) | |
7a768814 | 7882 | |
6570c0bd | 7883 | (define_expand "abstf2" |
45120407 DM |
7884 | [(set (match_operand:TF 0 "register_operand" "") |
7885 | (abs:TF (match_operand:TF 1 "register_operand" "")))] | |
7886 | "TARGET_FPU" | |
7887 | "") | |
7888 | ||
7889 | (define_insn "*abstf2_notv9" | |
b6d3c4ba JW |
7890 | [(set (match_operand:TF 0 "register_operand" "=e,e") |
7891 | (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
49a7ec10 | 7892 | ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. |
45120407 DM |
7893 | "TARGET_FPU && ! TARGET_V9" |
7894 | "@ | |
7895 | fabss\\t%0, %0 | |
7896 | #" | |
7897 | [(set_attr "type" "fpmove") | |
7898 | (set_attr "length" "1,2")]) | |
7899 | ||
7900 | (define_split | |
7901 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
7902 | (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
7903 | "TARGET_FPU | |
7904 | && ! TARGET_V9 | |
d5e8c40c JL |
7905 | && reload_completed |
7906 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" | |
45120407 DM |
7907 | [(set (match_dup 2) (abs:SF (match_dup 3))) |
7908 | (set (match_dup 4) (match_dup 5)) | |
7909 | (set (match_dup 6) (match_dup 7))] | |
e61c29e9 DM |
7910 | "if (GET_CODE (operands[0]) == SUBREG) |
7911 | operands[0] = alter_subreg (operands[0]); | |
7912 | if (GET_CODE (operands[1]) == SUBREG) | |
7913 | operands[1] = alter_subreg (operands[1]); | |
7914 | operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); | |
45120407 DM |
7915 | operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); |
7916 | operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); | |
7917 | operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1); | |
6570c0bd JJ |
7918 | operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); |
7919 | operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);") | |
7920 | ||
7921 | (define_insn "*abstf2_hq_v9" | |
7922 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
7923 | (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
7924 | "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD" | |
7925 | "@ | |
7926 | fabsd\\t%0, %0 | |
7927 | fabsq\\t%1, %0" | |
7928 | [(set_attr "type" "fpmove") | |
7929 | (set_attr "length" "1")]) | |
45120407 DM |
7930 | |
7931 | (define_insn "*abstf2_v9" | |
7932 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
7933 | (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
6570c0bd | 7934 | "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD" |
45120407 DM |
7935 | "@ |
7936 | fabsd\\t%0, %0 | |
7937 | #" | |
7938 | [(set_attr "type" "fpmove") | |
7939 | (set_attr "length" "1,2")]) | |
7940 | ||
7941 | (define_split | |
7942 | [(set (match_operand:TF 0 "register_operand" "=e,e") | |
7943 | (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] | |
7944 | "TARGET_FPU | |
7945 | && TARGET_V9 | |
d5e8c40c JL |
7946 | && reload_completed |
7947 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" | |
45120407 DM |
7948 | [(set (match_dup 2) (abs:DF (match_dup 3))) |
7949 | (set (match_dup 4) (match_dup 5))] | |
e61c29e9 DM |
7950 | "if (GET_CODE (operands[0]) == SUBREG) |
7951 | operands[0] = alter_subreg (operands[0]); | |
7952 | if (GET_CODE (operands[1]) == SUBREG) | |
7953 | operands[1] = alter_subreg (operands[1]); | |
7954 | operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0])); | |
45120407 DM |
7955 | operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1])); |
7956 | operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); | |
7957 | operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);") | |
7958 | ||
7959 | (define_expand "absdf2" | |
7960 | [(set (match_operand:DF 0 "register_operand" "") | |
7961 | (abs:DF (match_operand:DF 1 "register_operand" "")))] | |
ab5519b7 | 7962 | "TARGET_FPU" |
45120407 DM |
7963 | "") |
7964 | ||
7965 | (define_insn "*absdf2_notv9" | |
7966 | [(set (match_operand:DF 0 "register_operand" "=e,e") | |
7967 | (abs:DF (match_operand:DF 1 "register_operand" "0,e")))] | |
7968 | "TARGET_FPU && ! TARGET_V9" | |
7969 | "@ | |
7970 | fabss\\t%0, %0 | |
7971 | #" | |
bfd6bc60 | 7972 | [(set_attr "type" "fpmove") |
45120407 | 7973 | (set_attr "length" "1,2")]) |
795068a4 | 7974 | |
45120407 | 7975 | (define_split |
b6d3c4ba JW |
7976 | [(set (match_operand:DF 0 "register_operand" "=e,e") |
7977 | (abs:DF (match_operand:DF 1 "register_operand" "0,e")))] | |
45120407 DM |
7978 | "TARGET_FPU |
7979 | && ! TARGET_V9 | |
d5e8c40c JL |
7980 | && reload_completed |
7981 | && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" | |
45120407 DM |
7982 | [(set (match_dup 2) (abs:SF (match_dup 3))) |
7983 | (set (match_dup 4) (match_dup 5))] | |
e61c29e9 DM |
7984 | "if (GET_CODE (operands[0]) == SUBREG) |
7985 | operands[0] = alter_subreg (operands[0]); | |
7986 | if (GET_CODE (operands[1]) == SUBREG) | |
7987 | operands[1] = alter_subreg (operands[1]); | |
7988 | operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); | |
45120407 DM |
7989 | operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); |
7990 | operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); | |
7991 | operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);") | |
7992 | ||
7993 | (define_insn "*absdf2_v9" | |
7994 | [(set (match_operand:DF 0 "register_operand" "=e") | |
7995 | (abs:DF (match_operand:DF 1 "register_operand" "e")))] | |
7996 | "TARGET_FPU && TARGET_V9" | |
6570c0bd | 7997 | "fabsd\\t%1, %0" |
bfd6bc60 | 7998 | [(set_attr "type" "fpmove") |
45120407 | 7999 | (set_attr "length" "1")]) |
7a768814 RS |
8000 | |
8001 | (define_insn "abssf2" | |
8002 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8003 | (abs:SF (match_operand:SF 1 "register_operand" "f")))] | |
ab5519b7 | 8004 | "TARGET_FPU" |
e0d80184 DM |
8005 | "fabss\\t%1, %0" |
8006 | [(set_attr "type" "fpmove") | |
8007 | (set_attr "length" "1")]) | |
7a768814 | 8008 | |
47ac041c JJ |
8009 | (define_expand "sqrttf2" |
8010 | [(set (match_operand:TF 0 "register_operand" "=e") | |
8011 | (sqrt:TF (match_operand:TF 1 "register_operand" "e")))] | |
8012 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
8013 | " | |
8014 | { | |
8015 | if (! TARGET_HARD_QUAD) | |
8016 | { | |
8017 | rtx slot0, slot1; | |
8018 | ||
8019 | if (GET_CODE (operands[0]) != MEM) | |
8020 | slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
8021 | else | |
8022 | slot0 = operands[0]; | |
8023 | if (GET_CODE (operands[1]) != MEM) | |
8024 | { | |
8025 | slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0); | |
8026 | emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1])); | |
8027 | } | |
8028 | else | |
8029 | slot1 = operands[1]; | |
8030 | ||
8031 | emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0, | |
8032 | VOIDmode, 2, | |
8033 | XEXP (slot0, 0), Pmode, | |
8034 | XEXP (slot1, 0), Pmode); | |
8035 | ||
8036 | if (GET_CODE (operands[0]) != MEM) | |
8037 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0)); | |
8038 | DONE; | |
8039 | } | |
8040 | }") | |
8041 | ||
8042 | (define_insn "*sqrttf2_hq" | |
b6d3c4ba JW |
8043 | [(set (match_operand:TF 0 "register_operand" "=e") |
8044 | (sqrt:TF (match_operand:TF 1 "register_operand" "e")))] | |
ef903eca | 8045 | "TARGET_FPU && TARGET_HARD_QUAD" |
e0d80184 | 8046 | "fsqrtq\\t%1, %0" |
c0ec7a75 | 8047 | [(set_attr "type" "fpsqrtd") |
e0d80184 | 8048 | (set_attr "length" "1")]) |
795068a4 | 8049 | |
7a768814 | 8050 | (define_insn "sqrtdf2" |
b6d3c4ba JW |
8051 | [(set (match_operand:DF 0 "register_operand" "=e") |
8052 | (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] | |
ab5519b7 | 8053 | "TARGET_FPU" |
e0d80184 | 8054 | "fsqrtd\\t%1, %0" |
c0ec7a75 | 8055 | [(set_attr "type" "fpsqrtd") |
e0d80184 | 8056 | (set_attr "length" "1")]) |
7a768814 RS |
8057 | |
8058 | (define_insn "sqrtsf2" | |
8059 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8060 | (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] | |
ab5519b7 | 8061 | "TARGET_FPU" |
e0d80184 | 8062 | "fsqrts\\t%1, %0" |
c0ec7a75 | 8063 | [(set_attr "type" "fpsqrts") |
e0d80184 | 8064 | (set_attr "length" "1")]) |
7a768814 RS |
8065 | \f |
8066 | ;;- arithmetic shift instructions | |
8067 | ||
7a768814 RS |
8068 | (define_insn "ashlsi3" |
8069 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8070 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
0088e8ba | 8071 | (match_operand:SI 2 "arith_operand" "rI")))] |
7a768814 | 8072 | "" |
0088e8ba RK |
8073 | "* |
8074 | { | |
8075 | if (GET_CODE (operands[2]) == CONST_INT | |
5d4f5e87 | 8076 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31) |
0088e8ba RK |
8077 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8078 | ||
e0d80184 | 8079 | return \"sll\\t%1, %2, %0\"; |
c180bd1e | 8080 | }" |
e0d80184 DM |
8081 | [(set_attr "type" "shift") |
8082 | (set_attr "length" "1")]) | |
7a768814 | 8083 | |
295c5559 JJ |
8084 | ;; We special case multiplication by two, as add can be done |
8085 | ;; in both ALUs, while shift only in IEU0 on UltraSPARC. | |
8086 | (define_insn "*ashlsi3_const1" | |
8087 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8088 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
8089 | (const_int 1)))] | |
8090 | "" | |
8091 | "add\\t%1, %1, %0" | |
8092 | [(set_attr "type" "binary") | |
8093 | (set_attr "length" "1")]) | |
8094 | ||
284d86e9 JC |
8095 | (define_expand "ashldi3" |
8096 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8097 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
8098 | (match_operand:SI 2 "arith_operand" "rI")))] | |
8099 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
8100 | " | |
8101 | { | |
8102 | if (! TARGET_ARCH64) | |
8103 | { | |
8104 | if (GET_CODE (operands[2]) == CONST_INT) | |
8105 | FAIL; | |
8106 | emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2])); | |
8107 | DONE; | |
8108 | } | |
8109 | }") | |
8110 | ||
295c5559 JJ |
8111 | ;; We special case multiplication by two, as add can be done |
8112 | ;; in both ALUs, while shift only in IEU0 on UltraSPARC. | |
8113 | (define_insn "*ashldi3_const1" | |
8114 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8115 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
8116 | (const_int 1)))] | |
8117 | "TARGET_ARCH64" | |
8118 | "add\\t%1, %1, %0" | |
8119 | [(set_attr "type" "binary") | |
8120 | (set_attr "length" "1")]) | |
8121 | ||
8122 | (define_insn "*ashldi3_sp64" | |
a8d2b752 DE |
8123 | [(set (match_operand:DI 0 "register_operand" "=r") |
8124 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
8125 | (match_operand:SI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 8126 | "TARGET_ARCH64" |
a8d2b752 DE |
8127 | "* |
8128 | { | |
8129 | if (GET_CODE (operands[2]) == CONST_INT | |
f710f868 | 8130 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63) |
a8d2b752 DE |
8131 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); |
8132 | ||
e0d80184 DM |
8133 | return \"sllx\\t%1, %2, %0\"; |
8134 | }" | |
8135 | [(set_attr "type" "shift") | |
8136 | (set_attr "length" "1")]) | |
a8d2b752 | 8137 | |
e0d80184 | 8138 | ;; XXX UGH! |
284d86e9 JC |
8139 | (define_insn "ashldi3_v8plus" |
8140 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
c6b0465b | 8141 | (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
284d86e9 JC |
8142 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
8143 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
8144 | "TARGET_V8PLUS" | |
8145 | "*return sparc_v8plus_shift (operands, insn, \"sllx\");" | |
8146 | [(set_attr "length" "5,5,6")]) | |
8147 | ||
c6b0465b | 8148 | ;; Optimize (1LL<<x)-1 |
e61c29e9 DM |
8149 | ;; XXX this also needs to be fixed to handle equal subregs |
8150 | ;; XXX first before we could re-enable it. | |
c77e04ae RH |
8151 | ;(define_insn "" |
8152 | ; [(set (match_operand:DI 0 "register_operand" "=h") | |
8153 | ; (plus:DI (ashift:DI (const_int 1) | |
8154 | ; (match_operand:SI 1 "arith_operand" "rI")) | |
8155 | ; (const_int -1)))] | |
8156 | ; "0 && TARGET_V8PLUS" | |
8157 | ; "* | |
8158 | ;{ | |
8159 | ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0])) | |
8160 | ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\"; | |
8161 | ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\"; | |
8162 | ;}" | |
8163 | ; [(set_attr "length" "4")]) | |
c6b0465b | 8164 | |
c8b3b7d6 | 8165 | (define_insn "*cmp_cc_ashift_1" |
c4ce6853 | 8166 | [(set (reg:CC_NOOV 100) |
13a7eb33 JW |
8167 | (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r") |
8168 | (const_int 1)) | |
8169 | (const_int 0)))] | |
e6c1be7e | 8170 | "" |
e0d80184 DM |
8171 | "addcc\\t%0, %0, %%g0" |
8172 | [(set_attr "type" "compare") | |
8173 | (set_attr "length" "1")]) | |
13a7eb33 | 8174 | |
c8b3b7d6 | 8175 | (define_insn "*cmp_cc_set_ashift_1" |
c4ce6853 | 8176 | [(set (reg:CC_NOOV 100) |
13a7eb33 JW |
8177 | (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r") |
8178 | (const_int 1)) | |
8179 | (const_int 0))) | |
8180 | (set (match_operand:SI 0 "register_operand" "=r") | |
8181 | (ashift:SI (match_dup 1) (const_int 1)))] | |
8182 | "" | |
e0d80184 DM |
8183 | "addcc\\t%1, %1, %0" |
8184 | [(set_attr "type" "compare") | |
8185 | (set_attr "length" "1")]) | |
13a7eb33 | 8186 | |
7a768814 RS |
8187 | (define_insn "ashrsi3" |
8188 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8189 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
0088e8ba | 8190 | (match_operand:SI 2 "arith_operand" "rI")))] |
7a768814 | 8191 | "" |
0088e8ba RK |
8192 | "* |
8193 | { | |
8194 | if (GET_CODE (operands[2]) == CONST_INT | |
5d4f5e87 | 8195 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31) |
0088e8ba RK |
8196 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8197 | ||
e0d80184 | 8198 | return \"sra\\t%1, %2, %0\"; |
c180bd1e | 8199 | }" |
e0d80184 DM |
8200 | [(set_attr "type" "shift") |
8201 | (set_attr "length" "1")]) | |
7a768814 | 8202 | |
295c5559 | 8203 | (define_insn "*ashrsi3_extend" |
6570c0bd | 8204 | [(set (match_operand:DI 0 "register_operand" "=r") |
295c5559 JJ |
8205 | (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") |
8206 | (match_operand:SI 2 "arith_operand" "r"))))] | |
8207 | "TARGET_ARCH64" | |
8208 | "sra\\t%1, %2, %0" | |
8209 | [(set_attr "type" "shift") | |
8210 | (set_attr "length" "1")]) | |
8211 | ||
8212 | ;; This handles the case as above, but with constant shift instead of | |
8213 | ;; register. Combiner "simplifies" it for us a little bit though. | |
8214 | (define_insn "*ashrsi3_extend2" | |
6570c0bd | 8215 | [(set (match_operand:DI 0 "register_operand" "=r") |
295c5559 JJ |
8216 | (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) |
8217 | (const_int 32)) | |
8218 | (match_operand:SI 2 "small_int_or_double" "n")))] | |
8219 | "TARGET_ARCH64 | |
8220 | && ((GET_CODE (operands[2]) == CONST_INT | |
8221 | && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64) | |
8222 | || (GET_CODE (operands[2]) == CONST_DOUBLE | |
8223 | && !CONST_DOUBLE_HIGH (operands[2]) | |
8224 | && CONST_DOUBLE_LOW (operands[2]) >= 32 | |
8225 | && CONST_DOUBLE_LOW (operands[2]) < 64))" | |
8226 | "* | |
8227 | { | |
8228 | operands[2] = GEN_INT (INTVAL (operands[2]) - 32); | |
8229 | ||
8230 | return \"sra\\t%1, %2, %0\"; | |
8231 | }" | |
8232 | [(set_attr "type" "shift") | |
8233 | (set_attr "length" "1")]) | |
8234 | ||
284d86e9 JC |
8235 | (define_expand "ashrdi3" |
8236 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8237 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
8238 | (match_operand:SI 2 "arith_operand" "rI")))] | |
8239 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
8240 | " | |
e0d80184 DM |
8241 | { |
8242 | if (! TARGET_ARCH64) | |
8243 | { | |
8244 | if (GET_CODE (operands[2]) == CONST_INT) | |
8245 | FAIL; /* prefer generic code in this case */ | |
8246 | emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2])); | |
8247 | DONE; | |
8248 | } | |
8249 | }") | |
284d86e9 JC |
8250 | |
8251 | (define_insn "" | |
a8d2b752 DE |
8252 | [(set (match_operand:DI 0 "register_operand" "=r") |
8253 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
8254 | (match_operand:SI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 8255 | "TARGET_ARCH64" |
a8d2b752 DE |
8256 | "* |
8257 | { | |
8258 | if (GET_CODE (operands[2]) == CONST_INT | |
5d4f5e87 | 8259 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63) |
a8d2b752 DE |
8260 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); |
8261 | ||
e0d80184 DM |
8262 | return \"srax\\t%1, %2, %0\"; |
8263 | }" | |
8264 | [(set_attr "type" "shift") | |
8265 | (set_attr "length" "1")]) | |
a8d2b752 | 8266 | |
e0d80184 | 8267 | ;; XXX |
284d86e9 JC |
8268 | (define_insn "ashrdi3_v8plus" |
8269 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
c6b0465b | 8270 | (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
284d86e9 JC |
8271 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
8272 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
8273 | "TARGET_V8PLUS" | |
8274 | "*return sparc_v8plus_shift (operands, insn, \"srax\");" | |
8275 | [(set_attr "length" "5,5,6")]) | |
8276 | ||
7a768814 RS |
8277 | (define_insn "lshrsi3" |
8278 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8279 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
0088e8ba | 8280 | (match_operand:SI 2 "arith_operand" "rI")))] |
7a768814 | 8281 | "" |
0088e8ba RK |
8282 | "* |
8283 | { | |
8284 | if (GET_CODE (operands[2]) == CONST_INT | |
5d4f5e87 | 8285 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31) |
0088e8ba RK |
8286 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); |
8287 | ||
e0d80184 | 8288 | return \"srl\\t%1, %2, %0\"; |
c180bd1e | 8289 | }" |
e0d80184 DM |
8290 | [(set_attr "type" "shift") |
8291 | (set_attr "length" "1")]) | |
a8d2b752 | 8292 | |
295c5559 JJ |
8293 | ;; This handles the case where |
8294 | ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))), | |
8295 | ;; but combiner "simplifies" it for us. | |
8296 | (define_insn "*lshrsi3_extend" | |
6570c0bd | 8297 | [(set (match_operand:DI 0 "register_operand" "=r") |
295c5559 JJ |
8298 | (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") |
8299 | (match_operand:SI 2 "arith_operand" "r")) 0) | |
8300 | (match_operand 3 "" "")))] | |
8301 | "TARGET_ARCH64 | |
8302 | && ((GET_CODE (operands[3]) == CONST_DOUBLE | |
8303 | && CONST_DOUBLE_HIGH (operands[3]) == 0 | |
8304 | && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff) | |
8305 | #if HOST_BITS_PER_WIDE_INT >= 64 | |
8306 | || (GET_CODE (operands[3]) == CONST_INT | |
8307 | && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff) | |
8308 | #endif | |
8309 | )" | |
8310 | "srl\\t%1, %2, %0" | |
8311 | [(set_attr "type" "shift") | |
8312 | (set_attr "length" "1")]) | |
8313 | ||
8314 | ;; This handles the case where | |
8315 | ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32)) | |
8316 | ;; but combiner "simplifies" it for us. | |
8317 | (define_insn "*lshrsi3_extend2" | |
6570c0bd | 8318 | [(set (match_operand:DI 0 "register_operand" "=r") |
295c5559 JJ |
8319 | (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) |
8320 | (match_operand 2 "small_int_or_double" "n") | |
8321 | (const_int 32)))] | |
8322 | "TARGET_ARCH64 | |
8323 | && ((GET_CODE (operands[2]) == CONST_INT | |
8324 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32) | |
8325 | || (GET_CODE (operands[2]) == CONST_DOUBLE | |
8326 | && CONST_DOUBLE_HIGH (operands[2]) == 0 | |
8327 | && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))" | |
8328 | "* | |
8329 | { | |
8330 | operands[2] = GEN_INT (32 - INTVAL (operands[2])); | |
8331 | ||
8332 | return \"srl\\t%1, %2, %0\"; | |
8333 | }" | |
8334 | [(set_attr "type" "shift") | |
8335 | (set_attr "length" "1")]) | |
8336 | ||
284d86e9 JC |
8337 | (define_expand "lshrdi3" |
8338 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8339 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
8340 | (match_operand:SI 2 "arith_operand" "rI")))] | |
8341 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
8342 | " | |
e0d80184 DM |
8343 | { |
8344 | if (! TARGET_ARCH64) | |
8345 | { | |
8346 | if (GET_CODE (operands[2]) == CONST_INT) | |
8347 | FAIL; | |
8348 | emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2])); | |
8349 | DONE; | |
8350 | } | |
8351 | }") | |
284d86e9 JC |
8352 | |
8353 | (define_insn "" | |
a8d2b752 DE |
8354 | [(set (match_operand:DI 0 "register_operand" "=r") |
8355 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
8356 | (match_operand:SI 2 "arith_operand" "rI")))] | |
fa0f39e4 | 8357 | "TARGET_ARCH64" |
a8d2b752 DE |
8358 | "* |
8359 | { | |
8360 | if (GET_CODE (operands[2]) == CONST_INT | |
5d4f5e87 | 8361 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63) |
a8d2b752 DE |
8362 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); |
8363 | ||
e0d80184 DM |
8364 | return \"srlx\\t%1, %2, %0\"; |
8365 | }" | |
8366 | [(set_attr "type" "shift") | |
8367 | (set_attr "length" "1")]) | |
284d86e9 | 8368 | |
e0d80184 | 8369 | ;; XXX |
284d86e9 JC |
8370 | (define_insn "lshrdi3_v8plus" |
8371 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
c6b0465b | 8372 | (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
284d86e9 JC |
8373 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
8374 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
8375 | "TARGET_V8PLUS" | |
8376 | "*return sparc_v8plus_shift (operands, insn, \"srlx\");" | |
8377 | [(set_attr "length" "5,5,6")]) | |
5cb01b65 JJ |
8378 | |
8379 | (define_insn "" | |
8380 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8381 | (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
ddef6bc7 | 8382 | (const_int 32)) 4) |
5cb01b65 JJ |
8383 | (match_operand:SI 2 "small_int_or_double" "n")))] |
8384 | "TARGET_ARCH64 | |
8385 | && ((GET_CODE (operands[2]) == CONST_INT | |
8386 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32) | |
8387 | || (GET_CODE (operands[2]) == CONST_DOUBLE | |
8388 | && !CONST_DOUBLE_HIGH (operands[2]) | |
8389 | && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))" | |
8390 | "* | |
8391 | { | |
8392 | operands[2] = GEN_INT (INTVAL (operands[2]) + 32); | |
8393 | ||
8394 | return \"srax\\t%1, %2, %0\"; | |
8395 | }" | |
8396 | [(set_attr "type" "shift") | |
8397 | (set_attr "length" "1")]) | |
8398 | ||
8399 | (define_insn "" | |
8400 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8401 | (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
ddef6bc7 | 8402 | (const_int 32)) 4) |
5cb01b65 JJ |
8403 | (match_operand:SI 2 "small_int_or_double" "n")))] |
8404 | "TARGET_ARCH64 | |
8405 | && ((GET_CODE (operands[2]) == CONST_INT | |
8406 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32) | |
8407 | || (GET_CODE (operands[2]) == CONST_DOUBLE | |
8408 | && !CONST_DOUBLE_HIGH (operands[2]) | |
8409 | && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))" | |
8410 | "* | |
8411 | { | |
8412 | operands[2] = GEN_INT (INTVAL (operands[2]) + 32); | |
8413 | ||
8414 | return \"srlx\\t%1, %2, %0\"; | |
8415 | }" | |
8416 | [(set_attr "type" "shift") | |
8417 | (set_attr "length" "1")]) | |
8418 | ||
8419 | (define_insn "" | |
8420 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8421 | (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
ddef6bc7 | 8422 | (match_operand:SI 2 "small_int_or_double" "n")) 4) |
5cb01b65 JJ |
8423 | (match_operand:SI 3 "small_int_or_double" "n")))] |
8424 | "TARGET_ARCH64 | |
8425 | && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT | |
8426 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32 | |
8427 | && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32 | |
8428 | && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64" | |
8429 | "* | |
8430 | { | |
8431 | operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])); | |
8432 | ||
8433 | return \"srax\\t%1, %2, %0\"; | |
8434 | }" | |
8435 | [(set_attr "type" "shift") | |
8436 | (set_attr "length" "1")]) | |
8437 | ||
8438 | (define_insn "" | |
8439 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8440 | (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
ddef6bc7 | 8441 | (match_operand:SI 2 "small_int_or_double" "n")) 4) |
5cb01b65 JJ |
8442 | (match_operand:SI 3 "small_int_or_double" "n")))] |
8443 | "TARGET_ARCH64 | |
8444 | && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT | |
8445 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32 | |
8446 | && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32 | |
8447 | && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64" | |
8448 | "* | |
8449 | { | |
8450 | operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])); | |
8451 | ||
8452 | return \"srlx\\t%1, %2, %0\"; | |
8453 | }" | |
8454 | [(set_attr "type" "shift") | |
8455 | (set_attr "length" "1")]) | |
7a768814 RS |
8456 | \f |
8457 | ;; Unconditional and other jump instructions | |
c5791d70 JW |
8458 | ;; On the Sparc, by setting the annul bit on an unconditional branch, the |
8459 | ;; following insn is never executed. This saves us a nop. Dbx does not | |
8460 | ;; handle such branches though, so we only use them when optimizing. | |
7a768814 RS |
8461 | (define_insn "jump" |
8462 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
8463 | "" | |
8dcb5295 RH |
8464 | "* |
8465 | { | |
cb6420a0 | 8466 | /* TurboSparc is reported to have problems with |
82d6b402 | 8467 | with |
8dcb5295 RH |
8468 | foo: b,a foo |
8469 | i.e. an empty loop with the annul bit set. The workaround is to use | |
8470 | foo: b foo; nop | |
8471 | instead. */ | |
8472 | ||
cb6420a0 | 8473 | if (! TARGET_V9 && flag_delayed_branch |
9d98a694 AO |
8474 | && (INSN_ADDRESSES (INSN_UID (operands[0])) |
8475 | == INSN_ADDRESSES (INSN_UID (insn)))) | |
cb6420a0 | 8476 | return \"b\\t%l0%#\"; |
8dcb5295 | 8477 | else |
cb6420a0 | 8478 | return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\"; |
8dcb5295 | 8479 | }" |
e8d6096c | 8480 | [(set_attr "type" "uncond_branch")]) |
7a768814 RS |
8481 | |
8482 | (define_expand "tablejump" | |
a8d2b752 | 8483 | [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) |
7a768814 | 8484 | (use (label_ref (match_operand 1 "" "")))])] |
95726648 | 8485 | "" |
7a768814 RS |
8486 | " |
8487 | { | |
67cb8900 | 8488 | if (GET_MODE (operands[0]) != CASE_VECTOR_MODE) |
a8d2b752 DE |
8489 | abort (); |
8490 | ||
e0d80184 DM |
8491 | /* In pic mode, our address differences are against the base of the |
8492 | table. Add that base value back in; CSE ought to be able to combine | |
8493 | the two address loads. */ | |
7a768814 RS |
8494 | if (flag_pic) |
8495 | { | |
67cb8900 | 8496 | rtx tmp, tmp2; |
e0d80184 | 8497 | tmp = gen_rtx_LABEL_REF (Pmode, operands[1]); |
67cb8900 JJ |
8498 | tmp2 = operands[0]; |
8499 | if (CASE_VECTOR_MODE != Pmode) | |
8500 | tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2); | |
8501 | tmp = gen_rtx_PLUS (Pmode, tmp2, tmp); | |
e0d80184 | 8502 | operands[0] = memory_address (Pmode, tmp); |
7a768814 RS |
8503 | } |
8504 | }") | |
8505 | ||
c8b3b7d6 | 8506 | (define_insn "*tablejump_sp32" |
7a768814 RS |
8507 | [(set (pc) (match_operand:SI 0 "address_operand" "p")) |
8508 | (use (label_ref (match_operand 1 "" "")))] | |
7a2bf7af | 8509 | "! TARGET_ARCH64" |
e0d80184 | 8510 | "jmp\\t%a0%#" |
a8d2b752 DE |
8511 | [(set_attr "type" "uncond_branch")]) |
8512 | ||
c8b3b7d6 | 8513 | (define_insn "*tablejump_sp64" |
a8d2b752 DE |
8514 | [(set (pc) (match_operand:DI 0 "address_operand" "p")) |
8515 | (use (label_ref (match_operand 1 "" "")))] | |
7a2bf7af | 8516 | "TARGET_ARCH64" |
e0d80184 | 8517 | "jmp\\t%a0%#" |
e8d6096c | 8518 | [(set_attr "type" "uncond_branch")]) |
7a768814 | 8519 | |
7a768814 RS |
8520 | ;; This pattern recognizes the "instruction" that appears in |
8521 | ;; a function call that wants a structure value, | |
8522 | ;; to inform the called function if compiled with Sun CC. | |
c8b3b7d6 | 8523 | ;(define_insn "*unimp_insn" |
7a768814 RS |
8524 | ; [(match_operand:SI 0 "immediate_operand" "")] |
8525 | ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0" | |
e0d80184 | 8526 | ; "unimp\\t%0" |
7a768814 RS |
8527 | ; [(set_attr "type" "marker")]) |
8528 | ||
8529 | ;;- jump to subroutine | |
8530 | (define_expand "call" | |
8531 | ;; Note that this expression is not used for generating RTL. | |
8532 | ;; All the RTL is generated explicitly below. | |
a8d2b752 | 8533 | [(call (match_operand 0 "call_operand" "") |
7a768814 RS |
8534 | (match_operand 3 "" "i"))] |
8535 | ;; operands[2] is next_arg_register | |
8536 | ;; operands[3] is struct_value_size_rtx. | |
8537 | "" | |
8538 | " | |
8539 | { | |
8540 | rtx fn_rtx, nregs_rtx; | |
8541 | ||
a8d2b752 DE |
8542 | if (GET_MODE (operands[0]) != FUNCTION_MODE) |
8543 | abort (); | |
8544 | ||
60801f0b | 8545 | if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) |
7a768814 RS |
8546 | { |
8547 | /* This is really a PIC sequence. We want to represent | |
9ec36da5 | 8548 | it as a funny jump so its delay slots can be filled. |
7a768814 RS |
8549 | |
8550 | ??? But if this really *is* a CALL, will not it clobber the | |
8551 | call-clobbered registers? We lose this if it is a JUMP_INSN. | |
8552 | Why cannot we have delay slots filled if it were a CALL? */ | |
8553 | ||
fa0f39e4 | 8554 | if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) |
60801f0b | 8555 | emit_jump_insn |
c5c76735 JL |
8556 | (gen_rtx_PARALLEL |
8557 | (VOIDmode, | |
8558 | gen_rtvec (3, | |
8559 | gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)), | |
8232d28f | 8560 | operands[3], |
c5c76735 | 8561 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); |
7a768814 | 8562 | else |
60801f0b | 8563 | emit_jump_insn |
c5c76735 JL |
8564 | (gen_rtx_PARALLEL |
8565 | (VOIDmode, | |
8566 | gen_rtvec (2, | |
8567 | gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)), | |
8568 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); | |
7a768814 RS |
8569 | goto finish_call; |
8570 | } | |
8571 | ||
8572 | fn_rtx = operands[0]; | |
8573 | ||
8574 | /* Count the number of parameter registers being used by this call. | |
8575 | if that argument is NULL, it means we are using them all, which | |
8576 | means 6 on the sparc. */ | |
8577 | #if 0 | |
8578 | if (operands[2]) | |
5d4f5e87 | 8579 | nregs_rtx = GEN_INT (REGNO (operands[2]) - 8); |
7a768814 | 8580 | else |
5d4f5e87 | 8581 | nregs_rtx = GEN_INT (6); |
7a768814 RS |
8582 | #else |
8583 | nregs_rtx = const0_rtx; | |
8584 | #endif | |
8585 | ||
fa0f39e4 | 8586 | if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) |
60801f0b | 8587 | emit_call_insn |
c5c76735 JL |
8588 | (gen_rtx_PARALLEL |
8589 | (VOIDmode, | |
8590 | gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx), | |
8232d28f | 8591 | operands[3], |
c5c76735 | 8592 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); |
7a768814 | 8593 | else |
60801f0b | 8594 | emit_call_insn |
c5c76735 JL |
8595 | (gen_rtx_PARALLEL |
8596 | (VOIDmode, | |
8597 | gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx), | |
8598 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); | |
7a768814 RS |
8599 | |
8600 | finish_call: | |
8601 | #if 0 | |
8602 | /* If this call wants a structure value, | |
8603 | emit an unimp insn to let the called function know about this. */ | |
fa0f39e4 | 8604 | if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0) |
7a768814 RS |
8605 | { |
8606 | rtx insn = emit_insn (operands[3]); | |
8607 | SCHED_GROUP_P (insn) = 1; | |
8608 | } | |
8609 | #endif | |
8610 | ||
8611 | DONE; | |
8612 | }") | |
8613 | ||
bf97b967 JW |
8614 | ;; We can't use the same pattern for these two insns, because then registers |
8615 | ;; in the address may not be properly reloaded. | |
8616 | ||
c8b3b7d6 | 8617 | (define_insn "*call_address_sp32" |
bf97b967 JW |
8618 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
8619 | (match_operand 1 "" "")) | |
8620 | (clobber (reg:SI 15))] | |
8621 | ;;- Do not use operand 1 for most machines. | |
7a2bf7af | 8622 | "! TARGET_ARCH64" |
e0d80184 | 8623 | "call\\t%a0, %1%#" |
bf97b967 JW |
8624 | [(set_attr "type" "call")]) |
8625 | ||
c8b3b7d6 | 8626 | (define_insn "*call_symbolic_sp32" |
2c435002 | 8627 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
7a768814 RS |
8628 | (match_operand 1 "" "")) |
8629 | (clobber (reg:SI 15))] | |
8630 | ;;- Do not use operand 1 for most machines. | |
7a2bf7af | 8631 | "! TARGET_ARCH64" |
e0d80184 | 8632 | "call\\t%a0, %1%#" |
a8d2b752 DE |
8633 | [(set_attr "type" "call")]) |
8634 | ||
c8b3b7d6 | 8635 | (define_insn "*call_address_sp64" |
3276910d | 8636 | [(call (mem:DI (match_operand:DI 0 "address_operand" "p")) |
a8d2b752 DE |
8637 | (match_operand 1 "" "")) |
8638 | (clobber (reg:DI 15))] | |
8639 | ;;- Do not use operand 1 for most machines. | |
7a2bf7af | 8640 | "TARGET_ARCH64" |
e0d80184 | 8641 | "call\\t%a0, %1%#" |
a8d2b752 DE |
8642 | [(set_attr "type" "call")]) |
8643 | ||
c8b3b7d6 | 8644 | (define_insn "*call_symbolic_sp64" |
3276910d | 8645 | [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s")) |
a8d2b752 DE |
8646 | (match_operand 1 "" "")) |
8647 | (clobber (reg:DI 15))] | |
8648 | ;;- Do not use operand 1 for most machines. | |
7a2bf7af | 8649 | "TARGET_ARCH64" |
e0d80184 | 8650 | "call\\t%a0, %1%#" |
7a768814 RS |
8651 | [(set_attr "type" "call")]) |
8652 | ||
8653 | ;; This is a call that wants a structure value. | |
a8d2b752 | 8654 | ;; There is no such critter for v9 (??? we may need one anyway). |
c8b3b7d6 | 8655 | (define_insn "*call_address_struct_value_sp32" |
bf97b967 JW |
8656 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
8657 | (match_operand 1 "" "")) | |
8658 | (match_operand 2 "immediate_operand" "") | |
8659 | (clobber (reg:SI 15))] | |
8660 | ;;- Do not use operand 1 for most machines. | |
7d49f59f | 8661 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0" |
e0d80184 | 8662 | "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2" |
bf97b967 JW |
8663 | [(set_attr "type" "call_no_delay_slot")]) |
8664 | ||
8665 | ;; This is a call that wants a structure value. | |
a8d2b752 | 8666 | ;; There is no such critter for v9 (??? we may need one anyway). |
c8b3b7d6 | 8667 | (define_insn "*call_symbolic_struct_value_sp32" |
2c435002 | 8668 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
7a768814 RS |
8669 | (match_operand 1 "" "")) |
8670 | (match_operand 2 "immediate_operand" "") | |
8671 | (clobber (reg:SI 15))] | |
8672 | ;;- Do not use operand 1 for most machines. | |
7d49f59f | 8673 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0" |
e0d80184 | 8674 | "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2" |
7a768814 RS |
8675 | [(set_attr "type" "call_no_delay_slot")]) |
8676 | ||
d18d5ca2 JW |
8677 | ;; This is a call that may want a structure value. This is used for |
8678 | ;; untyped_calls. | |
c8b3b7d6 | 8679 | (define_insn "*call_address_untyped_struct_value_sp32" |
d18d5ca2 JW |
8680 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
8681 | (match_operand 1 "" "")) | |
8682 | (match_operand 2 "immediate_operand" "") | |
8683 | (clobber (reg:SI 15))] | |
8684 | ;;- Do not use operand 1 for most machines. | |
fa0f39e4 | 8685 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" |
e0d80184 | 8686 | "call\\t%a0, %1\\n\\tnop\\n\\tnop" |
d18d5ca2 JW |
8687 | [(set_attr "type" "call_no_delay_slot")]) |
8688 | ||
8689 | ;; This is a call that wants a structure value. | |
c8b3b7d6 | 8690 | (define_insn "*call_symbolic_untyped_struct_value_sp32" |
d18d5ca2 JW |
8691 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
8692 | (match_operand 1 "" "")) | |
8693 | (match_operand 2 "immediate_operand" "") | |
8694 | (clobber (reg:SI 15))] | |
8695 | ;;- Do not use operand 1 for most machines. | |
fa0f39e4 | 8696 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" |
e0d80184 | 8697 | "call\\t%a0, %1\\n\\tnop\\n\\tnop" |
d18d5ca2 JW |
8698 | [(set_attr "type" "call_no_delay_slot")]) |
8699 | ||
7a768814 | 8700 | (define_expand "call_value" |
a8d2b752 DE |
8701 | ;; Note that this expression is not used for generating RTL. |
8702 | ;; All the RTL is generated explicitly below. | |
7a768814 | 8703 | [(set (match_operand 0 "register_operand" "=rf") |
3276910d | 8704 | (call (match_operand 1 "" "") |
7a768814 | 8705 | (match_operand 4 "" "")))] |
a8d2b752 | 8706 | ;; operand 2 is stack_size_rtx |
7a768814 RS |
8707 | ;; operand 3 is next_arg_register |
8708 | "" | |
8709 | " | |
8710 | { | |
8711 | rtx fn_rtx, nregs_rtx; | |
8712 | rtvec vec; | |
8713 | ||
a8d2b752 DE |
8714 | if (GET_MODE (operands[1]) != FUNCTION_MODE) |
8715 | abort (); | |
8716 | ||
7a768814 RS |
8717 | fn_rtx = operands[1]; |
8718 | ||
8719 | #if 0 | |
8720 | if (operands[3]) | |
3a598fbe | 8721 | nregs_rtx = GEN_INT (REGNO (operands[3]) - 8); |
7a768814 | 8722 | else |
3a598fbe | 8723 | nregs_rtx = GEN_INT (6); |
7a768814 RS |
8724 | #else |
8725 | nregs_rtx = const0_rtx; | |
8726 | #endif | |
8727 | ||
8728 | vec = gen_rtvec (2, | |
5b8e7fa3 | 8729 | gen_rtx_SET (VOIDmode, operands[0], |
c5c76735 | 8730 | gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)), |
254110c2 | 8731 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))); |
7a768814 | 8732 | |
5b8e7fa3 | 8733 | emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec)); |
7a768814 RS |
8734 | |
8735 | DONE; | |
8736 | }") | |
8737 | ||
c8b3b7d6 | 8738 | (define_insn "*call_value_address_sp32" |
7a768814 | 8739 | [(set (match_operand 0 "" "=rf") |
bf97b967 JW |
8740 | (call (mem:SI (match_operand:SI 1 "address_operand" "p")) |
8741 | (match_operand 2 "" ""))) | |
8742 | (clobber (reg:SI 15))] | |
8743 | ;;- Do not use operand 2 for most machines. | |
7a2bf7af | 8744 | "! TARGET_ARCH64" |
e0d80184 | 8745 | "call\\t%a1, %2%#" |
bf97b967 JW |
8746 | [(set_attr "type" "call")]) |
8747 | ||
c8b3b7d6 | 8748 | (define_insn "*call_value_symbolic_sp32" |
bf97b967 | 8749 | [(set (match_operand 0 "" "=rf") |
2c435002 | 8750 | (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s")) |
7a768814 RS |
8751 | (match_operand 2 "" ""))) |
8752 | (clobber (reg:SI 15))] | |
8753 | ;;- Do not use operand 2 for most machines. | |
7a2bf7af | 8754 | "! TARGET_ARCH64" |
e0d80184 | 8755 | "call\\t%a1, %2%#" |
a8d2b752 DE |
8756 | [(set_attr "type" "call")]) |
8757 | ||
c8b3b7d6 | 8758 | (define_insn "*call_value_address_sp64" |
82d6b402 | 8759 | [(set (match_operand 0 "" "") |
3276910d | 8760 | (call (mem:DI (match_operand:DI 1 "address_operand" "p")) |
a8d2b752 DE |
8761 | (match_operand 2 "" ""))) |
8762 | (clobber (reg:DI 15))] | |
8763 | ;;- Do not use operand 2 for most machines. | |
7a2bf7af | 8764 | "TARGET_ARCH64" |
e0d80184 | 8765 | "call\\t%a1, %2%#" |
a8d2b752 DE |
8766 | [(set_attr "type" "call")]) |
8767 | ||
c8b3b7d6 | 8768 | (define_insn "*call_value_symbolic_sp64" |
82d6b402 | 8769 | [(set (match_operand 0 "" "") |
3276910d | 8770 | (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s")) |
a8d2b752 DE |
8771 | (match_operand 2 "" ""))) |
8772 | (clobber (reg:DI 15))] | |
8773 | ;;- Do not use operand 2 for most machines. | |
7a2bf7af | 8774 | "TARGET_ARCH64" |
e0d80184 | 8775 | "call\\t%a1, %2%#" |
7a768814 | 8776 | [(set_attr "type" "call")]) |
576182a3 TW |
8777 | |
8778 | (define_expand "untyped_call" | |
d18d5ca2 | 8779 | [(parallel [(call (match_operand 0 "" "") |
576182a3 | 8780 | (const_int 0)) |
d18d5ca2 JW |
8781 | (match_operand 1 "" "") |
8782 | (match_operand 2 "" "")])] | |
576182a3 TW |
8783 | "" |
8784 | " | |
8785 | { | |
d18d5ca2 | 8786 | int i; |
576182a3 | 8787 | |
d18d5ca2 JW |
8788 | /* Pass constm1 to indicate that it may expect a structure value, but |
8789 | we don't know what size it is. */ | |
0499c2e4 | 8790 | emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx)); |
bf97b967 | 8791 | |
d18d5ca2 JW |
8792 | for (i = 0; i < XVECLEN (operands[2], 0); i++) |
8793 | { | |
8794 | rtx set = XVECEXP (operands[2], 0, i); | |
8795 | emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
8796 | } | |
bf97b967 | 8797 | |
d18d5ca2 JW |
8798 | /* The optimizer does not know that the call sets the function value |
8799 | registers we stored in the result block. We avoid problems by | |
8800 | claiming that all hard registers are used and clobbered at this | |
8801 | point. */ | |
8802 | emit_insn (gen_blockage ()); | |
576182a3 | 8803 | |
d18d5ca2 JW |
8804 | DONE; |
8805 | }") | |
a8d2b752 | 8806 | |
7d167afd JJ |
8807 | ;;- tail calls |
8808 | (define_expand "sibcall" | |
8809 | [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0)) | |
8810 | (return)])] | |
8811 | "" | |
8812 | "") | |
8813 | ||
8814 | (define_insn "*sibcall_symbolic_sp32" | |
8815 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) | |
8816 | (match_operand 1 "" "")) | |
8817 | (return)] | |
7a2bf7af | 8818 | "! TARGET_ARCH64" |
7d167afd JJ |
8819 | "* return output_sibcall(insn, operands[0]);" |
8820 | [(set_attr "type" "sibcall")]) | |
8821 | ||
8822 | (define_insn "*sibcall_symbolic_sp64" | |
3276910d | 8823 | [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s")) |
7d167afd JJ |
8824 | (match_operand 1 "" "")) |
8825 | (return)] | |
7a2bf7af | 8826 | "TARGET_ARCH64" |
7d167afd JJ |
8827 | "* return output_sibcall(insn, operands[0]);" |
8828 | [(set_attr "type" "sibcall")]) | |
8829 | ||
8830 | (define_expand "sibcall_value" | |
8831 | [(parallel [(set (match_operand 0 "register_operand" "=rf") | |
3276910d | 8832 | (call (match_operand 1 "" "") (const_int 0))) |
7d167afd JJ |
8833 | (return)])] |
8834 | "" | |
8835 | "") | |
8836 | ||
8837 | (define_insn "*sibcall_value_symbolic_sp32" | |
8838 | [(set (match_operand 0 "" "=rf") | |
8839 | (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s")) | |
8840 | (match_operand 2 "" ""))) | |
8841 | (return)] | |
7a2bf7af | 8842 | "! TARGET_ARCH64" |
7d167afd JJ |
8843 | "* return output_sibcall(insn, operands[1]);" |
8844 | [(set_attr "type" "sibcall")]) | |
8845 | ||
8846 | (define_insn "*sibcall_value_symbolic_sp64" | |
8847 | [(set (match_operand 0 "" "") | |
3276910d | 8848 | (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s")) |
7d167afd JJ |
8849 | (match_operand 2 "" ""))) |
8850 | (return)] | |
7a2bf7af | 8851 | "TARGET_ARCH64" |
7d167afd JJ |
8852 | "* return output_sibcall(insn, operands[1]);" |
8853 | [(set_attr "type" "sibcall")]) | |
8854 | ||
8855 | (define_expand "sibcall_epilogue" | |
8856 | [(const_int 0)] | |
8857 | "" | |
8858 | "DONE;") | |
8859 | ||
d18d5ca2 JW |
8860 | ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and |
8861 | ;; all of memory. This blocks insns from being moved across this point. | |
a8d2b752 | 8862 | |
d18d5ca2 JW |
8863 | (define_insn "blockage" |
8864 | [(unspec_volatile [(const_int 0)] 0)] | |
8865 | "" | |
532eedf4 RH |
8866 | "" |
8867 | [(set_attr "length" "0")]) | |
a8d2b752 | 8868 | |
576182a3 TW |
8869 | ;; Prepare to return any type including a structure value. |
8870 | ||
8871 | (define_expand "untyped_return" | |
8872 | [(match_operand:BLK 0 "memory_operand" "") | |
8873 | (match_operand 1 "" "")] | |
8874 | "" | |
8875 | " | |
8876 | { | |
254110c2 DM |
8877 | rtx valreg1 = gen_rtx_REG (DImode, 24); |
8878 | rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); | |
576182a3 | 8879 | rtx result = operands[0]; |
576182a3 | 8880 | |
fa0f39e4 | 8881 | if (! TARGET_ARCH64) |
a8d2b752 | 8882 | { |
54ff41b7 JW |
8883 | rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs |
8884 | ? 15 : 31)); | |
a8d2b752 DE |
8885 | rtx value = gen_reg_rtx (SImode); |
8886 | ||
8887 | /* Fetch the instruction where we will return to and see if it's an unimp | |
8888 | instruction (the most significant 10 bits will be zero). If so, | |
8889 | update the return address to skip the unimp instruction. */ | |
8890 | emit_move_insn (value, | |
5b8e7fa3 | 8891 | gen_rtx_MEM (SImode, plus_constant (rtnreg, 8))); |
a8d2b752 DE |
8892 | emit_insn (gen_lshrsi3 (value, value, GEN_INT (22))); |
8893 | emit_insn (gen_update_return (rtnreg, value)); | |
8894 | } | |
576182a3 TW |
8895 | |
8896 | /* Reload the function value registers. */ | |
f4ef873c | 8897 | emit_move_insn (valreg1, adjust_address (result, DImode, 0)); |
576182a3 | 8898 | emit_move_insn (valreg2, |
f4ef873c | 8899 | adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8)); |
576182a3 TW |
8900 | |
8901 | /* Put USE insns before the return. */ | |
5b8e7fa3 DM |
8902 | emit_insn (gen_rtx_USE (VOIDmode, valreg1)); |
8903 | emit_insn (gen_rtx_USE (VOIDmode, valreg2)); | |
576182a3 TW |
8904 | |
8905 | /* Construct the return. */ | |
8906 | expand_null_return (); | |
8907 | ||
8908 | DONE; | |
8909 | }") | |
8910 | ||
8911 | ;; This is a bit of a hack. We're incrementing a fixed register (%i7), | |
8912 | ;; and parts of the compiler don't want to believe that the add is needed. | |
8913 | ||
8914 | (define_insn "update_return" | |
8915 | [(unspec:SI [(match_operand:SI 0 "register_operand" "r") | |
6fd1c67b | 8916 | (match_operand:SI 1 "register_operand" "r")] 1)] |
fa0f39e4 | 8917 | "! TARGET_ARCH64" |
9ea2bda9 | 8918 | "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0" |
576182a3 | 8919 | [(set_attr "type" "multi")]) |
7a768814 RS |
8920 | \f |
8921 | (define_insn "return" | |
9704efe6 MS |
8922 | [(return) |
8923 | (use (reg:SI 31))] | |
7a768814 RS |
8924 | "! TARGET_EPILOGUE" |
8925 | "* return output_return (operands);" | |
284d86e9 JC |
8926 | [(set_attr "type" "return")]) |
8927 | ||
8928 | (define_peephole | |
8929 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8930 | (match_operand:SI 1 "arith_operand" "rI")) | |
8931 | (parallel [(return) | |
8932 | (use (reg:SI 31))])] | |
8933 | "sparc_return_peephole_ok (operands[0], operands[1])" | |
e0d80184 | 8934 | "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0") |
7a768814 RS |
8935 | |
8936 | (define_insn "nop" | |
8937 | [(const_int 0)] | |
8938 | "" | |
3bc8b61e DM |
8939 | "nop" |
8940 | [(set_attr "type" "ialu") | |
8941 | (set_attr "length" "1")]) | |
7a768814 | 8942 | |
a8d2b752 DE |
8943 | (define_expand "indirect_jump" |
8944 | [(set (pc) (match_operand 0 "address_operand" "p"))] | |
7a768814 | 8945 | "" |
a8d2b752 DE |
8946 | "") |
8947 | ||
c8b3b7d6 | 8948 | (define_insn "*branch_sp32" |
a8d2b752 | 8949 | [(set (pc) (match_operand:SI 0 "address_operand" "p"))] |
7a2bf7af | 8950 | "! TARGET_ARCH64" |
e0d80184 | 8951 | "jmp\\t%a0%#" |
e8d6096c | 8952 | [(set_attr "type" "uncond_branch")]) |
7a768814 | 8953 | |
c8b3b7d6 | 8954 | (define_insn "*branch_sp64" |
a8d2b752 | 8955 | [(set (pc) (match_operand:DI 0 "address_operand" "p"))] |
7a2bf7af | 8956 | "TARGET_ARCH64" |
e0d80184 | 8957 | "jmp\\t%a0%#" |
a8d2b752 DE |
8958 | [(set_attr "type" "uncond_branch")]) |
8959 | ||
d9d0de41 | 8960 | ;; ??? Doesn't work with -mflat. |
7a768814 | 8961 | (define_expand "nonlocal_goto" |
284d86e9 | 8962 | [(match_operand:SI 0 "general_operand" "") |
7a768814 RS |
8963 | (match_operand:SI 1 "general_operand" "") |
8964 | (match_operand:SI 2 "general_operand" "") | |
284d86e9 | 8965 | (match_operand:SI 3 "" "")] |
7a768814 RS |
8966 | "" |
8967 | " | |
8968 | { | |
3bb5de61 | 8969 | #if 0 |
6fd1c67b | 8970 | rtx chain = operands[0]; |
3bb5de61 | 8971 | #endif |
6fd1c67b RH |
8972 | rtx fp = operands[1]; |
8973 | rtx stack = operands[2]; | |
8974 | rtx lab = operands[3]; | |
82d6b402 | 8975 | rtx labreg; |
6fd1c67b | 8976 | |
b6d3c4ba | 8977 | /* Trap instruction to flush all the register windows. */ |
4893584c | 8978 | emit_insn (gen_flush_register_windows ()); |
6fd1c67b RH |
8979 | |
8980 | /* Load the fp value for the containing fn into %fp. This is needed | |
8981 | because STACK refers to %fp. Note that virtual register instantiation | |
8982 | fails if the virtual %fp isn't set from a register. */ | |
8983 | if (GET_CODE (fp) != REG) | |
8984 | fp = force_reg (Pmode, fp); | |
8985 | emit_move_insn (virtual_stack_vars_rtx, fp); | |
8986 | ||
7a768814 RS |
8987 | /* Find the containing function's current nonlocal goto handler, |
8988 | which will do any cleanups and then jump to the label. */ | |
254110c2 | 8989 | labreg = gen_rtx_REG (Pmode, 8); |
82d6b402 | 8990 | emit_move_insn (labreg, lab); |
6fd1c67b | 8991 | |
7a768814 RS |
8992 | /* Restore %fp from stack pointer value for containing function. |
8993 | The restore insn that follows will move this to %sp, | |
8994 | and reload the appropriate value into %fp. */ | |
6fd1c67b RH |
8995 | emit_move_insn (frame_pointer_rtx, stack); |
8996 | ||
7a768814 RS |
8997 | /* USE of frame_pointer_rtx added for consistency; not clear if |
8998 | really needed. */ | |
5b8e7fa3 DM |
8999 | /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/ |
9000 | emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); | |
ba716ac9 BS |
9001 | |
9002 | #if 0 | |
7a768814 | 9003 | /* Return, restoring reg window and jumping to goto handler. */ |
82d6b402 RH |
9004 | if (TARGET_V9 && GET_CODE (chain) == CONST_INT |
9005 | && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff)) | |
284d86e9 | 9006 | { |
a338321e RK |
9007 | emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg, |
9008 | static_chain_rtx, | |
9009 | chain)); | |
284d86e9 JC |
9010 | emit_barrier (); |
9011 | DONE; | |
9012 | } | |
9013 | /* Put in the static chain register the nonlocal label address. */ | |
9014 | emit_move_insn (static_chain_rtx, chain); | |
ba716ac9 BS |
9015 | #endif |
9016 | ||
5b8e7fa3 | 9017 | emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx)); |
a338321e | 9018 | emit_jump_insn (gen_goto_handler_and_restore (labreg)); |
bf1b20da | 9019 | emit_barrier (); |
7a768814 RS |
9020 | DONE; |
9021 | }") | |
9022 | ||
9023 | ;; Special trap insn to flush register windows. | |
4893584c | 9024 | (define_insn "flush_register_windows" |
d18d5ca2 | 9025 | [(unspec_volatile [(const_int 0)] 1)] |
7a768814 | 9026 | "" |
e0d80184 | 9027 | "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";" |
3bc8b61e DM |
9028 | [(set_attr "type" "misc") |
9029 | (set_attr "length" "1")]) | |
7a768814 | 9030 | |
4893584c | 9031 | (define_insn "goto_handler_and_restore" |
073149a2 | 9032 | [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)] |
db7eb3e8 | 9033 | "GET_MODE (operands[0]) == Pmode" |
e0d80184 | 9034 | "jmp\\t%0+0\\n\\trestore" |
b4ac57ab RS |
9035 | [(set_attr "type" "misc") |
9036 | (set_attr "length" "2")]) | |
94698f4d | 9037 | |
ba716ac9 BS |
9038 | ;;(define_insn "goto_handler_and_restore_v9" |
9039 | ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r") | |
9040 | ;; (match_operand:SI 1 "register_operand" "=r,r") | |
9041 | ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)] | |
9042 | ;; "TARGET_V9 && ! TARGET_ARCH64" | |
9043 | ;; "@ | |
9044 | ;; return\\t%0+0\\n\\tmov\\t%2, %Y1 | |
9045 | ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1" | |
9046 | ;; [(set_attr "type" "misc") | |
9047 | ;; (set_attr "length" "2,3")]) | |
9048 | ;; | |
9049 | ;;(define_insn "*goto_handler_and_restore_v9_sp64" | |
9050 | ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r") | |
9051 | ;; (match_operand:DI 1 "register_operand" "=r,r") | |
9052 | ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)] | |
9053 | ;; "TARGET_V9 && TARGET_ARCH64" | |
9054 | ;; "@ | |
9055 | ;; return\\t%0+0\\n\\tmov\\t%2, %Y1 | |
9056 | ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1" | |
9057 | ;; [(set_attr "type" "misc") | |
9058 | ;; (set_attr "length" "2,3")]) | |
284d86e9 | 9059 | |
f36d6244 JJ |
9060 | ;; For __builtin_setjmp we need to flush register windows iff the function |
9061 | ;; calls alloca as well, because otherwise the register window might be | |
9062 | ;; saved after %sp adjustement and thus setjmp would crash | |
9063 | (define_expand "builtin_setjmp_setup" | |
9064 | [(match_operand 0 "register_operand" "r")] | |
9065 | "" | |
9066 | " | |
9067 | { | |
9068 | emit_insn (gen_do_builtin_setjmp_setup ()); | |
9069 | DONE; | |
9070 | }") | |
9071 | ||
9072 | (define_insn "do_builtin_setjmp_setup" | |
9073 | [(unspec_volatile [(const_int 0)] 5)] | |
9074 | "" | |
9075 | "* | |
9076 | { | |
9077 | if (!current_function_calls_alloca) | |
9078 | return \"\"; | |
9079 | if (TARGET_V9) | |
9080 | return \"flushw\"; | |
9081 | return \"ta\\t3\"; | |
9082 | }" | |
9083 | [(set_attr "type" "misc") | |
9084 | (set_attr "length" "1")]) | |
9085 | ||
284d86e9 JC |
9086 | ;; Pattern for use after a setjmp to store FP and the return register |
9087 | ;; into the stack area. | |
bf1b20da | 9088 | |
284d86e9 JC |
9089 | (define_expand "setjmp" |
9090 | [(const_int 0)] | |
bf1b20da RK |
9091 | "" |
9092 | " | |
9093 | { | |
9094 | if (TARGET_ARCH64) | |
9095 | emit_insn (gen_setjmp_64 ()); | |
9096 | else | |
9097 | emit_insn (gen_setjmp_32 ()); | |
bf1b20da RK |
9098 | DONE; |
9099 | }") | |
9100 | ||
9101 | (define_expand "setjmp_32" | |
9102 | [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0)) | |
9103 | (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))] | |
9104 | "" | |
9105 | " | |
9106 | { operands[0] = frame_pointer_rtx; }") | |
9107 | ||
9108 | (define_expand "setjmp_64" | |
9109 | [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0)) | |
9110 | (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))] | |
9111 | "" | |
9112 | " | |
9113 | { operands[0] = frame_pointer_rtx; }") | |
9114 | ||
94698f4d RS |
9115 | ;; Special pattern for the FLUSH instruction. |
9116 | ||
c219ddf7 BK |
9117 | ; We do SImode and DImode versions of this to quiet down genrecog's complaints |
9118 | ; of the define_insn otherwise missing a mode. We make "flush", aka | |
9119 | ; gen_flush, the default one since sparc_initialize_trampoline uses | |
9120 | ; it on SImode mem values. | |
9121 | ||
94698f4d | 9122 | (define_insn "flush" |
c219ddf7 | 9123 | [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)] |
94698f4d | 9124 | "" |
9ea2bda9 | 9125 | "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";" |
c219ddf7 BK |
9126 | [(set_attr "type" "misc")]) |
9127 | ||
9128 | (define_insn "flushdi" | |
9129 | [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)] | |
9130 | "" | |
9ea2bda9 | 9131 | "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";" |
c219ddf7 BK |
9132 | [(set_attr "type" "misc")]) |
9133 | ||
7a768814 | 9134 | \f |
114b9aa4 JW |
9135 | ;; find first set. |
9136 | ||
9137 | ;; The scan instruction searches from the most significant bit while ffs | |
9138 | ;; searches from the least significant bit. The bit index and treatment of | |
9139 | ;; zero also differ. It takes at least 7 instructions to get the proper | |
ddd5a7c1 | 9140 | ;; result. Here is an obvious 8 instruction sequence. |
114b9aa4 | 9141 | |
e0d80184 | 9142 | ;; XXX |
114b9aa4 JW |
9143 | (define_insn "ffssi2" |
9144 | [(set (match_operand:SI 0 "register_operand" "=&r") | |
9145 | (ffs:SI (match_operand:SI 1 "register_operand" "r"))) | |
9146 | (clobber (match_scratch:SI 2 "=&r"))] | |
967ba98d | 9147 | "TARGET_SPARCLITE || TARGET_SPARCLET" |
c4ce6853 DE |
9148 | "* |
9149 | { | |
9ea2bda9 | 9150 | return \"sub\\t%%g0, %1, %0\;and\\t%0, %1, %0\;scan\\t%0, 0, %0\;mov\\t32, %2\;sub\\t%2, %0, %0\;sra\\t%0, 31, %2\;and\\t%2, 31, %2\;add\\t%2, %0, %0\"; |
c4ce6853 | 9151 | }" |
114b9aa4 JW |
9152 | [(set_attr "type" "multi") |
9153 | (set_attr "length" "8")]) | |
a8d2b752 DE |
9154 | |
9155 | ;; ??? This should be a define expand, so that the extra instruction have | |
9156 | ;; a chance of being optimized away. | |
9157 | ||
0f177d7c RH |
9158 | ;; Disabled because none of the UltraSparcs implement popc. The HAL R1 |
9159 | ;; does, but no one uses that and we don't have a switch for it. | |
9160 | ; | |
9161 | ;(define_insn "ffsdi2" | |
9162 | ; [(set (match_operand:DI 0 "register_operand" "=&r") | |
9163 | ; (ffs:DI (match_operand:DI 1 "register_operand" "r"))) | |
9164 | ; (clobber (match_scratch:DI 2 "=&r"))] | |
9165 | ; "TARGET_ARCH64" | |
9ea2bda9 | 9166 | ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0" |
0f177d7c | 9167 | ; [(set_attr "type" "multi") |
50324922 | 9168 | ; (set_attr "length" "4")]) |
7a768814 | 9169 | |
c5c76735 | 9170 | |
7a768814 RS |
9171 | \f |
9172 | ;; Peepholes go at the end. | |
9173 | ||
35016322 JW |
9174 | ;; Optimize consecutive loads or stores into ldd and std when possible. |
9175 | ;; The conditions in which we do this are very restricted and are | |
9176 | ;; explained in the code for {registers,memory}_ok_for_ldd functions. | |
9177 | ||
bfd6bc60 JC |
9178 | (define_peephole |
9179 | [(set (match_operand:SI 0 "memory_operand" "") | |
9180 | (const_int 0)) | |
9181 | (set (match_operand:SI 1 "memory_operand" "") | |
9182 | (const_int 0))] | |
9183 | "TARGET_V9 | |
e0d80184 DM |
9184 | && ! MEM_VOLATILE_P (operands[0]) |
9185 | && ! MEM_VOLATILE_P (operands[1]) | |
bfd6bc60 | 9186 | && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))" |
e0d80184 | 9187 | "stx\\t%%g0, %0") |
bfd6bc60 JC |
9188 | |
9189 | (define_peephole | |
9190 | [(set (match_operand:SI 0 "memory_operand" "") | |
9191 | (const_int 0)) | |
9192 | (set (match_operand:SI 1 "memory_operand" "") | |
9193 | (const_int 0))] | |
9194 | "TARGET_V9 | |
e0d80184 DM |
9195 | && ! MEM_VOLATILE_P (operands[0]) |
9196 | && ! MEM_VOLATILE_P (operands[1]) | |
bfd6bc60 | 9197 | && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))" |
e0d80184 | 9198 | "stx\\t%%g0, %1") |
bfd6bc60 | 9199 | |
35016322 | 9200 | (define_peephole |
82b56258 | 9201 | [(set (match_operand:SI 0 "register_operand" "=rf") |
35016322 | 9202 | (match_operand:SI 1 "memory_operand" "")) |
82b56258 | 9203 | (set (match_operand:SI 2 "register_operand" "=rf") |
35016322 | 9204 | (match_operand:SI 3 "memory_operand" ""))] |
e0d80184 DM |
9205 | "registers_ok_for_ldd_peep (operands[0], operands[2]) |
9206 | && ! MEM_VOLATILE_P (operands[1]) | |
9207 | && ! MEM_VOLATILE_P (operands[3]) | |
e8d6096c | 9208 | && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" |
e0d80184 | 9209 | "ldd\\t%1, %0") |
35016322 JW |
9210 | |
9211 | (define_peephole | |
9212 | [(set (match_operand:SI 0 "memory_operand" "") | |
82b56258 | 9213 | (match_operand:SI 1 "register_operand" "rf")) |
35016322 | 9214 | (set (match_operand:SI 2 "memory_operand" "") |
82b56258 | 9215 | (match_operand:SI 3 "register_operand" "rf"))] |
e0d80184 DM |
9216 | "registers_ok_for_ldd_peep (operands[1], operands[3]) |
9217 | && ! MEM_VOLATILE_P (operands[0]) | |
9218 | && ! MEM_VOLATILE_P (operands[2]) | |
e8d6096c | 9219 | && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" |
e0d80184 | 9220 | "std\\t%1, %0") |
35016322 JW |
9221 | |
9222 | (define_peephole | |
2abaee93 | 9223 | [(set (match_operand:SF 0 "register_operand" "=fr") |
35016322 | 9224 | (match_operand:SF 1 "memory_operand" "")) |
2abaee93 | 9225 | (set (match_operand:SF 2 "register_operand" "=fr") |
35016322 | 9226 | (match_operand:SF 3 "memory_operand" ""))] |
e0d80184 DM |
9227 | "registers_ok_for_ldd_peep (operands[0], operands[2]) |
9228 | && ! MEM_VOLATILE_P (operands[1]) | |
9229 | && ! MEM_VOLATILE_P (operands[3]) | |
e8d6096c | 9230 | && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" |
e0d80184 | 9231 | "ldd\\t%1, %0") |
35016322 JW |
9232 | |
9233 | (define_peephole | |
9234 | [(set (match_operand:SF 0 "memory_operand" "") | |
9235 | (match_operand:SF 1 "register_operand" "fr")) | |
9236 | (set (match_operand:SF 2 "memory_operand" "") | |
9237 | (match_operand:SF 3 "register_operand" "fr"))] | |
e0d80184 DM |
9238 | "registers_ok_for_ldd_peep (operands[1], operands[3]) |
9239 | && ! MEM_VOLATILE_P (operands[0]) | |
9240 | && ! MEM_VOLATILE_P (operands[2]) | |
9241 | && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" | |
9242 | "std\\t%1, %0") | |
35016322 JW |
9243 | |
9244 | (define_peephole | |
82b56258 | 9245 | [(set (match_operand:SI 0 "register_operand" "=rf") |
35016322 | 9246 | (match_operand:SI 1 "memory_operand" "")) |
82b56258 | 9247 | (set (match_operand:SI 2 "register_operand" "=rf") |
35016322 | 9248 | (match_operand:SI 3 "memory_operand" ""))] |
e0d80184 DM |
9249 | "registers_ok_for_ldd_peep (operands[2], operands[0]) |
9250 | && ! MEM_VOLATILE_P (operands[3]) | |
9251 | && ! MEM_VOLATILE_P (operands[1]) | |
9252 | && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" | |
9253 | "ldd\\t%3, %2") | |
35016322 JW |
9254 | |
9255 | (define_peephole | |
9256 | [(set (match_operand:SI 0 "memory_operand" "") | |
82b56258 | 9257 | (match_operand:SI 1 "register_operand" "rf")) |
35016322 | 9258 | (set (match_operand:SI 2 "memory_operand" "") |
82b56258 | 9259 | (match_operand:SI 3 "register_operand" "rf"))] |
e0d80184 DM |
9260 | "registers_ok_for_ldd_peep (operands[3], operands[1]) |
9261 | && ! MEM_VOLATILE_P (operands[2]) | |
9262 | && ! MEM_VOLATILE_P (operands[0]) | |
9263 | && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" | |
9264 | "std\\t%3, %2") | |
35016322 JW |
9265 | |
9266 | (define_peephole | |
2abaee93 | 9267 | [(set (match_operand:SF 0 "register_operand" "=fr") |
35016322 | 9268 | (match_operand:SF 1 "memory_operand" "")) |
2abaee93 | 9269 | (set (match_operand:SF 2 "register_operand" "=fr") |
35016322 | 9270 | (match_operand:SF 3 "memory_operand" ""))] |
e0d80184 DM |
9271 | "registers_ok_for_ldd_peep (operands[2], operands[0]) |
9272 | && ! MEM_VOLATILE_P (operands[3]) | |
9273 | && ! MEM_VOLATILE_P (operands[1]) | |
9274 | && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" | |
9275 | "ldd\\t%3, %2") | |
35016322 JW |
9276 | |
9277 | (define_peephole | |
9278 | [(set (match_operand:SF 0 "memory_operand" "") | |
9279 | (match_operand:SF 1 "register_operand" "fr")) | |
9280 | (set (match_operand:SF 2 "memory_operand" "") | |
9281 | (match_operand:SF 3 "register_operand" "fr"))] | |
e0d80184 DM |
9282 | "registers_ok_for_ldd_peep (operands[3], operands[1]) |
9283 | && ! MEM_VOLATILE_P (operands[2]) | |
9284 | && ! MEM_VOLATILE_P (operands[0]) | |
9285 | && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" | |
9286 | "std\\t%3, %2") | |
35016322 | 9287 | |
7a768814 | 9288 | ;; Optimize the case of following a reg-reg move with a test |
1a1ba90e | 9289 | ;; of reg just moved. Don't allow floating point regs for operand 0 or 1. |
72f4648e | 9290 | ;; This can result from a float to fix conversion. |
7a768814 RS |
9291 | |
9292 | (define_peephole | |
9293 | [(set (match_operand:SI 0 "register_operand" "=r") | |
9294 | (match_operand:SI 1 "register_operand" "r")) | |
c4ce6853 | 9295 | (set (reg:CC 100) |
7a768814 RS |
9296 | (compare:CC (match_operand:SI 2 "register_operand" "r") |
9297 | (const_int 0)))] | |
72f4648e JW |
9298 | "(rtx_equal_p (operands[2], operands[0]) |
9299 | || rtx_equal_p (operands[2], operands[1])) | |
e0d80184 DM |
9300 | && ! FP_REG_P (operands[0]) |
9301 | && ! FP_REG_P (operands[1])" | |
9302 | "orcc\\t%1, 0, %0") | |
7a768814 | 9303 | |
a8d2b752 DE |
9304 | (define_peephole |
9305 | [(set (match_operand:DI 0 "register_operand" "=r") | |
9306 | (match_operand:DI 1 "register_operand" "r")) | |
c4ce6853 | 9307 | (set (reg:CCX 100) |
a8d2b752 DE |
9308 | (compare:CCX (match_operand:DI 2 "register_operand" "r") |
9309 | (const_int 0)))] | |
fa0f39e4 | 9310 | "TARGET_ARCH64 |
a8d2b752 DE |
9311 | && (rtx_equal_p (operands[2], operands[0]) |
9312 | || rtx_equal_p (operands[2], operands[1])) | |
e0d80184 DM |
9313 | && ! FP_REG_P (operands[0]) |
9314 | && ! FP_REG_P (operands[1])" | |
9315 | "orcc\\t%1, 0, %0") | |
7a768814 | 9316 | |
c4ce6853 DE |
9317 | ;; Return peepholes. First the "normal" ones. |
9318 | ;; These are necessary to catch insns ending up in the epilogue delay list. | |
262121f0 | 9319 | |
c8b3b7d6 | 9320 | (define_insn "*return_qi" |
262121f0 JW |
9321 | [(set (match_operand:QI 0 "restore_operand" "") |
9322 | (match_operand:QI 1 "arith_operand" "rI")) | |
9323 | (return)] | |
e6c1be7e | 9324 | "! TARGET_EPILOGUE" |
262121f0 JW |
9325 | "* |
9326 | { | |
fa0f39e4 | 9327 | if (! TARGET_ARCH64 && current_function_returns_struct) |
e0d80184 | 9328 | return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\"; |
284d86e9 JC |
9329 | else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT |
9330 | || IN_OR_GLOBAL_P (operands[1]))) | |
e0d80184 | 9331 | return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; |
262121f0 | 9332 | else |
e0d80184 | 9333 | return \"ret\\n\\trestore %%g0, %1, %Y0\"; |
262121f0 JW |
9334 | }" |
9335 | [(set_attr "type" "multi")]) | |
9336 | ||
c8b3b7d6 | 9337 | (define_insn "*return_hi" |
262121f0 JW |
9338 | [(set (match_operand:HI 0 "restore_operand" "") |
9339 | (match_operand:HI 1 "arith_operand" "rI")) | |
9340 | (return)] | |
e6c1be7e | 9341 | "! TARGET_EPILOGUE" |
262121f0 JW |
9342 | "* |
9343 | { | |
fa0f39e4 | 9344 | if (! TARGET_ARCH64 && current_function_returns_struct) |
e0d80184 | 9345 | return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\"; |
284d86e9 JC |
9346 | else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT |
9347 | || IN_OR_GLOBAL_P (operands[1]))) | |
e0d80184 | 9348 | return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; |
262121f0 | 9349 | else |
e0d80184 | 9350 | return \"ret\;restore %%g0, %1, %Y0\"; |
262121f0 JW |
9351 | }" |
9352 | [(set_attr "type" "multi")]) | |
9353 | ||
c8b3b7d6 | 9354 | (define_insn "*return_si" |
7a768814 RS |
9355 | [(set (match_operand:SI 0 "restore_operand" "") |
9356 | (match_operand:SI 1 "arith_operand" "rI")) | |
9357 | (return)] | |
e6c1be7e | 9358 | "! TARGET_EPILOGUE" |
7a768814 RS |
9359 | "* |
9360 | { | |
fa0f39e4 | 9361 | if (! TARGET_ARCH64 && current_function_returns_struct) |
e0d80184 | 9362 | return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\"; |
284d86e9 JC |
9363 | else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT |
9364 | || IN_OR_GLOBAL_P (operands[1]))) | |
e0d80184 | 9365 | return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; |
7a768814 | 9366 | else |
e0d80184 | 9367 | return \"ret\;restore %%g0, %1, %Y0\"; |
7a768814 RS |
9368 | }" |
9369 | [(set_attr "type" "multi")]) | |
9370 | ||
ab5519b7 | 9371 | ;; The following pattern is only generated by delayed-branch scheduling, |
e0d80184 DM |
9372 | ;; when the insn winds up in the epilogue. This can happen not only when |
9373 | ;; ! TARGET_FPU because we move complex types around by parts using | |
9374 | ;; SF mode SUBREGs. | |
c8b3b7d6 | 9375 | (define_insn "*return_sf_no_fpu" |
db7eb3e8 | 9376 | [(set (match_operand:SF 0 "restore_operand" "=r") |
ab5519b7 JW |
9377 | (match_operand:SF 1 "register_operand" "r")) |
9378 | (return)] | |
e6c1be7e | 9379 | "! TARGET_EPILOGUE" |
ab5519b7 JW |
9380 | "* |
9381 | { | |
fa0f39e4 | 9382 | if (! TARGET_ARCH64 && current_function_returns_struct) |
e0d80184 | 9383 | return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\"; |
284d86e9 | 9384 | else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])) |
e0d80184 | 9385 | return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; |
ab5519b7 | 9386 | else |
e0d80184 | 9387 | return \"ret\;restore %%g0, %1, %Y0\"; |
ab5519b7 JW |
9388 | }" |
9389 | [(set_attr "type" "multi")]) | |
9390 | ||
e6c1be7e JJ |
9391 | (define_insn "*return_df_no_fpu" |
9392 | [(set (match_operand:DF 0 "restore_operand" "=r") | |
9393 | (match_operand:DF 1 "register_operand" "r")) | |
9394 | (return)] | |
9395 | "! TARGET_EPILOGUE && TARGET_ARCH64" | |
9396 | "* | |
9397 | { | |
9398 | if (IN_OR_GLOBAL_P (operands[1])) | |
9399 | return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; | |
9400 | else | |
9401 | return \"ret\;restore %%g0, %1, %Y0\"; | |
9402 | }" | |
9403 | [(set_attr "type" "multi")]) | |
9404 | ||
c8b3b7d6 | 9405 | (define_insn "*return_addsi" |
7a768814 | 9406 | [(set (match_operand:SI 0 "restore_operand" "") |
284d86e9 | 9407 | (plus:SI (match_operand:SI 1 "register_operand" "r") |
7a768814 RS |
9408 | (match_operand:SI 2 "arith_operand" "rI"))) |
9409 | (return)] | |
e6c1be7e | 9410 | "! TARGET_EPILOGUE" |
7a768814 RS |
9411 | "* |
9412 | { | |
fa0f39e4 | 9413 | if (! TARGET_ARCH64 && current_function_returns_struct) |
e0d80184 | 9414 | return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\"; |
284d86e9 JC |
9415 | /* If operands are global or in registers, can use return */ |
9416 | else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]) | |
9417 | && (GET_CODE (operands[2]) == CONST_INT | |
9418 | || IN_OR_GLOBAL_P (operands[2]))) | |
e0d80184 | 9419 | return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\"; |
7a768814 | 9420 | else |
e0d80184 | 9421 | return \"ret\;restore %r1, %2, %Y0\"; |
7a768814 RS |
9422 | }" |
9423 | [(set_attr "type" "multi")]) | |
9424 | ||
e48addee JJ |
9425 | (define_insn "*return_losum_si" |
9426 | [(set (match_operand:SI 0 "restore_operand" "") | |
9427 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
9428 | (match_operand:SI 2 "immediate_operand" "in"))) | |
9429 | (return)] | |
e6c1be7e | 9430 | "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID" |
e48addee JJ |
9431 | "* |
9432 | { | |
9433 | if (! TARGET_ARCH64 && current_function_returns_struct) | |
9434 | return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\"; | |
9435 | /* If operands are global or in registers, can use return */ | |
9436 | else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])) | |
9437 | return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\"; | |
9438 | else | |
9439 | return \"ret\;restore %r1, %%lo(%a2), %Y0\"; | |
9440 | }" | |
9441 | [(set_attr "type" "multi")]) | |
9442 | ||
c8b3b7d6 | 9443 | (define_insn "*return_di" |
a8d2b752 DE |
9444 | [(set (match_operand:DI 0 "restore_operand" "") |
9445 | (match_operand:DI 1 "arith_double_operand" "rHI")) | |
9446 | (return)] | |
fa0f39e4 | 9447 | "TARGET_ARCH64 && ! TARGET_EPILOGUE" |
e0d80184 | 9448 | "ret\;restore %%g0, %1, %Y0" |
a8d2b752 DE |
9449 | [(set_attr "type" "multi")]) |
9450 | ||
c8b3b7d6 | 9451 | (define_insn "*return_adddi" |
a8d2b752 | 9452 | [(set (match_operand:DI 0 "restore_operand" "") |
bfd6bc60 | 9453 | (plus:DI (match_operand:DI 1 "arith_operand" "%r") |
a8d2b752 DE |
9454 | (match_operand:DI 2 "arith_double_operand" "rHI"))) |
9455 | (return)] | |
bfd6bc60 | 9456 | "TARGET_ARCH64 && ! TARGET_EPILOGUE" |
e0d80184 | 9457 | "ret\;restore %r1, %2, %Y0" |
a8d2b752 DE |
9458 | [(set_attr "type" "multi")]) |
9459 | ||
e48addee JJ |
9460 | (define_insn "*return_losum_di" |
9461 | [(set (match_operand:DI 0 "restore_operand" "") | |
9462 | (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r") | |
9463 | (match_operand:DI 2 "immediate_operand" "in"))) | |
9464 | (return)] | |
9465 | "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID" | |
3a2ea093 | 9466 | "ret\;restore %r1, %%lo(%a2), %Y0" |
e48addee JJ |
9467 | [(set_attr "type" "multi")]) |
9468 | ||
7a768814 RS |
9469 | ;; The following pattern is only generated by delayed-branch scheduling, |
9470 | ;; when the insn winds up in the epilogue. | |
c8b3b7d6 | 9471 | (define_insn "*return_sf" |
7a768814 RS |
9472 | [(set (reg:SF 32) |
9473 | (match_operand:SF 0 "register_operand" "f")) | |
9474 | (return)] | |
9475 | "! TARGET_EPILOGUE" | |
e0d80184 | 9476 | "ret\;fmovs\\t%0, %%f0" |
b4ac57ab | 9477 | [(set_attr "type" "multi")]) |
7a768814 | 9478 | |
a8d2b752 | 9479 | ;; Now peepholes to do a call followed by a jump. |
7a768814 RS |
9480 | |
9481 | (define_peephole | |
9482 | [(parallel [(set (match_operand 0 "" "") | |
2c435002 | 9483 | (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps")) |
7a768814 RS |
9484 | (match_operand 2 "" ""))) |
9485 | (clobber (reg:SI 15))]) | |
9486 | (set (pc) (label_ref (match_operand 3 "" "")))] | |
e0d80184 | 9487 | "short_branch (INSN_UID (insn), INSN_UID (operands[3])) |
1150a841 | 9488 | && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))" |
e0d80184 | 9489 | "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7") |
7a768814 RS |
9490 | |
9491 | (define_peephole | |
2c435002 | 9492 | [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps")) |
7a768814 RS |
9493 | (match_operand 1 "" "")) |
9494 | (clobber (reg:SI 15))]) | |
9495 | (set (pc) (label_ref (match_operand 2 "" "")))] | |
e0d80184 | 9496 | "short_branch (INSN_UID (insn), INSN_UID (operands[2])) |
1150a841 | 9497 | && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))" |
e0d80184 | 9498 | "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7") |
7a768814 | 9499 | |
a8d2b752 DE |
9500 | (define_peephole |
9501 | [(parallel [(set (match_operand 0 "" "") | |
2c435002 | 9502 | (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps")) |
a8d2b752 DE |
9503 | (match_operand 2 "" ""))) |
9504 | (clobber (reg:DI 15))]) | |
9505 | (set (pc) (label_ref (match_operand 3 "" "")))] | |
e0d80184 DM |
9506 | "TARGET_ARCH64 |
9507 | && short_branch (INSN_UID (insn), INSN_UID (operands[3])) | |
1150a841 | 9508 | && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))" |
e0d80184 | 9509 | "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7") |
a8d2b752 DE |
9510 | |
9511 | (define_peephole | |
2c435002 | 9512 | [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps")) |
a8d2b752 DE |
9513 | (match_operand 1 "" "")) |
9514 | (clobber (reg:DI 15))]) | |
9515 | (set (pc) (label_ref (match_operand 2 "" "")))] | |
e0d80184 DM |
9516 | "TARGET_ARCH64 |
9517 | && short_branch (INSN_UID (insn), INSN_UID (operands[2])) | |
1150a841 | 9518 | && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))" |
e0d80184 | 9519 | "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7") |
fccf9848 JJ |
9520 | \f |
9521 | (define_expand "prologue" | |
9522 | [(const_int 1)] | |
9523 | "flag_pic && current_function_uses_pic_offset_table" | |
9524 | " | |
9525 | { | |
9526 | load_pic_register (); | |
9527 | DONE; | |
9528 | }") | |
a8d2b752 | 9529 | |
fccf9848 JJ |
9530 | ;; We need to reload %l7 for -mflat -fpic, |
9531 | ;; otherwise %l7 should be preserved simply | |
9532 | ;; by loading the function's register window | |
9533 | (define_expand "exception_receiver" | |
9534 | [(const_int 0)] | |
9535 | "TARGET_FLAT && flag_pic" | |
9536 | " | |
9537 | { | |
9538 | load_pic_register (); | |
9539 | DONE; | |
9540 | }") | |
c85f7c16 | 9541 | |
fccf9848 JJ |
9542 | ;; Likewise |
9543 | (define_expand "builtin_setjmp_receiver" | |
9544 | [(label_ref (match_operand 0 "" ""))] | |
9545 | "TARGET_FLAT && flag_pic" | |
9546 | " | |
9547 | { | |
9548 | load_pic_register (); | |
9549 | DONE; | |
9550 | }") | |
e0cd0770 JC |
9551 | \f |
9552 | (define_insn "trap" | |
9553 | [(trap_if (const_int 1) (const_int 5))] | |
9554 | "" | |
e0d80184 | 9555 | "ta\\t5" |
3bc8b61e DM |
9556 | [(set_attr "type" "misc") |
9557 | (set_attr "length" "1")]) | |
e0cd0770 JC |
9558 | |
9559 | (define_expand "conditional_trap" | |
9560 | [(trap_if (match_operator 0 "noov_compare_op" | |
9561 | [(match_dup 2) (match_dup 3)]) | |
9562 | (match_operand:SI 1 "arith_operand" ""))] | |
9563 | "" | |
9564 | "operands[2] = gen_compare_reg (GET_CODE (operands[0]), | |
9565 | sparc_compare_op0, sparc_compare_op1); | |
9566 | operands[3] = const0_rtx;") | |
9567 | ||
9568 | (define_insn "" | |
9569 | [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)]) | |
9570 | (match_operand:SI 1 "arith_operand" "rM"))] | |
9571 | "" | |
e0d80184 | 9572 | "t%C0\\t%1" |
3bc8b61e DM |
9573 | [(set_attr "type" "misc") |
9574 | (set_attr "length" "1")]) | |
e0cd0770 JC |
9575 | |
9576 | (define_insn "" | |
9577 | [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)]) | |
9578 | (match_operand:SI 1 "arith_operand" "rM"))] | |
9579 | "TARGET_V9" | |
e0d80184 | 9580 | "t%C0\\t%%xcc, %1" |
3bc8b61e DM |
9581 | [(set_attr "type" "misc") |
9582 | (set_attr "length" "1")]) |