]>
Commit | Line | Data |
---|---|---|
9d234535 | 1 | ;; Machine description for SPARC chip for GCC |
3aea1f79 | 2 | ;; Copyright (C) 1987-2014 Free Software Foundation, Inc. |
4ad4584d | 3 | ;; Contributed by Michael Tiemann (tiemann@cygnus.com) |
0daea6cd | 4 | ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, |
4ad4584d | 5 | ;; at Cygnus Support. |
a44201ea | 6 | |
9d234535 | 7 | ;; This file is part of GCC. |
a44201ea | 8 | |
9d234535 | 9 | ;; GCC is free software; you can redistribute it and/or modify |
a44201ea | 10 | ;; it under the terms of the GNU General Public License as published by |
038d1e19 | 11 | ;; the Free Software Foundation; either version 3, or (at your option) |
a44201ea | 12 | ;; any later version. |
13 | ||
9d234535 | 14 | ;; GCC is distributed in the hope that it will be useful, |
a44201ea | 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | ;; GNU General Public License for more details. | |
18 | ||
19 | ;; You should have received a copy of the GNU General Public License | |
038d1e19 | 20 | ;; along with GCC; see the file COPYING3. If not see |
21 | ;; <http://www.gnu.org/licenses/>. | |
a44201ea | 22 | |
a44201ea | 23 | ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. |
24 | ||
6ef7d725 | 25 | (define_c_enum "unspec" [ |
26 | UNSPEC_MOVE_PIC | |
27 | UNSPEC_UPDATE_RETURN | |
28 | UNSPEC_LOAD_PCREL_SYM | |
29 | UNSPEC_FRAME_BLOCKAGE | |
30 | UNSPEC_MOVE_PIC_LABEL | |
31 | UNSPEC_SETH44 | |
32 | UNSPEC_SETM44 | |
33 | UNSPEC_SETHH | |
34 | UNSPEC_SETLM | |
35 | UNSPEC_EMB_HISUM | |
36 | UNSPEC_EMB_TEXTUHI | |
37 | UNSPEC_EMB_TEXTHI | |
38 | UNSPEC_EMB_TEXTULO | |
39 | UNSPEC_EMB_SETHM | |
40 | UNSPEC_MOVE_GOTDATA | |
05b3a83f | 41 | |
6ef7d725 | 42 | UNSPEC_MEMBAR |
43 | UNSPEC_ATOMIC | |
dc178856 | 44 | |
6ef7d725 | 45 | UNSPEC_TLSGD |
46 | UNSPEC_TLSLDM | |
47 | UNSPEC_TLSLDO | |
48 | UNSPEC_TLSIE | |
49 | UNSPEC_TLSLE | |
50 | UNSPEC_TLSLD_BASE | |
5e8cda9b | 51 | |
6ef7d725 | 52 | UNSPEC_FPACK16 |
53 | UNSPEC_FPACK32 | |
54 | UNSPEC_FPACKFIX | |
55 | UNSPEC_FEXPAND | |
56 | UNSPEC_MUL16AU | |
57 | UNSPEC_MUL16AL | |
58 | UNSPEC_MUL8UL | |
59 | UNSPEC_MULDUL | |
60 | UNSPEC_ALIGNDATA | |
61 | UNSPEC_FCMP | |
62 | UNSPEC_PDIST | |
63 | UNSPEC_EDGE8 | |
64 | UNSPEC_EDGE8L | |
65 | UNSPEC_EDGE16 | |
66 | UNSPEC_EDGE16L | |
67 | UNSPEC_EDGE32 | |
68 | UNSPEC_EDGE32L | |
69 | UNSPEC_ARRAY8 | |
70 | UNSPEC_ARRAY16 | |
71 | UNSPEC_ARRAY32 | |
fc5cceaf | 72 | |
6ef7d725 | 73 | UNSPEC_SP_SET |
74 | UNSPEC_SP_TEST | |
95c09f2c | 75 | |
6ef7d725 | 76 | UNSPEC_EDGE8N |
77 | UNSPEC_EDGE8LN | |
78 | UNSPEC_EDGE16N | |
79 | UNSPEC_EDGE16LN | |
80 | UNSPEC_EDGE32N | |
81 | UNSPEC_EDGE32LN | |
82 | UNSPEC_BSHUFFLE | |
83 | UNSPEC_CMASK8 | |
84 | UNSPEC_CMASK16 | |
85 | UNSPEC_CMASK32 | |
86 | UNSPEC_FCHKSM16 | |
87 | UNSPEC_PDISTN | |
88 | UNSPEC_FUCMP | |
89 | UNSPEC_FHADD | |
90 | UNSPEC_FHSUB | |
91 | UNSPEC_XMUL | |
92 | UNSPEC_MUL8 | |
93 | UNSPEC_MUL8SU | |
94 | UNSPEC_MULDSU | |
95 | ]) | |
40cc626c | 96 | |
6ef7d725 | 97 | (define_c_enum "unspecv" [ |
98 | UNSPECV_BLOCKAGE | |
d0e8b42e | 99 | UNSPECV_PROBE_STACK_RANGE |
100 | ||
6ef7d725 | 101 | UNSPECV_FLUSHW |
6ef7d725 | 102 | UNSPECV_SAVEW |
d0e8b42e | 103 | |
104 | UNSPECV_FLUSH | |
105 | ||
6ef7d725 | 106 | UNSPECV_LDSTUB |
d0e8b42e | 107 | UNSPECV_SWAP |
108 | UNSPECV_CAS | |
109 | ||
110 | UNSPECV_LDFSR | |
111 | UNSPECV_STFSR | |
6ef7d725 | 112 | ]) |
998032ba | 113 | |
2b25173f | 114 | (define_constants |
115 | [(G0_REG 0) | |
116 | (G1_REG 1) | |
117 | (G2_REG 2) | |
118 | (G3_REG 3) | |
119 | (G4_REG 4) | |
120 | (G5_REG 5) | |
121 | (G6_REG 6) | |
122 | (G7_REG 7) | |
123 | (O0_REG 8) | |
124 | (O1_REG 9) | |
125 | (O2_REG 10) | |
126 | (O3_REG 11) | |
127 | (O4_REG 12) | |
128 | (O5_REG 13) | |
129 | (O6_REG 14) | |
130 | (O7_REG 15) | |
131 | (L0_REG 16) | |
132 | (L1_REG 17) | |
133 | (L2_REG 18) | |
134 | (L3_REG 19) | |
135 | (L4_REG 20) | |
136 | (L5_REG 21) | |
137 | (L6_REG 22) | |
138 | (L7_REG 23) | |
139 | (I0_REG 24) | |
140 | (I1_REG 25) | |
141 | (I2_REG 26) | |
142 | (I3_REG 27) | |
143 | (I4_REG 28) | |
144 | (I5_REG 29) | |
145 | (I6_REG 30) | |
146 | (I7_REG 31) | |
147 | (F0_REG 32) | |
148 | (F1_REG 33) | |
149 | (F2_REG 34) | |
150 | (F3_REG 35) | |
151 | (F4_REG 36) | |
152 | (F5_REG 37) | |
153 | (F6_REG 38) | |
154 | (F7_REG 39) | |
155 | (F8_REG 40) | |
156 | (F9_REG 41) | |
157 | (F10_REG 42) | |
158 | (F11_REG 43) | |
159 | (F12_REG 44) | |
160 | (F13_REG 45) | |
161 | (F14_REG 46) | |
162 | (F15_REG 47) | |
163 | (F16_REG 48) | |
164 | (F17_REG 49) | |
165 | (F18_REG 50) | |
166 | (F19_REG 51) | |
167 | (F20_REG 52) | |
168 | (F21_REG 53) | |
169 | (F22_REG 54) | |
170 | (F23_REG 55) | |
171 | (F24_REG 56) | |
172 | (F25_REG 57) | |
173 | (F26_REG 58) | |
174 | (F27_REG 59) | |
175 | (F28_REG 60) | |
176 | (F29_REG 61) | |
177 | (F30_REG 62) | |
178 | (F31_REG 63) | |
179 | (F32_REG 64) | |
180 | (F34_REG 66) | |
181 | (F36_REG 68) | |
182 | (F38_REG 70) | |
183 | (F40_REG 72) | |
184 | (F42_REG 74) | |
185 | (F44_REG 76) | |
186 | (F46_REG 78) | |
187 | (F48_REG 80) | |
188 | (F50_REG 82) | |
189 | (F52_REG 84) | |
190 | (F54_REG 86) | |
191 | (F56_REG 88) | |
192 | (F58_REG 90) | |
193 | (F60_REG 92) | |
194 | (F62_REG 94) | |
195 | (FCC0_REG 96) | |
196 | (FCC1_REG 97) | |
197 | (FCC2_REG 98) | |
198 | (FCC3_REG 99) | |
199 | (CC_REG 100) | |
200 | (SFP_REG 101) | |
b011bbe2 | 201 | (GSR_REG 102) |
2b25173f | 202 | ]) |
74f4459c | 203 | |
204 | (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) | |
205 | (define_mode_iterator I [QI HI SI DI]) | |
206 | (define_mode_iterator F [SF DF TF]) | |
207 | ||
65ccdc13 | 208 | ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this |
209 | ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name | |
210 | ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding | |
211 | ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of | |
212 | ;; 'f' for all DF/TFmode values, including those that are specific to the v8. | |
213 | ||
7fa91985 | 214 | ;; Attribute for cpu type. |
191a0bb7 | 215 | ;; These must match the values of the enum processor_type in sparc-opts.h. |
e30b7bae | 216 | (define_attr "cpu" |
217 | "v7, | |
218 | cypress, | |
219 | v8, | |
220 | supersparc, | |
b0168e11 | 221 | hypersparc, |
222 | leon, | |
191a0bb7 | 223 | leon3, |
14091821 | 224 | leon3v7, |
b0168e11 | 225 | sparclite, |
226 | f930, | |
227 | f934, | |
228 | sparclite86x, | |
229 | sparclet, | |
230 | tsc701, | |
e30b7bae | 231 | v9, |
232 | ultrasparc, | |
6dbce0cb | 233 | ultrasparc3, |
d6ecc3a3 | 234 | niagara, |
3407e51d | 235 | niagara2, |
236 | niagara3, | |
237 | niagara4" | |
c187ce15 | 238 | (const (symbol_ref "sparc_cpu_attr"))) |
7fa91985 | 239 | |
d49f4f09 | 240 | ;; Attribute for the instruction set. |
241 | ;; At present we only need to distinguish v9/!v9, but for clarity we | |
242 | ;; test TARGET_V8 too. | |
aa49c7dd | 243 | (define_attr "isa" "v7,v8,v9,sparclet" |
d49f4f09 | 244 | (const |
245 | (cond [(symbol_ref "TARGET_V9") (const_string "v9") | |
0f925e9c | 246 | (symbol_ref "TARGET_V8") (const_string "v8") |
247 | (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")] | |
aa49c7dd | 248 | (const_string "v7")))) |
d49f4f09 | 249 | |
4aa70596 | 250 | (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none")) |
251 | ||
252 | (define_attr "enabled" "" | |
253 | (cond [(eq_attr "cpu_feature" "none") (const_int 1) | |
254 | (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU") | |
255 | (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9") | |
256 | (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9") | |
257 | (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS") | |
258 | (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")] | |
259 | (const_int 0))) | |
260 | ||
2ce8757a | 261 | ;; Insn type. |
a44201ea | 262 | (define_attr "type" |
e30b7bae | 263 | "ialu,compare,shift, |
264 | load,sload,store, | |
f317b732 | 265 | uncond_branch,branch,call,sibcall,call_no_delay_slot,return, |
6c940e8d | 266 | cbcond,uncond_cbcond, |
e30b7bae | 267 | imul,idiv, |
268 | fpload,fpstore, | |
269 | fp,fpmove, | |
270 | fpcmove,fpcrmove, | |
271 | fpcmp, | |
272 | fpmul,fpdivs,fpdivd, | |
273 | fpsqrts,fpsqrtd, | |
d3cb8b93 | 274 | fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array, |
e30b7bae | 275 | cmove, |
276 | ialuX, | |
f317b732 | 277 | multi,savew,flushw,iflush,trap" |
2ce8757a | 278 | (const_string "ialu")) |
a44201ea | 279 | |
e8d33c3a | 280 | ;; True if branch/call has empty delay slot and will emit a nop in it |
258103e3 | 281 | (define_attr "empty_delay_slot" "false,true" |
bc620c5c | 282 | (symbol_ref "(empty_delay_slot (insn) |
283 | ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)")) | |
258103e3 | 284 | |
6c940e8d | 285 | ;; True if we are making use of compare-and-branch instructions. |
286 | ;; True if we should emit a nop after a cbcond instruction | |
287 | (define_attr "emit_cbcond_nop" "false,true" | |
288 | (symbol_ref "(emit_cbcond_nop (insn) | |
289 | ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)")) | |
290 | ||
e8d33c3a | 291 | (define_attr "branch_type" "none,icc,fcc,reg" |
292 | (const_string "none")) | |
258103e3 | 293 | |
02b9b9f1 | 294 | (define_attr "pic" "false,true" |
6b5f7be2 | 295 | (symbol_ref "(flag_pic != 0 |
296 | ? PIC_TRUE : PIC_FALSE)")) | |
02b9b9f1 | 297 | |
e8d33c3a | 298 | (define_attr "calls_alloca" "false,true" |
bc620c5c | 299 | (symbol_ref "(cfun->calls_alloca != 0 |
300 | ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)")) | |
31d3e01c | 301 | |
e8d33c3a | 302 | (define_attr "calls_eh_return" "false,true" |
bc620c5c | 303 | (symbol_ref "(crtl->calls_eh_return != 0 |
304 | ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)")) | |
47529489 | 305 | |
e8d33c3a | 306 | (define_attr "leaf_function" "false,true" |
d5bf7b64 | 307 | (symbol_ref "(crtl->uses_only_leaf_regs != 0 |
bc620c5c | 308 | ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)")) |
e8d33c3a | 309 | |
d35f187f | 310 | (define_attr "delayed_branch" "false,true" |
bc620c5c | 311 | (symbol_ref "(flag_delayed_branch != 0 |
312 | ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)")) | |
d35f187f | 313 | |
47529489 | 314 | (define_attr "flat" "false,true" |
315 | (symbol_ref "(TARGET_FLAT != 0 | |
316 | ? FLAT_TRUE : FLAT_FALSE)")) | |
317 | ||
6b5f7be2 | 318 | (define_attr "fix_ut699" "false,true" |
319 | (symbol_ref "(sparc_fix_ut699 != 0 | |
320 | ? FIX_UT699_TRUE : FIX_UT699_FALSE)")) | |
321 | ||
a44201ea | 322 | ;; Length (in # of insns). |
370abbd6 | 323 | ;; Beware that setting a length greater or equal to 3 for conditional branches |
324 | ;; has a side-effect (see output_cbranch and output_v9branch). | |
258103e3 | 325 | (define_attr "length" "" |
e8d33c3a | 326 | (cond [(eq_attr "type" "uncond_branch,call") |
258103e3 | 327 | (if_then_else (eq_attr "empty_delay_slot" "true") |
328 | (const_int 2) | |
329 | (const_int 1)) | |
e8d33c3a | 330 | (eq_attr "type" "sibcall") |
331 | (if_then_else (eq_attr "leaf_function" "true") | |
332 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
333 | (const_int 3) | |
334 | (const_int 2)) | |
335 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
336 | (const_int 2) | |
337 | (const_int 1))) | |
258103e3 | 338 | (eq_attr "branch_type" "icc") |
27b36d57 | 339 | (if_then_else (match_operand 0 "noov_compare64_operator" "") |
258103e3 | 340 | (if_then_else (lt (pc) (match_dup 1)) |
341 | (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000)) | |
342 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
343 | (const_int 2) | |
344 | (const_int 1)) | |
345 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
346 | (const_int 4) | |
347 | (const_int 3))) | |
348 | (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000)) | |
349 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
350 | (const_int 2) | |
351 | (const_int 1)) | |
352 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
353 | (const_int 4) | |
354 | (const_int 3)))) | |
355 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
356 | (const_int 2) | |
357 | (const_int 1))) | |
358 | (eq_attr "branch_type" "fcc") | |
27b36d57 | 359 | (if_then_else (match_operand 0 "fcc0_register_operand" "") |
258103e3 | 360 | (if_then_else (eq_attr "empty_delay_slot" "true") |
9f608b27 | 361 | (if_then_else (not (match_test "TARGET_V9")) |
dd1585fc | 362 | (const_int 3) |
363 | (const_int 2)) | |
9f608b27 | 364 | (if_then_else (not (match_test "TARGET_V9")) |
dd1585fc | 365 | (const_int 2) |
366 | (const_int 1))) | |
258103e3 | 367 | (if_then_else (lt (pc) (match_dup 2)) |
368 | (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000)) | |
369 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
370 | (const_int 2) | |
371 | (const_int 1)) | |
372 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
373 | (const_int 4) | |
374 | (const_int 3))) | |
375 | (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000)) | |
376 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
377 | (const_int 2) | |
378 | (const_int 1)) | |
379 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
380 | (const_int 4) | |
381 | (const_int 3))))) | |
382 | (eq_attr "branch_type" "reg") | |
383 | (if_then_else (lt (pc) (match_dup 2)) | |
384 | (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000)) | |
385 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
386 | (const_int 2) | |
387 | (const_int 1)) | |
388 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
389 | (const_int 4) | |
390 | (const_int 3))) | |
391 | (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000)) | |
392 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
393 | (const_int 2) | |
394 | (const_int 1)) | |
395 | (if_then_else (eq_attr "empty_delay_slot" "true") | |
396 | (const_int 4) | |
397 | (const_int 3)))) | |
6c940e8d | 398 | (eq_attr "type" "cbcond") |
399 | (if_then_else (lt (pc) (match_dup 3)) | |
400 | (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500)) | |
401 | (if_then_else (eq_attr "emit_cbcond_nop" "true") | |
402 | (const_int 2) | |
403 | (const_int 1)) | |
404 | (const_int 4)) | |
405 | (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500)) | |
406 | (if_then_else (eq_attr "emit_cbcond_nop" "true") | |
407 | (const_int 2) | |
408 | (const_int 1)) | |
409 | (const_int 4))) | |
410 | (eq_attr "type" "uncond_cbcond") | |
411 | (if_then_else (lt (pc) (match_dup 0)) | |
412 | (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500)) | |
413 | (if_then_else (eq_attr "emit_cbcond_nop" "true") | |
414 | (const_int 2) | |
415 | (const_int 1)) | |
416 | (const_int 1)) | |
417 | (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500)) | |
418 | (if_then_else (eq_attr "emit_cbcond_nop" "true") | |
419 | (const_int 2) | |
420 | (const_int 1)) | |
421 | (const_int 1))) | |
258103e3 | 422 | ] (const_int 1))) |
a44201ea | 423 | |
a9208abf | 424 | ;; FP precision. |
e8d33c3a | 425 | (define_attr "fptype" "single,double" |
426 | (const_string "single")) | |
a44201ea | 427 | |
07ae93ca | 428 | ;; FP precision specific to the UT699. |
429 | (define_attr "fptype_ut699" "none,single" | |
430 | (const_string "none")) | |
431 | ||
bea4bad2 | 432 | ;; UltraSPARC-III integer load type. |
e8d33c3a | 433 | (define_attr "us3load_type" "2cycle,3cycle" |
434 | (const_string "2cycle")) | |
bea4bad2 | 435 | |
a44201ea | 436 | (define_asm_attributes |
a9208abf | 437 | [(set_attr "length" "2") |
a44201ea | 438 | (set_attr "type" "multi")]) |
439 | ||
6b5f7be2 | 440 | ;; Attributes for branch scheduling |
a44201ea | 441 | (define_attr "in_call_delay" "false,true" |
6b5f7be2 | 442 | (symbol_ref "(eligible_for_call_delay (insn) |
443 | ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)")) | |
444 | ||
445 | (define_attr "in_sibcall_delay" "false,true" | |
bc620c5c | 446 | (symbol_ref "(eligible_for_sibcall_delay (insn) |
6b5f7be2 | 447 | ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)")) |
7a8d641b | 448 | |
6b5f7be2 | 449 | (define_attr "in_return_delay" "false,true" |
bc620c5c | 450 | (symbol_ref "(eligible_for_return_delay (insn) |
6b5f7be2 | 451 | ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)")) |
367242d3 | 452 | |
f317b732 | 453 | ;; ??? !v9: Should implement the notion of predelay slots for floating-point |
a44201ea | 454 | ;; branches. This would allow us to remove the nop always inserted before |
455 | ;; a floating point branch. | |
456 | ||
50d93d69 | 457 | ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions |
458 | ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so. | |
459 | ;; This is because doing so will add several pipeline stalls to the path | |
460 | ;; that the load/store did not come from. Unfortunately, there is no way | |
461 | ;; to prevent fill_eager_delay_slots from using load/store without completely | |
462 | ;; disabling them. For the SPEC benchmark set, this is a serious lose, | |
463 | ;; because it prevents us from moving back the final store of inner loops. | |
74848118 | 464 | |
a44201ea | 465 | (define_attr "in_branch_delay" "false,true" |
6b5f7be2 | 466 | (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi") |
467 | (const_string "false") | |
468 | (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload")) | |
469 | (const_string "false") | |
c495d615 | 470 | (and (eq_attr "fix_ut699" "true") |
471 | (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts") | |
07ae93ca | 472 | (ior (eq_attr "fptype" "single") |
473 | (eq_attr "fptype_ut699" "single")))) | |
c495d615 | 474 | (const_string "false") |
6b5f7be2 | 475 | (eq_attr "length" "1") |
476 | (const_string "true") | |
477 | ] (const_string "false"))) | |
a44201ea | 478 | |
f317b732 | 479 | (define_delay (eq_attr "type" "call") |
480 | [(eq_attr "in_call_delay" "true") (nil) (nil)]) | |
481 | ||
482 | (define_delay (eq_attr "type" "sibcall") | |
6b5f7be2 | 483 | [(eq_attr "in_sibcall_delay" "true") (nil) (nil)]) |
484 | ||
485 | (define_delay (eq_attr "type" "return") | |
486 | [(eq_attr "in_return_delay" "true") (nil) (nil)]) | |
f317b732 | 487 | |
a44201ea | 488 | (define_delay (eq_attr "type" "branch") |
6b5f7be2 | 489 | [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")]) |
a44201ea | 490 | |
74848118 | 491 | (define_delay (eq_attr "type" "uncond_branch") |
6b5f7be2 | 492 | [(eq_attr "in_branch_delay" "true") (nil) (nil)]) |
f317b732 | 493 | |
d88ab5ca | 494 | |
aa5841a8 | 495 | ;; Include SPARC DFA schedulers |
496 | ||
497 | (include "cypress.md") | |
498 | (include "supersparc.md") | |
499 | (include "hypersparc.md") | |
b0168e11 | 500 | (include "leon.md") |
aa5841a8 | 501 | (include "sparclet.md") |
502 | (include "ultra1_2.md") | |
503 | (include "ultra3.md") | |
6dbce0cb | 504 | (include "niagara.md") |
d6ecc3a3 | 505 | (include "niagara2.md") |
65e00a51 | 506 | (include "niagara4.md") |
bea4bad2 | 507 | |
d88ab5ca | 508 | |
187a5b29 | 509 | ;; Operand and operator predicates and constraints |
27b36d57 | 510 | |
511 | (include "predicates.md") | |
187a5b29 | 512 | (include "constraints.md") |
27b36d57 | 513 | |
514 | ||
a44201ea | 515 | ;; Compare instructions. |
a44201ea | 516 | |
74f4459c | 517 | ;; These are just the DEFINE_INSNs to match the patterns and the |
518 | ;; DEFINE_SPLITs for some of the scc insns that actually require | |
519 | ;; more than one machine instruction. DEFINE_EXPANDs are further down. | |
93fed860 | 520 | |
74f4459c | 521 | ;; The compare DEFINE_INSNs. |
93e2cd75 | 522 | |
35415df4 | 523 | (define_insn "*cmpsi_insn" |
2b25173f | 524 | [(set (reg:CC CC_REG) |
93e2cd75 | 525 | (compare:CC (match_operand:SI 0 "register_operand" "r") |
526 | (match_operand:SI 1 "arith_operand" "rI")))] | |
35415df4 | 527 | "" |
a4ddaca5 | 528 | "cmp\t%0, %1" |
93e2cd75 | 529 | [(set_attr "type" "compare")]) |
530 | ||
93e2cd75 | 531 | (define_insn "*cmpdi_sp64" |
2b25173f | 532 | [(set (reg:CCX CC_REG) |
93e2cd75 | 533 | (compare:CCX (match_operand:DI 0 "register_operand" "r") |
27b36d57 | 534 | (match_operand:DI 1 "arith_operand" "rI")))] |
93e2cd75 | 535 | "TARGET_ARCH64" |
a4ddaca5 | 536 | "cmp\t%0, %1" |
93e2cd75 | 537 | [(set_attr "type" "compare")]) |
538 | ||
946e12d1 | 539 | (define_insn "*cmpsf_fpe" |
27b36d57 | 540 | [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") |
93e2cd75 | 541 | (compare:CCFPE (match_operand:SF 1 "register_operand" "f") |
542 | (match_operand:SF 2 "register_operand" "f")))] | |
946e12d1 | 543 | "TARGET_FPU" |
946e12d1 | 544 | { |
545 | if (TARGET_V9) | |
a4ddaca5 | 546 | return "fcmpes\t%0, %1, %2"; |
547 | return "fcmpes\t%1, %2"; | |
0037630d | 548 | } |
93e2cd75 | 549 | [(set_attr "type" "fpcmp")]) |
550 | ||
946e12d1 | 551 | (define_insn "*cmpdf_fpe" |
27b36d57 | 552 | [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") |
93e2cd75 | 553 | (compare:CCFPE (match_operand:DF 1 "register_operand" "e") |
554 | (match_operand:DF 2 "register_operand" "e")))] | |
946e12d1 | 555 | "TARGET_FPU" |
946e12d1 | 556 | { |
557 | if (TARGET_V9) | |
a4ddaca5 | 558 | return "fcmped\t%0, %1, %2"; |
559 | return "fcmped\t%1, %2"; | |
0037630d | 560 | } |
a9208abf | 561 | [(set_attr "type" "fpcmp") |
562 | (set_attr "fptype" "double")]) | |
93e2cd75 | 563 | |
946e12d1 | 564 | (define_insn "*cmptf_fpe" |
27b36d57 | 565 | [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c") |
93e2cd75 | 566 | (compare:CCFPE (match_operand:TF 1 "register_operand" "e") |
567 | (match_operand:TF 2 "register_operand" "e")))] | |
946e12d1 | 568 | "TARGET_FPU && TARGET_HARD_QUAD" |
946e12d1 | 569 | { |
570 | if (TARGET_V9) | |
a4ddaca5 | 571 | return "fcmpeq\t%0, %1, %2"; |
572 | return "fcmpeq\t%1, %2"; | |
0037630d | 573 | } |
93e2cd75 | 574 | [(set_attr "type" "fpcmp")]) |
575 | ||
946e12d1 | 576 | (define_insn "*cmpsf_fp" |
27b36d57 | 577 | [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") |
93e2cd75 | 578 | (compare:CCFP (match_operand:SF 1 "register_operand" "f") |
579 | (match_operand:SF 2 "register_operand" "f")))] | |
946e12d1 | 580 | "TARGET_FPU" |
946e12d1 | 581 | { |
582 | if (TARGET_V9) | |
a4ddaca5 | 583 | return "fcmps\t%0, %1, %2"; |
584 | return "fcmps\t%1, %2"; | |
0037630d | 585 | } |
93e2cd75 | 586 | [(set_attr "type" "fpcmp")]) |
587 | ||
946e12d1 | 588 | (define_insn "*cmpdf_fp" |
27b36d57 | 589 | [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") |
93e2cd75 | 590 | (compare:CCFP (match_operand:DF 1 "register_operand" "e") |
591 | (match_operand:DF 2 "register_operand" "e")))] | |
946e12d1 | 592 | "TARGET_FPU" |
946e12d1 | 593 | { |
594 | if (TARGET_V9) | |
a4ddaca5 | 595 | return "fcmpd\t%0, %1, %2"; |
596 | return "fcmpd\t%1, %2"; | |
0037630d | 597 | } |
a9208abf | 598 | [(set_attr "type" "fpcmp") |
599 | (set_attr "fptype" "double")]) | |
93e2cd75 | 600 | |
946e12d1 | 601 | (define_insn "*cmptf_fp" |
27b36d57 | 602 | [(set (match_operand:CCFP 0 "fcc_register_operand" "=c") |
93e2cd75 | 603 | (compare:CCFP (match_operand:TF 1 "register_operand" "e") |
604 | (match_operand:TF 2 "register_operand" "e")))] | |
946e12d1 | 605 | "TARGET_FPU && TARGET_HARD_QUAD" |
946e12d1 | 606 | { |
607 | if (TARGET_V9) | |
a4ddaca5 | 608 | return "fcmpq\t%0, %1, %2"; |
609 | return "fcmpq\t%1, %2"; | |
0037630d | 610 | } |
93e2cd75 | 611 | [(set_attr "type" "fpcmp")]) |
612 | \f | |
74f4459c | 613 | ;; Next come the scc insns. |
614 | ||
17f446a0 | 615 | ;; Note that the boolean result (operand 0) takes on DImode |
616 | ;; (not SImode) when TARGET_ARCH64. | |
617 | ||
74f4459c | 618 | (define_expand "cstoresi4" |
619 | [(use (match_operator 1 "comparison_operator" | |
620 | [(match_operand:SI 2 "compare_operand" "") | |
621 | (match_operand:SI 3 "arith_operand" "")])) | |
17f446a0 | 622 | (clobber (match_operand:SI 0 "cstore_result_operand"))] |
74f4459c | 623 | "" |
624 | { | |
625 | if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) | |
626 | operands[2] = force_reg (SImode, operands[2]); | |
627 | if (emit_scc_insn (operands)) DONE; else FAIL; | |
628 | }) | |
629 | ||
630 | (define_expand "cstoredi4" | |
631 | [(use (match_operator 1 "comparison_operator" | |
632 | [(match_operand:DI 2 "compare_operand" "") | |
633 | (match_operand:DI 3 "arith_operand" "")])) | |
17f446a0 | 634 | (clobber (match_operand:SI 0 "cstore_result_operand"))] |
74f4459c | 635 | "TARGET_ARCH64" |
636 | { | |
637 | if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) | |
638 | operands[2] = force_reg (DImode, operands[2]); | |
639 | if (emit_scc_insn (operands)) DONE; else FAIL; | |
640 | }) | |
641 | ||
642 | (define_expand "cstore<F:mode>4" | |
643 | [(use (match_operator 1 "comparison_operator" | |
644 | [(match_operand:F 2 "register_operand" "") | |
645 | (match_operand:F 3 "register_operand" "")])) | |
17f446a0 | 646 | (clobber (match_operand:SI 0 "cstore_result_operand"))] |
74f4459c | 647 | "TARGET_FPU" |
648 | { if (emit_scc_insn (operands)) DONE; else FAIL; }) | |
649 | ||
650 | \f | |
001e2308 | 651 | |
652 | ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they | |
a44201ea | 653 | ;; generate addcc/subcc instructions. |
654 | ||
17f446a0 | 655 | (define_expand "seqsi<P:mode>_special" |
001e2308 | 656 | [(set (match_dup 3) |
657 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
658 | (match_operand:SI 2 "register_operand" ""))) | |
17f446a0 | 659 | (parallel [(set (match_operand:P 0 "register_operand" "") |
660 | (eq:P (match_dup 3) (const_int 0))) | |
2b25173f | 661 | (clobber (reg:CC CC_REG))])] |
f8be3dfc | 662 | "" |
0037630d | 663 | { operands[3] = gen_reg_rtx (SImode); }) |
a44201ea | 664 | |
001e2308 | 665 | (define_expand "seqdi_special" |
666 | [(set (match_dup 3) | |
667 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
668 | (match_operand:DI 2 "register_operand" ""))) | |
17f446a0 | 669 | (set (match_operand:DI 0 "register_operand" "") |
670 | (eq:DI (match_dup 3) (const_int 0)))] | |
df5e9319 | 671 | "TARGET_ARCH64" |
0037630d | 672 | { operands[3] = gen_reg_rtx (DImode); }) |
001e2308 | 673 | |
17f446a0 | 674 | (define_expand "snesi<P:mode>_special" |
001e2308 | 675 | [(set (match_dup 3) |
676 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
677 | (match_operand:SI 2 "register_operand" ""))) | |
17f446a0 | 678 | (parallel [(set (match_operand:P 0 "register_operand" "") |
679 | (ne:P (match_dup 3) (const_int 0))) | |
2b25173f | 680 | (clobber (reg:CC CC_REG))])] |
f8be3dfc | 681 | "" |
0037630d | 682 | { operands[3] = gen_reg_rtx (SImode); }) |
a44201ea | 683 | |
001e2308 | 684 | (define_expand "snedi_special" |
001e2308 | 685 | [(set (match_dup 3) |
686 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
687 | (match_operand:DI 2 "register_operand" ""))) | |
17f446a0 | 688 | (set (match_operand:DI 0 "register_operand" "") |
689 | (ne:DI (match_dup 3) (const_int 0)))] | |
9c304cc0 | 690 | "TARGET_ARCH64 && ! TARGET_VIS3" |
691 | { operands[3] = gen_reg_rtx (DImode); }) | |
692 | ||
693 | (define_expand "snedi_special_vis3" | |
694 | [(set (match_dup 3) | |
695 | (xor:DI (match_operand:DI 1 "register_operand" "") | |
696 | (match_operand:DI 2 "register_operand" ""))) | |
17f446a0 | 697 | (parallel [(set (match_operand:DI 0 "register_operand" "") |
698 | (ne:DI (match_dup 3) (const_int 0))) | |
9c304cc0 | 699 | (clobber (reg:CCX CC_REG))])] |
700 | "TARGET_ARCH64 && TARGET_VIS3" | |
0037630d | 701 | { operands[3] = gen_reg_rtx (DImode); }) |
001e2308 | 702 | |
a44201ea | 703 | |
93e2cd75 | 704 | ;; Now the DEFINE_INSNs for the scc cases. |
001e2308 | 705 | |
a44201ea | 706 | ;; The SEQ and SNE patterns are special because they can be done |
998032ba | 707 | ;; without any branching and do not involve a COMPARE. We want |
442e3cb9 | 708 | ;; them to always use the splits below so the results can be |
998032ba | 709 | ;; scheduled. |
a44201ea | 710 | |
17f446a0 | 711 | (define_insn_and_split "*snesi<P:mode>_zero" |
712 | [(set (match_operand:P 0 "register_operand" "=r") | |
713 | (ne:P (match_operand:SI 1 "register_operand" "r") | |
001e2308 | 714 | (const_int 0))) |
2b25173f | 715 | (clobber (reg:CC CC_REG))] |
f8be3dfc | 716 | "" |
998032ba | 717 | "#" |
998032ba | 718 | "" |
2b25173f | 719 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
998032ba | 720 | (const_int 0))) |
17f446a0 | 721 | (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))] |
43c08597 | 722 | "" |
723 | [(set_attr "length" "2")]) | |
a44201ea | 724 | |
17f446a0 | 725 | (define_insn_and_split "*neg_snesisi_zero" |
a44201ea | 726 | [(set (match_operand:SI 0 "register_operand" "=r") |
727 | (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") | |
728 | (const_int 0)))) | |
2b25173f | 729 | (clobber (reg:CC CC_REG))] |
f8be3dfc | 730 | "" |
998032ba | 731 | "#" |
998032ba | 732 | "" |
2b25173f | 733 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
998032ba | 734 | (const_int 0))) |
2b25173f | 735 | (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
43c08597 | 736 | "" |
2ce8757a | 737 | [(set_attr "length" "2")]) |
b6f8e298 | 738 | |
17f446a0 | 739 | (define_insn_and_split "*neg_snesidi_zero" |
43c08597 | 740 | [(set (match_operand:DI 0 "register_operand" "=r") |
17f446a0 | 741 | (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r") |
742 | (const_int 0)))) | |
2b25173f | 743 | (clobber (reg:CC CC_REG))] |
611209d4 | 744 | "TARGET_ARCH64" |
43c08597 | 745 | "#" |
43c08597 | 746 | "" |
17f446a0 | 747 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
748 | (const_int 0))) | |
40d0b2ad | 749 | (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) |
750 | (const_int 0)))))] | |
751 | "" | |
752 | [(set_attr "length" "2")]) | |
753 | ||
43c08597 | 754 | (define_insn_and_split "*snedi_zero" |
11200747 | 755 | [(set (match_operand:DI 0 "register_operand" "=&r") |
43c08597 | 756 | (ne:DI (match_operand:DI 1 "register_operand" "r") |
757 | (const_int 0)))] | |
9c304cc0 | 758 | "TARGET_ARCH64 && ! TARGET_VIS3" |
998032ba | 759 | "#" |
43c08597 | 760 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
998032ba | 761 | [(set (match_dup 0) (const_int 0)) |
762 | (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1) | |
763 | (const_int 0)) | |
764 | (const_int 1) | |
765 | (match_dup 0)))] | |
43c08597 | 766 | "" |
767 | [(set_attr "length" "2")]) | |
998032ba | 768 | |
9c304cc0 | 769 | (define_insn_and_split "*snedi_zero_vis3" |
770 | [(set (match_operand:DI 0 "register_operand" "=r") | |
771 | (ne:DI (match_operand:DI 1 "register_operand" "r") | |
772 | (const_int 0))) | |
773 | (clobber (reg:CCX CC_REG))] | |
774 | "TARGET_ARCH64 && TARGET_VIS3" | |
775 | "#" | |
776 | "" | |
777 | [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1)) | |
778 | (const_int 0))) | |
779 | (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))] | |
780 | "" | |
781 | [(set_attr "length" "2")]) | |
782 | ||
43c08597 | 783 | (define_insn_and_split "*neg_snedi_zero" |
11200747 | 784 | [(set (match_operand:DI 0 "register_operand" "=&r") |
43c08597 | 785 | (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r") |
786 | (const_int 0))))] | |
df5e9319 | 787 | "TARGET_ARCH64" |
998032ba | 788 | "#" |
43c08597 | 789 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
998032ba | 790 | [(set (match_dup 0) (const_int 0)) |
791 | (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1) | |
792 | (const_int 0)) | |
793 | (const_int -1) | |
794 | (match_dup 0)))] | |
43c08597 | 795 | "" |
796 | [(set_attr "length" "2")]) | |
998032ba | 797 | |
43c08597 | 798 | (define_insn_and_split "*snedi_zero_trunc" |
11200747 | 799 | [(set (match_operand:SI 0 "register_operand" "=&r") |
43c08597 | 800 | (ne:SI (match_operand:DI 1 "register_operand" "r") |
801 | (const_int 0)))] | |
9c304cc0 | 802 | "TARGET_ARCH64 && ! TARGET_VIS3" |
998032ba | 803 | "#" |
43c08597 | 804 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
998032ba | 805 | [(set (match_dup 0) (const_int 0)) |
be840573 | 806 | (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1) |
998032ba | 807 | (const_int 0)) |
808 | (const_int 1) | |
809 | (match_dup 0)))] | |
43c08597 | 810 | "" |
811 | [(set_attr "length" "2")]) | |
998032ba | 812 | |
9c304cc0 | 813 | (define_insn_and_split "*snedi_zero_trunc_vis3" |
814 | [(set (match_operand:SI 0 "register_operand" "=r") | |
815 | (ne:SI (match_operand:DI 1 "register_operand" "r") | |
816 | (const_int 0))) | |
817 | (clobber (reg:CCX CC_REG))] | |
818 | "TARGET_ARCH64 && TARGET_VIS3" | |
819 | "#" | |
820 | "" | |
821 | [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1)) | |
822 | (const_int 0))) | |
823 | (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))] | |
824 | "" | |
825 | [(set_attr "length" "2")]) | |
826 | ||
17f446a0 | 827 | (define_insn_and_split "*seqsi<P:mode>_zero" |
828 | [(set (match_operand:P 0 "register_operand" "=r") | |
829 | (eq:P (match_operand:SI 1 "register_operand" "r") | |
001e2308 | 830 | (const_int 0))) |
2b25173f | 831 | (clobber (reg:CC CC_REG))] |
f8be3dfc | 832 | "" |
998032ba | 833 | "#" |
998032ba | 834 | "" |
2b25173f | 835 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
998032ba | 836 | (const_int 0))) |
17f446a0 | 837 | (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))] |
43c08597 | 838 | "" |
839 | [(set_attr "length" "2")]) | |
a44201ea | 840 | |
17f446a0 | 841 | (define_insn_and_split "*neg_seqsisi_zero" |
a44201ea | 842 | [(set (match_operand:SI 0 "register_operand" "=r") |
843 | (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") | |
844 | (const_int 0)))) | |
2b25173f | 845 | (clobber (reg:CC CC_REG))] |
f8be3dfc | 846 | "" |
998032ba | 847 | "#" |
998032ba | 848 | "" |
2b25173f | 849 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
998032ba | 850 | (const_int 0))) |
2b25173f | 851 | (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))] |
43c08597 | 852 | "" |
2ce8757a | 853 | [(set_attr "length" "2")]) |
b6f8e298 | 854 | |
17f446a0 | 855 | (define_insn_and_split "*neg_seqsidi_zero" |
40d0b2ad | 856 | [(set (match_operand:DI 0 "register_operand" "=r") |
857 | (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r") | |
858 | (const_int 0)))) | |
859 | (clobber (reg:CC CC_REG))] | |
860 | "TARGET_ARCH64" | |
861 | "#" | |
862 | "&& 1" | |
863 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) | |
864 | (const_int 0))) | |
865 | (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) | |
866 | (const_int 0)))))] | |
867 | "" | |
868 | [(set_attr "length" "2")]) | |
869 | ||
43c08597 | 870 | (define_insn_and_split "*seqdi_zero" |
11200747 | 871 | [(set (match_operand:DI 0 "register_operand" "=&r") |
43c08597 | 872 | (eq:DI (match_operand:DI 1 "register_operand" "r") |
873 | (const_int 0)))] | |
df5e9319 | 874 | "TARGET_ARCH64" |
998032ba | 875 | "#" |
43c08597 | 876 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
998032ba | 877 | [(set (match_dup 0) (const_int 0)) |
878 | (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1) | |
879 | (const_int 0)) | |
880 | (const_int 1) | |
881 | (match_dup 0)))] | |
43c08597 | 882 | "" |
883 | [(set_attr "length" "2")]) | |
998032ba | 884 | |
43c08597 | 885 | (define_insn_and_split "*neg_seqdi_zero" |
11200747 | 886 | [(set (match_operand:DI 0 "register_operand" "=&r") |
43c08597 | 887 | (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r") |
888 | (const_int 0))))] | |
df5e9319 | 889 | "TARGET_ARCH64" |
998032ba | 890 | "#" |
43c08597 | 891 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
998032ba | 892 | [(set (match_dup 0) (const_int 0)) |
893 | (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1) | |
894 | (const_int 0)) | |
895 | (const_int -1) | |
896 | (match_dup 0)))] | |
43c08597 | 897 | "" |
898 | [(set_attr "length" "2")]) | |
998032ba | 899 | |
43c08597 | 900 | (define_insn_and_split "*seqdi_zero_trunc" |
11200747 | 901 | [(set (match_operand:SI 0 "register_operand" "=&r") |
43c08597 | 902 | (eq:SI (match_operand:DI 1 "register_operand" "r") |
903 | (const_int 0)))] | |
df5e9319 | 904 | "TARGET_ARCH64" |
998032ba | 905 | "#" |
43c08597 | 906 | "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" |
998032ba | 907 | [(set (match_dup 0) (const_int 0)) |
be840573 | 908 | (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1) |
998032ba | 909 | (const_int 0)) |
910 | (const_int 1) | |
911 | (match_dup 0)))] | |
43c08597 | 912 | "" |
913 | [(set_attr "length" "2")]) | |
998032ba | 914 | |
a44201ea | 915 | ;; We can also do (x + (i == 0)) and related, so put them in. |
001e2308 | 916 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode |
917 | ;; versions for v9. | |
a44201ea | 918 | |
43c08597 | 919 | (define_insn_and_split "*x_plus_i_ne_0" |
a44201ea | 920 | [(set (match_operand:SI 0 "register_operand" "=r") |
921 | (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r") | |
922 | (const_int 0)) | |
923 | (match_operand:SI 2 "register_operand" "r"))) | |
2b25173f | 924 | (clobber (reg:CC CC_REG))] |
f8be3dfc | 925 | "" |
998032ba | 926 | "#" |
f8be3dfc | 927 | "" |
2b25173f | 928 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
998032ba | 929 | (const_int 0))) |
2b25173f | 930 | (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
998032ba | 931 | (match_dup 2)))] |
43c08597 | 932 | "" |
933 | [(set_attr "length" "2")]) | |
998032ba | 934 | |
43c08597 | 935 | (define_insn_and_split "*x_minus_i_ne_0" |
a44201ea | 936 | [(set (match_operand:SI 0 "register_operand" "=r") |
937 | (minus:SI (match_operand:SI 2 "register_operand" "r") | |
938 | (ne:SI (match_operand:SI 1 "register_operand" "r") | |
939 | (const_int 0)))) | |
2b25173f | 940 | (clobber (reg:CC CC_REG))] |
f8be3dfc | 941 | "" |
998032ba | 942 | "#" |
f8be3dfc | 943 | "" |
2b25173f | 944 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
998032ba | 945 | (const_int 0))) |
946 | (set (match_dup 0) (minus:SI (match_dup 2) | |
2b25173f | 947 | (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
43c08597 | 948 | "" |
949 | [(set_attr "length" "2")]) | |
998032ba | 950 | |
43c08597 | 951 | (define_insn_and_split "*x_plus_i_eq_0" |
a44201ea | 952 | [(set (match_operand:SI 0 "register_operand" "=r") |
953 | (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") | |
954 | (const_int 0)) | |
955 | (match_operand:SI 2 "register_operand" "r"))) | |
2b25173f | 956 | (clobber (reg:CC CC_REG))] |
f8be3dfc | 957 | "" |
998032ba | 958 | "#" |
f8be3dfc | 959 | "" |
2b25173f | 960 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
998032ba | 961 | (const_int 0))) |
2b25173f | 962 | (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0)) |
998032ba | 963 | (match_dup 2)))] |
43c08597 | 964 | "" |
965 | [(set_attr "length" "2")]) | |
998032ba | 966 | |
43c08597 | 967 | (define_insn_and_split "*x_minus_i_eq_0" |
a44201ea | 968 | [(set (match_operand:SI 0 "register_operand" "=r") |
969 | (minus:SI (match_operand:SI 2 "register_operand" "r") | |
970 | (eq:SI (match_operand:SI 1 "register_operand" "r") | |
971 | (const_int 0)))) | |
2b25173f | 972 | (clobber (reg:CC CC_REG))] |
f8be3dfc | 973 | "" |
998032ba | 974 | "#" |
f8be3dfc | 975 | "" |
2b25173f | 976 | [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) |
998032ba | 977 | (const_int 0))) |
978 | (set (match_dup 0) (minus:SI (match_dup 2) | |
2b25173f | 979 | (geu:SI (reg:CC CC_REG) (const_int 0))))] |
43c08597 | 980 | "" |
981 | [(set_attr "length" "2")]) | |
998032ba | 982 | |
001e2308 | 983 | ;; We can also do GEU and LTU directly, but these operate after a compare. |
984 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode | |
985 | ;; versions for v9. | |
a44201ea | 986 | |
17f446a0 | 987 | (define_insn "*sltu<P:mode>_insn" |
988 | [(set (match_operand:P 0 "register_operand" "=r") | |
989 | (ltu:P (reg:CC CC_REG) (const_int 0)))] | |
f8be3dfc | 990 | "" |
a4ddaca5 | 991 | "addx\t%%g0, 0, %0" |
e30b7bae | 992 | [(set_attr "type" "ialuX")]) |
a44201ea | 993 | |
9c304cc0 | 994 | (define_insn "*sltu_insn_vis3" |
995 | [(set (match_operand:DI 0 "register_operand" "=r") | |
996 | (ltu:DI (reg:CCX CC_REG) (const_int 0)))] | |
997 | "TARGET_ARCH64 && TARGET_VIS3" | |
998 | "addxc\t%%g0, %%g0, %0" | |
999 | [(set_attr "type" "ialuX")]) | |
1000 | ||
1001 | (define_insn "*sltu_insn_vis3_trunc" | |
1002 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1003 | (ltu:SI (reg:CCX CC_REG) (const_int 0)))] | |
1004 | "TARGET_ARCH64 && TARGET_VIS3" | |
1005 | "addxc\t%%g0, %%g0, %0" | |
1006 | [(set_attr "type" "ialuX")]) | |
1007 | ||
17f446a0 | 1008 | (define_insn "*neg_sltusi_insn" |
a44201ea | 1009 | [(set (match_operand:SI 0 "register_operand" "=r") |
2b25173f | 1010 | (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
f8be3dfc | 1011 | "" |
a4ddaca5 | 1012 | "subx\t%%g0, 0, %0" |
e30b7bae | 1013 | [(set_attr "type" "ialuX")]) |
a44201ea | 1014 | |
17f446a0 | 1015 | (define_insn "*neg_sltudi_insn" |
40d0b2ad | 1016 | [(set (match_operand:DI 0 "register_operand" "=r") |
1017 | (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))] | |
1018 | "TARGET_ARCH64" | |
1019 | "subx\t%%g0, 0, %0" | |
1020 | [(set_attr "type" "ialuX")]) | |
1021 | ||
4117925c | 1022 | (define_insn "*neg_sltu_minus_x" |
a44201ea | 1023 | [(set (match_operand:SI 0 "register_operand" "=r") |
2b25173f | 1024 | (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))) |
a44201ea | 1025 | (match_operand:SI 1 "arith_operand" "rI")))] |
f8be3dfc | 1026 | "" |
a4ddaca5 | 1027 | "subx\t%%g0, %1, %0" |
e30b7bae | 1028 | [(set_attr "type" "ialuX")]) |
a44201ea | 1029 | |
4117925c | 1030 | (define_insn "*neg_sltu_plus_x" |
a44201ea | 1031 | [(set (match_operand:SI 0 "register_operand" "=r") |
2b25173f | 1032 | (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
a44201ea | 1033 | (match_operand:SI 1 "arith_operand" "rI"))))] |
f8be3dfc | 1034 | "" |
a4ddaca5 | 1035 | "subx\t%%g0, %1, %0" |
e30b7bae | 1036 | [(set_attr "type" "ialuX")]) |
a44201ea | 1037 | |
17f446a0 | 1038 | (define_insn "*sgeu<P:mode>_insn" |
1039 | [(set (match_operand:P 0 "register_operand" "=r") | |
1040 | (geu:P (reg:CC CC_REG) (const_int 0)))] | |
f8be3dfc | 1041 | "" |
a4ddaca5 | 1042 | "subx\t%%g0, -1, %0" |
e30b7bae | 1043 | [(set_attr "type" "ialuX")]) |
a44201ea | 1044 | |
17f446a0 | 1045 | (define_insn "*neg_sgeusi_insn" |
a44201ea | 1046 | [(set (match_operand:SI 0 "register_operand" "=r") |
2b25173f | 1047 | (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))] |
f8be3dfc | 1048 | "" |
a4ddaca5 | 1049 | "addx\t%%g0, -1, %0" |
e30b7bae | 1050 | [(set_attr "type" "ialuX")]) |
a44201ea | 1051 | |
17f446a0 | 1052 | (define_insn "*neg_sgeudi_insn" |
40d0b2ad | 1053 | [(set (match_operand:DI 0 "register_operand" "=r") |
1054 | (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))] | |
1055 | "TARGET_ARCH64" | |
1056 | "addx\t%%g0, -1, %0" | |
1057 | [(set_attr "type" "ialuX")]) | |
1058 | ||
a44201ea | 1059 | ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. |
001e2308 | 1060 | ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode |
1061 | ;; versions for v9. | |
a44201ea | 1062 | |
4117925c | 1063 | (define_insn "*sltu_plus_x" |
a44201ea | 1064 | [(set (match_operand:SI 0 "register_operand" "=r") |
2b25173f | 1065 | (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
a44201ea | 1066 | (match_operand:SI 1 "arith_operand" "rI")))] |
f8be3dfc | 1067 | "" |
a4ddaca5 | 1068 | "addx\t%%g0, %1, %0" |
e30b7bae | 1069 | [(set_attr "type" "ialuX")]) |
a44201ea | 1070 | |
4117925c | 1071 | (define_insn "*sltu_plus_x_plus_y" |
a44201ea | 1072 | [(set (match_operand:SI 0 "register_operand" "=r") |
2b25173f | 1073 | (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
a44201ea | 1074 | (plus:SI (match_operand:SI 1 "arith_operand" "%r") |
1075 | (match_operand:SI 2 "arith_operand" "rI"))))] | |
1076 | "" | |
a4ddaca5 | 1077 | "addx\t%1, %2, %0" |
e30b7bae | 1078 | [(set_attr "type" "ialuX")]) |
a44201ea | 1079 | |
4117925c | 1080 | (define_insn "*x_minus_sltu" |
a44201ea | 1081 | [(set (match_operand:SI 0 "register_operand" "=r") |
1082 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
2b25173f | 1083 | (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
a44201ea | 1084 | "" |
a4ddaca5 | 1085 | "subx\t%1, 0, %0" |
e30b7bae | 1086 | [(set_attr "type" "ialuX")]) |
a44201ea | 1087 | |
1088 | ;; ??? Combine should canonicalize these next two to the same pattern. | |
4117925c | 1089 | (define_insn "*x_minus_y_minus_sltu" |
a44201ea | 1090 | [(set (match_operand:SI 0 "register_operand" "=r") |
27b36d57 | 1091 | (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") |
a44201ea | 1092 | (match_operand:SI 2 "arith_operand" "rI")) |
2b25173f | 1093 | (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
a44201ea | 1094 | "" |
a4ddaca5 | 1095 | "subx\t%r1, %2, %0" |
e30b7bae | 1096 | [(set_attr "type" "ialuX")]) |
a44201ea | 1097 | |
4117925c | 1098 | (define_insn "*x_minus_sltu_plus_y" |
a44201ea | 1099 | [(set (match_operand:SI 0 "register_operand" "=r") |
27b36d57 | 1100 | (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") |
2b25173f | 1101 | (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) |
a44201ea | 1102 | (match_operand:SI 2 "arith_operand" "rI"))))] |
1103 | "" | |
a4ddaca5 | 1104 | "subx\t%r1, %2, %0" |
e30b7bae | 1105 | [(set_attr "type" "ialuX")]) |
a44201ea | 1106 | |
4117925c | 1107 | (define_insn "*sgeu_plus_x" |
a44201ea | 1108 | [(set (match_operand:SI 0 "register_operand" "=r") |
2b25173f | 1109 | (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0)) |
a44201ea | 1110 | (match_operand:SI 1 "register_operand" "r")))] |
1111 | "" | |
a4ddaca5 | 1112 | "subx\t%1, -1, %0" |
e30b7bae | 1113 | [(set_attr "type" "ialuX")]) |
a44201ea | 1114 | |
4117925c | 1115 | (define_insn "*x_minus_sgeu" |
a44201ea | 1116 | [(set (match_operand:SI 0 "register_operand" "=r") |
1117 | (minus:SI (match_operand:SI 1 "register_operand" "r") | |
2b25173f | 1118 | (geu:SI (reg:CC CC_REG) (const_int 0))))] |
a44201ea | 1119 | "" |
a4ddaca5 | 1120 | "addx\t%1, -1, %0" |
e30b7bae | 1121 | [(set_attr "type" "ialuX")]) |
001e2308 | 1122 | |
58dc6b1f | 1123 | (define_split |
90a57e44 | 1124 | [(set (match_operand:SI 0 "register_operand" "") |
27b36d57 | 1125 | (match_operator:SI 2 "noov_compare_operator" |
1126 | [(match_operand 1 "icc_or_fcc_register_operand" "") | |
58dc6b1f | 1127 | (const_int 0)]))] |
f77b9d3c | 1128 | "TARGET_V9 |
1129 | && REGNO (operands[1]) == SPARC_ICC_REG | |
58dc6b1f | 1130 | && (GET_MODE (operands[1]) == CCXmode |
5b865faf | 1131 | /* 32-bit LTU/GEU are better implemented using addx/subx. */ |
58dc6b1f | 1132 | || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))" |
1133 | [(set (match_dup 0) (const_int 0)) | |
1134 | (set (match_dup 0) | |
1135 | (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)]) | |
1136 | (const_int 1) | |
1137 | (match_dup 0)))] | |
1138 | "") | |
1139 | ||
a44201ea | 1140 | \f |
1141 | ;; These control RTL generation for conditional jump insns | |
1142 | ||
74f4459c | 1143 | (define_expand "cbranchcc4" |
a44201ea | 1144 | [(set (pc) |
74f4459c | 1145 | (if_then_else (match_operator 0 "comparison_operator" |
1146 | [(match_operand 1 "compare_operand" "") | |
1147 | (match_operand 2 "const_zero_operand" "")]) | |
1148 | (label_ref (match_operand 3 "" "")) | |
a44201ea | 1149 | (pc)))] |
1150 | "" | |
74f4459c | 1151 | "") |
9312a956 | 1152 | |
74f4459c | 1153 | (define_expand "cbranchsi4" |
1154 | [(use (match_operator 0 "comparison_operator" | |
1155 | [(match_operand:SI 1 "compare_operand" "") | |
1156 | (match_operand:SI 2 "arith_operand" "")])) | |
1157 | (use (match_operand 3 ""))] | |
9312a956 | 1158 | "" |
9312a956 | 1159 | { |
74f4459c | 1160 | if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx) |
1161 | operands[1] = force_reg (SImode, operands[1]); | |
1162 | emit_conditional_branch_insn (operands); | |
1163 | DONE; | |
0037630d | 1164 | }) |
9312a956 | 1165 | |
74f4459c | 1166 | (define_expand "cbranchdi4" |
1167 | [(use (match_operator 0 "comparison_operator" | |
1168 | [(match_operand:DI 1 "compare_operand" "") | |
1169 | (match_operand:DI 2 "arith_operand" "")])) | |
1170 | (use (match_operand 3 ""))] | |
1171 | "TARGET_ARCH64" | |
9312a956 | 1172 | { |
74f4459c | 1173 | if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx) |
1174 | operands[1] = force_reg (DImode, operands[1]); | |
1175 | emit_conditional_branch_insn (operands); | |
1176 | DONE; | |
0037630d | 1177 | }) |
9312a956 | 1178 | |
74f4459c | 1179 | (define_expand "cbranch<F:mode>4" |
1180 | [(use (match_operator 0 "comparison_operator" | |
1181 | [(match_operand:F 1 "register_operand" "") | |
1182 | (match_operand:F 2 "register_operand" "")])) | |
1183 | (use (match_operand 3 ""))] | |
1184 | "TARGET_FPU" | |
1185 | { emit_conditional_branch_insn (operands); DONE; }) | |
9312a956 | 1186 | |
79777bad | 1187 | |
a44201ea | 1188 | ;; Now match both normal and inverted jump. |
1189 | ||
998032ba | 1190 | ;; XXX fpcmp nop braindamage |
4117925c | 1191 | (define_insn "*normal_branch" |
a44201ea | 1192 | [(set (pc) |
27b36d57 | 1193 | (if_then_else (match_operator 0 "noov_compare_operator" |
2b25173f | 1194 | [(reg CC_REG) (const_int 0)]) |
a44201ea | 1195 | (label_ref (match_operand 1 "" "")) |
1196 | (pc)))] | |
1197 | "" | |
a44201ea | 1198 | { |
ebd2c2bf | 1199 | return output_cbranch (operands[0], operands[1], 1, 0, |
a44201ea | 1200 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
461a1f48 | 1201 | insn); |
0037630d | 1202 | } |
ebd2c2bf | 1203 | [(set_attr "type" "branch") |
258103e3 | 1204 | (set_attr "branch_type" "icc")]) |
a44201ea | 1205 | |
998032ba | 1206 | ;; XXX fpcmp nop braindamage |
4117925c | 1207 | (define_insn "*inverted_branch" |
a44201ea | 1208 | [(set (pc) |
27b36d57 | 1209 | (if_then_else (match_operator 0 "noov_compare_operator" |
2b25173f | 1210 | [(reg CC_REG) (const_int 0)]) |
a44201ea | 1211 | (pc) |
1212 | (label_ref (match_operand 1 "" ""))))] | |
1213 | "" | |
a44201ea | 1214 | { |
ebd2c2bf | 1215 | return output_cbranch (operands[0], operands[1], 1, 1, |
a44201ea | 1216 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
461a1f48 | 1217 | insn); |
0037630d | 1218 | } |
ebd2c2bf | 1219 | [(set_attr "type" "branch") |
258103e3 | 1220 | (set_attr "branch_type" "icc")]) |
a44201ea | 1221 | |
998032ba | 1222 | ;; XXX fpcmp nop braindamage |
946e12d1 | 1223 | (define_insn "*normal_fp_branch" |
001e2308 | 1224 | [(set (pc) |
946e12d1 | 1225 | (if_then_else (match_operator 1 "comparison_operator" |
27b36d57 | 1226 | [(match_operand:CCFP 0 "fcc_register_operand" "c") |
001e2308 | 1227 | (const_int 0)]) |
1228 | (label_ref (match_operand 2 "" "")) | |
1229 | (pc)))] | |
946e12d1 | 1230 | "" |
1ee01ec7 | 1231 | { |
ebd2c2bf | 1232 | return output_cbranch (operands[1], operands[2], 2, 0, |
001e2308 | 1233 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
461a1f48 | 1234 | insn); |
0037630d | 1235 | } |
ebd2c2bf | 1236 | [(set_attr "type" "branch") |
258103e3 | 1237 | (set_attr "branch_type" "fcc")]) |
1ee01ec7 | 1238 | |
998032ba | 1239 | ;; XXX fpcmp nop braindamage |
946e12d1 | 1240 | (define_insn "*inverted_fp_branch" |
001e2308 | 1241 | [(set (pc) |
946e12d1 | 1242 | (if_then_else (match_operator 1 "comparison_operator" |
27b36d57 | 1243 | [(match_operand:CCFP 0 "fcc_register_operand" "c") |
001e2308 | 1244 | (const_int 0)]) |
1245 | (pc) | |
1246 | (label_ref (match_operand 2 "" ""))))] | |
946e12d1 | 1247 | "" |
001e2308 | 1248 | { |
ebd2c2bf | 1249 | return output_cbranch (operands[1], operands[2], 2, 1, |
001e2308 | 1250 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
461a1f48 | 1251 | insn); |
0037630d | 1252 | } |
ebd2c2bf | 1253 | [(set_attr "type" "branch") |
258103e3 | 1254 | (set_attr "branch_type" "fcc")]) |
1ee01ec7 | 1255 | |
998032ba | 1256 | ;; XXX fpcmp nop braindamage |
946e12d1 | 1257 | (define_insn "*normal_fpe_branch" |
001e2308 | 1258 | [(set (pc) |
946e12d1 | 1259 | (if_then_else (match_operator 1 "comparison_operator" |
27b36d57 | 1260 | [(match_operand:CCFPE 0 "fcc_register_operand" "c") |
001e2308 | 1261 | (const_int 0)]) |
1262 | (label_ref (match_operand 2 "" "")) | |
1263 | (pc)))] | |
946e12d1 | 1264 | "" |
001e2308 | 1265 | { |
ebd2c2bf | 1266 | return output_cbranch (operands[1], operands[2], 2, 0, |
001e2308 | 1267 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
461a1f48 | 1268 | insn); |
0037630d | 1269 | } |
ebd2c2bf | 1270 | [(set_attr "type" "branch") |
258103e3 | 1271 | (set_attr "branch_type" "fcc")]) |
1ee01ec7 | 1272 | |
998032ba | 1273 | ;; XXX fpcmp nop braindamage |
946e12d1 | 1274 | (define_insn "*inverted_fpe_branch" |
001e2308 | 1275 | [(set (pc) |
946e12d1 | 1276 | (if_then_else (match_operator 1 "comparison_operator" |
27b36d57 | 1277 | [(match_operand:CCFPE 0 "fcc_register_operand" "c") |
001e2308 | 1278 | (const_int 0)]) |
1279 | (pc) | |
1280 | (label_ref (match_operand 2 "" ""))))] | |
946e12d1 | 1281 | "" |
001e2308 | 1282 | { |
ebd2c2bf | 1283 | return output_cbranch (operands[1], operands[2], 2, 1, |
001e2308 | 1284 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
461a1f48 | 1285 | insn); |
0037630d | 1286 | } |
ebd2c2bf | 1287 | [(set_attr "type" "branch") |
258103e3 | 1288 | (set_attr "branch_type" "fcc")]) |
1ee01ec7 | 1289 | |
f25a48be | 1290 | ;; SPARC V9-specific jump insns. None of these are guaranteed to be |
001e2308 | 1291 | ;; in the architecture. |
1292 | ||
6c940e8d | 1293 | (define_insn "*cbcond_sp32" |
1294 | [(set (pc) | |
1295 | (if_then_else (match_operator 0 "noov_compare_operator" | |
1296 | [(match_operand:SI 1 "register_operand" "r") | |
1297 | (match_operand:SI 2 "arith5_operand" "rA")]) | |
1298 | (label_ref (match_operand 3 "" "")) | |
1299 | (pc)))] | |
1300 | "TARGET_CBCOND" | |
1301 | { | |
1302 | return output_cbcond (operands[0], operands[3], insn); | |
1303 | } | |
1304 | [(set_attr "type" "cbcond")]) | |
1305 | ||
1306 | (define_insn "*cbcond_sp64" | |
1307 | [(set (pc) | |
1308 | (if_then_else (match_operator 0 "noov_compare_operator" | |
1309 | [(match_operand:DI 1 "register_operand" "r") | |
1310 | (match_operand:DI 2 "arith5_operand" "rA")]) | |
1311 | (label_ref (match_operand 3 "" "")) | |
1312 | (pc)))] | |
1313 | "TARGET_ARCH64 && TARGET_CBCOND" | |
1314 | { | |
1315 | return output_cbcond (operands[0], operands[3], insn); | |
1316 | } | |
1317 | [(set_attr "type" "cbcond")]) | |
1318 | ||
001e2308 | 1319 | ;; There are no 32 bit brreg insns. |
1320 | ||
998032ba | 1321 | ;; XXX |
4117925c | 1322 | (define_insn "*normal_int_branch_sp64" |
001e2308 | 1323 | [(set (pc) |
27b36d57 | 1324 | (if_then_else (match_operator 0 "v9_register_compare_operator" |
001e2308 | 1325 | [(match_operand:DI 1 "register_operand" "r") |
1326 | (const_int 0)]) | |
1327 | (label_ref (match_operand 2 "" "")) | |
1328 | (pc)))] | |
df5e9319 | 1329 | "TARGET_ARCH64" |
1ee01ec7 | 1330 | { |
ebd2c2bf | 1331 | return output_v9branch (operands[0], operands[2], 1, 2, 0, |
001e2308 | 1332 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
461a1f48 | 1333 | insn); |
0037630d | 1334 | } |
ebd2c2bf | 1335 | [(set_attr "type" "branch") |
258103e3 | 1336 | (set_attr "branch_type" "reg")]) |
1ee01ec7 | 1337 | |
998032ba | 1338 | ;; XXX |
4117925c | 1339 | (define_insn "*inverted_int_branch_sp64" |
001e2308 | 1340 | [(set (pc) |
27b36d57 | 1341 | (if_then_else (match_operator 0 "v9_register_compare_operator" |
001e2308 | 1342 | [(match_operand:DI 1 "register_operand" "r") |
1343 | (const_int 0)]) | |
1344 | (pc) | |
1345 | (label_ref (match_operand 2 "" ""))))] | |
df5e9319 | 1346 | "TARGET_ARCH64" |
001e2308 | 1347 | { |
ebd2c2bf | 1348 | return output_v9branch (operands[0], operands[2], 1, 2, 1, |
001e2308 | 1349 | final_sequence && INSN_ANNULLED_BRANCH_P (insn), |
461a1f48 | 1350 | insn); |
0037630d | 1351 | } |
ebd2c2bf | 1352 | [(set_attr "type" "branch") |
258103e3 | 1353 | (set_attr "branch_type" "reg")]) |
d88ab5ca | 1354 | |
1355 | ||
6b122edb | 1356 | ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic |
1357 | ;; value subject to a PC-relative relocation. Operand 2 is a helper function | |
d552de41 | 1358 | ;; that adds the PC value at the call point to register #(operand 3). |
005acfe0 | 1359 | ;; |
1360 | ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..." | |
1361 | ;; because the RDPC instruction is extremely expensive and incurs a complete | |
1362 | ;; instruction pipeline flush. | |
1ee01ec7 | 1363 | |
f787e26b | 1364 | (define_insn "load_pcrel_sym<P:mode>" |
1365 | [(set (match_operand:P 0 "register_operand" "=r") | |
1366 | (unspec:P [(match_operand:P 1 "symbolic_operand" "") | |
d552de41 | 1367 | (match_operand:P 2 "call_address_operand" "") |
1368 | (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM)) | |
2b25173f | 1369 | (clobber (reg:P O7_REG))] |
d552de41 | 1370 | "REGNO (operands[0]) == INTVAL (operands[3])" |
d35f187f | 1371 | { |
1372 | if (flag_delayed_branch) | |
1373 | return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0"; | |
1374 | else | |
1375 | return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop"; | |
1376 | } | |
1377 | [(set (attr "type") (const_string "multi")) | |
1378 | (set (attr "length") | |
1379 | (if_then_else (eq_attr "delayed_branch" "true") | |
1380 | (const_int 3) | |
1381 | (const_int 4)))]) | |
d88ab5ca | 1382 | |
1383 | ||
1384 | ;; Integer move instructions | |
a44201ea | 1385 | |
998032ba | 1386 | (define_expand "movqi" |
b6a32a23 | 1387 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
998032ba | 1388 | (match_operand:QI 1 "general_operand" ""))] |
1389 | "" | |
998032ba | 1390 | { |
b6a32a23 | 1391 | if (sparc_expand_move (QImode, operands)) |
1392 | DONE; | |
0037630d | 1393 | }) |
998032ba | 1394 | |
1395 | (define_insn "*movqi_insn" | |
e9ac7268 | 1396 | [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m") |
998032ba | 1397 | (match_operand:QI 1 "input_operand" "rI,m,rJ"))] |
1398 | "(register_operand (operands[0], QImode) | |
27b36d57 | 1399 | || register_or_zero_operand (operands[1], QImode))" |
998032ba | 1400 | "@ |
a4ddaca5 | 1401 | mov\t%1, %0 |
1402 | ldub\t%1, %0 | |
1403 | stb\t%r1, %0" | |
bea4bad2 | 1404 | [(set_attr "type" "*,load,store") |
1405 | (set_attr "us3load_type" "*,3cycle,*")]) | |
998032ba | 1406 | |
1407 | (define_expand "movhi" | |
b6a32a23 | 1408 | [(set (match_operand:HI 0 "nonimmediate_operand" "") |
998032ba | 1409 | (match_operand:HI 1 "general_operand" ""))] |
1410 | "" | |
b0344bad | 1411 | { |
b6a32a23 | 1412 | if (sparc_expand_move (HImode, operands)) |
1413 | DONE; | |
0037630d | 1414 | }) |
001e2308 | 1415 | |
998032ba | 1416 | (define_insn "*movhi_insn" |
e9ac7268 | 1417 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") |
998032ba | 1418 | (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))] |
1419 | "(register_operand (operands[0], HImode) | |
27b36d57 | 1420 | || register_or_zero_operand (operands[1], HImode))" |
998032ba | 1421 | "@ |
a4ddaca5 | 1422 | mov\t%1, %0 |
1423 | sethi\t%%hi(%a1), %0 | |
1424 | lduh\t%1, %0 | |
1425 | sth\t%r1, %0" | |
bea4bad2 | 1426 | [(set_attr "type" "*,*,load,store") |
1427 | (set_attr "us3load_type" "*,*,3cycle,*")]) | |
998032ba | 1428 | |
611209d4 | 1429 | ;; We always work with constants here. |
998032ba | 1430 | (define_insn "*movhi_lo_sum" |
b191fa18 | 1431 | [(set (match_operand:HI 0 "register_operand" "=r") |
0daea6cd | 1432 | (ior:HI (match_operand:HI 1 "register_operand" "%r") |
27b36d57 | 1433 | (match_operand:HI 2 "small_int_operand" "I")))] |
998032ba | 1434 | "" |
a4ddaca5 | 1435 | "or\t%1, %2, %0") |
b191fa18 | 1436 | |
998032ba | 1437 | (define_expand "movsi" |
b6a32a23 | 1438 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
998032ba | 1439 | (match_operand:SI 1 "general_operand" ""))] |
1440 | "" | |
001e2308 | 1441 | { |
b6a32a23 | 1442 | if (sparc_expand_move (SImode, operands)) |
1443 | DONE; | |
0037630d | 1444 | }) |
998032ba | 1445 | |
4aa70596 | 1446 | (define_insn "*movsi_insn" |
30386ca0 | 1447 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d") |
1448 | (match_operand:SI 1 "input_operand" "rI,K,m,rJ,*f, r, f, m,*f,J,P"))] | |
4aa70596 | 1449 | "register_operand (operands[0], SImode) |
1450 | || register_or_zero_or_all_ones_operand (operands[1], SImode)" | |
30386ca0 | 1451 | "@ |
1452 | mov\t%1, %0 | |
1453 | sethi\t%%hi(%a1), %0 | |
1454 | ld\t%1, %0 | |
1455 | st\t%r1, %0 | |
1456 | movstouw\t%1, %0 | |
1457 | movwtos\t%1, %0 | |
1458 | fmovs\t%1, %0 | |
1459 | ld\t%1, %0 | |
1460 | st\t%1, %0 | |
1461 | fzeros\t%0 | |
1462 | fones\t%0" | |
d3cb8b93 | 1463 | [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl") |
4aa70596 | 1464 | (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")]) |
30386ca0 | 1465 | |
998032ba | 1466 | (define_insn "*movsi_lo_sum" |
1467 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1468 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
1469 | (match_operand:SI 2 "immediate_operand" "in")))] | |
1470 | "" | |
a4ddaca5 | 1471 | "or\t%1, %%lo(%a2), %0") |
998032ba | 1472 | |
1473 | (define_insn "*movsi_high" | |
1474 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1475 | (high:SI (match_operand:SI 1 "immediate_operand" "in")))] | |
1476 | "" | |
a4ddaca5 | 1477 | "sethi\t%%hi(%a1), %0") |
a44201ea | 1478 | |
998032ba | 1479 | ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC |
1480 | ;; so that CSE won't optimize the address computation away. | |
1481 | (define_insn "movsi_lo_sum_pic" | |
1482 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1483 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
40cc626c | 1484 | (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] |
998032ba | 1485 | "flag_pic" |
2f1e7d0b | 1486 | { |
1487 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1488 | return "xor\t%1, %%gdop_lox10(%a2), %0"; | |
1489 | #else | |
1490 | return "or\t%1, %%lo(%a2), %0"; | |
1491 | #endif | |
1492 | }) | |
001e2308 | 1493 | |
998032ba | 1494 | (define_insn "movsi_high_pic" |
1495 | [(set (match_operand:SI 0 "register_operand" "=r") | |
40cc626c | 1496 | (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] |
998032ba | 1497 | "flag_pic && check_pic (1)" |
2f1e7d0b | 1498 | { |
1499 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1500 | return "sethi\t%%gdop_hix22(%a1), %0"; | |
1501 | #else | |
1502 | return "sethi\t%%hi(%a1), %0"; | |
1503 | #endif | |
1504 | }) | |
1505 | ||
1506 | (define_insn "movsi_pic_gotdata_op" | |
1507 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1508 | (unspec:SI [(match_operand:SI 1 "register_operand" "r") | |
1509 | (match_operand:SI 2 "register_operand" "r") | |
1510 | (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))] | |
1511 | "flag_pic && check_pic (1)" | |
1512 | { | |
1513 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1514 | return "ld\t[%1 + %2], %0, %%gdop(%a3)"; | |
1515 | #else | |
1516 | return "ld\t[%1 + %2], %0"; | |
1517 | #endif | |
1518 | } | |
1519 | [(set_attr "type" "load")]) | |
998032ba | 1520 | |
1521 | (define_expand "movsi_pic_label_ref" | |
1522 | [(set (match_dup 3) (high:SI | |
1523 | (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") | |
40cc626c | 1524 | (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) |
998032ba | 1525 | (set (match_dup 4) (lo_sum:SI (match_dup 3) |
40cc626c | 1526 | (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) |
998032ba | 1527 | (set (match_operand:SI 0 "register_operand" "=r") |
1528 | (minus:SI (match_dup 5) (match_dup 4)))] | |
1529 | "flag_pic" | |
001e2308 | 1530 | { |
18d50ae6 | 1531 | crtl->uses_pic_offset_table = 1; |
0037630d | 1532 | operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); |
e1ba4a27 | 1533 | if (!can_create_pseudo_p ()) |
bf7619bc | 1534 | { |
1535 | operands[3] = operands[0]; | |
1536 | operands[4] = operands[0]; | |
1537 | } | |
1538 | else | |
1539 | { | |
1540 | operands[3] = gen_reg_rtx (SImode); | |
1541 | operands[4] = gen_reg_rtx (SImode); | |
1542 | } | |
998032ba | 1543 | operands[5] = pic_offset_table_rtx; |
0037630d | 1544 | }) |
001e2308 | 1545 | |
998032ba | 1546 | (define_insn "*movsi_high_pic_label_ref" |
1547 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1548 | (high:SI | |
1549 | (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") | |
40cc626c | 1550 | (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] |
998032ba | 1551 | "flag_pic" |
a4ddaca5 | 1552 | "sethi\t%%hi(%a2-(%a1-.)), %0") |
998032ba | 1553 | |
1554 | (define_insn "*movsi_lo_sum_pic_label_ref" | |
1555 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4c7488a6 | 1556 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") |
998032ba | 1557 | (unspec:SI [(match_operand:SI 2 "label_ref_operand" "") |
40cc626c | 1558 | (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] |
998032ba | 1559 | "flag_pic" |
a4ddaca5 | 1560 | "or\t%1, %%lo(%a3-(%a2-.)), %0") |
998032ba | 1561 | |
723e1902 | 1562 | ;; Set up the PIC register for VxWorks. |
1563 | ||
1564 | (define_expand "vxworks_load_got" | |
1565 | [(set (match_dup 0) | |
1566 | (high:SI (match_dup 1))) | |
1567 | (set (match_dup 0) | |
1568 | (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1)))) | |
1569 | (set (match_dup 0) | |
1570 | (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))] | |
1571 | "TARGET_VXWORKS_RTP" | |
1572 | { | |
1573 | operands[0] = pic_offset_table_rtx; | |
1574 | operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE); | |
1575 | operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX); | |
1576 | }) | |
1577 | ||
998032ba | 1578 | (define_expand "movdi" |
b6a32a23 | 1579 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
998032ba | 1580 | (match_operand:DI 1 "general_operand" ""))] |
1581 | "" | |
998032ba | 1582 | { |
b6a32a23 | 1583 | if (sparc_expand_move (DImode, operands)) |
1584 | DONE; | |
0037630d | 1585 | }) |
998032ba | 1586 | |
9251aedd | 1587 | ;; Be careful, fmovd does not exist when !v9. |
998032ba | 1588 | ;; We match MEM moves directly when we have correct even |
1589 | ;; numbered registers, but fall into splits otherwise. | |
1590 | ;; The constraint ordering here is really important to | |
1591 | ;; avoid insane problems in reload, especially for patterns | |
1592 | ;; of the form: | |
1593 | ;; | |
1594 | ;; (set (mem:DI (plus:SI (reg:SI 30 %fp) | |
1595 | ;; (const_int -5016))) | |
1596 | ;; (reg:DI 2 %g2)) | |
1597 | ;; | |
4d61c4ff | 1598 | |
d88ab5ca | 1599 | (define_insn "*movdi_insn_sp32" |
4d61c4ff | 1600 | [(set (match_operand:DI 0 "nonimmediate_operand" |
5d3ad0ab | 1601 | "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b") |
4d61c4ff | 1602 | (match_operand:DI 1 "input_operand" |
5d3ad0ab | 1603 | " J,J,U,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))] |
d88ab5ca | 1604 | "! TARGET_ARCH64 |
30386ca0 | 1605 | && (register_operand (operands[0], DImode) |
1606 | || register_or_zero_operand (operands[1], DImode))" | |
1607 | "@ | |
1608 | stx\t%%g0, %0 | |
1609 | # | |
1610 | std\t%1, %0 | |
1611 | ldd\t%1, %0 | |
1612 | # | |
1613 | # | |
1614 | # | |
1615 | # | |
1616 | std\t%1, %0 | |
1617 | ldd\t%1, %0 | |
1618 | # | |
1619 | # | |
1620 | fmovd\t%1, %0 | |
1621 | # | |
1622 | # | |
4aa70596 | 1623 | # |
30386ca0 | 1624 | ldd\t%1, %0 |
1625 | std\t%1, %0 | |
1626 | fzero\t%0 | |
1627 | fone\t%0" | |
d3cb8b93 | 1628 | [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl") |
4aa70596 | 1629 | (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*") |
1630 | (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double") | |
1631 | (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")]) | |
998032ba | 1632 | |
4aa70596 | 1633 | (define_insn "*movdi_insn_sp64" |
30386ca0 | 1634 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b") |
1635 | (match_operand:DI 1 "input_operand" "rI,N,m,rJ,*e, r, *e, W,*e,J,P"))] | |
1636 | "TARGET_ARCH64 | |
30386ca0 | 1637 | && (register_operand (operands[0], DImode) |
1638 | || register_or_zero_or_all_ones_operand (operands[1], DImode))" | |
1639 | "@ | |
1640 | mov\t%1, %0 | |
1641 | sethi\t%%hi(%a1), %0 | |
1642 | ldx\t%1, %0 | |
1643 | stx\t%r1, %0 | |
1644 | movdtox\t%1, %0 | |
1645 | movxtod\t%1, %0 | |
1646 | fmovd\t%1, %0 | |
1647 | ldd\t%1, %0 | |
1648 | std\t%1, %0 | |
1649 | fzero\t%0 | |
1650 | fone\t%0" | |
d3cb8b93 | 1651 | [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl") |
4aa70596 | 1652 | (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double") |
1653 | (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")]) | |
30386ca0 | 1654 | |
1197a03c | 1655 | (define_expand "movdi_pic_label_ref" |
1656 | [(set (match_dup 3) (high:DI | |
1657 | (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") | |
40cc626c | 1658 | (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) |
1197a03c | 1659 | (set (match_dup 4) (lo_sum:DI (match_dup 3) |
40cc626c | 1660 | (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL))) |
1197a03c | 1661 | (set (match_operand:DI 0 "register_operand" "=r") |
1662 | (minus:DI (match_dup 5) (match_dup 4)))] | |
1663 | "TARGET_ARCH64 && flag_pic" | |
998032ba | 1664 | { |
18d50ae6 | 1665 | crtl->uses_pic_offset_table = 1; |
0037630d | 1666 | operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); |
e1ba4a27 | 1667 | if (!can_create_pseudo_p ()) |
bf7619bc | 1668 | { |
1669 | operands[3] = operands[0]; | |
1670 | operands[4] = operands[0]; | |
1671 | } | |
1672 | else | |
1673 | { | |
1674 | operands[3] = gen_reg_rtx (DImode); | |
1675 | operands[4] = gen_reg_rtx (DImode); | |
1676 | } | |
1197a03c | 1677 | operands[5] = pic_offset_table_rtx; |
0037630d | 1678 | }) |
1197a03c | 1679 | |
1680 | (define_insn "*movdi_high_pic_label_ref" | |
1681 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1682 | (high:DI | |
1683 | (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") | |
40cc626c | 1684 | (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))] |
1197a03c | 1685 | "TARGET_ARCH64 && flag_pic" |
a4ddaca5 | 1686 | "sethi\t%%hi(%a2-(%a1-.)), %0") |
1197a03c | 1687 | |
1688 | (define_insn "*movdi_lo_sum_pic_label_ref" | |
1689 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1690 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
1691 | (unspec:DI [(match_operand:DI 2 "label_ref_operand" "") | |
40cc626c | 1692 | (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))] |
1197a03c | 1693 | "TARGET_ARCH64 && flag_pic" |
a4ddaca5 | 1694 | "or\t%1, %%lo(%a3-(%a2-.)), %0") |
001e2308 | 1695 | |
f25a48be | 1696 | ;; SPARC-v9 code model support insns. See sparc_emit_set_symbolic_const64 |
998032ba | 1697 | ;; in sparc.c to see what is going on here... PIC stuff comes first. |
1698 | ||
abce7786 | 1699 | (define_insn "movdi_lo_sum_pic" |
998032ba | 1700 | [(set (match_operand:DI 0 "register_operand" "=r") |
be840573 | 1701 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
40cc626c | 1702 | (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))] |
998032ba | 1703 | "TARGET_ARCH64 && flag_pic" |
2f1e7d0b | 1704 | { |
1705 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1706 | return "xor\t%1, %%gdop_lox10(%a2), %0"; | |
1707 | #else | |
1708 | return "or\t%1, %%lo(%a2), %0"; | |
1709 | #endif | |
1710 | }) | |
998032ba | 1711 | |
abce7786 | 1712 | (define_insn "movdi_high_pic" |
998032ba | 1713 | [(set (match_operand:DI 0 "register_operand" "=r") |
40cc626c | 1714 | (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))] |
998032ba | 1715 | "TARGET_ARCH64 && flag_pic && check_pic (1)" |
2f1e7d0b | 1716 | { |
1717 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1718 | return "sethi\t%%gdop_hix22(%a1), %0"; | |
1719 | #else | |
1720 | return "sethi\t%%hi(%a1), %0"; | |
1721 | #endif | |
1722 | }) | |
1723 | ||
1724 | (define_insn "movdi_pic_gotdata_op" | |
1725 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1726 | (unspec:DI [(match_operand:DI 1 "register_operand" "r") | |
1727 | (match_operand:DI 2 "register_operand" "r") | |
1728 | (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))] | |
1729 | "TARGET_ARCH64 && flag_pic && check_pic (1)" | |
1730 | { | |
1731 | #ifdef HAVE_AS_SPARC_GOTDATA_OP | |
1732 | return "ldx\t[%1 + %2], %0, %%gdop(%a3)"; | |
1733 | #else | |
1734 | return "ldx\t[%1 + %2], %0"; | |
1735 | #endif | |
1736 | } | |
1737 | [(set_attr "type" "load")]) | |
998032ba | 1738 | |
1739 | (define_insn "*sethi_di_medlow_embmedany_pic" | |
1740 | [(set (match_operand:DI 0 "register_operand" "=r") | |
27b36d57 | 1741 | (high:DI (match_operand:DI 1 "medium_pic_operand" "")))] |
998032ba | 1742 | "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)" |
a4ddaca5 | 1743 | "sethi\t%%hi(%a1), %0") |
bdf74c8a | 1744 | |
4117925c | 1745 | (define_insn "*sethi_di_medlow" |
001e2308 | 1746 | [(set (match_operand:DI 0 "register_operand" "=r") |
1458fd84 | 1747 | (high:DI (match_operand:DI 1 "symbolic_operand" "")))] |
adf09a2f | 1748 | "TARGET_CM_MEDLOW && check_pic (1)" |
a4ddaca5 | 1749 | "sethi\t%%hi(%a1), %0") |
a44201ea | 1750 | |
998032ba | 1751 | (define_insn "*losum_di_medlow" |
b0344bad | 1752 | [(set (match_operand:DI 0 "register_operand" "=r") |
998032ba | 1753 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
19e6708e | 1754 | (match_operand:DI 2 "symbolic_operand" "")))] |
998032ba | 1755 | "TARGET_CM_MEDLOW" |
a4ddaca5 | 1756 | "or\t%1, %%lo(%a2), %0") |
998032ba | 1757 | |
1758 | (define_insn "seth44" | |
1759 | [(set (match_operand:DI 0 "register_operand" "=r") | |
40cc626c | 1760 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))] |
998032ba | 1761 | "TARGET_CM_MEDMID" |
a4ddaca5 | 1762 | "sethi\t%%h44(%a1), %0") |
b0344bad | 1763 | |
998032ba | 1764 | (define_insn "setm44" |
1765 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1766 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
40cc626c | 1767 | (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))] |
998032ba | 1768 | "TARGET_CM_MEDMID" |
a4ddaca5 | 1769 | "or\t%1, %%m44(%a2), %0") |
001e2308 | 1770 | |
998032ba | 1771 | (define_insn "setl44" |
001e2308 | 1772 | [(set (match_operand:DI 0 "register_operand" "=r") |
998032ba | 1773 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") |
1774 | (match_operand:DI 2 "symbolic_operand" "")))] | |
1775 | "TARGET_CM_MEDMID" | |
a4ddaca5 | 1776 | "or\t%1, %%l44(%a2), %0") |
998032ba | 1777 | |
1778 | (define_insn "sethh" | |
1779 | [(set (match_operand:DI 0 "register_operand" "=r") | |
40cc626c | 1780 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))] |
998032ba | 1781 | "TARGET_CM_MEDANY" |
a4ddaca5 | 1782 | "sethi\t%%hh(%a1), %0") |
001e2308 | 1783 | |
998032ba | 1784 | (define_insn "setlm" |
001e2308 | 1785 | [(set (match_operand:DI 0 "register_operand" "=r") |
40cc626c | 1786 | (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))] |
998032ba | 1787 | "TARGET_CM_MEDANY" |
a4ddaca5 | 1788 | "sethi\t%%lm(%a1), %0") |
001e2308 | 1789 | |
998032ba | 1790 | (define_insn "sethm" |
1791 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1792 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
40cc626c | 1793 | (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))] |
998032ba | 1794 | "TARGET_CM_MEDANY" |
a4ddaca5 | 1795 | "or\t%1, %%hm(%a2), %0") |
001e2308 | 1796 | |
998032ba | 1797 | (define_insn "setlo" |
1798 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1799 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
19e6708e | 1800 | (match_operand:DI 2 "symbolic_operand" "")))] |
998032ba | 1801 | "TARGET_CM_MEDANY" |
a4ddaca5 | 1802 | "or\t%1, %%lo(%a2), %0") |
998032ba | 1803 | |
1804 | (define_insn "embmedany_sethi" | |
1805 | [(set (match_operand:DI 0 "register_operand" "=r") | |
40cc626c | 1806 | (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))] |
998032ba | 1807 | "TARGET_CM_EMBMEDANY && check_pic (1)" |
a4ddaca5 | 1808 | "sethi\t%%hi(%a1), %0") |
001e2308 | 1809 | |
998032ba | 1810 | (define_insn "embmedany_losum" |
1811 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1812 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
1813 | (match_operand:DI 2 "data_segment_operand" "")))] | |
1814 | "TARGET_CM_EMBMEDANY" | |
a4ddaca5 | 1815 | "add\t%1, %%lo(%a2), %0") |
001e2308 | 1816 | |
998032ba | 1817 | (define_insn "embmedany_brsum" |
1818 | [(set (match_operand:DI 0 "register_operand" "=r") | |
40cc626c | 1819 | (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))] |
998032ba | 1820 | "TARGET_CM_EMBMEDANY" |
a4ddaca5 | 1821 | "add\t%1, %_, %0") |
001e2308 | 1822 | |
998032ba | 1823 | (define_insn "embmedany_textuhi" |
1824 | [(set (match_operand:DI 0 "register_operand" "=r") | |
40cc626c | 1825 | (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))] |
998032ba | 1826 | "TARGET_CM_EMBMEDANY && check_pic (1)" |
a4ddaca5 | 1827 | "sethi\t%%uhi(%a1), %0") |
001e2308 | 1828 | |
998032ba | 1829 | (define_insn "embmedany_texthi" |
1830 | [(set (match_operand:DI 0 "register_operand" "=r") | |
40cc626c | 1831 | (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))] |
998032ba | 1832 | "TARGET_CM_EMBMEDANY && check_pic (1)" |
a4ddaca5 | 1833 | "sethi\t%%hi(%a1), %0") |
001e2308 | 1834 | |
998032ba | 1835 | (define_insn "embmedany_textulo" |
1836 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1837 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
40cc626c | 1838 | (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))] |
998032ba | 1839 | "TARGET_CM_EMBMEDANY" |
a4ddaca5 | 1840 | "or\t%1, %%ulo(%a2), %0") |
bdf74c8a | 1841 | |
998032ba | 1842 | (define_insn "embmedany_textlo" |
1843 | [(set (match_operand:DI 0 "register_operand" "=r") | |
1844 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
1845 | (match_operand:DI 2 "text_segment_operand" "")))] | |
1846 | "TARGET_CM_EMBMEDANY" | |
a4ddaca5 | 1847 | "or\t%1, %%lo(%a2), %0") |
001e2308 | 1848 | |
998032ba | 1849 | ;; Now some patterns to help reload out a bit. |
1850 | (define_expand "reload_indi" | |
1851 | [(parallel [(match_operand:DI 0 "register_operand" "=r") | |
1852 | (match_operand:DI 1 "immediate_operand" "") | |
1853 | (match_operand:TI 2 "register_operand" "=&r")])] | |
1854 | "(TARGET_CM_MEDANY | |
1855 | || TARGET_CM_EMBMEDANY) | |
1856 | && ! flag_pic" | |
001e2308 | 1857 | { |
c3479b10 | 1858 | sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]); |
998032ba | 1859 | DONE; |
0037630d | 1860 | }) |
001e2308 | 1861 | |
998032ba | 1862 | (define_expand "reload_outdi" |
1863 | [(parallel [(match_operand:DI 0 "register_operand" "=r") | |
1864 | (match_operand:DI 1 "immediate_operand" "") | |
1865 | (match_operand:TI 2 "register_operand" "=&r")])] | |
1866 | "(TARGET_CM_MEDANY | |
1867 | || TARGET_CM_EMBMEDANY) | |
1868 | && ! flag_pic" | |
a44201ea | 1869 | { |
c3479b10 | 1870 | sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]); |
998032ba | 1871 | DONE; |
0037630d | 1872 | }) |
a44201ea | 1873 | |
998032ba | 1874 | ;; Split up putting CONSTs and REGs into DI regs when !arch64 |
1875 | (define_split | |
1876 | [(set (match_operand:DI 0 "register_operand" "") | |
1877 | (match_operand:DI 1 "const_int_operand" ""))] | |
afcea937 | 1878 | "! TARGET_ARCH64 |
1879 | && ((GET_CODE (operands[0]) == REG | |
1880 | && SPARC_INT_REG_P (REGNO (operands[0]))) | |
1881 | || (GET_CODE (operands[0]) == SUBREG | |
1882 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
1883 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0]))))) | |
1884 | && reload_completed" | |
998032ba | 1885 | [(clobber (const_int 0))] |
f618d313 | 1886 | { |
463f13bf | 1887 | #if HOST_BITS_PER_WIDE_INT == 32 |
998032ba | 1888 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), |
1889 | (INTVAL (operands[1]) < 0) ? | |
1890 | constm1_rtx : | |
1891 | const0_rtx)); | |
1892 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
1893 | operands[1])); | |
463f13bf | 1894 | #else |
e0db3f6a | 1895 | HOST_WIDE_INT low, high; |
463f13bf | 1896 | |
fb124916 | 1897 | low = trunc_int_for_mode (INTVAL (operands[1]), SImode); |
1898 | high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode); | |
463f13bf | 1899 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high))); |
1900 | ||
1901 | /* Slick... but this trick loses if this subreg constant part | |
1902 | can be done in one insn. */ | |
3a191813 | 1903 | if (low == high |
1904 | && ! SPARC_SETHI32_P (high) | |
1905 | && ! SPARC_SIMM13_P (high)) | |
463f13bf | 1906 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), |
1907 | gen_highpart (SImode, operands[0]))); | |
1908 | else | |
1909 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low))); | |
1910 | #endif | |
998032ba | 1911 | DONE; |
0037630d | 1912 | }) |
f618d313 | 1913 | |
f618d313 | 1914 | (define_split |
998032ba | 1915 | [(set (match_operand:DI 0 "register_operand" "") |
1916 | (match_operand:DI 1 "const_double_operand" ""))] | |
9251aedd | 1917 | "reload_completed |
1918 | && (! TARGET_V9 | |
1919 | || (! TARGET_ARCH64 | |
1920 | && ((GET_CODE (operands[0]) == REG | |
308d5709 | 1921 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
9251aedd | 1922 | || (GET_CODE (operands[0]) == SUBREG |
1923 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
308d5709 | 1924 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))" |
998032ba | 1925 | [(clobber (const_int 0))] |
1ee01ec7 | 1926 | { |
998032ba | 1927 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), |
1928 | GEN_INT (CONST_DOUBLE_HIGH (operands[1])))); | |
1929 | ||
1930 | /* Slick... but this trick loses if this subreg constant part | |
1931 | can be done in one insn. */ | |
1932 | if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1]) | |
3bb6b41e | 1933 | && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1])) |
1934 | && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))) | |
001e2308 | 1935 | { |
998032ba | 1936 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), |
1937 | gen_highpart (SImode, operands[0]))); | |
001e2308 | 1938 | } |
998032ba | 1939 | else |
1940 | { | |
1941 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
1942 | GEN_INT (CONST_DOUBLE_LOW (operands[1])))); | |
1943 | } | |
1944 | DONE; | |
0037630d | 1945 | }) |
a44201ea | 1946 | |
998032ba | 1947 | (define_split |
1948 | [(set (match_operand:DI 0 "register_operand" "") | |
1949 | (match_operand:DI 1 "register_operand" ""))] | |
cf7838f0 | 1950 | "reload_completed |
1951 | && (! TARGET_V9 | |
1952 | || (! TARGET_ARCH64 | |
f8b63509 | 1953 | && sparc_split_regreg_legitimate (operands[0], |
1954 | operands[1])))" | |
998032ba | 1955 | [(clobber (const_int 0))] |
998032ba | 1956 | { |
1957 | rtx set_dest = operands[0]; | |
1958 | rtx set_src = operands[1]; | |
1959 | rtx dest1, dest2; | |
1960 | rtx src1, src2; | |
a44201ea | 1961 | |
998032ba | 1962 | dest1 = gen_highpart (SImode, set_dest); |
1963 | dest2 = gen_lowpart (SImode, set_dest); | |
1964 | src1 = gen_highpart (SImode, set_src); | |
1965 | src2 = gen_lowpart (SImode, set_src); | |
1966 | ||
1967 | /* Now emit using the real source and destination we found, swapping | |
1968 | the order if we detect overlap. */ | |
cf220fd0 | 1969 | if (reg_overlap_mentioned_p (dest1, src2)) |
998032ba | 1970 | { |
1971 | emit_insn (gen_movsi (dest2, src2)); | |
1972 | emit_insn (gen_movsi (dest1, src1)); | |
1973 | } | |
1974 | else | |
1975 | { | |
1976 | emit_insn (gen_movsi (dest1, src1)); | |
1977 | emit_insn (gen_movsi (dest2, src2)); | |
1978 | } | |
1979 | DONE; | |
0037630d | 1980 | }) |
998032ba | 1981 | |
1982 | ;; Now handle the cases of memory moves from/to non-even | |
1983 | ;; DI mode register pairs. | |
1984 | (define_split | |
1985 | [(set (match_operand:DI 0 "register_operand" "") | |
1986 | (match_operand:DI 1 "memory_operand" ""))] | |
1987 | "(! TARGET_ARCH64 | |
1988 | && reload_completed | |
1989 | && sparc_splitdi_legitimate (operands[0], operands[1]))" | |
1990 | [(clobber (const_int 0))] | |
93fed860 | 1991 | { |
e513d163 | 1992 | rtx word0 = adjust_address (operands[1], SImode, 0); |
b244d4c7 | 1993 | rtx word1 = adjust_address (operands[1], SImode, 4); |
998032ba | 1994 | rtx high_part = gen_highpart (SImode, operands[0]); |
1995 | rtx low_part = gen_lowpart (SImode, operands[0]); | |
998032ba | 1996 | |
2558754e | 1997 | if (reg_overlap_mentioned_p (high_part, word1)) |
93fed860 | 1998 | { |
998032ba | 1999 | emit_insn (gen_movsi (low_part, word1)); |
2000 | emit_insn (gen_movsi (high_part, word0)); | |
93fed860 | 2001 | } |
998032ba | 2002 | else |
2003 | { | |
2004 | emit_insn (gen_movsi (high_part, word0)); | |
2005 | emit_insn (gen_movsi (low_part, word1)); | |
2006 | } | |
2007 | DONE; | |
0037630d | 2008 | }) |
998032ba | 2009 | |
2010 | (define_split | |
2011 | [(set (match_operand:DI 0 "memory_operand" "") | |
2012 | (match_operand:DI 1 "register_operand" ""))] | |
2013 | "(! TARGET_ARCH64 | |
2014 | && reload_completed | |
2015 | && sparc_splitdi_legitimate (operands[1], operands[0]))" | |
2016 | [(clobber (const_int 0))] | |
998032ba | 2017 | { |
b244d4c7 | 2018 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), |
2019 | gen_highpart (SImode, operands[1]))); | |
2020 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), | |
2021 | gen_lowpart (SImode, operands[1]))); | |
998032ba | 2022 | DONE; |
0037630d | 2023 | }) |
998032ba | 2024 | |
5fd280eb | 2025 | (define_split |
2026 | [(set (match_operand:DI 0 "memory_operand" "") | |
3a191813 | 2027 | (match_operand:DI 1 "const_zero_operand" ""))] |
5fd280eb | 2028 | "reload_completed |
2029 | && (! TARGET_V9 | |
2030 | || (! TARGET_ARCH64 | |
2031 | && ! mem_min_alignment (operands[0], 8))) | |
2032 | && offsettable_memref_p (operands[0])" | |
2033 | [(clobber (const_int 0))] | |
5fd280eb | 2034 | { |
2035 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx)); | |
2036 | emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx)); | |
2037 | DONE; | |
0037630d | 2038 | }) |
93fed860 | 2039 | |
635e0e88 | 2040 | (define_expand "movti" |
2041 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
2042 | (match_operand:TI 1 "general_operand" ""))] | |
2043 | "TARGET_ARCH64" | |
2044 | { | |
2045 | if (sparc_expand_move (TImode, operands)) | |
2046 | DONE; | |
2047 | }) | |
2048 | ||
2049 | ;; We need to prevent reload from splitting TImode moves, because it | |
2050 | ;; might decide to overwrite a pointer with the value it points to. | |
2051 | ;; In that case we have to do the loads in the appropriate order so | |
2052 | ;; that the pointer is not destroyed too early. | |
2053 | ||
2054 | (define_insn "*movti_insn_sp64" | |
2055 | [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b") | |
2056 | (match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))] | |
2057 | "TARGET_ARCH64 | |
2058 | && ! TARGET_HARD_QUAD | |
2059 | && (register_operand (operands[0], TImode) | |
2060 | || register_or_zero_operand (operands[1], TImode))" | |
2061 | "#" | |
2062 | [(set_attr "length" "2,2,2,2,2") | |
2063 | (set_attr "cpu_feature" "*,*,fpu,fpu,vis")]) | |
2064 | ||
2065 | (define_insn "*movti_insn_sp64_hq" | |
2066 | [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b") | |
2067 | (match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))] | |
2068 | "TARGET_ARCH64 | |
2069 | && TARGET_HARD_QUAD | |
2070 | && (register_operand (operands[0], TImode) | |
2071 | || register_or_zero_operand (operands[1], TImode))" | |
2072 | "@ | |
2073 | # | |
2074 | # | |
2075 | fmovq\t%1, %0 | |
2076 | ldq\t%1, %0 | |
2077 | stq\t%1, %0 | |
2078 | #" | |
2079 | [(set_attr "type" "*,*,fpmove,fpload,fpstore,*") | |
2080 | (set_attr "length" "2,2,*,*,*,2")]) | |
2081 | ||
2082 | ;; Now all the splits to handle multi-insn TI mode moves. | |
2083 | (define_split | |
2084 | [(set (match_operand:TI 0 "register_operand" "") | |
2085 | (match_operand:TI 1 "register_operand" ""))] | |
2086 | "reload_completed | |
2087 | && ((TARGET_FPU | |
2088 | && ! TARGET_HARD_QUAD) | |
2089 | || (! fp_register_operand (operands[0], TImode) | |
2090 | && ! fp_register_operand (operands[1], TImode)))" | |
2091 | [(clobber (const_int 0))] | |
2092 | { | |
2093 | rtx set_dest = operands[0]; | |
2094 | rtx set_src = operands[1]; | |
2095 | rtx dest1, dest2; | |
2096 | rtx src1, src2; | |
2097 | ||
2098 | dest1 = gen_highpart (DImode, set_dest); | |
2099 | dest2 = gen_lowpart (DImode, set_dest); | |
2100 | src1 = gen_highpart (DImode, set_src); | |
2101 | src2 = gen_lowpart (DImode, set_src); | |
2102 | ||
2103 | /* Now emit using the real source and destination we found, swapping | |
2104 | the order if we detect overlap. */ | |
2105 | if (reg_overlap_mentioned_p (dest1, src2)) | |
2106 | { | |
2107 | emit_insn (gen_movdi (dest2, src2)); | |
2108 | emit_insn (gen_movdi (dest1, src1)); | |
2109 | } | |
2110 | else | |
2111 | { | |
2112 | emit_insn (gen_movdi (dest1, src1)); | |
2113 | emit_insn (gen_movdi (dest2, src2)); | |
2114 | } | |
2115 | DONE; | |
2116 | }) | |
2117 | ||
2118 | (define_split | |
2119 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
2120 | (match_operand:TI 1 "const_zero_operand" ""))] | |
2121 | "reload_completed" | |
2122 | [(clobber (const_int 0))] | |
2123 | { | |
2124 | rtx set_dest = operands[0]; | |
2125 | rtx dest1, dest2; | |
2126 | ||
2127 | switch (GET_CODE (set_dest)) | |
2128 | { | |
2129 | case REG: | |
2130 | dest1 = gen_highpart (DImode, set_dest); | |
2131 | dest2 = gen_lowpart (DImode, set_dest); | |
2132 | break; | |
2133 | case MEM: | |
2134 | dest1 = adjust_address (set_dest, DImode, 0); | |
2135 | dest2 = adjust_address (set_dest, DImode, 8); | |
2136 | break; | |
2137 | default: | |
2138 | gcc_unreachable (); | |
2139 | } | |
2140 | ||
2141 | emit_insn (gen_movdi (dest1, const0_rtx)); | |
2142 | emit_insn (gen_movdi (dest2, const0_rtx)); | |
2143 | DONE; | |
2144 | }) | |
2145 | ||
2146 | (define_split | |
2147 | [(set (match_operand:TI 0 "register_operand" "") | |
2148 | (match_operand:TI 1 "memory_operand" ""))] | |
2149 | "reload_completed | |
2150 | && offsettable_memref_p (operands[1]) | |
2151 | && (! TARGET_HARD_QUAD | |
2152 | || ! fp_register_operand (operands[0], TImode))" | |
2153 | [(clobber (const_int 0))] | |
2154 | { | |
2155 | rtx word0 = adjust_address (operands[1], DImode, 0); | |
2156 | rtx word1 = adjust_address (operands[1], DImode, 8); | |
2157 | rtx set_dest, dest1, dest2; | |
2158 | ||
2159 | set_dest = operands[0]; | |
2160 | ||
2161 | dest1 = gen_highpart (DImode, set_dest); | |
2162 | dest2 = gen_lowpart (DImode, set_dest); | |
2163 | ||
2164 | /* Now output, ordering such that we don't clobber any registers | |
2165 | mentioned in the address. */ | |
2166 | if (reg_overlap_mentioned_p (dest1, word1)) | |
2167 | ||
2168 | { | |
2169 | emit_insn (gen_movdi (dest2, word1)); | |
2170 | emit_insn (gen_movdi (dest1, word0)); | |
2171 | } | |
2172 | else | |
2173 | { | |
2174 | emit_insn (gen_movdi (dest1, word0)); | |
2175 | emit_insn (gen_movdi (dest2, word1)); | |
2176 | } | |
2177 | DONE; | |
2178 | }) | |
2179 | ||
2180 | (define_split | |
2181 | [(set (match_operand:TI 0 "memory_operand" "") | |
2182 | (match_operand:TI 1 "register_operand" ""))] | |
2183 | "reload_completed | |
2184 | && offsettable_memref_p (operands[0]) | |
2185 | && (! TARGET_HARD_QUAD | |
2186 | || ! fp_register_operand (operands[1], TImode))" | |
2187 | [(clobber (const_int 0))] | |
2188 | { | |
2189 | rtx set_src = operands[1]; | |
2190 | ||
2191 | emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0), | |
2192 | gen_highpart (DImode, set_src))); | |
2193 | emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8), | |
2194 | gen_lowpart (DImode, set_src))); | |
2195 | DONE; | |
2196 | }) | |
2197 | ||
c3f211ea | 2198 | |
bc963728 | 2199 | ;; Floating point move instructions |
c3f211ea | 2200 | |
bc963728 | 2201 | (define_expand "movsf" |
2202 | [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
2203 | (match_operand:SF 1 "general_operand" ""))] | |
2204 | "" | |
d88ab5ca | 2205 | { |
bc963728 | 2206 | if (sparc_expand_move (SFmode, operands)) |
b6a32a23 | 2207 | DONE; |
d88ab5ca | 2208 | }) |
2209 | ||
4aa70596 | 2210 | (define_insn "*movsf_insn" |
973b45a7 | 2211 | [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m") |
2212 | (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))] | |
4aa70596 | 2213 | "(register_operand (operands[0], SFmode) |
2214 | || register_or_zero_or_all_ones_operand (operands[1], SFmode))" | |
30386ca0 | 2215 | { |
2216 | if (GET_CODE (operands[1]) == CONST_DOUBLE | |
2217 | && (which_alternative == 3 | |
2218 | || which_alternative == 4 | |
2219 | || which_alternative == 5)) | |
2220 | { | |
2221 | REAL_VALUE_TYPE r; | |
2222 | long i; | |
2223 | ||
2224 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
2225 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
2226 | operands[1] = GEN_INT (i); | |
2227 | } | |
2228 | ||
2229 | switch (which_alternative) | |
2230 | { | |
2231 | case 0: | |
2232 | return "fzeros\t%0"; | |
2233 | case 1: | |
2234 | return "fones\t%0"; | |
2235 | case 2: | |
2236 | return "fmovs\t%1, %0"; | |
2237 | case 3: | |
2238 | return "mov\t%1, %0"; | |
2239 | case 4: | |
2240 | return "sethi\t%%hi(%a1), %0"; | |
2241 | case 5: | |
2242 | return "#"; | |
2243 | case 6: | |
2244 | return "movstouw\t%1, %0"; | |
2245 | case 7: | |
2246 | return "movwtos\t%1, %0"; | |
2247 | case 8: | |
2248 | case 9: | |
2249 | return "ld\t%1, %0"; | |
2250 | case 10: | |
2251 | case 11: | |
2252 | return "st\t%r1, %0"; | |
2253 | default: | |
2254 | gcc_unreachable (); | |
2255 | } | |
2256 | } | |
d3cb8b93 | 2257 | [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store") |
4aa70596 | 2258 | (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")]) |
40dffe0b | 2259 | |
14935712 | 2260 | ;; The following 3 patterns build SFmode constants in integer registers. |
2261 | ||
a495126b | 2262 | (define_insn "*movsf_lo_sum" |
40dffe0b | 2263 | [(set (match_operand:SF 0 "register_operand" "=r") |
2264 | (lo_sum:SF (match_operand:SF 1 "register_operand" "r") | |
c3f211ea | 2265 | (match_operand:SF 2 "fp_const_high_losum_operand" "S")))] |
2266 | "" | |
a495126b | 2267 | { |
2268 | REAL_VALUE_TYPE r; | |
2269 | long i; | |
2270 | ||
2271 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); | |
2272 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
2273 | operands[2] = GEN_INT (i); | |
a4ddaca5 | 2274 | return "or\t%1, %%lo(%a2), %0"; |
0037630d | 2275 | }) |
1772450b | 2276 | |
a495126b | 2277 | (define_insn "*movsf_high" |
40dffe0b | 2278 | [(set (match_operand:SF 0 "register_operand" "=r") |
c3f211ea | 2279 | (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))] |
2280 | "" | |
1772450b | 2281 | { |
2282 | REAL_VALUE_TYPE r; | |
2283 | long i; | |
2284 | ||
2285 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
2286 | REAL_VALUE_TO_TARGET_SINGLE (r, i); | |
2287 | operands[1] = GEN_INT (i); | |
a4ddaca5 | 2288 | return "sethi\t%%hi(%1), %0"; |
0037630d | 2289 | }) |
a495126b | 2290 | |
2291 | (define_split | |
2292 | [(set (match_operand:SF 0 "register_operand" "") | |
c3f211ea | 2293 | (match_operand:SF 1 "fp_const_high_losum_operand" ""))] |
308d5709 | 2294 | "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))" |
a495126b | 2295 | [(set (match_dup 0) (high:SF (match_dup 1))) |
2296 | (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))]) | |
2297 | ||
bc963728 | 2298 | (define_expand "movdf" |
2299 | [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
2300 | (match_operand:DF 1 "general_operand" ""))] | |
2301 | "" | |
a44201ea | 2302 | { |
bc963728 | 2303 | if (sparc_expand_move (DFmode, operands)) |
b6a32a23 | 2304 | DONE; |
0037630d | 2305 | }) |
a44201ea | 2306 | |
998032ba | 2307 | (define_insn "*movdf_insn_sp32" |
5d3ad0ab | 2308 | [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o") |
2309 | (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))] | |
4aa70596 | 2310 | "! TARGET_ARCH64 |
bc963728 | 2311 | && (register_operand (operands[0], DFmode) |
2312 | || register_or_zero_or_all_ones_operand (operands[1], DFmode))" | |
611209d4 | 2313 | "@ |
a4ddaca5 | 2314 | fzero\t%0 |
bbfdec17 | 2315 | fone\t%0 |
a4ddaca5 | 2316 | fmovd\t%1, %0 |
611209d4 | 2317 | # |
2318 | # | |
30386ca0 | 2319 | # |
2320 | ldd\t%1, %0 | |
2321 | stx\t%r1, %0 | |
2322 | std\t%1, %0 | |
2323 | ldd\t%1, %0 | |
2324 | std\t%1, %0 | |
2325 | # | |
2326 | # | |
d88ab5ca | 2327 | # |
2328 | #" | |
d3cb8b93 | 2329 | [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*") |
4aa70596 | 2330 | (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2") |
2331 | (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*") | |
2332 | (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")]) | |
f2ed3c03 | 2333 | |
4aa70596 | 2334 | (define_insn "*movdf_insn_sp64" |
0db4cb41 | 2335 | [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r") |
973b45a7 | 2336 | (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))] |
4aa70596 | 2337 | "TARGET_ARCH64 |
30386ca0 | 2338 | && (register_operand (operands[0], DFmode) |
2339 | || register_or_zero_or_all_ones_operand (operands[1], DFmode))" | |
2340 | "@ | |
2341 | fzero\t%0 | |
2342 | fone\t%0 | |
2343 | fmovd\t%1, %0 | |
2344 | movdtox\t%1, %0 | |
2345 | movxtod\t%1, %0 | |
2346 | ldd\t%1, %0 | |
2347 | std\t%1, %0 | |
2348 | mov\t%r1, %0 | |
2349 | ldx\t%1, %0 | |
2350 | stx\t%r1, %0 | |
2351 | #" | |
d3cb8b93 | 2352 | [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*") |
30386ca0 | 2353 | (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2") |
4aa70596 | 2354 | (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*") |
2355 | (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")]) | |
420a824d | 2356 | |
bc963728 | 2357 | ;; This pattern builds DFmode constants in integer registers. |
14a72bf6 | 2358 | (define_split |
bc963728 | 2359 | [(set (match_operand:DF 0 "register_operand" "") |
2360 | (match_operand:DF 1 "const_double_operand" ""))] | |
973b45a7 | 2361 | "REG_P (operands[0]) |
2362 | && SPARC_INT_REG_P (REGNO (operands[0])) | |
83c0aede | 2363 | && ! const_zero_operand (operands[1], GET_MODE (operands[0])) |
14a72bf6 | 2364 | && reload_completed" |
2365 | [(clobber (const_int 0))] | |
14a72bf6 | 2366 | { |
14a72bf6 | 2367 | operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0])); |
2368 | ||
2369 | if (TARGET_ARCH64) | |
2370 | { | |
3bb6b41e | 2371 | #if HOST_BITS_PER_WIDE_INT == 32 |
2372 | gcc_unreachable (); | |
2373 | #else | |
3754d046 | 2374 | machine_mode mode = GET_MODE (operands[1]); |
83c0aede | 2375 | rtx tem = simplify_subreg (DImode, operands[1], mode, 0); |
2376 | emit_insn (gen_movdi (operands[0], tem)); | |
14a72bf6 | 2377 | #endif |
2378 | } | |
2379 | else | |
2380 | { | |
3754d046 | 2381 | machine_mode mode = GET_MODE (operands[1]); |
83c0aede | 2382 | rtx hi = simplify_subreg (SImode, operands[1], mode, 0); |
2383 | rtx lo = simplify_subreg (SImode, operands[1], mode, 4); | |
2384 | ||
2385 | gcc_assert (GET_CODE (hi) == CONST_INT); | |
2386 | gcc_assert (GET_CODE (lo) == CONST_INT); | |
2387 | ||
2388 | emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi)); | |
14a72bf6 | 2389 | |
2390 | /* Slick... but this trick loses if this subreg constant part | |
2391 | can be done in one insn. */ | |
83c0aede | 2392 | if (lo == hi |
2393 | && ! SPARC_SETHI32_P (INTVAL (hi)) | |
2394 | && ! SPARC_SIMM13_P (INTVAL (hi))) | |
14a72bf6 | 2395 | { |
2396 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), | |
2397 | gen_highpart (SImode, operands[0]))); | |
2398 | } | |
2399 | else | |
2400 | { | |
83c0aede | 2401 | emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo)); |
14a72bf6 | 2402 | } |
2403 | } | |
2404 | DONE; | |
0037630d | 2405 | }) |
14a72bf6 | 2406 | |
998032ba | 2407 | ;; Ok, now the splits to handle all the multi insn and |
2408 | ;; mis-aligned memory address cases. | |
611209d4 | 2409 | ;; In these splits please take note that we must be |
2410 | ;; careful when V9 but not ARCH64 because the integer | |
2411 | ;; register DFmode cases must be handled. | |
690c31d5 | 2412 | (define_split |
bc963728 | 2413 | [(set (match_operand:DF 0 "register_operand" "") |
2414 | (match_operand:DF 1 "register_operand" ""))] | |
611209d4 | 2415 | "(! TARGET_V9 |
2416 | || (! TARGET_ARCH64 | |
f8b63509 | 2417 | && sparc_split_regreg_legitimate (operands[0], |
2418 | operands[1]))) | |
611209d4 | 2419 | && reload_completed" |
998032ba | 2420 | [(clobber (const_int 0))] |
d17f168a | 2421 | { |
998032ba | 2422 | rtx set_dest = operands[0]; |
2423 | rtx set_src = operands[1]; | |
2424 | rtx dest1, dest2; | |
2425 | rtx src1, src2; | |
2426 | ||
bc963728 | 2427 | dest1 = gen_highpart (SFmode, set_dest); |
2428 | dest2 = gen_lowpart (SFmode, set_dest); | |
2429 | src1 = gen_highpart (SFmode, set_src); | |
2430 | src2 = gen_lowpart (SFmode, set_src); | |
998032ba | 2431 | |
2432 | /* Now emit using the real source and destination we found, swapping | |
2433 | the order if we detect overlap. */ | |
cf220fd0 | 2434 | if (reg_overlap_mentioned_p (dest1, src2)) |
d17f168a | 2435 | { |
14935712 | 2436 | emit_move_insn_1 (dest2, src2); |
2437 | emit_move_insn_1 (dest1, src1); | |
d17f168a | 2438 | } |
2439 | else | |
2440 | { | |
14935712 | 2441 | emit_move_insn_1 (dest1, src1); |
2442 | emit_move_insn_1 (dest2, src2); | |
d17f168a | 2443 | } |
998032ba | 2444 | DONE; |
0037630d | 2445 | }) |
690c31d5 | 2446 | |
998032ba | 2447 | (define_split |
bc963728 | 2448 | [(set (match_operand:DF 0 "register_operand" "") |
2449 | (match_operand:DF 1 "memory_operand" ""))] | |
14a72bf6 | 2450 | "reload_completed |
2451 | && ! TARGET_ARCH64 | |
2452 | && (((REGNO (operands[0]) % 2) != 0) | |
2453 | || ! mem_min_alignment (operands[1], 8)) | |
2454 | && offsettable_memref_p (operands[1])" | |
998032ba | 2455 | [(clobber (const_int 0))] |
a44201ea | 2456 | { |
14935712 | 2457 | rtx word0, word1; |
2458 | ||
bc963728 | 2459 | word0 = adjust_address (operands[1], SFmode, 0); |
2460 | word1 = adjust_address (operands[1], SFmode, 4); | |
998032ba | 2461 | |
bc963728 | 2462 | if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1)) |
998032ba | 2463 | { |
bc963728 | 2464 | emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1); |
2465 | emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0); | |
998032ba | 2466 | } |
a44201ea | 2467 | else |
03cdbc29 | 2468 | { |
bc963728 | 2469 | emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0); |
2470 | emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1); | |
03cdbc29 | 2471 | } |
998032ba | 2472 | DONE; |
0037630d | 2473 | }) |
998032ba | 2474 | |
2475 | (define_split | |
bc963728 | 2476 | [(set (match_operand:DF 0 "memory_operand" "") |
2477 | (match_operand:DF 1 "register_operand" ""))] | |
14a72bf6 | 2478 | "reload_completed |
2479 | && ! TARGET_ARCH64 | |
2480 | && (((REGNO (operands[1]) % 2) != 0) | |
2481 | || ! mem_min_alignment (operands[0], 8)) | |
2482 | && offsettable_memref_p (operands[0])" | |
998032ba | 2483 | [(clobber (const_int 0))] |
998032ba | 2484 | { |
14935712 | 2485 | rtx word0, word1; |
998032ba | 2486 | |
bc963728 | 2487 | word0 = adjust_address (operands[0], SFmode, 0); |
2488 | word1 = adjust_address (operands[0], SFmode, 4); | |
14935712 | 2489 | |
bc963728 | 2490 | emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1])); |
2491 | emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1])); | |
998032ba | 2492 | DONE; |
0037630d | 2493 | }) |
03cdbc29 | 2494 | |
a5c6cf42 | 2495 | (define_split |
bc963728 | 2496 | [(set (match_operand:DF 0 "memory_operand" "") |
2497 | (match_operand:DF 1 "const_zero_operand" ""))] | |
14a72bf6 | 2498 | "reload_completed |
2499 | && (! TARGET_V9 | |
2500 | || (! TARGET_ARCH64 | |
2501 | && ! mem_min_alignment (operands[0], 8))) | |
2502 | && offsettable_memref_p (operands[0])" | |
2503 | [(clobber (const_int 0))] | |
a5c6cf42 | 2504 | { |
14a72bf6 | 2505 | rtx dest1, dest2; |
a5c6cf42 | 2506 | |
bc963728 | 2507 | dest1 = adjust_address (operands[0], SFmode, 0); |
2508 | dest2 = adjust_address (operands[0], SFmode, 4); | |
14935712 | 2509 | |
bc963728 | 2510 | emit_move_insn_1 (dest1, CONST0_RTX (SFmode)); |
2511 | emit_move_insn_1 (dest2, CONST0_RTX (SFmode)); | |
14a72bf6 | 2512 | DONE; |
0037630d | 2513 | }) |
a5c6cf42 | 2514 | |
2515 | (define_split | |
bc963728 | 2516 | [(set (match_operand:DF 0 "register_operand" "") |
2517 | (match_operand:DF 1 "const_zero_operand" ""))] | |
14a72bf6 | 2518 | "reload_completed |
2519 | && ! TARGET_ARCH64 | |
2520 | && ((GET_CODE (operands[0]) == REG | |
308d5709 | 2521 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
14a72bf6 | 2522 | || (GET_CODE (operands[0]) == SUBREG |
2523 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
308d5709 | 2524 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
14a72bf6 | 2525 | [(clobber (const_int 0))] |
a5c6cf42 | 2526 | { |
14a72bf6 | 2527 | rtx set_dest = operands[0]; |
2528 | rtx dest1, dest2; | |
2529 | ||
bc963728 | 2530 | dest1 = gen_highpart (SFmode, set_dest); |
2531 | dest2 = gen_lowpart (SFmode, set_dest); | |
2532 | emit_move_insn_1 (dest1, CONST0_RTX (SFmode)); | |
2533 | emit_move_insn_1 (dest2, CONST0_RTX (SFmode)); | |
14a72bf6 | 2534 | DONE; |
0037630d | 2535 | }) |
a5c6cf42 | 2536 | |
1ee01ec7 | 2537 | (define_expand "movtf" |
b6a32a23 | 2538 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
1ee01ec7 | 2539 | (match_operand:TF 1 "general_operand" ""))] |
a44201ea | 2540 | "" |
a44201ea | 2541 | { |
b6a32a23 | 2542 | if (sparc_expand_move (TFmode, operands)) |
2543 | DONE; | |
0037630d | 2544 | }) |
a44201ea | 2545 | |
998032ba | 2546 | (define_insn "*movtf_insn_sp32" |
5d3ad0ab | 2547 | [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r") |
2548 | (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))] | |
48d1ee37 | 2549 | "! TARGET_ARCH64 |
1ee01ec7 | 2550 | && (register_operand (operands[0], TFmode) |
c3f211ea | 2551 | || register_or_zero_operand (operands[1], TFmode))" |
998032ba | 2552 | "#" |
48d1ee37 | 2553 | [(set_attr "length" "4,4,4,4,4,4") |
2554 | (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")]) | |
998032ba | 2555 | |
d88ab5ca | 2556 | (define_insn "*movtf_insn_sp64" |
48d1ee37 | 2557 | [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r") |
2558 | (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))] | |
2559 | "TARGET_ARCH64 | |
d88ab5ca | 2560 | && ! TARGET_HARD_QUAD |
2561 | && (register_operand (operands[0], TFmode) | |
2562 | || register_or_zero_operand (operands[1], TFmode))" | |
2563 | "#" | |
48d1ee37 | 2564 | [(set_attr "length" "2,2,2,2,2") |
2565 | (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")]) | |
d88ab5ca | 2566 | |
c3f211ea | 2567 | (define_insn "*movtf_insn_sp64_hq" |
973b45a7 | 2568 | [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r") |
2569 | (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))] | |
48d1ee37 | 2570 | "TARGET_ARCH64 |
998032ba | 2571 | && TARGET_HARD_QUAD |
2572 | && (register_operand (operands[0], TFmode) | |
c3f211ea | 2573 | || register_or_zero_operand (operands[1], TFmode))" |
14a72bf6 | 2574 | "@ |
14a72bf6 | 2575 | # |
a4ddaca5 | 2576 | fmovq\t%1, %0 |
2577 | ldq\t%1, %0 | |
2578 | stq\t%1, %0 | |
998032ba | 2579 | # |
998032ba | 2580 | #" |
c3f211ea | 2581 | [(set_attr "type" "*,fpmove,fpload,fpstore,*,*") |
2582 | (set_attr "length" "2,*,*,*,2,2")]) | |
998032ba | 2583 | |
998032ba | 2584 | ;; Now all the splits to handle multi-insn TF mode moves. |
2585 | (define_split | |
2586 | [(set (match_operand:TF 0 "register_operand" "") | |
2587 | (match_operand:TF 1 "register_operand" ""))] | |
2588 | "reload_completed | |
2589 | && (! TARGET_ARCH64 | |
2590 | || (TARGET_FPU | |
fbeafc33 | 2591 | && ! TARGET_HARD_QUAD) |
30386ca0 | 2592 | || (! fp_register_operand (operands[0], TFmode) |
2593 | && ! fp_register_operand (operands[1], TFmode)))" | |
998032ba | 2594 | [(clobber (const_int 0))] |
1ee01ec7 | 2595 | { |
998032ba | 2596 | rtx set_dest = operands[0]; |
2597 | rtx set_src = operands[1]; | |
2598 | rtx dest1, dest2; | |
2599 | rtx src1, src2; | |
2600 | ||
ab151623 | 2601 | dest1 = gen_df_reg (set_dest, 0); |
2602 | dest2 = gen_df_reg (set_dest, 1); | |
2603 | src1 = gen_df_reg (set_src, 0); | |
2604 | src2 = gen_df_reg (set_src, 1); | |
998032ba | 2605 | |
2606 | /* Now emit using the real source and destination we found, swapping | |
2607 | the order if we detect overlap. */ | |
cf220fd0 | 2608 | if (reg_overlap_mentioned_p (dest1, src2)) |
998032ba | 2609 | { |
2610 | emit_insn (gen_movdf (dest2, src2)); | |
2611 | emit_insn (gen_movdf (dest1, src1)); | |
2612 | } | |
1ee01ec7 | 2613 | else |
998032ba | 2614 | { |
2615 | emit_insn (gen_movdf (dest1, src1)); | |
2616 | emit_insn (gen_movdf (dest2, src2)); | |
2617 | } | |
2618 | DONE; | |
0037630d | 2619 | }) |
998032ba | 2620 | |
14a72bf6 | 2621 | (define_split |
2622 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
27b36d57 | 2623 | (match_operand:TF 1 "const_zero_operand" ""))] |
14a72bf6 | 2624 | "reload_completed" |
2625 | [(clobber (const_int 0))] | |
14a72bf6 | 2626 | { |
2627 | rtx set_dest = operands[0]; | |
2628 | rtx dest1, dest2; | |
2629 | ||
2630 | switch (GET_CODE (set_dest)) | |
2631 | { | |
14a72bf6 | 2632 | case REG: |
2633 | dest1 = gen_df_reg (set_dest, 0); | |
2634 | dest2 = gen_df_reg (set_dest, 1); | |
2635 | break; | |
2636 | case MEM: | |
e513d163 | 2637 | dest1 = adjust_address (set_dest, DFmode, 0); |
b244d4c7 | 2638 | dest2 = adjust_address (set_dest, DFmode, 8); |
14a72bf6 | 2639 | break; |
2640 | default: | |
635e0e88 | 2641 | gcc_unreachable (); |
14a72bf6 | 2642 | } |
2643 | ||
2644 | emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode))); | |
2645 | emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode))); | |
2646 | DONE; | |
0037630d | 2647 | }) |
14a72bf6 | 2648 | |
998032ba | 2649 | (define_split |
2650 | [(set (match_operand:TF 0 "register_operand" "") | |
2651 | (match_operand:TF 1 "memory_operand" ""))] | |
2652 | "(reload_completed | |
fbeafc33 | 2653 | && offsettable_memref_p (operands[1]) |
2654 | && (! TARGET_ARCH64 | |
2655 | || ! TARGET_HARD_QUAD | |
2656 | || ! fp_register_operand (operands[0], TFmode)))" | |
998032ba | 2657 | [(clobber (const_int 0))] |
998032ba | 2658 | { |
e513d163 | 2659 | rtx word0 = adjust_address (operands[1], DFmode, 0); |
b244d4c7 | 2660 | rtx word1 = adjust_address (operands[1], DFmode, 8); |
8c61c8e6 | 2661 | rtx set_dest, dest1, dest2; |
2662 | ||
2663 | set_dest = operands[0]; | |
998032ba | 2664 | |
ab151623 | 2665 | dest1 = gen_df_reg (set_dest, 0); |
2666 | dest2 = gen_df_reg (set_dest, 1); | |
ce5150c5 | 2667 | |
2668 | /* Now output, ordering such that we don't clobber any registers | |
2669 | mentioned in the address. */ | |
2558754e | 2670 | if (reg_overlap_mentioned_p (dest1, word1)) |
2671 | ||
ce5150c5 | 2672 | { |
2673 | emit_insn (gen_movdf (dest2, word1)); | |
2674 | emit_insn (gen_movdf (dest1, word0)); | |
2675 | } | |
2676 | else | |
2677 | { | |
2678 | emit_insn (gen_movdf (dest1, word0)); | |
2679 | emit_insn (gen_movdf (dest2, word1)); | |
2680 | } | |
998032ba | 2681 | DONE; |
0037630d | 2682 | }) |
998032ba | 2683 | |
2684 | (define_split | |
2685 | [(set (match_operand:TF 0 "memory_operand" "") | |
2686 | (match_operand:TF 1 "register_operand" ""))] | |
2687 | "(reload_completed | |
fbeafc33 | 2688 | && offsettable_memref_p (operands[0]) |
2689 | && (! TARGET_ARCH64 | |
2690 | || ! TARGET_HARD_QUAD | |
2691 | || ! fp_register_operand (operands[1], TFmode)))" | |
998032ba | 2692 | [(clobber (const_int 0))] |
998032ba | 2693 | { |
b244d4c7 | 2694 | rtx set_src = operands[1]; |
8c61c8e6 | 2695 | |
b244d4c7 | 2696 | emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0), |
2697 | gen_df_reg (set_src, 0))); | |
2698 | emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8), | |
2699 | gen_df_reg (set_src, 1))); | |
998032ba | 2700 | DONE; |
0037630d | 2701 | }) |
d88ab5ca | 2702 | |
2703 | ||
fa17c3f9 | 2704 | ;; SPARC-V9 conditional move instructions |
001e2308 | 2705 | |
8b27d6ba | 2706 | ;; We can handle larger constants here for some flavors, but for now we keep |
808a491c | 2707 | ;; it simple and only allow those constants supported by all flavors. |
c74468c0 | 2708 | ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand |
2709 | ;; 3 contains the constant if one is present, but we handle either for | |
2710 | ;; generality (sparc.c puts a constant in operand 2). | |
6c53772f | 2711 | ;; |
2712 | ;; Our instruction patterns, on the other hand, canonicalize such that | |
2713 | ;; operand 3 must be the set destination. | |
c74468c0 | 2714 | |
fa17c3f9 | 2715 | (define_expand "mov<I:mode>cc" |
2716 | [(set (match_operand:I 0 "register_operand" "") | |
2717 | (if_then_else:I (match_operand 1 "comparison_operator" "") | |
2718 | (match_operand:I 2 "arith10_operand" "") | |
2719 | (match_operand:I 3 "arith10_operand" "")))] | |
2720 | "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" | |
3a7728cc | 2721 | { |
6c53772f | 2722 | if (! sparc_expand_conditional_move (<I:MODE>mode, operands)) |
c74468c0 | 2723 | FAIL; |
6c53772f | 2724 | DONE; |
74f4459c | 2725 | }) |
3a7728cc | 2726 | |
fa17c3f9 | 2727 | (define_expand "mov<F:mode>cc" |
2728 | [(set (match_operand:F 0 "register_operand" "") | |
2729 | (if_then_else:F (match_operand 1 "comparison_operator" "") | |
2730 | (match_operand:F 2 "register_operand" "") | |
2731 | (match_operand:F 3 "register_operand" "")))] | |
c74468c0 | 2732 | "TARGET_V9 && TARGET_FPU" |
3a7728cc | 2733 | { |
6c53772f | 2734 | if (! sparc_expand_conditional_move (<F:MODE>mode, operands)) |
c74468c0 | 2735 | FAIL; |
6c53772f | 2736 | DONE; |
0037630d | 2737 | }) |
3a7728cc | 2738 | |
fa17c3f9 | 2739 | ;; Conditional move define_insns |
001e2308 | 2740 | |
fa17c3f9 | 2741 | (define_insn "*mov<I:mode>_cc_v9" |
6c53772f | 2742 | [(set (match_operand:I 0 "register_operand" "=r") |
fa17c3f9 | 2743 | (if_then_else:I (match_operator 1 "comparison_operator" |
6c53772f | 2744 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
fa17c3f9 | 2745 | (const_int 0)]) |
6c53772f | 2746 | (match_operand:I 3 "arith11_operand" "rL") |
2747 | (match_operand:I 4 "register_operand" "0")))] | |
fa17c3f9 | 2748 | "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)" |
6c53772f | 2749 | "mov%C1\t%x2, %3, %0" |
a9208abf | 2750 | [(set_attr "type" "cmove")]) |
998032ba | 2751 | |
fa17c3f9 | 2752 | (define_insn "*mov<I:mode>_cc_reg_sp64" |
6c53772f | 2753 | [(set (match_operand:I 0 "register_operand" "=r") |
fa17c3f9 | 2754 | (if_then_else:I (match_operator 1 "v9_register_compare_operator" |
6c53772f | 2755 | [(match_operand:DI 2 "register_operand" "r") |
998032ba | 2756 | (const_int 0)]) |
6c53772f | 2757 | (match_operand:I 3 "arith10_operand" "rM") |
2758 | (match_operand:I 4 "register_operand" "0")))] | |
998032ba | 2759 | "TARGET_ARCH64" |
6c53772f | 2760 | "movr%D1\t%2, %r3, %0" |
a9208abf | 2761 | [(set_attr "type" "cmove")]) |
001e2308 | 2762 | |
fa17c3f9 | 2763 | (define_insn "*movsf_cc_v9" |
6c53772f | 2764 | [(set (match_operand:SF 0 "register_operand" "=f") |
c74468c0 | 2765 | (if_then_else:SF (match_operator 1 "comparison_operator" |
6c53772f | 2766 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
001e2308 | 2767 | (const_int 0)]) |
6c53772f | 2768 | (match_operand:SF 3 "register_operand" "f") |
2769 | (match_operand:SF 4 "register_operand" "0")))] | |
c74468c0 | 2770 | "TARGET_V9 && TARGET_FPU" |
6c53772f | 2771 | "fmovs%C1\t%x2, %3, %0" |
a9208abf | 2772 | [(set_attr "type" "fpcmove")]) |
001e2308 | 2773 | |
fa17c3f9 | 2774 | (define_insn "*movsf_cc_reg_sp64" |
6c53772f | 2775 | [(set (match_operand:SF 0 "register_operand" "=f") |
fa17c3f9 | 2776 | (if_then_else:SF (match_operator 1 "v9_register_compare_operator" |
6c53772f | 2777 | [(match_operand:DI 2 "register_operand" "r") |
fa17c3f9 | 2778 | (const_int 0)]) |
6c53772f | 2779 | (match_operand:SF 3 "register_operand" "f") |
2780 | (match_operand:SF 4 "register_operand" "0")))] | |
fa17c3f9 | 2781 | "TARGET_ARCH64 && TARGET_FPU" |
6c53772f | 2782 | "fmovrs%D1\t%2, %3, %0" |
fa17c3f9 | 2783 | [(set_attr "type" "fpcrmove")]) |
2784 | ||
2785 | ;; Named because invoked by movtf_cc_v9 | |
2786 | (define_insn "movdf_cc_v9" | |
6c53772f | 2787 | [(set (match_operand:DF 0 "register_operand" "=e") |
c74468c0 | 2788 | (if_then_else:DF (match_operator 1 "comparison_operator" |
6c53772f | 2789 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
001e2308 | 2790 | (const_int 0)]) |
6c53772f | 2791 | (match_operand:DF 3 "register_operand" "e") |
2792 | (match_operand:DF 4 "register_operand" "0")))] | |
c74468c0 | 2793 | "TARGET_V9 && TARGET_FPU" |
6c53772f | 2794 | "fmovd%C1\t%x2, %3, %0" |
998032ba | 2795 | [(set_attr "type" "fpcmove") |
a9208abf | 2796 | (set_attr "fptype" "double")]) |
001e2308 | 2797 | |
fa17c3f9 | 2798 | ;; Named because invoked by movtf_cc_reg_sp64 |
2799 | (define_insn "movdf_cc_reg_sp64" | |
6c53772f | 2800 | [(set (match_operand:DF 0 "register_operand" "=e") |
fa17c3f9 | 2801 | (if_then_else:DF (match_operator 1 "v9_register_compare_operator" |
6c53772f | 2802 | [(match_operand:DI 2 "register_operand" "r") |
fa17c3f9 | 2803 | (const_int 0)]) |
6c53772f | 2804 | (match_operand:DF 3 "register_operand" "e") |
2805 | (match_operand:DF 4 "register_operand" "0")))] | |
fa17c3f9 | 2806 | "TARGET_ARCH64 && TARGET_FPU" |
6c53772f | 2807 | "fmovrd%D1\t%2, %3, %0" |
fa17c3f9 | 2808 | [(set_attr "type" "fpcrmove") |
2809 | (set_attr "fptype" "double")]) | |
2810 | ||
2811 | (define_insn "*movtf_cc_hq_v9" | |
6c53772f | 2812 | [(set (match_operand:TF 0 "register_operand" "=e") |
c74468c0 | 2813 | (if_then_else:TF (match_operator 1 "comparison_operator" |
6c53772f | 2814 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
001e2308 | 2815 | (const_int 0)]) |
6c53772f | 2816 | (match_operand:TF 3 "register_operand" "e") |
2817 | (match_operand:TF 4 "register_operand" "0")))] | |
142db97c | 2818 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
6c53772f | 2819 | "fmovq%C1\t%x2, %3, %0" |
a9208abf | 2820 | [(set_attr "type" "fpcmove")]) |
c74468c0 | 2821 | |
fa17c3f9 | 2822 | (define_insn "*movtf_cc_reg_hq_sp64" |
6c53772f | 2823 | [(set (match_operand:TF 0 "register_operand" "=e") |
fa17c3f9 | 2824 | (if_then_else:TF (match_operator 1 "v9_register_compare_operator" |
6c53772f | 2825 | [(match_operand:DI 2 "register_operand" "r") |
fa17c3f9 | 2826 | (const_int 0)]) |
6c53772f | 2827 | (match_operand:TF 3 "register_operand" "e") |
2828 | (match_operand:TF 4 "register_operand" "0")))] | |
fa17c3f9 | 2829 | "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" |
6c53772f | 2830 | "fmovrq%D1\t%2, %3, %0" |
fa17c3f9 | 2831 | [(set_attr "type" "fpcrmove")]) |
2832 | ||
2833 | (define_insn_and_split "*movtf_cc_v9" | |
6c53772f | 2834 | [(set (match_operand:TF 0 "register_operand" "=e") |
8c61c8e6 | 2835 | (if_then_else:TF (match_operator 1 "comparison_operator" |
6c53772f | 2836 | [(match_operand 2 "icc_or_fcc_register_operand" "X") |
43c08597 | 2837 | (const_int 0)]) |
6c53772f | 2838 | (match_operand:TF 3 "register_operand" "e") |
2839 | (match_operand:TF 4 "register_operand" "0")))] | |
8c61c8e6 | 2840 | "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" |
2841 | "#" | |
43c08597 | 2842 | "&& reload_completed" |
8c61c8e6 | 2843 | [(clobber (const_int 0))] |
8c61c8e6 | 2844 | { |
2845 | rtx set_dest = operands[0]; | |
2846 | rtx set_srca = operands[3]; | |
8c61c8e6 | 2847 | rtx dest1, dest2; |
6c53772f | 2848 | rtx srca1, srca2; |
8c61c8e6 | 2849 | |
ab151623 | 2850 | dest1 = gen_df_reg (set_dest, 0); |
2851 | dest2 = gen_df_reg (set_dest, 1); | |
2852 | srca1 = gen_df_reg (set_srca, 0); | |
2853 | srca2 = gen_df_reg (set_srca, 1); | |
8c61c8e6 | 2854 | |
6c53772f | 2855 | if (reg_overlap_mentioned_p (dest1, srca2)) |
8c61c8e6 | 2856 | { |
6c53772f | 2857 | emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2)); |
2858 | emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1)); | |
8c61c8e6 | 2859 | } |
2860 | else | |
2861 | { | |
6c53772f | 2862 | emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1)); |
2863 | emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2)); | |
8c61c8e6 | 2864 | } |
2865 | DONE; | |
0037630d | 2866 | } |
43c08597 | 2867 | [(set_attr "length" "2")]) |
8c61c8e6 | 2868 | |
43c08597 | 2869 | (define_insn_and_split "*movtf_cc_reg_sp64" |
6c53772f | 2870 | [(set (match_operand:TF 0 "register_operand" "=e") |
27b36d57 | 2871 | (if_then_else:TF (match_operator 1 "v9_register_compare_operator" |
6c53772f | 2872 | [(match_operand:DI 2 "register_operand" "r") |
8c61c8e6 | 2873 | (const_int 0)]) |
6c53772f | 2874 | (match_operand:TF 3 "register_operand" "e") |
2875 | (match_operand:TF 4 "register_operand" "0")))] | |
8c61c8e6 | 2876 | "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD" |
2877 | "#" | |
43c08597 | 2878 | "&& reload_completed" |
8c61c8e6 | 2879 | [(clobber (const_int 0))] |
8c61c8e6 | 2880 | { |
2881 | rtx set_dest = operands[0]; | |
2882 | rtx set_srca = operands[3]; | |
8c61c8e6 | 2883 | rtx dest1, dest2; |
6c53772f | 2884 | rtx srca1, srca2; |
8c61c8e6 | 2885 | |
ab151623 | 2886 | dest1 = gen_df_reg (set_dest, 0); |
2887 | dest2 = gen_df_reg (set_dest, 1); | |
2888 | srca1 = gen_df_reg (set_srca, 0); | |
2889 | srca2 = gen_df_reg (set_srca, 1); | |
8c61c8e6 | 2890 | |
6c53772f | 2891 | if (reg_overlap_mentioned_p (dest1, srca2)) |
8c61c8e6 | 2892 | { |
6c53772f | 2893 | emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2)); |
2894 | emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1)); | |
8c61c8e6 | 2895 | } |
2896 | else | |
2897 | { | |
6c53772f | 2898 | emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1)); |
2899 | emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2)); | |
8c61c8e6 | 2900 | } |
2901 | DONE; | |
0037630d | 2902 | } |
43c08597 | 2903 | [(set_attr "length" "2")]) |
8c61c8e6 | 2904 | |
001e2308 | 2905 | \f |
d88ab5ca | 2906 | ;; Zero-extension instructions |
a44201ea | 2907 | |
2908 | ;; These patterns originally accepted general_operands, however, slightly | |
2909 | ;; better code is generated by only accepting register_operands, and then | |
2910 | ;; letting combine generate the ldu[hb] insns. | |
2911 | ||
2912 | (define_expand "zero_extendhisi2" | |
2913 | [(set (match_operand:SI 0 "register_operand" "") | |
2914 | (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] | |
2915 | "" | |
a44201ea | 2916 | { |
2917 | rtx temp = gen_reg_rtx (SImode); | |
142db97c | 2918 | rtx shift_16 = GEN_INT (16); |
701e46d0 | 2919 | int op1_subbyte = 0; |
a44201ea | 2920 | |
2921 | if (GET_CODE (operand1) == SUBREG) | |
59eef41d | 2922 | { |
701e46d0 | 2923 | op1_subbyte = SUBREG_BYTE (operand1); |
2924 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
2925 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
59eef41d | 2926 | operand1 = XEXP (operand1, 0); |
2927 | } | |
a44201ea | 2928 | |
701e46d0 | 2929 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
a44201ea | 2930 | shift_16)); |
2931 | emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); | |
2932 | DONE; | |
0037630d | 2933 | }) |
a44201ea | 2934 | |
4117925c | 2935 | (define_insn "*zero_extendhisi2_insn" |
a44201ea | 2936 | [(set (match_operand:SI 0 "register_operand" "=r") |
2937 | (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
2938 | "" | |
a4ddaca5 | 2939 | "lduh\t%1, %0" |
bea4bad2 | 2940 | [(set_attr "type" "load") |
2941 | (set_attr "us3load_type" "3cycle")]) | |
a44201ea | 2942 | |
2943 | (define_expand "zero_extendqihi2" | |
2944 | [(set (match_operand:HI 0 "register_operand" "") | |
2945 | (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] | |
2946 | "" | |
2947 | "") | |
2948 | ||
4117925c | 2949 | (define_insn "*zero_extendqihi2_insn" |
7a179223 | 2950 | [(set (match_operand:HI 0 "register_operand" "=r,r") |
998032ba | 2951 | (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))] |
a44201ea | 2952 | "GET_CODE (operands[1]) != CONST_INT" |
2953 | "@ | |
a4ddaca5 | 2954 | and\t%1, 0xff, %0 |
2955 | ldub\t%1, %0" | |
bea4bad2 | 2956 | [(set_attr "type" "*,load") |
2957 | (set_attr "us3load_type" "*,3cycle")]) | |
a44201ea | 2958 | |
2959 | (define_expand "zero_extendqisi2" | |
2960 | [(set (match_operand:SI 0 "register_operand" "") | |
2961 | (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] | |
2962 | "" | |
2963 | "") | |
2964 | ||
4117925c | 2965 | (define_insn "*zero_extendqisi2_insn" |
7a179223 | 2966 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
998032ba | 2967 | (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))] |
a44201ea | 2968 | "GET_CODE (operands[1]) != CONST_INT" |
2969 | "@ | |
a4ddaca5 | 2970 | and\t%1, 0xff, %0 |
2971 | ldub\t%1, %0" | |
bea4bad2 | 2972 | [(set_attr "type" "*,load") |
2973 | (set_attr "us3load_type" "*,3cycle")]) | |
a44201ea | 2974 | |
001e2308 | 2975 | (define_expand "zero_extendqidi2" |
2976 | [(set (match_operand:DI 0 "register_operand" "") | |
2977 | (zero_extend:DI (match_operand:QI 1 "register_operand" "")))] | |
df5e9319 | 2978 | "TARGET_ARCH64" |
001e2308 | 2979 | "") |
2980 | ||
4117925c | 2981 | (define_insn "*zero_extendqidi2_insn" |
001e2308 | 2982 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
998032ba | 2983 | (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))] |
df5e9319 | 2984 | "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT" |
001e2308 | 2985 | "@ |
a4ddaca5 | 2986 | and\t%1, 0xff, %0 |
2987 | ldub\t%1, %0" | |
bea4bad2 | 2988 | [(set_attr "type" "*,load") |
2989 | (set_attr "us3load_type" "*,3cycle")]) | |
001e2308 | 2990 | |
2991 | (define_expand "zero_extendhidi2" | |
2992 | [(set (match_operand:DI 0 "register_operand" "") | |
2993 | (zero_extend:DI (match_operand:HI 1 "register_operand" "")))] | |
df5e9319 | 2994 | "TARGET_ARCH64" |
001e2308 | 2995 | { |
2996 | rtx temp = gen_reg_rtx (DImode); | |
142db97c | 2997 | rtx shift_48 = GEN_INT (48); |
701e46d0 | 2998 | int op1_subbyte = 0; |
001e2308 | 2999 | |
3000 | if (GET_CODE (operand1) == SUBREG) | |
3001 | { | |
701e46d0 | 3002 | op1_subbyte = SUBREG_BYTE (operand1); |
3003 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
3004 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
001e2308 | 3005 | operand1 = XEXP (operand1, 0); |
3006 | } | |
3007 | ||
701e46d0 | 3008 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
001e2308 | 3009 | shift_48)); |
3010 | emit_insn (gen_lshrdi3 (operand0, temp, shift_48)); | |
3011 | DONE; | |
0037630d | 3012 | }) |
001e2308 | 3013 | |
4117925c | 3014 | (define_insn "*zero_extendhidi2_insn" |
001e2308 | 3015 | [(set (match_operand:DI 0 "register_operand" "=r") |
3016 | (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] | |
df5e9319 | 3017 | "TARGET_ARCH64" |
a4ddaca5 | 3018 | "lduh\t%1, %0" |
bea4bad2 | 3019 | [(set_attr "type" "load") |
3020 | (set_attr "us3load_type" "3cycle")]) | |
001e2308 | 3021 | |
3022 | ;; ??? Write truncdisi pattern using sra? | |
3023 | ||
3024 | (define_expand "zero_extendsidi2" | |
3025 | [(set (match_operand:DI 0 "register_operand" "") | |
3026 | (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] | |
35415df4 | 3027 | "" |
001e2308 | 3028 | "") |
3029 | ||
4aa70596 | 3030 | (define_insn "*zero_extendsidi2_insn_sp64" |
30386ca0 | 3031 | [(set (match_operand:DI 0 "register_operand" "=r,r,r") |
3032 | (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))] | |
3033 | "TARGET_ARCH64 | |
30386ca0 | 3034 | && GET_CODE (operands[1]) != CONST_INT" |
3035 | "@ | |
3036 | srl\t%1, 0, %0 | |
3037 | lduw\t%1, %0 | |
3038 | movstouw\t%1, %0" | |
4aa70596 | 3039 | [(set_attr "type" "shift,load,*") |
3040 | (set_attr "cpu_feature" "*,*,vis3")]) | |
30386ca0 | 3041 | |
43c08597 | 3042 | (define_insn_and_split "*zero_extendsidi2_insn_sp32" |
35415df4 | 3043 | [(set (match_operand:DI 0 "register_operand" "=r") |
3044 | (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] | |
3045 | "! TARGET_ARCH64" | |
3046 | "#" | |
43c08597 | 3047 | "&& reload_completed" |
35415df4 | 3048 | [(set (match_dup 2) (match_dup 3)) |
3049 | (set (match_dup 4) (match_dup 5))] | |
35415df4 | 3050 | { |
3051 | rtx dest1, dest2; | |
3052 | ||
35415df4 | 3053 | dest1 = gen_highpart (SImode, operands[0]); |
3054 | dest2 = gen_lowpart (SImode, operands[0]); | |
3055 | ||
3056 | /* Swap the order in case of overlap. */ | |
3057 | if (REGNO (dest1) == REGNO (operands[1])) | |
3058 | { | |
3059 | operands[2] = dest2; | |
3060 | operands[3] = operands[1]; | |
3061 | operands[4] = dest1; | |
3062 | operands[5] = const0_rtx; | |
3063 | } | |
3064 | else | |
3065 | { | |
3066 | operands[2] = dest1; | |
3067 | operands[3] = const0_rtx; | |
3068 | operands[4] = dest2; | |
3069 | operands[5] = operands[1]; | |
3070 | } | |
0037630d | 3071 | } |
43c08597 | 3072 | [(set_attr "length" "2")]) |
35415df4 | 3073 | |
001e2308 | 3074 | ;; Simplify comparisons of extended values. |
3075 | ||
4117925c | 3076 | (define_insn "*cmp_zero_extendqisi2" |
2b25173f | 3077 | [(set (reg:CC CC_REG) |
a44201ea | 3078 | (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) |
3079 | (const_int 0)))] | |
f8be3dfc | 3080 | "" |
a4ddaca5 | 3081 | "andcc\t%0, 0xff, %%g0" |
a9208abf | 3082 | [(set_attr "type" "compare")]) |
a44201ea | 3083 | |
e07f852f | 3084 | (define_insn "*cmp_zero_qi" |
2b25173f | 3085 | [(set (reg:CC CC_REG) |
e07f852f | 3086 | (compare:CC (match_operand:QI 0 "register_operand" "r") |
3087 | (const_int 0)))] | |
f8be3dfc | 3088 | "" |
a4ddaca5 | 3089 | "andcc\t%0, 0xff, %%g0" |
a9208abf | 3090 | [(set_attr "type" "compare")]) |
e07f852f | 3091 | |
4117925c | 3092 | (define_insn "*cmp_zero_extendqisi2_set" |
2b25173f | 3093 | [(set (reg:CC CC_REG) |
a44201ea | 3094 | (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) |
3095 | (const_int 0))) | |
3096 | (set (match_operand:SI 0 "register_operand" "=r") | |
3097 | (zero_extend:SI (match_dup 1)))] | |
3098 | "" | |
a4ddaca5 | 3099 | "andcc\t%1, 0xff, %0" |
a9208abf | 3100 | [(set_attr "type" "compare")]) |
998032ba | 3101 | |
e07f852f | 3102 | (define_insn "*cmp_zero_extendqisi2_andcc_set" |
2b25173f | 3103 | [(set (reg:CC CC_REG) |
e07f852f | 3104 | (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r") |
3105 | (const_int 255)) | |
3106 | (const_int 0))) | |
3107 | (set (match_operand:SI 0 "register_operand" "=r") | |
3108 | (zero_extend:SI (subreg:QI (match_dup 1) 0)))] | |
3109 | "" | |
a4ddaca5 | 3110 | "andcc\t%1, 0xff, %0" |
a9208abf | 3111 | [(set_attr "type" "compare")]) |
e07f852f | 3112 | |
998032ba | 3113 | (define_insn "*cmp_zero_extendqidi2" |
2b25173f | 3114 | [(set (reg:CCX CC_REG) |
998032ba | 3115 | (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r")) |
3116 | (const_int 0)))] | |
3117 | "TARGET_ARCH64" | |
a4ddaca5 | 3118 | "andcc\t%0, 0xff, %%g0" |
a9208abf | 3119 | [(set_attr "type" "compare")]) |
998032ba | 3120 | |
e07f852f | 3121 | (define_insn "*cmp_zero_qi_sp64" |
2b25173f | 3122 | [(set (reg:CCX CC_REG) |
e07f852f | 3123 | (compare:CCX (match_operand:QI 0 "register_operand" "r") |
3124 | (const_int 0)))] | |
3125 | "TARGET_ARCH64" | |
a4ddaca5 | 3126 | "andcc\t%0, 0xff, %%g0" |
a9208abf | 3127 | [(set_attr "type" "compare")]) |
e07f852f | 3128 | |
998032ba | 3129 | (define_insn "*cmp_zero_extendqidi2_set" |
2b25173f | 3130 | [(set (reg:CCX CC_REG) |
998032ba | 3131 | (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) |
3132 | (const_int 0))) | |
3133 | (set (match_operand:DI 0 "register_operand" "=r") | |
3134 | (zero_extend:DI (match_dup 1)))] | |
3135 | "TARGET_ARCH64" | |
a4ddaca5 | 3136 | "andcc\t%1, 0xff, %0" |
a9208abf | 3137 | [(set_attr "type" "compare")]) |
44d13235 | 3138 | |
e07f852f | 3139 | (define_insn "*cmp_zero_extendqidi2_andcc_set" |
2b25173f | 3140 | [(set (reg:CCX CC_REG) |
e07f852f | 3141 | (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r") |
3142 | (const_int 255)) | |
3143 | (const_int 0))) | |
3144 | (set (match_operand:DI 0 "register_operand" "=r") | |
3145 | (zero_extend:DI (subreg:QI (match_dup 1) 0)))] | |
3146 | "TARGET_ARCH64" | |
a4ddaca5 | 3147 | "andcc\t%1, 0xff, %0" |
a9208abf | 3148 | [(set_attr "type" "compare")]) |
e07f852f | 3149 | |
998032ba | 3150 | ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare. |
44d13235 | 3151 | |
4117925c | 3152 | (define_insn "*cmp_siqi_trunc" |
2b25173f | 3153 | [(set (reg:CC CC_REG) |
701e46d0 | 3154 | (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3) |
44d13235 | 3155 | (const_int 0)))] |
f8be3dfc | 3156 | "" |
a4ddaca5 | 3157 | "andcc\t%0, 0xff, %%g0" |
a9208abf | 3158 | [(set_attr "type" "compare")]) |
44d13235 | 3159 | |
4117925c | 3160 | (define_insn "*cmp_siqi_trunc_set" |
2b25173f | 3161 | [(set (reg:CC CC_REG) |
701e46d0 | 3162 | (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3) |
44d13235 | 3163 | (const_int 0))) |
3164 | (set (match_operand:QI 0 "register_operand" "=r") | |
701e46d0 | 3165 | (subreg:QI (match_dup 1) 3))] |
44d13235 | 3166 | "" |
a4ddaca5 | 3167 | "andcc\t%1, 0xff, %0" |
a9208abf | 3168 | [(set_attr "type" "compare")]) |
998032ba | 3169 | |
3170 | (define_insn "*cmp_diqi_trunc" | |
2b25173f | 3171 | [(set (reg:CC CC_REG) |
701e46d0 | 3172 | (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7) |
998032ba | 3173 | (const_int 0)))] |
3174 | "TARGET_ARCH64" | |
a4ddaca5 | 3175 | "andcc\t%0, 0xff, %%g0" |
a9208abf | 3176 | [(set_attr "type" "compare")]) |
998032ba | 3177 | |
3178 | (define_insn "*cmp_diqi_trunc_set" | |
2b25173f | 3179 | [(set (reg:CC CC_REG) |
701e46d0 | 3180 | (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7) |
998032ba | 3181 | (const_int 0))) |
3182 | (set (match_operand:QI 0 "register_operand" "=r") | |
701e46d0 | 3183 | (subreg:QI (match_dup 1) 7))] |
998032ba | 3184 | "TARGET_ARCH64" |
a4ddaca5 | 3185 | "andcc\t%1, 0xff, %0" |
a9208abf | 3186 | [(set_attr "type" "compare")]) |
a44201ea | 3187 | \f |
d88ab5ca | 3188 | |
3189 | ;; Sign-extension instructions | |
a44201ea | 3190 | |
3191 | ;; These patterns originally accepted general_operands, however, slightly | |
3192 | ;; better code is generated by only accepting register_operands, and then | |
3193 | ;; letting combine generate the lds[hb] insns. | |
3194 | ||
3195 | (define_expand "extendhisi2" | |
3196 | [(set (match_operand:SI 0 "register_operand" "") | |
3197 | (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] | |
3198 | "" | |
a44201ea | 3199 | { |
3200 | rtx temp = gen_reg_rtx (SImode); | |
142db97c | 3201 | rtx shift_16 = GEN_INT (16); |
701e46d0 | 3202 | int op1_subbyte = 0; |
a44201ea | 3203 | |
3204 | if (GET_CODE (operand1) == SUBREG) | |
59eef41d | 3205 | { |
701e46d0 | 3206 | op1_subbyte = SUBREG_BYTE (operand1); |
3207 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
3208 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
59eef41d | 3209 | operand1 = XEXP (operand1, 0); |
3210 | } | |
a44201ea | 3211 | |
701e46d0 | 3212 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
a44201ea | 3213 | shift_16)); |
3214 | emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); | |
3215 | DONE; | |
0037630d | 3216 | }) |
a44201ea | 3217 | |
4117925c | 3218 | (define_insn "*sign_extendhisi2_insn" |
a44201ea | 3219 | [(set (match_operand:SI 0 "register_operand" "=r") |
3220 | (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] | |
3221 | "" | |
a4ddaca5 | 3222 | "ldsh\t%1, %0" |
bea4bad2 | 3223 | [(set_attr "type" "sload") |
3224 | (set_attr "us3load_type" "3cycle")]) | |
a44201ea | 3225 | |
001e2308 | 3226 | (define_expand "extendqihi2" |
3227 | [(set (match_operand:HI 0 "register_operand" "") | |
3228 | (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] | |
3229 | "" | |
001e2308 | 3230 | { |
3231 | rtx temp = gen_reg_rtx (SImode); | |
142db97c | 3232 | rtx shift_24 = GEN_INT (24); |
701e46d0 | 3233 | int op1_subbyte = 0; |
3234 | int op0_subbyte = 0; | |
001e2308 | 3235 | |
3236 | if (GET_CODE (operand1) == SUBREG) | |
3237 | { | |
701e46d0 | 3238 | op1_subbyte = SUBREG_BYTE (operand1); |
3239 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
3240 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
001e2308 | 3241 | operand1 = XEXP (operand1, 0); |
3242 | } | |
3243 | if (GET_CODE (operand0) == SUBREG) | |
3244 | { | |
701e46d0 | 3245 | op0_subbyte = SUBREG_BYTE (operand0); |
3246 | op0_subbyte /= GET_MODE_SIZE (SImode); | |
3247 | op0_subbyte *= GET_MODE_SIZE (SImode); | |
001e2308 | 3248 | operand0 = XEXP (operand0, 0); |
3249 | } | |
701e46d0 | 3250 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
001e2308 | 3251 | shift_24)); |
3252 | if (GET_MODE (operand0) != SImode) | |
701e46d0 | 3253 | operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte); |
001e2308 | 3254 | emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); |
3255 | DONE; | |
0037630d | 3256 | }) |
001e2308 | 3257 | |
4117925c | 3258 | (define_insn "*sign_extendqihi2_insn" |
001e2308 | 3259 | [(set (match_operand:HI 0 "register_operand" "=r") |
3260 | (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] | |
3261 | "" | |
a4ddaca5 | 3262 | "ldsb\t%1, %0" |
bea4bad2 | 3263 | [(set_attr "type" "sload") |
3264 | (set_attr "us3load_type" "3cycle")]) | |
001e2308 | 3265 | |
3266 | (define_expand "extendqisi2" | |
3267 | [(set (match_operand:SI 0 "register_operand" "") | |
3268 | (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] | |
3269 | "" | |
001e2308 | 3270 | { |
3271 | rtx temp = gen_reg_rtx (SImode); | |
142db97c | 3272 | rtx shift_24 = GEN_INT (24); |
701e46d0 | 3273 | int op1_subbyte = 0; |
001e2308 | 3274 | |
3275 | if (GET_CODE (operand1) == SUBREG) | |
3276 | { | |
701e46d0 | 3277 | op1_subbyte = SUBREG_BYTE (operand1); |
3278 | op1_subbyte /= GET_MODE_SIZE (SImode); | |
3279 | op1_subbyte *= GET_MODE_SIZE (SImode); | |
001e2308 | 3280 | operand1 = XEXP (operand1, 0); |
3281 | } | |
3282 | ||
701e46d0 | 3283 | emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte), |
001e2308 | 3284 | shift_24)); |
3285 | emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); | |
3286 | DONE; | |
0037630d | 3287 | }) |
001e2308 | 3288 | |
4117925c | 3289 | (define_insn "*sign_extendqisi2_insn" |
001e2308 | 3290 | [(set (match_operand:SI 0 "register_operand" "=r") |
3291 | (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] | |
3292 | "" | |
a4ddaca5 | 3293 | "ldsb\t%1, %0" |
bea4bad2 | 3294 | [(set_attr "type" "sload") |
3295 | (set_attr "us3load_type" "3cycle")]) | |
001e2308 | 3296 | |
3297 | (define_expand "extendqidi2" | |
3298 | [(set (match_operand:DI 0 "register_operand" "") | |
3299 | (sign_extend:DI (match_operand:QI 1 "register_operand" "")))] | |
df5e9319 | 3300 | "TARGET_ARCH64" |
a44201ea | 3301 | { |
001e2308 | 3302 | rtx temp = gen_reg_rtx (DImode); |
142db97c | 3303 | rtx shift_56 = GEN_INT (56); |
701e46d0 | 3304 | int op1_subbyte = 0; |
a44201ea | 3305 | |
3306 | if (GET_CODE (operand1) == SUBREG) | |
59eef41d | 3307 | { |
701e46d0 | 3308 | op1_subbyte = SUBREG_BYTE (operand1); |
3309 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
3310 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
59eef41d | 3311 | operand1 = XEXP (operand1, 0); |
3312 | } | |
001e2308 | 3313 | |
701e46d0 | 3314 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
001e2308 | 3315 | shift_56)); |
3316 | emit_insn (gen_ashrdi3 (operand0, temp, shift_56)); | |
a44201ea | 3317 | DONE; |
0037630d | 3318 | }) |
a44201ea | 3319 | |
4117925c | 3320 | (define_insn "*sign_extendqidi2_insn" |
001e2308 | 3321 | [(set (match_operand:DI 0 "register_operand" "=r") |
3322 | (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] | |
df5e9319 | 3323 | "TARGET_ARCH64" |
a4ddaca5 | 3324 | "ldsb\t%1, %0" |
bea4bad2 | 3325 | [(set_attr "type" "sload") |
3326 | (set_attr "us3load_type" "3cycle")]) | |
a44201ea | 3327 | |
001e2308 | 3328 | (define_expand "extendhidi2" |
3329 | [(set (match_operand:DI 0 "register_operand" "") | |
3330 | (sign_extend:DI (match_operand:HI 1 "register_operand" "")))] | |
df5e9319 | 3331 | "TARGET_ARCH64" |
a44201ea | 3332 | { |
001e2308 | 3333 | rtx temp = gen_reg_rtx (DImode); |
142db97c | 3334 | rtx shift_48 = GEN_INT (48); |
701e46d0 | 3335 | int op1_subbyte = 0; |
a44201ea | 3336 | |
3337 | if (GET_CODE (operand1) == SUBREG) | |
59eef41d | 3338 | { |
701e46d0 | 3339 | op1_subbyte = SUBREG_BYTE (operand1); |
3340 | op1_subbyte /= GET_MODE_SIZE (DImode); | |
3341 | op1_subbyte *= GET_MODE_SIZE (DImode); | |
59eef41d | 3342 | operand1 = XEXP (operand1, 0); |
3343 | } | |
3344 | ||
701e46d0 | 3345 | emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte), |
001e2308 | 3346 | shift_48)); |
3347 | emit_insn (gen_ashrdi3 (operand0, temp, shift_48)); | |
a44201ea | 3348 | DONE; |
0037630d | 3349 | }) |
a44201ea | 3350 | |
4117925c | 3351 | (define_insn "*sign_extendhidi2_insn" |
001e2308 | 3352 | [(set (match_operand:DI 0 "register_operand" "=r") |
3353 | (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] | |
df5e9319 | 3354 | "TARGET_ARCH64" |
a4ddaca5 | 3355 | "ldsh\t%1, %0" |
bea4bad2 | 3356 | [(set_attr "type" "sload") |
3357 | (set_attr "us3load_type" "3cycle")]) | |
001e2308 | 3358 | |
3359 | (define_expand "extendsidi2" | |
3360 | [(set (match_operand:DI 0 "register_operand" "") | |
3361 | (sign_extend:DI (match_operand:SI 1 "register_operand" "")))] | |
df5e9319 | 3362 | "TARGET_ARCH64" |
001e2308 | 3363 | "") |
3364 | ||
4aa70596 | 3365 | (define_insn "*sign_extendsidi2_insn" |
30386ca0 | 3366 | [(set (match_operand:DI 0 "register_operand" "=r,r,r") |
3367 | (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))] | |
4aa70596 | 3368 | "TARGET_ARCH64" |
30386ca0 | 3369 | "@ |
3370 | sra\t%1, 0, %0 | |
3371 | ldsw\t%1, %0 | |
3372 | movstosw\t%1, %0" | |
3373 | [(set_attr "type" "shift,sload,*") | |
4aa70596 | 3374 | (set_attr "us3load_type" "*,3cycle,*") |
3375 | (set_attr "cpu_feature" "*,*,vis3")]) | |
30386ca0 | 3376 | |
d88ab5ca | 3377 | |
bdf74c8a | 3378 | ;; Special pattern for optimizing bit-field compares. This is needed |
3379 | ;; because combine uses this as a canonical form. | |
3380 | ||
4117925c | 3381 | (define_insn "*cmp_zero_extract" |
2b25173f | 3382 | [(set (reg:CC CC_REG) |
bdf74c8a | 3383 | (compare:CC |
3384 | (zero_extract:SI (match_operand:SI 0 "register_operand" "r") | |
27b36d57 | 3385 | (match_operand:SI 1 "small_int_operand" "I") |
3386 | (match_operand:SI 2 "small_int_operand" "I")) | |
bdf74c8a | 3387 | (const_int 0)))] |
27b36d57 | 3388 | "INTVAL (operands[2]) > 19" |
3389 | { | |
3390 | int len = INTVAL (operands[1]); | |
3391 | int pos = 32 - INTVAL (operands[2]) - len; | |
19e6708e | 3392 | HOST_WIDE_INT mask = ((1 << len) - 1) << pos; |
142db97c | 3393 | operands[1] = GEN_INT (mask); |
a4ddaca5 | 3394 | return "andcc\t%0, %1, %%g0"; |
0037630d | 3395 | } |
a9208abf | 3396 | [(set_attr "type" "compare")]) |
001e2308 | 3397 | |
4117925c | 3398 | (define_insn "*cmp_zero_extract_sp64" |
2b25173f | 3399 | [(set (reg:CCX CC_REG) |
001e2308 | 3400 | (compare:CCX |
3401 | (zero_extract:DI (match_operand:DI 0 "register_operand" "r") | |
27b36d57 | 3402 | (match_operand:SI 1 "small_int_operand" "I") |
3403 | (match_operand:SI 2 "small_int_operand" "I")) | |
001e2308 | 3404 | (const_int 0)))] |
27b36d57 | 3405 | "TARGET_ARCH64 && INTVAL (operands[2]) > 51" |
3406 | { | |
3407 | int len = INTVAL (operands[1]); | |
3408 | int pos = 64 - INTVAL (operands[2]) - len; | |
19e6708e | 3409 | HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos; |
142db97c | 3410 | operands[1] = GEN_INT (mask); |
a4ddaca5 | 3411 | return "andcc\t%0, %1, %%g0"; |
0037630d | 3412 | } |
a9208abf | 3413 | [(set_attr "type" "compare")]) |
d88ab5ca | 3414 | |
3415 | ||
93fed860 | 3416 | ;; Conversions between float, double and long double. |
a44201ea | 3417 | |
3418 | (define_insn "extendsfdf2" | |
65ccdc13 | 3419 | [(set (match_operand:DF 0 "register_operand" "=e") |
a44201ea | 3420 | (float_extend:DF |
3421 | (match_operand:SF 1 "register_operand" "f")))] | |
f2ed3c03 | 3422 | "TARGET_FPU" |
a4ddaca5 | 3423 | "fstod\t%1, %0" |
998032ba | 3424 | [(set_attr "type" "fp") |
a9208abf | 3425 | (set_attr "fptype" "double")]) |
a44201ea | 3426 | |
75997b31 | 3427 | (define_expand "extendsftf2" |
c00088b6 | 3428 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
75997b31 | 3429 | (float_extend:TF |
c00088b6 | 3430 | (match_operand:SF 1 "register_operand" "")))] |
75997b31 | 3431 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 3432 | "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;") |
75997b31 | 3433 | |
3434 | (define_insn "*extendsftf2_hq" | |
65ccdc13 | 3435 | [(set (match_operand:TF 0 "register_operand" "=e") |
93fed860 | 3436 | (float_extend:TF |
3437 | (match_operand:SF 1 "register_operand" "f")))] | |
b0454100 | 3438 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 3439 | "fstoq\t%1, %0" |
a9208abf | 3440 | [(set_attr "type" "fp")]) |
93fed860 | 3441 | |
75997b31 | 3442 | (define_expand "extenddftf2" |
c00088b6 | 3443 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
75997b31 | 3444 | (float_extend:TF |
c00088b6 | 3445 | (match_operand:DF 1 "register_operand" "")))] |
75997b31 | 3446 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 3447 | "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;") |
75997b31 | 3448 | |
3449 | (define_insn "*extenddftf2_hq" | |
65ccdc13 | 3450 | [(set (match_operand:TF 0 "register_operand" "=e") |
93fed860 | 3451 | (float_extend:TF |
65ccdc13 | 3452 | (match_operand:DF 1 "register_operand" "e")))] |
b0454100 | 3453 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 3454 | "fdtoq\t%1, %0" |
a9208abf | 3455 | [(set_attr "type" "fp")]) |
93fed860 | 3456 | |
a44201ea | 3457 | (define_insn "truncdfsf2" |
3458 | [(set (match_operand:SF 0 "register_operand" "=f") | |
3459 | (float_truncate:SF | |
65ccdc13 | 3460 | (match_operand:DF 1 "register_operand" "e")))] |
f2ed3c03 | 3461 | "TARGET_FPU" |
a4ddaca5 | 3462 | "fdtos\t%1, %0" |
998032ba | 3463 | [(set_attr "type" "fp") |
07ae93ca | 3464 | (set_attr "fptype" "double") |
3465 | (set_attr "fptype_ut699" "single")]) | |
93fed860 | 3466 | |
75997b31 | 3467 | (define_expand "trunctfsf2" |
c00088b6 | 3468 | [(set (match_operand:SF 0 "register_operand" "") |
75997b31 | 3469 | (float_truncate:SF |
c00088b6 | 3470 | (match_operand:TF 1 "general_operand" "")))] |
75997b31 | 3471 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 3472 | "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;") |
75997b31 | 3473 | |
3474 | (define_insn "*trunctfsf2_hq" | |
93fed860 | 3475 | [(set (match_operand:SF 0 "register_operand" "=f") |
3476 | (float_truncate:SF | |
65ccdc13 | 3477 | (match_operand:TF 1 "register_operand" "e")))] |
b0454100 | 3478 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 3479 | "fqtos\t%1, %0" |
a9208abf | 3480 | [(set_attr "type" "fp")]) |
93fed860 | 3481 | |
75997b31 | 3482 | (define_expand "trunctfdf2" |
c00088b6 | 3483 | [(set (match_operand:DF 0 "register_operand" "") |
75997b31 | 3484 | (float_truncate:DF |
c00088b6 | 3485 | (match_operand:TF 1 "general_operand" "")))] |
75997b31 | 3486 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 3487 | "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;") |
75997b31 | 3488 | |
3489 | (define_insn "*trunctfdf2_hq" | |
65ccdc13 | 3490 | [(set (match_operand:DF 0 "register_operand" "=e") |
93fed860 | 3491 | (float_truncate:DF |
65ccdc13 | 3492 | (match_operand:TF 1 "register_operand" "e")))] |
b0454100 | 3493 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 3494 | "fqtod\t%1, %0" |
a9208abf | 3495 | [(set_attr "type" "fp")]) |
d88ab5ca | 3496 | |
3497 | ||
a44201ea | 3498 | ;; Conversion between fixed point and floating point. |
3499 | ||
3500 | (define_insn "floatsisf2" | |
72a06a96 | 3501 | [(set (match_operand:SF 0 "register_operand" "=f") |
3502 | (float:SF (match_operand:SI 1 "register_operand" "f")))] | |
f2ed3c03 | 3503 | "TARGET_FPU" |
a4ddaca5 | 3504 | "fitos\t%1, %0" |
998032ba | 3505 | [(set_attr "type" "fp") |
07ae93ca | 3506 | (set_attr "fptype" "single")]) |
a44201ea | 3507 | |
3508 | (define_insn "floatsidf2" | |
65ccdc13 | 3509 | [(set (match_operand:DF 0 "register_operand" "=e") |
72a06a96 | 3510 | (float:DF (match_operand:SI 1 "register_operand" "f")))] |
f2ed3c03 | 3511 | "TARGET_FPU" |
a4ddaca5 | 3512 | "fitod\t%1, %0" |
998032ba | 3513 | [(set_attr "type" "fp") |
a9208abf | 3514 | (set_attr "fptype" "double")]) |
a44201ea | 3515 | |
75997b31 | 3516 | (define_expand "floatsitf2" |
c00088b6 | 3517 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
3518 | (float:TF (match_operand:SI 1 "register_operand" "")))] | |
75997b31 | 3519 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 3520 | "emit_tfmode_cvt (FLOAT, operands); DONE;") |
75997b31 | 3521 | |
3522 | (define_insn "*floatsitf2_hq" | |
65ccdc13 | 3523 | [(set (match_operand:TF 0 "register_operand" "=e") |
72a06a96 | 3524 | (float:TF (match_operand:SI 1 "register_operand" "f")))] |
b0454100 | 3525 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 3526 | "fitoq\t%1, %0" |
a9208abf | 3527 | [(set_attr "type" "fp")]) |
93fed860 | 3528 | |
75997b31 | 3529 | (define_expand "floatunssitf2" |
c00088b6 | 3530 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
3531 | (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))] | |
75997b31 | 3532 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" |
c00088b6 | 3533 | "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;") |
75997b31 | 3534 | |
001e2308 | 3535 | ;; Now the same for 64 bit sources. |
001e2308 | 3536 | |
367242d3 | 3537 | (define_insn "floatdisf2" |
001e2308 | 3538 | [(set (match_operand:SF 0 "register_operand" "=f") |
65ccdc13 | 3539 | (float:SF (match_operand:DI 1 "register_operand" "e")))] |
367242d3 | 3540 | "TARGET_V9 && TARGET_FPU" |
a4ddaca5 | 3541 | "fxtos\t%1, %0" |
998032ba | 3542 | [(set_attr "type" "fp") |
a9208abf | 3543 | (set_attr "fptype" "double")]) |
001e2308 | 3544 | |
eef858ab | 3545 | (define_expand "floatunsdisf2" |
3546 | [(use (match_operand:SF 0 "register_operand" "")) | |
520b7351 | 3547 | (use (match_operand:DI 1 "general_operand" ""))] |
eef858ab | 3548 | "TARGET_ARCH64 && TARGET_FPU" |
520b7351 | 3549 | "sparc_emit_floatunsdi (operands, SFmode); DONE;") |
eef858ab | 3550 | |
367242d3 | 3551 | (define_insn "floatdidf2" |
65ccdc13 | 3552 | [(set (match_operand:DF 0 "register_operand" "=e") |
3553 | (float:DF (match_operand:DI 1 "register_operand" "e")))] | |
367242d3 | 3554 | "TARGET_V9 && TARGET_FPU" |
a4ddaca5 | 3555 | "fxtod\t%1, %0" |
998032ba | 3556 | [(set_attr "type" "fp") |
a9208abf | 3557 | (set_attr "fptype" "double")]) |
001e2308 | 3558 | |
eef858ab | 3559 | (define_expand "floatunsdidf2" |
3560 | [(use (match_operand:DF 0 "register_operand" "")) | |
520b7351 | 3561 | (use (match_operand:DI 1 "general_operand" ""))] |
eef858ab | 3562 | "TARGET_ARCH64 && TARGET_FPU" |
520b7351 | 3563 | "sparc_emit_floatunsdi (operands, DFmode); DONE;") |
eef858ab | 3564 | |
75997b31 | 3565 | (define_expand "floatditf2" |
c00088b6 | 3566 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
3567 | (float:TF (match_operand:DI 1 "register_operand" "")))] | |
75997b31 | 3568 | "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 3569 | "emit_tfmode_cvt (FLOAT, operands); DONE;") |
75997b31 | 3570 | |
3571 | (define_insn "*floatditf2_hq" | |
65ccdc13 | 3572 | [(set (match_operand:TF 0 "register_operand" "=e") |
3573 | (float:TF (match_operand:DI 1 "register_operand" "e")))] | |
367242d3 | 3574 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 3575 | "fxtoq\t%1, %0" |
a9208abf | 3576 | [(set_attr "type" "fp")]) |
001e2308 | 3577 | |
75997b31 | 3578 | (define_expand "floatunsditf2" |
c00088b6 | 3579 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
3580 | (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))] | |
75997b31 | 3581 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" |
c00088b6 | 3582 | "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;") |
75997b31 | 3583 | |
a44201ea | 3584 | ;; Convert a float to an actual integer. |
3585 | ;; Truncation is performed as part of the conversion. | |
3586 | ||
3587 | (define_insn "fix_truncsfsi2" | |
72a06a96 | 3588 | [(set (match_operand:SI 0 "register_operand" "=f") |
3589 | (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] | |
f2ed3c03 | 3590 | "TARGET_FPU" |
a4ddaca5 | 3591 | "fstoi\t%1, %0" |
998032ba | 3592 | [(set_attr "type" "fp") |
07ae93ca | 3593 | (set_attr "fptype" "single")]) |
a44201ea | 3594 | |
3595 | (define_insn "fix_truncdfsi2" | |
72a06a96 | 3596 | [(set (match_operand:SI 0 "register_operand" "=f") |
65ccdc13 | 3597 | (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] |
f2ed3c03 | 3598 | "TARGET_FPU" |
a4ddaca5 | 3599 | "fdtoi\t%1, %0" |
998032ba | 3600 | [(set_attr "type" "fp") |
07ae93ca | 3601 | (set_attr "fptype" "double") |
3602 | (set_attr "fptype_ut699" "single")]) | |
4495c759 | 3603 | |
75997b31 | 3604 | (define_expand "fix_trunctfsi2" |
c00088b6 | 3605 | [(set (match_operand:SI 0 "register_operand" "") |
3606 | (fix:SI (match_operand:TF 1 "general_operand" "")))] | |
75997b31 | 3607 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 3608 | "emit_tfmode_cvt (FIX, operands); DONE;") |
75997b31 | 3609 | |
3610 | (define_insn "*fix_trunctfsi2_hq" | |
72a06a96 | 3611 | [(set (match_operand:SI 0 "register_operand" "=f") |
c00088b6 | 3612 | (fix:SI (match_operand:TF 1 "register_operand" "e")))] |
b0454100 | 3613 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 3614 | "fqtoi\t%1, %0" |
a9208abf | 3615 | [(set_attr "type" "fp")]) |
001e2308 | 3616 | |
75997b31 | 3617 | (define_expand "fixuns_trunctfsi2" |
c00088b6 | 3618 | [(set (match_operand:SI 0 "register_operand" "") |
3619 | (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))] | |
75997b31 | 3620 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" |
c00088b6 | 3621 | "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;") |
75997b31 | 3622 | |
367242d3 | 3623 | ;; Now the same, for V9 targets |
001e2308 | 3624 | |
367242d3 | 3625 | (define_insn "fix_truncsfdi2" |
65ccdc13 | 3626 | [(set (match_operand:DI 0 "register_operand" "=e") |
001e2308 | 3627 | (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] |
367242d3 | 3628 | "TARGET_V9 && TARGET_FPU" |
a4ddaca5 | 3629 | "fstox\t%1, %0" |
998032ba | 3630 | [(set_attr "type" "fp") |
a9208abf | 3631 | (set_attr "fptype" "double")]) |
001e2308 | 3632 | |
520b7351 | 3633 | (define_expand "fixuns_truncsfdi2" |
3634 | [(use (match_operand:DI 0 "register_operand" "")) | |
3635 | (use (match_operand:SF 1 "general_operand" ""))] | |
3636 | "TARGET_ARCH64 && TARGET_FPU" | |
3637 | "sparc_emit_fixunsdi (operands, SFmode); DONE;") | |
3638 | ||
367242d3 | 3639 | (define_insn "fix_truncdfdi2" |
65ccdc13 | 3640 | [(set (match_operand:DI 0 "register_operand" "=e") |
3641 | (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] | |
367242d3 | 3642 | "TARGET_V9 && TARGET_FPU" |
a4ddaca5 | 3643 | "fdtox\t%1, %0" |
998032ba | 3644 | [(set_attr "type" "fp") |
a9208abf | 3645 | (set_attr "fptype" "double")]) |
001e2308 | 3646 | |
520b7351 | 3647 | (define_expand "fixuns_truncdfdi2" |
3648 | [(use (match_operand:DI 0 "register_operand" "")) | |
3649 | (use (match_operand:DF 1 "general_operand" ""))] | |
3650 | "TARGET_ARCH64 && TARGET_FPU" | |
3651 | "sparc_emit_fixunsdi (operands, DFmode); DONE;") | |
3652 | ||
75997b31 | 3653 | (define_expand "fix_trunctfdi2" |
c00088b6 | 3654 | [(set (match_operand:DI 0 "register_operand" "") |
3655 | (fix:DI (match_operand:TF 1 "general_operand" "")))] | |
75997b31 | 3656 | "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 3657 | "emit_tfmode_cvt (FIX, operands); DONE;") |
75997b31 | 3658 | |
3659 | (define_insn "*fix_trunctfdi2_hq" | |
65ccdc13 | 3660 | [(set (match_operand:DI 0 "register_operand" "=e") |
c00088b6 | 3661 | (fix:DI (match_operand:TF 1 "register_operand" "e")))] |
367242d3 | 3662 | "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 3663 | "fqtox\t%1, %0" |
a9208abf | 3664 | [(set_attr "type" "fp")]) |
75997b31 | 3665 | |
3666 | (define_expand "fixuns_trunctfdi2" | |
c00088b6 | 3667 | [(set (match_operand:DI 0 "register_operand" "") |
3668 | (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))] | |
75997b31 | 3669 | "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD" |
c00088b6 | 3670 | "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;") |
27b36d57 | 3671 | |
d88ab5ca | 3672 | |
3673 | ;; Integer addition/subtraction instructions. | |
a44201ea | 3674 | |
001e2308 | 3675 | (define_expand "adddi3" |
8877d71a | 3676 | [(set (match_operand:DI 0 "register_operand" "") |
3677 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
3678 | (match_operand:DI 2 "arith_double_add_operand" "")))] | |
001e2308 | 3679 | "" |
001e2308 | 3680 | { |
df5e9319 | 3681 | if (! TARGET_ARCH64) |
001e2308 | 3682 | { |
2e533a5d | 3683 | emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, |
3684 | gen_rtx_SET (VOIDmode, operands[0], | |
3685 | gen_rtx_PLUS (DImode, operands[1], | |
3686 | operands[2])), | |
3687 | gen_rtx_CLOBBER (VOIDmode, | |
58dc6b1f | 3688 | gen_rtx_REG (CCmode, SPARC_ICC_REG))))); |
001e2308 | 3689 | DONE; |
3690 | } | |
0037630d | 3691 | }) |
001e2308 | 3692 | |
76ab33ff | 3693 | (define_insn_and_split "*adddi3_insn_sp32" |
9c103f9f | 3694 | [(set (match_operand:DI 0 "register_operand" "=&r") |
0e255165 | 3695 | (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") |
a44201ea | 3696 | (match_operand:DI 2 "arith_double_operand" "rHI"))) |
2b25173f | 3697 | (clobber (reg:CC CC_REG))] |
df5e9319 | 3698 | "! TARGET_ARCH64" |
998032ba | 3699 | "#" |
43c08597 | 3700 | "&& reload_completed" |
2b25173f | 3701 | [(parallel [(set (reg:CC_NOOV CC_REG) |
367242d3 | 3702 | (compare:CC_NOOV (plus:SI (match_dup 4) |
3703 | (match_dup 5)) | |
3704 | (const_int 0))) | |
3705 | (set (match_dup 3) | |
3706 | (plus:SI (match_dup 4) (match_dup 5)))]) | |
3707 | (set (match_dup 6) | |
3708 | (plus:SI (plus:SI (match_dup 7) | |
3709 | (match_dup 8)) | |
2b25173f | 3710 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
144b3a44 | 3711 | { |
3712 | operands[3] = gen_lowpart (SImode, operands[0]); | |
3713 | operands[4] = gen_lowpart (SImode, operands[1]); | |
3714 | operands[5] = gen_lowpart (SImode, operands[2]); | |
3715 | operands[6] = gen_highpart (SImode, operands[0]); | |
704fcf2b | 3716 | operands[7] = gen_highpart_mode (SImode, DImode, operands[1]); |
463f13bf | 3717 | #if HOST_BITS_PER_WIDE_INT == 32 |
144b3a44 | 3718 | if (GET_CODE (operands[2]) == CONST_INT) |
3719 | { | |
3720 | if (INTVAL (operands[2]) < 0) | |
3721 | operands[8] = constm1_rtx; | |
3722 | else | |
3723 | operands[8] = const0_rtx; | |
3724 | } | |
3725 | else | |
463f13bf | 3726 | #endif |
704fcf2b | 3727 | operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); |
0037630d | 3728 | } |
43c08597 | 3729 | [(set_attr "length" "2")]) |
367242d3 | 3730 | |
367242d3 | 3731 | ;; LTU here means "carry set" |
998032ba | 3732 | (define_insn "addx" |
367242d3 | 3733 | [(set (match_operand:SI 0 "register_operand" "=r") |
0e255165 | 3734 | (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r") |
367242d3 | 3735 | (match_operand:SI 2 "arith_operand" "rI")) |
2b25173f | 3736 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
367242d3 | 3737 | "" |
a4ddaca5 | 3738 | "addx\t%1, %2, %0" |
e30b7bae | 3739 | [(set_attr "type" "ialuX")]) |
998032ba | 3740 | |
9c304cc0 | 3741 | (define_insn "addxc" |
3742 | [(set (match_operand:DI 0 "register_operand" "=r") | |
3743 | (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ") | |
3744 | (match_operand:DI 2 "register_or_zero_operand" "rJ")) | |
3745 | (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))] | |
3746 | "TARGET_ARCH64 && TARGET_VIS3" | |
3747 | "addxc\t%r1, %r2, %0" | |
3748 | [(set_attr "type" "ialuX")]) | |
3749 | ||
43c08597 | 3750 | (define_insn_and_split "*addx_extend_sp32" |
998032ba | 3751 | [(set (match_operand:DI 0 "register_operand" "=r") |
43c08597 | 3752 | (zero_extend:DI (plus:SI (plus:SI |
27b36d57 | 3753 | (match_operand:SI 1 "register_or_zero_operand" "%rJ") |
43c08597 | 3754 | (match_operand:SI 2 "arith_operand" "rI")) |
2b25173f | 3755 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] |
933dfc50 | 3756 | "! TARGET_ARCH64" |
3757 | "#" | |
43c08597 | 3758 | "&& reload_completed" |
933dfc50 | 3759 | [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2)) |
2b25173f | 3760 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))) |
933dfc50 | 3761 | (set (match_dup 4) (const_int 0))] |
3762 | "operands[3] = gen_lowpart (SImode, operands[0]); | |
43c08597 | 3763 | operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);" |
3764 | [(set_attr "length" "2")]) | |
933dfc50 | 3765 | |
3766 | (define_insn "*addx_extend_sp64" | |
3767 | [(set (match_operand:DI 0 "register_operand" "=r") | |
27b36d57 | 3768 | (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") |
9c304cc0 | 3769 | (match_operand:SI 2 "register_or_zero_operand" "rJ")) |
2b25173f | 3770 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] |
933dfc50 | 3771 | "TARGET_ARCH64" |
9c304cc0 | 3772 | "addx\t%r1, %r2, %0" |
3773 | [(set_attr "type" "ialuX")]) | |
3774 | ||
3775 | (define_insn "*addxc_trunc_sp64_vis3" | |
3776 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3777 | (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") | |
3778 | (match_operand:SI 2 "register_or_zero_operand" "rJ")) | |
3779 | (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))] | |
3780 | "TARGET_ARCH64 && TARGET_VIS3" | |
3781 | "addxc\t%r1, %r2, %0" | |
e30b7bae | 3782 | [(set_attr "type" "ialuX")]) |
367242d3 | 3783 | |
76ab33ff | 3784 | (define_insn_and_split "*adddi3_extend_sp32" |
f618d313 | 3785 | [(set (match_operand:DI 0 "register_operand" "=r") |
933dfc50 | 3786 | (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) |
3787 | (match_operand:DI 2 "register_operand" "r"))) | |
2b25173f | 3788 | (clobber (reg:CC CC_REG))] |
f618d313 | 3789 | "! TARGET_ARCH64" |
998032ba | 3790 | "#" |
43c08597 | 3791 | "&& reload_completed" |
2b25173f | 3792 | [(parallel [(set (reg:CC_NOOV CC_REG) |
933dfc50 | 3793 | (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1)) |
3794 | (const_int 0))) | |
3795 | (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))]) | |
3796 | (set (match_dup 6) | |
998032ba | 3797 | (plus:SI (plus:SI (match_dup 4) (const_int 0)) |
2b25173f | 3798 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
998032ba | 3799 | "operands[3] = gen_lowpart (SImode, operands[2]); |
933dfc50 | 3800 | operands[4] = gen_highpart (SImode, operands[2]); |
3801 | operands[5] = gen_lowpart (SImode, operands[0]); | |
43c08597 | 3802 | operands[6] = gen_highpart (SImode, operands[0]);" |
3803 | [(set_attr "length" "2")]) | |
f618d313 | 3804 | |
4117925c | 3805 | (define_insn "*adddi3_sp64" |
8877d71a | 3806 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
3807 | (plus:DI (match_operand:DI 1 "register_operand" "%r,r") | |
27b36d57 | 3808 | (match_operand:DI 2 "arith_add_operand" "rI,O")))] |
df5e9319 | 3809 | "TARGET_ARCH64" |
8877d71a | 3810 | "@ |
3811 | add\t%1, %2, %0 | |
3812 | sub\t%1, -%2, %0") | |
2aafe30f | 3813 | |
8877d71a | 3814 | (define_insn "addsi3" |
bc963728 | 3815 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
3816 | (plus:SI (match_operand:SI 1 "register_operand" "%r,r") | |
3817 | (match_operand:SI 2 "arith_add_operand" "rI,O")))] | |
a44201ea | 3818 | "" |
f618d313 | 3819 | "@ |
a4ddaca5 | 3820 | add\t%1, %2, %0 |
bc963728 | 3821 | sub\t%1, -%2, %0" |
3822 | [(set_attr "type" "*,*") | |
3823 | (set_attr "fptype" "*,*")]) | |
a44201ea | 3824 | |
4117925c | 3825 | (define_insn "*cmp_cc_plus" |
2b25173f | 3826 | [(set (reg:CC_NOOV CC_REG) |
0e255165 | 3827 | (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") |
a44201ea | 3828 | (match_operand:SI 1 "arith_operand" "rI")) |
3829 | (const_int 0)))] | |
f8be3dfc | 3830 | "" |
a4ddaca5 | 3831 | "addcc\t%0, %1, %%g0" |
a9208abf | 3832 | [(set_attr "type" "compare")]) |
a44201ea | 3833 | |
4117925c | 3834 | (define_insn "*cmp_ccx_plus" |
2b25173f | 3835 | [(set (reg:CCX_NOOV CC_REG) |
0e255165 | 3836 | (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r") |
27b36d57 | 3837 | (match_operand:DI 1 "arith_operand" "rI")) |
001e2308 | 3838 | (const_int 0)))] |
df5e9319 | 3839 | "TARGET_ARCH64" |
a4ddaca5 | 3840 | "addcc\t%0, %1, %%g0" |
a9208abf | 3841 | [(set_attr "type" "compare")]) |
001e2308 | 3842 | |
4117925c | 3843 | (define_insn "*cmp_cc_plus_set" |
2b25173f | 3844 | [(set (reg:CC_NOOV CC_REG) |
0e255165 | 3845 | (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r") |
a44201ea | 3846 | (match_operand:SI 2 "arith_operand" "rI")) |
3847 | (const_int 0))) | |
3848 | (set (match_operand:SI 0 "register_operand" "=r") | |
3849 | (plus:SI (match_dup 1) (match_dup 2)))] | |
3850 | "" | |
a4ddaca5 | 3851 | "addcc\t%1, %2, %0" |
a9208abf | 3852 | [(set_attr "type" "compare")]) |
a44201ea | 3853 | |
4117925c | 3854 | (define_insn "*cmp_ccx_plus_set" |
2b25173f | 3855 | [(set (reg:CCX_NOOV CC_REG) |
0e255165 | 3856 | (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r") |
27b36d57 | 3857 | (match_operand:DI 2 "arith_operand" "rI")) |
001e2308 | 3858 | (const_int 0))) |
3859 | (set (match_operand:DI 0 "register_operand" "=r") | |
3860 | (plus:DI (match_dup 1) (match_dup 2)))] | |
df5e9319 | 3861 | "TARGET_ARCH64" |
a4ddaca5 | 3862 | "addcc\t%1, %2, %0" |
a9208abf | 3863 | [(set_attr "type" "compare")]) |
001e2308 | 3864 | |
3865 | (define_expand "subdi3" | |
8877d71a | 3866 | [(set (match_operand:DI 0 "register_operand" "") |
3867 | (minus:DI (match_operand:DI 1 "register_operand" "") | |
3868 | (match_operand:DI 2 "arith_double_add_operand" "")))] | |
001e2308 | 3869 | "" |
001e2308 | 3870 | { |
df5e9319 | 3871 | if (! TARGET_ARCH64) |
001e2308 | 3872 | { |
2e533a5d | 3873 | emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, |
3874 | gen_rtx_SET (VOIDmode, operands[0], | |
3875 | gen_rtx_MINUS (DImode, operands[1], | |
3876 | operands[2])), | |
3877 | gen_rtx_CLOBBER (VOIDmode, | |
58dc6b1f | 3878 | gen_rtx_REG (CCmode, SPARC_ICC_REG))))); |
001e2308 | 3879 | DONE; |
3880 | } | |
0037630d | 3881 | }) |
001e2308 | 3882 | |
76ab33ff | 3883 | (define_insn_and_split "*subdi3_insn_sp32" |
a44201ea | 3884 | [(set (match_operand:DI 0 "register_operand" "=r") |
27b36d57 | 3885 | (minus:DI (match_operand:DI 1 "register_operand" "r") |
3886 | (match_operand:DI 2 "arith_double_operand" "rHI"))) | |
2b25173f | 3887 | (clobber (reg:CC CC_REG))] |
df5e9319 | 3888 | "! TARGET_ARCH64" |
998032ba | 3889 | "#" |
27b36d57 | 3890 | "&& reload_completed" |
2b25173f | 3891 | [(parallel [(set (reg:CC_NOOV CC_REG) |
27b36d57 | 3892 | (compare:CC_NOOV (minus:SI (match_dup 4) |
3893 | (match_dup 5)) | |
3894 | (const_int 0))) | |
3895 | (set (match_dup 3) | |
3896 | (minus:SI (match_dup 4) (match_dup 5)))]) | |
3897 | (set (match_dup 6) | |
3898 | (minus:SI (minus:SI (match_dup 7) | |
3899 | (match_dup 8)) | |
2b25173f | 3900 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
a44201ea | 3901 | { |
27b36d57 | 3902 | operands[3] = gen_lowpart (SImode, operands[0]); |
3903 | operands[4] = gen_lowpart (SImode, operands[1]); | |
3904 | operands[5] = gen_lowpart (SImode, operands[2]); | |
3905 | operands[6] = gen_highpart (SImode, operands[0]); | |
3906 | operands[7] = gen_highpart (SImode, operands[1]); | |
3907 | #if HOST_BITS_PER_WIDE_INT == 32 | |
3908 | if (GET_CODE (operands[2]) == CONST_INT) | |
a44201ea | 3909 | { |
27b36d57 | 3910 | if (INTVAL (operands[2]) < 0) |
3911 | operands[8] = constm1_rtx; | |
3912 | else | |
3913 | operands[8] = const0_rtx; | |
a44201ea | 3914 | } |
998032ba | 3915 | else |
27b36d57 | 3916 | #endif |
3917 | operands[8] = gen_highpart_mode (SImode, DImode, operands[2]); | |
0037630d | 3918 | } |
43c08597 | 3919 | [(set_attr "length" "2")]) |
998032ba | 3920 | |
27b36d57 | 3921 | ;; LTU here means "carry set" |
3922 | (define_insn "subx" | |
3923 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3924 | (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
3925 | (match_operand:SI 2 "arith_operand" "rI")) | |
2b25173f | 3926 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
27b36d57 | 3927 | "" |
3928 | "subx\t%r1, %2, %0" | |
3929 | [(set_attr "type" "ialuX")]) | |
3930 | ||
3931 | (define_insn "*subx_extend_sp64" | |
3932 | [(set (match_operand:DI 0 "register_operand" "=r") | |
3933 | (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
3934 | (match_operand:SI 2 "arith_operand" "rI")) | |
2b25173f | 3935 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] |
27b36d57 | 3936 | "TARGET_ARCH64" |
3937 | "subx\t%r1, %2, %0" | |
3938 | [(set_attr "type" "ialuX")]) | |
3939 | ||
3940 | (define_insn_and_split "*subx_extend" | |
3941 | [(set (match_operand:DI 0 "register_operand" "=r") | |
3942 | (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
3943 | (match_operand:SI 2 "arith_operand" "rI")) | |
2b25173f | 3944 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] |
27b36d57 | 3945 | "! TARGET_ARCH64" |
3946 | "#" | |
3947 | "&& reload_completed" | |
3948 | [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2)) | |
2b25173f | 3949 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))) |
27b36d57 | 3950 | (set (match_dup 4) (const_int 0))] |
3951 | "operands[3] = gen_lowpart (SImode, operands[0]); | |
3952 | operands[4] = gen_highpart (SImode, operands[0]);" | |
3953 | [(set_attr "length" "2")]) | |
a44201ea | 3954 | |
76ab33ff | 3955 | (define_insn_and_split "*subdi3_extend_sp32" |
f618d313 | 3956 | [(set (match_operand:DI 0 "register_operand" "=r") |
3957 | (minus:DI (match_operand:DI 1 "register_operand" "r") | |
3958 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))) | |
2b25173f | 3959 | (clobber (reg:CC CC_REG))] |
f618d313 | 3960 | "! TARGET_ARCH64" |
998032ba | 3961 | "#" |
43c08597 | 3962 | "&& reload_completed" |
2b25173f | 3963 | [(parallel [(set (reg:CC_NOOV CC_REG) |
933dfc50 | 3964 | (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2)) |
3965 | (const_int 0))) | |
3966 | (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))]) | |
3967 | (set (match_dup 6) | |
3968 | (minus:SI (minus:SI (match_dup 4) (const_int 0)) | |
2b25173f | 3969 | (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] |
998032ba | 3970 | "operands[3] = gen_lowpart (SImode, operands[1]); |
933dfc50 | 3971 | operands[4] = gen_highpart (SImode, operands[1]); |
3972 | operands[5] = gen_lowpart (SImode, operands[0]); | |
43c08597 | 3973 | operands[6] = gen_highpart (SImode, operands[0]);" |
3974 | [(set_attr "length" "2")]) | |
f618d313 | 3975 | |
4117925c | 3976 | (define_insn "*subdi3_sp64" |
8877d71a | 3977 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
3978 | (minus:DI (match_operand:DI 1 "register_operand" "r,r") | |
27b36d57 | 3979 | (match_operand:DI 2 "arith_add_operand" "rI,O")))] |
df5e9319 | 3980 | "TARGET_ARCH64" |
8877d71a | 3981 | "@ |
3982 | sub\t%1, %2, %0 | |
3983 | add\t%1, -%2, %0") | |
2aafe30f | 3984 | |
8877d71a | 3985 | (define_insn "subsi3" |
bc963728 | 3986 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
3987 | (minus:SI (match_operand:SI 1 "register_operand" "r,r") | |
3988 | (match_operand:SI 2 "arith_add_operand" "rI,O")))] | |
a44201ea | 3989 | "" |
f618d313 | 3990 | "@ |
a4ddaca5 | 3991 | sub\t%1, %2, %0 |
bc963728 | 3992 | add\t%1, -%2, %0" |
3993 | [(set_attr "type" "*,*") | |
3994 | (set_attr "fptype" "*,*")]) | |
a44201ea | 3995 | |
4117925c | 3996 | (define_insn "*cmp_minus_cc" |
2b25173f | 3997 | [(set (reg:CC_NOOV CC_REG) |
27b36d57 | 3998 | (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") |
a44201ea | 3999 | (match_operand:SI 1 "arith_operand" "rI")) |
4000 | (const_int 0)))] | |
f8be3dfc | 4001 | "" |
a4ddaca5 | 4002 | "subcc\t%r0, %1, %%g0" |
a9208abf | 4003 | [(set_attr "type" "compare")]) |
a44201ea | 4004 | |
4117925c | 4005 | (define_insn "*cmp_minus_ccx" |
2b25173f | 4006 | [(set (reg:CCX_NOOV CC_REG) |
001e2308 | 4007 | (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r") |
27b36d57 | 4008 | (match_operand:DI 1 "arith_operand" "rI")) |
001e2308 | 4009 | (const_int 0)))] |
df5e9319 | 4010 | "TARGET_ARCH64" |
a4ddaca5 | 4011 | "subcc\t%0, %1, %%g0" |
a9208abf | 4012 | [(set_attr "type" "compare")]) |
001e2308 | 4013 | |
998032ba | 4014 | (define_insn "cmp_minus_cc_set" |
2b25173f | 4015 | [(set (reg:CC_NOOV CC_REG) |
27b36d57 | 4016 | (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") |
a44201ea | 4017 | (match_operand:SI 2 "arith_operand" "rI")) |
4018 | (const_int 0))) | |
4019 | (set (match_operand:SI 0 "register_operand" "=r") | |
4020 | (minus:SI (match_dup 1) (match_dup 2)))] | |
4021 | "" | |
a4ddaca5 | 4022 | "subcc\t%r1, %2, %0" |
a9208abf | 4023 | [(set_attr "type" "compare")]) |
a44201ea | 4024 | |
4117925c | 4025 | (define_insn "*cmp_minus_ccx_set" |
2b25173f | 4026 | [(set (reg:CCX_NOOV CC_REG) |
001e2308 | 4027 | (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r") |
27b36d57 | 4028 | (match_operand:DI 2 "arith_operand" "rI")) |
001e2308 | 4029 | (const_int 0))) |
4030 | (set (match_operand:DI 0 "register_operand" "=r") | |
4031 | (minus:DI (match_dup 1) (match_dup 2)))] | |
df5e9319 | 4032 | "TARGET_ARCH64" |
a4ddaca5 | 4033 | "subcc\t%1, %2, %0" |
a9208abf | 4034 | [(set_attr "type" "compare")]) |
d88ab5ca | 4035 | |
4036 | ||
4037 | ;; Integer multiply/divide instructions. | |
001e2308 | 4038 | |
5b865faf | 4039 | ;; The 32-bit multiply/divide instructions are deprecated on v9, but at |
99227eff | 4040 | ;; least in UltraSPARC I, II and IIi it is a win tick-wise. |
001e2308 | 4041 | |
7466c783 | 4042 | (define_insn "mulsi3" |
4043 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4044 | (mult:SI (match_operand:SI 1 "arith_operand" "%r") | |
4045 | (match_operand:SI 2 "arith_operand" "rI")))] | |
f618d313 | 4046 | "TARGET_HARD_MUL" |
a4ddaca5 | 4047 | "smul\t%1, %2, %0" |
a9208abf | 4048 | [(set_attr "type" "imul")]) |
7466c783 | 4049 | |
367242d3 | 4050 | (define_expand "muldi3" |
27b36d57 | 4051 | [(set (match_operand:DI 0 "register_operand" "") |
4052 | (mult:DI (match_operand:DI 1 "arith_operand" "") | |
4053 | (match_operand:DI 2 "arith_operand" "")))] | |
367242d3 | 4054 | "TARGET_ARCH64 || TARGET_V8PLUS" |
367242d3 | 4055 | { |
4056 | if (TARGET_V8PLUS) | |
4057 | { | |
4058 | emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2])); | |
4059 | DONE; | |
4060 | } | |
0037630d | 4061 | }) |
367242d3 | 4062 | |
4063 | (define_insn "*muldi3_sp64" | |
001e2308 | 4064 | [(set (match_operand:DI 0 "register_operand" "=r") |
27b36d57 | 4065 | (mult:DI (match_operand:DI 1 "arith_operand" "%r") |
4066 | (match_operand:DI 2 "arith_operand" "rI")))] | |
df5e9319 | 4067 | "TARGET_ARCH64" |
a4ddaca5 | 4068 | "mulx\t%1, %2, %0" |
a9208abf | 4069 | [(set_attr "type" "imul")]) |
001e2308 | 4070 | |
367242d3 | 4071 | ;; V8plus wide multiply. |
998032ba | 4072 | ;; XXX |
367242d3 | 4073 | (define_insn "muldi3_v8plus" |
4074 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
27b36d57 | 4075 | (mult:DI (match_operand:DI 1 "arith_operand" "%r,0") |
4076 | (match_operand:DI 2 "arith_operand" "rI,rI"))) | |
367242d3 | 4077 | (clobber (match_scratch:SI 3 "=&h,X")) |
4078 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
4079 | "TARGET_V8PLUS" | |
47cc4525 | 4080 | "* return output_v8plus_mult (insn, operands, \"mulx\");" |
a9208abf | 4081 | [(set_attr "type" "multi") |
4082 | (set_attr "length" "9,8")]) | |
367242d3 | 4083 | |
4117925c | 4084 | (define_insn "*cmp_mul_set" |
2b25173f | 4085 | [(set (reg:CC CC_REG) |
99227eff | 4086 | (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r") |
4087 | (match_operand:SI 2 "arith_operand" "rI")) | |
4088 | (const_int 0))) | |
4089 | (set (match_operand:SI 0 "register_operand" "=r") | |
4090 | (mult:SI (match_dup 1) (match_dup 2)))] | |
d49f4f09 | 4091 | "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" |
a4ddaca5 | 4092 | "smulcc\t%1, %2, %0" |
a9208abf | 4093 | [(set_attr "type" "imul")]) |
7466c783 | 4094 | |
f2ed3c03 | 4095 | (define_expand "mulsidi3" |
4096 | [(set (match_operand:DI 0 "register_operand" "") | |
4097 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) | |
4098 | (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))] | |
f618d313 | 4099 | "TARGET_HARD_MUL" |
f2ed3c03 | 4100 | { |
4101 | if (CONSTANT_P (operands[2])) | |
4102 | { | |
8aa5639c | 4103 | if (TARGET_V8PLUS) |
99227eff | 4104 | emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1], |
4105 | operands[2])); | |
0dd62afe | 4106 | else if (TARGET_ARCH32) |
99227eff | 4107 | emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1], |
4108 | operands[2])); | |
0dd62afe | 4109 | else |
4110 | emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1], | |
4111 | operands[2])); | |
f2ed3c03 | 4112 | DONE; |
4113 | } | |
8aa5639c | 4114 | if (TARGET_V8PLUS) |
4115 | { | |
4116 | emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2])); | |
4117 | DONE; | |
4118 | } | |
0037630d | 4119 | }) |
f2ed3c03 | 4120 | |
5b865faf | 4121 | ;; V9 puts the 64-bit product in a 64-bit register. Only out or global |
4122 | ;; registers can hold 64-bit values in the V8plus environment. | |
998032ba | 4123 | ;; XXX |
8aa5639c | 4124 | (define_insn "mulsidi3_v8plus" |
367242d3 | 4125 | [(set (match_operand:DI 0 "register_operand" "=h,r") |
4126 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4127 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) | |
4128 | (clobber (match_scratch:SI 3 "=X,&h"))] | |
4129 | "TARGET_V8PLUS" | |
4130 | "@ | |
a4ddaca5 | 4131 | smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 |
4132 | smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" | |
a9208abf | 4133 | [(set_attr "type" "multi") |
4134 | (set_attr "length" "2,3")]) | |
367242d3 | 4135 | |
998032ba | 4136 | ;; XXX |
8aa5639c | 4137 | (define_insn "const_mulsidi3_v8plus" |
367242d3 | 4138 | [(set (match_operand:DI 0 "register_operand" "=h,r") |
4139 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
27b36d57 | 4140 | (match_operand:DI 2 "small_int_operand" "I,I"))) |
367242d3 | 4141 | (clobber (match_scratch:SI 3 "=X,&h"))] |
4142 | "TARGET_V8PLUS" | |
4143 | "@ | |
a4ddaca5 | 4144 | smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 |
4145 | smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" | |
a9208abf | 4146 | [(set_attr "type" "multi") |
4147 | (set_attr "length" "2,3")]) | |
367242d3 | 4148 | |
998032ba | 4149 | ;; XXX |
4117925c | 4150 | (define_insn "*mulsidi3_sp32" |
7466c783 | 4151 | [(set (match_operand:DI 0 "register_operand" "=r") |
f2ed3c03 | 4152 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) |
4153 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
367242d3 | 4154 | "TARGET_HARD_MUL32" |
0f925e9c | 4155 | { |
0037630d | 4156 | return TARGET_SPARCLET |
a4ddaca5 | 4157 | ? "smuld\t%1, %2, %L0" |
4158 | : "smul\t%1, %2, %L0\n\trd\t%%y, %H0"; | |
0037630d | 4159 | } |
a9208abf | 4160 | [(set (attr "type") |
4161 | (if_then_else (eq_attr "isa" "sparclet") | |
4162 | (const_string "imul") (const_string "multi"))) | |
4163 | (set (attr "length") | |
0f925e9c | 4164 | (if_then_else (eq_attr "isa" "sparclet") |
4165 | (const_int 1) (const_int 2)))]) | |
7466c783 | 4166 | |
99227eff | 4167 | (define_insn "*mulsidi3_sp64" |
4168 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4169 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4170 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
4171 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
a4ddaca5 | 4172 | "smul\t%1, %2, %0" |
a9208abf | 4173 | [(set_attr "type" "imul")]) |
99227eff | 4174 | |
fd6efe25 | 4175 | ;; Extra pattern, because sign_extend of a constant isn't valid. |
f2ed3c03 | 4176 | |
998032ba | 4177 | ;; XXX |
99227eff | 4178 | (define_insn "const_mulsidi3_sp32" |
7466c783 | 4179 | [(set (match_operand:DI 0 "register_operand" "=r") |
f2ed3c03 | 4180 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) |
27b36d57 | 4181 | (match_operand:DI 2 "small_int_operand" "I")))] |
99227eff | 4182 | "TARGET_HARD_MUL32" |
0f925e9c | 4183 | { |
0037630d | 4184 | return TARGET_SPARCLET |
a4ddaca5 | 4185 | ? "smuld\t%1, %2, %L0" |
4186 | : "smul\t%1, %2, %L0\n\trd\t%%y, %H0"; | |
0037630d | 4187 | } |
a9208abf | 4188 | [(set (attr "type") |
4189 | (if_then_else (eq_attr "isa" "sparclet") | |
4190 | (const_string "imul") (const_string "multi"))) | |
4191 | (set (attr "length") | |
0f925e9c | 4192 | (if_then_else (eq_attr "isa" "sparclet") |
4193 | (const_int 1) (const_int 2)))]) | |
f2ed3c03 | 4194 | |
99227eff | 4195 | (define_insn "const_mulsidi3_sp64" |
4196 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4197 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
27b36d57 | 4198 | (match_operand:DI 2 "small_int_operand" "I")))] |
99227eff | 4199 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" |
a4ddaca5 | 4200 | "smul\t%1, %2, %0" |
a9208abf | 4201 | [(set_attr "type" "imul")]) |
99227eff | 4202 | |
cbcbaefa | 4203 | (define_expand "smulsi3_highpart" |
4204 | [(set (match_operand:SI 0 "register_operand" "") | |
4205 | (truncate:SI | |
4206 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) | |
4207 | (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))) | |
4208 | (const_int 32))))] | |
99227eff | 4209 | "TARGET_HARD_MUL && TARGET_ARCH32" |
cbcbaefa | 4210 | { |
4211 | if (CONSTANT_P (operands[2])) | |
4212 | { | |
8aa5639c | 4213 | if (TARGET_V8PLUS) |
4214 | { | |
4215 | emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0], | |
4216 | operands[1], | |
4217 | operands[2], | |
4218 | GEN_INT (32))); | |
4219 | DONE; | |
4220 | } | |
cbcbaefa | 4221 | emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2])); |
4222 | DONE; | |
4223 | } | |
367242d3 | 4224 | if (TARGET_V8PLUS) |
4225 | { | |
8aa5639c | 4226 | emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1], |
4227 | operands[2], GEN_INT (32))); | |
367242d3 | 4228 | DONE; |
4229 | } | |
0037630d | 4230 | }) |
cbcbaefa | 4231 | |
998032ba | 4232 | ;; XXX |
8aa5639c | 4233 | (define_insn "smulsi3_highpart_v8plus" |
367242d3 | 4234 | [(set (match_operand:SI 0 "register_operand" "=h,r") |
4235 | (truncate:SI | |
4236 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4237 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
27b36d57 | 4238 | (match_operand:SI 3 "small_int_operand" "I,I")))) |
367242d3 | 4239 | (clobber (match_scratch:SI 4 "=X,&h"))] |
4240 | "TARGET_V8PLUS" | |
4241 | "@ | |
a4ddaca5 | 4242 | smul\t%1, %2, %0\;srlx\t%0, %3, %0 |
4243 | smul\t%1, %2, %4\;srlx\t%4, %3, %0" | |
a9208abf | 4244 | [(set_attr "type" "multi") |
4245 | (set_attr "length" "2")]) | |
367242d3 | 4246 | |
58dc6b1f | 4247 | ;; The combiner changes TRUNCATE in the previous pattern to SUBREG. |
998032ba | 4248 | ;; XXX |
58dc6b1f | 4249 | (define_insn "" |
4250 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
4251 | (subreg:SI | |
4252 | (lshiftrt:DI | |
4253 | (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4254 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
27b36d57 | 4255 | (match_operand:SI 3 "small_int_operand" "I,I")) |
701e46d0 | 4256 | 4)) |
58dc6b1f | 4257 | (clobber (match_scratch:SI 4 "=X,&h"))] |
4258 | "TARGET_V8PLUS" | |
4259 | "@ | |
a4ddaca5 | 4260 | smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 |
4261 | smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" | |
a9208abf | 4262 | [(set_attr "type" "multi") |
4263 | (set_attr "length" "2")]) | |
58dc6b1f | 4264 | |
998032ba | 4265 | ;; XXX |
8aa5639c | 4266 | (define_insn "const_smulsi3_highpart_v8plus" |
4267 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
4268 | (truncate:SI | |
4269 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
27b36d57 | 4270 | (match_operand:DI 2 "small_int_operand" "I,I")) |
4271 | (match_operand:SI 3 "small_int_operand" "I,I")))) | |
8aa5639c | 4272 | (clobber (match_scratch:SI 4 "=X,&h"))] |
4273 | "TARGET_V8PLUS" | |
4274 | "@ | |
a4ddaca5 | 4275 | smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 |
4276 | smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" | |
a9208abf | 4277 | [(set_attr "type" "multi") |
4278 | (set_attr "length" "2")]) | |
8aa5639c | 4279 | |
998032ba | 4280 | ;; XXX |
8aa5639c | 4281 | (define_insn "*smulsi3_highpart_sp32" |
cbcbaefa | 4282 | [(set (match_operand:SI 0 "register_operand" "=r") |
4283 | (truncate:SI | |
4284 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4285 | (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) | |
4286 | (const_int 32))))] | |
f8be3dfc | 4287 | "TARGET_HARD_MUL32" |
a4ddaca5 | 4288 | "smul\t%1, %2, %%g0\n\trd\t%%y, %0" |
a9208abf | 4289 | [(set_attr "type" "multi") |
4290 | (set_attr "length" "2")]) | |
cbcbaefa | 4291 | |
998032ba | 4292 | ;; XXX |
cbcbaefa | 4293 | (define_insn "const_smulsi3_highpart" |
4294 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4295 | (truncate:SI | |
4296 | (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
27b36d57 | 4297 | (match_operand:DI 2 "small_int_operand" "i")) |
cbcbaefa | 4298 | (const_int 32))))] |
f8be3dfc | 4299 | "TARGET_HARD_MUL32" |
a4ddaca5 | 4300 | "smul\t%1, %2, %%g0\n\trd\t%%y, %0" |
a9208abf | 4301 | [(set_attr "type" "multi") |
4302 | (set_attr "length" "2")]) | |
cbcbaefa | 4303 | |
f2ed3c03 | 4304 | (define_expand "umulsidi3" |
4305 | [(set (match_operand:DI 0 "register_operand" "") | |
4306 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | |
6284ae16 | 4307 | (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))] |
f618d313 | 4308 | "TARGET_HARD_MUL" |
f2ed3c03 | 4309 | { |
4310 | if (CONSTANT_P (operands[2])) | |
4311 | { | |
8aa5639c | 4312 | if (TARGET_V8PLUS) |
99227eff | 4313 | emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1], |
4314 | operands[2])); | |
0dd62afe | 4315 | else if (TARGET_ARCH32) |
99227eff | 4316 | emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1], |
4317 | operands[2])); | |
0dd62afe | 4318 | else |
4319 | emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1], | |
4320 | operands[2])); | |
f2ed3c03 | 4321 | DONE; |
4322 | } | |
367242d3 | 4323 | if (TARGET_V8PLUS) |
4324 | { | |
4325 | emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2])); | |
4326 | DONE; | |
4327 | } | |
0037630d | 4328 | }) |
f2ed3c03 | 4329 | |
998032ba | 4330 | ;; XXX |
367242d3 | 4331 | (define_insn "umulsidi3_v8plus" |
4332 | [(set (match_operand:DI 0 "register_operand" "=h,r") | |
4333 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4334 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))) | |
4335 | (clobber (match_scratch:SI 3 "=X,&h"))] | |
4336 | "TARGET_V8PLUS" | |
4337 | "@ | |
a4ddaca5 | 4338 | umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0 |
4339 | umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" | |
a9208abf | 4340 | [(set_attr "type" "multi") |
4341 | (set_attr "length" "2,3")]) | |
367242d3 | 4342 | |
998032ba | 4343 | ;; XXX |
4117925c | 4344 | (define_insn "*umulsidi3_sp32" |
f2ed3c03 | 4345 | [(set (match_operand:DI 0 "register_operand" "=r") |
4346 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4347 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
367242d3 | 4348 | "TARGET_HARD_MUL32" |
0f925e9c | 4349 | { |
0037630d | 4350 | return TARGET_SPARCLET |
a4ddaca5 | 4351 | ? "umuld\t%1, %2, %L0" |
4352 | : "umul\t%1, %2, %L0\n\trd\t%%y, %H0"; | |
0037630d | 4353 | } |
a9208abf | 4354 | [(set (attr "type") |
4355 | (if_then_else (eq_attr "isa" "sparclet") | |
4356 | (const_string "imul") (const_string "multi"))) | |
4357 | (set (attr "length") | |
0f925e9c | 4358 | (if_then_else (eq_attr "isa" "sparclet") |
4359 | (const_int 1) (const_int 2)))]) | |
f2ed3c03 | 4360 | |
99227eff | 4361 | (define_insn "*umulsidi3_sp64" |
4362 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4363 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4364 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] | |
4365 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
a4ddaca5 | 4366 | "umul\t%1, %2, %0" |
a9208abf | 4367 | [(set_attr "type" "imul")]) |
99227eff | 4368 | |
fd6efe25 | 4369 | ;; Extra pattern, because sign_extend of a constant isn't valid. |
f2ed3c03 | 4370 | |
998032ba | 4371 | ;; XXX |
99227eff | 4372 | (define_insn "const_umulsidi3_sp32" |
f2ed3c03 | 4373 | [(set (match_operand:DI 0 "register_operand" "=r") |
4374 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
27b36d57 | 4375 | (match_operand:DI 2 "uns_small_int_operand" "")))] |
367242d3 | 4376 | "TARGET_HARD_MUL32" |
0f925e9c | 4377 | { |
0037630d | 4378 | return TARGET_SPARCLET |
95989dc6 | 4379 | ? "umuld\t%1, %s2, %L0" |
4380 | : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0"; | |
0037630d | 4381 | } |
a9208abf | 4382 | [(set (attr "type") |
4383 | (if_then_else (eq_attr "isa" "sparclet") | |
4384 | (const_string "imul") (const_string "multi"))) | |
4385 | (set (attr "length") | |
0f925e9c | 4386 | (if_then_else (eq_attr "isa" "sparclet") |
4387 | (const_int 1) (const_int 2)))]) | |
7466c783 | 4388 | |
99227eff | 4389 | (define_insn "const_umulsidi3_sp64" |
4390 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4391 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
27b36d57 | 4392 | (match_operand:DI 2 "uns_small_int_operand" "")))] |
99227eff | 4393 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" |
95989dc6 | 4394 | "umul\t%1, %s2, %0" |
a9208abf | 4395 | [(set_attr "type" "imul")]) |
99227eff | 4396 | |
998032ba | 4397 | ;; XXX |
367242d3 | 4398 | (define_insn "const_umulsidi3_v8plus" |
4399 | [(set (match_operand:DI 0 "register_operand" "=h,r") | |
4400 | (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
27b36d57 | 4401 | (match_operand:DI 2 "uns_small_int_operand" ""))) |
367242d3 | 4402 | (clobber (match_scratch:SI 3 "=X,h"))] |
4403 | "TARGET_V8PLUS" | |
4404 | "@ | |
95989dc6 | 4405 | umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0 |
4406 | umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0" | |
a9208abf | 4407 | [(set_attr "type" "multi") |
4408 | (set_attr "length" "2,3")]) | |
367242d3 | 4409 | |
cbcbaefa | 4410 | (define_expand "umulsi3_highpart" |
4411 | [(set (match_operand:SI 0 "register_operand" "") | |
4412 | (truncate:SI | |
4413 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | |
4414 | (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))) | |
4415 | (const_int 32))))] | |
99227eff | 4416 | "TARGET_HARD_MUL && TARGET_ARCH32" |
cbcbaefa | 4417 | { |
8aa5639c | 4418 | if (CONSTANT_P (operands[2])) |
367242d3 | 4419 | { |
8aa5639c | 4420 | if (TARGET_V8PLUS) |
4421 | { | |
4422 | emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0], | |
4423 | operands[1], | |
4424 | operands[2], | |
4425 | GEN_INT (32))); | |
4426 | DONE; | |
4427 | } | |
4428 | emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2])); | |
367242d3 | 4429 | DONE; |
4430 | } | |
8aa5639c | 4431 | if (TARGET_V8PLUS) |
cbcbaefa | 4432 | { |
8aa5639c | 4433 | emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1], |
4434 | operands[2], GEN_INT (32))); | |
cbcbaefa | 4435 | DONE; |
4436 | } | |
0037630d | 4437 | }) |
cbcbaefa | 4438 | |
998032ba | 4439 | ;; XXX |
8aa5639c | 4440 | (define_insn "umulsi3_highpart_v8plus" |
367242d3 | 4441 | [(set (match_operand:SI 0 "register_operand" "=h,r") |
4442 | (truncate:SI | |
4443 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
4444 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))) | |
27b36d57 | 4445 | (match_operand:SI 3 "small_int_operand" "I,I")))) |
367242d3 | 4446 | (clobber (match_scratch:SI 4 "=X,h"))] |
4447 | "TARGET_V8PLUS" | |
4448 | "@ | |
a4ddaca5 | 4449 | umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0 |
4450 | umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0" | |
a9208abf | 4451 | [(set_attr "type" "multi") |
4452 | (set_attr "length" "2")]) | |
367242d3 | 4453 | |
998032ba | 4454 | ;; XXX |
367242d3 | 4455 | (define_insn "const_umulsi3_highpart_v8plus" |
4456 | [(set (match_operand:SI 0 "register_operand" "=h,r") | |
4457 | (truncate:SI | |
4458 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) | |
27b36d57 | 4459 | (match_operand:DI 2 "uns_small_int_operand" "")) |
4460 | (match_operand:SI 3 "small_int_operand" "I,I")))) | |
367242d3 | 4461 | (clobber (match_scratch:SI 4 "=X,h"))] |
4462 | "TARGET_V8PLUS" | |
4463 | "@ | |
95989dc6 | 4464 | umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0 |
4465 | umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0" | |
a9208abf | 4466 | [(set_attr "type" "multi") |
4467 | (set_attr "length" "2")]) | |
367242d3 | 4468 | |
998032ba | 4469 | ;; XXX |
8aa5639c | 4470 | (define_insn "*umulsi3_highpart_sp32" |
cbcbaefa | 4471 | [(set (match_operand:SI 0 "register_operand" "=r") |
4472 | (truncate:SI | |
4473 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
4474 | (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) | |
4475 | (const_int 32))))] | |
f8be3dfc | 4476 | "TARGET_HARD_MUL32" |
a4ddaca5 | 4477 | "umul\t%1, %2, %%g0\n\trd\t%%y, %0" |
a9208abf | 4478 | [(set_attr "type" "multi") |
4479 | (set_attr "length" "2")]) | |
cbcbaefa | 4480 | |
998032ba | 4481 | ;; XXX |
cbcbaefa | 4482 | (define_insn "const_umulsi3_highpart" |
4483 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4484 | (truncate:SI | |
4485 | (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) | |
27b36d57 | 4486 | (match_operand:DI 2 "uns_small_int_operand" "")) |
cbcbaefa | 4487 | (const_int 32))))] |
f8be3dfc | 4488 | "TARGET_HARD_MUL32" |
95989dc6 | 4489 | "umul\t%1, %s2, %%g0\n\trd\t%%y, %0" |
a9208abf | 4490 | [(set_attr "type" "multi") |
4491 | (set_attr "length" "2")]) | |
cbcbaefa | 4492 | |
99227eff | 4493 | (define_expand "divsi3" |
0e517585 | 4494 | [(parallel [(set (match_operand:SI 0 "register_operand" "") |
4495 | (div:SI (match_operand:SI 1 "register_operand" "") | |
4496 | (match_operand:SI 2 "input_operand" ""))) | |
4497 | (clobber (match_scratch:SI 3 ""))])] | |
99227eff | 4498 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
99227eff | 4499 | { |
4500 | if (TARGET_ARCH64) | |
4501 | { | |
4502 | operands[3] = gen_reg_rtx(SImode); | |
4503 | emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31))); | |
4504 | emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2], | |
4505 | operands[3])); | |
4506 | DONE; | |
4507 | } | |
0037630d | 4508 | }) |
99227eff | 4509 | |
0e517585 | 4510 | ;; The V8 architecture specifies that there must be at least 3 instructions |
4511 | ;; between a write to the Y register and a use of it for correct results. | |
4512 | ;; We try to fill one of them with a simple constant or a memory load. | |
4513 | ||
99227eff | 4514 | (define_insn "divsi3_sp32" |
0e517585 | 4515 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") |
4516 | (div:SI (match_operand:SI 1 "register_operand" "r,r,r") | |
4517 | (match_operand:SI 2 "input_operand" "rI,K,m"))) | |
4518 | (clobber (match_scratch:SI 3 "=&r,&r,&r"))] | |
4519 | "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32" | |
d49f4f09 | 4520 | { |
0e517585 | 4521 | output_asm_insn ("sra\t%1, 31, %3", operands); |
4522 | output_asm_insn ("wr\t%3, 0, %%y", operands); | |
4523 | ||
4524 | switch (which_alternative) | |
4525 | { | |
4526 | case 0: | |
4527 | if (TARGET_V9) | |
4528 | return "sdiv\t%1, %2, %0"; | |
4529 | else | |
4530 | return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0"; | |
4531 | case 1: | |
4532 | if (TARGET_V9) | |
4533 | return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0"; | |
4534 | else | |
4535 | return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; | |
4536 | case 2: | |
4537 | if (TARGET_V9) | |
4538 | return "ld\t%2, %3\n\tsdiv\t%1, %3, %0"; | |
4539 | else | |
4540 | return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0"; | |
4541 | default: | |
4542 | gcc_unreachable (); | |
4543 | } | |
0037630d | 4544 | } |
a9208abf | 4545 | [(set_attr "type" "multi") |
4546 | (set (attr "length") | |
d49f4f09 | 4547 | (if_then_else (eq_attr "isa" "v9") |
258103e3 | 4548 | (const_int 4) (const_int 6)))]) |
7466c783 | 4549 | |
99227eff | 4550 | (define_insn "divsi3_sp64" |
4551 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4552 | (div:SI (match_operand:SI 1 "register_operand" "r") | |
4553 | (match_operand:SI 2 "input_operand" "rI"))) | |
4554 | (use (match_operand:SI 3 "register_operand" "r"))] | |
4555 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
a4ddaca5 | 4556 | "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0" |
a9208abf | 4557 | [(set_attr "type" "multi") |
4558 | (set_attr "length" "2")]) | |
99227eff | 4559 | |
001e2308 | 4560 | (define_insn "divdi3" |
4561 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4562 | (div:DI (match_operand:DI 1 "register_operand" "r") | |
27b36d57 | 4563 | (match_operand:DI 2 "arith_operand" "rI")))] |
df5e9319 | 4564 | "TARGET_ARCH64" |
a4ddaca5 | 4565 | "sdivx\t%1, %2, %0" |
a9208abf | 4566 | [(set_attr "type" "idiv")]) |
001e2308 | 4567 | |
4117925c | 4568 | (define_insn "*cmp_sdiv_cc_set" |
2b25173f | 4569 | [(set (reg:CC CC_REG) |
99227eff | 4570 | (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r") |
4571 | (match_operand:SI 2 "arith_operand" "rI")) | |
7466c783 | 4572 | (const_int 0))) |
99227eff | 4573 | (set (match_operand:SI 0 "register_operand" "=r") |
4574 | (div:SI (match_dup 1) (match_dup 2))) | |
7466c783 | 4575 | (clobber (match_scratch:SI 3 "=&r"))] |
99227eff | 4576 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
d49f4f09 | 4577 | { |
0e517585 | 4578 | output_asm_insn ("sra\t%1, 31, %3", operands); |
4579 | output_asm_insn ("wr\t%3, 0, %%y", operands); | |
4580 | ||
d49f4f09 | 4581 | if (TARGET_V9) |
0e517585 | 4582 | return "sdivcc\t%1, %2, %0"; |
d49f4f09 | 4583 | else |
0e517585 | 4584 | return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0"; |
0037630d | 4585 | } |
a9208abf | 4586 | [(set_attr "type" "multi") |
4587 | (set (attr "length") | |
d49f4f09 | 4588 | (if_then_else (eq_attr "isa" "v9") |
4589 | (const_int 3) (const_int 6)))]) | |
7466c783 | 4590 | |
998032ba | 4591 | ;; XXX |
99227eff | 4592 | (define_expand "udivsi3" |
4593 | [(set (match_operand:SI 0 "register_operand" "") | |
27b36d57 | 4594 | (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "") |
99227eff | 4595 | (match_operand:SI 2 "input_operand" "")))] |
f8be3dfc | 4596 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
99227eff | 4597 | "") |
4598 | ||
0e517585 | 4599 | ;; The V8 architecture specifies that there must be at least 3 instructions |
4600 | ;; between a write to the Y register and a use of it for correct results. | |
4601 | ;; We try to fill one of them with a simple constant or a memory load. | |
27b36d57 | 4602 | |
99227eff | 4603 | (define_insn "udivsi3_sp32" |
0e517585 | 4604 | [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r") |
4605 | (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m") | |
4606 | (match_operand:SI 2 "input_operand" "rI,K,m,r")))] | |
4607 | "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32" | |
d49f4f09 | 4608 | { |
0e517585 | 4609 | output_asm_insn ("wr\t%%g0, 0, %%y", operands); |
4610 | ||
367242d3 | 4611 | switch (which_alternative) |
4612 | { | |
0e517585 | 4613 | case 0: |
4614 | if (TARGET_V9) | |
4615 | return "udiv\t%1, %2, %0"; | |
4616 | else | |
4617 | return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0"; | |
367242d3 | 4618 | case 1: |
0e517585 | 4619 | if (TARGET_V9) |
4620 | return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0"; | |
4621 | else | |
4622 | return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; | |
367242d3 | 4623 | case 2: |
0e517585 | 4624 | if (TARGET_V9) |
4625 | return "ld\t%2, %0\n\tudiv\t%1, %0, %0"; | |
4626 | else | |
4627 | return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0"; | |
4628 | case 3: | |
4629 | if (TARGET_V9) | |
4630 | return "ld\t%1, %0\n\tudiv\t%0, %2, %0"; | |
4631 | else | |
4632 | return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0"; | |
4633 | default: | |
4634 | gcc_unreachable (); | |
367242d3 | 4635 | } |
0037630d | 4636 | } |
a9208abf | 4637 | [(set_attr "type" "multi") |
0e517585 | 4638 | (set (attr "length") |
4639 | (if_then_else (eq_attr "isa" "v9") | |
4640 | (const_int 3) (const_int 5)))]) | |
99227eff | 4641 | |
4642 | (define_insn "udivsi3_sp64" | |
4643 | [(set (match_operand:SI 0 "register_operand" "=r") | |
27b36d57 | 4644 | (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r") |
99227eff | 4645 | (match_operand:SI 2 "input_operand" "rI")))] |
4646 | "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64" | |
a4ddaca5 | 4647 | "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0" |
a9208abf | 4648 | [(set_attr "type" "multi") |
4649 | (set_attr "length" "2")]) | |
7466c783 | 4650 | |
001e2308 | 4651 | (define_insn "udivdi3" |
4652 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4653 | (udiv:DI (match_operand:DI 1 "register_operand" "r") | |
27b36d57 | 4654 | (match_operand:DI 2 "arith_operand" "rI")))] |
df5e9319 | 4655 | "TARGET_ARCH64" |
a4ddaca5 | 4656 | "udivx\t%1, %2, %0" |
a9208abf | 4657 | [(set_attr "type" "idiv")]) |
001e2308 | 4658 | |
4117925c | 4659 | (define_insn "*cmp_udiv_cc_set" |
2b25173f | 4660 | [(set (reg:CC CC_REG) |
99227eff | 4661 | (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r") |
4662 | (match_operand:SI 2 "arith_operand" "rI")) | |
4663 | (const_int 0))) | |
4664 | (set (match_operand:SI 0 "register_operand" "=r") | |
4665 | (udiv:SI (match_dup 1) (match_dup 2)))] | |
0e517585 | 4666 | "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" |
d49f4f09 | 4667 | { |
0e517585 | 4668 | output_asm_insn ("wr\t%%g0, 0, %%y", operands); |
4669 | ||
d49f4f09 | 4670 | if (TARGET_V9) |
0e517585 | 4671 | return "udivcc\t%1, %2, %0"; |
d49f4f09 | 4672 | else |
0e517585 | 4673 | return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0"; |
0037630d | 4674 | } |
a9208abf | 4675 | [(set_attr "type" "multi") |
4676 | (set (attr "length") | |
d49f4f09 | 4677 | (if_then_else (eq_attr "isa" "v9") |
4678 | (const_int 2) (const_int 5)))]) | |
93e2cd75 | 4679 | |
4680 | ; sparclet multiply/accumulate insns | |
4681 | ||
4682 | (define_insn "*smacsi" | |
cfdf558e | 4683 | [(set (match_operand:SI 0 "register_operand" "=r") |
93e2cd75 | 4684 | (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r") |
4685 | (match_operand:SI 2 "arith_operand" "rI")) | |
0f925e9c | 4686 | (match_operand:SI 3 "register_operand" "0")))] |
93e2cd75 | 4687 | "TARGET_SPARCLET" |
a4ddaca5 | 4688 | "smac\t%1, %2, %0" |
a9208abf | 4689 | [(set_attr "type" "imul")]) |
93e2cd75 | 4690 | |
4691 | (define_insn "*smacdi" | |
cfdf558e | 4692 | [(set (match_operand:DI 0 "register_operand" "=r") |
93e2cd75 | 4693 | (plus:DI (mult:DI (sign_extend:DI |
4694 | (match_operand:SI 1 "register_operand" "%r")) | |
4695 | (sign_extend:DI | |
4696 | (match_operand:SI 2 "register_operand" "r"))) | |
0f925e9c | 4697 | (match_operand:DI 3 "register_operand" "0")))] |
93e2cd75 | 4698 | "TARGET_SPARCLET" |
a4ddaca5 | 4699 | "smacd\t%1, %2, %L0" |
a9208abf | 4700 | [(set_attr "type" "imul")]) |
93e2cd75 | 4701 | |
4702 | (define_insn "*umacdi" | |
cfdf558e | 4703 | [(set (match_operand:DI 0 "register_operand" "=r") |
93e2cd75 | 4704 | (plus:DI (mult:DI (zero_extend:DI |
4705 | (match_operand:SI 1 "register_operand" "%r")) | |
4706 | (zero_extend:DI | |
4707 | (match_operand:SI 2 "register_operand" "r"))) | |
0f925e9c | 4708 | (match_operand:DI 3 "register_operand" "0")))] |
93e2cd75 | 4709 | "TARGET_SPARCLET" |
a4ddaca5 | 4710 | "umacd\t%1, %2, %L0" |
a9208abf | 4711 | [(set_attr "type" "imul")]) |
d88ab5ca | 4712 | |
4713 | ||
4714 | ;; Boolean instructions. | |
4715 | ||
93e2cd75 | 4716 | ;; We define DImode `and' so with DImode `not' we can get |
4717 | ;; DImode `andn'. Other combinations are possible. | |
a44201ea | 4718 | |
bc963728 | 4719 | (define_expand "anddi3" |
4720 | [(set (match_operand:DI 0 "register_operand" "") | |
4721 | (and:DI (match_operand:DI 1 "arith_double_operand" "") | |
4722 | (match_operand:DI 2 "arith_double_operand" "")))] | |
a44201ea | 4723 | "" |
4724 | "") | |
4725 | ||
bc963728 | 4726 | (define_insn "*anddi3_sp32" |
4727 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4728 | (and:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
4729 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
df5e9319 | 4730 | "! TARGET_ARCH64" |
bc963728 | 4731 | "#") |
4732 | ||
4733 | (define_insn "*anddi3_sp64" | |
4734 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4735 | (and:DI (match_operand:DI 1 "arith_operand" "%r") | |
4736 | (match_operand:DI 2 "arith_operand" "rI")))] | |
df5e9319 | 4737 | "TARGET_ARCH64" |
bc963728 | 4738 | "and\t%1, %2, %0") |
001e2308 | 4739 | |
bc963728 | 4740 | (define_insn "andsi3" |
4741 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4742 | (and:SI (match_operand:SI 1 "arith_operand" "%r") | |
4743 | (match_operand:SI 2 "arith_operand" "rI")))] | |
a44201ea | 4744 | "" |
bc963728 | 4745 | "and\t%1, %2, %0") |
a44201ea | 4746 | |
edd18e3f | 4747 | (define_split |
4748 | [(set (match_operand:SI 0 "register_operand" "") | |
4749 | (and:SI (match_operand:SI 1 "register_operand" "") | |
35f85e39 | 4750 | (match_operand:SI 2 "const_compl_high_operand" ""))) |
21183941 | 4751 | (clobber (match_operand:SI 3 "register_operand" ""))] |
35f85e39 | 4752 | "" |
21183941 | 4753 | [(set (match_dup 3) (match_dup 4)) |
4754 | (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))] | |
edd18e3f | 4755 | { |
fb124916 | 4756 | operands[4] = GEN_INT (~INTVAL (operands[2])); |
0037630d | 4757 | }) |
edd18e3f | 4758 | |
bc963728 | 4759 | (define_insn_and_split "*and_not_di_sp32" |
4760 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4761 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r")) | |
4762 | (match_operand:DI 2 "register_operand" "r")))] | |
df5e9319 | 4763 | "! TARGET_ARCH64" |
bc963728 | 4764 | "#" |
43c08597 | 4765 | "&& reload_completed |
9ef15f91 | 4766 | && ((GET_CODE (operands[0]) == REG |
308d5709 | 4767 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
9ef15f91 | 4768 | || (GET_CODE (operands[0]) == SUBREG |
4769 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
308d5709 | 4770 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
998032ba | 4771 | [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5))) |
4772 | (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))] | |
a0fb7382 | 4773 | "operands[3] = gen_highpart (SImode, operands[0]); |
998032ba | 4774 | operands[4] = gen_highpart (SImode, operands[1]); |
4775 | operands[5] = gen_highpart (SImode, operands[2]); | |
4776 | operands[6] = gen_lowpart (SImode, operands[0]); | |
4777 | operands[7] = gen_lowpart (SImode, operands[1]); | |
43c08597 | 4778 | operands[8] = gen_lowpart (SImode, operands[2]);" |
bc963728 | 4779 | [(set_attr "length" "2")]) |
4780 | ||
4781 | (define_insn "*and_not_di_sp64" | |
4782 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4783 | (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r")) | |
4784 | (match_operand:DI 2 "register_operand" "r")))] | |
df5e9319 | 4785 | "TARGET_ARCH64" |
bc963728 | 4786 | "andn\t%2, %1, %0") |
001e2308 | 4787 | |
bc963728 | 4788 | (define_insn "*and_not_si" |
4789 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4790 | (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r")) | |
4791 | (match_operand:SI 2 "register_operand" "r")))] | |
a44201ea | 4792 | "" |
bc963728 | 4793 | "andn\t%2, %1, %0") |
a44201ea | 4794 | |
bc963728 | 4795 | (define_expand "iordi3" |
4796 | [(set (match_operand:DI 0 "register_operand" "") | |
4797 | (ior:DI (match_operand:DI 1 "arith_double_operand" "") | |
4798 | (match_operand:DI 2 "arith_double_operand" "")))] | |
a44201ea | 4799 | "" |
4800 | "") | |
4801 | ||
bc963728 | 4802 | (define_insn "*iordi3_sp32" |
4803 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4804 | (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
4805 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
df5e9319 | 4806 | "! TARGET_ARCH64" |
bc963728 | 4807 | "#" |
4808 | [(set_attr "length" "2")]) | |
4809 | ||
4810 | (define_insn "*iordi3_sp64" | |
4811 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4812 | (ior:DI (match_operand:DI 1 "arith_operand" "%r") | |
4813 | (match_operand:DI 2 "arith_operand" "rI")))] | |
df5e9319 | 4814 | "TARGET_ARCH64" |
bc963728 | 4815 | "or\t%1, %2, %0") |
001e2308 | 4816 | |
bc963728 | 4817 | (define_insn "iorsi3" |
4818 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4819 | (ior:SI (match_operand:SI 1 "arith_operand" "%r") | |
4820 | (match_operand:SI 2 "arith_operand" "rI")))] | |
a44201ea | 4821 | "" |
bc963728 | 4822 | "or\t%1, %2, %0") |
a44201ea | 4823 | |
edd18e3f | 4824 | (define_split |
4825 | [(set (match_operand:SI 0 "register_operand" "") | |
4826 | (ior:SI (match_operand:SI 1 "register_operand" "") | |
35f85e39 | 4827 | (match_operand:SI 2 "const_compl_high_operand" ""))) |
21183941 | 4828 | (clobber (match_operand:SI 3 "register_operand" ""))] |
35f85e39 | 4829 | "" |
21183941 | 4830 | [(set (match_dup 3) (match_dup 4)) |
4831 | (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))] | |
edd18e3f | 4832 | { |
e0db3f6a | 4833 | operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode); |
0037630d | 4834 | }) |
edd18e3f | 4835 | |
bc963728 | 4836 | (define_insn_and_split "*or_not_di_sp32" |
4837 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4838 | (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) | |
4839 | (match_operand:DI 2 "register_operand" "r")))] | |
df5e9319 | 4840 | "! TARGET_ARCH64" |
bc963728 | 4841 | "#" |
43c08597 | 4842 | "&& reload_completed |
9ef15f91 | 4843 | && ((GET_CODE (operands[0]) == REG |
308d5709 | 4844 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
9ef15f91 | 4845 | || (GET_CODE (operands[0]) == SUBREG |
4846 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
308d5709 | 4847 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
998032ba | 4848 | [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5))) |
4849 | (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))] | |
a0fb7382 | 4850 | "operands[3] = gen_highpart (SImode, operands[0]); |
998032ba | 4851 | operands[4] = gen_highpart (SImode, operands[1]); |
4852 | operands[5] = gen_highpart (SImode, operands[2]); | |
4853 | operands[6] = gen_lowpart (SImode, operands[0]); | |
4854 | operands[7] = gen_lowpart (SImode, operands[1]); | |
43c08597 | 4855 | operands[8] = gen_lowpart (SImode, operands[2]);" |
bc963728 | 4856 | [(set_attr "length" "2")]) |
4857 | ||
4858 | (define_insn "*or_not_di_sp64" | |
4859 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4860 | (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) | |
4861 | (match_operand:DI 2 "register_operand" "r")))] | |
df5e9319 | 4862 | "TARGET_ARCH64" |
bc963728 | 4863 | "orn\t%2, %1, %0") |
001e2308 | 4864 | |
bc963728 | 4865 | (define_insn "*or_not_si" |
4866 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4867 | (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) | |
4868 | (match_operand:SI 2 "register_operand" "r")))] | |
a44201ea | 4869 | "" |
bc963728 | 4870 | "orn\t%2, %1, %0") |
a44201ea | 4871 | |
bc963728 | 4872 | (define_expand "xordi3" |
4873 | [(set (match_operand:DI 0 "register_operand" "") | |
4874 | (xor:DI (match_operand:DI 1 "arith_double_operand" "") | |
4875 | (match_operand:DI 2 "arith_double_operand" "")))] | |
a44201ea | 4876 | "" |
4877 | "") | |
4878 | ||
bc963728 | 4879 | (define_insn "*xordi3_sp32" |
4880 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4881 | (xor:DI (match_operand:DI 1 "arith_double_operand" "%r") | |
4882 | (match_operand:DI 2 "arith_double_operand" "rHI")))] | |
df5e9319 | 4883 | "! TARGET_ARCH64" |
bc963728 | 4884 | "#" |
4885 | [(set_attr "length" "2")]) | |
4886 | ||
4887 | (define_insn "*xordi3_sp64" | |
4888 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4889 | (xor:DI (match_operand:DI 1 "arith_operand" "%rJ") | |
4890 | (match_operand:DI 2 "arith_operand" "rI")))] | |
df5e9319 | 4891 | "TARGET_ARCH64" |
bc963728 | 4892 | "xor\t%r1, %2, %0") |
998032ba | 4893 | |
bc963728 | 4894 | (define_insn "xorsi3" |
4895 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4896 | (xor:SI (match_operand:SI 1 "arith_operand" "%rJ") | |
4897 | (match_operand:SI 2 "arith_operand" "rI")))] | |
a44201ea | 4898 | "" |
bc963728 | 4899 | "xor\t%r1, %2, %0") |
a44201ea | 4900 | |
edd18e3f | 4901 | (define_split |
4902 | [(set (match_operand:SI 0 "register_operand" "") | |
4903 | (xor:SI (match_operand:SI 1 "register_operand" "") | |
35f85e39 | 4904 | (match_operand:SI 2 "const_compl_high_operand" ""))) |
21183941 | 4905 | (clobber (match_operand:SI 3 "register_operand" ""))] |
35f85e39 | 4906 | "" |
21183941 | 4907 | [(set (match_dup 3) (match_dup 4)) |
4908 | (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))] | |
edd18e3f | 4909 | { |
e0db3f6a | 4910 | operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode); |
0037630d | 4911 | }) |
edd18e3f | 4912 | |
4913 | (define_split | |
4914 | [(set (match_operand:SI 0 "register_operand" "") | |
4915 | (not:SI (xor:SI (match_operand:SI 1 "register_operand" "") | |
35f85e39 | 4916 | (match_operand:SI 2 "const_compl_high_operand" "")))) |
21183941 | 4917 | (clobber (match_operand:SI 3 "register_operand" ""))] |
35f85e39 | 4918 | "" |
21183941 | 4919 | [(set (match_dup 3) (match_dup 4)) |
4920 | (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))] | |
edd18e3f | 4921 | { |
e0db3f6a | 4922 | operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode); |
0037630d | 4923 | }) |
edd18e3f | 4924 | |
690f1a75 | 4925 | ;; Split DImode logical operations requiring two instructions. |
4926 | (define_split | |
bc963728 | 4927 | [(set (match_operand:DI 0 "register_operand" "") |
4928 | (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR | |
4929 | [(match_operand:DI 2 "register_operand" "") | |
4930 | (match_operand:DI 3 "arith_double_operand" "")]))] | |
690f1a75 | 4931 | "! TARGET_ARCH64 |
4932 | && reload_completed | |
4933 | && ((GET_CODE (operands[0]) == REG | |
308d5709 | 4934 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
690f1a75 | 4935 | || (GET_CODE (operands[0]) == SUBREG |
4936 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
308d5709 | 4937 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
690f1a75 | 4938 | [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)])) |
4939 | (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))] | |
4940 | { | |
4941 | operands[4] = gen_highpart (SImode, operands[0]); | |
4942 | operands[5] = gen_lowpart (SImode, operands[0]); | |
4943 | operands[6] = gen_highpart (SImode, operands[2]); | |
4944 | operands[7] = gen_lowpart (SImode, operands[2]); | |
4945 | #if HOST_BITS_PER_WIDE_INT == 32 | |
bc963728 | 4946 | if (GET_CODE (operands[3]) == CONST_INT) |
690f1a75 | 4947 | { |
4948 | if (INTVAL (operands[3]) < 0) | |
4949 | operands[8] = constm1_rtx; | |
4950 | else | |
4951 | operands[8] = const0_rtx; | |
4952 | } | |
4953 | else | |
4954 | #endif | |
bc963728 | 4955 | operands[8] = gen_highpart_mode (SImode, DImode, operands[3]); |
690f1a75 | 4956 | operands[9] = gen_lowpart (SImode, operands[3]); |
4957 | }) | |
4958 | ||
a44201ea | 4959 | ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b). |
4960 | ;; Combine now canonicalizes to the rightmost expression. | |
bc963728 | 4961 | (define_insn_and_split "*xor_not_di_sp32" |
4962 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4963 | (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") | |
4964 | (match_operand:DI 2 "register_operand" "r"))))] | |
df5e9319 | 4965 | "! TARGET_ARCH64" |
bc963728 | 4966 | "#" |
43c08597 | 4967 | "&& reload_completed |
9ef15f91 | 4968 | && ((GET_CODE (operands[0]) == REG |
308d5709 | 4969 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
9ef15f91 | 4970 | || (GET_CODE (operands[0]) == SUBREG |
4971 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
308d5709 | 4972 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
998032ba | 4973 | [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5)))) |
4974 | (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))] | |
a0fb7382 | 4975 | "operands[3] = gen_highpart (SImode, operands[0]); |
998032ba | 4976 | operands[4] = gen_highpart (SImode, operands[1]); |
4977 | operands[5] = gen_highpart (SImode, operands[2]); | |
4978 | operands[6] = gen_lowpart (SImode, operands[0]); | |
4979 | operands[7] = gen_lowpart (SImode, operands[1]); | |
43c08597 | 4980 | operands[8] = gen_lowpart (SImode, operands[2]);" |
bc963728 | 4981 | [(set_attr "length" "2")]) |
4982 | ||
4983 | (define_insn "*xor_not_di_sp64" | |
4984 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4985 | (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") | |
4986 | (match_operand:DI 2 "arith_operand" "rI"))))] | |
df5e9319 | 4987 | "TARGET_ARCH64" |
bc963728 | 4988 | "xnor\t%r1, %2, %0") |
001e2308 | 4989 | |
bc963728 | 4990 | (define_insn "*xor_not_si" |
4991 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4992 | (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
4993 | (match_operand:SI 2 "arith_operand" "rI"))))] | |
a44201ea | 4994 | "" |
bc963728 | 4995 | "xnor\t%r1, %2, %0") |
a44201ea | 4996 | |
4997 | ;; These correspond to the above in the case where we also (or only) | |
4998 | ;; want to set the condition code. | |
4999 | ||
4117925c | 5000 | (define_insn "*cmp_cc_arith_op" |
2b25173f | 5001 | [(set (reg:CC CC_REG) |
a44201ea | 5002 | (compare:CC |
27b36d57 | 5003 | (match_operator:SI 2 "cc_arith_operator" |
a44201ea | 5004 | [(match_operand:SI 0 "arith_operand" "%r") |
5005 | (match_operand:SI 1 "arith_operand" "rI")]) | |
5006 | (const_int 0)))] | |
f8be3dfc | 5007 | "" |
a4ddaca5 | 5008 | "%A2cc\t%0, %1, %%g0" |
a9208abf | 5009 | [(set_attr "type" "compare")]) |
a44201ea | 5010 | |
4117925c | 5011 | (define_insn "*cmp_ccx_arith_op" |
2b25173f | 5012 | [(set (reg:CCX CC_REG) |
001e2308 | 5013 | (compare:CCX |
27b36d57 | 5014 | (match_operator:DI 2 "cc_arith_operator" |
5015 | [(match_operand:DI 0 "arith_operand" "%r") | |
5016 | (match_operand:DI 1 "arith_operand" "rI")]) | |
001e2308 | 5017 | (const_int 0)))] |
df5e9319 | 5018 | "TARGET_ARCH64" |
a4ddaca5 | 5019 | "%A2cc\t%0, %1, %%g0" |
a9208abf | 5020 | [(set_attr "type" "compare")]) |
001e2308 | 5021 | |
4117925c | 5022 | (define_insn "*cmp_cc_arith_op_set" |
2b25173f | 5023 | [(set (reg:CC CC_REG) |
a44201ea | 5024 | (compare:CC |
27b36d57 | 5025 | (match_operator:SI 3 "cc_arith_operator" |
a44201ea | 5026 | [(match_operand:SI 1 "arith_operand" "%r") |
5027 | (match_operand:SI 2 "arith_operand" "rI")]) | |
5028 | (const_int 0))) | |
5029 | (set (match_operand:SI 0 "register_operand" "=r") | |
27b36d57 | 5030 | (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))] |
e35ffb4d | 5031 | "GET_CODE (operands[3]) == GET_CODE (operands[4])" |
a4ddaca5 | 5032 | "%A3cc\t%1, %2, %0" |
a9208abf | 5033 | [(set_attr "type" "compare")]) |
001e2308 | 5034 | |
4117925c | 5035 | (define_insn "*cmp_ccx_arith_op_set" |
2b25173f | 5036 | [(set (reg:CCX CC_REG) |
001e2308 | 5037 | (compare:CCX |
27b36d57 | 5038 | (match_operator:DI 3 "cc_arith_operator" |
5039 | [(match_operand:DI 1 "arith_operand" "%r") | |
5040 | (match_operand:DI 2 "arith_operand" "rI")]) | |
001e2308 | 5041 | (const_int 0))) |
5042 | (set (match_operand:DI 0 "register_operand" "=r") | |
27b36d57 | 5043 | (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))] |
e35ffb4d | 5044 | "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])" |
a4ddaca5 | 5045 | "%A3cc\t%1, %2, %0" |
a9208abf | 5046 | [(set_attr "type" "compare")]) |
a44201ea | 5047 | |
4117925c | 5048 | (define_insn "*cmp_cc_xor_not" |
2b25173f | 5049 | [(set (reg:CC CC_REG) |
a44201ea | 5050 | (compare:CC |
27b36d57 | 5051 | (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ") |
a44201ea | 5052 | (match_operand:SI 1 "arith_operand" "rI"))) |
5053 | (const_int 0)))] | |
f8be3dfc | 5054 | "" |
a4ddaca5 | 5055 | "xnorcc\t%r0, %1, %%g0" |
a9208abf | 5056 | [(set_attr "type" "compare")]) |
a44201ea | 5057 | |
4117925c | 5058 | (define_insn "*cmp_ccx_xor_not" |
2b25173f | 5059 | [(set (reg:CCX CC_REG) |
001e2308 | 5060 | (compare:CCX |
27b36d57 | 5061 | (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ") |
5062 | (match_operand:DI 1 "arith_operand" "rI"))) | |
001e2308 | 5063 | (const_int 0)))] |
df5e9319 | 5064 | "TARGET_ARCH64" |
a4ddaca5 | 5065 | "xnorcc\t%r0, %1, %%g0" |
a9208abf | 5066 | [(set_attr "type" "compare")]) |
001e2308 | 5067 | |
4117925c | 5068 | (define_insn "*cmp_cc_xor_not_set" |
2b25173f | 5069 | [(set (reg:CC CC_REG) |
a44201ea | 5070 | (compare:CC |
27b36d57 | 5071 | (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") |
a44201ea | 5072 | (match_operand:SI 2 "arith_operand" "rI"))) |
5073 | (const_int 0))) | |
5074 | (set (match_operand:SI 0 "register_operand" "=r") | |
5075 | (not:SI (xor:SI (match_dup 1) (match_dup 2))))] | |
5076 | "" | |
a4ddaca5 | 5077 | "xnorcc\t%r1, %2, %0" |
a9208abf | 5078 | [(set_attr "type" "compare")]) |
a44201ea | 5079 | |
4117925c | 5080 | (define_insn "*cmp_ccx_xor_not_set" |
2b25173f | 5081 | [(set (reg:CCX CC_REG) |
001e2308 | 5082 | (compare:CCX |
27b36d57 | 5083 | (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ") |
5084 | (match_operand:DI 2 "arith_operand" "rI"))) | |
001e2308 | 5085 | (const_int 0))) |
5086 | (set (match_operand:DI 0 "register_operand" "=r") | |
5087 | (not:DI (xor:DI (match_dup 1) (match_dup 2))))] | |
df5e9319 | 5088 | "TARGET_ARCH64" |
a4ddaca5 | 5089 | "xnorcc\t%r1, %2, %0" |
a9208abf | 5090 | [(set_attr "type" "compare")]) |
001e2308 | 5091 | |
4117925c | 5092 | (define_insn "*cmp_cc_arith_op_not" |
2b25173f | 5093 | [(set (reg:CC CC_REG) |
a44201ea | 5094 | (compare:CC |
27b36d57 | 5095 | (match_operator:SI 2 "cc_arith_not_operator" |
a44201ea | 5096 | [(not:SI (match_operand:SI 0 "arith_operand" "rI")) |
27b36d57 | 5097 | (match_operand:SI 1 "register_or_zero_operand" "rJ")]) |
a44201ea | 5098 | (const_int 0)))] |
f8be3dfc | 5099 | "" |
a4ddaca5 | 5100 | "%B2cc\t%r1, %0, %%g0" |
a9208abf | 5101 | [(set_attr "type" "compare")]) |
a44201ea | 5102 | |
4117925c | 5103 | (define_insn "*cmp_ccx_arith_op_not" |
2b25173f | 5104 | [(set (reg:CCX CC_REG) |
001e2308 | 5105 | (compare:CCX |
27b36d57 | 5106 | (match_operator:DI 2 "cc_arith_not_operator" |
5107 | [(not:DI (match_operand:DI 0 "arith_operand" "rI")) | |
5108 | (match_operand:DI 1 "register_or_zero_operand" "rJ")]) | |
001e2308 | 5109 | (const_int 0)))] |
df5e9319 | 5110 | "TARGET_ARCH64" |
a4ddaca5 | 5111 | "%B2cc\t%r1, %0, %%g0" |
a9208abf | 5112 | [(set_attr "type" "compare")]) |
001e2308 | 5113 | |
4117925c | 5114 | (define_insn "*cmp_cc_arith_op_not_set" |
2b25173f | 5115 | [(set (reg:CC CC_REG) |
a44201ea | 5116 | (compare:CC |
27b36d57 | 5117 | (match_operator:SI 3 "cc_arith_not_operator" |
a44201ea | 5118 | [(not:SI (match_operand:SI 1 "arith_operand" "rI")) |
27b36d57 | 5119 | (match_operand:SI 2 "register_or_zero_operand" "rJ")]) |
a44201ea | 5120 | (const_int 0))) |
5121 | (set (match_operand:SI 0 "register_operand" "=r") | |
27b36d57 | 5122 | (match_operator:SI 4 "cc_arith_not_operator" |
e35ffb4d | 5123 | [(not:SI (match_dup 1)) (match_dup 2)]))] |
5124 | "GET_CODE (operands[3]) == GET_CODE (operands[4])" | |
a4ddaca5 | 5125 | "%B3cc\t%r2, %1, %0" |
a9208abf | 5126 | [(set_attr "type" "compare")]) |
a44201ea | 5127 | |
4117925c | 5128 | (define_insn "*cmp_ccx_arith_op_not_set" |
2b25173f | 5129 | [(set (reg:CCX CC_REG) |
001e2308 | 5130 | (compare:CCX |
27b36d57 | 5131 | (match_operator:DI 3 "cc_arith_not_operator" |
5132 | [(not:DI (match_operand:DI 1 "arith_operand" "rI")) | |
5133 | (match_operand:DI 2 "register_or_zero_operand" "rJ")]) | |
001e2308 | 5134 | (const_int 0))) |
5135 | (set (match_operand:DI 0 "register_operand" "=r") | |
27b36d57 | 5136 | (match_operator:DI 4 "cc_arith_not_operator" |
e35ffb4d | 5137 | [(not:DI (match_dup 1)) (match_dup 2)]))] |
5138 | "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])" | |
a4ddaca5 | 5139 | "%B3cc\t%r2, %1, %0" |
a9208abf | 5140 | [(set_attr "type" "compare")]) |
001e2308 | 5141 | |
a44201ea | 5142 | ;; We cannot use the "neg" pseudo insn because the Sun assembler |
5143 | ;; does not know how to make it work for constants. | |
5144 | ||
001e2308 | 5145 | (define_expand "negdi2" |
5146 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5147 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
5148 | "" | |
001e2308 | 5149 | { |
df5e9319 | 5150 | if (! TARGET_ARCH64) |
001e2308 | 5151 | { |
7014838c | 5152 | emit_insn (gen_rtx_PARALLEL |
5153 | (VOIDmode, | |
5154 | gen_rtvec (2, | |
5155 | gen_rtx_SET (VOIDmode, operand0, | |
5156 | gen_rtx_NEG (DImode, operand1)), | |
5157 | gen_rtx_CLOBBER (VOIDmode, | |
5158 | gen_rtx_REG (CCmode, | |
5159 | SPARC_ICC_REG))))); | |
001e2308 | 5160 | DONE; |
5161 | } | |
0037630d | 5162 | }) |
001e2308 | 5163 | |
43c08597 | 5164 | (define_insn_and_split "*negdi2_sp32" |
a44201ea | 5165 | [(set (match_operand:DI 0 "register_operand" "=r") |
5166 | (neg:DI (match_operand:DI 1 "register_operand" "r"))) | |
2b25173f | 5167 | (clobber (reg:CC CC_REG))] |
76ab33ff | 5168 | "! TARGET_ARCH64" |
998032ba | 5169 | "#" |
43c08597 | 5170 | "&& reload_completed" |
2b25173f | 5171 | [(parallel [(set (reg:CC_NOOV CC_REG) |
998032ba | 5172 | (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5)) |
5173 | (const_int 0))) | |
5174 | (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))]) | |
5175 | (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) | |
2b25173f | 5176 | (ltu:SI (reg:CC CC_REG) (const_int 0))))] |
998032ba | 5177 | "operands[2] = gen_highpart (SImode, operands[0]); |
5178 | operands[3] = gen_highpart (SImode, operands[1]); | |
5179 | operands[4] = gen_lowpart (SImode, operands[0]); | |
43c08597 | 5180 | operands[5] = gen_lowpart (SImode, operands[1]);" |
5181 | [(set_attr "length" "2")]) | |
998032ba | 5182 | |
4117925c | 5183 | (define_insn "*negdi2_sp64" |
001e2308 | 5184 | [(set (match_operand:DI 0 "register_operand" "=r") |
5185 | (neg:DI (match_operand:DI 1 "register_operand" "r")))] | |
df5e9319 | 5186 | "TARGET_ARCH64" |
a4ddaca5 | 5187 | "sub\t%%g0, %1, %0") |
001e2308 | 5188 | |
f8be3dfc | 5189 | (define_insn "negsi2" |
998032ba | 5190 | [(set (match_operand:SI 0 "register_operand" "=r") |
f8be3dfc | 5191 | (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] |
5192 | "" | |
a4ddaca5 | 5193 | "sub\t%%g0, %1, %0") |
a44201ea | 5194 | |
4117925c | 5195 | (define_insn "*cmp_cc_neg" |
2b25173f | 5196 | [(set (reg:CC_NOOV CC_REG) |
a44201ea | 5197 | (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) |
5198 | (const_int 0)))] | |
f8be3dfc | 5199 | "" |
a4ddaca5 | 5200 | "subcc\t%%g0, %0, %%g0" |
a9208abf | 5201 | [(set_attr "type" "compare")]) |
a44201ea | 5202 | |
4117925c | 5203 | (define_insn "*cmp_ccx_neg" |
2b25173f | 5204 | [(set (reg:CCX_NOOV CC_REG) |
27b36d57 | 5205 | (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI")) |
001e2308 | 5206 | (const_int 0)))] |
df5e9319 | 5207 | "TARGET_ARCH64" |
a4ddaca5 | 5208 | "subcc\t%%g0, %0, %%g0" |
a9208abf | 5209 | [(set_attr "type" "compare")]) |
001e2308 | 5210 | |
4117925c | 5211 | (define_insn "*cmp_cc_set_neg" |
2b25173f | 5212 | [(set (reg:CC_NOOV CC_REG) |
a44201ea | 5213 | (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) |
5214 | (const_int 0))) | |
5215 | (set (match_operand:SI 0 "register_operand" "=r") | |
5216 | (neg:SI (match_dup 1)))] | |
f8be3dfc | 5217 | "" |
a4ddaca5 | 5218 | "subcc\t%%g0, %1, %0" |
a9208abf | 5219 | [(set_attr "type" "compare")]) |
a44201ea | 5220 | |
4117925c | 5221 | (define_insn "*cmp_ccx_set_neg" |
2b25173f | 5222 | [(set (reg:CCX_NOOV CC_REG) |
27b36d57 | 5223 | (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI")) |
001e2308 | 5224 | (const_int 0))) |
5225 | (set (match_operand:DI 0 "register_operand" "=r") | |
5226 | (neg:DI (match_dup 1)))] | |
df5e9319 | 5227 | "TARGET_ARCH64" |
a4ddaca5 | 5228 | "subcc\t%%g0, %1, %0" |
a9208abf | 5229 | [(set_attr "type" "compare")]) |
001e2308 | 5230 | |
a44201ea | 5231 | ;; We cannot use the "not" pseudo insn because the Sun assembler |
5232 | ;; does not know how to make it work for constants. | |
bc963728 | 5233 | (define_expand "one_cmpldi2" |
5234 | [(set (match_operand:DI 0 "register_operand" "") | |
5235 | (not:DI (match_operand:DI 1 "register_operand" "")))] | |
a44201ea | 5236 | "" |
5237 | "") | |
5238 | ||
bc963728 | 5239 | (define_insn_and_split "*one_cmpldi2_sp32" |
5240 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5241 | (not:DI (match_operand:DI 1 "register_operand" "r")))] | |
df5e9319 | 5242 | "! TARGET_ARCH64" |
bc963728 | 5243 | "#" |
43c08597 | 5244 | "&& reload_completed |
9ef15f91 | 5245 | && ((GET_CODE (operands[0]) == REG |
308d5709 | 5246 | && SPARC_INT_REG_P (REGNO (operands[0]))) |
9ef15f91 | 5247 | || (GET_CODE (operands[0]) == SUBREG |
5248 | && GET_CODE (SUBREG_REG (operands[0])) == REG | |
308d5709 | 5249 | && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))" |
998032ba | 5250 | [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0)))) |
5251 | (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))] | |
a0fb7382 | 5252 | "operands[2] = gen_highpart (SImode, operands[0]); |
998032ba | 5253 | operands[3] = gen_highpart (SImode, operands[1]); |
5254 | operands[4] = gen_lowpart (SImode, operands[0]); | |
43c08597 | 5255 | operands[5] = gen_lowpart (SImode, operands[1]);" |
bc963728 | 5256 | [(set_attr "length" "2")]) |
998032ba | 5257 | |
bc963728 | 5258 | (define_insn "*one_cmpldi2_sp64" |
5259 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5260 | (not:DI (match_operand:DI 1 "arith_operand" "rI")))] | |
df5e9319 | 5261 | "TARGET_ARCH64" |
bc963728 | 5262 | "xnor\t%%g0, %1, %0") |
001e2308 | 5263 | |
bc963728 | 5264 | (define_insn "one_cmplsi2" |
5265 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5266 | (not:SI (match_operand:SI 1 "arith_operand" "rI")))] | |
f8be3dfc | 5267 | "" |
bc963728 | 5268 | "xnor\t%%g0, %1, %0") |
998032ba | 5269 | |
4117925c | 5270 | (define_insn "*cmp_cc_not" |
2b25173f | 5271 | [(set (reg:CC CC_REG) |
a44201ea | 5272 | (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) |
5273 | (const_int 0)))] | |
f8be3dfc | 5274 | "" |
a4ddaca5 | 5275 | "xnorcc\t%%g0, %0, %%g0" |
a9208abf | 5276 | [(set_attr "type" "compare")]) |
a44201ea | 5277 | |
4117925c | 5278 | (define_insn "*cmp_ccx_not" |
2b25173f | 5279 | [(set (reg:CCX CC_REG) |
27b36d57 | 5280 | (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI")) |
001e2308 | 5281 | (const_int 0)))] |
df5e9319 | 5282 | "TARGET_ARCH64" |
a4ddaca5 | 5283 | "xnorcc\t%%g0, %0, %%g0" |
a9208abf | 5284 | [(set_attr "type" "compare")]) |
001e2308 | 5285 | |
4117925c | 5286 | (define_insn "*cmp_cc_set_not" |
2b25173f | 5287 | [(set (reg:CC CC_REG) |
a44201ea | 5288 | (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) |
5289 | (const_int 0))) | |
5290 | (set (match_operand:SI 0 "register_operand" "=r") | |
5291 | (not:SI (match_dup 1)))] | |
f8be3dfc | 5292 | "" |
a4ddaca5 | 5293 | "xnorcc\t%%g0, %1, %0" |
a9208abf | 5294 | [(set_attr "type" "compare")]) |
001e2308 | 5295 | |
4117925c | 5296 | (define_insn "*cmp_ccx_set_not" |
2b25173f | 5297 | [(set (reg:CCX CC_REG) |
27b36d57 | 5298 | (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI")) |
001e2308 | 5299 | (const_int 0))) |
5300 | (set (match_operand:DI 0 "register_operand" "=r") | |
5301 | (not:DI (match_dup 1)))] | |
df5e9319 | 5302 | "TARGET_ARCH64" |
a4ddaca5 | 5303 | "xnorcc\t%%g0, %1, %0" |
a9208abf | 5304 | [(set_attr "type" "compare")]) |
55d52cfe | 5305 | |
5306 | (define_insn "*cmp_cc_set" | |
5307 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5308 | (match_operand:SI 1 "register_operand" "r")) | |
2b25173f | 5309 | (set (reg:CC CC_REG) |
55d52cfe | 5310 | (compare:CC (match_dup 1) |
5311 | (const_int 0)))] | |
5312 | "" | |
a4ddaca5 | 5313 | "orcc\t%1, 0, %0" |
55d52cfe | 5314 | [(set_attr "type" "compare")]) |
5315 | ||
5316 | (define_insn "*cmp_ccx_set64" | |
5317 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5318 | (match_operand:DI 1 "register_operand" "r")) | |
2b25173f | 5319 | (set (reg:CCX CC_REG) |
55d52cfe | 5320 | (compare:CCX (match_dup 1) |
5321 | (const_int 0)))] | |
5322 | "TARGET_ARCH64" | |
a4ddaca5 | 5323 | "orcc\t%1, 0, %0" |
55d52cfe | 5324 | [(set_attr "type" "compare")]) |
d88ab5ca | 5325 | |
5326 | ||
a44201ea | 5327 | ;; Floating point arithmetic instructions. |
5328 | ||
75997b31 | 5329 | (define_expand "addtf3" |
5330 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
5331 | (plus:TF (match_operand:TF 1 "general_operand" "") | |
5332 | (match_operand:TF 2 "general_operand" "")))] | |
5333 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
c00088b6 | 5334 | "emit_tfmode_binop (PLUS, operands); DONE;") |
75997b31 | 5335 | |
5336 | (define_insn "*addtf3_hq" | |
65ccdc13 | 5337 | [(set (match_operand:TF 0 "register_operand" "=e") |
5338 | (plus:TF (match_operand:TF 1 "register_operand" "e") | |
5339 | (match_operand:TF 2 "register_operand" "e")))] | |
b0454100 | 5340 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 5341 | "faddq\t%1, %2, %0" |
a9208abf | 5342 | [(set_attr "type" "fp")]) |
93fed860 | 5343 | |
a44201ea | 5344 | (define_insn "adddf3" |
65ccdc13 | 5345 | [(set (match_operand:DF 0 "register_operand" "=e") |
5346 | (plus:DF (match_operand:DF 1 "register_operand" "e") | |
5347 | (match_operand:DF 2 "register_operand" "e")))] | |
f2ed3c03 | 5348 | "TARGET_FPU" |
a4ddaca5 | 5349 | "faddd\t%1, %2, %0" |
998032ba | 5350 | [(set_attr "type" "fp") |
a9208abf | 5351 | (set_attr "fptype" "double")]) |
a44201ea | 5352 | |
5353 | (define_insn "addsf3" | |
5354 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5355 | (plus:SF (match_operand:SF 1 "register_operand" "f") | |
5356 | (match_operand:SF 2 "register_operand" "f")))] | |
f2ed3c03 | 5357 | "TARGET_FPU" |
a4ddaca5 | 5358 | "fadds\t%1, %2, %0" |
a9208abf | 5359 | [(set_attr "type" "fp")]) |
a44201ea | 5360 | |
75997b31 | 5361 | (define_expand "subtf3" |
5362 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
5363 | (minus:TF (match_operand:TF 1 "general_operand" "") | |
5364 | (match_operand:TF 2 "general_operand" "")))] | |
5365 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
c00088b6 | 5366 | "emit_tfmode_binop (MINUS, operands); DONE;") |
75997b31 | 5367 | |
5368 | (define_insn "*subtf3_hq" | |
65ccdc13 | 5369 | [(set (match_operand:TF 0 "register_operand" "=e") |
5370 | (minus:TF (match_operand:TF 1 "register_operand" "e") | |
5371 | (match_operand:TF 2 "register_operand" "e")))] | |
b0454100 | 5372 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 5373 | "fsubq\t%1, %2, %0" |
a9208abf | 5374 | [(set_attr "type" "fp")]) |
93fed860 | 5375 | |
a44201ea | 5376 | (define_insn "subdf3" |
65ccdc13 | 5377 | [(set (match_operand:DF 0 "register_operand" "=e") |
5378 | (minus:DF (match_operand:DF 1 "register_operand" "e") | |
5379 | (match_operand:DF 2 "register_operand" "e")))] | |
f2ed3c03 | 5380 | "TARGET_FPU" |
a4ddaca5 | 5381 | "fsubd\t%1, %2, %0" |
998032ba | 5382 | [(set_attr "type" "fp") |
a9208abf | 5383 | (set_attr "fptype" "double")]) |
a44201ea | 5384 | |
5385 | (define_insn "subsf3" | |
5386 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5387 | (minus:SF (match_operand:SF 1 "register_operand" "f") | |
5388 | (match_operand:SF 2 "register_operand" "f")))] | |
f2ed3c03 | 5389 | "TARGET_FPU" |
a4ddaca5 | 5390 | "fsubs\t%1, %2, %0" |
a9208abf | 5391 | [(set_attr "type" "fp")]) |
a44201ea | 5392 | |
75997b31 | 5393 | (define_expand "multf3" |
5394 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
5395 | (mult:TF (match_operand:TF 1 "general_operand" "") | |
5396 | (match_operand:TF 2 "general_operand" "")))] | |
5397 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
c00088b6 | 5398 | "emit_tfmode_binop (MULT, operands); DONE;") |
75997b31 | 5399 | |
5400 | (define_insn "*multf3_hq" | |
65ccdc13 | 5401 | [(set (match_operand:TF 0 "register_operand" "=e") |
5402 | (mult:TF (match_operand:TF 1 "register_operand" "e") | |
5403 | (match_operand:TF 2 "register_operand" "e")))] | |
b0454100 | 5404 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 5405 | "fmulq\t%1, %2, %0" |
a9208abf | 5406 | [(set_attr "type" "fpmul")]) |
93fed860 | 5407 | |
a44201ea | 5408 | (define_insn "muldf3" |
65ccdc13 | 5409 | [(set (match_operand:DF 0 "register_operand" "=e") |
5410 | (mult:DF (match_operand:DF 1 "register_operand" "e") | |
5411 | (match_operand:DF 2 "register_operand" "e")))] | |
f2ed3c03 | 5412 | "TARGET_FPU" |
a4ddaca5 | 5413 | "fmuld\t%1, %2, %0" |
998032ba | 5414 | [(set_attr "type" "fpmul") |
a9208abf | 5415 | (set_attr "fptype" "double")]) |
a44201ea | 5416 | |
5417 | (define_insn "mulsf3" | |
5418 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5419 | (mult:SF (match_operand:SF 1 "register_operand" "f") | |
5420 | (match_operand:SF 2 "register_operand" "f")))] | |
f2ed3c03 | 5421 | "TARGET_FPU" |
a4ddaca5 | 5422 | "fmuls\t%1, %2, %0" |
a9208abf | 5423 | [(set_attr "type" "fpmul")]) |
a44201ea | 5424 | |
0468cf8f | 5425 | (define_insn "fmadf4" |
5426 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5427 | (fma:DF (match_operand:DF 1 "register_operand" "e") | |
5428 | (match_operand:DF 2 "register_operand" "e") | |
5429 | (match_operand:DF 3 "register_operand" "e")))] | |
5430 | "TARGET_FMAF" | |
5431 | "fmaddd\t%1, %2, %3, %0" | |
5432 | [(set_attr "type" "fpmul")]) | |
5433 | ||
5434 | (define_insn "fmsdf4" | |
5435 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5436 | (fma:DF (match_operand:DF 1 "register_operand" "e") | |
5437 | (match_operand:DF 2 "register_operand" "e") | |
5438 | (neg:DF (match_operand:DF 3 "register_operand" "e"))))] | |
5439 | "TARGET_FMAF" | |
5440 | "fmsubd\t%1, %2, %3, %0" | |
5441 | [(set_attr "type" "fpmul")]) | |
5442 | ||
5443 | (define_insn "*nfmadf4" | |
5444 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5445 | (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e") | |
5446 | (match_operand:DF 2 "register_operand" "e") | |
5447 | (match_operand:DF 3 "register_operand" "e"))))] | |
5448 | "TARGET_FMAF" | |
5449 | "fnmaddd\t%1, %2, %3, %0" | |
5450 | [(set_attr "type" "fpmul")]) | |
5451 | ||
5452 | (define_insn "*nfmsdf4" | |
5453 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5454 | (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e") | |
5455 | (match_operand:DF 2 "register_operand" "e") | |
5456 | (neg:DF (match_operand:DF 3 "register_operand" "e")))))] | |
5457 | "TARGET_FMAF" | |
5458 | "fnmsubd\t%1, %2, %3, %0" | |
5459 | [(set_attr "type" "fpmul")]) | |
5460 | ||
5461 | (define_insn "fmasf4" | |
5462 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5463 | (fma:SF (match_operand:SF 1 "register_operand" "f") | |
5464 | (match_operand:SF 2 "register_operand" "f") | |
5465 | (match_operand:SF 3 "register_operand" "f")))] | |
5466 | "TARGET_FMAF" | |
5467 | "fmadds\t%1, %2, %3, %0" | |
5468 | [(set_attr "type" "fpmul")]) | |
5469 | ||
5470 | (define_insn "fmssf4" | |
5471 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5472 | (fma:SF (match_operand:SF 1 "register_operand" "f") | |
5473 | (match_operand:SF 2 "register_operand" "f") | |
5474 | (neg:SF (match_operand:SF 3 "register_operand" "f"))))] | |
5475 | "TARGET_FMAF" | |
5476 | "fmsubs\t%1, %2, %3, %0" | |
5477 | [(set_attr "type" "fpmul")]) | |
5478 | ||
5479 | (define_insn "*nfmasf4" | |
5480 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5481 | (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f") | |
5482 | (match_operand:SF 2 "register_operand" "f") | |
5483 | (match_operand:SF 3 "register_operand" "f"))))] | |
5484 | "TARGET_FMAF" | |
5485 | "fnmadds\t%1, %2, %3, %0" | |
5486 | [(set_attr "type" "fpmul")]) | |
5487 | ||
5488 | (define_insn "*nfmssf4" | |
5489 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5490 | (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f") | |
5491 | (match_operand:SF 2 "register_operand" "f") | |
5492 | (neg:SF (match_operand:SF 3 "register_operand" "f")))))] | |
5493 | "TARGET_FMAF" | |
5494 | "fnmsubs\t%1, %2, %3, %0" | |
5495 | [(set_attr "type" "fpmul")]) | |
5496 | ||
4117925c | 5497 | (define_insn "*muldf3_extend" |
65ccdc13 | 5498 | [(set (match_operand:DF 0 "register_operand" "=e") |
2dfa6bfc | 5499 | (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f")) |
5500 | (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))] | |
d6a0a4b0 | 5501 | "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699" |
a4ddaca5 | 5502 | "fsmuld\t%1, %2, %0" |
998032ba | 5503 | [(set_attr "type" "fpmul") |
a9208abf | 5504 | (set_attr "fptype" "double")]) |
2dfa6bfc | 5505 | |
4117925c | 5506 | (define_insn "*multf3_extend" |
65ccdc13 | 5507 | [(set (match_operand:TF 0 "register_operand" "=e") |
5508 | (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e")) | |
5509 | (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))] | |
df5e9319 | 5510 | "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 5511 | "fdmulq\t%1, %2, %0" |
a9208abf | 5512 | [(set_attr "type" "fpmul")]) |
2dfa6bfc | 5513 | |
75997b31 | 5514 | (define_expand "divtf3" |
5515 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
5516 | (div:TF (match_operand:TF 1 "general_operand" "") | |
5517 | (match_operand:TF 2 "general_operand" "")))] | |
5518 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" | |
c00088b6 | 5519 | "emit_tfmode_binop (DIV, operands); DONE;") |
75997b31 | 5520 | |
e521d1d7 | 5521 | ;; don't have timing for quad-prec. divide. |
75997b31 | 5522 | (define_insn "*divtf3_hq" |
65ccdc13 | 5523 | [(set (match_operand:TF 0 "register_operand" "=e") |
5524 | (div:TF (match_operand:TF 1 "register_operand" "e") | |
5525 | (match_operand:TF 2 "register_operand" "e")))] | |
b0454100 | 5526 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 5527 | "fdivq\t%1, %2, %0" |
c495d615 | 5528 | [(set_attr "type" "fpdivs")]) |
93fed860 | 5529 | |
d6a0a4b0 | 5530 | (define_expand "divdf3" |
65ccdc13 | 5531 | [(set (match_operand:DF 0 "register_operand" "=e") |
5532 | (div:DF (match_operand:DF 1 "register_operand" "e") | |
5533 | (match_operand:DF 2 "register_operand" "e")))] | |
f2ed3c03 | 5534 | "TARGET_FPU" |
d6a0a4b0 | 5535 | "") |
5536 | ||
5537 | (define_insn "*divdf3_nofix" | |
5538 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5539 | (div:DF (match_operand:DF 1 "register_operand" "e") | |
5540 | (match_operand:DF 2 "register_operand" "e")))] | |
5541 | "TARGET_FPU && !sparc_fix_ut699" | |
a4ddaca5 | 5542 | "fdivd\t%1, %2, %0" |
998032ba | 5543 | [(set_attr "type" "fpdivd") |
a9208abf | 5544 | (set_attr "fptype" "double")]) |
a44201ea | 5545 | |
d6a0a4b0 | 5546 | (define_insn "*divdf3_fix" |
5547 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5548 | (div:DF (match_operand:DF 1 "register_operand" "e") | |
5549 | (match_operand:DF 2 "register_operand" "e")))] | |
5550 | "TARGET_FPU && sparc_fix_ut699" | |
5551 | "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]" | |
5552 | [(set_attr "type" "fpdivd") | |
5553 | (set_attr "fptype" "double") | |
5554 | (set_attr "length" "2")]) | |
5555 | ||
a44201ea | 5556 | (define_insn "divsf3" |
5557 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5558 | (div:SF (match_operand:SF 1 "register_operand" "f") | |
5559 | (match_operand:SF 2 "register_operand" "f")))] | |
d6a0a4b0 | 5560 | "TARGET_FPU && !sparc_fix_ut699" |
a4ddaca5 | 5561 | "fdivs\t%1, %2, %0" |
a9208abf | 5562 | [(set_attr "type" "fpdivs")]) |
a44201ea | 5563 | |
1772450b | 5564 | (define_expand "negtf2" |
07ae93ca | 5565 | [(set (match_operand:TF 0 "register_operand" "") |
5566 | (neg:TF (match_operand:TF 1 "register_operand" "")))] | |
f2ed3c03 | 5567 | "TARGET_FPU" |
1772450b | 5568 | "") |
5569 | ||
07ae93ca | 5570 | (define_insn "*negtf2_hq" |
5571 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5572 | (neg:TF (match_operand:TF 1 "register_operand" "e")))] | |
5573 | "TARGET_FPU && TARGET_HARD_QUAD" | |
5574 | "fnegq\t%1, %0" | |
5575 | [(set_attr "type" "fpmove")]) | |
5576 | ||
5577 | (define_insn_and_split "*negtf2" | |
5578 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5579 | (neg:TF (match_operand:TF 1 "register_operand" "e")))] | |
5580 | "TARGET_FPU && !TARGET_HARD_QUAD" | |
5581 | "#" | |
5582 | "&& reload_completed" | |
5583 | [(clobber (const_int 0))] | |
5584 | { | |
5585 | rtx set_dest = operands[0]; | |
5586 | rtx set_src = operands[1]; | |
5587 | rtx dest1, dest2; | |
5588 | rtx src1, src2; | |
5589 | ||
5590 | dest1 = gen_df_reg (set_dest, 0); | |
5591 | dest2 = gen_df_reg (set_dest, 1); | |
5592 | src1 = gen_df_reg (set_src, 0); | |
5593 | src2 = gen_df_reg (set_src, 1); | |
5594 | ||
5595 | /* Now emit using the real source and destination we found, swapping | |
5596 | the order if we detect overlap. */ | |
5597 | if (reg_overlap_mentioned_p (dest1, src2)) | |
5598 | { | |
5599 | emit_insn (gen_movdf (dest2, src2)); | |
5600 | emit_insn (gen_negdf2 (dest1, src1)); | |
5601 | } | |
5602 | else | |
5603 | { | |
5604 | emit_insn (gen_negdf2 (dest1, src1)); | |
5605 | if (REGNO (dest2) != REGNO (src2)) | |
5606 | emit_insn (gen_movdf (dest2, src2)); | |
5607 | } | |
5608 | DONE; | |
5609 | } | |
5610 | [(set_attr "length" "2")]) | |
1772450b | 5611 | |
5612 | (define_expand "negdf2" | |
5613 | [(set (match_operand:DF 0 "register_operand" "") | |
5614 | (neg:DF (match_operand:DF 1 "register_operand" "")))] | |
5615 | "TARGET_FPU" | |
5616 | "") | |
5617 | ||
43c08597 | 5618 | (define_insn_and_split "*negdf2_notv9" |
07ae93ca | 5619 | [(set (match_operand:DF 0 "register_operand" "=e") |
5620 | (neg:DF (match_operand:DF 1 "register_operand" "e")))] | |
5621 | "TARGET_FPU && !TARGET_V9" | |
5622 | "#" | |
5623 | "&& reload_completed" | |
5624 | [(clobber (const_int 0))] | |
5625 | { | |
5626 | rtx set_dest = operands[0]; | |
5627 | rtx set_src = operands[1]; | |
5628 | rtx dest1, dest2; | |
5629 | rtx src1, src2; | |
5630 | ||
5631 | dest1 = gen_highpart (SFmode, set_dest); | |
5632 | dest2 = gen_lowpart (SFmode, set_dest); | |
5633 | src1 = gen_highpart (SFmode, set_src); | |
5634 | src2 = gen_lowpart (SFmode, set_src); | |
5635 | ||
5636 | /* Now emit using the real source and destination we found, swapping | |
5637 | the order if we detect overlap. */ | |
5638 | if (reg_overlap_mentioned_p (dest1, src2)) | |
5639 | { | |
5640 | emit_insn (gen_movsf (dest2, src2)); | |
5641 | emit_insn (gen_negsf2 (dest1, src1)); | |
5642 | } | |
5643 | else | |
5644 | { | |
5645 | emit_insn (gen_negsf2 (dest1, src1)); | |
5646 | if (REGNO (dest2) != REGNO (src2)) | |
5647 | emit_insn (gen_movsf (dest2, src2)); | |
5648 | } | |
5649 | DONE; | |
5650 | } | |
5651 | [(set_attr "length" "2")]) | |
1772450b | 5652 | |
5653 | (define_insn "*negdf2_v9" | |
5654 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5655 | (neg:DF (match_operand:DF 1 "register_operand" "e")))] | |
5656 | "TARGET_FPU && TARGET_V9" | |
a4ddaca5 | 5657 | "fnegd\t%1, %0" |
1772450b | 5658 | [(set_attr "type" "fpmove") |
a9208abf | 5659 | (set_attr "fptype" "double")]) |
a44201ea | 5660 | |
a44201ea | 5661 | (define_insn "negsf2" |
5662 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5663 | (neg:SF (match_operand:SF 1 "register_operand" "f")))] | |
f2ed3c03 | 5664 | "TARGET_FPU" |
a4ddaca5 | 5665 | "fnegs\t%1, %0" |
a9208abf | 5666 | [(set_attr "type" "fpmove")]) |
a44201ea | 5667 | |
6fcf3e75 | 5668 | (define_expand "abstf2" |
1772450b | 5669 | [(set (match_operand:TF 0 "register_operand" "") |
5670 | (abs:TF (match_operand:TF 1 "register_operand" "")))] | |
5671 | "TARGET_FPU" | |
5672 | "") | |
5673 | ||
07ae93ca | 5674 | (define_insn "*abstf2_hq" |
5675 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5676 | (abs:TF (match_operand:TF 1 "register_operand" "e")))] | |
5677 | "TARGET_FPU && TARGET_HARD_QUAD" | |
5678 | "fabsq\t%1, %0" | |
5679 | [(set_attr "type" "fpmove")]) | |
1772450b | 5680 | |
07ae93ca | 5681 | (define_insn_and_split "*abstf2" |
5682 | [(set (match_operand:TF 0 "register_operand" "=e") | |
5683 | (abs:TF (match_operand:TF 1 "register_operand" "e")))] | |
5684 | "TARGET_FPU && !TARGET_HARD_QUAD" | |
5685 | "#" | |
5686 | "&& reload_completed" | |
5687 | [(clobber (const_int 0))] | |
5688 | { | |
5689 | rtx set_dest = operands[0]; | |
5690 | rtx set_src = operands[1]; | |
5691 | rtx dest1, dest2; | |
5692 | rtx src1, src2; | |
5693 | ||
5694 | dest1 = gen_df_reg (set_dest, 0); | |
5695 | dest2 = gen_df_reg (set_dest, 1); | |
5696 | src1 = gen_df_reg (set_src, 0); | |
5697 | src2 = gen_df_reg (set_src, 1); | |
5698 | ||
5699 | /* Now emit using the real source and destination we found, swapping | |
5700 | the order if we detect overlap. */ | |
5701 | if (reg_overlap_mentioned_p (dest1, src2)) | |
5702 | { | |
5703 | emit_insn (gen_movdf (dest2, src2)); | |
5704 | emit_insn (gen_absdf2 (dest1, src1)); | |
5705 | } | |
5706 | else | |
5707 | { | |
5708 | emit_insn (gen_absdf2 (dest1, src1)); | |
5709 | if (REGNO (dest2) != REGNO (src2)) | |
5710 | emit_insn (gen_movdf (dest2, src2)); | |
5711 | } | |
5712 | DONE; | |
5713 | } | |
5714 | [(set_attr "length" "2")]) | |
1772450b | 5715 | |
5716 | (define_expand "absdf2" | |
5717 | [(set (match_operand:DF 0 "register_operand" "") | |
5718 | (abs:DF (match_operand:DF 1 "register_operand" "")))] | |
f2ed3c03 | 5719 | "TARGET_FPU" |
1772450b | 5720 | "") |
5721 | ||
43c08597 | 5722 | (define_insn_and_split "*absdf2_notv9" |
07ae93ca | 5723 | [(set (match_operand:DF 0 "register_operand" "=e") |
5724 | (abs:DF (match_operand:DF 1 "register_operand" "e")))] | |
5725 | "TARGET_FPU && !TARGET_V9" | |
5726 | "#" | |
5727 | "&& reload_completed" | |
5728 | [(clobber (const_int 0))] | |
5729 | { | |
5730 | rtx set_dest = operands[0]; | |
5731 | rtx set_src = operands[1]; | |
5732 | rtx dest1, dest2; | |
5733 | rtx src1, src2; | |
5734 | ||
5735 | dest1 = gen_highpart (SFmode, set_dest); | |
5736 | dest2 = gen_lowpart (SFmode, set_dest); | |
5737 | src1 = gen_highpart (SFmode, set_src); | |
5738 | src2 = gen_lowpart (SFmode, set_src); | |
5739 | ||
5740 | /* Now emit using the real source and destination we found, swapping | |
5741 | the order if we detect overlap. */ | |
5742 | if (reg_overlap_mentioned_p (dest1, src2)) | |
5743 | { | |
5744 | emit_insn (gen_movsf (dest2, src2)); | |
5745 | emit_insn (gen_abssf2 (dest1, src1)); | |
5746 | } | |
5747 | else | |
5748 | { | |
5749 | emit_insn (gen_abssf2 (dest1, src1)); | |
5750 | if (REGNO (dest2) != REGNO (src2)) | |
5751 | emit_insn (gen_movsf (dest2, src2)); | |
5752 | } | |
5753 | DONE; | |
5754 | } | |
5755 | [(set_attr "length" "2")]) | |
1772450b | 5756 | |
5757 | (define_insn "*absdf2_v9" | |
5758 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5759 | (abs:DF (match_operand:DF 1 "register_operand" "e")))] | |
5760 | "TARGET_FPU && TARGET_V9" | |
a4ddaca5 | 5761 | "fabsd\t%1, %0" |
f618d313 | 5762 | [(set_attr "type" "fpmove") |
a9208abf | 5763 | (set_attr "fptype" "double")]) |
a44201ea | 5764 | |
5765 | (define_insn "abssf2" | |
5766 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5767 | (abs:SF (match_operand:SF 1 "register_operand" "f")))] | |
f2ed3c03 | 5768 | "TARGET_FPU" |
a4ddaca5 | 5769 | "fabss\t%1, %0" |
a9208abf | 5770 | [(set_attr "type" "fpmove")]) |
a44201ea | 5771 | |
75997b31 | 5772 | (define_expand "sqrttf2" |
c00088b6 | 5773 | [(set (match_operand:TF 0 "nonimmediate_operand" "") |
5774 | (sqrt:TF (match_operand:TF 1 "general_operand" "")))] | |
75997b31 | 5775 | "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)" |
c00088b6 | 5776 | "emit_tfmode_unop (SQRT, operands); DONE;") |
75997b31 | 5777 | |
5778 | (define_insn "*sqrttf2_hq" | |
65ccdc13 | 5779 | [(set (match_operand:TF 0 "register_operand" "=e") |
5780 | (sqrt:TF (match_operand:TF 1 "register_operand" "e")))] | |
b0454100 | 5781 | "TARGET_FPU && TARGET_HARD_QUAD" |
a4ddaca5 | 5782 | "fsqrtq\t%1, %0" |
c495d615 | 5783 | [(set_attr "type" "fpsqrts")]) |
93fed860 | 5784 | |
d6a0a4b0 | 5785 | (define_expand "sqrtdf2" |
65ccdc13 | 5786 | [(set (match_operand:DF 0 "register_operand" "=e") |
5787 | (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] | |
f2ed3c03 | 5788 | "TARGET_FPU" |
d6a0a4b0 | 5789 | "") |
5790 | ||
5791 | (define_insn "*sqrtdf2_nofix" | |
5792 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5793 | (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] | |
5794 | "TARGET_FPU && !sparc_fix_ut699" | |
a4ddaca5 | 5795 | "fsqrtd\t%1, %0" |
192847bd | 5796 | [(set_attr "type" "fpsqrtd") |
a9208abf | 5797 | (set_attr "fptype" "double")]) |
a44201ea | 5798 | |
d6a0a4b0 | 5799 | (define_insn "*sqrtdf2_fix" |
5800 | [(set (match_operand:DF 0 "register_operand" "=e") | |
5801 | (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] | |
5802 | "TARGET_FPU && sparc_fix_ut699" | |
5803 | "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]" | |
5804 | [(set_attr "type" "fpsqrtd") | |
5805 | (set_attr "fptype" "double") | |
5806 | (set_attr "length" "2")]) | |
5807 | ||
a44201ea | 5808 | (define_insn "sqrtsf2" |
5809 | [(set (match_operand:SF 0 "register_operand" "=f") | |
5810 | (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] | |
d6a0a4b0 | 5811 | "TARGET_FPU && !sparc_fix_ut699" |
a4ddaca5 | 5812 | "fsqrts\t%1, %0" |
a9208abf | 5813 | [(set_attr "type" "fpsqrts")]) |
d88ab5ca | 5814 | |
5815 | ||
5816 | ;; Arithmetic shift instructions. | |
a44201ea | 5817 | |
a44201ea | 5818 | (define_insn "ashlsi3" |
5819 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5820 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
b2ffdb63 | 5821 | (match_operand:SI 2 "arith_operand" "rI")))] |
a44201ea | 5822 | "" |
22eddec2 | 5823 | { |
5824 | if (GET_CODE (operands[2]) == CONST_INT) | |
5825 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
5826 | return "sll\t%1, %2, %0"; | |
5827 | } | |
5828 | [(set_attr "type" "shift")]) | |
cfbc5540 | 5829 | |
367242d3 | 5830 | (define_expand "ashldi3" |
5831 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5832 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
5833 | (match_operand:SI 2 "arith_operand" "rI")))] | |
5834 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
367242d3 | 5835 | { |
5836 | if (! TARGET_ARCH64) | |
5837 | { | |
5838 | if (GET_CODE (operands[2]) == CONST_INT) | |
5839 | FAIL; | |
5840 | emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2])); | |
5841 | DONE; | |
5842 | } | |
0037630d | 5843 | }) |
367242d3 | 5844 | |
cfbc5540 | 5845 | (define_insn "*ashldi3_sp64" |
001e2308 | 5846 | [(set (match_operand:DI 0 "register_operand" "=r") |
5847 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
5848 | (match_operand:SI 2 "arith_operand" "rI")))] | |
df5e9319 | 5849 | "TARGET_ARCH64" |
001e2308 | 5850 | { |
49b2e0fc | 5851 | if (GET_CODE (operands[2]) == CONST_INT) |
5852 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
a4ddaca5 | 5853 | return "sllx\t%1, %2, %0"; |
0037630d | 5854 | } |
22eddec2 | 5855 | [(set_attr "type" "shift")]) |
001e2308 | 5856 | |
998032ba | 5857 | ;; XXX UGH! |
367242d3 | 5858 | (define_insn "ashldi3_v8plus" |
5859 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
58dc6b1f | 5860 | (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
367242d3 | 5861 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
5862 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
5863 | "TARGET_V8PLUS" | |
091f282f | 5864 | "* return output_v8plus_shift (insn ,operands, \"sllx\");" |
a9208abf | 5865 | [(set_attr "type" "multi") |
5866 | (set_attr "length" "5,5,6")]) | |
367242d3 | 5867 | |
58dc6b1f | 5868 | ;; Optimize (1LL<<x)-1 |
9ef15f91 | 5869 | ;; XXX this also needs to be fixed to handle equal subregs |
5870 | ;; XXX first before we could re-enable it. | |
dd193d7c | 5871 | ;(define_insn "" |
5872 | ; [(set (match_operand:DI 0 "register_operand" "=h") | |
5873 | ; (plus:DI (ashift:DI (const_int 1) | |
5874 | ; (match_operand:SI 1 "arith_operand" "rI")) | |
5875 | ; (const_int -1)))] | |
5876 | ; "0 && TARGET_V8PLUS" | |
dd193d7c | 5877 | ;{ |
5878 | ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0])) | |
a4ddaca5 | 5879 | ; return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0"; |
5880 | ; return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0"; | |
0037630d | 5881 | ;} |
a9208abf | 5882 | ; [(set_attr "type" "multi") |
5883 | ; (set_attr "length" "4")]) | |
58dc6b1f | 5884 | |
4117925c | 5885 | (define_insn "*cmp_cc_ashift_1" |
2b25173f | 5886 | [(set (reg:CC_NOOV CC_REG) |
6284ae16 | 5887 | (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r") |
5888 | (const_int 1)) | |
5889 | (const_int 0)))] | |
f8be3dfc | 5890 | "" |
a4ddaca5 | 5891 | "addcc\t%0, %0, %%g0" |
a9208abf | 5892 | [(set_attr "type" "compare")]) |
6284ae16 | 5893 | |
4117925c | 5894 | (define_insn "*cmp_cc_set_ashift_1" |
2b25173f | 5895 | [(set (reg:CC_NOOV CC_REG) |
6284ae16 | 5896 | (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r") |
5897 | (const_int 1)) | |
5898 | (const_int 0))) | |
5899 | (set (match_operand:SI 0 "register_operand" "=r") | |
5900 | (ashift:SI (match_dup 1) (const_int 1)))] | |
5901 | "" | |
a4ddaca5 | 5902 | "addcc\t%1, %1, %0" |
a9208abf | 5903 | [(set_attr "type" "compare")]) |
6284ae16 | 5904 | |
a44201ea | 5905 | (define_insn "ashrsi3" |
5906 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5907 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
b2ffdb63 | 5908 | (match_operand:SI 2 "arith_operand" "rI")))] |
a44201ea | 5909 | "" |
49b2e0fc | 5910 | { |
5911 | if (GET_CODE (operands[2]) == CONST_INT) | |
5912 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
5913 | return "sra\t%1, %2, %0"; | |
5914 | } | |
a9208abf | 5915 | [(set_attr "type" "shift")]) |
a44201ea | 5916 | |
cfbc5540 | 5917 | (define_insn "*ashrsi3_extend" |
6fcf3e75 | 5918 | [(set (match_operand:DI 0 "register_operand" "=r") |
cfbc5540 | 5919 | (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") |
5920 | (match_operand:SI 2 "arith_operand" "r"))))] | |
5921 | "TARGET_ARCH64" | |
a4ddaca5 | 5922 | "sra\t%1, %2, %0" |
a9208abf | 5923 | [(set_attr "type" "shift")]) |
cfbc5540 | 5924 | |
5925 | ;; This handles the case as above, but with constant shift instead of | |
5926 | ;; register. Combiner "simplifies" it for us a little bit though. | |
5927 | (define_insn "*ashrsi3_extend2" | |
6fcf3e75 | 5928 | [(set (match_operand:DI 0 "register_operand" "=r") |
cfbc5540 | 5929 | (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) |
5930 | (const_int 32)) | |
27b36d57 | 5931 | (match_operand:SI 2 "small_int_operand" "I")))] |
5932 | "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64" | |
cfbc5540 | 5933 | { |
5934 | operands[2] = GEN_INT (INTVAL (operands[2]) - 32); | |
a4ddaca5 | 5935 | return "sra\t%1, %2, %0"; |
0037630d | 5936 | } |
a9208abf | 5937 | [(set_attr "type" "shift")]) |
cfbc5540 | 5938 | |
367242d3 | 5939 | (define_expand "ashrdi3" |
5940 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5941 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
5942 | (match_operand:SI 2 "arith_operand" "rI")))] | |
5943 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
998032ba | 5944 | { |
5945 | if (! TARGET_ARCH64) | |
5946 | { | |
5947 | if (GET_CODE (operands[2]) == CONST_INT) | |
5948 | FAIL; /* prefer generic code in this case */ | |
5949 | emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2])); | |
5950 | DONE; | |
5951 | } | |
0037630d | 5952 | }) |
367242d3 | 5953 | |
49b2e0fc | 5954 | (define_insn "*ashrdi3_sp64" |
001e2308 | 5955 | [(set (match_operand:DI 0 "register_operand" "=r") |
5956 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
5957 | (match_operand:SI 2 "arith_operand" "rI")))] | |
df5e9319 | 5958 | "TARGET_ARCH64" |
49b2e0fc | 5959 | |
5960 | { | |
5961 | if (GET_CODE (operands[2]) == CONST_INT) | |
5962 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
5963 | return "srax\t%1, %2, %0"; | |
5964 | } | |
a9208abf | 5965 | [(set_attr "type" "shift")]) |
001e2308 | 5966 | |
998032ba | 5967 | ;; XXX |
367242d3 | 5968 | (define_insn "ashrdi3_v8plus" |
5969 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
58dc6b1f | 5970 | (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
367242d3 | 5971 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
5972 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
5973 | "TARGET_V8PLUS" | |
091f282f | 5974 | "* return output_v8plus_shift (insn, operands, \"srax\");" |
a9208abf | 5975 | [(set_attr "type" "multi") |
5976 | (set_attr "length" "5,5,6")]) | |
367242d3 | 5977 | |
a44201ea | 5978 | (define_insn "lshrsi3" |
5979 | [(set (match_operand:SI 0 "register_operand" "=r") | |
5980 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
b2ffdb63 | 5981 | (match_operand:SI 2 "arith_operand" "rI")))] |
a44201ea | 5982 | "" |
49b2e0fc | 5983 | { |
5984 | if (GET_CODE (operands[2]) == CONST_INT) | |
5985 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
5986 | return "srl\t%1, %2, %0"; | |
5987 | } | |
a9208abf | 5988 | [(set_attr "type" "shift")]) |
001e2308 | 5989 | |
22eddec2 | 5990 | (define_insn "*lshrsi3_extend0" |
5991 | [(set (match_operand:DI 0 "register_operand" "=r") | |
5992 | (zero_extend:DI | |
5993 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
5994 | (match_operand:SI 2 "arith_operand" "rI"))))] | |
5995 | "TARGET_ARCH64" | |
5996 | { | |
5997 | if (GET_CODE (operands[2]) == CONST_INT) | |
5998 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); | |
5999 | return "srl\t%1, %2, %0"; | |
6000 | } | |
6001 | [(set_attr "type" "shift")]) | |
6002 | ||
cfbc5540 | 6003 | ;; This handles the case where |
6004 | ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))), | |
6005 | ;; but combiner "simplifies" it for us. | |
22eddec2 | 6006 | (define_insn "*lshrsi3_extend1" |
6fcf3e75 | 6007 | [(set (match_operand:DI 0 "register_operand" "=r") |
cfbc5540 | 6008 | (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") |
6009 | (match_operand:SI 2 "arith_operand" "r")) 0) | |
3bb6b41e | 6010 | (match_operand 3 "const_int_operand" "")))] |
6011 | "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff" | |
a4ddaca5 | 6012 | "srl\t%1, %2, %0" |
a9208abf | 6013 | [(set_attr "type" "shift")]) |
cfbc5540 | 6014 | |
6015 | ;; This handles the case where | |
6016 | ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32)) | |
6017 | ;; but combiner "simplifies" it for us. | |
6018 | (define_insn "*lshrsi3_extend2" | |
6fcf3e75 | 6019 | [(set (match_operand:DI 0 "register_operand" "=r") |
cfbc5540 | 6020 | (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) |
27b36d57 | 6021 | (match_operand 2 "small_int_operand" "I") |
cfbc5540 | 6022 | (const_int 32)))] |
27b36d57 | 6023 | "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32" |
cfbc5540 | 6024 | { |
6025 | operands[2] = GEN_INT (32 - INTVAL (operands[2])); | |
a4ddaca5 | 6026 | return "srl\t%1, %2, %0"; |
0037630d | 6027 | } |
a9208abf | 6028 | [(set_attr "type" "shift")]) |
cfbc5540 | 6029 | |
367242d3 | 6030 | (define_expand "lshrdi3" |
6031 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6032 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
6033 | (match_operand:SI 2 "arith_operand" "rI")))] | |
6034 | "TARGET_ARCH64 || TARGET_V8PLUS" | |
998032ba | 6035 | { |
6036 | if (! TARGET_ARCH64) | |
6037 | { | |
6038 | if (GET_CODE (operands[2]) == CONST_INT) | |
6039 | FAIL; | |
6040 | emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2])); | |
6041 | DONE; | |
6042 | } | |
0037630d | 6043 | }) |
367242d3 | 6044 | |
49b2e0fc | 6045 | (define_insn "*lshrdi3_sp64" |
001e2308 | 6046 | [(set (match_operand:DI 0 "register_operand" "=r") |
6047 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
6048 | (match_operand:SI 2 "arith_operand" "rI")))] | |
df5e9319 | 6049 | "TARGET_ARCH64" |
49b2e0fc | 6050 | { |
6051 | if (GET_CODE (operands[2]) == CONST_INT) | |
6052 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); | |
6053 | return "srlx\t%1, %2, %0"; | |
6054 | } | |
a9208abf | 6055 | [(set_attr "type" "shift")]) |
367242d3 | 6056 | |
998032ba | 6057 | ;; XXX |
367242d3 | 6058 | (define_insn "lshrdi3_v8plus" |
6059 | [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") | |
58dc6b1f | 6060 | (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") |
367242d3 | 6061 | (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) |
6062 | (clobber (match_scratch:SI 3 "=X,X,&h"))] | |
6063 | "TARGET_V8PLUS" | |
091f282f | 6064 | "* return output_v8plus_shift (insn, operands, \"srlx\");" |
a9208abf | 6065 | [(set_attr "type" "multi") |
6066 | (set_attr "length" "5,5,6")]) | |
99227eff | 6067 | |
6068 | (define_insn "" | |
6069 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6070 | (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
701e46d0 | 6071 | (const_int 32)) 4) |
27b36d57 | 6072 | (match_operand:SI 2 "small_int_operand" "I")))] |
6073 | "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32" | |
99227eff | 6074 | { |
6075 | operands[2] = GEN_INT (INTVAL (operands[2]) + 32); | |
a4ddaca5 | 6076 | return "srax\t%1, %2, %0"; |
0037630d | 6077 | } |
a9208abf | 6078 | [(set_attr "type" "shift")]) |
99227eff | 6079 | |
6080 | (define_insn "" | |
6081 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6082 | (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
701e46d0 | 6083 | (const_int 32)) 4) |
27b36d57 | 6084 | (match_operand:SI 2 "small_int_operand" "I")))] |
6085 | "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32" | |
99227eff | 6086 | { |
6087 | operands[2] = GEN_INT (INTVAL (operands[2]) + 32); | |
a4ddaca5 | 6088 | return "srlx\t%1, %2, %0"; |
0037630d | 6089 | } |
a9208abf | 6090 | [(set_attr "type" "shift")]) |
99227eff | 6091 | |
6092 | (define_insn "" | |
6093 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6094 | (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
27b36d57 | 6095 | (match_operand:SI 2 "small_int_operand" "I")) 4) |
6096 | (match_operand:SI 3 "small_int_operand" "I")))] | |
99227eff | 6097 | "TARGET_ARCH64 |
99227eff | 6098 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32 |
6099 | && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32 | |
6100 | && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64" | |
99227eff | 6101 | { |
6102 | operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])); | |
6103 | ||
a4ddaca5 | 6104 | return "srax\t%1, %2, %0"; |
0037630d | 6105 | } |
a9208abf | 6106 | [(set_attr "type" "shift")]) |
99227eff | 6107 | |
6108 | (define_insn "" | |
6109 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6110 | (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
27b36d57 | 6111 | (match_operand:SI 2 "small_int_operand" "I")) 4) |
6112 | (match_operand:SI 3 "small_int_operand" "I")))] | |
99227eff | 6113 | "TARGET_ARCH64 |
99227eff | 6114 | && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32 |
6115 | && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32 | |
6116 | && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64" | |
99227eff | 6117 | { |
6118 | operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])); | |
6119 | ||
a4ddaca5 | 6120 | return "srlx\t%1, %2, %0"; |
0037630d | 6121 | } |
a9208abf | 6122 | [(set_attr "type" "shift")]) |
d88ab5ca | 6123 | |
6124 | ||
6125 | ;; Unconditional and other jump instructions. | |
6126 | ||
6c940e8d | 6127 | (define_expand "jump" |
a44201ea | 6128 | [(set (pc) (label_ref (match_operand 0 "" "")))] |
6c940e8d | 6129 | "") |
6130 | ||
6131 | (define_insn "*jump_ubranch" | |
6132 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
6133 | "! TARGET_CBCOND" | |
6134 | "* return output_ubranch (operands[0], insn);" | |
74848118 | 6135 | [(set_attr "type" "uncond_branch")]) |
a44201ea | 6136 | |
6c940e8d | 6137 | (define_insn "*jump_cbcond" |
6138 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
6139 | "TARGET_CBCOND" | |
6140 | "* return output_ubranch (operands[0], insn);" | |
6141 | [(set_attr "type" "uncond_cbcond")]) | |
6142 | ||
a44201ea | 6143 | (define_expand "tablejump" |
001e2308 | 6144 | [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) |
a44201ea | 6145 | (use (label_ref (match_operand 1 "" "")))])] |
b0344bad | 6146 | "" |
a44201ea | 6147 | { |
b86b0e16 | 6148 | gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE); |
001e2308 | 6149 | |
998032ba | 6150 | /* In pic mode, our address differences are against the base of the |
6151 | table. Add that base value back in; CSE ought to be able to combine | |
6152 | the two address loads. */ | |
a44201ea | 6153 | if (flag_pic) |
6154 | { | |
99037f28 | 6155 | rtx tmp, tmp2; |
998032ba | 6156 | tmp = gen_rtx_LABEL_REF (Pmode, operands[1]); |
99037f28 | 6157 | tmp2 = operands[0]; |
6158 | if (CASE_VECTOR_MODE != Pmode) | |
6159 | tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2); | |
6160 | tmp = gen_rtx_PLUS (Pmode, tmp2, tmp); | |
998032ba | 6161 | operands[0] = memory_address (Pmode, tmp); |
a44201ea | 6162 | } |
0037630d | 6163 | }) |
a44201ea | 6164 | |
4117925c | 6165 | (define_insn "*tablejump_sp32" |
a44201ea | 6166 | [(set (pc) (match_operand:SI 0 "address_operand" "p")) |
6167 | (use (label_ref (match_operand 1 "" "")))] | |
f3811c30 | 6168 | "! TARGET_ARCH64" |
a4ddaca5 | 6169 | "jmp\t%a0%#" |
001e2308 | 6170 | [(set_attr "type" "uncond_branch")]) |
6171 | ||
4117925c | 6172 | (define_insn "*tablejump_sp64" |
001e2308 | 6173 | [(set (pc) (match_operand:DI 0 "address_operand" "p")) |
6174 | (use (label_ref (match_operand 1 "" "")))] | |
f3811c30 | 6175 | "TARGET_ARCH64" |
a4ddaca5 | 6176 | "jmp\t%a0%#" |
74848118 | 6177 | [(set_attr "type" "uncond_branch")]) |
a44201ea | 6178 | |
d88ab5ca | 6179 | |
6180 | ;; Jump to subroutine instructions. | |
6181 | ||
a44201ea | 6182 | (define_expand "call" |
6183 | ;; Note that this expression is not used for generating RTL. | |
6184 | ;; All the RTL is generated explicitly below. | |
001e2308 | 6185 | [(call (match_operand 0 "call_operand" "") |
a44201ea | 6186 | (match_operand 3 "" "i"))] |
6187 | ;; operands[2] is next_arg_register | |
6188 | ;; operands[3] is struct_value_size_rtx. | |
6189 | "" | |
a44201ea | 6190 | { |
765940d4 | 6191 | rtx fn_rtx; |
a44201ea | 6192 | |
723e1902 | 6193 | gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE); |
001e2308 | 6194 | |
b86b0e16 | 6195 | gcc_assert (GET_CODE (operands[3]) == CONST_INT); |
954084b8 | 6196 | |
0a7c56dd | 6197 | if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF) |
a44201ea | 6198 | { |
6199 | /* This is really a PIC sequence. We want to represent | |
9e042f31 | 6200 | it as a funny jump so its delay slots can be filled. |
a44201ea | 6201 | |
6202 | ??? But if this really *is* a CALL, will not it clobber the | |
6203 | call-clobbered registers? We lose this if it is a JUMP_INSN. | |
6204 | Why cannot we have delay slots filled if it were a CALL? */ | |
6205 | ||
954084b8 | 6206 | /* We accept negative sizes for untyped calls. */ |
df5e9319 | 6207 | if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) |
0a7c56dd | 6208 | emit_jump_insn |
7014838c | 6209 | (gen_rtx_PARALLEL |
6210 | (VOIDmode, | |
6211 | gen_rtvec (3, | |
6212 | gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)), | |
403c05ec | 6213 | operands[3], |
7014838c | 6214 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); |
a44201ea | 6215 | else |
0a7c56dd | 6216 | emit_jump_insn |
7014838c | 6217 | (gen_rtx_PARALLEL |
6218 | (VOIDmode, | |
6219 | gen_rtvec (2, | |
6220 | gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)), | |
6221 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); | |
a44201ea | 6222 | goto finish_call; |
6223 | } | |
6224 | ||
6225 | fn_rtx = operands[0]; | |
6226 | ||
954084b8 | 6227 | /* We accept negative sizes for untyped calls. */ |
df5e9319 | 6228 | if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0) |
723e1902 | 6229 | sparc_emit_call_insn |
7014838c | 6230 | (gen_rtx_PARALLEL |
6231 | (VOIDmode, | |
765940d4 | 6232 | gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx), |
403c05ec | 6233 | operands[3], |
723e1902 | 6234 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))), |
6235 | XEXP (fn_rtx, 0)); | |
a44201ea | 6236 | else |
723e1902 | 6237 | sparc_emit_call_insn |
7014838c | 6238 | (gen_rtx_PARALLEL |
6239 | (VOIDmode, | |
765940d4 | 6240 | gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx), |
723e1902 | 6241 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))), |
6242 | XEXP (fn_rtx, 0)); | |
a44201ea | 6243 | |
6244 | finish_call: | |
a44201ea | 6245 | |
6246 | DONE; | |
0037630d | 6247 | }) |
a44201ea | 6248 | |
a6620ee7 | 6249 | ;; We can't use the same pattern for these two insns, because then registers |
6250 | ;; in the address may not be properly reloaded. | |
6251 | ||
4117925c | 6252 | (define_insn "*call_address_sp32" |
a6620ee7 | 6253 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
6254 | (match_operand 1 "" "")) | |
2b25173f | 6255 | (clobber (reg:SI O7_REG))] |
a6620ee7 | 6256 | ;;- Do not use operand 1 for most machines. |
f3811c30 | 6257 | "! TARGET_ARCH64" |
a4ddaca5 | 6258 | "call\t%a0, %1%#" |
a6620ee7 | 6259 | [(set_attr "type" "call")]) |
6260 | ||
4117925c | 6261 | (define_insn "*call_symbolic_sp32" |
1c39e847 | 6262 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
a44201ea | 6263 | (match_operand 1 "" "")) |
2b25173f | 6264 | (clobber (reg:SI O7_REG))] |
a44201ea | 6265 | ;;- Do not use operand 1 for most machines. |
f3811c30 | 6266 | "! TARGET_ARCH64" |
a4ddaca5 | 6267 | "call\t%a0, %1%#" |
001e2308 | 6268 | [(set_attr "type" "call")]) |
6269 | ||
4117925c | 6270 | (define_insn "*call_address_sp64" |
bb0456e6 | 6271 | [(call (mem:DI (match_operand:DI 0 "address_operand" "p")) |
001e2308 | 6272 | (match_operand 1 "" "")) |
2b25173f | 6273 | (clobber (reg:DI O7_REG))] |
001e2308 | 6274 | ;;- Do not use operand 1 for most machines. |
f3811c30 | 6275 | "TARGET_ARCH64" |
a4ddaca5 | 6276 | "call\t%a0, %1%#" |
001e2308 | 6277 | [(set_attr "type" "call")]) |
6278 | ||
4117925c | 6279 | (define_insn "*call_symbolic_sp64" |
bb0456e6 | 6280 | [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s")) |
001e2308 | 6281 | (match_operand 1 "" "")) |
2b25173f | 6282 | (clobber (reg:DI O7_REG))] |
001e2308 | 6283 | ;;- Do not use operand 1 for most machines. |
f3811c30 | 6284 | "TARGET_ARCH64" |
a4ddaca5 | 6285 | "call\t%a0, %1%#" |
a44201ea | 6286 | [(set_attr "type" "call")]) |
6287 | ||
6288 | ;; This is a call that wants a structure value. | |
001e2308 | 6289 | ;; There is no such critter for v9 (??? we may need one anyway). |
4117925c | 6290 | (define_insn "*call_address_struct_value_sp32" |
a6620ee7 | 6291 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
6292 | (match_operand 1 "" "")) | |
6293 | (match_operand 2 "immediate_operand" "") | |
2b25173f | 6294 | (clobber (reg:SI O7_REG))] |
a6620ee7 | 6295 | ;;- Do not use operand 1 for most machines. |
954084b8 | 6296 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" |
2b8849d7 | 6297 | { |
6298 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff); | |
6299 | return "call\t%a0, %1\n\t nop\n\tunimp\t%2"; | |
6300 | } | |
e34757ad | 6301 | [(set_attr "type" "call_no_delay_slot") |
258103e3 | 6302 | (set_attr "length" "3")]) |
a6620ee7 | 6303 | |
6304 | ;; This is a call that wants a structure value. | |
001e2308 | 6305 | ;; There is no such critter for v9 (??? we may need one anyway). |
4117925c | 6306 | (define_insn "*call_symbolic_struct_value_sp32" |
1c39e847 | 6307 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
a44201ea | 6308 | (match_operand 1 "" "")) |
6309 | (match_operand 2 "immediate_operand" "") | |
2b25173f | 6310 | (clobber (reg:SI O7_REG))] |
a44201ea | 6311 | ;;- Do not use operand 1 for most machines. |
954084b8 | 6312 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" |
2b8849d7 | 6313 | { |
6314 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff); | |
6315 | return "call\t%a0, %1\n\t nop\n\tunimp\t%2"; | |
6316 | } | |
e34757ad | 6317 | [(set_attr "type" "call_no_delay_slot") |
258103e3 | 6318 | (set_attr "length" "3")]) |
a44201ea | 6319 | |
84682793 | 6320 | ;; This is a call that may want a structure value. This is used for |
6321 | ;; untyped_calls. | |
4117925c | 6322 | (define_insn "*call_address_untyped_struct_value_sp32" |
84682793 | 6323 | [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) |
6324 | (match_operand 1 "" "")) | |
6325 | (match_operand 2 "immediate_operand" "") | |
2b25173f | 6326 | (clobber (reg:SI O7_REG))] |
84682793 | 6327 | ;;- Do not use operand 1 for most machines. |
df5e9319 | 6328 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" |
19aea418 | 6329 | "call\t%a0, %1\n\t nop\n\tnop" |
e34757ad | 6330 | [(set_attr "type" "call_no_delay_slot") |
258103e3 | 6331 | (set_attr "length" "3")]) |
84682793 | 6332 | |
954084b8 | 6333 | ;; This is a call that may want a structure value. This is used for |
6334 | ;; untyped_calls. | |
4117925c | 6335 | (define_insn "*call_symbolic_untyped_struct_value_sp32" |
84682793 | 6336 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) |
6337 | (match_operand 1 "" "")) | |
6338 | (match_operand 2 "immediate_operand" "") | |
2b25173f | 6339 | (clobber (reg:SI O7_REG))] |
84682793 | 6340 | ;;- Do not use operand 1 for most machines. |
df5e9319 | 6341 | "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" |
19aea418 | 6342 | "call\t%a0, %1\n\t nop\n\tnop" |
e34757ad | 6343 | [(set_attr "type" "call_no_delay_slot") |
258103e3 | 6344 | (set_attr "length" "3")]) |
84682793 | 6345 | |
a44201ea | 6346 | (define_expand "call_value" |
001e2308 | 6347 | ;; Note that this expression is not used for generating RTL. |
6348 | ;; All the RTL is generated explicitly below. | |
a44201ea | 6349 | [(set (match_operand 0 "register_operand" "=rf") |
bb0456e6 | 6350 | (call (match_operand 1 "" "") |
a44201ea | 6351 | (match_operand 4 "" "")))] |
001e2308 | 6352 | ;; operand 2 is stack_size_rtx |
a44201ea | 6353 | ;; operand 3 is next_arg_register |
6354 | "" | |
a44201ea | 6355 | { |
765940d4 | 6356 | rtx fn_rtx; |
a44201ea | 6357 | rtvec vec; |
6358 | ||
723e1902 | 6359 | gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE); |
001e2308 | 6360 | |
a44201ea | 6361 | fn_rtx = operands[1]; |
6362 | ||
a44201ea | 6363 | vec = gen_rtvec (2, |
2e533a5d | 6364 | gen_rtx_SET (VOIDmode, operands[0], |
765940d4 | 6365 | gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)), |
5a5d82d2 | 6366 | gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))); |
a44201ea | 6367 | |
723e1902 | 6368 | sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0)); |
a44201ea | 6369 | |
6370 | DONE; | |
0037630d | 6371 | }) |
a44201ea | 6372 | |
4117925c | 6373 | (define_insn "*call_value_address_sp32" |
a44201ea | 6374 | [(set (match_operand 0 "" "=rf") |
a6620ee7 | 6375 | (call (mem:SI (match_operand:SI 1 "address_operand" "p")) |
6376 | (match_operand 2 "" ""))) | |
2b25173f | 6377 | (clobber (reg:SI O7_REG))] |
a6620ee7 | 6378 | ;;- Do not use operand 2 for most machines. |
f3811c30 | 6379 | "! TARGET_ARCH64" |
a4ddaca5 | 6380 | "call\t%a1, %2%#" |
a6620ee7 | 6381 | [(set_attr "type" "call")]) |
6382 | ||
4117925c | 6383 | (define_insn "*call_value_symbolic_sp32" |
a6620ee7 | 6384 | [(set (match_operand 0 "" "=rf") |
1c39e847 | 6385 | (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s")) |
a44201ea | 6386 | (match_operand 2 "" ""))) |
2b25173f | 6387 | (clobber (reg:SI O7_REG))] |
a44201ea | 6388 | ;;- Do not use operand 2 for most machines. |
f3811c30 | 6389 | "! TARGET_ARCH64" |
a4ddaca5 | 6390 | "call\t%a1, %2%#" |
001e2308 | 6391 | [(set_attr "type" "call")]) |
6392 | ||
4117925c | 6393 | (define_insn "*call_value_address_sp64" |
8e1581a1 | 6394 | [(set (match_operand 0 "" "") |
bb0456e6 | 6395 | (call (mem:DI (match_operand:DI 1 "address_operand" "p")) |
001e2308 | 6396 | (match_operand 2 "" ""))) |
2b25173f | 6397 | (clobber (reg:DI O7_REG))] |
001e2308 | 6398 | ;;- Do not use operand 2 for most machines. |
f3811c30 | 6399 | "TARGET_ARCH64" |
a4ddaca5 | 6400 | "call\t%a1, %2%#" |
001e2308 | 6401 | [(set_attr "type" "call")]) |
6402 | ||
4117925c | 6403 | (define_insn "*call_value_symbolic_sp64" |
8e1581a1 | 6404 | [(set (match_operand 0 "" "") |
bb0456e6 | 6405 | (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s")) |
001e2308 | 6406 | (match_operand 2 "" ""))) |
2b25173f | 6407 | (clobber (reg:DI O7_REG))] |
001e2308 | 6408 | ;;- Do not use operand 2 for most machines. |
f3811c30 | 6409 | "TARGET_ARCH64" |
a4ddaca5 | 6410 | "call\t%a1, %2%#" |
a44201ea | 6411 | [(set_attr "type" "call")]) |
d2cd7749 | 6412 | |
6413 | (define_expand "untyped_call" | |
84682793 | 6414 | [(parallel [(call (match_operand 0 "" "") |
d2cd7749 | 6415 | (const_int 0)) |
5d0a85a2 | 6416 | (match_operand:BLK 1 "memory_operand" "") |
84682793 | 6417 | (match_operand 2 "" "")])] |
d2cd7749 | 6418 | "" |
d2cd7749 | 6419 | { |
5d0a85a2 | 6420 | rtx valreg1 = gen_rtx_REG (DImode, 8); |
6421 | rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); | |
6422 | rtx result = operands[1]; | |
d2cd7749 | 6423 | |
84682793 | 6424 | /* Pass constm1 to indicate that it may expect a structure value, but |
6425 | we don't know what size it is. */ | |
2c6f8e4d | 6426 | emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx)); |
a6620ee7 | 6427 | |
5d0a85a2 | 6428 | /* Save the function value registers. */ |
6429 | emit_move_insn (adjust_address (result, DImode, 0), valreg1); | |
6430 | emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8), | |
6431 | valreg2); | |
a6620ee7 | 6432 | |
84682793 | 6433 | /* The optimizer does not know that the call sets the function value |
6434 | registers we stored in the result block. We avoid problems by | |
6435 | claiming that all hard registers are used and clobbered at this | |
6436 | point. */ | |
6437 | emit_insn (gen_blockage ()); | |
d2cd7749 | 6438 | |
84682793 | 6439 | DONE; |
0037630d | 6440 | }) |
001e2308 | 6441 | |
d88ab5ca | 6442 | ;; Tail call instructions. |
6443 | ||
7a8d641b | 6444 | (define_expand "sibcall" |
6445 | [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0)) | |
6446 | (return)])] | |
6447 | "" | |
6448 | "") | |
6449 | ||
6450 | (define_insn "*sibcall_symbolic_sp32" | |
6451 | [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) | |
6452 | (match_operand 1 "" "")) | |
6453 | (return)] | |
f3811c30 | 6454 | "! TARGET_ARCH64" |
7a8d641b | 6455 | "* return output_sibcall(insn, operands[0]);" |
6456 | [(set_attr "type" "sibcall")]) | |
6457 | ||
6458 | (define_insn "*sibcall_symbolic_sp64" | |
bb0456e6 | 6459 | [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s")) |
7a8d641b | 6460 | (match_operand 1 "" "")) |
6461 | (return)] | |
f3811c30 | 6462 | "TARGET_ARCH64" |
7a8d641b | 6463 | "* return output_sibcall(insn, operands[0]);" |
6464 | [(set_attr "type" "sibcall")]) | |
6465 | ||
6466 | (define_expand "sibcall_value" | |
6467 | [(parallel [(set (match_operand 0 "register_operand" "=rf") | |
bb0456e6 | 6468 | (call (match_operand 1 "" "") (const_int 0))) |
7a8d641b | 6469 | (return)])] |
6470 | "" | |
6471 | "") | |
6472 | ||
6473 | (define_insn "*sibcall_value_symbolic_sp32" | |
6474 | [(set (match_operand 0 "" "=rf") | |
6475 | (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s")) | |
6476 | (match_operand 2 "" ""))) | |
6477 | (return)] | |
f3811c30 | 6478 | "! TARGET_ARCH64" |
7a8d641b | 6479 | "* return output_sibcall(insn, operands[1]);" |
6480 | [(set_attr "type" "sibcall")]) | |
6481 | ||
6482 | (define_insn "*sibcall_value_symbolic_sp64" | |
6483 | [(set (match_operand 0 "" "") | |
bb0456e6 | 6484 | (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s")) |
7a8d641b | 6485 | (match_operand 2 "" ""))) |
6486 | (return)] | |
f3811c30 | 6487 | "TARGET_ARCH64" |
7a8d641b | 6488 | "* return output_sibcall(insn, operands[1]);" |
6489 | [(set_attr "type" "sibcall")]) | |
6490 | ||
d88ab5ca | 6491 | |
6492 | ;; Special instructions. | |
f317b732 | 6493 | |
6494 | (define_expand "prologue" | |
7a8d641b | 6495 | [(const_int 0)] |
6496 | "" | |
f317b732 | 6497 | { |
47529489 | 6498 | if (TARGET_FLAT) |
6499 | sparc_flat_expand_prologue (); | |
6500 | else | |
6501 | sparc_expand_prologue (); | |
f317b732 | 6502 | DONE; |
6503 | }) | |
6504 | ||
b3965770 | 6505 | ;; The "register window save" insn is modelled as follows. The dwarf2 |
6506 | ;; information is manually added in emit_window_save. | |
e0a0aad2 | 6507 | |
b3965770 | 6508 | (define_insn "window_save" |
e0a0aad2 | 6509 | [(unspec_volatile |
6510 | [(match_operand 0 "arith_operand" "rI")] | |
6511 | UNSPECV_SAVEW)] | |
47529489 | 6512 | "!TARGET_FLAT" |
f317b732 | 6513 | "save\t%%sp, %0, %%sp" |
6514 | [(set_attr "type" "savew")]) | |
6515 | ||
6516 | (define_expand "epilogue" | |
6517 | [(return)] | |
6518 | "" | |
6519 | { | |
47529489 | 6520 | if (TARGET_FLAT) |
6521 | sparc_flat_expand_epilogue (false); | |
6522 | else | |
6523 | sparc_expand_epilogue (false); | |
f317b732 | 6524 | }) |
6525 | ||
d88ab5ca | 6526 | (define_expand "sibcall_epilogue" |
6527 | [(return)] | |
6528 | "" | |
6529 | { | |
47529489 | 6530 | if (TARGET_FLAT) |
6531 | sparc_flat_expand_epilogue (false); | |
6532 | else | |
6533 | sparc_expand_epilogue (false); | |
6534 | DONE; | |
6535 | }) | |
6536 | ||
6537 | (define_expand "eh_return" | |
6538 | [(use (match_operand 0 "general_operand" ""))] | |
6539 | "" | |
6540 | { | |
6541 | emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]); | |
6542 | emit_jump_insn (gen_eh_return_internal ()); | |
6543 | emit_barrier (); | |
d88ab5ca | 6544 | DONE; |
6545 | }) | |
6546 | ||
47529489 | 6547 | (define_insn_and_split "eh_return_internal" |
6548 | [(eh_return)] | |
6549 | "" | |
6550 | "#" | |
6551 | "epilogue_completed" | |
6552 | [(return)] | |
6553 | { | |
6554 | if (TARGET_FLAT) | |
6555 | sparc_flat_expand_epilogue (true); | |
6556 | else | |
6557 | sparc_expand_epilogue (true); | |
6558 | }) | |
6559 | ||
644b3b25 | 6560 | (define_expand "return" |
6561 | [(return)] | |
6562 | "sparc_can_use_return_insn_p ()" | |
6563 | "") | |
6564 | ||
f317b732 | 6565 | (define_insn "*return_internal" |
6566 | [(return)] | |
6567 | "" | |
6568 | "* return output_return (insn);" | |
6569 | [(set_attr "type" "return") | |
e8d33c3a | 6570 | (set (attr "length") |
47529489 | 6571 | (cond [(eq_attr "calls_eh_return" "true") |
6572 | (if_then_else (eq_attr "delayed_branch" "true") | |
6573 | (if_then_else (ior (eq_attr "isa" "v9") | |
6574 | (eq_attr "flat" "true")) | |
6575 | (const_int 2) | |
6576 | (const_int 3)) | |
6577 | (if_then_else (eq_attr "flat" "true") | |
6578 | (const_int 3) | |
6579 | (const_int 4))) | |
6580 | (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true")) | |
56d43973 | 6581 | (if_then_else (eq_attr "empty_delay_slot" "true") |
6582 | (const_int 2) | |
6583 | (const_int 1)) | |
56d43973 | 6584 | (eq_attr "empty_delay_slot" "true") |
6585 | (if_then_else (eq_attr "delayed_branch" "true") | |
6586 | (const_int 2) | |
6587 | (const_int 3)) | |
6588 | ] (const_int 1)))]) | |
7a8d641b | 6589 | |
84682793 | 6590 | ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and |
6591 | ;; all of memory. This blocks insns from being moved across this point. | |
001e2308 | 6592 | |
84682793 | 6593 | (define_insn "blockage" |
40cc626c | 6594 | [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] |
84682793 | 6595 | "" |
084360fc | 6596 | "" |
6597 | [(set_attr "length" "0")]) | |
001e2308 | 6598 | |
80ab83af | 6599 | ;; Do not schedule instructions accessing memory before this point. |
6600 | ||
6601 | (define_expand "frame_blockage" | |
6602 | [(set (match_dup 0) | |
6603 | (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))] | |
6604 | "" | |
6605 | { | |
6606 | operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); | |
6607 | MEM_VOLATILE_P (operands[0]) = 1; | |
6608 | operands[1] = stack_pointer_rtx; | |
6609 | }) | |
6610 | ||
6611 | (define_insn "*frame_blockage<P:mode>" | |
6612 | [(set (match_operand:BLK 0 "" "") | |
6613 | (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))] | |
6614 | "" | |
6615 | "" | |
6616 | [(set_attr "length" "0")]) | |
6617 | ||
53226a3c | 6618 | (define_expand "probe_stack" |
6619 | [(set (match_operand 0 "memory_operand" "") (const_int 0))] | |
6620 | "" | |
6621 | { | |
6622 | operands[0] | |
6623 | = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS); | |
6624 | }) | |
6625 | ||
f164c08a | 6626 | (define_insn "probe_stack_range<P:mode>" |
6627 | [(set (match_operand:P 0 "register_operand" "=r") | |
6628 | (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") | |
6629 | (match_operand:P 2 "register_operand" "r")] | |
6630 | UNSPECV_PROBE_STACK_RANGE))] | |
6631 | "" | |
6632 | "* return output_probe_stack_range (operands[0], operands[2]);" | |
6633 | [(set_attr "type" "multi")]) | |
6634 | ||
d2cd7749 | 6635 | ;; Prepare to return any type including a structure value. |
6636 | ||
6637 | (define_expand "untyped_return" | |
6638 | [(match_operand:BLK 0 "memory_operand" "") | |
6639 | (match_operand 1 "" "")] | |
6640 | "" | |
d2cd7749 | 6641 | { |
5a5d82d2 | 6642 | rtx valreg1 = gen_rtx_REG (DImode, 24); |
6643 | rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32); | |
d2cd7749 | 6644 | rtx result = operands[0]; |
d2cd7749 | 6645 | |
df5e9319 | 6646 | if (! TARGET_ARCH64) |
001e2308 | 6647 | { |
47529489 | 6648 | rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM); |
001e2308 | 6649 | rtx value = gen_reg_rtx (SImode); |
6650 | ||
6651 | /* Fetch the instruction where we will return to and see if it's an unimp | |
6652 | instruction (the most significant 10 bits will be zero). If so, | |
6653 | update the return address to skip the unimp instruction. */ | |
6654 | emit_move_insn (value, | |
29c05e22 | 6655 | gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8))); |
001e2308 | 6656 | emit_insn (gen_lshrsi3 (value, value, GEN_INT (22))); |
6657 | emit_insn (gen_update_return (rtnreg, value)); | |
6658 | } | |
d2cd7749 | 6659 | |
6660 | /* Reload the function value registers. */ | |
e513d163 | 6661 | emit_move_insn (valreg1, adjust_address (result, DImode, 0)); |
d2cd7749 | 6662 | emit_move_insn (valreg2, |
e513d163 | 6663 | adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8)); |
d2cd7749 | 6664 | |
6665 | /* Put USE insns before the return. */ | |
18b42941 | 6666 | emit_use (valreg1); |
6667 | emit_use (valreg2); | |
d2cd7749 | 6668 | |
6669 | /* Construct the return. */ | |
62380d2d | 6670 | expand_naked_return (); |
d2cd7749 | 6671 | |
6672 | DONE; | |
0037630d | 6673 | }) |
d2cd7749 | 6674 | |
d8c09ceb | 6675 | ;; Adjust the return address conditionally. If the value of op1 is equal |
6676 | ;; to all zero then adjust the return address i.e. op0 = op0 + 4. | |
6677 | ;; This is technically *half* the check required by the 32-bit SPARC | |
6678 | ;; psABI. This check only ensures that an "unimp" insn was written by | |
6679 | ;; the caller, but doesn't check to see if the expected size matches | |
6680 | ;; (this is encoded in the 12 lower bits). This check is obsolete and | |
6681 | ;; only used by the above code "untyped_return". | |
d2cd7749 | 6682 | |
6683 | (define_insn "update_return" | |
6684 | [(unspec:SI [(match_operand:SI 0 "register_operand" "r") | |
40cc626c | 6685 | (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)] |
df5e9319 | 6686 | "! TARGET_ARCH64" |
dfdef7c7 | 6687 | { |
6688 | if (flag_delayed_branch) | |
6689 | return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0"; | |
6690 | else | |
6691 | return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0"; | |
6692 | } | |
6693 | [(set (attr "type") (const_string "multi")) | |
6694 | (set (attr "length") | |
6695 | (if_then_else (eq_attr "delayed_branch" "true") | |
6696 | (const_int 3) | |
6697 | (const_int 4)))]) | |
a44201ea | 6698 | \f |
a44201ea | 6699 | (define_insn "nop" |
6700 | [(const_int 0)] | |
6701 | "" | |
a9208abf | 6702 | "nop") |
a44201ea | 6703 | |
001e2308 | 6704 | (define_expand "indirect_jump" |
6705 | [(set (pc) (match_operand 0 "address_operand" "p"))] | |
a44201ea | 6706 | "" |
001e2308 | 6707 | "") |
6708 | ||
4117925c | 6709 | (define_insn "*branch_sp32" |
001e2308 | 6710 | [(set (pc) (match_operand:SI 0 "address_operand" "p"))] |
f3811c30 | 6711 | "! TARGET_ARCH64" |
a4ddaca5 | 6712 | "jmp\t%a0%#" |
74848118 | 6713 | [(set_attr "type" "uncond_branch")]) |
a44201ea | 6714 | |
4117925c | 6715 | (define_insn "*branch_sp64" |
001e2308 | 6716 | [(set (pc) (match_operand:DI 0 "address_operand" "p"))] |
f3811c30 | 6717 | "TARGET_ARCH64" |
a4ddaca5 | 6718 | "jmp\t%a0%#" |
001e2308 | 6719 | [(set_attr "type" "uncond_branch")]) |
6720 | ||
d1ff492e | 6721 | (define_expand "save_stack_nonlocal" |
6722 | [(set (match_operand 0 "memory_operand" "") | |
6723 | (match_operand 1 "register_operand" "")) | |
6724 | (set (match_dup 2) (match_dup 3))] | |
6725 | "" | |
6726 | { | |
6727 | operands[0] = adjust_address_nv (operands[0], Pmode, 0); | |
6728 | operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode)); | |
47529489 | 6729 | operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); |
d1ff492e | 6730 | }) |
6731 | ||
6732 | (define_expand "restore_stack_nonlocal" | |
6733 | [(set (match_operand 0 "register_operand" "") | |
6734 | (match_operand 1 "memory_operand" ""))] | |
6735 | "" | |
6736 | { | |
6737 | operands[1] = adjust_address_nv (operands[1], Pmode, 0); | |
6738 | }) | |
6739 | ||
a44201ea | 6740 | (define_expand "nonlocal_goto" |
d1ff492e | 6741 | [(match_operand 0 "general_operand" "") |
6742 | (match_operand 1 "general_operand" "") | |
6743 | (match_operand 2 "memory_operand" "") | |
6744 | (match_operand 3 "memory_operand" "")] | |
a44201ea | 6745 | "" |
a44201ea | 6746 | { |
4cdb9b47 | 6747 | rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); |
d1ff492e | 6748 | rtx r_label = copy_to_reg (operands[1]); |
6749 | rtx r_sp = adjust_address_nv (operands[2], Pmode, 0); | |
6750 | rtx r_fp = operands[3]; | |
6751 | rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode)); | |
0d179e03 | 6752 | |
d1ff492e | 6753 | /* We need to flush all the register windows so that their contents will |
6754 | be re-synchronized by the restore insn of the target function. */ | |
47529489 | 6755 | if (!TARGET_FLAT) |
6756 | emit_insn (gen_flush_register_windows ()); | |
0d179e03 | 6757 | |
d1ff492e | 6758 | emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); |
6759 | emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); | |
0d179e03 | 6760 | |
d1ff492e | 6761 | /* Restore frame pointer for containing function. */ |
6762 | emit_move_insn (hard_frame_pointer_rtx, r_fp); | |
6763 | emit_stack_restore (SAVE_NONLOCAL, r_sp); | |
4cdb9b47 | 6764 | emit_move_insn (i7, r_i7); |
0d179e03 | 6765 | |
d1ff492e | 6766 | /* USE of hard_frame_pointer_rtx added for consistency; |
6767 | not clear if really needed. */ | |
6768 | emit_use (hard_frame_pointer_rtx); | |
18b42941 | 6769 | emit_use (stack_pointer_rtx); |
4cdb9b47 | 6770 | emit_use (i7); |
80c07a0c | 6771 | |
4cdb9b47 | 6772 | emit_jump_insn (gen_indirect_jump (r_label)); |
84b46239 | 6773 | emit_barrier (); |
a44201ea | 6774 | DONE; |
0037630d | 6775 | }) |
a44201ea | 6776 | |
d1ff492e | 6777 | (define_expand "builtin_setjmp_receiver" |
6778 | [(label_ref (match_operand 0 "" ""))] | |
6779 | "flag_pic" | |
3b0fa6b6 | 6780 | { |
d1ff492e | 6781 | load_got_register (); |
3b0fa6b6 | 6782 | DONE; |
0037630d | 6783 | }) |
3b0fa6b6 | 6784 | |
d1ff492e | 6785 | ;; Special insn to flush register windows. |
84b46239 | 6786 | |
d1ff492e | 6787 | (define_insn "flush_register_windows" |
6788 | [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)] | |
84b46239 | 6789 | "" |
d1ff492e | 6790 | { return TARGET_V9 ? "flushw" : "ta\t3"; } |
6791 | [(set_attr "type" "flushw")]) | |
84b46239 | 6792 | |
8e2456aa | 6793 | ;; Special pattern for the FLUSH instruction. |
6794 | ||
d0e8b42e | 6795 | (define_insn "flush<P:mode>" |
6796 | [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)] | |
8e2456aa | 6797 | "" |
a4ddaca5 | 6798 | { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; } |
e30b7bae | 6799 | [(set_attr "type" "iflush")]) |
6c04732d | 6800 | |
d0e8b42e | 6801 | ;; Special insns to load and store the 32-bit FP Status Register. |
6802 | ||
6803 | (define_insn "ldfsr" | |
6804 | [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)] | |
6805 | "TARGET_FPU" | |
6806 | "ld\t%0, %%fsr" | |
6807 | [(set_attr "type" "load")]) | |
6808 | ||
6809 | (define_insn "stfsr" | |
6810 | [(set (match_operand:SI 0 "memory_operand" "=m") | |
6811 | (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))] | |
6812 | "TARGET_FPU" | |
6813 | "st\t%%fsr, %0" | |
6814 | [(set_attr "type" "store")]) | |
6c04732d | 6815 | |
d88ab5ca | 6816 | |
6817 | ;; Find first set instructions. | |
4b7044af | 6818 | |
6819 | ;; The scan instruction searches from the most significant bit while ffs | |
6820 | ;; searches from the least significant bit. The bit index and treatment of | |
6821 | ;; zero also differ. It takes at least 7 instructions to get the proper | |
01cc3b75 | 6822 | ;; result. Here is an obvious 8 instruction sequence. |
4b7044af | 6823 | |
998032ba | 6824 | ;; XXX |
4b7044af | 6825 | (define_insn "ffssi2" |
6826 | [(set (match_operand:SI 0 "register_operand" "=&r") | |
6827 | (ffs:SI (match_operand:SI 1 "register_operand" "r"))) | |
6828 | (clobber (match_scratch:SI 2 "=&r"))] | |
93e2cd75 | 6829 | "TARGET_SPARCLITE || TARGET_SPARCLET" |
946e12d1 | 6830 | { |
a4ddaca5 | 6831 | 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"; |
0037630d | 6832 | } |
4b7044af | 6833 | [(set_attr "type" "multi") |
6834 | (set_attr "length" "8")]) | |
001e2308 | 6835 | |
498af5fe | 6836 | (define_expand "popcountdi2" |
6837 | [(set (match_operand:DI 0 "register_operand" "") | |
6838 | (popcount:DI (match_operand:DI 1 "register_operand" "")))] | |
80c0ee75 | 6839 | "TARGET_POPC" |
6840 | { | |
6841 | if (! TARGET_ARCH64) | |
6842 | { | |
498af5fe | 6843 | emit_insn (gen_popcountdi_v8plus (operands[0], operands[1])); |
80c0ee75 | 6844 | DONE; |
6845 | } | |
6846 | }) | |
6847 | ||
498af5fe | 6848 | (define_insn "*popcountdi_sp64" |
6849 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6850 | (popcount:DI (match_operand:DI 1 "register_operand" "r")))] | |
80c0ee75 | 6851 | "TARGET_POPC && TARGET_ARCH64" |
6852 | "popc\t%1, %0") | |
6853 | ||
80c0ee75 | 6854 | (define_insn "popcountdi_v8plus" |
6855 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6856 | (popcount:DI (match_operand:DI 1 "register_operand" "r"))) | |
6857 | (clobber (match_scratch:SI 2 "=&h"))] | |
6858 | "TARGET_POPC && ! TARGET_ARCH64" | |
6859 | { | |
6860 | if (sparc_check_64 (operands[1], insn) <= 0) | |
6861 | output_asm_insn ("srl\t%L1, 0, %L1", operands); | |
6862 | return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0"; | |
6863 | } | |
6864 | [(set_attr "type" "multi") | |
6865 | (set_attr "length" "5")]) | |
6866 | ||
498af5fe | 6867 | (define_expand "popcountsi2" |
6868 | [(set (match_dup 2) | |
6869 | (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
6870 | (set (match_operand:SI 0 "register_operand" "") | |
6871 | (truncate:SI (popcount:DI (match_dup 2))))] | |
6872 | "TARGET_POPC" | |
6873 | { | |
6874 | if (! TARGET_ARCH64) | |
6875 | { | |
6876 | emit_insn (gen_popcountsi_v8plus (operands[0], operands[1])); | |
6877 | DONE; | |
6878 | } | |
6879 | else | |
6880 | operands[2] = gen_reg_rtx (DImode); | |
6881 | }) | |
6882 | ||
6883 | (define_insn "*popcountsi_sp64" | |
6884 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6885 | (truncate:SI | |
6886 | (popcount:DI (match_operand:DI 1 "register_operand" "r"))))] | |
6887 | "TARGET_POPC && TARGET_ARCH64" | |
6888 | "popc\t%1, %0") | |
6889 | ||
6890 | (define_insn "popcountsi_v8plus" | |
6891 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6892 | (popcount:SI (match_operand:SI 1 "register_operand" "r")))] | |
6893 | "TARGET_POPC && ! TARGET_ARCH64" | |
6894 | { | |
6895 | if (sparc_check_64 (operands[1], insn) <= 0) | |
6896 | output_asm_insn ("srl\t%1, 0, %1", operands); | |
6897 | return "popc\t%1, %0"; | |
6898 | } | |
6899 | [(set_attr "type" "multi") | |
6900 | (set_attr "length" "2")]) | |
6901 | ||
6902 | (define_expand "clzdi2" | |
6903 | [(set (match_operand:DI 0 "register_operand" "") | |
6904 | (clz:DI (match_operand:DI 1 "register_operand" "")))] | |
80c0ee75 | 6905 | "TARGET_VIS3" |
6906 | { | |
6907 | if (! TARGET_ARCH64) | |
6908 | { | |
498af5fe | 6909 | emit_insn (gen_clzdi_v8plus (operands[0], operands[1])); |
80c0ee75 | 6910 | DONE; |
6911 | } | |
6912 | }) | |
6913 | ||
6914 | (define_insn "*clzdi_sp64" | |
6915 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6916 | (clz:DI (match_operand:DI 1 "register_operand" "r")))] | |
6917 | "TARGET_VIS3 && TARGET_ARCH64" | |
6918 | "lzd\t%1, %0") | |
6919 | ||
6920 | (define_insn "clzdi_v8plus" | |
6921 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6922 | (clz:DI (match_operand:DI 1 "register_operand" "r"))) | |
6923 | (clobber (match_scratch:SI 2 "=&h"))] | |
6924 | "TARGET_VIS3 && ! TARGET_ARCH64" | |
6925 | { | |
6926 | if (sparc_check_64 (operands[1], insn) <= 0) | |
6927 | output_asm_insn ("srl\t%L1, 0, %L1", operands); | |
6928 | return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0"; | |
6929 | } | |
6930 | [(set_attr "type" "multi") | |
6931 | (set_attr "length" "5")]) | |
6932 | ||
498af5fe | 6933 | (define_expand "clzsi2" |
6934 | [(set (match_dup 2) | |
6935 | (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
6936 | (set (match_dup 3) | |
6937 | (truncate:SI (clz:DI (match_dup 2)))) | |
6938 | (set (match_operand:SI 0 "register_operand" "") | |
6939 | (minus:SI (match_dup 3) (const_int 32)))] | |
6940 | "TARGET_VIS3" | |
6941 | { | |
6942 | if (! TARGET_ARCH64) | |
6943 | { | |
6944 | emit_insn (gen_clzsi_v8plus (operands[0], operands[1])); | |
6945 | DONE; | |
6946 | } | |
6947 | else | |
6948 | { | |
6949 | operands[2] = gen_reg_rtx (DImode); | |
6950 | operands[3] = gen_reg_rtx (SImode); | |
6951 | } | |
6952 | }) | |
6953 | ||
80c0ee75 | 6954 | (define_insn "*clzsi_sp64" |
6955 | [(set (match_operand:SI 0 "register_operand" "=r") | |
498af5fe | 6956 | (truncate:SI |
6957 | (clz:DI (match_operand:DI 1 "register_operand" "r"))))] | |
80c0ee75 | 6958 | "TARGET_VIS3 && TARGET_ARCH64" |
498af5fe | 6959 | "lzd\t%1, %0") |
a44201ea | 6960 | |
80c0ee75 | 6961 | (define_insn "clzsi_v8plus" |
6962 | [(set (match_operand:SI 0 "register_operand" "=r") | |
6963 | (clz:SI (match_operand:SI 1 "register_operand" "r")))] | |
6964 | "TARGET_VIS3 && ! TARGET_ARCH64" | |
6965 | { | |
6966 | if (sparc_check_64 (operands[1], insn) <= 0) | |
6967 | output_asm_insn ("srl\t%1, 0, %1", operands); | |
6968 | return "lzd\t%1, %0\n\tsub\t%0, 32, %0"; | |
6969 | } | |
6970 | [(set_attr "type" "multi") | |
6971 | (set_attr "length" "3")]) | |
7014838c | 6972 | |
a44201ea | 6973 | \f |
6974 | ;; Peepholes go at the end. | |
6975 | ||
94e3b728 | 6976 | ;; Optimize consecutive loads or stores into ldd and std when possible. |
6977 | ;; The conditions in which we do this are very restricted and are | |
6978 | ;; explained in the code for {registers,memory}_ok_for_ldd functions. | |
6979 | ||
55d52cfe | 6980 | (define_peephole2 |
f618d313 | 6981 | [(set (match_operand:SI 0 "memory_operand" "") |
6982 | (const_int 0)) | |
6983 | (set (match_operand:SI 1 "memory_operand" "") | |
6984 | (const_int 0))] | |
6985 | "TARGET_V9 | |
b409d1e2 | 6986 | && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)" |
66181596 | 6987 | [(set (match_dup 0) (const_int 0))] |
6988 | { | |
6989 | operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode); | |
6990 | }) | |
f618d313 | 6991 | |
55d52cfe | 6992 | (define_peephole2 |
f618d313 | 6993 | [(set (match_operand:SI 0 "memory_operand" "") |
6994 | (const_int 0)) | |
6995 | (set (match_operand:SI 1 "memory_operand" "") | |
6996 | (const_int 0))] | |
6997 | "TARGET_V9 | |
b409d1e2 | 6998 | && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)" |
66181596 | 6999 | [(set (match_dup 1) (const_int 0))] |
7000 | { | |
7001 | operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode); | |
7002 | }) | |
f618d313 | 7003 | |
55d52cfe | 7004 | (define_peephole2 |
7005 | [(set (match_operand:SI 0 "register_operand" "") | |
94e3b728 | 7006 | (match_operand:SI 1 "memory_operand" "")) |
55d52cfe | 7007 | (set (match_operand:SI 2 "register_operand" "") |
94e3b728 | 7008 | (match_operand:SI 3 "memory_operand" ""))] |
998032ba | 7009 | "registers_ok_for_ldd_peep (operands[0], operands[2]) |
b409d1e2 | 7010 | && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" |
66181596 | 7011 | [(set (match_dup 0) (match_dup 1))] |
7012 | { | |
7013 | operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode); | |
7014 | operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); | |
7015 | }) | |
94e3b728 | 7016 | |
55d52cfe | 7017 | (define_peephole2 |
94e3b728 | 7018 | [(set (match_operand:SI 0 "memory_operand" "") |
55d52cfe | 7019 | (match_operand:SI 1 "register_operand" "")) |
94e3b728 | 7020 | (set (match_operand:SI 2 "memory_operand" "") |
55d52cfe | 7021 | (match_operand:SI 3 "register_operand" ""))] |
998032ba | 7022 | "registers_ok_for_ldd_peep (operands[1], operands[3]) |
b409d1e2 | 7023 | && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)" |
66181596 | 7024 | [(set (match_dup 0) (match_dup 1))] |
7025 | { | |
7026 | operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode); | |
7027 | operands[1] = gen_rtx_REG (DImode, REGNO (operands[1])); | |
7028 | }) | |
55d52cfe | 7029 | |
7030 | (define_peephole2 | |
7031 | [(set (match_operand:SF 0 "register_operand" "") | |
94e3b728 | 7032 | (match_operand:SF 1 "memory_operand" "")) |
55d52cfe | 7033 | (set (match_operand:SF 2 "register_operand" "") |
94e3b728 | 7034 | (match_operand:SF 3 "memory_operand" ""))] |
998032ba | 7035 | "registers_ok_for_ldd_peep (operands[0], operands[2]) |
b409d1e2 | 7036 | && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" |
66181596 | 7037 | [(set (match_dup 0) (match_dup 1))] |
7038 | { | |
7039 | operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode); | |
7040 | operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0])); | |
7041 | }) | |
94e3b728 | 7042 | |
55d52cfe | 7043 | (define_peephole2 |
94e3b728 | 7044 | [(set (match_operand:SF 0 "memory_operand" "") |
55d52cfe | 7045 | (match_operand:SF 1 "register_operand" "")) |
94e3b728 | 7046 | (set (match_operand:SF 2 "memory_operand" "") |
55d52cfe | 7047 | (match_operand:SF 3 "register_operand" ""))] |
998032ba | 7048 | "registers_ok_for_ldd_peep (operands[1], operands[3]) |
b409d1e2 | 7049 | && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)" |
66181596 | 7050 | [(set (match_dup 0) (match_dup 1))] |
7051 | { | |
7052 | operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode); | |
7053 | operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1])); | |
7054 | }) | |
94e3b728 | 7055 | |
55d52cfe | 7056 | (define_peephole2 |
7057 | [(set (match_operand:SI 0 "register_operand" "") | |
94e3b728 | 7058 | (match_operand:SI 1 "memory_operand" "")) |
55d52cfe | 7059 | (set (match_operand:SI 2 "register_operand" "") |
94e3b728 | 7060 | (match_operand:SI 3 "memory_operand" ""))] |
998032ba | 7061 | "registers_ok_for_ldd_peep (operands[2], operands[0]) |
a3c7ab5f | 7062 | && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])" |
66181596 | 7063 | [(set (match_dup 2) (match_dup 3))] |
7064 | { | |
7065 | operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode); | |
7066 | operands[2] = gen_rtx_REG (DImode, REGNO (operands[2])); | |
7067 | }) | |
94e3b728 | 7068 | |
55d52cfe | 7069 | (define_peephole2 |
94e3b728 | 7070 | [(set (match_operand:SI 0 "memory_operand" "") |
55d52cfe | 7071 | (match_operand:SI 1 "register_operand" "")) |
94e3b728 | 7072 | (set (match_operand:SI 2 "memory_operand" "") |
55d52cfe | 7073 | (match_operand:SI 3 "register_operand" ""))] |
998032ba | 7074 | "registers_ok_for_ldd_peep (operands[3], operands[1]) |
b409d1e2 | 7075 | && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" |
66181596 | 7076 | [(set (match_dup 2) (match_dup 3))] |
7077 | { | |
7078 | operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DImode); | |
7079 | operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); | |
7080 | }) | |
94e3b728 | 7081 | |
55d52cfe | 7082 | (define_peephole2 |
7083 | [(set (match_operand:SF 0 "register_operand" "") | |
94e3b728 | 7084 | (match_operand:SF 1 "memory_operand" "")) |
55d52cfe | 7085 | (set (match_operand:SF 2 "register_operand" "") |
94e3b728 | 7086 | (match_operand:SF 3 "memory_operand" ""))] |
998032ba | 7087 | "registers_ok_for_ldd_peep (operands[2], operands[0]) |
a3c7ab5f | 7088 | && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])" |
66181596 | 7089 | [(set (match_dup 2) (match_dup 3))] |
7090 | { | |
7091 | operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode); | |
7092 | operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2])); | |
7093 | }) | |
94e3b728 | 7094 | |
55d52cfe | 7095 | (define_peephole2 |
94e3b728 | 7096 | [(set (match_operand:SF 0 "memory_operand" "") |
55d52cfe | 7097 | (match_operand:SF 1 "register_operand" "")) |
94e3b728 | 7098 | (set (match_operand:SF 2 "memory_operand" "") |
55d52cfe | 7099 | (match_operand:SF 3 "register_operand" ""))] |
998032ba | 7100 | "registers_ok_for_ldd_peep (operands[3], operands[1]) |
b409d1e2 | 7101 | && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" |
66181596 | 7102 | [(set (match_dup 2) (match_dup 3))] |
7103 | { | |
7104 | operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode); | |
7105 | operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3])); | |
7106 | }) | |
94e3b728 | 7107 | |
a44201ea | 7108 | ;; Optimize the case of following a reg-reg move with a test |
8cc4c881 | 7109 | ;; of reg just moved. Don't allow floating point regs for operand 0 or 1. |
601443c6 | 7110 | ;; This can result from a float to fix conversion. |
a44201ea | 7111 | |
55d52cfe | 7112 | (define_peephole2 |
7113 | [(set (match_operand:SI 0 "register_operand" "") | |
7114 | (match_operand:SI 1 "register_operand" "")) | |
2b25173f | 7115 | (set (reg:CC CC_REG) |
55d52cfe | 7116 | (compare:CC (match_operand:SI 2 "register_operand" "") |
a44201ea | 7117 | (const_int 0)))] |
601443c6 | 7118 | "(rtx_equal_p (operands[2], operands[0]) |
7119 | || rtx_equal_p (operands[2], operands[1])) | |
55d52cfe | 7120 | && ! SPARC_FP_REG_P (REGNO (operands[0])) |
7121 | && ! SPARC_FP_REG_P (REGNO (operands[1]))" | |
7122 | [(parallel [(set (match_dup 0) (match_dup 1)) | |
2b25173f | 7123 | (set (reg:CC CC_REG) |
55d52cfe | 7124 | (compare:CC (match_dup 1) (const_int 0)))])] |
7125 | "") | |
a44201ea | 7126 | |
55d52cfe | 7127 | (define_peephole2 |
7128 | [(set (match_operand:DI 0 "register_operand" "") | |
7129 | (match_operand:DI 1 "register_operand" "")) | |
2b25173f | 7130 | (set (reg:CCX CC_REG) |
55d52cfe | 7131 | (compare:CCX (match_operand:DI 2 "register_operand" "") |
001e2308 | 7132 | (const_int 0)))] |
df5e9319 | 7133 | "TARGET_ARCH64 |
001e2308 | 7134 | && (rtx_equal_p (operands[2], operands[0]) |
7135 | || rtx_equal_p (operands[2], operands[1])) | |
55d52cfe | 7136 | && ! SPARC_FP_REG_P (REGNO (operands[0])) |
7137 | && ! SPARC_FP_REG_P (REGNO (operands[1]))" | |
7138 | [(parallel [(set (match_dup 0) (match_dup 1)) | |
2b25173f | 7139 | (set (reg:CCX CC_REG) |
1c7ebefd | 7140 | (compare:CCX (match_dup 1) (const_int 0)))])] |
55d52cfe | 7141 | "") |
a44201ea | 7142 | |
d88ab5ca | 7143 | |
7144 | ;; Prefetch instructions. | |
7145 | ||
924b7bea | 7146 | ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register |
7147 | ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory | |
7148 | ;; ??? operations. With DFA we might be able to model this, but it requires a lot of | |
7149 | ;; ??? state. | |
7150 | (define_expand "prefetch" | |
7151 | [(match_operand 0 "address_operand" "") | |
7152 | (match_operand 1 "const_int_operand" "") | |
7153 | (match_operand 2 "const_int_operand" "")] | |
7154 | "TARGET_V9" | |
924b7bea | 7155 | { |
7156 | if (TARGET_ARCH64) | |
7157 | emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2])); | |
7158 | else | |
7159 | emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2])); | |
7160 | DONE; | |
0037630d | 7161 | }) |
924b7bea | 7162 | |
7163 | (define_insn "prefetch_64" | |
76956cca | 7164 | [(prefetch (match_operand:DI 0 "address_operand" "p") |
7165 | (match_operand:DI 1 "const_int_operand" "n") | |
7166 | (match_operand:DI 2 "const_int_operand" "n"))] | |
924b7bea | 7167 | "" |
7168 | { | |
7169 | static const char * const prefetch_instr[2][2] = { | |
7170 | { | |
a4ddaca5 | 7171 | "prefetch\t[%a0], 1", /* no locality: prefetch for one read */ |
7172 | "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */ | |
924b7bea | 7173 | }, |
7174 | { | |
a4ddaca5 | 7175 | "prefetch\t[%a0], 3", /* no locality: prefetch for one write */ |
7176 | "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */ | |
924b7bea | 7177 | } |
7178 | }; | |
7179 | int read_or_write = INTVAL (operands[1]); | |
7180 | int locality = INTVAL (operands[2]); | |
7181 | ||
b86b0e16 | 7182 | gcc_assert (read_or_write == 0 || read_or_write == 1); |
7183 | gcc_assert (locality >= 0 && locality < 4); | |
924b7bea | 7184 | return prefetch_instr [read_or_write][locality == 0 ? 0 : 1]; |
7185 | } | |
7186 | [(set_attr "type" "load")]) | |
7187 | ||
7188 | (define_insn "prefetch_32" | |
7189 | [(prefetch (match_operand:SI 0 "address_operand" "p") | |
7190 | (match_operand:SI 1 "const_int_operand" "n") | |
7191 | (match_operand:SI 2 "const_int_operand" "n"))] | |
7192 | "" | |
76956cca | 7193 | { |
924b7bea | 7194 | static const char * const prefetch_instr[2][2] = { |
76956cca | 7195 | { |
a4ddaca5 | 7196 | "prefetch\t[%a0], 1", /* no locality: prefetch for one read */ |
7197 | "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */ | |
76956cca | 7198 | }, |
7199 | { | |
a4ddaca5 | 7200 | "prefetch\t[%a0], 3", /* no locality: prefetch for one write */ |
7201 | "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */ | |
76956cca | 7202 | } |
7203 | }; | |
7204 | int read_or_write = INTVAL (operands[1]); | |
7205 | int locality = INTVAL (operands[2]); | |
7206 | ||
b86b0e16 | 7207 | gcc_assert (read_or_write == 0 || read_or_write == 1); |
7208 | gcc_assert (locality >= 0 && locality < 4); | |
924b7bea | 7209 | return prefetch_instr [read_or_write][locality == 0 ? 0 : 1]; |
76956cca | 7210 | } |
7211 | [(set_attr "type" "load")]) | |
d88ab5ca | 7212 | |
7213 | ||
7214 | ;; Trap instructions. | |
7215 | ||
9e5192ed | 7216 | (define_insn "trap" |
7217 | [(trap_if (const_int 1) (const_int 5))] | |
7218 | "" | |
a4ddaca5 | 7219 | "ta\t5" |
e30b7bae | 7220 | [(set_attr "type" "trap")]) |
9e5192ed | 7221 | |
74f4459c | 7222 | (define_expand "ctrapsi4" |
7223 | [(trap_if (match_operator 0 "noov_compare_operator" | |
7224 | [(match_operand:SI 1 "compare_operand" "") | |
7225 | (match_operand:SI 2 "arith_operand" "")]) | |
ada2d491 | 7226 | (match_operand 3 "arith_operand"))] |
9e5192ed | 7227 | "" |
74f4459c | 7228 | "operands[1] = gen_compare_reg (operands[0]); |
7229 | if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode) | |
f77b9d3c | 7230 | FAIL; |
74f4459c | 7231 | operands[2] = const0_rtx;") |
7232 | ||
7233 | (define_expand "ctrapdi4" | |
7234 | [(trap_if (match_operator 0 "noov_compare_operator" | |
7235 | [(match_operand:DI 1 "compare_operand" "") | |
7236 | (match_operand:DI 2 "arith_operand" "")]) | |
ada2d491 | 7237 | (match_operand 3 "arith_operand"))] |
74f4459c | 7238 | "TARGET_ARCH64" |
7239 | "operands[1] = gen_compare_reg (operands[0]); | |
7240 | if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode) | |
7241 | FAIL; | |
7242 | operands[2] = const0_rtx;") | |
7243 | ||
9e5192ed | 7244 | |
7245 | (define_insn "" | |
2b25173f | 7246 | [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)]) |
9e5192ed | 7247 | (match_operand:SI 1 "arith_operand" "rM"))] |
7248 | "" | |
f77b9d3c | 7249 | { |
7250 | if (TARGET_V9) | |
7251 | return "t%C0\t%%icc, %1"; | |
7252 | else | |
7253 | return "t%C0\t%1"; | |
7254 | } | |
e30b7bae | 7255 | [(set_attr "type" "trap")]) |
9e5192ed | 7256 | |
7257 | (define_insn "" | |
2b25173f | 7258 | [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)]) |
9e5192ed | 7259 | (match_operand:SI 1 "arith_operand" "rM"))] |
7260 | "TARGET_V9" | |
a4ddaca5 | 7261 | "t%C0\t%%xcc, %1" |
e30b7bae | 7262 | [(set_attr "type" "trap")]) |
05b3a83f | 7263 | |
d88ab5ca | 7264 | |
7265 | ;; TLS support instructions. | |
7266 | ||
05b3a83f | 7267 | (define_insn "tgd_hi22" |
7268 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7269 | (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] | |
7270 | UNSPEC_TLSGD)))] | |
7271 | "TARGET_TLS" | |
7272 | "sethi\\t%%tgd_hi22(%a1), %0") | |
7273 | ||
7274 | (define_insn "tgd_lo10" | |
7275 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7276 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7277 | (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")] | |
7278 | UNSPEC_TLSGD)))] | |
7279 | "TARGET_TLS" | |
7280 | "add\\t%1, %%tgd_lo10(%a2), %0") | |
7281 | ||
7282 | (define_insn "tgd_add32" | |
7283 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7284 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
7285 | (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7286 | (match_operand 3 "tgd_symbolic_operand" "")] | |
7287 | UNSPEC_TLSGD)))] | |
7288 | "TARGET_TLS && TARGET_ARCH32" | |
7289 | "add\\t%1, %2, %0, %%tgd_add(%a3)") | |
7290 | ||
7291 | (define_insn "tgd_add64" | |
7292 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7293 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
7294 | (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7295 | (match_operand 3 "tgd_symbolic_operand" "")] | |
7296 | UNSPEC_TLSGD)))] | |
7297 | "TARGET_TLS && TARGET_ARCH64" | |
7298 | "add\\t%1, %2, %0, %%tgd_add(%a3)") | |
7299 | ||
7300 | (define_insn "tgd_call32" | |
7301 | [(set (match_operand 0 "register_operand" "=r") | |
7302 | (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s") | |
7303 | (match_operand 2 "tgd_symbolic_operand" "")] | |
7304 | UNSPEC_TLSGD)) | |
7305 | (match_operand 3 "" ""))) | |
2b25173f | 7306 | (clobber (reg:SI O7_REG))] |
05b3a83f | 7307 | "TARGET_TLS && TARGET_ARCH32" |
7308 | "call\t%a1, %%tgd_call(%a2)%#" | |
7309 | [(set_attr "type" "call")]) | |
7310 | ||
7311 | (define_insn "tgd_call64" | |
7312 | [(set (match_operand 0 "register_operand" "=r") | |
7313 | (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s") | |
7314 | (match_operand 2 "tgd_symbolic_operand" "")] | |
7315 | UNSPEC_TLSGD)) | |
7316 | (match_operand 3 "" ""))) | |
2b25173f | 7317 | (clobber (reg:DI O7_REG))] |
05b3a83f | 7318 | "TARGET_TLS && TARGET_ARCH64" |
7319 | "call\t%a1, %%tgd_call(%a2)%#" | |
7320 | [(set_attr "type" "call")]) | |
7321 | ||
7322 | (define_insn "tldm_hi22" | |
7323 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7324 | (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))] | |
7325 | "TARGET_TLS" | |
7326 | "sethi\\t%%tldm_hi22(%&), %0") | |
7327 | ||
7328 | (define_insn "tldm_lo10" | |
7329 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7330 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7331 | (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))] | |
7332 | "TARGET_TLS" | |
7333 | "add\\t%1, %%tldm_lo10(%&), %0") | |
7334 | ||
7335 | (define_insn "tldm_add32" | |
7336 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7337 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
7338 | (unspec:SI [(match_operand:SI 2 "register_operand" "r")] | |
7339 | UNSPEC_TLSLDM)))] | |
7340 | "TARGET_TLS && TARGET_ARCH32" | |
7341 | "add\\t%1, %2, %0, %%tldm_add(%&)") | |
7342 | ||
7343 | (define_insn "tldm_add64" | |
7344 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7345 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
7346 | (unspec:DI [(match_operand:SI 2 "register_operand" "r")] | |
7347 | UNSPEC_TLSLDM)))] | |
7348 | "TARGET_TLS && TARGET_ARCH64" | |
7349 | "add\\t%1, %2, %0, %%tldm_add(%&)") | |
7350 | ||
7351 | (define_insn "tldm_call32" | |
7352 | [(set (match_operand 0 "register_operand" "=r") | |
7353 | (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")] | |
7354 | UNSPEC_TLSLDM)) | |
7355 | (match_operand 2 "" ""))) | |
2b25173f | 7356 | (clobber (reg:SI O7_REG))] |
05b3a83f | 7357 | "TARGET_TLS && TARGET_ARCH32" |
7358 | "call\t%a1, %%tldm_call(%&)%#" | |
7359 | [(set_attr "type" "call")]) | |
7360 | ||
7361 | (define_insn "tldm_call64" | |
7362 | [(set (match_operand 0 "register_operand" "=r") | |
7363 | (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")] | |
7364 | UNSPEC_TLSLDM)) | |
7365 | (match_operand 2 "" ""))) | |
2b25173f | 7366 | (clobber (reg:DI O7_REG))] |
05b3a83f | 7367 | "TARGET_TLS && TARGET_ARCH64" |
7368 | "call\t%a1, %%tldm_call(%&)%#" | |
7369 | [(set_attr "type" "call")]) | |
7370 | ||
7371 | (define_insn "tldo_hix22" | |
7372 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7373 | (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] | |
7374 | UNSPEC_TLSLDO)))] | |
7375 | "TARGET_TLS" | |
7376 | "sethi\\t%%tldo_hix22(%a1), %0") | |
7377 | ||
7378 | (define_insn "tldo_lox10" | |
7379 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7380 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7381 | (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")] | |
7382 | UNSPEC_TLSLDO)))] | |
7383 | "TARGET_TLS" | |
7384 | "xor\\t%1, %%tldo_lox10(%a2), %0") | |
7385 | ||
7386 | (define_insn "tldo_add32" | |
7387 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7388 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
7389 | (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7390 | (match_operand 3 "tld_symbolic_operand" "")] | |
7391 | UNSPEC_TLSLDO)))] | |
7392 | "TARGET_TLS && TARGET_ARCH32" | |
7393 | "add\\t%1, %2, %0, %%tldo_add(%a3)") | |
7394 | ||
7395 | (define_insn "tldo_add64" | |
7396 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7397 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
7398 | (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7399 | (match_operand 3 "tld_symbolic_operand" "")] | |
7400 | UNSPEC_TLSLDO)))] | |
7401 | "TARGET_TLS && TARGET_ARCH64" | |
7402 | "add\\t%1, %2, %0, %%tldo_add(%a3)") | |
7403 | ||
7404 | (define_insn "tie_hi22" | |
7405 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7406 | (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] | |
7407 | UNSPEC_TLSIE)))] | |
7408 | "TARGET_TLS" | |
7409 | "sethi\\t%%tie_hi22(%a1), %0") | |
7410 | ||
7411 | (define_insn "tie_lo10" | |
7412 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7413 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7414 | (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")] | |
7415 | UNSPEC_TLSIE)))] | |
7416 | "TARGET_TLS" | |
7417 | "add\\t%1, %%tie_lo10(%a2), %0") | |
7418 | ||
7419 | (define_insn "tie_ld32" | |
7420 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7421 | (unspec:SI [(match_operand:SI 1 "register_operand" "r") | |
7422 | (match_operand:SI 2 "register_operand" "r") | |
7423 | (match_operand 3 "tie_symbolic_operand" "")] | |
7424 | UNSPEC_TLSIE))] | |
7425 | "TARGET_TLS && TARGET_ARCH32" | |
7426 | "ld\\t[%1 + %2], %0, %%tie_ld(%a3)" | |
7427 | [(set_attr "type" "load")]) | |
7428 | ||
7429 | (define_insn "tie_ld64" | |
7430 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7431 | (unspec:DI [(match_operand:DI 1 "register_operand" "r") | |
7432 | (match_operand:SI 2 "register_operand" "r") | |
7433 | (match_operand 3 "tie_symbolic_operand" "")] | |
7434 | UNSPEC_TLSIE))] | |
7435 | "TARGET_TLS && TARGET_ARCH64" | |
7436 | "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)" | |
7437 | [(set_attr "type" "load")]) | |
7438 | ||
7439 | (define_insn "tie_add32" | |
7440 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7441 | (plus:SI (match_operand:SI 1 "register_operand" "r") | |
7442 | (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
3419591d | 7443 | (match_operand 3 "tie_symbolic_operand" "")] |
05b3a83f | 7444 | UNSPEC_TLSIE)))] |
7445 | "TARGET_SUN_TLS && TARGET_ARCH32" | |
7446 | "add\\t%1, %2, %0, %%tie_add(%a3)") | |
7447 | ||
7448 | (define_insn "tie_add64" | |
7449 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7450 | (plus:DI (match_operand:DI 1 "register_operand" "r") | |
7451 | (unspec:DI [(match_operand:DI 2 "register_operand" "r") | |
3419591d | 7452 | (match_operand 3 "tie_symbolic_operand" "")] |
05b3a83f | 7453 | UNSPEC_TLSIE)))] |
7454 | "TARGET_SUN_TLS && TARGET_ARCH64" | |
7455 | "add\\t%1, %2, %0, %%tie_add(%a3)") | |
7456 | ||
7457 | (define_insn "tle_hix22_sp32" | |
7458 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7459 | (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")] | |
7460 | UNSPEC_TLSLE)))] | |
7461 | "TARGET_TLS && TARGET_ARCH32" | |
7462 | "sethi\\t%%tle_hix22(%a1), %0") | |
7463 | ||
7464 | (define_insn "tle_lox10_sp32" | |
7465 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7466 | (lo_sum:SI (match_operand:SI 1 "register_operand" "r") | |
7467 | (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")] | |
7468 | UNSPEC_TLSLE)))] | |
7469 | "TARGET_TLS && TARGET_ARCH32" | |
7470 | "xor\\t%1, %%tle_lox10(%a2), %0") | |
7471 | ||
7472 | (define_insn "tle_hix22_sp64" | |
7473 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7474 | (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")] | |
7475 | UNSPEC_TLSLE)))] | |
7476 | "TARGET_TLS && TARGET_ARCH64" | |
7477 | "sethi\\t%%tle_hix22(%a1), %0") | |
7478 | ||
7479 | (define_insn "tle_lox10_sp64" | |
7480 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7481 | (lo_sum:DI (match_operand:DI 1 "register_operand" "r") | |
7482 | (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")] | |
7483 | UNSPEC_TLSLE)))] | |
7484 | "TARGET_TLS && TARGET_ARCH64" | |
7485 | "xor\\t%1, %%tle_lox10(%a2), %0") | |
7486 | ||
efee20da | 7487 | ;; Now patterns combining tldo_add{32,64} with some integer loads or stores |
05b3a83f | 7488 | (define_insn "*tldo_ldub_sp32" |
7489 | [(set (match_operand:QI 0 "register_operand" "=r") | |
7490 | (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7491 | (match_operand 3 "tld_symbolic_operand" "")] | |
7492 | UNSPEC_TLSLDO) | |
7493 | (match_operand:SI 1 "register_operand" "r"))))] | |
7494 | "TARGET_TLS && TARGET_ARCH32" | |
7495 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7496 | [(set_attr "type" "load") | |
7497 | (set_attr "us3load_type" "3cycle")]) | |
7498 | ||
7499 | (define_insn "*tldo_ldub1_sp32" | |
7500 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7501 | (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7502 | (match_operand 3 "tld_symbolic_operand" "")] | |
7503 | UNSPEC_TLSLDO) | |
7504 | (match_operand:SI 1 "register_operand" "r")))))] | |
7505 | "TARGET_TLS && TARGET_ARCH32" | |
7506 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7507 | [(set_attr "type" "load") | |
7508 | (set_attr "us3load_type" "3cycle")]) | |
7509 | ||
7510 | (define_insn "*tldo_ldub2_sp32" | |
7511 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7512 | (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7513 | (match_operand 3 "tld_symbolic_operand" "")] | |
7514 | UNSPEC_TLSLDO) | |
7515 | (match_operand:SI 1 "register_operand" "r")))))] | |
7516 | "TARGET_TLS && TARGET_ARCH32" | |
7517 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7518 | [(set_attr "type" "load") | |
7519 | (set_attr "us3load_type" "3cycle")]) | |
7520 | ||
7521 | (define_insn "*tldo_ldsb1_sp32" | |
7522 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7523 | (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7524 | (match_operand 3 "tld_symbolic_operand" "")] | |
7525 | UNSPEC_TLSLDO) | |
7526 | (match_operand:SI 1 "register_operand" "r")))))] | |
7527 | "TARGET_TLS && TARGET_ARCH32" | |
7528 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7529 | [(set_attr "type" "sload") | |
7530 | (set_attr "us3load_type" "3cycle")]) | |
7531 | ||
7532 | (define_insn "*tldo_ldsb2_sp32" | |
7533 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7534 | (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7535 | (match_operand 3 "tld_symbolic_operand" "")] | |
7536 | UNSPEC_TLSLDO) | |
7537 | (match_operand:SI 1 "register_operand" "r")))))] | |
7538 | "TARGET_TLS && TARGET_ARCH32" | |
7539 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7540 | [(set_attr "type" "sload") | |
7541 | (set_attr "us3load_type" "3cycle")]) | |
7542 | ||
7543 | (define_insn "*tldo_ldub_sp64" | |
7544 | [(set (match_operand:QI 0 "register_operand" "=r") | |
7545 | (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7546 | (match_operand 3 "tld_symbolic_operand" "")] | |
7547 | UNSPEC_TLSLDO) | |
7548 | (match_operand:DI 1 "register_operand" "r"))))] | |
7549 | "TARGET_TLS && TARGET_ARCH64" | |
7550 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7551 | [(set_attr "type" "load") | |
7552 | (set_attr "us3load_type" "3cycle")]) | |
7553 | ||
7554 | (define_insn "*tldo_ldub1_sp64" | |
7555 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7556 | (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7557 | (match_operand 3 "tld_symbolic_operand" "")] | |
7558 | UNSPEC_TLSLDO) | |
7559 | (match_operand:DI 1 "register_operand" "r")))))] | |
7560 | "TARGET_TLS && TARGET_ARCH64" | |
7561 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7562 | [(set_attr "type" "load") | |
7563 | (set_attr "us3load_type" "3cycle")]) | |
7564 | ||
7565 | (define_insn "*tldo_ldub2_sp64" | |
7566 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7567 | (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7568 | (match_operand 3 "tld_symbolic_operand" "")] | |
7569 | UNSPEC_TLSLDO) | |
7570 | (match_operand:DI 1 "register_operand" "r")))))] | |
7571 | "TARGET_TLS && TARGET_ARCH64" | |
7572 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7573 | [(set_attr "type" "load") | |
7574 | (set_attr "us3load_type" "3cycle")]) | |
7575 | ||
7576 | (define_insn "*tldo_ldub3_sp64" | |
7577 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7578 | (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7579 | (match_operand 3 "tld_symbolic_operand" "")] | |
7580 | UNSPEC_TLSLDO) | |
7581 | (match_operand:DI 1 "register_operand" "r")))))] | |
7582 | "TARGET_TLS && TARGET_ARCH64" | |
7583 | "ldub\t[%1 + %2], %0, %%tldo_add(%3)" | |
7584 | [(set_attr "type" "load") | |
7585 | (set_attr "us3load_type" "3cycle")]) | |
7586 | ||
7587 | (define_insn "*tldo_ldsb1_sp64" | |
7588 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7589 | (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7590 | (match_operand 3 "tld_symbolic_operand" "")] | |
7591 | UNSPEC_TLSLDO) | |
7592 | (match_operand:DI 1 "register_operand" "r")))))] | |
7593 | "TARGET_TLS && TARGET_ARCH64" | |
7594 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7595 | [(set_attr "type" "sload") | |
7596 | (set_attr "us3load_type" "3cycle")]) | |
7597 | ||
7598 | (define_insn "*tldo_ldsb2_sp64" | |
7599 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7600 | (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7601 | (match_operand 3 "tld_symbolic_operand" "")] | |
7602 | UNSPEC_TLSLDO) | |
7603 | (match_operand:DI 1 "register_operand" "r")))))] | |
7604 | "TARGET_TLS && TARGET_ARCH64" | |
7605 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7606 | [(set_attr "type" "sload") | |
7607 | (set_attr "us3load_type" "3cycle")]) | |
7608 | ||
7609 | (define_insn "*tldo_ldsb3_sp64" | |
7610 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7611 | (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7612 | (match_operand 3 "tld_symbolic_operand" "")] | |
7613 | UNSPEC_TLSLDO) | |
7614 | (match_operand:DI 1 "register_operand" "r")))))] | |
7615 | "TARGET_TLS && TARGET_ARCH64" | |
7616 | "ldsb\t[%1 + %2], %0, %%tldo_add(%3)" | |
7617 | [(set_attr "type" "sload") | |
7618 | (set_attr "us3load_type" "3cycle")]) | |
7619 | ||
7620 | (define_insn "*tldo_lduh_sp32" | |
7621 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7622 | (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7623 | (match_operand 3 "tld_symbolic_operand" "")] | |
7624 | UNSPEC_TLSLDO) | |
7625 | (match_operand:SI 1 "register_operand" "r"))))] | |
7626 | "TARGET_TLS && TARGET_ARCH32" | |
7627 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7628 | [(set_attr "type" "load") | |
7629 | (set_attr "us3load_type" "3cycle")]) | |
7630 | ||
7631 | (define_insn "*tldo_lduh1_sp32" | |
7632 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7633 | (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7634 | (match_operand 3 "tld_symbolic_operand" "")] | |
7635 | UNSPEC_TLSLDO) | |
7636 | (match_operand:SI 1 "register_operand" "r")))))] | |
7637 | "TARGET_TLS && TARGET_ARCH32" | |
7638 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7639 | [(set_attr "type" "load") | |
7640 | (set_attr "us3load_type" "3cycle")]) | |
7641 | ||
7642 | (define_insn "*tldo_ldsh1_sp32" | |
7643 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7644 | (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7645 | (match_operand 3 "tld_symbolic_operand" "")] | |
7646 | UNSPEC_TLSLDO) | |
7647 | (match_operand:SI 1 "register_operand" "r")))))] | |
7648 | "TARGET_TLS && TARGET_ARCH32" | |
7649 | "ldsh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7650 | [(set_attr "type" "sload") | |
7651 | (set_attr "us3load_type" "3cycle")]) | |
7652 | ||
7653 | (define_insn "*tldo_lduh_sp64" | |
7654 | [(set (match_operand:HI 0 "register_operand" "=r") | |
7655 | (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7656 | (match_operand 3 "tld_symbolic_operand" "")] | |
7657 | UNSPEC_TLSLDO) | |
7658 | (match_operand:DI 1 "register_operand" "r"))))] | |
7659 | "TARGET_TLS && TARGET_ARCH64" | |
7660 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7661 | [(set_attr "type" "load") | |
7662 | (set_attr "us3load_type" "3cycle")]) | |
7663 | ||
7664 | (define_insn "*tldo_lduh1_sp64" | |
7665 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7666 | (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7667 | (match_operand 3 "tld_symbolic_operand" "")] | |
7668 | UNSPEC_TLSLDO) | |
7669 | (match_operand:DI 1 "register_operand" "r")))))] | |
7670 | "TARGET_TLS && TARGET_ARCH64" | |
7671 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7672 | [(set_attr "type" "load") | |
7673 | (set_attr "us3load_type" "3cycle")]) | |
7674 | ||
7675 | (define_insn "*tldo_lduh2_sp64" | |
7676 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7677 | (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7678 | (match_operand 3 "tld_symbolic_operand" "")] | |
7679 | UNSPEC_TLSLDO) | |
7680 | (match_operand:DI 1 "register_operand" "r")))))] | |
7681 | "TARGET_TLS && TARGET_ARCH64" | |
7682 | "lduh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7683 | [(set_attr "type" "load") | |
7684 | (set_attr "us3load_type" "3cycle")]) | |
7685 | ||
7686 | (define_insn "*tldo_ldsh1_sp64" | |
7687 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7688 | (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7689 | (match_operand 3 "tld_symbolic_operand" "")] | |
7690 | UNSPEC_TLSLDO) | |
7691 | (match_operand:DI 1 "register_operand" "r")))))] | |
7692 | "TARGET_TLS && TARGET_ARCH64" | |
7693 | "ldsh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7694 | [(set_attr "type" "sload") | |
7695 | (set_attr "us3load_type" "3cycle")]) | |
7696 | ||
7697 | (define_insn "*tldo_ldsh2_sp64" | |
7698 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7699 | (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7700 | (match_operand 3 "tld_symbolic_operand" "")] | |
7701 | UNSPEC_TLSLDO) | |
7702 | (match_operand:DI 1 "register_operand" "r")))))] | |
7703 | "TARGET_TLS && TARGET_ARCH64" | |
7704 | "ldsh\t[%1 + %2], %0, %%tldo_add(%3)" | |
7705 | [(set_attr "type" "sload") | |
7706 | (set_attr "us3load_type" "3cycle")]) | |
7707 | ||
7708 | (define_insn "*tldo_lduw_sp32" | |
7709 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7710 | (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7711 | (match_operand 3 "tld_symbolic_operand" "")] | |
7712 | UNSPEC_TLSLDO) | |
7713 | (match_operand:SI 1 "register_operand" "r"))))] | |
7714 | "TARGET_TLS && TARGET_ARCH32" | |
7715 | "ld\t[%1 + %2], %0, %%tldo_add(%3)" | |
7716 | [(set_attr "type" "load")]) | |
7717 | ||
7718 | (define_insn "*tldo_lduw_sp64" | |
7719 | [(set (match_operand:SI 0 "register_operand" "=r") | |
7720 | (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7721 | (match_operand 3 "tld_symbolic_operand" "")] | |
7722 | UNSPEC_TLSLDO) | |
7723 | (match_operand:DI 1 "register_operand" "r"))))] | |
7724 | "TARGET_TLS && TARGET_ARCH64" | |
7725 | "lduw\t[%1 + %2], %0, %%tldo_add(%3)" | |
7726 | [(set_attr "type" "load")]) | |
7727 | ||
7728 | (define_insn "*tldo_lduw1_sp64" | |
7729 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7730 | (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7731 | (match_operand 3 "tld_symbolic_operand" "")] | |
7732 | UNSPEC_TLSLDO) | |
7733 | (match_operand:DI 1 "register_operand" "r")))))] | |
7734 | "TARGET_TLS && TARGET_ARCH64" | |
7735 | "lduw\t[%1 + %2], %0, %%tldo_add(%3)" | |
7736 | [(set_attr "type" "load")]) | |
7737 | ||
7738 | (define_insn "*tldo_ldsw1_sp64" | |
7739 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7740 | (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7741 | (match_operand 3 "tld_symbolic_operand" "")] | |
7742 | UNSPEC_TLSLDO) | |
7743 | (match_operand:DI 1 "register_operand" "r")))))] | |
7744 | "TARGET_TLS && TARGET_ARCH64" | |
7745 | "ldsw\t[%1 + %2], %0, %%tldo_add(%3)" | |
7746 | [(set_attr "type" "sload") | |
7747 | (set_attr "us3load_type" "3cycle")]) | |
7748 | ||
7749 | (define_insn "*tldo_ldx_sp64" | |
7750 | [(set (match_operand:DI 0 "register_operand" "=r") | |
7751 | (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7752 | (match_operand 3 "tld_symbolic_operand" "")] | |
7753 | UNSPEC_TLSLDO) | |
7754 | (match_operand:DI 1 "register_operand" "r"))))] | |
7755 | "TARGET_TLS && TARGET_ARCH64" | |
7756 | "ldx\t[%1 + %2], %0, %%tldo_add(%3)" | |
7757 | [(set_attr "type" "load")]) | |
7758 | ||
7759 | (define_insn "*tldo_stb_sp32" | |
7760 | [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7761 | (match_operand 3 "tld_symbolic_operand" "")] | |
7762 | UNSPEC_TLSLDO) | |
7763 | (match_operand:SI 1 "register_operand" "r"))) | |
e197f24a | 7764 | (match_operand:QI 0 "register_operand" "r"))] |
05b3a83f | 7765 | "TARGET_TLS && TARGET_ARCH32" |
7766 | "stb\t%0, [%1 + %2], %%tldo_add(%3)" | |
7767 | [(set_attr "type" "store")]) | |
7768 | ||
7769 | (define_insn "*tldo_stb_sp64" | |
7770 | [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7771 | (match_operand 3 "tld_symbolic_operand" "")] | |
7772 | UNSPEC_TLSLDO) | |
7773 | (match_operand:DI 1 "register_operand" "r"))) | |
e197f24a | 7774 | (match_operand:QI 0 "register_operand" "r"))] |
05b3a83f | 7775 | "TARGET_TLS && TARGET_ARCH64" |
7776 | "stb\t%0, [%1 + %2], %%tldo_add(%3)" | |
7777 | [(set_attr "type" "store")]) | |
7778 | ||
7779 | (define_insn "*tldo_sth_sp32" | |
7780 | [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7781 | (match_operand 3 "tld_symbolic_operand" "")] | |
7782 | UNSPEC_TLSLDO) | |
7783 | (match_operand:SI 1 "register_operand" "r"))) | |
e197f24a | 7784 | (match_operand:HI 0 "register_operand" "r"))] |
05b3a83f | 7785 | "TARGET_TLS && TARGET_ARCH32" |
7786 | "sth\t%0, [%1 + %2], %%tldo_add(%3)" | |
7787 | [(set_attr "type" "store")]) | |
7788 | ||
7789 | (define_insn "*tldo_sth_sp64" | |
7790 | [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7791 | (match_operand 3 "tld_symbolic_operand" "")] | |
7792 | UNSPEC_TLSLDO) | |
7793 | (match_operand:DI 1 "register_operand" "r"))) | |
e197f24a | 7794 | (match_operand:HI 0 "register_operand" "r"))] |
05b3a83f | 7795 | "TARGET_TLS && TARGET_ARCH64" |
7796 | "sth\t%0, [%1 + %2], %%tldo_add(%3)" | |
7797 | [(set_attr "type" "store")]) | |
7798 | ||
7799 | (define_insn "*tldo_stw_sp32" | |
7800 | [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r") | |
7801 | (match_operand 3 "tld_symbolic_operand" "")] | |
7802 | UNSPEC_TLSLDO) | |
7803 | (match_operand:SI 1 "register_operand" "r"))) | |
e197f24a | 7804 | (match_operand:SI 0 "register_operand" "r"))] |
05b3a83f | 7805 | "TARGET_TLS && TARGET_ARCH32" |
7806 | "st\t%0, [%1 + %2], %%tldo_add(%3)" | |
7807 | [(set_attr "type" "store")]) | |
7808 | ||
7809 | (define_insn "*tldo_stw_sp64" | |
7810 | [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7811 | (match_operand 3 "tld_symbolic_operand" "")] | |
7812 | UNSPEC_TLSLDO) | |
7813 | (match_operand:DI 1 "register_operand" "r"))) | |
e197f24a | 7814 | (match_operand:SI 0 "register_operand" "r"))] |
05b3a83f | 7815 | "TARGET_TLS && TARGET_ARCH64" |
7816 | "stw\t%0, [%1 + %2], %%tldo_add(%3)" | |
7817 | [(set_attr "type" "store")]) | |
7818 | ||
7819 | (define_insn "*tldo_stx_sp64" | |
7820 | [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r") | |
7821 | (match_operand 3 "tld_symbolic_operand" "")] | |
7822 | UNSPEC_TLSLDO) | |
7823 | (match_operand:DI 1 "register_operand" "r"))) | |
e197f24a | 7824 | (match_operand:DI 0 "register_operand" "r"))] |
05b3a83f | 7825 | "TARGET_TLS && TARGET_ARCH64" |
7826 | "stx\t%0, [%1 + %2], %%tldo_add(%3)" | |
7827 | [(set_attr "type" "store")]) | |
f9545184 | 7828 | |
d88ab5ca | 7829 | |
fc5cceaf | 7830 | ;; Stack protector instructions. |
7831 | ||
7832 | (define_expand "stack_protect_set" | |
7833 | [(match_operand 0 "memory_operand" "") | |
7834 | (match_operand 1 "memory_operand" "")] | |
7835 | "" | |
7836 | { | |
7837 | #ifdef TARGET_THREAD_SSP_OFFSET | |
7838 | rtx tlsreg = gen_rtx_REG (Pmode, 7); | |
7839 | rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); | |
7840 | operands[1] = gen_rtx_MEM (Pmode, addr); | |
7841 | #endif | |
7842 | if (TARGET_ARCH64) | |
7843 | emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); | |
7844 | else | |
7845 | emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); | |
7846 | DONE; | |
7847 | }) | |
7848 | ||
7849 | (define_insn "stack_protect_setsi" | |
7850 | [(set (match_operand:SI 0 "memory_operand" "=m") | |
7851 | (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) | |
7852 | (set (match_scratch:SI 2 "=&r") (const_int 0))] | |
7853 | "TARGET_ARCH32" | |
7854 | "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2" | |
7855 | [(set_attr "type" "multi") | |
7856 | (set_attr "length" "3")]) | |
7857 | ||
7858 | (define_insn "stack_protect_setdi" | |
7859 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
7860 | (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) | |
7861 | (set (match_scratch:DI 2 "=&r") (const_int 0))] | |
7862 | "TARGET_ARCH64" | |
7863 | "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2" | |
7864 | [(set_attr "type" "multi") | |
7865 | (set_attr "length" "3")]) | |
7866 | ||
7867 | (define_expand "stack_protect_test" | |
7868 | [(match_operand 0 "memory_operand" "") | |
7869 | (match_operand 1 "memory_operand" "") | |
7870 | (match_operand 2 "" "")] | |
7871 | "" | |
7872 | { | |
74f4459c | 7873 | rtx result, test; |
fc5cceaf | 7874 | #ifdef TARGET_THREAD_SSP_OFFSET |
7875 | rtx tlsreg = gen_rtx_REG (Pmode, 7); | |
7876 | rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); | |
7877 | operands[1] = gen_rtx_MEM (Pmode, addr); | |
7878 | #endif | |
7879 | if (TARGET_ARCH64) | |
7880 | { | |
74f4459c | 7881 | result = gen_reg_rtx (Pmode); |
7882 | emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1])); | |
7883 | test = gen_rtx_EQ (VOIDmode, result, const0_rtx); | |
7884 | emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2])); | |
fc5cceaf | 7885 | } |
7886 | else | |
7887 | { | |
7888 | emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); | |
74f4459c | 7889 | result = gen_rtx_REG (CCmode, SPARC_ICC_REG); |
7890 | test = gen_rtx_EQ (VOIDmode, result, const0_rtx); | |
7891 | emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2])); | |
fc5cceaf | 7892 | } |
fc5cceaf | 7893 | DONE; |
7894 | }) | |
7895 | ||
7896 | (define_insn "stack_protect_testsi" | |
2b25173f | 7897 | [(set (reg:CC CC_REG) |
fc5cceaf | 7898 | (unspec:CC [(match_operand:SI 0 "memory_operand" "m") |
7899 | (match_operand:SI 1 "memory_operand" "m")] | |
7900 | UNSPEC_SP_TEST)) | |
d40145fa | 7901 | (set (match_scratch:SI 3 "=r") (const_int 0)) |
7902 | (clobber (match_scratch:SI 2 "=&r"))] | |
fc5cceaf | 7903 | "TARGET_ARCH32" |
7904 | "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3" | |
7905 | [(set_attr "type" "multi") | |
7906 | (set_attr "length" "4")]) | |
7907 | ||
7908 | (define_insn "stack_protect_testdi" | |
7909 | [(set (match_operand:DI 0 "register_operand" "=&r") | |
7910 | (unspec:DI [(match_operand:DI 1 "memory_operand" "m") | |
7911 | (match_operand:DI 2 "memory_operand" "m")] | |
7912 | UNSPEC_SP_TEST)) | |
7913 | (set (match_scratch:DI 3 "=r") (const_int 0))] | |
7914 | "TARGET_ARCH64" | |
7915 | "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3" | |
7916 | [(set_attr "type" "multi") | |
7917 | (set_attr "length" "4")]) | |
7918 | ||
f9545184 | 7919 | ;; Vector instructions. |
7920 | ||
bc963728 | 7921 | (define_mode_iterator VM32 [V1SI V2HI V4QI]) |
7922 | (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI]) | |
7923 | (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI]) | |
7924 | ||
7925 | (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")]) | |
7926 | (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f") | |
7927 | (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")]) | |
7928 | (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single") | |
7929 | (V1DI "double") (V2SI "double") (V4HI "double") | |
7930 | (V8QI "double")]) | |
7931 | ||
7932 | (define_expand "mov<VMALL:mode>" | |
7933 | [(set (match_operand:VMALL 0 "nonimmediate_operand" "") | |
7934 | (match_operand:VMALL 1 "general_operand" ""))] | |
7935 | "TARGET_VIS" | |
7936 | { | |
7937 | if (sparc_expand_move (<VMALL:MODE>mode, operands)) | |
7938 | DONE; | |
7939 | }) | |
7940 | ||
4aa70596 | 7941 | (define_insn "*mov<VM32:mode>_insn" |
0db4cb41 | 7942 | [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f") |
7943 | (match_operand:VM32 1 "input_operand" "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))] | |
bc963728 | 7944 | "TARGET_VIS |
30386ca0 | 7945 | && (register_operand (operands[0], <VM32:MODE>mode) |
7946 | || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))" | |
7947 | "@ | |
7948 | fzeros\t%0 | |
7949 | fones\t%0 | |
d3cb8b93 | 7950 | fsrc2s\t%1, %0 |
30386ca0 | 7951 | ld\t%1, %0 |
7952 | st\t%1, %0 | |
7953 | st\t%r1, %0 | |
7954 | ld\t%1, %0 | |
7955 | st\t%1, %0 | |
7956 | mov\t%1, %0 | |
7957 | movstouw\t%1, %0 | |
7958 | movwtos\t%1, %0" | |
d3cb8b93 | 7959 | [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv") |
4aa70596 | 7960 | (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")]) |
bc963728 | 7961 | |
4aa70596 | 7962 | (define_insn "*mov<VM64:mode>_insn_sp64" |
3b0af68d | 7963 | [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r") |
7964 | (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))] | |
bc963728 | 7965 | "TARGET_VIS |
30386ca0 | 7966 | && TARGET_ARCH64 |
7967 | && (register_operand (operands[0], <VM64:MODE>mode) | |
7968 | || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))" | |
7969 | "@ | |
7970 | fzero\t%0 | |
7971 | fone\t%0 | |
d3cb8b93 | 7972 | fsrc2\t%1, %0 |
30386ca0 | 7973 | ldd\t%1, %0 |
7974 | std\t%1, %0 | |
7975 | stx\t%r1, %0 | |
7976 | ldx\t%1, %0 | |
7977 | stx\t%1, %0 | |
7978 | movdtox\t%1, %0 | |
7979 | movxtod\t%1, %0 | |
7980 | mov\t%1, %0" | |
d3cb8b93 | 7981 | [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*") |
4aa70596 | 7982 | (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")]) |
30386ca0 | 7983 | |
4aa70596 | 7984 | (define_insn "*mov<VM64:mode>_insn_sp32" |
5d3ad0ab | 7985 | [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r") |
7986 | (match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))] | |
30386ca0 | 7987 | "TARGET_VIS |
30386ca0 | 7988 | && ! TARGET_ARCH64 |
7989 | && (register_operand (operands[0], <VM64:MODE>mode) | |
7990 | || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))" | |
7991 | "@ | |
7992 | fzero\t%0 | |
7993 | fone\t%0 | |
d3cb8b93 | 7994 | fsrc2\t%1, %0 |
30386ca0 | 7995 | # |
7996 | # | |
7997 | ldd\t%1, %0 | |
7998 | std\t%1, %0 | |
7999 | stx\t%r1, %0 | |
8000 | ldd\t%1, %0 | |
8001 | std\t%1, %0 | |
8002 | # | |
8003 | #" | |
d3cb8b93 | 8004 | [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*") |
4aa70596 | 8005 | (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2") |
8006 | (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")]) | |
bc963728 | 8007 | |
8008 | (define_split | |
8009 | [(set (match_operand:VM64 0 "memory_operand" "") | |
8010 | (match_operand:VM64 1 "register_operand" ""))] | |
8011 | "reload_completed | |
8012 | && TARGET_VIS | |
8013 | && ! TARGET_ARCH64 | |
8014 | && (((REGNO (operands[1]) % 2) != 0) | |
8015 | || ! mem_min_alignment (operands[0], 8)) | |
8016 | && offsettable_memref_p (operands[0])" | |
8017 | [(clobber (const_int 0))] | |
8018 | { | |
8019 | rtx word0, word1; | |
8020 | ||
8021 | word0 = adjust_address (operands[0], SImode, 0); | |
8022 | word1 = adjust_address (operands[0], SImode, 4); | |
8023 | ||
8024 | emit_move_insn_1 (word0, gen_highpart (SImode, operands[1])); | |
8025 | emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1])); | |
8026 | DONE; | |
8027 | }) | |
8028 | ||
30386ca0 | 8029 | (define_split |
8030 | [(set (match_operand:VM64 0 "register_operand" "") | |
8031 | (match_operand:VM64 1 "register_operand" ""))] | |
8032 | "reload_completed | |
8033 | && TARGET_VIS | |
8034 | && ! TARGET_ARCH64 | |
8035 | && sparc_split_regreg_legitimate (operands[0], operands[1])" | |
8036 | [(clobber (const_int 0))] | |
8037 | { | |
8038 | rtx set_dest = operands[0]; | |
8039 | rtx set_src = operands[1]; | |
8040 | rtx dest1, dest2; | |
8041 | rtx src1, src2; | |
8042 | ||
8043 | dest1 = gen_highpart (SImode, set_dest); | |
8044 | dest2 = gen_lowpart (SImode, set_dest); | |
8045 | src1 = gen_highpart (SImode, set_src); | |
8046 | src2 = gen_lowpart (SImode, set_src); | |
8047 | ||
8048 | /* Now emit using the real source and destination we found, swapping | |
8049 | the order if we detect overlap. */ | |
8050 | if (reg_overlap_mentioned_p (dest1, src2)) | |
8051 | { | |
8052 | emit_insn (gen_movsi (dest2, src2)); | |
8053 | emit_insn (gen_movsi (dest1, src1)); | |
8054 | } | |
8055 | else | |
8056 | { | |
8057 | emit_insn (gen_movsi (dest1, src1)); | |
8058 | emit_insn (gen_movsi (dest2, src2)); | |
8059 | } | |
8060 | DONE; | |
8061 | }) | |
8062 | ||
bc963728 | 8063 | (define_expand "vec_init<mode>" |
8064 | [(match_operand:VMALL 0 "register_operand" "") | |
8065 | (match_operand:VMALL 1 "" "")] | |
8066 | "TARGET_VIS" | |
8067 | { | |
8068 | sparc_expand_vector_init (operands[0], operands[1]); | |
8069 | DONE; | |
8070 | }) | |
8071 | ||
216010d3 | 8072 | (define_code_iterator plusminus [plus minus]) |
8073 | (define_code_attr plusminus_insn [(plus "add") (minus "sub")]) | |
f9545184 | 8074 | |
bc963728 | 8075 | (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI]) |
8076 | ||
8077 | (define_insn "<plusminus_insn><mode>3" | |
8078 | [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>") | |
8079 | (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>") | |
8080 | (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))] | |
f9545184 | 8081 | "TARGET_VIS" |
bc963728 | 8082 | "fp<plusminus_insn><vbits>\t%1, %2, %0" |
f9545184 | 8083 | [(set_attr "type" "fga") |
bc963728 | 8084 | (set_attr "fptype" "<vfptype>")]) |
8085 | ||
8086 | (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI]) | |
8087 | (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s") | |
8088 | (V1DI "") (V2SI "") (V4HI "") (V8QI "")]) | |
8089 | (define_code_iterator vlop [ior and xor]) | |
8090 | (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")]) | |
8091 | (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")]) | |
8092 | ||
8093 | (define_insn "<code><mode>3" | |
8094 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8095 | (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>") | |
8096 | (match_operand:VL 2 "register_operand" "<vconstr>")))] | |
8097 | "TARGET_VIS" | |
8098 | "f<vlinsn><vlsuf>\t%1, %2, %0" | |
d3cb8b93 | 8099 | [(set_attr "type" "visl") |
bc963728 | 8100 | (set_attr "fptype" "<vfptype>")]) |
f9545184 | 8101 | |
bc963728 | 8102 | (define_insn "*not_<code><mode>3" |
8103 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8104 | (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>") | |
8105 | (match_operand:VL 2 "register_operand" "<vconstr>"))))] | |
f9545184 | 8106 | "TARGET_VIS" |
bc963728 | 8107 | "f<vlninsn><vlsuf>\t%1, %2, %0" |
d3cb8b93 | 8108 | [(set_attr "type" "visl") |
bc963728 | 8109 | (set_attr "fptype" "<vfptype>")]) |
f9545184 | 8110 | |
bc963728 | 8111 | ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND. |
8112 | (define_insn "*nand<mode>_vis" | |
8113 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8114 | (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")) | |
8115 | (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))] | |
f9545184 | 8116 | "TARGET_VIS" |
bc963728 | 8117 | "fnand<vlsuf>\t%1, %2, %0" |
d3cb8b93 | 8118 | [(set_attr "type" "visl") |
bc963728 | 8119 | (set_attr "fptype" "<vfptype>")]) |
690f1a75 | 8120 | |
bc963728 | 8121 | (define_code_iterator vlnotop [ior and]) |
690f1a75 | 8122 | |
bc963728 | 8123 | (define_insn "*<code>_not1<mode>_vis" |
8124 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8125 | (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")) | |
8126 | (match_operand:VL 2 "register_operand" "<vconstr>")))] | |
8127 | "TARGET_VIS" | |
8128 | "f<vlinsn>not1<vlsuf>\t%1, %2, %0" | |
d3cb8b93 | 8129 | [(set_attr "type" "visl") |
bc963728 | 8130 | (set_attr "fptype" "<vfptype>")]) |
690f1a75 | 8131 | |
bc963728 | 8132 | (define_insn "*<code>_not2<mode>_vis" |
8133 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8134 | (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>") | |
8135 | (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))] | |
690f1a75 | 8136 | "TARGET_VIS" |
bc963728 | 8137 | "f<vlinsn>not2<vlsuf>\t%1, %2, %0" |
d3cb8b93 | 8138 | [(set_attr "type" "visl") |
bc963728 | 8139 | (set_attr "fptype" "<vfptype>")]) |
690f1a75 | 8140 | |
bc963728 | 8141 | (define_insn "one_cmpl<mode>2" |
8142 | [(set (match_operand:VL 0 "register_operand" "=<vconstr>") | |
8143 | (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))] | |
690f1a75 | 8144 | "TARGET_VIS" |
bc963728 | 8145 | "fnot1<vlsuf>\t%1, %0" |
d3cb8b93 | 8146 | [(set_attr "type" "visl") |
bc963728 | 8147 | (set_attr "fptype" "<vfptype>")]) |
5e8cda9b | 8148 | |
8149 | ;; Hard to generate VIS instructions. We have builtins for these. | |
8150 | ||
8151 | (define_insn "fpack16_vis" | |
8152 | [(set (match_operand:V4QI 0 "register_operand" "=f") | |
5b160e35 | 8153 | (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e") |
8154 | (reg:DI GSR_REG)] | |
8155 | UNSPEC_FPACK16))] | |
5e8cda9b | 8156 | "TARGET_VIS" |
8157 | "fpack16\t%1, %0" | |
cd7e5042 | 8158 | [(set_attr "type" "fgm_pack") |
5e8cda9b | 8159 | (set_attr "fptype" "double")]) |
8160 | ||
8161 | (define_insn "fpackfix_vis" | |
8162 | [(set (match_operand:V2HI 0 "register_operand" "=f") | |
5b160e35 | 8163 | (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e") |
8164 | (reg:DI GSR_REG)] | |
8165 | UNSPEC_FPACKFIX))] | |
5e8cda9b | 8166 | "TARGET_VIS" |
8167 | "fpackfix\t%1, %0" | |
cd7e5042 | 8168 | [(set_attr "type" "fgm_pack") |
5e8cda9b | 8169 | (set_attr "fptype" "double")]) |
8170 | ||
8171 | (define_insn "fpack32_vis" | |
8172 | [(set (match_operand:V8QI 0 "register_operand" "=e") | |
8173 | (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e") | |
5b160e35 | 8174 | (match_operand:V8QI 2 "register_operand" "e") |
8175 | (reg:DI GSR_REG)] | |
8176 | UNSPEC_FPACK32))] | |
5e8cda9b | 8177 | "TARGET_VIS" |
8178 | "fpack32\t%1, %2, %0" | |
cd7e5042 | 8179 | [(set_attr "type" "fgm_pack") |
5e8cda9b | 8180 | (set_attr "fptype" "double")]) |
8181 | ||
8182 | (define_insn "fexpand_vis" | |
8183 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8184 | (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")] | |
8185 | UNSPEC_FEXPAND))] | |
8186 | "TARGET_VIS" | |
8187 | "fexpand\t%1, %0" | |
8188 | [(set_attr "type" "fga") | |
8189 | (set_attr "fptype" "double")]) | |
8190 | ||
5e8cda9b | 8191 | (define_insn "fpmerge_vis" |
8192 | [(set (match_operand:V8QI 0 "register_operand" "=e") | |
beb1857f | 8193 | (vec_select:V8QI |
8194 | (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f") | |
8195 | (match_operand:V4QI 2 "register_operand" "f")) | |
8196 | (parallel [(const_int 0) (const_int 4) | |
8197 | (const_int 1) (const_int 5) | |
8198 | (const_int 2) (const_int 6) | |
8199 | (const_int 3) (const_int 7)])))] | |
5e8cda9b | 8200 | "TARGET_VIS" |
8201 | "fpmerge\t%1, %2, %0" | |
8202 | [(set_attr "type" "fga") | |
8203 | (set_attr "fptype" "double")]) | |
8204 | ||
beb1857f | 8205 | (define_insn "vec_interleave_lowv8qi" |
8206 | [(set (match_operand:V8QI 0 "register_operand" "=e") | |
8207 | (vec_select:V8QI | |
8208 | (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f") | |
8209 | (match_operand:V8QI 2 "register_operand" "f")) | |
8210 | (parallel [(const_int 0) (const_int 8) | |
8211 | (const_int 1) (const_int 9) | |
8212 | (const_int 2) (const_int 10) | |
8213 | (const_int 3) (const_int 11)])))] | |
8214 | "TARGET_VIS" | |
8215 | "fpmerge\t%L1, %L2, %0" | |
8216 | [(set_attr "type" "fga") | |
8217 | (set_attr "fptype" "double")]) | |
8218 | ||
8219 | (define_insn "vec_interleave_highv8qi" | |
8220 | [(set (match_operand:V8QI 0 "register_operand" "=e") | |
8221 | (vec_select:V8QI | |
8222 | (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f") | |
8223 | (match_operand:V8QI 2 "register_operand" "f")) | |
8224 | (parallel [(const_int 4) (const_int 12) | |
8225 | (const_int 5) (const_int 13) | |
8226 | (const_int 6) (const_int 14) | |
8227 | (const_int 7) (const_int 15)])))] | |
8228 | "TARGET_VIS" | |
8229 | "fpmerge\t%H1, %H2, %0" | |
8230 | [(set_attr "type" "fga") | |
8231 | (set_attr "fptype" "double")]) | |
8232 | ||
5e8cda9b | 8233 | ;; Partitioned multiply instructions |
8234 | (define_insn "fmul8x16_vis" | |
8235 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
beb1857f | 8236 | (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") |
8237 | (match_operand:V4HI 2 "register_operand" "e")] | |
8238 | UNSPEC_MUL8))] | |
5e8cda9b | 8239 | "TARGET_VIS" |
8240 | "fmul8x16\t%1, %2, %0" | |
cd7e5042 | 8241 | [(set_attr "type" "fgm_mul") |
5e8cda9b | 8242 | (set_attr "fptype" "double")]) |
8243 | ||
5e8cda9b | 8244 | (define_insn "fmul8x16au_vis" |
8245 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
beb1857f | 8246 | (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") |
8247 | (match_operand:V2HI 2 "register_operand" "f")] | |
8248 | UNSPEC_MUL16AU))] | |
5e8cda9b | 8249 | "TARGET_VIS" |
8250 | "fmul8x16au\t%1, %2, %0" | |
cd7e5042 | 8251 | [(set_attr "type" "fgm_mul") |
5e8cda9b | 8252 | (set_attr "fptype" "double")]) |
8253 | ||
8254 | (define_insn "fmul8x16al_vis" | |
8255 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8256 | (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") | |
8257 | (match_operand:V2HI 2 "register_operand" "f")] | |
8258 | UNSPEC_MUL16AL))] | |
8259 | "TARGET_VIS" | |
8260 | "fmul8x16al\t%1, %2, %0" | |
cd7e5042 | 8261 | [(set_attr "type" "fgm_mul") |
5e8cda9b | 8262 | (set_attr "fptype" "double")]) |
8263 | ||
5e8cda9b | 8264 | (define_insn "fmul8sux16_vis" |
8265 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
beb1857f | 8266 | (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e") |
8267 | (match_operand:V4HI 2 "register_operand" "e")] | |
8268 | UNSPEC_MUL8SU))] | |
5e8cda9b | 8269 | "TARGET_VIS" |
8270 | "fmul8sux16\t%1, %2, %0" | |
cd7e5042 | 8271 | [(set_attr "type" "fgm_mul") |
5e8cda9b | 8272 | (set_attr "fptype" "double")]) |
8273 | ||
8274 | (define_insn "fmul8ulx16_vis" | |
8275 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8276 | (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e") | |
8277 | (match_operand:V4HI 2 "register_operand" "e")] | |
8278 | UNSPEC_MUL8UL))] | |
8279 | "TARGET_VIS" | |
8280 | "fmul8ulx16\t%1, %2, %0" | |
cd7e5042 | 8281 | [(set_attr "type" "fgm_mul") |
5e8cda9b | 8282 | (set_attr "fptype" "double")]) |
8283 | ||
5e8cda9b | 8284 | (define_insn "fmuld8sux16_vis" |
8285 | [(set (match_operand:V2SI 0 "register_operand" "=e") | |
beb1857f | 8286 | (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f") |
8287 | (match_operand:V2HI 2 "register_operand" "f")] | |
8288 | UNSPEC_MULDSU))] | |
5e8cda9b | 8289 | "TARGET_VIS" |
8290 | "fmuld8sux16\t%1, %2, %0" | |
cd7e5042 | 8291 | [(set_attr "type" "fgm_mul") |
5e8cda9b | 8292 | (set_attr "fptype" "double")]) |
8293 | ||
8294 | (define_insn "fmuld8ulx16_vis" | |
8295 | [(set (match_operand:V2SI 0 "register_operand" "=e") | |
8296 | (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f") | |
8297 | (match_operand:V2HI 2 "register_operand" "f")] | |
8298 | UNSPEC_MULDUL))] | |
8299 | "TARGET_VIS" | |
8300 | "fmuld8ulx16\t%1, %2, %0" | |
cd7e5042 | 8301 | [(set_attr "type" "fgm_mul") |
5e8cda9b | 8302 | (set_attr "fptype" "double")]) |
8303 | ||
b011bbe2 | 8304 | (define_expand "wrgsr_vis" |
8ec7259a | 8305 | [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))] |
b011bbe2 | 8306 | "TARGET_VIS" |
8307 | { | |
8308 | if (! TARGET_ARCH64) | |
8309 | { | |
8310 | emit_insn (gen_wrgsr_v8plus (operands[0])); | |
8311 | DONE; | |
8312 | } | |
8313 | }) | |
8314 | ||
8315 | (define_insn "*wrgsr_sp64" | |
8ec7259a | 8316 | [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))] |
b011bbe2 | 8317 | "TARGET_VIS && TARGET_ARCH64" |
8318 | "wr\t%%g0, %0, %%gsr" | |
8319 | [(set_attr "type" "gsr")]) | |
8320 | ||
8321 | (define_insn "wrgsr_v8plus" | |
8ec7259a | 8322 | [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r")) |
b011bbe2 | 8323 | (clobber (match_scratch:SI 1 "=X,&h"))] |
8324 | "TARGET_VIS && ! TARGET_ARCH64" | |
8325 | { | |
8326 | if (GET_CODE (operands[0]) == CONST_INT | |
8327 | || sparc_check_64 (operands[0], insn)) | |
8328 | return "wr\t%%g0, %0, %%gsr"; | |
8329 | ||
8330 | output_asm_insn("srl\t%L0, 0, %L0", operands); | |
8331 | return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr"; | |
8332 | } | |
8333 | [(set_attr "type" "multi")]) | |
8334 | ||
8335 | (define_expand "rdgsr_vis" | |
8336 | [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))] | |
8337 | "TARGET_VIS" | |
8338 | { | |
8339 | if (! TARGET_ARCH64) | |
8340 | { | |
8341 | emit_insn (gen_rdgsr_v8plus (operands[0])); | |
8342 | DONE; | |
8343 | } | |
8344 | }) | |
8345 | ||
8346 | (define_insn "*rdgsr_sp64" | |
8347 | [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))] | |
8348 | "TARGET_VIS && TARGET_ARCH64" | |
8349 | "rd\t%%gsr, %0" | |
8350 | [(set_attr "type" "gsr")]) | |
8351 | ||
8352 | (define_insn "rdgsr_v8plus" | |
8353 | [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG)) | |
8354 | (clobber (match_scratch:SI 1 "=&h"))] | |
8355 | "TARGET_VIS && ! TARGET_ARCH64" | |
8356 | { | |
8357 | return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0"; | |
8358 | } | |
8359 | [(set_attr "type" "multi")]) | |
8360 | ||
5e8cda9b | 8361 | ;; Using faligndata only makes sense after an alignaddr since the choice of |
442e3cb9 | 8362 | ;; bytes to take out of each operand is dependent on the results of the last |
5e8cda9b | 8363 | ;; alignaddr. |
bc963728 | 8364 | (define_insn "faligndata<VM64:mode>_vis" |
8365 | [(set (match_operand:VM64 0 "register_operand" "=e") | |
8366 | (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e") | |
8367 | (match_operand:VM64 2 "register_operand" "e") | |
5b160e35 | 8368 | (reg:DI GSR_REG)] |
8369 | UNSPEC_ALIGNDATA))] | |
5e8cda9b | 8370 | "TARGET_VIS" |
8371 | "faligndata\t%1, %2, %0" | |
8372 | [(set_attr "type" "fga") | |
8373 | (set_attr "fptype" "double")]) | |
8374 | ||
b011bbe2 | 8375 | (define_insn "alignaddrsi_vis" |
8376 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8377 | (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
8378 | (match_operand:SI 2 "register_or_zero_operand" "rJ"))) | |
5b160e35 | 8379 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) |
8380 | (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] | |
5e8cda9b | 8381 | "TARGET_VIS" |
cd7e5042 | 8382 | "alignaddr\t%r1, %r2, %0" |
8383 | [(set_attr "type" "gsr")]) | |
5e8cda9b | 8384 | |
b011bbe2 | 8385 | (define_insn "alignaddrdi_vis" |
8386 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8387 | (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") | |
8388 | (match_operand:DI 2 "register_or_zero_operand" "rJ"))) | |
5b160e35 | 8389 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) |
8390 | (plus:DI (match_dup 1) (match_dup 2)))] | |
b011bbe2 | 8391 | "TARGET_VIS" |
cd7e5042 | 8392 | "alignaddr\t%r1, %r2, %0" |
8393 | [(set_attr "type" "gsr")]) | |
b011bbe2 | 8394 | |
8395 | (define_insn "alignaddrlsi_vis" | |
8396 | [(set (match_operand:SI 0 "register_operand" "=r") | |
8397 | (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") | |
8398 | (match_operand:SI 2 "register_or_zero_operand" "rJ"))) | |
5b160e35 | 8399 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) |
8400 | (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))) | |
8401 | (const_int 7)))] | |
b011bbe2 | 8402 | "TARGET_VIS" |
cd7e5042 | 8403 | "alignaddrl\t%r1, %r2, %0" |
8404 | [(set_attr "type" "gsr")]) | |
b011bbe2 | 8405 | |
8406 | (define_insn "alignaddrldi_vis" | |
8407 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8408 | (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") | |
8409 | (match_operand:DI 2 "register_or_zero_operand" "rJ"))) | |
5b160e35 | 8410 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) |
8411 | (xor:DI (plus:DI (match_dup 1) (match_dup 2)) | |
8412 | (const_int 7)))] | |
4e3a6159 | 8413 | "TARGET_VIS" |
cd7e5042 | 8414 | "alignaddrl\t%r1, %r2, %0" |
8415 | [(set_attr "type" "gsr")]) | |
4e3a6159 | 8416 | |
5e8cda9b | 8417 | (define_insn "pdist_vis" |
8418 | [(set (match_operand:DI 0 "register_operand" "=e") | |
8419 | (unspec:DI [(match_operand:V8QI 1 "register_operand" "e") | |
8420 | (match_operand:V8QI 2 "register_operand" "e") | |
8421 | (match_operand:DI 3 "register_operand" "0")] | |
8422 | UNSPEC_PDIST))] | |
8423 | "TARGET_VIS" | |
8424 | "pdist\t%1, %2, %0" | |
d3cb8b93 | 8425 | [(set_attr "type" "pdist") |
5e8cda9b | 8426 | (set_attr "fptype" "double")]) |
6c6e47a5 | 8427 | |
010db245 | 8428 | ;; Edge instructions produce condition codes equivalent to a 'subcc' |
8429 | ;; with the same operands. | |
4e3a6159 | 8430 | (define_insn "edge8<P:mode>_vis" |
2b25173f | 8431 | [(set (reg:CC_NOOV CC_REG) |
d510308a | 8432 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8433 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
4e3a6159 | 8434 | (const_int 0))) |
faa087bb | 8435 | (set (match_operand:P 0 "register_operand" "=r") |
8436 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))] | |
010db245 | 8437 | "TARGET_VIS" |
8438 | "edge8\t%r1, %r2, %0" | |
8439 | [(set_attr "type" "edge")]) | |
8440 | ||
4e3a6159 | 8441 | (define_insn "edge8l<P:mode>_vis" |
2b25173f | 8442 | [(set (reg:CC_NOOV CC_REG) |
d510308a | 8443 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8444 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
4e3a6159 | 8445 | (const_int 0))) |
faa087bb | 8446 | (set (match_operand:P 0 "register_operand" "=r") |
8447 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))] | |
010db245 | 8448 | "TARGET_VIS" |
8449 | "edge8l\t%r1, %r2, %0" | |
8450 | [(set_attr "type" "edge")]) | |
8451 | ||
4e3a6159 | 8452 | (define_insn "edge16<P:mode>_vis" |
2b25173f | 8453 | [(set (reg:CC_NOOV CC_REG) |
d510308a | 8454 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8455 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
4e3a6159 | 8456 | (const_int 0))) |
faa087bb | 8457 | (set (match_operand:P 0 "register_operand" "=r") |
8458 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))] | |
010db245 | 8459 | "TARGET_VIS" |
8460 | "edge16\t%r1, %r2, %0" | |
8461 | [(set_attr "type" "edge")]) | |
8462 | ||
4e3a6159 | 8463 | (define_insn "edge16l<P:mode>_vis" |
2b25173f | 8464 | [(set (reg:CC_NOOV CC_REG) |
d510308a | 8465 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8466 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
4e3a6159 | 8467 | (const_int 0))) |
faa087bb | 8468 | (set (match_operand:P 0 "register_operand" "=r") |
8469 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))] | |
010db245 | 8470 | "TARGET_VIS" |
8471 | "edge16l\t%r1, %r2, %0" | |
8472 | [(set_attr "type" "edge")]) | |
8473 | ||
4e3a6159 | 8474 | (define_insn "edge32<P:mode>_vis" |
2b25173f | 8475 | [(set (reg:CC_NOOV CC_REG) |
d510308a | 8476 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8477 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
4e3a6159 | 8478 | (const_int 0))) |
faa087bb | 8479 | (set (match_operand:P 0 "register_operand" "=r") |
8480 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))] | |
010db245 | 8481 | "TARGET_VIS" |
8482 | "edge32\t%r1, %r2, %0" | |
8483 | [(set_attr "type" "edge")]) | |
8484 | ||
4e3a6159 | 8485 | (define_insn "edge32l<P:mode>_vis" |
2b25173f | 8486 | [(set (reg:CC_NOOV CC_REG) |
d510308a | 8487 | (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") |
8488 | (match_operand:P 2 "register_or_zero_operand" "rJ")) | |
4e3a6159 | 8489 | (const_int 0))) |
faa087bb | 8490 | (set (match_operand:P 0 "register_operand" "=r") |
8491 | (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))] | |
010db245 | 8492 | "TARGET_VIS" |
8493 | "edge32l\t%r1, %r2, %0" | |
8494 | [(set_attr "type" "edge")]) | |
8495 | ||
1e5d768e | 8496 | (define_code_iterator gcond [le ne gt eq]) |
1e5d768e | 8497 | (define_mode_iterator GCM [V4HI V2SI]) |
8498 | (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")]) | |
7228aca8 | 8499 | |
6919b5e5 | 8500 | (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis" |
faa087bb | 8501 | [(set (match_operand:P 0 "register_operand" "=r") |
1e5d768e | 8502 | (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e") |
8503 | (match_operand:GCM 2 "register_operand" "e"))] | |
8504 | UNSPEC_FCMP))] | |
7228aca8 | 8505 | "TARGET_VIS" |
6919b5e5 | 8506 | "fcmp<code><GCM:gcm_name>\t%1, %2, %0" |
d3cb8b93 | 8507 | [(set_attr "type" "visl") |
7228aca8 | 8508 | (set_attr "fptype" "double")]) |
8509 | ||
efa273f5 | 8510 | (define_expand "vcond<mode><mode>" |
8511 | [(match_operand:GCM 0 "register_operand" "") | |
8512 | (match_operand:GCM 1 "register_operand" "") | |
8513 | (match_operand:GCM 2 "register_operand" "") | |
8514 | (match_operator 3 "" | |
8515 | [(match_operand:GCM 4 "register_operand" "") | |
8516 | (match_operand:GCM 5 "register_operand" "")])] | |
8517 | "TARGET_VIS3" | |
8518 | { | |
8519 | sparc_expand_vcond (<MODE>mode, operands, | |
8520 | UNSPEC_CMASK<gcm_name>, | |
8521 | UNSPEC_FCMP); | |
8522 | DONE; | |
8523 | }) | |
8524 | ||
8525 | (define_expand "vconduv8qiv8qi" | |
8526 | [(match_operand:V8QI 0 "register_operand" "") | |
8527 | (match_operand:V8QI 1 "register_operand" "") | |
8528 | (match_operand:V8QI 2 "register_operand" "") | |
8529 | (match_operator 3 "" | |
8530 | [(match_operand:V8QI 4 "register_operand" "") | |
8531 | (match_operand:V8QI 5 "register_operand" "")])] | |
8532 | "TARGET_VIS3" | |
8533 | { | |
8534 | sparc_expand_vcond (V8QImode, operands, | |
8535 | UNSPEC_CMASK8, | |
8536 | UNSPEC_FUCMP); | |
8537 | DONE; | |
8538 | }) | |
8539 | ||
386d043d | 8540 | (define_insn "array8<P:mode>_vis" |
8541 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8542 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8543 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
386d043d | 8544 | UNSPEC_ARRAY8))] |
8545 | "TARGET_VIS" | |
8546 | "array8\t%r1, %r2, %0" | |
8547 | [(set_attr "type" "array")]) | |
8548 | ||
8549 | (define_insn "array16<P:mode>_vis" | |
8550 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8551 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8552 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
386d043d | 8553 | UNSPEC_ARRAY16))] |
8554 | "TARGET_VIS" | |
8555 | "array16\t%r1, %r2, %0" | |
8556 | [(set_attr "type" "array")]) | |
8557 | ||
8558 | (define_insn "array32<P:mode>_vis" | |
8559 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8560 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8561 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
386d043d | 8562 | UNSPEC_ARRAY32))] |
8563 | "TARGET_VIS" | |
8564 | "array32\t%r1, %r2, %0" | |
8565 | [(set_attr "type" "array")]) | |
8566 | ||
6e122c86 | 8567 | (define_insn "bmaskdi_vis" |
8568 | [(set (match_operand:DI 0 "register_operand" "=r") | |
d510308a | 8569 | (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") |
8570 | (match_operand:DI 2 "register_or_zero_operand" "rJ"))) | |
6e122c86 | 8571 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32)) |
8572 | (plus:DI (match_dup 1) (match_dup 2)))] | |
8573 | "TARGET_VIS2" | |
8574 | "bmask\t%r1, %r2, %0" | |
8575 | [(set_attr "type" "array")]) | |
8576 | ||
8577 | (define_insn "bmasksi_vis" | |
8578 | [(set (match_operand:SI 0 "register_operand" "=r") | |
d510308a | 8579 | (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") |
8580 | (match_operand:SI 2 "register_or_zero_operand" "rJ"))) | |
6e122c86 | 8581 | (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32)) |
8582 | (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] | |
95c09f2c | 8583 | "TARGET_VIS2" |
8584 | "bmask\t%r1, %r2, %0" | |
8585 | [(set_attr "type" "array")]) | |
8586 | ||
bc963728 | 8587 | (define_insn "bshuffle<VM64:mode>_vis" |
8588 | [(set (match_operand:VM64 0 "register_operand" "=e") | |
8589 | (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e") | |
8590 | (match_operand:VM64 2 "register_operand" "e") | |
5b160e35 | 8591 | (reg:DI GSR_REG)] |
6e122c86 | 8592 | UNSPEC_BSHUFFLE))] |
95c09f2c | 8593 | "TARGET_VIS2" |
8594 | "bshuffle\t%1, %2, %0" | |
8595 | [(set_attr "type" "fga") | |
8596 | (set_attr "fptype" "double")]) | |
8597 | ||
05d36c46 | 8598 | ;; The rtl expanders will happily convert constant permutations on other |
8599 | ;; modes down to V8QI. Rely on this to avoid the complexity of the byte | |
8600 | ;; order of the permutation. | |
8601 | (define_expand "vec_perm_constv8qi" | |
8602 | [(match_operand:V8QI 0 "register_operand" "") | |
8603 | (match_operand:V8QI 1 "register_operand" "") | |
8604 | (match_operand:V8QI 2 "register_operand" "") | |
8605 | (match_operand:V8QI 3 "" "")] | |
8606 | "TARGET_VIS2" | |
8607 | { | |
8608 | unsigned int i, mask; | |
8609 | rtx sel = operands[3]; | |
8610 | ||
8611 | for (i = mask = 0; i < 8; ++i) | |
8612 | mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4); | |
8613 | sel = force_reg (SImode, gen_int_mode (mask, SImode)); | |
8614 | ||
65c294e9 | 8615 | emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx)); |
05d36c46 | 8616 | emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2])); |
8617 | DONE; | |
8618 | }) | |
8619 | ||
8620 | ;; Unlike constant permutation, we can vastly simplify the compression of | |
8621 | ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the | |
8622 | ;; width of the input is. | |
8623 | (define_expand "vec_perm<mode>" | |
8624 | [(match_operand:VM64 0 "register_operand" "") | |
8625 | (match_operand:VM64 1 "register_operand" "") | |
8626 | (match_operand:VM64 2 "register_operand" "") | |
8627 | (match_operand:VM64 3 "register_operand" "")] | |
8628 | "TARGET_VIS2" | |
8629 | { | |
8630 | sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]); | |
8631 | emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2])); | |
8632 | DONE; | |
8633 | }) | |
8634 | ||
95c09f2c | 8635 | ;; VIS 2.0 adds edge variants which do not set the condition codes |
8636 | (define_insn "edge8n<P:mode>_vis" | |
8637 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8638 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8639 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
95c09f2c | 8640 | UNSPEC_EDGE8N))] |
8641 | "TARGET_VIS2" | |
8642 | "edge8n\t%r1, %r2, %0" | |
8643 | [(set_attr "type" "edgen")]) | |
8644 | ||
8645 | (define_insn "edge8ln<P:mode>_vis" | |
8646 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8647 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8648 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
95c09f2c | 8649 | UNSPEC_EDGE8LN))] |
8650 | "TARGET_VIS2" | |
8651 | "edge8ln\t%r1, %r2, %0" | |
8652 | [(set_attr "type" "edgen")]) | |
8653 | ||
8654 | (define_insn "edge16n<P:mode>_vis" | |
8655 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8656 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8657 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
95c09f2c | 8658 | UNSPEC_EDGE16N))] |
8659 | "TARGET_VIS2" | |
8660 | "edge16n\t%r1, %r2, %0" | |
8661 | [(set_attr "type" "edgen")]) | |
8662 | ||
8663 | (define_insn "edge16ln<P:mode>_vis" | |
8664 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8665 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8666 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
95c09f2c | 8667 | UNSPEC_EDGE16LN))] |
8668 | "TARGET_VIS2" | |
8669 | "edge16ln\t%r1, %r2, %0" | |
8670 | [(set_attr "type" "edgen")]) | |
8671 | ||
8672 | (define_insn "edge32n<P:mode>_vis" | |
8673 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8674 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8675 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
95c09f2c | 8676 | UNSPEC_EDGE32N))] |
8677 | "TARGET_VIS2" | |
8678 | "edge32n\t%r1, %r2, %0" | |
8679 | [(set_attr "type" "edgen")]) | |
8680 | ||
8681 | (define_insn "edge32ln<P:mode>_vis" | |
8682 | [(set (match_operand:P 0 "register_operand" "=r") | |
d510308a | 8683 | (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") |
8684 | (match_operand:P 2 "register_or_zero_operand" "rJ")] | |
95c09f2c | 8685 | UNSPEC_EDGE32LN))] |
8686 | "TARGET_VIS2" | |
8687 | "edge32ln\t%r1, %r2, %0" | |
8688 | [(set_attr "type" "edge")]) | |
8689 | ||
33e7b55c | 8690 | ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle |
8691 | (define_insn "cmask8<P:mode>_vis" | |
8692 | [(set (reg:DI GSR_REG) | |
9eb6eca9 | 8693 | (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") |
33e7b55c | 8694 | (reg:DI GSR_REG)] |
8695 | UNSPEC_CMASK8))] | |
8696 | "TARGET_VIS3" | |
cd7e5042 | 8697 | "cmask8\t%r0" |
8698 | [(set_attr "type" "fga")]) | |
33e7b55c | 8699 | |
8700 | (define_insn "cmask16<P:mode>_vis" | |
8701 | [(set (reg:DI GSR_REG) | |
9eb6eca9 | 8702 | (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") |
33e7b55c | 8703 | (reg:DI GSR_REG)] |
8704 | UNSPEC_CMASK16))] | |
8705 | "TARGET_VIS3" | |
cd7e5042 | 8706 | "cmask16\t%r0" |
8707 | [(set_attr "type" "fga")]) | |
33e7b55c | 8708 | |
8709 | (define_insn "cmask32<P:mode>_vis" | |
8710 | [(set (reg:DI GSR_REG) | |
9eb6eca9 | 8711 | (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") |
33e7b55c | 8712 | (reg:DI GSR_REG)] |
8713 | UNSPEC_CMASK32))] | |
8714 | "TARGET_VIS3" | |
cd7e5042 | 8715 | "cmask32\t%r0" |
8716 | [(set_attr "type" "fga")]) | |
33e7b55c | 8717 | |
8718 | (define_insn "fchksm16_vis" | |
8719 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8720 | (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e") | |
8721 | (match_operand:V4HI 2 "register_operand" "e")] | |
8722 | UNSPEC_FCHKSM16))] | |
8723 | "TARGET_VIS3" | |
cd7e5042 | 8724 | "fchksm16\t%1, %2, %0" |
8725 | [(set_attr "type" "fga")]) | |
33e7b55c | 8726 | |
8727 | (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt]) | |
8728 | (define_code_attr vis3_shift_insn | |
8729 | [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")]) | |
beb1857f | 8730 | (define_code_attr vis3_shift_patname |
8731 | [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")]) | |
33e7b55c | 8732 | |
beb1857f | 8733 | (define_insn "v<vis3_shift_patname><mode>3" |
bc963728 | 8734 | [(set (match_operand:GCM 0 "register_operand" "=<vconstr>") |
8735 | (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>") | |
8736 | (match_operand:GCM 2 "register_operand" "<vconstr>")))] | |
33e7b55c | 8737 | "TARGET_VIS3" |
cd7e5042 | 8738 | "<vis3_shift_insn><vbits>\t%1, %2, %0" |
8739 | [(set_attr "type" "fga")]) | |
33e7b55c | 8740 | |
8741 | (define_insn "pdistn<mode>_vis" | |
8742 | [(set (match_operand:P 0 "register_operand" "=r") | |
8743 | (unspec:P [(match_operand:V8QI 1 "register_operand" "e") | |
8744 | (match_operand:V8QI 2 "register_operand" "e")] | |
8745 | UNSPEC_PDISTN))] | |
8746 | "TARGET_VIS3" | |
cd7e5042 | 8747 | "pdistn\t%1, %2, %0" |
d3cb8b93 | 8748 | [(set_attr "type" "pdistn") |
cd7e5042 | 8749 | (set_attr "fptype" "double")]) |
33e7b55c | 8750 | |
8751 | (define_insn "fmean16_vis" | |
8752 | [(set (match_operand:V4HI 0 "register_operand" "=e") | |
8753 | (truncate:V4HI | |
8754 | (lshiftrt:V4SI | |
8755 | (plus:V4SI | |
8756 | (plus:V4SI | |
8757 | (zero_extend:V4SI | |
8758 | (match_operand:V4HI 1 "register_operand" "e")) | |
8759 | (zero_extend:V4SI | |
8760 | (match_operand:V4HI 2 "register_operand" "e"))) | |
8761 | (const_vector:V4SI [(const_int 1) (const_int 1) | |
8762 | (const_int 1) (const_int 1)])) | |
8763 | (const_int 1))))] | |
8764 | "TARGET_VIS3" | |
cd7e5042 | 8765 | "fmean16\t%1, %2, %0" |
8766 | [(set_attr "type" "fga")]) | |
33e7b55c | 8767 | |
216010d3 | 8768 | (define_insn "fp<plusminus_insn>64_vis" |
bc963728 | 8769 | [(set (match_operand:V1DI 0 "register_operand" "=e") |
8770 | (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e") | |
8771 | (match_operand:V1DI 2 "register_operand" "e")))] | |
33e7b55c | 8772 | "TARGET_VIS3" |
cd7e5042 | 8773 | "fp<plusminus_insn>64\t%1, %2, %0" |
8774 | [(set_attr "type" "fga")]) | |
33e7b55c | 8775 | |
bc963728 | 8776 | (define_mode_iterator VASS [V4HI V2SI V2HI V1SI]) |
33e7b55c | 8777 | (define_code_iterator vis3_addsub_ss [ss_plus ss_minus]) |
8778 | (define_code_attr vis3_addsub_ss_insn | |
8779 | [(ss_plus "fpadds") (ss_minus "fpsubs")]) | |
beb1857f | 8780 | (define_code_attr vis3_addsub_ss_patname |
8781 | [(ss_plus "ssadd") (ss_minus "sssub")]) | |
33e7b55c | 8782 | |
beb1857f | 8783 | (define_insn "<vis3_addsub_ss_patname><mode>3" |
33e7b55c | 8784 | [(set (match_operand:VASS 0 "register_operand" "=<vconstr>") |
8785 | (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>") | |
8786 | (match_operand:VASS 2 "register_operand" "<vconstr>")))] | |
8787 | "TARGET_VIS3" | |
cd7e5042 | 8788 | "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0" |
8789 | [(set_attr "type" "fga")]) | |
33e7b55c | 8790 | |
8791 | (define_insn "fucmp<code>8<P:mode>_vis" | |
8792 | [(set (match_operand:P 0 "register_operand" "=r") | |
8793 | (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e") | |
8794 | (match_operand:V8QI 2 "register_operand" "e"))] | |
8795 | UNSPEC_FUCMP))] | |
8796 | "TARGET_VIS3" | |
cd7e5042 | 8797 | "fucmp<code>8\t%1, %2, %0" |
d3cb8b93 | 8798 | [(set_attr "type" "visl")]) |
33e7b55c | 8799 | |
47cc4525 | 8800 | (define_insn "*naddsf3" |
8801 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8802 | (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f") | |
8803 | (match_operand:SF 2 "register_operand" "f"))))] | |
8804 | "TARGET_VIS3" | |
8805 | "fnadds\t%1, %2, %0" | |
8806 | [(set_attr "type" "fp")]) | |
8807 | ||
8808 | (define_insn "*nadddf3" | |
8809 | [(set (match_operand:DF 0 "register_operand" "=e") | |
8810 | (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e") | |
8811 | (match_operand:DF 2 "register_operand" "e"))))] | |
8812 | "TARGET_VIS3" | |
8813 | "fnaddd\t%1, %2, %0" | |
8814 | [(set_attr "type" "fp") | |
8815 | (set_attr "fptype" "double")]) | |
8816 | ||
8817 | (define_insn "*nmulsf3" | |
8818 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8819 | (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) | |
8820 | (match_operand:SF 2 "register_operand" "f")))] | |
8821 | "TARGET_VIS3" | |
8822 | "fnmuls\t%1, %2, %0" | |
8823 | [(set_attr "type" "fpmul")]) | |
8824 | ||
8825 | (define_insn "*nmuldf3" | |
8826 | [(set (match_operand:DF 0 "register_operand" "=e") | |
8827 | (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e")) | |
8828 | (match_operand:DF 2 "register_operand" "e")))] | |
8829 | "TARGET_VIS3" | |
8830 | "fnmuld\t%1, %2, %0" | |
8831 | [(set_attr "type" "fpmul") | |
8832 | (set_attr "fptype" "double")]) | |
8833 | ||
8834 | (define_insn "*nmuldf3_extend" | |
8835 | [(set (match_operand:DF 0 "register_operand" "=e") | |
8836 | (mult:DF (neg:DF (float_extend:DF | |
8837 | (match_operand:SF 1 "register_operand" "f"))) | |
8838 | (float_extend:DF | |
8839 | (match_operand:SF 2 "register_operand" "f"))))] | |
8840 | "TARGET_VIS3" | |
8841 | "fnsmuld\t%1, %2, %0" | |
8842 | [(set_attr "type" "fpmul") | |
8843 | (set_attr "fptype" "double")]) | |
8844 | ||
8845 | (define_insn "fhaddsf_vis" | |
8846 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8847 | (unspec:SF [(match_operand:SF 1 "register_operand" "f") | |
8848 | (match_operand:SF 2 "register_operand" "f")] | |
8849 | UNSPEC_FHADD))] | |
8850 | "TARGET_VIS3" | |
8851 | "fhadds\t%1, %2, %0" | |
8852 | [(set_attr "type" "fp")]) | |
8853 | ||
8854 | (define_insn "fhadddf_vis" | |
8855 | [(set (match_operand:DF 0 "register_operand" "=f") | |
8856 | (unspec:DF [(match_operand:DF 1 "register_operand" "f") | |
8857 | (match_operand:DF 2 "register_operand" "f")] | |
8858 | UNSPEC_FHADD))] | |
8859 | "TARGET_VIS3" | |
8860 | "fhaddd\t%1, %2, %0" | |
8861 | [(set_attr "type" "fp") | |
8862 | (set_attr "fptype" "double")]) | |
8863 | ||
8864 | (define_insn "fhsubsf_vis" | |
8865 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8866 | (unspec:SF [(match_operand:SF 1 "register_operand" "f") | |
8867 | (match_operand:SF 2 "register_operand" "f")] | |
8868 | UNSPEC_FHSUB))] | |
8869 | "TARGET_VIS3" | |
8870 | "fhsubs\t%1, %2, %0" | |
8871 | [(set_attr "type" "fp")]) | |
8872 | ||
8873 | (define_insn "fhsubdf_vis" | |
8874 | [(set (match_operand:DF 0 "register_operand" "=f") | |
8875 | (unspec:DF [(match_operand:DF 1 "register_operand" "f") | |
8876 | (match_operand:DF 2 "register_operand" "f")] | |
8877 | UNSPEC_FHSUB))] | |
8878 | "TARGET_VIS3" | |
8879 | "fhsubd\t%1, %2, %0" | |
8880 | [(set_attr "type" "fp") | |
8881 | (set_attr "fptype" "double")]) | |
8882 | ||
8883 | (define_insn "fnhaddsf_vis" | |
8884 | [(set (match_operand:SF 0 "register_operand" "=f") | |
8885 | (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f") | |
8886 | (match_operand:SF 2 "register_operand" "f")] | |
8887 | UNSPEC_FHADD)))] | |
8888 | "TARGET_VIS3" | |
8889 | "fnhadds\t%1, %2, %0" | |
8890 | [(set_attr "type" "fp")]) | |
8891 | ||
8892 | (define_insn "fnhadddf_vis" | |
8893 | [(set (match_operand:DF 0 "register_operand" "=f") | |
8894 | (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f") | |
8895 | (match_operand:DF 2 "register_operand" "f")] | |
8896 | UNSPEC_FHADD)))] | |
8897 | "TARGET_VIS3" | |
8898 | "fnhaddd\t%1, %2, %0" | |
8899 | [(set_attr "type" "fp") | |
8900 | (set_attr "fptype" "double")]) | |
8901 | ||
8902 | (define_expand "umulxhi_vis" | |
8903 | [(set (match_operand:DI 0 "register_operand" "") | |
8904 | (truncate:DI | |
8905 | (lshiftrt:TI | |
8906 | (mult:TI (zero_extend:TI | |
8907 | (match_operand:DI 1 "arith_operand" "")) | |
8908 | (zero_extend:TI | |
8909 | (match_operand:DI 2 "arith_operand" ""))) | |
8910 | (const_int 64))))] | |
8911 | "TARGET_VIS3" | |
8912 | { | |
8913 | if (! TARGET_ARCH64) | |
8914 | { | |
8915 | emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2])); | |
8916 | DONE; | |
8917 | } | |
8918 | }) | |
8919 | ||
8920 | (define_insn "*umulxhi_sp64" | |
8921 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8922 | (truncate:DI | |
8923 | (lshiftrt:TI | |
8924 | (mult:TI (zero_extend:TI | |
8925 | (match_operand:DI 1 "arith_operand" "%r")) | |
8926 | (zero_extend:TI | |
8927 | (match_operand:DI 2 "arith_operand" "rI"))) | |
8928 | (const_int 64))))] | |
8929 | "TARGET_VIS3 && TARGET_ARCH64" | |
8930 | "umulxhi\t%1, %2, %0" | |
8931 | [(set_attr "type" "imul")]) | |
8932 | ||
8933 | (define_insn "umulxhi_v8plus" | |
8934 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
8935 | (truncate:DI | |
8936 | (lshiftrt:TI | |
8937 | (mult:TI (zero_extend:TI | |
8938 | (match_operand:DI 1 "arith_operand" "%r,0")) | |
8939 | (zero_extend:TI | |
8940 | (match_operand:DI 2 "arith_operand" "rI,rI"))) | |
8941 | (const_int 64)))) | |
8942 | (clobber (match_scratch:SI 3 "=&h,X")) | |
8943 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
8944 | "TARGET_VIS3 && ! TARGET_ARCH64" | |
8945 | "* return output_v8plus_mult (insn, operands, \"umulxhi\");" | |
8946 | [(set_attr "type" "imul") | |
8947 | (set_attr "length" "9,8")]) | |
8948 | ||
8949 | (define_expand "xmulx_vis" | |
8950 | [(set (match_operand:DI 0 "register_operand" "") | |
8951 | (truncate:DI | |
8952 | (unspec:TI [(zero_extend:TI | |
8953 | (match_operand:DI 1 "arith_operand" "")) | |
8954 | (zero_extend:TI | |
8955 | (match_operand:DI 2 "arith_operand" ""))] | |
8956 | UNSPEC_XMUL)))] | |
8957 | "TARGET_VIS3" | |
8958 | { | |
8959 | if (! TARGET_ARCH64) | |
8960 | { | |
8961 | emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2])); | |
8962 | DONE; | |
8963 | } | |
8964 | }) | |
8965 | ||
8966 | (define_insn "*xmulx_sp64" | |
8967 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8968 | (truncate:DI | |
8969 | (unspec:TI [(zero_extend:TI | |
8970 | (match_operand:DI 1 "arith_operand" "%r")) | |
8971 | (zero_extend:TI | |
8972 | (match_operand:DI 2 "arith_operand" "rI"))] | |
8973 | UNSPEC_XMUL)))] | |
8974 | "TARGET_VIS3 && TARGET_ARCH64" | |
8975 | "xmulx\t%1, %2, %0" | |
8976 | [(set_attr "type" "imul")]) | |
8977 | ||
8978 | (define_insn "xmulx_v8plus" | |
8979 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
8980 | (truncate:DI | |
8981 | (unspec:TI [(zero_extend:TI | |
8982 | (match_operand:DI 1 "arith_operand" "%r,0")) | |
8983 | (zero_extend:TI | |
8984 | (match_operand:DI 2 "arith_operand" "rI,rI"))] | |
8985 | UNSPEC_XMUL))) | |
8986 | (clobber (match_scratch:SI 3 "=&h,X")) | |
8987 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
8988 | "TARGET_VIS3 && ! TARGET_ARCH64" | |
8989 | "* return output_v8plus_mult (insn, operands, \"xmulx\");" | |
8990 | [(set_attr "type" "imul") | |
8991 | (set_attr "length" "9,8")]) | |
8992 | ||
8993 | (define_expand "xmulxhi_vis" | |
8994 | [(set (match_operand:DI 0 "register_operand" "") | |
8995 | (truncate:DI | |
8996 | (lshiftrt:TI | |
8997 | (unspec:TI [(zero_extend:TI | |
8998 | (match_operand:DI 1 "arith_operand" "")) | |
8999 | (zero_extend:TI | |
9000 | (match_operand:DI 2 "arith_operand" ""))] | |
9001 | UNSPEC_XMUL) | |
9002 | (const_int 64))))] | |
9003 | "TARGET_VIS3" | |
9004 | { | |
9005 | if (! TARGET_ARCH64) | |
9006 | { | |
9007 | emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2])); | |
9008 | DONE; | |
9009 | } | |
9010 | }) | |
9011 | ||
9012 | (define_insn "*xmulxhi_sp64" | |
9013 | [(set (match_operand:DI 0 "register_operand" "=r") | |
9014 | (truncate:DI | |
9015 | (lshiftrt:TI | |
9016 | (unspec:TI [(zero_extend:TI | |
9017 | (match_operand:DI 1 "arith_operand" "%r")) | |
9018 | (zero_extend:TI | |
9019 | (match_operand:DI 2 "arith_operand" "rI"))] | |
9020 | UNSPEC_XMUL) | |
9021 | (const_int 64))))] | |
9022 | "TARGET_VIS3 && TARGET_ARCH64" | |
9023 | "xmulxhi\t%1, %2, %0" | |
9024 | [(set_attr "type" "imul")]) | |
9025 | ||
9026 | (define_insn "xmulxhi_v8plus" | |
9027 | [(set (match_operand:DI 0 "register_operand" "=r,h") | |
9028 | (truncate:DI | |
9029 | (lshiftrt:TI | |
9030 | (unspec:TI [(zero_extend:TI | |
9031 | (match_operand:DI 1 "arith_operand" "%r,0")) | |
9032 | (zero_extend:TI | |
9033 | (match_operand:DI 2 "arith_operand" "rI,rI"))] | |
9034 | UNSPEC_XMUL) | |
9035 | (const_int 64)))) | |
9036 | (clobber (match_scratch:SI 3 "=&h,X")) | |
9037 | (clobber (match_scratch:SI 4 "=&h,X"))] | |
9038 | "TARGET_VIS3 && !TARGET_ARCH64" | |
9039 | "* return output_v8plus_mult (insn, operands, \"xmulxhi\");" | |
9040 | [(set_attr "type" "imul") | |
9041 | (set_attr "length" "9,8")]) | |
9042 | ||
6c6e47a5 | 9043 | (include "sync.md") |