]>
Commit | Line | Data |
---|---|---|
d2836273 | 1 | ;; GCC machine description for IA-32 and x86-64. |
36210500 | 2 | ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
e47b7d04 | 3 | ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
4592bdcb | 4 | ;; Free Software Foundation, Inc. |
886c62d1 | 5 | ;; Mostly by William Schelter. |
d2836273 | 6 | ;; x86_64 support added by Jan Hubicka |
e075ae69 | 7 | ;; |
188fc5b5 | 8 | ;; This file is part of GCC. |
e075ae69 | 9 | ;; |
188fc5b5 | 10 | ;; GCC is free software; you can redistribute it and/or modify |
886c62d1 | 11 | ;; it under the terms of the GNU General Public License as published by |
2f83c7d6 | 12 | ;; the Free Software Foundation; either version 3, or (at your option) |
886c62d1 | 13 | ;; any later version. |
e075ae69 | 14 | ;; |
188fc5b5 | 15 | ;; GCC is distributed in the hope that it will be useful, |
886c62d1 JVA |
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ;; GNU General Public License for more details. | |
e075ae69 | 19 | ;; |
886c62d1 | 20 | ;; You should have received a copy of the GNU General Public License |
2f83c7d6 NC |
21 | ;; along with GCC; see the file COPYING3. If not see |
22 | ;; <http://www.gnu.org/licenses/>. */ | |
e075ae69 | 23 | ;; |
4af3895e JVA |
24 | ;; The original PO technology requires these to be ordered by speed, |
25 | ;; so that assigner will pick the fastest. | |
e075ae69 | 26 | ;; |
4af3895e | 27 | ;; See file "rtl.def" for documentation on define_insn, match_*, et. al. |
e075ae69 | 28 | ;; |
e075ae69 | 29 | ;; The special asm out single letter directives following a '%' are: |
a3a5e3d1 UB |
30 | ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand. |
31 | ;; C -- print opcode suffix for set/cmov insn. | |
32 | ;; c -- like C, but print reversed condition | |
33 | ;; E,e -- likewise, but for compare-and-branch fused insn. | |
34 | ;; F,f -- likewise, but for floating-point. | |
35 | ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.", | |
36 | ;; otherwise nothing | |
37 | ;; R -- print the prefix for register names. | |
38 | ;; z -- print the opcode suffix for the size of the current operand. | |
b91322f2 | 39 | ;; Z -- likewise, with special suffixes for x87 instructions. |
a3a5e3d1 UB |
40 | ;; * -- print a star (in certain assembler syntax) |
41 | ;; A -- print an absolute memory reference. | |
42 | ;; w -- print the operand as if it's a "word" (HImode) even if it isn't. | |
43 | ;; s -- print a shift double count, followed by the assemblers argument | |
44 | ;; delimiter. | |
45 | ;; b -- print the QImode name of the register for the indicated operand. | |
46 | ;; %b0 would print %al if operands[0] is reg 0. | |
47 | ;; w -- likewise, print the HImode name of the register. | |
48 | ;; k -- likewise, print the SImode name of the register. | |
49 | ;; q -- likewise, print the DImode name of the register. | |
50 | ;; x -- likewise, print the V4SFmode name of the register. | |
51 | ;; t -- likewise, print the V8SFmode name of the register. | |
52 | ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh. | |
53 | ;; y -- print "st(0)" instead of "st" as a register. | |
54 | ;; d -- print duplicated register operand for AVX instruction. | |
55 | ;; D -- print condition for SSE cmp instruction. | |
56 | ;; P -- if PIC, print an @PLT suffix. | |
57 | ;; X -- don't print any sort of PIC '@' suffix for a symbol. | |
58 | ;; & -- print some in-use local-dynamic symbol name. | |
59 | ;; H -- print a memory address offset by 8; used for sse high-parts | |
60 | ;; Y -- print condition for SSE5 com* instruction. | |
61 | ;; + -- print a branch hint as 'cs' or 'ds' prefix | |
62 | ;; ; -- print a semicolon (after prefixes due to bug in older gas). | |
8ee41eaf | 63 | |
4af3895e | 64 | ;; UNSPEC usage: |
8ee41eaf RH |
65 | |
66 | (define_constants | |
f996902d RH |
67 | [; Relocation specifiers |
68 | (UNSPEC_GOT 0) | |
69 | (UNSPEC_GOTOFF 1) | |
70 | (UNSPEC_GOTPCREL 2) | |
71 | (UNSPEC_GOTTPOFF 3) | |
72 | (UNSPEC_TPOFF 4) | |
73 | (UNSPEC_NTPOFF 5) | |
74 | (UNSPEC_DTPOFF 6) | |
dea73790 JJ |
75 | (UNSPEC_GOTNTPOFF 7) |
76 | (UNSPEC_INDNTPOFF 8) | |
dc4d7240 | 77 | (UNSPEC_PLTOFF 9) |
08a6a74b | 78 | (UNSPEC_MACHOPIC_OFFSET 10) |
f996902d RH |
79 | |
80 | ; Prologue support | |
f996902d RH |
81 | (UNSPEC_STACK_ALLOC 11) |
82 | (UNSPEC_SET_GOT 12) | |
8ee41eaf | 83 | (UNSPEC_SSE_PROLOGUE_SAVE 13) |
150cdc9e RH |
84 | (UNSPEC_REG_SAVE 14) |
85 | (UNSPEC_DEF_CFA 15) | |
dc4d7240 JH |
86 | (UNSPEC_SET_RIP 16) |
87 | (UNSPEC_SET_GOT_OFFSET 17) | |
b058b753 | 88 | (UNSPEC_MEMORY_BLOCKAGE 18) |
f996902d RH |
89 | |
90 | ; TLS support | |
b058b753 UB |
91 | (UNSPEC_TP 20) |
92 | (UNSPEC_TLS_GD 21) | |
93 | (UNSPEC_TLS_LD_BASE 22) | |
94 | (UNSPEC_TLSDESC 23) | |
f996902d RH |
95 | |
96 | ; Other random patterns | |
dc4d7240 JH |
97 | (UNSPEC_SCAS 30) |
98 | (UNSPEC_FNSTSW 31) | |
99 | (UNSPEC_SAHF 32) | |
100 | (UNSPEC_FSTCW 33) | |
101 | (UNSPEC_ADD_CARRY 34) | |
102 | (UNSPEC_FLDCW 35) | |
103 | (UNSPEC_REP 36) | |
dc4d7240 JH |
104 | (UNSPEC_LD_MPIC 38) ; load_macho_picbase |
105 | (UNSPEC_TRUNC_NOOP 39) | |
8ee41eaf RH |
106 | |
107 | ; For SSE/MMX support: | |
dc4d7240 JH |
108 | (UNSPEC_FIX_NOTRUNC 40) |
109 | (UNSPEC_MASKMOV 41) | |
110 | (UNSPEC_MOVMSK 42) | |
111 | (UNSPEC_MOVNT 43) | |
112 | (UNSPEC_MOVU 44) | |
113 | (UNSPEC_RCP 45) | |
114 | (UNSPEC_RSQRT 46) | |
115 | (UNSPEC_SFENCE 47) | |
dc4d7240 | 116 | (UNSPEC_PFRCP 49) |
d7b4b07a RH |
117 | (UNSPEC_PFRCPIT1 40) |
118 | (UNSPEC_PFRCPIT2 41) | |
119 | (UNSPEC_PFRSQRT 42) | |
120 | (UNSPEC_PFRSQIT1 43) | |
121 | (UNSPEC_MFENCE 44) | |
122 | (UNSPEC_LFENCE 45) | |
123 | (UNSPEC_PSADBW 46) | |
96208aed | 124 | (UNSPEC_LDDQU 47) |
924eabec | 125 | (UNSPEC_MS_TO_SYSV_CALL 48) |
d7b4b07a RH |
126 | |
127 | ; Generic math support | |
128 | (UNSPEC_COPYSIGN 50) | |
ab8efbd8 RH |
129 | (UNSPEC_IEEE_MIN 51) ; not commutative |
130 | (UNSPEC_IEEE_MAX 52) ; not commutative | |
1fb54135 RS |
131 | |
132 | ; x87 Floating point | |
d7b4b07a RH |
133 | (UNSPEC_SIN 60) |
134 | (UNSPEC_COS 61) | |
135 | (UNSPEC_FPATAN 62) | |
136 | (UNSPEC_FYL2X 63) | |
137 | (UNSPEC_FYL2XP1 64) | |
138 | (UNSPEC_FRNDINT 65) | |
139 | (UNSPEC_FIST 66) | |
140 | (UNSPEC_F2XM1 67) | |
d85c7550 | 141 | (UNSPEC_TAN 68) |
9ed4207f | 142 | (UNSPEC_FXAM 69) |
d7b4b07a RH |
143 | |
144 | ; x87 Rounding | |
145 | (UNSPEC_FRNDINT_FLOOR 70) | |
146 | (UNSPEC_FRNDINT_CEIL 71) | |
147 | (UNSPEC_FRNDINT_TRUNC 72) | |
148 | (UNSPEC_FRNDINT_MASK_PM 73) | |
4a927664 UB |
149 | (UNSPEC_FIST_FLOOR 74) |
150 | (UNSPEC_FIST_CEIL 75) | |
253c7a00 | 151 | |
a072d43b | 152 | ; x87 Double output FP |
6c7cf1f0 UB |
153 | (UNSPEC_SINCOS_COS 80) |
154 | (UNSPEC_SINCOS_SIN 81) | |
88b28a31 UB |
155 | (UNSPEC_XTRACT_FRACT 84) |
156 | (UNSPEC_XTRACT_EXP 85) | |
f964bd29 UB |
157 | (UNSPEC_FSCALE_FRACT 86) |
158 | (UNSPEC_FSCALE_EXP 87) | |
5ae27cfa UB |
159 | (UNSPEC_FPREM_F 88) |
160 | (UNSPEC_FPREM_U 89) | |
161 | (UNSPEC_FPREM1_F 90) | |
162 | (UNSPEC_FPREM1_U 91) | |
77008252 | 163 | |
79cd820a | 164 | (UNSPEC_C2_FLAG 95) |
6b67572e | 165 | (UNSPEC_FXAM_MEM 96) |
79cd820a | 166 | |
77008252 JJ |
167 | ; SSP patterns |
168 | (UNSPEC_SP_SET 100) | |
169 | (UNSPEC_SP_TEST 101) | |
170 | (UNSPEC_SP_TLS_SET 102) | |
171 | (UNSPEC_SP_TLS_TEST 103) | |
b1875f52 L |
172 | |
173 | ; SSSE3 | |
174 | (UNSPEC_PSHUFB 120) | |
175 | (UNSPEC_PSIGN 121) | |
176 | (UNSPEC_PALIGNR 122) | |
21efb4d4 HJ |
177 | |
178 | ; For SSE4A support | |
179 | (UNSPEC_EXTRQI 130) | |
4f3f76e6 | 180 | (UNSPEC_EXTRQ 131) |
21efb4d4 HJ |
181 | (UNSPEC_INSERTQI 132) |
182 | (UNSPEC_INSERTQ 133) | |
9a5cee02 L |
183 | |
184 | ; For SSE4.1 support | |
185 | (UNSPEC_BLENDV 134) | |
186 | (UNSPEC_INSERTPS 135) | |
187 | (UNSPEC_DP 136) | |
188 | (UNSPEC_MOVNTDQA 137) | |
189 | (UNSPEC_MPSADBW 138) | |
190 | (UNSPEC_PHMINPOSUW 139) | |
191 | (UNSPEC_PTEST 140) | |
f28eb39c | 192 | (UNSPEC_ROUND 141) |
3b8dd071 L |
193 | |
194 | ; For SSE4.2 support | |
195 | (UNSPEC_CRC32 143) | |
06f4e35d L |
196 | (UNSPEC_PCMPESTR 144) |
197 | (UNSPEC_PCMPISTR 145) | |
04e1d06b MM |
198 | |
199 | ;; For SSE5 | |
200 | (UNSPEC_SSE5_INTRINSIC 150) | |
201 | (UNSPEC_SSE5_UNSIGNED_CMP 151) | |
202 | (UNSPEC_SSE5_TRUEFALSE 152) | |
203 | (UNSPEC_SSE5_PERMUTE 153) | |
71d46ca5 MM |
204 | (UNSPEC_FRCZ 154) |
205 | (UNSPEC_CVTPH2PS 155) | |
206 | (UNSPEC_CVTPS2PH 156) | |
8b96a312 L |
207 | |
208 | ; For AES support | |
209 | (UNSPEC_AESENC 159) | |
210 | (UNSPEC_AESENCLAST 160) | |
211 | (UNSPEC_AESDEC 161) | |
212 | (UNSPEC_AESDECLAST 162) | |
213 | (UNSPEC_AESIMC 163) | |
214 | (UNSPEC_AESKEYGENASSIST 164) | |
215 | ||
216 | ; For PCLMUL support | |
217 | (UNSPEC_PCLMUL 165) | |
95879c72 L |
218 | |
219 | ; For AVX support | |
220 | (UNSPEC_PCMP 166) | |
221 | (UNSPEC_VPERMIL 167) | |
e47b7d04 L |
222 | (UNSPEC_VPERMIL2F128 168) |
223 | (UNSPEC_MASKLOAD 169) | |
224 | (UNSPEC_MASKSTORE 170) | |
225 | (UNSPEC_CAST 171) | |
226 | (UNSPEC_VTESTP 172) | |
8ee41eaf RH |
227 | ]) |
228 | ||
229 | (define_constants | |
230 | [(UNSPECV_BLOCKAGE 0) | |
d7b4b07a RH |
231 | (UNSPECV_STACK_PROBE 1) |
232 | (UNSPECV_EMMS 2) | |
233 | (UNSPECV_LDMXCSR 3) | |
234 | (UNSPECV_STMXCSR 4) | |
235 | (UNSPECV_FEMMS 5) | |
236 | (UNSPECV_CLFLUSH 6) | |
237 | (UNSPECV_ALIGN 7) | |
238 | (UNSPECV_MONITOR 8) | |
239 | (UNSPECV_MWAIT 9) | |
148153c1 | 240 | (UNSPECV_CMPXCHG 10) |
1ef45b77 RH |
241 | (UNSPECV_XCHG 12) |
242 | (UNSPECV_LOCK 13) | |
6fb5fa3c | 243 | (UNSPECV_PROLOGUE_USE 14) |
922e3e33 | 244 | (UNSPECV_CLD 15) |
95879c72 L |
245 | (UNSPECV_VZEROALL 16) |
246 | (UNSPECV_VZEROUPPER 17) | |
8ee41eaf | 247 | ]) |
915119a5 | 248 | |
84fbffb2 | 249 | ;; Constants to represent pcomtrue/pcomfalse variants |
04e1d06b MM |
250 | (define_constants |
251 | [(PCOM_FALSE 0) | |
252 | (PCOM_TRUE 1) | |
253 | (COM_FALSE_S 2) | |
254 | (COM_FALSE_P 3) | |
255 | (COM_TRUE_S 4) | |
256 | (COM_TRUE_P 5) | |
257 | ]) | |
258 | ||
71d46ca5 MM |
259 | ;; Constants used in the SSE5 pperm instruction |
260 | (define_constants | |
261 | [(PPERM_SRC 0x00) /* copy source */ | |
262 | (PPERM_INVERT 0x20) /* invert source */ | |
263 | (PPERM_REVERSE 0x40) /* bit reverse source */ | |
264 | (PPERM_REV_INV 0x60) /* bit reverse & invert src */ | |
265 | (PPERM_ZERO 0x80) /* all 0's */ | |
266 | (PPERM_ONES 0xa0) /* all 1's */ | |
267 | (PPERM_SIGN 0xc0) /* propagate sign bit */ | |
268 | (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */ | |
269 | (PPERM_SRC1 0x00) /* use first source byte */ | |
270 | (PPERM_SRC2 0x10) /* use second source byte */ | |
271 | ]) | |
272 | ||
8bc527af SB |
273 | ;; Registers by name. |
274 | (define_constants | |
29b74761 UB |
275 | [(AX_REG 0) |
276 | (DX_REG 1) | |
277 | (CX_REG 2) | |
2e3f842f | 278 | (BX_REG 3) |
8ec12e35 NF |
279 | (SI_REG 4) |
280 | (DI_REG 5) | |
29b74761 | 281 | (BP_REG 6) |
8bc527af | 282 | (SP_REG 7) |
78168632 UB |
283 | (ST0_REG 8) |
284 | (ST1_REG 9) | |
285 | (ST2_REG 10) | |
286 | (ST3_REG 11) | |
287 | (ST4_REG 12) | |
288 | (ST5_REG 13) | |
289 | (ST6_REG 14) | |
290 | (ST7_REG 15) | |
8bc527af SB |
291 | (FLAGS_REG 17) |
292 | (FPSR_REG 18) | |
03c259ad | 293 | (FPCR_REG 19) |
95879c72 L |
294 | (XMM0_REG 21) |
295 | (XMM1_REG 22) | |
296 | (XMM2_REG 23) | |
297 | (XMM3_REG 24) | |
298 | (XMM4_REG 25) | |
299 | (XMM5_REG 26) | |
300 | (XMM6_REG 27) | |
301 | (XMM7_REG 28) | |
78168632 UB |
302 | (MM0_REG 29) |
303 | (MM1_REG 30) | |
304 | (MM2_REG 31) | |
305 | (MM3_REG 32) | |
306 | (MM4_REG 33) | |
307 | (MM5_REG 34) | |
308 | (MM6_REG 35) | |
309 | (MM7_REG 36) | |
6c6094f1 UB |
310 | (R8_REG 37) |
311 | (R9_REG 38) | |
b0d95de8 UB |
312 | (R10_REG 39) |
313 | (R11_REG 40) | |
a952487c | 314 | (R12_REG 41) |
2e3f842f | 315 | (R13_REG 42) |
95879c72 L |
316 | (XMM8_REG 45) |
317 | (XMM9_REG 46) | |
318 | (XMM10_REG 47) | |
319 | (XMM11_REG 48) | |
320 | (XMM12_REG 49) | |
321 | (XMM13_REG 50) | |
322 | (XMM14_REG 51) | |
323 | (XMM15_REG 52) | |
8bc527af SB |
324 | ]) |
325 | ||
6343a50e ZW |
326 | ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls |
327 | ;; from i386.c. | |
328 | ||
1b0c37d7 ZW |
329 | ;; In C guard expressions, put expressions which may be compile-time |
330 | ;; constants first. This allows for better optimization. For | |
331 | ;; example, write "TARGET_64BIT && reload_completed", not | |
332 | ;; "reload_completed && TARGET_64BIT". | |
333 | ||
2ae0f82c | 334 | \f |
7ab91c5f | 335 | ;; Processor type. |
b6837b94 | 336 | (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom, |
7ab91c5f L |
337 | generic64,amdfam10" |
338 | (const (symbol_ref "ix86_schedule"))) | |
2ae0f82c | 339 | |
e075ae69 RH |
340 | ;; A basic instruction type. Refinements due to arguments to be |
341 | ;; provided in other attributes. | |
a269a03c | 342 | (define_attr "type" |
9a5834ae ZW |
343 | "other,multi, |
344 | alu,alu1,negnot,imov,imovx,lea, | |
1b245ade | 345 | incdec,ishift,ishift1,rotate,rotate1,imul,idiv, |
9a5834ae | 346 | icmp,test,ibr,setcc,icmov, |
4977bab6 | 347 | push,pop,call,callv,leave, |
21efb4d4 | 348 | str,bitmanip, |
9199f050 | 349 | fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, |
04e1d06b MM |
350 | sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul, |
351 | sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins, | |
352 | ssemuladd,sse4arg, | |
9a5834ae | 353 | mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" |
e075ae69 RH |
354 | (const_string "other")) |
355 | ||
6ef67412 | 356 | ;; Main data type used by the insn |
9a5834ae | 357 | (define_attr "mode" |
95879c72 | 358 | "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF" |
6ef67412 JH |
359 | (const_string "unknown")) |
360 | ||
3d34cd91 JH |
361 | ;; The CPU unit operations uses. |
362 | (define_attr "unit" "integer,i387,sse,mmx,unknown" | |
9199f050 | 363 | (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") |
3d34cd91 | 364 | (const_string "i387") |
04e1d06b MM |
365 | (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul, |
366 | sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt, | |
367 | ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg") | |
3d34cd91 | 368 | (const_string "sse") |
9a5834ae | 369 | (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") |
4c9c9a3d JH |
370 | (const_string "mmx") |
371 | (eq_attr "type" "other") | |
372 | (const_string "unknown")] | |
3d34cd91 | 373 | (const_string "integer"))) |
6ef67412 JH |
374 | |
375 | ;; The (bounding maximum) length of an instruction immediate. | |
376 | (define_attr "length_immediate" "" | |
21efb4d4 HJ |
377 | (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave, |
378 | bitmanip") | |
6ef67412 | 379 | (const_int 0) |
3d34cd91 | 380 | (eq_attr "unit" "i387,sse,mmx") |
6ef67412 | 381 | (const_int 0) |
1b245ade JH |
382 | (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1, |
383 | imul,icmp,push,pop") | |
6ef67412 JH |
384 | (symbol_ref "ix86_attr_length_immediate_default(insn,1)") |
385 | (eq_attr "type" "imov,test") | |
386 | (symbol_ref "ix86_attr_length_immediate_default(insn,0)") | |
387 | (eq_attr "type" "call") | |
388 | (if_then_else (match_operand 0 "constant_call_address_operand" "") | |
389 | (const_int 4) | |
390 | (const_int 0)) | |
391 | (eq_attr "type" "callv") | |
392 | (if_then_else (match_operand 1 "constant_call_address_operand" "") | |
393 | (const_int 4) | |
394 | (const_int 0)) | |
efcc7037 JH |
395 | ;; We don't know the size before shorten_branches. Expect |
396 | ;; the instruction to fit for better scheduling. | |
6ef67412 | 397 | (eq_attr "type" "ibr") |
efcc7037 | 398 | (const_int 1) |
6ef67412 | 399 | ] |
9a5834ae | 400 | (symbol_ref "/* Update immediate_length and other attributes! */ |
7637e42c | 401 | gcc_unreachable (),1"))) |
e075ae69 | 402 | |
6ef67412 JH |
403 | ;; The (bounding maximum) length of an instruction address. |
404 | (define_attr "length_address" "" | |
90c56b45 | 405 | (cond [(eq_attr "type" "str,other,multi,fxch") |
6ef67412 JH |
406 | (const_int 0) |
407 | (and (eq_attr "type" "call") | |
c7375e61 | 408 | (match_operand 0 "constant_call_address_operand" "")) |
6ef67412 JH |
409 | (const_int 0) |
410 | (and (eq_attr "type" "callv") | |
411 | (match_operand 1 "constant_call_address_operand" "")) | |
412 | (const_int 0) | |
413 | ] | |
414 | (symbol_ref "ix86_attr_length_address_default (insn)"))) | |
415 | ||
416 | ;; Set when length prefix is used. | |
417 | (define_attr "prefix_data16" "" | |
725fd454 JJ |
418 | (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") |
419 | (const_int 0) | |
420 | (eq_attr "mode" "HI") | |
421 | (const_int 1) | |
422 | (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI")) | |
423 | (const_int 1) | |
424 | ] | |
425 | (const_int 0))) | |
6ef67412 JH |
426 | |
427 | ;; Set when string REP prefix is used. | |
6300f037 | 428 | (define_attr "prefix_rep" "" |
725fd454 JJ |
429 | (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") |
430 | (const_int 0) | |
431 | (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) | |
432 | (const_int 1) | |
433 | ] | |
434 | (const_int 0))) | |
6ef67412 JH |
435 | |
436 | ;; Set when 0f opcode prefix is used. | |
437 | (define_attr "prefix_0f" "" | |
6300f037 | 438 | (if_then_else |
21efb4d4 | 439 | (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip") |
cb297538 | 440 | (eq_attr "unit" "sse,mmx")) |
6ef67412 JH |
441 | (const_int 1) |
442 | (const_int 0))) | |
443 | ||
56bab446 | 444 | ;; Set when REX opcode prefix is used. |
4977bab6 | 445 | (define_attr "prefix_rex" "" |
a952487c JJ |
446 | (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0)) |
447 | (const_int 0) | |
448 | (and (eq_attr "mode" "DI") | |
725fd454 JJ |
449 | (and (eq_attr "type" "!push,pop,call,callv,leave,ibr") |
450 | (eq_attr "unit" "!mmx"))) | |
4977bab6 ZW |
451 | (const_int 1) |
452 | (and (eq_attr "mode" "QI") | |
453 | (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)") | |
454 | (const_int 0))) | |
455 | (const_int 1) | |
456 | (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)") | |
457 | (const_int 0)) | |
458 | (const_int 1) | |
a952487c JJ |
459 | (and (eq_attr "type" "imovx") |
460 | (match_operand:QI 1 "ext_QIreg_operand" "")) | |
461 | (const_int 1) | |
4977bab6 ZW |
462 | ] |
463 | (const_int 0))) | |
464 | ||
725fd454 JJ |
465 | ;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5. |
466 | ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte, | |
467 | ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte. | |
468 | ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a. | |
469 | (define_attr "prefix_extra" "" | |
470 | (cond [(eq_attr "type" "ssemuladd,sse4arg") | |
471 | (const_int 2) | |
472 | (eq_attr "type" "sseiadd1,ssecvt1") | |
473 | (const_int 1) | |
474 | ] | |
475 | (const_int 0))) | |
10e4d956 | 476 | |
95879c72 L |
477 | ;; Prefix used: original, VEX or maybe VEX. |
478 | (define_attr "prefix" "orig,vex,maybe_vex" | |
479 | (if_then_else (eq_attr "mode" "OI,V8SF,V4DF") | |
480 | (const_string "vex") | |
481 | (const_string "orig"))) | |
482 | ||
95879c72 L |
483 | ;; VEX W bit is used. |
484 | (define_attr "prefix_vex_w" "" (const_int 0)) | |
485 | ||
486 | ;; The length of VEX prefix | |
725fd454 JJ |
487 | ;; Only instructions with 0f prefix can have 2 byte VEX prefix, |
488 | ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is | |
489 | ;; still prefix_0f 1, with prefix_extra 1. | |
95879c72 | 490 | (define_attr "length_vex" "" |
725fd454 JJ |
491 | (if_then_else (and (eq_attr "prefix_0f" "1") |
492 | (eq_attr "prefix_extra" "0")) | |
95879c72 L |
493 | (if_then_else (eq_attr "prefix_vex_w" "1") |
494 | (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)") | |
495 | (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)")) | |
496 | (if_then_else (eq_attr "prefix_vex_w" "1") | |
497 | (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)") | |
498 | (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)")))) | |
499 | ||
6ef67412 JH |
500 | ;; Set when modrm byte is used. |
501 | (define_attr "modrm" "" | |
90c56b45 | 502 | (cond [(eq_attr "type" "str,leave") |
6ef67412 | 503 | (const_int 0) |
3d34cd91 | 504 | (eq_attr "unit" "i387") |
6ef67412 | 505 | (const_int 0) |
e075ae69 | 506 | (and (eq_attr "type" "incdec") |
725fd454 JJ |
507 | (and (eq (symbol_ref "TARGET_64BIT") (const_int 0)) |
508 | (ior (match_operand:SI 1 "register_operand" "") | |
509 | (match_operand:HI 1 "register_operand" "")))) | |
6ef67412 | 510 | (const_int 0) |
e075ae69 RH |
511 | (and (eq_attr "type" "push") |
512 | (not (match_operand 1 "memory_operand" ""))) | |
6ef67412 | 513 | (const_int 0) |
e075ae69 RH |
514 | (and (eq_attr "type" "pop") |
515 | (not (match_operand 0 "memory_operand" ""))) | |
6ef67412 | 516 | (const_int 0) |
e075ae69 | 517 | (and (eq_attr "type" "imov") |
a952487c JJ |
518 | (and (not (eq_attr "mode" "DI")) |
519 | (ior (and (match_operand 0 "register_operand" "") | |
520 | (match_operand 1 "immediate_operand" "")) | |
521 | (ior (and (match_operand 0 "ax_reg_operand" "") | |
522 | (match_operand 1 "memory_displacement_only_operand" "")) | |
523 | (and (match_operand 0 "memory_displacement_only_operand" "") | |
524 | (match_operand 1 "ax_reg_operand" "")))))) | |
6ef67412 | 525 | (const_int 0) |
c7375e61 EB |
526 | (and (eq_attr "type" "call") |
527 | (match_operand 0 "constant_call_address_operand" "")) | |
528 | (const_int 0) | |
529 | (and (eq_attr "type" "callv") | |
530 | (match_operand 1 "constant_call_address_operand" "")) | |
531 | (const_int 0) | |
a952487c JJ |
532 | (and (eq_attr "type" "alu,alu1,icmp,test") |
533 | (match_operand 0 "ax_reg_operand" "")) | |
534 | (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))") | |
e075ae69 | 535 | ] |
6ef67412 JH |
536 | (const_int 1))) |
537 | ||
538 | ;; The (bounding maximum) length of an instruction in bytes. | |
edeacc14 UB |
539 | ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. |
540 | ;; Later we may want to split them and compute proper length as for | |
541 | ;; other insns. | |
6ef67412 | 542 | (define_attr "length" "" |
edeacc14 | 543 | (cond [(eq_attr "type" "other,multi,fistp,frndint") |
6ef67412 | 544 | (const_int 16) |
a3033f34 EB |
545 | (eq_attr "type" "fcmp") |
546 | (const_int 4) | |
3d34cd91 JH |
547 | (eq_attr "unit" "i387") |
548 | (plus (const_int 2) | |
549 | (plus (attr "prefix_data16") | |
95879c72 L |
550 | (attr "length_address"))) |
551 | (ior (eq_attr "prefix" "vex") | |
552 | (and (eq_attr "prefix" "maybe_vex") | |
553 | (ne (symbol_ref "TARGET_AVX") (const_int 0)))) | |
554 | (plus (attr "length_vex") | |
725fd454 | 555 | (plus (attr "length_immediate") |
95879c72 L |
556 | (plus (attr "modrm") |
557 | (attr "length_address"))))] | |
6ef67412 JH |
558 | (plus (plus (attr "modrm") |
559 | (plus (attr "prefix_0f") | |
4977bab6 | 560 | (plus (attr "prefix_rex") |
10e4d956 L |
561 | (plus (attr "prefix_extra") |
562 | (const_int 1))))) | |
6ef67412 JH |
563 | (plus (attr "prefix_rep") |
564 | (plus (attr "prefix_data16") | |
565 | (plus (attr "length_immediate") | |
566 | (attr "length_address"))))))) | |
e075ae69 RH |
567 | |
568 | ;; The `memory' attribute is `none' if no memory is referenced, `load' or | |
569 | ;; `store' if there is a simple memory reference therein, or `unknown' | |
570 | ;; if the instruction is complex. | |
571 | ||
572 | (define_attr "memory" "none,load,store,both,unknown" | |
7c7ef435 | 573 | (cond [(eq_attr "type" "other,multi,str") |
e075ae69 | 574 | (const_string "unknown") |
90c56b45 | 575 | (eq_attr "type" "lea,fcmov,fpspc") |
e075ae69 | 576 | (const_string "none") |
4977bab6 | 577 | (eq_attr "type" "fistp,leave") |
22fb740d | 578 | (const_string "both") |
edeacc14 UB |
579 | (eq_attr "type" "frndint") |
580 | (const_string "load") | |
e075ae69 RH |
581 | (eq_attr "type" "push") |
582 | (if_then_else (match_operand 1 "memory_operand" "") | |
583 | (const_string "both") | |
584 | (const_string "store")) | |
abd2dd6d | 585 | (eq_attr "type" "pop") |
e075ae69 RH |
586 | (if_then_else (match_operand 0 "memory_operand" "") |
587 | (const_string "both") | |
588 | (const_string "load")) | |
abd2dd6d JH |
589 | (eq_attr "type" "setcc") |
590 | (if_then_else (match_operand 0 "memory_operand" "") | |
591 | (const_string "store") | |
592 | (const_string "none")) | |
f56e86bd | 593 | (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") |
e075ae69 RH |
594 | (if_then_else (ior (match_operand 0 "memory_operand" "") |
595 | (match_operand 1 "memory_operand" "")) | |
596 | (const_string "load") | |
597 | (const_string "none")) | |
598 | (eq_attr "type" "ibr") | |
599 | (if_then_else (match_operand 0 "memory_operand" "") | |
600 | (const_string "load") | |
601 | (const_string "none")) | |
602 | (eq_attr "type" "call") | |
603 | (if_then_else (match_operand 0 "constant_call_address_operand" "") | |
604 | (const_string "none") | |
605 | (const_string "load")) | |
606 | (eq_attr "type" "callv") | |
607 | (if_then_else (match_operand 1 "constant_call_address_operand" "") | |
608 | (const_string "none") | |
609 | (const_string "load")) | |
ef719a44 | 610 | (and (eq_attr "type" "alu1,negnot,ishift1,sselog1") |
a269a03c | 611 | (match_operand 1 "memory_operand" "")) |
e075ae69 RH |
612 | (const_string "both") |
613 | (and (match_operand 0 "memory_operand" "") | |
614 | (match_operand 1 "memory_operand" "")) | |
615 | (const_string "both") | |
616 | (match_operand 0 "memory_operand" "") | |
617 | (const_string "store") | |
618 | (match_operand 1 "memory_operand" "") | |
619 | (const_string "load") | |
9a5834ae | 620 | (and (eq_attr "type" |
f527d196 | 621 | "!alu1,negnot,ishift1, |
21efb4d4 | 622 | imov,imovx,icmp,test,bitmanip, |
9a5834ae | 623 | fmov,fcmp,fsgn, |
04e1d06b MM |
624 | sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1, |
625 | sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt") | |
e075ae69 RH |
626 | (match_operand 2 "memory_operand" "")) |
627 | (const_string "load") | |
04e1d06b | 628 | (and (eq_attr "type" "icmov,ssemuladd,sse4arg") |
e075ae69 RH |
629 | (match_operand 3 "memory_operand" "")) |
630 | (const_string "load") | |
631 | ] | |
a269a03c JC |
632 | (const_string "none"))) |
633 | ||
e075ae69 RH |
634 | ;; Indicates if an instruction has both an immediate and a displacement. |
635 | ||
636 | (define_attr "imm_disp" "false,true,unknown" | |
637 | (cond [(eq_attr "type" "other,multi") | |
638 | (const_string "unknown") | |
1b245ade | 639 | (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") |
e075ae69 RH |
640 | (and (match_operand 0 "memory_displacement_operand" "") |
641 | (match_operand 1 "immediate_operand" ""))) | |
642 | (const_string "true") | |
890d52e8 | 643 | (and (eq_attr "type" "alu,ishift,rotate,imul,idiv") |
e075ae69 RH |
644 | (and (match_operand 0 "memory_displacement_operand" "") |
645 | (match_operand 2 "immediate_operand" ""))) | |
646 | (const_string "true") | |
647 | ] | |
648 | (const_string "false"))) | |
649 | ||
650 | ;; Indicates if an FP operation has an integer source. | |
651 | ||
652 | (define_attr "fp_int_src" "false,true" | |
653 | (const_string "false")) | |
654 | ||
edeacc14 UB |
655 | ;; Defines rounding mode of an FP operation. |
656 | ||
ff680eb1 | 657 | (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" |
edeacc14 UB |
658 | (const_string "any")) |
659 | ||
b6837b94 JY |
660 | ;; Define attribute to classify add/sub insns that consumes carry flag (CF) |
661 | (define_attr "use_carry" "0,1" (const_string "0")) | |
662 | ||
663 | ;; Define attribute to indicate unaligned ssemov insns | |
664 | (define_attr "movu" "0,1" (const_string "0")) | |
665 | ||
e075ae69 RH |
666 | ;; Describe a user's asm statement. |
667 | (define_asm_attributes | |
668 | [(set_attr "length" "128") | |
669 | (set_attr "type" "multi")]) | |
0e8c2b0d | 670 | |
a7438d6d UB |
671 | ;; All integer comparison codes. |
672 | (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ]) | |
673 | ||
674 | ;; All floating-point comparison codes. | |
675 | (define_code_iterator fp_cond [unordered ordered | |
676 | uneq unge ungt unle unlt ltgt ]) | |
677 | ||
3abcb3a7 | 678 | (define_code_iterator plusminus [plus minus]) |
d39d658d | 679 | |
d1c3b587 L |
680 | (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus]) |
681 | ||
682 | ;; Base name for define_insn | |
683 | (define_code_attr plusminus_insn | |
684 | [(plus "add") (ss_plus "ssadd") (us_plus "usadd") | |
685 | (minus "sub") (ss_minus "sssub") (us_minus "ussub")]) | |
686 | ||
687 | ;; Base name for insn mnemonic. | |
688 | (define_code_attr plusminus_mnemonic | |
689 | [(plus "add") (ss_plus "adds") (us_plus "addus") | |
690 | (minus "sub") (ss_minus "subs") (us_minus "subus")]) | |
d39d658d RIL |
691 | |
692 | ;; Mark commutative operators as such in constraints. | |
d1c3b587 L |
693 | (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%") |
694 | (minus "") (ss_minus "") (us_minus "")]) | |
d39d658d | 695 | |
78e8956b L |
696 | ;; Mapping of signed max and min |
697 | (define_code_iterator smaxmin [smax smin]) | |
698 | ||
699 | ;; Mapping of unsigned max and min | |
700 | (define_code_iterator umaxmin [umax umin]) | |
701 | ||
95879c72 L |
702 | ;; Mapping of signed/unsigned max and min |
703 | (define_code_iterator maxmin [smax smin umax umin]) | |
704 | ||
78e8956b | 705 | ;; Base name for integer and FP insn mnemonic |
6dd18eb1 UB |
706 | (define_code_attr maxminiprefix [(smax "maxs") (smin "mins") |
707 | (umax "maxu") (umin "minu")]) | |
78e8956b L |
708 | (define_code_attr maxminfprefix [(smax "max") (smin "min")]) |
709 | ||
94237c92 L |
710 | ;; Mapping of parallel logic operators |
711 | (define_code_iterator plogic [and ior xor]) | |
712 | ||
713 | ;; Base name for insn mnemonic. | |
714 | (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")]) | |
715 | ||
6dd18eb1 UB |
716 | ;; Mapping of abs neg operators |
717 | (define_code_iterator absneg [abs neg]) | |
718 | ||
719 | ;; Base name for x87 insn mnemonic. | |
720 | (define_code_attr absnegprefix [(abs "abs") (neg "chs")]) | |
721 | ||
d39d658d | 722 | ;; All single word integer modes. |
3abcb3a7 | 723 | (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")]) |
d39d658d | 724 | |
a00ce5fe UB |
725 | ;; Single word integer modes without QImode. |
726 | (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")]) | |
4e7f50e5 | 727 | |
d39d658d RIL |
728 | ;; Instruction suffix for integer modes. |
729 | (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")]) | |
730 | ||
731 | ;; Register class for integer modes. | |
732 | (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) | |
733 | ||
734 | ;; Immediate operand constraint for integer modes. | |
0edb82cb | 735 | (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")]) |
d39d658d RIL |
736 | |
737 | ;; General operand predicate for integer modes. | |
738 | (define_mode_attr general_operand | |
739 | [(QI "general_operand") | |
740 | (HI "general_operand") | |
741 | (SI "general_operand") | |
742 | (DI "x86_64_general_operand")]) | |
743 | ||
00188daa UB |
744 | ;; SSE and x87 SFmode and DFmode floating point modes |
745 | (define_mode_iterator MODEF [SF DF]) | |
746 | ||
9199f050 | 747 | ;; All x87 floating point modes |
3abcb3a7 | 748 | (define_mode_iterator X87MODEF [SF DF XF]) |
6300f037 | 749 | |
9199f050 | 750 | ;; All integer modes handled by x87 fisttp operator. |
3abcb3a7 | 751 | (define_mode_iterator X87MODEI [HI SI DI]) |
9199f050 | 752 | |
0e8c2b0d | 753 | ;; All integer modes handled by integer x87 operators. |
3abcb3a7 | 754 | (define_mode_iterator X87MODEI12 [HI SI]) |
9199f050 | 755 | |
9199f050 | 756 | ;; All integer modes handled by SSE cvtts?2si* operators. |
3abcb3a7 | 757 | (define_mode_iterator SSEMODEI24 [SI DI]) |
9199f050 | 758 | |
01302104 UB |
759 | ;; SSE asm suffix for floating point modes |
760 | (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")]) | |
761 | ||
174c12c7 RH |
762 | ;; SSE vector mode corresponding to a scalar mode |
763 | (define_mode_attr ssevecmode | |
764 | [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")]) | |
380edc9f UB |
765 | |
766 | ;; Instruction suffix for REX 64bit operators. | |
767 | (define_mode_attr rex64suffix [(SI "") (DI "{q}")]) | |
90b48492 KT |
768 | |
769 | ;; This mode iterator allows :P to be used for patterns that operate on | |
770 | ;; pointer-sized quantities. Exactly one of the two alternatives will match. | |
771 | (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) | |
772 | ||
e075ae69 | 773 | \f |
8fe75e43 RH |
774 | ;; Scheduling descriptions |
775 | ||
af2728a4 JL |
776 | (include "pentium.md") |
777 | (include "ppro.md") | |
778 | (include "k6.md") | |
779 | (include "athlon.md") | |
cfe1b18f | 780 | (include "geode.md") |
b6837b94 | 781 | (include "atom.md") |
8fe75e43 RH |
782 | |
783 | \f | |
08b1e29a | 784 | ;; Operand and operator predicates and constraints |
8fe75e43 RH |
785 | |
786 | (include "predicates.md") | |
08b1e29a | 787 | (include "constraints.md") |
8fe75e43 | 788 | |
309ada50 | 789 | \f |
f90b7a5a | 790 | ;; Compare and branch/compare and store instructions. |
886c62d1 | 791 | |
f90b7a5a PB |
792 | (define_expand "cbranchti4" |
793 | [(set (reg:CC FLAGS_REG) | |
794 | (compare:CC (match_operand:TI 1 "nonimmediate_operand" "") | |
795 | (match_operand:TI 2 "x86_64_general_operand" ""))) | |
796 | (set (pc) (if_then_else | |
797 | (match_operator 0 "comparison_operator" | |
798 | [(reg:CC FLAGS_REG) | |
799 | (const_int 0)]) | |
800 | (label_ref (match_operand 3 "" "")) | |
801 | (pc)))] | |
802 | "TARGET_64BIT" | |
803 | { | |
804 | if (MEM_P (operands[1]) && MEM_P (operands[2])) | |
805 | operands[1] = force_reg (TImode, operands[1]); | |
806 | ix86_compare_op0 = operands[1]; | |
807 | ix86_compare_op1 = operands[2]; | |
808 | ix86_expand_branch (GET_CODE (operands[0]), operands[3]); | |
809 | DONE; | |
810 | }) | |
886c62d1 | 811 | |
f90b7a5a | 812 | (define_expand "cbranchdi4" |
28356f52 | 813 | [(set (reg:CC FLAGS_REG) |
f90b7a5a PB |
814 | (compare:CC (match_operand:DI 1 "nonimmediate_operand" "") |
815 | (match_operand:DI 2 "x86_64_general_operand" ""))) | |
816 | (set (pc) (if_then_else | |
817 | (match_operator 0 "comparison_operator" | |
818 | [(reg:CC FLAGS_REG) | |
819 | (const_int 0)]) | |
820 | (label_ref (match_operand 3 "" "")) | |
821 | (pc)))] | |
822 | "" | |
823 | { | |
824 | if (MEM_P (operands[1]) && MEM_P (operands[2])) | |
825 | operands[1] = force_reg (DImode, operands[1]); | |
826 | ix86_compare_op0 = operands[1]; | |
827 | ix86_compare_op1 = operands[2]; | |
828 | ix86_expand_branch (GET_CODE (operands[0]), operands[3]); | |
829 | DONE; | |
830 | }) | |
831 | ||
832 | (define_expand "cstoredi4" | |
833 | [(set (reg:CC FLAGS_REG) | |
834 | (compare:CC (match_operand:DI 2 "nonimmediate_operand" "") | |
835 | (match_operand:DI 3 "x86_64_general_operand" ""))) | |
836 | (set (match_operand:QI 0 "register_operand" "") | |
837 | (match_operator 1 "comparison_operator" | |
838 | [(reg:CC FLAGS_REG) | |
839 | (const_int 0)]))] | |
28356f52 JB |
840 | "TARGET_64BIT" |
841 | { | |
f90b7a5a PB |
842 | if (MEM_P (operands[2]) && MEM_P (operands[3])) |
843 | operands[2] = force_reg (DImode, operands[2]); | |
844 | ix86_compare_op0 = operands[2]; | |
845 | ix86_compare_op1 = operands[3]; | |
846 | ix86_expand_setcc (GET_CODE (operands[1]), operands[0]); | |
28356f52 JB |
847 | DONE; |
848 | }) | |
849 | ||
f90b7a5a | 850 | (define_expand "cbranchsi4" |
8bc527af | 851 | [(set (reg:CC FLAGS_REG) |
f90b7a5a PB |
852 | (compare:CC (match_operand:SI 1 "cmpsi_operand" "") |
853 | (match_operand:SI 2 "general_operand" ""))) | |
854 | (set (pc) (if_then_else | |
855 | (match_operator 0 "comparison_operator" | |
856 | [(reg:CC FLAGS_REG) | |
857 | (const_int 0)]) | |
858 | (label_ref (match_operand 3 "" "")) | |
859 | (pc)))] | |
c572e5ba | 860 | "" |
c572e5ba | 861 | { |
f90b7a5a PB |
862 | if (MEM_P (operands[1]) && MEM_P (operands[2])) |
863 | operands[1] = force_reg (SImode, operands[1]); | |
864 | ix86_compare_op0 = operands[1]; | |
865 | ix86_compare_op1 = operands[2]; | |
866 | ix86_expand_branch (GET_CODE (operands[0]), operands[3]); | |
c572e5ba | 867 | DONE; |
0f40f9f7 | 868 | }) |
c572e5ba | 869 | |
f90b7a5a | 870 | (define_expand "cstoresi4" |
8bc527af | 871 | [(set (reg:CC FLAGS_REG) |
f90b7a5a PB |
872 | (compare:CC (match_operand:SI 2 "cmpsi_operand" "") |
873 | (match_operand:SI 3 "general_operand" ""))) | |
874 | (set (match_operand:QI 0 "register_operand" "") | |
875 | (match_operator 1 "comparison_operator" | |
876 | [(reg:CC FLAGS_REG) | |
877 | (const_int 0)]))] | |
c572e5ba | 878 | "" |
c572e5ba | 879 | { |
f90b7a5a PB |
880 | if (MEM_P (operands[2]) && MEM_P (operands[3])) |
881 | operands[2] = force_reg (SImode, operands[2]); | |
882 | ix86_compare_op0 = operands[2]; | |
883 | ix86_compare_op1 = operands[3]; | |
884 | ix86_expand_setcc (GET_CODE (operands[1]), operands[0]); | |
c572e5ba | 885 | DONE; |
0f40f9f7 | 886 | }) |
c572e5ba | 887 | |
f90b7a5a | 888 | (define_expand "cbranchhi4" |
8bc527af | 889 | [(set (reg:CC FLAGS_REG) |
f90b7a5a PB |
890 | (compare:CC (match_operand:HI 1 "nonimmediate_operand" "") |
891 | (match_operand:HI 2 "general_operand" ""))) | |
892 | (set (pc) (if_then_else | |
893 | (match_operator 0 "comparison_operator" | |
894 | [(reg:CC FLAGS_REG) | |
895 | (const_int 0)]) | |
896 | (label_ref (match_operand 3 "" "")) | |
897 | (pc)))] | |
c572e5ba | 898 | "" |
c572e5ba | 899 | { |
f90b7a5a PB |
900 | if (MEM_P (operands[1]) && MEM_P (operands[2])) |
901 | operands[1] = force_reg (HImode, operands[1]); | |
902 | ix86_compare_op0 = operands[1]; | |
903 | ix86_compare_op1 = operands[2]; | |
904 | ix86_expand_branch (GET_CODE (operands[0]), operands[3]); | |
c572e5ba | 905 | DONE; |
0f40f9f7 | 906 | }) |
c572e5ba | 907 | |
f90b7a5a | 908 | (define_expand "cstorehi4" |
8bc527af | 909 | [(set (reg:CC FLAGS_REG) |
f90b7a5a PB |
910 | (compare:CC (match_operand:HI 2 "nonimmediate_operand" "") |
911 | (match_operand:HI 3 "general_operand" ""))) | |
912 | (set (match_operand:QI 0 "register_operand" "") | |
913 | (match_operator 1 "comparison_operator" | |
914 | [(reg:CC FLAGS_REG) | |
915 | (const_int 0)]))] | |
916 | "" | |
c572e5ba | 917 | { |
f90b7a5a PB |
918 | if (MEM_P (operands[2]) && MEM_P (operands[3])) |
919 | operands[2] = force_reg (HImode, operands[2]); | |
920 | ix86_compare_op0 = operands[2]; | |
921 | ix86_compare_op1 = operands[3]; | |
922 | ix86_expand_setcc (GET_CODE (operands[1]), operands[0]); | |
923 | DONE; | |
924 | }) | |
925 | ||
926 | ||
927 | (define_expand "cbranchqi4" | |
928 | [(set (reg:CC FLAGS_REG) | |
929 | (compare:CC (match_operand:QI 1 "nonimmediate_operand" "") | |
930 | (match_operand:QI 2 "general_operand" ""))) | |
931 | (set (pc) (if_then_else | |
932 | (match_operator 0 "comparison_operator" | |
933 | [(reg:CC FLAGS_REG) | |
934 | (const_int 0)]) | |
935 | (label_ref (match_operand 3 "" "")) | |
936 | (pc)))] | |
937 | "" | |
938 | { | |
939 | if (MEM_P (operands[1]) && MEM_P (operands[2])) | |
940 | operands[1] = force_reg (QImode, operands[1]); | |
941 | ix86_compare_op0 = operands[1]; | |
942 | ix86_compare_op1 = operands[2]; | |
943 | ix86_expand_branch (GET_CODE (operands[0]), operands[3]); | |
944 | DONE; | |
945 | }) | |
946 | ||
947 | ||
948 | (define_expand "cstoreqi4" | |
949 | [(set (reg:CC FLAGS_REG) | |
950 | (compare:CC (match_operand:QI 2 "nonimmediate_operand" "") | |
951 | (match_operand:QI 3 "general_operand" ""))) | |
952 | (set (match_operand:QI 0 "register_operand" "") | |
953 | (match_operator 1 "comparison_operator" | |
954 | [(reg:CC FLAGS_REG) | |
955 | (const_int 0)]))] | |
956 | "" | |
957 | { | |
958 | if (MEM_P (operands[2]) && MEM_P (operands[3])) | |
959 | operands[2] = force_reg (QImode, operands[2]); | |
960 | ix86_compare_op0 = operands[2]; | |
961 | ix86_compare_op1 = operands[3]; | |
962 | ix86_expand_setcc (GET_CODE (operands[1]), operands[0]); | |
c572e5ba | 963 | DONE; |
0f40f9f7 | 964 | }) |
886c62d1 | 965 | |
f90b7a5a | 966 | |
9b70259d | 967 | (define_insn "cmpdi_ccno_1_rex64" |
42fabf21 | 968 | [(set (reg FLAGS_REG) |
9b70259d | 969 | (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr") |
0edb82cb | 970 | (match_operand:DI 1 "const0_operand" "")))] |
9b70259d JH |
971 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" |
972 | "@ | |
a23132e1 | 973 | test{q}\t%0, %0 |
0f40f9f7 | 974 | cmp{q}\t{%1, %0|%0, %1}" |
9b70259d JH |
975 | [(set_attr "type" "test,icmp") |
976 | (set_attr "length_immediate" "0,1") | |
977 | (set_attr "mode" "DI")]) | |
978 | ||
979 | (define_insn "*cmpdi_minus_1_rex64" | |
42fabf21 | 980 | [(set (reg FLAGS_REG) |
9b70259d JH |
981 | (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r") |
982 | (match_operand:DI 1 "x86_64_general_operand" "re,mr")) | |
983 | (const_int 0)))] | |
1b0c37d7 | 984 | "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)" |
0f40f9f7 | 985 | "cmp{q}\t{%1, %0|%0, %1}" |
9b70259d JH |
986 | [(set_attr "type" "icmp") |
987 | (set_attr "mode" "DI")]) | |
988 | ||
989 | (define_expand "cmpdi_1_rex64" | |
8bc527af | 990 | [(set (reg:CC FLAGS_REG) |
9b70259d JH |
991 | (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") |
992 | (match_operand:DI 1 "general_operand" "")))] | |
1b0c37d7 | 993 | "TARGET_64BIT" |
9b70259d JH |
994 | "") |
995 | ||
996 | (define_insn "cmpdi_1_insn_rex64" | |
42fabf21 | 997 | [(set (reg FLAGS_REG) |
9b70259d JH |
998 | (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r") |
999 | (match_operand:DI 1 "x86_64_general_operand" "re,mr")))] | |
1000 | "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" | |
0f40f9f7 | 1001 | "cmp{q}\t{%1, %0|%0, %1}" |
9b70259d JH |
1002 | [(set_attr "type" "icmp") |
1003 | (set_attr "mode" "DI")]) | |
1004 | ||
1005 | ||
9076b9c1 | 1006 | (define_insn "*cmpsi_ccno_1" |
42fabf21 | 1007 | [(set (reg FLAGS_REG) |
9076b9c1 | 1008 | (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") |
0edb82cb | 1009 | (match_operand:SI 1 "const0_operand" "")))] |
9076b9c1 | 1010 | "ix86_match_ccmode (insn, CCNOmode)" |
16189740 | 1011 | "@ |
a23132e1 | 1012 | test{l}\t%0, %0 |
0f40f9f7 | 1013 | cmp{l}\t{%1, %0|%0, %1}" |
6ef67412 JH |
1014 | [(set_attr "type" "test,icmp") |
1015 | (set_attr "length_immediate" "0,1") | |
1016 | (set_attr "mode" "SI")]) | |
16189740 | 1017 | |
9076b9c1 | 1018 | (define_insn "*cmpsi_minus_1" |
42fabf21 | 1019 | [(set (reg FLAGS_REG) |
9076b9c1 JH |
1020 | (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r") |
1021 | (match_operand:SI 1 "general_operand" "ri,mr")) | |
1022 | (const_int 0)))] | |
1023 | "ix86_match_ccmode (insn, CCGOCmode)" | |
0f40f9f7 | 1024 | "cmp{l}\t{%1, %0|%0, %1}" |
9076b9c1 | 1025 | [(set_attr "type" "icmp") |
6ef67412 | 1026 | (set_attr "mode" "SI")]) |
886c62d1 | 1027 | |
9076b9c1 | 1028 | (define_expand "cmpsi_1" |
8bc527af | 1029 | [(set (reg:CC FLAGS_REG) |
00188daa UB |
1030 | (compare:CC (match_operand:SI 0 "nonimmediate_operand" "") |
1031 | (match_operand:SI 1 "general_operand" "")))] | |
9076b9c1 JH |
1032 | "" |
1033 | "") | |
1034 | ||
1035 | (define_insn "*cmpsi_1_insn" | |
42fabf21 | 1036 | [(set (reg FLAGS_REG) |
9076b9c1 JH |
1037 | (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r") |
1038 | (match_operand:SI 1 "general_operand" "ri,mr")))] | |
7656aee4 | 1039 | "!(MEM_P (operands[0]) && MEM_P (operands[1])) |
9076b9c1 | 1040 | && ix86_match_ccmode (insn, CCmode)" |
0f40f9f7 | 1041 | "cmp{l}\t{%1, %0|%0, %1}" |
6ef67412 JH |
1042 | [(set_attr "type" "icmp") |
1043 | (set_attr "mode" "SI")]) | |
886c62d1 | 1044 | |
9076b9c1 | 1045 | (define_insn "*cmphi_ccno_1" |
42fabf21 | 1046 | [(set (reg FLAGS_REG) |
16189740 | 1047 | (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") |
0edb82cb | 1048 | (match_operand:HI 1 "const0_operand" "")))] |
16189740 | 1049 | "ix86_match_ccmode (insn, CCNOmode)" |
e075ae69 | 1050 | "@ |
a23132e1 | 1051 | test{w}\t%0, %0 |
0f40f9f7 | 1052 | cmp{w}\t{%1, %0|%0, %1}" |
6ef67412 JH |
1053 | [(set_attr "type" "test,icmp") |
1054 | (set_attr "length_immediate" "0,1") | |
1055 | (set_attr "mode" "HI")]) | |
886c62d1 | 1056 | |
9076b9c1 | 1057 | (define_insn "*cmphi_minus_1" |
42fabf21 | 1058 | [(set (reg FLAGS_REG) |
9076b9c1 | 1059 | (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") |
0edb82cb | 1060 | (match_operand:HI 1 "general_operand" "rn,mr")) |
9076b9c1 JH |
1061 | (const_int 0)))] |
1062 | "ix86_match_ccmode (insn, CCGOCmode)" | |
0f40f9f7 | 1063 | "cmp{w}\t{%1, %0|%0, %1}" |
6ef67412 JH |
1064 | [(set_attr "type" "icmp") |
1065 | (set_attr "mode" "HI")]) | |
e075ae69 | 1066 | |
9076b9c1 | 1067 | (define_insn "*cmphi_1" |
42fabf21 | 1068 | [(set (reg FLAGS_REG) |
9076b9c1 | 1069 | (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") |
0edb82cb | 1070 | (match_operand:HI 1 "general_operand" "rn,mr")))] |
7656aee4 | 1071 | "!(MEM_P (operands[0]) && MEM_P (operands[1])) |
9076b9c1 | 1072 | && ix86_match_ccmode (insn, CCmode)" |
0f40f9f7 | 1073 | "cmp{w}\t{%1, %0|%0, %1}" |
9076b9c1 JH |
1074 | [(set_attr "type" "icmp") |
1075 | (set_attr "mode" "HI")]) | |
16189740 RH |
1076 | |
1077 | (define_insn "*cmpqi_ccno_1" | |
42fabf21 | 1078 | [(set (reg FLAGS_REG) |
9076b9c1 | 1079 | (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") |
0edb82cb | 1080 | (match_operand:QI 1 "const0_operand" "")))] |
9076b9c1 | 1081 | "ix86_match_ccmode (insn, CCNOmode)" |
e075ae69 | 1082 | "@ |
a23132e1 | 1083 | test{b}\t%0, %0 |
0f40f9f7 | 1084 | cmp{b}\t{$0, %0|%0, 0}" |
6ef67412 JH |
1085 | [(set_attr "type" "test,icmp") |
1086 | (set_attr "length_immediate" "0,1") | |
1087 | (set_attr "mode" "QI")]) | |
886c62d1 | 1088 | |
16189740 | 1089 | (define_insn "*cmpqi_1" |
42fabf21 | 1090 | [(set (reg FLAGS_REG) |
9076b9c1 | 1091 | (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") |
0edb82cb | 1092 | (match_operand:QI 1 "general_operand" "qn,mq")))] |
7656aee4 | 1093 | "!(MEM_P (operands[0]) && MEM_P (operands[1])) |
9076b9c1 | 1094 | && ix86_match_ccmode (insn, CCmode)" |
0f40f9f7 | 1095 | "cmp{b}\t{%1, %0|%0, %1}" |
6ef67412 JH |
1096 | [(set_attr "type" "icmp") |
1097 | (set_attr "mode" "QI")]) | |
e075ae69 | 1098 | |
9076b9c1 | 1099 | (define_insn "*cmpqi_minus_1" |
42fabf21 | 1100 | [(set (reg FLAGS_REG) |
d70401eb | 1101 | (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q") |
0edb82cb | 1102 | (match_operand:QI 1 "general_operand" "qn,mq")) |
9076b9c1 JH |
1103 | (const_int 0)))] |
1104 | "ix86_match_ccmode (insn, CCGOCmode)" | |
0f40f9f7 | 1105 | "cmp{b}\t{%1, %0|%0, %1}" |
9076b9c1 JH |
1106 | [(set_attr "type" "icmp") |
1107 | (set_attr "mode" "QI")]) | |
1108 | ||
e075ae69 | 1109 | (define_insn "*cmpqi_ext_1" |
42fabf21 | 1110 | [(set (reg FLAGS_REG) |
9076b9c1 | 1111 | (compare |
d2836273 | 1112 | (match_operand:QI 0 "general_operand" "Qm") |
e075ae69 RH |
1113 | (subreg:QI |
1114 | (zero_extract:SI | |
d2836273 | 1115 | (match_operand 1 "ext_register_operand" "Q") |
e075ae69 RH |
1116 | (const_int 8) |
1117 | (const_int 8)) 0)))] | |
d2836273 | 1118 | "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" |
0f40f9f7 | 1119 | "cmp{b}\t{%h1, %0|%0, %h1}" |
d2836273 JH |
1120 | [(set_attr "type" "icmp") |
1121 | (set_attr "mode" "QI")]) | |
1122 | ||
1123 | (define_insn "*cmpqi_ext_1_rex64" | |
42fabf21 | 1124 | [(set (reg FLAGS_REG) |
d2836273 | 1125 | (compare |
3522082b | 1126 | (match_operand:QI 0 "register_operand" "Q") |
d2836273 JH |
1127 | (subreg:QI |
1128 | (zero_extract:SI | |
1129 | (match_operand 1 "ext_register_operand" "Q") | |
1130 | (const_int 8) | |
1131 | (const_int 8)) 0)))] | |
1132 | "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" | |
0f40f9f7 | 1133 | "cmp{b}\t{%h1, %0|%0, %h1}" |
6ef67412 JH |
1134 | [(set_attr "type" "icmp") |
1135 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
1136 | |
1137 | (define_insn "*cmpqi_ext_2" | |
42fabf21 | 1138 | [(set (reg FLAGS_REG) |
16189740 | 1139 | (compare |
e075ae69 RH |
1140 | (subreg:QI |
1141 | (zero_extract:SI | |
d2836273 | 1142 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
1143 | (const_int 8) |
1144 | (const_int 8)) 0) | |
0edb82cb | 1145 | (match_operand:QI 1 "const0_operand" "")))] |
16189740 | 1146 | "ix86_match_ccmode (insn, CCNOmode)" |
0f40f9f7 | 1147 | "test{b}\t%h0, %h0" |
6ef67412 JH |
1148 | [(set_attr "type" "test") |
1149 | (set_attr "length_immediate" "0") | |
1150 | (set_attr "mode" "QI")]) | |
e075ae69 | 1151 | |
9076b9c1 | 1152 | (define_expand "cmpqi_ext_3" |
8bc527af | 1153 | [(set (reg:CC FLAGS_REG) |
e075ae69 RH |
1154 | (compare:CC |
1155 | (subreg:QI | |
1156 | (zero_extract:SI | |
d2836273 | 1157 | (match_operand 0 "ext_register_operand" "") |
e075ae69 RH |
1158 | (const_int 8) |
1159 | (const_int 8)) 0) | |
d2836273 | 1160 | (match_operand:QI 1 "general_operand" "")))] |
e075ae69 | 1161 | "" |
9076b9c1 JH |
1162 | "") |
1163 | ||
1164 | (define_insn "cmpqi_ext_3_insn" | |
42fabf21 | 1165 | [(set (reg FLAGS_REG) |
9076b9c1 JH |
1166 | (compare |
1167 | (subreg:QI | |
1168 | (zero_extract:SI | |
d2836273 | 1169 | (match_operand 0 "ext_register_operand" "Q") |
9076b9c1 JH |
1170 | (const_int 8) |
1171 | (const_int 8)) 0) | |
d2836273 JH |
1172 | (match_operand:QI 1 "general_operand" "Qmn")))] |
1173 | "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" | |
0f40f9f7 | 1174 | "cmp{b}\t{%1, %h0|%h0, %1}" |
d2836273 | 1175 | [(set_attr "type" "icmp") |
725fd454 | 1176 | (set_attr "modrm" "1") |
d2836273 JH |
1177 | (set_attr "mode" "QI")]) |
1178 | ||
1179 | (define_insn "cmpqi_ext_3_insn_rex64" | |
42fabf21 | 1180 | [(set (reg FLAGS_REG) |
d2836273 JH |
1181 | (compare |
1182 | (subreg:QI | |
1183 | (zero_extract:SI | |
1184 | (match_operand 0 "ext_register_operand" "Q") | |
1185 | (const_int 8) | |
1186 | (const_int 8)) 0) | |
1187 | (match_operand:QI 1 "nonmemory_operand" "Qn")))] | |
1188 | "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" | |
0f40f9f7 | 1189 | "cmp{b}\t{%1, %h0|%h0, %1}" |
6ef67412 | 1190 | [(set_attr "type" "icmp") |
725fd454 | 1191 | (set_attr "modrm" "1") |
6ef67412 | 1192 | (set_attr "mode" "QI")]) |
e075ae69 RH |
1193 | |
1194 | (define_insn "*cmpqi_ext_4" | |
42fabf21 | 1195 | [(set (reg FLAGS_REG) |
9076b9c1 | 1196 | (compare |
e075ae69 RH |
1197 | (subreg:QI |
1198 | (zero_extract:SI | |
d2836273 | 1199 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
1200 | (const_int 8) |
1201 | (const_int 8)) 0) | |
1202 | (subreg:QI | |
1203 | (zero_extract:SI | |
d2836273 | 1204 | (match_operand 1 "ext_register_operand" "Q") |
e075ae69 RH |
1205 | (const_int 8) |
1206 | (const_int 8)) 0)))] | |
9076b9c1 | 1207 | "ix86_match_ccmode (insn, CCmode)" |
0f40f9f7 | 1208 | "cmp{b}\t{%h1, %h0|%h0, %h1}" |
6ef67412 JH |
1209 | [(set_attr "type" "icmp") |
1210 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
1211 | |
1212 | ;; These implement float point compares. | |
1213 | ;; %%% See if we can get away with VOIDmode operands on the actual insns, | |
1214 | ;; which would allow mix and match FP modes on the compares. Which is what | |
1215 | ;; the old patterns did, but with many more of them. | |
c572e5ba | 1216 | |
f90b7a5a PB |
1217 | (define_expand "cbranchxf4" |
1218 | [(set (reg:CC FLAGS_REG) | |
1219 | (compare:CC (match_operand:XF 1 "nonmemory_operand" "") | |
1220 | (match_operand:XF 2 "nonmemory_operand" ""))) | |
1221 | (set (pc) (if_then_else | |
1222 | (match_operator 0 "comparison_operator" | |
1223 | [(reg:CC FLAGS_REG) | |
1224 | (const_int 0)]) | |
1225 | (label_ref (match_operand 3 "" "")) | |
1226 | (pc)))] | |
1227 | "TARGET_80387" | |
1228 | { | |
1229 | ix86_compare_op0 = operands[1]; | |
1230 | ix86_compare_op1 = operands[2]; | |
1231 | ix86_expand_branch (GET_CODE (operands[0]), operands[3]); | |
1232 | DONE; | |
1233 | }) | |
1234 | ||
1235 | (define_expand "cstorexf4" | |
8bc527af | 1236 | [(set (reg:CC FLAGS_REG) |
f90b7a5a PB |
1237 | (compare:CC (match_operand:XF 2 "nonmemory_operand" "") |
1238 | (match_operand:XF 3 "nonmemory_operand" ""))) | |
1239 | (set (match_operand:QI 0 "register_operand" "") | |
1240 | (match_operator 1 "comparison_operator" | |
1241 | [(reg:CC FLAGS_REG) | |
1242 | (const_int 0)]))] | |
2b589241 | 1243 | "TARGET_80387" |
2b589241 | 1244 | { |
f90b7a5a PB |
1245 | ix86_compare_op0 = operands[2]; |
1246 | ix86_compare_op1 = operands[3]; | |
1247 | ix86_expand_setcc (GET_CODE (operands[1]), operands[0]); | |
2b589241 | 1248 | DONE; |
0f40f9f7 | 1249 | }) |
2b589241 | 1250 | |
f90b7a5a | 1251 | (define_expand "cbranch<mode>4" |
8bc527af | 1252 | [(set (reg:CC FLAGS_REG) |
f90b7a5a PB |
1253 | (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "") |
1254 | (match_operand:MODEF 2 "cmp_fp_expander_operand" ""))) | |
1255 | (set (pc) (if_then_else | |
1256 | (match_operator 0 "comparison_operator" | |
1257 | [(reg:CC FLAGS_REG) | |
1258 | (const_int 0)]) | |
1259 | (label_ref (match_operand 3 "" "")) | |
1260 | (pc)))] | |
8766652c | 1261 | "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" |
c572e5ba | 1262 | { |
f90b7a5a PB |
1263 | ix86_compare_op0 = operands[1]; |
1264 | ix86_compare_op1 = operands[2]; | |
1265 | ix86_expand_branch (GET_CODE (operands[0]), operands[3]); | |
c572e5ba | 1266 | DONE; |
0f40f9f7 | 1267 | }) |
c572e5ba | 1268 | |
f90b7a5a | 1269 | (define_expand "cstore<mode>4" |
4a77c72b | 1270 | [(set (reg:CC FLAGS_REG) |
f90b7a5a PB |
1271 | (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "") |
1272 | (match_operand:MODEF 3 "cmp_fp_expander_operand" ""))) | |
1273 | (set (match_operand:QI 0 "register_operand" "") | |
1274 | (match_operator 1 "comparison_operator" | |
1275 | [(reg:CC FLAGS_REG) | |
1276 | (const_int 0)]))] | |
1277 | "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" | |
1278 | { | |
1279 | ix86_compare_op0 = operands[2]; | |
1280 | ix86_compare_op1 = operands[3]; | |
1281 | ix86_expand_setcc (GET_CODE (operands[1]), operands[0]); | |
1282 | DONE; | |
1283 | }) | |
1284 | ||
1285 | (define_expand "cbranchcc4" | |
1286 | [(set (pc) (if_then_else | |
1287 | (match_operator 0 "comparison_operator" | |
1288 | [(match_operand 1 "flags_reg_operand" "") | |
1289 | (match_operand 2 "const0_operand" "")]) | |
1290 | (label_ref (match_operand 3 "" "")) | |
1291 | (pc)))] | |
1292 | "" | |
1293 | { | |
1294 | ix86_compare_op0 = operands[1]; | |
1295 | ix86_compare_op1 = operands[2]; | |
1296 | ix86_expand_branch (GET_CODE (operands[0]), operands[3]); | |
1297 | DONE; | |
1298 | }) | |
1299 | ||
1300 | (define_expand "cstorecc4" | |
1301 | [(set (match_operand:QI 0 "register_operand" "") | |
1302 | (match_operator 1 "comparison_operator" | |
1303 | [(match_operand 2 "flags_reg_operand" "") | |
1304 | (match_operand 3 "const0_operand" "")]))] | |
4a77c72b PB |
1305 | "" |
1306 | { | |
f90b7a5a PB |
1307 | ix86_compare_op0 = operands[2]; |
1308 | ix86_compare_op1 = operands[3]; | |
1309 | ix86_expand_setcc (GET_CODE (operands[1]), operands[0]); | |
4a77c72b PB |
1310 | DONE; |
1311 | }) | |
1312 | ||
f90b7a5a | 1313 | |
e075ae69 RH |
1314 | ;; FP compares, step 1: |
1315 | ;; Set the FP condition codes. | |
1316 | ;; | |
1317 | ;; CCFPmode compare with exceptions | |
1318 | ;; CCFPUmode compare with no exceptions | |
fe4435d9 | 1319 | |
7c82106f UB |
1320 | ;; We may not use "#" to split and emit these, since the REG_DEAD notes |
1321 | ;; used to manage the reg stack popping would not be preserved. | |
1322 | ||
af12f8ea | 1323 | (define_insn "*cmpfp_0" |
45c8c47f UB |
1324 | [(set (match_operand:HI 0 "register_operand" "=a") |
1325 | (unspec:HI | |
1326 | [(compare:CCFP | |
af12f8ea | 1327 | (match_operand 1 "register_operand" "f") |
0edb82cb | 1328 | (match_operand 2 "const0_operand" ""))] |
45c8c47f | 1329 | UNSPEC_FNSTSW))] |
27ac40e2 | 1330 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
af12f8ea | 1331 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" |
7c82106f | 1332 | "* return output_fp_compare (insn, operands, 0, 0);" |
45c8c47f | 1333 | [(set_attr "type" "multi") |
af12f8ea UB |
1334 | (set_attr "unit" "i387") |
1335 | (set (attr "mode") | |
1336 | (cond [(match_operand:SF 1 "" "") | |
1337 | (const_string "SF") | |
1338 | (match_operand:DF 1 "" "") | |
1339 | (const_string "DF") | |
1340 | ] | |
1341 | (const_string "XF")))]) | |
c572e5ba | 1342 | |
1406ee90 UB |
1343 | (define_insn_and_split "*cmpfp_0_cc" |
1344 | [(set (reg:CCFP FLAGS_REG) | |
1345 | (compare:CCFP | |
1346 | (match_operand 1 "register_operand" "f") | |
0edb82cb | 1347 | (match_operand 2 "const0_operand" ""))) |
1406ee90 UB |
1348 | (clobber (match_operand:HI 0 "register_operand" "=a"))] |
1349 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) | |
1350 | && TARGET_SAHF && !TARGET_CMOVE | |
1351 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
1352 | "#" | |
1353 | "&& reload_completed" | |
1354 | [(set (match_dup 0) | |
1355 | (unspec:HI | |
1356 | [(compare:CCFP (match_dup 1)(match_dup 2))] | |
1357 | UNSPEC_FNSTSW)) | |
1358 | (set (reg:CC FLAGS_REG) | |
1359 | (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] | |
1360 | "" | |
1361 | [(set_attr "type" "multi") | |
1362 | (set_attr "unit" "i387") | |
1363 | (set (attr "mode") | |
1364 | (cond [(match_operand:SF 1 "" "") | |
1365 | (const_string "SF") | |
1366 | (match_operand:DF 1 "" "") | |
1367 | (const_string "DF") | |
1368 | ] | |
1369 | (const_string "XF")))]) | |
1370 | ||
8766652c | 1371 | (define_insn "*cmpfp_xf" |
e075ae69 RH |
1372 | [(set (match_operand:HI 0 "register_operand" "=a") |
1373 | (unspec:HI | |
1374 | [(compare:CCFP | |
8766652c UB |
1375 | (match_operand:XF 1 "register_operand" "f") |
1376 | (match_operand:XF 2 "register_operand" "f"))] | |
8ee41eaf | 1377 | UNSPEC_FNSTSW))] |
4fb21e90 | 1378 | "TARGET_80387" |
7c82106f | 1379 | "* return output_fp_compare (insn, operands, 0, 0);" |
6ef67412 | 1380 | [(set_attr "type" "multi") |
af12f8ea | 1381 | (set_attr "unit" "i387") |
8766652c | 1382 | (set_attr "mode" "XF")]) |
e075ae69 | 1383 | |
1406ee90 UB |
1384 | (define_insn_and_split "*cmpfp_xf_cc" |
1385 | [(set (reg:CCFP FLAGS_REG) | |
1386 | (compare:CCFP | |
1387 | (match_operand:XF 1 "register_operand" "f") | |
1388 | (match_operand:XF 2 "register_operand" "f"))) | |
1389 | (clobber (match_operand:HI 0 "register_operand" "=a"))] | |
1390 | "TARGET_80387 | |
1391 | && TARGET_SAHF && !TARGET_CMOVE" | |
1392 | "#" | |
1393 | "&& reload_completed" | |
1394 | [(set (match_dup 0) | |
1395 | (unspec:HI | |
1396 | [(compare:CCFP (match_dup 1)(match_dup 2))] | |
1397 | UNSPEC_FNSTSW)) | |
1398 | (set (reg:CC FLAGS_REG) | |
1399 | (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] | |
1400 | "" | |
1401 | [(set_attr "type" "multi") | |
1402 | (set_attr "unit" "i387") | |
1403 | (set_attr "mode" "XF")]) | |
1404 | ||
8766652c | 1405 | (define_insn "*cmpfp_<mode>" |
e075ae69 RH |
1406 | [(set (match_operand:HI 0 "register_operand" "=a") |
1407 | (unspec:HI | |
1408 | [(compare:CCFP | |
00188daa UB |
1409 | (match_operand:MODEF 1 "register_operand" "f") |
1410 | (match_operand:MODEF 2 "nonimmediate_operand" "fm"))] | |
8ee41eaf | 1411 | UNSPEC_FNSTSW))] |
2b589241 | 1412 | "TARGET_80387" |
7c82106f | 1413 | "* return output_fp_compare (insn, operands, 0, 0);" |
2b589241 | 1414 | [(set_attr "type" "multi") |
af12f8ea | 1415 | (set_attr "unit" "i387") |
8766652c | 1416 | (set_attr "mode" "<MODE>")]) |
2b589241 | 1417 | |
1406ee90 UB |
1418 | (define_insn_and_split "*cmpfp_<mode>_cc" |
1419 | [(set (reg:CCFP FLAGS_REG) | |
1420 | (compare:CCFP | |
00188daa UB |
1421 | (match_operand:MODEF 1 "register_operand" "f") |
1422 | (match_operand:MODEF 2 "nonimmediate_operand" "fm"))) | |
1406ee90 UB |
1423 | (clobber (match_operand:HI 0 "register_operand" "=a"))] |
1424 | "TARGET_80387 | |
1425 | && TARGET_SAHF && !TARGET_CMOVE" | |
1426 | "#" | |
1427 | "&& reload_completed" | |
1428 | [(set (match_dup 0) | |
1429 | (unspec:HI | |
1430 | [(compare:CCFP (match_dup 1)(match_dup 2))] | |
1431 | UNSPEC_FNSTSW)) | |
1432 | (set (reg:CC FLAGS_REG) | |
1433 | (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] | |
1434 | "" | |
1435 | [(set_attr "type" "multi") | |
1436 | (set_attr "unit" "i387") | |
1437 | (set_attr "mode" "<MODE>")]) | |
1438 | ||
7c82106f | 1439 | (define_insn "*cmpfp_u" |
e075ae69 RH |
1440 | [(set (match_operand:HI 0 "register_operand" "=a") |
1441 | (unspec:HI | |
1442 | [(compare:CCFPU | |
1443 | (match_operand 1 "register_operand" "f") | |
8ee41eaf RH |
1444 | (match_operand 2 "register_operand" "f"))] |
1445 | UNSPEC_FNSTSW))] | |
27ac40e2 | 1446 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
e075ae69 | 1447 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" |
7c82106f | 1448 | "* return output_fp_compare (insn, operands, 0, 1);" |
6ef67412 | 1449 | [(set_attr "type" "multi") |
af12f8ea | 1450 | (set_attr "unit" "i387") |
4977bab6 ZW |
1451 | (set (attr "mode") |
1452 | (cond [(match_operand:SF 1 "" "") | |
1453 | (const_string "SF") | |
1454 | (match_operand:DF 1 "" "") | |
1455 | (const_string "DF") | |
1456 | ] | |
1457 | (const_string "XF")))]) | |
08a7baac | 1458 | |
1406ee90 UB |
1459 | (define_insn_and_split "*cmpfp_u_cc" |
1460 | [(set (reg:CCFPU FLAGS_REG) | |
1461 | (compare:CCFPU | |
1462 | (match_operand 1 "register_operand" "f") | |
1463 | (match_operand 2 "register_operand" "f"))) | |
1464 | (clobber (match_operand:HI 0 "register_operand" "=a"))] | |
1465 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) | |
1466 | && TARGET_SAHF && !TARGET_CMOVE | |
1467 | && GET_MODE (operands[1]) == GET_MODE (operands[2])" | |
1468 | "#" | |
1469 | "&& reload_completed" | |
1470 | [(set (match_dup 0) | |
1471 | (unspec:HI | |
1472 | [(compare:CCFPU (match_dup 1)(match_dup 2))] | |
1473 | UNSPEC_FNSTSW)) | |
1474 | (set (reg:CC FLAGS_REG) | |
1475 | (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] | |
1476 | "" | |
1477 | [(set_attr "type" "multi") | |
1478 | (set_attr "unit" "i387") | |
1479 | (set (attr "mode") | |
1480 | (cond [(match_operand:SF 1 "" "") | |
1481 | (const_string "SF") | |
1482 | (match_operand:DF 1 "" "") | |
1483 | (const_string "DF") | |
1484 | ] | |
1485 | (const_string "XF")))]) | |
1486 | ||
0e8c2b0d | 1487 | (define_insn "*cmpfp_<mode>" |
7c82106f UB |
1488 | [(set (match_operand:HI 0 "register_operand" "=a") |
1489 | (unspec:HI | |
1490 | [(compare:CCFP | |
1491 | (match_operand 1 "register_operand" "f") | |
1492 | (match_operator 3 "float_operator" | |
0e8c2b0d | 1493 | [(match_operand:X87MODEI12 2 "memory_operand" "m")]))] |
7c82106f | 1494 | UNSPEC_FNSTSW))] |
27ac40e2 | 1495 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
3debdc1e | 1496 | && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) |
7c82106f UB |
1497 | && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" |
1498 | "* return output_fp_compare (insn, operands, 0, 0);" | |
1499 | [(set_attr "type" "multi") | |
af12f8ea | 1500 | (set_attr "unit" "i387") |
7c82106f | 1501 | (set_attr "fp_int_src" "true") |
0e8c2b0d | 1502 | (set_attr "mode" "<MODE>")]) |
e075ae69 | 1503 | |
1406ee90 UB |
1504 | (define_insn_and_split "*cmpfp_<mode>_cc" |
1505 | [(set (reg:CCFP FLAGS_REG) | |
1506 | (compare:CCFP | |
1507 | (match_operand 1 "register_operand" "f") | |
1508 | (match_operator 3 "float_operator" | |
1509 | [(match_operand:X87MODEI12 2 "memory_operand" "m")]))) | |
1510 | (clobber (match_operand:HI 0 "register_operand" "=a"))] | |
1511 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) | |
1512 | && TARGET_SAHF && !TARGET_CMOVE | |
3debdc1e | 1513 | && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) |
1406ee90 UB |
1514 | && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" |
1515 | "#" | |
1516 | "&& reload_completed" | |
1517 | [(set (match_dup 0) | |
1518 | (unspec:HI | |
1519 | [(compare:CCFP | |
1520 | (match_dup 1) | |
1521 | (match_op_dup 3 [(match_dup 2)]))] | |
1522 | UNSPEC_FNSTSW)) | |
1523 | (set (reg:CC FLAGS_REG) | |
1524 | (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] | |
1525 | "" | |
1526 | [(set_attr "type" "multi") | |
1527 | (set_attr "unit" "i387") | |
1528 | (set_attr "fp_int_src" "true") | |
1529 | (set_attr "mode" "<MODE>")]) | |
1530 | ||
e075ae69 RH |
1531 | ;; FP compares, step 2 |
1532 | ;; Move the fpsw to ax. | |
1533 | ||
5ae27cfa | 1534 | (define_insn "x86_fnstsw_1" |
e075ae69 | 1535 | [(set (match_operand:HI 0 "register_operand" "=a") |
8bc527af | 1536 | (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] |
2ae0f82c | 1537 | "TARGET_80387" |
0f40f9f7 | 1538 | "fnstsw\t%0" |
725fd454 | 1539 | [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2")) |
6ef67412 | 1540 | (set_attr "mode" "SI") |
56bab446 | 1541 | (set_attr "unit" "i387")]) |
e075ae69 RH |
1542 | |
1543 | ;; FP compares, step 3 | |
1544 | ;; Get ax into flags, general case. | |
1545 | ||
1546 | (define_insn "x86_sahf_1" | |
8bc527af | 1547 | [(set (reg:CC FLAGS_REG) |
3c2d980c UB |
1548 | (unspec:CC [(match_operand:HI 0 "register_operand" "a")] |
1549 | UNSPEC_SAHF))] | |
1550 | "TARGET_SAHF" | |
419452fe UB |
1551 | { |
1552 | #ifdef HAVE_AS_IX86_SAHF | |
1553 | return "sahf"; | |
1554 | #else | |
1555 | return ".byte\t0x9e"; | |
1556 | #endif | |
1557 | } | |
e075ae69 | 1558 | [(set_attr "length" "1") |
0b5107cf | 1559 | (set_attr "athlon_decode" "vector") |
21efb4d4 | 1560 | (set_attr "amdfam10_decode" "direct") |
56bab446 | 1561 | (set_attr "mode" "SI")]) |
e075ae69 RH |
1562 | |
1563 | ;; Pentium Pro can do steps 1 through 3 in one go. | |
4f3f76e6 | 1564 | ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) |
eaa49b49 | 1565 | (define_insn "*cmpfp_i_mixed" |
8bc527af | 1566 | [(set (reg:CCFP FLAGS_REG) |
b5c82fa1 PB |
1567 | (compare:CCFP (match_operand 0 "register_operand" "f,x") |
1568 | (match_operand 1 "nonimmediate_operand" "f,xm")))] | |
eaa49b49 | 1569 | "TARGET_MIX_SSE_I387 |
0644b628 | 1570 | && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) |
869d095e | 1571 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" |
0644b628 | 1572 | "* return output_fp_compare (insn, operands, 1, 0);" |
26771da7 | 1573 | [(set_attr "type" "fcmp,ssecomi") |
95879c72 | 1574 | (set_attr "prefix" "orig,maybe_vex") |
4977bab6 ZW |
1575 | (set (attr "mode") |
1576 | (if_then_else (match_operand:SF 1 "" "") | |
1577 | (const_string "SF") | |
1578 | (const_string "DF"))) | |
725fd454 JJ |
1579 | (set (attr "prefix_rep") |
1580 | (if_then_else (eq_attr "type" "ssecomi") | |
1581 | (const_string "0") | |
1582 | (const_string "*"))) | |
1583 | (set (attr "prefix_data16") | |
1584 | (cond [(eq_attr "type" "fcmp") | |
1585 | (const_string "*") | |
1586 | (eq_attr "mode" "DF") | |
1587 | (const_string "1") | |
1588 | ] | |
1589 | (const_string "0"))) | |
21efb4d4 HJ |
1590 | (set_attr "athlon_decode" "vector") |
1591 | (set_attr "amdfam10_decode" "direct")]) | |
0644b628 | 1592 | |
eaa49b49 | 1593 | (define_insn "*cmpfp_i_sse" |
8bc527af | 1594 | [(set (reg:CCFP FLAGS_REG) |
0644b628 JH |
1595 | (compare:CCFP (match_operand 0 "register_operand" "x") |
1596 | (match_operand 1 "nonimmediate_operand" "xm")))] | |
eaa49b49 RH |
1597 | "TARGET_SSE_MATH |
1598 | && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) | |
869d095e | 1599 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" |
0644b628 | 1600 | "* return output_fp_compare (insn, operands, 1, 0);" |
26771da7 | 1601 | [(set_attr "type" "ssecomi") |
95879c72 | 1602 | (set_attr "prefix" "maybe_vex") |
4977bab6 ZW |
1603 | (set (attr "mode") |
1604 | (if_then_else (match_operand:SF 1 "" "") | |
1605 | (const_string "SF") | |
1606 | (const_string "DF"))) | |
725fd454 JJ |
1607 | (set_attr "prefix_rep" "0") |
1608 | (set (attr "prefix_data16") | |
1609 | (if_then_else (eq_attr "mode" "DF") | |
1610 | (const_string "1") | |
1611 | (const_string "0"))) | |
21efb4d4 HJ |
1612 | (set_attr "athlon_decode" "vector") |
1613 | (set_attr "amdfam10_decode" "direct")]) | |
0644b628 | 1614 | |
eaa49b49 RH |
1615 | (define_insn "*cmpfp_i_i387" |
1616 | [(set (reg:CCFP FLAGS_REG) | |
1617 | (compare:CCFP (match_operand 0 "register_operand" "f") | |
1618 | (match_operand 1 "register_operand" "f")))] | |
27ac40e2 UB |
1619 | "X87_FLOAT_MODE_P (GET_MODE (operands[0])) |
1620 | && TARGET_CMOVE | |
00188daa | 1621 | && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH) |
e075ae69 | 1622 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" |
eaa49b49 | 1623 | "* return output_fp_compare (insn, operands, 1, 0);" |
309ada50 | 1624 | [(set_attr "type" "fcmp") |
4977bab6 ZW |
1625 | (set (attr "mode") |
1626 | (cond [(match_operand:SF 1 "" "") | |
1627 | (const_string "SF") | |
1628 | (match_operand:DF 1 "" "") | |
1629 | (const_string "DF") | |
1630 | ] | |
1631 | (const_string "XF"))) | |
21efb4d4 HJ |
1632 | (set_attr "athlon_decode" "vector") |
1633 | (set_attr "amdfam10_decode" "direct")]) | |
0644b628 | 1634 | |
eaa49b49 | 1635 | (define_insn "*cmpfp_iu_mixed" |
8bc527af | 1636 | [(set (reg:CCFPU FLAGS_REG) |
b5c82fa1 PB |
1637 | (compare:CCFPU (match_operand 0 "register_operand" "f,x") |
1638 | (match_operand 1 "nonimmediate_operand" "f,xm")))] | |
eaa49b49 | 1639 | "TARGET_MIX_SSE_I387 |
0644b628 JH |
1640 | && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) |
1641 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" | |
1642 | "* return output_fp_compare (insn, operands, 1, 1);" | |
26771da7 | 1643 | [(set_attr "type" "fcmp,ssecomi") |
95879c72 | 1644 | (set_attr "prefix" "orig,maybe_vex") |
4977bab6 ZW |
1645 | (set (attr "mode") |
1646 | (if_then_else (match_operand:SF 1 "" "") | |
1647 | (const_string "SF") | |
1648 | (const_string "DF"))) | |
725fd454 JJ |
1649 | (set (attr "prefix_rep") |
1650 | (if_then_else (eq_attr "type" "ssecomi") | |
1651 | (const_string "0") | |
1652 | (const_string "*"))) | |
1653 | (set (attr "prefix_data16") | |
1654 | (cond [(eq_attr "type" "fcmp") | |
1655 | (const_string "*") | |
1656 | (eq_attr "mode" "DF") | |
1657 | (const_string "1") | |
1658 | ] | |
1659 | (const_string "0"))) | |
21efb4d4 HJ |
1660 | (set_attr "athlon_decode" "vector") |
1661 | (set_attr "amdfam10_decode" "direct")]) | |
0644b628 | 1662 | |
eaa49b49 | 1663 | (define_insn "*cmpfp_iu_sse" |
8bc527af | 1664 | [(set (reg:CCFPU FLAGS_REG) |
0644b628 JH |
1665 | (compare:CCFPU (match_operand 0 "register_operand" "x") |
1666 | (match_operand 1 "nonimmediate_operand" "xm")))] | |
eaa49b49 RH |
1667 | "TARGET_SSE_MATH |
1668 | && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) | |
0644b628 JH |
1669 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" |
1670 | "* return output_fp_compare (insn, operands, 1, 1);" | |
26771da7 | 1671 | [(set_attr "type" "ssecomi") |
95879c72 | 1672 | (set_attr "prefix" "maybe_vex") |
4977bab6 ZW |
1673 | (set (attr "mode") |
1674 | (if_then_else (match_operand:SF 1 "" "") | |
1675 | (const_string "SF") | |
1676 | (const_string "DF"))) | |
725fd454 JJ |
1677 | (set_attr "prefix_rep" "0") |
1678 | (set (attr "prefix_data16") | |
1679 | (if_then_else (eq_attr "mode" "DF") | |
1680 | (const_string "1") | |
1681 | (const_string "0"))) | |
21efb4d4 HJ |
1682 | (set_attr "athlon_decode" "vector") |
1683 | (set_attr "amdfam10_decode" "direct")]) | |
eaa49b49 RH |
1684 | |
1685 | (define_insn "*cmpfp_iu_387" | |
1686 | [(set (reg:CCFPU FLAGS_REG) | |
1687 | (compare:CCFPU (match_operand 0 "register_operand" "f") | |
1688 | (match_operand 1 "register_operand" "f")))] | |
27ac40e2 UB |
1689 | "X87_FLOAT_MODE_P (GET_MODE (operands[0])) |
1690 | && TARGET_CMOVE | |
00188daa | 1691 | && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH) |
eaa49b49 RH |
1692 | && GET_MODE (operands[0]) == GET_MODE (operands[1])" |
1693 | "* return output_fp_compare (insn, operands, 1, 1);" | |
1694 | [(set_attr "type" "fcmp") | |
1695 | (set (attr "mode") | |
1696 | (cond [(match_operand:SF 1 "" "") | |
1697 | (const_string "SF") | |
1698 | (match_operand:DF 1 "" "") | |
1699 | (const_string "DF") | |
1700 | ] | |
1701 | (const_string "XF"))) | |
21efb4d4 HJ |
1702 | (set_attr "athlon_decode" "vector") |
1703 | (set_attr "amdfam10_decode" "direct")]) | |
e075ae69 RH |
1704 | \f |
1705 | ;; Move instructions. | |
2ae0f82c | 1706 | |
e075ae69 | 1707 | ;; General case of fullword move. |
886c62d1 | 1708 | |
e075ae69 RH |
1709 | (define_expand "movsi" |
1710 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
1711 | (match_operand:SI 1 "general_operand" ""))] | |
1712 | "" | |
1713 | "ix86_expand_move (SImode, operands); DONE;") | |
08a7baac | 1714 | |
e075ae69 RH |
1715 | ;; Push/pop instructions. They are separate since autoinc/dec is not a |
1716 | ;; general_operand. | |
1717 | ;; | |
6300f037 | 1718 | ;; %%% We don't use a post-inc memory reference because x86 is not a |
e075ae69 RH |
1719 | ;; general AUTO_INC_DEC host, which impacts how it is treated in flow. |
1720 | ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC | |
1721 | ;; targets without our curiosities, and it is just as easy to represent | |
1722 | ;; this differently. | |
886c62d1 | 1723 | |
a4414093 | 1724 | (define_insn "*pushsi2" |
e075ae69 | 1725 | [(set (match_operand:SI 0 "push_operand" "=<") |
2c5a510c | 1726 | (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] |
0ec259ed | 1727 | "!TARGET_64BIT" |
0f40f9f7 | 1728 | "push{l}\t%1" |
6ef67412 JH |
1729 | [(set_attr "type" "push") |
1730 | (set_attr "mode" "SI")]) | |
4fb21e90 | 1731 | |
0ec259ed JH |
1732 | ;; For 64BIT abi we always round up to 8 bytes. |
1733 | (define_insn "*pushsi2_rex64" | |
1734 | [(set (match_operand:SI 0 "push_operand" "=X") | |
1735 | (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))] | |
1736 | "TARGET_64BIT" | |
0f40f9f7 | 1737 | "push{q}\t%q1" |
0ec259ed JH |
1738 | [(set_attr "type" "push") |
1739 | (set_attr "mode" "SI")]) | |
1740 | ||
bdeb029c JH |
1741 | (define_insn "*pushsi2_prologue" |
1742 | [(set (match_operand:SI 0 "push_operand" "=<") | |
1743 | (match_operand:SI 1 "general_no_elim_operand" "ri*m")) | |
f2042df3 | 1744 | (clobber (mem:BLK (scratch)))] |
0ec259ed | 1745 | "!TARGET_64BIT" |
0f40f9f7 | 1746 | "push{l}\t%1" |
6ef67412 JH |
1747 | [(set_attr "type" "push") |
1748 | (set_attr "mode" "SI")]) | |
bdeb029c JH |
1749 | |
1750 | (define_insn "*popsi1_epilogue" | |
1751 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") | |
8bc527af SB |
1752 | (mem:SI (reg:SI SP_REG))) |
1753 | (set (reg:SI SP_REG) | |
1754 | (plus:SI (reg:SI SP_REG) (const_int 4))) | |
f2042df3 | 1755 | (clobber (mem:BLK (scratch)))] |
1e07edd3 | 1756 | "!TARGET_64BIT" |
0f40f9f7 | 1757 | "pop{l}\t%0" |
6ef67412 JH |
1758 | [(set_attr "type" "pop") |
1759 | (set_attr "mode" "SI")]) | |
bdeb029c | 1760 | |
e075ae69 RH |
1761 | (define_insn "popsi1" |
1762 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") | |
8bc527af SB |
1763 | (mem:SI (reg:SI SP_REG))) |
1764 | (set (reg:SI SP_REG) | |
1765 | (plus:SI (reg:SI SP_REG) (const_int 4)))] | |
1e07edd3 | 1766 | "!TARGET_64BIT" |
0f40f9f7 | 1767 | "pop{l}\t%0" |
6ef67412 JH |
1768 | [(set_attr "type" "pop") |
1769 | (set_attr "mode" "SI")]) | |
c572e5ba | 1770 | |
a8bac9ab | 1771 | (define_insn "*movsi_xor" |
591702de | 1772 | [(set (match_operand:SI 0 "register_operand" "=r") |
0edb82cb | 1773 | (match_operand:SI 1 "const0_operand" "")) |
8bc527af | 1774 | (clobber (reg:CC FLAGS_REG))] |
18bd082d | 1775 | "reload_completed" |
a23132e1 | 1776 | "xor{l}\t%0, %0" |
591702de | 1777 | [(set_attr "type" "alu1") |
6ef67412 JH |
1778 | (set_attr "mode" "SI") |
1779 | (set_attr "length_immediate" "0")]) | |
6300f037 | 1780 | |
591702de JH |
1781 | (define_insn "*movsi_or" |
1782 | [(set (match_operand:SI 0 "register_operand" "=r") | |
1783 | (match_operand:SI 1 "immediate_operand" "i")) | |
8bc527af | 1784 | (clobber (reg:CC FLAGS_REG))] |
87d9741e | 1785 | "reload_completed |
18bd082d | 1786 | && operands[1] == constm1_rtx" |
c572e5ba | 1787 | { |
591702de | 1788 | operands[1] = constm1_rtx; |
0f40f9f7 ZW |
1789 | return "or{l}\t{%1, %0|%0, %1}"; |
1790 | } | |
591702de | 1791 | [(set_attr "type" "alu1") |
6ef67412 JH |
1792 | (set_attr "mode" "SI") |
1793 | (set_attr "length_immediate" "1")]) | |
e075ae69 | 1794 | |
591702de | 1795 | (define_insn "*movsi_1" |
6c4ccfd8 | 1796 | [(set (match_operand:SI 0 "nonimmediate_operand" |
0edb82cb | 1797 | "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") |
6c4ccfd8 | 1798 | (match_operand:SI 1 "general_operand" |
0edb82cb | 1799 | "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] |
f75959a6 | 1800 | "!(MEM_P (operands[0]) && MEM_P (operands[1]))" |
8f62128d JH |
1801 | { |
1802 | switch (get_attr_type (insn)) | |
1803 | { | |
f75959a6 | 1804 | case TYPE_SSELOG1: |
1d5b4e0b | 1805 | if (get_attr_mode (insn) == MODE_TI) |
95879c72 L |
1806 | return "%vpxor\t%0, %d0"; |
1807 | return "%vxorps\t%0, %d0"; | |
8f62128d | 1808 | |
5f90a099 | 1809 | case TYPE_SSEMOV: |
f75959a6 RH |
1810 | switch (get_attr_mode (insn)) |
1811 | { | |
1812 | case MODE_TI: | |
95879c72 | 1813 | return "%vmovdqa\t{%1, %0|%0, %1}"; |
f75959a6 | 1814 | case MODE_V4SF: |
95879c72 | 1815 | return "%vmovaps\t{%1, %0|%0, %1}"; |
f75959a6 | 1816 | case MODE_SI: |
95879c72 | 1817 | return "%vmovd\t{%1, %0|%0, %1}"; |
f75959a6 | 1818 | case MODE_SF: |
95879c72 | 1819 | return "%vmovss\t{%1, %0|%0, %1}"; |
f75959a6 RH |
1820 | default: |
1821 | gcc_unreachable (); | |
1822 | } | |
1823 | ||
87673f84 | 1824 | case TYPE_MMX: |
f75959a6 | 1825 | return "pxor\t%0, %0"; |
141e454b | 1826 | |
5f90a099 | 1827 | case TYPE_MMXMOV: |
1d5b4e0b | 1828 | if (get_attr_mode (insn) == MODE_DI) |
e5a20888 | 1829 | return "movq\t{%1, %0|%0, %1}"; |
0f40f9f7 | 1830 | return "movd\t{%1, %0|%0, %1}"; |
915119a5 | 1831 | |
e075ae69 | 1832 | case TYPE_LEA: |
0f40f9f7 | 1833 | return "lea{l}\t{%1, %0|%0, %1}"; |
915119a5 | 1834 | |
e075ae69 | 1835 | default: |
7637e42c | 1836 | gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); |
0f40f9f7 | 1837 | return "mov{l}\t{%1, %0|%0, %1}"; |
886c62d1 | 1838 | } |
0f40f9f7 | 1839 | } |
e075ae69 | 1840 | [(set (attr "type") |
f75959a6 | 1841 | (cond [(eq_attr "alternative" "2") |
87673f84 | 1842 | (const_string "mmx") |
f75959a6 | 1843 | (eq_attr "alternative" "3,4,5") |
3d34cd91 | 1844 | (const_string "mmxmov") |
f75959a6 RH |
1845 | (eq_attr "alternative" "6") |
1846 | (const_string "sselog1") | |
1847 | (eq_attr "alternative" "7,8,9,10,11") | |
3d34cd91 | 1848 | (const_string "ssemov") |
47efdea4 | 1849 | (match_operand:DI 1 "pic_32bit_operand" "") |
e075ae69 RH |
1850 | (const_string "lea") |
1851 | ] | |
6ef67412 | 1852 | (const_string "imov"))) |
95879c72 L |
1853 | (set (attr "prefix") |
1854 | (if_then_else (eq_attr "alternative" "0,1,2,3,4,5") | |
1855 | (const_string "orig") | |
1856 | (const_string "maybe_vex"))) | |
725fd454 JJ |
1857 | (set (attr "prefix_data16") |
1858 | (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) | |
1859 | (const_string "1") | |
1860 | (const_string "*"))) | |
f75959a6 RH |
1861 | (set (attr "mode") |
1862 | (cond [(eq_attr "alternative" "2,3") | |
1863 | (const_string "DI") | |
1864 | (eq_attr "alternative" "6,7") | |
1865 | (if_then_else | |
1866 | (eq (symbol_ref "TARGET_SSE2") (const_int 0)) | |
1867 | (const_string "V4SF") | |
1868 | (const_string "TI")) | |
1869 | (and (eq_attr "alternative" "8,9,10,11") | |
1870 | (eq (symbol_ref "TARGET_SSE2") (const_int 0))) | |
1871 | (const_string "SF") | |
1872 | ] | |
1873 | (const_string "SI")))]) | |
e075ae69 | 1874 | |
d1f87653 | 1875 | ;; Stores and loads of ax to arbitrary constant address. |
0ec259ed JH |
1876 | ;; We fake an second form of instruction to force reload to load address |
1877 | ;; into register when rax is not available | |
1878 | (define_insn "*movabssi_1_rex64" | |
7e6dc358 JJ |
1879 | [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) |
1880 | (match_operand:SI 1 "nonmemory_operand" "a,er"))] | |
1881 | "TARGET_64BIT && ix86_check_movabs (insn, 0)" | |
0ec259ed | 1882 | "@ |
0f40f9f7 | 1883 | movabs{l}\t{%1, %P0|%P0, %1} |
7e6dc358 | 1884 | mov{l}\t{%1, %a0|%a0, %1}" |
0ec259ed | 1885 | [(set_attr "type" "imov") |
7e6dc358 JJ |
1886 | (set_attr "modrm" "0,*") |
1887 | (set_attr "length_address" "8,0") | |
1888 | (set_attr "length_immediate" "0,*") | |
0ec259ed JH |
1889 | (set_attr "memory" "store") |
1890 | (set_attr "mode" "SI")]) | |
1891 | ||
1892 | (define_insn "*movabssi_2_rex64" | |
1893 | [(set (match_operand:SI 0 "register_operand" "=a,r") | |
1894 | (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] | |
7e6dc358 | 1895 | "TARGET_64BIT && ix86_check_movabs (insn, 1)" |
0ec259ed | 1896 | "@ |
0f40f9f7 ZW |
1897 | movabs{l}\t{%P1, %0|%0, %P1} |
1898 | mov{l}\t{%a1, %0|%0, %a1}" | |
0ec259ed JH |
1899 | [(set_attr "type" "imov") |
1900 | (set_attr "modrm" "0,*") | |
1901 | (set_attr "length_address" "8,0") | |
1902 | (set_attr "length_immediate" "0") | |
1903 | (set_attr "memory" "load") | |
1904 | (set_attr "mode" "SI")]) | |
1905 | ||
e075ae69 RH |
1906 | (define_insn "*swapsi" |
1907 | [(set (match_operand:SI 0 "register_operand" "+r") | |
1908 | (match_operand:SI 1 "register_operand" "+r")) | |
1909 | (set (match_dup 1) | |
1910 | (match_dup 0))] | |
2bb7a0f5 | 1911 | "" |
0f40f9f7 | 1912 | "xchg{l}\t%1, %0" |
e075ae69 | 1913 | [(set_attr "type" "imov") |
6ef67412 | 1914 | (set_attr "mode" "SI") |
7cc6af0c | 1915 | (set_attr "pent_pair" "np") |
21efb4d4 | 1916 | (set_attr "athlon_decode" "vector") |
4f3f76e6 | 1917 | (set_attr "amdfam10_decode" "double")]) |
886c62d1 | 1918 | |
e075ae69 RH |
1919 | (define_expand "movhi" |
1920 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
1921 | (match_operand:HI 1 "general_operand" ""))] | |
ca097615 | 1922 | "" |
e075ae69 | 1923 | "ix86_expand_move (HImode, operands); DONE;") |
2f2a49e8 | 1924 | |
a4414093 | 1925 | (define_insn "*pushhi2" |
6541fe75 JJ |
1926 | [(set (match_operand:HI 0 "push_operand" "=X") |
1927 | (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))] | |
1e07edd3 | 1928 | "!TARGET_64BIT" |
6541fe75 | 1929 | "push{l}\t%k1" |
6ef67412 | 1930 | [(set_attr "type" "push") |
6541fe75 | 1931 | (set_attr "mode" "SI")]) |
e075ae69 | 1932 | |
b3298882 JH |
1933 | ;; For 64BIT abi we always round up to 8 bytes. |
1934 | (define_insn "*pushhi2_rex64" | |
1935 | [(set (match_operand:HI 0 "push_operand" "=X") | |
0edb82cb | 1936 | (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))] |
b3298882 | 1937 | "TARGET_64BIT" |
0f40f9f7 | 1938 | "push{q}\t%q1" |
b3298882 | 1939 | [(set_attr "type" "push") |
6541fe75 | 1940 | (set_attr "mode" "DI")]) |
b3298882 | 1941 | |
e075ae69 | 1942 | (define_insn "*movhi_1" |
9b73c90a EB |
1943 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") |
1944 | (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] | |
7656aee4 | 1945 | "!(MEM_P (operands[0]) && MEM_P (operands[1]))" |
886c62d1 | 1946 | { |
e075ae69 | 1947 | switch (get_attr_type (insn)) |
886c62d1 | 1948 | { |
e075ae69 RH |
1949 | case TYPE_IMOVX: |
1950 | /* movzwl is faster than movw on p2 due to partial word stalls, | |
1951 | though not as fast as an aligned movl. */ | |
0f40f9f7 | 1952 | return "movz{wl|x}\t{%1, %k0|%k0, %1}"; |
e075ae69 | 1953 | default: |
6ef67412 | 1954 | if (get_attr_mode (insn) == MODE_SI) |
0f40f9f7 | 1955 | return "mov{l}\t{%k1, %k0|%k0, %k1}"; |
e075ae69 | 1956 | else |
0f40f9f7 | 1957 | return "mov{w}\t{%1, %0|%0, %1}"; |
886c62d1 | 1958 | } |
0f40f9f7 | 1959 | } |
e075ae69 | 1960 | [(set (attr "type") |
3debdc1e | 1961 | (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)) |
68f48f39 RS |
1962 | (const_string "imov") |
1963 | (and (eq_attr "alternative" "0") | |
0b5107cf JH |
1964 | (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") |
1965 | (const_int 0)) | |
1966 | (eq (symbol_ref "TARGET_HIMODE_MATH") | |
1967 | (const_int 0)))) | |
369e59b1 | 1968 | (const_string "imov") |
9b73c90a | 1969 | (and (eq_attr "alternative" "1,2") |
2247f6ed | 1970 | (match_operand:HI 1 "aligned_operand" "")) |
e075ae69 RH |
1971 | (const_string "imov") |
1972 | (and (ne (symbol_ref "TARGET_MOVX") | |
1973 | (const_int 0)) | |
9b73c90a | 1974 | (eq_attr "alternative" "0,2")) |
e075ae69 RH |
1975 | (const_string "imovx") |
1976 | ] | |
1977 | (const_string "imov"))) | |
6ef67412 | 1978 | (set (attr "mode") |
e075ae69 | 1979 | (cond [(eq_attr "type" "imovx") |
6ef67412 | 1980 | (const_string "SI") |
9b73c90a | 1981 | (and (eq_attr "alternative" "1,2") |
369e59b1 | 1982 | (match_operand:HI 1 "aligned_operand" "")) |
6ef67412 | 1983 | (const_string "SI") |
9b73c90a | 1984 | (and (eq_attr "alternative" "0") |
0b5107cf JH |
1985 | (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") |
1986 | (const_int 0)) | |
1987 | (eq (symbol_ref "TARGET_HIMODE_MATH") | |
1988 | (const_int 0)))) | |
6ef67412 | 1989 | (const_string "SI") |
e075ae69 | 1990 | ] |
9b73c90a | 1991 | (const_string "HI")))]) |
e075ae69 | 1992 | |
d1f87653 | 1993 | ;; Stores and loads of ax to arbitrary constant address. |
0ec259ed JH |
1994 | ;; We fake an second form of instruction to force reload to load address |
1995 | ;; into register when rax is not available | |
1996 | (define_insn "*movabshi_1_rex64" | |
7e6dc358 JJ |
1997 | [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) |
1998 | (match_operand:HI 1 "nonmemory_operand" "a,er"))] | |
1999 | "TARGET_64BIT && ix86_check_movabs (insn, 0)" | |
0ec259ed | 2000 | "@ |
0f40f9f7 | 2001 | movabs{w}\t{%1, %P0|%P0, %1} |
7e6dc358 | 2002 | mov{w}\t{%1, %a0|%a0, %1}" |
0ec259ed | 2003 | [(set_attr "type" "imov") |
7e6dc358 JJ |
2004 | (set_attr "modrm" "0,*") |
2005 | (set_attr "length_address" "8,0") | |
2006 | (set_attr "length_immediate" "0,*") | |
0ec259ed JH |
2007 | (set_attr "memory" "store") |
2008 | (set_attr "mode" "HI")]) | |
2009 | ||
2010 | (define_insn "*movabshi_2_rex64" | |
2011 | [(set (match_operand:HI 0 "register_operand" "=a,r") | |
2012 | (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] | |
7e6dc358 | 2013 | "TARGET_64BIT && ix86_check_movabs (insn, 1)" |
0ec259ed | 2014 | "@ |
0f40f9f7 ZW |
2015 | movabs{w}\t{%P1, %0|%0, %P1} |
2016 | mov{w}\t{%a1, %0|%0, %a1}" | |
0ec259ed JH |
2017 | [(set_attr "type" "imov") |
2018 | (set_attr "modrm" "0,*") | |
2019 | (set_attr "length_address" "8,0") | |
2020 | (set_attr "length_immediate" "0") | |
2021 | (set_attr "memory" "load") | |
2022 | (set_attr "mode" "HI")]) | |
2023 | ||
e075ae69 RH |
2024 | (define_insn "*swaphi_1" |
2025 | [(set (match_operand:HI 0 "register_operand" "+r") | |
2026 | (match_operand:HI 1 "register_operand" "+r")) | |
2027 | (set (match_dup 1) | |
2028 | (match_dup 0))] | |
3debdc1e | 2029 | "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" |
7cc6af0c | 2030 | "xchg{l}\t%k1, %k0" |
e075ae69 | 2031 | [(set_attr "type" "imov") |
7cc6af0c | 2032 | (set_attr "mode" "SI") |
e075ae69 | 2033 | (set_attr "pent_pair" "np") |
21efb4d4 | 2034 | (set_attr "athlon_decode" "vector") |
4f3f76e6 | 2035 | (set_attr "amdfam10_decode" "double")]) |
e075ae69 | 2036 | |
21efb4d4 | 2037 | ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10 |
e075ae69 RH |
2038 | (define_insn "*swaphi_2" |
2039 | [(set (match_operand:HI 0 "register_operand" "+r") | |
2040 | (match_operand:HI 1 "register_operand" "+r")) | |
2041 | (set (match_dup 1) | |
2042 | (match_dup 0))] | |
7cc6af0c RH |
2043 | "TARGET_PARTIAL_REG_STALL" |
2044 | "xchg{w}\t%1, %0" | |
e075ae69 | 2045 | [(set_attr "type" "imov") |
7cc6af0c | 2046 | (set_attr "mode" "HI") |
e075ae69 | 2047 | (set_attr "pent_pair" "np") |
7cc6af0c | 2048 | (set_attr "athlon_decode" "vector")]) |
886c62d1 | 2049 | |
2f2a49e8 | 2050 | (define_expand "movstricthi" |
e075ae69 | 2051 | [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) |
2f2a49e8 | 2052 | (match_operand:HI 1 "general_operand" ""))] |
3debdc1e | 2053 | "" |
2f2a49e8 | 2054 | { |
3debdc1e JH |
2055 | if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) |
2056 | FAIL; | |
2f2a49e8 | 2057 | /* Don't generate memory->memory moves, go through a register */ |
7656aee4 | 2058 | if (MEM_P (operands[0]) && MEM_P (operands[1])) |
e075ae69 | 2059 | operands[1] = force_reg (HImode, operands[1]); |
0f40f9f7 | 2060 | }) |
2f2a49e8 | 2061 | |
e075ae69 | 2062 | (define_insn "*movstricthi_1" |
fc524c1c | 2063 | [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r")) |
e075ae69 | 2064 | (match_operand:HI 1 "general_operand" "rn,m"))] |
3debdc1e | 2065 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 2066 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 2067 | "mov{w}\t{%1, %0|%0, %1}" |
6ef67412 JH |
2068 | [(set_attr "type" "imov") |
2069 | (set_attr "mode" "HI")]) | |
2070 | ||
2071 | (define_insn "*movstricthi_xor" | |
208b0ab1 | 2072 | [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) |
0edb82cb | 2073 | (match_operand:HI 1 "const0_operand" "")) |
8bc527af | 2074 | (clobber (reg:CC FLAGS_REG))] |
18bd082d | 2075 | "reload_completed" |
a23132e1 | 2076 | "xor{w}\t%0, %0" |
6ef67412 JH |
2077 | [(set_attr "type" "alu1") |
2078 | (set_attr "mode" "HI") | |
2079 | (set_attr "length_immediate" "0")]) | |
886c62d1 | 2080 | |
2f2a49e8 | 2081 | (define_expand "movqi" |
4cbfbb1b | 2082 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
2f2a49e8 MM |
2083 | (match_operand:QI 1 "general_operand" ""))] |
2084 | "" | |
e075ae69 RH |
2085 | "ix86_expand_move (QImode, operands); DONE;") |
2086 | ||
7dd4b4a3 | 2087 | ;; emit_push_insn when it calls move_by_pieces requires an insn to |
6541fe75 JJ |
2088 | ;; "push a byte". But actually we use pushl, which has the effect |
2089 | ;; of rounding the amount pushed up to a word. | |
7dd4b4a3 JH |
2090 | |
2091 | (define_insn "*pushqi2" | |
6541fe75 JJ |
2092 | [(set (match_operand:QI 0 "push_operand" "=X") |
2093 | (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))] | |
7dd4b4a3 | 2094 | "!TARGET_64BIT" |
6541fe75 | 2095 | "push{l}\t%k1" |
7dd4b4a3 | 2096 | [(set_attr "type" "push") |
6541fe75 | 2097 | (set_attr "mode" "SI")]) |
7dd4b4a3 | 2098 | |
b3298882 JH |
2099 | ;; For 64BIT abi we always round up to 8 bytes. |
2100 | (define_insn "*pushqi2_rex64" | |
2101 | [(set (match_operand:QI 0 "push_operand" "=X") | |
0edb82cb | 2102 | (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))] |
b3298882 | 2103 | "TARGET_64BIT" |
0f40f9f7 | 2104 | "push{q}\t%q1" |
b3298882 | 2105 | [(set_attr "type" "push") |
6541fe75 | 2106 | (set_attr "mode" "DI")]) |
b3298882 | 2107 | |
0b5107cf JH |
2108 | ;; Situation is quite tricky about when to choose full sized (SImode) move |
2109 | ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for | |
2110 | ;; partial register dependency machines (such as AMD Athlon), where QImode | |
2111 | ;; moves issue extra dependency and for partial register stalls machines | |
2112 | ;; that don't use QImode patterns (and QImode move cause stall on the next | |
2113 | ;; instruction). | |
2114 | ;; | |
2115 | ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial | |
2116 | ;; register stall machines with, where we use QImode instructions, since | |
2117 | ;; partial register stall can be caused there. Then we use movzx. | |
e075ae69 | 2118 | (define_insn "*movqi_1" |
0b5107cf | 2119 | [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") |
0cd0c6fb | 2120 | (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] |
7656aee4 | 2121 | "!(MEM_P (operands[0]) && MEM_P (operands[1]))" |
886c62d1 | 2122 | { |
e075ae69 | 2123 | switch (get_attr_type (insn)) |
b76c90cf | 2124 | { |
e075ae69 | 2125 | case TYPE_IMOVX: |
7656aee4 | 2126 | gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])); |
0f40f9f7 | 2127 | return "movz{bl|x}\t{%1, %k0|%k0, %1}"; |
e075ae69 | 2128 | default: |
6ef67412 | 2129 | if (get_attr_mode (insn) == MODE_SI) |
0f40f9f7 | 2130 | return "mov{l}\t{%k1, %k0|%k0, %k1}"; |
b76c90cf | 2131 | else |
0f40f9f7 | 2132 | return "mov{b}\t{%1, %0|%0, %1}"; |
b76c90cf | 2133 | } |
0f40f9f7 | 2134 | } |
e075ae69 | 2135 | [(set (attr "type") |
0cd0c6fb JJ |
2136 | (cond [(and (eq_attr "alternative" "5") |
2137 | (not (match_operand:QI 1 "aligned_operand" ""))) | |
f66eb2af | 2138 | (const_string "imovx") |
3debdc1e | 2139 | (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)) |
68f48f39 RS |
2140 | (const_string "imov") |
2141 | (and (eq_attr "alternative" "3") | |
0b5107cf JH |
2142 | (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") |
2143 | (const_int 0)) | |
2144 | (eq (symbol_ref "TARGET_QIMODE_MATH") | |
2145 | (const_int 0)))) | |
2146 | (const_string "imov") | |
0cd0c6fb | 2147 | (eq_attr "alternative" "3,5") |
e075ae69 RH |
2148 | (const_string "imovx") |
2149 | (and (ne (symbol_ref "TARGET_MOVX") | |
2150 | (const_int 0)) | |
0b5107cf | 2151 | (eq_attr "alternative" "2")) |
e075ae69 RH |
2152 | (const_string "imovx") |
2153 | ] | |
2154 | (const_string "imov"))) | |
6ef67412 JH |
2155 | (set (attr "mode") |
2156 | (cond [(eq_attr "alternative" "3,4,5") | |
2157 | (const_string "SI") | |
2158 | (eq_attr "alternative" "6") | |
2159 | (const_string "QI") | |
2160 | (eq_attr "type" "imovx") | |
2161 | (const_string "SI") | |
0b5107cf | 2162 | (and (eq_attr "type" "imov") |
d49b398c | 2163 | (and (eq_attr "alternative" "0,1") |
d326eaf0 JH |
2164 | (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY") |
2165 | (const_int 0)) | |
3debdc1e | 2166 | (and (eq (symbol_ref "optimize_function_for_size_p (cfun)") |
d326eaf0 JH |
2167 | (const_int 0)) |
2168 | (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") | |
2169 | (const_int 0)))))) | |
6ef67412 | 2170 | (const_string "SI") |
0b5107cf JH |
2171 | ;; Avoid partial register stalls when not using QImode arithmetic |
2172 | (and (eq_attr "type" "imov") | |
d49b398c | 2173 | (and (eq_attr "alternative" "0,1") |
0b5107cf JH |
2174 | (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL") |
2175 | (const_int 0)) | |
2176 | (eq (symbol_ref "TARGET_QIMODE_MATH") | |
2177 | (const_int 0))))) | |
6ef67412 JH |
2178 | (const_string "SI") |
2179 | ] | |
2180 | (const_string "QI")))]) | |
e075ae69 | 2181 | |
7cc6af0c | 2182 | (define_insn "*swapqi_1" |
e075ae69 RH |
2183 | [(set (match_operand:QI 0 "register_operand" "+r") |
2184 | (match_operand:QI 1 "register_operand" "+r")) | |
2185 | (set (match_dup 1) | |
2186 | (match_dup 0))] | |
3debdc1e | 2187 | "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" |
7cc6af0c | 2188 | "xchg{l}\t%k1, %k0" |
e075ae69 | 2189 | [(set_attr "type" "imov") |
7cc6af0c | 2190 | (set_attr "mode" "SI") |
e075ae69 | 2191 | (set_attr "pent_pair" "np") |
21efb4d4 | 2192 | (set_attr "athlon_decode" "vector") |
4f3f76e6 | 2193 | (set_attr "amdfam10_decode" "vector")]) |
7cc6af0c | 2194 | |
21efb4d4 | 2195 | ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10 |
7cc6af0c RH |
2196 | (define_insn "*swapqi_2" |
2197 | [(set (match_operand:QI 0 "register_operand" "+q") | |
2198 | (match_operand:QI 1 "register_operand" "+q")) | |
2199 | (set (match_dup 1) | |
2200 | (match_dup 0))] | |
2201 | "TARGET_PARTIAL_REG_STALL" | |
2202 | "xchg{b}\t%1, %0" | |
2203 | [(set_attr "type" "imov") | |
6ef67412 | 2204 | (set_attr "mode" "QI") |
7cc6af0c RH |
2205 | (set_attr "pent_pair" "np") |
2206 | (set_attr "athlon_decode" "vector")]) | |
886c62d1 | 2207 | |
2f2a49e8 | 2208 | (define_expand "movstrictqi" |
4cbfbb1b | 2209 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) |
2f2a49e8 | 2210 | (match_operand:QI 1 "general_operand" ""))] |
3debdc1e | 2211 | "" |
2f2a49e8 | 2212 | { |
3debdc1e JH |
2213 | if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) |
2214 | FAIL; | |
e03f5d43 | 2215 | /* Don't generate memory->memory moves, go through a register. */ |
7656aee4 | 2216 | if (MEM_P (operands[0]) && MEM_P (operands[1])) |
e075ae69 | 2217 | operands[1] = force_reg (QImode, operands[1]); |
0f40f9f7 | 2218 | }) |
2f2a49e8 | 2219 | |
e075ae69 | 2220 | (define_insn "*movstrictqi_1" |
2ae0f82c | 2221 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) |
c0f06344 | 2222 | (match_operand:QI 1 "general_operand" "*qn,m"))] |
3debdc1e | 2223 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 2224 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 2225 | "mov{b}\t{%1, %0|%0, %1}" |
6ef67412 JH |
2226 | [(set_attr "type" "imov") |
2227 | (set_attr "mode" "QI")]) | |
2228 | ||
2229 | (define_insn "*movstrictqi_xor" | |
5e6d6bf0 | 2230 | [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) |
0edb82cb | 2231 | (match_operand:QI 1 "const0_operand" "")) |
8bc527af | 2232 | (clobber (reg:CC FLAGS_REG))] |
18bd082d | 2233 | "reload_completed" |
a23132e1 | 2234 | "xor{b}\t%0, %0" |
6ef67412 JH |
2235 | [(set_attr "type" "alu1") |
2236 | (set_attr "mode" "QI") | |
2237 | (set_attr "length_immediate" "0")]) | |
e075ae69 RH |
2238 | |
2239 | (define_insn "*movsi_extv_1" | |
d2836273 | 2240 | [(set (match_operand:SI 0 "register_operand" "=R") |
3522082b | 2241 | (sign_extract:SI (match_operand 1 "ext_register_operand" "Q") |
e075ae69 RH |
2242 | (const_int 8) |
2243 | (const_int 8)))] | |
2244 | "" | |
0f40f9f7 | 2245 | "movs{bl|x}\t{%h1, %0|%0, %h1}" |
6ef67412 JH |
2246 | [(set_attr "type" "imovx") |
2247 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
2248 | |
2249 | (define_insn "*movhi_extv_1" | |
d2836273 | 2250 | [(set (match_operand:HI 0 "register_operand" "=R") |
3522082b | 2251 | (sign_extract:HI (match_operand 1 "ext_register_operand" "Q") |
e075ae69 RH |
2252 | (const_int 8) |
2253 | (const_int 8)))] | |
2254 | "" | |
0f40f9f7 | 2255 | "movs{bl|x}\t{%h1, %k0|%k0, %h1}" |
6ef67412 JH |
2256 | [(set_attr "type" "imovx") |
2257 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
2258 | |
2259 | (define_insn "*movqi_extv_1" | |
0ec259ed | 2260 | [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") |
3522082b | 2261 | (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") |
e075ae69 RH |
2262 | (const_int 8) |
2263 | (const_int 8)))] | |
0ec259ed | 2264 | "!TARGET_64BIT" |
886c62d1 | 2265 | { |
e075ae69 | 2266 | switch (get_attr_type (insn)) |
886c62d1 | 2267 | { |
e075ae69 | 2268 | case TYPE_IMOVX: |
0f40f9f7 | 2269 | return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; |
e075ae69 | 2270 | default: |
0f40f9f7 | 2271 | return "mov{b}\t{%h1, %0|%0, %h1}"; |
886c62d1 | 2272 | } |
0f40f9f7 | 2273 | } |
e075ae69 RH |
2274 | [(set (attr "type") |
2275 | (if_then_else (and (match_operand:QI 0 "register_operand" "") | |
2276 | (ior (not (match_operand:QI 0 "q_regs_operand" "")) | |
2277 | (ne (symbol_ref "TARGET_MOVX") | |
2278 | (const_int 0)))) | |
2279 | (const_string "imovx") | |
6ef67412 JH |
2280 | (const_string "imov"))) |
2281 | (set (attr "mode") | |
2282 | (if_then_else (eq_attr "type" "imovx") | |
2283 | (const_string "SI") | |
2284 | (const_string "QI")))]) | |
e075ae69 | 2285 | |
0ec259ed JH |
2286 | (define_insn "*movqi_extv_1_rex64" |
2287 | [(set (match_operand:QI 0 "register_operand" "=Q,?R") | |
3522082b | 2288 | (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") |
0ec259ed JH |
2289 | (const_int 8) |
2290 | (const_int 8)))] | |
2291 | "TARGET_64BIT" | |
0ec259ed JH |
2292 | { |
2293 | switch (get_attr_type (insn)) | |
2294 | { | |
2295 | case TYPE_IMOVX: | |
0f40f9f7 | 2296 | return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; |
0ec259ed | 2297 | default: |
0f40f9f7 | 2298 | return "mov{b}\t{%h1, %0|%0, %h1}"; |
0ec259ed | 2299 | } |
0f40f9f7 | 2300 | } |
0ec259ed JH |
2301 | [(set (attr "type") |
2302 | (if_then_else (and (match_operand:QI 0 "register_operand" "") | |
2303 | (ior (not (match_operand:QI 0 "q_regs_operand" "")) | |
2304 | (ne (symbol_ref "TARGET_MOVX") | |
2305 | (const_int 0)))) | |
2306 | (const_string "imovx") | |
2307 | (const_string "imov"))) | |
2308 | (set (attr "mode") | |
2309 | (if_then_else (eq_attr "type" "imovx") | |
2310 | (const_string "SI") | |
2311 | (const_string "QI")))]) | |
2312 | ||
d1f87653 | 2313 | ;; Stores and loads of ax to arbitrary constant address. |
0ec259ed JH |
2314 | ;; We fake an second form of instruction to force reload to load address |
2315 | ;; into register when rax is not available | |
2316 | (define_insn "*movabsqi_1_rex64" | |
7e6dc358 JJ |
2317 | [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) |
2318 | (match_operand:QI 1 "nonmemory_operand" "a,er"))] | |
2319 | "TARGET_64BIT && ix86_check_movabs (insn, 0)" | |
0ec259ed | 2320 | "@ |
5e2ce672 | 2321 | movabs{b}\t{%1, %P0|%P0, %1} |
7e6dc358 | 2322 | mov{b}\t{%1, %a0|%a0, %1}" |
0ec259ed | 2323 | [(set_attr "type" "imov") |
7e6dc358 JJ |
2324 | (set_attr "modrm" "0,*") |
2325 | (set_attr "length_address" "8,0") | |
2326 | (set_attr "length_immediate" "0,*") | |
0ec259ed JH |
2327 | (set_attr "memory" "store") |
2328 | (set_attr "mode" "QI")]) | |
2329 | ||
2330 | (define_insn "*movabsqi_2_rex64" | |
2331 | [(set (match_operand:QI 0 "register_operand" "=a,r") | |
2332 | (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] | |
7e6dc358 | 2333 | "TARGET_64BIT && ix86_check_movabs (insn, 1)" |
0ec259ed | 2334 | "@ |
5e2ce672 JH |
2335 | movabs{b}\t{%P1, %0|%0, %P1} |
2336 | mov{b}\t{%a1, %0|%0, %a1}" | |
0ec259ed JH |
2337 | [(set_attr "type" "imov") |
2338 | (set_attr "modrm" "0,*") | |
2339 | (set_attr "length_address" "8,0") | |
2340 | (set_attr "length_immediate" "0") | |
2341 | (set_attr "memory" "load") | |
2342 | (set_attr "mode" "QI")]) | |
2343 | ||
422edd6f JB |
2344 | (define_insn "*movdi_extzv_1" |
2345 | [(set (match_operand:DI 0 "register_operand" "=R") | |
2346 | (zero_extract:DI (match_operand 1 "ext_register_operand" "Q") | |
2347 | (const_int 8) | |
2348 | (const_int 8)))] | |
2349 | "TARGET_64BIT" | |
2350 | "movz{bl|x}\t{%h1, %k0|%k0, %h1}" | |
2351 | [(set_attr "type" "imovx") | |
a952487c | 2352 | (set_attr "mode" "SI")]) |
422edd6f | 2353 | |
e075ae69 | 2354 | (define_insn "*movsi_extzv_1" |
d2836273 JH |
2355 | [(set (match_operand:SI 0 "register_operand" "=R") |
2356 | (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") | |
e075ae69 RH |
2357 | (const_int 8) |
2358 | (const_int 8)))] | |
2359 | "" | |
0f40f9f7 | 2360 | "movz{bl|x}\t{%h1, %0|%0, %h1}" |
6ef67412 JH |
2361 | [(set_attr "type" "imovx") |
2362 | (set_attr "mode" "SI")]) | |
886c62d1 | 2363 | |
d2836273 JH |
2364 | (define_insn "*movqi_extzv_2" |
2365 | [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") | |
2366 | (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") | |
e075ae69 RH |
2367 | (const_int 8) |
2368 | (const_int 8)) 0))] | |
d2836273 | 2369 | "!TARGET_64BIT" |
f31fce3f | 2370 | { |
e075ae69 | 2371 | switch (get_attr_type (insn)) |
f31fce3f | 2372 | { |
e075ae69 | 2373 | case TYPE_IMOVX: |
0f40f9f7 | 2374 | return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; |
e075ae69 | 2375 | default: |
0f40f9f7 | 2376 | return "mov{b}\t{%h1, %0|%0, %h1}"; |
e075ae69 | 2377 | } |
0f40f9f7 | 2378 | } |
e075ae69 RH |
2379 | [(set (attr "type") |
2380 | (if_then_else (and (match_operand:QI 0 "register_operand" "") | |
2381 | (ior (not (match_operand:QI 0 "q_regs_operand" "")) | |
2382 | (ne (symbol_ref "TARGET_MOVX") | |
2383 | (const_int 0)))) | |
2384 | (const_string "imovx") | |
6ef67412 JH |
2385 | (const_string "imov"))) |
2386 | (set (attr "mode") | |
2387 | (if_then_else (eq_attr "type" "imovx") | |
2388 | (const_string "SI") | |
2389 | (const_string "QI")))]) | |
e075ae69 | 2390 | |
d2836273 JH |
2391 | (define_insn "*movqi_extzv_2_rex64" |
2392 | [(set (match_operand:QI 0 "register_operand" "=Q,?R") | |
2393 | (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") | |
2394 | (const_int 8) | |
2395 | (const_int 8)) 0))] | |
2396 | "TARGET_64BIT" | |
d2836273 JH |
2397 | { |
2398 | switch (get_attr_type (insn)) | |
2399 | { | |
2400 | case TYPE_IMOVX: | |
0f40f9f7 | 2401 | return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; |
d2836273 | 2402 | default: |
0f40f9f7 | 2403 | return "mov{b}\t{%h1, %0|%0, %h1}"; |
d2836273 | 2404 | } |
0f40f9f7 | 2405 | } |
d2836273 JH |
2406 | [(set (attr "type") |
2407 | (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" "")) | |
2408 | (ne (symbol_ref "TARGET_MOVX") | |
2409 | (const_int 0))) | |
2410 | (const_string "imovx") | |
2411 | (const_string "imov"))) | |
2412 | (set (attr "mode") | |
2413 | (if_then_else (eq_attr "type" "imovx") | |
2414 | (const_string "SI") | |
2415 | (const_string "QI")))]) | |
2416 | ||
7a2e09f4 | 2417 | (define_insn "movsi_insv_1" |
d2836273 | 2418 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") |
e075ae69 RH |
2419 | (const_int 8) |
2420 | (const_int 8)) | |
f47c8646 | 2421 | (match_operand:SI 1 "general_operand" "Qmn"))] |
d2836273 | 2422 | "!TARGET_64BIT" |
0f40f9f7 | 2423 | "mov{b}\t{%b1, %h0|%h0, %b1}" |
d2836273 JH |
2424 | [(set_attr "type" "imov") |
2425 | (set_attr "mode" "QI")]) | |
2426 | ||
8c996513 JH |
2427 | (define_insn "*movsi_insv_1_rex64" |
2428 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") | |
2429 | (const_int 8) | |
2430 | (const_int 8)) | |
2431 | (match_operand:SI 1 "nonmemory_operand" "Qn"))] | |
2432 | "TARGET_64BIT" | |
2433 | "mov{b}\t{%b1, %h0|%h0, %b1}" | |
2434 | [(set_attr "type" "imov") | |
2435 | (set_attr "mode" "QI")]) | |
2436 | ||
044b3892 L |
2437 | (define_insn "movdi_insv_1_rex64" |
2438 | [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q") | |
d2836273 JH |
2439 | (const_int 8) |
2440 | (const_int 8)) | |
044b3892 | 2441 | (match_operand:DI 1 "nonmemory_operand" "Qn"))] |
d2836273 | 2442 | "TARGET_64BIT" |
0f40f9f7 | 2443 | "mov{b}\t{%b1, %h0|%h0, %b1}" |
6ef67412 JH |
2444 | [(set_attr "type" "imov") |
2445 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
2446 | |
2447 | (define_insn "*movqi_insv_2" | |
d2836273 | 2448 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") |
e075ae69 RH |
2449 | (const_int 8) |
2450 | (const_int 8)) | |
99f296a0 KH |
2451 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") |
2452 | (const_int 8)))] | |
e075ae69 | 2453 | "" |
0f40f9f7 | 2454 | "mov{b}\t{%h1, %h0|%h0, %h1}" |
6ef67412 JH |
2455 | [(set_attr "type" "imov") |
2456 | (set_attr "mode" "QI")]) | |
f31fce3f | 2457 | |
e075ae69 | 2458 | (define_expand "movdi" |
4cbfbb1b | 2459 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
e075ae69 RH |
2460 | (match_operand:DI 1 "general_operand" ""))] |
2461 | "" | |
2462 | "ix86_expand_move (DImode, operands); DONE;") | |
f31fce3f | 2463 | |
e075ae69 RH |
2464 | (define_insn "*pushdi" |
2465 | [(set (match_operand:DI 0 "push_operand" "=<") | |
2c5a510c | 2466 | (match_operand:DI 1 "general_no_elim_operand" "riF*m"))] |
1e07edd3 | 2467 | "!TARGET_64BIT" |
e075ae69 | 2468 | "#") |
f31fce3f | 2469 | |
6c4ccfd8 | 2470 | (define_insn "*pushdi2_rex64" |
0ec259ed JH |
2471 | [(set (match_operand:DI 0 "push_operand" "=<,!<") |
2472 | (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] | |
2473 | "TARGET_64BIT" | |
2474 | "@ | |
0f40f9f7 | 2475 | push{q}\t%1 |
0ec259ed JH |
2476 | #" |
2477 | [(set_attr "type" "push,multi") | |
2478 | (set_attr "mode" "DI")]) | |
2479 | ||
2480 | ;; Convert impossible pushes of immediate to existing instructions. | |
f5143c46 | 2481 | ;; First try to get scratch register and go through it. In case this |
0ec259ed JH |
2482 | ;; fails, push sign extended lower part first and then overwrite |
2483 | ;; upper part by 32bit move. | |
2484 | (define_peephole2 | |
2485 | [(match_scratch:DI 2 "r") | |
2486 | (set (match_operand:DI 0 "push_operand" "") | |
2487 | (match_operand:DI 1 "immediate_operand" ""))] | |
2488 | "TARGET_64BIT && !symbolic_operand (operands[1], DImode) | |
2489 | && !x86_64_immediate_operand (operands[1], DImode)" | |
2490 | [(set (match_dup 2) (match_dup 1)) | |
2491 | (set (match_dup 0) (match_dup 2))] | |
2492 | "") | |
2493 | ||
2494 | ;; We need to define this as both peepholer and splitter for case | |
2495 | ;; peephole2 pass is not run. | |
731edaed | 2496 | ;; "&& 1" is needed to keep it from matching the previous pattern. |
0ec259ed JH |
2497 | (define_peephole2 |
2498 | [(set (match_operand:DI 0 "push_operand" "") | |
2499 | (match_operand:DI 1 "immediate_operand" ""))] | |
2500 | "TARGET_64BIT && !symbolic_operand (operands[1], DImode) | |
731edaed | 2501 | && !x86_64_immediate_operand (operands[1], DImode) && 1" |
0ec259ed JH |
2502 | [(set (match_dup 0) (match_dup 1)) |
2503 | (set (match_dup 2) (match_dup 3))] | |
c2b814b9 | 2504 | "split_di (&operands[1], 1, &operands[2], &operands[3]); |
0ec259ed JH |
2505 | operands[1] = gen_lowpart (DImode, operands[2]); |
2506 | operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, | |
2507 | GEN_INT (4))); | |
2508 | ") | |
2509 | ||
2510 | (define_split | |
2511 | [(set (match_operand:DI 0 "push_operand" "") | |
2512 | (match_operand:DI 1 "immediate_operand" ""))] | |
99523994 | 2513 | "TARGET_64BIT && ((optimize > 0 && flag_peephole2) |
6fb5fa3c | 2514 | ? epilogue_completed : reload_completed) |
0ec259ed JH |
2515 | && !symbolic_operand (operands[1], DImode) |
2516 | && !x86_64_immediate_operand (operands[1], DImode)" | |
2517 | [(set (match_dup 0) (match_dup 1)) | |
2518 | (set (match_dup 2) (match_dup 3))] | |
c2b814b9 | 2519 | "split_di (&operands[1], 1, &operands[2], &operands[3]); |
0ec259ed JH |
2520 | operands[1] = gen_lowpart (DImode, operands[2]); |
2521 | operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, | |
2522 | GEN_INT (4))); | |
2523 | ") | |
2524 | ||
2525 | (define_insn "*pushdi2_prologue_rex64" | |
2526 | [(set (match_operand:DI 0 "push_operand" "=<") | |
2527 | (match_operand:DI 1 "general_no_elim_operand" "re*m")) | |
f2042df3 | 2528 | (clobber (mem:BLK (scratch)))] |
0ec259ed | 2529 | "TARGET_64BIT" |
0f40f9f7 | 2530 | "push{q}\t%1" |
0ec259ed JH |
2531 | [(set_attr "type" "push") |
2532 | (set_attr "mode" "DI")]) | |
2533 | ||
2534 | (define_insn "*popdi1_epilogue_rex64" | |
2535 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") | |
8bc527af SB |
2536 | (mem:DI (reg:DI SP_REG))) |
2537 | (set (reg:DI SP_REG) | |
2538 | (plus:DI (reg:DI SP_REG) (const_int 8))) | |
f2042df3 | 2539 | (clobber (mem:BLK (scratch)))] |
0ec259ed | 2540 | "TARGET_64BIT" |
0f40f9f7 | 2541 | "pop{q}\t%0" |
0ec259ed JH |
2542 | [(set_attr "type" "pop") |
2543 | (set_attr "mode" "DI")]) | |
2544 | ||
2545 | (define_insn "popdi1" | |
2546 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") | |
8bc527af SB |
2547 | (mem:DI (reg:DI SP_REG))) |
2548 | (set (reg:DI SP_REG) | |
2549 | (plus:DI (reg:DI SP_REG) (const_int 8)))] | |
0ec259ed | 2550 | "TARGET_64BIT" |
0f40f9f7 | 2551 | "pop{q}\t%0" |
0ec259ed JH |
2552 | [(set_attr "type" "pop") |
2553 | (set_attr "mode" "DI")]) | |
2554 | ||
2555 | (define_insn "*movdi_xor_rex64" | |
2556 | [(set (match_operand:DI 0 "register_operand" "=r") | |
0edb82cb | 2557 | (match_operand:DI 1 "const0_operand" "")) |
8bc527af | 2558 | (clobber (reg:CC FLAGS_REG))] |
18bd082d | 2559 | "TARGET_64BIT |
1b0c37d7 | 2560 | && reload_completed" |
a23132e1 | 2561 | "xor{l}\t%k0, %k0"; |
0ec259ed JH |
2562 | [(set_attr "type" "alu1") |
2563 | (set_attr "mode" "SI") | |
2564 | (set_attr "length_immediate" "0")]) | |
2565 | ||
2566 | (define_insn "*movdi_or_rex64" | |
2567 | [(set (match_operand:DI 0 "register_operand" "=r") | |
2568 | (match_operand:DI 1 "const_int_operand" "i")) | |
8bc527af | 2569 | (clobber (reg:CC FLAGS_REG))] |
18bd082d | 2570 | "TARGET_64BIT |
1b0c37d7 | 2571 | && reload_completed |
87d9741e | 2572 | && operands[1] == constm1_rtx" |
0ec259ed JH |
2573 | { |
2574 | operands[1] = constm1_rtx; | |
0f40f9f7 ZW |
2575 | return "or{q}\t{%1, %0|%0, %1}"; |
2576 | } | |
0ec259ed JH |
2577 | [(set_attr "type" "alu1") |
2578 | (set_attr "mode" "DI") | |
2579 | (set_attr "length_immediate" "1")]) | |
2580 | ||
e075ae69 | 2581 | (define_insn "*movdi_2" |
d30c9461 | 2582 | [(set (match_operand:DI 0 "nonimmediate_operand" |
e2520c41 | 2583 | "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x") |
d30c9461 | 2584 | (match_operand:DI 1 "general_operand" |
e2520c41 | 2585 | "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))] |
f75959a6 | 2586 | "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
915119a5 BS |
2587 | "@ |
2588 | # | |
2589 | # | |
f75959a6 | 2590 | pxor\t%0, %0 |
0f40f9f7 ZW |
2591 | movq\t{%1, %0|%0, %1} |
2592 | movq\t{%1, %0|%0, %1} | |
95879c72 L |
2593 | %vpxor\t%0, %d0 |
2594 | %vmovq\t{%1, %0|%0, %1} | |
2595 | %vmovdqa\t{%1, %0|%0, %1} | |
2596 | %vmovq\t{%1, %0|%0, %1} | |
f75959a6 | 2597 | xorps\t%0, %0 |
d30c9461 RH |
2598 | movlps\t{%1, %0|%0, %1} |
2599 | movaps\t{%1, %0|%0, %1} | |
2600 | movlps\t{%1, %0|%0, %1}" | |
51df7179 | 2601 | [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov") |
95879c72 L |
2602 | (set (attr "prefix") |
2603 | (if_then_else (eq_attr "alternative" "5,6,7,8") | |
2604 | (const_string "vex") | |
2605 | (const_string "orig"))) | |
f75959a6 | 2606 | (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")]) |
dc0f0eb8 | 2607 | |
e075ae69 RH |
2608 | (define_split |
2609 | [(set (match_operand:DI 0 "push_operand" "") | |
2610 | (match_operand:DI 1 "general_operand" ""))] | |
6c12e488 JH |
2611 | "!TARGET_64BIT && reload_completed |
2612 | && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" | |
2450a057 | 2613 | [(const_int 0)] |
26e5b205 | 2614 | "ix86_split_long_move (operands); DONE;") |
f31fce3f | 2615 | |
e075ae69 | 2616 | ;; %%% This multiword shite has got to go. |
e075ae69 | 2617 | (define_split |
c76aab11 | 2618 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
e075ae69 | 2619 | (match_operand:DI 1 "general_operand" ""))] |
6c12e488 JH |
2620 | "!TARGET_64BIT && reload_completed |
2621 | && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) | |
2622 | && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" | |
26e5b205 JH |
2623 | [(const_int 0)] |
2624 | "ix86_split_long_move (operands); DONE;") | |
0ec259ed JH |
2625 | |
2626 | (define_insn "*movdi_1_rex64" | |
6c4ccfd8 | 2627 | [(set (match_operand:DI 0 "nonimmediate_operand" |
4afb7791 | 2628 | "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym") |
6c4ccfd8 | 2629 | (match_operand:DI 1 "general_operand" |
4afb7791 | 2630 | "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))] |
f75959a6 | 2631 | "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0ec259ed JH |
2632 | { |
2633 | switch (get_attr_type (insn)) | |
2634 | { | |
9e9fb0ce | 2635 | case TYPE_SSECVT: |
ed69105c | 2636 | if (SSE_REG_P (operands[0])) |
9e9fb0ce JB |
2637 | return "movq2dq\t{%1, %0|%0, %1}"; |
2638 | else | |
2639 | return "movdq2q\t{%1, %0|%0, %1}"; | |
ed69105c | 2640 | |
5f90a099 | 2641 | case TYPE_SSEMOV: |
95879c72 L |
2642 | if (TARGET_AVX) |
2643 | { | |
2644 | if (get_attr_mode (insn) == MODE_TI) | |
2645 | return "vmovdqa\t{%1, %0|%0, %1}"; | |
2646 | else | |
2647 | return "vmovq\t{%1, %0|%0, %1}"; | |
2648 | } | |
2649 | ||
8f62128d | 2650 | if (get_attr_mode (insn) == MODE_TI) |
ed69105c | 2651 | return "movdqa\t{%1, %0|%0, %1}"; |
5efb1046 | 2652 | /* FALLTHRU */ |
ed69105c | 2653 | |
5ccbcd8c | 2654 | case TYPE_MMXMOV: |
ed69105c RH |
2655 | /* Moves from and into integer register is done using movd |
2656 | opcode with REX prefix. */ | |
8f62128d | 2657 | if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) |
ed69105c | 2658 | return "movd\t{%1, %0|%0, %1}"; |
0f40f9f7 | 2659 | return "movq\t{%1, %0|%0, %1}"; |
ed69105c | 2660 | |
f75959a6 | 2661 | case TYPE_SSELOG1: |
95879c72 L |
2662 | return "%vpxor\t%0, %d0"; |
2663 | ||
87673f84 | 2664 | case TYPE_MMX: |
f75959a6 | 2665 | return "pxor\t%0, %0"; |
ed69105c | 2666 | |
0ec259ed | 2667 | case TYPE_MULTI: |
0f40f9f7 | 2668 | return "#"; |
ed69105c | 2669 | |
0ec259ed | 2670 | case TYPE_LEA: |
0f40f9f7 | 2671 | return "lea{q}\t{%a1, %0|%0, %a1}"; |
ed69105c | 2672 | |
0ec259ed | 2673 | default: |
7637e42c | 2674 | gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); |
0ec259ed | 2675 | if (get_attr_mode (insn) == MODE_SI) |
0f40f9f7 | 2676 | return "mov{l}\t{%k1, %k0|%k0, %k1}"; |
0ec259ed | 2677 | else if (which_alternative == 2) |
0f40f9f7 | 2678 | return "movabs{q}\t{%1, %0|%0, %1}"; |
0ec259ed | 2679 | else |
0f40f9f7 | 2680 | return "mov{q}\t{%1, %0|%0, %1}"; |
0ec259ed | 2681 | } |
0f40f9f7 | 2682 | } |
0ec259ed | 2683 | [(set (attr "type") |
f75959a6 | 2684 | (cond [(eq_attr "alternative" "5") |
87673f84 | 2685 | (const_string "mmx") |
ed69105c | 2686 | (eq_attr "alternative" "6,7,8,9,10") |
3d34cd91 | 2687 | (const_string "mmxmov") |
ed69105c | 2688 | (eq_attr "alternative" "11") |
f75959a6 | 2689 | (const_string "sselog1") |
ed69105c | 2690 | (eq_attr "alternative" "12,13,14,15,16") |
3d34cd91 | 2691 | (const_string "ssemov") |
ed69105c | 2692 | (eq_attr "alternative" "17,18") |
9e9fb0ce | 2693 | (const_string "ssecvt") |
0ec259ed JH |
2694 | (eq_attr "alternative" "4") |
2695 | (const_string "multi") | |
47efdea4 | 2696 | (match_operand:DI 1 "pic_32bit_operand" "") |
0ec259ed JH |
2697 | (const_string "lea") |
2698 | ] | |
2699 | (const_string "imov"))) | |
a952487c JJ |
2700 | (set (attr "modrm") |
2701 | (if_then_else | |
2702 | (and (eq_attr "alternative" "2") (eq_attr "type" "imov")) | |
2703 | (const_string "0") | |
2704 | (const_string "*"))) | |
2705 | (set (attr "length_immediate") | |
2706 | (if_then_else | |
2707 | (and (eq_attr "alternative" "2") (eq_attr "type" "imov")) | |
2708 | (const_string "8") | |
2709 | (const_string "*"))) | |
725fd454 JJ |
2710 | (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*") |
2711 | (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*") | |
95879c72 L |
2712 | (set (attr "prefix") |
2713 | (if_then_else (eq_attr "alternative" "11,12,13,14,15,16") | |
2714 | (const_string "maybe_vex") | |
2715 | (const_string "orig"))) | |
ed69105c | 2716 | (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")]) |
0ec259ed | 2717 | |
d1f87653 | 2718 | ;; Stores and loads of ax to arbitrary constant address. |
0ec259ed JH |
2719 | ;; We fake an second form of instruction to force reload to load address |
2720 | ;; into register when rax is not available | |
2721 | (define_insn "*movabsdi_1_rex64" | |
7e6dc358 JJ |
2722 | [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) |
2723 | (match_operand:DI 1 "nonmemory_operand" "a,er"))] | |
2724 | "TARGET_64BIT && ix86_check_movabs (insn, 0)" | |
0ec259ed | 2725 | "@ |
0f40f9f7 | 2726 | movabs{q}\t{%1, %P0|%P0, %1} |
7e6dc358 | 2727 | mov{q}\t{%1, %a0|%a0, %1}" |
0ec259ed | 2728 | [(set_attr "type" "imov") |
7e6dc358 JJ |
2729 | (set_attr "modrm" "0,*") |
2730 | (set_attr "length_address" "8,0") | |
2731 | (set_attr "length_immediate" "0,*") | |
0ec259ed JH |
2732 | (set_attr "memory" "store") |
2733 | (set_attr "mode" "DI")]) | |
2734 | ||
2735 | (define_insn "*movabsdi_2_rex64" | |
2736 | [(set (match_operand:DI 0 "register_operand" "=a,r") | |
2737 | (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] | |
7e6dc358 | 2738 | "TARGET_64BIT && ix86_check_movabs (insn, 1)" |
0ec259ed | 2739 | "@ |
0f40f9f7 ZW |
2740 | movabs{q}\t{%P1, %0|%0, %P1} |
2741 | mov{q}\t{%a1, %0|%0, %a1}" | |
0ec259ed JH |
2742 | [(set_attr "type" "imov") |
2743 | (set_attr "modrm" "0,*") | |
2744 | (set_attr "length_address" "8,0") | |
2745 | (set_attr "length_immediate" "0") | |
2746 | (set_attr "memory" "load") | |
2747 | (set_attr "mode" "DI")]) | |
2748 | ||
2749 | ;; Convert impossible stores of immediate to existing instructions. | |
f5143c46 | 2750 | ;; First try to get scratch register and go through it. In case this |
0ec259ed JH |
2751 | ;; fails, move by 32bit parts. |
2752 | (define_peephole2 | |
2753 | [(match_scratch:DI 2 "r") | |
2754 | (set (match_operand:DI 0 "memory_operand" "") | |
2755 | (match_operand:DI 1 "immediate_operand" ""))] | |
2756 | "TARGET_64BIT && !symbolic_operand (operands[1], DImode) | |
2757 | && !x86_64_immediate_operand (operands[1], DImode)" | |
2758 | [(set (match_dup 2) (match_dup 1)) | |
2759 | (set (match_dup 0) (match_dup 2))] | |
2760 | "") | |
2761 | ||
2762 | ;; We need to define this as both peepholer and splitter for case | |
2763 | ;; peephole2 pass is not run. | |
731edaed | 2764 | ;; "&& 1" is needed to keep it from matching the previous pattern. |
0ec259ed JH |
2765 | (define_peephole2 |
2766 | [(set (match_operand:DI 0 "memory_operand" "") | |
2767 | (match_operand:DI 1 "immediate_operand" ""))] | |
2768 | "TARGET_64BIT && !symbolic_operand (operands[1], DImode) | |
731edaed | 2769 | && !x86_64_immediate_operand (operands[1], DImode) && 1" |
0ec259ed JH |
2770 | [(set (match_dup 2) (match_dup 3)) |
2771 | (set (match_dup 4) (match_dup 5))] | |
c2b814b9 | 2772 | "split_di (&operands[0], 2, &operands[2], &operands[4]);") |
0ec259ed JH |
2773 | |
2774 | (define_split | |
2775 | [(set (match_operand:DI 0 "memory_operand" "") | |
2776 | (match_operand:DI 1 "immediate_operand" ""))] | |
99523994 | 2777 | "TARGET_64BIT && ((optimize > 0 && flag_peephole2) |
6fb5fa3c | 2778 | ? epilogue_completed : reload_completed) |
0ec259ed JH |
2779 | && !symbolic_operand (operands[1], DImode) |
2780 | && !x86_64_immediate_operand (operands[1], DImode)" | |
2781 | [(set (match_dup 2) (match_dup 3)) | |
2782 | (set (match_dup 4) (match_dup 5))] | |
c2b814b9 | 2783 | "split_di (&operands[0], 2, &operands[2], &operands[4]);") |
0ec259ed JH |
2784 | |
2785 | (define_insn "*swapdi_rex64" | |
2786 | [(set (match_operand:DI 0 "register_operand" "+r") | |
2787 | (match_operand:DI 1 "register_operand" "+r")) | |
2788 | (set (match_dup 1) | |
2789 | (match_dup 0))] | |
2790 | "TARGET_64BIT" | |
0f40f9f7 | 2791 | "xchg{q}\t%1, %0" |
0ec259ed | 2792 | [(set_attr "type" "imov") |
0ec259ed | 2793 | (set_attr "mode" "DI") |
7cc6af0c | 2794 | (set_attr "pent_pair" "np") |
21efb4d4 | 2795 | (set_attr "athlon_decode" "vector") |
4f3f76e6 | 2796 | (set_attr "amdfam10_decode" "double")]) |
0ec259ed | 2797 | |
95879c72 L |
2798 | (define_expand "movoi" |
2799 | [(set (match_operand:OI 0 "nonimmediate_operand" "") | |
2800 | (match_operand:OI 1 "general_operand" ""))] | |
2801 | "TARGET_AVX" | |
2802 | "ix86_expand_move (OImode, operands); DONE;") | |
2803 | ||
2804 | (define_insn "*movoi_internal" | |
2805 | [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m") | |
2806 | (match_operand:OI 1 "vector_move_operand" "C,xm,x"))] | |
2807 | "TARGET_AVX | |
2808 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
2809 | { | |
2810 | switch (which_alternative) | |
2811 | { | |
2812 | case 0: | |
2813 | return "vxorps\t%0, %0, %0"; | |
2814 | case 1: | |
2815 | case 2: | |
2816 | if (misaligned_operand (operands[0], OImode) | |
2817 | || misaligned_operand (operands[1], OImode)) | |
2818 | return "vmovdqu\t{%1, %0|%0, %1}"; | |
2819 | else | |
2820 | return "vmovdqa\t{%1, %0|%0, %1}"; | |
2821 | default: | |
2822 | gcc_unreachable (); | |
2823 | } | |
2824 | } | |
2825 | [(set_attr "type" "sselog1,ssemov,ssemov") | |
2826 | (set_attr "prefix" "vex") | |
2827 | (set_attr "mode" "OI")]) | |
2828 | ||
ef719a44 RH |
2829 | (define_expand "movti" |
2830 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
2831 | (match_operand:TI 1 "nonimmediate_operand" ""))] | |
2832 | "TARGET_SSE || TARGET_64BIT" | |
2833 | { | |
2834 | if (TARGET_64BIT) | |
2835 | ix86_expand_move (TImode, operands); | |
72bd078f UB |
2836 | else if (push_operand (operands[0], TImode)) |
2837 | ix86_expand_push (TImode, operands[1]); | |
ef719a44 RH |
2838 | else |
2839 | ix86_expand_vector_move (TImode, operands); | |
2840 | DONE; | |
2841 | }) | |
2842 | ||
2843 | (define_insn "*movti_internal" | |
2844 | [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") | |
2845 | (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] | |
2846 | "TARGET_SSE && !TARGET_64BIT | |
7656aee4 | 2847 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
ef719a44 RH |
2848 | { |
2849 | switch (which_alternative) | |
2850 | { | |
2851 | case 0: | |
2852 | if (get_attr_mode (insn) == MODE_V4SF) | |
95879c72 | 2853 | return "%vxorps\t%0, %d0"; |
ef719a44 | 2854 | else |
95879c72 | 2855 | return "%vpxor\t%0, %d0"; |
ef719a44 RH |
2856 | case 1: |
2857 | case 2: | |
66e1ecfe L |
2858 | /* TDmode values are passed as TImode on the stack. Moving them |
2859 | to stack may result in unaligned memory access. */ | |
2860 | if (misaligned_operand (operands[0], TImode) | |
2861 | || misaligned_operand (operands[1], TImode)) | |
1ffcdc02 | 2862 | { |
66e1ecfe | 2863 | if (get_attr_mode (insn) == MODE_V4SF) |
95879c72 | 2864 | return "%vmovups\t{%1, %0|%0, %1}"; |
66e1ecfe | 2865 | else |
95879c72 | 2866 | return "%vmovdqu\t{%1, %0|%0, %1}"; |
66e1ecfe | 2867 | } |
ef719a44 | 2868 | else |
1ffcdc02 | 2869 | { |
66e1ecfe | 2870 | if (get_attr_mode (insn) == MODE_V4SF) |
95879c72 | 2871 | return "%vmovaps\t{%1, %0|%0, %1}"; |
66e1ecfe | 2872 | else |
95879c72 | 2873 | return "%vmovdqa\t{%1, %0|%0, %1}"; |
66e1ecfe | 2874 | } |
ef719a44 | 2875 | default: |
7637e42c | 2876 | gcc_unreachable (); |
ef719a44 RH |
2877 | } |
2878 | } | |
4501d314 | 2879 | [(set_attr "type" "sselog1,ssemov,ssemov") |
95879c72 | 2880 | (set_attr "prefix" "maybe_vex") |
ef719a44 | 2881 | (set (attr "mode") |
4501d314 | 2882 | (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0)) |
3debdc1e | 2883 | (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))) |
ef719a44 | 2884 | (const_string "V4SF") |
4501d314 JB |
2885 | (and (eq_attr "alternative" "2") |
2886 | (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") | |
2887 | (const_int 0))) | |
2888 | (const_string "V4SF")] | |
2889 | (const_string "TI")))]) | |
ef719a44 RH |
2890 | |
2891 | (define_insn "*movti_rex64" | |
33af070f | 2892 | [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm") |
ef719a44 RH |
2893 | (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] |
2894 | "TARGET_64BIT | |
7656aee4 | 2895 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
ef719a44 RH |
2896 | { |
2897 | switch (which_alternative) | |
2898 | { | |
2899 | case 0: | |
2900 | case 1: | |
2901 | return "#"; | |
2902 | case 2: | |
2903 | if (get_attr_mode (insn) == MODE_V4SF) | |
95879c72 | 2904 | return "%vxorps\t%0, %d0"; |
ef719a44 | 2905 | else |
95879c72 | 2906 | return "%vpxor\t%0, %d0"; |
ef719a44 RH |
2907 | case 3: |
2908 | case 4: | |
66e1ecfe L |
2909 | /* TDmode values are passed as TImode on the stack. Moving them |
2910 | to stack may result in unaligned memory access. */ | |
2911 | if (misaligned_operand (operands[0], TImode) | |
2912 | || misaligned_operand (operands[1], TImode)) | |
1ffcdc02 | 2913 | { |
66e1ecfe | 2914 | if (get_attr_mode (insn) == MODE_V4SF) |
95879c72 | 2915 | return "%vmovups\t{%1, %0|%0, %1}"; |
66e1ecfe | 2916 | else |
95879c72 | 2917 | return "%vmovdqu\t{%1, %0|%0, %1}"; |
66e1ecfe | 2918 | } |
ef719a44 | 2919 | else |
1ffcdc02 | 2920 | { |
66e1ecfe | 2921 | if (get_attr_mode (insn) == MODE_V4SF) |
95879c72 | 2922 | return "%vmovaps\t{%1, %0|%0, %1}"; |
66e1ecfe | 2923 | else |
95879c72 | 2924 | return "%vmovdqa\t{%1, %0|%0, %1}"; |
66e1ecfe | 2925 | } |
ef719a44 | 2926 | default: |
7637e42c | 2927 | gcc_unreachable (); |
ef719a44 RH |
2928 | } |
2929 | } | |
4501d314 | 2930 | [(set_attr "type" "*,*,sselog1,ssemov,ssemov") |
95879c72 | 2931 | (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex") |
ef719a44 RH |
2932 | (set (attr "mode") |
2933 | (cond [(eq_attr "alternative" "2,3") | |
2934 | (if_then_else | |
3debdc1e | 2935 | (ne (symbol_ref "optimize_function_for_size_p (cfun)") |
ef719a44 RH |
2936 | (const_int 0)) |
2937 | (const_string "V4SF") | |
2938 | (const_string "TI")) | |
2939 | (eq_attr "alternative" "4") | |
2940 | (if_then_else | |
2941 | (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") | |
2942 | (const_int 0)) | |
3debdc1e | 2943 | (ne (symbol_ref "optimize_function_for_size_p (cfun)") |
ef719a44 RH |
2944 | (const_int 0))) |
2945 | (const_string "V4SF") | |
2946 | (const_string "TI"))] | |
2947 | (const_string "DI")))]) | |
2948 | ||
2949 | (define_split | |
2950 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
2951 | (match_operand:TI 1 "general_operand" ""))] | |
2952 | "reload_completed && !SSE_REG_P (operands[0]) | |
2953 | && !SSE_REG_P (operands[1])" | |
2954 | [(const_int 0)] | |
2955 | "ix86_split_long_move (operands); DONE;") | |
2956 | ||
ceca734e RH |
2957 | ;; This expands to what emit_move_complex would generate if we didn't |
2958 | ;; have a movti pattern. Having this avoids problems with reload on | |
2959 | ;; 32-bit targets when SSE is present, but doesn't seem to be harmful | |
2960 | ;; to have around all the time. | |
2961 | (define_expand "movcdi" | |
2962 | [(set (match_operand:CDI 0 "nonimmediate_operand" "") | |
2963 | (match_operand:CDI 1 "general_operand" ""))] | |
2964 | "" | |
2965 | { | |
2966 | if (push_operand (operands[0], CDImode)) | |
2967 | emit_move_complex_push (CDImode, operands[0], operands[1]); | |
2968 | else | |
2969 | emit_move_complex_parts (operands[0], operands[1]); | |
2970 | DONE; | |
2971 | }) | |
2972 | ||
0be5d99f | 2973 | (define_expand "movsf" |
4cbfbb1b | 2974 | [(set (match_operand:SF 0 "nonimmediate_operand" "") |
0be5d99f MM |
2975 | (match_operand:SF 1 "general_operand" ""))] |
2976 | "" | |
e075ae69 RH |
2977 | "ix86_expand_move (SFmode, operands); DONE;") |
2978 | ||
2979 | (define_insn "*pushsf" | |
446988df | 2980 | [(set (match_operand:SF 0 "push_operand" "=<,<,<") |
b5c82fa1 | 2981 | (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] |
0ec259ed | 2982 | "!TARGET_64BIT" |
0be5d99f | 2983 | { |
7637e42c NS |
2984 | /* Anything else should be already split before reg-stack. */ |
2985 | gcc_assert (which_alternative == 1); | |
2986 | return "push{l}\t%1"; | |
0f40f9f7 | 2987 | } |
446988df | 2988 | [(set_attr "type" "multi,push,multi") |
af12f8ea | 2989 | (set_attr "unit" "i387,*,*") |
446988df | 2990 | (set_attr "mode" "SF,SI,SF")]) |
0be5d99f | 2991 | |
0ec259ed | 2992 | (define_insn "*pushsf_rex64" |
a7efdc84 | 2993 | [(set (match_operand:SF 0 "push_operand" "=X,X,X") |
b5c82fa1 | 2994 | (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] |
0ec259ed | 2995 | "TARGET_64BIT" |
0ec259ed | 2996 | { |
7637e42c NS |
2997 | /* Anything else should be already split before reg-stack. */ |
2998 | gcc_assert (which_alternative == 1); | |
2999 | return "push{q}\t%q1"; | |
0f40f9f7 | 3000 | } |
0ec259ed | 3001 | [(set_attr "type" "multi,push,multi") |
af12f8ea | 3002 | (set_attr "unit" "i387,*,*") |
0ec259ed JH |
3003 | (set_attr "mode" "SF,DI,SF")]) |
3004 | ||
d7a29404 JH |
3005 | (define_split |
3006 | [(set (match_operand:SF 0 "push_operand" "") | |
3007 | (match_operand:SF 1 "memory_operand" ""))] | |
3008 | "reload_completed | |
7656aee4 | 3009 | && MEM_P (operands[1]) |
2a450639 | 3010 | && (operands[2] = find_constant_src (insn))" |
d7a29404 | 3011 | [(set (match_dup 0) |
2a450639 | 3012 | (match_dup 2))]) |
d7a29404 JH |
3013 | |
3014 | ||
e075ae69 RH |
3015 | ;; %%% Kill this when call knows how to work this out. |
3016 | (define_split | |
3017 | [(set (match_operand:SF 0 "push_operand" "") | |
c3c637e3 GS |
3018 | (match_operand:SF 1 "any_fp_register_operand" ""))] |
3019 | "!TARGET_64BIT" | |
8bc527af SB |
3020 | [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) |
3021 | (set (mem:SF (reg:SI SP_REG)) (match_dup 1))]) | |
e075ae69 | 3022 | |
0ec259ed JH |
3023 | (define_split |
3024 | [(set (match_operand:SF 0 "push_operand" "") | |
c3c637e3 GS |
3025 | (match_operand:SF 1 "any_fp_register_operand" ""))] |
3026 | "TARGET_64BIT" | |
8bc527af SB |
3027 | [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) |
3028 | (set (mem:SF (reg:DI SP_REG)) (match_dup 1))]) | |
0ec259ed | 3029 | |
e075ae69 | 3030 | (define_insn "*movsf_1" |
6c4ccfd8 | 3031 | [(set (match_operand:SF 0 "nonimmediate_operand" |
4afb7791 | 3032 | "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r") |
6c4ccfd8 | 3033 | (match_operand:SF 1 "general_operand" |
4afb7791 | 3034 | "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))] |
f75959a6 | 3035 | "!(MEM_P (operands[0]) && MEM_P (operands[1])) |
d7a29404 | 3036 | && (reload_in_progress || reload_completed |
3987b9db | 3037 | || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) |
3debdc1e | 3038 | || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun) |
8002331e | 3039 | && standard_80387_constant_p (operands[1])) |
d7a29404 | 3040 | || GET_CODE (operands[1]) != CONST_DOUBLE |
6300f037 | 3041 | || memory_operand (operands[0], SFmode))" |
886c62d1 | 3042 | { |
e075ae69 | 3043 | switch (which_alternative) |
886c62d1 | 3044 | { |
e075ae69 | 3045 | case 0: |
e075ae69 | 3046 | case 1: |
d869c351 | 3047 | return output_387_reg_move (insn, operands); |
886c62d1 | 3048 | |
e075ae69 | 3049 | case 2: |
881b2a96 | 3050 | return standard_80387_constant_opcode (operands[1]); |
886c62d1 | 3051 | |
e075ae69 RH |
3052 | case 3: |
3053 | case 4: | |
0f40f9f7 | 3054 | return "mov{l}\t{%1, %0|%0, %1}"; |
446988df | 3055 | case 5: |
4977bab6 | 3056 | if (get_attr_mode (insn) == MODE_TI) |
95879c72 | 3057 | return "%vpxor\t%0, %d0"; |
692efa8e | 3058 | else |
95879c72 | 3059 | return "%vxorps\t%0, %d0"; |
446988df | 3060 | case 6: |
4977bab6 | 3061 | if (get_attr_mode (insn) == MODE_V4SF) |
95879c72 L |
3062 | return "%vmovaps\t{%1, %0|%0, %1}"; |
3063 | else | |
3064 | return "%vmovss\t{%1, %d0|%d0, %1}"; | |
3065 | case 7: | |
3066 | if (TARGET_AVX) | |
3067 | return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}" | |
3068 | : "vmovss\t{%1, %0|%0, %1}"; | |
2b04e52b | 3069 | else |
0f40f9f7 | 3070 | return "movss\t{%1, %0|%0, %1}"; |
95879c72 L |
3071 | case 8: |
3072 | return "%vmovss\t{%1, %0|%0, %1}"; | |
886c62d1 | 3073 | |
95879c72 | 3074 | case 9: case 10: case 14: case 15: |
ac300a45 | 3075 | return "movd\t{%1, %0|%0, %1}"; |
95879c72 L |
3076 | case 12: case 13: |
3077 | return "%vmovd\t{%1, %0|%0, %1}"; | |
ac300a45 | 3078 | |
e5a20888 JJ |
3079 | case 11: |
3080 | return "movq\t{%1, %0|%0, %1}"; | |
3081 | ||
e075ae69 | 3082 | default: |
7637e42c | 3083 | gcc_unreachable (); |
e075ae69 | 3084 | } |
0f40f9f7 | 3085 | } |
ed69105c | 3086 | [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov") |
95879c72 L |
3087 | (set (attr "prefix") |
3088 | (if_then_else (eq_attr "alternative" "5,6,7,8,12,13") | |
3089 | (const_string "maybe_vex") | |
3090 | (const_string "orig"))) | |
4977bab6 ZW |
3091 | (set (attr "mode") |
3092 | (cond [(eq_attr "alternative" "3,4,9,10") | |
3093 | (const_string "SI") | |
3094 | (eq_attr "alternative" "5") | |
3095 | (if_then_else | |
3096 | (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") | |
3097 | (const_int 0)) | |
3098 | (ne (symbol_ref "TARGET_SSE2") | |
3099 | (const_int 0))) | |
3debdc1e | 3100 | (eq (symbol_ref "optimize_function_for_size_p (cfun)") |
4977bab6 ZW |
3101 | (const_int 0))) |
3102 | (const_string "TI") | |
3103 | (const_string "V4SF")) | |
3104 | /* For architectures resolving dependencies on | |
3105 | whole SSE registers use APS move to break dependency | |
6300f037 | 3106 | chains, otherwise use short move to avoid extra work. |
4977bab6 ZW |
3107 | |
3108 | Do the same for architectures resolving dependencies on | |
3109 | the parts. While in DF mode it is better to always handle | |
3110 | just register parts, the SF mode is different due to lack | |
3111 | of instructions to load just part of the register. It is | |
3112 | better to maintain the whole registers in single format | |
3113 | to avoid problems on using packed logical operations. */ | |
3114 | (eq_attr "alternative" "6") | |
3115 | (if_then_else | |
3116 | (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") | |
3117 | (const_int 0)) | |
41afe4ef | 3118 | (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") |
4977bab6 ZW |
3119 | (const_int 0))) |
3120 | (const_string "V4SF") | |
3121 | (const_string "SF")) | |
3122 | (eq_attr "alternative" "11") | |
3123 | (const_string "DI")] | |
3124 | (const_string "SF")))]) | |
d7a29404 | 3125 | |
a4414093 | 3126 | (define_insn "*swapsf" |
6c4ccfd8 RH |
3127 | [(set (match_operand:SF 0 "fp_register_operand" "+f") |
3128 | (match_operand:SF 1 "fp_register_operand" "+f")) | |
0be5d99f MM |
3129 | (set (match_dup 1) |
3130 | (match_dup 0))] | |
6c4ccfd8 | 3131 | "reload_completed || TARGET_80387" |
0be5d99f MM |
3132 | { |
3133 | if (STACK_TOP_P (operands[0])) | |
0f40f9f7 | 3134 | return "fxch\t%1"; |
0be5d99f | 3135 | else |
0f40f9f7 ZW |
3136 | return "fxch\t%0"; |
3137 | } | |
6ef67412 JH |
3138 | [(set_attr "type" "fxch") |
3139 | (set_attr "mode" "SF")]) | |
0be5d99f | 3140 | |
e075ae69 | 3141 | (define_expand "movdf" |
4cbfbb1b | 3142 | [(set (match_operand:DF 0 "nonimmediate_operand" "") |
e075ae69 RH |
3143 | (match_operand:DF 1 "general_operand" ""))] |
3144 | "" | |
3145 | "ix86_expand_move (DFmode, operands); DONE;") | |
55953cea | 3146 | |
8fcaaa80 | 3147 | ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. |
d1f87653 | 3148 | ;; Size of pushdf using integer instructions is 2+2*memory operand size |
8fcaaa80 JH |
3149 | ;; On the average, pushdf using integers can be still shorter. Allow this |
3150 | ;; pattern for optimize_size too. | |
3151 | ||
0b5107cf | 3152 | (define_insn "*pushdf_nointeger" |
446988df | 3153 | [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") |
e2520c41 | 3154 | (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))] |
0ec259ed | 3155 | "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" |
0b5107cf | 3156 | { |
839a4992 | 3157 | /* This insn should be already split before reg-stack. */ |
7637e42c | 3158 | gcc_unreachable (); |
0f40f9f7 | 3159 | } |
6ef67412 | 3160 | [(set_attr "type" "multi") |
af12f8ea | 3161 | (set_attr "unit" "i387,*,*,*") |
446988df | 3162 | (set_attr "mode" "DF,SI,SI,DF")]) |
0b5107cf JH |
3163 | |
3164 | (define_insn "*pushdf_integer" | |
446988df | 3165 | [(set (match_operand:DF 0 "push_operand" "=<,<,<") |
e2520c41 | 3166 | (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))] |
0ec259ed | 3167 | "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" |
f31fce3f | 3168 | { |
839a4992 | 3169 | /* This insn should be already split before reg-stack. */ |
7637e42c | 3170 | gcc_unreachable (); |
0f40f9f7 | 3171 | } |
6ef67412 | 3172 | [(set_attr "type" "multi") |
af12f8ea | 3173 | (set_attr "unit" "i387,*,*") |
446988df | 3174 | (set_attr "mode" "DF,SI,DF")]) |
f31fce3f | 3175 | |
e075ae69 | 3176 | ;; %%% Kill this when call knows how to work this out. |
f72b27a5 JH |
3177 | (define_split |
3178 | [(set (match_operand:DF 0 "push_operand" "") | |
c3c637e3 | 3179 | (match_operand:DF 1 "any_fp_register_operand" ""))] |
90b48492 KT |
3180 | "reload_completed" |
3181 | [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) | |
3182 | (set (mem:DF (reg:P SP_REG)) (match_dup 1))] | |
0ec259ed JH |
3183 | "") |
3184 | ||
e075ae69 RH |
3185 | (define_split |
3186 | [(set (match_operand:DF 0 "push_operand" "") | |
0be5d99f | 3187 | (match_operand:DF 1 "general_operand" ""))] |
e075ae69 | 3188 | "reload_completed" |
2450a057 | 3189 | [(const_int 0)] |
26e5b205 | 3190 | "ix86_split_long_move (operands); DONE;") |
0be5d99f | 3191 | |
8fcaaa80 JH |
3192 | ;; Moving is usually shorter when only FP registers are used. This separate |
3193 | ;; movdf pattern avoids the use of integer registers for FP operations | |
3194 | ;; when optimizing for size. | |
3195 | ||
3196 | (define_insn "*movdf_nointeger" | |
6c4ccfd8 | 3197 | [(set (match_operand:DF 0 "nonimmediate_operand" |
e2520c41 | 3198 | "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ") |
6c4ccfd8 | 3199 | (match_operand:DF 1 "general_operand" |
20a415f8 | 3200 | "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))] |
7656aee4 | 3201 | "!(MEM_P (operands[0]) && MEM_P (operands[1])) |
3debdc1e JH |
3202 | && ((optimize_function_for_size_p (cfun) |
3203 | || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT) | |
d7a29404 | 3204 | && (reload_in_progress || reload_completed |
3987b9db | 3205 | || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) |
3debdc1e JH |
3206 | || (!(TARGET_SSE2 && TARGET_SSE_MATH) |
3207 | && optimize_function_for_size_p (cfun) | |
20a415f8 | 3208 | && !memory_operand (operands[0], DFmode) |
8002331e | 3209 | && standard_80387_constant_p (operands[1])) |
d7a29404 | 3210 | || GET_CODE (operands[1]) != CONST_DOUBLE |
3debdc1e | 3211 | || ((optimize_function_for_size_p (cfun) |
20a415f8 JH |
3212 | || !TARGET_MEMORY_MISMATCH_STALL |
3213 | || reload_in_progress || reload_completed) | |
3214 | && memory_operand (operands[0], DFmode)))" | |
8fcaaa80 JH |
3215 | { |
3216 | switch (which_alternative) | |
3217 | { | |
3218 | case 0: | |
8fcaaa80 | 3219 | case 1: |
d869c351 | 3220 | return output_387_reg_move (insn, operands); |
8fcaaa80 JH |
3221 | |
3222 | case 2: | |
881b2a96 | 3223 | return standard_80387_constant_opcode (operands[1]); |
8fcaaa80 JH |
3224 | |
3225 | case 3: | |
3226 | case 4: | |
0f40f9f7 | 3227 | return "#"; |
446988df | 3228 | case 5: |
4977bab6 ZW |
3229 | switch (get_attr_mode (insn)) |
3230 | { | |
3231 | case MODE_V4SF: | |
95879c72 | 3232 | return "%vxorps\t%0, %d0"; |
4977bab6 | 3233 | case MODE_V2DF: |
95879c72 | 3234 | return "%vxorpd\t%0, %d0"; |
4977bab6 | 3235 | case MODE_TI: |
95879c72 | 3236 | return "%vpxor\t%0, %d0"; |
4977bab6 | 3237 | default: |
7637e42c | 3238 | gcc_unreachable (); |
4977bab6 | 3239 | } |
446988df | 3240 | case 6: |
6c4ccfd8 RH |
3241 | case 7: |
3242 | case 8: | |
4977bab6 ZW |
3243 | switch (get_attr_mode (insn)) |
3244 | { | |
3245 | case MODE_V4SF: | |
95879c72 | 3246 | return "%vmovaps\t{%1, %0|%0, %1}"; |
4977bab6 | 3247 | case MODE_V2DF: |
95879c72 | 3248 | return "%vmovapd\t{%1, %0|%0, %1}"; |
6c4ccfd8 | 3249 | case MODE_TI: |
95879c72 | 3250 | return "%vmovdqa\t{%1, %0|%0, %1}"; |
6c4ccfd8 | 3251 | case MODE_DI: |
95879c72 | 3252 | return "%vmovq\t{%1, %0|%0, %1}"; |
4977bab6 | 3253 | case MODE_DF: |
95879c72 L |
3254 | if (TARGET_AVX) |
3255 | { | |
3256 | if (REG_P (operands[0]) && REG_P (operands[1])) | |
3257 | return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; | |
3258 | else | |
3259 | return "vmovsd\t{%1, %0|%0, %1}"; | |
3260 | } | |
3261 | else | |
3262 | return "movsd\t{%1, %0|%0, %1}"; | |
6c4ccfd8 | 3263 | case MODE_V1DF: |
95879c72 L |
3264 | if (TARGET_AVX) |
3265 | { | |
3266 | if (REG_P (operands[0])) | |
3267 | return "vmovlpd\t{%1, %0, %0|%0, %0, %1}"; | |
3268 | else | |
3269 | return "vmovlpd\t{%1, %0|%0, %1}"; | |
3270 | } | |
3271 | else | |
3272 | return "movlpd\t{%1, %0|%0, %1}"; | |
d30c9461 | 3273 | case MODE_V2SF: |
95879c72 L |
3274 | if (TARGET_AVX) |
3275 | { | |
3276 | if (REG_P (operands[0])) | |
3277 | return "vmovlps\t{%1, %0, %0|%0, %0, %1}"; | |
3278 | else | |
3279 | return "vmovlps\t{%1, %0|%0, %1}"; | |
3280 | } | |
3281 | else | |
3282 | return "movlps\t{%1, %0|%0, %1}"; | |
4977bab6 | 3283 | default: |
7637e42c | 3284 | gcc_unreachable (); |
4977bab6 | 3285 | } |
8fcaaa80 JH |
3286 | |
3287 | default: | |
7637e42c | 3288 | gcc_unreachable (); |
8fcaaa80 | 3289 | } |
0f40f9f7 | 3290 | } |
4501d314 | 3291 | [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") |
95879c72 L |
3292 | (set (attr "prefix") |
3293 | (if_then_else (eq_attr "alternative" "0,1,2,3,4") | |
3294 | (const_string "orig") | |
3295 | (const_string "maybe_vex"))) | |
725fd454 JJ |
3296 | (set (attr "prefix_data16") |
3297 | (if_then_else (eq_attr "mode" "V1DF") | |
3298 | (const_string "1") | |
3299 | (const_string "*"))) | |
4977bab6 | 3300 | (set (attr "mode") |
d30c9461 RH |
3301 | (cond [(eq_attr "alternative" "0,1,2") |
3302 | (const_string "DF") | |
3303 | (eq_attr "alternative" "3,4") | |
4977bab6 | 3304 | (const_string "SI") |
6c4ccfd8 RH |
3305 | |
3306 | /* For SSE1, we have many fewer alternatives. */ | |
3307 | (eq (symbol_ref "TARGET_SSE2") (const_int 0)) | |
3308 | (cond [(eq_attr "alternative" "5,6") | |
d30c9461 | 3309 | (const_string "V4SF") |
6c4ccfd8 | 3310 | ] |
d30c9461 | 3311 | (const_string "V2SF")) |
6c4ccfd8 | 3312 | |
4977bab6 ZW |
3313 | /* xorps is one byte shorter. */ |
3314 | (eq_attr "alternative" "5") | |
3debdc1e | 3315 | (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") |
4977bab6 ZW |
3316 | (const_int 0)) |
3317 | (const_string "V4SF") | |
3318 | (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") | |
3319 | (const_int 0)) | |
6c4ccfd8 RH |
3320 | (const_string "TI") |
3321 | ] | |
4977bab6 | 3322 | (const_string "V2DF")) |
6c4ccfd8 | 3323 | |
4977bab6 ZW |
3324 | /* For architectures resolving dependencies on |
3325 | whole SSE registers use APD move to break dependency | |
3326 | chains, otherwise use short move to avoid extra work. | |
3327 | ||
3328 | movaps encodes one byte shorter. */ | |
3329 | (eq_attr "alternative" "6") | |
3330 | (cond | |
3debdc1e | 3331 | [(ne (symbol_ref "optimize_function_for_size_p (cfun)") |
6c4ccfd8 RH |
3332 | (const_int 0)) |
3333 | (const_string "V4SF") | |
3334 | (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") | |
3335 | (const_int 0)) | |
3336 | (const_string "V2DF") | |
3337 | ] | |
4977bab6 | 3338 | (const_string "DF")) |
d1f87653 | 3339 | /* For architectures resolving dependencies on register |
4977bab6 ZW |
3340 | parts we may avoid extra work to zero out upper part |
3341 | of register. */ | |
3342 | (eq_attr "alternative" "7") | |
3343 | (if_then_else | |
41afe4ef | 3344 | (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") |
4977bab6 | 3345 | (const_int 0)) |
6c4ccfd8 RH |
3346 | (const_string "V1DF") |
3347 | (const_string "DF")) | |
3348 | ] | |
3349 | (const_string "DF")))]) | |
8fcaaa80 | 3350 | |
ed69105c RH |
3351 | (define_insn "*movdf_integer_rex64" |
3352 | [(set (match_operand:DF 0 "nonimmediate_operand" | |
e2520c41 | 3353 | "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ") |
ed69105c | 3354 | (match_operand:DF 1 "general_operand" |
e2520c41 | 3355 | "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))] |
ed69105c RH |
3356 | "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1])) |
3357 | && (reload_in_progress || reload_completed | |
3358 | || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) | |
3debdc1e JH |
3359 | || (!(TARGET_SSE2 && TARGET_SSE_MATH) |
3360 | && optimize_function_for_size_p (cfun) | |
ed69105c RH |
3361 | && standard_80387_constant_p (operands[1])) |
3362 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
3363 | || memory_operand (operands[0], DFmode))" | |
3364 | { | |
3365 | switch (which_alternative) | |
3366 | { | |
3367 | case 0: | |
ed69105c | 3368 | case 1: |
d869c351 | 3369 | return output_387_reg_move (insn, operands); |
ed69105c RH |
3370 | |
3371 | case 2: | |
3372 | return standard_80387_constant_opcode (operands[1]); | |
3373 | ||
3374 | case 3: | |
3375 | case 4: | |
3376 | return "#"; | |
3377 | ||
3378 | case 5: | |
3379 | switch (get_attr_mode (insn)) | |
3380 | { | |
3381 | case MODE_V4SF: | |
95879c72 | 3382 | return "%vxorps\t%0, %d0"; |
ed69105c | 3383 | case MODE_V2DF: |
95879c72 | 3384 | return "%vxorpd\t%0, %d0"; |
ed69105c | 3385 | case MODE_TI: |
95879c72 | 3386 | return "%vpxor\t%0, %d0"; |
ed69105c RH |
3387 | default: |
3388 | gcc_unreachable (); | |
3389 | } | |
3390 | case 6: | |
3391 | case 7: | |
3392 | case 8: | |
3393 | switch (get_attr_mode (insn)) | |
3394 | { | |
3395 | case MODE_V4SF: | |
95879c72 | 3396 | return "%vmovaps\t{%1, %0|%0, %1}"; |
ed69105c | 3397 | case MODE_V2DF: |
95879c72 | 3398 | return "%vmovapd\t{%1, %0|%0, %1}"; |
ed69105c | 3399 | case MODE_TI: |
95879c72 | 3400 | return "%vmovdqa\t{%1, %0|%0, %1}"; |
ed69105c | 3401 | case MODE_DI: |
95879c72 | 3402 | return "%vmovq\t{%1, %0|%0, %1}"; |
ed69105c | 3403 | case MODE_DF: |
95879c72 L |
3404 | if (TARGET_AVX) |
3405 | { | |
3406 | if (REG_P (operands[0]) && REG_P (operands[1])) | |
3407 | return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; | |
3408 | else | |
3409 | return "vmovsd\t{%1, %0|%0, %1}"; | |
3410 | } | |
3411 | else | |
3412 | return "movsd\t{%1, %0|%0, %1}"; | |
ed69105c | 3413 | case MODE_V1DF: |
95879c72 | 3414 | return "%vmovlpd\t{%1, %d0|%d0, %1}"; |
ed69105c | 3415 | case MODE_V2SF: |
95879c72 | 3416 | return "%vmovlps\t{%1, %d0|%d0, %1}"; |
ed69105c RH |
3417 | default: |
3418 | gcc_unreachable (); | |
3419 | } | |
3420 | ||
3421 | case 9: | |
3422 | case 10: | |
95879c72 | 3423 | return "%vmovd\t{%1, %0|%0, %1}"; |
ed69105c RH |
3424 | |
3425 | default: | |
3426 | gcc_unreachable(); | |
3427 | } | |
3428 | } | |
3429 | [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov") | |
95879c72 L |
3430 | (set (attr "prefix") |
3431 | (if_then_else (eq_attr "alternative" "0,1,2,3,4") | |
3432 | (const_string "orig") | |
3433 | (const_string "maybe_vex"))) | |
725fd454 JJ |
3434 | (set (attr "prefix_data16") |
3435 | (if_then_else (eq_attr "mode" "V1DF") | |
3436 | (const_string "1") | |
3437 | (const_string "*"))) | |
ed69105c RH |
3438 | (set (attr "mode") |
3439 | (cond [(eq_attr "alternative" "0,1,2") | |
3440 | (const_string "DF") | |
3441 | (eq_attr "alternative" "3,4,9,10") | |
3442 | (const_string "DI") | |
3443 | ||
3444 | /* For SSE1, we have many fewer alternatives. */ | |
3445 | (eq (symbol_ref "TARGET_SSE2") (const_int 0)) | |
3446 | (cond [(eq_attr "alternative" "5,6") | |
3447 | (const_string "V4SF") | |
3448 | ] | |
3449 | (const_string "V2SF")) | |
3450 | ||
3451 | /* xorps is one byte shorter. */ | |
3452 | (eq_attr "alternative" "5") | |
3debdc1e | 3453 | (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") |
ed69105c RH |
3454 | (const_int 0)) |
3455 | (const_string "V4SF") | |
3456 | (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") | |
3457 | (const_int 0)) | |
3458 | (const_string "TI") | |
3459 | ] | |
3460 | (const_string "V2DF")) | |
3461 | ||
3462 | /* For architectures resolving dependencies on | |
3463 | whole SSE registers use APD move to break dependency | |
3464 | chains, otherwise use short move to avoid extra work. | |
3465 | ||
3466 | movaps encodes one byte shorter. */ | |
3467 | (eq_attr "alternative" "6") | |
3468 | (cond | |
3debdc1e | 3469 | [(ne (symbol_ref "optimize_function_for_size_p (cfun)") |
ed69105c RH |
3470 | (const_int 0)) |
3471 | (const_string "V4SF") | |
3472 | (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") | |
3473 | (const_int 0)) | |
3474 | (const_string "V2DF") | |
3475 | ] | |
3476 | (const_string "DF")) | |
3477 | /* For architectures resolving dependencies on register | |
3478 | parts we may avoid extra work to zero out upper part | |
3479 | of register. */ | |
3480 | (eq_attr "alternative" "7") | |
3481 | (if_then_else | |
3482 | (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") | |
3483 | (const_int 0)) | |
3484 | (const_string "V1DF") | |
3485 | (const_string "DF")) | |
3486 | ] | |
3487 | (const_string "DF")))]) | |
3488 | ||
8fcaaa80 | 3489 | (define_insn "*movdf_integer" |
6c4ccfd8 | 3490 | [(set (match_operand:DF 0 "nonimmediate_operand" |
e2520c41 | 3491 | "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ") |
6c4ccfd8 | 3492 | (match_operand:DF 1 "general_operand" |
e2520c41 | 3493 | "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))] |
7656aee4 | 3494 | "!(MEM_P (operands[0]) && MEM_P (operands[1])) |
3debdc1e JH |
3495 | && optimize_function_for_speed_p (cfun) |
3496 | && TARGET_INTEGER_DFMODE_MOVES | |
d7a29404 | 3497 | && (reload_in_progress || reload_completed |
3987b9db | 3498 | || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) |
3debdc1e JH |
3499 | || (!(TARGET_SSE2 && TARGET_SSE_MATH) |
3500 | && optimize_function_for_size_p (cfun) | |
8002331e | 3501 | && standard_80387_constant_p (operands[1])) |
d7a29404 | 3502 | || GET_CODE (operands[1]) != CONST_DOUBLE |
6300f037 | 3503 | || memory_operand (operands[0], DFmode))" |
886c62d1 | 3504 | { |
e075ae69 | 3505 | switch (which_alternative) |
886c62d1 | 3506 | { |
e075ae69 | 3507 | case 0: |
e075ae69 | 3508 | case 1: |
d869c351 | 3509 | return output_387_reg_move (insn, operands); |
886c62d1 | 3510 | |
e075ae69 | 3511 | case 2: |
881b2a96 | 3512 | return standard_80387_constant_opcode (operands[1]); |
886c62d1 | 3513 | |
e075ae69 RH |
3514 | case 3: |
3515 | case 4: | |
0f40f9f7 | 3516 | return "#"; |
886c62d1 | 3517 | |
446988df | 3518 | case 5: |
4977bab6 ZW |
3519 | switch (get_attr_mode (insn)) |
3520 | { | |
3521 | case MODE_V4SF: | |
3522 | return "xorps\t%0, %0"; | |
3523 | case MODE_V2DF: | |
3524 | return "xorpd\t%0, %0"; | |
3525 | case MODE_TI: | |
3526 | return "pxor\t%0, %0"; | |
3527 | default: | |
7637e42c | 3528 | gcc_unreachable (); |
4977bab6 | 3529 | } |
446988df | 3530 | case 6: |
6c4ccfd8 RH |
3531 | case 7: |
3532 | case 8: | |
4977bab6 ZW |
3533 | switch (get_attr_mode (insn)) |
3534 | { | |
3535 | case MODE_V4SF: | |
3536 | return "movaps\t{%1, %0|%0, %1}"; | |
3537 | case MODE_V2DF: | |
3538 | return "movapd\t{%1, %0|%0, %1}"; | |
6c4ccfd8 RH |
3539 | case MODE_TI: |
3540 | return "movdqa\t{%1, %0|%0, %1}"; | |
3541 | case MODE_DI: | |
3542 | return "movq\t{%1, %0|%0, %1}"; | |
4977bab6 ZW |
3543 | case MODE_DF: |
3544 | return "movsd\t{%1, %0|%0, %1}"; | |
6c4ccfd8 RH |
3545 | case MODE_V1DF: |
3546 | return "movlpd\t{%1, %0|%0, %1}"; | |
d30c9461 RH |
3547 | case MODE_V2SF: |
3548 | return "movlps\t{%1, %0|%0, %1}"; | |
4977bab6 | 3549 | default: |
7637e42c | 3550 | gcc_unreachable (); |
4977bab6 | 3551 | } |
446988df | 3552 | |
e075ae69 | 3553 | default: |
7637e42c | 3554 | gcc_unreachable(); |
e075ae69 | 3555 | } |
0f40f9f7 | 3556 | } |
4501d314 | 3557 | [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") |
725fd454 JJ |
3558 | (set (attr "prefix_data16") |
3559 | (if_then_else (eq_attr "mode" "V1DF") | |
3560 | (const_string "1") | |
3561 | (const_string "*"))) | |
4977bab6 | 3562 | (set (attr "mode") |
d30c9461 RH |
3563 | (cond [(eq_attr "alternative" "0,1,2") |
3564 | (const_string "DF") | |
3565 | (eq_attr "alternative" "3,4") | |
4977bab6 | 3566 | (const_string "SI") |
6c4ccfd8 RH |
3567 | |
3568 | /* For SSE1, we have many fewer alternatives. */ | |
3569 | (eq (symbol_ref "TARGET_SSE2") (const_int 0)) | |
3570 | (cond [(eq_attr "alternative" "5,6") | |
d30c9461 | 3571 | (const_string "V4SF") |
6c4ccfd8 | 3572 | ] |
d30c9461 | 3573 | (const_string "V2SF")) |
6c4ccfd8 | 3574 | |
4977bab6 ZW |
3575 | /* xorps is one byte shorter. */ |
3576 | (eq_attr "alternative" "5") | |
3debdc1e | 3577 | (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") |
4977bab6 ZW |
3578 | (const_int 0)) |
3579 | (const_string "V4SF") | |
3580 | (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") | |
3581 | (const_int 0)) | |
6c4ccfd8 RH |
3582 | (const_string "TI") |
3583 | ] | |
4977bab6 | 3584 | (const_string "V2DF")) |
6c4ccfd8 | 3585 | |
4977bab6 ZW |
3586 | /* For architectures resolving dependencies on |
3587 | whole SSE registers use APD move to break dependency | |
6c4ccfd8 | 3588 | chains, otherwise use short move to avoid extra work. |
4977bab6 ZW |
3589 | |
3590 | movaps encodes one byte shorter. */ | |
3591 | (eq_attr "alternative" "6") | |
3592 | (cond | |
3debdc1e | 3593 | [(ne (symbol_ref "optimize_function_for_size_p (cfun)") |
6c4ccfd8 RH |
3594 | (const_int 0)) |
3595 | (const_string "V4SF") | |
3596 | (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") | |
3597 | (const_int 0)) | |
3598 | (const_string "V2DF") | |
3599 | ] | |
4977bab6 | 3600 | (const_string "DF")) |
d1f87653 | 3601 | /* For architectures resolving dependencies on register |
4977bab6 ZW |
3602 | parts we may avoid extra work to zero out upper part |
3603 | of register. */ | |
3604 | (eq_attr "alternative" "7") | |
3605 | (if_then_else | |
41afe4ef | 3606 | (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") |
4977bab6 | 3607 | (const_int 0)) |
6c4ccfd8 RH |
3608 | (const_string "V1DF") |
3609 | (const_string "DF")) | |
3610 | ] | |
3611 | (const_string "DF")))]) | |
2ae0f82c | 3612 | |
e075ae69 RH |
3613 | (define_split |
3614 | [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
3615 | (match_operand:DF 1 "general_operand" ""))] | |
3616 | "reload_completed | |
7656aee4 | 3617 | && !(MEM_P (operands[0]) && MEM_P (operands[1])) |
6300f037 | 3618 | && ! (ANY_FP_REG_P (operands[0]) || |
e075ae69 | 3619 | (GET_CODE (operands[0]) == SUBREG |
446988df | 3620 | && ANY_FP_REG_P (SUBREG_REG (operands[0])))) |
6300f037 | 3621 | && ! (ANY_FP_REG_P (operands[1]) || |
e075ae69 | 3622 | (GET_CODE (operands[1]) == SUBREG |
446988df | 3623 | && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" |
26e5b205 JH |
3624 | [(const_int 0)] |
3625 | "ix86_split_long_move (operands); DONE;") | |
886c62d1 | 3626 | |
a4414093 | 3627 | (define_insn "*swapdf" |
6c4ccfd8 RH |
3628 | [(set (match_operand:DF 0 "fp_register_operand" "+f") |
3629 | (match_operand:DF 1 "fp_register_operand" "+f")) | |
0be5d99f MM |
3630 | (set (match_dup 1) |
3631 | (match_dup 0))] | |
6c4ccfd8 | 3632 | "reload_completed || TARGET_80387" |
0be5d99f MM |
3633 | { |
3634 | if (STACK_TOP_P (operands[0])) | |
0f40f9f7 | 3635 | return "fxch\t%1"; |
0be5d99f | 3636 | else |
0f40f9f7 ZW |
3637 | return "fxch\t%0"; |
3638 | } | |
6ef67412 JH |
3639 | [(set_attr "type" "fxch") |
3640 | (set_attr "mode" "DF")]) | |
e075ae69 RH |
3641 | |
3642 | (define_expand "movxf" | |
4cbfbb1b | 3643 | [(set (match_operand:XF 0 "nonimmediate_operand" "") |
e075ae69 | 3644 | (match_operand:XF 1 "general_operand" ""))] |
2b589241 | 3645 | "" |
f8a1ebc6 | 3646 | "ix86_expand_move (XFmode, operands); DONE;") |
2b589241 | 3647 | |
8fcaaa80 | 3648 | ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. |
d1f87653 | 3649 | ;; Size of pushdf using integer instructions is 3+3*memory operand size |
8fcaaa80 JH |
3650 | ;; Pushing using integer instructions is longer except for constants |
3651 | ;; and direct memory references. | |
3652 | ;; (assuming that any given constant is pushed only once, but this ought to be | |
3653 | ;; handled elsewhere). | |
3654 | ||
3655 | (define_insn "*pushxf_nointeger" | |
1e07edd3 | 3656 | [(set (match_operand:XF 0 "push_operand" "=X,X,X") |
2c5a510c | 3657 | (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))] |
3debdc1e | 3658 | "optimize_function_for_size_p (cfun)" |
2b589241 | 3659 | { |
839a4992 | 3660 | /* This insn should be already split before reg-stack. */ |
7637e42c | 3661 | gcc_unreachable (); |
0f40f9f7 | 3662 | } |
2b589241 | 3663 | [(set_attr "type" "multi") |
af12f8ea | 3664 | (set_attr "unit" "i387,*,*") |
2b589241 JH |
3665 | (set_attr "mode" "XF,SI,SI")]) |
3666 | ||
8fcaaa80 | 3667 | (define_insn "*pushxf_integer" |
2450a057 | 3668 | [(set (match_operand:XF 0 "push_operand" "=<,<") |
b5c82fa1 | 3669 | (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] |
3debdc1e | 3670 | "optimize_function_for_speed_p (cfun)" |
2b589241 | 3671 | { |
839a4992 | 3672 | /* This insn should be already split before reg-stack. */ |
7637e42c | 3673 | gcc_unreachable (); |
0f40f9f7 | 3674 | } |
2b589241 | 3675 | [(set_attr "type" "multi") |
af12f8ea | 3676 | (set_attr "unit" "i387,*") |
2b589241 JH |
3677 | (set_attr "mode" "XF,SI")]) |
3678 | ||
2450a057 | 3679 | (define_split |
2b589241 JH |
3680 | [(set (match_operand 0 "push_operand" "") |
3681 | (match_operand 1 "general_operand" ""))] | |
2450a057 | 3682 | "reload_completed |
2b589241 | 3683 | && (GET_MODE (operands[0]) == XFmode |
2b589241 | 3684 | || GET_MODE (operands[0]) == DFmode) |
c3c637e3 | 3685 | && !ANY_FP_REG_P (operands[1])" |
2450a057 | 3686 | [(const_int 0)] |
26e5b205 | 3687 | "ix86_split_long_move (operands); DONE;") |
2450a057 | 3688 | |
f72b27a5 JH |
3689 | (define_split |
3690 | [(set (match_operand:XF 0 "push_operand" "") | |
c3c637e3 | 3691 | (match_operand:XF 1 "any_fp_register_operand" ""))] |
90b48492 KT |
3692 | "" |
3693 | [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) | |
3694 | (set (mem:XF (reg:P SP_REG)) (match_dup 1))] | |
f8a1ebc6 | 3695 | "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") |
0ec259ed | 3696 | |
8fcaaa80 JH |
3697 | ;; Do not use integer registers when optimizing for size |
3698 | (define_insn "*movxf_nointeger" | |
3699 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o") | |
3700 | (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))] | |
3debdc1e | 3701 | "optimize_function_for_size_p (cfun) |
7656aee4 | 3702 | && !(MEM_P (operands[0]) && MEM_P (operands[1])) |
d7a29404 | 3703 | && (reload_in_progress || reload_completed |
3debdc1e | 3704 | || standard_80387_constant_p (operands[1]) |
d7a29404 | 3705 | || GET_CODE (operands[1]) != CONST_DOUBLE |
6300f037 | 3706 | || memory_operand (operands[0], XFmode))" |
0be5d99f | 3707 | { |
8fcaaa80 JH |
3708 | switch (which_alternative) |
3709 | { | |
3710 | case 0: | |
8fcaaa80 | 3711 | case 1: |
d869c351 | 3712 | return output_387_reg_move (insn, operands); |
8fcaaa80 JH |
3713 | |
3714 | case 2: | |
881b2a96 | 3715 | return standard_80387_constant_opcode (operands[1]); |
8fcaaa80 JH |
3716 | |
3717 | case 3: case 4: | |
0f40f9f7 | 3718 | return "#"; |
7637e42c NS |
3719 | default: |
3720 | gcc_unreachable (); | |
8fcaaa80 | 3721 | } |
0f40f9f7 | 3722 | } |
6ef67412 JH |
3723 | [(set_attr "type" "fmov,fmov,fmov,multi,multi") |
3724 | (set_attr "mode" "XF,XF,XF,SI,SI")]) | |
8fcaaa80 JH |
3725 | |
3726 | (define_insn "*movxf_integer" | |
b5c82fa1 PB |
3727 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o") |
3728 | (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))] | |
3debdc1e | 3729 | "optimize_function_for_speed_p (cfun) |
7656aee4 | 3730 | && !(MEM_P (operands[0]) && MEM_P (operands[1])) |
d7a29404 JH |
3731 | && (reload_in_progress || reload_completed |
3732 | || GET_CODE (operands[1]) != CONST_DOUBLE | |
6300f037 | 3733 | || memory_operand (operands[0], XFmode))" |
4fb21e90 | 3734 | { |
e075ae69 | 3735 | switch (which_alternative) |
4fb21e90 | 3736 | { |
e075ae69 | 3737 | case 0: |
e075ae69 | 3738 | case 1: |
d869c351 | 3739 | return output_387_reg_move (insn, operands); |
2f17722a | 3740 | |
e075ae69 | 3741 | case 2: |
881b2a96 | 3742 | return standard_80387_constant_opcode (operands[1]); |
467403ca RH |
3743 | |
3744 | case 3: case 4: | |
0f40f9f7 | 3745 | return "#"; |
7637e42c NS |
3746 | |
3747 | default: | |
3748 | gcc_unreachable (); | |
4fb21e90 | 3749 | } |
0f40f9f7 | 3750 | } |
6ef67412 JH |
3751 | [(set_attr "type" "fmov,fmov,fmov,multi,multi") |
3752 | (set_attr "mode" "XF,XF,XF,SI,SI")]) | |
4fb21e90 | 3753 | |
a91d32a4 UB |
3754 | (define_expand "movtf" |
3755 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
3756 | (match_operand:TF 1 "nonimmediate_operand" ""))] | |
5bb77598 | 3757 | "TARGET_SSE2" |
a91d32a4 UB |
3758 | { |
3759 | ix86_expand_move (TFmode, operands); | |
3760 | DONE; | |
3761 | }) | |
3762 | ||
3763 | (define_insn "*movtf_internal" | |
3764 | [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o") | |
3765 | (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))] | |
5bb77598 | 3766 | "TARGET_SSE2 |
a91d32a4 UB |
3767 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
3768 | { | |
3769 | switch (which_alternative) | |
3770 | { | |
3771 | case 0: | |
3772 | case 1: | |
3773 | if (get_attr_mode (insn) == MODE_V4SF) | |
95879c72 | 3774 | return "%vmovaps\t{%1, %0|%0, %1}"; |
a91d32a4 | 3775 | else |
95879c72 | 3776 | return "%vmovdqa\t{%1, %0|%0, %1}"; |
a91d32a4 UB |
3777 | case 2: |
3778 | if (get_attr_mode (insn) == MODE_V4SF) | |
95879c72 | 3779 | return "%vxorps\t%0, %d0"; |
a91d32a4 | 3780 | else |
95879c72 | 3781 | return "%vpxor\t%0, %d0"; |
a91d32a4 UB |
3782 | case 3: |
3783 | case 4: | |
3784 | return "#"; | |
3785 | default: | |
3786 | gcc_unreachable (); | |
3787 | } | |
3788 | } | |
3789 | [(set_attr "type" "ssemov,ssemov,sselog1,*,*") | |
95879c72 | 3790 | (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*") |
a91d32a4 UB |
3791 | (set (attr "mode") |
3792 | (cond [(eq_attr "alternative" "0,2") | |
3793 | (if_then_else | |
3debdc1e | 3794 | (ne (symbol_ref "optimize_function_for_size_p (cfun)") |
a91d32a4 UB |
3795 | (const_int 0)) |
3796 | (const_string "V4SF") | |
3797 | (const_string "TI")) | |
3798 | (eq_attr "alternative" "1") | |
3799 | (if_then_else | |
3800 | (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") | |
3801 | (const_int 0)) | |
3debdc1e | 3802 | (ne (symbol_ref "optimize_function_for_size_p (cfun)") |
a91d32a4 UB |
3803 | (const_int 0))) |
3804 | (const_string "V4SF") | |
3805 | (const_string "TI"))] | |
3806 | (const_string "DI")))]) | |
3807 | ||
dcde22ac UB |
3808 | (define_insn "*pushtf_sse" |
3809 | [(set (match_operand:TF 0 "push_operand" "=<,<,<") | |
3810 | (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))] | |
3811 | "TARGET_SSE2" | |
3812 | { | |
3813 | /* This insn should be already split before reg-stack. */ | |
3814 | gcc_unreachable (); | |
3815 | } | |
3816 | [(set_attr "type" "multi") | |
3817 | (set_attr "unit" "sse,*,*") | |
3818 | (set_attr "mode" "TF,SI,SI")]) | |
3819 | ||
3820 | (define_split | |
3821 | [(set (match_operand:TF 0 "push_operand" "") | |
3822 | (match_operand:TF 1 "general_operand" ""))] | |
3823 | "TARGET_SSE2 && reload_completed | |
3824 | && !SSE_REG_P (operands[1])" | |
3825 | [(const_int 0)] | |
3826 | "ix86_split_long_move (operands); DONE;") | |
3827 | ||
3828 | (define_split | |
3829 | [(set (match_operand:TF 0 "push_operand" "") | |
3830 | (match_operand:TF 1 "any_fp_register_operand" ""))] | |
3831 | "TARGET_SSE2" | |
3832 | [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) | |
3833 | (set (mem:TF (reg:P SP_REG)) (match_dup 1))] | |
3834 | "") | |
3835 | ||
467403ca | 3836 | (define_split |
2b589241 JH |
3837 | [(set (match_operand 0 "nonimmediate_operand" "") |
3838 | (match_operand 1 "general_operand" ""))] | |
2450a057 | 3839 | "reload_completed |
7656aee4 | 3840 | && !(MEM_P (operands[0]) && MEM_P (operands[1])) |
f8a1ebc6 | 3841 | && GET_MODE (operands[0]) == XFmode |
6300f037 | 3842 | && ! (ANY_FP_REG_P (operands[0]) || |
8fcaaa80 | 3843 | (GET_CODE (operands[0]) == SUBREG |
446988df | 3844 | && ANY_FP_REG_P (SUBREG_REG (operands[0])))) |
6300f037 | 3845 | && ! (ANY_FP_REG_P (operands[1]) || |
8fcaaa80 | 3846 | (GET_CODE (operands[1]) == SUBREG |
446988df | 3847 | && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" |
26e5b205 JH |
3848 | [(const_int 0)] |
3849 | "ix86_split_long_move (operands); DONE;") | |
467403ca | 3850 | |
d7a29404 | 3851 | (define_split |
2b589241 JH |
3852 | [(set (match_operand 0 "register_operand" "") |
3853 | (match_operand 1 "memory_operand" ""))] | |
d7a29404 | 3854 | "reload_completed |
7656aee4 | 3855 | && MEM_P (operands[1]) |
edc5bbcd UB |
3856 | && (GET_MODE (operands[0]) == TFmode |
3857 | || GET_MODE (operands[0]) == XFmode | |
7656aee4 UB |
3858 | || GET_MODE (operands[0]) == SFmode |
3859 | || GET_MODE (operands[0]) == DFmode) | |
2a450639 RS |
3860 | && (operands[2] = find_constant_src (insn))" |
3861 | [(set (match_dup 0) (match_dup 2))] | |
b87cfcfb | 3862 | { |
2a450639 | 3863 | rtx c = operands[2]; |
b87cfcfb RH |
3864 | rtx r = operands[0]; |
3865 | ||
3866 | if (GET_CODE (r) == SUBREG) | |
3867 | r = SUBREG_REG (r); | |
3868 | ||
3869 | if (SSE_REG_P (r)) | |
3870 | { | |
3871 | if (!standard_sse_constant_p (c)) | |
3872 | FAIL; | |
3873 | } | |
3874 | else if (FP_REG_P (r)) | |
3875 | { | |
3876 | if (!standard_80387_constant_p (c)) | |
3877 | FAIL; | |
3878 | } | |
3879 | else if (MMX_REG_P (r)) | |
3880 | FAIL; | |
b87cfcfb | 3881 | }) |
d7a29404 | 3882 | |
ce7d4645 UB |
3883 | (define_split |
3884 | [(set (match_operand 0 "register_operand" "") | |
3885 | (float_extend (match_operand 1 "memory_operand" "")))] | |
3886 | "reload_completed | |
7656aee4 | 3887 | && MEM_P (operands[1]) |
a91d32a4 UB |
3888 | && (GET_MODE (operands[0]) == TFmode |
3889 | || GET_MODE (operands[0]) == XFmode | |
7656aee4 UB |
3890 | || GET_MODE (operands[0]) == SFmode |
3891 | || GET_MODE (operands[0]) == DFmode) | |
2a450639 RS |
3892 | && (operands[2] = find_constant_src (insn))" |
3893 | [(set (match_dup 0) (match_dup 2))] | |
ce7d4645 | 3894 | { |
2a450639 | 3895 | rtx c = operands[2]; |
ce7d4645 UB |
3896 | rtx r = operands[0]; |
3897 | ||
3898 | if (GET_CODE (r) == SUBREG) | |
3899 | r = SUBREG_REG (r); | |
3900 | ||
3901 | if (SSE_REG_P (r)) | |
3902 | { | |
3903 | if (!standard_sse_constant_p (c)) | |
3904 | FAIL; | |
3905 | } | |
3906 | else if (FP_REG_P (r)) | |
3907 | { | |
3908 | if (!standard_80387_constant_p (c)) | |
3909 | FAIL; | |
3910 | } | |
3911 | else if (MMX_REG_P (r)) | |
3912 | FAIL; | |
ce7d4645 UB |
3913 | }) |
3914 | ||
e075ae69 RH |
3915 | (define_insn "swapxf" |
3916 | [(set (match_operand:XF 0 "register_operand" "+f") | |
3917 | (match_operand:XF 1 "register_operand" "+f")) | |
0be5d99f MM |
3918 | (set (match_dup 1) |
3919 | (match_dup 0))] | |
6c4ccfd8 | 3920 | "TARGET_80387" |
0be5d99f MM |
3921 | { |
3922 | if (STACK_TOP_P (operands[0])) | |
0f40f9f7 | 3923 | return "fxch\t%1"; |
0be5d99f | 3924 | else |
0f40f9f7 ZW |
3925 | return "fxch\t%0"; |
3926 | } | |
0b5107cf | 3927 | [(set_attr "type" "fxch") |
6ef67412 | 3928 | (set_attr "mode" "XF")]) |
ef719a44 | 3929 | |
2e1f15bd UB |
3930 | ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence |
3931 | (define_split | |
3932 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
3933 | (match_operand:X87MODEF 1 "immediate_operand" ""))] | |
3934 | "reload_completed && FP_REGNO_P (REGNO (operands[0])) | |
3935 | && (standard_80387_constant_p (operands[1]) == 8 | |
3936 | || standard_80387_constant_p (operands[1]) == 9)" | |
3937 | [(set (match_dup 0)(match_dup 1)) | |
3938 | (set (match_dup 0) | |
3939 | (neg:X87MODEF (match_dup 0)))] | |
3940 | { | |
3941 | REAL_VALUE_TYPE r; | |
3942 | ||
3943 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
3944 | if (real_isnegzero (&r)) | |
3945 | operands[1] = CONST0_RTX (<MODE>mode); | |
3946 | else | |
3947 | operands[1] = CONST1_RTX (<MODE>mode); | |
3948 | }) | |
3949 | ||
ef719a44 RH |
3950 | (define_split |
3951 | [(set (match_operand:TF 0 "nonimmediate_operand" "") | |
3952 | (match_operand:TF 1 "general_operand" ""))] | |
a91d32a4 UB |
3953 | "reload_completed |
3954 | && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))" | |
ef719a44 RH |
3955 | [(const_int 0)] |
3956 | "ix86_split_long_move (operands); DONE;") | |
886c62d1 | 3957 | \f |
e075ae69 | 3958 | ;; Zero extension instructions |
886c62d1 | 3959 | |
8f7661f2 JH |
3960 | (define_expand "zero_extendhisi2" |
3961 | [(set (match_operand:SI 0 "register_operand" "") | |
3962 | (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] | |
d626200a | 3963 | "" |
e075ae69 | 3964 | { |
3debdc1e | 3965 | if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) |
2ae0f82c | 3966 | { |
8f7661f2 JH |
3967 | operands[1] = force_reg (HImode, operands[1]); |
3968 | emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); | |
3969 | DONE; | |
2ae0f82c | 3970 | } |
0f40f9f7 | 3971 | }) |
886c62d1 | 3972 | |
8f7661f2 JH |
3973 | (define_insn "zero_extendhisi2_and" |
3974 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3975 | (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) | |
8bc527af | 3976 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 3977 | "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" |
8f7661f2 | 3978 | "#" |
6ef67412 JH |
3979 | [(set_attr "type" "alu1") |
3980 | (set_attr "mode" "SI")]) | |
2ae0f82c SC |
3981 | |
3982 | (define_split | |
3983 | [(set (match_operand:SI 0 "register_operand" "") | |
8f7661f2 | 3984 | (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) |
8bc527af | 3985 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e JH |
3986 | "reload_completed && TARGET_ZERO_EXTEND_WITH_AND |
3987 | && optimize_function_for_speed_p (cfun)" | |
8f7661f2 | 3988 | [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) |
8bc527af | 3989 | (clobber (reg:CC FLAGS_REG))])] |
d626200a JL |
3990 | "") |
3991 | ||
8f7661f2 JH |
3992 | (define_insn "*zero_extendhisi2_movzwl" |
3993 | [(set (match_operand:SI 0 "register_operand" "=r") | |
3994 | (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] | |
3debdc1e JH |
3995 | "!TARGET_ZERO_EXTEND_WITH_AND |
3996 | || optimize_function_for_size_p (cfun)" | |
0f40f9f7 | 3997 | "movz{wl|x}\t{%1, %0|%0, %1}" |
6ef67412 JH |
3998 | [(set_attr "type" "imovx") |
3999 | (set_attr "mode" "SI")]) | |
8f7661f2 JH |
4000 | |
4001 | (define_expand "zero_extendqihi2" | |
4002 | [(parallel | |
4003 | [(set (match_operand:HI 0 "register_operand" "") | |
4004 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) | |
8bc527af | 4005 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 | 4006 | "" |
8f7661f2 JH |
4007 | "") |
4008 | ||
4009 | (define_insn "*zero_extendqihi2_and" | |
4010 | [(set (match_operand:HI 0 "register_operand" "=r,?&q") | |
4011 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) | |
8bc527af | 4012 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 4013 | "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" |
8f7661f2 | 4014 | "#" |
6ef67412 JH |
4015 | [(set_attr "type" "alu1") |
4016 | (set_attr "mode" "HI")]) | |
8f7661f2 JH |
4017 | |
4018 | (define_insn "*zero_extendqihi2_movzbw_and" | |
4019 | [(set (match_operand:HI 0 "register_operand" "=r,r") | |
4020 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) | |
8bc527af | 4021 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 4022 | "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)" |
8f7661f2 | 4023 | "#" |
6ef67412 JH |
4024 | [(set_attr "type" "imovx,alu1") |
4025 | (set_attr "mode" "HI")]) | |
886c62d1 | 4026 | |
0d9e7244 EC |
4027 | ; zero extend to SImode here to avoid partial register stalls |
4028 | (define_insn "*zero_extendqihi2_movzbl" | |
8f7661f2 JH |
4029 | [(set (match_operand:HI 0 "register_operand" "=r") |
4030 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] | |
71aaa2ff | 4031 | "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)) |
3debdc1e | 4032 | && reload_completed" |
9ad5e54f | 4033 | "movz{bl|x}\t{%1, %k0|%k0, %1}" |
6ef67412 | 4034 | [(set_attr "type" "imovx") |
0d9e7244 | 4035 | (set_attr "mode" "SI")]) |
8f7661f2 JH |
4036 | |
4037 | ;; For the movzbw case strip only the clobber | |
2ae0f82c SC |
4038 | (define_split |
4039 | [(set (match_operand:HI 0 "register_operand" "") | |
e075ae69 | 4040 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) |
8bc527af | 4041 | (clobber (reg:CC FLAGS_REG))] |
6300f037 | 4042 | "reload_completed |
3debdc1e JH |
4043 | && (!TARGET_ZERO_EXTEND_WITH_AND |
4044 | || optimize_function_for_size_p (cfun)) | |
1a06f5fe | 4045 | && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" |
8f7661f2 JH |
4046 | [(set (match_operand:HI 0 "register_operand" "") |
4047 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) | |
2ae0f82c | 4048 | |
8f7661f2 JH |
4049 | ;; When source and destination does not overlap, clear destination |
4050 | ;; first and then do the movb | |
2ae0f82c SC |
4051 | (define_split |
4052 | [(set (match_operand:HI 0 "register_operand" "") | |
8f7661f2 | 4053 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) |
8bc527af | 4054 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 4055 | "reload_completed |
1a06f5fe | 4056 | && ANY_QI_REG_P (operands[0]) |
3debdc1e JH |
4057 | && (TARGET_ZERO_EXTEND_WITH_AND |
4058 | && optimize_function_for_speed_p (cfun)) | |
8f7661f2 JH |
4059 | && !reg_overlap_mentioned_p (operands[0], operands[1])" |
4060 | [(set (match_dup 0) (const_int 0)) | |
4061 | (set (strict_low_part (match_dup 2)) (match_dup 1))] | |
4062 | "operands[2] = gen_lowpart (QImode, operands[0]);") | |
2ae0f82c | 4063 | |
8f7661f2 | 4064 | ;; Rest is handled by single and. |
2ae0f82c SC |
4065 | (define_split |
4066 | [(set (match_operand:HI 0 "register_operand" "") | |
e075ae69 | 4067 | (zero_extend:HI (match_operand:QI 1 "register_operand" ""))) |
8bc527af | 4068 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 4069 | "reload_completed |
8f7661f2 JH |
4070 | && true_regnum (operands[0]) == true_regnum (operands[1])" |
4071 | [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) | |
8bc527af | 4072 | (clobber (reg:CC FLAGS_REG))])] |
d626200a JL |
4073 | "") |
4074 | ||
8f7661f2 JH |
4075 | (define_expand "zero_extendqisi2" |
4076 | [(parallel | |
4077 | [(set (match_operand:SI 0 "register_operand" "") | |
4078 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) | |
8bc527af | 4079 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 | 4080 | "" |
8f7661f2 JH |
4081 | "") |
4082 | ||
4083 | (define_insn "*zero_extendqisi2_and" | |
4084 | [(set (match_operand:SI 0 "register_operand" "=r,?&q") | |
4085 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) | |
8bc527af | 4086 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 4087 | "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" |
8f7661f2 | 4088 | "#" |
6ef67412 JH |
4089 | [(set_attr "type" "alu1") |
4090 | (set_attr "mode" "SI")]) | |
8f7661f2 JH |
4091 | |
4092 | (define_insn "*zero_extendqisi2_movzbw_and" | |
4093 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
4094 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) | |
8bc527af | 4095 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 4096 | "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)" |
8f7661f2 | 4097 | "#" |
6ef67412 JH |
4098 | [(set_attr "type" "imovx,alu1") |
4099 | (set_attr "mode" "SI")]) | |
2ae0f82c | 4100 | |
8f7661f2 JH |
4101 | (define_insn "*zero_extendqisi2_movzbw" |
4102 | [(set (match_operand:SI 0 "register_operand" "=r") | |
4103 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] | |
3debdc1e JH |
4104 | "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)) |
4105 | && reload_completed" | |
0f40f9f7 | 4106 | "movz{bl|x}\t{%1, %0|%0, %1}" |
6ef67412 JH |
4107 | [(set_attr "type" "imovx") |
4108 | (set_attr "mode" "SI")]) | |
8f7661f2 JH |
4109 | |
4110 | ;; For the movzbl case strip only the clobber | |
4111 | (define_split | |
4112 | [(set (match_operand:SI 0 "register_operand" "") | |
4113 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) | |
8bc527af | 4114 | (clobber (reg:CC FLAGS_REG))] |
6300f037 | 4115 | "reload_completed |
3debdc1e | 4116 | && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)) |
1a06f5fe | 4117 | && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" |
8f7661f2 JH |
4118 | [(set (match_dup 0) |
4119 | (zero_extend:SI (match_dup 1)))]) | |
4120 | ||
4121 | ;; When source and destination does not overlap, clear destination | |
4122 | ;; first and then do the movb | |
2ae0f82c SC |
4123 | (define_split |
4124 | [(set (match_operand:SI 0 "register_operand" "") | |
e075ae69 | 4125 | (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) |
8bc527af | 4126 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 4127 | "reload_completed |
1a06f5fe | 4128 | && ANY_QI_REG_P (operands[0]) |
7656aee4 | 4129 | && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])) |
3debdc1e | 4130 | && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) |
e075ae69 | 4131 | && !reg_overlap_mentioned_p (operands[0], operands[1])" |
8f7661f2 JH |
4132 | [(set (match_dup 0) (const_int 0)) |
4133 | (set (strict_low_part (match_dup 2)) (match_dup 1))] | |
4134 | "operands[2] = gen_lowpart (QImode, operands[0]);") | |
2ae0f82c | 4135 | |
8f7661f2 | 4136 | ;; Rest is handled by single and. |
2ae0f82c SC |
4137 | (define_split |
4138 | [(set (match_operand:SI 0 "register_operand" "") | |
e075ae69 | 4139 | (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) |
8bc527af | 4140 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 4141 | "reload_completed |
8f7661f2 JH |
4142 | && true_regnum (operands[0]) == true_regnum (operands[1])" |
4143 | [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) | |
8bc527af | 4144 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 | 4145 | "") |
2ae0f82c | 4146 | |
e075ae69 | 4147 | ;; %%% Kill me once multi-word ops are sane. |
123bf9e3 | 4148 | (define_expand "zero_extendsidi2" |
00188daa UB |
4149 | [(set (match_operand:DI 0 "register_operand" "") |
4150 | (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] | |
123bf9e3 | 4151 | "" |
ed69105c RH |
4152 | { |
4153 | if (!TARGET_64BIT) | |
4154 | { | |
4155 | emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1])); | |
4156 | DONE; | |
4157 | } | |
4158 | }) | |
123bf9e3 JH |
4159 | |
4160 | (define_insn "zero_extendsidi2_32" | |
e2520c41 | 4161 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2") |
50961141 | 4162 | (zero_extend:DI |
4afb7791 | 4163 | (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m"))) |
8bc527af | 4164 | (clobber (reg:CC FLAGS_REG))] |
f75959a6 | 4165 | "!TARGET_64BIT" |
ebe75517 JH |
4166 | "@ |
4167 | # | |
4168 | # | |
4169 | # | |
4170 | movd\t{%1, %0|%0, %1} | |
ed69105c | 4171 | movd\t{%1, %0|%0, %1} |
95879c72 L |
4172 | %vmovd\t{%1, %0|%0, %1} |
4173 | %vmovd\t{%1, %0|%0, %1}" | |
4174 | [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov") | |
4175 | (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex") | |
4176 | (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")]) | |
2ae0f82c | 4177 | |
123bf9e3 | 4178 | (define_insn "zero_extendsidi2_rex64" |
e2520c41 | 4179 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2") |
50961141 | 4180 | (zero_extend:DI |
4afb7791 | 4181 | (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))] |
f75959a6 | 4182 | "TARGET_64BIT" |
ebe75517 JH |
4183 | "@ |
4184 | mov\t{%k1, %k0|%k0, %k1} | |
4185 | # | |
4186 | movd\t{%1, %0|%0, %1} | |
ed69105c | 4187 | movd\t{%1, %0|%0, %1} |
95879c72 L |
4188 | %vmovd\t{%1, %0|%0, %1} |
4189 | %vmovd\t{%1, %0|%0, %1}" | |
ed69105c | 4190 | [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov") |
95879c72 | 4191 | (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex") |
a952487c | 4192 | (set_attr "prefix_0f" "0,*,*,*,*,*") |
ed69105c | 4193 | (set_attr "mode" "SI,DI,DI,DI,TI,TI")]) |
123bf9e3 JH |
4194 | |
4195 | (define_split | |
4196 | [(set (match_operand:DI 0 "memory_operand" "") | |
4197 | (zero_extend:DI (match_dup 0)))] | |
1b0c37d7 | 4198 | "TARGET_64BIT" |
123bf9e3 JH |
4199 | [(set (match_dup 4) (const_int 0))] |
4200 | "split_di (&operands[0], 1, &operands[3], &operands[4]);") | |
4201 | ||
6300f037 | 4202 | (define_split |
bb62e19a | 4203 | [(set (match_operand:DI 0 "register_operand" "") |
e075ae69 | 4204 | (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) |
8bc527af | 4205 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 ZW |
4206 | "!TARGET_64BIT && reload_completed |
4207 | && true_regnum (operands[0]) == true_regnum (operands[1])" | |
591702de | 4208 | [(set (match_dup 4) (const_int 0))] |
bb62e19a JH |
4209 | "split_di (&operands[0], 1, &operands[3], &operands[4]);") |
4210 | ||
6300f037 | 4211 | (define_split |
bb62e19a | 4212 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
e075ae69 | 4213 | (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) |
8bc527af | 4214 | (clobber (reg:CC FLAGS_REG))] |
ebe75517 JH |
4215 | "!TARGET_64BIT && reload_completed |
4216 | && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])" | |
bb62e19a | 4217 | [(set (match_dup 3) (match_dup 1)) |
591702de | 4218 | (set (match_dup 4) (const_int 0))] |
bb62e19a | 4219 | "split_di (&operands[0], 1, &operands[3], &operands[4]);") |
123bf9e3 JH |
4220 | |
4221 | (define_insn "zero_extendhidi2" | |
422edd6f JB |
4222 | [(set (match_operand:DI 0 "register_operand" "=r") |
4223 | (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] | |
123bf9e3 | 4224 | "TARGET_64BIT" |
422edd6f | 4225 | "movz{wl|x}\t{%1, %k0|%k0, %1}" |
123bf9e3 | 4226 | [(set_attr "type" "imovx") |
a952487c | 4227 | (set_attr "mode" "SI")]) |
123bf9e3 JH |
4228 | |
4229 | (define_insn "zero_extendqidi2" | |
422edd6f JB |
4230 | [(set (match_operand:DI 0 "register_operand" "=r") |
4231 | (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))] | |
123bf9e3 | 4232 | "TARGET_64BIT" |
422edd6f | 4233 | "movz{bl|x}\t{%1, %k0|%k0, %1}" |
123bf9e3 | 4234 | [(set_attr "type" "imovx") |
a952487c | 4235 | (set_attr "mode" "SI")]) |
886c62d1 | 4236 | \f |
e075ae69 | 4237 | ;; Sign extension instructions |
886c62d1 | 4238 | |
123bf9e3 JH |
4239 | (define_expand "extendsidi2" |
4240 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
4241 | (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
8bc527af | 4242 | (clobber (reg:CC FLAGS_REG)) |
123bf9e3 JH |
4243 | (clobber (match_scratch:SI 2 ""))])] |
4244 | "" | |
123bf9e3 JH |
4245 | { |
4246 | if (TARGET_64BIT) | |
4247 | { | |
4248 | emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1])); | |
4249 | DONE; | |
4250 | } | |
0f40f9f7 | 4251 | }) |
123bf9e3 JH |
4252 | |
4253 | (define_insn "*extendsidi2_1" | |
e075ae69 RH |
4254 | [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") |
4255 | (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) | |
8bc527af | 4256 | (clobber (reg:CC FLAGS_REG)) |
6b29b0e2 | 4257 | (clobber (match_scratch:SI 2 "=X,X,X,&r"))] |
123bf9e3 | 4258 | "!TARGET_64BIT" |
724d568a JH |
4259 | "#") |
4260 | ||
123bf9e3 JH |
4261 | (define_insn "extendsidi2_rex64" |
4262 | [(set (match_operand:DI 0 "register_operand" "=*a,r") | |
4263 | (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] | |
4264 | "TARGET_64BIT" | |
4265 | "@ | |
4266 | {cltq|cdqe} | |
725fd454 | 4267 | movs{lq|x}\t{%1, %0|%0, %1}" |
123bf9e3 JH |
4268 | [(set_attr "type" "imovx") |
4269 | (set_attr "mode" "DI") | |
4270 | (set_attr "prefix_0f" "0") | |
4271 | (set_attr "modrm" "0,1")]) | |
4272 | ||
4273 | (define_insn "extendhidi2" | |
4274 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4275 | (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] | |
4276 | "TARGET_64BIT" | |
725fd454 | 4277 | "movs{wq|x}\t{%1, %0|%0, %1}" |
123bf9e3 JH |
4278 | [(set_attr "type" "imovx") |
4279 | (set_attr "mode" "DI")]) | |
4280 | ||
4281 | (define_insn "extendqidi2" | |
4282 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4283 | (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))] | |
4284 | "TARGET_64BIT" | |
725fd454 | 4285 | "movs{bq|x}\t{%1, %0|%0, %1}" |
123bf9e3 JH |
4286 | [(set_attr "type" "imovx") |
4287 | (set_attr "mode" "DI")]) | |
4288 | ||
724d568a | 4289 | ;; Extend to memory case when source register does die. |
6300f037 | 4290 | (define_split |
724d568a JH |
4291 | [(set (match_operand:DI 0 "memory_operand" "") |
4292 | (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
8bc527af | 4293 | (clobber (reg:CC FLAGS_REG)) |
6b29b0e2 | 4294 | (clobber (match_operand:SI 2 "register_operand" ""))] |
d7a29404 | 4295 | "(reload_completed |
724d568a JH |
4296 | && dead_or_set_p (insn, operands[1]) |
4297 | && !reg_mentioned_p (operands[1], operands[0]))" | |
4298 | [(set (match_dup 3) (match_dup 1)) | |
e075ae69 | 4299 | (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) |
8bc527af | 4300 | (clobber (reg:CC FLAGS_REG))]) |
724d568a JH |
4301 | (set (match_dup 4) (match_dup 1))] |
4302 | "split_di (&operands[0], 1, &operands[3], &operands[4]);") | |
4303 | ||
4304 | ;; Extend to memory case when source register does not die. | |
6300f037 | 4305 | (define_split |
724d568a JH |
4306 | [(set (match_operand:DI 0 "memory_operand" "") |
4307 | (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
8bc527af | 4308 | (clobber (reg:CC FLAGS_REG)) |
6b29b0e2 | 4309 | (clobber (match_operand:SI 2 "register_operand" ""))] |
d7a29404 | 4310 | "reload_completed" |
724d568a | 4311 | [(const_int 0)] |
9c530261 | 4312 | { |
724d568a JH |
4313 | split_di (&operands[0], 1, &operands[3], &operands[4]); |
4314 | ||
4315 | emit_move_insn (operands[3], operands[1]); | |
4316 | ||
4317 | /* Generate a cltd if possible and doing so it profitable. */ | |
3debdc1e | 4318 | if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) |
29b74761 UB |
4319 | && true_regnum (operands[1]) == AX_REG |
4320 | && true_regnum (operands[2]) == DX_REG) | |
71a247f0 | 4321 | { |
e075ae69 | 4322 | emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31))); |
724d568a JH |
4323 | } |
4324 | else | |
4325 | { | |
4326 | emit_move_insn (operands[2], operands[1]); | |
e075ae69 | 4327 | emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31))); |
71a247f0 | 4328 | } |
724d568a JH |
4329 | emit_move_insn (operands[4], operands[2]); |
4330 | DONE; | |
0f40f9f7 | 4331 | }) |
9c530261 | 4332 | |
724d568a JH |
4333 | ;; Extend to register case. Optimize case where source and destination |
4334 | ;; registers match and cases where we can use cltd. | |
6300f037 | 4335 | (define_split |
724d568a JH |
4336 | [(set (match_operand:DI 0 "register_operand" "") |
4337 | (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) | |
8bc527af | 4338 | (clobber (reg:CC FLAGS_REG)) |
6b29b0e2 | 4339 | (clobber (match_scratch:SI 2 ""))] |
724d568a JH |
4340 | "reload_completed" |
4341 | [(const_int 0)] | |
724d568a JH |
4342 | { |
4343 | split_di (&operands[0], 1, &operands[3], &operands[4]); | |
4344 | ||
4345 | if (true_regnum (operands[3]) != true_regnum (operands[1])) | |
4346 | emit_move_insn (operands[3], operands[1]); | |
9c530261 | 4347 | |
724d568a | 4348 | /* Generate a cltd if possible and doing so it profitable. */ |
3debdc1e | 4349 | if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) |
29b74761 | 4350 | && true_regnum (operands[3]) == AX_REG) |
724d568a | 4351 | { |
e075ae69 | 4352 | emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31))); |
724d568a JH |
4353 | DONE; |
4354 | } | |
4355 | ||
4356 | if (true_regnum (operands[4]) != true_regnum (operands[1])) | |
4357 | emit_move_insn (operands[4], operands[1]); | |
4358 | ||
e075ae69 | 4359 | emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31))); |
724d568a | 4360 | DONE; |
0f40f9f7 | 4361 | }) |
886c62d1 | 4362 | |
886c62d1 | 4363 | (define_insn "extendhisi2" |
e075ae69 RH |
4364 | [(set (match_operand:SI 0 "register_operand" "=*a,r") |
4365 | (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] | |
886c62d1 | 4366 | "" |
886c62d1 | 4367 | { |
6ef67412 | 4368 | switch (get_attr_prefix_0f (insn)) |
e075ae69 | 4369 | { |
6ef67412 | 4370 | case 0: |
0f40f9f7 | 4371 | return "{cwtl|cwde}"; |
e075ae69 | 4372 | default: |
725fd454 | 4373 | return "movs{wl|x}\t{%1, %0|%0, %1}"; |
e075ae69 | 4374 | } |
0f40f9f7 | 4375 | } |
e075ae69 | 4376 | [(set_attr "type" "imovx") |
6ef67412 JH |
4377 | (set_attr "mode" "SI") |
4378 | (set (attr "prefix_0f") | |
4379 | ;; movsx is short decodable while cwtl is vector decoded. | |
4380 | (if_then_else (and (eq_attr "cpu" "!k6") | |
4381 | (eq_attr "alternative" "0")) | |
4382 | (const_string "0") | |
4383 | (const_string "1"))) | |
4384 | (set (attr "modrm") | |
4385 | (if_then_else (eq_attr "prefix_0f" "0") | |
4386 | (const_string "0") | |
4387 | (const_string "1")))]) | |
886c62d1 | 4388 | |
123bf9e3 JH |
4389 | (define_insn "*extendhisi2_zext" |
4390 | [(set (match_operand:DI 0 "register_operand" "=*a,r") | |
4391 | (zero_extend:DI | |
4392 | (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] | |
4393 | "TARGET_64BIT" | |
123bf9e3 JH |
4394 | { |
4395 | switch (get_attr_prefix_0f (insn)) | |
4396 | { | |
4397 | case 0: | |
0f40f9f7 | 4398 | return "{cwtl|cwde}"; |
123bf9e3 | 4399 | default: |
725fd454 | 4400 | return "movs{wl|x}\t{%1, %k0|%k0, %1}"; |
123bf9e3 | 4401 | } |
0f40f9f7 | 4402 | } |
123bf9e3 JH |
4403 | [(set_attr "type" "imovx") |
4404 | (set_attr "mode" "SI") | |
4405 | (set (attr "prefix_0f") | |
4406 | ;; movsx is short decodable while cwtl is vector decoded. | |
4407 | (if_then_else (and (eq_attr "cpu" "!k6") | |
4408 | (eq_attr "alternative" "0")) | |
4409 | (const_string "0") | |
4410 | (const_string "1"))) | |
4411 | (set (attr "modrm") | |
4412 | (if_then_else (eq_attr "prefix_0f" "0") | |
4413 | (const_string "0") | |
4414 | (const_string "1")))]) | |
4415 | ||
886c62d1 | 4416 | (define_insn "extendqihi2" |
e075ae69 RH |
4417 | [(set (match_operand:HI 0 "register_operand" "=*a,r") |
4418 | (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] | |
886c62d1 | 4419 | "" |
886c62d1 | 4420 | { |
6ef67412 | 4421 | switch (get_attr_prefix_0f (insn)) |
e075ae69 | 4422 | { |
6ef67412 | 4423 | case 0: |
0f40f9f7 | 4424 | return "{cbtw|cbw}"; |
e075ae69 | 4425 | default: |
725fd454 | 4426 | return "movs{bw|x}\t{%1, %0|%0, %1}"; |
e075ae69 | 4427 | } |
0f40f9f7 | 4428 | } |
e075ae69 | 4429 | [(set_attr "type" "imovx") |
6ef67412 JH |
4430 | (set_attr "mode" "HI") |
4431 | (set (attr "prefix_0f") | |
4432 | ;; movsx is short decodable while cwtl is vector decoded. | |
4433 | (if_then_else (and (eq_attr "cpu" "!k6") | |
4434 | (eq_attr "alternative" "0")) | |
4435 | (const_string "0") | |
4436 | (const_string "1"))) | |
4437 | (set (attr "modrm") | |
4438 | (if_then_else (eq_attr "prefix_0f" "0") | |
4439 | (const_string "0") | |
4440 | (const_string "1")))]) | |
886c62d1 JVA |
4441 | |
4442 | (define_insn "extendqisi2" | |
2ae0f82c SC |
4443 | [(set (match_operand:SI 0 "register_operand" "=r") |
4444 | (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] | |
886c62d1 | 4445 | "" |
725fd454 | 4446 | "movs{bl|x}\t{%1, %0|%0, %1}" |
6ef67412 JH |
4447 | [(set_attr "type" "imovx") |
4448 | (set_attr "mode" "SI")]) | |
123bf9e3 JH |
4449 | |
4450 | (define_insn "*extendqisi2_zext" | |
4451 | [(set (match_operand:DI 0 "register_operand" "=r") | |
4452 | (zero_extend:DI | |
4453 | (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] | |
4454 | "TARGET_64BIT" | |
725fd454 | 4455 | "movs{bl|x}\t{%1, %k0|%k0, %1}" |
123bf9e3 JH |
4456 | [(set_attr "type" "imovx") |
4457 | (set_attr "mode" "SI")]) | |
886c62d1 JVA |
4458 | \f |
4459 | ;; Conversions between float and double. | |
4460 | ||
e075ae69 RH |
4461 | ;; These are all no-ops in the model used for the 80387. So just |
4462 | ;; emit moves. | |
6a4a5d95 | 4463 | |
6300f037 | 4464 | ;; %%% Kill these when call knows how to work out a DFmode push earlier. |
6343a50e | 4465 | (define_insn "*dummy_extendsfdf2" |
e075ae69 | 4466 | [(set (match_operand:DF 0 "push_operand" "=<") |
e2520c41 | 4467 | (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))] |
e075ae69 RH |
4468 | "0" |
4469 | "#") | |
6a4a5d95 JW |
4470 | |
4471 | (define_split | |
e075ae69 | 4472 | [(set (match_operand:DF 0 "push_operand" "") |
c3c637e3 | 4473 | (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] |
90b48492 KT |
4474 | "" |
4475 | [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) | |
4476 | (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))]) | |
123bf9e3 | 4477 | |
6343a50e | 4478 | (define_insn "*dummy_extendsfxf2" |
e075ae69 RH |
4479 | [(set (match_operand:XF 0 "push_operand" "=<") |
4480 | (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))] | |
4481 | "0" | |
4482 | "#") | |
e4ad1003 JW |
4483 | |
4484 | (define_split | |
e075ae69 | 4485 | [(set (match_operand:XF 0 "push_operand" "") |
c3c637e3 | 4486 | (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] |
f8a1ebc6 | 4487 | "" |
90b48492 KT |
4488 | [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) |
4489 | (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] | |
f8a1ebc6 | 4490 | "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") |
e4ad1003 JW |
4491 | |
4492 | (define_split | |
e075ae69 | 4493 | [(set (match_operand:XF 0 "push_operand" "") |
c3c637e3 | 4494 | (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] |
f8a1ebc6 | 4495 | "" |
90b48492 KT |
4496 | [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) |
4497 | (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] | |
f8a1ebc6 | 4498 | "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") |
123bf9e3 | 4499 | |
f97d9ec3 JH |
4500 | (define_expand "extendsfdf2" |
4501 | [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
51286de6 | 4502 | (float_extend:DF (match_operand:SF 1 "general_operand" "")))] |
2312581e | 4503 | "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" |
f97d9ec3 | 4504 | { |
51286de6 RH |
4505 | /* ??? Needed for compress_float_constant since all fp constants |
4506 | are LEGITIMATE_CONSTANT_P. */ | |
4507 | if (GET_CODE (operands[1]) == CONST_DOUBLE) | |
e046a30a PB |
4508 | { |
4509 | if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) | |
4510 | && standard_80387_constant_p (operands[1]) > 0) | |
4511 | { | |
4512 | operands[1] = simplify_const_unary_operation | |
4513 | (FLOAT_EXTEND, DFmode, operands[1], SFmode); | |
4514 | emit_move_insn_1 (operands[0], operands[1]); | |
4515 | DONE; | |
4516 | } | |
4517 | operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); | |
4518 | } | |
0f40f9f7 | 4519 | }) |
f97d9ec3 | 4520 | |
4845dbb5 JH |
4521 | /* For converting SF(xmm2) to DF(xmm1), use the following code instead of |
4522 | cvtss2sd: | |
4523 | unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs | |
4524 | cvtps2pd xmm2,xmm1 | |
4525 | We do the conversion post reload to avoid producing of 128bit spills | |
4526 | that might lead to ICE on 32bit target. The sequence unlikely combine | |
4527 | anyway. */ | |
4528 | (define_split | |
4529 | [(set (match_operand:DF 0 "register_operand" "") | |
4530 | (float_extend:DF | |
4531 | (match_operand:SF 1 "nonimmediate_operand" "")))] | |
54723b46 | 4532 | "TARGET_USE_VECTOR_FP_CONVERTS |
3debdc1e | 4533 | && optimize_insn_for_speed_p () |
4845dbb5 JH |
4534 | && reload_completed && SSE_REG_P (operands[0])" |
4535 | [(set (match_dup 2) | |
4536 | (float_extend:V2DF | |
4537 | (vec_select:V2SF | |
4538 | (match_dup 3) | |
4539 | (parallel [(const_int 0) (const_int 1)]))))] | |
4540 | { | |
4541 | operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); | |
4542 | operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0); | |
4543 | /* Use movss for loading from memory, unpcklps reg, reg for registers. | |
4544 | Try to avoid move when unpacking can be done in source. */ | |
4545 | if (REG_P (operands[1])) | |
4546 | { | |
4547 | /* If it is unsafe to overwrite upper half of source, we need | |
4548 | to move to destination and unpack there. */ | |
4549 | if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
4550 | || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4) | |
4551 | && true_regnum (operands[0]) != true_regnum (operands[1])) | |
4552 | { | |
4553 | rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0])); | |
4554 | emit_move_insn (tmp, operands[1]); | |
4555 | } | |
4556 | else | |
4557 | operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0); | |
4558 | emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3])); | |
4559 | } | |
4560 | else | |
4f3f76e6 | 4561 | emit_insn (gen_vec_setv4sf_0 (operands[3], |
4845dbb5 JH |
4562 | CONST0_RTX (V4SFmode), operands[1])); |
4563 | }) | |
4564 | ||
2312581e | 4565 | (define_insn "*extendsfdf2_mixed" |
50961141 RH |
4566 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x") |
4567 | (float_extend:DF | |
4568 | (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))] | |
509a77dc | 4569 | "TARGET_SSE2 && TARGET_MIX_SSE_I387" |
4fb21e90 | 4570 | { |
e075ae69 | 4571 | switch (which_alternative) |
4fb21e90 | 4572 | { |
e075ae69 | 4573 | case 0: |
e075ae69 | 4574 | case 1: |
d869c351 | 4575 | return output_387_reg_move (insn, operands); |
5ea9cb6e | 4576 | |
42a0aa6f | 4577 | case 2: |
95879c72 | 4578 | return "%vcvtss2sd\t{%1, %d0|%d0, %1}"; |
4fb21e90 | 4579 | |
e075ae69 | 4580 | default: |
7637e42c | 4581 | gcc_unreachable (); |
e075ae69 | 4582 | } |
0f40f9f7 | 4583 | } |
3d34cd91 | 4584 | [(set_attr "type" "fmov,fmov,ssecvt") |
95879c72 | 4585 | (set_attr "prefix" "orig,orig,maybe_vex") |
a811cc63 | 4586 | (set_attr "mode" "SF,XF,DF")]) |
42a0aa6f | 4587 | |
2312581e | 4588 | (define_insn "*extendsfdf2_sse" |
50961141 RH |
4589 | [(set (match_operand:DF 0 "nonimmediate_operand" "=x") |
4590 | (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))] | |
509a77dc | 4591 | "TARGET_SSE2 && TARGET_SSE_MATH" |
95879c72 | 4592 | "%vcvtss2sd\t{%1, %d0|%d0, %1}" |
3d34cd91 | 4593 | [(set_attr "type" "ssecvt") |
95879c72 | 4594 | (set_attr "prefix" "maybe_vex") |
42a0aa6f | 4595 | (set_attr "mode" "DF")]) |
e075ae69 | 4596 | |
2312581e UB |
4597 | (define_insn "*extendsfdf2_i387" |
4598 | [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") | |
4599 | (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] | |
509a77dc | 4600 | "TARGET_80387" |
d869c351 | 4601 | "* return output_387_reg_move (insn, operands);" |
2312581e UB |
4602 | [(set_attr "type" "fmov") |
4603 | (set_attr "mode" "SF,XF")]) | |
4604 | ||
a344e3cb | 4605 | (define_expand "extend<mode>xf2" |
f97d9ec3 | 4606 | [(set (match_operand:XF 0 "nonimmediate_operand" "") |
00188daa | 4607 | (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))] |
f8a1ebc6 | 4608 | "TARGET_80387" |
f97d9ec3 | 4609 | { |
51286de6 RH |
4610 | /* ??? Needed for compress_float_constant since all fp constants |
4611 | are LEGITIMATE_CONSTANT_P. */ | |
4612 | if (GET_CODE (operands[1]) == CONST_DOUBLE) | |
e046a30a PB |
4613 | { |
4614 | if (standard_80387_constant_p (operands[1]) > 0) | |
4615 | { | |
4616 | operands[1] = simplify_const_unary_operation | |
a344e3cb | 4617 | (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode); |
e046a30a PB |
4618 | emit_move_insn_1 (operands[0], operands[1]); |
4619 | DONE; | |
4620 | } | |
a344e3cb | 4621 | operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1])); |
e046a30a | 4622 | } |
0f40f9f7 | 4623 | }) |
f97d9ec3 | 4624 | |
a344e3cb | 4625 | (define_insn "*extend<mode>xf2_i387" |
e075ae69 | 4626 | [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") |
a344e3cb | 4627 | (float_extend:XF |
00188daa | 4628 | (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))] |
509a77dc | 4629 | "TARGET_80387" |
d869c351 | 4630 | "* return output_387_reg_move (insn, operands);" |
2b589241 | 4631 | [(set_attr "type" "fmov") |
a344e3cb | 4632 | (set_attr "mode" "<MODE>,XF")]) |
2b589241 | 4633 | |
e075ae69 RH |
4634 | ;; %%% This seems bad bad news. |
4635 | ;; This cannot output into an f-reg because there is no way to be sure | |
4636 | ;; of truncating in that case. Otherwise this is just like a simple move | |
4637 | ;; insn. So we pretend we can output to a reg in order to get better | |
4638 | ;; register preferencing, but we really use a stack slot. | |
886c62d1 | 4639 | |
5b1f1e63 | 4640 | ;; Conversion from DFmode to SFmode. |
bc725565 | 4641 | |
5b1f1e63 RH |
4642 | (define_expand "truncdfsf2" |
4643 | [(set (match_operand:SF 0 "nonimmediate_operand" "") | |
4644 | (float_truncate:SF | |
4645 | (match_operand:DF 1 "nonimmediate_operand" "")))] | |
4646 | "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" | |
82a6a758 | 4647 | { |
5b1f1e63 RH |
4648 | if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) |
4649 | ; | |
4650 | else if (flag_unsafe_math_optimizations) | |
4651 | ; | |
4652 | else | |
4653 | { | |
bbbbb16a ILT |
4654 | enum ix86_stack_slot slot = (virtuals_instantiated |
4655 | ? SLOT_TEMP | |
4656 | : SLOT_VIRTUAL); | |
be0c4603 | 4657 | rtx temp = assign_386_stack_local (SFmode, slot); |
5b1f1e63 RH |
4658 | emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); |
4659 | DONE; | |
4660 | } | |
4661 | }) | |
4662 | ||
4845dbb5 JH |
4663 | /* For converting DF(xmm2) to SF(xmm1), use the following code instead of |
4664 | cvtsd2ss: | |
4665 | unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs | |
4666 | cvtpd2ps xmm2,xmm1 | |
4667 | We do the conversion post reload to avoid producing of 128bit spills | |
4668 | that might lead to ICE on 32bit target. The sequence unlikely combine | |
4669 | anyway. */ | |
4670 | (define_split | |
4671 | [(set (match_operand:SF 0 "register_operand" "") | |
4672 | (float_truncate:SF | |
4673 | (match_operand:DF 1 "nonimmediate_operand" "")))] | |
54723b46 | 4674 | "TARGET_USE_VECTOR_FP_CONVERTS |
3debdc1e | 4675 | && optimize_insn_for_speed_p () |
4845dbb5 JH |
4676 | && reload_completed && SSE_REG_P (operands[0])" |
4677 | [(set (match_dup 2) | |
4678 | (vec_concat:V4SF | |
4679 | (float_truncate:V2SF | |
4680 | (match_dup 4)) | |
4681 | (match_dup 3)))] | |
4682 | { | |
4683 | operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); | |
4684 | operands[3] = CONST0_RTX (V2SFmode); | |
4685 | operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0); | |
4686 | /* Use movsd for loading from memory, unpcklpd for registers. | |
4687 | Try to avoid move when unpacking can be done in source, or SSE3 | |
4688 | movddup is available. */ | |
4689 | if (REG_P (operands[1])) | |
4690 | { | |
4691 | if (!TARGET_SSE3 | |
4692 | && true_regnum (operands[0]) != true_regnum (operands[1]) | |
4693 | && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER | |
4694 | || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8)) | |
4695 | { | |
4696 | rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0); | |
4697 | emit_move_insn (tmp, operands[1]); | |
4698 | operands[1] = tmp; | |
4699 | } | |
4700 | else if (!TARGET_SSE3) | |
4701 | operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0); | |
4702 | emit_insn (gen_vec_dupv2df (operands[4], operands[1])); | |
4703 | } | |
4704 | else | |
4705 | emit_insn (gen_sse2_loadlpd (operands[4], | |
4706 | CONST0_RTX (V2DFmode), operands[1])); | |
4707 | }) | |
4708 | ||
5b1f1e63 RH |
4709 | (define_expand "truncdfsf2_with_temp" |
4710 | [(parallel [(set (match_operand:SF 0 "" "") | |
4711 | (float_truncate:SF (match_operand:DF 1 "" ""))) | |
4712 | (clobber (match_operand:SF 2 "" ""))])] | |
4713 | "") | |
4714 | ||
4715 | (define_insn "*truncdfsf_fast_mixed" | |
73e8165a | 4716 | [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x") |
5b1f1e63 | 4717 | (float_truncate:SF |
73e8165a | 4718 | (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))] |
5b1f1e63 | 4719 | "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" |
e075ae69 RH |
4720 | { |
4721 | switch (which_alternative) | |
4722 | { | |
4723 | case 0: | |
5b1f1e63 | 4724 | return output_387_reg_move (insn, operands); |
73e8165a | 4725 | case 1: |
95879c72 | 4726 | return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; |
46ed7963 | 4727 | default: |
7637e42c | 4728 | gcc_unreachable (); |
e075ae69 | 4729 | } |
0f40f9f7 | 4730 | } |
73e8165a | 4731 | [(set_attr "type" "fmov,ssecvt") |
95879c72 | 4732 | (set_attr "prefix" "orig,maybe_vex") |
5b1f1e63 RH |
4733 | (set_attr "mode" "SF")]) |
4734 | ||
4735 | ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, | |
4736 | ;; because nothing we do here is unsafe. | |
4737 | (define_insn "*truncdfsf_fast_sse" | |
50961141 | 4738 | [(set (match_operand:SF 0 "nonimmediate_operand" "=x") |
5b1f1e63 | 4739 | (float_truncate:SF |
50961141 | 4740 | (match_operand:DF 1 "nonimmediate_operand" "xm")))] |
5b1f1e63 | 4741 | "TARGET_SSE2 && TARGET_SSE_MATH" |
95879c72 | 4742 | "%vcvtsd2ss\t{%1, %d0|%d0, %1}" |
5b1f1e63 | 4743 | [(set_attr "type" "ssecvt") |
95879c72 | 4744 | (set_attr "prefix" "maybe_vex") |
5b1f1e63 RH |
4745 | (set_attr "mode" "SF")]) |
4746 | ||
4747 | (define_insn "*truncdfsf_fast_i387" | |
4748 | [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") | |
4749 | (float_truncate:SF | |
4750 | (match_operand:DF 1 "nonimmediate_operand" "f")))] | |
4751 | "TARGET_80387 && flag_unsafe_math_optimizations" | |
4752 | "* return output_387_reg_move (insn, operands);" | |
4753 | [(set_attr "type" "fmov") | |
4754 | (set_attr "mode" "SF")]) | |
42a0aa6f | 4755 | |
5b1f1e63 | 4756 | (define_insn "*truncdfsf_mixed" |
9ade279b | 4757 | [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r") |
42a0aa6f | 4758 | (float_truncate:SF |
9ade279b UB |
4759 | (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f"))) |
4760 | (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))] | |
5b1f1e63 | 4761 | "TARGET_MIX_SSE_I387" |
4977bab6 ZW |
4762 | { |
4763 | switch (which_alternative) | |
4764 | { | |
4765 | case 0: | |
a344e3cb | 4766 | return output_387_reg_move (insn, operands); |
5b1f1e63 | 4767 | case 1: |
95879c72 | 4768 | return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; |
9ade279b | 4769 | |
46ed7963 | 4770 | default: |
9ade279b | 4771 | return "#"; |
42a0aa6f | 4772 | } |
0f40f9f7 | 4773 | } |
9ade279b UB |
4774 | [(set_attr "type" "fmov,ssecvt,multi,multi,multi") |
4775 | (set_attr "unit" "*,*,i387,i387,i387") | |
4776 | (set_attr "prefix" "orig,maybe_vex,orig,orig,orig") | |
5b1f1e63 | 4777 | (set_attr "mode" "SF")]) |
53b5ce19 | 4778 | |
5b1f1e63 | 4779 | (define_insn "*truncdfsf_i387" |
9ade279b | 4780 | [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") |
42a0aa6f | 4781 | (float_truncate:SF |
9ade279b UB |
4782 | (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f"))) |
4783 | (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] | |
5b1f1e63 | 4784 | "TARGET_80387" |
42a0aa6f JH |
4785 | { |
4786 | switch (which_alternative) | |
4787 | { | |
4788 | case 0: | |
a344e3cb UB |
4789 | return output_387_reg_move (insn, operands); |
4790 | ||
0f40f9f7 | 4791 | default: |
9ade279b | 4792 | return "#"; |
42a0aa6f | 4793 | } |
0f40f9f7 | 4794 | } |
9ade279b UB |
4795 | [(set_attr "type" "fmov,multi,multi,multi") |
4796 | (set_attr "unit" "*,i387,i387,i387") | |
26f74aa3 | 4797 | (set_attr "mode" "SF")]) |
acaa3bf7 RS |
4798 | |
4799 | (define_insn "*truncdfsf2_i387_1" | |
4800 | [(set (match_operand:SF 0 "memory_operand" "=m") | |
4801 | (float_truncate:SF | |
4802 | (match_operand:DF 1 "register_operand" "f")))] | |
4803 | "TARGET_80387 | |
4804 | && !(TARGET_SSE2 && TARGET_SSE_MATH) | |
4805 | && !TARGET_MIX_SSE_I387" | |
a344e3cb | 4806 | "* return output_387_reg_move (insn, operands);" |
acaa3bf7 RS |
4807 | [(set_attr "type" "fmov") |
4808 | (set_attr "mode" "SF")]) | |
42a0aa6f | 4809 | |
42a0aa6f | 4810 | (define_split |
4977bab6 | 4811 | [(set (match_operand:SF 0 "register_operand" "") |
42a0aa6f | 4812 | (float_truncate:SF |
5b1f1e63 | 4813 | (match_operand:DF 1 "fp_register_operand" ""))) |
42a0aa6f | 4814 | (clobber (match_operand 2 "" ""))] |
5b1f1e63 RH |
4815 | "reload_completed" |
4816 | [(set (match_dup 2) (match_dup 1)) | |
4817 | (set (match_dup 0) (match_dup 2))] | |
4977bab6 | 4818 | { |
5b1f1e63 | 4819 | operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1])); |
4977bab6 | 4820 | }) |
42a0aa6f | 4821 | |
a344e3cb | 4822 | ;; Conversion from XFmode to {SF,DF}mode |
53b5ce19 | 4823 | |
a344e3cb | 4824 | (define_expand "truncxf<mode>2" |
00188daa UB |
4825 | [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "") |
4826 | (float_truncate:MODEF | |
a344e3cb | 4827 | (match_operand:XF 1 "register_operand" ""))) |
e075ae69 | 4828 | (clobber (match_dup 2))])] |
f8a1ebc6 | 4829 | "TARGET_80387" |
5b1f1e63 | 4830 | { |
0c5faf29 RS |
4831 | if (flag_unsafe_math_optimizations) |
4832 | { | |
a344e3cb UB |
4833 | rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode); |
4834 | emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1])); | |
0c5faf29 RS |
4835 | if (reg != operands[0]) |
4836 | emit_move_insn (operands[0], reg); | |
4837 | DONE; | |
4838 | } | |
4839 | else | |
be0c4603 | 4840 | { |
bbbbb16a ILT |
4841 | enum ix86_stack_slot slot = (virtuals_instantiated |
4842 | ? SLOT_TEMP | |
4843 | : SLOT_VIRTUAL); | |
be0c4603 UB |
4844 | operands[2] = assign_386_stack_local (<MODE>mode, slot); |
4845 | } | |
5b1f1e63 RH |
4846 | }) |
4847 | ||
4848 | (define_insn "*truncxfsf2_mixed" | |
9ade279b | 4849 | [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") |
5b1f1e63 | 4850 | (float_truncate:SF |
9ade279b UB |
4851 | (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) |
4852 | (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] | |
e26feb2c | 4853 | "TARGET_80387" |
5b1f1e63 | 4854 | { |
7637e42c | 4855 | gcc_assert (!which_alternative); |
a344e3cb | 4856 | return output_387_reg_move (insn, operands); |
0f40f9f7 | 4857 | } |
9ade279b UB |
4858 | [(set_attr "type" "fmov,multi,multi,multi") |
4859 | (set_attr "unit" "*,i387,i387,i387") | |
6ef67412 | 4860 | (set_attr "mode" "SF")]) |
bc725565 | 4861 | |
5b1f1e63 | 4862 | (define_insn "*truncxfdf2_mixed" |
9ade279b | 4863 | [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r") |
5b1f1e63 | 4864 | (float_truncate:DF |
9ade279b UB |
4865 | (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) |
4866 | (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))] | |
e26feb2c | 4867 | "TARGET_80387" |
5b1f1e63 | 4868 | { |
7637e42c | 4869 | gcc_assert (!which_alternative); |
a344e3cb | 4870 | return output_387_reg_move (insn, operands); |
5b1f1e63 | 4871 | } |
9ade279b UB |
4872 | [(set_attr "type" "fmov,multi,multi,multi") |
4873 | (set_attr "unit" "*,i387,i387,i387") | |
5b1f1e63 | 4874 | (set_attr "mode" "DF")]) |
0c5faf29 | 4875 | |
a344e3cb | 4876 | (define_insn "truncxf<mode>2_i387_noop" |
00188daa UB |
4877 | [(set (match_operand:MODEF 0 "register_operand" "=f") |
4878 | (float_truncate:MODEF | |
a344e3cb | 4879 | (match_operand:XF 1 "register_operand" "f")))] |
0c5faf29 | 4880 | "TARGET_80387 && flag_unsafe_math_optimizations" |
01302104 | 4881 | "* return output_387_reg_move (insn, operands);" |
82a6a758 | 4882 | [(set_attr "type" "fmov") |
a344e3cb | 4883 | (set_attr "mode" "<MODE>")]) |
bc725565 | 4884 | |
a344e3cb | 4885 | (define_insn "*truncxf<mode>2_i387" |
00188daa UB |
4886 | [(set (match_operand:MODEF 0 "memory_operand" "=m") |
4887 | (float_truncate:MODEF | |
e075ae69 | 4888 | (match_operand:XF 1 "register_operand" "f")))] |
f8a1ebc6 | 4889 | "TARGET_80387" |
a344e3cb | 4890 | "* return output_387_reg_move (insn, operands);" |
6ef67412 | 4891 | [(set_attr "type" "fmov") |
a344e3cb | 4892 | (set_attr "mode" "<MODE>")]) |
bc725565 JW |
4893 | |
4894 | (define_split | |
00188daa UB |
4895 | [(set (match_operand:MODEF 0 "register_operand" "") |
4896 | (float_truncate:MODEF | |
a344e3cb | 4897 | (match_operand:XF 1 "register_operand" ""))) |
00188daa | 4898 | (clobber (match_operand:MODEF 2 "memory_operand" ""))] |
5b1f1e63 | 4899 | "TARGET_80387 && reload_completed" |
00188daa | 4900 | [(set (match_dup 2) (float_truncate:MODEF (match_dup 1))) |
5b1f1e63 | 4901 | (set (match_dup 0) (match_dup 2))] |
4fb21e90 JVA |
4902 | "") |
4903 | ||
bc725565 | 4904 | (define_split |
00188daa UB |
4905 | [(set (match_operand:MODEF 0 "memory_operand" "") |
4906 | (float_truncate:MODEF | |
a344e3cb | 4907 | (match_operand:XF 1 "register_operand" ""))) |
00188daa | 4908 | (clobber (match_operand:MODEF 2 "memory_operand" ""))] |
5b1f1e63 | 4909 | "TARGET_80387" |
00188daa | 4910 | [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))] |
4fb21e90 | 4911 | "") |
e075ae69 | 4912 | \f |
e075ae69 RH |
4913 | ;; Signed conversion to DImode. |
4914 | ||
2b589241 | 4915 | (define_expand "fix_truncxfdi2" |
ec13ba83 CT |
4916 | [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") |
4917 | (fix:DI (match_operand:XF 1 "register_operand" ""))) | |
8bc527af | 4918 | (clobber (reg:CC FLAGS_REG))])] |
bc725565 | 4919 | "TARGET_80387" |
46ed7963 | 4920 | { |
9199f050 | 4921 | if (TARGET_FISTTP) |
46ed7963 | 4922 | { |
9199f050 | 4923 | emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); |
46ed7963 JH |
4924 | DONE; |
4925 | } | |
0f40f9f7 | 4926 | }) |
53b5ce19 | 4927 | |
9199f050 | 4928 | (define_expand "fix_trunc<mode>di2" |
ec13ba83 | 4929 | [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") |
00188daa | 4930 | (fix:DI (match_operand:MODEF 1 "register_operand" ""))) |
9199f050 UB |
4931 | (clobber (reg:CC FLAGS_REG))])] |
4932 | "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" | |
46ed7963 | 4933 | { |
9199f050 UB |
4934 | if (TARGET_FISTTP |
4935 | && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) | |
4936 | { | |
4937 | emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); | |
4938 | DONE; | |
4939 | } | |
4940 | if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) | |
46ed7963 JH |
4941 | { |
4942 | rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); | |
9199f050 | 4943 | emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); |
46ed7963 JH |
4944 | if (out != operands[0]) |
4945 | emit_move_insn (operands[0], out); | |
4946 | DONE; | |
4947 | } | |
0f40f9f7 | 4948 | }) |
e075ae69 | 4949 | |
e075ae69 | 4950 | ;; Signed conversion to SImode. |
53b5ce19 | 4951 | |
e075ae69 | 4952 | (define_expand "fix_truncxfsi2" |
ec13ba83 | 4953 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") |
9199f050 | 4954 | (fix:SI (match_operand:XF 1 "register_operand" ""))) |
8bc527af | 4955 | (clobber (reg:CC FLAGS_REG))])] |
2b589241 | 4956 | "TARGET_80387" |
42a0aa6f | 4957 | { |
9199f050 | 4958 | if (TARGET_FISTTP) |
42a0aa6f | 4959 | { |
9199f050 | 4960 | emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); |
42a0aa6f JH |
4961 | DONE; |
4962 | } | |
0f40f9f7 | 4963 | }) |
886c62d1 | 4964 | |
9199f050 | 4965 | (define_expand "fix_trunc<mode>si2" |
ec13ba83 | 4966 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") |
00188daa | 4967 | (fix:SI (match_operand:MODEF 1 "register_operand" ""))) |
9199f050 | 4968 | (clobber (reg:CC FLAGS_REG))])] |
84c2b4da | 4969 | "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" |
42a0aa6f | 4970 | { |
9199f050 UB |
4971 | if (TARGET_FISTTP |
4972 | && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) | |
4973 | { | |
4974 | emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); | |
4975 | DONE; | |
4976 | } | |
4977 | if (SSE_FLOAT_MODE_P (<MODE>mode)) | |
42a0aa6f | 4978 | { |
ca9a9b12 | 4979 | rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); |
9199f050 | 4980 | emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); |
b1675dbd JH |
4981 | if (out != operands[0]) |
4982 | emit_move_insn (operands[0], out); | |
42a0aa6f JH |
4983 | DONE; |
4984 | } | |
0f40f9f7 | 4985 | }) |
e075ae69 | 4986 | |
9199f050 UB |
4987 | ;; Signed conversion to HImode. |
4988 | ||
4989 | (define_expand "fix_trunc<mode>hi2" | |
4990 | [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
4991 | (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) | |
4992 | (clobber (reg:CC FLAGS_REG))])] | |
4993 | "TARGET_80387 | |
4994 | && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" | |
22fb740d | 4995 | { |
9199f050 UB |
4996 | if (TARGET_FISTTP) |
4997 | { | |
4998 | emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); | |
4999 | DONE; | |
5000 | } | |
5001 | }) | |
22fb740d | 5002 | |
ebff937c SH |
5003 | ;; Unsigned conversion to SImode. |
5004 | ||
5005 | (define_expand "fixuns_trunc<mode>si2" | |
174c12c7 RH |
5006 | [(parallel |
5007 | [(set (match_operand:SI 0 "register_operand" "") | |
5008 | (unsigned_fix:SI | |
00188daa | 5009 | (match_operand:MODEF 1 "nonimmediate_operand" ""))) |
174c12c7 RH |
5010 | (use (match_dup 2)) |
5011 | (clobber (match_scratch:<ssevecmode> 3 "")) | |
5012 | (clobber (match_scratch:<ssevecmode> 4 ""))])] | |
18bd082d | 5013 | "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" |
174c12c7 RH |
5014 | { |
5015 | enum machine_mode mode = <MODE>mode; | |
5016 | enum machine_mode vecmode = <ssevecmode>mode; | |
5017 | REAL_VALUE_TYPE TWO31r; | |
5018 | rtx two31; | |
5019 | ||
18bd082d JH |
5020 | if (optimize_insn_for_size_p ()) |
5021 | FAIL; | |
5022 | ||
174c12c7 RH |
5023 | real_ldexp (&TWO31r, &dconst1, 31); |
5024 | two31 = const_double_from_real_value (TWO31r, mode); | |
5025 | two31 = ix86_build_const_vector (mode, true, two31); | |
5026 | operands[2] = force_reg (vecmode, two31); | |
5027 | }) | |
5028 | ||
5029 | (define_insn_and_split "*fixuns_trunc<mode>_1" | |
5030 | [(set (match_operand:SI 0 "register_operand" "=&x,&x") | |
5031 | (unsigned_fix:SI | |
00188daa | 5032 | (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm"))) |
174c12c7 RH |
5033 | (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x")) |
5034 | (clobber (match_scratch:<ssevecmode> 1 "=x,&x")) | |
5035 | (clobber (match_scratch:<ssevecmode> 2 "=x,x"))] | |
3debdc1e JH |
5036 | "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH |
5037 | && optimize_function_for_speed_p (cfun)" | |
174c12c7 RH |
5038 | "#" |
5039 | "&& reload_completed" | |
5040 | [(const_int 0)] | |
ebff937c | 5041 | { |
174c12c7 | 5042 | ix86_split_convert_uns_si_sse (operands); |
ebff937c SH |
5043 | DONE; |
5044 | }) | |
5045 | ||
5046 | ;; Unsigned conversion to HImode. | |
5047 | ;; Without these patterns, we'll try the unsigned SI conversion which | |
5048 | ;; is complex for SSE, rather than the signed SI conversion, which isn't. | |
5049 | ||
d8e3118a | 5050 | (define_expand "fixuns_trunc<mode>hi2" |
ebff937c | 5051 | [(set (match_dup 2) |
00188daa | 5052 | (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" ""))) |
ebff937c SH |
5053 | (set (match_operand:HI 0 "nonimmediate_operand" "") |
5054 | (subreg:HI (match_dup 2) 0))] | |
d8e3118a | 5055 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" |
ebff937c SH |
5056 | "operands[2] = gen_reg_rtx (SImode);") |
5057 | ||
9199f050 | 5058 | ;; When SSE is available, it is always faster to use it! |
d8e3118a | 5059 | (define_insn "fix_trunc<mode>di_sse" |
9199f050 | 5060 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
00188daa | 5061 | (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] |
d8e3118a UB |
5062 | "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) |
5063 | && (!TARGET_FISTTP || TARGET_SSE_MATH)" | |
95879c72 | 5064 | "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}" |
9199f050 | 5065 | [(set_attr "type" "sseicvt") |
95879c72 | 5066 | (set_attr "prefix" "maybe_vex") |
725fd454 | 5067 | (set_attr "prefix_rex" "1") |
d8e3118a | 5068 | (set_attr "mode" "<MODE>") |
21efb4d4 HJ |
5069 | (set_attr "athlon_decode" "double,vector") |
5070 | (set_attr "amdfam10_decode" "double,double")]) | |
22fb740d | 5071 | |
d8e3118a | 5072 | (define_insn "fix_trunc<mode>si_sse" |
f56e86bd | 5073 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
00188daa | 5074 | (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] |
d8e3118a UB |
5075 | "SSE_FLOAT_MODE_P (<MODE>mode) |
5076 | && (!TARGET_FISTTP || TARGET_SSE_MATH)" | |
95879c72 | 5077 | "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}" |
f56e86bd | 5078 | [(set_attr "type" "sseicvt") |
95879c72 | 5079 | (set_attr "prefix" "maybe_vex") |
d8e3118a | 5080 | (set_attr "mode" "<MODE>") |
21efb4d4 HJ |
5081 | (set_attr "athlon_decode" "double,vector") |
5082 | (set_attr "amdfam10_decode" "double,double")]) | |
42a0aa6f | 5083 | |
962ef7fe UB |
5084 | ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns. |
5085 | (define_peephole2 | |
00188daa UB |
5086 | [(set (match_operand:MODEF 0 "register_operand" "") |
5087 | (match_operand:MODEF 1 "memory_operand" "")) | |
962ef7fe UB |
5088 | (set (match_operand:SSEMODEI24 2 "register_operand" "") |
5089 | (fix:SSEMODEI24 (match_dup 0)))] | |
ddff69b9 | 5090 | "TARGET_SHORTEN_X87_SSE |
962ef7fe UB |
5091 | && peep2_reg_dead_p (2, operands[0])" |
5092 | [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))] | |
5093 | "") | |
5094 | ||
9199f050 | 5095 | ;; Avoid vector decoded forms of the instruction. |
8dfa3bb0 | 5096 | (define_peephole2 |
e2520c41 | 5097 | [(match_scratch:DF 2 "Y2") |
9199f050 UB |
5098 | (set (match_operand:SSEMODEI24 0 "register_operand" "") |
5099 | (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))] | |
3debdc1e | 5100 | "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()" |
8dfa3bb0 | 5101 | [(set (match_dup 2) (match_dup 1)) |
9199f050 | 5102 | (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] |
8dfa3bb0 JH |
5103 | "") |
5104 | ||
9199f050 UB |
5105 | (define_peephole2 |
5106 | [(match_scratch:SF 2 "x") | |
5107 | (set (match_operand:SSEMODEI24 0 "register_operand" "") | |
5108 | (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))] | |
3debdc1e | 5109 | "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()" |
9199f050 UB |
5110 | [(set (match_dup 2) (match_dup 1)) |
5111 | (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] | |
bc725565 | 5112 | "") |
4fb21e90 | 5113 | |
9199f050 | 5114 | (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" |
00188daa UB |
5115 | [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") |
5116 | (fix:X87MODEI (match_operand 1 "register_operand" "")))] | |
27ac40e2 UB |
5117 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
5118 | && TARGET_FISTTP | |
9199f050 UB |
5119 | && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) |
5120 | && (TARGET_64BIT || <MODE>mode != DImode)) | |
5121 | && TARGET_SSE_MATH) | |
5122 | && !(reload_completed || reload_in_progress)" | |
5123 | "#" | |
5124 | "&& 1" | |
5125 | [(const_int 0)] | |
5126 | { | |
5127 | if (memory_operand (operands[0], VOIDmode)) | |
5128 | emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); | |
5129 | else | |
5130 | { | |
ff680eb1 | 5131 | operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); |
9199f050 UB |
5132 | emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], |
5133 | operands[1], | |
5134 | operands[2])); | |
5135 | } | |
5136 | DONE; | |
5137 | } | |
5138 | [(set_attr "type" "fisttp") | |
5139 | (set_attr "mode" "<MODE>")]) | |
22fb740d | 5140 | |
9199f050 UB |
5141 | (define_insn "fix_trunc<mode>_i387_fisttp" |
5142 | [(set (match_operand:X87MODEI 0 "memory_operand" "=m") | |
5143 | (fix:X87MODEI (match_operand 1 "register_operand" "f"))) | |
5144 | (clobber (match_scratch:XF 2 "=&1f"))] | |
27ac40e2 UB |
5145 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
5146 | && TARGET_FISTTP | |
9199f050 UB |
5147 | && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) |
5148 | && (TARGET_64BIT || <MODE>mode != DImode)) | |
5149 | && TARGET_SSE_MATH)" | |
5150 | "* return output_fix_trunc (insn, operands, 1);" | |
5151 | [(set_attr "type" "fisttp") | |
5152 | (set_attr "mode" "<MODE>")]) | |
46d21d2c | 5153 | |
9199f050 UB |
5154 | (define_insn "fix_trunc<mode>_i387_fisttp_with_temp" |
5155 | [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") | |
5156 | (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) | |
73e8165a | 5157 | (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m")) |
9199f050 | 5158 | (clobber (match_scratch:XF 3 "=&1f,&1f"))] |
27ac40e2 UB |
5159 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
5160 | && TARGET_FISTTP | |
9199f050 UB |
5161 | && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) |
5162 | && (TARGET_64BIT || <MODE>mode != DImode)) | |
5163 | && TARGET_SSE_MATH)" | |
5164 | "#" | |
5165 | [(set_attr "type" "fisttp") | |
5166 | (set_attr "mode" "<MODE>")]) | |
2b589241 | 5167 | |
9199f050 UB |
5168 | (define_split |
5169 | [(set (match_operand:X87MODEI 0 "register_operand" "") | |
5170 | (fix:X87MODEI (match_operand 1 "register_operand" ""))) | |
5171 | (clobber (match_operand:X87MODEI 2 "memory_operand" "")) | |
5172 | (clobber (match_scratch 3 ""))] | |
5173 | "reload_completed" | |
5174 | [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1))) | |
5175 | (clobber (match_dup 3))]) | |
5176 | (set (match_dup 0) (match_dup 2))] | |
22fb740d | 5177 | "") |
46d21d2c | 5178 | |
9199f050 UB |
5179 | (define_split |
5180 | [(set (match_operand:X87MODEI 0 "memory_operand" "") | |
5181 | (fix:X87MODEI (match_operand 1 "register_operand" ""))) | |
5182 | (clobber (match_operand:X87MODEI 2 "memory_operand" "")) | |
5183 | (clobber (match_scratch 3 ""))] | |
5184 | "reload_completed" | |
5185 | [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1))) | |
5186 | (clobber (match_dup 3))])] | |
22fb740d JH |
5187 | "") |
5188 | ||
5189 | ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description | |
9199f050 UB |
5190 | ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control |
5191 | ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG | |
5192 | ;; clobbering insns can be used. Look at emit_i387_cw_initialization () | |
5193 | ;; function in i386.c. | |
5194 | (define_insn_and_split "*fix_trunc<mode>_i387_1" | |
00188daa UB |
5195 | [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") |
5196 | (fix:X87MODEI (match_operand 1 "register_operand" ""))) | |
8bc527af | 5197 | (clobber (reg:CC FLAGS_REG))] |
27ac40e2 UB |
5198 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
5199 | && !TARGET_FISTTP | |
9199f050 UB |
5200 | && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) |
5201 | && (TARGET_64BIT || <MODE>mode != DImode)) | |
5202 | && !(reload_completed || reload_in_progress)" | |
22fb740d | 5203 | "#" |
d7518354 | 5204 | "&& 1" |
22fb740d JH |
5205 | [(const_int 0)] |
5206 | { | |
ff680eb1 UB |
5207 | ix86_optimize_mode_switching[I387_TRUNC] = 1; |
5208 | ||
5209 | operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); | |
5210 | operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); | |
22fb740d | 5211 | if (memory_operand (operands[0], VOIDmode)) |
9199f050 UB |
5212 | emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], |
5213 | operands[2], operands[3])); | |
22fb740d JH |
5214 | else |
5215 | { | |
ff680eb1 | 5216 | operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); |
9199f050 UB |
5217 | emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], |
5218 | operands[2], operands[3], | |
5219 | operands[4])); | |
22fb740d JH |
5220 | } |
5221 | DONE; | |
5222 | } | |
26f74aa3 | 5223 | [(set_attr "type" "fistp") |
edeacc14 | 5224 | (set_attr "i387_cw" "trunc") |
9199f050 UB |
5225 | (set_attr "mode" "<MODE>")]) |
5226 | ||
5227 | (define_insn "fix_truncdi_i387" | |
5228 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
5229 | (fix:DI (match_operand 1 "register_operand" "f"))) | |
5230 | (use (match_operand:HI 2 "memory_operand" "m")) | |
5231 | (use (match_operand:HI 3 "memory_operand" "m")) | |
5232 | (clobber (match_scratch:XF 4 "=&1f"))] | |
27ac40e2 UB |
5233 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
5234 | && !TARGET_FISTTP | |
9199f050 UB |
5235 | && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" |
5236 | "* return output_fix_trunc (insn, operands, 0);" | |
5237 | [(set_attr "type" "fistp") | |
5238 | (set_attr "i387_cw" "trunc") | |
5239 | (set_attr "mode" "DI")]) | |
46d21d2c | 5240 | |
9199f050 UB |
5241 | (define_insn "fix_truncdi_i387_with_temp" |
5242 | [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") | |
5243 | (fix:DI (match_operand 1 "register_operand" "f,f"))) | |
7a2e09f4 JH |
5244 | (use (match_operand:HI 2 "memory_operand" "m,m")) |
5245 | (use (match_operand:HI 3 "memory_operand" "m,m")) | |
73e8165a | 5246 | (clobber (match_operand:DI 4 "memory_operand" "=X,m")) |
9199f050 | 5247 | (clobber (match_scratch:XF 5 "=&1f,&1f"))] |
27ac40e2 UB |
5248 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
5249 | && !TARGET_FISTTP | |
9199f050 | 5250 | && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" |
22fb740d | 5251 | "#" |
26f74aa3 | 5252 | [(set_attr "type" "fistp") |
edeacc14 | 5253 | (set_attr "i387_cw" "trunc") |
9199f050 | 5254 | (set_attr "mode" "DI")]) |
22fb740d | 5255 | |
6300f037 | 5256 | (define_split |
9199f050 UB |
5257 | [(set (match_operand:DI 0 "register_operand" "") |
5258 | (fix:DI (match_operand 1 "register_operand" ""))) | |
5259 | (use (match_operand:HI 2 "memory_operand" "")) | |
5260 | (use (match_operand:HI 3 "memory_operand" "")) | |
5261 | (clobber (match_operand:DI 4 "memory_operand" "")) | |
5262 | (clobber (match_scratch 5 ""))] | |
5263 | "reload_completed" | |
5264 | [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) | |
5265 | (use (match_dup 2)) | |
5266 | (use (match_dup 3)) | |
5267 | (clobber (match_dup 5))]) | |
5268 | (set (match_dup 0) (match_dup 4))] | |
5269 | "") | |
5270 | ||
6300f037 | 5271 | (define_split |
9199f050 UB |
5272 | [(set (match_operand:DI 0 "memory_operand" "") |
5273 | (fix:DI (match_operand 1 "register_operand" ""))) | |
5274 | (use (match_operand:HI 2 "memory_operand" "")) | |
5275 | (use (match_operand:HI 3 "memory_operand" "")) | |
5276 | (clobber (match_operand:DI 4 "memory_operand" "")) | |
5277 | (clobber (match_scratch 5 ""))] | |
5278 | "reload_completed" | |
5279 | [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) | |
5280 | (use (match_dup 2)) | |
5281 | (use (match_dup 3)) | |
5282 | (clobber (match_dup 5))])] | |
5283 | "") | |
5284 | ||
5285 | (define_insn "fix_trunc<mode>_i387" | |
5286 | [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") | |
5287 | (fix:X87MODEI12 (match_operand 1 "register_operand" "f"))) | |
22fb740d JH |
5288 | (use (match_operand:HI 2 "memory_operand" "m")) |
5289 | (use (match_operand:HI 3 "memory_operand" "m"))] | |
27ac40e2 UB |
5290 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
5291 | && !TARGET_FISTTP | |
22fb740d | 5292 | && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" |
9199f050 | 5293 | "* return output_fix_trunc (insn, operands, 0);" |
26f74aa3 | 5294 | [(set_attr "type" "fistp") |
edeacc14 | 5295 | (set_attr "i387_cw" "trunc") |
9199f050 UB |
5296 | (set_attr "mode" "<MODE>")]) |
5297 | ||
5298 | (define_insn "fix_trunc<mode>_i387_with_temp" | |
5299 | [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") | |
5300 | (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f"))) | |
5301 | (use (match_operand:HI 2 "memory_operand" "m,m")) | |
5302 | (use (match_operand:HI 3 "memory_operand" "m,m")) | |
73e8165a | 5303 | (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))] |
27ac40e2 UB |
5304 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
5305 | && !TARGET_FISTTP | |
9199f050 UB |
5306 | && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" |
5307 | "#" | |
5308 | [(set_attr "type" "fistp") | |
5309 | (set_attr "i387_cw" "trunc") | |
5310 | (set_attr "mode" "<MODE>")]) | |
22fb740d | 5311 | |
6300f037 | 5312 | (define_split |
9199f050 UB |
5313 | [(set (match_operand:X87MODEI12 0 "register_operand" "") |
5314 | (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) | |
22fb740d JH |
5315 | (use (match_operand:HI 2 "memory_operand" "")) |
5316 | (use (match_operand:HI 3 "memory_operand" "")) | |
9199f050 | 5317 | (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] |
22fb740d | 5318 | "reload_completed" |
9199f050 | 5319 | [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1))) |
22fb740d | 5320 | (use (match_dup 2)) |
9199f050 UB |
5321 | (use (match_dup 3))]) |
5322 | (set (match_dup 0) (match_dup 4))] | |
22fb740d | 5323 | "") |
46d21d2c | 5324 | |
6300f037 | 5325 | (define_split |
9199f050 UB |
5326 | [(set (match_operand:X87MODEI12 0 "memory_operand" "") |
5327 | (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) | |
7a2e09f4 JH |
5328 | (use (match_operand:HI 2 "memory_operand" "")) |
5329 | (use (match_operand:HI 3 "memory_operand" "")) | |
9199f050 | 5330 | (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] |
46d21d2c | 5331 | "reload_completed" |
9199f050 | 5332 | [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1))) |
7a2e09f4 | 5333 | (use (match_dup 2)) |
9199f050 | 5334 | (use (match_dup 3))])] |
46d21d2c JW |
5335 | "") |
5336 | ||
e075ae69 | 5337 | (define_insn "x86_fnstcw_1" |
c76aab11 | 5338 | [(set (match_operand:HI 0 "memory_operand" "=m") |
03c259ad | 5339 | (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))] |
e1f998ad | 5340 | "TARGET_80387" |
0f40f9f7 | 5341 | "fnstcw\t%0" |
725fd454 | 5342 | [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2")) |
6ef67412 | 5343 | (set_attr "mode" "HI") |
56bab446 | 5344 | (set_attr "unit" "i387")]) |
bc725565 | 5345 | |
e075ae69 | 5346 | (define_insn "x86_fldcw_1" |
03c259ad | 5347 | [(set (reg:HI FPCR_REG) |
8ee41eaf | 5348 | (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] |
bc725565 | 5349 | "TARGET_80387" |
0f40f9f7 | 5350 | "fldcw\t%0" |
725fd454 | 5351 | [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2")) |
6ef67412 | 5352 | (set_attr "mode" "HI") |
3d34cd91 | 5353 | (set_attr "unit" "i387") |
21efb4d4 | 5354 | (set_attr "athlon_decode" "vector") |
4f3f76e6 | 5355 | (set_attr "amdfam10_decode" "vector")]) |
e075ae69 RH |
5356 | \f |
5357 | ;; Conversion between fixed point and floating point. | |
886c62d1 | 5358 | |
e075ae69 RH |
5359 | ;; Even though we only accept memory inputs, the backend _really_ |
5360 | ;; wants to be able to do this between registers. | |
5361 | ||
0218c012 | 5362 | (define_expand "floathi<mode>2" |
380edc9f UB |
5363 | [(set (match_operand:X87MODEF 0 "register_operand" "") |
5364 | (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))] | |
5365 | "TARGET_80387 | |
5366 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5367 | || TARGET_MIX_SSE_I387)" | |
5368 | "") | |
35c28a13 | 5369 | |
380edc9f UB |
5370 | ;; Pre-reload splitter to add memory clobber to the pattern. |
5371 | (define_insn_and_split "*floathi<mode>2_1" | |
5372 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
5373 | (float:X87MODEF (match_operand:HI 1 "register_operand" "")))] | |
5374 | "TARGET_80387 | |
5375 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5376 | || TARGET_MIX_SSE_I387) | |
5377 | && !(reload_completed || reload_in_progress)" | |
5378 | "#" | |
5379 | "&& 1" | |
5380 | [(parallel [(set (match_dup 0) | |
5381 | (float:X87MODEF (match_dup 1))) | |
5382 | (clobber (match_dup 2))])] | |
5383 | "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);") | |
5384 | ||
5385 | (define_insn "*floathi<mode>2_i387_with_temp" | |
5386 | [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") | |
5387 | (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r"))) | |
5388 | (clobber (match_operand:HI 2 "memory_operand" "=m,m"))] | |
0218c012 UB |
5389 | "TARGET_80387 |
5390 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5391 | || TARGET_MIX_SSE_I387)" | |
380edc9f | 5392 | "#" |
155d8a47 | 5393 | [(set_attr "type" "fmov,multi") |
0218c012 | 5394 | (set_attr "mode" "<MODE>") |
af12f8ea | 5395 | (set_attr "unit" "*,i387") |
155d8a47 JW |
5396 | (set_attr "fp_int_src" "true")]) |
5397 | ||
380edc9f UB |
5398 | (define_insn "*floathi<mode>2_i387" |
5399 | [(set (match_operand:X87MODEF 0 "register_operand" "=f") | |
5400 | (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))] | |
5401 | "TARGET_80387 | |
5402 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5403 | || TARGET_MIX_SSE_I387)" | |
a3a5e3d1 | 5404 | "fild%Z1\t%1" |
380edc9f UB |
5405 | [(set_attr "type" "fmov") |
5406 | (set_attr "mode" "<MODE>") | |
630ecd8d JH |
5407 | (set_attr "fp_int_src" "true")]) |
5408 | ||
4f3f76e6 | 5409 | (define_split |
380edc9f UB |
5410 | [(set (match_operand:X87MODEF 0 "register_operand" "") |
5411 | (float:X87MODEF (match_operand:HI 1 "register_operand" ""))) | |
5412 | (clobber (match_operand:HI 2 "memory_operand" ""))] | |
5413 | "TARGET_80387 | |
5414 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5415 | || TARGET_MIX_SSE_I387) | |
5416 | && reload_completed" | |
5417 | [(set (match_dup 2) (match_dup 1)) | |
5418 | (set (match_dup 0) (float:X87MODEF (match_dup 2)))] | |
5419 | "") | |
4845dbb5 | 5420 | |
4f3f76e6 | 5421 | (define_split |
380edc9f UB |
5422 | [(set (match_operand:X87MODEF 0 "register_operand" "") |
5423 | (float:X87MODEF (match_operand:HI 1 "memory_operand" ""))) | |
5424 | (clobber (match_operand:HI 2 "memory_operand" ""))] | |
5425 | "TARGET_80387 | |
5426 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5427 | || TARGET_MIX_SSE_I387) | |
5428 | && reload_completed" | |
5429 | [(set (match_dup 0) (float:X87MODEF (match_dup 1)))] | |
5430 | "") | |
4845dbb5 | 5431 | |
380edc9f UB |
5432 | (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2" |
5433 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
5434 | (float:X87MODEF | |
5435 | (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))] | |
5436 | "TARGET_80387 | |
5437 | || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5438 | && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)" | |
8ce94e44 JM |
5439 | " |
5440 | { | |
5441 | if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5442 | && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) | |
5443 | && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)) | |
5444 | { | |
5445 | rtx reg = gen_reg_rtx (XFmode); | |
5446 | emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1])); | |
5447 | /* Avoid references to nonexistent function in dead code in XFmode case. */ | |
5448 | #define gen_truncxfxf2 gen_truncxfdf2 | |
5449 | emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg)); | |
5450 | #undef gen_truncxfxf2 | |
5451 | DONE; | |
5452 | } | |
5453 | }") | |
bc725565 | 5454 | |
380edc9f UB |
5455 | ;; Pre-reload splitter to add memory clobber to the pattern. |
5456 | (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1" | |
5457 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
5458 | (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))] | |
5459 | "((TARGET_80387 | |
8ce94e44 | 5460 | && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode) |
380edc9f UB |
5461 | && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) |
5462 | && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) | |
5463 | || TARGET_MIX_SSE_I387)) | |
5464 | || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5465 | && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH | |
5466 | && ((<SSEMODEI24:MODE>mode == SImode | |
3debdc1e JH |
5467 | && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS |
5468 | && optimize_function_for_speed_p (cfun) | |
380edc9f | 5469 | && flag_trapping_math) |
3debdc1e JH |
5470 | || !(TARGET_INTER_UNIT_CONVERSIONS |
5471 | || optimize_function_for_size_p (cfun))))) | |
380edc9f UB |
5472 | && !(reload_completed || reload_in_progress)" |
5473 | "#" | |
5474 | "&& 1" | |
5475 | [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1))) | |
5476 | (clobber (match_dup 2))])] | |
7b198002 UB |
5477 | { |
5478 | operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP); | |
5479 | ||
5480 | /* Avoid store forwarding (partial memory) stall penalty | |
5481 | by passing DImode value through XMM registers. */ | |
1ffcdc02 L |
5482 | if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT |
5483 | && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES | |
3debdc1e | 5484 | && optimize_function_for_speed_p (cfun)) |
7b198002 UB |
5485 | { |
5486 | emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0], | |
5487 | operands[1], | |
5488 | operands[2])); | |
5489 | DONE; | |
5490 | } | |
5491 | }) | |
630ecd8d | 5492 | |
380edc9f UB |
5493 | (define_insn "*floatsi<mode>2_vector_mixed_with_temp" |
5494 | [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x") | |
5495 | (float:MODEF | |
5496 | (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x"))) | |
73e8165a | 5497 | (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))] |
4845dbb5 | 5498 | "TARGET_SSE2 && TARGET_MIX_SSE_I387 |
3debdc1e | 5499 | && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" |
380edc9f | 5500 | "#" |
4845dbb5 | 5501 | [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt") |
380edc9f | 5502 | (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>") |
4845dbb5 JH |
5503 | (set_attr "unit" "*,i387,*,*,*") |
5504 | (set_attr "athlon_decode" "*,*,double,direct,double") | |
5505 | (set_attr "amdfam10_decode" "*,*,vector,double,double") | |
380edc9f | 5506 | (set_attr "fp_int_src" "true")]) |
4845dbb5 | 5507 | |
380edc9f UB |
5508 | (define_insn "*floatsi<mode>2_vector_mixed" |
5509 | [(set (match_operand:MODEF 0 "register_operand" "=f,x") | |
5510 | (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))] | |
630ecd8d | 5511 | "TARGET_SSE2 && TARGET_MIX_SSE_I387 |
3debdc1e | 5512 | && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" |
630ecd8d | 5513 | "@ |
a3a5e3d1 | 5514 | fild%Z1\t%1 |
380edc9f | 5515 | #" |
630ecd8d | 5516 | [(set_attr "type" "fmov,sseicvt") |
380edc9f UB |
5517 | (set_attr "mode" "<MODE>,<ssevecmode>") |
5518 | (set_attr "unit" "i387,*") | |
630ecd8d JH |
5519 | (set_attr "athlon_decode" "*,direct") |
5520 | (set_attr "amdfam10_decode" "*,double") | |
5521 | (set_attr "fp_int_src" "true")]) | |
5522 | ||
380edc9f UB |
5523 | (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp" |
5524 | [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") | |
5525 | (float:MODEF | |
5526 | (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m"))) | |
73e8165a | 5527 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))] |
380edc9f UB |
5528 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) |
5529 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387" | |
5530 | "#" | |
5531 | [(set_attr "type" "fmov,multi,sseicvt,sseicvt") | |
5532 | (set_attr "mode" "<MODEF:MODE>") | |
5533 | (set_attr "unit" "*,i387,*,*") | |
5534 | (set_attr "athlon_decode" "*,*,double,direct") | |
5535 | (set_attr "amdfam10_decode" "*,*,vector,double") | |
0218c012 UB |
5536 | (set_attr "fp_int_src" "true")]) |
5537 | ||
4f3f76e6 | 5538 | (define_split |
380edc9f UB |
5539 | [(set (match_operand:MODEF 0 "register_operand" "") |
5540 | (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" ""))) | |
5541 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))] | |
5542 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5543 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 | |
5544 | && TARGET_INTER_UNIT_CONVERSIONS | |
5545 | && reload_completed | |
5546 | && (SSE_REG_P (operands[0]) | |
5547 | || (GET_CODE (operands[0]) == SUBREG | |
5548 | && SSE_REG_P (operands[0])))" | |
5549 | [(set (match_dup 0) (float:MODEF (match_dup 1)))] | |
5550 | "") | |
0218c012 | 5551 | |
380edc9f UB |
5552 | (define_split |
5553 | [(set (match_operand:MODEF 0 "register_operand" "") | |
5554 | (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" ""))) | |
5555 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))] | |
5556 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5557 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 | |
3debdc1e | 5558 | && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) |
380edc9f UB |
5559 | && reload_completed |
5560 | && (SSE_REG_P (operands[0]) | |
5561 | || (GET_CODE (operands[0]) == SUBREG | |
5562 | && SSE_REG_P (operands[0])))" | |
5563 | [(set (match_dup 2) (match_dup 1)) | |
5564 | (set (match_dup 0) (float:MODEF (match_dup 2)))] | |
5565 | "") | |
630ecd8d | 5566 | |
380edc9f UB |
5567 | (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit" |
5568 | [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") | |
00188daa | 5569 | (float:MODEF |
0d5fd2b8 | 5570 | (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))] |
380edc9f UB |
5571 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) |
5572 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 | |
3debdc1e | 5573 | && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" |
e075ae69 | 5574 | "@ |
a3a5e3d1 | 5575 | fild%Z1\t%1 |
95879c72 L |
5576 | %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1} |
5577 | %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}" | |
380edc9f | 5578 | [(set_attr "type" "fmov,sseicvt,sseicvt") |
95879c72 | 5579 | (set_attr "prefix" "orig,maybe_vex,maybe_vex") |
380edc9f | 5580 | (set_attr "mode" "<MODEF:MODE>") |
a952487c JJ |
5581 | (set (attr "prefix_rex") |
5582 | (if_then_else | |
5583 | (and (eq_attr "prefix" "maybe_vex") | |
5584 | (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0))) | |
5585 | (const_string "1") | |
5586 | (const_string "*"))) | |
380edc9f UB |
5587 | (set_attr "unit" "i387,*,*") |
5588 | (set_attr "athlon_decode" "*,double,direct") | |
5589 | (set_attr "amdfam10_decode" "*,vector,double") | |
46ed7963 JH |
5590 | (set_attr "fp_int_src" "true")]) |
5591 | ||
380edc9f UB |
5592 | (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit" |
5593 | [(set (match_operand:MODEF 0 "register_operand" "=f,x") | |
5594 | (float:MODEF | |
5595 | (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))] | |
5596 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5597 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387 | |
3debdc1e | 5598 | && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" |
630ecd8d | 5599 | "@ |
a3a5e3d1 | 5600 | fild%Z1\t%1 |
95879c72 | 5601 | %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}" |
630ecd8d | 5602 | [(set_attr "type" "fmov,sseicvt") |
95879c72 | 5603 | (set_attr "prefix" "orig,maybe_vex") |
380edc9f | 5604 | (set_attr "mode" "<MODEF:MODE>") |
a952487c JJ |
5605 | (set (attr "prefix_rex") |
5606 | (if_then_else | |
5607 | (and (eq_attr "prefix" "maybe_vex") | |
5608 | (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0))) | |
5609 | (const_string "1") | |
5610 | (const_string "*"))) | |
380edc9f | 5611 | (set_attr "athlon_decode" "*,direct") |
630ecd8d JH |
5612 | (set_attr "amdfam10_decode" "*,double") |
5613 | (set_attr "fp_int_src" "true")]) | |
5614 | ||
380edc9f UB |
5615 | (define_insn "*floatsi<mode>2_vector_sse_with_temp" |
5616 | [(set (match_operand:MODEF 0 "register_operand" "=x,x,x") | |
5617 | (float:MODEF | |
5618 | (match_operand:SI 1 "nonimmediate_operand" "r,m,!x"))) | |
73e8165a | 5619 | (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))] |
380edc9f | 5620 | "TARGET_SSE2 && TARGET_SSE_MATH |
3debdc1e | 5621 | && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" |
380edc9f | 5622 | "#" |
f56e86bd | 5623 | [(set_attr "type" "sseicvt") |
380edc9f UB |
5624 | (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>") |
5625 | (set_attr "athlon_decode" "double,direct,double") | |
5626 | (set_attr "amdfam10_decode" "vector,double,double") | |
e075ae69 | 5627 | (set_attr "fp_int_src" "true")]) |
bc725565 | 5628 | |
380edc9f UB |
5629 | (define_insn "*floatsi<mode>2_vector_sse" |
5630 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
5631 | (float:MODEF (match_operand:SI 1 "memory_operand" "m")))] | |
5632 | "TARGET_SSE2 && TARGET_SSE_MATH | |
3debdc1e | 5633 | && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)" |
380edc9f | 5634 | "#" |
630ecd8d | 5635 | [(set_attr "type" "sseicvt") |
380edc9f UB |
5636 | (set_attr "mode" "<MODE>") |
5637 | (set_attr "athlon_decode" "direct") | |
630ecd8d JH |
5638 | (set_attr "amdfam10_decode" "double") |
5639 | (set_attr "fp_int_src" "true")]) | |
5640 | ||
380edc9f UB |
5641 | (define_split |
5642 | [(set (match_operand:MODEF 0 "register_operand" "") | |
5643 | (float:MODEF (match_operand:SI 1 "register_operand" ""))) | |
5644 | (clobber (match_operand:SI 2 "memory_operand" ""))] | |
5645 | "TARGET_SSE2 && TARGET_SSE_MATH | |
3debdc1e | 5646 | && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) |
380edc9f UB |
5647 | && reload_completed |
5648 | && (SSE_REG_P (operands[0]) | |
5649 | || (GET_CODE (operands[0]) == SUBREG | |
5650 | && SSE_REG_P (operands[0])))" | |
5651 | [(const_int 0)] | |
ebff937c | 5652 | { |
380edc9f UB |
5653 | rtx op1 = operands[1]; |
5654 | ||
5655 | operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], | |
5656 | <MODE>mode, 0); | |
5657 | if (GET_CODE (op1) == SUBREG) | |
5658 | op1 = SUBREG_REG (op1); | |
5659 | ||
5660 | if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES) | |
ebff937c | 5661 | { |
380edc9f UB |
5662 | operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); |
5663 | emit_insn (gen_sse2_loadld (operands[4], | |
5664 | CONST0_RTX (V4SImode), operands[1])); | |
ebff937c | 5665 | } |
380edc9f UB |
5666 | /* We can ignore possible trapping value in the |
5667 | high part of SSE register for non-trapping math. */ | |
5668 | else if (SSE_REG_P (op1) && !flag_trapping_math) | |
5669 | operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); | |
5670 | else | |
630ecd8d | 5671 | { |
380edc9f UB |
5672 | operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); |
5673 | emit_move_insn (operands[2], operands[1]); | |
5674 | emit_insn (gen_sse2_loadld (operands[4], | |
5675 | CONST0_RTX (V4SImode), operands[2])); | |
630ecd8d | 5676 | } |
380edc9f UB |
5677 | emit_insn |
5678 | (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4])); | |
5679 | DONE; | |
ebff937c | 5680 | }) |
da8947b0 | 5681 | |
380edc9f UB |
5682 | (define_split |
5683 | [(set (match_operand:MODEF 0 "register_operand" "") | |
5684 | (float:MODEF (match_operand:SI 1 "memory_operand" ""))) | |
5685 | (clobber (match_operand:SI 2 "memory_operand" ""))] | |
5686 | "TARGET_SSE2 && TARGET_SSE_MATH | |
3debdc1e | 5687 | && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) |
380edc9f UB |
5688 | && reload_completed |
5689 | && (SSE_REG_P (operands[0]) | |
5690 | || (GET_CODE (operands[0]) == SUBREG | |
5691 | && SSE_REG_P (operands[0])))" | |
5692 | [(const_int 0)] | |
5693 | { | |
5694 | operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], | |
5695 | <MODE>mode, 0); | |
5696 | operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); | |
5697 | ||
5698 | emit_insn (gen_sse2_loadld (operands[4], | |
5699 | CONST0_RTX (V4SImode), operands[1])); | |
5700 | emit_insn | |
5701 | (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4])); | |
5702 | DONE; | |
5703 | }) | |
46ed7963 | 5704 | |
380edc9f UB |
5705 | (define_split |
5706 | [(set (match_operand:MODEF 0 "register_operand" "") | |
5707 | (float:MODEF (match_operand:SI 1 "register_operand" "")))] | |
5708 | "TARGET_SSE2 && TARGET_SSE_MATH | |
3debdc1e | 5709 | && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) |
380edc9f UB |
5710 | && reload_completed |
5711 | && (SSE_REG_P (operands[0]) | |
5712 | || (GET_CODE (operands[0]) == SUBREG | |
5713 | && SSE_REG_P (operands[0])))" | |
5714 | [(const_int 0)] | |
5715 | { | |
5716 | rtx op1 = operands[1]; | |
5717 | ||
5718 | operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], | |
5719 | <MODE>mode, 0); | |
5720 | if (GET_CODE (op1) == SUBREG) | |
5721 | op1 = SUBREG_REG (op1); | |
5722 | ||
5723 | if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES) | |
5724 | { | |
5725 | operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); | |
5726 | emit_insn (gen_sse2_loadld (operands[4], | |
5727 | CONST0_RTX (V4SImode), operands[1])); | |
5728 | } | |
5729 | /* We can ignore possible trapping value in the | |
5730 | high part of SSE register for non-trapping math. */ | |
5731 | else if (SSE_REG_P (op1) && !flag_trapping_math) | |
5732 | operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0); | |
5733 | else | |
5734 | gcc_unreachable (); | |
ddd5eeb1 L |
5735 | emit_insn |
5736 | (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4])); | |
5737 | DONE; | |
380edc9f UB |
5738 | }) |
5739 | ||
5740 | (define_split | |
5741 | [(set (match_operand:MODEF 0 "register_operand" "") | |
5742 | (float:MODEF (match_operand:SI 1 "memory_operand" "")))] | |
5743 | "TARGET_SSE2 && TARGET_SSE_MATH | |
3debdc1e | 5744 | && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) |
380edc9f UB |
5745 | && reload_completed |
5746 | && (SSE_REG_P (operands[0]) | |
5747 | || (GET_CODE (operands[0]) == SUBREG | |
5748 | && SSE_REG_P (operands[0])))" | |
5749 | [(const_int 0)] | |
5750 | { | |
5751 | operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], | |
5752 | <MODE>mode, 0); | |
5753 | operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); | |
5754 | ||
5755 | emit_insn (gen_sse2_loadld (operands[4], | |
5756 | CONST0_RTX (V4SImode), operands[1])); | |
5757 | emit_insn | |
5758 | (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4])); | |
5759 | DONE; | |
5760 | }) | |
5761 | ||
5762 | (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp" | |
5763 | [(set (match_operand:MODEF 0 "register_operand" "=x,x") | |
5764 | (float:MODEF | |
5765 | (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m"))) | |
73e8165a | 5766 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))] |
380edc9f UB |
5767 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) |
5768 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" | |
5769 | "#" | |
5770 | [(set_attr "type" "sseicvt") | |
5771 | (set_attr "mode" "<MODEF:MODE>") | |
5772 | (set_attr "athlon_decode" "double,direct") | |
5773 | (set_attr "amdfam10_decode" "vector,double") | |
630ecd8d JH |
5774 | (set_attr "fp_int_src" "true")]) |
5775 | ||
380edc9f UB |
5776 | (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit" |
5777 | [(set (match_operand:MODEF 0 "register_operand" "=x,x") | |
5778 | (float:MODEF | |
5779 | (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))] | |
5780 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5781 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH | |
3debdc1e | 5782 | && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" |
95879c72 | 5783 | "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}" |
f56e86bd | 5784 | [(set_attr "type" "sseicvt") |
95879c72 | 5785 | (set_attr "prefix" "maybe_vex") |
380edc9f | 5786 | (set_attr "mode" "<MODEF:MODE>") |
a952487c JJ |
5787 | (set (attr "prefix_rex") |
5788 | (if_then_else | |
5789 | (and (eq_attr "prefix" "maybe_vex") | |
5790 | (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0))) | |
5791 | (const_string "1") | |
5792 | (const_string "*"))) | |
f56e86bd | 5793 | (set_attr "athlon_decode" "double,direct") |
21efb4d4 | 5794 | (set_attr "amdfam10_decode" "vector,double") |
e075ae69 | 5795 | (set_attr "fp_int_src" "true")]) |
bc725565 | 5796 | |
380edc9f UB |
5797 | (define_split |
5798 | [(set (match_operand:MODEF 0 "register_operand" "") | |
5799 | (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" ""))) | |
5800 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))] | |
5801 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5802 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH | |
3debdc1e | 5803 | && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) |
380edc9f UB |
5804 | && reload_completed |
5805 | && (SSE_REG_P (operands[0]) | |
5806 | || (GET_CODE (operands[0]) == SUBREG | |
5807 | && SSE_REG_P (operands[0])))" | |
5808 | [(set (match_dup 0) (float:MODEF (match_dup 1)))] | |
5809 | "") | |
5810 | ||
5811 | (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit" | |
5812 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
5813 | (float:MODEF | |
5814 | (match_operand:SSEMODEI24 1 "memory_operand" "m")))] | |
5815 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5816 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH | |
3debdc1e | 5817 | && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))" |
95879c72 | 5818 | "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}" |
630ecd8d | 5819 | [(set_attr "type" "sseicvt") |
95879c72 | 5820 | (set_attr "prefix" "maybe_vex") |
380edc9f | 5821 | (set_attr "mode" "<MODEF:MODE>") |
a952487c JJ |
5822 | (set (attr "prefix_rex") |
5823 | (if_then_else | |
5824 | (and (eq_attr "prefix" "maybe_vex") | |
5825 | (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0))) | |
5826 | (const_string "1") | |
5827 | (const_string "*"))) | |
630ecd8d JH |
5828 | (set_attr "athlon_decode" "direct") |
5829 | (set_attr "amdfam10_decode" "double") | |
5830 | (set_attr "fp_int_src" "true")]) | |
5831 | ||
380edc9f UB |
5832 | (define_split |
5833 | [(set (match_operand:MODEF 0 "register_operand" "") | |
5834 | (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" ""))) | |
5835 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))] | |
5836 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5837 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH | |
3debdc1e | 5838 | && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun)) |
380edc9f UB |
5839 | && reload_completed |
5840 | && (SSE_REG_P (operands[0]) | |
5841 | || (GET_CODE (operands[0]) == SUBREG | |
5842 | && SSE_REG_P (operands[0])))" | |
5843 | [(set (match_dup 2) (match_dup 1)) | |
5844 | (set (match_dup 0) (float:MODEF (match_dup 2)))] | |
5845 | "") | |
5846 | ||
5847 | (define_split | |
5848 | [(set (match_operand:MODEF 0 "register_operand" "") | |
5849 | (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" ""))) | |
5850 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))] | |
5851 | "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT) | |
5852 | && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH | |
5853 | && reload_completed | |
5854 | && (SSE_REG_P (operands[0]) | |
5855 | || (GET_CODE (operands[0]) == SUBREG | |
5856 | && SSE_REG_P (operands[0])))" | |
5857 | [(set (match_dup 0) (float:MODEF (match_dup 1)))] | |
5858 | "") | |
5859 | ||
5860 | (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp" | |
5861 | [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") | |
5862 | (float:X87MODEF | |
5863 | (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r"))) | |
73e8165a | 5864 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))] |
8ce94e44 JM |
5865 | "TARGET_80387 |
5866 | && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)" | |
2b589241 | 5867 | "@ |
a3a5e3d1 | 5868 | fild%Z1\t%1 |
2b589241 JH |
5869 | #" |
5870 | [(set_attr "type" "fmov,multi") | |
380edc9f | 5871 | (set_attr "mode" "<X87MODEF:MODE>") |
af12f8ea | 5872 | (set_attr "unit" "*,i387") |
2b589241 JH |
5873 | (set_attr "fp_int_src" "true")]) |
5874 | ||
380edc9f UB |
5875 | (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387" |
5876 | [(set (match_operand:X87MODEF 0 "register_operand" "=f") | |
5877 | (float:X87MODEF | |
5878 | (match_operand:SSEMODEI24 1 "memory_operand" "m")))] | |
8ce94e44 JM |
5879 | "TARGET_80387 |
5880 | && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)" | |
a3a5e3d1 | 5881 | "fild%Z1\t%1" |
380edc9f UB |
5882 | [(set_attr "type" "fmov") |
5883 | (set_attr "mode" "<X87MODEF:MODE>") | |
2b589241 JH |
5884 | (set_attr "fp_int_src" "true")]) |
5885 | ||
155d8a47 | 5886 | (define_split |
380edc9f UB |
5887 | [(set (match_operand:X87MODEF 0 "register_operand" "") |
5888 | (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" ""))) | |
5889 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))] | |
5890 | "TARGET_80387 | |
8ce94e44 | 5891 | && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode) |
380edc9f UB |
5892 | && reload_completed |
5893 | && FP_REG_P (operands[0])" | |
5894 | [(set (match_dup 2) (match_dup 1)) | |
5895 | (set (match_dup 0) (float:X87MODEF (match_dup 2)))] | |
5896 | "") | |
5897 | ||
5898 | (define_split | |
5899 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
5900 | (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" ""))) | |
5901 | (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))] | |
5902 | "TARGET_80387 | |
8ce94e44 | 5903 | && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode) |
380edc9f UB |
5904 | && reload_completed |
5905 | && FP_REG_P (operands[0])" | |
5906 | [(set (match_dup 0) (float:X87MODEF (match_dup 1)))] | |
5907 | "") | |
8d705469 | 5908 | |
7b198002 UB |
5909 | ;; Avoid store forwarding (partial memory) stall penalty |
5910 | ;; by passing DImode value through XMM registers. */ | |
5911 | ||
5912 | (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm" | |
5913 | [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") | |
5914 | (float:X87MODEF | |
5915 | (match_operand:DI 1 "nonimmediate_operand" "m,?r"))) | |
73e8165a UB |
5916 | (clobber (match_scratch:V4SI 3 "=X,x")) |
5917 | (clobber (match_scratch:V4SI 4 "=X,x")) | |
5918 | (clobber (match_operand:DI 2 "memory_operand" "=X,m"))] | |
8ce94e44 JM |
5919 | "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) |
5920 | && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES | |
3debdc1e | 5921 | && !TARGET_64BIT && optimize_function_for_speed_p (cfun)" |
7b198002 UB |
5922 | "#" |
5923 | [(set_attr "type" "multi") | |
5924 | (set_attr "mode" "<X87MODEF:MODE>") | |
5925 | (set_attr "unit" "i387") | |
5926 | (set_attr "fp_int_src" "true")]) | |
5927 | ||
5928 | (define_split | |
5929 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
5930 | (float:X87MODEF (match_operand:DI 1 "register_operand" ""))) | |
e356fac8 UB |
5931 | (clobber (match_scratch:V4SI 3 "")) |
5932 | (clobber (match_scratch:V4SI 4 "")) | |
7b198002 | 5933 | (clobber (match_operand:DI 2 "memory_operand" ""))] |
8ce94e44 JM |
5934 | "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) |
5935 | && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES | |
3debdc1e | 5936 | && !TARGET_64BIT && optimize_function_for_speed_p (cfun) |
7b198002 UB |
5937 | && reload_completed |
5938 | && FP_REG_P (operands[0])" | |
5939 | [(set (match_dup 2) (match_dup 3)) | |
5940 | (set (match_dup 0) (float:X87MODEF (match_dup 2)))] | |
5941 | { | |
5942 | /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). | |
5943 | Assemble the 64-bit DImode value in an xmm register. */ | |
5944 | emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode), | |
5945 | gen_rtx_SUBREG (SImode, operands[1], 0))); | |
5946 | emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode), | |
5947 | gen_rtx_SUBREG (SImode, operands[1], 4))); | |
5948 | emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4])); | |
5949 | ||
5950 | operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); | |
5951 | }) | |
5952 | ||
5953 | (define_split | |
5954 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
5955 | (float:X87MODEF (match_operand:DI 1 "memory_operand" ""))) | |
e356fac8 UB |
5956 | (clobber (match_scratch:V4SI 3 "")) |
5957 | (clobber (match_scratch:V4SI 4 "")) | |
5958 | (clobber (match_operand:DI 2 "memory_operand" ""))] | |
8ce94e44 JM |
5959 | "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) |
5960 | && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES | |
3debdc1e | 5961 | && !TARGET_64BIT && optimize_function_for_speed_p (cfun) |
7b198002 UB |
5962 | && reload_completed |
5963 | && FP_REG_P (operands[0])" | |
5964 | [(set (match_dup 0) (float:X87MODEF (match_dup 1)))] | |
5965 | "") | |
5966 | ||
7fb1431b UB |
5967 | ;; Avoid store forwarding (partial memory) stall penalty by extending |
5968 | ;; SImode value to DImode through XMM register instead of pushing two | |
5969 | ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES | |
5970 | ;; targets benefit from this optimization. Also note that fild | |
5971 | ;; loads from memory only. | |
5972 | ||
5973 | (define_insn "*floatunssi<mode>2_1" | |
5974 | [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") | |
5975 | (unsigned_float:X87MODEF | |
5976 | (match_operand:SI 1 "nonimmediate_operand" "x,m"))) | |
5977 | (clobber (match_operand:DI 2 "memory_operand" "=m,m")) | |
5978 | (clobber (match_scratch:SI 3 "=X,x"))] | |
5979 | "!TARGET_64BIT | |
8f612190 | 5980 | && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) |
8ce94e44 | 5981 | && TARGET_SSE" |
7fb1431b UB |
5982 | "#" |
5983 | [(set_attr "type" "multi") | |
5984 | (set_attr "mode" "<MODE>")]) | |
5985 | ||
5986 | (define_split | |
5987 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
5988 | (unsigned_float:X87MODEF | |
5989 | (match_operand:SI 1 "register_operand" ""))) | |
5990 | (clobber (match_operand:DI 2 "memory_operand" "")) | |
5991 | (clobber (match_scratch:SI 3 ""))] | |
5992 | "!TARGET_64BIT | |
8f612190 | 5993 | && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) |
8ce94e44 | 5994 | && TARGET_SSE |
7fb1431b UB |
5995 | && reload_completed" |
5996 | [(set (match_dup 2) (match_dup 1)) | |
5997 | (set (match_dup 0) | |
5998 | (float:X87MODEF (match_dup 2)))] | |
5999 | "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);") | |
6000 | ||
6001 | (define_split | |
6002 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
6003 | (unsigned_float:X87MODEF | |
6004 | (match_operand:SI 1 "memory_operand" ""))) | |
6005 | (clobber (match_operand:DI 2 "memory_operand" "")) | |
6006 | (clobber (match_scratch:SI 3 ""))] | |
6007 | "!TARGET_64BIT | |
8f612190 | 6008 | && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) |
8ce94e44 | 6009 | && TARGET_SSE |
7fb1431b UB |
6010 | && reload_completed" |
6011 | [(set (match_dup 2) (match_dup 3)) | |
6012 | (set (match_dup 0) | |
6013 | (float:X87MODEF (match_dup 2)))] | |
6014 | { | |
6015 | emit_move_insn (operands[3], operands[1]); | |
6016 | operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0); | |
6017 | }) | |
6018 | ||
def7425b | 6019 | (define_expand "floatunssi<mode>2" |
7fb1431b UB |
6020 | [(parallel |
6021 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
6022 | (unsigned_float:X87MODEF | |
6023 | (match_operand:SI 1 "nonimmediate_operand" ""))) | |
6024 | (clobber (match_dup 2)) | |
6025 | (clobber (match_scratch:SI 3 ""))])] | |
6026 | "!TARGET_64BIT | |
8f612190 | 6027 | && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) |
8ce94e44 | 6028 | && TARGET_SSE) |
7fb1431b | 6029 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" |
ebff937c | 6030 | { |
7fb1431b UB |
6031 | if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
6032 | { | |
6033 | ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]); | |
6034 | DONE; | |
6035 | } | |
6036 | else | |
6037 | { | |
bbbbb16a ILT |
6038 | enum ix86_stack_slot slot = (virtuals_instantiated |
6039 | ? SLOT_TEMP | |
6040 | : SLOT_VIRTUAL); | |
7fb1431b UB |
6041 | operands[2] = assign_386_stack_local (DImode, slot); |
6042 | } | |
ebff937c SH |
6043 | }) |
6044 | ||
8d705469 JH |
6045 | (define_expand "floatunsdisf2" |
6046 | [(use (match_operand:SF 0 "register_operand" "")) | |
ebff937c | 6047 | (use (match_operand:DI 1 "nonimmediate_operand" ""))] |
da8947b0 | 6048 | "TARGET_64BIT && TARGET_SSE_MATH" |
8d705469 JH |
6049 | "x86_emit_floatuns (operands); DONE;") |
6050 | ||
6051 | (define_expand "floatunsdidf2" | |
6052 | [(use (match_operand:DF 0 "register_operand" "")) | |
ebff937c | 6053 | (use (match_operand:DI 1 "nonimmediate_operand" ""))] |
def7425b UB |
6054 | "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK) |
6055 | && TARGET_SSE2 && TARGET_SSE_MATH" | |
ebff937c SH |
6056 | { |
6057 | if (TARGET_64BIT) | |
6058 | x86_emit_floatuns (operands); | |
6059 | else | |
6060 | ix86_expand_convert_uns_didf_sse (operands[0], operands[1]); | |
6061 | DONE; | |
6062 | }) | |
997404de | 6063 | \f |
e075ae69 | 6064 | ;; Add instructions |
53b5ce19 | 6065 | |
28356f52 JB |
6066 | ;; %%% splits for addditi3 |
6067 | ||
6068 | (define_expand "addti3" | |
6069 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
6070 | (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") | |
7ae14d31 | 6071 | (match_operand:TI 2 "x86_64_general_operand" "")))] |
28356f52 JB |
6072 | "TARGET_64BIT" |
6073 | "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;") | |
6074 | ||
6075 | (define_insn "*addti3_1" | |
6076 | [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") | |
6077 | (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0") | |
68b8830a | 6078 | (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) |
28356f52 JB |
6079 | (clobber (reg:CC FLAGS_REG))] |
6080 | "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)" | |
6081 | "#") | |
6082 | ||
6083 | (define_split | |
6084 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
6085 | (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") | |
68b8830a | 6086 | (match_operand:TI 2 "x86_64_general_operand" ""))) |
28356f52 JB |
6087 | (clobber (reg:CC FLAGS_REG))] |
6088 | "TARGET_64BIT && reload_completed" | |
6089 | [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] | |
6090 | UNSPEC_ADD_CARRY)) | |
6091 | (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]) | |
6092 | (parallel [(set (match_dup 3) | |
6093 | (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) | |
6094 | (match_dup 4)) | |
6095 | (match_dup 5))) | |
6096 | (clobber (reg:CC FLAGS_REG))])] | |
c2b814b9 | 6097 | "split_ti (&operands[0], 3, &operands[0], &operands[3]);") |
28356f52 | 6098 | |
e075ae69 RH |
6099 | ;; %%% splits for addsidi3 |
6100 | ; [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
6101 | ; (plus:DI (match_operand:DI 1 "general_operand" "") | |
6102 | ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))] | |
e1f998ad | 6103 | |
9b70259d JH |
6104 | (define_expand "adddi3" |
6105 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
6106 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") | |
7ae14d31 | 6107 | (match_operand:DI 2 "x86_64_general_operand" "")))] |
9b70259d JH |
6108 | "" |
6109 | "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;") | |
6110 | ||
6111 | (define_insn "*adddi3_1" | |
e075ae69 RH |
6112 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") |
6113 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") | |
6114 | (match_operand:DI 2 "general_operand" "roiF,riF"))) | |
8bc527af | 6115 | (clobber (reg:CC FLAGS_REG))] |
c15c18c5 | 6116 | "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" |
bc725565 JW |
6117 | "#") |
6118 | ||
6119 | (define_split | |
e075ae69 | 6120 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
4cbfbb1b | 6121 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") |
e075ae69 | 6122 | (match_operand:DI 2 "general_operand" ""))) |
8bc527af | 6123 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 6124 | "!TARGET_64BIT && reload_completed" |
8bc527af | 6125 | [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] |
8ee41eaf | 6126 | UNSPEC_ADD_CARRY)) |
e075ae69 RH |
6127 | (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) |
6128 | (parallel [(set (match_dup 3) | |
8bc527af | 6129 | (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) |
9dcbdc7e JH |
6130 | (match_dup 4)) |
6131 | (match_dup 5))) | |
8bc527af | 6132 | (clobber (reg:CC FLAGS_REG))])] |
c2b814b9 | 6133 | "split_di (&operands[0], 3, &operands[0], &operands[3]);") |
e075ae69 | 6134 | |
7b52eede | 6135 | (define_insn "adddi3_carry_rex64" |
9b70259d | 6136 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") |
e6e81735 | 6137 | (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") |
9b70259d JH |
6138 | (match_operand:DI 1 "nonimmediate_operand" "%0,0")) |
6139 | (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) | |
8bc527af | 6140 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 6141 | "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" |
0f40f9f7 | 6142 | "adc{q}\t{%2, %0|%0, %2}" |
9b70259d | 6143 | [(set_attr "type" "alu") |
b6837b94 | 6144 | (set_attr "use_carry" "1") |
9b70259d | 6145 | (set_attr "pent_pair" "pu") |
56bab446 | 6146 | (set_attr "mode" "DI")]) |
9b70259d JH |
6147 | |
6148 | (define_insn "*adddi3_cc_rex64" | |
8bc527af | 6149 | [(set (reg:CC FLAGS_REG) |
8ee41eaf RH |
6150 | (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0") |
6151 | (match_operand:DI 2 "x86_64_general_operand" "re,rm")] | |
6152 | UNSPEC_ADD_CARRY)) | |
9b70259d JH |
6153 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") |
6154 | (plus:DI (match_dup 1) (match_dup 2)))] | |
6155 | "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" | |
0f40f9f7 | 6156 | "add{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
6157 | [(set_attr "type" "alu") |
6158 | (set_attr "mode" "DI")]) | |
6159 | ||
d1c3b587 | 6160 | (define_insn "*<plusminus_insn><mode>3_cc_overflow" |
d39d658d RIL |
6161 | [(set (reg:CCC FLAGS_REG) |
6162 | (compare:CCC | |
6163 | (plusminus:SWI | |
6164 | (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0") | |
6165 | (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) | |
6166 | (match_dup 1))) | |
6167 | (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") | |
6168 | (plusminus:SWI (match_dup 1) (match_dup 2)))] | |
6169 | "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" | |
d1c3b587 | 6170 | "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}" |
d39d658d RIL |
6171 | [(set_attr "type" "alu") |
6172 | (set_attr "mode" "<MODE>")]) | |
6173 | ||
6174 | (define_insn "*add<mode>3_cconly_overflow" | |
6175 | [(set (reg:CCC FLAGS_REG) | |
6176 | (compare:CCC | |
6177 | (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0") | |
6178 | (match_operand:SWI 2 "<general_operand>" "<r><i>m")) | |
6179 | (match_dup 1))) | |
6180 | (clobber (match_scratch:SWI 0 "=<r>"))] | |
6181 | "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" | |
6182 | "add{<imodesuffix>}\t{%2, %0|%0, %2}" | |
6183 | [(set_attr "type" "alu") | |
6184 | (set_attr "mode" "<MODE>")]) | |
6185 | ||
6186 | (define_insn "*sub<mode>3_cconly_overflow" | |
6187 | [(set (reg:CCC FLAGS_REG) | |
6188 | (compare:CCC | |
6189 | (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") | |
6190 | (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) | |
6191 | (match_dup 0)))] | |
6192 | "" | |
6193 | "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" | |
6194 | [(set_attr "type" "icmp") | |
6195 | (set_attr "mode" "<MODE>")]) | |
6196 | ||
d1c3b587 | 6197 | (define_insn "*<plusminus_insn>si3_zext_cc_overflow" |
d39d658d RIL |
6198 | [(set (reg:CCC FLAGS_REG) |
6199 | (compare:CCC | |
6200 | (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0") | |
6201 | (match_operand:SI 2 "general_operand" "g")) | |
6202 | (match_dup 1))) | |
6203 | (set (match_operand:DI 0 "register_operand" "=r") | |
6204 | (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))] | |
6205 | "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" | |
d1c3b587 | 6206 | "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}" |
d39d658d RIL |
6207 | [(set_attr "type" "alu") |
6208 | (set_attr "mode" "SI")]) | |
6209 | ||
7b52eede | 6210 | (define_insn "addqi3_carry" |
d67e96cf | 6211 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") |
e6e81735 | 6212 | (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") |
7b52eede | 6213 | (match_operand:QI 1 "nonimmediate_operand" "%0,0")) |
0edb82cb | 6214 | (match_operand:QI 2 "general_operand" "qn,qm"))) |
8bc527af | 6215 | (clobber (reg:CC FLAGS_REG))] |
7b52eede JH |
6216 | "ix86_binary_operator_ok (PLUS, QImode, operands)" |
6217 | "adc{b}\t{%2, %0|%0, %2}" | |
6218 | [(set_attr "type" "alu") | |
b6837b94 | 6219 | (set_attr "use_carry" "1") |
7b52eede | 6220 | (set_attr "pent_pair" "pu") |
56bab446 | 6221 | (set_attr "mode" "QI")]) |
7b52eede JH |
6222 | |
6223 | (define_insn "addhi3_carry" | |
6224 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
e6e81735 | 6225 | (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") |
7b52eede | 6226 | (match_operand:HI 1 "nonimmediate_operand" "%0,0")) |
0edb82cb | 6227 | (match_operand:HI 2 "general_operand" "rn,rm"))) |
8bc527af | 6228 | (clobber (reg:CC FLAGS_REG))] |
7b52eede JH |
6229 | "ix86_binary_operator_ok (PLUS, HImode, operands)" |
6230 | "adc{w}\t{%2, %0|%0, %2}" | |
6231 | [(set_attr "type" "alu") | |
b6837b94 | 6232 | (set_attr "use_carry" "1") |
7b52eede | 6233 | (set_attr "pent_pair" "pu") |
56bab446 | 6234 | (set_attr "mode" "HI")]) |
7b52eede JH |
6235 | |
6236 | (define_insn "addsi3_carry" | |
e075ae69 | 6237 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
e6e81735 | 6238 | (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") |
9dcbdc7e JH |
6239 | (match_operand:SI 1 "nonimmediate_operand" "%0,0")) |
6240 | (match_operand:SI 2 "general_operand" "ri,rm"))) | |
8bc527af | 6241 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 6242 | "ix86_binary_operator_ok (PLUS, SImode, operands)" |
0f40f9f7 | 6243 | "adc{l}\t{%2, %0|%0, %2}" |
e075ae69 | 6244 | [(set_attr "type" "alu") |
b6837b94 | 6245 | (set_attr "use_carry" "1") |
e075ae69 | 6246 | (set_attr "pent_pair" "pu") |
56bab446 | 6247 | (set_attr "mode" "SI")]) |
4fb21e90 | 6248 | |
9b70259d JH |
6249 | (define_insn "*addsi3_carry_zext" |
6250 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6300f037 | 6251 | (zero_extend:DI |
e6e81735 | 6252 | (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") |
9b70259d | 6253 | (match_operand:SI 1 "nonimmediate_operand" "%0")) |
73f48658 | 6254 | (match_operand:SI 2 "general_operand" "g")))) |
8bc527af | 6255 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 6256 | "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" |
0f40f9f7 | 6257 | "adc{l}\t{%2, %k0|%k0, %2}" |
9b70259d | 6258 | [(set_attr "type" "alu") |
b6837b94 | 6259 | (set_attr "use_carry" "1") |
9b70259d | 6260 | (set_attr "pent_pair" "pu") |
56bab446 | 6261 | (set_attr "mode" "SI")]) |
9b70259d | 6262 | |
7e08e190 | 6263 | (define_insn "*addsi3_cc" |
8bc527af | 6264 | [(set (reg:CC FLAGS_REG) |
8ee41eaf RH |
6265 | (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0") |
6266 | (match_operand:SI 2 "general_operand" "ri,rm")] | |
6267 | UNSPEC_ADD_CARRY)) | |
7e08e190 JH |
6268 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
6269 | (plus:SI (match_dup 1) (match_dup 2)))] | |
265dab10 | 6270 | "ix86_binary_operator_ok (PLUS, SImode, operands)" |
0f40f9f7 | 6271 | "add{l}\t{%2, %0|%0, %2}" |
265dab10 | 6272 | [(set_attr "type" "alu") |
7e08e190 JH |
6273 | (set_attr "mode" "SI")]) |
6274 | ||
6275 | (define_insn "addqi3_cc" | |
8bc527af | 6276 | [(set (reg:CC FLAGS_REG) |
8ee41eaf | 6277 | (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0") |
0edb82cb | 6278 | (match_operand:QI 2 "general_operand" "qn,qm")] |
8ee41eaf | 6279 | UNSPEC_ADD_CARRY)) |
7e08e190 JH |
6280 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") |
6281 | (plus:QI (match_dup 1) (match_dup 2)))] | |
6282 | "ix86_binary_operator_ok (PLUS, QImode, operands)" | |
0f40f9f7 | 6283 | "add{b}\t{%2, %0|%0, %2}" |
7e08e190 JH |
6284 | [(set_attr "type" "alu") |
6285 | (set_attr "mode" "QI")]) | |
265dab10 | 6286 | |
e075ae69 | 6287 | (define_expand "addsi3" |
7ae14d31 UB |
6288 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
6289 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
6290 | (match_operand:SI 2 "general_operand" "")))] | |
e075ae69 RH |
6291 | "" |
6292 | "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;") | |
886c62d1 | 6293 | |
ac62a60e | 6294 | (define_insn "*lea_1" |
e075ae69 | 6295 | [(set (match_operand:SI 0 "register_operand" "=r") |
74dc3e94 | 6296 | (match_operand:SI 1 "no_seg_address_operand" "p"))] |
ac62a60e | 6297 | "!TARGET_64BIT" |
0f40f9f7 | 6298 | "lea{l}\t{%a1, %0|%0, %a1}" |
6ef67412 JH |
6299 | [(set_attr "type" "lea") |
6300 | (set_attr "mode" "SI")]) | |
2ae0f82c | 6301 | |
ac62a60e JH |
6302 | (define_insn "*lea_1_rex64" |
6303 | [(set (match_operand:SI 0 "register_operand" "=r") | |
74dc3e94 | 6304 | (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] |
ac62a60e | 6305 | "TARGET_64BIT" |
0f40f9f7 | 6306 | "lea{l}\t{%a1, %0|%0, %a1}" |
ac62a60e JH |
6307 | [(set_attr "type" "lea") |
6308 | (set_attr "mode" "SI")]) | |
6309 | ||
6310 | (define_insn "*lea_1_zext" | |
6311 | [(set (match_operand:DI 0 "register_operand" "=r") | |
74dc3e94 RH |
6312 | (zero_extend:DI |
6313 | (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))] | |
d4f33f6c | 6314 | "TARGET_64BIT" |
0f40f9f7 | 6315 | "lea{l}\t{%a1, %k0|%k0, %a1}" |
ac62a60e JH |
6316 | [(set_attr "type" "lea") |
6317 | (set_attr "mode" "SI")]) | |
6318 | ||
6319 | (define_insn "*lea_2_rex64" | |
6320 | [(set (match_operand:DI 0 "register_operand" "=r") | |
74dc3e94 | 6321 | (match_operand:DI 1 "no_seg_address_operand" "p"))] |
ac62a60e | 6322 | "TARGET_64BIT" |
0f40f9f7 | 6323 | "lea{q}\t{%a1, %0|%0, %a1}" |
ac62a60e JH |
6324 | [(set_attr "type" "lea") |
6325 | (set_attr "mode" "DI")]) | |
6326 | ||
58787064 JH |
6327 | ;; The lea patterns for non-Pmodes needs to be matched by several |
6328 | ;; insns converted to real lea by splitters. | |
6329 | ||
6330 | (define_insn_and_split "*lea_general_1" | |
6331 | [(set (match_operand 0 "register_operand" "=r") | |
9a9286af | 6332 | (plus (plus (match_operand 1 "index_register_operand" "l") |
58787064 JH |
6333 | (match_operand 2 "register_operand" "r")) |
6334 | (match_operand 3 "immediate_operand" "i")))] | |
ac62a60e JH |
6335 | "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode |
6336 | || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) | |
3debdc1e | 6337 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
58787064 JH |
6338 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) |
6339 | && GET_MODE (operands[0]) == GET_MODE (operands[2]) | |
6340 | && (GET_MODE (operands[0]) == GET_MODE (operands[3]) | |
6341 | || GET_MODE (operands[3]) == VOIDmode)" | |
6342 | "#" | |
cb694d2c | 6343 | "&& reload_completed" |
58787064 | 6344 | [(const_int 0)] |
58787064 JH |
6345 | { |
6346 | rtx pat; | |
6347 | operands[0] = gen_lowpart (SImode, operands[0]); | |
6348 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
6349 | operands[2] = gen_lowpart (Pmode, operands[2]); | |
6350 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
6351 | pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]), | |
6352 | operands[3]); | |
6353 | if (Pmode != SImode) | |
6354 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
6355 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
6356 | DONE; | |
0f40f9f7 | 6357 | } |
58787064 JH |
6358 | [(set_attr "type" "lea") |
6359 | (set_attr "mode" "SI")]) | |
6360 | ||
ac62a60e JH |
6361 | (define_insn_and_split "*lea_general_1_zext" |
6362 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6363 | (zero_extend:DI | |
9a9286af | 6364 | (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l") |
ac62a60e JH |
6365 | (match_operand:SI 2 "register_operand" "r")) |
6366 | (match_operand:SI 3 "immediate_operand" "i"))))] | |
6367 | "TARGET_64BIT" | |
6368 | "#" | |
6369 | "&& reload_completed" | |
6370 | [(set (match_dup 0) | |
6371 | (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1) | |
6372 | (match_dup 2)) | |
6373 | (match_dup 3)) 0)))] | |
ac62a60e JH |
6374 | { |
6375 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
6376 | operands[2] = gen_lowpart (Pmode, operands[2]); | |
6377 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
0f40f9f7 | 6378 | } |
ac62a60e JH |
6379 | [(set_attr "type" "lea") |
6380 | (set_attr "mode" "SI")]) | |
6381 | ||
58787064 JH |
6382 | (define_insn_and_split "*lea_general_2" |
6383 | [(set (match_operand 0 "register_operand" "=r") | |
9a9286af | 6384 | (plus (mult (match_operand 1 "index_register_operand" "l") |
58787064 JH |
6385 | (match_operand 2 "const248_operand" "i")) |
6386 | (match_operand 3 "nonmemory_operand" "ri")))] | |
ac62a60e JH |
6387 | "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode |
6388 | || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) | |
3debdc1e | 6389 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
58787064 JH |
6390 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) |
6391 | && (GET_MODE (operands[0]) == GET_MODE (operands[3]) | |
6392 | || GET_MODE (operands[3]) == VOIDmode)" | |
6393 | "#" | |
cb694d2c | 6394 | "&& reload_completed" |
58787064 | 6395 | [(const_int 0)] |
58787064 JH |
6396 | { |
6397 | rtx pat; | |
6398 | operands[0] = gen_lowpart (SImode, operands[0]); | |
6399 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
6400 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
6401 | pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]), | |
6402 | operands[3]); | |
6403 | if (Pmode != SImode) | |
6404 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
6405 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
6406 | DONE; | |
0f40f9f7 | 6407 | } |
58787064 JH |
6408 | [(set_attr "type" "lea") |
6409 | (set_attr "mode" "SI")]) | |
6410 | ||
ac62a60e JH |
6411 | (define_insn_and_split "*lea_general_2_zext" |
6412 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6413 | (zero_extend:DI | |
9a9286af | 6414 | (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l") |
ac62a60e JH |
6415 | (match_operand:SI 2 "const248_operand" "n")) |
6416 | (match_operand:SI 3 "nonmemory_operand" "ri"))))] | |
6417 | "TARGET_64BIT" | |
6418 | "#" | |
6419 | "&& reload_completed" | |
6420 | [(set (match_dup 0) | |
6421 | (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1) | |
6422 | (match_dup 2)) | |
6423 | (match_dup 3)) 0)))] | |
ac62a60e JH |
6424 | { |
6425 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
6426 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
0f40f9f7 | 6427 | } |
ac62a60e JH |
6428 | [(set_attr "type" "lea") |
6429 | (set_attr "mode" "SI")]) | |
6430 | ||
58787064 JH |
6431 | (define_insn_and_split "*lea_general_3" |
6432 | [(set (match_operand 0 "register_operand" "=r") | |
9a9286af | 6433 | (plus (plus (mult (match_operand 1 "index_register_operand" "l") |
58787064 JH |
6434 | (match_operand 2 "const248_operand" "i")) |
6435 | (match_operand 3 "register_operand" "r")) | |
6436 | (match_operand 4 "immediate_operand" "i")))] | |
ac62a60e JH |
6437 | "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode |
6438 | || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) | |
3debdc1e | 6439 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
58787064 JH |
6440 | && GET_MODE (operands[0]) == GET_MODE (operands[1]) |
6441 | && GET_MODE (operands[0]) == GET_MODE (operands[3])" | |
6442 | "#" | |
cb694d2c | 6443 | "&& reload_completed" |
58787064 | 6444 | [(const_int 0)] |
58787064 JH |
6445 | { |
6446 | rtx pat; | |
6447 | operands[0] = gen_lowpart (SImode, operands[0]); | |
6448 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
6449 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
6450 | operands[4] = gen_lowpart (Pmode, operands[4]); | |
6451 | pat = gen_rtx_PLUS (Pmode, | |
6452 | gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], | |
6453 | operands[2]), | |
6454 | operands[3]), | |
6455 | operands[4]); | |
6456 | if (Pmode != SImode) | |
6457 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
6458 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
6459 | DONE; | |
0f40f9f7 | 6460 | } |
58787064 JH |
6461 | [(set_attr "type" "lea") |
6462 | (set_attr "mode" "SI")]) | |
6463 | ||
ac62a60e JH |
6464 | (define_insn_and_split "*lea_general_3_zext" |
6465 | [(set (match_operand:DI 0 "register_operand" "=r") | |
6466 | (zero_extend:DI | |
9a9286af RH |
6467 | (plus:SI (plus:SI (mult:SI |
6468 | (match_operand:SI 1 "index_register_operand" "l") | |
6469 | (match_operand:SI 2 "const248_operand" "n")) | |
ac62a60e JH |
6470 | (match_operand:SI 3 "register_operand" "r")) |
6471 | (match_operand:SI 4 "immediate_operand" "i"))))] | |
6472 | "TARGET_64BIT" | |
6473 | "#" | |
6474 | "&& reload_completed" | |
6475 | [(set (match_dup 0) | |
6476 | (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1) | |
6477 | (match_dup 2)) | |
6478 | (match_dup 3)) | |
6479 | (match_dup 4)) 0)))] | |
ac62a60e JH |
6480 | { |
6481 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
6482 | operands[3] = gen_lowpart (Pmode, operands[3]); | |
6483 | operands[4] = gen_lowpart (Pmode, operands[4]); | |
0f40f9f7 | 6484 | } |
ac62a60e JH |
6485 | [(set_attr "type" "lea") |
6486 | (set_attr "mode" "SI")]) | |
6487 | ||
9b70259d | 6488 | (define_insn "*adddi_1_rex64" |
b6837b94 JY |
6489 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") |
6490 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r") | |
6491 | (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le"))) | |
8bc527af | 6492 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 6493 | "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" |
2ae0f82c | 6494 | { |
e075ae69 | 6495 | switch (get_attr_type (insn)) |
2ae0f82c | 6496 | { |
e075ae69 RH |
6497 | case TYPE_LEA: |
6498 | operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); | |
0f40f9f7 | 6499 | return "lea{q}\t{%a2, %0|%0, %a2}"; |
2ae0f82c | 6500 | |
e075ae69 | 6501 | case TYPE_INCDEC: |
7637e42c | 6502 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
e075ae69 | 6503 | if (operands[2] == const1_rtx) |
0f40f9f7 | 6504 | return "inc{q}\t%0"; |
2ae0f82c | 6505 | else |
7637e42c NS |
6506 | { |
6507 | gcc_assert (operands[2] == constm1_rtx); | |
6508 | return "dec{q}\t%0"; | |
6509 | } | |
2ae0f82c | 6510 | |
e075ae69 | 6511 | default: |
b6837b94 JY |
6512 | /* Use add as much as possible to replace lea for AGU optimization. */ |
6513 | if (which_alternative == 2 && TARGET_OPT_AGU) | |
6514 | return "add{q}\t{%1, %0|%0, %1}"; | |
6515 | ||
7637e42c | 6516 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
2ae0f82c | 6517 | |
e075ae69 RH |
6518 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
6519 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 6520 | if (CONST_INT_P (operands[2]) |
ef6257cd | 6521 | /* Avoid overflows. */ |
0f40f9f7 | 6522 | && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) |
e075ae69 RH |
6523 | && (INTVAL (operands[2]) == 128 |
6524 | || (INTVAL (operands[2]) < 0 | |
6525 | && INTVAL (operands[2]) != -128))) | |
6526 | { | |
6527 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 6528 | return "sub{q}\t{%2, %0|%0, %2}"; |
e075ae69 | 6529 | } |
0f40f9f7 | 6530 | return "add{q}\t{%2, %0|%0, %2}"; |
e075ae69 | 6531 | } |
0f40f9f7 | 6532 | } |
e075ae69 | 6533 | [(set (attr "type") |
b6837b94 JY |
6534 | (cond [(and (eq_attr "alternative" "2") |
6535 | (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0))) | |
e075ae69 | 6536 | (const_string "lea") |
b6837b94 JY |
6537 | (eq_attr "alternative" "3") |
6538 | (const_string "lea") | |
e075ae69 RH |
6539 | ; Current assemblers are broken and do not allow @GOTOFF in |
6540 | ; ought but a memory context. | |
9b70259d | 6541 | (match_operand:DI 2 "pic_symbolic_operand" "") |
e075ae69 | 6542 | (const_string "lea") |
9b70259d | 6543 | (match_operand:DI 2 "incdec_operand" "") |
e075ae69 RH |
6544 | (const_string "incdec") |
6545 | ] | |
6ef67412 | 6546 | (const_string "alu"))) |
a952487c JJ |
6547 | (set (attr "length_immediate") |
6548 | (if_then_else | |
6549 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
6550 | (const_string "1") | |
6551 | (const_string "*"))) | |
9b70259d | 6552 | (set_attr "mode" "DI")]) |
e075ae69 | 6553 | |
1c27d4b2 JH |
6554 | ;; Convert lea to the lea pattern to avoid flags dependency. |
6555 | (define_split | |
9b70259d JH |
6556 | [(set (match_operand:DI 0 "register_operand" "") |
6557 | (plus:DI (match_operand:DI 1 "register_operand" "") | |
6558 | (match_operand:DI 2 "x86_64_nonmemory_operand" ""))) | |
8bc527af | 6559 | (clobber (reg:CC FLAGS_REG))] |
6ff078d4 JY |
6560 | "TARGET_64BIT && reload_completed |
6561 | && ix86_lea_for_add_ok (PLUS, insn, operands)" | |
9b70259d JH |
6562 | [(set (match_dup 0) |
6563 | (plus:DI (match_dup 1) | |
6564 | (match_dup 2)))] | |
6565 | "") | |
1c27d4b2 | 6566 | |
9b70259d | 6567 | (define_insn "*adddi_2_rex64" |
42fabf21 | 6568 | [(set (reg FLAGS_REG) |
16189740 | 6569 | (compare |
9b70259d JH |
6570 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
6571 | (match_operand:DI 2 "x86_64_general_operand" "rme,re")) | |
6300f037 | 6572 | (const_int 0))) |
9b70259d JH |
6573 | (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") |
6574 | (plus:DI (match_dup 1) (match_dup 2)))] | |
6575 | "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) | |
6576 | && ix86_binary_operator_ok (PLUS, DImode, operands) | |
e075ae69 | 6577 | /* Current assemblers are broken and do not allow @GOTOFF in |
892a2d68 | 6578 | ought but a memory context. */ |
e075ae69 | 6579 | && ! pic_symbolic_operand (operands[2], VOIDmode)" |
886c62d1 | 6580 | { |
e075ae69 | 6581 | switch (get_attr_type (insn)) |
96f218bb | 6582 | { |
e075ae69 | 6583 | case TYPE_INCDEC: |
7637e42c | 6584 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
e075ae69 | 6585 | if (operands[2] == const1_rtx) |
0f40f9f7 | 6586 | return "inc{q}\t%0"; |
96f218bb | 6587 | else |
7637e42c NS |
6588 | { |
6589 | gcc_assert (operands[2] == constm1_rtx); | |
6590 | return "dec{q}\t%0"; | |
6591 | } | |
96f218bb | 6592 | |
e075ae69 | 6593 | default: |
7637e42c | 6594 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d | 6595 | /* ???? We ought to handle there the 32bit case too |
5bdc5878 | 6596 | - do we need new constraint? */ |
e075ae69 RH |
6597 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
6598 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 6599 | if (CONST_INT_P (operands[2]) |
ef6257cd | 6600 | /* Avoid overflows. */ |
0f40f9f7 | 6601 | && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) |
e075ae69 RH |
6602 | && (INTVAL (operands[2]) == 128 |
6603 | || (INTVAL (operands[2]) < 0 | |
6604 | && INTVAL (operands[2]) != -128))) | |
6605 | { | |
6606 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 6607 | return "sub{q}\t{%2, %0|%0, %2}"; |
e075ae69 | 6608 | } |
0f40f9f7 | 6609 | return "add{q}\t{%2, %0|%0, %2}"; |
9c530261 | 6610 | } |
0f40f9f7 | 6611 | } |
e075ae69 | 6612 | [(set (attr "type") |
9b70259d | 6613 | (if_then_else (match_operand:DI 2 "incdec_operand" "") |
e075ae69 | 6614 | (const_string "incdec") |
6ef67412 | 6615 | (const_string "alu"))) |
a952487c JJ |
6616 | (set (attr "length_immediate") |
6617 | (if_then_else | |
6618 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
6619 | (const_string "1") | |
6620 | (const_string "*"))) | |
9b70259d | 6621 | (set_attr "mode" "DI")]) |
e075ae69 | 6622 | |
e74061a9 | 6623 | (define_insn "*adddi_3_rex64" |
42fabf21 | 6624 | [(set (reg FLAGS_REG) |
9b70259d JH |
6625 | (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme")) |
6626 | (match_operand:DI 1 "x86_64_general_operand" "%0"))) | |
6627 | (clobber (match_scratch:DI 0 "=r"))] | |
e74061a9 JH |
6628 | "TARGET_64BIT |
6629 | && ix86_match_ccmode (insn, CCZmode) | |
7656aee4 | 6630 | && !(MEM_P (operands[1]) && MEM_P (operands[2])) |
d90ffc8d | 6631 | /* Current assemblers are broken and do not allow @GOTOFF in |
892a2d68 | 6632 | ought but a memory context. */ |
d90ffc8d | 6633 | && ! pic_symbolic_operand (operands[2], VOIDmode)" |
d90ffc8d JH |
6634 | { |
6635 | switch (get_attr_type (insn)) | |
6636 | { | |
6637 | case TYPE_INCDEC: | |
7637e42c | 6638 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
d90ffc8d | 6639 | if (operands[2] == const1_rtx) |
0f40f9f7 | 6640 | return "inc{q}\t%0"; |
d90ffc8d | 6641 | else |
7637e42c NS |
6642 | { |
6643 | gcc_assert (operands[2] == constm1_rtx); | |
6644 | return "dec{q}\t%0"; | |
6645 | } | |
d90ffc8d JH |
6646 | |
6647 | default: | |
7637e42c | 6648 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d | 6649 | /* ???? We ought to handle there the 32bit case too |
5bdc5878 | 6650 | - do we need new constraint? */ |
d90ffc8d JH |
6651 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
6652 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 6653 | if (CONST_INT_P (operands[2]) |
ef6257cd | 6654 | /* Avoid overflows. */ |
0f40f9f7 | 6655 | && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) |
d90ffc8d JH |
6656 | && (INTVAL (operands[2]) == 128 |
6657 | || (INTVAL (operands[2]) < 0 | |
6658 | && INTVAL (operands[2]) != -128))) | |
6659 | { | |
6660 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 6661 | return "sub{q}\t{%2, %0|%0, %2}"; |
d90ffc8d | 6662 | } |
0f40f9f7 | 6663 | return "add{q}\t{%2, %0|%0, %2}"; |
d90ffc8d | 6664 | } |
0f40f9f7 | 6665 | } |
d90ffc8d | 6666 | [(set (attr "type") |
9b70259d | 6667 | (if_then_else (match_operand:DI 2 "incdec_operand" "") |
d90ffc8d JH |
6668 | (const_string "incdec") |
6669 | (const_string "alu"))) | |
a952487c JJ |
6670 | (set (attr "length_immediate") |
6671 | (if_then_else | |
6672 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
6673 | (const_string "1") | |
6674 | (const_string "*"))) | |
9b70259d | 6675 | (set_attr "mode" "DI")]) |
d90ffc8d | 6676 | |
9b70259d | 6677 | ; For comparisons against 1, -1 and 128, we may generate better code |
7e08e190 JH |
6678 | ; by converting cmp to add, inc or dec as done by peephole2. This pattern |
6679 | ; is matched then. We can't accept general immediate, because for | |
6680 | ; case of overflows, the result is messed up. | |
9b70259d | 6681 | ; This pattern also don't hold of 0x8000000000000000, since the value overflows |
7e08e190 | 6682 | ; when negated. |
d6a7951f | 6683 | ; Also carry flag is reversed compared to cmp, so this conversion is valid |
7e08e190 | 6684 | ; only for comparisons not depending on it. |
e74061a9 | 6685 | (define_insn "*adddi_4_rex64" |
42fabf21 | 6686 | [(set (reg FLAGS_REG) |
9b70259d JH |
6687 | (compare (match_operand:DI 1 "nonimmediate_operand" "0") |
6688 | (match_operand:DI 2 "x86_64_immediate_operand" "e"))) | |
6689 | (clobber (match_scratch:DI 0 "=rm"))] | |
e74061a9 JH |
6690 | "TARGET_64BIT |
6691 | && ix86_match_ccmode (insn, CCGCmode)" | |
7e08e190 JH |
6692 | { |
6693 | switch (get_attr_type (insn)) | |
6694 | { | |
6695 | case TYPE_INCDEC: | |
6696 | if (operands[2] == constm1_rtx) | |
0f40f9f7 | 6697 | return "inc{q}\t%0"; |
7e08e190 | 6698 | else |
7637e42c NS |
6699 | { |
6700 | gcc_assert (operands[2] == const1_rtx); | |
6701 | return "dec{q}\t%0"; | |
6702 | } | |
e075ae69 | 6703 | |
7e08e190 | 6704 | default: |
7637e42c | 6705 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
7e08e190 JH |
6706 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
6707 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
6708 | if ((INTVAL (operands[2]) == -128 | |
6709 | || (INTVAL (operands[2]) > 0 | |
ef6257cd JH |
6710 | && INTVAL (operands[2]) != 128)) |
6711 | /* Avoid overflows. */ | |
0f40f9f7 ZW |
6712 | && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))) |
6713 | return "sub{q}\t{%2, %0|%0, %2}"; | |
7e08e190 | 6714 | operands[2] = GEN_INT (-INTVAL (operands[2])); |
0f40f9f7 | 6715 | return "add{q}\t{%2, %0|%0, %2}"; |
7e08e190 | 6716 | } |
0f40f9f7 | 6717 | } |
7e08e190 | 6718 | [(set (attr "type") |
9b70259d | 6719 | (if_then_else (match_operand:DI 2 "incdec_operand" "") |
7e08e190 JH |
6720 | (const_string "incdec") |
6721 | (const_string "alu"))) | |
93cac287 JJ |
6722 | (set (attr "length_immediate") |
6723 | (if_then_else | |
725fd454 | 6724 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) |
93cac287 JJ |
6725 | (const_string "1") |
6726 | (const_string "*"))) | |
9b70259d | 6727 | (set_attr "mode" "DI")]) |
d90ffc8d | 6728 | |
e74061a9 | 6729 | (define_insn "*adddi_5_rex64" |
42fabf21 | 6730 | [(set (reg FLAGS_REG) |
9076b9c1 | 6731 | (compare |
9b70259d JH |
6732 | (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") |
6733 | (match_operand:DI 2 "x86_64_general_operand" "rme")) | |
6300f037 | 6734 | (const_int 0))) |
9b70259d | 6735 | (clobber (match_scratch:DI 0 "=r"))] |
e74061a9 JH |
6736 | "TARGET_64BIT |
6737 | && ix86_match_ccmode (insn, CCGOCmode) | |
7656aee4 | 6738 | && !(MEM_P (operands[1]) && MEM_P (operands[2])) |
9076b9c1 | 6739 | /* Current assemblers are broken and do not allow @GOTOFF in |
892a2d68 | 6740 | ought but a memory context. */ |
9076b9c1 | 6741 | && ! pic_symbolic_operand (operands[2], VOIDmode)" |
9076b9c1 JH |
6742 | { |
6743 | switch (get_attr_type (insn)) | |
6744 | { | |
6745 | case TYPE_INCDEC: | |
7637e42c | 6746 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9076b9c1 | 6747 | if (operands[2] == const1_rtx) |
0f40f9f7 | 6748 | return "inc{q}\t%0"; |
9076b9c1 | 6749 | else |
7637e42c NS |
6750 | { |
6751 | gcc_assert (operands[2] == constm1_rtx); | |
6752 | return "dec{q}\t%0"; | |
6753 | } | |
9076b9c1 JH |
6754 | |
6755 | default: | |
7637e42c | 6756 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9076b9c1 JH |
6757 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
6758 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 6759 | if (CONST_INT_P (operands[2]) |
ef6257cd | 6760 | /* Avoid overflows. */ |
0f40f9f7 | 6761 | && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) |
9076b9c1 JH |
6762 | && (INTVAL (operands[2]) == 128 |
6763 | || (INTVAL (operands[2]) < 0 | |
6764 | && INTVAL (operands[2]) != -128))) | |
6765 | { | |
6766 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 6767 | return "sub{q}\t{%2, %0|%0, %2}"; |
9076b9c1 | 6768 | } |
0f40f9f7 | 6769 | return "add{q}\t{%2, %0|%0, %2}"; |
9076b9c1 | 6770 | } |
0f40f9f7 | 6771 | } |
9076b9c1 | 6772 | [(set (attr "type") |
9b70259d | 6773 | (if_then_else (match_operand:DI 2 "incdec_operand" "") |
9076b9c1 JH |
6774 | (const_string "incdec") |
6775 | (const_string "alu"))) | |
a952487c JJ |
6776 | (set (attr "length_immediate") |
6777 | (if_then_else | |
6778 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
6779 | (const_string "1") | |
6780 | (const_string "*"))) | |
9b70259d | 6781 | (set_attr "mode" "DI")]) |
2ae0f82c | 6782 | |
e075ae69 | 6783 | |
9b70259d | 6784 | (define_insn "*addsi_1" |
b6837b94 JY |
6785 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r") |
6786 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r") | |
6787 | (match_operand:SI 2 "general_operand" "g,ri,0,li"))) | |
8bc527af | 6788 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 6789 | "ix86_binary_operator_ok (PLUS, SImode, operands)" |
58787064 JH |
6790 | { |
6791 | switch (get_attr_type (insn)) | |
6792 | { | |
6793 | case TYPE_LEA: | |
9b70259d | 6794 | operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); |
0f40f9f7 | 6795 | return "lea{l}\t{%a2, %0|%0, %a2}"; |
9b70259d | 6796 | |
58787064 | 6797 | case TYPE_INCDEC: |
7637e42c | 6798 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
58787064 | 6799 | if (operands[2] == const1_rtx) |
0f40f9f7 | 6800 | return "inc{l}\t%0"; |
9b70259d | 6801 | else |
7637e42c NS |
6802 | { |
6803 | gcc_assert (operands[2] == constm1_rtx); | |
6804 | return "dec{l}\t%0"; | |
6805 | } | |
58787064 JH |
6806 | |
6807 | default: | |
b6837b94 JY |
6808 | /* Use add as much as possible to replace lea for AGU optimization. */ |
6809 | if (which_alternative == 2 && TARGET_OPT_AGU) | |
6810 | return "add{l}\t{%1, %0|%0, %1}"; | |
6811 | ||
7637e42c | 6812 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d | 6813 | |
58787064 JH |
6814 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
6815 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 6816 | if (CONST_INT_P (operands[2]) |
58787064 JH |
6817 | && (INTVAL (operands[2]) == 128 |
6818 | || (INTVAL (operands[2]) < 0 | |
6819 | && INTVAL (operands[2]) != -128))) | |
9b70259d JH |
6820 | { |
6821 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 6822 | return "sub{l}\t{%2, %0|%0, %2}"; |
9b70259d | 6823 | } |
0f40f9f7 | 6824 | return "add{l}\t{%2, %0|%0, %2}"; |
58787064 | 6825 | } |
0f40f9f7 | 6826 | } |
58787064 | 6827 | [(set (attr "type") |
b6837b94 JY |
6828 | (cond [(and (eq_attr "alternative" "2") |
6829 | (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0))) | |
6830 | (const_string "lea") | |
6831 | (eq_attr "alternative" "3") | |
9b70259d JH |
6832 | (const_string "lea") |
6833 | ; Current assemblers are broken and do not allow @GOTOFF in | |
6834 | ; ought but a memory context. | |
6835 | (match_operand:SI 2 "pic_symbolic_operand" "") | |
6836 | (const_string "lea") | |
6837 | (match_operand:SI 2 "incdec_operand" "") | |
6838 | (const_string "incdec") | |
6839 | ] | |
6840 | (const_string "alu"))) | |
a952487c JJ |
6841 | (set (attr "length_immediate") |
6842 | (if_then_else | |
6843 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
6844 | (const_string "1") | |
6845 | (const_string "*"))) | |
9b70259d | 6846 | (set_attr "mode" "SI")]) |
58787064 | 6847 | |
9b70259d JH |
6848 | ;; Convert lea to the lea pattern to avoid flags dependency. |
6849 | (define_split | |
6850 | [(set (match_operand 0 "register_operand" "") | |
6851 | (plus (match_operand 1 "register_operand" "") | |
6852 | (match_operand 2 "nonmemory_operand" ""))) | |
8bc527af | 6853 | (clobber (reg:CC FLAGS_REG))] |
6ff078d4 | 6854 | "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" |
9b70259d | 6855 | [(const_int 0)] |
9b70259d JH |
6856 | { |
6857 | rtx pat; | |
6858 | /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) | |
6859 | may confuse gen_lowpart. */ | |
6860 | if (GET_MODE (operands[0]) != Pmode) | |
6861 | { | |
6862 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
6863 | operands[2] = gen_lowpart (Pmode, operands[2]); | |
6864 | } | |
6865 | operands[0] = gen_lowpart (SImode, operands[0]); | |
6866 | pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); | |
6867 | if (Pmode != SImode) | |
6868 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
6869 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
6870 | DONE; | |
0f40f9f7 | 6871 | }) |
9b70259d JH |
6872 | |
6873 | ;; It may seem that nonimmediate operand is proper one for operand 1. | |
6874 | ;; The addsi_1 pattern allows nonimmediate operand at that place and | |
6875 | ;; we take care in ix86_binary_operator_ok to not allow two memory | |
6876 | ;; operands so proper swapping will be done in reload. This allow | |
6877 | ;; patterns constructed from addsi_1 to match. | |
6878 | (define_insn "addsi_1_zext" | |
6879 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
6880 | (zero_extend:DI | |
6881 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") | |
0edb82cb | 6882 | (match_operand:SI 2 "general_operand" "g,li")))) |
8bc527af | 6883 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 6884 | "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" |
886c62d1 | 6885 | { |
e075ae69 | 6886 | switch (get_attr_type (insn)) |
7c802a40 | 6887 | { |
9b70259d JH |
6888 | case TYPE_LEA: |
6889 | operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); | |
0f40f9f7 | 6890 | return "lea{l}\t{%a2, %k0|%k0, %a2}"; |
9b70259d | 6891 | |
e075ae69 RH |
6892 | case TYPE_INCDEC: |
6893 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 6894 | return "inc{l}\t%k0"; |
9b70259d | 6895 | else |
7637e42c NS |
6896 | { |
6897 | gcc_assert (operands[2] == constm1_rtx); | |
6898 | return "dec{l}\t%k0"; | |
6899 | } | |
9b70259d JH |
6900 | |
6901 | default: | |
6902 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
6903 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 6904 | if (CONST_INT_P (operands[2]) |
9b70259d JH |
6905 | && (INTVAL (operands[2]) == 128 |
6906 | || (INTVAL (operands[2]) < 0 | |
6907 | && INTVAL (operands[2]) != -128))) | |
6908 | { | |
6909 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 6910 | return "sub{l}\t{%2, %k0|%k0, %2}"; |
9b70259d | 6911 | } |
0f40f9f7 | 6912 | return "add{l}\t{%2, %k0|%k0, %2}"; |
9b70259d | 6913 | } |
0f40f9f7 | 6914 | } |
9b70259d JH |
6915 | [(set (attr "type") |
6916 | (cond [(eq_attr "alternative" "1") | |
6917 | (const_string "lea") | |
6918 | ; Current assemblers are broken and do not allow @GOTOFF in | |
6919 | ; ought but a memory context. | |
6920 | (match_operand:SI 2 "pic_symbolic_operand" "") | |
6921 | (const_string "lea") | |
6922 | (match_operand:SI 2 "incdec_operand" "") | |
6923 | (const_string "incdec") | |
6924 | ] | |
6925 | (const_string "alu"))) | |
a952487c JJ |
6926 | (set (attr "length_immediate") |
6927 | (if_then_else | |
6928 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
6929 | (const_string "1") | |
6930 | (const_string "*"))) | |
9b70259d JH |
6931 | (set_attr "mode" "SI")]) |
6932 | ||
6933 | ;; Convert lea to the lea pattern to avoid flags dependency. | |
6934 | (define_split | |
6935 | [(set (match_operand:DI 0 "register_operand" "") | |
6936 | (zero_extend:DI | |
6937 | (plus:SI (match_operand:SI 1 "register_operand" "") | |
6938 | (match_operand:SI 2 "nonmemory_operand" "")))) | |
8bc527af | 6939 | (clobber (reg:CC FLAGS_REG))] |
bc8a6d63 | 6940 | "TARGET_64BIT && reload_completed |
9b70259d JH |
6941 | && true_regnum (operands[0]) != true_regnum (operands[1])" |
6942 | [(set (match_dup 0) | |
6943 | (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] | |
9b70259d JH |
6944 | { |
6945 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
6946 | operands[2] = gen_lowpart (Pmode, operands[2]); | |
0f40f9f7 | 6947 | }) |
9b70259d JH |
6948 | |
6949 | (define_insn "*addsi_2" | |
42fabf21 | 6950 | [(set (reg FLAGS_REG) |
9b70259d JH |
6951 | (compare |
6952 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
0edb82cb | 6953 | (match_operand:SI 2 "general_operand" "g,ri")) |
6300f037 | 6954 | (const_int 0))) |
9b70259d JH |
6955 | (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") |
6956 | (plus:SI (match_dup 1) (match_dup 2)))] | |
6957 | "ix86_match_ccmode (insn, CCGOCmode) | |
6958 | && ix86_binary_operator_ok (PLUS, SImode, operands) | |
6959 | /* Current assemblers are broken and do not allow @GOTOFF in | |
892a2d68 | 6960 | ought but a memory context. */ |
9b70259d | 6961 | && ! pic_symbolic_operand (operands[2], VOIDmode)" |
9b70259d JH |
6962 | { |
6963 | switch (get_attr_type (insn)) | |
6964 | { | |
6965 | case TYPE_INCDEC: | |
7637e42c | 6966 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d | 6967 | if (operands[2] == const1_rtx) |
0f40f9f7 | 6968 | return "inc{l}\t%0"; |
9b70259d | 6969 | else |
7637e42c NS |
6970 | { |
6971 | gcc_assert (operands[2] == constm1_rtx); | |
6972 | return "dec{l}\t%0"; | |
6973 | } | |
9b70259d JH |
6974 | |
6975 | default: | |
7637e42c | 6976 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d JH |
6977 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
6978 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 6979 | if (CONST_INT_P (operands[2]) |
9b70259d JH |
6980 | && (INTVAL (operands[2]) == 128 |
6981 | || (INTVAL (operands[2]) < 0 | |
6982 | && INTVAL (operands[2]) != -128))) | |
6983 | { | |
6984 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 6985 | return "sub{l}\t{%2, %0|%0, %2}"; |
9b70259d | 6986 | } |
0f40f9f7 | 6987 | return "add{l}\t{%2, %0|%0, %2}"; |
9b70259d | 6988 | } |
0f40f9f7 | 6989 | } |
9b70259d JH |
6990 | [(set (attr "type") |
6991 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
6992 | (const_string "incdec") | |
6993 | (const_string "alu"))) | |
a952487c JJ |
6994 | (set (attr "length_immediate") |
6995 | (if_then_else | |
6996 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
6997 | (const_string "1") | |
6998 | (const_string "*"))) | |
9b70259d JH |
6999 | (set_attr "mode" "SI")]) |
7000 | ||
7001 | ;; See comment for addsi_1_zext why we do use nonimmediate_operand | |
7002 | (define_insn "*addsi_2_zext" | |
42fabf21 | 7003 | [(set (reg FLAGS_REG) |
9b70259d JH |
7004 | (compare |
7005 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") | |
0edb82cb | 7006 | (match_operand:SI 2 "general_operand" "g")) |
6300f037 | 7007 | (const_int 0))) |
9b70259d JH |
7008 | (set (match_operand:DI 0 "register_operand" "=r") |
7009 | (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] | |
7010 | "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) | |
7011 | && ix86_binary_operator_ok (PLUS, SImode, operands) | |
7012 | /* Current assemblers are broken and do not allow @GOTOFF in | |
892a2d68 | 7013 | ought but a memory context. */ |
9b70259d | 7014 | && ! pic_symbolic_operand (operands[2], VOIDmode)" |
9b70259d JH |
7015 | { |
7016 | switch (get_attr_type (insn)) | |
7017 | { | |
7018 | case TYPE_INCDEC: | |
7019 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7020 | return "inc{l}\t%k0"; |
9b70259d | 7021 | else |
7637e42c NS |
7022 | { |
7023 | gcc_assert (operands[2] == constm1_rtx); | |
7024 | return "dec{l}\t%k0"; | |
7025 | } | |
9b70259d JH |
7026 | |
7027 | default: | |
7028 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7029 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7030 | if (CONST_INT_P (operands[2]) |
9b70259d JH |
7031 | && (INTVAL (operands[2]) == 128 |
7032 | || (INTVAL (operands[2]) < 0 | |
7033 | && INTVAL (operands[2]) != -128))) | |
7034 | { | |
7035 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7036 | return "sub{l}\t{%2, %k0|%k0, %2}"; |
9b70259d | 7037 | } |
0f40f9f7 | 7038 | return "add{l}\t{%2, %k0|%k0, %2}"; |
9b70259d | 7039 | } |
0f40f9f7 | 7040 | } |
9b70259d JH |
7041 | [(set (attr "type") |
7042 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
7043 | (const_string "incdec") | |
7044 | (const_string "alu"))) | |
a952487c JJ |
7045 | (set (attr "length_immediate") |
7046 | (if_then_else | |
7047 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7048 | (const_string "1") | |
7049 | (const_string "*"))) | |
9b70259d JH |
7050 | (set_attr "mode" "SI")]) |
7051 | ||
7052 | (define_insn "*addsi_3" | |
42fabf21 | 7053 | [(set (reg FLAGS_REG) |
0edb82cb | 7054 | (compare (neg:SI (match_operand:SI 2 "general_operand" "g")) |
9b70259d JH |
7055 | (match_operand:SI 1 "nonimmediate_operand" "%0"))) |
7056 | (clobber (match_scratch:SI 0 "=r"))] | |
7057 | "ix86_match_ccmode (insn, CCZmode) | |
7656aee4 | 7058 | && !(MEM_P (operands[1]) && MEM_P (operands[2])) |
9b70259d | 7059 | /* Current assemblers are broken and do not allow @GOTOFF in |
892a2d68 | 7060 | ought but a memory context. */ |
9b70259d | 7061 | && ! pic_symbolic_operand (operands[2], VOIDmode)" |
9b70259d JH |
7062 | { |
7063 | switch (get_attr_type (insn)) | |
7064 | { | |
7065 | case TYPE_INCDEC: | |
7637e42c | 7066 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d | 7067 | if (operands[2] == const1_rtx) |
0f40f9f7 | 7068 | return "inc{l}\t%0"; |
9b70259d | 7069 | else |
7637e42c NS |
7070 | { |
7071 | gcc_assert (operands[2] == constm1_rtx); | |
7072 | return "dec{l}\t%0"; | |
7073 | } | |
9b70259d JH |
7074 | |
7075 | default: | |
7637e42c | 7076 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d JH |
7077 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
7078 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7079 | if (CONST_INT_P (operands[2]) |
9b70259d JH |
7080 | && (INTVAL (operands[2]) == 128 |
7081 | || (INTVAL (operands[2]) < 0 | |
7082 | && INTVAL (operands[2]) != -128))) | |
7083 | { | |
7084 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7085 | return "sub{l}\t{%2, %0|%0, %2}"; |
9b70259d | 7086 | } |
0f40f9f7 | 7087 | return "add{l}\t{%2, %0|%0, %2}"; |
9b70259d | 7088 | } |
0f40f9f7 | 7089 | } |
9b70259d JH |
7090 | [(set (attr "type") |
7091 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
7092 | (const_string "incdec") | |
7093 | (const_string "alu"))) | |
a952487c JJ |
7094 | (set (attr "length_immediate") |
7095 | (if_then_else | |
7096 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7097 | (const_string "1") | |
7098 | (const_string "*"))) | |
9b70259d JH |
7099 | (set_attr "mode" "SI")]) |
7100 | ||
7101 | ;; See comment for addsi_1_zext why we do use nonimmediate_operand | |
7102 | (define_insn "*addsi_3_zext" | |
42fabf21 | 7103 | [(set (reg FLAGS_REG) |
0edb82cb | 7104 | (compare (neg:SI (match_operand:SI 2 "general_operand" "g")) |
9b70259d JH |
7105 | (match_operand:SI 1 "nonimmediate_operand" "%0"))) |
7106 | (set (match_operand:DI 0 "register_operand" "=r") | |
7107 | (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] | |
7108 | "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) | |
7109 | && ix86_binary_operator_ok (PLUS, SImode, operands) | |
7110 | /* Current assemblers are broken and do not allow @GOTOFF in | |
892a2d68 | 7111 | ought but a memory context. */ |
9b70259d | 7112 | && ! pic_symbolic_operand (operands[2], VOIDmode)" |
9b70259d JH |
7113 | { |
7114 | switch (get_attr_type (insn)) | |
7115 | { | |
7116 | case TYPE_INCDEC: | |
7117 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7118 | return "inc{l}\t%k0"; |
9b70259d | 7119 | else |
7637e42c NS |
7120 | { |
7121 | gcc_assert (operands[2] == constm1_rtx); | |
7122 | return "dec{l}\t%k0"; | |
7123 | } | |
9b70259d JH |
7124 | |
7125 | default: | |
7126 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7127 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7128 | if (CONST_INT_P (operands[2]) |
9b70259d JH |
7129 | && (INTVAL (operands[2]) == 128 |
7130 | || (INTVAL (operands[2]) < 0 | |
7131 | && INTVAL (operands[2]) != -128))) | |
7132 | { | |
7133 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7134 | return "sub{l}\t{%2, %k0|%k0, %2}"; |
9b70259d | 7135 | } |
0f40f9f7 | 7136 | return "add{l}\t{%2, %k0|%k0, %2}"; |
9b70259d | 7137 | } |
0f40f9f7 | 7138 | } |
9b70259d JH |
7139 | [(set (attr "type") |
7140 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
7141 | (const_string "incdec") | |
7142 | (const_string "alu"))) | |
a952487c JJ |
7143 | (set (attr "length_immediate") |
7144 | (if_then_else | |
7145 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7146 | (const_string "1") | |
7147 | (const_string "*"))) | |
9b70259d JH |
7148 | (set_attr "mode" "SI")]) |
7149 | ||
4aae8a9a | 7150 | ; For comparisons against 1, -1 and 128, we may generate better code |
9b70259d JH |
7151 | ; by converting cmp to add, inc or dec as done by peephole2. This pattern |
7152 | ; is matched then. We can't accept general immediate, because for | |
7153 | ; case of overflows, the result is messed up. | |
7154 | ; This pattern also don't hold of 0x80000000, since the value overflows | |
7155 | ; when negated. | |
d6a7951f | 7156 | ; Also carry flag is reversed compared to cmp, so this conversion is valid |
9b70259d JH |
7157 | ; only for comparisons not depending on it. |
7158 | (define_insn "*addsi_4" | |
42fabf21 | 7159 | [(set (reg FLAGS_REG) |
9b70259d JH |
7160 | (compare (match_operand:SI 1 "nonimmediate_operand" "0") |
7161 | (match_operand:SI 2 "const_int_operand" "n"))) | |
7162 | (clobber (match_scratch:SI 0 "=rm"))] | |
7163 | "ix86_match_ccmode (insn, CCGCmode) | |
7164 | && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000" | |
9b70259d JH |
7165 | { |
7166 | switch (get_attr_type (insn)) | |
7167 | { | |
7168 | case TYPE_INCDEC: | |
7169 | if (operands[2] == constm1_rtx) | |
0f40f9f7 | 7170 | return "inc{l}\t%0"; |
9b70259d | 7171 | else |
7637e42c NS |
7172 | { |
7173 | gcc_assert (operands[2] == const1_rtx); | |
7174 | return "dec{l}\t%0"; | |
7175 | } | |
9b70259d JH |
7176 | |
7177 | default: | |
7637e42c | 7178 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d JH |
7179 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
7180 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7181 | if ((INTVAL (operands[2]) == -128 | |
7182 | || (INTVAL (operands[2]) > 0 | |
7183 | && INTVAL (operands[2]) != 128))) | |
0f40f9f7 | 7184 | return "sub{l}\t{%2, %0|%0, %2}"; |
9b70259d | 7185 | operands[2] = GEN_INT (-INTVAL (operands[2])); |
0f40f9f7 | 7186 | return "add{l}\t{%2, %0|%0, %2}"; |
9b70259d | 7187 | } |
0f40f9f7 | 7188 | } |
9b70259d JH |
7189 | [(set (attr "type") |
7190 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
7191 | (const_string "incdec") | |
7192 | (const_string "alu"))) | |
93cac287 JJ |
7193 | (set (attr "length_immediate") |
7194 | (if_then_else | |
725fd454 | 7195 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) |
93cac287 JJ |
7196 | (const_string "1") |
7197 | (const_string "*"))) | |
9b70259d JH |
7198 | (set_attr "mode" "SI")]) |
7199 | ||
7200 | (define_insn "*addsi_5" | |
42fabf21 | 7201 | [(set (reg FLAGS_REG) |
9b70259d JH |
7202 | (compare |
7203 | (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") | |
0edb82cb | 7204 | (match_operand:SI 2 "general_operand" "g")) |
6300f037 | 7205 | (const_int 0))) |
9b70259d JH |
7206 | (clobber (match_scratch:SI 0 "=r"))] |
7207 | "ix86_match_ccmode (insn, CCGOCmode) | |
7656aee4 | 7208 | && !(MEM_P (operands[1]) && MEM_P (operands[2])) |
9b70259d | 7209 | /* Current assemblers are broken and do not allow @GOTOFF in |
892a2d68 | 7210 | ought but a memory context. */ |
9b70259d | 7211 | && ! pic_symbolic_operand (operands[2], VOIDmode)" |
9b70259d JH |
7212 | { |
7213 | switch (get_attr_type (insn)) | |
7214 | { | |
7215 | case TYPE_INCDEC: | |
7637e42c | 7216 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d | 7217 | if (operands[2] == const1_rtx) |
0f40f9f7 | 7218 | return "inc{l}\t%0"; |
9b70259d | 7219 | else |
7637e42c NS |
7220 | { |
7221 | gcc_assert (operands[2] == constm1_rtx); | |
7222 | return "dec{l}\t%0"; | |
7223 | } | |
9b70259d JH |
7224 | |
7225 | default: | |
7637e42c | 7226 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d JH |
7227 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
7228 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7229 | if (CONST_INT_P (operands[2]) |
9b70259d JH |
7230 | && (INTVAL (operands[2]) == 128 |
7231 | || (INTVAL (operands[2]) < 0 | |
7232 | && INTVAL (operands[2]) != -128))) | |
7233 | { | |
7234 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7235 | return "sub{l}\t{%2, %0|%0, %2}"; |
9b70259d | 7236 | } |
0f40f9f7 | 7237 | return "add{l}\t{%2, %0|%0, %2}"; |
9b70259d | 7238 | } |
0f40f9f7 | 7239 | } |
9b70259d JH |
7240 | [(set (attr "type") |
7241 | (if_then_else (match_operand:SI 2 "incdec_operand" "") | |
7242 | (const_string "incdec") | |
7243 | (const_string "alu"))) | |
a952487c JJ |
7244 | (set (attr "length_immediate") |
7245 | (if_then_else | |
7246 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7247 | (const_string "1") | |
7248 | (const_string "*"))) | |
9b70259d JH |
7249 | (set_attr "mode" "SI")]) |
7250 | ||
7251 | (define_expand "addhi3" | |
7ae14d31 UB |
7252 | [(set (match_operand:HI 0 "nonimmediate_operand" "") |
7253 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7254 | (match_operand:HI 2 "general_operand" "")))] | |
9b70259d JH |
7255 | "TARGET_HIMODE_MATH" |
7256 | "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;") | |
7257 | ||
7258 | ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah | |
7259 | ;; type optimizations enabled by define-splits. This is not important | |
7260 | ;; for PII, and in fact harmful because of partial register stalls. | |
7261 | ||
7262 | (define_insn "*addhi_1_lea" | |
7263 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") | |
7264 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") | |
0edb82cb | 7265 | (match_operand:HI 2 "general_operand" "rn,rm,ln"))) |
8bc527af | 7266 | (clobber (reg:CC FLAGS_REG))] |
9b70259d JH |
7267 | "!TARGET_PARTIAL_REG_STALL |
7268 | && ix86_binary_operator_ok (PLUS, HImode, operands)" | |
9b70259d JH |
7269 | { |
7270 | switch (get_attr_type (insn)) | |
7271 | { | |
7272 | case TYPE_LEA: | |
0f40f9f7 | 7273 | return "#"; |
9b70259d JH |
7274 | case TYPE_INCDEC: |
7275 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7276 | return "inc{w}\t%0"; |
7637e42c NS |
7277 | else |
7278 | { | |
7279 | gcc_assert (operands[2] == constm1_rtx); | |
7280 | return "dec{w}\t%0"; | |
7281 | } | |
9b70259d JH |
7282 | |
7283 | default: | |
7284 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7285 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7286 | if (CONST_INT_P (operands[2]) |
9b70259d JH |
7287 | && (INTVAL (operands[2]) == 128 |
7288 | || (INTVAL (operands[2]) < 0 | |
7289 | && INTVAL (operands[2]) != -128))) | |
7290 | { | |
7291 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7292 | return "sub{w}\t{%2, %0|%0, %2}"; |
9b70259d | 7293 | } |
0f40f9f7 | 7294 | return "add{w}\t{%2, %0|%0, %2}"; |
9b70259d | 7295 | } |
0f40f9f7 | 7296 | } |
9b70259d JH |
7297 | [(set (attr "type") |
7298 | (if_then_else (eq_attr "alternative" "2") | |
7299 | (const_string "lea") | |
7300 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
7301 | (const_string "incdec") | |
7302 | (const_string "alu")))) | |
a952487c JJ |
7303 | (set (attr "length_immediate") |
7304 | (if_then_else | |
7305 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7306 | (const_string "1") | |
7307 | (const_string "*"))) | |
9b70259d JH |
7308 | (set_attr "mode" "HI,HI,SI")]) |
7309 | ||
7310 | (define_insn "*addhi_1" | |
7311 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
7312 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
0edb82cb | 7313 | (match_operand:HI 2 "general_operand" "rn,rm"))) |
8bc527af | 7314 | (clobber (reg:CC FLAGS_REG))] |
9b70259d JH |
7315 | "TARGET_PARTIAL_REG_STALL |
7316 | && ix86_binary_operator_ok (PLUS, HImode, operands)" | |
9b70259d JH |
7317 | { |
7318 | switch (get_attr_type (insn)) | |
7319 | { | |
7320 | case TYPE_INCDEC: | |
7321 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7322 | return "inc{w}\t%0"; |
7637e42c NS |
7323 | else |
7324 | { | |
7325 | gcc_assert (operands[2] == constm1_rtx); | |
7326 | return "dec{w}\t%0"; | |
7327 | } | |
7c802a40 | 7328 | |
e075ae69 RH |
7329 | default: |
7330 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7331 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7332 | if (CONST_INT_P (operands[2]) |
e075ae69 RH |
7333 | && (INTVAL (operands[2]) == 128 |
7334 | || (INTVAL (operands[2]) < 0 | |
7335 | && INTVAL (operands[2]) != -128))) | |
7336 | { | |
7337 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7338 | return "sub{w}\t{%2, %0|%0, %2}"; |
e075ae69 | 7339 | } |
0f40f9f7 | 7340 | return "add{w}\t{%2, %0|%0, %2}"; |
7c802a40 | 7341 | } |
0f40f9f7 | 7342 | } |
e075ae69 RH |
7343 | [(set (attr "type") |
7344 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
7345 | (const_string "incdec") | |
6ef67412 | 7346 | (const_string "alu"))) |
a952487c JJ |
7347 | (set (attr "length_immediate") |
7348 | (if_then_else | |
7349 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7350 | (const_string "1") | |
7351 | (const_string "*"))) | |
6ef67412 | 7352 | (set_attr "mode" "HI")]) |
7c802a40 | 7353 | |
e075ae69 | 7354 | (define_insn "*addhi_2" |
42fabf21 | 7355 | [(set (reg FLAGS_REG) |
16189740 | 7356 | (compare |
e075ae69 | 7357 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") |
0edb82cb | 7358 | (match_operand:HI 2 "general_operand" "rmn,rn")) |
6300f037 | 7359 | (const_int 0))) |
e075ae69 RH |
7360 | (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") |
7361 | (plus:HI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 7362 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 7363 | && ix86_binary_operator_ok (PLUS, HImode, operands)" |
e075ae69 RH |
7364 | { |
7365 | switch (get_attr_type (insn)) | |
b980bec0 | 7366 | { |
e075ae69 RH |
7367 | case TYPE_INCDEC: |
7368 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7369 | return "inc{w}\t%0"; |
7637e42c NS |
7370 | else |
7371 | { | |
7372 | gcc_assert (operands[2] == constm1_rtx); | |
7373 | return "dec{w}\t%0"; | |
7374 | } | |
b980bec0 | 7375 | |
e075ae69 RH |
7376 | default: |
7377 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7378 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7379 | if (CONST_INT_P (operands[2]) |
e075ae69 RH |
7380 | && (INTVAL (operands[2]) == 128 |
7381 | || (INTVAL (operands[2]) < 0 | |
7382 | && INTVAL (operands[2]) != -128))) | |
7383 | { | |
7384 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7385 | return "sub{w}\t{%2, %0|%0, %2}"; |
e075ae69 | 7386 | } |
0f40f9f7 | 7387 | return "add{w}\t{%2, %0|%0, %2}"; |
b980bec0 | 7388 | } |
0f40f9f7 | 7389 | } |
e075ae69 RH |
7390 | [(set (attr "type") |
7391 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
7392 | (const_string "incdec") | |
6ef67412 | 7393 | (const_string "alu"))) |
a952487c JJ |
7394 | (set (attr "length_immediate") |
7395 | (if_then_else | |
7396 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7397 | (const_string "1") | |
7398 | (const_string "*"))) | |
6ef67412 | 7399 | (set_attr "mode" "HI")]) |
e075ae69 RH |
7400 | |
7401 | (define_insn "*addhi_3" | |
42fabf21 | 7402 | [(set (reg FLAGS_REG) |
0edb82cb | 7403 | (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn")) |
7e08e190 | 7404 | (match_operand:HI 1 "nonimmediate_operand" "%0"))) |
d90ffc8d | 7405 | (clobber (match_scratch:HI 0 "=r"))] |
7e08e190 | 7406 | "ix86_match_ccmode (insn, CCZmode) |
7656aee4 | 7407 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
d90ffc8d JH |
7408 | { |
7409 | switch (get_attr_type (insn)) | |
7410 | { | |
7411 | case TYPE_INCDEC: | |
7412 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7413 | return "inc{w}\t%0"; |
7637e42c NS |
7414 | else |
7415 | { | |
7416 | gcc_assert (operands[2] == constm1_rtx); | |
7417 | return "dec{w}\t%0"; | |
7418 | } | |
d90ffc8d JH |
7419 | |
7420 | default: | |
7421 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7422 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7423 | if (CONST_INT_P (operands[2]) |
d90ffc8d JH |
7424 | && (INTVAL (operands[2]) == 128 |
7425 | || (INTVAL (operands[2]) < 0 | |
7426 | && INTVAL (operands[2]) != -128))) | |
7427 | { | |
7428 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7429 | return "sub{w}\t{%2, %0|%0, %2}"; |
d90ffc8d | 7430 | } |
0f40f9f7 | 7431 | return "add{w}\t{%2, %0|%0, %2}"; |
d90ffc8d | 7432 | } |
0f40f9f7 | 7433 | } |
d90ffc8d JH |
7434 | [(set (attr "type") |
7435 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
7436 | (const_string "incdec") | |
7437 | (const_string "alu"))) | |
a952487c JJ |
7438 | (set (attr "length_immediate") |
7439 | (if_then_else | |
7440 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7441 | (const_string "1") | |
7442 | (const_string "*"))) | |
d90ffc8d JH |
7443 | (set_attr "mode" "HI")]) |
7444 | ||
d1c9ce9f | 7445 | ; See comments above addsi_4 for details. |
d90ffc8d | 7446 | (define_insn "*addhi_4" |
42fabf21 | 7447 | [(set (reg FLAGS_REG) |
7e08e190 JH |
7448 | (compare (match_operand:HI 1 "nonimmediate_operand" "0") |
7449 | (match_operand:HI 2 "const_int_operand" "n"))) | |
7450 | (clobber (match_scratch:HI 0 "=rm"))] | |
7451 | "ix86_match_ccmode (insn, CCGCmode) | |
7452 | && (INTVAL (operands[2]) & 0xffff) != 0x8000" | |
7e08e190 JH |
7453 | { |
7454 | switch (get_attr_type (insn)) | |
7455 | { | |
7456 | case TYPE_INCDEC: | |
2f41793e | 7457 | if (operands[2] == constm1_rtx) |
0f40f9f7 | 7458 | return "inc{w}\t%0"; |
7e08e190 | 7459 | else |
7637e42c NS |
7460 | { |
7461 | gcc_assert (operands[2] == const1_rtx); | |
7462 | return "dec{w}\t%0"; | |
7463 | } | |
7e08e190 JH |
7464 | |
7465 | default: | |
7637e42c | 7466 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
7e08e190 JH |
7467 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. |
7468 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7469 | if ((INTVAL (operands[2]) == -128 | |
7470 | || (INTVAL (operands[2]) > 0 | |
7471 | && INTVAL (operands[2]) != 128))) | |
0f40f9f7 | 7472 | return "sub{w}\t{%2, %0|%0, %2}"; |
7e08e190 | 7473 | operands[2] = GEN_INT (-INTVAL (operands[2])); |
0f40f9f7 | 7474 | return "add{w}\t{%2, %0|%0, %2}"; |
7e08e190 | 7475 | } |
0f40f9f7 | 7476 | } |
7e08e190 JH |
7477 | [(set (attr "type") |
7478 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
7479 | (const_string "incdec") | |
7480 | (const_string "alu"))) | |
93cac287 JJ |
7481 | (set (attr "length_immediate") |
7482 | (if_then_else | |
725fd454 | 7483 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) |
93cac287 JJ |
7484 | (const_string "1") |
7485 | (const_string "*"))) | |
725fd454 | 7486 | (set_attr "mode" "HI")]) |
b980bec0 | 7487 | |
d90ffc8d | 7488 | |
7e08e190 | 7489 | (define_insn "*addhi_5" |
42fabf21 | 7490 | [(set (reg FLAGS_REG) |
9076b9c1 JH |
7491 | (compare |
7492 | (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") | |
0edb82cb | 7493 | (match_operand:HI 2 "general_operand" "rmn")) |
6300f037 | 7494 | (const_int 0))) |
9076b9c1 JH |
7495 | (clobber (match_scratch:HI 0 "=r"))] |
7496 | "ix86_match_ccmode (insn, CCGOCmode) | |
7656aee4 | 7497 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
9076b9c1 JH |
7498 | { |
7499 | switch (get_attr_type (insn)) | |
7500 | { | |
7501 | case TYPE_INCDEC: | |
7502 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7503 | return "inc{w}\t%0"; |
7637e42c NS |
7504 | else |
7505 | { | |
7506 | gcc_assert (operands[2] == constm1_rtx); | |
7507 | return "dec{w}\t%0"; | |
7508 | } | |
9076b9c1 JH |
7509 | |
7510 | default: | |
7511 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7512 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7513 | if (CONST_INT_P (operands[2]) |
9076b9c1 JH |
7514 | && (INTVAL (operands[2]) == 128 |
7515 | || (INTVAL (operands[2]) < 0 | |
7516 | && INTVAL (operands[2]) != -128))) | |
7517 | { | |
7518 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7519 | return "sub{w}\t{%2, %0|%0, %2}"; |
9076b9c1 | 7520 | } |
0f40f9f7 | 7521 | return "add{w}\t{%2, %0|%0, %2}"; |
9076b9c1 | 7522 | } |
0f40f9f7 | 7523 | } |
9076b9c1 JH |
7524 | [(set (attr "type") |
7525 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
7526 | (const_string "incdec") | |
7527 | (const_string "alu"))) | |
a952487c JJ |
7528 | (set (attr "length_immediate") |
7529 | (if_then_else | |
7530 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7531 | (const_string "1") | |
7532 | (const_string "*"))) | |
9076b9c1 JH |
7533 | (set_attr "mode" "HI")]) |
7534 | ||
e075ae69 | 7535 | (define_expand "addqi3" |
7ae14d31 UB |
7536 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
7537 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7538 | (match_operand:QI 2 "general_operand" "")))] | |
d9f32422 | 7539 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
7540 | "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;") |
7541 | ||
7542 | ;; %%% Potential partial reg stall on alternative 2. What to do? | |
58787064 JH |
7543 | (define_insn "*addqi_1_lea" |
7544 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r") | |
7545 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r") | |
9a9286af | 7546 | (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln"))) |
8bc527af | 7547 | (clobber (reg:CC FLAGS_REG))] |
58787064 JH |
7548 | "!TARGET_PARTIAL_REG_STALL |
7549 | && ix86_binary_operator_ok (PLUS, QImode, operands)" | |
58787064 JH |
7550 | { |
7551 | int widen = (which_alternative == 2); | |
7552 | switch (get_attr_type (insn)) | |
7553 | { | |
7554 | case TYPE_LEA: | |
0f40f9f7 | 7555 | return "#"; |
58787064 JH |
7556 | case TYPE_INCDEC: |
7557 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7558 | return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; |
7637e42c NS |
7559 | else |
7560 | { | |
7561 | gcc_assert (operands[2] == constm1_rtx); | |
7562 | return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; | |
7563 | } | |
58787064 JH |
7564 | |
7565 | default: | |
7566 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7567 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7568 | if (CONST_INT_P (operands[2]) |
58787064 JH |
7569 | && (INTVAL (operands[2]) == 128 |
7570 | || (INTVAL (operands[2]) < 0 | |
7571 | && INTVAL (operands[2]) != -128))) | |
7572 | { | |
7573 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
7574 | if (widen) | |
0f40f9f7 | 7575 | return "sub{l}\t{%2, %k0|%k0, %2}"; |
58787064 | 7576 | else |
0f40f9f7 | 7577 | return "sub{b}\t{%2, %0|%0, %2}"; |
58787064 JH |
7578 | } |
7579 | if (widen) | |
0f40f9f7 | 7580 | return "add{l}\t{%k2, %k0|%k0, %k2}"; |
58787064 | 7581 | else |
0f40f9f7 | 7582 | return "add{b}\t{%2, %0|%0, %2}"; |
58787064 | 7583 | } |
0f40f9f7 | 7584 | } |
58787064 JH |
7585 | [(set (attr "type") |
7586 | (if_then_else (eq_attr "alternative" "3") | |
7587 | (const_string "lea") | |
adc88131 | 7588 | (if_then_else (match_operand:QI 2 "incdec_operand" "") |
58787064 JH |
7589 | (const_string "incdec") |
7590 | (const_string "alu")))) | |
a952487c JJ |
7591 | (set (attr "length_immediate") |
7592 | (if_then_else | |
7593 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7594 | (const_string "1") | |
7595 | (const_string "*"))) | |
adc88131 | 7596 | (set_attr "mode" "QI,QI,SI,SI")]) |
58787064 | 7597 | |
e075ae69 | 7598 | (define_insn "*addqi_1" |
7c6b971d | 7599 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") |
e075ae69 | 7600 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
7c6b971d | 7601 | (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) |
8bc527af | 7602 | (clobber (reg:CC FLAGS_REG))] |
58787064 JH |
7603 | "TARGET_PARTIAL_REG_STALL |
7604 | && ix86_binary_operator_ok (PLUS, QImode, operands)" | |
e075ae69 RH |
7605 | { |
7606 | int widen = (which_alternative == 2); | |
7607 | switch (get_attr_type (insn)) | |
5bc7cd8e | 7608 | { |
e075ae69 RH |
7609 | case TYPE_INCDEC: |
7610 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7611 | return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; |
7637e42c NS |
7612 | else |
7613 | { | |
7614 | gcc_assert (operands[2] == constm1_rtx); | |
7615 | return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; | |
7616 | } | |
5bc7cd8e | 7617 | |
e075ae69 RH |
7618 | default: |
7619 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. | |
7620 | Exceptions: -128 encodes smaller than 128, so swap sign and op. */ | |
7656aee4 | 7621 | if (CONST_INT_P (operands[2]) |
e075ae69 RH |
7622 | && (INTVAL (operands[2]) == 128 |
7623 | || (INTVAL (operands[2]) < 0 | |
7624 | && INTVAL (operands[2]) != -128))) | |
5bc7cd8e | 7625 | { |
e075ae69 RH |
7626 | operands[2] = GEN_INT (-INTVAL (operands[2])); |
7627 | if (widen) | |
0f40f9f7 | 7628 | return "sub{l}\t{%2, %k0|%k0, %2}"; |
e075ae69 | 7629 | else |
0f40f9f7 | 7630 | return "sub{b}\t{%2, %0|%0, %2}"; |
5bc7cd8e | 7631 | } |
e075ae69 | 7632 | if (widen) |
0f40f9f7 | 7633 | return "add{l}\t{%k2, %k0|%k0, %k2}"; |
e075ae69 | 7634 | else |
0f40f9f7 | 7635 | return "add{b}\t{%2, %0|%0, %2}"; |
5bc7cd8e | 7636 | } |
0f40f9f7 | 7637 | } |
e075ae69 RH |
7638 | [(set (attr "type") |
7639 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
7640 | (const_string "incdec") | |
6ef67412 | 7641 | (const_string "alu"))) |
a952487c JJ |
7642 | (set (attr "length_immediate") |
7643 | (if_then_else | |
7644 | (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) | |
7645 | (const_string "1") | |
7646 | (const_string "*"))) | |
6ef67412 | 7647 | (set_attr "mode" "QI,QI,SI")]) |
e075ae69 | 7648 | |
2f41793e JH |
7649 | (define_insn "*addqi_1_slp" |
7650 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) | |
1b245ade JH |
7651 | (plus:QI (match_dup 0) |
7652 | (match_operand:QI 1 "general_operand" "qn,qnm"))) | |
8bc527af | 7653 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 7654 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 7655 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
2f41793e JH |
7656 | { |
7657 | switch (get_attr_type (insn)) | |
7658 | { | |
7659 | case TYPE_INCDEC: | |
95199202 | 7660 | if (operands[1] == const1_rtx) |
2f41793e | 7661 | return "inc{b}\t%0"; |
7637e42c NS |
7662 | else |
7663 | { | |
7664 | gcc_assert (operands[1] == constm1_rtx); | |
7665 | return "dec{b}\t%0"; | |
7666 | } | |
2f41793e JH |
7667 | |
7668 | default: | |
7669 | /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */ | |
7656aee4 | 7670 | if (CONST_INT_P (operands[1]) |
95199202 | 7671 | && INTVAL (operands[1]) < 0) |
2f41793e | 7672 | { |
79551a56 | 7673 | operands[1] = GEN_INT (-INTVAL (operands[1])); |
1b245ade | 7674 | return "sub{b}\t{%1, %0|%0, %1}"; |
2f41793e | 7675 | } |
1b245ade | 7676 | return "add{b}\t{%1, %0|%0, %1}"; |
2f41793e JH |
7677 | } |
7678 | } | |
7679 | [(set (attr "type") | |
ba3ed8d8 | 7680 | (if_then_else (match_operand:QI 1 "incdec_operand" "") |
2f41793e | 7681 | (const_string "incdec") |
95199202 | 7682 | (const_string "alu1"))) |
ebc0c8bb JJ |
7683 | (set (attr "memory") |
7684 | (if_then_else (match_operand 1 "memory_operand" "") | |
7685 | (const_string "load") | |
7686 | (const_string "none"))) | |
2f41793e JH |
7687 | (set_attr "mode" "QI")]) |
7688 | ||
e075ae69 | 7689 | (define_insn "*addqi_2" |
42fabf21 | 7690 | [(set (reg FLAGS_REG) |
16189740 | 7691 | (compare |
e075ae69 | 7692 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") |
0edb82cb | 7693 | (match_operand:QI 2 "general_operand" "qmn,qn")) |
e075ae69 RH |
7694 | (const_int 0))) |
7695 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") | |
7696 | (plus:QI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 7697 | "ix86_match_ccmode (insn, CCGOCmode) |
16189740 | 7698 | && ix86_binary_operator_ok (PLUS, QImode, operands)" |
e075ae69 RH |
7699 | { |
7700 | switch (get_attr_type (insn)) | |
7701 | { | |
7702 | case TYPE_INCDEC: | |
7703 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7704 | return "inc{b}\t%0"; |
7637e42c NS |
7705 | else |
7706 | { | |
7707 | gcc_assert (operands[2] == constm1_rtx | |
7656aee4 | 7708 | || (CONST_INT_P (operands[2]) |
7637e42c NS |
7709 | && INTVAL (operands[2]) == 255)); |
7710 | return "dec{b}\t%0"; | |
7711 | } | |
5bc7cd8e | 7712 | |
e075ae69 RH |
7713 | default: |
7714 | /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ | |
7656aee4 | 7715 | if (CONST_INT_P (operands[2]) |
e075ae69 RH |
7716 | && INTVAL (operands[2]) < 0) |
7717 | { | |
7718 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7719 | return "sub{b}\t{%2, %0|%0, %2}"; |
e075ae69 | 7720 | } |
0f40f9f7 | 7721 | return "add{b}\t{%2, %0|%0, %2}"; |
e075ae69 | 7722 | } |
0f40f9f7 | 7723 | } |
e075ae69 RH |
7724 | [(set (attr "type") |
7725 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
7726 | (const_string "incdec") | |
6ef67412 JH |
7727 | (const_string "alu"))) |
7728 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
7729 | |
7730 | (define_insn "*addqi_3" | |
42fabf21 | 7731 | [(set (reg FLAGS_REG) |
0edb82cb | 7732 | (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn")) |
7e08e190 JH |
7733 | (match_operand:QI 1 "nonimmediate_operand" "%0"))) |
7734 | (clobber (match_scratch:QI 0 "=q"))] | |
7735 | "ix86_match_ccmode (insn, CCZmode) | |
7656aee4 | 7736 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
d90ffc8d JH |
7737 | { |
7738 | switch (get_attr_type (insn)) | |
7739 | { | |
7740 | case TYPE_INCDEC: | |
7741 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7742 | return "inc{b}\t%0"; |
7637e42c NS |
7743 | else |
7744 | { | |
7745 | gcc_assert (operands[2] == constm1_rtx | |
7656aee4 | 7746 | || (CONST_INT_P (operands[2]) |
7637e42c NS |
7747 | && INTVAL (operands[2]) == 255)); |
7748 | return "dec{b}\t%0"; | |
7749 | } | |
d90ffc8d JH |
7750 | |
7751 | default: | |
7752 | /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ | |
7656aee4 | 7753 | if (CONST_INT_P (operands[2]) |
d90ffc8d JH |
7754 | && INTVAL (operands[2]) < 0) |
7755 | { | |
7756 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7757 | return "sub{b}\t{%2, %0|%0, %2}"; |
d90ffc8d | 7758 | } |
0f40f9f7 | 7759 | return "add{b}\t{%2, %0|%0, %2}"; |
d90ffc8d | 7760 | } |
0f40f9f7 | 7761 | } |
d90ffc8d JH |
7762 | [(set (attr "type") |
7763 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
7764 | (const_string "incdec") | |
7765 | (const_string "alu"))) | |
7766 | (set_attr "mode" "QI")]) | |
7767 | ||
d1c9ce9f | 7768 | ; See comments above addsi_4 for details. |
d90ffc8d | 7769 | (define_insn "*addqi_4" |
42fabf21 | 7770 | [(set (reg FLAGS_REG) |
7e08e190 JH |
7771 | (compare (match_operand:QI 1 "nonimmediate_operand" "0") |
7772 | (match_operand:QI 2 "const_int_operand" "n"))) | |
7773 | (clobber (match_scratch:QI 0 "=qm"))] | |
7774 | "ix86_match_ccmode (insn, CCGCmode) | |
7775 | && (INTVAL (operands[2]) & 0xff) != 0x80" | |
7e08e190 JH |
7776 | { |
7777 | switch (get_attr_type (insn)) | |
7778 | { | |
7779 | case TYPE_INCDEC: | |
7780 | if (operands[2] == constm1_rtx | |
7656aee4 | 7781 | || (CONST_INT_P (operands[2]) |
7e08e190 | 7782 | && INTVAL (operands[2]) == 255)) |
0f40f9f7 | 7783 | return "inc{b}\t%0"; |
7e08e190 | 7784 | else |
7637e42c NS |
7785 | { |
7786 | gcc_assert (operands[2] == const1_rtx); | |
7787 | return "dec{b}\t%0"; | |
7788 | } | |
7e08e190 JH |
7789 | |
7790 | default: | |
7637e42c | 7791 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
7e08e190 JH |
7792 | if (INTVAL (operands[2]) < 0) |
7793 | { | |
7794 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7795 | return "add{b}\t{%2, %0|%0, %2}"; |
7e08e190 | 7796 | } |
0f40f9f7 | 7797 | return "sub{b}\t{%2, %0|%0, %2}"; |
7e08e190 | 7798 | } |
0f40f9f7 | 7799 | } |
7e08e190 JH |
7800 | [(set (attr "type") |
7801 | (if_then_else (match_operand:HI 2 "incdec_operand" "") | |
7802 | (const_string "incdec") | |
7803 | (const_string "alu"))) | |
6ef67412 | 7804 | (set_attr "mode" "QI")]) |
886c62d1 | 7805 | |
9dcbdc7e | 7806 | |
d90ffc8d | 7807 | (define_insn "*addqi_5" |
42fabf21 | 7808 | [(set (reg FLAGS_REG) |
9076b9c1 JH |
7809 | (compare |
7810 | (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") | |
0edb82cb | 7811 | (match_operand:QI 2 "general_operand" "qmn")) |
9076b9c1 | 7812 | (const_int 0))) |
7e08e190 | 7813 | (clobber (match_scratch:QI 0 "=q"))] |
9076b9c1 | 7814 | "ix86_match_ccmode (insn, CCGOCmode) |
7656aee4 | 7815 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
9076b9c1 JH |
7816 | { |
7817 | switch (get_attr_type (insn)) | |
7818 | { | |
7819 | case TYPE_INCDEC: | |
7820 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7821 | return "inc{b}\t%0"; |
7637e42c NS |
7822 | else |
7823 | { | |
7824 | gcc_assert (operands[2] == constm1_rtx | |
7656aee4 | 7825 | || (CONST_INT_P (operands[2]) |
7637e42c NS |
7826 | && INTVAL (operands[2]) == 255)); |
7827 | return "dec{b}\t%0"; | |
7828 | } | |
9076b9c1 JH |
7829 | |
7830 | default: | |
7831 | /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ | |
7656aee4 | 7832 | if (CONST_INT_P (operands[2]) |
9076b9c1 JH |
7833 | && INTVAL (operands[2]) < 0) |
7834 | { | |
7835 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 7836 | return "sub{b}\t{%2, %0|%0, %2}"; |
9076b9c1 | 7837 | } |
0f40f9f7 | 7838 | return "add{b}\t{%2, %0|%0, %2}"; |
9076b9c1 | 7839 | } |
0f40f9f7 | 7840 | } |
9076b9c1 JH |
7841 | [(set (attr "type") |
7842 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
7843 | (const_string "incdec") | |
7844 | (const_string "alu"))) | |
7845 | (set_attr "mode" "QI")]) | |
7846 | ||
e075ae69 RH |
7847 | |
7848 | (define_insn "addqi_ext_1" | |
3522082b | 7849 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
7850 | (const_int 8) |
7851 | (const_int 8)) | |
7852 | (plus:SI | |
7853 | (zero_extract:SI | |
7854 | (match_operand 1 "ext_register_operand" "0") | |
7855 | (const_int 8) | |
7856 | (const_int 8)) | |
3522082b | 7857 | (match_operand:QI 2 "general_operand" "Qmn"))) |
8bc527af | 7858 | (clobber (reg:CC FLAGS_REG))] |
d2836273 | 7859 | "!TARGET_64BIT" |
d2836273 JH |
7860 | { |
7861 | switch (get_attr_type (insn)) | |
7862 | { | |
7863 | case TYPE_INCDEC: | |
7864 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7865 | return "inc{b}\t%h0"; |
7637e42c NS |
7866 | else |
7867 | { | |
7868 | gcc_assert (operands[2] == constm1_rtx | |
7656aee4 | 7869 | || (CONST_INT_P (operands[2]) |
7637e42c NS |
7870 | && INTVAL (operands[2]) == 255)); |
7871 | return "dec{b}\t%h0"; | |
7872 | } | |
d2836273 JH |
7873 | |
7874 | default: | |
0f40f9f7 | 7875 | return "add{b}\t{%2, %h0|%h0, %2}"; |
d2836273 | 7876 | } |
0f40f9f7 | 7877 | } |
d2836273 JH |
7878 | [(set (attr "type") |
7879 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
7880 | (const_string "incdec") | |
7881 | (const_string "alu"))) | |
725fd454 | 7882 | (set_attr "modrm" "1") |
d2836273 JH |
7883 | (set_attr "mode" "QI")]) |
7884 | ||
7885 | (define_insn "*addqi_ext_1_rex64" | |
7886 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
7887 | (const_int 8) | |
7888 | (const_int 8)) | |
7889 | (plus:SI | |
7890 | (zero_extract:SI | |
7891 | (match_operand 1 "ext_register_operand" "0") | |
7892 | (const_int 8) | |
7893 | (const_int 8)) | |
7894 | (match_operand:QI 2 "nonmemory_operand" "Qn"))) | |
8bc527af | 7895 | (clobber (reg:CC FLAGS_REG))] |
d2836273 | 7896 | "TARGET_64BIT" |
e075ae69 RH |
7897 | { |
7898 | switch (get_attr_type (insn)) | |
7899 | { | |
7900 | case TYPE_INCDEC: | |
7901 | if (operands[2] == const1_rtx) | |
0f40f9f7 | 7902 | return "inc{b}\t%h0"; |
7637e42c NS |
7903 | else |
7904 | { | |
7905 | gcc_assert (operands[2] == constm1_rtx | |
7656aee4 | 7906 | || (CONST_INT_P (operands[2]) |
7637e42c NS |
7907 | && INTVAL (operands[2]) == 255)); |
7908 | return "dec{b}\t%h0"; | |
7909 | } | |
886c62d1 | 7910 | |
e075ae69 | 7911 | default: |
0f40f9f7 | 7912 | return "add{b}\t{%2, %h0|%h0, %2}"; |
e075ae69 | 7913 | } |
0f40f9f7 | 7914 | } |
e075ae69 RH |
7915 | [(set (attr "type") |
7916 | (if_then_else (match_operand:QI 2 "incdec_operand" "") | |
7917 | (const_string "incdec") | |
6ef67412 | 7918 | (const_string "alu"))) |
725fd454 | 7919 | (set_attr "modrm" "1") |
6ef67412 | 7920 | (set_attr "mode" "QI")]) |
e075ae69 RH |
7921 | |
7922 | (define_insn "*addqi_ext_2" | |
d2836273 | 7923 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
7924 | (const_int 8) |
7925 | (const_int 8)) | |
7926 | (plus:SI | |
7927 | (zero_extract:SI | |
7928 | (match_operand 1 "ext_register_operand" "%0") | |
7929 | (const_int 8) | |
7930 | (const_int 8)) | |
7931 | (zero_extract:SI | |
d2836273 | 7932 | (match_operand 2 "ext_register_operand" "Q") |
e075ae69 RH |
7933 | (const_int 8) |
7934 | (const_int 8)))) | |
8bc527af | 7935 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 7936 | "" |
0f40f9f7 | 7937 | "add{b}\t{%h2, %h0|%h0, %h2}" |
6ef67412 JH |
7938 | [(set_attr "type" "alu") |
7939 | (set_attr "mode" "QI")]) | |
886c62d1 | 7940 | |
886c62d1 JVA |
7941 | ;; The patterns that match these are at the end of this file. |
7942 | ||
4fb21e90 JVA |
7943 | (define_expand "addxf3" |
7944 | [(set (match_operand:XF 0 "register_operand" "") | |
2ae0f82c SC |
7945 | (plus:XF (match_operand:XF 1 "register_operand" "") |
7946 | (match_operand:XF 2 "register_operand" "")))] | |
2b589241 JH |
7947 | "TARGET_80387" |
7948 | "") | |
7949 | ||
00188daa UB |
7950 | (define_expand "add<mode>3" |
7951 | [(set (match_operand:MODEF 0 "register_operand" "") | |
7952 | (plus:MODEF (match_operand:MODEF 1 "register_operand" "") | |
7953 | (match_operand:MODEF 2 "nonimmediate_operand" "")))] | |
8ce94e44 JM |
7954 | "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) |
7955 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" | |
886c62d1 JVA |
7956 | "") |
7957 | \f | |
e075ae69 | 7958 | ;; Subtract instructions |
a269a03c | 7959 | |
28356f52 JB |
7960 | ;; %%% splits for subditi3 |
7961 | ||
7962 | (define_expand "subti3" | |
7ae14d31 UB |
7963 | [(set (match_operand:TI 0 "nonimmediate_operand" "") |
7964 | (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") | |
7965 | (match_operand:TI 2 "x86_64_general_operand" "")))] | |
28356f52 JB |
7966 | "TARGET_64BIT" |
7967 | "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;") | |
7968 | ||
7969 | (define_insn "*subti3_1" | |
7970 | [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") | |
7971 | (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0") | |
68b8830a | 7972 | (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) |
28356f52 JB |
7973 | (clobber (reg:CC FLAGS_REG))] |
7974 | "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)" | |
7975 | "#") | |
7976 | ||
7977 | (define_split | |
7978 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
7979 | (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") | |
68b8830a | 7980 | (match_operand:TI 2 "x86_64_general_operand" ""))) |
28356f52 JB |
7981 | (clobber (reg:CC FLAGS_REG))] |
7982 | "TARGET_64BIT && reload_completed" | |
7983 | [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) | |
7984 | (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))]) | |
7985 | (parallel [(set (match_dup 3) | |
7986 | (minus:DI (match_dup 4) | |
7987 | (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) | |
7988 | (match_dup 5)))) | |
7989 | (clobber (reg:CC FLAGS_REG))])] | |
c2b814b9 | 7990 | "split_ti (&operands[0], 3, &operands[0], &operands[3]);") |
28356f52 | 7991 | |
e075ae69 | 7992 | ;; %%% splits for subsidi3 |
2ae0f82c | 7993 | |
9b70259d | 7994 | (define_expand "subdi3" |
7ae14d31 UB |
7995 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
7996 | (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") | |
7997 | (match_operand:DI 2 "x86_64_general_operand" "")))] | |
9b70259d JH |
7998 | "" |
7999 | "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;") | |
8000 | ||
8001 | (define_insn "*subdi3_1" | |
e075ae69 | 8002 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") |
4cbfbb1b | 8003 | (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") |
e075ae69 | 8004 | (match_operand:DI 2 "general_operand" "roiF,riF"))) |
8bc527af | 8005 | (clobber (reg:CC FLAGS_REG))] |
43146684 | 8006 | "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" |
e075ae69 | 8007 | "#") |
9c530261 | 8008 | |
e075ae69 RH |
8009 | (define_split |
8010 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
4cbfbb1b | 8011 | (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") |
e075ae69 | 8012 | (match_operand:DI 2 "general_operand" ""))) |
8bc527af | 8013 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 8014 | "!TARGET_64BIT && reload_completed" |
8bc527af | 8015 | [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) |
e075ae69 RH |
8016 | (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) |
8017 | (parallel [(set (match_dup 3) | |
8018 | (minus:SI (match_dup 4) | |
8bc527af | 8019 | (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) |
9dcbdc7e | 8020 | (match_dup 5)))) |
8bc527af | 8021 | (clobber (reg:CC FLAGS_REG))])] |
c2b814b9 | 8022 | "split_di (&operands[0], 3, &operands[0], &operands[3]);") |
e075ae69 | 8023 | |
9b70259d JH |
8024 | (define_insn "subdi3_carry_rex64" |
8025 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") | |
8026 | (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") | |
9b74f3ea | 8027 | (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") |
9b70259d | 8028 | (match_operand:DI 2 "x86_64_general_operand" "re,rm")))) |
8bc527af | 8029 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 8030 | "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" |
0f40f9f7 | 8031 | "sbb{q}\t{%2, %0|%0, %2}" |
9b70259d | 8032 | [(set_attr "type" "alu") |
b6837b94 | 8033 | (set_attr "use_carry" "1") |
9b70259d | 8034 | (set_attr "pent_pair" "pu") |
9b70259d JH |
8035 | (set_attr "mode" "DI")]) |
8036 | ||
8037 | (define_insn "*subdi_1_rex64" | |
8038 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") | |
8039 | (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") | |
8040 | (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) | |
8bc527af | 8041 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 8042 | "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" |
0f40f9f7 | 8043 | "sub{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
8044 | [(set_attr "type" "alu") |
8045 | (set_attr "mode" "DI")]) | |
8046 | ||
8047 | (define_insn "*subdi_2_rex64" | |
42fabf21 | 8048 | [(set (reg FLAGS_REG) |
9b70259d JH |
8049 | (compare |
8050 | (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") | |
8051 | (match_operand:DI 2 "x86_64_general_operand" "re,rm")) | |
8052 | (const_int 0))) | |
8053 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") | |
8054 | (minus:DI (match_dup 1) (match_dup 2)))] | |
8055 | "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) | |
8056 | && ix86_binary_operator_ok (MINUS, DImode, operands)" | |
0f40f9f7 | 8057 | "sub{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
8058 | [(set_attr "type" "alu") |
8059 | (set_attr "mode" "DI")]) | |
8060 | ||
8061 | (define_insn "*subdi_3_rex63" | |
42fabf21 | 8062 | [(set (reg FLAGS_REG) |
9b70259d JH |
8063 | (compare (match_operand:DI 1 "nonimmediate_operand" "0,0") |
8064 | (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) | |
8065 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") | |
8066 | (minus:DI (match_dup 1) (match_dup 2)))] | |
8067 | "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) | |
8068 | && ix86_binary_operator_ok (MINUS, SImode, operands)" | |
0f40f9f7 | 8069 | "sub{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
8070 | [(set_attr "type" "alu") |
8071 | (set_attr "mode" "DI")]) | |
8072 | ||
7b52eede | 8073 | (define_insn "subqi3_carry" |
d67e96cf | 8074 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") |
7b52eede | 8075 | (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") |
e6e81735 | 8076 | (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") |
0edb82cb | 8077 | (match_operand:QI 2 "general_operand" "qn,qm")))) |
8bc527af | 8078 | (clobber (reg:CC FLAGS_REG))] |
7b52eede JH |
8079 | "ix86_binary_operator_ok (MINUS, QImode, operands)" |
8080 | "sbb{b}\t{%2, %0|%0, %2}" | |
8081 | [(set_attr "type" "alu") | |
b6837b94 | 8082 | (set_attr "use_carry" "1") |
7b52eede | 8083 | (set_attr "pent_pair" "pu") |
7b52eede JH |
8084 | (set_attr "mode" "QI")]) |
8085 | ||
8086 | (define_insn "subhi3_carry" | |
8087 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
8088 | (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
e6e81735 | 8089 | (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") |
0edb82cb | 8090 | (match_operand:HI 2 "general_operand" "rn,rm")))) |
8bc527af | 8091 | (clobber (reg:CC FLAGS_REG))] |
7b52eede JH |
8092 | "ix86_binary_operator_ok (MINUS, HImode, operands)" |
8093 | "sbb{w}\t{%2, %0|%0, %2}" | |
8094 | [(set_attr "type" "alu") | |
b6837b94 | 8095 | (set_attr "use_carry" "1") |
7b52eede | 8096 | (set_attr "pent_pair" "pu") |
7b52eede | 8097 | (set_attr "mode" "HI")]) |
9b70259d | 8098 | |
7e08e190 | 8099 | (define_insn "subsi3_carry" |
e075ae69 RH |
8100 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
8101 | (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
e6e81735 | 8102 | (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") |
9dcbdc7e | 8103 | (match_operand:SI 2 "general_operand" "ri,rm")))) |
8bc527af | 8104 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 8105 | "ix86_binary_operator_ok (MINUS, SImode, operands)" |
0f40f9f7 | 8106 | "sbb{l}\t{%2, %0|%0, %2}" |
e075ae69 | 8107 | [(set_attr "type" "alu") |
b6837b94 | 8108 | (set_attr "use_carry" "1") |
e075ae69 | 8109 | (set_attr "pent_pair" "pu") |
6ef67412 | 8110 | (set_attr "mode" "SI")]) |
886c62d1 | 8111 | |
9b70259d | 8112 | (define_insn "subsi3_carry_zext" |
a6783d12 | 8113 | [(set (match_operand:DI 0 "register_operand" "=r") |
9b70259d | 8114 | (zero_extend:DI |
a6783d12 | 8115 | (minus:SI (match_operand:SI 1 "register_operand" "0") |
e6e81735 | 8116 | (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") |
73f48658 | 8117 | (match_operand:SI 2 "general_operand" "g"))))) |
8bc527af | 8118 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 8119 | "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" |
0f40f9f7 | 8120 | "sbb{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
8121 | [(set_attr "type" "alu") |
8122 | (set_attr "pent_pair" "pu") | |
9b70259d JH |
8123 | (set_attr "mode" "SI")]) |
8124 | ||
2ae0f82c | 8125 | (define_expand "subsi3" |
7ae14d31 UB |
8126 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
8127 | (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
8128 | (match_operand:SI 2 "general_operand" "")))] | |
886c62d1 | 8129 | "" |
e075ae69 | 8130 | "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;") |
2ae0f82c | 8131 | |
e075ae69 | 8132 | (define_insn "*subsi_1" |
2ae0f82c SC |
8133 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
8134 | (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
e075ae69 | 8135 | (match_operand:SI 2 "general_operand" "ri,rm"))) |
8bc527af | 8136 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 8137 | "ix86_binary_operator_ok (MINUS, SImode, operands)" |
0f40f9f7 | 8138 | "sub{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
8139 | [(set_attr "type" "alu") |
8140 | (set_attr "mode" "SI")]) | |
e075ae69 | 8141 | |
9b70259d JH |
8142 | (define_insn "*subsi_1_zext" |
8143 | [(set (match_operand:DI 0 "register_operand" "=r") | |
8144 | (zero_extend:DI | |
8145 | (minus:SI (match_operand:SI 1 "register_operand" "0") | |
73f48658 | 8146 | (match_operand:SI 2 "general_operand" "g")))) |
8bc527af | 8147 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 8148 | "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" |
0f40f9f7 | 8149 | "sub{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
8150 | [(set_attr "type" "alu") |
8151 | (set_attr "mode" "SI")]) | |
8152 | ||
e075ae69 | 8153 | (define_insn "*subsi_2" |
42fabf21 | 8154 | [(set (reg FLAGS_REG) |
16189740 | 8155 | (compare |
e075ae69 RH |
8156 | (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") |
8157 | (match_operand:SI 2 "general_operand" "ri,rm")) | |
8158 | (const_int 0))) | |
8159 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
8160 | (minus:SI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 8161 | "ix86_match_ccmode (insn, CCGOCmode) |
d90ffc8d | 8162 | && ix86_binary_operator_ok (MINUS, SImode, operands)" |
0f40f9f7 | 8163 | "sub{l}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
8164 | [(set_attr "type" "alu") |
8165 | (set_attr "mode" "SI")]) | |
8166 | ||
9b70259d | 8167 | (define_insn "*subsi_2_zext" |
42fabf21 | 8168 | [(set (reg FLAGS_REG) |
9b70259d JH |
8169 | (compare |
8170 | (minus:SI (match_operand:SI 1 "register_operand" "0") | |
73f48658 | 8171 | (match_operand:SI 2 "general_operand" "g")) |
9b70259d JH |
8172 | (const_int 0))) |
8173 | (set (match_operand:DI 0 "register_operand" "=r") | |
8174 | (zero_extend:DI | |
8175 | (minus:SI (match_dup 1) | |
8176 | (match_dup 2))))] | |
8177 | "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) | |
8178 | && ix86_binary_operator_ok (MINUS, SImode, operands)" | |
0f40f9f7 | 8179 | "sub{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
8180 | [(set_attr "type" "alu") |
8181 | (set_attr "mode" "SI")]) | |
8182 | ||
d90ffc8d | 8183 | (define_insn "*subsi_3" |
42fabf21 | 8184 | [(set (reg FLAGS_REG) |
d90ffc8d JH |
8185 | (compare (match_operand:SI 1 "nonimmediate_operand" "0,0") |
8186 | (match_operand:SI 2 "general_operand" "ri,rm"))) | |
8187 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
8188 | (minus:SI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
8189 | "ix86_match_ccmode (insn, CCmode) |
8190 | && ix86_binary_operator_ok (MINUS, SImode, operands)" | |
0f40f9f7 | 8191 | "sub{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
8192 | [(set_attr "type" "alu") |
8193 | (set_attr "mode" "SI")]) | |
886c62d1 | 8194 | |
9b70259d | 8195 | (define_insn "*subsi_3_zext" |
42fabf21 | 8196 | [(set (reg FLAGS_REG) |
10e9fecc | 8197 | (compare (match_operand:SI 1 "register_operand" "0") |
73f48658 | 8198 | (match_operand:SI 2 "general_operand" "g"))) |
9b70259d JH |
8199 | (set (match_operand:DI 0 "register_operand" "=r") |
8200 | (zero_extend:DI | |
8201 | (minus:SI (match_dup 1) | |
8202 | (match_dup 2))))] | |
8362f420 | 8203 | "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) |
9b70259d | 8204 | && ix86_binary_operator_ok (MINUS, SImode, operands)" |
3dcdd4e4 | 8205 | "sub{l}\t{%2, %1|%1, %2}" |
9b70259d JH |
8206 | [(set_attr "type" "alu") |
8207 | (set_attr "mode" "DI")]) | |
8208 | ||
2ae0f82c | 8209 | (define_expand "subhi3" |
7ae14d31 UB |
8210 | [(set (match_operand:HI 0 "nonimmediate_operand" "") |
8211 | (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
8212 | (match_operand:HI 2 "general_operand" "")))] | |
d9f32422 | 8213 | "TARGET_HIMODE_MATH" |
e075ae69 | 8214 | "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;") |
2ae0f82c | 8215 | |
e075ae69 | 8216 | (define_insn "*subhi_1" |
2ae0f82c | 8217 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") |
87fd1847 | 8218 | (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") |
0edb82cb | 8219 | (match_operand:HI 2 "general_operand" "rn,rm"))) |
8bc527af | 8220 | (clobber (reg:CC FLAGS_REG))] |
2ae0f82c | 8221 | "ix86_binary_operator_ok (MINUS, HImode, operands)" |
0f40f9f7 | 8222 | "sub{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
8223 | [(set_attr "type" "alu") |
8224 | (set_attr "mode" "HI")]) | |
e075ae69 RH |
8225 | |
8226 | (define_insn "*subhi_2" | |
42fabf21 | 8227 | [(set (reg FLAGS_REG) |
16189740 | 8228 | (compare |
e075ae69 | 8229 | (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") |
0edb82cb | 8230 | (match_operand:HI 2 "general_operand" "rn,rm")) |
e075ae69 RH |
8231 | (const_int 0))) |
8232 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
8233 | (minus:HI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 8234 | "ix86_match_ccmode (insn, CCGOCmode) |
d90ffc8d | 8235 | && ix86_binary_operator_ok (MINUS, HImode, operands)" |
0f40f9f7 | 8236 | "sub{w}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
8237 | [(set_attr "type" "alu") |
8238 | (set_attr "mode" "HI")]) | |
8239 | ||
8240 | (define_insn "*subhi_3" | |
42fabf21 | 8241 | [(set (reg FLAGS_REG) |
d90ffc8d | 8242 | (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") |
0edb82cb | 8243 | (match_operand:HI 2 "general_operand" "rn,rm"))) |
d90ffc8d JH |
8244 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") |
8245 | (minus:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
8246 | "ix86_match_ccmode (insn, CCmode) |
8247 | && ix86_binary_operator_ok (MINUS, HImode, operands)" | |
0f40f9f7 | 8248 | "sub{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
8249 | [(set_attr "type" "alu") |
8250 | (set_attr "mode" "HI")]) | |
886c62d1 | 8251 | |
2ae0f82c | 8252 | (define_expand "subqi3" |
7ae14d31 UB |
8253 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
8254 | (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
8255 | (match_operand:QI 2 "general_operand" "")))] | |
d9f32422 | 8256 | "TARGET_QIMODE_MATH" |
e075ae69 | 8257 | "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;") |
2ae0f82c | 8258 | |
e075ae69 | 8259 | (define_insn "*subqi_1" |
2ae0f82c SC |
8260 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") |
8261 | (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
0edb82cb | 8262 | (match_operand:QI 2 "general_operand" "qn,qm"))) |
8bc527af | 8263 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 8264 | "ix86_binary_operator_ok (MINUS, QImode, operands)" |
0f40f9f7 | 8265 | "sub{b}\t{%2, %0|%0, %2}" |
6ef67412 JH |
8266 | [(set_attr "type" "alu") |
8267 | (set_attr "mode" "QI")]) | |
e075ae69 | 8268 | |
2f41793e JH |
8269 | (define_insn "*subqi_1_slp" |
8270 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) | |
1b245ade | 8271 | (minus:QI (match_dup 0) |
0edb82cb | 8272 | (match_operand:QI 1 "general_operand" "qn,qm"))) |
8bc527af | 8273 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 8274 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 8275 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
1b245ade | 8276 | "sub{b}\t{%1, %0|%0, %1}" |
95199202 | 8277 | [(set_attr "type" "alu1") |
2f41793e JH |
8278 | (set_attr "mode" "QI")]) |
8279 | ||
e075ae69 | 8280 | (define_insn "*subqi_2" |
42fabf21 | 8281 | [(set (reg FLAGS_REG) |
16189740 | 8282 | (compare |
e075ae69 | 8283 | (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") |
0edb82cb | 8284 | (match_operand:QI 2 "general_operand" "qn,qm")) |
e075ae69 | 8285 | (const_int 0))) |
0edb82cb UB |
8286 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") |
8287 | (minus:QI (match_dup 1) (match_dup 2)))] | |
9076b9c1 | 8288 | "ix86_match_ccmode (insn, CCGOCmode) |
d90ffc8d | 8289 | && ix86_binary_operator_ok (MINUS, QImode, operands)" |
0f40f9f7 | 8290 | "sub{b}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
8291 | [(set_attr "type" "alu") |
8292 | (set_attr "mode" "QI")]) | |
8293 | ||
8294 | (define_insn "*subqi_3" | |
42fabf21 | 8295 | [(set (reg FLAGS_REG) |
d90ffc8d | 8296 | (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") |
0edb82cb UB |
8297 | (match_operand:QI 2 "general_operand" "qn,qm"))) |
8298 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") | |
8299 | (minus:QI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
8300 | "ix86_match_ccmode (insn, CCmode) |
8301 | && ix86_binary_operator_ok (MINUS, QImode, operands)" | |
0f40f9f7 | 8302 | "sub{b}\t{%2, %0|%0, %2}" |
6ef67412 JH |
8303 | [(set_attr "type" "alu") |
8304 | (set_attr "mode" "QI")]) | |
2ae0f82c | 8305 | |
886c62d1 JVA |
8306 | ;; The patterns that match these are at the end of this file. |
8307 | ||
4fb21e90 JVA |
8308 | (define_expand "subxf3" |
8309 | [(set (match_operand:XF 0 "register_operand" "") | |
2ae0f82c SC |
8310 | (minus:XF (match_operand:XF 1 "register_operand" "") |
8311 | (match_operand:XF 2 "register_operand" "")))] | |
2b589241 JH |
8312 | "TARGET_80387" |
8313 | "") | |
8314 | ||
00188daa UB |
8315 | (define_expand "sub<mode>3" |
8316 | [(set (match_operand:MODEF 0 "register_operand" "") | |
8317 | (minus:MODEF (match_operand:MODEF 1 "register_operand" "") | |
8318 | (match_operand:MODEF 2 "nonimmediate_operand" "")))] | |
8ce94e44 JM |
8319 | "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) |
8320 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" | |
886c62d1 JVA |
8321 | "") |
8322 | \f | |
e075ae69 | 8323 | ;; Multiply instructions |
886c62d1 | 8324 | |
9b70259d JH |
8325 | (define_expand "muldi3" |
8326 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
8327 | (mult:DI (match_operand:DI 1 "register_operand" "") | |
8328 | (match_operand:DI 2 "x86_64_general_operand" ""))) | |
8bc527af | 8329 | (clobber (reg:CC FLAGS_REG))])] |
9b70259d JH |
8330 | "TARGET_64BIT" |
8331 | "") | |
8332 | ||
4f3f76e6 | 8333 | ;; On AMDFAM10 |
21efb4d4 HJ |
8334 | ;; IMUL reg64, reg64, imm8 Direct |
8335 | ;; IMUL reg64, mem64, imm8 VectorPath | |
8336 | ;; IMUL reg64, reg64, imm32 Direct | |
4f3f76e6 | 8337 | ;; IMUL reg64, mem64, imm32 VectorPath |
21efb4d4 HJ |
8338 | ;; IMUL reg64, reg64 Direct |
8339 | ;; IMUL reg64, mem64 Direct | |
8340 | ||
9b70259d JH |
8341 | (define_insn "*muldi3_1_rex64" |
8342 | [(set (match_operand:DI 0 "register_operand" "=r,r,r") | |
f56e86bd | 8343 | (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0") |
9b70259d | 8344 | (match_operand:DI 2 "x86_64_general_operand" "K,e,mr"))) |
8bc527af | 8345 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 8346 | "TARGET_64BIT |
7656aee4 | 8347 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
9b70259d | 8348 | "@ |
0f40f9f7 ZW |
8349 | imul{q}\t{%2, %1, %0|%0, %1, %2} |
8350 | imul{q}\t{%2, %1, %0|%0, %1, %2} | |
8351 | imul{q}\t{%2, %0|%0, %2}" | |
9b70259d JH |
8352 | [(set_attr "type" "imul") |
8353 | (set_attr "prefix_0f" "0,0,1") | |
f56e86bd JH |
8354 | (set (attr "athlon_decode") |
8355 | (cond [(eq_attr "cpu" "athlon") | |
8356 | (const_string "vector") | |
8357 | (eq_attr "alternative" "1") | |
8358 | (const_string "vector") | |
8359 | (and (eq_attr "alternative" "2") | |
8360 | (match_operand 1 "memory_operand" "")) | |
8361 | (const_string "vector")] | |
8362 | (const_string "direct"))) | |
21efb4d4 HJ |
8363 | (set (attr "amdfam10_decode") |
8364 | (cond [(and (eq_attr "alternative" "0,1") | |
8365 | (match_operand 1 "memory_operand" "")) | |
8366 | (const_string "vector")] | |
4f3f76e6 | 8367 | (const_string "direct"))) |
9b70259d JH |
8368 | (set_attr "mode" "DI")]) |
8369 | ||
d525dfdf JH |
8370 | (define_expand "mulsi3" |
8371 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
8372 | (mult:SI (match_operand:SI 1 "register_operand" "") | |
8373 | (match_operand:SI 2 "general_operand" ""))) | |
8bc527af | 8374 | (clobber (reg:CC FLAGS_REG))])] |
d525dfdf JH |
8375 | "" |
8376 | "") | |
8377 | ||
4f3f76e6 | 8378 | ;; On AMDFAM10 |
21efb4d4 HJ |
8379 | ;; IMUL reg32, reg32, imm8 Direct |
8380 | ;; IMUL reg32, mem32, imm8 VectorPath | |
8381 | ;; IMUL reg32, reg32, imm32 Direct | |
8382 | ;; IMUL reg32, mem32, imm32 VectorPath | |
8383 | ;; IMUL reg32, reg32 Direct | |
8384 | ;; IMUL reg32, mem32 Direct | |
8385 | ||
d525dfdf | 8386 | (define_insn "*mulsi3_1" |
e075ae69 | 8387 | [(set (match_operand:SI 0 "register_operand" "=r,r,r") |
f56e86bd | 8388 | (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") |
e075ae69 | 8389 | (match_operand:SI 2 "general_operand" "K,i,mr"))) |
8bc527af | 8390 | (clobber (reg:CC FLAGS_REG))] |
7656aee4 | 8391 | "!(MEM_P (operands[1]) && MEM_P (operands[2]))" |
e075ae69 | 8392 | "@ |
0f40f9f7 ZW |
8393 | imul{l}\t{%2, %1, %0|%0, %1, %2} |
8394 | imul{l}\t{%2, %1, %0|%0, %1, %2} | |
8395 | imul{l}\t{%2, %0|%0, %2}" | |
e075ae69 | 8396 | [(set_attr "type" "imul") |
6ef67412 | 8397 | (set_attr "prefix_0f" "0,0,1") |
f56e86bd JH |
8398 | (set (attr "athlon_decode") |
8399 | (cond [(eq_attr "cpu" "athlon") | |
8400 | (const_string "vector") | |
8401 | (eq_attr "alternative" "1") | |
8402 | (const_string "vector") | |
8403 | (and (eq_attr "alternative" "2") | |
8404 | (match_operand 1 "memory_operand" "")) | |
8405 | (const_string "vector")] | |
8406 | (const_string "direct"))) | |
21efb4d4 HJ |
8407 | (set (attr "amdfam10_decode") |
8408 | (cond [(and (eq_attr "alternative" "0,1") | |
8409 | (match_operand 1 "memory_operand" "")) | |
8410 | (const_string "vector")] | |
4f3f76e6 | 8411 | (const_string "direct"))) |
6ef67412 | 8412 | (set_attr "mode" "SI")]) |
886c62d1 | 8413 | |
9b70259d JH |
8414 | (define_insn "*mulsi3_1_zext" |
8415 | [(set (match_operand:DI 0 "register_operand" "=r,r,r") | |
8416 | (zero_extend:DI | |
f56e86bd | 8417 | (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") |
9b70259d | 8418 | (match_operand:SI 2 "general_operand" "K,i,mr")))) |
8bc527af | 8419 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 8420 | "TARGET_64BIT |
7656aee4 | 8421 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
9b70259d | 8422 | "@ |
0f40f9f7 ZW |
8423 | imul{l}\t{%2, %1, %k0|%k0, %1, %2} |
8424 | imul{l}\t{%2, %1, %k0|%k0, %1, %2} | |
8425 | imul{l}\t{%2, %k0|%k0, %2}" | |
9b70259d JH |
8426 | [(set_attr "type" "imul") |
8427 | (set_attr "prefix_0f" "0,0,1") | |
f56e86bd JH |
8428 | (set (attr "athlon_decode") |
8429 | (cond [(eq_attr "cpu" "athlon") | |
8430 | (const_string "vector") | |
8431 | (eq_attr "alternative" "1") | |
8432 | (const_string "vector") | |
8433 | (and (eq_attr "alternative" "2") | |
8434 | (match_operand 1 "memory_operand" "")) | |
8435 | (const_string "vector")] | |
8436 | (const_string "direct"))) | |
21efb4d4 HJ |
8437 | (set (attr "amdfam10_decode") |
8438 | (cond [(and (eq_attr "alternative" "0,1") | |
8439 | (match_operand 1 "memory_operand" "")) | |
8440 | (const_string "vector")] | |
4f3f76e6 | 8441 | (const_string "direct"))) |
9b70259d JH |
8442 | (set_attr "mode" "SI")]) |
8443 | ||
d525dfdf JH |
8444 | (define_expand "mulhi3" |
8445 | [(parallel [(set (match_operand:HI 0 "register_operand" "") | |
8446 | (mult:HI (match_operand:HI 1 "register_operand" "") | |
8447 | (match_operand:HI 2 "general_operand" ""))) | |
8bc527af | 8448 | (clobber (reg:CC FLAGS_REG))])] |
d9f32422 | 8449 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
8450 | "") |
8451 | ||
21efb4d4 HJ |
8452 | ;; On AMDFAM10 |
8453 | ;; IMUL reg16, reg16, imm8 VectorPath | |
8454 | ;; IMUL reg16, mem16, imm8 VectorPath | |
8455 | ;; IMUL reg16, reg16, imm16 VectorPath | |
8456 | ;; IMUL reg16, mem16, imm16 VectorPath | |
8457 | ;; IMUL reg16, reg16 Direct | |
8458 | ;; IMUL reg16, mem16 Direct | |
d525dfdf | 8459 | (define_insn "*mulhi3_1" |
6ef67412 | 8460 | [(set (match_operand:HI 0 "register_operand" "=r,r,r") |
f56e86bd | 8461 | (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") |
0edb82cb | 8462 | (match_operand:HI 2 "general_operand" "K,n,mr"))) |
8bc527af | 8463 | (clobber (reg:CC FLAGS_REG))] |
7656aee4 | 8464 | "!(MEM_P (operands[1]) && MEM_P (operands[2]))" |
e075ae69 | 8465 | "@ |
0f40f9f7 ZW |
8466 | imul{w}\t{%2, %1, %0|%0, %1, %2} |
8467 | imul{w}\t{%2, %1, %0|%0, %1, %2} | |
8468 | imul{w}\t{%2, %0|%0, %2}" | |
6ef67412 JH |
8469 | [(set_attr "type" "imul") |
8470 | (set_attr "prefix_0f" "0,0,1") | |
f56e86bd JH |
8471 | (set (attr "athlon_decode") |
8472 | (cond [(eq_attr "cpu" "athlon") | |
8473 | (const_string "vector") | |
8474 | (eq_attr "alternative" "1,2") | |
8475 | (const_string "vector")] | |
8476 | (const_string "direct"))) | |
21efb4d4 HJ |
8477 | (set (attr "amdfam10_decode") |
8478 | (cond [(eq_attr "alternative" "0,1") | |
8479 | (const_string "vector")] | |
8480 | (const_string "direct"))) | |
6ef67412 | 8481 | (set_attr "mode" "HI")]) |
886c62d1 | 8482 | |
558740bf JH |
8483 | (define_expand "mulqi3" |
8484 | [(parallel [(set (match_operand:QI 0 "register_operand" "") | |
8485 | (mult:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
8486 | (match_operand:QI 2 "register_operand" ""))) | |
8bc527af | 8487 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8488 | "TARGET_QIMODE_MATH" |
8489 | "") | |
8490 | ||
21efb4d4 HJ |
8491 | ;;On AMDFAM10 |
8492 | ;; MUL reg8 Direct | |
8493 | ;; MUL mem8 Direct | |
8494 | ||
558740bf | 8495 | (define_insn "*mulqi3_1" |
765a46f9 | 8496 | [(set (match_operand:QI 0 "register_operand" "=a") |
558740bf | 8497 | (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") |
765a46f9 | 8498 | (match_operand:QI 2 "nonimmediate_operand" "qm"))) |
8bc527af | 8499 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8500 | "TARGET_QIMODE_MATH |
7656aee4 | 8501 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8502 | "mul{b}\t%2" |
6ef67412 JH |
8503 | [(set_attr "type" "imul") |
8504 | (set_attr "length_immediate" "0") | |
f56e86bd JH |
8505 | (set (attr "athlon_decode") |
8506 | (if_then_else (eq_attr "cpu" "athlon") | |
8507 | (const_string "vector") | |
8508 | (const_string "direct"))) | |
4f3f76e6 | 8509 | (set_attr "amdfam10_decode" "direct") |
6ef67412 | 8510 | (set_attr "mode" "QI")]) |
765a46f9 | 8511 | |
558740bf JH |
8512 | (define_expand "umulqihi3" |
8513 | [(parallel [(set (match_operand:HI 0 "register_operand" "") | |
8514 | (mult:HI (zero_extend:HI | |
8515 | (match_operand:QI 1 "nonimmediate_operand" "")) | |
8516 | (zero_extend:HI | |
8517 | (match_operand:QI 2 "register_operand" "")))) | |
8bc527af | 8518 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8519 | "TARGET_QIMODE_MATH" |
8520 | "") | |
8521 | ||
8522 | (define_insn "*umulqihi3_1" | |
2ae0f82c | 8523 | [(set (match_operand:HI 0 "register_operand" "=a") |
558740bf | 8524 | (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) |
e075ae69 | 8525 | (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) |
8bc527af | 8526 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8527 | "TARGET_QIMODE_MATH |
7656aee4 | 8528 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8529 | "mul{b}\t%2" |
6ef67412 JH |
8530 | [(set_attr "type" "imul") |
8531 | (set_attr "length_immediate" "0") | |
f56e86bd JH |
8532 | (set (attr "athlon_decode") |
8533 | (if_then_else (eq_attr "cpu" "athlon") | |
8534 | (const_string "vector") | |
8535 | (const_string "direct"))) | |
04e1d06b | 8536 | (set_attr "amdfam10_decode" "direct") |
6ef67412 | 8537 | (set_attr "mode" "QI")]) |
886c62d1 | 8538 | |
558740bf JH |
8539 | (define_expand "mulqihi3" |
8540 | [(parallel [(set (match_operand:HI 0 "register_operand" "") | |
8541 | (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")) | |
8542 | (sign_extend:HI (match_operand:QI 2 "register_operand" "")))) | |
8bc527af | 8543 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8544 | "TARGET_QIMODE_MATH" |
8545 | "") | |
8546 | ||
8547 | (define_insn "*mulqihi3_insn" | |
2ae0f82c | 8548 | [(set (match_operand:HI 0 "register_operand" "=a") |
558740bf | 8549 | (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) |
e075ae69 | 8550 | (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) |
8bc527af | 8551 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8552 | "TARGET_QIMODE_MATH |
7656aee4 | 8553 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8554 | "imul{b}\t%2" |
6ef67412 JH |
8555 | [(set_attr "type" "imul") |
8556 | (set_attr "length_immediate" "0") | |
f56e86bd JH |
8557 | (set (attr "athlon_decode") |
8558 | (if_then_else (eq_attr "cpu" "athlon") | |
8559 | (const_string "vector") | |
8560 | (const_string "direct"))) | |
4f3f76e6 | 8561 | (set_attr "amdfam10_decode" "direct") |
6ef67412 | 8562 | (set_attr "mode" "QI")]) |
4b71cd6e | 8563 | |
558740bf JH |
8564 | (define_expand "umulditi3" |
8565 | [(parallel [(set (match_operand:TI 0 "register_operand" "") | |
8566 | (mult:TI (zero_extend:TI | |
8567 | (match_operand:DI 1 "nonimmediate_operand" "")) | |
8568 | (zero_extend:TI | |
8569 | (match_operand:DI 2 "register_operand" "")))) | |
8bc527af | 8570 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8571 | "TARGET_64BIT" |
8572 | "") | |
8573 | ||
8574 | (define_insn "*umulditi3_insn" | |
9b70259d | 8575 | [(set (match_operand:TI 0 "register_operand" "=A") |
558740bf | 8576 | (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) |
9b70259d | 8577 | (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) |
8bc527af | 8578 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8579 | "TARGET_64BIT |
7656aee4 | 8580 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8581 | "mul{q}\t%2" |
1e07edd3 | 8582 | [(set_attr "type" "imul") |
1e07edd3 | 8583 | (set_attr "length_immediate" "0") |
f56e86bd JH |
8584 | (set (attr "athlon_decode") |
8585 | (if_then_else (eq_attr "cpu" "athlon") | |
8586 | (const_string "vector") | |
8587 | (const_string "double"))) | |
4f3f76e6 | 8588 | (set_attr "amdfam10_decode" "double") |
9b70259d | 8589 | (set_attr "mode" "DI")]) |
1e07edd3 JH |
8590 | |
8591 | ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers | |
558740bf JH |
8592 | (define_expand "umulsidi3" |
8593 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
8594 | (mult:DI (zero_extend:DI | |
8595 | (match_operand:SI 1 "nonimmediate_operand" "")) | |
8596 | (zero_extend:DI | |
8597 | (match_operand:SI 2 "register_operand" "")))) | |
8bc527af | 8598 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8599 | "!TARGET_64BIT" |
8600 | "") | |
8601 | ||
8602 | (define_insn "*umulsidi3_insn" | |
4b71cd6e | 8603 | [(set (match_operand:DI 0 "register_operand" "=A") |
558740bf | 8604 | (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) |
e075ae69 | 8605 | (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) |
8bc527af | 8606 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8607 | "!TARGET_64BIT |
7656aee4 | 8608 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8609 | "mul{l}\t%2" |
e075ae69 | 8610 | [(set_attr "type" "imul") |
6ef67412 | 8611 | (set_attr "length_immediate" "0") |
f56e86bd JH |
8612 | (set (attr "athlon_decode") |
8613 | (if_then_else (eq_attr "cpu" "athlon") | |
8614 | (const_string "vector") | |
8615 | (const_string "double"))) | |
4f3f76e6 | 8616 | (set_attr "amdfam10_decode" "double") |
6ef67412 | 8617 | (set_attr "mode" "SI")]) |
4b71cd6e | 8618 | |
558740bf JH |
8619 | (define_expand "mulditi3" |
8620 | [(parallel [(set (match_operand:TI 0 "register_operand" "") | |
8621 | (mult:TI (sign_extend:TI | |
8622 | (match_operand:DI 1 "nonimmediate_operand" "")) | |
8623 | (sign_extend:TI | |
8624 | (match_operand:DI 2 "register_operand" "")))) | |
8bc527af | 8625 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8626 | "TARGET_64BIT" |
8627 | "") | |
8628 | ||
8629 | (define_insn "*mulditi3_insn" | |
9b70259d | 8630 | [(set (match_operand:TI 0 "register_operand" "=A") |
558740bf | 8631 | (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) |
9b70259d | 8632 | (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) |
8bc527af | 8633 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8634 | "TARGET_64BIT |
7656aee4 | 8635 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8636 | "imul{q}\t%2" |
9b70259d JH |
8637 | [(set_attr "type" "imul") |
8638 | (set_attr "length_immediate" "0") | |
f56e86bd JH |
8639 | (set (attr "athlon_decode") |
8640 | (if_then_else (eq_attr "cpu" "athlon") | |
8641 | (const_string "vector") | |
8642 | (const_string "double"))) | |
21efb4d4 | 8643 | (set_attr "amdfam10_decode" "double") |
9b70259d JH |
8644 | (set_attr "mode" "DI")]) |
8645 | ||
558740bf JH |
8646 | (define_expand "mulsidi3" |
8647 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
8648 | (mult:DI (sign_extend:DI | |
8649 | (match_operand:SI 1 "nonimmediate_operand" "")) | |
8650 | (sign_extend:DI | |
8651 | (match_operand:SI 2 "register_operand" "")))) | |
8bc527af | 8652 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8653 | "!TARGET_64BIT" |
8654 | "") | |
8655 | ||
8656 | (define_insn "*mulsidi3_insn" | |
4b71cd6e | 8657 | [(set (match_operand:DI 0 "register_operand" "=A") |
558740bf | 8658 | (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) |
e075ae69 | 8659 | (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) |
8bc527af | 8660 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8661 | "!TARGET_64BIT |
7656aee4 | 8662 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8663 | "imul{l}\t%2" |
6ef67412 JH |
8664 | [(set_attr "type" "imul") |
8665 | (set_attr "length_immediate" "0") | |
f56e86bd JH |
8666 | (set (attr "athlon_decode") |
8667 | (if_then_else (eq_attr "cpu" "athlon") | |
8668 | (const_string "vector") | |
8669 | (const_string "double"))) | |
4f3f76e6 | 8670 | (set_attr "amdfam10_decode" "double") |
6ef67412 | 8671 | (set_attr "mode" "SI")]) |
2f2a49e8 | 8672 | |
558740bf JH |
8673 | (define_expand "umuldi3_highpart" |
8674 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
8675 | (truncate:DI | |
8676 | (lshiftrt:TI | |
8677 | (mult:TI (zero_extend:TI | |
8678 | (match_operand:DI 1 "nonimmediate_operand" "")) | |
8679 | (zero_extend:TI | |
8680 | (match_operand:DI 2 "register_operand" ""))) | |
8681 | (const_int 64)))) | |
8682 | (clobber (match_scratch:DI 3 "")) | |
8bc527af | 8683 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8684 | "TARGET_64BIT" |
8685 | "") | |
8686 | ||
9b70259d JH |
8687 | (define_insn "*umuldi3_highpart_rex64" |
8688 | [(set (match_operand:DI 0 "register_operand" "=d") | |
8689 | (truncate:DI | |
8690 | (lshiftrt:TI | |
8691 | (mult:TI (zero_extend:TI | |
558740bf | 8692 | (match_operand:DI 1 "nonimmediate_operand" "%a")) |
9b70259d JH |
8693 | (zero_extend:TI |
8694 | (match_operand:DI 2 "nonimmediate_operand" "rm"))) | |
8695 | (const_int 64)))) | |
558740bf | 8696 | (clobber (match_scratch:DI 3 "=1")) |
8bc527af | 8697 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8698 | "TARGET_64BIT |
7656aee4 | 8699 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8700 | "mul{q}\t%2" |
9b70259d | 8701 | [(set_attr "type" "imul") |
9b70259d | 8702 | (set_attr "length_immediate" "0") |
f56e86bd JH |
8703 | (set (attr "athlon_decode") |
8704 | (if_then_else (eq_attr "cpu" "athlon") | |
8705 | (const_string "vector") | |
8706 | (const_string "double"))) | |
4f3f76e6 | 8707 | (set_attr "amdfam10_decode" "double") |
9b70259d JH |
8708 | (set_attr "mode" "DI")]) |
8709 | ||
558740bf JH |
8710 | (define_expand "umulsi3_highpart" |
8711 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
8712 | (truncate:SI | |
8713 | (lshiftrt:DI | |
8714 | (mult:DI (zero_extend:DI | |
8715 | (match_operand:SI 1 "nonimmediate_operand" "")) | |
8716 | (zero_extend:DI | |
8717 | (match_operand:SI 2 "register_operand" ""))) | |
8718 | (const_int 32)))) | |
8719 | (clobber (match_scratch:SI 3 "")) | |
8bc527af | 8720 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8721 | "" |
8722 | "") | |
8723 | ||
8724 | (define_insn "*umulsi3_highpart_insn" | |
2f2a49e8 | 8725 | [(set (match_operand:SI 0 "register_operand" "=d") |
e075ae69 RH |
8726 | (truncate:SI |
8727 | (lshiftrt:DI | |
8728 | (mult:DI (zero_extend:DI | |
558740bf | 8729 | (match_operand:SI 1 "nonimmediate_operand" "%a")) |
e075ae69 RH |
8730 | (zero_extend:DI |
8731 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) | |
8732 | (const_int 32)))) | |
558740bf | 8733 | (clobber (match_scratch:SI 3 "=1")) |
8bc527af | 8734 | (clobber (reg:CC FLAGS_REG))] |
7656aee4 | 8735 | "!(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8736 | "mul{l}\t%2" |
32ee7d1d | 8737 | [(set_attr "type" "imul") |
32ee7d1d | 8738 | (set_attr "length_immediate" "0") |
f56e86bd JH |
8739 | (set (attr "athlon_decode") |
8740 | (if_then_else (eq_attr "cpu" "athlon") | |
8741 | (const_string "vector") | |
8742 | (const_string "double"))) | |
21efb4d4 | 8743 | (set_attr "amdfam10_decode" "double") |
32ee7d1d JH |
8744 | (set_attr "mode" "SI")]) |
8745 | ||
8746 | (define_insn "*umulsi3_highpart_zext" | |
8747 | [(set (match_operand:DI 0 "register_operand" "=d") | |
8748 | (zero_extend:DI (truncate:SI | |
8749 | (lshiftrt:DI | |
8750 | (mult:DI (zero_extend:DI | |
558740bf | 8751 | (match_operand:SI 1 "nonimmediate_operand" "%a")) |
32ee7d1d JH |
8752 | (zero_extend:DI |
8753 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) | |
8754 | (const_int 32))))) | |
558740bf | 8755 | (clobber (match_scratch:SI 3 "=1")) |
8bc527af | 8756 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8757 | "TARGET_64BIT |
7656aee4 | 8758 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8759 | "mul{l}\t%2" |
e075ae69 | 8760 | [(set_attr "type" "imul") |
6ef67412 | 8761 | (set_attr "length_immediate" "0") |
f56e86bd JH |
8762 | (set (attr "athlon_decode") |
8763 | (if_then_else (eq_attr "cpu" "athlon") | |
8764 | (const_string "vector") | |
8765 | (const_string "double"))) | |
21efb4d4 | 8766 | (set_attr "amdfam10_decode" "double") |
6ef67412 | 8767 | (set_attr "mode" "SI")]) |
2f2a49e8 | 8768 | |
558740bf | 8769 | (define_expand "smuldi3_highpart" |
00188daa | 8770 | [(parallel [(set (match_operand:DI 0 "register_operand" "") |
558740bf JH |
8771 | (truncate:DI |
8772 | (lshiftrt:TI | |
8773 | (mult:TI (sign_extend:TI | |
8774 | (match_operand:DI 1 "nonimmediate_operand" "")) | |
8775 | (sign_extend:TI | |
8776 | (match_operand:DI 2 "register_operand" ""))) | |
8777 | (const_int 64)))) | |
8778 | (clobber (match_scratch:DI 3 "")) | |
8bc527af | 8779 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8780 | "TARGET_64BIT" |
8781 | "") | |
8782 | ||
9b70259d JH |
8783 | (define_insn "*smuldi3_highpart_rex64" |
8784 | [(set (match_operand:DI 0 "register_operand" "=d") | |
8785 | (truncate:DI | |
8786 | (lshiftrt:TI | |
8787 | (mult:TI (sign_extend:TI | |
558740bf | 8788 | (match_operand:DI 1 "nonimmediate_operand" "%a")) |
9b70259d JH |
8789 | (sign_extend:TI |
8790 | (match_operand:DI 2 "nonimmediate_operand" "rm"))) | |
8791 | (const_int 64)))) | |
558740bf | 8792 | (clobber (match_scratch:DI 3 "=1")) |
8bc527af | 8793 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8794 | "TARGET_64BIT |
7656aee4 | 8795 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8796 | "imul{q}\t%2" |
9b70259d | 8797 | [(set_attr "type" "imul") |
f56e86bd JH |
8798 | (set (attr "athlon_decode") |
8799 | (if_then_else (eq_attr "cpu" "athlon") | |
8800 | (const_string "vector") | |
8801 | (const_string "double"))) | |
21efb4d4 | 8802 | (set_attr "amdfam10_decode" "double") |
9b70259d JH |
8803 | (set_attr "mode" "DI")]) |
8804 | ||
558740bf JH |
8805 | (define_expand "smulsi3_highpart" |
8806 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
8807 | (truncate:SI | |
8808 | (lshiftrt:DI | |
8809 | (mult:DI (sign_extend:DI | |
8810 | (match_operand:SI 1 "nonimmediate_operand" "")) | |
8811 | (sign_extend:DI | |
8812 | (match_operand:SI 2 "register_operand" ""))) | |
8813 | (const_int 32)))) | |
8814 | (clobber (match_scratch:SI 3 "")) | |
8bc527af | 8815 | (clobber (reg:CC FLAGS_REG))])] |
558740bf JH |
8816 | "" |
8817 | "") | |
8818 | ||
8819 | (define_insn "*smulsi3_highpart_insn" | |
2f2a49e8 | 8820 | [(set (match_operand:SI 0 "register_operand" "=d") |
e075ae69 RH |
8821 | (truncate:SI |
8822 | (lshiftrt:DI | |
8823 | (mult:DI (sign_extend:DI | |
558740bf | 8824 | (match_operand:SI 1 "nonimmediate_operand" "%a")) |
e075ae69 RH |
8825 | (sign_extend:DI |
8826 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) | |
8827 | (const_int 32)))) | |
558740bf | 8828 | (clobber (match_scratch:SI 3 "=1")) |
8bc527af | 8829 | (clobber (reg:CC FLAGS_REG))] |
7656aee4 | 8830 | "!(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8831 | "imul{l}\t%2" |
e075ae69 | 8832 | [(set_attr "type" "imul") |
f56e86bd JH |
8833 | (set (attr "athlon_decode") |
8834 | (if_then_else (eq_attr "cpu" "athlon") | |
8835 | (const_string "vector") | |
8836 | (const_string "double"))) | |
21efb4d4 | 8837 | (set_attr "amdfam10_decode" "double") |
6ef67412 | 8838 | (set_attr "mode" "SI")]) |
4b71cd6e | 8839 | |
9b70259d JH |
8840 | (define_insn "*smulsi3_highpart_zext" |
8841 | [(set (match_operand:DI 0 "register_operand" "=d") | |
8842 | (zero_extend:DI (truncate:SI | |
8843 | (lshiftrt:DI | |
8844 | (mult:DI (sign_extend:DI | |
558740bf | 8845 | (match_operand:SI 1 "nonimmediate_operand" "%a")) |
9b70259d JH |
8846 | (sign_extend:DI |
8847 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) | |
8848 | (const_int 32))))) | |
558740bf | 8849 | (clobber (match_scratch:SI 3 "=1")) |
8bc527af | 8850 | (clobber (reg:CC FLAGS_REG))] |
558740bf | 8851 | "TARGET_64BIT |
7656aee4 | 8852 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 8853 | "imul{l}\t%2" |
9b70259d | 8854 | [(set_attr "type" "imul") |
f56e86bd JH |
8855 | (set (attr "athlon_decode") |
8856 | (if_then_else (eq_attr "cpu" "athlon") | |
8857 | (const_string "vector") | |
8858 | (const_string "double"))) | |
21efb4d4 | 8859 | (set_attr "amdfam10_decode" "double") |
9b70259d JH |
8860 | (set_attr "mode" "SI")]) |
8861 | ||
886c62d1 JVA |
8862 | ;; The patterns that match these are at the end of this file. |
8863 | ||
4fb21e90 JVA |
8864 | (define_expand "mulxf3" |
8865 | [(set (match_operand:XF 0 "register_operand" "") | |
2ae0f82c SC |
8866 | (mult:XF (match_operand:XF 1 "register_operand" "") |
8867 | (match_operand:XF 2 "register_operand" "")))] | |
2b589241 JH |
8868 | "TARGET_80387" |
8869 | "") | |
8870 | ||
00188daa UB |
8871 | (define_expand "mul<mode>3" |
8872 | [(set (match_operand:MODEF 0 "register_operand" "") | |
8873 | (mult:MODEF (match_operand:MODEF 1 "register_operand" "") | |
8874 | (match_operand:MODEF 2 "nonimmediate_operand" "")))] | |
8ce94e44 JM |
8875 | "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) |
8876 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" | |
886c62d1 | 8877 | "") |
04e1d06b MM |
8878 | |
8879 | ;; SSE5 scalar multiply/add instructions are defined in sse.md. | |
8880 | ||
886c62d1 | 8881 | \f |
e075ae69 | 8882 | ;; Divide instructions |
886c62d1 JVA |
8883 | |
8884 | (define_insn "divqi3" | |
2ae0f82c SC |
8885 | [(set (match_operand:QI 0 "register_operand" "=a") |
8886 | (div:QI (match_operand:HI 1 "register_operand" "0") | |
e075ae69 | 8887 | (match_operand:QI 2 "nonimmediate_operand" "qm"))) |
8bc527af | 8888 | (clobber (reg:CC FLAGS_REG))] |
d9f32422 | 8889 | "TARGET_QIMODE_MATH" |
0f40f9f7 | 8890 | "idiv{b}\t%2" |
e075ae69 | 8891 | [(set_attr "type" "idiv") |
56bab446 | 8892 | (set_attr "mode" "QI")]) |
886c62d1 JVA |
8893 | |
8894 | (define_insn "udivqi3" | |
2ae0f82c SC |
8895 | [(set (match_operand:QI 0 "register_operand" "=a") |
8896 | (udiv:QI (match_operand:HI 1 "register_operand" "0") | |
e075ae69 | 8897 | (match_operand:QI 2 "nonimmediate_operand" "qm"))) |
8bc527af | 8898 | (clobber (reg:CC FLAGS_REG))] |
d9f32422 | 8899 | "TARGET_QIMODE_MATH" |
0f40f9f7 | 8900 | "div{b}\t%2" |
e075ae69 | 8901 | [(set_attr "type" "idiv") |
56bab446 | 8902 | (set_attr "mode" "QI")]) |
886c62d1 JVA |
8903 | |
8904 | ;; The patterns that match these are at the end of this file. | |
8905 | ||
4fb21e90 JVA |
8906 | (define_expand "divxf3" |
8907 | [(set (match_operand:XF 0 "register_operand" "") | |
2ae0f82c SC |
8908 | (div:XF (match_operand:XF 1 "register_operand" "") |
8909 | (match_operand:XF 2 "register_operand" "")))] | |
2b589241 JH |
8910 | "TARGET_80387" |
8911 | "") | |
8912 | ||
a78cb986 SC |
8913 | (define_expand "divdf3" |
8914 | [(set (match_operand:DF 0 "register_operand" "") | |
8915 | (div:DF (match_operand:DF 1 "register_operand" "") | |
8916 | (match_operand:DF 2 "nonimmediate_operand" "")))] | |
8ce94e44 JM |
8917 | "(TARGET_80387 && X87_ENABLE_ARITH (DFmode)) |
8918 | || (TARGET_SSE2 && TARGET_SSE_MATH)" | |
a78cb986 | 8919 | "") |
6300f037 | 8920 | |
886c62d1 JVA |
8921 | (define_expand "divsf3" |
8922 | [(set (match_operand:SF 0 "register_operand" "") | |
2ae0f82c | 8923 | (div:SF (match_operand:SF 1 "register_operand" "") |
886c62d1 | 8924 | (match_operand:SF 2 "nonimmediate_operand" "")))] |
8ce94e44 JM |
8925 | "(TARGET_80387 && X87_ENABLE_ARITH (SFmode)) |
8926 | || TARGET_SSE_MATH" | |
6b889d89 | 8927 | { |
18bd082d | 8928 | if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p () |
6b889d89 UB |
8929 | && flag_finite_math_only && !flag_trapping_math |
8930 | && flag_unsafe_math_optimizations) | |
8931 | { | |
8932 | ix86_emit_swdivsf (operands[0], operands[1], | |
8933 | operands[2], SFmode); | |
8934 | DONE; | |
8935 | } | |
8936 | }) | |
886c62d1 JVA |
8937 | \f |
8938 | ;; Remainder instructions. | |
9b70259d JH |
8939 | |
8940 | (define_expand "divmoddi4" | |
8941 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
8942 | (div:DI (match_operand:DI 1 "register_operand" "") | |
8943 | (match_operand:DI 2 "nonimmediate_operand" ""))) | |
8944 | (set (match_operand:DI 3 "register_operand" "") | |
8945 | (mod:DI (match_dup 1) (match_dup 2))) | |
8bc527af | 8946 | (clobber (reg:CC FLAGS_REG))])] |
9b70259d JH |
8947 | "TARGET_64BIT" |
8948 | "") | |
8949 | ||
8950 | ;; Allow to come the parameter in eax or edx to avoid extra moves. | |
d1f87653 | 8951 | ;; Penalize eax case slightly because it results in worse scheduling |
9b70259d JH |
8952 | ;; of code. |
8953 | (define_insn "*divmoddi4_nocltd_rex64" | |
8954 | [(set (match_operand:DI 0 "register_operand" "=&a,?a") | |
8955 | (div:DI (match_operand:DI 2 "register_operand" "1,0") | |
8956 | (match_operand:DI 3 "nonimmediate_operand" "rm,rm"))) | |
8957 | (set (match_operand:DI 1 "register_operand" "=&d,&d") | |
8958 | (mod:DI (match_dup 2) (match_dup 3))) | |
8bc527af | 8959 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 8960 | "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD" |
9b70259d JH |
8961 | "#" |
8962 | [(set_attr "type" "multi")]) | |
8963 | ||
8964 | (define_insn "*divmoddi4_cltd_rex64" | |
8965 | [(set (match_operand:DI 0 "register_operand" "=a") | |
8966 | (div:DI (match_operand:DI 2 "register_operand" "a") | |
8967 | (match_operand:DI 3 "nonimmediate_operand" "rm"))) | |
8968 | (set (match_operand:DI 1 "register_operand" "=&d") | |
8969 | (mod:DI (match_dup 2) (match_dup 3))) | |
8bc527af | 8970 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 8971 | "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)" |
9b70259d JH |
8972 | "#" |
8973 | [(set_attr "type" "multi")]) | |
8974 | ||
8975 | (define_insn "*divmoddi_noext_rex64" | |
8976 | [(set (match_operand:DI 0 "register_operand" "=a") | |
8977 | (div:DI (match_operand:DI 1 "register_operand" "0") | |
8978 | (match_operand:DI 2 "nonimmediate_operand" "rm"))) | |
8979 | (set (match_operand:DI 3 "register_operand" "=d") | |
8980 | (mod:DI (match_dup 1) (match_dup 2))) | |
8981 | (use (match_operand:DI 4 "register_operand" "3")) | |
8bc527af | 8982 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 8983 | "TARGET_64BIT" |
0f40f9f7 | 8984 | "idiv{q}\t%2" |
9b70259d | 8985 | [(set_attr "type" "idiv") |
56bab446 | 8986 | (set_attr "mode" "DI")]) |
9b70259d JH |
8987 | |
8988 | (define_split | |
8989 | [(set (match_operand:DI 0 "register_operand" "") | |
8990 | (div:DI (match_operand:DI 1 "register_operand" "") | |
8991 | (match_operand:DI 2 "nonimmediate_operand" ""))) | |
8992 | (set (match_operand:DI 3 "register_operand" "") | |
8993 | (mod:DI (match_dup 1) (match_dup 2))) | |
8bc527af | 8994 | (clobber (reg:CC FLAGS_REG))] |
9b70259d JH |
8995 | "TARGET_64BIT && reload_completed" |
8996 | [(parallel [(set (match_dup 3) | |
8997 | (ashiftrt:DI (match_dup 4) (const_int 63))) | |
8bc527af | 8998 | (clobber (reg:CC FLAGS_REG))]) |
9b70259d JH |
8999 | (parallel [(set (match_dup 0) |
9000 | (div:DI (reg:DI 0) (match_dup 2))) | |
9001 | (set (match_dup 3) | |
9002 | (mod:DI (reg:DI 0) (match_dup 2))) | |
9003 | (use (match_dup 3)) | |
8bc527af | 9004 | (clobber (reg:CC FLAGS_REG))])] |
9b70259d | 9005 | { |
9cd10576 | 9006 | /* Avoid use of cltd in favor of a mov+shift. */ |
3debdc1e | 9007 | if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun)) |
9b70259d JH |
9008 | { |
9009 | if (true_regnum (operands[1])) | |
9010 | emit_move_insn (operands[0], operands[1]); | |
9011 | else | |
9012 | emit_move_insn (operands[3], operands[1]); | |
9013 | operands[4] = operands[3]; | |
9014 | } | |
9015 | else | |
9016 | { | |
7637e42c | 9017 | gcc_assert (!true_regnum (operands[1])); |
9b70259d JH |
9018 | operands[4] = operands[1]; |
9019 | } | |
0f40f9f7 | 9020 | }) |
9b70259d JH |
9021 | |
9022 | ||
40745eec JH |
9023 | (define_expand "divmodsi4" |
9024 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
9025 | (div:SI (match_operand:SI 1 "register_operand" "") | |
9026 | (match_operand:SI 2 "nonimmediate_operand" ""))) | |
9027 | (set (match_operand:SI 3 "register_operand" "") | |
9028 | (mod:SI (match_dup 1) (match_dup 2))) | |
8bc527af | 9029 | (clobber (reg:CC FLAGS_REG))])] |
40745eec JH |
9030 | "" |
9031 | "") | |
9032 | ||
9033 | ;; Allow to come the parameter in eax or edx to avoid extra moves. | |
d1f87653 | 9034 | ;; Penalize eax case slightly because it results in worse scheduling |
40745eec JH |
9035 | ;; of code. |
9036 | (define_insn "*divmodsi4_nocltd" | |
9037 | [(set (match_operand:SI 0 "register_operand" "=&a,?a") | |
9038 | (div:SI (match_operand:SI 2 "register_operand" "1,0") | |
9039 | (match_operand:SI 3 "nonimmediate_operand" "rm,rm"))) | |
9040 | (set (match_operand:SI 1 "register_operand" "=&d,&d") | |
9041 | (mod:SI (match_dup 2) (match_dup 3))) | |
8bc527af | 9042 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 9043 | "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD" |
40745eec JH |
9044 | "#" |
9045 | [(set_attr "type" "multi")]) | |
886c62d1 | 9046 | |
40745eec | 9047 | (define_insn "*divmodsi4_cltd" |
2bb7a0f5 | 9048 | [(set (match_operand:SI 0 "register_operand" "=a") |
40745eec JH |
9049 | (div:SI (match_operand:SI 2 "register_operand" "a") |
9050 | (match_operand:SI 3 "nonimmediate_operand" "rm"))) | |
9051 | (set (match_operand:SI 1 "register_operand" "=&d") | |
9052 | (mod:SI (match_dup 2) (match_dup 3))) | |
8bc527af | 9053 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 9054 | "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD" |
40745eec | 9055 | "#" |
e075ae69 RH |
9056 | [(set_attr "type" "multi")]) |
9057 | ||
6343a50e | 9058 | (define_insn "*divmodsi_noext" |
e075ae69 | 9059 | [(set (match_operand:SI 0 "register_operand" "=a") |
40745eec | 9060 | (div:SI (match_operand:SI 1 "register_operand" "0") |
e075ae69 RH |
9061 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) |
9062 | (set (match_operand:SI 3 "register_operand" "=d") | |
9063 | (mod:SI (match_dup 1) (match_dup 2))) | |
40745eec | 9064 | (use (match_operand:SI 4 "register_operand" "3")) |
8bc527af | 9065 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 9066 | "" |
0f40f9f7 | 9067 | "idiv{l}\t%2" |
e075ae69 | 9068 | [(set_attr "type" "idiv") |
56bab446 | 9069 | (set_attr "mode" "SI")]) |
e075ae69 RH |
9070 | |
9071 | (define_split | |
9072 | [(set (match_operand:SI 0 "register_operand" "") | |
9073 | (div:SI (match_operand:SI 1 "register_operand" "") | |
9074 | (match_operand:SI 2 "nonimmediate_operand" ""))) | |
9075 | (set (match_operand:SI 3 "register_operand" "") | |
9076 | (mod:SI (match_dup 1) (match_dup 2))) | |
8bc527af | 9077 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 RH |
9078 | "reload_completed" |
9079 | [(parallel [(set (match_dup 3) | |
9080 | (ashiftrt:SI (match_dup 4) (const_int 31))) | |
8bc527af | 9081 | (clobber (reg:CC FLAGS_REG))]) |
e075ae69 | 9082 | (parallel [(set (match_dup 0) |
40745eec | 9083 | (div:SI (reg:SI 0) (match_dup 2))) |
e075ae69 | 9084 | (set (match_dup 3) |
40745eec | 9085 | (mod:SI (reg:SI 0) (match_dup 2))) |
e075ae69 | 9086 | (use (match_dup 3)) |
8bc527af | 9087 | (clobber (reg:CC FLAGS_REG))])] |
886c62d1 | 9088 | { |
9cd10576 | 9089 | /* Avoid use of cltd in favor of a mov+shift. */ |
3debdc1e | 9090 | if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun)) |
e075ae69 | 9091 | { |
40745eec JH |
9092 | if (true_regnum (operands[1])) |
9093 | emit_move_insn (operands[0], operands[1]); | |
9094 | else | |
9095 | emit_move_insn (operands[3], operands[1]); | |
e075ae69 RH |
9096 | operands[4] = operands[3]; |
9097 | } | |
9098 | else | |
40745eec | 9099 | { |
7637e42c | 9100 | gcc_assert (!true_regnum (operands[1])); |
40745eec JH |
9101 | operands[4] = operands[1]; |
9102 | } | |
0f40f9f7 | 9103 | }) |
e075ae69 | 9104 | ;; %%% Split me. |
886c62d1 | 9105 | (define_insn "divmodhi4" |
2bb7a0f5 RS |
9106 | [(set (match_operand:HI 0 "register_operand" "=a") |
9107 | (div:HI (match_operand:HI 1 "register_operand" "0") | |
2ae0f82c | 9108 | (match_operand:HI 2 "nonimmediate_operand" "rm"))) |
2bb7a0f5 | 9109 | (set (match_operand:HI 3 "register_operand" "=&d") |
e075ae69 | 9110 | (mod:HI (match_dup 1) (match_dup 2))) |
8bc527af | 9111 | (clobber (reg:CC FLAGS_REG))] |
d9f32422 | 9112 | "TARGET_HIMODE_MATH" |
0f40f9f7 | 9113 | "cwtd\;idiv{w}\t%2" |
6ef67412 JH |
9114 | [(set_attr "type" "multi") |
9115 | (set_attr "length_immediate" "0") | |
9116 | (set_attr "mode" "SI")]) | |
886c62d1 | 9117 | |
9b70259d JH |
9118 | (define_insn "udivmoddi4" |
9119 | [(set (match_operand:DI 0 "register_operand" "=a") | |
9120 | (udiv:DI (match_operand:DI 1 "register_operand" "0") | |
9121 | (match_operand:DI 2 "nonimmediate_operand" "rm"))) | |
9122 | (set (match_operand:DI 3 "register_operand" "=&d") | |
9123 | (umod:DI (match_dup 1) (match_dup 2))) | |
8bc527af | 9124 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 9125 | "TARGET_64BIT" |
0f40f9f7 | 9126 | "xor{q}\t%3, %3\;div{q}\t%2" |
9b70259d JH |
9127 | [(set_attr "type" "multi") |
9128 | (set_attr "length_immediate" "0") | |
9129 | (set_attr "mode" "DI")]) | |
9130 | ||
9131 | (define_insn "*udivmoddi4_noext" | |
9132 | [(set (match_operand:DI 0 "register_operand" "=a") | |
9133 | (udiv:DI (match_operand:DI 1 "register_operand" "0") | |
9134 | (match_operand:DI 2 "nonimmediate_operand" "rm"))) | |
9135 | (set (match_operand:DI 3 "register_operand" "=d") | |
9136 | (umod:DI (match_dup 1) (match_dup 2))) | |
9137 | (use (match_dup 3)) | |
8bc527af | 9138 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 9139 | "TARGET_64BIT" |
0f40f9f7 | 9140 | "div{q}\t%2" |
9b70259d | 9141 | [(set_attr "type" "idiv") |
9b70259d JH |
9142 | (set_attr "mode" "DI")]) |
9143 | ||
9144 | (define_split | |
9145 | [(set (match_operand:DI 0 "register_operand" "") | |
9146 | (udiv:DI (match_operand:DI 1 "register_operand" "") | |
9147 | (match_operand:DI 2 "nonimmediate_operand" ""))) | |
9148 | (set (match_operand:DI 3 "register_operand" "") | |
9149 | (umod:DI (match_dup 1) (match_dup 2))) | |
8bc527af | 9150 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 9151 | "TARGET_64BIT && reload_completed" |
9b70259d JH |
9152 | [(set (match_dup 3) (const_int 0)) |
9153 | (parallel [(set (match_dup 0) | |
9154 | (udiv:DI (match_dup 1) (match_dup 2))) | |
9155 | (set (match_dup 3) | |
9156 | (umod:DI (match_dup 1) (match_dup 2))) | |
9157 | (use (match_dup 3)) | |
8bc527af | 9158 | (clobber (reg:CC FLAGS_REG))])] |
9b70259d JH |
9159 | "") |
9160 | ||
886c62d1 | 9161 | (define_insn "udivmodsi4" |
2bb7a0f5 RS |
9162 | [(set (match_operand:SI 0 "register_operand" "=a") |
9163 | (udiv:SI (match_operand:SI 1 "register_operand" "0") | |
2ae0f82c | 9164 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) |
2bb7a0f5 | 9165 | (set (match_operand:SI 3 "register_operand" "=&d") |
e075ae69 | 9166 | (umod:SI (match_dup 1) (match_dup 2))) |
8bc527af | 9167 | (clobber (reg:CC FLAGS_REG))] |
886c62d1 | 9168 | "" |
0f40f9f7 | 9169 | "xor{l}\t%3, %3\;div{l}\t%2" |
6ef67412 JH |
9170 | [(set_attr "type" "multi") |
9171 | (set_attr "length_immediate" "0") | |
9172 | (set_attr "mode" "SI")]) | |
886c62d1 | 9173 | |
6343a50e | 9174 | (define_insn "*udivmodsi4_noext" |
2bb7a0f5 | 9175 | [(set (match_operand:SI 0 "register_operand" "=a") |
e075ae69 | 9176 | (udiv:SI (match_operand:SI 1 "register_operand" "0") |
2ae0f82c | 9177 | (match_operand:SI 2 "nonimmediate_operand" "rm"))) |
2bb7a0f5 | 9178 | (set (match_operand:SI 3 "register_operand" "=d") |
e075ae69 RH |
9179 | (umod:SI (match_dup 1) (match_dup 2))) |
9180 | (use (match_dup 3)) | |
8bc527af | 9181 | (clobber (reg:CC FLAGS_REG))] |
886c62d1 | 9182 | "" |
0f40f9f7 | 9183 | "div{l}\t%2" |
e075ae69 | 9184 | [(set_attr "type" "idiv") |
6ef67412 | 9185 | (set_attr "mode" "SI")]) |
886c62d1 | 9186 | |
e075ae69 RH |
9187 | (define_split |
9188 | [(set (match_operand:SI 0 "register_operand" "") | |
9189 | (udiv:SI (match_operand:SI 1 "register_operand" "") | |
9190 | (match_operand:SI 2 "nonimmediate_operand" ""))) | |
9191 | (set (match_operand:SI 3 "register_operand" "") | |
9192 | (umod:SI (match_dup 1) (match_dup 2))) | |
8bc527af | 9193 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 9194 | "reload_completed" |
591702de | 9195 | [(set (match_dup 3) (const_int 0)) |
e075ae69 RH |
9196 | (parallel [(set (match_dup 0) |
9197 | (udiv:SI (match_dup 1) (match_dup 2))) | |
9198 | (set (match_dup 3) | |
9199 | (umod:SI (match_dup 1) (match_dup 2))) | |
9200 | (use (match_dup 3)) | |
8bc527af | 9201 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 | 9202 | "") |
886c62d1 | 9203 | |
e075ae69 | 9204 | (define_expand "udivmodhi4" |
591702de | 9205 | [(set (match_dup 4) (const_int 0)) |
40745eec JH |
9206 | (parallel [(set (match_operand:HI 0 "register_operand" "") |
9207 | (udiv:HI (match_operand:HI 1 "register_operand" "") | |
9208 | (match_operand:HI 2 "nonimmediate_operand" ""))) | |
9209 | (set (match_operand:HI 3 "register_operand" "") | |
e075ae69 RH |
9210 | (umod:HI (match_dup 1) (match_dup 2))) |
9211 | (use (match_dup 4)) | |
8bc527af | 9212 | (clobber (reg:CC FLAGS_REG))])] |
d9f32422 | 9213 | "TARGET_HIMODE_MATH" |
e075ae69 | 9214 | "operands[4] = gen_reg_rtx (HImode);") |
886c62d1 | 9215 | |
6343a50e | 9216 | (define_insn "*udivmodhi_noext" |
e075ae69 RH |
9217 | [(set (match_operand:HI 0 "register_operand" "=a") |
9218 | (udiv:HI (match_operand:HI 1 "register_operand" "0") | |
9219 | (match_operand:HI 2 "nonimmediate_operand" "rm"))) | |
9220 | (set (match_operand:HI 3 "register_operand" "=d") | |
9221 | (umod:HI (match_dup 1) (match_dup 2))) | |
9222 | (use (match_operand:HI 4 "register_operand" "3")) | |
8bc527af | 9223 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 9224 | "" |
0f40f9f7 | 9225 | "div{w}\t%2" |
e075ae69 | 9226 | [(set_attr "type" "idiv") |
56bab446 | 9227 | (set_attr "mode" "HI")]) |
e075ae69 | 9228 | |
1e5f1716 | 9229 | ;; We cannot use div/idiv for double division, because it causes |
e075ae69 RH |
9230 | ;; "division by zero" on the overflow and that's not what we expect |
9231 | ;; from truncate. Because true (non truncating) double division is | |
9232 | ;; never generated, we can't create this insn anyway. | |
9233 | ; | |
9234 | ;(define_insn "" | |
9235 | ; [(set (match_operand:SI 0 "register_operand" "=a") | |
9236 | ; (truncate:SI | |
9237 | ; (udiv:DI (match_operand:DI 1 "register_operand" "A") | |
9238 | ; (zero_extend:DI | |
9239 | ; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) | |
9240 | ; (set (match_operand:SI 3 "register_operand" "=d") | |
9241 | ; (truncate:SI | |
9242 | ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) | |
8bc527af | 9243 | ; (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 9244 | ; "" |
0f40f9f7 | 9245 | ; "div{l}\t{%2, %0|%0, %2}" |
56bab446 | 9246 | ; [(set_attr "type" "idiv")]) |
886c62d1 | 9247 | \f |
e075ae69 RH |
9248 | ;;- Logical AND instructions |
9249 | ||
9250 | ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. | |
9251 | ;; Note that this excludes ah. | |
9252 | ||
9b70259d | 9253 | (define_insn "*testdi_1_rex64" |
42fabf21 | 9254 | [(set (reg FLAGS_REG) |
9b70259d | 9255 | (compare |
2bac97f7 | 9256 | (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") |
e1fea6ee | 9257 | (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) |
9b70259d | 9258 | (const_int 0)))] |
e1fea6ee | 9259 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 9260 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
9b70259d | 9261 | "@ |
5a0855a0 JJ |
9262 | test{l}\t{%k1, %k0|%k0, %k1} |
9263 | test{l}\t{%k1, %k0|%k0, %k1} | |
9264 | test{q}\t{%1, %0|%0, %1} | |
9265 | test{q}\t{%1, %0|%0, %1} | |
0f40f9f7 | 9266 | test{q}\t{%1, %0|%0, %1}" |
9b70259d JH |
9267 | [(set_attr "type" "test") |
9268 | (set_attr "modrm" "0,1,0,1,1") | |
9269 | (set_attr "mode" "SI,SI,DI,DI,DI") | |
9270 | (set_attr "pent_pair" "uv,np,uv,np,uv")]) | |
9076b9c1 JH |
9271 | |
9272 | (define_insn "testsi_1" | |
42fabf21 | 9273 | [(set (reg FLAGS_REG) |
9076b9c1 | 9274 | (compare |
2bac97f7 | 9275 | (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm") |
0edb82cb | 9276 | (match_operand:SI 1 "general_operand" "i,i,ri")) |
16189740 | 9277 | (const_int 0)))] |
e1fea6ee | 9278 | "ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 9279 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 9280 | "test{l}\t{%1, %0|%0, %1}" |
6ef67412 JH |
9281 | [(set_attr "type" "test") |
9282 | (set_attr "modrm" "0,1,1") | |
9283 | (set_attr "mode" "SI") | |
e075ae69 RH |
9284 | (set_attr "pent_pair" "uv,np,uv")]) |
9285 | ||
9076b9c1 | 9286 | (define_expand "testsi_ccno_1" |
8bc527af | 9287 | [(set (reg:CCNO FLAGS_REG) |
16189740 | 9288 | (compare:CCNO |
9076b9c1 JH |
9289 | (and:SI (match_operand:SI 0 "nonimmediate_operand" "") |
9290 | (match_operand:SI 1 "nonmemory_operand" "")) | |
16189740 | 9291 | (const_int 0)))] |
a1cbdd7f | 9292 | "" |
9076b9c1 | 9293 | "") |
16189740 RH |
9294 | |
9295 | (define_insn "*testhi_1" | |
42fabf21 | 9296 | [(set (reg FLAGS_REG) |
2bac97f7 | 9297 | (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm") |
e1fea6ee | 9298 | (match_operand:HI 1 "general_operand" "n,n,rn")) |
16189740 | 9299 | (const_int 0)))] |
e1fea6ee | 9300 | "ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 9301 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 9302 | "test{w}\t{%1, %0|%0, %1}" |
6ef67412 JH |
9303 | [(set_attr "type" "test") |
9304 | (set_attr "modrm" "0,1,1") | |
9305 | (set_attr "mode" "HI") | |
e075ae69 RH |
9306 | (set_attr "pent_pair" "uv,np,uv")]) |
9307 | ||
9076b9c1 | 9308 | (define_expand "testqi_ccz_1" |
8bc527af | 9309 | [(set (reg:CCZ FLAGS_REG) |
9076b9c1 JH |
9310 | (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") |
9311 | (match_operand:QI 1 "nonmemory_operand" "")) | |
9312 | (const_int 0)))] | |
16189740 | 9313 | "" |
9076b9c1 | 9314 | "") |
16189740 | 9315 | |
88d60956 | 9316 | (define_insn "*testqi_1_maybe_si" |
93330ea1 | 9317 | [(set (reg FLAGS_REG) |
88d60956 RH |
9318 | (compare |
9319 | (and:QI | |
9320 | (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") | |
9321 | (match_operand:QI 1 "general_operand" "n,n,qn,n")) | |
9322 | (const_int 0)))] | |
7656aee4 | 9323 | "!(MEM_P (operands[0]) && MEM_P (operands[1])) |
88d60956 | 9324 | && ix86_match_ccmode (insn, |
7656aee4 | 9325 | CONST_INT_P (operands[1]) |
88d60956 | 9326 | && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" |
adc88131 JJ |
9327 | { |
9328 | if (which_alternative == 3) | |
9329 | { | |
7656aee4 | 9330 | if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0) |
adc88131 | 9331 | operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); |
0f40f9f7 | 9332 | return "test{l}\t{%1, %k0|%k0, %1}"; |
adc88131 | 9333 | } |
0f40f9f7 ZW |
9334 | return "test{b}\t{%1, %0|%0, %1}"; |
9335 | } | |
6ef67412 JH |
9336 | [(set_attr "type" "test") |
9337 | (set_attr "modrm" "0,1,1,1") | |
9338 | (set_attr "mode" "QI,QI,QI,SI") | |
9339 | (set_attr "pent_pair" "uv,np,uv,np")]) | |
e075ae69 | 9340 | |
88d60956 RH |
9341 | (define_insn "*testqi_1" |
9342 | [(set (reg FLAGS_REG) | |
9343 | (compare | |
9344 | (and:QI | |
9345 | (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm") | |
9346 | (match_operand:QI 1 "general_operand" "n,n,qn")) | |
9347 | (const_int 0)))] | |
7656aee4 | 9348 | "!(MEM_P (operands[0]) && MEM_P (operands[1])) |
88d60956 RH |
9349 | && ix86_match_ccmode (insn, CCNOmode)" |
9350 | "test{b}\t{%1, %0|%0, %1}" | |
9351 | [(set_attr "type" "test") | |
9352 | (set_attr "modrm" "0,1,1") | |
9353 | (set_attr "mode" "QI") | |
9354 | (set_attr "pent_pair" "uv,np,uv")]) | |
9355 | ||
9076b9c1 | 9356 | (define_expand "testqi_ext_ccno_0" |
8bc527af | 9357 | [(set (reg:CCNO FLAGS_REG) |
9076b9c1 | 9358 | (compare:CCNO |
16189740 RH |
9359 | (and:SI |
9360 | (zero_extract:SI | |
9076b9c1 | 9361 | (match_operand 0 "ext_register_operand" "") |
16189740 RH |
9362 | (const_int 8) |
9363 | (const_int 8)) | |
9076b9c1 | 9364 | (match_operand 1 "const_int_operand" "")) |
16189740 | 9365 | (const_int 0)))] |
9076b9c1 JH |
9366 | "" |
9367 | "") | |
e075ae69 | 9368 | |
9076b9c1 | 9369 | (define_insn "*testqi_ext_0" |
42fabf21 | 9370 | [(set (reg FLAGS_REG) |
9076b9c1 | 9371 | (compare |
e075ae69 RH |
9372 | (and:SI |
9373 | (zero_extract:SI | |
d2836273 | 9374 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
9375 | (const_int 8) |
9376 | (const_int 8)) | |
9377 | (match_operand 1 "const_int_operand" "n")) | |
9378 | (const_int 0)))] | |
2f41793e | 9379 | "ix86_match_ccmode (insn, CCNOmode)" |
0f40f9f7 | 9380 | "test{b}\t{%1, %h0|%h0, %1}" |
6ef67412 JH |
9381 | [(set_attr "type" "test") |
9382 | (set_attr "mode" "QI") | |
9383 | (set_attr "length_immediate" "1") | |
725fd454 | 9384 | (set_attr "modrm" "1") |
e075ae69 RH |
9385 | (set_attr "pent_pair" "np")]) |
9386 | ||
9387 | (define_insn "*testqi_ext_1" | |
42fabf21 | 9388 | [(set (reg FLAGS_REG) |
16189740 | 9389 | (compare |
e075ae69 RH |
9390 | (and:SI |
9391 | (zero_extract:SI | |
d2836273 | 9392 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
9393 | (const_int 8) |
9394 | (const_int 8)) | |
9395 | (zero_extend:SI | |
e1fea6ee | 9396 | (match_operand:QI 1 "general_operand" "Qm"))) |
e075ae69 | 9397 | (const_int 0)))] |
e1fea6ee | 9398 | "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 9399 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 9400 | "test{b}\t{%1, %h0|%h0, %1}" |
d2836273 JH |
9401 | [(set_attr "type" "test") |
9402 | (set_attr "mode" "QI")]) | |
9403 | ||
9404 | (define_insn "*testqi_ext_1_rex64" | |
42fabf21 | 9405 | [(set (reg FLAGS_REG) |
d2836273 JH |
9406 | (compare |
9407 | (and:SI | |
9408 | (zero_extract:SI | |
9409 | (match_operand 0 "ext_register_operand" "Q") | |
9410 | (const_int 8) | |
9411 | (const_int 8)) | |
9412 | (zero_extend:SI | |
3522082b | 9413 | (match_operand:QI 1 "register_operand" "Q"))) |
d2836273 JH |
9414 | (const_int 0)))] |
9415 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" | |
0f40f9f7 | 9416 | "test{b}\t{%1, %h0|%h0, %1}" |
6ef67412 JH |
9417 | [(set_attr "type" "test") |
9418 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
9419 | |
9420 | (define_insn "*testqi_ext_2" | |
42fabf21 | 9421 | [(set (reg FLAGS_REG) |
16189740 | 9422 | (compare |
e075ae69 RH |
9423 | (and:SI |
9424 | (zero_extract:SI | |
d2836273 | 9425 | (match_operand 0 "ext_register_operand" "Q") |
e075ae69 RH |
9426 | (const_int 8) |
9427 | (const_int 8)) | |
9428 | (zero_extract:SI | |
d2836273 | 9429 | (match_operand 1 "ext_register_operand" "Q") |
e075ae69 RH |
9430 | (const_int 8) |
9431 | (const_int 8))) | |
9432 | (const_int 0)))] | |
16189740 | 9433 | "ix86_match_ccmode (insn, CCNOmode)" |
0f40f9f7 | 9434 | "test{b}\t{%h1, %h0|%h0, %h1}" |
6ef67412 JH |
9435 | [(set_attr "type" "test") |
9436 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
9437 | |
9438 | ;; Combine likes to form bit extractions for some tests. Humor it. | |
6343a50e | 9439 | (define_insn "*testqi_ext_3" |
42fabf21 | 9440 | [(set (reg FLAGS_REG) |
16189740 RH |
9441 | (compare (zero_extract:SI |
9442 | (match_operand 0 "nonimmediate_operand" "rm") | |
9443 | (match_operand:SI 1 "const_int_operand" "") | |
9444 | (match_operand:SI 2 "const_int_operand" "")) | |
9445 | (const_int 0)))] | |
9446 | "ix86_match_ccmode (insn, CCNOmode) | |
d90ee6be JJ |
9447 | && INTVAL (operands[1]) > 0 |
9448 | && INTVAL (operands[2]) >= 0 | |
9449 | && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 | |
16189740 | 9450 | && (GET_MODE (operands[0]) == SImode |
9b70259d JH |
9451 | || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) |
9452 | || GET_MODE (operands[0]) == HImode | |
9453 | || GET_MODE (operands[0]) == QImode)" | |
9454 | "#") | |
9455 | ||
9456 | (define_insn "*testqi_ext_3_rex64" | |
42fabf21 | 9457 | [(set (reg FLAGS_REG) |
9b70259d JH |
9458 | (compare (zero_extract:DI |
9459 | (match_operand 0 "nonimmediate_operand" "rm") | |
9460 | (match_operand:DI 1 "const_int_operand" "") | |
9461 | (match_operand:DI 2 "const_int_operand" "")) | |
9462 | (const_int 0)))] | |
1b0c37d7 ZW |
9463 | "TARGET_64BIT |
9464 | && ix86_match_ccmode (insn, CCNOmode) | |
d90ee6be JJ |
9465 | && INTVAL (operands[1]) > 0 |
9466 | && INTVAL (operands[2]) >= 0 | |
44cf5b6a JH |
9467 | /* Ensure that resulting mask is zero or sign extended operand. */ |
9468 | && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 | |
9469 | || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 | |
9470 | && INTVAL (operands[1]) > 32)) | |
9b70259d JH |
9471 | && (GET_MODE (operands[0]) == SImode |
9472 | || GET_MODE (operands[0]) == DImode | |
16189740 RH |
9473 | || GET_MODE (operands[0]) == HImode |
9474 | || GET_MODE (operands[0]) == QImode)" | |
e075ae69 | 9475 | "#") |
4fce8e83 | 9476 | |
e075ae69 | 9477 | (define_split |
25da5dc7 RH |
9478 | [(set (match_operand 0 "flags_reg_operand" "") |
9479 | (match_operator 1 "compare_operator" | |
9480 | [(zero_extract | |
9481 | (match_operand 2 "nonimmediate_operand" "") | |
9482 | (match_operand 3 "const_int_operand" "") | |
9483 | (match_operand 4 "const_int_operand" "")) | |
9484 | (const_int 0)]))] | |
16189740 | 9485 | "ix86_match_ccmode (insn, CCNOmode)" |
25da5dc7 | 9486 | [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] |
e075ae69 | 9487 | { |
25da5dc7 RH |
9488 | rtx val = operands[2]; |
9489 | HOST_WIDE_INT len = INTVAL (operands[3]); | |
9490 | HOST_WIDE_INT pos = INTVAL (operands[4]); | |
e075ae69 | 9491 | HOST_WIDE_INT mask; |
592188a5 | 9492 | enum machine_mode mode, submode; |
886c62d1 | 9493 | |
25da5dc7 | 9494 | mode = GET_MODE (val); |
7656aee4 | 9495 | if (MEM_P (val)) |
5bc7cd8e | 9496 | { |
e075ae69 RH |
9497 | /* ??? Combine likes to put non-volatile mem extractions in QImode |
9498 | no matter the size of the test. So find a mode that works. */ | |
25da5dc7 | 9499 | if (! MEM_VOLATILE_P (val)) |
e075ae69 RH |
9500 | { |
9501 | mode = smallest_mode_for_size (pos + len, MODE_INT); | |
25da5dc7 | 9502 | val = adjust_address (val, mode, 0); |
e075ae69 | 9503 | } |
5bc7cd8e | 9504 | } |
25da5dc7 RH |
9505 | else if (GET_CODE (val) == SUBREG |
9506 | && (submode = GET_MODE (SUBREG_REG (val)), | |
592188a5 RH |
9507 | GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) |
9508 | && pos + len <= GET_MODE_BITSIZE (submode)) | |
9509 | { | |
9510 | /* Narrow a paradoxical subreg to prevent partial register stalls. */ | |
9511 | mode = submode; | |
25da5dc7 | 9512 | val = SUBREG_REG (val); |
592188a5 | 9513 | } |
e075ae69 | 9514 | else if (mode == HImode && pos + len <= 8) |
5bc7cd8e | 9515 | { |
e075ae69 RH |
9516 | /* Small HImode tests can be converted to QImode. */ |
9517 | mode = QImode; | |
25da5dc7 | 9518 | val = gen_lowpart (QImode, val); |
5bc7cd8e SC |
9519 | } |
9520 | ||
d90ee6be JJ |
9521 | if (len == HOST_BITS_PER_WIDE_INT) |
9522 | mask = -1; | |
9523 | else | |
9524 | mask = ((HOST_WIDE_INT)1 << len) - 1; | |
9525 | mask <<= pos; | |
886c62d1 | 9526 | |
25da5dc7 | 9527 | operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); |
0f40f9f7 | 9528 | }) |
886c62d1 | 9529 | |
6c81a490 JH |
9530 | ;; Convert HImode/SImode test instructions with immediate to QImode ones. |
9531 | ;; i386 does not allow to encode test with 8bit sign extended immediate, so | |
9532 | ;; this is relatively important trick. | |
d1f87653 | 9533 | ;; Do the conversion only post-reload to avoid limiting of the register class |
6c81a490 JH |
9534 | ;; to QI regs. |
9535 | (define_split | |
25da5dc7 RH |
9536 | [(set (match_operand 0 "flags_reg_operand" "") |
9537 | (match_operator 1 "compare_operator" | |
9538 | [(and (match_operand 2 "register_operand" "") | |
9539 | (match_operand 3 "const_int_operand" "")) | |
9540 | (const_int 0)]))] | |
2f41793e | 9541 | "reload_completed |
25da5dc7 RH |
9542 | && QI_REG_P (operands[2]) |
9543 | && GET_MODE (operands[2]) != QImode | |
6c81a490 | 9544 | && ((ix86_match_ccmode (insn, CCZmode) |
25da5dc7 | 9545 | && !(INTVAL (operands[3]) & ~(255 << 8))) |
6c81a490 | 9546 | || (ix86_match_ccmode (insn, CCNOmode) |
25da5dc7 RH |
9547 | && !(INTVAL (operands[3]) & ~(127 << 8))))" |
9548 | [(set (match_dup 0) | |
9549 | (match_op_dup 1 | |
9550 | [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) | |
9551 | (match_dup 3)) | |
9552 | (const_int 0)]))] | |
9553 | "operands[2] = gen_lowpart (SImode, operands[2]); | |
9554 | operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);") | |
6c81a490 JH |
9555 | |
9556 | (define_split | |
25da5dc7 RH |
9557 | [(set (match_operand 0 "flags_reg_operand" "") |
9558 | (match_operator 1 "compare_operator" | |
9559 | [(and (match_operand 2 "nonimmediate_operand" "") | |
9560 | (match_operand 3 "const_int_operand" "")) | |
9561 | (const_int 0)]))] | |
2f41793e | 9562 | "reload_completed |
25da5dc7 RH |
9563 | && GET_MODE (operands[2]) != QImode |
9564 | && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) | |
6c81a490 | 9565 | && ((ix86_match_ccmode (insn, CCZmode) |
25da5dc7 | 9566 | && !(INTVAL (operands[3]) & ~255)) |
6c81a490 | 9567 | || (ix86_match_ccmode (insn, CCNOmode) |
25da5dc7 RH |
9568 | && !(INTVAL (operands[3]) & ~127)))" |
9569 | [(set (match_dup 0) | |
9570 | (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) | |
9571 | (const_int 0)]))] | |
9572 | "operands[2] = gen_lowpart (QImode, operands[2]); | |
9573 | operands[3] = gen_lowpart (QImode, operands[3]);") | |
6c81a490 JH |
9574 | |
9575 | ||
e075ae69 RH |
9576 | ;; %%% This used to optimize known byte-wide and operations to memory, |
9577 | ;; and sometimes to QImode registers. If this is considered useful, | |
9578 | ;; it should be done with splitters. | |
9579 | ||
9b70259d JH |
9580 | (define_expand "anddi3" |
9581 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
9582 | (and:DI (match_operand:DI 1 "nonimmediate_operand" "") | |
7ae14d31 | 9583 | (match_operand:DI 2 "x86_64_szext_general_operand" "")))] |
9b70259d JH |
9584 | "TARGET_64BIT" |
9585 | "ix86_expand_binary_operator (AND, DImode, operands); DONE;") | |
9586 | ||
9587 | (define_insn "*anddi_1_rex64" | |
9588 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") | |
9589 | (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") | |
9590 | (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) | |
8bc527af | 9591 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 9592 | "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" |
9b70259d JH |
9593 | { |
9594 | switch (get_attr_type (insn)) | |
9595 | { | |
9596 | case TYPE_IMOVX: | |
9597 | { | |
9598 | enum machine_mode mode; | |
9599 | ||
7656aee4 | 9600 | gcc_assert (CONST_INT_P (operands[2])); |
9b70259d JH |
9601 | if (INTVAL (operands[2]) == 0xff) |
9602 | mode = QImode; | |
9b70259d | 9603 | else |
7637e42c NS |
9604 | { |
9605 | gcc_assert (INTVAL (operands[2]) == 0xffff); | |
9606 | mode = HImode; | |
9607 | } | |
6300f037 | 9608 | |
9b70259d JH |
9609 | operands[1] = gen_lowpart (mode, operands[1]); |
9610 | if (mode == QImode) | |
725fd454 | 9611 | return "movz{bl|x}\t{%1, %k0|%k0, %1}"; |
9b70259d | 9612 | else |
725fd454 | 9613 | return "movz{wl|x}\t{%1, %k0|%k0, %1}"; |
9b70259d JH |
9614 | } |
9615 | ||
9616 | default: | |
7637e42c | 9617 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
9b70259d | 9618 | if (get_attr_mode (insn) == MODE_SI) |
0f40f9f7 | 9619 | return "and{l}\t{%k2, %k0|%k0, %k2}"; |
9b70259d | 9620 | else |
0f40f9f7 | 9621 | return "and{q}\t{%2, %0|%0, %2}"; |
9b70259d | 9622 | } |
0f40f9f7 | 9623 | } |
9b70259d JH |
9624 | [(set_attr "type" "alu,alu,alu,imovx") |
9625 | (set_attr "length_immediate" "*,*,*,0") | |
725fd454 JJ |
9626 | (set (attr "prefix_rex") |
9627 | (if_then_else | |
9628 | (and (eq_attr "type" "imovx") | |
9629 | (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0)) | |
9630 | (match_operand 1 "ext_QIreg_nomode_operand" ""))) | |
9631 | (const_string "1") | |
9632 | (const_string "*"))) | |
9633 | (set_attr "mode" "SI,DI,DI,SI")]) | |
9b70259d JH |
9634 | |
9635 | (define_insn "*anddi_2" | |
42fabf21 | 9636 | [(set (reg FLAGS_REG) |
9b70259d JH |
9637 | (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") |
9638 | (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) | |
9639 | (const_int 0))) | |
9640 | (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") | |
9641 | (and:DI (match_dup 1) (match_dup 2)))] | |
9642 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) | |
9643 | && ix86_binary_operator_ok (AND, DImode, operands)" | |
9644 | "@ | |
5a0855a0 JJ |
9645 | and{l}\t{%k2, %k0|%k0, %k2} |
9646 | and{q}\t{%2, %0|%0, %2} | |
0f40f9f7 | 9647 | and{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
9648 | [(set_attr "type" "alu") |
9649 | (set_attr "mode" "SI,DI,DI")]) | |
9650 | ||
e075ae69 RH |
9651 | (define_expand "andsi3" |
9652 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
9653 | (and:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
7ae14d31 | 9654 | (match_operand:SI 2 "general_operand" "")))] |
e075ae69 RH |
9655 | "" |
9656 | "ix86_expand_binary_operator (AND, SImode, operands); DONE;") | |
9657 | ||
9658 | (define_insn "*andsi_1" | |
9659 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") | |
9660 | (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") | |
9661 | (match_operand:SI 2 "general_operand" "ri,rm,L"))) | |
8bc527af | 9662 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 9663 | "ix86_binary_operator_ok (AND, SImode, operands)" |
886c62d1 | 9664 | { |
e075ae69 | 9665 | switch (get_attr_type (insn)) |
886c62d1 | 9666 | { |
e075ae69 RH |
9667 | case TYPE_IMOVX: |
9668 | { | |
9669 | enum machine_mode mode; | |
5bc7cd8e | 9670 | |
7656aee4 | 9671 | gcc_assert (CONST_INT_P (operands[2])); |
e075ae69 RH |
9672 | if (INTVAL (operands[2]) == 0xff) |
9673 | mode = QImode; | |
e075ae69 | 9674 | else |
7637e42c NS |
9675 | { |
9676 | gcc_assert (INTVAL (operands[2]) == 0xffff); | |
9677 | mode = HImode; | |
9678 | } | |
6300f037 | 9679 | |
e075ae69 RH |
9680 | operands[1] = gen_lowpart (mode, operands[1]); |
9681 | if (mode == QImode) | |
725fd454 | 9682 | return "movz{bl|x}\t{%1, %0|%0, %1}"; |
e075ae69 | 9683 | else |
725fd454 | 9684 | return "movz{wl|x}\t{%1, %0|%0, %1}"; |
e075ae69 | 9685 | } |
5bc7cd8e | 9686 | |
e075ae69 | 9687 | default: |
7637e42c | 9688 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
0f40f9f7 | 9689 | return "and{l}\t{%2, %0|%0, %2}"; |
886c62d1 | 9690 | } |
0f40f9f7 | 9691 | } |
6ef67412 | 9692 | [(set_attr "type" "alu,alu,imovx") |
725fd454 JJ |
9693 | (set (attr "prefix_rex") |
9694 | (if_then_else | |
9695 | (and (eq_attr "type" "imovx") | |
9696 | (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0)) | |
9697 | (match_operand 1 "ext_QIreg_nomode_operand" ""))) | |
9698 | (const_string "1") | |
9699 | (const_string "*"))) | |
6ef67412 JH |
9700 | (set_attr "length_immediate" "*,*,0") |
9701 | (set_attr "mode" "SI")]) | |
9702 | ||
9703 | (define_split | |
05b432db | 9704 | [(set (match_operand 0 "register_operand" "") |
9b70259d JH |
9705 | (and (match_dup 0) |
9706 | (const_int -65536))) | |
8bc527af | 9707 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 9708 | "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)" |
6ef67412 JH |
9709 | [(set (strict_low_part (match_dup 1)) (const_int 0))] |
9710 | "operands[1] = gen_lowpart (HImode, operands[0]);") | |
9711 | ||
9712 | (define_split | |
3522082b | 9713 | [(set (match_operand 0 "ext_register_operand" "") |
5e1a2fc7 | 9714 | (and (match_dup 0) |
9b70259d | 9715 | (const_int -256))) |
8bc527af | 9716 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 9717 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed" |
6ef67412 JH |
9718 | [(set (strict_low_part (match_dup 1)) (const_int 0))] |
9719 | "operands[1] = gen_lowpart (QImode, operands[0]);") | |
9720 | ||
9721 | (define_split | |
3522082b | 9722 | [(set (match_operand 0 "ext_register_operand" "") |
6ef67412 JH |
9723 | (and (match_dup 0) |
9724 | (const_int -65281))) | |
8bc527af | 9725 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 9726 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed" |
6ef67412 JH |
9727 | [(parallel [(set (zero_extract:SI (match_dup 0) |
9728 | (const_int 8) | |
9729 | (const_int 8)) | |
6300f037 | 9730 | (xor:SI |
6ef67412 JH |
9731 | (zero_extract:SI (match_dup 0) |
9732 | (const_int 8) | |
9733 | (const_int 8)) | |
9734 | (zero_extract:SI (match_dup 0) | |
9735 | (const_int 8) | |
9736 | (const_int 8)))) | |
8bc527af | 9737 | (clobber (reg:CC FLAGS_REG))])] |
6ef67412 | 9738 | "operands[0] = gen_lowpart (SImode, operands[0]);") |
e075ae69 | 9739 | |
9b70259d JH |
9740 | ;; See comment for addsi_1_zext why we do use nonimmediate_operand |
9741 | (define_insn "*andsi_1_zext" | |
9742 | [(set (match_operand:DI 0 "register_operand" "=r") | |
9743 | (zero_extend:DI | |
9744 | (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") | |
73f48658 | 9745 | (match_operand:SI 2 "general_operand" "g")))) |
8bc527af | 9746 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 9747 | "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" |
0f40f9f7 | 9748 | "and{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
9749 | [(set_attr "type" "alu") |
9750 | (set_attr "mode" "SI")]) | |
9751 | ||
e075ae69 | 9752 | (define_insn "*andsi_2" |
42fabf21 | 9753 | [(set (reg FLAGS_REG) |
16189740 | 9754 | (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") |
73f48658 | 9755 | (match_operand:SI 2 "general_operand" "g,ri")) |
16189740 | 9756 | (const_int 0))) |
e075ae69 RH |
9757 | (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") |
9758 | (and:SI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
9759 | "ix86_match_ccmode (insn, CCNOmode) |
9760 | && ix86_binary_operator_ok (AND, SImode, operands)" | |
0f40f9f7 | 9761 | "and{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
9762 | [(set_attr "type" "alu") |
9763 | (set_attr "mode" "SI")]) | |
e075ae69 | 9764 | |
9b70259d JH |
9765 | ;; See comment for addsi_1_zext why we do use nonimmediate_operand |
9766 | (define_insn "*andsi_2_zext" | |
42fabf21 | 9767 | [(set (reg FLAGS_REG) |
9b70259d | 9768 | (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") |
73f48658 | 9769 | (match_operand:SI 2 "general_operand" "g")) |
9b70259d JH |
9770 | (const_int 0))) |
9771 | (set (match_operand:DI 0 "register_operand" "=r") | |
9772 | (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] | |
9773 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) | |
9774 | && ix86_binary_operator_ok (AND, SImode, operands)" | |
0f40f9f7 | 9775 | "and{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
9776 | [(set_attr "type" "alu") |
9777 | (set_attr "mode" "SI")]) | |
9778 | ||
e075ae69 RH |
9779 | (define_expand "andhi3" |
9780 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
9781 | (and:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7ae14d31 | 9782 | (match_operand:HI 2 "general_operand" "")))] |
d9f32422 | 9783 | "TARGET_HIMODE_MATH" |
e075ae69 RH |
9784 | "ix86_expand_binary_operator (AND, HImode, operands); DONE;") |
9785 | ||
9786 | (define_insn "*andhi_1" | |
9787 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") | |
9788 | (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") | |
0edb82cb | 9789 | (match_operand:HI 2 "general_operand" "rn,rm,L"))) |
8bc527af | 9790 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 9791 | "ix86_binary_operator_ok (AND, HImode, operands)" |
886c62d1 | 9792 | { |
e075ae69 | 9793 | switch (get_attr_type (insn)) |
886c62d1 | 9794 | { |
e075ae69 | 9795 | case TYPE_IMOVX: |
7656aee4 | 9796 | gcc_assert (CONST_INT_P (operands[2])); |
7637e42c NS |
9797 | gcc_assert (INTVAL (operands[2]) == 0xff); |
9798 | return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; | |
886c62d1 | 9799 | |
e075ae69 | 9800 | default: |
7637e42c | 9801 | gcc_assert (rtx_equal_p (operands[0], operands[1])); |
886c62d1 | 9802 | |
0f40f9f7 | 9803 | return "and{w}\t{%2, %0|%0, %2}"; |
5bc7cd8e | 9804 | } |
0f40f9f7 | 9805 | } |
6ef67412 JH |
9806 | [(set_attr "type" "alu,alu,imovx") |
9807 | (set_attr "length_immediate" "*,*,0") | |
725fd454 JJ |
9808 | (set (attr "prefix_rex") |
9809 | (if_then_else | |
9810 | (and (eq_attr "type" "imovx") | |
9811 | (match_operand 1 "ext_QIreg_nomode_operand" "")) | |
9812 | (const_string "1") | |
9813 | (const_string "*"))) | |
6ef67412 | 9814 | (set_attr "mode" "HI,HI,SI")]) |
5bc7cd8e | 9815 | |
e075ae69 | 9816 | (define_insn "*andhi_2" |
42fabf21 | 9817 | [(set (reg FLAGS_REG) |
16189740 | 9818 | (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") |
0edb82cb | 9819 | (match_operand:HI 2 "general_operand" "rmn,rn")) |
16189740 | 9820 | (const_int 0))) |
e075ae69 RH |
9821 | (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") |
9822 | (and:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
9823 | "ix86_match_ccmode (insn, CCNOmode) |
9824 | && ix86_binary_operator_ok (AND, HImode, operands)" | |
0f40f9f7 | 9825 | "and{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
9826 | [(set_attr "type" "alu") |
9827 | (set_attr "mode" "HI")]) | |
5bc7cd8e | 9828 | |
e075ae69 RH |
9829 | (define_expand "andqi3" |
9830 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
9831 | (and:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7ae14d31 | 9832 | (match_operand:QI 2 "general_operand" "")))] |
d9f32422 | 9833 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
9834 | "ix86_expand_binary_operator (AND, QImode, operands); DONE;") |
9835 | ||
9836 | ;; %%% Potential partial reg stall on alternative 2. What to do? | |
9837 | (define_insn "*andqi_1" | |
7c6b971d | 9838 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") |
e075ae69 | 9839 | (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
0edb82cb | 9840 | (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) |
8bc527af | 9841 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 RH |
9842 | "ix86_binary_operator_ok (AND, QImode, operands)" |
9843 | "@ | |
0f40f9f7 ZW |
9844 | and{b}\t{%2, %0|%0, %2} |
9845 | and{b}\t{%2, %0|%0, %2} | |
9846 | and{l}\t{%k2, %k0|%k0, %k2}" | |
6ef67412 JH |
9847 | [(set_attr "type" "alu") |
9848 | (set_attr "mode" "QI,QI,SI")]) | |
e075ae69 | 9849 | |
a1b8572c JH |
9850 | (define_insn "*andqi_1_slp" |
9851 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) | |
9852 | (and:QI (match_dup 0) | |
0edb82cb | 9853 | (match_operand:QI 1 "general_operand" "qn,qmn"))) |
8bc527af | 9854 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 9855 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 9856 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 9857 | "and{b}\t{%1, %0|%0, %1}" |
a1b8572c JH |
9858 | [(set_attr "type" "alu1") |
9859 | (set_attr "mode" "QI")]) | |
9860 | ||
88d60956 | 9861 | (define_insn "*andqi_2_maybe_si" |
42fabf21 | 9862 | [(set (reg FLAGS_REG) |
16189740 | 9863 | (compare (and:QI |
88d60956 | 9864 | (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
0edb82cb | 9865 | (match_operand:QI 2 "general_operand" "qmn,qn,n")) |
16189740 | 9866 | (const_int 0))) |
e075ae69 RH |
9867 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") |
9868 | (and:QI (match_dup 1) (match_dup 2)))] | |
88d60956 RH |
9869 | "ix86_binary_operator_ok (AND, QImode, operands) |
9870 | && ix86_match_ccmode (insn, | |
7656aee4 | 9871 | CONST_INT_P (operands[2]) |
88d60956 | 9872 | && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" |
adc88131 JJ |
9873 | { |
9874 | if (which_alternative == 2) | |
9875 | { | |
7656aee4 | 9876 | if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) |
adc88131 | 9877 | operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); |
0f40f9f7 | 9878 | return "and{l}\t{%2, %k0|%k0, %2}"; |
adc88131 | 9879 | } |
0f40f9f7 ZW |
9880 | return "and{b}\t{%2, %0|%0, %2}"; |
9881 | } | |
6ef67412 JH |
9882 | [(set_attr "type" "alu") |
9883 | (set_attr "mode" "QI,QI,SI")]) | |
e075ae69 | 9884 | |
88d60956 RH |
9885 | (define_insn "*andqi_2" |
9886 | [(set (reg FLAGS_REG) | |
9887 | (compare (and:QI | |
9888 | (match_operand:QI 1 "nonimmediate_operand" "%0,0") | |
0edb82cb | 9889 | (match_operand:QI 2 "general_operand" "qmn,qn")) |
88d60956 RH |
9890 | (const_int 0))) |
9891 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") | |
9892 | (and:QI (match_dup 1) (match_dup 2)))] | |
9893 | "ix86_match_ccmode (insn, CCNOmode) | |
9894 | && ix86_binary_operator_ok (AND, QImode, operands)" | |
9895 | "and{b}\t{%2, %0|%0, %2}" | |
9896 | [(set_attr "type" "alu") | |
9897 | (set_attr "mode" "QI")]) | |
9898 | ||
a1b8572c | 9899 | (define_insn "*andqi_2_slp" |
42fabf21 | 9900 | [(set (reg FLAGS_REG) |
a1b8572c JH |
9901 | (compare (and:QI |
9902 | (match_operand:QI 0 "nonimmediate_operand" "+q,qm") | |
0edb82cb | 9903 | (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) |
a1b8572c JH |
9904 | (const_int 0))) |
9905 | (set (strict_low_part (match_dup 0)) | |
9906 | (and:QI (match_dup 0) (match_dup 1)))] | |
3debdc1e | 9907 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
1b245ade | 9908 | && ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 9909 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 9910 | "and{b}\t{%1, %0|%0, %1}" |
a1b8572c JH |
9911 | [(set_attr "type" "alu1") |
9912 | (set_attr "mode" "QI")]) | |
9913 | ||
e075ae69 RH |
9914 | ;; ??? A bug in recog prevents it from recognizing a const_int as an |
9915 | ;; operand to zero_extend in andqi_ext_1. It was checking explicitly | |
9916 | ;; for a QImode operand, which of course failed. | |
9917 | ||
9918 | (define_insn "andqi_ext_0" | |
d2836273 | 9919 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
9920 | (const_int 8) |
9921 | (const_int 8)) | |
6300f037 | 9922 | (and:SI |
e075ae69 RH |
9923 | (zero_extract:SI |
9924 | (match_operand 1 "ext_register_operand" "0") | |
9925 | (const_int 8) | |
9926 | (const_int 8)) | |
9927 | (match_operand 2 "const_int_operand" "n"))) | |
8bc527af | 9928 | (clobber (reg:CC FLAGS_REG))] |
2f41793e | 9929 | "" |
0f40f9f7 | 9930 | "and{b}\t{%2, %h0|%h0, %2}" |
6ef67412 JH |
9931 | [(set_attr "type" "alu") |
9932 | (set_attr "length_immediate" "1") | |
725fd454 | 9933 | (set_attr "modrm" "1") |
6ef67412 | 9934 | (set_attr "mode" "QI")]) |
e075ae69 RH |
9935 | |
9936 | ;; Generated by peephole translating test to and. This shows up | |
9937 | ;; often in fp comparisons. | |
9938 | ||
9939 | (define_insn "*andqi_ext_0_cc" | |
42fabf21 | 9940 | [(set (reg FLAGS_REG) |
16189740 | 9941 | (compare |
e075ae69 RH |
9942 | (and:SI |
9943 | (zero_extract:SI | |
084e679a | 9944 | (match_operand 1 "ext_register_operand" "0") |
3522082b | 9945 | (const_int 8) |
e075ae69 RH |
9946 | (const_int 8)) |
9947 | (match_operand 2 "const_int_operand" "n")) | |
9948 | (const_int 0))) | |
d2836273 | 9949 | (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
9950 | (const_int 8) |
9951 | (const_int 8)) | |
6300f037 | 9952 | (and:SI |
e075ae69 RH |
9953 | (zero_extract:SI |
9954 | (match_dup 1) | |
9955 | (const_int 8) | |
9956 | (const_int 8)) | |
9957 | (match_dup 2)))] | |
2f41793e | 9958 | "ix86_match_ccmode (insn, CCNOmode)" |
0f40f9f7 | 9959 | "and{b}\t{%2, %h0|%h0, %2}" |
6ef67412 JH |
9960 | [(set_attr "type" "alu") |
9961 | (set_attr "length_immediate" "1") | |
725fd454 | 9962 | (set_attr "modrm" "1") |
6ef67412 | 9963 | (set_attr "mode" "QI")]) |
e075ae69 RH |
9964 | |
9965 | (define_insn "*andqi_ext_1" | |
d2836273 | 9966 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
9967 | (const_int 8) |
9968 | (const_int 8)) | |
6300f037 | 9969 | (and:SI |
e075ae69 RH |
9970 | (zero_extract:SI |
9971 | (match_operand 1 "ext_register_operand" "0") | |
9972 | (const_int 8) | |
9973 | (const_int 8)) | |
9974 | (zero_extend:SI | |
d2836273 | 9975 | (match_operand:QI 2 "general_operand" "Qm")))) |
8bc527af | 9976 | (clobber (reg:CC FLAGS_REG))] |
d2836273 | 9977 | "!TARGET_64BIT" |
0f40f9f7 | 9978 | "and{b}\t{%2, %h0|%h0, %2}" |
d2836273 JH |
9979 | [(set_attr "type" "alu") |
9980 | (set_attr "length_immediate" "0") | |
9981 | (set_attr "mode" "QI")]) | |
9982 | ||
9983 | (define_insn "*andqi_ext_1_rex64" | |
9984 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
9985 | (const_int 8) | |
9986 | (const_int 8)) | |
6300f037 | 9987 | (and:SI |
d2836273 JH |
9988 | (zero_extract:SI |
9989 | (match_operand 1 "ext_register_operand" "0") | |
9990 | (const_int 8) | |
9991 | (const_int 8)) | |
9992 | (zero_extend:SI | |
3522082b | 9993 | (match_operand 2 "ext_register_operand" "Q")))) |
8bc527af | 9994 | (clobber (reg:CC FLAGS_REG))] |
d2836273 | 9995 | "TARGET_64BIT" |
0f40f9f7 | 9996 | "and{b}\t{%2, %h0|%h0, %2}" |
6ef67412 JH |
9997 | [(set_attr "type" "alu") |
9998 | (set_attr "length_immediate" "0") | |
9999 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
10000 | |
10001 | (define_insn "*andqi_ext_2" | |
d2836273 | 10002 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
e075ae69 RH |
10003 | (const_int 8) |
10004 | (const_int 8)) | |
10005 | (and:SI | |
10006 | (zero_extract:SI | |
10007 | (match_operand 1 "ext_register_operand" "%0") | |
10008 | (const_int 8) | |
10009 | (const_int 8)) | |
10010 | (zero_extract:SI | |
d2836273 | 10011 | (match_operand 2 "ext_register_operand" "Q") |
e075ae69 RH |
10012 | (const_int 8) |
10013 | (const_int 8)))) | |
8bc527af | 10014 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 10015 | "" |
0f40f9f7 | 10016 | "and{b}\t{%h2, %h0|%h0, %h2}" |
6ef67412 JH |
10017 | [(set_attr "type" "alu") |
10018 | (set_attr "length_immediate" "0") | |
10019 | (set_attr "mode" "QI")]) | |
2f41793e JH |
10020 | |
10021 | ;; Convert wide AND instructions with immediate operand to shorter QImode | |
10022 | ;; equivalents when possible. | |
d1f87653 | 10023 | ;; Don't do the splitting with memory operands, since it introduces risk |
2f41793e JH |
10024 | ;; of memory mismatch stalls. We may want to do the splitting for optimizing |
10025 | ;; for size, but that can (should?) be handled by generic code instead. | |
10026 | (define_split | |
10027 | [(set (match_operand 0 "register_operand" "") | |
10028 | (and (match_operand 1 "register_operand" "") | |
10029 | (match_operand 2 "const_int_operand" ""))) | |
8bc527af | 10030 | (clobber (reg:CC FLAGS_REG))] |
2f41793e JH |
10031 | "reload_completed |
10032 | && QI_REG_P (operands[0]) | |
3debdc1e | 10033 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
2f41793e JH |
10034 | && !(~INTVAL (operands[2]) & ~(255 << 8)) |
10035 | && GET_MODE (operands[0]) != QImode" | |
10036 | [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) | |
10037 | (and:SI (zero_extract:SI (match_dup 1) | |
10038 | (const_int 8) (const_int 8)) | |
10039 | (match_dup 2))) | |
8bc527af | 10040 | (clobber (reg:CC FLAGS_REG))])] |
2f41793e JH |
10041 | "operands[0] = gen_lowpart (SImode, operands[0]); |
10042 | operands[1] = gen_lowpart (SImode, operands[1]); | |
10043 | operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") | |
10044 | ||
10045 | ;; Since AND can be encoded with sign extended immediate, this is only | |
10046 | ;; profitable when 7th bit is not set. | |
10047 | (define_split | |
10048 | [(set (match_operand 0 "register_operand" "") | |
10049 | (and (match_operand 1 "general_operand" "") | |
10050 | (match_operand 2 "const_int_operand" ""))) | |
8bc527af | 10051 | (clobber (reg:CC FLAGS_REG))] |
2f41793e JH |
10052 | "reload_completed |
10053 | && ANY_QI_REG_P (operands[0]) | |
3debdc1e | 10054 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
2f41793e JH |
10055 | && !(~INTVAL (operands[2]) & ~255) |
10056 | && !(INTVAL (operands[2]) & 128) | |
10057 | && GET_MODE (operands[0]) != QImode" | |
10058 | [(parallel [(set (strict_low_part (match_dup 0)) | |
10059 | (and:QI (match_dup 1) | |
10060 | (match_dup 2))) | |
8bc527af | 10061 | (clobber (reg:CC FLAGS_REG))])] |
2f41793e JH |
10062 | "operands[0] = gen_lowpart (QImode, operands[0]); |
10063 | operands[1] = gen_lowpart (QImode, operands[1]); | |
10064 | operands[2] = gen_lowpart (QImode, operands[2]);") | |
886c62d1 | 10065 | \f |
e075ae69 | 10066 | ;; Logical inclusive OR instructions |
57dbca5e | 10067 | |
e075ae69 RH |
10068 | ;; %%% This used to optimize known byte-wide and operations to memory. |
10069 | ;; If this is considered useful, it should be done with splitters. | |
10070 | ||
9b70259d JH |
10071 | (define_expand "iordi3" |
10072 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
10073 | (ior:DI (match_operand:DI 1 "nonimmediate_operand" "") | |
7ae14d31 | 10074 | (match_operand:DI 2 "x86_64_general_operand" "")))] |
9b70259d JH |
10075 | "TARGET_64BIT" |
10076 | "ix86_expand_binary_operator (IOR, DImode, operands); DONE;") | |
10077 | ||
10078 | (define_insn "*iordi_1_rex64" | |
10079 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") | |
10080 | (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") | |
10081 | (match_operand:DI 2 "x86_64_general_operand" "re,rme"))) | |
8bc527af | 10082 | (clobber (reg:CC FLAGS_REG))] |
9b70259d JH |
10083 | "TARGET_64BIT |
10084 | && ix86_binary_operator_ok (IOR, DImode, operands)" | |
0f40f9f7 | 10085 | "or{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
10086 | [(set_attr "type" "alu") |
10087 | (set_attr "mode" "DI")]) | |
10088 | ||
10089 | (define_insn "*iordi_2_rex64" | |
42fabf21 | 10090 | [(set (reg FLAGS_REG) |
9b70259d JH |
10091 | (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
10092 | (match_operand:DI 2 "x86_64_general_operand" "rem,re")) | |
10093 | (const_int 0))) | |
10094 | (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") | |
10095 | (ior:DI (match_dup 1) (match_dup 2)))] | |
10096 | "TARGET_64BIT | |
10097 | && ix86_match_ccmode (insn, CCNOmode) | |
10098 | && ix86_binary_operator_ok (IOR, DImode, operands)" | |
0f40f9f7 | 10099 | "or{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
10100 | [(set_attr "type" "alu") |
10101 | (set_attr "mode" "DI")]) | |
10102 | ||
10103 | (define_insn "*iordi_3_rex64" | |
42fabf21 | 10104 | [(set (reg FLAGS_REG) |
9b70259d JH |
10105 | (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0") |
10106 | (match_operand:DI 2 "x86_64_general_operand" "rem")) | |
10107 | (const_int 0))) | |
10108 | (clobber (match_scratch:DI 0 "=r"))] | |
10109 | "TARGET_64BIT | |
10110 | && ix86_match_ccmode (insn, CCNOmode) | |
10111 | && ix86_binary_operator_ok (IOR, DImode, operands)" | |
0f40f9f7 | 10112 | "or{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
10113 | [(set_attr "type" "alu") |
10114 | (set_attr "mode" "DI")]) | |
10115 | ||
10116 | ||
e075ae69 RH |
10117 | (define_expand "iorsi3" |
10118 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
10119 | (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
7ae14d31 | 10120 | (match_operand:SI 2 "general_operand" "")))] |
57dbca5e | 10121 | "" |
e075ae69 RH |
10122 | "ix86_expand_binary_operator (IOR, SImode, operands); DONE;") |
10123 | ||
10124 | (define_insn "*iorsi_1" | |
10125 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
10126 | (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
73f48658 | 10127 | (match_operand:SI 2 "general_operand" "ri,g"))) |
8bc527af | 10128 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 10129 | "ix86_binary_operator_ok (IOR, SImode, operands)" |
0f40f9f7 | 10130 | "or{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10131 | [(set_attr "type" "alu") |
10132 | (set_attr "mode" "SI")]) | |
e075ae69 | 10133 | |
9b70259d JH |
10134 | ;; See comment for addsi_1_zext why we do use nonimmediate_operand |
10135 | (define_insn "*iorsi_1_zext" | |
a6783d12 | 10136 | [(set (match_operand:DI 0 "register_operand" "=r") |
9b70259d JH |
10137 | (zero_extend:DI |
10138 | (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") | |
73f48658 | 10139 | (match_operand:SI 2 "general_operand" "g")))) |
8bc527af | 10140 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 10141 | "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)" |
0f40f9f7 | 10142 | "or{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
10143 | [(set_attr "type" "alu") |
10144 | (set_attr "mode" "SI")]) | |
10145 | ||
10146 | (define_insn "*iorsi_1_zext_imm" | |
a6783d12 | 10147 | [(set (match_operand:DI 0 "register_operand" "=r") |
9b70259d JH |
10148 | (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) |
10149 | (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) | |
8bc527af | 10150 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 10151 | "TARGET_64BIT" |
0f40f9f7 | 10152 | "or{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
10153 | [(set_attr "type" "alu") |
10154 | (set_attr "mode" "SI")]) | |
10155 | ||
e075ae69 | 10156 | (define_insn "*iorsi_2" |
42fabf21 | 10157 | [(set (reg FLAGS_REG) |
16189740 | 10158 | (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") |
73f48658 | 10159 | (match_operand:SI 2 "general_operand" "g,ri")) |
16189740 | 10160 | (const_int 0))) |
e075ae69 RH |
10161 | (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") |
10162 | (ior:SI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
10163 | "ix86_match_ccmode (insn, CCNOmode) |
10164 | && ix86_binary_operator_ok (IOR, SImode, operands)" | |
0f40f9f7 | 10165 | "or{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10166 | [(set_attr "type" "alu") |
10167 | (set_attr "mode" "SI")]) | |
e075ae69 | 10168 | |
9b70259d JH |
10169 | ;; See comment for addsi_1_zext why we do use nonimmediate_operand |
10170 | ;; ??? Special case for immediate operand is missing - it is tricky. | |
10171 | (define_insn "*iorsi_2_zext" | |
42fabf21 | 10172 | [(set (reg FLAGS_REG) |
9b70259d | 10173 | (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") |
73f48658 | 10174 | (match_operand:SI 2 "general_operand" "g")) |
9b70259d JH |
10175 | (const_int 0))) |
10176 | (set (match_operand:DI 0 "register_operand" "=r") | |
10177 | (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))] | |
10178 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) | |
10179 | && ix86_binary_operator_ok (IOR, SImode, operands)" | |
0f40f9f7 | 10180 | "or{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
10181 | [(set_attr "type" "alu") |
10182 | (set_attr "mode" "SI")]) | |
10183 | ||
10184 | (define_insn "*iorsi_2_zext_imm" | |
42fabf21 | 10185 | [(set (reg FLAGS_REG) |
9b70259d JH |
10186 | (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") |
10187 | (match_operand 2 "x86_64_zext_immediate_operand" "Z")) | |
10188 | (const_int 0))) | |
10189 | (set (match_operand:DI 0 "register_operand" "=r") | |
10190 | (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] | |
10191 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) | |
10192 | && ix86_binary_operator_ok (IOR, SImode, operands)" | |
0f40f9f7 | 10193 | "or{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
10194 | [(set_attr "type" "alu") |
10195 | (set_attr "mode" "SI")]) | |
10196 | ||
d90ffc8d | 10197 | (define_insn "*iorsi_3" |
42fabf21 | 10198 | [(set (reg FLAGS_REG) |
d90ffc8d | 10199 | (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") |
73f48658 | 10200 | (match_operand:SI 2 "general_operand" "g")) |
d90ffc8d JH |
10201 | (const_int 0))) |
10202 | (clobber (match_scratch:SI 0 "=r"))] | |
10203 | "ix86_match_ccmode (insn, CCNOmode) | |
7656aee4 | 10204 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 10205 | "or{l}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
10206 | [(set_attr "type" "alu") |
10207 | (set_attr "mode" "SI")]) | |
10208 | ||
e075ae69 RH |
10209 | (define_expand "iorhi3" |
10210 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
10211 | (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7ae14d31 | 10212 | (match_operand:HI 2 "general_operand" "")))] |
d9f32422 | 10213 | "TARGET_HIMODE_MATH" |
e075ae69 RH |
10214 | "ix86_expand_binary_operator (IOR, HImode, operands); DONE;") |
10215 | ||
10216 | (define_insn "*iorhi_1" | |
10217 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") | |
10218 | (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
0edb82cb | 10219 | (match_operand:HI 2 "general_operand" "rmn,rn"))) |
8bc527af | 10220 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 10221 | "ix86_binary_operator_ok (IOR, HImode, operands)" |
0f40f9f7 | 10222 | "or{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10223 | [(set_attr "type" "alu") |
10224 | (set_attr "mode" "HI")]) | |
e075ae69 | 10225 | |
e075ae69 | 10226 | (define_insn "*iorhi_2" |
42fabf21 | 10227 | [(set (reg FLAGS_REG) |
16189740 | 10228 | (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") |
0edb82cb | 10229 | (match_operand:HI 2 "general_operand" "rmn,rn")) |
16189740 | 10230 | (const_int 0))) |
e075ae69 RH |
10231 | (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") |
10232 | (ior:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
10233 | "ix86_match_ccmode (insn, CCNOmode) |
10234 | && ix86_binary_operator_ok (IOR, HImode, operands)" | |
0f40f9f7 | 10235 | "or{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10236 | [(set_attr "type" "alu") |
10237 | (set_attr "mode" "HI")]) | |
e075ae69 | 10238 | |
d90ffc8d | 10239 | (define_insn "*iorhi_3" |
42fabf21 | 10240 | [(set (reg FLAGS_REG) |
d90ffc8d | 10241 | (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") |
0edb82cb | 10242 | (match_operand:HI 2 "general_operand" "rmn")) |
d90ffc8d JH |
10243 | (const_int 0))) |
10244 | (clobber (match_scratch:HI 0 "=r"))] | |
10245 | "ix86_match_ccmode (insn, CCNOmode) | |
7656aee4 | 10246 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 10247 | "or{w}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
10248 | [(set_attr "type" "alu") |
10249 | (set_attr "mode" "HI")]) | |
10250 | ||
e075ae69 RH |
10251 | (define_expand "iorqi3" |
10252 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
10253 | (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7ae14d31 | 10254 | (match_operand:QI 2 "general_operand" "")))] |
d9f32422 | 10255 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
10256 | "ix86_expand_binary_operator (IOR, QImode, operands); DONE;") |
10257 | ||
10258 | ;; %%% Potential partial reg stall on alternative 2. What to do? | |
10259 | (define_insn "*iorqi_1" | |
7c6b971d | 10260 | [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") |
e075ae69 | 10261 | (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
0edb82cb | 10262 | (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) |
8bc527af | 10263 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 RH |
10264 | "ix86_binary_operator_ok (IOR, QImode, operands)" |
10265 | "@ | |
0f40f9f7 ZW |
10266 | or{b}\t{%2, %0|%0, %2} |
10267 | or{b}\t{%2, %0|%0, %2} | |
10268 | or{l}\t{%k2, %k0|%k0, %k2}" | |
6ef67412 | 10269 | [(set_attr "type" "alu") |
a1b8572c JH |
10270 | (set_attr "mode" "QI,QI,SI")]) |
10271 | ||
10272 | (define_insn "*iorqi_1_slp" | |
10273 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) | |
10274 | (ior:QI (match_dup 0) | |
0edb82cb | 10275 | (match_operand:QI 1 "general_operand" "qmn,qn"))) |
8bc527af | 10276 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 10277 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 10278 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 10279 | "or{b}\t{%1, %0|%0, %1}" |
a1b8572c | 10280 | [(set_attr "type" "alu1") |
6ef67412 | 10281 | (set_attr "mode" "QI")]) |
e075ae69 RH |
10282 | |
10283 | (define_insn "*iorqi_2" | |
42fabf21 | 10284 | [(set (reg FLAGS_REG) |
16189740 | 10285 | (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") |
0edb82cb | 10286 | (match_operand:QI 2 "general_operand" "qmn,qn")) |
16189740 | 10287 | (const_int 0))) |
e075ae69 RH |
10288 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") |
10289 | (ior:QI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
10290 | "ix86_match_ccmode (insn, CCNOmode) |
10291 | && ix86_binary_operator_ok (IOR, QImode, operands)" | |
0f40f9f7 | 10292 | "or{b}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10293 | [(set_attr "type" "alu") |
10294 | (set_attr "mode" "QI")]) | |
d90ffc8d | 10295 | |
a1b8572c | 10296 | (define_insn "*iorqi_2_slp" |
42fabf21 | 10297 | [(set (reg FLAGS_REG) |
a1b8572c | 10298 | (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") |
0edb82cb | 10299 | (match_operand:QI 1 "general_operand" "qmn,qn")) |
a1b8572c JH |
10300 | (const_int 0))) |
10301 | (set (strict_low_part (match_dup 0)) | |
10302 | (ior:QI (match_dup 0) (match_dup 1)))] | |
3debdc1e | 10303 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
1b245ade | 10304 | && ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 10305 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
0f40f9f7 | 10306 | "or{b}\t{%1, %0|%0, %1}" |
a1b8572c JH |
10307 | [(set_attr "type" "alu1") |
10308 | (set_attr "mode" "QI")]) | |
10309 | ||
d90ffc8d | 10310 | (define_insn "*iorqi_3" |
42fabf21 | 10311 | [(set (reg FLAGS_REG) |
d90ffc8d | 10312 | (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") |
0edb82cb | 10313 | (match_operand:QI 2 "general_operand" "qmn")) |
d90ffc8d | 10314 | (const_int 0))) |
7e08e190 | 10315 | (clobber (match_scratch:QI 0 "=q"))] |
d90ffc8d | 10316 | "ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 10317 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 10318 | "or{b}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
10319 | [(set_attr "type" "alu") |
10320 | (set_attr "mode" "QI")]) | |
10321 | ||
3debdc1e | 10322 | (define_insn "*iorqi_ext_0" |
2f41793e JH |
10323 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
10324 | (const_int 8) | |
10325 | (const_int 8)) | |
6300f037 | 10326 | (ior:SI |
2f41793e JH |
10327 | (zero_extract:SI |
10328 | (match_operand 1 "ext_register_operand" "0") | |
10329 | (const_int 8) | |
10330 | (const_int 8)) | |
10331 | (match_operand 2 "const_int_operand" "n"))) | |
8bc527af | 10332 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 10333 | "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" |
2f41793e JH |
10334 | "or{b}\t{%2, %h0|%h0, %2}" |
10335 | [(set_attr "type" "alu") | |
10336 | (set_attr "length_immediate" "1") | |
725fd454 | 10337 | (set_attr "modrm" "1") |
2f41793e JH |
10338 | (set_attr "mode" "QI")]) |
10339 | ||
10340 | (define_insn "*iorqi_ext_1" | |
10341 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
10342 | (const_int 8) | |
10343 | (const_int 8)) | |
6300f037 | 10344 | (ior:SI |
2f41793e JH |
10345 | (zero_extract:SI |
10346 | (match_operand 1 "ext_register_operand" "0") | |
10347 | (const_int 8) | |
10348 | (const_int 8)) | |
10349 | (zero_extend:SI | |
10350 | (match_operand:QI 2 "general_operand" "Qm")))) | |
8bc527af | 10351 | (clobber (reg:CC FLAGS_REG))] |
2f41793e | 10352 | "!TARGET_64BIT |
3debdc1e | 10353 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" |
2f41793e JH |
10354 | "or{b}\t{%2, %h0|%h0, %2}" |
10355 | [(set_attr "type" "alu") | |
10356 | (set_attr "length_immediate" "0") | |
10357 | (set_attr "mode" "QI")]) | |
10358 | ||
10359 | (define_insn "*iorqi_ext_1_rex64" | |
10360 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
10361 | (const_int 8) | |
10362 | (const_int 8)) | |
6300f037 | 10363 | (ior:SI |
2f41793e JH |
10364 | (zero_extract:SI |
10365 | (match_operand 1 "ext_register_operand" "0") | |
10366 | (const_int 8) | |
10367 | (const_int 8)) | |
10368 | (zero_extend:SI | |
10369 | (match_operand 2 "ext_register_operand" "Q")))) | |
8bc527af | 10370 | (clobber (reg:CC FLAGS_REG))] |
2f41793e | 10371 | "TARGET_64BIT |
3debdc1e | 10372 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" |
2f41793e JH |
10373 | "or{b}\t{%2, %h0|%h0, %2}" |
10374 | [(set_attr "type" "alu") | |
10375 | (set_attr "length_immediate" "0") | |
10376 | (set_attr "mode" "QI")]) | |
10377 | ||
10378 | (define_insn "*iorqi_ext_2" | |
10379 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
10380 | (const_int 8) | |
10381 | (const_int 8)) | |
6300f037 | 10382 | (ior:SI |
2f41793e JH |
10383 | (zero_extract:SI (match_operand 1 "ext_register_operand" "0") |
10384 | (const_int 8) | |
10385 | (const_int 8)) | |
10386 | (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") | |
10387 | (const_int 8) | |
10388 | (const_int 8)))) | |
8bc527af | 10389 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 10390 | "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" |
2f41793e JH |
10391 | "ior{b}\t{%h2, %h0|%h0, %h2}" |
10392 | [(set_attr "type" "alu") | |
10393 | (set_attr "length_immediate" "0") | |
10394 | (set_attr "mode" "QI")]) | |
10395 | ||
10396 | (define_split | |
10397 | [(set (match_operand 0 "register_operand" "") | |
10398 | (ior (match_operand 1 "register_operand" "") | |
10399 | (match_operand 2 "const_int_operand" ""))) | |
8bc527af | 10400 | (clobber (reg:CC FLAGS_REG))] |
2f41793e JH |
10401 | "reload_completed |
10402 | && QI_REG_P (operands[0]) | |
3debdc1e | 10403 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
2f41793e JH |
10404 | && !(INTVAL (operands[2]) & ~(255 << 8)) |
10405 | && GET_MODE (operands[0]) != QImode" | |
10406 | [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) | |
10407 | (ior:SI (zero_extract:SI (match_dup 1) | |
10408 | (const_int 8) (const_int 8)) | |
10409 | (match_dup 2))) | |
8bc527af | 10410 | (clobber (reg:CC FLAGS_REG))])] |
2f41793e JH |
10411 | "operands[0] = gen_lowpart (SImode, operands[0]); |
10412 | operands[1] = gen_lowpart (SImode, operands[1]); | |
10413 | operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") | |
10414 | ||
10415 | ;; Since OR can be encoded with sign extended immediate, this is only | |
10416 | ;; profitable when 7th bit is set. | |
10417 | (define_split | |
10418 | [(set (match_operand 0 "register_operand" "") | |
10419 | (ior (match_operand 1 "general_operand" "") | |
10420 | (match_operand 2 "const_int_operand" ""))) | |
8bc527af | 10421 | (clobber (reg:CC FLAGS_REG))] |
2f41793e JH |
10422 | "reload_completed |
10423 | && ANY_QI_REG_P (operands[0]) | |
3debdc1e | 10424 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
2f41793e JH |
10425 | && !(INTVAL (operands[2]) & ~255) |
10426 | && (INTVAL (operands[2]) & 128) | |
10427 | && GET_MODE (operands[0]) != QImode" | |
10428 | [(parallel [(set (strict_low_part (match_dup 0)) | |
10429 | (ior:QI (match_dup 1) | |
10430 | (match_dup 2))) | |
8bc527af | 10431 | (clobber (reg:CC FLAGS_REG))])] |
2f41793e JH |
10432 | "operands[0] = gen_lowpart (QImode, operands[0]); |
10433 | operands[1] = gen_lowpart (QImode, operands[1]); | |
10434 | operands[2] = gen_lowpart (QImode, operands[2]);") | |
e075ae69 RH |
10435 | \f |
10436 | ;; Logical XOR instructions | |
a269a03c | 10437 | |
e075ae69 RH |
10438 | ;; %%% This used to optimize known byte-wide and operations to memory. |
10439 | ;; If this is considered useful, it should be done with splitters. | |
57dbca5e | 10440 | |
9b70259d JH |
10441 | (define_expand "xordi3" |
10442 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
10443 | (xor:DI (match_operand:DI 1 "nonimmediate_operand" "") | |
7ae14d31 | 10444 | (match_operand:DI 2 "x86_64_general_operand" "")))] |
9b70259d JH |
10445 | "TARGET_64BIT" |
10446 | "ix86_expand_binary_operator (XOR, DImode, operands); DONE;") | |
10447 | ||
10448 | (define_insn "*xordi_1_rex64" | |
10449 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") | |
10450 | (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") | |
10451 | (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) | |
8bc527af | 10452 | (clobber (reg:CC FLAGS_REG))] |
9b70259d JH |
10453 | "TARGET_64BIT |
10454 | && ix86_binary_operator_ok (XOR, DImode, operands)" | |
8c32cbc9 | 10455 | "xor{q}\t{%2, %0|%0, %2}" |
9b70259d | 10456 | [(set_attr "type" "alu") |
8c32cbc9 | 10457 | (set_attr "mode" "DI")]) |
9b70259d JH |
10458 | |
10459 | (define_insn "*xordi_2_rex64" | |
42fabf21 | 10460 | [(set (reg FLAGS_REG) |
9b70259d JH |
10461 | (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") |
10462 | (match_operand:DI 2 "x86_64_general_operand" "rem,re")) | |
10463 | (const_int 0))) | |
10464 | (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") | |
10465 | (xor:DI (match_dup 1) (match_dup 2)))] | |
10466 | "TARGET_64BIT | |
10467 | && ix86_match_ccmode (insn, CCNOmode) | |
10468 | && ix86_binary_operator_ok (XOR, DImode, operands)" | |
8c32cbc9 | 10469 | "xor{q}\t{%2, %0|%0, %2}" |
9b70259d | 10470 | [(set_attr "type" "alu") |
8c32cbc9 | 10471 | (set_attr "mode" "DI")]) |
9b70259d JH |
10472 | |
10473 | (define_insn "*xordi_3_rex64" | |
42fabf21 | 10474 | [(set (reg FLAGS_REG) |
9b70259d JH |
10475 | (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0") |
10476 | (match_operand:DI 2 "x86_64_general_operand" "rem")) | |
10477 | (const_int 0))) | |
10478 | (clobber (match_scratch:DI 0 "=r"))] | |
10479 | "TARGET_64BIT | |
10480 | && ix86_match_ccmode (insn, CCNOmode) | |
10481 | && ix86_binary_operator_ok (XOR, DImode, operands)" | |
0f40f9f7 | 10482 | "xor{q}\t{%2, %0|%0, %2}" |
9b70259d JH |
10483 | [(set_attr "type" "alu") |
10484 | (set_attr "mode" "DI")]) | |
10485 | ||
e075ae69 RH |
10486 | (define_expand "xorsi3" |
10487 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
10488 | (xor:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
7ae14d31 | 10489 | (match_operand:SI 2 "general_operand" "")))] |
57dbca5e | 10490 | "" |
e075ae69 | 10491 | "ix86_expand_binary_operator (XOR, SImode, operands); DONE;") |
a269a03c | 10492 | |
e075ae69 RH |
10493 | (define_insn "*xorsi_1" |
10494 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") | |
10495 | (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") | |
10496 | (match_operand:SI 2 "general_operand" "ri,rm"))) | |
8bc527af | 10497 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 10498 | "ix86_binary_operator_ok (XOR, SImode, operands)" |
0f40f9f7 | 10499 | "xor{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10500 | [(set_attr "type" "alu") |
10501 | (set_attr "mode" "SI")]) | |
e075ae69 | 10502 | |
9b70259d JH |
10503 | ;; See comment for addsi_1_zext why we do use nonimmediate_operand |
10504 | ;; Add speccase for immediates | |
10505 | (define_insn "*xorsi_1_zext" | |
10506 | [(set (match_operand:DI 0 "register_operand" "=r") | |
10507 | (zero_extend:DI | |
10508 | (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") | |
73f48658 | 10509 | (match_operand:SI 2 "general_operand" "g")))) |
8bc527af | 10510 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 10511 | "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" |
0f40f9f7 | 10512 | "xor{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
10513 | [(set_attr "type" "alu") |
10514 | (set_attr "mode" "SI")]) | |
10515 | ||
10516 | (define_insn "*xorsi_1_zext_imm" | |
10517 | [(set (match_operand:DI 0 "register_operand" "=r") | |
10518 | (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) | |
10519 | (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) | |
8bc527af | 10520 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 10521 | "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" |
0f40f9f7 | 10522 | "xor{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
10523 | [(set_attr "type" "alu") |
10524 | (set_attr "mode" "SI")]) | |
10525 | ||
e075ae69 | 10526 | (define_insn "*xorsi_2" |
42fabf21 | 10527 | [(set (reg FLAGS_REG) |
16189740 | 10528 | (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") |
73f48658 | 10529 | (match_operand:SI 2 "general_operand" "g,ri")) |
16189740 | 10530 | (const_int 0))) |
e075ae69 RH |
10531 | (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") |
10532 | (xor:SI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
10533 | "ix86_match_ccmode (insn, CCNOmode) |
10534 | && ix86_binary_operator_ok (XOR, SImode, operands)" | |
0f40f9f7 | 10535 | "xor{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10536 | [(set_attr "type" "alu") |
10537 | (set_attr "mode" "SI")]) | |
e075ae69 | 10538 | |
9b70259d JH |
10539 | ;; See comment for addsi_1_zext why we do use nonimmediate_operand |
10540 | ;; ??? Special case for immediate operand is missing - it is tricky. | |
10541 | (define_insn "*xorsi_2_zext" | |
42fabf21 | 10542 | [(set (reg FLAGS_REG) |
9b70259d | 10543 | (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") |
73f48658 | 10544 | (match_operand:SI 2 "general_operand" "g")) |
9b70259d JH |
10545 | (const_int 0))) |
10546 | (set (match_operand:DI 0 "register_operand" "=r") | |
10547 | (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))] | |
10548 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) | |
10549 | && ix86_binary_operator_ok (XOR, SImode, operands)" | |
0f40f9f7 | 10550 | "xor{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
10551 | [(set_attr "type" "alu") |
10552 | (set_attr "mode" "SI")]) | |
10553 | ||
10554 | (define_insn "*xorsi_2_zext_imm" | |
42fabf21 | 10555 | [(set (reg FLAGS_REG) |
9b70259d JH |
10556 | (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") |
10557 | (match_operand 2 "x86_64_zext_immediate_operand" "Z")) | |
10558 | (const_int 0))) | |
10559 | (set (match_operand:DI 0 "register_operand" "=r") | |
10560 | (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] | |
10561 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) | |
10562 | && ix86_binary_operator_ok (XOR, SImode, operands)" | |
0f40f9f7 | 10563 | "xor{l}\t{%2, %k0|%k0, %2}" |
9b70259d JH |
10564 | [(set_attr "type" "alu") |
10565 | (set_attr "mode" "SI")]) | |
10566 | ||
d90ffc8d | 10567 | (define_insn "*xorsi_3" |
42fabf21 | 10568 | [(set (reg FLAGS_REG) |
d90ffc8d | 10569 | (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") |
73f48658 | 10570 | (match_operand:SI 2 "general_operand" "g")) |
d90ffc8d JH |
10571 | (const_int 0))) |
10572 | (clobber (match_scratch:SI 0 "=r"))] | |
10573 | "ix86_match_ccmode (insn, CCNOmode) | |
7656aee4 | 10574 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 10575 | "xor{l}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
10576 | [(set_attr "type" "alu") |
10577 | (set_attr "mode" "SI")]) | |
10578 | ||
e075ae69 RH |
10579 | (define_expand "xorhi3" |
10580 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
10581 | (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7ae14d31 | 10582 | (match_operand:HI 2 "general_operand" "")))] |
d9f32422 | 10583 | "TARGET_HIMODE_MATH" |
e075ae69 RH |
10584 | "ix86_expand_binary_operator (XOR, HImode, operands); DONE;") |
10585 | ||
10586 | (define_insn "*xorhi_1" | |
10587 | [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") | |
10588 | (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") | |
0edb82cb | 10589 | (match_operand:HI 2 "general_operand" "rmn,rn"))) |
8bc527af | 10590 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 10591 | "ix86_binary_operator_ok (XOR, HImode, operands)" |
0f40f9f7 | 10592 | "xor{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10593 | [(set_attr "type" "alu") |
10594 | (set_attr "mode" "HI")]) | |
57dbca5e | 10595 | |
e075ae69 | 10596 | (define_insn "*xorhi_2" |
42fabf21 | 10597 | [(set (reg FLAGS_REG) |
16189740 | 10598 | (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") |
0edb82cb | 10599 | (match_operand:HI 2 "general_operand" "rmn,rn")) |
16189740 | 10600 | (const_int 0))) |
e075ae69 RH |
10601 | (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") |
10602 | (xor:HI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
10603 | "ix86_match_ccmode (insn, CCNOmode) |
10604 | && ix86_binary_operator_ok (XOR, HImode, operands)" | |
0f40f9f7 | 10605 | "xor{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10606 | [(set_attr "type" "alu") |
10607 | (set_attr "mode" "HI")]) | |
e075ae69 | 10608 | |
d90ffc8d | 10609 | (define_insn "*xorhi_3" |
42fabf21 | 10610 | [(set (reg FLAGS_REG) |
d90ffc8d | 10611 | (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") |
0edb82cb | 10612 | (match_operand:HI 2 "general_operand" "rmn")) |
d90ffc8d JH |
10613 | (const_int 0))) |
10614 | (clobber (match_scratch:HI 0 "=r"))] | |
10615 | "ix86_match_ccmode (insn, CCNOmode) | |
7656aee4 | 10616 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 10617 | "xor{w}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
10618 | [(set_attr "type" "alu") |
10619 | (set_attr "mode" "HI")]) | |
10620 | ||
e075ae69 RH |
10621 | (define_expand "xorqi3" |
10622 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
10623 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7ae14d31 | 10624 | (match_operand:QI 2 "general_operand" "")))] |
d9f32422 | 10625 | "TARGET_QIMODE_MATH" |
e075ae69 RH |
10626 | "ix86_expand_binary_operator (XOR, QImode, operands); DONE;") |
10627 | ||
10628 | ;; %%% Potential partial reg stall on alternative 2. What to do? | |
10629 | (define_insn "*xorqi_1" | |
7c6b971d | 10630 | [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") |
e075ae69 | 10631 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") |
0edb82cb | 10632 | (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) |
8bc527af | 10633 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 RH |
10634 | "ix86_binary_operator_ok (XOR, QImode, operands)" |
10635 | "@ | |
0f40f9f7 ZW |
10636 | xor{b}\t{%2, %0|%0, %2} |
10637 | xor{b}\t{%2, %0|%0, %2} | |
10638 | xor{l}\t{%k2, %k0|%k0, %k2}" | |
6ef67412 JH |
10639 | [(set_attr "type" "alu") |
10640 | (set_attr "mode" "QI,QI,SI")]) | |
10641 | ||
b6bb1d56 JH |
10642 | (define_insn "*xorqi_1_slp" |
10643 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) | |
10644 | (xor:QI (match_dup 0) | |
0edb82cb | 10645 | (match_operand:QI 1 "general_operand" "qn,qmn"))) |
8bc527af | 10646 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 10647 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 10648 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
b6bb1d56 JH |
10649 | "xor{b}\t{%1, %0|%0, %1}" |
10650 | [(set_attr "type" "alu1") | |
10651 | (set_attr "mode" "QI")]) | |
10652 | ||
3debdc1e | 10653 | (define_insn "*xorqi_ext_0" |
2f41793e JH |
10654 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
10655 | (const_int 8) | |
10656 | (const_int 8)) | |
6300f037 | 10657 | (xor:SI |
2f41793e JH |
10658 | (zero_extract:SI |
10659 | (match_operand 1 "ext_register_operand" "0") | |
10660 | (const_int 8) | |
10661 | (const_int 8)) | |
10662 | (match_operand 2 "const_int_operand" "n"))) | |
8bc527af | 10663 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 10664 | "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" |
2f41793e JH |
10665 | "xor{b}\t{%2, %h0|%h0, %2}" |
10666 | [(set_attr "type" "alu") | |
10667 | (set_attr "length_immediate" "1") | |
725fd454 | 10668 | (set_attr "modrm" "1") |
2f41793e JH |
10669 | (set_attr "mode" "QI")]) |
10670 | ||
a4414093 | 10671 | (define_insn "*xorqi_ext_1" |
2f41793e JH |
10672 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
10673 | (const_int 8) | |
10674 | (const_int 8)) | |
6300f037 | 10675 | (xor:SI |
2f41793e JH |
10676 | (zero_extract:SI |
10677 | (match_operand 1 "ext_register_operand" "0") | |
10678 | (const_int 8) | |
10679 | (const_int 8)) | |
10680 | (zero_extend:SI | |
10681 | (match_operand:QI 2 "general_operand" "Qm")))) | |
8bc527af | 10682 | (clobber (reg:CC FLAGS_REG))] |
2f41793e | 10683 | "!TARGET_64BIT |
3debdc1e | 10684 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" |
2f41793e JH |
10685 | "xor{b}\t{%2, %h0|%h0, %2}" |
10686 | [(set_attr "type" "alu") | |
10687 | (set_attr "length_immediate" "0") | |
10688 | (set_attr "mode" "QI")]) | |
10689 | ||
10690 | (define_insn "*xorqi_ext_1_rex64" | |
10691 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
10692 | (const_int 8) | |
10693 | (const_int 8)) | |
6300f037 | 10694 | (xor:SI |
2f41793e JH |
10695 | (zero_extract:SI |
10696 | (match_operand 1 "ext_register_operand" "0") | |
10697 | (const_int 8) | |
10698 | (const_int 8)) | |
10699 | (zero_extend:SI | |
10700 | (match_operand 2 "ext_register_operand" "Q")))) | |
8bc527af | 10701 | (clobber (reg:CC FLAGS_REG))] |
2f41793e | 10702 | "TARGET_64BIT |
3debdc1e | 10703 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" |
2f41793e JH |
10704 | "xor{b}\t{%2, %h0|%h0, %2}" |
10705 | [(set_attr "type" "alu") | |
10706 | (set_attr "length_immediate" "0") | |
10707 | (set_attr "mode" "QI")]) | |
10708 | ||
10709 | (define_insn "*xorqi_ext_2" | |
d2836273 | 10710 | [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") |
6ef67412 JH |
10711 | (const_int 8) |
10712 | (const_int 8)) | |
6300f037 | 10713 | (xor:SI |
6ef67412 JH |
10714 | (zero_extract:SI (match_operand 1 "ext_register_operand" "0") |
10715 | (const_int 8) | |
10716 | (const_int 8)) | |
d2836273 | 10717 | (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") |
6ef67412 JH |
10718 | (const_int 8) |
10719 | (const_int 8)))) | |
8bc527af | 10720 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 10721 | "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))" |
0f40f9f7 | 10722 | "xor{b}\t{%h2, %h0|%h0, %h2}" |
6ef67412 JH |
10723 | [(set_attr "type" "alu") |
10724 | (set_attr "length_immediate" "0") | |
10725 | (set_attr "mode" "QI")]) | |
e075ae69 | 10726 | |
7abd4e00 | 10727 | (define_insn "*xorqi_cc_1" |
42fabf21 | 10728 | [(set (reg FLAGS_REG) |
16189740 | 10729 | (compare |
e075ae69 | 10730 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") |
0edb82cb | 10731 | (match_operand:QI 2 "general_operand" "qmn,qn")) |
e075ae69 RH |
10732 | (const_int 0))) |
10733 | (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") | |
10734 | (xor:QI (match_dup 1) (match_dup 2)))] | |
16189740 RH |
10735 | "ix86_match_ccmode (insn, CCNOmode) |
10736 | && ix86_binary_operator_ok (XOR, QImode, operands)" | |
0f40f9f7 | 10737 | "xor{b}\t{%2, %0|%0, %2}" |
6ef67412 JH |
10738 | [(set_attr "type" "alu") |
10739 | (set_attr "mode" "QI")]) | |
e075ae69 | 10740 | |
b6bb1d56 | 10741 | (define_insn "*xorqi_2_slp" |
42fabf21 | 10742 | [(set (reg FLAGS_REG) |
b6bb1d56 | 10743 | (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") |
0edb82cb | 10744 | (match_operand:QI 1 "general_operand" "qmn,qn")) |
b6bb1d56 JH |
10745 | (const_int 0))) |
10746 | (set (strict_low_part (match_dup 0)) | |
10747 | (xor:QI (match_dup 0) (match_dup 1)))] | |
3debdc1e | 10748 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
1b245ade | 10749 | && ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 10750 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
b6bb1d56 JH |
10751 | "xor{b}\t{%1, %0|%0, %1}" |
10752 | [(set_attr "type" "alu1") | |
10753 | (set_attr "mode" "QI")]) | |
10754 | ||
d90ffc8d | 10755 | (define_insn "*xorqi_cc_2" |
42fabf21 | 10756 | [(set (reg FLAGS_REG) |
d90ffc8d JH |
10757 | (compare |
10758 | (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") | |
0edb82cb | 10759 | (match_operand:QI 2 "general_operand" "qmn")) |
d90ffc8d | 10760 | (const_int 0))) |
7e08e190 | 10761 | (clobber (match_scratch:QI 0 "=q"))] |
d90ffc8d | 10762 | "ix86_match_ccmode (insn, CCNOmode) |
7656aee4 | 10763 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
0f40f9f7 | 10764 | "xor{b}\t{%2, %0|%0, %2}" |
d90ffc8d JH |
10765 | [(set_attr "type" "alu") |
10766 | (set_attr "mode" "QI")]) | |
10767 | ||
9076b9c1 | 10768 | (define_insn "*xorqi_cc_ext_1" |
42fabf21 | 10769 | [(set (reg FLAGS_REG) |
9076b9c1 | 10770 | (compare |
e075ae69 RH |
10771 | (xor:SI |
10772 | (zero_extract:SI | |
10773 | (match_operand 1 "ext_register_operand" "0") | |
10774 | (const_int 8) | |
10775 | (const_int 8)) | |
10776 | (match_operand:QI 2 "general_operand" "qmn")) | |
10777 | (const_int 0))) | |
10778 | (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") | |
10779 | (const_int 8) | |
10780 | (const_int 8)) | |
6300f037 | 10781 | (xor:SI |
e075ae69 RH |
10782 | (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) |
10783 | (match_dup 2)))] | |
d2836273 | 10784 | "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" |
0f40f9f7 | 10785 | "xor{b}\t{%2, %h0|%h0, %2}" |
d2836273 | 10786 | [(set_attr "type" "alu") |
725fd454 | 10787 | (set_attr "modrm" "1") |
d2836273 JH |
10788 | (set_attr "mode" "QI")]) |
10789 | ||
10790 | (define_insn "*xorqi_cc_ext_1_rex64" | |
42fabf21 | 10791 | [(set (reg FLAGS_REG) |
d2836273 JH |
10792 | (compare |
10793 | (xor:SI | |
10794 | (zero_extract:SI | |
10795 | (match_operand 1 "ext_register_operand" "0") | |
10796 | (const_int 8) | |
10797 | (const_int 8)) | |
10798 | (match_operand:QI 2 "nonmemory_operand" "Qn")) | |
10799 | (const_int 0))) | |
10800 | (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") | |
10801 | (const_int 8) | |
10802 | (const_int 8)) | |
6300f037 | 10803 | (xor:SI |
d2836273 JH |
10804 | (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) |
10805 | (match_dup 2)))] | |
10806 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" | |
0f40f9f7 | 10807 | "xor{b}\t{%2, %h0|%h0, %2}" |
6ef67412 | 10808 | [(set_attr "type" "alu") |
725fd454 | 10809 | (set_attr "modrm" "1") |
6ef67412 | 10810 | (set_attr "mode" "QI")]) |
9076b9c1 JH |
10811 | |
10812 | (define_expand "xorqi_cc_ext_1" | |
10813 | [(parallel [ | |
8bc527af | 10814 | (set (reg:CCNO FLAGS_REG) |
9076b9c1 JH |
10815 | (compare:CCNO |
10816 | (xor:SI | |
10817 | (zero_extract:SI | |
10818 | (match_operand 1 "ext_register_operand" "") | |
10819 | (const_int 8) | |
10820 | (const_int 8)) | |
10821 | (match_operand:QI 2 "general_operand" "")) | |
10822 | (const_int 0))) | |
10823 | (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") | |
10824 | (const_int 8) | |
10825 | (const_int 8)) | |
6300f037 | 10826 | (xor:SI |
9076b9c1 JH |
10827 | (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) |
10828 | (match_dup 2)))])] | |
10829 | "" | |
10830 | "") | |
2f41793e JH |
10831 | |
10832 | (define_split | |
10833 | [(set (match_operand 0 "register_operand" "") | |
10834 | (xor (match_operand 1 "register_operand" "") | |
10835 | (match_operand 2 "const_int_operand" ""))) | |
8bc527af | 10836 | (clobber (reg:CC FLAGS_REG))] |
2f41793e JH |
10837 | "reload_completed |
10838 | && QI_REG_P (operands[0]) | |
3debdc1e | 10839 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
2f41793e JH |
10840 | && !(INTVAL (operands[2]) & ~(255 << 8)) |
10841 | && GET_MODE (operands[0]) != QImode" | |
10842 | [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) | |
10843 | (xor:SI (zero_extract:SI (match_dup 1) | |
10844 | (const_int 8) (const_int 8)) | |
10845 | (match_dup 2))) | |
8bc527af | 10846 | (clobber (reg:CC FLAGS_REG))])] |
2f41793e JH |
10847 | "operands[0] = gen_lowpart (SImode, operands[0]); |
10848 | operands[1] = gen_lowpart (SImode, operands[1]); | |
10849 | operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") | |
10850 | ||
10851 | ;; Since XOR can be encoded with sign extended immediate, this is only | |
10852 | ;; profitable when 7th bit is set. | |
10853 | (define_split | |
10854 | [(set (match_operand 0 "register_operand" "") | |
10855 | (xor (match_operand 1 "general_operand" "") | |
10856 | (match_operand 2 "const_int_operand" ""))) | |
8bc527af | 10857 | (clobber (reg:CC FLAGS_REG))] |
2f41793e JH |
10858 | "reload_completed |
10859 | && ANY_QI_REG_P (operands[0]) | |
3debdc1e | 10860 | && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
2f41793e JH |
10861 | && !(INTVAL (operands[2]) & ~255) |
10862 | && (INTVAL (operands[2]) & 128) | |
10863 | && GET_MODE (operands[0]) != QImode" | |
10864 | [(parallel [(set (strict_low_part (match_dup 0)) | |
10865 | (xor:QI (match_dup 1) | |
10866 | (match_dup 2))) | |
8bc527af | 10867 | (clobber (reg:CC FLAGS_REG))])] |
2f41793e JH |
10868 | "operands[0] = gen_lowpart (QImode, operands[0]); |
10869 | operands[1] = gen_lowpart (QImode, operands[1]); | |
10870 | operands[2] = gen_lowpart (QImode, operands[2]);") | |
e075ae69 RH |
10871 | \f |
10872 | ;; Negation instructions | |
57dbca5e | 10873 | |
28356f52 | 10874 | (define_expand "negti2" |
7ae14d31 UB |
10875 | [(set (match_operand:TI 0 "nonimmediate_operand" "") |
10876 | (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))] | |
28356f52 JB |
10877 | "TARGET_64BIT" |
10878 | "ix86_expand_unary_operator (NEG, TImode, operands); DONE;") | |
10879 | ||
10880 | (define_insn "*negti2_1" | |
10881 | [(set (match_operand:TI 0 "nonimmediate_operand" "=ro") | |
68b8830a | 10882 | (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0"))) |
28356f52 JB |
10883 | (clobber (reg:CC FLAGS_REG))] |
10884 | "TARGET_64BIT | |
10885 | && ix86_unary_operator_ok (NEG, TImode, operands)" | |
10886 | "#") | |
10887 | ||
10888 | (define_split | |
10889 | [(set (match_operand:TI 0 "nonimmediate_operand" "") | |
68b8830a | 10890 | (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) |
28356f52 JB |
10891 | (clobber (reg:CC FLAGS_REG))] |
10892 | "TARGET_64BIT && reload_completed" | |
10893 | [(parallel | |
10894 | [(set (reg:CCZ FLAGS_REG) | |
c2b814b9 UB |
10895 | (compare:CCZ (neg:DI (match_dup 1)) (const_int 0))) |
10896 | (set (match_dup 0) (neg:DI (match_dup 1)))]) | |
28356f52 | 10897 | (parallel |
c2b814b9 | 10898 | [(set (match_dup 2) |
28356f52 JB |
10899 | (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) |
10900 | (match_dup 3)) | |
10901 | (const_int 0))) | |
10902 | (clobber (reg:CC FLAGS_REG))]) | |
10903 | (parallel | |
c2b814b9 UB |
10904 | [(set (match_dup 2) |
10905 | (neg:DI (match_dup 2))) | |
28356f52 | 10906 | (clobber (reg:CC FLAGS_REG))])] |
c2b814b9 | 10907 | "split_ti (&operands[0], 2, &operands[0], &operands[2]);") |
28356f52 | 10908 | |
06a964de | 10909 | (define_expand "negdi2" |
7ae14d31 UB |
10910 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
10911 | (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))] | |
06a964de JH |
10912 | "" |
10913 | "ix86_expand_unary_operator (NEG, DImode, operands); DONE;") | |
10914 | ||
10915 | (define_insn "*negdi2_1" | |
e075ae69 RH |
10916 | [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") |
10917 | (neg:DI (match_operand:DI 1 "general_operand" "0"))) | |
8bc527af | 10918 | (clobber (reg:CC FLAGS_REG))] |
d2836273 JH |
10919 | "!TARGET_64BIT |
10920 | && ix86_unary_operator_ok (NEG, DImode, operands)" | |
e075ae69 | 10921 | "#") |
886c62d1 | 10922 | |
e075ae69 RH |
10923 | (define_split |
10924 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
10925 | (neg:DI (match_operand:DI 1 "general_operand" ""))) | |
8bc527af | 10926 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 10927 | "!TARGET_64BIT && reload_completed" |
e075ae69 | 10928 | [(parallel |
8bc527af | 10929 | [(set (reg:CCZ FLAGS_REG) |
c2b814b9 UB |
10930 | (compare:CCZ (neg:SI (match_dup 1)) (const_int 0))) |
10931 | (set (match_dup 0) (neg:SI (match_dup 1)))]) | |
e075ae69 | 10932 | (parallel |
c2b814b9 | 10933 | [(set (match_dup 2) |
8bc527af | 10934 | (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) |
9dcbdc7e JH |
10935 | (match_dup 3)) |
10936 | (const_int 0))) | |
8bc527af | 10937 | (clobber (reg:CC FLAGS_REG))]) |
e075ae69 | 10938 | (parallel |
c2b814b9 UB |
10939 | [(set (match_dup 2) |
10940 | (neg:SI (match_dup 2))) | |
8bc527af | 10941 | (clobber (reg:CC FLAGS_REG))])] |
c2b814b9 | 10942 | "split_di (&operands[0], 2, &operands[0], &operands[2]);"); |
886c62d1 | 10943 | |
9b70259d JH |
10944 | (define_insn "*negdi2_1_rex64" |
10945 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
10946 | (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))) | |
8bc527af | 10947 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 10948 | "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" |
0f40f9f7 | 10949 | "neg{q}\t%0" |
9b70259d JH |
10950 | [(set_attr "type" "negnot") |
10951 | (set_attr "mode" "DI")]) | |
10952 | ||
10953 | ;; The problem with neg is that it does not perform (compare x 0), | |
10954 | ;; it really performs (compare 0 x), which leaves us with the zero | |
10955 | ;; flag being the only useful item. | |
10956 | ||
10957 | (define_insn "*negdi2_cmpz_rex64" | |
8bc527af | 10958 | [(set (reg:CCZ FLAGS_REG) |
9b70259d JH |
10959 | (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")) |
10960 | (const_int 0))) | |
10961 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
10962 | (neg:DI (match_dup 1)))] | |
10963 | "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" | |
0f40f9f7 | 10964 | "neg{q}\t%0" |
9b70259d JH |
10965 | [(set_attr "type" "negnot") |
10966 | (set_attr "mode" "DI")]) | |
10967 | ||
10968 | ||
06a964de | 10969 | (define_expand "negsi2" |
7ae14d31 UB |
10970 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
10971 | (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))] | |
06a964de JH |
10972 | "" |
10973 | "ix86_expand_unary_operator (NEG, SImode, operands); DONE;") | |
10974 | ||
10975 | (define_insn "*negsi2_1" | |
2ae0f82c | 10976 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 10977 | (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))) |
8bc527af | 10978 | (clobber (reg:CC FLAGS_REG))] |
06a964de | 10979 | "ix86_unary_operator_ok (NEG, SImode, operands)" |
0f40f9f7 | 10980 | "neg{l}\t%0" |
6ef67412 JH |
10981 | [(set_attr "type" "negnot") |
10982 | (set_attr "mode" "SI")]) | |
e075ae69 | 10983 | |
9b70259d JH |
10984 | ;; Combine is quite creative about this pattern. |
10985 | (define_insn "*negsi2_1_zext" | |
10986 | [(set (match_operand:DI 0 "register_operand" "=r") | |
10987 | (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") | |
10988 | (const_int 32))) | |
10989 | (const_int 32))) | |
8bc527af | 10990 | (clobber (reg:CC FLAGS_REG))] |
9b70259d | 10991 | "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" |
0f40f9f7 | 10992 | "neg{l}\t%k0" |
9b70259d JH |
10993 | [(set_attr "type" "negnot") |
10994 | (set_attr "mode" "SI")]) | |
10995 | ||
16189740 RH |
10996 | ;; The problem with neg is that it does not perform (compare x 0), |
10997 | ;; it really performs (compare 0 x), which leaves us with the zero | |
10998 | ;; flag being the only useful item. | |
e075ae69 | 10999 | |
16189740 | 11000 | (define_insn "*negsi2_cmpz" |
8bc527af | 11001 | [(set (reg:CCZ FLAGS_REG) |
16189740 RH |
11002 | (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")) |
11003 | (const_int 0))) | |
e075ae69 RH |
11004 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
11005 | (neg:SI (match_dup 1)))] | |
06a964de | 11006 | "ix86_unary_operator_ok (NEG, SImode, operands)" |
0f40f9f7 | 11007 | "neg{l}\t%0" |
6ef67412 JH |
11008 | [(set_attr "type" "negnot") |
11009 | (set_attr "mode" "SI")]) | |
886c62d1 | 11010 | |
9b70259d | 11011 | (define_insn "*negsi2_cmpz_zext" |
8bc527af | 11012 | [(set (reg:CCZ FLAGS_REG) |
9b70259d JH |
11013 | (compare:CCZ (lshiftrt:DI |
11014 | (neg:DI (ashift:DI | |
11015 | (match_operand:DI 1 "register_operand" "0") | |
11016 | (const_int 32))) | |
11017 | (const_int 32)) | |
11018 | (const_int 0))) | |
11019 | (set (match_operand:DI 0 "register_operand" "=r") | |
11020 | (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) | |
11021 | (const_int 32))) | |
11022 | (const_int 32)))] | |
11023 | "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" | |
0f40f9f7 | 11024 | "neg{l}\t%k0" |
9b70259d JH |
11025 | [(set_attr "type" "negnot") |
11026 | (set_attr "mode" "SI")]) | |
11027 | ||
06a964de | 11028 | (define_expand "neghi2" |
7ae14d31 UB |
11029 | [(set (match_operand:HI 0 "nonimmediate_operand" "") |
11030 | (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))] | |
d9f32422 | 11031 | "TARGET_HIMODE_MATH" |
06a964de JH |
11032 | "ix86_expand_unary_operator (NEG, HImode, operands); DONE;") |
11033 | ||
11034 | (define_insn "*neghi2_1" | |
2ae0f82c | 11035 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 11036 | (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))) |
8bc527af | 11037 | (clobber (reg:CC FLAGS_REG))] |
06a964de | 11038 | "ix86_unary_operator_ok (NEG, HImode, operands)" |
0f40f9f7 | 11039 | "neg{w}\t%0" |
6ef67412 JH |
11040 | [(set_attr "type" "negnot") |
11041 | (set_attr "mode" "HI")]) | |
e075ae69 | 11042 | |
16189740 | 11043 | (define_insn "*neghi2_cmpz" |
8bc527af | 11044 | [(set (reg:CCZ FLAGS_REG) |
16189740 RH |
11045 | (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")) |
11046 | (const_int 0))) | |
e075ae69 RH |
11047 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
11048 | (neg:HI (match_dup 1)))] | |
06a964de | 11049 | "ix86_unary_operator_ok (NEG, HImode, operands)" |
0f40f9f7 | 11050 | "neg{w}\t%0" |
6ef67412 JH |
11051 | [(set_attr "type" "negnot") |
11052 | (set_attr "mode" "HI")]) | |
886c62d1 | 11053 | |
06a964de | 11054 | (define_expand "negqi2" |
7ae14d31 UB |
11055 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
11056 | (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
d9f32422 | 11057 | "TARGET_QIMODE_MATH" |
06a964de JH |
11058 | "ix86_expand_unary_operator (NEG, QImode, operands); DONE;") |
11059 | ||
11060 | (define_insn "*negqi2_1" | |
2ae0f82c | 11061 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
e075ae69 | 11062 | (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))) |
8bc527af | 11063 | (clobber (reg:CC FLAGS_REG))] |
06a964de | 11064 | "ix86_unary_operator_ok (NEG, QImode, operands)" |
0f40f9f7 | 11065 | "neg{b}\t%0" |
6ef67412 JH |
11066 | [(set_attr "type" "negnot") |
11067 | (set_attr "mode" "QI")]) | |
e075ae69 | 11068 | |
16189740 | 11069 | (define_insn "*negqi2_cmpz" |
8bc527af | 11070 | [(set (reg:CCZ FLAGS_REG) |
16189740 RH |
11071 | (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")) |
11072 | (const_int 0))) | |
e075ae69 RH |
11073 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
11074 | (neg:QI (match_dup 1)))] | |
06a964de | 11075 | "ix86_unary_operator_ok (NEG, QImode, operands)" |
0f40f9f7 | 11076 | "neg{b}\t%0" |
6ef67412 JH |
11077 | [(set_attr "type" "negnot") |
11078 | (set_attr "mode" "QI")]) | |
886c62d1 | 11079 | |
06a964de | 11080 | ;; Changing of sign for FP values is doable using integer unit too. |
1ce485ec | 11081 | |
6dd18eb1 | 11082 | (define_expand "<code><mode>2" |
6b761851 | 11083 | [(set (match_operand:X87MODEF 0 "register_operand" "") |
6dd18eb1 | 11084 | (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))] |
6b761851 | 11085 | "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" |
6dd18eb1 | 11086 | "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") |
b3298882 | 11087 | |
6b761851 UB |
11088 | (define_insn "*absneg<mode>2_mixed" |
11089 | [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r") | |
11090 | (match_operator:MODEF 3 "absneg_operator" | |
11091 | [(match_operand:MODEF 1 "register_operand" "0,x,0,0")])) | |
11092 | (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X")) | |
8bc527af | 11093 | (clobber (reg:CC FLAGS_REG))] |
6b761851 | 11094 | "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)" |
141e454b JH |
11095 | "#") |
11096 | ||
6b761851 UB |
11097 | (define_insn "*absneg<mode>2_sse" |
11098 | [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r") | |
11099 | (match_operator:MODEF 3 "absneg_operator" | |
11100 | [(match_operand:MODEF 1 "register_operand" "0 ,x,0")])) | |
11101 | (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X")) | |
8bc527af | 11102 | (clobber (reg:CC FLAGS_REG))] |
6b761851 | 11103 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" |
b3298882 JH |
11104 | "#") |
11105 | ||
6b761851 UB |
11106 | (define_insn "*absneg<mode>2_i387" |
11107 | [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r") | |
11108 | (match_operator:X87MODEF 3 "absneg_operator" | |
11109 | [(match_operand:X87MODEF 1 "register_operand" "0,0")])) | |
7cacf53e | 11110 | (use (match_operand 2 "" "")) |
8bc527af | 11111 | (clobber (reg:CC FLAGS_REG))] |
6b761851 | 11112 | "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" |
7cacf53e RH |
11113 | "#") |
11114 | ||
6dd18eb1 | 11115 | (define_expand "<code>tf2" |
6b761851 | 11116 | [(set (match_operand:TF 0 "register_operand" "") |
6dd18eb1 | 11117 | (absneg:TF (match_operand:TF 1 "register_operand" "")))] |
5bb77598 | 11118 | "TARGET_SSE2" |
6dd18eb1 | 11119 | "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") |
edc5bbcd UB |
11120 | |
11121 | (define_insn "*absnegtf2_sse" | |
6b761851 | 11122 | [(set (match_operand:TF 0 "register_operand" "=x,x") |
edc5bbcd | 11123 | (match_operator:TF 3 "absneg_operator" |
6b761851 UB |
11124 | [(match_operand:TF 1 "register_operand" "0,x")])) |
11125 | (use (match_operand:TF 2 "nonimmediate_operand" "xm,0")) | |
edc5bbcd | 11126 | (clobber (reg:CC FLAGS_REG))] |
5bb77598 | 11127 | "TARGET_SSE2" |
edc5bbcd UB |
11128 | "#") |
11129 | ||
7cacf53e | 11130 | ;; Splitters for fp abs and neg. |
b3298882 | 11131 | |
141e454b | 11132 | (define_split |
7cacf53e RH |
11133 | [(set (match_operand 0 "fp_register_operand" "") |
11134 | (match_operator 1 "absneg_operator" [(match_dup 0)])) | |
11135 | (use (match_operand 2 "" "")) | |
8bc527af | 11136 | (clobber (reg:CC FLAGS_REG))] |
7cacf53e RH |
11137 | "reload_completed" |
11138 | [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) | |
141e454b | 11139 | |
b3298882 | 11140 | (define_split |
7cacf53e RH |
11141 | [(set (match_operand 0 "register_operand" "") |
11142 | (match_operator 3 "absneg_operator" | |
11143 | [(match_operand 1 "register_operand" "")])) | |
11144 | (use (match_operand 2 "nonimmediate_operand" "")) | |
8bc527af | 11145 | (clobber (reg:CC FLAGS_REG))] |
b3298882 | 11146 | "reload_completed && SSE_REG_P (operands[0])" |
7cacf53e | 11147 | [(set (match_dup 0) (match_dup 3))] |
b3298882 | 11148 | { |
7cacf53e RH |
11149 | enum machine_mode mode = GET_MODE (operands[0]); |
11150 | enum machine_mode vmode = GET_MODE (operands[2]); | |
11151 | rtx tmp; | |
6300f037 | 11152 | |
7cacf53e RH |
11153 | operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); |
11154 | operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); | |
b3298882 JH |
11155 | if (operands_match_p (operands[0], operands[2])) |
11156 | { | |
b3298882 JH |
11157 | tmp = operands[1]; |
11158 | operands[1] = operands[2]; | |
11159 | operands[2] = tmp; | |
11160 | } | |
7cacf53e RH |
11161 | if (GET_CODE (operands[3]) == ABS) |
11162 | tmp = gen_rtx_AND (vmode, operands[1], operands[2]); | |
11163 | else | |
11164 | tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); | |
11165 | operands[3] = tmp; | |
0f40f9f7 | 11166 | }) |
06a964de | 11167 | |
1ce485ec | 11168 | (define_split |
7cacf53e RH |
11169 | [(set (match_operand:SF 0 "register_operand" "") |
11170 | (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) | |
11171 | (use (match_operand:V4SF 2 "" "")) | |
8bc527af | 11172 | (clobber (reg:CC FLAGS_REG))] |
7cacf53e RH |
11173 | "reload_completed" |
11174 | [(parallel [(set (match_dup 0) (match_dup 1)) | |
11175 | (clobber (reg:CC FLAGS_REG))])] | |
6300f037 | 11176 | { |
7cacf53e RH |
11177 | rtx tmp; |
11178 | operands[0] = gen_lowpart (SImode, operands[0]); | |
11179 | if (GET_CODE (operands[1]) == ABS) | |
11180 | { | |
11181 | tmp = gen_int_mode (0x7fffffff, SImode); | |
11182 | tmp = gen_rtx_AND (SImode, operands[0], tmp); | |
11183 | } | |
11184 | else | |
11185 | { | |
11186 | tmp = gen_int_mode (0x80000000, SImode); | |
11187 | tmp = gen_rtx_XOR (SImode, operands[0], tmp); | |
11188 | } | |
11189 | operands[1] = tmp; | |
11190 | }) | |
1ce485ec JH |
11191 | |
11192 | (define_split | |
7cacf53e RH |
11193 | [(set (match_operand:DF 0 "register_operand" "") |
11194 | (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) | |
11195 | (use (match_operand 2 "" "")) | |
8bc527af | 11196 | (clobber (reg:CC FLAGS_REG))] |
7cacf53e RH |
11197 | "reload_completed" |
11198 | [(parallel [(set (match_dup 0) (match_dup 1)) | |
8bc527af | 11199 | (clobber (reg:CC FLAGS_REG))])] |
7cacf53e RH |
11200 | { |
11201 | rtx tmp; | |
11202 | if (TARGET_64BIT) | |
11203 | { | |
11204 | tmp = gen_lowpart (DImode, operands[0]); | |
11205 | tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); | |
11206 | operands[0] = tmp; | |
2b589241 | 11207 | |
7cacf53e RH |
11208 | if (GET_CODE (operands[1]) == ABS) |
11209 | tmp = const0_rtx; | |
11210 | else | |
11211 | tmp = gen_rtx_NOT (DImode, tmp); | |
11212 | } | |
11213 | else | |
11214 | { | |
11215 | operands[0] = gen_highpart (SImode, operands[0]); | |
11216 | if (GET_CODE (operands[1]) == ABS) | |
11217 | { | |
11218 | tmp = gen_int_mode (0x7fffffff, SImode); | |
11219 | tmp = gen_rtx_AND (SImode, operands[0], tmp); | |
11220 | } | |
11221 | else | |
11222 | { | |
11223 | tmp = gen_int_mode (0x80000000, SImode); | |
11224 | tmp = gen_rtx_XOR (SImode, operands[0], tmp); | |
11225 | } | |
11226 | } | |
11227 | operands[1] = tmp; | |
11228 | }) | |
1ce485ec JH |
11229 | |
11230 | (define_split | |
7cacf53e RH |
11231 | [(set (match_operand:XF 0 "register_operand" "") |
11232 | (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) | |
11233 | (use (match_operand 2 "" "")) | |
8bc527af | 11234 | (clobber (reg:CC FLAGS_REG))] |
7cacf53e RH |
11235 | "reload_completed" |
11236 | [(parallel [(set (match_dup 0) (match_dup 1)) | |
11237 | (clobber (reg:CC FLAGS_REG))])] | |
11238 | { | |
11239 | rtx tmp; | |
11240 | operands[0] = gen_rtx_REG (SImode, | |
11241 | true_regnum (operands[0]) | |
11242 | + (TARGET_64BIT ? 1 : 2)); | |
11243 | if (GET_CODE (operands[1]) == ABS) | |
11244 | { | |
11245 | tmp = GEN_INT (0x7fff); | |
11246 | tmp = gen_rtx_AND (SImode, operands[0], tmp); | |
11247 | } | |
11248 | else | |
11249 | { | |
11250 | tmp = GEN_INT (0x8000); | |
11251 | tmp = gen_rtx_XOR (SImode, operands[0], tmp); | |
11252 | } | |
11253 | operands[1] = tmp; | |
11254 | }) | |
1ce485ec | 11255 | |
6300f037 | 11256 | ;; Conditionalize these after reload. If they match before reload, we |
1ce485ec JH |
11257 | ;; lose the clobber and ability to use integer instructions. |
11258 | ||
6dd18eb1 | 11259 | (define_insn "*<code><mode>2_1" |
6b761851 | 11260 | [(set (match_operand:X87MODEF 0 "register_operand" "=f") |
6dd18eb1 | 11261 | (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] |
6b761851 | 11262 | "TARGET_80387 |
6dd18eb1 UB |
11263 | && (reload_completed |
11264 | || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" | |
11265 | "f<absnegprefix>" | |
7cacf53e | 11266 | [(set_attr "type" "fsgn") |
6b761851 | 11267 | (set_attr "mode" "<MODE>")]) |
4fb21e90 | 11268 | |
6dd18eb1 | 11269 | (define_insn "*<code>extendsfdf2" |
886c62d1 | 11270 | [(set (match_operand:DF 0 "register_operand" "=f") |
6dd18eb1 UB |
11271 | (absneg:DF (float_extend:DF |
11272 | (match_operand:SF 1 "register_operand" "0"))))] | |
7cacf53e | 11273 | "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" |
6dd18eb1 | 11274 | "f<absnegprefix>" |
6ef67412 JH |
11275 | [(set_attr "type" "fsgn") |
11276 | (set_attr "mode" "DF")]) | |
4fb21e90 | 11277 | |
6dd18eb1 | 11278 | (define_insn "*<code>extendsfxf2" |
4fb21e90 | 11279 | [(set (match_operand:XF 0 "register_operand" "=f") |
6dd18eb1 UB |
11280 | (absneg:XF (float_extend:XF |
11281 | (match_operand:SF 1 "register_operand" "0"))))] | |
f8a1ebc6 | 11282 | "TARGET_80387" |
6dd18eb1 | 11283 | "f<absnegprefix>" |
6ef67412 JH |
11284 | [(set_attr "type" "fsgn") |
11285 | (set_attr "mode" "XF")]) | |
a199fdd6 | 11286 | |
6dd18eb1 | 11287 | (define_insn "*<code>extenddfxf2" |
58733f96 | 11288 | [(set (match_operand:XF 0 "register_operand" "=f") |
6dd18eb1 UB |
11289 | (absneg:XF (float_extend:XF |
11290 | (match_operand:DF 1 "register_operand" "0"))))] | |
2b589241 | 11291 | "TARGET_80387" |
6dd18eb1 | 11292 | "f<absnegprefix>" |
2b589241 JH |
11293 | [(set_attr "type" "fsgn") |
11294 | (set_attr "mode" "XF")]) | |
edc5bbcd UB |
11295 | |
11296 | ;; Copysign instructions | |
11297 | ||
3abcb3a7 | 11298 | (define_mode_iterator CSGNMODE [SF DF TF]) |
edc5bbcd UB |
11299 | (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) |
11300 | ||
11301 | (define_expand "copysign<mode>3" | |
11302 | [(match_operand:CSGNMODE 0 "register_operand" "") | |
11303 | (match_operand:CSGNMODE 1 "nonmemory_operand" "") | |
11304 | (match_operand:CSGNMODE 2 "register_operand" "")] | |
11305 | "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5bb77598 | 11306 | || (TARGET_SSE2 && (<MODE>mode == TFmode))" |
edc5bbcd UB |
11307 | { |
11308 | ix86_expand_copysign (operands); | |
11309 | DONE; | |
11310 | }) | |
11311 | ||
11312 | (define_insn_and_split "copysign<mode>3_const" | |
11313 | [(set (match_operand:CSGNMODE 0 "register_operand" "=x") | |
11314 | (unspec:CSGNMODE | |
11315 | [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC") | |
11316 | (match_operand:CSGNMODE 2 "register_operand" "0") | |
11317 | (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")] | |
11318 | UNSPEC_COPYSIGN))] | |
11319 | "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5bb77598 | 11320 | || (TARGET_SSE2 && (<MODE>mode == TFmode))" |
edc5bbcd UB |
11321 | "#" |
11322 | "&& reload_completed" | |
11323 | [(const_int 0)] | |
11324 | { | |
11325 | ix86_split_copysign_const (operands); | |
11326 | DONE; | |
11327 | }) | |
11328 | ||
11329 | (define_insn "copysign<mode>3_var" | |
11330 | [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x") | |
11331 | (unspec:CSGNMODE | |
11332 | [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x") | |
11333 | (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x") | |
11334 | (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0") | |
11335 | (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")] | |
11336 | UNSPEC_COPYSIGN)) | |
11337 | (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))] | |
11338 | "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5bb77598 | 11339 | || (TARGET_SSE2 && (<MODE>mode == TFmode))" |
edc5bbcd UB |
11340 | "#") |
11341 | ||
11342 | (define_split | |
11343 | [(set (match_operand:CSGNMODE 0 "register_operand" "") | |
11344 | (unspec:CSGNMODE | |
11345 | [(match_operand:CSGNMODE 2 "register_operand" "") | |
11346 | (match_operand:CSGNMODE 3 "register_operand" "") | |
11347 | (match_operand:<CSGNVMODE> 4 "" "") | |
11348 | (match_operand:<CSGNVMODE> 5 "" "")] | |
11349 | UNSPEC_COPYSIGN)) | |
11350 | (clobber (match_scratch:<CSGNVMODE> 1 ""))] | |
11351 | "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
5bb77598 | 11352 | || (TARGET_SSE2 && (<MODE>mode == TFmode))) |
edc5bbcd UB |
11353 | && reload_completed" |
11354 | [(const_int 0)] | |
11355 | { | |
11356 | ix86_split_copysign_var (operands); | |
11357 | DONE; | |
11358 | }) | |
886c62d1 | 11359 | \f |
e075ae69 | 11360 | ;; One complement instructions |
886c62d1 | 11361 | |
9b70259d JH |
11362 | (define_expand "one_cmpldi2" |
11363 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
11364 | (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))] | |
11365 | "TARGET_64BIT" | |
11366 | "ix86_expand_unary_operator (NOT, DImode, operands); DONE;") | |
11367 | ||
11368 | (define_insn "*one_cmpldi2_1_rex64" | |
11369 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
11370 | (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] | |
11371 | "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)" | |
0f40f9f7 | 11372 | "not{q}\t%0" |
9b70259d JH |
11373 | [(set_attr "type" "negnot") |
11374 | (set_attr "mode" "DI")]) | |
11375 | ||
11376 | (define_insn "*one_cmpldi2_2_rex64" | |
42fabf21 | 11377 | [(set (reg FLAGS_REG) |
9b70259d JH |
11378 | (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")) |
11379 | (const_int 0))) | |
11380 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
11381 | (not:DI (match_dup 1)))] | |
11382 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) | |
11383 | && ix86_unary_operator_ok (NOT, DImode, operands)" | |
11384 | "#" | |
11385 | [(set_attr "type" "alu1") | |
11386 | (set_attr "mode" "DI")]) | |
11387 | ||
11388 | (define_split | |
25da5dc7 RH |
11389 | [(set (match_operand 0 "flags_reg_operand" "") |
11390 | (match_operator 2 "compare_operator" | |
11391 | [(not:DI (match_operand:DI 3 "nonimmediate_operand" "")) | |
11392 | (const_int 0)])) | |
11393 | (set (match_operand:DI 1 "nonimmediate_operand" "") | |
11394 | (not:DI (match_dup 3)))] | |
9b70259d | 11395 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" |
25da5dc7 RH |
11396 | [(parallel [(set (match_dup 0) |
11397 | (match_op_dup 2 | |
11398 | [(xor:DI (match_dup 3) (const_int -1)) | |
11399 | (const_int 0)])) | |
11400 | (set (match_dup 1) | |
11401 | (xor:DI (match_dup 3) (const_int -1)))])] | |
9b70259d JH |
11402 | "") |
11403 | ||
06a964de | 11404 | (define_expand "one_cmplsi2" |
a1cbdd7f JH |
11405 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
11406 | (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] | |
06a964de JH |
11407 | "" |
11408 | "ix86_expand_unary_operator (NOT, SImode, operands); DONE;") | |
11409 | ||
11410 | (define_insn "*one_cmplsi2_1" | |
2ae0f82c SC |
11411 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
11412 | (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] | |
a1cbdd7f | 11413 | "ix86_unary_operator_ok (NOT, SImode, operands)" |
0f40f9f7 | 11414 | "not{l}\t%0" |
6ef67412 JH |
11415 | [(set_attr "type" "negnot") |
11416 | (set_attr "mode" "SI")]) | |
bb524860 | 11417 | |
9b70259d JH |
11418 | ;; ??? Currently never generated - xor is used instead. |
11419 | (define_insn "*one_cmplsi2_1_zext" | |
11420 | [(set (match_operand:DI 0 "register_operand" "=r") | |
11421 | (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))] | |
11422 | "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" | |
0f40f9f7 | 11423 | "not{l}\t%k0" |
9b70259d JH |
11424 | [(set_attr "type" "negnot") |
11425 | (set_attr "mode" "SI")]) | |
11426 | ||
06a964de | 11427 | (define_insn "*one_cmplsi2_2" |
42fabf21 | 11428 | [(set (reg FLAGS_REG) |
16189740 RH |
11429 | (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")) |
11430 | (const_int 0))) | |
e075ae69 RH |
11431 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
11432 | (not:SI (match_dup 1)))] | |
16189740 RH |
11433 | "ix86_match_ccmode (insn, CCNOmode) |
11434 | && ix86_unary_operator_ok (NOT, SImode, operands)" | |
e075ae69 | 11435 | "#" |
6ef67412 JH |
11436 | [(set_attr "type" "alu1") |
11437 | (set_attr "mode" "SI")]) | |
e075ae69 RH |
11438 | |
11439 | (define_split | |
25da5dc7 RH |
11440 | [(set (match_operand 0 "flags_reg_operand" "") |
11441 | (match_operator 2 "compare_operator" | |
11442 | [(not:SI (match_operand:SI 3 "nonimmediate_operand" "")) | |
11443 | (const_int 0)])) | |
11444 | (set (match_operand:SI 1 "nonimmediate_operand" "") | |
11445 | (not:SI (match_dup 3)))] | |
16189740 | 11446 | "ix86_match_ccmode (insn, CCNOmode)" |
25da5dc7 RH |
11447 | [(parallel [(set (match_dup 0) |
11448 | (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) | |
11449 | (const_int 0)])) | |
11450 | (set (match_dup 1) | |
11451 | (xor:SI (match_dup 3) (const_int -1)))])] | |
e075ae69 | 11452 | "") |
886c62d1 | 11453 | |
9b70259d JH |
11454 | ;; ??? Currently never generated - xor is used instead. |
11455 | (define_insn "*one_cmplsi2_2_zext" | |
42fabf21 | 11456 | [(set (reg FLAGS_REG) |
9b70259d JH |
11457 | (compare (not:SI (match_operand:SI 1 "register_operand" "0")) |
11458 | (const_int 0))) | |
11459 | (set (match_operand:DI 0 "register_operand" "=r") | |
11460 | (zero_extend:DI (not:SI (match_dup 1))))] | |
11461 | "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) | |
11462 | && ix86_unary_operator_ok (NOT, SImode, operands)" | |
11463 | "#" | |
11464 | [(set_attr "type" "alu1") | |
11465 | (set_attr "mode" "SI")]) | |
11466 | ||
11467 | (define_split | |
25da5dc7 RH |
11468 | [(set (match_operand 0 "flags_reg_operand" "") |
11469 | (match_operator 2 "compare_operator" | |
11470 | [(not:SI (match_operand:SI 3 "register_operand" "")) | |
11471 | (const_int 0)])) | |
11472 | (set (match_operand:DI 1 "register_operand" "") | |
11473 | (zero_extend:DI (not:SI (match_dup 3))))] | |
9b70259d | 11474 | "ix86_match_ccmode (insn, CCNOmode)" |
25da5dc7 RH |
11475 | [(parallel [(set (match_dup 0) |
11476 | (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) | |
11477 | (const_int 0)])) | |
11478 | (set (match_dup 1) | |
11479 | (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])] | |
9b70259d JH |
11480 | "") |
11481 | ||
06a964de | 11482 | (define_expand "one_cmplhi2" |
a1cbdd7f JH |
11483 | [(set (match_operand:HI 0 "nonimmediate_operand" "") |
11484 | (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] | |
d9f32422 | 11485 | "TARGET_HIMODE_MATH" |
06a964de JH |
11486 | "ix86_expand_unary_operator (NOT, HImode, operands); DONE;") |
11487 | ||
11488 | (define_insn "*one_cmplhi2_1" | |
2ae0f82c SC |
11489 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
11490 | (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] | |
a1cbdd7f | 11491 | "ix86_unary_operator_ok (NOT, HImode, operands)" |
0f40f9f7 | 11492 | "not{w}\t%0" |
6ef67412 JH |
11493 | [(set_attr "type" "negnot") |
11494 | (set_attr "mode" "HI")]) | |
bb524860 | 11495 | |
06a964de | 11496 | (define_insn "*one_cmplhi2_2" |
42fabf21 | 11497 | [(set (reg FLAGS_REG) |
16189740 RH |
11498 | (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")) |
11499 | (const_int 0))) | |
e075ae69 RH |
11500 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
11501 | (not:HI (match_dup 1)))] | |
16189740 RH |
11502 | "ix86_match_ccmode (insn, CCNOmode) |
11503 | && ix86_unary_operator_ok (NEG, HImode, operands)" | |
e075ae69 | 11504 | "#" |
6ef67412 JH |
11505 | [(set_attr "type" "alu1") |
11506 | (set_attr "mode" "HI")]) | |
e075ae69 RH |
11507 | |
11508 | (define_split | |
25da5dc7 RH |
11509 | [(set (match_operand 0 "flags_reg_operand" "") |
11510 | (match_operator 2 "compare_operator" | |
11511 | [(not:HI (match_operand:HI 3 "nonimmediate_operand" "")) | |
11512 | (const_int 0)])) | |
11513 | (set (match_operand:HI 1 "nonimmediate_operand" "") | |
11514 | (not:HI (match_dup 3)))] | |
16189740 | 11515 | "ix86_match_ccmode (insn, CCNOmode)" |
25da5dc7 RH |
11516 | [(parallel [(set (match_dup 0) |
11517 | (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1)) | |
11518 | (const_int 0)])) | |
11519 | (set (match_dup 1) | |
11520 | (xor:HI (match_dup 3) (const_int -1)))])] | |
e075ae69 | 11521 | "") |
886c62d1 | 11522 | |
e075ae69 | 11523 | ;; %%% Potential partial reg stall on alternative 1. What to do? |
06a964de | 11524 | (define_expand "one_cmplqi2" |
a1cbdd7f JH |
11525 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
11526 | (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
d9f32422 | 11527 | "TARGET_QIMODE_MATH" |
06a964de JH |
11528 | "ix86_expand_unary_operator (NOT, QImode, operands); DONE;") |
11529 | ||
11530 | (define_insn "*one_cmplqi2_1" | |
7c6b971d | 11531 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") |
e075ae69 | 11532 | (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] |
a1cbdd7f | 11533 | "ix86_unary_operator_ok (NOT, QImode, operands)" |
e075ae69 | 11534 | "@ |
0f40f9f7 ZW |
11535 | not{b}\t%0 |
11536 | not{l}\t%k0" | |
6ef67412 JH |
11537 | [(set_attr "type" "negnot") |
11538 | (set_attr "mode" "QI,SI")]) | |
bb524860 | 11539 | |
06a964de | 11540 | (define_insn "*one_cmplqi2_2" |
42fabf21 | 11541 | [(set (reg FLAGS_REG) |
16189740 RH |
11542 | (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")) |
11543 | (const_int 0))) | |
e075ae69 RH |
11544 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
11545 | (not:QI (match_dup 1)))] | |
16189740 RH |
11546 | "ix86_match_ccmode (insn, CCNOmode) |
11547 | && ix86_unary_operator_ok (NOT, QImode, operands)" | |
e075ae69 | 11548 | "#" |
6ef67412 JH |
11549 | [(set_attr "type" "alu1") |
11550 | (set_attr "mode" "QI")]) | |
e075ae69 RH |
11551 | |
11552 | (define_split | |
25da5dc7 RH |
11553 | [(set (match_operand 0 "flags_reg_operand" "") |
11554 | (match_operator 2 "compare_operator" | |
11555 | [(not:QI (match_operand:QI 3 "nonimmediate_operand" "")) | |
11556 | (const_int 0)])) | |
11557 | (set (match_operand:QI 1 "nonimmediate_operand" "") | |
11558 | (not:QI (match_dup 3)))] | |
16189740 | 11559 | "ix86_match_ccmode (insn, CCNOmode)" |
25da5dc7 RH |
11560 | [(parallel [(set (match_dup 0) |
11561 | (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1)) | |
11562 | (const_int 0)])) | |
11563 | (set (match_dup 1) | |
11564 | (xor:QI (match_dup 3) (const_int -1)))])] | |
e075ae69 | 11565 | "") |
886c62d1 | 11566 | \f |
e075ae69 | 11567 | ;; Arithmetic shift instructions |
886c62d1 JVA |
11568 | |
11569 | ;; DImode shifts are implemented using the i386 "shift double" opcode, | |
11570 | ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count | |
11571 | ;; is variable, then the count is in %cl and the "imm" operand is dropped | |
11572 | ;; from the assembler input. | |
e075ae69 | 11573 | ;; |
886c62d1 JVA |
11574 | ;; This instruction shifts the target reg/mem as usual, but instead of |
11575 | ;; shifting in zeros, bits are shifted in from reg operand. If the insn | |
11576 | ;; is a left shift double, bits are taken from the high order bits of | |
11577 | ;; reg, else if the insn is a shift right double, bits are taken from the | |
11578 | ;; low order bits of reg. So if %eax is "1234" and %edx is "5678", | |
11579 | ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". | |
e075ae69 | 11580 | ;; |
886c62d1 JVA |
11581 | ;; Since sh[lr]d does not change the `reg' operand, that is done |
11582 | ;; separately, making all shifts emit pairs of shift double and normal | |
11583 | ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to | |
11584 | ;; support a 63 bit shift, each shift where the count is in a reg expands | |
f58acb67 | 11585 | ;; to a pair of shifts, a branch, a shift by 32 and a label. |
e075ae69 | 11586 | ;; |
886c62d1 JVA |
11587 | ;; If the shift count is a constant, we need never emit more than one |
11588 | ;; shift pair, instead using moves and sign extension for counts greater | |
11589 | ;; than 31. | |
11590 | ||
28356f52 | 11591 | (define_expand "ashlti3" |
934f2a96 UB |
11592 | [(set (match_operand:TI 0 "register_operand" "") |
11593 | (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "") | |
11594 | (match_operand:QI 2 "nonmemory_operand" "")))] | |
28356f52 | 11595 | "TARGET_64BIT" |
934f2a96 | 11596 | "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;") |
28356f52 | 11597 | |
934f2a96 UB |
11598 | ;; This pattern must be defined before *ashlti3_1 to prevent |
11599 | ;; combine pass from converting sse2_ashlti3 to *ashlti3_1. | |
69c553ef | 11600 | |
95879c72 L |
11601 | (define_insn "*avx_ashlti3" |
11602 | [(set (match_operand:TI 0 "register_operand" "=x") | |
11603 | (ashift:TI (match_operand:TI 1 "register_operand" "x") | |
11604 | (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))] | |
11605 | "TARGET_AVX" | |
11606 | { | |
11607 | operands[2] = GEN_INT (INTVAL (operands[2]) / 8); | |
11608 | return "vpslldq\t{%2, %1, %0|%0, %1, %2}"; | |
11609 | } | |
11610 | [(set_attr "type" "sseishft") | |
11611 | (set_attr "prefix" "vex") | |
725fd454 | 11612 | (set_attr "length_immediate" "1") |
95879c72 L |
11613 | (set_attr "mode" "TI")]) |
11614 | ||
69c553ef UB |
11615 | (define_insn "sse2_ashlti3" |
11616 | [(set (match_operand:TI 0 "register_operand" "=x") | |
11617 | (ashift:TI (match_operand:TI 1 "register_operand" "0") | |
11618 | (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))] | |
11619 | "TARGET_SSE2" | |
11620 | { | |
11621 | operands[2] = GEN_INT (INTVAL (operands[2]) / 8); | |
11622 | return "pslldq\t{%2, %0|%0, %2}"; | |
11623 | } | |
11624 | [(set_attr "type" "sseishft") | |
11625 | (set_attr "prefix_data16" "1") | |
725fd454 | 11626 | (set_attr "length_immediate" "1") |
69c553ef UB |
11627 | (set_attr "mode" "TI")]) |
11628 | ||
934f2a96 UB |
11629 | (define_insn "*ashlti3_1" |
11630 | [(set (match_operand:TI 0 "register_operand" "=&r,r") | |
11631 | (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0") | |
11632 | (match_operand:QI 2 "nonmemory_operand" "Oc,Oc"))) | |
28356f52 JB |
11633 | (clobber (reg:CC FLAGS_REG))] |
11634 | "TARGET_64BIT" | |
11635 | "#" | |
11636 | [(set_attr "type" "multi")]) | |
11637 | ||
934f2a96 UB |
11638 | (define_peephole2 |
11639 | [(match_scratch:DI 3 "r") | |
11640 | (parallel [(set (match_operand:TI 0 "register_operand" "") | |
11641 | (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") | |
11642 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
11643 | (clobber (reg:CC FLAGS_REG))]) | |
11644 | (match_dup 3)] | |
11645 | "TARGET_64BIT" | |
28356f52 JB |
11646 | [(const_int 0)] |
11647 | "ix86_split_ashl (operands, operands[3], TImode); DONE;") | |
11648 | ||
11649 | (define_split | |
11650 | [(set (match_operand:TI 0 "register_operand" "") | |
934f2a96 UB |
11651 | (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") |
11652 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
28356f52 | 11653 | (clobber (reg:CC FLAGS_REG))] |
934f2a96 UB |
11654 | "TARGET_64BIT && ((optimize > 0 && flag_peephole2) |
11655 | ? epilogue_completed : reload_completed)" | |
28356f52 JB |
11656 | [(const_int 0)] |
11657 | "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;") | |
11658 | ||
11659 | (define_insn "x86_64_shld" | |
934f2a96 | 11660 | [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") |
28356f52 | 11661 | (ior:DI (ashift:DI (match_dup 0) |
934f2a96 UB |
11662 | (match_operand:QI 2 "nonmemory_operand" "Jc")) |
11663 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") | |
28356f52 JB |
11664 | (minus:QI (const_int 64) (match_dup 2))))) |
11665 | (clobber (reg:CC FLAGS_REG))] | |
11666 | "TARGET_64BIT" | |
934f2a96 | 11667 | "shld{q}\t{%s2%1, %0|%0, %1, %2}" |
28356f52 JB |
11668 | [(set_attr "type" "ishift") |
11669 | (set_attr "prefix_0f" "1") | |
11670 | (set_attr "mode" "DI") | |
21efb4d4 | 11671 | (set_attr "athlon_decode" "vector") |
4f3f76e6 | 11672 | (set_attr "amdfam10_decode" "vector")]) |
28356f52 | 11673 | |
72ea2555 | 11674 | (define_expand "x86_64_shift_adj_1" |
28356f52 JB |
11675 | [(set (reg:CCZ FLAGS_REG) |
11676 | (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") | |
11677 | (const_int 64)) | |
11678 | (const_int 0))) | |
11679 | (set (match_operand:DI 0 "register_operand" "") | |
11680 | (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) | |
11681 | (match_operand:DI 1 "register_operand" "") | |
11682 | (match_dup 0))) | |
11683 | (set (match_dup 1) | |
11684 | (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) | |
11685 | (match_operand:DI 3 "register_operand" "r") | |
11686 | (match_dup 1)))] | |
11687 | "TARGET_64BIT" | |
11688 | "") | |
11689 | ||
72ea2555 UB |
11690 | (define_expand "x86_64_shift_adj_2" |
11691 | [(use (match_operand:DI 0 "register_operand" "")) | |
11692 | (use (match_operand:DI 1 "register_operand" "")) | |
11693 | (use (match_operand:QI 2 "register_operand" ""))] | |
11694 | "TARGET_64BIT" | |
11695 | { | |
11696 | rtx label = gen_label_rtx (); | |
11697 | rtx tmp; | |
11698 | ||
11699 | emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64))); | |
11700 | ||
11701 | tmp = gen_rtx_REG (CCZmode, FLAGS_REG); | |
11702 | tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); | |
11703 | tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, | |
11704 | gen_rtx_LABEL_REF (VOIDmode, label), | |
11705 | pc_rtx); | |
11706 | tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); | |
11707 | JUMP_LABEL (tmp) = label; | |
11708 | ||
11709 | emit_move_insn (operands[0], operands[1]); | |
11710 | ix86_expand_clear (operands[1]); | |
11711 | ||
11712 | emit_label (label); | |
11713 | LABEL_NUSES (label) = 1; | |
11714 | ||
11715 | DONE; | |
11716 | }) | |
11717 | ||
56c0e8fa | 11718 | (define_expand "ashldi3" |
93330ea1 RH |
11719 | [(set (match_operand:DI 0 "shiftdi_operand" "") |
11720 | (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "") | |
11721 | (match_operand:QI 2 "nonmemory_operand" "")))] | |
56c0e8fa | 11722 | "" |
93330ea1 | 11723 | "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;") |
56c0e8fa | 11724 | |
371bc54b JH |
11725 | (define_insn "*ashldi3_1_rex64" |
11726 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") | |
9a9286af | 11727 | (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l") |
7c17f553 | 11728 | (match_operand:QI 2 "nonmemory_operand" "cJ,M"))) |
8bc527af | 11729 | (clobber (reg:CC FLAGS_REG))] |
371bc54b | 11730 | "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)" |
371bc54b JH |
11731 | { |
11732 | switch (get_attr_type (insn)) | |
11733 | { | |
11734 | case TYPE_ALU: | |
7637e42c NS |
11735 | gcc_assert (operands[2] == const1_rtx); |
11736 | gcc_assert (rtx_equal_p (operands[0], operands[1])); | |
a23132e1 | 11737 | return "add{q}\t%0, %0"; |
371bc54b JH |
11738 | |
11739 | case TYPE_LEA: | |
7656aee4 | 11740 | gcc_assert (CONST_INT_P (operands[2])); |
7637e42c | 11741 | gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3); |
371bc54b JH |
11742 | operands[1] = gen_rtx_MULT (DImode, operands[1], |
11743 | GEN_INT (1 << INTVAL (operands[2]))); | |
0f40f9f7 | 11744 | return "lea{q}\t{%a1, %0|%0, %a1}"; |
371bc54b JH |
11745 | |
11746 | default: | |
11747 | if (REG_P (operands[2])) | |
0f40f9f7 | 11748 | return "sal{q}\t{%b2, %0|%0, %b2}"; |
b4e0dd8e | 11749 | else if (operands[2] == const1_rtx |
3debdc1e | 11750 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 11751 | return "sal{q}\t%0"; |
371bc54b | 11752 | else |
0f40f9f7 | 11753 | return "sal{q}\t{%2, %0|%0, %2}"; |
371bc54b | 11754 | } |
0f40f9f7 | 11755 | } |
371bc54b JH |
11756 | [(set (attr "type") |
11757 | (cond [(eq_attr "alternative" "1") | |
11758 | (const_string "lea") | |
11759 | (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
11760 | (const_int 0)) | |
11761 | (match_operand 0 "register_operand" "")) | |
11762 | (match_operand 2 "const1_operand" "")) | |
11763 | (const_string "alu") | |
11764 | ] | |
11765 | (const_string "ishift"))) | |
a952487c JJ |
11766 | (set (attr "length_immediate") |
11767 | (if_then_else | |
11768 | (ior (eq_attr "type" "alu") | |
11769 | (and (eq_attr "type" "ishift") | |
11770 | (and (match_operand 2 "const1_operand" "") | |
11771 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
11772 | (const_int 0))))) | |
11773 | (const_string "0") | |
11774 | (const_string "*"))) | |
371bc54b JH |
11775 | (set_attr "mode" "DI")]) |
11776 | ||
11777 | ;; Convert lea to the lea pattern to avoid flags dependency. | |
11778 | (define_split | |
11779 | [(set (match_operand:DI 0 "register_operand" "") | |
9a9286af | 11780 | (ashift:DI (match_operand:DI 1 "index_register_operand" "") |
371bc54b | 11781 | (match_operand:QI 2 "immediate_operand" ""))) |
8bc527af | 11782 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 11783 | "TARGET_64BIT && reload_completed |
371bc54b JH |
11784 | && true_regnum (operands[0]) != true_regnum (operands[1])" |
11785 | [(set (match_dup 0) | |
11786 | (mult:DI (match_dup 1) | |
11787 | (match_dup 2)))] | |
d8bf17f9 | 11788 | "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);") |
371bc54b JH |
11789 | |
11790 | ;; This pattern can't accept a variable shift count, since shifts by | |
11791 | ;; zero don't affect the flags. We assume that shifts by constant | |
11792 | ;; zero are optimized away. | |
11793 | (define_insn "*ashldi3_cmp_rex64" | |
42fabf21 | 11794 | [(set (reg FLAGS_REG) |
371bc54b JH |
11795 | (compare |
11796 | (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
934f2a96 | 11797 | (match_operand:QI 2 "const_1_to_63_operand" "J")) |
371bc54b JH |
11798 | (const_int 0))) |
11799 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
11800 | (ashift:DI (match_dup 1) (match_dup 2)))] | |
d5d5d289 | 11801 | "TARGET_64BIT |
3debdc1e | 11802 | && (optimize_function_for_size_p (cfun) |
995cc369 L |
11803 | || !TARGET_PARTIAL_FLAG_REG_STALL |
11804 | || (operands[2] == const1_rtx | |
11805 | && (TARGET_SHIFT1 | |
d5d5d289 L |
11806 | || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) |
11807 | && ix86_match_ccmode (insn, CCGOCmode) | |
11808 | && ix86_binary_operator_ok (ASHIFT, DImode, operands)" | |
371bc54b JH |
11809 | { |
11810 | switch (get_attr_type (insn)) | |
11811 | { | |
11812 | case TYPE_ALU: | |
7637e42c | 11813 | gcc_assert (operands[2] == const1_rtx); |
a23132e1 | 11814 | return "add{q}\t%0, %0"; |
371bc54b JH |
11815 | |
11816 | default: | |
11817 | if (REG_P (operands[2])) | |
0f40f9f7 | 11818 | return "sal{q}\t{%b2, %0|%0, %b2}"; |
b4e0dd8e | 11819 | else if (operands[2] == const1_rtx |
3debdc1e | 11820 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 11821 | return "sal{q}\t%0"; |
371bc54b | 11822 | else |
0f40f9f7 | 11823 | return "sal{q}\t{%2, %0|%0, %2}"; |
371bc54b | 11824 | } |
0f40f9f7 | 11825 | } |
371bc54b JH |
11826 | [(set (attr "type") |
11827 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
11828 | (const_int 0)) | |
11829 | (match_operand 0 "register_operand" "")) | |
11830 | (match_operand 2 "const1_operand" "")) | |
11831 | (const_string "alu") | |
11832 | ] | |
11833 | (const_string "ishift"))) | |
a952487c JJ |
11834 | (set (attr "length_immediate") |
11835 | (if_then_else | |
11836 | (ior (eq_attr "type" "alu") | |
11837 | (and (eq_attr "type" "ishift") | |
11838 | (and (match_operand 2 "const1_operand" "") | |
11839 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
11840 | (const_int 0))))) | |
11841 | (const_string "0") | |
11842 | (const_string "*"))) | |
371bc54b JH |
11843 | (set_attr "mode" "DI")]) |
11844 | ||
f42684d5 UB |
11845 | (define_insn "*ashldi3_cconly_rex64" |
11846 | [(set (reg FLAGS_REG) | |
11847 | (compare | |
11848 | (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
934f2a96 | 11849 | (match_operand:QI 2 "const_1_to_63_operand" "J")) |
f42684d5 UB |
11850 | (const_int 0))) |
11851 | (clobber (match_scratch:DI 0 "=r"))] | |
d5d5d289 | 11852 | "TARGET_64BIT |
3debdc1e | 11853 | && (optimize_function_for_size_p (cfun) |
995cc369 L |
11854 | || !TARGET_PARTIAL_FLAG_REG_STALL |
11855 | || (operands[2] == const1_rtx | |
11856 | && (TARGET_SHIFT1 | |
d5d5d289 L |
11857 | || TARGET_DOUBLE_WITH_ADD))) |
11858 | && ix86_match_ccmode (insn, CCGOCmode) | |
11859 | && ix86_binary_operator_ok (ASHIFT, DImode, operands)" | |
f42684d5 UB |
11860 | { |
11861 | switch (get_attr_type (insn)) | |
11862 | { | |
11863 | case TYPE_ALU: | |
11864 | gcc_assert (operands[2] == const1_rtx); | |
a23132e1 | 11865 | return "add{q}\t%0, %0"; |
f42684d5 UB |
11866 | |
11867 | default: | |
11868 | if (REG_P (operands[2])) | |
11869 | return "sal{q}\t{%b2, %0|%0, %b2}"; | |
11870 | else if (operands[2] == const1_rtx | |
3debdc1e | 11871 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
f42684d5 UB |
11872 | return "sal{q}\t%0"; |
11873 | else | |
11874 | return "sal{q}\t{%2, %0|%0, %2}"; | |
11875 | } | |
11876 | } | |
11877 | [(set (attr "type") | |
11878 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
11879 | (const_int 0)) | |
11880 | (match_operand 0 "register_operand" "")) | |
11881 | (match_operand 2 "const1_operand" "")) | |
11882 | (const_string "alu") | |
11883 | ] | |
11884 | (const_string "ishift"))) | |
a952487c JJ |
11885 | (set (attr "length_immediate") |
11886 | (if_then_else | |
11887 | (ior (eq_attr "type" "alu") | |
11888 | (and (eq_attr "type" "ishift") | |
11889 | (and (match_operand 2 "const1_operand" "") | |
11890 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
11891 | (const_int 0))))) | |
11892 | (const_string "0") | |
11893 | (const_string "*"))) | |
f42684d5 UB |
11894 | (set_attr "mode" "DI")]) |
11895 | ||
93330ea1 RH |
11896 | (define_insn "*ashldi3_1" |
11897 | [(set (match_operand:DI 0 "register_operand" "=&r,r") | |
11898 | (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0") | |
11899 | (match_operand:QI 2 "nonmemory_operand" "Jc,Jc"))) | |
8bc527af | 11900 | (clobber (reg:CC FLAGS_REG))] |
371bc54b | 11901 | "!TARGET_64BIT" |
e075ae69 RH |
11902 | "#" |
11903 | [(set_attr "type" "multi")]) | |
886c62d1 | 11904 | |
93330ea1 RH |
11905 | ;; By default we don't ask for a scratch register, because when DImode |
11906 | ;; values are manipulated, registers are already at a premium. But if | |
11907 | ;; we have one handy, we won't turn it away. | |
11908 | (define_peephole2 | |
11909 | [(match_scratch:SI 3 "r") | |
11910 | (parallel [(set (match_operand:DI 0 "register_operand" "") | |
11911 | (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") | |
11912 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
11913 | (clobber (reg:CC FLAGS_REG))]) | |
11914 | (match_dup 3)] | |
11915 | "!TARGET_64BIT && TARGET_CMOVE" | |
e075ae69 | 11916 | [(const_int 0)] |
28356f52 | 11917 | "ix86_split_ashl (operands, operands[3], DImode); DONE;") |
47f59fd4 | 11918 | |
e075ae69 RH |
11919 | (define_split |
11920 | [(set (match_operand:DI 0 "register_operand" "") | |
93330ea1 | 11921 | (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") |
e075ae69 | 11922 | (match_operand:QI 2 "nonmemory_operand" ""))) |
8bc527af | 11923 | (clobber (reg:CC FLAGS_REG))] |
99523994 | 11924 | "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) |
6fb5fa3c | 11925 | ? epilogue_completed : reload_completed)" |
e075ae69 | 11926 | [(const_int 0)] |
28356f52 | 11927 | "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;") |
6ec6d558 | 11928 | |
934f2a96 UB |
11929 | (define_insn "x86_shld" |
11930 | [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") | |
e075ae69 | 11931 | (ior:SI (ashift:SI (match_dup 0) |
934f2a96 UB |
11932 | (match_operand:QI 2 "nonmemory_operand" "Ic")) |
11933 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") | |
e075ae69 | 11934 | (minus:QI (const_int 32) (match_dup 2))))) |
8bc527af | 11935 | (clobber (reg:CC FLAGS_REG))] |
6ec6d558 | 11936 | "" |
934f2a96 | 11937 | "shld{l}\t{%s2%1, %0|%0, %1, %2}" |
e075ae69 | 11938 | [(set_attr "type" "ishift") |
6ef67412 JH |
11939 | (set_attr "prefix_0f" "1") |
11940 | (set_attr "mode" "SI") | |
e075ae69 | 11941 | (set_attr "pent_pair" "np") |
21efb4d4 | 11942 | (set_attr "athlon_decode" "vector") |
4f3f76e6 | 11943 | (set_attr "amdfam10_decode" "vector")]) |
e075ae69 RH |
11944 | |
11945 | (define_expand "x86_shift_adj_1" | |
8bc527af | 11946 | [(set (reg:CCZ FLAGS_REG) |
16189740 RH |
11947 | (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") |
11948 | (const_int 32)) | |
11949 | (const_int 0))) | |
e075ae69 | 11950 | (set (match_operand:SI 0 "register_operand" "") |
8bc527af | 11951 | (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) |
e075ae69 RH |
11952 | (match_operand:SI 1 "register_operand" "") |
11953 | (match_dup 0))) | |
11954 | (set (match_dup 1) | |
8bc527af | 11955 | (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) |
e075ae69 RH |
11956 | (match_operand:SI 3 "register_operand" "r") |
11957 | (match_dup 1)))] | |
11958 | "TARGET_CMOVE" | |
6ec6d558 JH |
11959 | "") |
11960 | ||
e075ae69 RH |
11961 | (define_expand "x86_shift_adj_2" |
11962 | [(use (match_operand:SI 0 "register_operand" "")) | |
11963 | (use (match_operand:SI 1 "register_operand" "")) | |
11964 | (use (match_operand:QI 2 "register_operand" ""))] | |
886c62d1 | 11965 | "" |
e075ae69 RH |
11966 | { |
11967 | rtx label = gen_label_rtx (); | |
11968 | rtx tmp; | |
886c62d1 | 11969 | |
16189740 | 11970 | emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); |
886c62d1 | 11971 | |
16189740 | 11972 | tmp = gen_rtx_REG (CCZmode, FLAGS_REG); |
e075ae69 RH |
11973 | tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); |
11974 | tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, | |
11975 | gen_rtx_LABEL_REF (VOIDmode, label), | |
11976 | pc_rtx); | |
11977 | tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); | |
11978 | JUMP_LABEL (tmp) = label; | |
886c62d1 | 11979 | |
e075ae69 | 11980 | emit_move_insn (operands[0], operands[1]); |
93330ea1 | 11981 | ix86_expand_clear (operands[1]); |
886c62d1 | 11982 | |
e075ae69 RH |
11983 | emit_label (label); |
11984 | LABEL_NUSES (label) = 1; | |
56c0e8fa JVA |
11985 | |
11986 | DONE; | |
0f40f9f7 | 11987 | }) |
56c0e8fa | 11988 | |
d525dfdf JH |
11989 | (define_expand "ashlsi3" |
11990 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
11991 | (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
7ae14d31 | 11992 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d525dfdf JH |
11993 | "" |
11994 | "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;") | |
11995 | ||
11996 | (define_insn "*ashlsi3_1" | |
e075ae69 | 11997 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") |
9a9286af | 11998 | (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l") |
e075ae69 | 11999 | (match_operand:QI 2 "nonmemory_operand" "cI,M"))) |
8bc527af | 12000 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 12001 | "ix86_binary_operator_ok (ASHIFT, SImode, operands)" |
2ae0f82c | 12002 | { |
e075ae69 RH |
12003 | switch (get_attr_type (insn)) |
12004 | { | |
12005 | case TYPE_ALU: | |
7637e42c NS |
12006 | gcc_assert (operands[2] == const1_rtx); |
12007 | gcc_assert (rtx_equal_p (operands[0], operands[1])); | |
a23132e1 | 12008 | return "add{l}\t%0, %0"; |
2ae0f82c | 12009 | |
e075ae69 | 12010 | case TYPE_LEA: |
0f40f9f7 | 12011 | return "#"; |
2ae0f82c | 12012 | |
e075ae69 RH |
12013 | default: |
12014 | if (REG_P (operands[2])) | |
0f40f9f7 | 12015 | return "sal{l}\t{%b2, %0|%0, %b2}"; |
b4e0dd8e | 12016 | else if (operands[2] == const1_rtx |
3debdc1e | 12017 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 12018 | return "sal{l}\t%0"; |
e075ae69 | 12019 | else |
0f40f9f7 | 12020 | return "sal{l}\t{%2, %0|%0, %2}"; |
e075ae69 | 12021 | } |
0f40f9f7 | 12022 | } |
e075ae69 RH |
12023 | [(set (attr "type") |
12024 | (cond [(eq_attr "alternative" "1") | |
12025 | (const_string "lea") | |
12026 | (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12027 | (const_int 0)) | |
12028 | (match_operand 0 "register_operand" "")) | |
12029 | (match_operand 2 "const1_operand" "")) | |
12030 | (const_string "alu") | |
12031 | ] | |
6ef67412 | 12032 | (const_string "ishift"))) |
a952487c JJ |
12033 | (set (attr "length_immediate") |
12034 | (if_then_else | |
12035 | (ior (eq_attr "type" "alu") | |
12036 | (and (eq_attr "type" "ishift") | |
12037 | (and (match_operand 2 "const1_operand" "") | |
12038 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12039 | (const_int 0))))) | |
12040 | (const_string "0") | |
12041 | (const_string "*"))) | |
6ef67412 | 12042 | (set_attr "mode" "SI")]) |
e075ae69 | 12043 | |
1c27d4b2 JH |
12044 | ;; Convert lea to the lea pattern to avoid flags dependency. |
12045 | (define_split | |
58787064 | 12046 | [(set (match_operand 0 "register_operand" "") |
7ec70495 | 12047 | (ashift (match_operand 1 "index_register_operand" "") |
ca4ae08d | 12048 | (match_operand:QI 2 "const_int_operand" ""))) |
8bc527af | 12049 | (clobber (reg:CC FLAGS_REG))] |
abe24fb3 | 12050 | "reload_completed |
9a9286af RH |
12051 | && true_regnum (operands[0]) != true_regnum (operands[1]) |
12052 | && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4" | |
58787064 | 12053 | [(const_int 0)] |
58787064 JH |
12054 | { |
12055 | rtx pat; | |
9a9286af RH |
12056 | enum machine_mode mode = GET_MODE (operands[0]); |
12057 | ||
12058 | if (GET_MODE_SIZE (mode) < 4) | |
12059 | operands[0] = gen_lowpart (SImode, operands[0]); | |
12060 | if (mode != Pmode) | |
12061 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
d8bf17f9 | 12062 | operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); |
9a9286af | 12063 | |
58787064 JH |
12064 | pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); |
12065 | if (Pmode != SImode) | |
12066 | pat = gen_rtx_SUBREG (SImode, pat, 0); | |
12067 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); | |
12068 | DONE; | |
0f40f9f7 | 12069 | }) |
1c27d4b2 | 12070 | |
7ec70495 JH |
12071 | ;; Rare case of shifting RSP is handled by generating move and shift |
12072 | (define_split | |
12073 | [(set (match_operand 0 "register_operand" "") | |
12074 | (ashift (match_operand 1 "register_operand" "") | |
12075 | (match_operand:QI 2 "const_int_operand" ""))) | |
8bc527af | 12076 | (clobber (reg:CC FLAGS_REG))] |
7ec70495 JH |
12077 | "reload_completed |
12078 | && true_regnum (operands[0]) != true_regnum (operands[1])" | |
12079 | [(const_int 0)] | |
12080 | { | |
12081 | rtx pat, clob; | |
61da04bd | 12082 | emit_move_insn (operands[0], operands[1]); |
7ec70495 JH |
12083 | pat = gen_rtx_SET (VOIDmode, operands[0], |
12084 | gen_rtx_ASHIFT (GET_MODE (operands[0]), | |
12085 | operands[0], operands[2])); | |
12086 | clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); | |
12087 | emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob))); | |
12088 | DONE; | |
12089 | }) | |
12090 | ||
371bc54b JH |
12091 | (define_insn "*ashlsi3_1_zext" |
12092 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
9a9286af | 12093 | (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l") |
371bc54b | 12094 | (match_operand:QI 2 "nonmemory_operand" "cI,M")))) |
8bc527af | 12095 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 12096 | "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" |
371bc54b JH |
12097 | { |
12098 | switch (get_attr_type (insn)) | |
12099 | { | |
12100 | case TYPE_ALU: | |
7637e42c | 12101 | gcc_assert (operands[2] == const1_rtx); |
a23132e1 | 12102 | return "add{l}\t%k0, %k0"; |
371bc54b JH |
12103 | |
12104 | case TYPE_LEA: | |
0f40f9f7 | 12105 | return "#"; |
371bc54b JH |
12106 | |
12107 | default: | |
12108 | if (REG_P (operands[2])) | |
0f40f9f7 | 12109 | return "sal{l}\t{%b2, %k0|%k0, %b2}"; |
b4e0dd8e | 12110 | else if (operands[2] == const1_rtx |
3debdc1e | 12111 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 12112 | return "sal{l}\t%k0"; |
371bc54b | 12113 | else |
0f40f9f7 | 12114 | return "sal{l}\t{%2, %k0|%k0, %2}"; |
371bc54b | 12115 | } |
0f40f9f7 | 12116 | } |
371bc54b JH |
12117 | [(set (attr "type") |
12118 | (cond [(eq_attr "alternative" "1") | |
12119 | (const_string "lea") | |
12120 | (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12121 | (const_int 0)) | |
12122 | (match_operand 2 "const1_operand" "")) | |
12123 | (const_string "alu") | |
12124 | ] | |
12125 | (const_string "ishift"))) | |
a952487c JJ |
12126 | (set (attr "length_immediate") |
12127 | (if_then_else | |
12128 | (ior (eq_attr "type" "alu") | |
12129 | (and (eq_attr "type" "ishift") | |
12130 | (and (match_operand 2 "const1_operand" "") | |
12131 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12132 | (const_int 0))))) | |
12133 | (const_string "0") | |
12134 | (const_string "*"))) | |
371bc54b JH |
12135 | (set_attr "mode" "SI")]) |
12136 | ||
12137 | ;; Convert lea to the lea pattern to avoid flags dependency. | |
12138 | (define_split | |
12139 | [(set (match_operand:DI 0 "register_operand" "") | |
12140 | (zero_extend:DI (ashift (match_operand 1 "register_operand" "") | |
12141 | (match_operand:QI 2 "const_int_operand" "")))) | |
8bc527af | 12142 | (clobber (reg:CC FLAGS_REG))] |
bc8a6d63 | 12143 | "TARGET_64BIT && reload_completed |
371bc54b | 12144 | && true_regnum (operands[0]) != true_regnum (operands[1])" |
bc8a6d63 RH |
12145 | [(set (match_dup 0) (zero_extend:DI |
12146 | (subreg:SI (mult:SI (match_dup 1) | |
12147 | (match_dup 2)) 0)))] | |
371bc54b JH |
12148 | { |
12149 | operands[1] = gen_lowpart (Pmode, operands[1]); | |
d8bf17f9 | 12150 | operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); |
0f40f9f7 | 12151 | }) |
371bc54b | 12152 | |
28cefcd2 BS |
12153 | ;; This pattern can't accept a variable shift count, since shifts by |
12154 | ;; zero don't affect the flags. We assume that shifts by constant | |
12155 | ;; zero are optimized away. | |
2c873473 | 12156 | (define_insn "*ashlsi3_cmp" |
42fabf21 | 12157 | [(set (reg FLAGS_REG) |
16189740 | 12158 | (compare |
e075ae69 | 12159 | (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") |
ef719a44 | 12160 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 RH |
12161 | (const_int 0))) |
12162 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
12163 | (ashift:SI (match_dup 1) (match_dup 2)))] | |
3debdc1e | 12164 | "(optimize_function_for_size_p (cfun) |
d5d5d289 L |
12165 | || !TARGET_PARTIAL_FLAG_REG_STALL |
12166 | || (operands[2] == const1_rtx | |
12167 | && (TARGET_SHIFT1 | |
12168 | || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) | |
12169 | && ix86_match_ccmode (insn, CCGOCmode) | |
12170 | && ix86_binary_operator_ok (ASHIFT, SImode, operands)" | |
886c62d1 | 12171 | { |
e075ae69 | 12172 | switch (get_attr_type (insn)) |
886c62d1 | 12173 | { |
e075ae69 | 12174 | case TYPE_ALU: |
7637e42c | 12175 | gcc_assert (operands[2] == const1_rtx); |
a23132e1 | 12176 | return "add{l}\t%0, %0"; |
886c62d1 | 12177 | |
e075ae69 RH |
12178 | default: |
12179 | if (REG_P (operands[2])) | |
0f40f9f7 | 12180 | return "sal{l}\t{%b2, %0|%0, %b2}"; |
b4e0dd8e | 12181 | else if (operands[2] == const1_rtx |
3debdc1e | 12182 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 12183 | return "sal{l}\t%0"; |
e075ae69 | 12184 | else |
0f40f9f7 | 12185 | return "sal{l}\t{%2, %0|%0, %2}"; |
56c0e8fa | 12186 | } |
0f40f9f7 | 12187 | } |
e075ae69 RH |
12188 | [(set (attr "type") |
12189 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12190 | (const_int 0)) | |
12191 | (match_operand 0 "register_operand" "")) | |
12192 | (match_operand 2 "const1_operand" "")) | |
12193 | (const_string "alu") | |
12194 | ] | |
6ef67412 | 12195 | (const_string "ishift"))) |
a952487c JJ |
12196 | (set (attr "length_immediate") |
12197 | (if_then_else | |
12198 | (ior (eq_attr "type" "alu") | |
12199 | (and (eq_attr "type" "ishift") | |
12200 | (and (match_operand 2 "const1_operand" "") | |
12201 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12202 | (const_int 0))))) | |
12203 | (const_string "0") | |
12204 | (const_string "*"))) | |
6ef67412 | 12205 | (set_attr "mode" "SI")]) |
e075ae69 | 12206 | |
f42684d5 UB |
12207 | (define_insn "*ashlsi3_cconly" |
12208 | [(set (reg FLAGS_REG) | |
12209 | (compare | |
12210 | (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
12211 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
12212 | (const_int 0))) | |
12213 | (clobber (match_scratch:SI 0 "=r"))] | |
3debdc1e | 12214 | "(optimize_function_for_size_p (cfun) |
d5d5d289 L |
12215 | || !TARGET_PARTIAL_FLAG_REG_STALL |
12216 | || (operands[2] == const1_rtx | |
12217 | && (TARGET_SHIFT1 | |
12218 | || TARGET_DOUBLE_WITH_ADD))) | |
12219 | && ix86_match_ccmode (insn, CCGOCmode) | |
12220 | && ix86_binary_operator_ok (ASHIFT, SImode, operands)" | |
f42684d5 UB |
12221 | { |
12222 | switch (get_attr_type (insn)) | |
12223 | { | |
12224 | case TYPE_ALU: | |
12225 | gcc_assert (operands[2] == const1_rtx); | |
a23132e1 | 12226 | return "add{l}\t%0, %0"; |
f42684d5 UB |
12227 | |
12228 | default: | |
12229 | if (REG_P (operands[2])) | |
12230 | return "sal{l}\t{%b2, %0|%0, %b2}"; | |
12231 | else if (operands[2] == const1_rtx | |
3debdc1e | 12232 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
f42684d5 UB |
12233 | return "sal{l}\t%0"; |
12234 | else | |
12235 | return "sal{l}\t{%2, %0|%0, %2}"; | |
12236 | } | |
12237 | } | |
12238 | [(set (attr "type") | |
12239 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12240 | (const_int 0)) | |
12241 | (match_operand 0 "register_operand" "")) | |
12242 | (match_operand 2 "const1_operand" "")) | |
12243 | (const_string "alu") | |
12244 | ] | |
12245 | (const_string "ishift"))) | |
a952487c JJ |
12246 | (set (attr "length_immediate") |
12247 | (if_then_else | |
12248 | (ior (eq_attr "type" "alu") | |
12249 | (and (eq_attr "type" "ishift") | |
12250 | (and (match_operand 2 "const1_operand" "") | |
12251 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12252 | (const_int 0))))) | |
12253 | (const_string "0") | |
12254 | (const_string "*"))) | |
f42684d5 UB |
12255 | (set_attr "mode" "SI")]) |
12256 | ||
371bc54b | 12257 | (define_insn "*ashlsi3_cmp_zext" |
42fabf21 | 12258 | [(set (reg FLAGS_REG) |
371bc54b JH |
12259 | (compare |
12260 | (ashift:SI (match_operand:SI 1 "register_operand" "0") | |
ef719a44 | 12261 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
371bc54b JH |
12262 | (const_int 0))) |
12263 | (set (match_operand:DI 0 "register_operand" "=r") | |
12264 | (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] | |
d5d5d289 | 12265 | "TARGET_64BIT |
3debdc1e | 12266 | && (optimize_function_for_size_p (cfun) |
995cc369 L |
12267 | || !TARGET_PARTIAL_FLAG_REG_STALL |
12268 | || (operands[2] == const1_rtx | |
12269 | && (TARGET_SHIFT1 | |
d5d5d289 L |
12270 | || TARGET_DOUBLE_WITH_ADD))) |
12271 | && ix86_match_ccmode (insn, CCGOCmode) | |
12272 | && ix86_binary_operator_ok (ASHIFT, SImode, operands)" | |
371bc54b JH |
12273 | { |
12274 | switch (get_attr_type (insn)) | |
12275 | { | |
12276 | case TYPE_ALU: | |
7637e42c | 12277 | gcc_assert (operands[2] == const1_rtx); |
a23132e1 | 12278 | return "add{l}\t%k0, %k0"; |
371bc54b JH |
12279 | |
12280 | default: | |
12281 | if (REG_P (operands[2])) | |
0f40f9f7 | 12282 | return "sal{l}\t{%b2, %k0|%k0, %b2}"; |
b4e0dd8e | 12283 | else if (operands[2] == const1_rtx |
3debdc1e | 12284 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 12285 | return "sal{l}\t%k0"; |
371bc54b | 12286 | else |
0f40f9f7 | 12287 | return "sal{l}\t{%2, %k0|%k0, %2}"; |
371bc54b | 12288 | } |
0f40f9f7 | 12289 | } |
371bc54b JH |
12290 | [(set (attr "type") |
12291 | (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12292 | (const_int 0)) | |
12293 | (match_operand 2 "const1_operand" "")) | |
12294 | (const_string "alu") | |
12295 | ] | |
12296 | (const_string "ishift"))) | |
a952487c JJ |
12297 | (set (attr "length_immediate") |
12298 | (if_then_else | |
12299 | (ior (eq_attr "type" "alu") | |
12300 | (and (eq_attr "type" "ishift") | |
12301 | (and (match_operand 2 "const1_operand" "") | |
12302 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12303 | (const_int 0))))) | |
12304 | (const_string "0") | |
12305 | (const_string "*"))) | |
371bc54b JH |
12306 | (set_attr "mode" "SI")]) |
12307 | ||
d525dfdf JH |
12308 | (define_expand "ashlhi3" |
12309 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
12310 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7ae14d31 | 12311 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 12312 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
12313 | "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;") |
12314 | ||
58787064 JH |
12315 | (define_insn "*ashlhi3_1_lea" |
12316 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") | |
9a9286af | 12317 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") |
58787064 | 12318 | (match_operand:QI 2 "nonmemory_operand" "cI,M"))) |
8bc527af | 12319 | (clobber (reg:CC FLAGS_REG))] |
58787064 JH |
12320 | "!TARGET_PARTIAL_REG_STALL |
12321 | && ix86_binary_operator_ok (ASHIFT, HImode, operands)" | |
58787064 JH |
12322 | { |
12323 | switch (get_attr_type (insn)) | |
12324 | { | |
12325 | case TYPE_LEA: | |
0f40f9f7 | 12326 | return "#"; |
58787064 | 12327 | case TYPE_ALU: |
7637e42c | 12328 | gcc_assert (operands[2] == const1_rtx); |
a23132e1 | 12329 | return "add{w}\t%0, %0"; |
58787064 JH |
12330 | |
12331 | default: | |
12332 | if (REG_P (operands[2])) | |
0f40f9f7 | 12333 | return "sal{w}\t{%b2, %0|%0, %b2}"; |
b4e0dd8e | 12334 | else if (operands[2] == const1_rtx |
3debdc1e | 12335 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 12336 | return "sal{w}\t%0"; |
58787064 | 12337 | else |
0f40f9f7 | 12338 | return "sal{w}\t{%2, %0|%0, %2}"; |
58787064 | 12339 | } |
0f40f9f7 | 12340 | } |
58787064 JH |
12341 | [(set (attr "type") |
12342 | (cond [(eq_attr "alternative" "1") | |
12343 | (const_string "lea") | |
12344 | (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12345 | (const_int 0)) | |
12346 | (match_operand 0 "register_operand" "")) | |
12347 | (match_operand 2 "const1_operand" "")) | |
12348 | (const_string "alu") | |
12349 | ] | |
12350 | (const_string "ishift"))) | |
a952487c JJ |
12351 | (set (attr "length_immediate") |
12352 | (if_then_else | |
12353 | (ior (eq_attr "type" "alu") | |
12354 | (and (eq_attr "type" "ishift") | |
12355 | (and (match_operand 2 "const1_operand" "") | |
12356 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12357 | (const_int 0))))) | |
12358 | (const_string "0") | |
12359 | (const_string "*"))) | |
58787064 JH |
12360 | (set_attr "mode" "HI,SI")]) |
12361 | ||
d525dfdf | 12362 | (define_insn "*ashlhi3_1" |
e075ae69 RH |
12363 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
12364 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
12365 | (match_operand:QI 2 "nonmemory_operand" "cI"))) | |
8bc527af | 12366 | (clobber (reg:CC FLAGS_REG))] |
58787064 JH |
12367 | "TARGET_PARTIAL_REG_STALL |
12368 | && ix86_binary_operator_ok (ASHIFT, HImode, operands)" | |
56c0e8fa | 12369 | { |
e075ae69 RH |
12370 | switch (get_attr_type (insn)) |
12371 | { | |
12372 | case TYPE_ALU: | |
7637e42c | 12373 | gcc_assert (operands[2] == const1_rtx); |
a23132e1 | 12374 | return "add{w}\t%0, %0"; |
886c62d1 | 12375 | |
e075ae69 RH |
12376 | default: |
12377 | if (REG_P (operands[2])) | |
0f40f9f7 | 12378 | return "sal{w}\t{%b2, %0|%0, %b2}"; |
b4e0dd8e | 12379 | else if (operands[2] == const1_rtx |
3debdc1e | 12380 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 12381 | return "sal{w}\t%0"; |
e075ae69 | 12382 | else |
0f40f9f7 | 12383 | return "sal{w}\t{%2, %0|%0, %2}"; |
e075ae69 | 12384 | } |
0f40f9f7 | 12385 | } |
e075ae69 RH |
12386 | [(set (attr "type") |
12387 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12388 | (const_int 0)) | |
12389 | (match_operand 0 "register_operand" "")) | |
12390 | (match_operand 2 "const1_operand" "")) | |
12391 | (const_string "alu") | |
12392 | ] | |
6ef67412 | 12393 | (const_string "ishift"))) |
a952487c JJ |
12394 | (set (attr "length_immediate") |
12395 | (if_then_else | |
12396 | (ior (eq_attr "type" "alu") | |
12397 | (and (eq_attr "type" "ishift") | |
12398 | (and (match_operand 2 "const1_operand" "") | |
12399 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12400 | (const_int 0))))) | |
12401 | (const_string "0") | |
12402 | (const_string "*"))) | |
6ef67412 | 12403 | (set_attr "mode" "HI")]) |
bb62e19a | 12404 | |
28cefcd2 BS |
12405 | ;; This pattern can't accept a variable shift count, since shifts by |
12406 | ;; zero don't affect the flags. We assume that shifts by constant | |
12407 | ;; zero are optimized away. | |
2c873473 | 12408 | (define_insn "*ashlhi3_cmp" |
42fabf21 | 12409 | [(set (reg FLAGS_REG) |
16189740 | 12410 | (compare |
e075ae69 | 12411 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") |
ef719a44 | 12412 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 RH |
12413 | (const_int 0))) |
12414 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
12415 | (ashift:HI (match_dup 1) (match_dup 2)))] | |
3debdc1e | 12416 | "(optimize_function_for_size_p (cfun) |
d5d5d289 L |
12417 | || !TARGET_PARTIAL_FLAG_REG_STALL |
12418 | || (operands[2] == const1_rtx | |
12419 | && (TARGET_SHIFT1 | |
12420 | || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) | |
12421 | && ix86_match_ccmode (insn, CCGOCmode) | |
12422 | && ix86_binary_operator_ok (ASHIFT, HImode, operands)" | |
886c62d1 | 12423 | { |
e075ae69 RH |
12424 | switch (get_attr_type (insn)) |
12425 | { | |
12426 | case TYPE_ALU: | |
7637e42c | 12427 | gcc_assert (operands[2] == const1_rtx); |
a23132e1 | 12428 | return "add{w}\t%0, %0"; |
886c62d1 | 12429 | |
e075ae69 RH |
12430 | default: |
12431 | if (REG_P (operands[2])) | |
0f40f9f7 | 12432 | return "sal{w}\t{%b2, %0|%0, %b2}"; |
b4e0dd8e | 12433 | else if (operands[2] == const1_rtx |
3debdc1e | 12434 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 12435 | return "sal{w}\t%0"; |
e075ae69 | 12436 | else |
0f40f9f7 | 12437 | return "sal{w}\t{%2, %0|%0, %2}"; |
e075ae69 | 12438 | } |
0f40f9f7 | 12439 | } |
e075ae69 RH |
12440 | [(set (attr "type") |
12441 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12442 | (const_int 0)) | |
12443 | (match_operand 0 "register_operand" "")) | |
12444 | (match_operand 2 "const1_operand" "")) | |
12445 | (const_string "alu") | |
12446 | ] | |
6ef67412 | 12447 | (const_string "ishift"))) |
a952487c JJ |
12448 | (set (attr "length_immediate") |
12449 | (if_then_else | |
12450 | (ior (eq_attr "type" "alu") | |
12451 | (and (eq_attr "type" "ishift") | |
12452 | (and (match_operand 2 "const1_operand" "") | |
12453 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12454 | (const_int 0))))) | |
12455 | (const_string "0") | |
12456 | (const_string "*"))) | |
6ef67412 | 12457 | (set_attr "mode" "HI")]) |
e075ae69 | 12458 | |
f42684d5 UB |
12459 | (define_insn "*ashlhi3_cconly" |
12460 | [(set (reg FLAGS_REG) | |
12461 | (compare | |
12462 | (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
12463 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
12464 | (const_int 0))) | |
12465 | (clobber (match_scratch:HI 0 "=r"))] | |
3debdc1e | 12466 | "(optimize_function_for_size_p (cfun) |
d5d5d289 L |
12467 | || !TARGET_PARTIAL_FLAG_REG_STALL |
12468 | || (operands[2] == const1_rtx | |
12469 | && (TARGET_SHIFT1 | |
12470 | || TARGET_DOUBLE_WITH_ADD))) | |
12471 | && ix86_match_ccmode (insn, CCGOCmode) | |
12472 | && ix86_binary_operator_ok (ASHIFT, HImode, operands)" | |
f42684d5 UB |
12473 | { |
12474 | switch (get_attr_type (insn)) | |
12475 | { | |
12476 | case TYPE_ALU: | |
12477 | gcc_assert (operands[2] == const1_rtx); | |
a23132e1 | 12478 | return "add{w}\t%0, %0"; |
f42684d5 UB |
12479 | |
12480 | default: | |
12481 | if (REG_P (operands[2])) | |
12482 | return "sal{w}\t{%b2, %0|%0, %b2}"; | |
12483 | else if (operands[2] == const1_rtx | |
3debdc1e | 12484 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
f42684d5 UB |
12485 | return "sal{w}\t%0"; |
12486 | else | |
12487 | return "sal{w}\t{%2, %0|%0, %2}"; | |
12488 | } | |
12489 | } | |
12490 | [(set (attr "type") | |
12491 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12492 | (const_int 0)) | |
12493 | (match_operand 0 "register_operand" "")) | |
12494 | (match_operand 2 "const1_operand" "")) | |
12495 | (const_string "alu") | |
12496 | ] | |
12497 | (const_string "ishift"))) | |
a952487c JJ |
12498 | (set (attr "length_immediate") |
12499 | (if_then_else | |
12500 | (ior (eq_attr "type" "alu") | |
12501 | (and (eq_attr "type" "ishift") | |
12502 | (and (match_operand 2 "const1_operand" "") | |
12503 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12504 | (const_int 0))))) | |
12505 | (const_string "0") | |
12506 | (const_string "*"))) | |
f42684d5 UB |
12507 | (set_attr "mode" "HI")]) |
12508 | ||
d525dfdf JH |
12509 | (define_expand "ashlqi3" |
12510 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
12511 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7ae14d31 | 12512 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 12513 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
12514 | "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;") |
12515 | ||
e075ae69 | 12516 | ;; %%% Potential partial reg stall on alternative 2. What to do? |
58787064 JH |
12517 | |
12518 | (define_insn "*ashlqi3_1_lea" | |
12519 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r") | |
9a9286af | 12520 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") |
91f9a498 | 12521 | (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) |
8bc527af | 12522 | (clobber (reg:CC FLAGS_REG))] |
58787064 JH |
12523 | "!TARGET_PARTIAL_REG_STALL |
12524 | && ix86_binary_operator_ok (ASHIFT, QImode, operands)" | |
58787064 JH |
12525 | { |
12526 | switch (get_attr_type (insn)) | |
12527 | { | |
12528 | case TYPE_LEA: | |
0f40f9f7 | 12529 | return "#"; |
58787064 | 12530 | case TYPE_ALU: |
7637e42c | 12531 | gcc_assert (operands[2] == const1_rtx); |
1a06f5fe | 12532 | if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) |
a23132e1 | 12533 | return "add{l}\t%k0, %k0"; |
58787064 | 12534 | else |
a23132e1 | 12535 | return "add{b}\t%0, %0"; |
58787064 JH |
12536 | |
12537 | default: | |
12538 | if (REG_P (operands[2])) | |
12539 | { | |
12540 | if (get_attr_mode (insn) == MODE_SI) | |
0f40f9f7 | 12541 | return "sal{l}\t{%b2, %k0|%k0, %b2}"; |
58787064 | 12542 | else |
0f40f9f7 | 12543 | return "sal{b}\t{%b2, %0|%0, %b2}"; |
58787064 | 12544 | } |
b4e0dd8e | 12545 | else if (operands[2] == const1_rtx |
3debdc1e | 12546 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
58787064 JH |
12547 | { |
12548 | if (get_attr_mode (insn) == MODE_SI) | |
0f40f9f7 | 12549 | return "sal{l}\t%0"; |
58787064 | 12550 | else |
0f40f9f7 | 12551 | return "sal{b}\t%0"; |
58787064 JH |
12552 | } |
12553 | else | |
12554 | { | |
12555 | if (get_attr_mode (insn) == MODE_SI) | |
0f40f9f7 | 12556 | return "sal{l}\t{%2, %k0|%k0, %2}"; |
58787064 | 12557 | else |
0f40f9f7 | 12558 | return "sal{b}\t{%2, %0|%0, %2}"; |
58787064 JH |
12559 | } |
12560 | } | |
0f40f9f7 | 12561 | } |
58787064 JH |
12562 | [(set (attr "type") |
12563 | (cond [(eq_attr "alternative" "2") | |
12564 | (const_string "lea") | |
12565 | (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12566 | (const_int 0)) | |
12567 | (match_operand 0 "register_operand" "")) | |
12568 | (match_operand 2 "const1_operand" "")) | |
12569 | (const_string "alu") | |
12570 | ] | |
12571 | (const_string "ishift"))) | |
a952487c JJ |
12572 | (set (attr "length_immediate") |
12573 | (if_then_else | |
12574 | (ior (eq_attr "type" "alu") | |
12575 | (and (eq_attr "type" "ishift") | |
12576 | (and (match_operand 2 "const1_operand" "") | |
12577 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12578 | (const_int 0))))) | |
12579 | (const_string "0") | |
12580 | (const_string "*"))) | |
58787064 JH |
12581 | (set_attr "mode" "QI,SI,SI")]) |
12582 | ||
d525dfdf JH |
12583 | (define_insn "*ashlqi3_1" |
12584 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") | |
e075ae69 RH |
12585 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") |
12586 | (match_operand:QI 2 "nonmemory_operand" "cI,cI"))) | |
8bc527af | 12587 | (clobber (reg:CC FLAGS_REG))] |
58787064 JH |
12588 | "TARGET_PARTIAL_REG_STALL |
12589 | && ix86_binary_operator_ok (ASHIFT, QImode, operands)" | |
886c62d1 | 12590 | { |
e075ae69 RH |
12591 | switch (get_attr_type (insn)) |
12592 | { | |
12593 | case TYPE_ALU: | |
7637e42c | 12594 | gcc_assert (operands[2] == const1_rtx); |
1a06f5fe | 12595 | if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) |
a23132e1 | 12596 | return "add{l}\t%k0, %k0"; |
e075ae69 | 12597 | else |
a23132e1 | 12598 | return "add{b}\t%0, %0"; |
886c62d1 | 12599 | |
e075ae69 RH |
12600 | default: |
12601 | if (REG_P (operands[2])) | |
12602 | { | |
1a06f5fe | 12603 | if (get_attr_mode (insn) == MODE_SI) |
0f40f9f7 | 12604 | return "sal{l}\t{%b2, %k0|%k0, %b2}"; |
e075ae69 | 12605 | else |
0f40f9f7 | 12606 | return "sal{b}\t{%b2, %0|%0, %b2}"; |
e075ae69 | 12607 | } |
b4e0dd8e | 12608 | else if (operands[2] == const1_rtx |
3debdc1e | 12609 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
8bad7136 | 12610 | { |
1a06f5fe | 12611 | if (get_attr_mode (insn) == MODE_SI) |
0f40f9f7 | 12612 | return "sal{l}\t%0"; |
8bad7136 | 12613 | else |
0f40f9f7 | 12614 | return "sal{b}\t%0"; |
8bad7136 | 12615 | } |
e075ae69 RH |
12616 | else |
12617 | { | |
1a06f5fe | 12618 | if (get_attr_mode (insn) == MODE_SI) |
0f40f9f7 | 12619 | return "sal{l}\t{%2, %k0|%k0, %2}"; |
e075ae69 | 12620 | else |
0f40f9f7 | 12621 | return "sal{b}\t{%2, %0|%0, %2}"; |
e075ae69 RH |
12622 | } |
12623 | } | |
0f40f9f7 | 12624 | } |
e075ae69 RH |
12625 | [(set (attr "type") |
12626 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12627 | (const_int 0)) | |
12628 | (match_operand 0 "register_operand" "")) | |
12629 | (match_operand 2 "const1_operand" "")) | |
12630 | (const_string "alu") | |
12631 | ] | |
6ef67412 | 12632 | (const_string "ishift"))) |
a952487c JJ |
12633 | (set (attr "length_immediate") |
12634 | (if_then_else | |
12635 | (ior (eq_attr "type" "alu") | |
12636 | (and (eq_attr "type" "ishift") | |
12637 | (and (match_operand 2 "const1_operand" "") | |
12638 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12639 | (const_int 0))))) | |
12640 | (const_string "0") | |
12641 | (const_string "*"))) | |
6ef67412 | 12642 | (set_attr "mode" "QI,SI")]) |
e075ae69 | 12643 | |
28cefcd2 BS |
12644 | ;; This pattern can't accept a variable shift count, since shifts by |
12645 | ;; zero don't affect the flags. We assume that shifts by constant | |
12646 | ;; zero are optimized away. | |
2c873473 | 12647 | (define_insn "*ashlqi3_cmp" |
42fabf21 | 12648 | [(set (reg FLAGS_REG) |
16189740 | 12649 | (compare |
e075ae69 | 12650 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") |
ef719a44 | 12651 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 RH |
12652 | (const_int 0))) |
12653 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
12654 | (ashift:QI (match_dup 1) (match_dup 2)))] | |
3debdc1e | 12655 | "(optimize_function_for_size_p (cfun) |
d5d5d289 L |
12656 | || !TARGET_PARTIAL_FLAG_REG_STALL |
12657 | || (operands[2] == const1_rtx | |
12658 | && (TARGET_SHIFT1 | |
12659 | || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) | |
12660 | && ix86_match_ccmode (insn, CCGOCmode) | |
12661 | && ix86_binary_operator_ok (ASHIFT, QImode, operands)" | |
886c62d1 | 12662 | { |
e075ae69 RH |
12663 | switch (get_attr_type (insn)) |
12664 | { | |
12665 | case TYPE_ALU: | |
7637e42c | 12666 | gcc_assert (operands[2] == const1_rtx); |
a23132e1 | 12667 | return "add{b}\t%0, %0"; |
e075ae69 RH |
12668 | |
12669 | default: | |
12670 | if (REG_P (operands[2])) | |
0f40f9f7 | 12671 | return "sal{b}\t{%b2, %0|%0, %b2}"; |
b4e0dd8e | 12672 | else if (operands[2] == const1_rtx |
3debdc1e | 12673 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
0f40f9f7 | 12674 | return "sal{b}\t%0"; |
e075ae69 | 12675 | else |
0f40f9f7 | 12676 | return "sal{b}\t{%2, %0|%0, %2}"; |
e075ae69 | 12677 | } |
0f40f9f7 | 12678 | } |
e075ae69 RH |
12679 | [(set (attr "type") |
12680 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12681 | (const_int 0)) | |
12682 | (match_operand 0 "register_operand" "")) | |
12683 | (match_operand 2 "const1_operand" "")) | |
12684 | (const_string "alu") | |
12685 | ] | |
6ef67412 | 12686 | (const_string "ishift"))) |
a952487c JJ |
12687 | (set (attr "length_immediate") |
12688 | (if_then_else | |
12689 | (ior (eq_attr "type" "alu") | |
12690 | (and (eq_attr "type" "ishift") | |
12691 | (and (match_operand 2 "const1_operand" "") | |
12692 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12693 | (const_int 0))))) | |
12694 | (const_string "0") | |
12695 | (const_string "*"))) | |
6ef67412 | 12696 | (set_attr "mode" "QI")]) |
886c62d1 | 12697 | |
f42684d5 UB |
12698 | (define_insn "*ashlqi3_cconly" |
12699 | [(set (reg FLAGS_REG) | |
12700 | (compare | |
12701 | (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
12702 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
12703 | (const_int 0))) | |
12704 | (clobber (match_scratch:QI 0 "=q"))] | |
3debdc1e | 12705 | "(optimize_function_for_size_p (cfun) |
d5d5d289 L |
12706 | || !TARGET_PARTIAL_FLAG_REG_STALL |
12707 | || (operands[2] == const1_rtx | |
12708 | && (TARGET_SHIFT1 | |
12709 | || TARGET_DOUBLE_WITH_ADD))) | |
12710 | && ix86_match_ccmode (insn, CCGOCmode) | |
12711 | && ix86_binary_operator_ok (ASHIFT, QImode, operands)" | |
f42684d5 UB |
12712 | { |
12713 | switch (get_attr_type (insn)) | |
12714 | { | |
12715 | case TYPE_ALU: | |
12716 | gcc_assert (operands[2] == const1_rtx); | |
a23132e1 | 12717 | return "add{b}\t%0, %0"; |
f42684d5 UB |
12718 | |
12719 | default: | |
12720 | if (REG_P (operands[2])) | |
12721 | return "sal{b}\t{%b2, %0|%0, %b2}"; | |
12722 | else if (operands[2] == const1_rtx | |
3debdc1e | 12723 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) |
f42684d5 UB |
12724 | return "sal{b}\t%0"; |
12725 | else | |
12726 | return "sal{b}\t{%2, %0|%0, %2}"; | |
12727 | } | |
12728 | } | |
12729 | [(set (attr "type") | |
12730 | (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") | |
12731 | (const_int 0)) | |
12732 | (match_operand 0 "register_operand" "")) | |
12733 | (match_operand 2 "const1_operand" "")) | |
12734 | (const_string "alu") | |
12735 | ] | |
12736 | (const_string "ishift"))) | |
a952487c JJ |
12737 | (set (attr "length_immediate") |
12738 | (if_then_else | |
12739 | (ior (eq_attr "type" "alu") | |
12740 | (and (eq_attr "type" "ishift") | |
12741 | (and (match_operand 2 "const1_operand" "") | |
12742 | (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") | |
12743 | (const_int 0))))) | |
12744 | (const_string "0") | |
12745 | (const_string "*"))) | |
f42684d5 UB |
12746 | (set_attr "mode" "QI")]) |
12747 | ||
886c62d1 JVA |
12748 | ;; See comment above `ashldi3' about how this works. |
12749 | ||
28356f52 | 12750 | (define_expand "ashrti3" |
934f2a96 UB |
12751 | [(set (match_operand:TI 0 "register_operand" "") |
12752 | (ashiftrt:TI (match_operand:TI 1 "register_operand" "") | |
12753 | (match_operand:QI 2 "nonmemory_operand" "")))] | |
28356f52 | 12754 | "TARGET_64BIT" |
934f2a96 | 12755 | "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;") |
28356f52 | 12756 | |
934f2a96 | 12757 | (define_insn "*ashrti3_1" |
28356f52 JB |
12758 | [(set (match_operand:TI 0 "register_operand" "=r") |
12759 | (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") | |
934f2a96 | 12760 | (match_operand:QI 2 "nonmemory_operand" "Oc"))) |
28356f52 JB |
12761 | (clobber (reg:CC FLAGS_REG))] |
12762 | "TARGET_64BIT" | |
12763 | "#" | |
12764 | [(set_attr "type" "multi")]) | |
12765 | ||
934f2a96 UB |
12766 | (define_peephole2 |
12767 | [(match_scratch:DI 3 "r") | |
12768 | (parallel [(set (match_operand:TI 0 "register_operand" "") | |
12769 | (ashiftrt:TI (match_operand:TI 1 "register_operand" "") | |
12770 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
12771 | (clobber (reg:CC FLAGS_REG))]) | |
12772 | (match_dup 3)] | |
28356f52 | 12773 | "TARGET_64BIT" |
28356f52 JB |
12774 | [(const_int 0)] |
12775 | "ix86_split_ashr (operands, operands[3], TImode); DONE;") | |
12776 | ||
12777 | (define_split | |
12778 | [(set (match_operand:TI 0 "register_operand" "") | |
12779 | (ashiftrt:TI (match_operand:TI 1 "register_operand" "") | |
934f2a96 | 12780 | (match_operand:QI 2 "nonmemory_operand" ""))) |
28356f52 | 12781 | (clobber (reg:CC FLAGS_REG))] |
934f2a96 UB |
12782 | "TARGET_64BIT && ((optimize > 0 && flag_peephole2) |
12783 | ? epilogue_completed : reload_completed)" | |
28356f52 JB |
12784 | [(const_int 0)] |
12785 | "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;") | |
12786 | ||
12787 | (define_insn "x86_64_shrd" | |
934f2a96 | 12788 | [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") |
28356f52 | 12789 | (ior:DI (ashiftrt:DI (match_dup 0) |
934f2a96 UB |
12790 | (match_operand:QI 2 "nonmemory_operand" "Jc")) |
12791 | (ashift:DI (match_operand:DI 1 "register_operand" "r") | |
28356f52 JB |
12792 | (minus:QI (const_int 64) (match_dup 2))))) |
12793 | (clobber (reg:CC FLAGS_REG))] | |
12794 | "TARGET_64BIT" | |
934f2a96 | 12795 | "shrd{q}\t{%s2%1, %0|%0, %1, %2}" |
28356f52 JB |
12796 | [(set_attr "type" "ishift") |
12797 | (set_attr "prefix_0f" "1") | |
12798 | (set_attr "mode" "DI") | |
21efb4d4 | 12799 | (set_attr "athlon_decode" "vector") |
4f3f76e6 | 12800 | (set_attr "amdfam10_decode" "vector")]) |
28356f52 | 12801 | |
e075ae69 | 12802 | (define_expand "ashrdi3" |
93330ea1 RH |
12803 | [(set (match_operand:DI 0 "shiftdi_operand" "") |
12804 | (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") | |
12805 | (match_operand:QI 2 "nonmemory_operand" "")))] | |
56c0e8fa | 12806 | "" |
93330ea1 | 12807 | "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;") |
2ae0f82c | 12808 | |
72ea2555 UB |
12809 | (define_expand "x86_64_shift_adj_3" |
12810 | [(use (match_operand:DI 0 "register_operand" "")) | |
12811 | (use (match_operand:DI 1 "register_operand" "")) | |
12812 | (use (match_operand:QI 2 "register_operand" ""))] | |
12813 | "" | |
12814 | { | |
12815 | rtx label = gen_label_rtx (); | |
12816 | rtx tmp; | |
12817 | ||
12818 | emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64))); | |
12819 | ||
12820 | tmp = gen_rtx_REG (CCZmode, FLAGS_REG); | |
12821 | tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); | |
12822 | tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, | |
12823 | gen_rtx_LABEL_REF (VOIDmode, label), | |
12824 | pc_rtx); | |
12825 | tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); | |
12826 | JUMP_LABEL (tmp) = label; | |
12827 | ||
12828 | emit_move_insn (operands[0], operands[1]); | |
12829 | emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63))); | |
12830 | ||
12831 | emit_label (label); | |
12832 | LABEL_NUSES (label) = 1; | |
12833 | ||
12834 | DONE; | |
12835 | }) | |
12836 | ||
12837 | (define_insn "ashrdi3_63_rex64" | |
371bc54b JH |
12838 | [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") |
12839 | (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") | |
12840 | (match_operand:DI 2 "const_int_operand" "i,i"))) | |
8bc527af | 12841 | (clobber (reg:CC FLAGS_REG))] |
93330ea1 | 12842 | "TARGET_64BIT && INTVAL (operands[2]) == 63 |
3debdc1e | 12843 | && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) |
371bc54b JH |
12844 | && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" |
12845 | "@ | |
12846 | {cqto|cqo} | |
0f40f9f7 | 12847 | sar{q}\t{%2, %0|%0, %2}" |
371bc54b JH |
12848 | [(set_attr "type" "imovx,ishift") |
12849 | (set_attr "prefix_0f" "0,*") | |
12850 | (set_attr "length_immediate" "0,*") | |
12851 | (set_attr "modrm" "0,1") | |
12852 | (set_attr "mode" "DI")]) | |
12853 | ||
12854 | (define_insn "*ashrdi3_1_one_bit_rex64" | |
12855 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
12856 | (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
630eef90 | 12857 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 12858 | (clobber (reg:CC FLAGS_REG))] |
d5d5d289 | 12859 | "TARGET_64BIT |
3debdc1e | 12860 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 12861 | && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" |
0f40f9f7 | 12862 | "sar{q}\t%0" |
371bc54b | 12863 | [(set_attr "type" "ishift") |
a952487c JJ |
12864 | (set_attr "length_immediate" "0") |
12865 | (set_attr "mode" "DI")]) | |
371bc54b JH |
12866 | |
12867 | (define_insn "*ashrdi3_1_rex64" | |
12868 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") | |
12869 | (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") | |
7c17f553 | 12870 | (match_operand:QI 2 "nonmemory_operand" "J,c"))) |
8bc527af | 12871 | (clobber (reg:CC FLAGS_REG))] |
371bc54b JH |
12872 | "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" |
12873 | "@ | |
0f40f9f7 ZW |
12874 | sar{q}\t{%2, %0|%0, %2} |
12875 | sar{q}\t{%b2, %0|%0, %b2}" | |
371bc54b JH |
12876 | [(set_attr "type" "ishift") |
12877 | (set_attr "mode" "DI")]) | |
12878 | ||
12879 | ;; This pattern can't accept a variable shift count, since shifts by | |
12880 | ;; zero don't affect the flags. We assume that shifts by constant | |
12881 | ;; zero are optimized away. | |
12882 | (define_insn "*ashrdi3_one_bit_cmp_rex64" | |
42fabf21 | 12883 | [(set (reg FLAGS_REG) |
371bc54b JH |
12884 | (compare |
12885 | (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
630eef90 | 12886 | (match_operand:QI 2 "const1_operand" "")) |
371bc54b JH |
12887 | (const_int 0))) |
12888 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
12889 | (ashiftrt:DI (match_dup 1) (match_dup 2)))] | |
d5d5d289 | 12890 | "TARGET_64BIT |
3debdc1e | 12891 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 12892 | && ix86_match_ccmode (insn, CCGOCmode) |
371bc54b | 12893 | && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" |
0f40f9f7 | 12894 | "sar{q}\t%0" |
371bc54b | 12895 | [(set_attr "type" "ishift") |
a952487c JJ |
12896 | (set_attr "length_immediate" "0") |
12897 | (set_attr "mode" "DI")]) | |
371bc54b | 12898 | |
f42684d5 UB |
12899 | (define_insn "*ashrdi3_one_bit_cconly_rex64" |
12900 | [(set (reg FLAGS_REG) | |
12901 | (compare | |
12902 | (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
12903 | (match_operand:QI 2 "const1_operand" "")) | |
12904 | (const_int 0))) | |
12905 | (clobber (match_scratch:DI 0 "=r"))] | |
d5d5d289 | 12906 | "TARGET_64BIT |
3debdc1e | 12907 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 12908 | && ix86_match_ccmode (insn, CCGOCmode) |
f42684d5 UB |
12909 | && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" |
12910 | "sar{q}\t%0" | |
12911 | [(set_attr "type" "ishift") | |
a952487c JJ |
12912 | (set_attr "length_immediate" "0") |
12913 | (set_attr "mode" "DI")]) | |
f42684d5 | 12914 | |
371bc54b JH |
12915 | ;; This pattern can't accept a variable shift count, since shifts by |
12916 | ;; zero don't affect the flags. We assume that shifts by constant | |
12917 | ;; zero are optimized away. | |
12918 | (define_insn "*ashrdi3_cmp_rex64" | |
42fabf21 | 12919 | [(set (reg FLAGS_REG) |
371bc54b JH |
12920 | (compare |
12921 | (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
934f2a96 | 12922 | (match_operand:QI 2 "const_1_to_63_operand" "J")) |
371bc54b JH |
12923 | (const_int 0))) |
12924 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
12925 | (ashiftrt:DI (match_dup 1) (match_dup 2)))] | |
d5d5d289 | 12926 | "TARGET_64BIT |
3debdc1e | 12927 | && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
12928 | && ix86_match_ccmode (insn, CCGOCmode) |
12929 | && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" | |
0f40f9f7 | 12930 | "sar{q}\t{%2, %0|%0, %2}" |
371bc54b JH |
12931 | [(set_attr "type" "ishift") |
12932 | (set_attr "mode" "DI")]) | |
12933 | ||
f42684d5 UB |
12934 | (define_insn "*ashrdi3_cconly_rex64" |
12935 | [(set (reg FLAGS_REG) | |
12936 | (compare | |
12937 | (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
934f2a96 | 12938 | (match_operand:QI 2 "const_1_to_63_operand" "J")) |
f42684d5 UB |
12939 | (const_int 0))) |
12940 | (clobber (match_scratch:DI 0 "=r"))] | |
d5d5d289 | 12941 | "TARGET_64BIT |
3debdc1e | 12942 | && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
12943 | && ix86_match_ccmode (insn, CCGOCmode) |
12944 | && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" | |
f42684d5 UB |
12945 | "sar{q}\t{%2, %0|%0, %2}" |
12946 | [(set_attr "type" "ishift") | |
12947 | (set_attr "mode" "DI")]) | |
12948 | ||
93330ea1 | 12949 | (define_insn "*ashrdi3_1" |
e075ae69 RH |
12950 | [(set (match_operand:DI 0 "register_operand" "=r") |
12951 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
12952 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) | |
8bc527af | 12953 | (clobber (reg:CC FLAGS_REG))] |
371bc54b | 12954 | "!TARGET_64BIT" |
e075ae69 RH |
12955 | "#" |
12956 | [(set_attr "type" "multi")]) | |
886c62d1 | 12957 | |
93330ea1 RH |
12958 | ;; By default we don't ask for a scratch register, because when DImode |
12959 | ;; values are manipulated, registers are already at a premium. But if | |
12960 | ;; we have one handy, we won't turn it away. | |
12961 | (define_peephole2 | |
12962 | [(match_scratch:SI 3 "r") | |
12963 | (parallel [(set (match_operand:DI 0 "register_operand" "") | |
12964 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
12965 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
12966 | (clobber (reg:CC FLAGS_REG))]) | |
12967 | (match_dup 3)] | |
12968 | "!TARGET_64BIT && TARGET_CMOVE" | |
e075ae69 | 12969 | [(const_int 0)] |
28356f52 | 12970 | "ix86_split_ashr (operands, operands[3], DImode); DONE;") |
886c62d1 | 12971 | |
e075ae69 RH |
12972 | (define_split |
12973 | [(set (match_operand:DI 0 "register_operand" "") | |
12974 | (ashiftrt:DI (match_operand:DI 1 "register_operand" "") | |
12975 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8bc527af | 12976 | (clobber (reg:CC FLAGS_REG))] |
99523994 | 12977 | "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) |
6fb5fa3c | 12978 | ? epilogue_completed : reload_completed)" |
e075ae69 | 12979 | [(const_int 0)] |
28356f52 | 12980 | "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;") |
886c62d1 | 12981 | |
934f2a96 UB |
12982 | (define_insn "x86_shrd" |
12983 | [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") | |
e075ae69 | 12984 | (ior:SI (ashiftrt:SI (match_dup 0) |
934f2a96 UB |
12985 | (match_operand:QI 2 "nonmemory_operand" "Ic")) |
12986 | (ashift:SI (match_operand:SI 1 "register_operand" "r") | |
e075ae69 | 12987 | (minus:QI (const_int 32) (match_dup 2))))) |
8bc527af | 12988 | (clobber (reg:CC FLAGS_REG))] |
886c62d1 | 12989 | "" |
934f2a96 | 12990 | "shrd{l}\t{%s2%1, %0|%0, %1, %2}" |
e075ae69 | 12991 | [(set_attr "type" "ishift") |
6ef67412 | 12992 | (set_attr "prefix_0f" "1") |
e075ae69 | 12993 | (set_attr "pent_pair" "np") |
6ef67412 | 12994 | (set_attr "mode" "SI")]) |
e075ae69 RH |
12995 | |
12996 | (define_expand "x86_shift_adj_3" | |
12997 | [(use (match_operand:SI 0 "register_operand" "")) | |
12998 | (use (match_operand:SI 1 "register_operand" "")) | |
12999 | (use (match_operand:QI 2 "register_operand" ""))] | |
13000 | "" | |
886c62d1 | 13001 | { |
e075ae69 RH |
13002 | rtx label = gen_label_rtx (); |
13003 | rtx tmp; | |
13004 | ||
16189740 | 13005 | emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); |
e075ae69 | 13006 | |
16189740 | 13007 | tmp = gen_rtx_REG (CCZmode, FLAGS_REG); |
e075ae69 RH |
13008 | tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); |
13009 | tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, | |
13010 | gen_rtx_LABEL_REF (VOIDmode, label), | |
13011 | pc_rtx); | |
13012 | tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); | |
13013 | JUMP_LABEL (tmp) = label; | |
13014 | ||
13015 | emit_move_insn (operands[0], operands[1]); | |
13016 | emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31))); | |
13017 | ||
13018 | emit_label (label); | |
13019 | LABEL_NUSES (label) = 1; | |
13020 | ||
13021 | DONE; | |
0f40f9f7 | 13022 | }) |
886c62d1 | 13023 | |
3debdc1e JH |
13024 | (define_expand "ashrsi3_31" |
13025 | [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") | |
13026 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") | |
13027 | (match_operand:SI 2 "const_int_operand" "i,i"))) | |
13028 | (clobber (reg:CC FLAGS_REG))])] | |
13029 | "") | |
13030 | ||
13031 | (define_insn "*ashrsi3_31" | |
e075ae69 RH |
13032 | [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") |
13033 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") | |
13034 | (match_operand:SI 2 "const_int_operand" "i,i"))) | |
8bc527af | 13035 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e JH |
13036 | "INTVAL (operands[2]) == 31 |
13037 | && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) | |
d525dfdf | 13038 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
e075ae69 RH |
13039 | "@ |
13040 | {cltd|cdq} | |
0f40f9f7 | 13041 | sar{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
13042 | [(set_attr "type" "imovx,ishift") |
13043 | (set_attr "prefix_0f" "0,*") | |
13044 | (set_attr "length_immediate" "0,*") | |
13045 | (set_attr "modrm" "0,1") | |
13046 | (set_attr "mode" "SI")]) | |
e075ae69 | 13047 | |
371bc54b JH |
13048 | (define_insn "*ashrsi3_31_zext" |
13049 | [(set (match_operand:DI 0 "register_operand" "=*d,r") | |
13050 | (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") | |
13051 | (match_operand:SI 2 "const_int_operand" "i,i")))) | |
8bc527af | 13052 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13053 | "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) |
1b0c37d7 ZW |
13054 | && INTVAL (operands[2]) == 31 |
13055 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" | |
371bc54b JH |
13056 | "@ |
13057 | {cltd|cdq} | |
0f40f9f7 | 13058 | sar{l}\t{%2, %k0|%k0, %2}" |
371bc54b JH |
13059 | [(set_attr "type" "imovx,ishift") |
13060 | (set_attr "prefix_0f" "0,*") | |
13061 | (set_attr "length_immediate" "0,*") | |
13062 | (set_attr "modrm" "0,1") | |
13063 | (set_attr "mode" "SI")]) | |
13064 | ||
d525dfdf JH |
13065 | (define_expand "ashrsi3" |
13066 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
155d8a47 | 13067 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") |
7ae14d31 | 13068 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d525dfdf JH |
13069 | "" |
13070 | "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;") | |
13071 | ||
8bad7136 JL |
13072 | (define_insn "*ashrsi3_1_one_bit" |
13073 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
13074 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
630eef90 | 13075 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 13076 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13077 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13078 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
0f40f9f7 | 13079 | "sar{l}\t%0" |
8bad7136 | 13080 | [(set_attr "type" "ishift") |
a952487c JJ |
13081 | (set_attr "length_immediate" "0") |
13082 | (set_attr "mode" "SI")]) | |
8bad7136 | 13083 | |
371bc54b JH |
13084 | (define_insn "*ashrsi3_1_one_bit_zext" |
13085 | [(set (match_operand:DI 0 "register_operand" "=r") | |
13086 | (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") | |
630eef90 | 13087 | (match_operand:QI 2 "const1_operand" "")))) |
8bc527af | 13088 | (clobber (reg:CC FLAGS_REG))] |
d5d5d289 | 13089 | "TARGET_64BIT |
3debdc1e | 13090 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13091 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
0f40f9f7 | 13092 | "sar{l}\t%k0" |
371bc54b | 13093 | [(set_attr "type" "ishift") |
a952487c JJ |
13094 | (set_attr "length_immediate" "0") |
13095 | (set_attr "mode" "SI")]) | |
371bc54b | 13096 | |
d525dfdf | 13097 | (define_insn "*ashrsi3_1" |
e075ae69 RH |
13098 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") |
13099 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
13100 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 13101 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 13102 | "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
e075ae69 | 13103 | "@ |
0f40f9f7 ZW |
13104 | sar{l}\t{%2, %0|%0, %2} |
13105 | sar{l}\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
13106 | [(set_attr "type" "ishift") |
13107 | (set_attr "mode" "SI")]) | |
886c62d1 | 13108 | |
371bc54b JH |
13109 | (define_insn "*ashrsi3_1_zext" |
13110 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
13111 | (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") | |
13112 | (match_operand:QI 2 "nonmemory_operand" "I,c")))) | |
8bc527af | 13113 | (clobber (reg:CC FLAGS_REG))] |
371bc54b JH |
13114 | "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
13115 | "@ | |
0f40f9f7 ZW |
13116 | sar{l}\t{%2, %k0|%k0, %2} |
13117 | sar{l}\t{%b2, %k0|%k0, %b2}" | |
371bc54b JH |
13118 | [(set_attr "type" "ishift") |
13119 | (set_attr "mode" "SI")]) | |
13120 | ||
8bad7136 JL |
13121 | ;; This pattern can't accept a variable shift count, since shifts by |
13122 | ;; zero don't affect the flags. We assume that shifts by constant | |
13123 | ;; zero are optimized away. | |
2c873473 | 13124 | (define_insn "*ashrsi3_one_bit_cmp" |
42fabf21 | 13125 | [(set (reg FLAGS_REG) |
8bad7136 JL |
13126 | (compare |
13127 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
630eef90 | 13128 | (match_operand:QI 2 "const1_operand" "")) |
8bad7136 JL |
13129 | (const_int 0))) |
13130 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
13131 | (ashiftrt:SI (match_dup 1) (match_dup 2)))] | |
3debdc1e | 13132 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13133 | && ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 | 13134 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
0f40f9f7 | 13135 | "sar{l}\t%0" |
8bad7136 | 13136 | [(set_attr "type" "ishift") |
a952487c JJ |
13137 | (set_attr "length_immediate" "0") |
13138 | (set_attr "mode" "SI")]) | |
8bad7136 | 13139 | |
f42684d5 UB |
13140 | (define_insn "*ashrsi3_one_bit_cconly" |
13141 | [(set (reg FLAGS_REG) | |
13142 | (compare | |
13143 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
13144 | (match_operand:QI 2 "const1_operand" "")) | |
13145 | (const_int 0))) | |
13146 | (clobber (match_scratch:SI 0 "=r"))] | |
3debdc1e | 13147 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13148 | && ix86_match_ccmode (insn, CCGOCmode) |
f42684d5 UB |
13149 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
13150 | "sar{l}\t%0" | |
13151 | [(set_attr "type" "ishift") | |
a952487c JJ |
13152 | (set_attr "length_immediate" "0") |
13153 | (set_attr "mode" "SI")]) | |
f42684d5 | 13154 | |
371bc54b | 13155 | (define_insn "*ashrsi3_one_bit_cmp_zext" |
42fabf21 | 13156 | [(set (reg FLAGS_REG) |
371bc54b JH |
13157 | (compare |
13158 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") | |
630eef90 | 13159 | (match_operand:QI 2 "const1_operand" "")) |
371bc54b JH |
13160 | (const_int 0))) |
13161 | (set (match_operand:DI 0 "register_operand" "=r") | |
13162 | (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] | |
d5d5d289 | 13163 | "TARGET_64BIT |
3debdc1e | 13164 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13165 | && ix86_match_ccmode (insn, CCmode) |
371bc54b | 13166 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" |
0f40f9f7 | 13167 | "sar{l}\t%k0" |
371bc54b | 13168 | [(set_attr "type" "ishift") |
a952487c JJ |
13169 | (set_attr "length_immediate" "0") |
13170 | (set_attr "mode" "SI")]) | |
371bc54b | 13171 | |
28cefcd2 BS |
13172 | ;; This pattern can't accept a variable shift count, since shifts by |
13173 | ;; zero don't affect the flags. We assume that shifts by constant | |
13174 | ;; zero are optimized away. | |
2c873473 | 13175 | (define_insn "*ashrsi3_cmp" |
42fabf21 | 13176 | [(set (reg FLAGS_REG) |
16189740 | 13177 | (compare |
28cefcd2 | 13178 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") |
ef719a44 | 13179 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 | 13180 | (const_int 0))) |
28cefcd2 | 13181 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 13182 | (ashiftrt:SI (match_dup 1) (match_dup 2)))] |
3debdc1e | 13183 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13184 | && ix86_match_ccmode (insn, CCGOCmode) |
13185 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" | |
0f40f9f7 | 13186 | "sar{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
13187 | [(set_attr "type" "ishift") |
13188 | (set_attr "mode" "SI")]) | |
886c62d1 | 13189 | |
f42684d5 UB |
13190 | (define_insn "*ashrsi3_cconly" |
13191 | [(set (reg FLAGS_REG) | |
13192 | (compare | |
13193 | (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
13194 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
13195 | (const_int 0))) | |
13196 | (clobber (match_scratch:SI 0 "=r"))] | |
3debdc1e | 13197 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13198 | && ix86_match_ccmode (insn, CCGOCmode) |
13199 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" | |
f42684d5 UB |
13200 | "sar{l}\t{%2, %0|%0, %2}" |
13201 | [(set_attr "type" "ishift") | |
13202 | (set_attr "mode" "SI")]) | |
13203 | ||
371bc54b | 13204 | (define_insn "*ashrsi3_cmp_zext" |
42fabf21 | 13205 | [(set (reg FLAGS_REG) |
371bc54b JH |
13206 | (compare |
13207 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") | |
ef719a44 | 13208 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
371bc54b JH |
13209 | (const_int 0))) |
13210 | (set (match_operand:DI 0 "register_operand" "=r") | |
13211 | (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] | |
d5d5d289 | 13212 | "TARGET_64BIT |
3debdc1e | 13213 | && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13214 | && ix86_match_ccmode (insn, CCGOCmode) |
13215 | && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" | |
0f40f9f7 | 13216 | "sar{l}\t{%2, %k0|%k0, %2}" |
371bc54b JH |
13217 | [(set_attr "type" "ishift") |
13218 | (set_attr "mode" "SI")]) | |
13219 | ||
d525dfdf JH |
13220 | (define_expand "ashrhi3" |
13221 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
155d8a47 | 13222 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") |
7ae14d31 | 13223 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 13224 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
13225 | "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;") |
13226 | ||
8bad7136 JL |
13227 | (define_insn "*ashrhi3_1_one_bit" |
13228 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
13229 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
630eef90 | 13230 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 13231 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13232 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13233 | && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" |
0f40f9f7 | 13234 | "sar{w}\t%0" |
8bad7136 | 13235 | [(set_attr "type" "ishift") |
a952487c JJ |
13236 | (set_attr "length_immediate" "0") |
13237 | (set_attr "mode" "HI")]) | |
8bad7136 | 13238 | |
d525dfdf | 13239 | (define_insn "*ashrhi3_1" |
e075ae69 RH |
13240 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") |
13241 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
13242 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 13243 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 13244 | "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" |
e075ae69 | 13245 | "@ |
0f40f9f7 ZW |
13246 | sar{w}\t{%2, %0|%0, %2} |
13247 | sar{w}\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
13248 | [(set_attr "type" "ishift") |
13249 | (set_attr "mode" "HI")]) | |
886c62d1 | 13250 | |
8bad7136 JL |
13251 | ;; This pattern can't accept a variable shift count, since shifts by |
13252 | ;; zero don't affect the flags. We assume that shifts by constant | |
13253 | ;; zero are optimized away. | |
2c873473 | 13254 | (define_insn "*ashrhi3_one_bit_cmp" |
42fabf21 | 13255 | [(set (reg FLAGS_REG) |
8bad7136 JL |
13256 | (compare |
13257 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
630eef90 | 13258 | (match_operand:QI 2 "const1_operand" "")) |
8bad7136 JL |
13259 | (const_int 0))) |
13260 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
13261 | (ashiftrt:HI (match_dup 1) (match_dup 2)))] | |
3debdc1e | 13262 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13263 | && ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 | 13264 | && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" |
0f40f9f7 | 13265 | "sar{w}\t%0" |
8bad7136 | 13266 | [(set_attr "type" "ishift") |
a952487c JJ |
13267 | (set_attr "length_immediate" "0") |
13268 | (set_attr "mode" "HI")]) | |
8bad7136 | 13269 | |
f42684d5 UB |
13270 | (define_insn "*ashrhi3_one_bit_cconly" |
13271 | [(set (reg FLAGS_REG) | |
13272 | (compare | |
13273 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
13274 | (match_operand:QI 2 "const1_operand" "")) | |
13275 | (const_int 0))) | |
13276 | (clobber (match_scratch:HI 0 "=r"))] | |
3debdc1e | 13277 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13278 | && ix86_match_ccmode (insn, CCGOCmode) |
f42684d5 UB |
13279 | && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" |
13280 | "sar{w}\t%0" | |
13281 | [(set_attr "type" "ishift") | |
a952487c JJ |
13282 | (set_attr "length_immediate" "0") |
13283 | (set_attr "mode" "HI")]) | |
f42684d5 | 13284 | |
28cefcd2 BS |
13285 | ;; This pattern can't accept a variable shift count, since shifts by |
13286 | ;; zero don't affect the flags. We assume that shifts by constant | |
13287 | ;; zero are optimized away. | |
2c873473 | 13288 | (define_insn "*ashrhi3_cmp" |
42fabf21 | 13289 | [(set (reg FLAGS_REG) |
16189740 | 13290 | (compare |
28cefcd2 | 13291 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") |
ef719a44 | 13292 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 | 13293 | (const_int 0))) |
28cefcd2 | 13294 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 13295 | (ashiftrt:HI (match_dup 1) (match_dup 2)))] |
3debdc1e | 13296 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13297 | && ix86_match_ccmode (insn, CCGOCmode) |
13298 | && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" | |
0f40f9f7 | 13299 | "sar{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
13300 | [(set_attr "type" "ishift") |
13301 | (set_attr "mode" "HI")]) | |
886c62d1 | 13302 | |
f42684d5 UB |
13303 | (define_insn "*ashrhi3_cconly" |
13304 | [(set (reg FLAGS_REG) | |
13305 | (compare | |
13306 | (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
13307 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
13308 | (const_int 0))) | |
13309 | (clobber (match_scratch:HI 0 "=r"))] | |
3debdc1e | 13310 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13311 | && ix86_match_ccmode (insn, CCGOCmode) |
13312 | && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" | |
f42684d5 UB |
13313 | "sar{w}\t{%2, %0|%0, %2}" |
13314 | [(set_attr "type" "ishift") | |
13315 | (set_attr "mode" "HI")]) | |
13316 | ||
d525dfdf JH |
13317 | (define_expand "ashrqi3" |
13318 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
155d8a47 | 13319 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") |
7ae14d31 | 13320 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 13321 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
13322 | "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;") |
13323 | ||
8bad7136 JL |
13324 | (define_insn "*ashrqi3_1_one_bit" |
13325 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
13326 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
630eef90 | 13327 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 13328 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13329 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13330 | && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" |
0f40f9f7 | 13331 | "sar{b}\t%0" |
8bad7136 | 13332 | [(set_attr "type" "ishift") |
a952487c JJ |
13333 | (set_attr "length_immediate" "0") |
13334 | (set_attr "mode" "QI")]) | |
8bad7136 | 13335 | |
2f41793e JH |
13336 | (define_insn "*ashrqi3_1_one_bit_slp" |
13337 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) | |
1b245ade | 13338 | (ashiftrt:QI (match_dup 0) |
630eef90 | 13339 | (match_operand:QI 1 "const1_operand" ""))) |
8bc527af | 13340 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e JH |
13341 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
13342 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) | |
d5d5d289 | 13343 | && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" |
2f41793e | 13344 | "sar{b}\t%0" |
1b245ade | 13345 | [(set_attr "type" "ishift1") |
a952487c JJ |
13346 | (set_attr "length_immediate" "0") |
13347 | (set_attr "mode" "QI")]) | |
2f41793e | 13348 | |
d525dfdf | 13349 | (define_insn "*ashrqi3_1" |
e075ae69 RH |
13350 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") |
13351 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
13352 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 13353 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 13354 | "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" |
e075ae69 | 13355 | "@ |
0f40f9f7 ZW |
13356 | sar{b}\t{%2, %0|%0, %2} |
13357 | sar{b}\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
13358 | [(set_attr "type" "ishift") |
13359 | (set_attr "mode" "QI")]) | |
886c62d1 | 13360 | |
2f41793e JH |
13361 | (define_insn "*ashrqi3_1_slp" |
13362 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) | |
1b245ade JH |
13363 | (ashiftrt:QI (match_dup 0) |
13364 | (match_operand:QI 1 "nonmemory_operand" "I,c"))) | |
8bc527af | 13365 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13366 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 13367 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
2f41793e | 13368 | "@ |
1b245ade JH |
13369 | sar{b}\t{%1, %0|%0, %1} |
13370 | sar{b}\t{%b1, %0|%0, %b1}" | |
13371 | [(set_attr "type" "ishift1") | |
2f41793e JH |
13372 | (set_attr "mode" "QI")]) |
13373 | ||
8bad7136 JL |
13374 | ;; This pattern can't accept a variable shift count, since shifts by |
13375 | ;; zero don't affect the flags. We assume that shifts by constant | |
13376 | ;; zero are optimized away. | |
2c873473 | 13377 | (define_insn "*ashrqi3_one_bit_cmp" |
42fabf21 | 13378 | [(set (reg FLAGS_REG) |
8bad7136 JL |
13379 | (compare |
13380 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
630eef90 | 13381 | (match_operand:QI 2 "const1_operand" "I")) |
8bad7136 | 13382 | (const_int 0))) |
5f90a099 | 13383 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
8bad7136 | 13384 | (ashiftrt:QI (match_dup 1) (match_dup 2)))] |
3debdc1e | 13385 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13386 | && ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 | 13387 | && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" |
0f40f9f7 | 13388 | "sar{b}\t%0" |
8bad7136 | 13389 | [(set_attr "type" "ishift") |
a952487c JJ |
13390 | (set_attr "length_immediate" "0") |
13391 | (set_attr "mode" "QI")]) | |
8bad7136 | 13392 | |
f42684d5 UB |
13393 | (define_insn "*ashrqi3_one_bit_cconly" |
13394 | [(set (reg FLAGS_REG) | |
13395 | (compare | |
13396 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
0edb82cb | 13397 | (match_operand:QI 2 "const1_operand" "")) |
f42684d5 UB |
13398 | (const_int 0))) |
13399 | (clobber (match_scratch:QI 0 "=q"))] | |
3debdc1e | 13400 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13401 | && ix86_match_ccmode (insn, CCGOCmode) |
f42684d5 UB |
13402 | && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" |
13403 | "sar{b}\t%0" | |
13404 | [(set_attr "type" "ishift") | |
a952487c JJ |
13405 | (set_attr "length_immediate" "0") |
13406 | (set_attr "mode" "QI")]) | |
f42684d5 | 13407 | |
28cefcd2 BS |
13408 | ;; This pattern can't accept a variable shift count, since shifts by |
13409 | ;; zero don't affect the flags. We assume that shifts by constant | |
13410 | ;; zero are optimized away. | |
2c873473 | 13411 | (define_insn "*ashrqi3_cmp" |
42fabf21 | 13412 | [(set (reg FLAGS_REG) |
16189740 | 13413 | (compare |
28cefcd2 | 13414 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") |
ef719a44 | 13415 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 | 13416 | (const_int 0))) |
5f90a099 | 13417 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
e075ae69 | 13418 | (ashiftrt:QI (match_dup 1) (match_dup 2)))] |
3debdc1e | 13419 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13420 | && ix86_match_ccmode (insn, CCGOCmode) |
13421 | && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" | |
0f40f9f7 | 13422 | "sar{b}\t{%2, %0|%0, %2}" |
6ef67412 JH |
13423 | [(set_attr "type" "ishift") |
13424 | (set_attr "mode" "QI")]) | |
f42684d5 UB |
13425 | |
13426 | (define_insn "*ashrqi3_cconly" | |
13427 | [(set (reg FLAGS_REG) | |
13428 | (compare | |
13429 | (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
13430 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
13431 | (const_int 0))) | |
13432 | (clobber (match_scratch:QI 0 "=q"))] | |
3debdc1e | 13433 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13434 | && ix86_match_ccmode (insn, CCGOCmode) |
13435 | && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" | |
f42684d5 UB |
13436 | "sar{b}\t{%2, %0|%0, %2}" |
13437 | [(set_attr "type" "ishift") | |
13438 | (set_attr "mode" "QI")]) | |
13439 | ||
886c62d1 | 13440 | \f |
e075ae69 RH |
13441 | ;; Logical shift instructions |
13442 | ||
13443 | ;; See comment above `ashldi3' about how this works. | |
13444 | ||
28356f52 | 13445 | (define_expand "lshrti3" |
934f2a96 UB |
13446 | [(set (match_operand:TI 0 "register_operand" "") |
13447 | (lshiftrt:TI (match_operand:TI 1 "register_operand" "") | |
13448 | (match_operand:QI 2 "nonmemory_operand" "")))] | |
28356f52 | 13449 | "TARGET_64BIT" |
934f2a96 | 13450 | "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;") |
28356f52 | 13451 | |
934f2a96 UB |
13452 | ;; This pattern must be defined before *lshrti3_1 to prevent |
13453 | ;; combine pass from converting sse2_lshrti3 to *lshrti3_1. | |
69c553ef | 13454 | |
95879c72 L |
13455 | (define_insn "*avx_lshrti3" |
13456 | [(set (match_operand:TI 0 "register_operand" "=x") | |
13457 | (lshiftrt:TI (match_operand:TI 1 "register_operand" "x") | |
13458 | (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))] | |
13459 | "TARGET_AVX" | |
13460 | { | |
13461 | operands[2] = GEN_INT (INTVAL (operands[2]) / 8); | |
13462 | return "vpsrldq\t{%2, %1, %0|%0, %1, %2}"; | |
13463 | } | |
13464 | [(set_attr "type" "sseishft") | |
13465 | (set_attr "prefix" "vex") | |
725fd454 | 13466 | (set_attr "length_immediate" "1") |
95879c72 L |
13467 | (set_attr "mode" "TI")]) |
13468 | ||
69c553ef UB |
13469 | (define_insn "sse2_lshrti3" |
13470 | [(set (match_operand:TI 0 "register_operand" "=x") | |
13471 | (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") | |
13472 | (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))] | |
13473 | "TARGET_SSE2" | |
13474 | { | |
13475 | operands[2] = GEN_INT (INTVAL (operands[2]) / 8); | |
13476 | return "psrldq\t{%2, %0|%0, %2}"; | |
13477 | } | |
13478 | [(set_attr "type" "sseishft") | |
13479 | (set_attr "prefix_data16" "1") | |
725fd454 | 13480 | (set_attr "length_immediate" "1") |
69c553ef UB |
13481 | (set_attr "mode" "TI")]) |
13482 | ||
934f2a96 | 13483 | (define_insn "*lshrti3_1" |
28356f52 JB |
13484 | [(set (match_operand:TI 0 "register_operand" "=r") |
13485 | (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") | |
934f2a96 | 13486 | (match_operand:QI 2 "nonmemory_operand" "Oc"))) |
28356f52 JB |
13487 | (clobber (reg:CC FLAGS_REG))] |
13488 | "TARGET_64BIT" | |
13489 | "#" | |
13490 | [(set_attr "type" "multi")]) | |
13491 | ||
934f2a96 UB |
13492 | (define_peephole2 |
13493 | [(match_scratch:DI 3 "r") | |
13494 | (parallel [(set (match_operand:TI 0 "register_operand" "") | |
13495 | (lshiftrt:TI (match_operand:TI 1 "register_operand" "") | |
13496 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
13497 | (clobber (reg:CC FLAGS_REG))]) | |
13498 | (match_dup 3)] | |
13499 | "TARGET_64BIT" | |
28356f52 JB |
13500 | [(const_int 0)] |
13501 | "ix86_split_lshr (operands, operands[3], TImode); DONE;") | |
13502 | ||
6300f037 | 13503 | (define_split |
28356f52 JB |
13504 | [(set (match_operand:TI 0 "register_operand" "") |
13505 | (lshiftrt:TI (match_operand:TI 1 "register_operand" "") | |
934f2a96 | 13506 | (match_operand:QI 2 "nonmemory_operand" ""))) |
28356f52 | 13507 | (clobber (reg:CC FLAGS_REG))] |
7059ea88 UB |
13508 | "TARGET_64BIT && ((optimize > 0 && flag_peephole2) |
13509 | ? epilogue_completed : reload_completed)" | |
28356f52 JB |
13510 | [(const_int 0)] |
13511 | "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;") | |
13512 | ||
e075ae69 | 13513 | (define_expand "lshrdi3" |
93330ea1 RH |
13514 | [(set (match_operand:DI 0 "shiftdi_operand" "") |
13515 | (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") | |
13516 | (match_operand:QI 2 "nonmemory_operand" "")))] | |
886c62d1 | 13517 | "" |
93330ea1 | 13518 | "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;") |
886c62d1 | 13519 | |
371bc54b JH |
13520 | (define_insn "*lshrdi3_1_one_bit_rex64" |
13521 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
13522 | (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
630eef90 | 13523 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 13524 | (clobber (reg:CC FLAGS_REG))] |
d5d5d289 | 13525 | "TARGET_64BIT |
3debdc1e | 13526 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13527 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
0f40f9f7 | 13528 | "shr{q}\t%0" |
371bc54b | 13529 | [(set_attr "type" "ishift") |
a952487c JJ |
13530 | (set_attr "length_immediate" "0") |
13531 | (set_attr "mode" "DI")]) | |
371bc54b JH |
13532 | |
13533 | (define_insn "*lshrdi3_1_rex64" | |
13534 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") | |
13535 | (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") | |
13536 | (match_operand:QI 2 "nonmemory_operand" "J,c"))) | |
8bc527af | 13537 | (clobber (reg:CC FLAGS_REG))] |
371bc54b JH |
13538 | "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
13539 | "@ | |
0f40f9f7 ZW |
13540 | shr{q}\t{%2, %0|%0, %2} |
13541 | shr{q}\t{%b2, %0|%0, %b2}" | |
371bc54b JH |
13542 | [(set_attr "type" "ishift") |
13543 | (set_attr "mode" "DI")]) | |
13544 | ||
13545 | ;; This pattern can't accept a variable shift count, since shifts by | |
13546 | ;; zero don't affect the flags. We assume that shifts by constant | |
13547 | ;; zero are optimized away. | |
13548 | (define_insn "*lshrdi3_cmp_one_bit_rex64" | |
42fabf21 | 13549 | [(set (reg FLAGS_REG) |
371bc54b JH |
13550 | (compare |
13551 | (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
630eef90 | 13552 | (match_operand:QI 2 "const1_operand" "")) |
371bc54b JH |
13553 | (const_int 0))) |
13554 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
13555 | (lshiftrt:DI (match_dup 1) (match_dup 2)))] | |
d5d5d289 | 13556 | "TARGET_64BIT |
3debdc1e | 13557 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13558 | && ix86_match_ccmode (insn, CCGOCmode) |
371bc54b | 13559 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
0f40f9f7 | 13560 | "shr{q}\t%0" |
371bc54b | 13561 | [(set_attr "type" "ishift") |
a952487c JJ |
13562 | (set_attr "length_immediate" "0") |
13563 | (set_attr "mode" "DI")]) | |
371bc54b | 13564 | |
f42684d5 UB |
13565 | (define_insn "*lshrdi3_cconly_one_bit_rex64" |
13566 | [(set (reg FLAGS_REG) | |
13567 | (compare | |
13568 | (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
13569 | (match_operand:QI 2 "const1_operand" "")) | |
13570 | (const_int 0))) | |
13571 | (clobber (match_scratch:DI 0 "=r"))] | |
d5d5d289 | 13572 | "TARGET_64BIT |
3debdc1e | 13573 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13574 | && ix86_match_ccmode (insn, CCGOCmode) |
f42684d5 UB |
13575 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
13576 | "shr{q}\t%0" | |
13577 | [(set_attr "type" "ishift") | |
a952487c JJ |
13578 | (set_attr "length_immediate" "0") |
13579 | (set_attr "mode" "DI")]) | |
f42684d5 | 13580 | |
371bc54b JH |
13581 | ;; This pattern can't accept a variable shift count, since shifts by |
13582 | ;; zero don't affect the flags. We assume that shifts by constant | |
13583 | ;; zero are optimized away. | |
13584 | (define_insn "*lshrdi3_cmp_rex64" | |
42fabf21 | 13585 | [(set (reg FLAGS_REG) |
371bc54b JH |
13586 | (compare |
13587 | (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
934f2a96 | 13588 | (match_operand:QI 2 "const_1_to_63_operand" "J")) |
371bc54b JH |
13589 | (const_int 0))) |
13590 | (set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
13591 | (lshiftrt:DI (match_dup 1) (match_dup 2)))] | |
d5d5d289 | 13592 | "TARGET_64BIT |
3debdc1e | 13593 | && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13594 | && ix86_match_ccmode (insn, CCGOCmode) |
13595 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
0f40f9f7 | 13596 | "shr{q}\t{%2, %0|%0, %2}" |
371bc54b JH |
13597 | [(set_attr "type" "ishift") |
13598 | (set_attr "mode" "DI")]) | |
13599 | ||
f42684d5 UB |
13600 | (define_insn "*lshrdi3_cconly_rex64" |
13601 | [(set (reg FLAGS_REG) | |
13602 | (compare | |
13603 | (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
934f2a96 | 13604 | (match_operand:QI 2 "const_1_to_63_operand" "J")) |
f42684d5 UB |
13605 | (const_int 0))) |
13606 | (clobber (match_scratch:DI 0 "=r"))] | |
d5d5d289 | 13607 | "TARGET_64BIT |
3debdc1e | 13608 | && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13609 | && ix86_match_ccmode (insn, CCGOCmode) |
13610 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
f42684d5 UB |
13611 | "shr{q}\t{%2, %0|%0, %2}" |
13612 | [(set_attr "type" "ishift") | |
13613 | (set_attr "mode" "DI")]) | |
13614 | ||
93330ea1 | 13615 | (define_insn "*lshrdi3_1" |
e075ae69 RH |
13616 | [(set (match_operand:DI 0 "register_operand" "=r") |
13617 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") | |
13618 | (match_operand:QI 2 "nonmemory_operand" "Jc"))) | |
8bc527af | 13619 | (clobber (reg:CC FLAGS_REG))] |
1e07edd3 | 13620 | "!TARGET_64BIT" |
e075ae69 RH |
13621 | "#" |
13622 | [(set_attr "type" "multi")]) | |
886c62d1 | 13623 | |
93330ea1 RH |
13624 | ;; By default we don't ask for a scratch register, because when DImode |
13625 | ;; values are manipulated, registers are already at a premium. But if | |
13626 | ;; we have one handy, we won't turn it away. | |
13627 | (define_peephole2 | |
13628 | [(match_scratch:SI 3 "r") | |
13629 | (parallel [(set (match_operand:DI 0 "register_operand" "") | |
13630 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
13631 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
13632 | (clobber (reg:CC FLAGS_REG))]) | |
13633 | (match_dup 3)] | |
13634 | "!TARGET_64BIT && TARGET_CMOVE" | |
e075ae69 | 13635 | [(const_int 0)] |
28356f52 | 13636 | "ix86_split_lshr (operands, operands[3], DImode); DONE;") |
886c62d1 | 13637 | |
6300f037 | 13638 | (define_split |
e075ae69 RH |
13639 | [(set (match_operand:DI 0 "register_operand" "") |
13640 | (lshiftrt:DI (match_operand:DI 1 "register_operand" "") | |
13641 | (match_operand:QI 2 "nonmemory_operand" ""))) | |
8bc527af | 13642 | (clobber (reg:CC FLAGS_REG))] |
99523994 | 13643 | "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) |
6fb5fa3c | 13644 | ? epilogue_completed : reload_completed)" |
e075ae69 | 13645 | [(const_int 0)] |
28356f52 | 13646 | "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;") |
886c62d1 | 13647 | |
d525dfdf JH |
13648 | (define_expand "lshrsi3" |
13649 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
13650 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
7ae14d31 | 13651 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d525dfdf JH |
13652 | "" |
13653 | "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;") | |
13654 | ||
8bad7136 JL |
13655 | (define_insn "*lshrsi3_1_one_bit" |
13656 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
13657 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
630eef90 | 13658 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 13659 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13660 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13661 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
0f40f9f7 | 13662 | "shr{l}\t%0" |
8bad7136 | 13663 | [(set_attr "type" "ishift") |
a952487c JJ |
13664 | (set_attr "length_immediate" "0") |
13665 | (set_attr "mode" "SI")]) | |
8bad7136 | 13666 | |
371bc54b JH |
13667 | (define_insn "*lshrsi3_1_one_bit_zext" |
13668 | [(set (match_operand:DI 0 "register_operand" "=r") | |
13669 | (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0")) | |
630eef90 | 13670 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 13671 | (clobber (reg:CC FLAGS_REG))] |
d5d5d289 | 13672 | "TARGET_64BIT |
3debdc1e | 13673 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13674 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
0f40f9f7 | 13675 | "shr{l}\t%k0" |
371bc54b | 13676 | [(set_attr "type" "ishift") |
a952487c JJ |
13677 | (set_attr "length_immediate" "0") |
13678 | (set_attr "mode" "SI")]) | |
371bc54b | 13679 | |
d525dfdf | 13680 | (define_insn "*lshrsi3_1" |
e075ae69 RH |
13681 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") |
13682 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
13683 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 13684 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 13685 | "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
e075ae69 | 13686 | "@ |
0f40f9f7 ZW |
13687 | shr{l}\t{%2, %0|%0, %2} |
13688 | shr{l}\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
13689 | [(set_attr "type" "ishift") |
13690 | (set_attr "mode" "SI")]) | |
886c62d1 | 13691 | |
371bc54b JH |
13692 | (define_insn "*lshrsi3_1_zext" |
13693 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
13694 | (zero_extend:DI | |
13695 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
13696 | (match_operand:QI 2 "nonmemory_operand" "I,c")))) | |
8bc527af | 13697 | (clobber (reg:CC FLAGS_REG))] |
371bc54b JH |
13698 | "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
13699 | "@ | |
0f40f9f7 ZW |
13700 | shr{l}\t{%2, %k0|%k0, %2} |
13701 | shr{l}\t{%b2, %k0|%k0, %b2}" | |
371bc54b JH |
13702 | [(set_attr "type" "ishift") |
13703 | (set_attr "mode" "SI")]) | |
13704 | ||
8bad7136 JL |
13705 | ;; This pattern can't accept a variable shift count, since shifts by |
13706 | ;; zero don't affect the flags. We assume that shifts by constant | |
13707 | ;; zero are optimized away. | |
2c873473 | 13708 | (define_insn "*lshrsi3_one_bit_cmp" |
42fabf21 | 13709 | [(set (reg FLAGS_REG) |
8bad7136 JL |
13710 | (compare |
13711 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
630eef90 | 13712 | (match_operand:QI 2 "const1_operand" "")) |
8bad7136 JL |
13713 | (const_int 0))) |
13714 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
13715 | (lshiftrt:SI (match_dup 1) (match_dup 2)))] | |
3debdc1e | 13716 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13717 | && ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 | 13718 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
0f40f9f7 | 13719 | "shr{l}\t%0" |
8bad7136 | 13720 | [(set_attr "type" "ishift") |
a952487c JJ |
13721 | (set_attr "length_immediate" "0") |
13722 | (set_attr "mode" "SI")]) | |
8bad7136 | 13723 | |
f42684d5 UB |
13724 | (define_insn "*lshrsi3_one_bit_cconly" |
13725 | [(set (reg FLAGS_REG) | |
13726 | (compare | |
13727 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
13728 | (match_operand:QI 2 "const1_operand" "")) | |
13729 | (const_int 0))) | |
13730 | (clobber (match_scratch:SI 0 "=r"))] | |
3debdc1e | 13731 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13732 | && ix86_match_ccmode (insn, CCGOCmode) |
f42684d5 UB |
13733 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
13734 | "shr{l}\t%0" | |
13735 | [(set_attr "type" "ishift") | |
a952487c JJ |
13736 | (set_attr "length_immediate" "0") |
13737 | (set_attr "mode" "SI")]) | |
f42684d5 | 13738 | |
371bc54b | 13739 | (define_insn "*lshrsi3_cmp_one_bit_zext" |
42fabf21 | 13740 | [(set (reg FLAGS_REG) |
371bc54b JH |
13741 | (compare |
13742 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") | |
630eef90 | 13743 | (match_operand:QI 2 "const1_operand" "")) |
371bc54b JH |
13744 | (const_int 0))) |
13745 | (set (match_operand:DI 0 "register_operand" "=r") | |
13746 | (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] | |
d5d5d289 | 13747 | "TARGET_64BIT |
3debdc1e | 13748 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13749 | && ix86_match_ccmode (insn, CCGOCmode) |
371bc54b | 13750 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
0f40f9f7 | 13751 | "shr{l}\t%k0" |
371bc54b | 13752 | [(set_attr "type" "ishift") |
a952487c JJ |
13753 | (set_attr "length_immediate" "0") |
13754 | (set_attr "mode" "SI")]) | |
371bc54b | 13755 | |
28cefcd2 BS |
13756 | ;; This pattern can't accept a variable shift count, since shifts by |
13757 | ;; zero don't affect the flags. We assume that shifts by constant | |
13758 | ;; zero are optimized away. | |
2c873473 | 13759 | (define_insn "*lshrsi3_cmp" |
42fabf21 | 13760 | [(set (reg FLAGS_REG) |
16189740 | 13761 | (compare |
28cefcd2 | 13762 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") |
ef719a44 | 13763 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 | 13764 | (const_int 0))) |
28cefcd2 | 13765 | (set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 13766 | (lshiftrt:SI (match_dup 1) (match_dup 2)))] |
3debdc1e | 13767 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13768 | && ix86_match_ccmode (insn, CCGOCmode) |
13769 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
0f40f9f7 | 13770 | "shr{l}\t{%2, %0|%0, %2}" |
6ef67412 JH |
13771 | [(set_attr "type" "ishift") |
13772 | (set_attr "mode" "SI")]) | |
886c62d1 | 13773 | |
f42684d5 UB |
13774 | (define_insn "*lshrsi3_cconly" |
13775 | [(set (reg FLAGS_REG) | |
13776 | (compare | |
13777 | (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
13778 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
13779 | (const_int 0))) | |
13780 | (clobber (match_scratch:SI 0 "=r"))] | |
3debdc1e | 13781 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13782 | && ix86_match_ccmode (insn, CCGOCmode) |
13783 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
f42684d5 UB |
13784 | "shr{l}\t{%2, %0|%0, %2}" |
13785 | [(set_attr "type" "ishift") | |
13786 | (set_attr "mode" "SI")]) | |
13787 | ||
371bc54b | 13788 | (define_insn "*lshrsi3_cmp_zext" |
42fabf21 | 13789 | [(set (reg FLAGS_REG) |
371bc54b JH |
13790 | (compare |
13791 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") | |
ef719a44 | 13792 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
371bc54b JH |
13793 | (const_int 0))) |
13794 | (set (match_operand:DI 0 "register_operand" "=r") | |
13795 | (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] | |
d5d5d289 | 13796 | "TARGET_64BIT |
3debdc1e | 13797 | && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13798 | && ix86_match_ccmode (insn, CCGOCmode) |
13799 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
0f40f9f7 | 13800 | "shr{l}\t{%2, %k0|%k0, %2}" |
371bc54b JH |
13801 | [(set_attr "type" "ishift") |
13802 | (set_attr "mode" "SI")]) | |
13803 | ||
d525dfdf JH |
13804 | (define_expand "lshrhi3" |
13805 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
13806 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7ae14d31 | 13807 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 13808 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
13809 | "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;") |
13810 | ||
8bad7136 JL |
13811 | (define_insn "*lshrhi3_1_one_bit" |
13812 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
13813 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
630eef90 | 13814 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 13815 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13816 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13817 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
0f40f9f7 | 13818 | "shr{w}\t%0" |
8bad7136 | 13819 | [(set_attr "type" "ishift") |
a952487c JJ |
13820 | (set_attr "length_immediate" "0") |
13821 | (set_attr "mode" "HI")]) | |
8bad7136 | 13822 | |
d525dfdf | 13823 | (define_insn "*lshrhi3_1" |
e075ae69 RH |
13824 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") |
13825 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
13826 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 13827 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 13828 | "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
e075ae69 | 13829 | "@ |
0f40f9f7 ZW |
13830 | shr{w}\t{%2, %0|%0, %2} |
13831 | shr{w}\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
13832 | [(set_attr "type" "ishift") |
13833 | (set_attr "mode" "HI")]) | |
886c62d1 | 13834 | |
8bad7136 JL |
13835 | ;; This pattern can't accept a variable shift count, since shifts by |
13836 | ;; zero don't affect the flags. We assume that shifts by constant | |
13837 | ;; zero are optimized away. | |
2c873473 | 13838 | (define_insn "*lshrhi3_one_bit_cmp" |
42fabf21 | 13839 | [(set (reg FLAGS_REG) |
8bad7136 JL |
13840 | (compare |
13841 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
630eef90 | 13842 | (match_operand:QI 2 "const1_operand" "")) |
8bad7136 JL |
13843 | (const_int 0))) |
13844 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
13845 | (lshiftrt:HI (match_dup 1) (match_dup 2)))] | |
3debdc1e | 13846 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13847 | && ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 | 13848 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
0f40f9f7 | 13849 | "shr{w}\t%0" |
8bad7136 | 13850 | [(set_attr "type" "ishift") |
a952487c JJ |
13851 | (set_attr "length_immediate" "0") |
13852 | (set_attr "mode" "HI")]) | |
8bad7136 | 13853 | |
f42684d5 UB |
13854 | (define_insn "*lshrhi3_one_bit_cconly" |
13855 | [(set (reg FLAGS_REG) | |
13856 | (compare | |
13857 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
13858 | (match_operand:QI 2 "const1_operand" "")) | |
13859 | (const_int 0))) | |
13860 | (clobber (match_scratch:HI 0 "=r"))] | |
3debdc1e | 13861 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13862 | && ix86_match_ccmode (insn, CCGOCmode) |
f42684d5 UB |
13863 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" |
13864 | "shr{w}\t%0" | |
13865 | [(set_attr "type" "ishift") | |
a952487c JJ |
13866 | (set_attr "length_immediate" "0") |
13867 | (set_attr "mode" "HI")]) | |
f42684d5 | 13868 | |
28cefcd2 BS |
13869 | ;; This pattern can't accept a variable shift count, since shifts by |
13870 | ;; zero don't affect the flags. We assume that shifts by constant | |
13871 | ;; zero are optimized away. | |
2c873473 | 13872 | (define_insn "*lshrhi3_cmp" |
42fabf21 | 13873 | [(set (reg FLAGS_REG) |
16189740 | 13874 | (compare |
28cefcd2 | 13875 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") |
ef719a44 | 13876 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 | 13877 | (const_int 0))) |
28cefcd2 | 13878 | (set (match_operand:HI 0 "nonimmediate_operand" "=rm") |
e075ae69 | 13879 | (lshiftrt:HI (match_dup 1) (match_dup 2)))] |
3debdc1e | 13880 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13881 | && ix86_match_ccmode (insn, CCGOCmode) |
13882 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
0f40f9f7 | 13883 | "shr{w}\t{%2, %0|%0, %2}" |
6ef67412 JH |
13884 | [(set_attr "type" "ishift") |
13885 | (set_attr "mode" "HI")]) | |
886c62d1 | 13886 | |
f42684d5 UB |
13887 | (define_insn "*lshrhi3_cconly" |
13888 | [(set (reg FLAGS_REG) | |
13889 | (compare | |
13890 | (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
13891 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
13892 | (const_int 0))) | |
13893 | (clobber (match_scratch:HI 0 "=r"))] | |
3debdc1e | 13894 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
13895 | && ix86_match_ccmode (insn, CCGOCmode) |
13896 | && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" | |
f42684d5 UB |
13897 | "shr{w}\t{%2, %0|%0, %2}" |
13898 | [(set_attr "type" "ishift") | |
13899 | (set_attr "mode" "HI")]) | |
13900 | ||
d525dfdf JH |
13901 | (define_expand "lshrqi3" |
13902 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
13903 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7ae14d31 | 13904 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 13905 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
13906 | "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;") |
13907 | ||
8bad7136 JL |
13908 | (define_insn "*lshrqi3_1_one_bit" |
13909 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
13910 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
630eef90 | 13911 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 13912 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13913 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13914 | && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" |
0f40f9f7 | 13915 | "shr{b}\t%0" |
8bad7136 | 13916 | [(set_attr "type" "ishift") |
a952487c JJ |
13917 | (set_attr "length_immediate" "0") |
13918 | (set_attr "mode" "QI")]) | |
8bad7136 | 13919 | |
2f41793e JH |
13920 | (define_insn "*lshrqi3_1_one_bit_slp" |
13921 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) | |
1b245ade | 13922 | (lshiftrt:QI (match_dup 0) |
630eef90 | 13923 | (match_operand:QI 1 "const1_operand" ""))) |
8bc527af | 13924 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e JH |
13925 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
13926 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))" | |
2f41793e | 13927 | "shr{b}\t%0" |
1b245ade | 13928 | [(set_attr "type" "ishift1") |
a952487c JJ |
13929 | (set_attr "length_immediate" "0") |
13930 | (set_attr "mode" "QI")]) | |
2f41793e | 13931 | |
d525dfdf | 13932 | (define_insn "*lshrqi3_1" |
e075ae69 RH |
13933 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") |
13934 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
13935 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 13936 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 13937 | "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" |
e075ae69 | 13938 | "@ |
0f40f9f7 ZW |
13939 | shr{b}\t{%2, %0|%0, %2} |
13940 | shr{b}\t{%b2, %0|%0, %b2}" | |
6ef67412 JH |
13941 | [(set_attr "type" "ishift") |
13942 | (set_attr "mode" "QI")]) | |
886c62d1 | 13943 | |
2f41793e JH |
13944 | (define_insn "*lshrqi3_1_slp" |
13945 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) | |
1b245ade JH |
13946 | (lshiftrt:QI (match_dup 0) |
13947 | (match_operand:QI 1 "nonmemory_operand" "I,c"))) | |
8bc527af | 13948 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 13949 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 13950 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
2f41793e | 13951 | "@ |
1b245ade JH |
13952 | shr{b}\t{%1, %0|%0, %1} |
13953 | shr{b}\t{%b1, %0|%0, %b1}" | |
13954 | [(set_attr "type" "ishift1") | |
2f41793e JH |
13955 | (set_attr "mode" "QI")]) |
13956 | ||
8bad7136 JL |
13957 | ;; This pattern can't accept a variable shift count, since shifts by |
13958 | ;; zero don't affect the flags. We assume that shifts by constant | |
13959 | ;; zero are optimized away. | |
2c873473 | 13960 | (define_insn "*lshrqi2_one_bit_cmp" |
42fabf21 | 13961 | [(set (reg FLAGS_REG) |
8bad7136 JL |
13962 | (compare |
13963 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
630eef90 | 13964 | (match_operand:QI 2 "const1_operand" "")) |
8bad7136 JL |
13965 | (const_int 0))) |
13966 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
13967 | (lshiftrt:QI (match_dup 1) (match_dup 2)))] | |
3debdc1e | 13968 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13969 | && ix86_match_ccmode (insn, CCGOCmode) |
8bad7136 | 13970 | && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" |
0f40f9f7 | 13971 | "shr{b}\t%0" |
8bad7136 | 13972 | [(set_attr "type" "ishift") |
a952487c JJ |
13973 | (set_attr "length_immediate" "0") |
13974 | (set_attr "mode" "QI")]) | |
8bad7136 | 13975 | |
f42684d5 UB |
13976 | (define_insn "*lshrqi2_one_bit_cconly" |
13977 | [(set (reg FLAGS_REG) | |
13978 | (compare | |
13979 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
13980 | (match_operand:QI 2 "const1_operand" "")) | |
13981 | (const_int 0))) | |
13982 | (clobber (match_scratch:QI 0 "=q"))] | |
3debdc1e | 13983 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 13984 | && ix86_match_ccmode (insn, CCGOCmode) |
f42684d5 UB |
13985 | && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" |
13986 | "shr{b}\t%0" | |
13987 | [(set_attr "type" "ishift") | |
a952487c JJ |
13988 | (set_attr "length_immediate" "0") |
13989 | (set_attr "mode" "QI")]) | |
f42684d5 | 13990 | |
28cefcd2 BS |
13991 | ;; This pattern can't accept a variable shift count, since shifts by |
13992 | ;; zero don't affect the flags. We assume that shifts by constant | |
13993 | ;; zero are optimized away. | |
2c873473 | 13994 | (define_insn "*lshrqi2_cmp" |
42fabf21 | 13995 | [(set (reg FLAGS_REG) |
16189740 | 13996 | (compare |
28cefcd2 | 13997 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") |
ef719a44 | 13998 | (match_operand:QI 2 "const_1_to_31_operand" "I")) |
e075ae69 | 13999 | (const_int 0))) |
122ddbf9 | 14000 | (set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
e075ae69 | 14001 | (lshiftrt:QI (match_dup 1) (match_dup 2)))] |
3debdc1e | 14002 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
14003 | && ix86_match_ccmode (insn, CCGOCmode) |
14004 | && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" | |
0f40f9f7 | 14005 | "shr{b}\t{%2, %0|%0, %2}" |
6ef67412 JH |
14006 | [(set_attr "type" "ishift") |
14007 | (set_attr "mode" "QI")]) | |
f42684d5 UB |
14008 | |
14009 | (define_insn "*lshrqi2_cconly" | |
14010 | [(set (reg FLAGS_REG) | |
14011 | (compare | |
14012 | (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
14013 | (match_operand:QI 2 "const_1_to_31_operand" "I")) | |
14014 | (const_int 0))) | |
14015 | (clobber (match_scratch:QI 0 "=q"))] | |
3debdc1e | 14016 | "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL) |
d5d5d289 L |
14017 | && ix86_match_ccmode (insn, CCGOCmode) |
14018 | && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" | |
f42684d5 UB |
14019 | "shr{b}\t{%2, %0|%0, %2}" |
14020 | [(set_attr "type" "ishift") | |
14021 | (set_attr "mode" "QI")]) | |
886c62d1 | 14022 | \f |
e075ae69 | 14023 | ;; Rotate instructions |
886c62d1 | 14024 | |
371bc54b | 14025 | (define_expand "rotldi3" |
0f8594ee MM |
14026 | [(set (match_operand:DI 0 "shiftdi_operand" "") |
14027 | (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") | |
7ae14d31 | 14028 | (match_operand:QI 2 "nonmemory_operand" "")))] |
0f8594ee MM |
14029 | "" |
14030 | { | |
14031 | if (TARGET_64BIT) | |
14032 | { | |
14033 | ix86_expand_binary_operator (ROTATE, DImode, operands); | |
14034 | DONE; | |
14035 | } | |
14036 | if (!const_1_to_31_operand (operands[2], VOIDmode)) | |
14037 | FAIL; | |
14038 | emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2])); | |
14039 | DONE; | |
14040 | }) | |
371bc54b | 14041 | |
0f8594ee | 14042 | ;; Implement rotation using two double-precision shift instructions |
6300f037 | 14043 | ;; and a scratch register. |
0f8594ee MM |
14044 | (define_insn_and_split "ix86_rotldi3" |
14045 | [(set (match_operand:DI 0 "register_operand" "=r") | |
14046 | (rotate:DI (match_operand:DI 1 "register_operand" "0") | |
14047 | (match_operand:QI 2 "const_1_to_31_operand" "I"))) | |
14048 | (clobber (reg:CC FLAGS_REG)) | |
14049 | (clobber (match_scratch:SI 3 "=&r"))] | |
14050 | "!TARGET_64BIT" | |
6300f037 | 14051 | "" |
0f8594ee MM |
14052 | "&& reload_completed" |
14053 | [(set (match_dup 3) (match_dup 4)) | |
14054 | (parallel | |
14055 | [(set (match_dup 4) | |
14056 | (ior:SI (ashift:SI (match_dup 4) (match_dup 2)) | |
14057 | (lshiftrt:SI (match_dup 5) | |
14058 | (minus:QI (const_int 32) (match_dup 2))))) | |
14059 | (clobber (reg:CC FLAGS_REG))]) | |
14060 | (parallel | |
14061 | [(set (match_dup 5) | |
14062 | (ior:SI (ashift:SI (match_dup 5) (match_dup 2)) | |
14063 | (lshiftrt:SI (match_dup 3) | |
14064 | (minus:QI (const_int 32) (match_dup 2))))) | |
14065 | (clobber (reg:CC FLAGS_REG))])] | |
c2b814b9 | 14066 | "split_di (&operands[0], 1, &operands[4], &operands[5]);") |
6300f037 | 14067 | |
371bc54b JH |
14068 | (define_insn "*rotlsi3_1_one_bit_rex64" |
14069 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
14070 | (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
630eef90 | 14071 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 14072 | (clobber (reg:CC FLAGS_REG))] |
d5d5d289 | 14073 | "TARGET_64BIT |
3debdc1e | 14074 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14075 | && ix86_binary_operator_ok (ROTATE, DImode, operands)" |
0f40f9f7 | 14076 | "rol{q}\t%0" |
890d52e8 | 14077 | [(set_attr "type" "rotate") |
a952487c JJ |
14078 | (set_attr "length_immediate" "0") |
14079 | (set_attr "mode" "DI")]) | |
371bc54b JH |
14080 | |
14081 | (define_insn "*rotldi3_1_rex64" | |
14082 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") | |
14083 | (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") | |
14084 | (match_operand:QI 2 "nonmemory_operand" "e,c"))) | |
8bc527af | 14085 | (clobber (reg:CC FLAGS_REG))] |
371bc54b JH |
14086 | "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)" |
14087 | "@ | |
0f40f9f7 ZW |
14088 | rol{q}\t{%2, %0|%0, %2} |
14089 | rol{q}\t{%b2, %0|%0, %b2}" | |
890d52e8 | 14090 | [(set_attr "type" "rotate") |
371bc54b JH |
14091 | (set_attr "mode" "DI")]) |
14092 | ||
d525dfdf JH |
14093 | (define_expand "rotlsi3" |
14094 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
14095 | (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
7ae14d31 | 14096 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d525dfdf JH |
14097 | "" |
14098 | "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") | |
14099 | ||
8bad7136 JL |
14100 | (define_insn "*rotlsi3_1_one_bit" |
14101 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
14102 | (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
630eef90 | 14103 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 14104 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 14105 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14106 | && ix86_binary_operator_ok (ROTATE, SImode, operands)" |
0f40f9f7 | 14107 | "rol{l}\t%0" |
890d52e8 | 14108 | [(set_attr "type" "rotate") |
a952487c JJ |
14109 | (set_attr "length_immediate" "0") |
14110 | (set_attr "mode" "SI")]) | |
8bad7136 | 14111 | |
371bc54b JH |
14112 | (define_insn "*rotlsi3_1_one_bit_zext" |
14113 | [(set (match_operand:DI 0 "register_operand" "=r") | |
14114 | (zero_extend:DI | |
14115 | (rotate:SI (match_operand:SI 1 "register_operand" "0") | |
630eef90 | 14116 | (match_operand:QI 2 "const1_operand" "")))) |
8bc527af | 14117 | (clobber (reg:CC FLAGS_REG))] |
d5d5d289 | 14118 | "TARGET_64BIT |
3debdc1e | 14119 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14120 | && ix86_binary_operator_ok (ROTATE, SImode, operands)" |
0f40f9f7 | 14121 | "rol{l}\t%k0" |
890d52e8 | 14122 | [(set_attr "type" "rotate") |
a952487c JJ |
14123 | (set_attr "length_immediate" "0") |
14124 | (set_attr "mode" "SI")]) | |
371bc54b | 14125 | |
d525dfdf | 14126 | (define_insn "*rotlsi3_1" |
e075ae69 RH |
14127 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") |
14128 | (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
14129 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 14130 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 14131 | "ix86_binary_operator_ok (ROTATE, SImode, operands)" |
e075ae69 | 14132 | "@ |
0f40f9f7 ZW |
14133 | rol{l}\t{%2, %0|%0, %2} |
14134 | rol{l}\t{%b2, %0|%0, %b2}" | |
890d52e8 | 14135 | [(set_attr "type" "rotate") |
6ef67412 | 14136 | (set_attr "mode" "SI")]) |
b4ac57ab | 14137 | |
371bc54b JH |
14138 | (define_insn "*rotlsi3_1_zext" |
14139 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
14140 | (zero_extend:DI | |
14141 | (rotate:SI (match_operand:SI 1 "register_operand" "0,0") | |
14142 | (match_operand:QI 2 "nonmemory_operand" "I,c")))) | |
8bc527af | 14143 | (clobber (reg:CC FLAGS_REG))] |
371bc54b JH |
14144 | "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)" |
14145 | "@ | |
0f40f9f7 ZW |
14146 | rol{l}\t{%2, %k0|%k0, %2} |
14147 | rol{l}\t{%b2, %k0|%k0, %b2}" | |
890d52e8 | 14148 | [(set_attr "type" "rotate") |
371bc54b JH |
14149 | (set_attr "mode" "SI")]) |
14150 | ||
d525dfdf JH |
14151 | (define_expand "rotlhi3" |
14152 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
14153 | (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7ae14d31 | 14154 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 14155 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
14156 | "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") |
14157 | ||
8bad7136 JL |
14158 | (define_insn "*rotlhi3_1_one_bit" |
14159 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
14160 | (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
630eef90 | 14161 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 14162 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 14163 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14164 | && ix86_binary_operator_ok (ROTATE, HImode, operands)" |
0f40f9f7 | 14165 | "rol{w}\t%0" |
890d52e8 | 14166 | [(set_attr "type" "rotate") |
a952487c JJ |
14167 | (set_attr "length_immediate" "0") |
14168 | (set_attr "mode" "HI")]) | |
8bad7136 | 14169 | |
d525dfdf | 14170 | (define_insn "*rotlhi3_1" |
e075ae69 RH |
14171 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") |
14172 | (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
14173 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 14174 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 14175 | "ix86_binary_operator_ok (ROTATE, HImode, operands)" |
e075ae69 | 14176 | "@ |
0f40f9f7 ZW |
14177 | rol{w}\t{%2, %0|%0, %2} |
14178 | rol{w}\t{%b2, %0|%0, %b2}" | |
890d52e8 | 14179 | [(set_attr "type" "rotate") |
6ef67412 | 14180 | (set_attr "mode" "HI")]) |
47af5d50 | 14181 | |
fa681e39 UB |
14182 | (define_split |
14183 | [(set (match_operand:HI 0 "register_operand" "") | |
14184 | (rotate:HI (match_dup 0) (const_int 8))) | |
14185 | (clobber (reg:CC FLAGS_REG))] | |
14186 | "reload_completed" | |
14187 | [(parallel [(set (strict_low_part (match_dup 0)) | |
14188 | (bswap:HI (match_dup 0))) | |
14189 | (clobber (reg:CC FLAGS_REG))])] | |
14190 | "") | |
14191 | ||
d525dfdf JH |
14192 | (define_expand "rotlqi3" |
14193 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
14194 | (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7ae14d31 | 14195 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 14196 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
14197 | "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") |
14198 | ||
2f41793e JH |
14199 | (define_insn "*rotlqi3_1_one_bit_slp" |
14200 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) | |
1b245ade | 14201 | (rotate:QI (match_dup 0) |
630eef90 | 14202 | (match_operand:QI 1 "const1_operand" ""))) |
8bc527af | 14203 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e JH |
14204 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
14205 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))" | |
2f41793e | 14206 | "rol{b}\t%0" |
1b245ade | 14207 | [(set_attr "type" "rotate1") |
a952487c JJ |
14208 | (set_attr "length_immediate" "0") |
14209 | (set_attr "mode" "QI")]) | |
2f41793e | 14210 | |
8bad7136 JL |
14211 | (define_insn "*rotlqi3_1_one_bit" |
14212 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
14213 | (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
630eef90 | 14214 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 14215 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 14216 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14217 | && ix86_binary_operator_ok (ROTATE, QImode, operands)" |
0f40f9f7 | 14218 | "rol{b}\t%0" |
890d52e8 | 14219 | [(set_attr "type" "rotate") |
a952487c JJ |
14220 | (set_attr "length_immediate" "0") |
14221 | (set_attr "mode" "QI")]) | |
8bad7136 | 14222 | |
2f41793e JH |
14223 | (define_insn "*rotlqi3_1_slp" |
14224 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) | |
1b245ade JH |
14225 | (rotate:QI (match_dup 0) |
14226 | (match_operand:QI 1 "nonmemory_operand" "I,c"))) | |
8bc527af | 14227 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 14228 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 14229 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
2f41793e | 14230 | "@ |
1b245ade JH |
14231 | rol{b}\t{%1, %0|%0, %1} |
14232 | rol{b}\t{%b1, %0|%0, %b1}" | |
14233 | [(set_attr "type" "rotate1") | |
2f41793e JH |
14234 | (set_attr "mode" "QI")]) |
14235 | ||
d525dfdf | 14236 | (define_insn "*rotlqi3_1" |
e075ae69 RH |
14237 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") |
14238 | (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
14239 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 14240 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 14241 | "ix86_binary_operator_ok (ROTATE, QImode, operands)" |
e075ae69 | 14242 | "@ |
0f40f9f7 ZW |
14243 | rol{b}\t{%2, %0|%0, %2} |
14244 | rol{b}\t{%b2, %0|%0, %b2}" | |
890d52e8 | 14245 | [(set_attr "type" "rotate") |
6ef67412 | 14246 | (set_attr "mode" "QI")]) |
47af5d50 | 14247 | |
371bc54b | 14248 | (define_expand "rotrdi3" |
0f8594ee MM |
14249 | [(set (match_operand:DI 0 "shiftdi_operand" "") |
14250 | (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") | |
7ae14d31 | 14251 | (match_operand:QI 2 "nonmemory_operand" "")))] |
0f8594ee MM |
14252 | "" |
14253 | { | |
14254 | if (TARGET_64BIT) | |
14255 | { | |
14256 | ix86_expand_binary_operator (ROTATERT, DImode, operands); | |
14257 | DONE; | |
14258 | } | |
14259 | if (!const_1_to_31_operand (operands[2], VOIDmode)) | |
14260 | FAIL; | |
14261 | emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2])); | |
14262 | DONE; | |
14263 | }) | |
6300f037 | 14264 | |
0f8594ee | 14265 | ;; Implement rotation using two double-precision shift instructions |
6300f037 | 14266 | ;; and a scratch register. |
0f8594ee MM |
14267 | (define_insn_and_split "ix86_rotrdi3" |
14268 | [(set (match_operand:DI 0 "register_operand" "=r") | |
14269 | (rotatert:DI (match_operand:DI 1 "register_operand" "0") | |
14270 | (match_operand:QI 2 "const_1_to_31_operand" "I"))) | |
14271 | (clobber (reg:CC FLAGS_REG)) | |
14272 | (clobber (match_scratch:SI 3 "=&r"))] | |
14273 | "!TARGET_64BIT" | |
14274 | "" | |
14275 | "&& reload_completed" | |
14276 | [(set (match_dup 3) (match_dup 4)) | |
14277 | (parallel | |
14278 | [(set (match_dup 4) | |
14279 | (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2)) | |
14280 | (ashift:SI (match_dup 5) | |
14281 | (minus:QI (const_int 32) (match_dup 2))))) | |
14282 | (clobber (reg:CC FLAGS_REG))]) | |
14283 | (parallel | |
14284 | [(set (match_dup 5) | |
14285 | (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2)) | |
14286 | (ashift:SI (match_dup 3) | |
14287 | (minus:QI (const_int 32) (match_dup 2))))) | |
14288 | (clobber (reg:CC FLAGS_REG))])] | |
c2b814b9 | 14289 | "split_di (&operands[0], 1, &operands[4], &operands[5]);") |
371bc54b JH |
14290 | |
14291 | (define_insn "*rotrdi3_1_one_bit_rex64" | |
14292 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") | |
14293 | (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0") | |
630eef90 | 14294 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 14295 | (clobber (reg:CC FLAGS_REG))] |
d5d5d289 | 14296 | "TARGET_64BIT |
3debdc1e | 14297 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14298 | && ix86_binary_operator_ok (ROTATERT, DImode, operands)" |
0f40f9f7 | 14299 | "ror{q}\t%0" |
890d52e8 | 14300 | [(set_attr "type" "rotate") |
a952487c JJ |
14301 | (set_attr "length_immediate" "0") |
14302 | (set_attr "mode" "DI")]) | |
371bc54b JH |
14303 | |
14304 | (define_insn "*rotrdi3_1_rex64" | |
14305 | [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") | |
14306 | (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") | |
14307 | (match_operand:QI 2 "nonmemory_operand" "J,c"))) | |
8bc527af | 14308 | (clobber (reg:CC FLAGS_REG))] |
371bc54b JH |
14309 | "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)" |
14310 | "@ | |
0f40f9f7 ZW |
14311 | ror{q}\t{%2, %0|%0, %2} |
14312 | ror{q}\t{%b2, %0|%0, %b2}" | |
890d52e8 | 14313 | [(set_attr "type" "rotate") |
371bc54b JH |
14314 | (set_attr "mode" "DI")]) |
14315 | ||
d525dfdf JH |
14316 | (define_expand "rotrsi3" |
14317 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
14318 | (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
7ae14d31 | 14319 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d525dfdf JH |
14320 | "" |
14321 | "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") | |
14322 | ||
8bad7136 JL |
14323 | (define_insn "*rotrsi3_1_one_bit" |
14324 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
14325 | (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") | |
630eef90 | 14326 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 14327 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 14328 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14329 | && ix86_binary_operator_ok (ROTATERT, SImode, operands)" |
0f40f9f7 | 14330 | "ror{l}\t%0" |
890d52e8 | 14331 | [(set_attr "type" "rotate") |
a952487c JJ |
14332 | (set_attr "length_immediate" "0") |
14333 | (set_attr "mode" "SI")]) | |
8bad7136 | 14334 | |
371bc54b JH |
14335 | (define_insn "*rotrsi3_1_one_bit_zext" |
14336 | [(set (match_operand:DI 0 "register_operand" "=r") | |
14337 | (zero_extend:DI | |
14338 | (rotatert:SI (match_operand:SI 1 "register_operand" "0") | |
630eef90 | 14339 | (match_operand:QI 2 "const1_operand" "")))) |
8bc527af | 14340 | (clobber (reg:CC FLAGS_REG))] |
d5d5d289 | 14341 | "TARGET_64BIT |
3debdc1e | 14342 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14343 | && ix86_binary_operator_ok (ROTATERT, SImode, operands)" |
0f40f9f7 | 14344 | "ror{l}\t%k0" |
890d52e8 | 14345 | [(set_attr "type" "rotate") |
a952487c JJ |
14346 | (set_attr "length_immediate" "0") |
14347 | (set_attr "mode" "SI")]) | |
371bc54b | 14348 | |
d525dfdf | 14349 | (define_insn "*rotrsi3_1" |
e075ae69 RH |
14350 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") |
14351 | (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") | |
14352 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 14353 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 14354 | "ix86_binary_operator_ok (ROTATERT, SImode, operands)" |
e075ae69 | 14355 | "@ |
0f40f9f7 ZW |
14356 | ror{l}\t{%2, %0|%0, %2} |
14357 | ror{l}\t{%b2, %0|%0, %b2}" | |
890d52e8 | 14358 | [(set_attr "type" "rotate") |
6ef67412 | 14359 | (set_attr "mode" "SI")]) |
47af5d50 | 14360 | |
371bc54b JH |
14361 | (define_insn "*rotrsi3_1_zext" |
14362 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
14363 | (zero_extend:DI | |
14364 | (rotatert:SI (match_operand:SI 1 "register_operand" "0,0") | |
14365 | (match_operand:QI 2 "nonmemory_operand" "I,c")))) | |
8bc527af | 14366 | (clobber (reg:CC FLAGS_REG))] |
371bc54b JH |
14367 | "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" |
14368 | "@ | |
0f40f9f7 ZW |
14369 | ror{l}\t{%2, %k0|%k0, %2} |
14370 | ror{l}\t{%b2, %k0|%k0, %b2}" | |
890d52e8 | 14371 | [(set_attr "type" "rotate") |
371bc54b JH |
14372 | (set_attr "mode" "SI")]) |
14373 | ||
d525dfdf JH |
14374 | (define_expand "rotrhi3" |
14375 | [(set (match_operand:HI 0 "nonimmediate_operand" "") | |
14376 | (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
7ae14d31 | 14377 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 14378 | "TARGET_HIMODE_MATH" |
d525dfdf JH |
14379 | "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") |
14380 | ||
8bad7136 JL |
14381 | (define_insn "*rotrhi3_one_bit" |
14382 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") | |
14383 | (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") | |
630eef90 | 14384 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 14385 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 14386 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14387 | && ix86_binary_operator_ok (ROTATERT, HImode, operands)" |
0f40f9f7 | 14388 | "ror{w}\t%0" |
890d52e8 | 14389 | [(set_attr "type" "rotate") |
a952487c JJ |
14390 | (set_attr "length_immediate" "0") |
14391 | (set_attr "mode" "HI")]) | |
8bad7136 | 14392 | |
fa681e39 | 14393 | (define_insn "*rotrhi3_1" |
e075ae69 RH |
14394 | [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") |
14395 | (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") | |
14396 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 14397 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 14398 | "ix86_binary_operator_ok (ROTATERT, HImode, operands)" |
e075ae69 | 14399 | "@ |
0f40f9f7 ZW |
14400 | ror{w}\t{%2, %0|%0, %2} |
14401 | ror{w}\t{%b2, %0|%0, %b2}" | |
890d52e8 | 14402 | [(set_attr "type" "rotate") |
6ef67412 | 14403 | (set_attr "mode" "HI")]) |
a199fdd6 | 14404 | |
fa681e39 UB |
14405 | (define_split |
14406 | [(set (match_operand:HI 0 "register_operand" "") | |
14407 | (rotatert:HI (match_dup 0) (const_int 8))) | |
14408 | (clobber (reg:CC FLAGS_REG))] | |
14409 | "reload_completed" | |
14410 | [(parallel [(set (strict_low_part (match_dup 0)) | |
14411 | (bswap:HI (match_dup 0))) | |
14412 | (clobber (reg:CC FLAGS_REG))])] | |
14413 | "") | |
14414 | ||
d525dfdf JH |
14415 | (define_expand "rotrqi3" |
14416 | [(set (match_operand:QI 0 "nonimmediate_operand" "") | |
14417 | (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") | |
7ae14d31 | 14418 | (match_operand:QI 2 "nonmemory_operand" "")))] |
d9f32422 | 14419 | "TARGET_QIMODE_MATH" |
d525dfdf JH |
14420 | "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") |
14421 | ||
8bad7136 JL |
14422 | (define_insn "*rotrqi3_1_one_bit" |
14423 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") | |
14424 | (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") | |
630eef90 | 14425 | (match_operand:QI 2 "const1_operand" ""))) |
8bc527af | 14426 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 14427 | "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) |
d5d5d289 | 14428 | && ix86_binary_operator_ok (ROTATERT, QImode, operands)" |
0f40f9f7 | 14429 | "ror{b}\t%0" |
890d52e8 | 14430 | [(set_attr "type" "rotate") |
a952487c JJ |
14431 | (set_attr "length_immediate" "0") |
14432 | (set_attr "mode" "QI")]) | |
8bad7136 | 14433 | |
2f41793e JH |
14434 | (define_insn "*rotrqi3_1_one_bit_slp" |
14435 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) | |
1b245ade | 14436 | (rotatert:QI (match_dup 0) |
630eef90 | 14437 | (match_operand:QI 1 "const1_operand" ""))) |
8bc527af | 14438 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e JH |
14439 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
14440 | && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))" | |
2f41793e | 14441 | "ror{b}\t%0" |
1b245ade | 14442 | [(set_attr "type" "rotate1") |
a952487c JJ |
14443 | (set_attr "length_immediate" "0") |
14444 | (set_attr "mode" "QI")]) | |
2f41793e | 14445 | |
d525dfdf | 14446 | (define_insn "*rotrqi3_1" |
e075ae69 RH |
14447 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") |
14448 | (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") | |
14449 | (match_operand:QI 2 "nonmemory_operand" "I,c"))) | |
8bc527af | 14450 | (clobber (reg:CC FLAGS_REG))] |
d525dfdf | 14451 | "ix86_binary_operator_ok (ROTATERT, QImode, operands)" |
e075ae69 | 14452 | "@ |
0f40f9f7 ZW |
14453 | ror{b}\t{%2, %0|%0, %2} |
14454 | ror{b}\t{%b2, %0|%0, %b2}" | |
890d52e8 | 14455 | [(set_attr "type" "rotate") |
6ef67412 | 14456 | (set_attr "mode" "QI")]) |
2f41793e JH |
14457 | |
14458 | (define_insn "*rotrqi3_1_slp" | |
14459 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) | |
1b245ade JH |
14460 | (rotatert:QI (match_dup 0) |
14461 | (match_operand:QI 1 "nonmemory_operand" "I,c"))) | |
8bc527af | 14462 | (clobber (reg:CC FLAGS_REG))] |
3debdc1e | 14463 | "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) |
7656aee4 | 14464 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" |
2f41793e | 14465 | "@ |
1b245ade JH |
14466 | ror{b}\t{%1, %0|%0, %1} |
14467 | ror{b}\t{%b1, %0|%0, %b1}" | |
14468 | [(set_attr "type" "rotate1") | |
2f41793e | 14469 | (set_attr "mode" "QI")]) |
e075ae69 RH |
14470 | \f |
14471 | ;; Bit set / bit test instructions | |
a199fdd6 | 14472 | |
e075ae69 RH |
14473 | (define_expand "extv" |
14474 | [(set (match_operand:SI 0 "register_operand" "") | |
14475 | (sign_extract:SI (match_operand:SI 1 "register_operand" "") | |
f7acbf4c RS |
14476 | (match_operand:SI 2 "const8_operand" "") |
14477 | (match_operand:SI 3 "const8_operand" "")))] | |
e075ae69 | 14478 | "" |
e075ae69 RH |
14479 | { |
14480 | /* Handle extractions from %ah et al. */ | |
14481 | if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) | |
14482 | FAIL; | |
a199fdd6 | 14483 | |
e075ae69 RH |
14484 | /* From mips.md: extract_bit_field doesn't verify that our source |
14485 | matches the predicate, so check it again here. */ | |
6e62a38d | 14486 | if (! ext_register_operand (operands[1], VOIDmode)) |
e075ae69 | 14487 | FAIL; |
0f40f9f7 | 14488 | }) |
a199fdd6 | 14489 | |
e075ae69 RH |
14490 | (define_expand "extzv" |
14491 | [(set (match_operand:SI 0 "register_operand" "") | |
14492 | (zero_extract:SI (match_operand 1 "ext_register_operand" "") | |
f7acbf4c RS |
14493 | (match_operand:SI 2 "const8_operand" "") |
14494 | (match_operand:SI 3 "const8_operand" "")))] | |
e075ae69 | 14495 | "" |
e075ae69 RH |
14496 | { |
14497 | /* Handle extractions from %ah et al. */ | |
14498 | if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) | |
14499 | FAIL; | |
a199fdd6 | 14500 | |
e075ae69 RH |
14501 | /* From mips.md: extract_bit_field doesn't verify that our source |
14502 | matches the predicate, so check it again here. */ | |
6e62a38d | 14503 | if (! ext_register_operand (operands[1], VOIDmode)) |
e075ae69 | 14504 | FAIL; |
0f40f9f7 | 14505 | }) |
a199fdd6 | 14506 | |
e075ae69 | 14507 | (define_expand "insv" |
044b3892 | 14508 | [(set (zero_extract (match_operand 0 "ext_register_operand" "") |
f7acbf4c RS |
14509 | (match_operand 1 "const8_operand" "") |
14510 | (match_operand 2 "const8_operand" "")) | |
044b3892 | 14511 | (match_operand 3 "register_operand" ""))] |
e075ae69 | 14512 | "" |
e075ae69 | 14513 | { |
f7acbf4c | 14514 | /* Handle insertions to %ah et al. */ |
e075ae69 RH |
14515 | if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) |
14516 | FAIL; | |
a199fdd6 | 14517 | |
e075ae69 RH |
14518 | /* From mips.md: insert_bit_field doesn't verify that our source |
14519 | matches the predicate, so check it again here. */ | |
6e62a38d | 14520 | if (! ext_register_operand (operands[0], VOIDmode)) |
e075ae69 | 14521 | FAIL; |
044b3892 L |
14522 | |
14523 | if (TARGET_64BIT) | |
14524 | emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3])); | |
14525 | else | |
14526 | emit_insn (gen_movsi_insv_1 (operands[0], operands[3])); | |
14527 | ||
14528 | DONE; | |
0f40f9f7 | 14529 | }) |
e075ae69 RH |
14530 | |
14531 | ;; %%% bts, btr, btc, bt. | |
7cacf53e RH |
14532 | ;; In general these instructions are *slow* when applied to memory, |
14533 | ;; since they enforce atomic operation. When applied to registers, | |
14534 | ;; it depends on the cpu implementation. They're never faster than | |
14535 | ;; the corresponding and/ior/xor operations, so with 32-bit there's | |
14536 | ;; no point. But in 64-bit, we can't hold the relevant immediates | |
14537 | ;; within the instruction itself, so operating on bits in the high | |
14538 | ;; 32-bits of a register becomes easier. | |
14539 | ;; | |
14540 | ;; These are slow on Nocona, but fast on Athlon64. We do require the use | |
14541 | ;; of btrq and btcq for corner cases of post-reload expansion of absdf and | |
14542 | ;; negdf respectively, so they can never be disabled entirely. | |
14543 | ||
14544 | (define_insn "*btsq" | |
ad4f9e7e | 14545 | [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") |
7cacf53e | 14546 | (const_int 1) |
ad4f9e7e | 14547 | (match_operand:DI 1 "const_0_to_63_operand" "")) |
7cacf53e RH |
14548 | (const_int 1)) |
14549 | (clobber (reg:CC FLAGS_REG))] | |
14550 | "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" | |
33ee5810 | 14551 | "bts{q}\t{%1, %0|%0, %1}" |
a952487c | 14552 | [(set_attr "type" "alu1") |
725fd454 JJ |
14553 | (set_attr "prefix_0f" "1") |
14554 | (set_attr "mode" "DI")]) | |
7cacf53e RH |
14555 | |
14556 | (define_insn "*btrq" | |
ad4f9e7e | 14557 | [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") |
7cacf53e | 14558 | (const_int 1) |
ad4f9e7e | 14559 | (match_operand:DI 1 "const_0_to_63_operand" "")) |
7cacf53e RH |
14560 | (const_int 0)) |
14561 | (clobber (reg:CC FLAGS_REG))] | |
14562 | "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" | |
33ee5810 | 14563 | "btr{q}\t{%1, %0|%0, %1}" |
a952487c | 14564 | [(set_attr "type" "alu1") |
725fd454 JJ |
14565 | (set_attr "prefix_0f" "1") |
14566 | (set_attr "mode" "DI")]) | |
7cacf53e RH |
14567 | |
14568 | (define_insn "*btcq" | |
ad4f9e7e | 14569 | [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") |
7cacf53e | 14570 | (const_int 1) |
ad4f9e7e | 14571 | (match_operand:DI 1 "const_0_to_63_operand" "")) |
7cacf53e RH |
14572 | (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) |
14573 | (clobber (reg:CC FLAGS_REG))] | |
14574 | "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" | |
33ee5810 | 14575 | "btc{q}\t{%1, %0|%0, %1}" |
a952487c | 14576 | [(set_attr "type" "alu1") |
725fd454 JJ |
14577 | (set_attr "prefix_0f" "1") |
14578 | (set_attr "mode" "DI")]) | |
7cacf53e RH |
14579 | |
14580 | ;; Allow Nocona to avoid these instructions if a register is available. | |
14581 | ||
14582 | (define_peephole2 | |
14583 | [(match_scratch:DI 2 "r") | |
14584 | (parallel [(set (zero_extract:DI | |
ad4f9e7e | 14585 | (match_operand:DI 0 "register_operand" "") |
7cacf53e | 14586 | (const_int 1) |
ad4f9e7e | 14587 | (match_operand:DI 1 "const_0_to_63_operand" "")) |
7cacf53e RH |
14588 | (const_int 1)) |
14589 | (clobber (reg:CC FLAGS_REG))])] | |
14590 | "TARGET_64BIT && !TARGET_USE_BT" | |
14591 | [(const_int 0)] | |
14592 | { | |
14593 | HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; | |
14594 | rtx op1; | |
14595 | ||
14596 | if (HOST_BITS_PER_WIDE_INT >= 64) | |
14597 | lo = (HOST_WIDE_INT)1 << i, hi = 0; | |
14598 | else if (i < HOST_BITS_PER_WIDE_INT) | |
14599 | lo = (HOST_WIDE_INT)1 << i, hi = 0; | |
14600 | else | |
14601 | lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); | |
14602 | ||
14603 | op1 = immed_double_const (lo, hi, DImode); | |
14604 | if (i >= 31) | |
14605 | { | |
14606 | emit_move_insn (operands[2], op1); | |
14607 | op1 = operands[2]; | |
14608 | } | |
14609 | ||
14610 | emit_insn (gen_iordi3 (operands[0], operands[0], op1)); | |
14611 | DONE; | |
14612 | }) | |
14613 | ||
14614 | (define_peephole2 | |
14615 | [(match_scratch:DI 2 "r") | |
14616 | (parallel [(set (zero_extract:DI | |
ad4f9e7e | 14617 | (match_operand:DI 0 "register_operand" "") |
7cacf53e | 14618 | (const_int 1) |
ad4f9e7e | 14619 | (match_operand:DI 1 "const_0_to_63_operand" "")) |
7cacf53e RH |
14620 | (const_int 0)) |
14621 | (clobber (reg:CC FLAGS_REG))])] | |
14622 | "TARGET_64BIT && !TARGET_USE_BT" | |
14623 | [(const_int 0)] | |
14624 | { | |
14625 | HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; | |
14626 | rtx op1; | |
14627 | ||
14628 | if (HOST_BITS_PER_WIDE_INT >= 64) | |
14629 | lo = (HOST_WIDE_INT)1 << i, hi = 0; | |
14630 | else if (i < HOST_BITS_PER_WIDE_INT) | |
14631 | lo = (HOST_WIDE_INT)1 << i, hi = 0; | |
14632 | else | |
14633 | lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); | |
14634 | ||
14635 | op1 = immed_double_const (~lo, ~hi, DImode); | |
14636 | if (i >= 32) | |
14637 | { | |
14638 | emit_move_insn (operands[2], op1); | |
14639 | op1 = operands[2]; | |
14640 | } | |
14641 | ||
14642 | emit_insn (gen_anddi3 (operands[0], operands[0], op1)); | |
14643 | DONE; | |
14644 | }) | |
14645 | ||
14646 | (define_peephole2 | |
14647 | [(match_scratch:DI 2 "r") | |
14648 | (parallel [(set (zero_extract:DI | |
ad4f9e7e | 14649 | (match_operand:DI 0 "register_operand" "") |
7cacf53e | 14650 | (const_int 1) |
ad4f9e7e | 14651 | (match_operand:DI 1 "const_0_to_63_operand" "")) |
7cacf53e RH |
14652 | (not:DI (zero_extract:DI |
14653 | (match_dup 0) (const_int 1) (match_dup 1)))) | |
14654 | (clobber (reg:CC FLAGS_REG))])] | |
14655 | "TARGET_64BIT && !TARGET_USE_BT" | |
14656 | [(const_int 0)] | |
14657 | { | |
14658 | HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; | |
14659 | rtx op1; | |
14660 | ||
14661 | if (HOST_BITS_PER_WIDE_INT >= 64) | |
14662 | lo = (HOST_WIDE_INT)1 << i, hi = 0; | |
14663 | else if (i < HOST_BITS_PER_WIDE_INT) | |
14664 | lo = (HOST_WIDE_INT)1 << i, hi = 0; | |
14665 | else | |
14666 | lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); | |
14667 | ||
14668 | op1 = immed_double_const (lo, hi, DImode); | |
14669 | if (i >= 31) | |
14670 | { | |
14671 | emit_move_insn (operands[2], op1); | |
14672 | op1 = operands[2]; | |
14673 | } | |
14674 | ||
14675 | emit_insn (gen_xordi3 (operands[0], operands[0], op1)); | |
14676 | DONE; | |
14677 | }) | |
33ee5810 UB |
14678 | |
14679 | (define_insn "*btdi_rex64" | |
14680 | [(set (reg:CCC FLAGS_REG) | |
14681 | (compare:CCC | |
14682 | (zero_extract:DI | |
14683 | (match_operand:DI 0 "register_operand" "r") | |
14684 | (const_int 1) | |
88b9490b | 14685 | (match_operand:DI 1 "nonmemory_operand" "rN")) |
33ee5810 | 14686 | (const_int 0)))] |
3debdc1e | 14687 | "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))" |
33ee5810 | 14688 | "bt{q}\t{%1, %0|%0, %1}" |
a952487c | 14689 | [(set_attr "type" "alu1") |
725fd454 JJ |
14690 | (set_attr "prefix_0f" "1") |
14691 | (set_attr "mode" "DI")]) | |
33ee5810 UB |
14692 | |
14693 | (define_insn "*btsi" | |
14694 | [(set (reg:CCC FLAGS_REG) | |
14695 | (compare:CCC | |
14696 | (zero_extract:SI | |
14697 | (match_operand:SI 0 "register_operand" "r") | |
14698 | (const_int 1) | |
88b9490b | 14699 | (match_operand:SI 1 "nonmemory_operand" "rN")) |
33ee5810 | 14700 | (const_int 0)))] |
3debdc1e | 14701 | "TARGET_USE_BT || optimize_function_for_size_p (cfun)" |
33ee5810 | 14702 | "bt{l}\t{%1, %0|%0, %1}" |
a952487c | 14703 | [(set_attr "type" "alu1") |
725fd454 JJ |
14704 | (set_attr "prefix_0f" "1") |
14705 | (set_attr "mode" "SI")]) | |
886c62d1 JVA |
14706 | \f |
14707 | ;; Store-flag instructions. | |
14708 | ||
c572e5ba JVA |
14709 | ;; For all sCOND expanders, also expand the compare or test insn that |
14710 | ;; generates cc0. Generate an equality comparison if `seq' or `sne'. | |
14711 | ||
e075ae69 RH |
14712 | ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way |
14713 | ;; to avoid partial register stalls. Otherwise do things the setcc+movzx | |
14714 | ;; way, which can later delete the movzx if only QImode is needed. | |
14715 | ||
e075ae69 | 14716 | (define_insn "*setcc_1" |
a269a03c | 14717 | [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") |
9076b9c1 | 14718 | (match_operator:QI 1 "ix86_comparison_operator" |
42fabf21 | 14719 | [(reg FLAGS_REG) (const_int 0)]))] |
e075ae69 | 14720 | "" |
0f40f9f7 | 14721 | "set%C1\t%0" |
6ef67412 JH |
14722 | [(set_attr "type" "setcc") |
14723 | (set_attr "mode" "QI")]) | |
a269a03c | 14724 | |
93330ea1 | 14725 | (define_insn "*setcc_2" |
e075ae69 | 14726 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) |
9076b9c1 | 14727 | (match_operator:QI 1 "ix86_comparison_operator" |
42fabf21 | 14728 | [(reg FLAGS_REG) (const_int 0)]))] |
e075ae69 | 14729 | "" |
0f40f9f7 | 14730 | "set%C1\t%0" |
6ef67412 JH |
14731 | [(set_attr "type" "setcc") |
14732 | (set_attr "mode" "QI")]) | |
e075ae69 | 14733 | |
10978207 | 14734 | ;; In general it is not safe to assume too much about CCmode registers, |
6300f037 | 14735 | ;; so simplify-rtx stops when it sees a second one. Under certain |
10978207 RH |
14736 | ;; conditions this is safe on x86, so help combine not create |
14737 | ;; | |
14738 | ;; seta %al | |
14739 | ;; testb %al, %al | |
14740 | ;; sete %al | |
14741 | ||
6300f037 | 14742 | (define_split |
10978207 RH |
14743 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
14744 | (ne:QI (match_operator 1 "ix86_comparison_operator" | |
42fabf21 | 14745 | [(reg FLAGS_REG) (const_int 0)]) |
10978207 RH |
14746 | (const_int 0)))] |
14747 | "" | |
14748 | [(set (match_dup 0) (match_dup 1))] | |
14749 | { | |
14750 | PUT_MODE (operands[1], QImode); | |
14751 | }) | |
14752 | ||
6300f037 | 14753 | (define_split |
10978207 RH |
14754 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) |
14755 | (ne:QI (match_operator 1 "ix86_comparison_operator" | |
42fabf21 | 14756 | [(reg FLAGS_REG) (const_int 0)]) |
10978207 RH |
14757 | (const_int 0)))] |
14758 | "" | |
14759 | [(set (match_dup 0) (match_dup 1))] | |
14760 | { | |
14761 | PUT_MODE (operands[1], QImode); | |
14762 | }) | |
14763 | ||
6300f037 | 14764 | (define_split |
10978207 RH |
14765 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
14766 | (eq:QI (match_operator 1 "ix86_comparison_operator" | |
42fabf21 | 14767 | [(reg FLAGS_REG) (const_int 0)]) |
10978207 RH |
14768 | (const_int 0)))] |
14769 | "" | |
14770 | [(set (match_dup 0) (match_dup 1))] | |
14771 | { | |
14772 | rtx new_op1 = copy_rtx (operands[1]); | |
14773 | operands[1] = new_op1; | |
14774 | PUT_MODE (new_op1, QImode); | |
3c5cb3e4 KH |
14775 | PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), |
14776 | GET_MODE (XEXP (new_op1, 0)))); | |
10978207 RH |
14777 | |
14778 | /* Make sure that (a) the CCmode we have for the flags is strong | |
14779 | enough for the reversed compare or (b) we have a valid FP compare. */ | |
14780 | if (! ix86_comparison_operator (new_op1, VOIDmode)) | |
14781 | FAIL; | |
14782 | }) | |
14783 | ||
6300f037 | 14784 | (define_split |
10978207 RH |
14785 | [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) |
14786 | (eq:QI (match_operator 1 "ix86_comparison_operator" | |
42fabf21 | 14787 | [(reg FLAGS_REG) (const_int 0)]) |
10978207 RH |
14788 | (const_int 0)))] |
14789 | "" | |
14790 | [(set (match_dup 0) (match_dup 1))] | |
14791 | { | |
14792 | rtx new_op1 = copy_rtx (operands[1]); | |
14793 | operands[1] = new_op1; | |
14794 | PUT_MODE (new_op1, QImode); | |
3c5cb3e4 KH |
14795 | PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), |
14796 | GET_MODE (XEXP (new_op1, 0)))); | |
10978207 RH |
14797 | |
14798 | /* Make sure that (a) the CCmode we have for the flags is strong | |
14799 | enough for the reversed compare or (b) we have a valid FP compare. */ | |
14800 | if (! ix86_comparison_operator (new_op1, VOIDmode)) | |
14801 | FAIL; | |
14802 | }) | |
14803 | ||
a46d1d38 JH |
14804 | ;; The SSE store flag instructions saves 0 or 0xffffffff to the result. |
14805 | ;; subsequent logical operations are used to imitate conditional moves. | |
14806 | ;; 0xffffffff is NaN, but not in normalized form, so we can't represent | |
ab8efbd8 | 14807 | ;; it directly. |
a46d1d38 | 14808 | |
95879c72 L |
14809 | (define_insn "*avx_setcc<mode>" |
14810 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
14811 | (match_operator:MODEF 1 "avx_comparison_float_operator" | |
14812 | [(match_operand:MODEF 2 "register_operand" "x") | |
14813 | (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))] | |
14814 | "TARGET_AVX" | |
14815 | "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}" | |
14816 | [(set_attr "type" "ssecmp") | |
14817 | (set_attr "prefix" "vex") | |
725fd454 | 14818 | (set_attr "length_immediate" "1") |
95879c72 L |
14819 | (set_attr "mode" "<MODE>")]) |
14820 | ||
d6023b50 UB |
14821 | (define_insn "*sse_setcc<mode>" |
14822 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
14823 | (match_operator:MODEF 1 "sse_comparison_operator" | |
14824 | [(match_operand:MODEF 2 "register_operand" "0") | |
14825 | (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))] | |
14826 | "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5" | |
14827 | "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}" | |
3d34cd91 | 14828 | [(set_attr "type" "ssecmp") |
725fd454 | 14829 | (set_attr "length_immediate" "1") |
d6023b50 | 14830 | (set_attr "mode" "<MODE>")]) |
04e1d06b MM |
14831 | |
14832 | (define_insn "*sse5_setcc<mode>" | |
14833 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
14834 | (match_operator:MODEF 1 "sse5_comparison_float_operator" | |
14835 | [(match_operand:MODEF 2 "register_operand" "x") | |
14836 | (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))] | |
14837 | "TARGET_SSE5" | |
d51fba8e | 14838 | "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}" |
04e1d06b | 14839 | [(set_attr "type" "sse4arg") |
725fd454 | 14840 | (set_attr "length_immediate" "1") |
04e1d06b MM |
14841 | (set_attr "mode" "<MODE>")]) |
14842 | ||
886c62d1 JVA |
14843 | \f |
14844 | ;; Basic conditional jump instructions. | |
14845 | ;; We ignore the overflow flag for signed branch instructions. | |
14846 | ||
e075ae69 RH |
14847 | (define_insn "*jcc_1" |
14848 | [(set (pc) | |
9076b9c1 | 14849 | (if_then_else (match_operator 1 "ix86_comparison_operator" |
42fabf21 | 14850 | [(reg FLAGS_REG) (const_int 0)]) |
6ef67412 | 14851 | (label_ref (match_operand 0 "" "")) |
e075ae69 RH |
14852 | (pc)))] |
14853 | "" | |
0f40f9f7 | 14854 | "%+j%C1\t%l0" |
e075ae69 | 14855 | [(set_attr "type" "ibr") |
c7375e61 | 14856 | (set_attr "modrm" "0") |
efcc7037 | 14857 | (set (attr "length") |
6ef67412 | 14858 | (if_then_else (and (ge (minus (match_dup 0) (pc)) |
db1077d3 | 14859 | (const_int -126)) |
6ef67412 | 14860 | (lt (minus (match_dup 0) (pc)) |
db1077d3 | 14861 | (const_int 128))) |
efcc7037 JH |
14862 | (const_int 2) |
14863 | (const_int 6)))]) | |
e075ae69 RH |
14864 | |
14865 | (define_insn "*jcc_2" | |
14866 | [(set (pc) | |
9076b9c1 | 14867 | (if_then_else (match_operator 1 "ix86_comparison_operator" |
42fabf21 | 14868 | [(reg FLAGS_REG) (const_int 0)]) |
e075ae69 | 14869 | (pc) |
6ef67412 | 14870 | (label_ref (match_operand 0 "" ""))))] |
e075ae69 | 14871 | "" |
0f40f9f7 | 14872 | "%+j%c1\t%l0" |
e075ae69 | 14873 | [(set_attr "type" "ibr") |
c7375e61 | 14874 | (set_attr "modrm" "0") |
efcc7037 | 14875 | (set (attr "length") |
6ef67412 | 14876 | (if_then_else (and (ge (minus (match_dup 0) (pc)) |
db1077d3 | 14877 | (const_int -126)) |
6ef67412 | 14878 | (lt (minus (match_dup 0) (pc)) |
db1077d3 | 14879 | (const_int 128))) |
efcc7037 JH |
14880 | (const_int 2) |
14881 | (const_int 6)))]) | |
e075ae69 | 14882 | |
592188a5 | 14883 | ;; In general it is not safe to assume too much about CCmode registers, |
6300f037 | 14884 | ;; so simplify-rtx stops when it sees a second one. Under certain |
592188a5 RH |
14885 | ;; conditions this is safe on x86, so help combine not create |
14886 | ;; | |
14887 | ;; seta %al | |
14888 | ;; testb %al, %al | |
14889 | ;; je Lfoo | |
14890 | ||
6300f037 | 14891 | (define_split |
592188a5 RH |
14892 | [(set (pc) |
14893 | (if_then_else (ne (match_operator 0 "ix86_comparison_operator" | |
42fabf21 | 14894 | [(reg FLAGS_REG) (const_int 0)]) |
592188a5 RH |
14895 | (const_int 0)) |
14896 | (label_ref (match_operand 1 "" "")) | |
14897 | (pc)))] | |
14898 | "" | |
14899 | [(set (pc) | |
14900 | (if_then_else (match_dup 0) | |
14901 | (label_ref (match_dup 1)) | |
14902 | (pc)))] | |
14903 | { | |
14904 | PUT_MODE (operands[0], VOIDmode); | |
14905 | }) | |
6300f037 EC |
14906 | |
14907 | (define_split | |
592188a5 RH |
14908 | [(set (pc) |
14909 | (if_then_else (eq (match_operator 0 "ix86_comparison_operator" | |
42fabf21 | 14910 | [(reg FLAGS_REG) (const_int 0)]) |
592188a5 RH |
14911 | (const_int 0)) |
14912 | (label_ref (match_operand 1 "" "")) | |
14913 | (pc)))] | |
14914 | "" | |
14915 | [(set (pc) | |
14916 | (if_then_else (match_dup 0) | |
14917 | (label_ref (match_dup 1)) | |
14918 | (pc)))] | |
14919 | { | |
14920 | rtx new_op0 = copy_rtx (operands[0]); | |
14921 | operands[0] = new_op0; | |
14922 | PUT_MODE (new_op0, VOIDmode); | |
3c5cb3e4 KH |
14923 | PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), |
14924 | GET_MODE (XEXP (new_op0, 0)))); | |
592188a5 RH |
14925 | |
14926 | /* Make sure that (a) the CCmode we have for the flags is strong | |
14927 | enough for the reversed compare or (b) we have a valid FP compare. */ | |
14928 | if (! ix86_comparison_operator (new_op0, VOIDmode)) | |
14929 | FAIL; | |
14930 | }) | |
14931 | ||
33ee5810 UB |
14932 | ;; zero_extend in SImode is correct, since this is what combine pass |
14933 | ;; generates from shift insn with QImode operand. Actually, the mode of | |
14934 | ;; operand 2 (bit offset operand) doesn't matter since bt insn takes | |
14935 | ;; appropriate modulo of the bit offset value. | |
14936 | ||
14937 | (define_insn_and_split "*jcc_btdi_rex64" | |
14938 | [(set (pc) | |
14939 | (if_then_else (match_operator 0 "bt_comparison_operator" | |
14940 | [(zero_extract:DI | |
14941 | (match_operand:DI 1 "register_operand" "r") | |
14942 | (const_int 1) | |
14943 | (zero_extend:SI | |
14944 | (match_operand:QI 2 "register_operand" "r"))) | |
14945 | (const_int 0)]) | |
14946 | (label_ref (match_operand 3 "" "")) | |
b7f58d5d UB |
14947 | (pc))) |
14948 | (clobber (reg:CC FLAGS_REG))] | |
3debdc1e | 14949 | "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))" |
33ee5810 UB |
14950 | "#" |
14951 | "&& 1" | |
14952 | [(set (reg:CCC FLAGS_REG) | |
14953 | (compare:CCC | |
14954 | (zero_extract:DI | |
14955 | (match_dup 1) | |
14956 | (const_int 1) | |
14957 | (match_dup 2)) | |
14958 | (const_int 0))) | |
14959 | (set (pc) | |
14960 | (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) | |
14961 | (label_ref (match_dup 3)) | |
14962 | (pc)))] | |
14963 | { | |
14964 | operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0); | |
14965 | ||
14966 | PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); | |
14967 | }) | |
14968 | ||
88b9490b UB |
14969 | ;; avoid useless masking of bit offset operand |
14970 | (define_insn_and_split "*jcc_btdi_mask_rex64" | |
14971 | [(set (pc) | |
14972 | (if_then_else (match_operator 0 "bt_comparison_operator" | |
14973 | [(zero_extract:DI | |
14974 | (match_operand:DI 1 "register_operand" "r") | |
14975 | (const_int 1) | |
14976 | (and:SI | |
14977 | (match_operand:SI 2 "register_operand" "r") | |
14978 | (match_operand:SI 3 "const_int_operand" "n")))]) | |
14979 | (label_ref (match_operand 4 "" "")) | |
b7f58d5d UB |
14980 | (pc))) |
14981 | (clobber (reg:CC FLAGS_REG))] | |
3debdc1e | 14982 | "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun)) |
88b9490b UB |
14983 | && (INTVAL (operands[3]) & 0x3f) == 0x3f" |
14984 | "#" | |
14985 | "&& 1" | |
14986 | [(set (reg:CCC FLAGS_REG) | |
14987 | (compare:CCC | |
14988 | (zero_extract:DI | |
14989 | (match_dup 1) | |
14990 | (const_int 1) | |
14991 | (match_dup 2)) | |
14992 | (const_int 0))) | |
14993 | (set (pc) | |
14994 | (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) | |
14995 | (label_ref (match_dup 4)) | |
14996 | (pc)))] | |
14997 | { | |
14998 | operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0); | |
14999 | ||
15000 | PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); | |
15001 | }) | |
15002 | ||
33ee5810 UB |
15003 | (define_insn_and_split "*jcc_btsi" |
15004 | [(set (pc) | |
15005 | (if_then_else (match_operator 0 "bt_comparison_operator" | |
15006 | [(zero_extract:SI | |
15007 | (match_operand:SI 1 "register_operand" "r") | |
15008 | (const_int 1) | |
15009 | (zero_extend:SI | |
15010 | (match_operand:QI 2 "register_operand" "r"))) | |
15011 | (const_int 0)]) | |
15012 | (label_ref (match_operand 3 "" "")) | |
b7f58d5d UB |
15013 | (pc))) |
15014 | (clobber (reg:CC FLAGS_REG))] | |
3debdc1e | 15015 | "TARGET_USE_BT || optimize_function_for_size_p (cfun)" |
33ee5810 UB |
15016 | "#" |
15017 | "&& 1" | |
15018 | [(set (reg:CCC FLAGS_REG) | |
15019 | (compare:CCC | |
15020 | (zero_extract:SI | |
15021 | (match_dup 1) | |
15022 | (const_int 1) | |
15023 | (match_dup 2)) | |
15024 | (const_int 0))) | |
15025 | (set (pc) | |
15026 | (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) | |
15027 | (label_ref (match_dup 3)) | |
15028 | (pc)))] | |
15029 | { | |
15030 | operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); | |
15031 | ||
15032 | PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); | |
15033 | }) | |
15034 | ||
88b9490b UB |
15035 | ;; avoid useless masking of bit offset operand |
15036 | (define_insn_and_split "*jcc_btsi_mask" | |
15037 | [(set (pc) | |
15038 | (if_then_else (match_operator 0 "bt_comparison_operator" | |
15039 | [(zero_extract:SI | |
15040 | (match_operand:SI 1 "register_operand" "r") | |
15041 | (const_int 1) | |
15042 | (and:SI | |
15043 | (match_operand:SI 2 "register_operand" "r") | |
15044 | (match_operand:SI 3 "const_int_operand" "n")))]) | |
15045 | (label_ref (match_operand 4 "" "")) | |
b7f58d5d UB |
15046 | (pc))) |
15047 | (clobber (reg:CC FLAGS_REG))] | |
3debdc1e | 15048 | "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) |
88b9490b UB |
15049 | && (INTVAL (operands[3]) & 0x1f) == 0x1f" |
15050 | "#" | |
15051 | "&& 1" | |
15052 | [(set (reg:CCC FLAGS_REG) | |
15053 | (compare:CCC | |
15054 | (zero_extract:SI | |
15055 | (match_dup 1) | |
15056 | (const_int 1) | |
15057 | (match_dup 2)) | |
15058 | (const_int 0))) | |
15059 | (set (pc) | |
15060 | (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) | |
15061 | (label_ref (match_dup 4)) | |
15062 | (pc)))] | |
15063 | "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));") | |
15064 | ||
33ee5810 UB |
15065 | (define_insn_and_split "*jcc_btsi_1" |
15066 | [(set (pc) | |
15067 | (if_then_else (match_operator 0 "bt_comparison_operator" | |
15068 | [(and:SI | |
15069 | (lshiftrt:SI | |
15070 | (match_operand:SI 1 "register_operand" "r") | |
15071 | (match_operand:QI 2 "register_operand" "r")) | |
15072 | (const_int 1)) | |
15073 | (const_int 0)]) | |
15074 | (label_ref (match_operand 3 "" "")) | |
b7f58d5d UB |
15075 | (pc))) |
15076 | (clobber (reg:CC FLAGS_REG))] | |
3debdc1e | 15077 | "TARGET_USE_BT || optimize_function_for_size_p (cfun)" |
33ee5810 UB |
15078 | "#" |
15079 | "&& 1" | |
15080 | [(set (reg:CCC FLAGS_REG) | |
15081 | (compare:CCC | |
15082 | (zero_extract:SI | |
15083 | (match_dup 1) | |
15084 | (const_int 1) | |
15085 | (match_dup 2)) | |
15086 | (const_int 0))) | |
15087 | (set (pc) | |
15088 | (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) | |
15089 | (label_ref (match_dup 3)) | |
15090 | (pc)))] | |
15091 | { | |
15092 | operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); | |
15093 | ||
15094 | PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); | |
15095 | }) | |
15096 | ||
88b9490b UB |
15097 | ;; avoid useless masking of bit offset operand |
15098 | (define_insn_and_split "*jcc_btsi_mask_1" | |
15099 | [(set (pc) | |
15100 | (if_then_else | |
15101 | (match_operator 0 "bt_comparison_operator" | |
15102 | [(and:SI | |
15103 | (lshiftrt:SI | |
15104 | (match_operand:SI 1 "register_operand" "r") | |
15105 | (subreg:QI | |
15106 | (and:SI | |
15107 | (match_operand:SI 2 "register_operand" "r") | |
15108 | (match_operand:SI 3 "const_int_operand" "n")) 0)) | |
15109 | (const_int 1)) | |
15110 | (const_int 0)]) | |
15111 | (label_ref (match_operand 4 "" "")) | |
b7f58d5d UB |
15112 | (pc))) |
15113 | (clobber (reg:CC FLAGS_REG))] | |
3debdc1e | 15114 | "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) |
88b9490b UB |
15115 | && (INTVAL (operands[3]) & 0x1f) == 0x1f" |
15116 | "#" | |
15117 | "&& 1" | |
15118 | [(set (reg:CCC FLAGS_REG) | |
15119 | (compare:CCC | |
15120 | (zero_extract:SI | |
15121 | (match_dup 1) | |
15122 | (const_int 1) | |
15123 | (match_dup 2)) | |
15124 | (const_int 0))) | |
15125 | (set (pc) | |
15126 | (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) | |
15127 | (label_ref (match_dup 4)) | |
15128 | (pc)))] | |
15129 | "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));") | |
15130 | ||
3a3677ff RH |
15131 | ;; Define combination compare-and-branch fp compare instructions to use |
15132 | ;; during early optimization. Splitting the operation apart early makes | |
15133 | ;; for bad code when we want to reverse the operation. | |
15134 | ||
eaa49b49 | 15135 | (define_insn "*fp_jcc_1_mixed" |
3a3677ff RH |
15136 | [(set (pc) |
15137 | (if_then_else (match_operator 0 "comparison_operator" | |
b5c82fa1 PB |
15138 | [(match_operand 1 "register_operand" "f,x") |
15139 | (match_operand 2 "nonimmediate_operand" "f,xm")]) | |
3a3677ff RH |
15140 | (label_ref (match_operand 3 "" "")) |
15141 | (pc))) | |
8bc527af SB |
15142 | (clobber (reg:CCFP FPSR_REG)) |
15143 | (clobber (reg:CCFP FLAGS_REG))] | |
eaa49b49 RH |
15144 | "TARGET_MIX_SSE_I387 |
15145 | && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) | |
03598dea JH |
15146 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
15147 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
3a3677ff RH |
15148 | "#") |
15149 | ||
0644b628 JH |
15150 | (define_insn "*fp_jcc_1_sse" |
15151 | [(set (pc) | |
15152 | (if_then_else (match_operator 0 "comparison_operator" | |
eaa49b49 RH |
15153 | [(match_operand 1 "register_operand" "x") |
15154 | (match_operand 2 "nonimmediate_operand" "xm")]) | |
0644b628 JH |
15155 | (label_ref (match_operand 3 "" "")) |
15156 | (pc))) | |
8bc527af SB |
15157 | (clobber (reg:CCFP FPSR_REG)) |
15158 | (clobber (reg:CCFP FLAGS_REG))] | |
eaa49b49 | 15159 | "TARGET_SSE_MATH |
0644b628 | 15160 | && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) |
03598dea JH |
15161 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
15162 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
0644b628 JH |
15163 | "#") |
15164 | ||
eaa49b49 | 15165 | (define_insn "*fp_jcc_1_387" |
0644b628 JH |
15166 | [(set (pc) |
15167 | (if_then_else (match_operator 0 "comparison_operator" | |
eaa49b49 RH |
15168 | [(match_operand 1 "register_operand" "f") |
15169 | (match_operand 2 "register_operand" "f")]) | |
0644b628 JH |
15170 | (label_ref (match_operand 3 "" "")) |
15171 | (pc))) | |
8bc527af SB |
15172 | (clobber (reg:CCFP FPSR_REG)) |
15173 | (clobber (reg:CCFP FLAGS_REG))] | |
27ac40e2 UB |
15174 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
15175 | && TARGET_CMOVE | |
03598dea JH |
15176 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
15177 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
0644b628 JH |
15178 | "#") |
15179 | ||
eaa49b49 | 15180 | (define_insn "*fp_jcc_2_mixed" |
3a3677ff RH |
15181 | [(set (pc) |
15182 | (if_then_else (match_operator 0 "comparison_operator" | |
b5c82fa1 PB |
15183 | [(match_operand 1 "register_operand" "f,x") |
15184 | (match_operand 2 "nonimmediate_operand" "f,xm")]) | |
3a3677ff RH |
15185 | (pc) |
15186 | (label_ref (match_operand 3 "" "")))) | |
8bc527af SB |
15187 | (clobber (reg:CCFP FPSR_REG)) |
15188 | (clobber (reg:CCFP FLAGS_REG))] | |
eaa49b49 RH |
15189 | "TARGET_MIX_SSE_I387 |
15190 | && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) | |
03598dea JH |
15191 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
15192 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
3a3677ff RH |
15193 | "#") |
15194 | ||
0644b628 JH |
15195 | (define_insn "*fp_jcc_2_sse" |
15196 | [(set (pc) | |
15197 | (if_then_else (match_operator 0 "comparison_operator" | |
eaa49b49 RH |
15198 | [(match_operand 1 "register_operand" "x") |
15199 | (match_operand 2 "nonimmediate_operand" "xm")]) | |
0644b628 JH |
15200 | (pc) |
15201 | (label_ref (match_operand 3 "" "")))) | |
8bc527af SB |
15202 | (clobber (reg:CCFP FPSR_REG)) |
15203 | (clobber (reg:CCFP FLAGS_REG))] | |
eaa49b49 | 15204 | "TARGET_SSE_MATH |
0644b628 | 15205 | && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) |
03598dea JH |
15206 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
15207 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
0644b628 JH |
15208 | "#") |
15209 | ||
eaa49b49 | 15210 | (define_insn "*fp_jcc_2_387" |
0644b628 JH |
15211 | [(set (pc) |
15212 | (if_then_else (match_operator 0 "comparison_operator" | |
eaa49b49 RH |
15213 | [(match_operand 1 "register_operand" "f") |
15214 | (match_operand 2 "register_operand" "f")]) | |
0644b628 JH |
15215 | (pc) |
15216 | (label_ref (match_operand 3 "" "")))) | |
8bc527af SB |
15217 | (clobber (reg:CCFP FPSR_REG)) |
15218 | (clobber (reg:CCFP FLAGS_REG))] | |
27ac40e2 UB |
15219 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
15220 | && TARGET_CMOVE | |
03598dea JH |
15221 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
15222 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
0644b628 JH |
15223 | "#") |
15224 | ||
eaa49b49 | 15225 | (define_insn "*fp_jcc_3_387" |
3a3677ff | 15226 | [(set (pc) |
b1cdafbb | 15227 | (if_then_else (match_operator 0 "comparison_operator" |
3a3677ff RH |
15228 | [(match_operand 1 "register_operand" "f") |
15229 | (match_operand 2 "nonimmediate_operand" "fm")]) | |
15230 | (label_ref (match_operand 3 "" "")) | |
15231 | (pc))) | |
8bc527af SB |
15232 | (clobber (reg:CCFP FPSR_REG)) |
15233 | (clobber (reg:CCFP FLAGS_REG)) | |
3a3677ff RH |
15234 | (clobber (match_scratch:HI 4 "=a"))] |
15235 | "TARGET_80387 | |
15236 | && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) | |
a940d8bd | 15237 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
b1cdafbb JH |
15238 | && !ix86_use_fcomi_compare (GET_CODE (operands[0])) |
15239 | && SELECT_CC_MODE (GET_CODE (operands[0]), | |
03598dea JH |
15240 | operands[1], operands[2]) == CCFPmode |
15241 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
3a3677ff RH |
15242 | "#") |
15243 | ||
eaa49b49 | 15244 | (define_insn "*fp_jcc_4_387" |
3a3677ff | 15245 | [(set (pc) |
b1cdafbb | 15246 | (if_then_else (match_operator 0 "comparison_operator" |
3a3677ff RH |
15247 | [(match_operand 1 "register_operand" "f") |
15248 | (match_operand 2 "nonimmediate_operand" "fm")]) | |
15249 | (pc) | |
15250 | (label_ref (match_operand 3 "" "")))) | |
8bc527af SB |
15251 | (clobber (reg:CCFP FPSR_REG)) |
15252 | (clobber (reg:CCFP FLAGS_REG)) | |
3a3677ff RH |
15253 | (clobber (match_scratch:HI 4 "=a"))] |
15254 | "TARGET_80387 | |
15255 | && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) | |
a940d8bd | 15256 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
b1cdafbb JH |
15257 | && !ix86_use_fcomi_compare (GET_CODE (operands[0])) |
15258 | && SELECT_CC_MODE (GET_CODE (operands[0]), | |
03598dea JH |
15259 | operands[1], operands[2]) == CCFPmode |
15260 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
3a3677ff RH |
15261 | "#") |
15262 | ||
eaa49b49 | 15263 | (define_insn "*fp_jcc_5_387" |
3a3677ff RH |
15264 | [(set (pc) |
15265 | (if_then_else (match_operator 0 "comparison_operator" | |
15266 | [(match_operand 1 "register_operand" "f") | |
15267 | (match_operand 2 "register_operand" "f")]) | |
15268 | (label_ref (match_operand 3 "" "")) | |
15269 | (pc))) | |
8bc527af SB |
15270 | (clobber (reg:CCFP FPSR_REG)) |
15271 | (clobber (reg:CCFP FLAGS_REG)) | |
3a3677ff | 15272 | (clobber (match_scratch:HI 4 "=a"))] |
27ac40e2 | 15273 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
03598dea JH |
15274 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
15275 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
3a3677ff RH |
15276 | "#") |
15277 | ||
eaa49b49 | 15278 | (define_insn "*fp_jcc_6_387" |
3a3677ff RH |
15279 | [(set (pc) |
15280 | (if_then_else (match_operator 0 "comparison_operator" | |
15281 | [(match_operand 1 "register_operand" "f") | |
15282 | (match_operand 2 "register_operand" "f")]) | |
15283 | (pc) | |
15284 | (label_ref (match_operand 3 "" "")))) | |
8bc527af SB |
15285 | (clobber (reg:CCFP FPSR_REG)) |
15286 | (clobber (reg:CCFP FLAGS_REG)) | |
3a3677ff | 15287 | (clobber (match_scratch:HI 4 "=a"))] |
27ac40e2 | 15288 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
03598dea JH |
15289 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
15290 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
3a3677ff RH |
15291 | "#") |
15292 | ||
eaa49b49 | 15293 | (define_insn "*fp_jcc_7_387" |
45c8c47f UB |
15294 | [(set (pc) |
15295 | (if_then_else (match_operator 0 "comparison_operator" | |
15296 | [(match_operand 1 "register_operand" "f") | |
0edb82cb | 15297 | (match_operand 2 "const0_operand" "")]) |
45c8c47f UB |
15298 | (label_ref (match_operand 3 "" "")) |
15299 | (pc))) | |
15300 | (clobber (reg:CCFP FPSR_REG)) | |
15301 | (clobber (reg:CCFP FLAGS_REG)) | |
15302 | (clobber (match_scratch:HI 4 "=a"))] | |
27ac40e2 | 15303 | "X87_FLOAT_MODE_P (GET_MODE (operands[1])) |
17153653 | 15304 | && GET_MODE (operands[1]) == GET_MODE (operands[2]) |
45c8c47f UB |
15305 | && !ix86_use_fcomi_compare (GET_CODE (operands[0])) |
15306 | && SELECT_CC_MODE (GET_CODE (operands[0]), | |
15307 | operands[1], operands[2]) == CCFPmode | |
15308 | && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" | |
15309 | "#") | |
15310 | ||
0e8c2b0d | 15311 | ;; The order of operands in *fp_jcc_8_387 is forced by combine in |
7c82106f UB |
15312 | ;; simplify_comparison () function. Float operator is treated as RTX_OBJ |
15313 | ;; with a precedence over other operators and is always put in the first | |
15314 | ;; place. Swap condition and operands to match ficom instruction. | |
15315 | ||
0e8c2b0d | 15316 | (define_insn "*fp_jcc_8<mode>_387" |
7c82106f UB |
15317 | [(set (pc) |
15318 | (if_then_else (match_operator 0 "comparison_operator" | |
15319 | [(match_operator 1 "float_operator" | |
0e8c2b0d | 15320 | [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")]) |
7c82106f UB |
15321 | (match_operand 3 "register_operand" "f,f")]) |
15322 | (label_ref (match_operand 4 "" "")) | |
15323 | (pc))) | |
15324 | (clobber (reg:CCFP FPSR_REG)) | |
15325 | (clobber (reg:CCFP FLAGS_REG)) | |
15326 | (clobber (match_scratch:HI 5 "=a,a"))] | |
27ac40e2 | 15327 | "X87_FLOAT_MODE_P (GET_MODE (operands[3])) |
3debdc1e | 15328 | && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun)) |
7c82106f UB |
15329 | && GET_MODE (operands[1]) == GET_MODE (operands[3]) |
15330 | && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0]))) | |
15331 | && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode | |
15332 | && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))" | |
15333 | "#") | |
15334 | ||
3a3677ff RH |
15335 | (define_split |
15336 | [(set (pc) | |
15337 | (if_then_else (match_operator 0 "comparison_operator" | |
15338 | [(match_operand 1 "register_operand" "") | |
15339 | (match_operand 2 "nonimmediate_operand" "")]) | |
15340 | (match_operand 3 "" "") | |
15341 | (match_operand 4 "" ""))) | |
8bc527af SB |
15342 | (clobber (reg:CCFP FPSR_REG)) |
15343 | (clobber (reg:CCFP FLAGS_REG))] | |
3a3677ff | 15344 | "reload_completed" |
9e7adcb3 | 15345 | [(const_int 0)] |
3a3677ff | 15346 | { |
03598dea | 15347 | ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], |
7c82106f | 15348 | operands[3], operands[4], NULL_RTX, NULL_RTX); |
9e7adcb3 | 15349 | DONE; |
0f40f9f7 | 15350 | }) |
3a3677ff RH |
15351 | |
15352 | (define_split | |
15353 | [(set (pc) | |
15354 | (if_then_else (match_operator 0 "comparison_operator" | |
15355 | [(match_operand 1 "register_operand" "") | |
45c8c47f | 15356 | (match_operand 2 "general_operand" "")]) |
3a3677ff RH |
15357 | (match_operand 3 "" "") |
15358 | (match_operand 4 "" ""))) | |
8bc527af SB |
15359 | (clobber (reg:CCFP FPSR_REG)) |
15360 | (clobber (reg:CCFP FLAGS_REG)) | |
3a3677ff RH |
15361 | (clobber (match_scratch:HI 5 "=a"))] |
15362 | "reload_completed" | |
45c8c47f | 15363 | [(const_int 0)] |
3a3677ff | 15364 | { |
03598dea | 15365 | ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], |
7c82106f UB |
15366 | operands[3], operands[4], operands[5], NULL_RTX); |
15367 | DONE; | |
15368 | }) | |
15369 | ||
15370 | (define_split | |
15371 | [(set (pc) | |
15372 | (if_then_else (match_operator 0 "comparison_operator" | |
15373 | [(match_operator 1 "float_operator" | |
0e8c2b0d | 15374 | [(match_operand:X87MODEI12 2 "memory_operand" "")]) |
7c82106f UB |
15375 | (match_operand 3 "register_operand" "")]) |
15376 | (match_operand 4 "" "") | |
15377 | (match_operand 5 "" ""))) | |
15378 | (clobber (reg:CCFP FPSR_REG)) | |
15379 | (clobber (reg:CCFP FLAGS_REG)) | |
15380 | (clobber (match_scratch:HI 6 "=a"))] | |
15381 | "reload_completed" | |
15382 | [(const_int 0)] | |
15383 | { | |
15384 | operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); | |
15385 | ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), | |
15386 | operands[3], operands[7], | |
15387 | operands[4], operands[5], operands[6], NULL_RTX); | |
15388 | DONE; | |
15389 | }) | |
15390 | ||
15391 | ;; %%% Kill this when reload knows how to do it. | |
15392 | (define_split | |
15393 | [(set (pc) | |
15394 | (if_then_else (match_operator 0 "comparison_operator" | |
15395 | [(match_operator 1 "float_operator" | |
0e8c2b0d | 15396 | [(match_operand:X87MODEI12 2 "register_operand" "")]) |
7c82106f UB |
15397 | (match_operand 3 "register_operand" "")]) |
15398 | (match_operand 4 "" "") | |
15399 | (match_operand 5 "" ""))) | |
15400 | (clobber (reg:CCFP FPSR_REG)) | |
15401 | (clobber (reg:CCFP FLAGS_REG)) | |
15402 | (clobber (match_scratch:HI 6 "=a"))] | |
15403 | "reload_completed" | |
15404 | [(const_int 0)] | |
15405 | { | |
15406 | operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); | |
15407 | operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); | |
15408 | ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), | |
15409 | operands[3], operands[7], | |
15410 | operands[4], operands[5], operands[6], operands[2]); | |
9e7adcb3 | 15411 | DONE; |
0f40f9f7 | 15412 | }) |
886c62d1 JVA |
15413 | \f |
15414 | ;; Unconditional and other jump instructions | |
15415 | ||
15416 | (define_insn "jump" | |
15417 | [(set (pc) | |
15418 | (label_ref (match_operand 0 "" "")))] | |
15419 | "" | |
0f40f9f7 | 15420 | "jmp\t%l0" |
c7375e61 | 15421 | [(set_attr "type" "ibr") |
efcc7037 JH |
15422 | (set (attr "length") |
15423 | (if_then_else (and (ge (minus (match_dup 0) (pc)) | |
db1077d3 | 15424 | (const_int -126)) |
efcc7037 | 15425 | (lt (minus (match_dup 0) (pc)) |
db1077d3 | 15426 | (const_int 128))) |
efcc7037 JH |
15427 | (const_int 2) |
15428 | (const_int 5))) | |
c7375e61 | 15429 | (set_attr "modrm" "0")]) |
886c62d1 | 15430 | |
14f73b5a | 15431 | (define_expand "indirect_jump" |
00188daa | 15432 | [(set (pc) (match_operand 0 "nonimmediate_operand" ""))] |
886c62d1 | 15433 | "" |
14f73b5a JH |
15434 | "") |
15435 | ||
15436 | (define_insn "*indirect_jump" | |
c4fe74e0 UB |
15437 | [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))] |
15438 | "" | |
0f40f9f7 | 15439 | "jmp\t%A0" |
6ef67412 JH |
15440 | [(set_attr "type" "ibr") |
15441 | (set_attr "length_immediate" "0")]) | |
4801403e | 15442 | |
90675921 | 15443 | (define_expand "tablejump" |
00188daa | 15444 | [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "")) |
90675921 RH |
15445 | (use (label_ref (match_operand 1 "" "")))])] |
15446 | "" | |
15447 | { | |
66edd3b4 RH |
15448 | /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) |
15449 | relative. Convert the relative address to an absolute address. */ | |
90675921 RH |
15450 | if (flag_pic) |
15451 | { | |
66edd3b4 RH |
15452 | rtx op0, op1; |
15453 | enum rtx_code code; | |
15454 | ||
170bdaba RS |
15455 | /* We can't use @GOTOFF for text labels on VxWorks; |
15456 | see gotoff_operand. */ | |
15457 | if (TARGET_64BIT || TARGET_VXWORKS_RTP) | |
66edd3b4 RH |
15458 | { |
15459 | code = PLUS; | |
15460 | op0 = operands[0]; | |
15461 | op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); | |
15462 | } | |
b069de3b | 15463 | else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) |
f88c65f7 | 15464 | { |
66edd3b4 RH |
15465 | code = PLUS; |
15466 | op0 = operands[0]; | |
15467 | op1 = pic_offset_table_rtx; | |
f88c65f7 | 15468 | } |
6eb791fc JH |
15469 | else |
15470 | { | |
66edd3b4 RH |
15471 | code = MINUS; |
15472 | op0 = pic_offset_table_rtx; | |
15473 | op1 = operands[0]; | |
6eb791fc | 15474 | } |
66edd3b4 | 15475 | |
c16576e6 | 15476 | operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, |
66edd3b4 | 15477 | OPTAB_DIRECT); |
90675921 | 15478 | } |
0f40f9f7 | 15479 | }) |
2bb7a0f5 | 15480 | |
90675921 | 15481 | (define_insn "*tablejump_1" |
c4fe74e0 | 15482 | [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm")) |
14f73b5a | 15483 | (use (label_ref (match_operand 1 "" "")))] |
c4fe74e0 | 15484 | "" |
0f40f9f7 | 15485 | "jmp\t%A0" |
6ef67412 JH |
15486 | [(set_attr "type" "ibr") |
15487 | (set_attr "length_immediate" "0")]) | |
e075ae69 | 15488 | \f |
c50e5bc0 RH |
15489 | ;; Convert setcc + movzbl to xor + setcc if operands don't overlap. |
15490 | ||
15491 | (define_peephole2 | |
42fabf21 | 15492 | [(set (reg FLAGS_REG) (match_operand 0 "" "")) |
c50e5bc0 RH |
15493 | (set (match_operand:QI 1 "register_operand" "") |
15494 | (match_operator:QI 2 "ix86_comparison_operator" | |
42fabf21 | 15495 | [(reg FLAGS_REG) (const_int 0)])) |
c50e5bc0 RH |
15496 | (set (match_operand 3 "q_regs_operand" "") |
15497 | (zero_extend (match_dup 1)))] | |
646ded90 RH |
15498 | "(peep2_reg_dead_p (3, operands[1]) |
15499 | || operands_match_p (operands[1], operands[3])) | |
c50e5bc0 | 15500 | && ! reg_overlap_mentioned_p (operands[3], operands[0])" |
646ded90 RH |
15501 | [(set (match_dup 4) (match_dup 0)) |
15502 | (set (strict_low_part (match_dup 5)) | |
15503 | (match_dup 2))] | |
15504 | { | |
ff680eb1 | 15505 | operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); |
1e2115dc | 15506 | operands[5] = gen_lowpart (QImode, operands[3]); |
a8bac9ab | 15507 | ix86_expand_clear (operands[3]); |
646ded90 RH |
15508 | }) |
15509 | ||
15510 | ;; Similar, but match zero_extendhisi2_and, which adds a clobber. | |
15511 | ||
15512 | (define_peephole2 | |
42fabf21 | 15513 | [(set (reg FLAGS_REG) (match_operand 0 "" "")) |
646ded90 RH |
15514 | (set (match_operand:QI 1 "register_operand" "") |
15515 | (match_operator:QI 2 "ix86_comparison_operator" | |
42fabf21 | 15516 | [(reg FLAGS_REG) (const_int 0)])) |
646ded90 RH |
15517 | (parallel [(set (match_operand 3 "q_regs_operand" "") |
15518 | (zero_extend (match_dup 1))) | |
8bc527af | 15519 | (clobber (reg:CC FLAGS_REG))])] |
646ded90 RH |
15520 | "(peep2_reg_dead_p (3, operands[1]) |
15521 | || operands_match_p (operands[1], operands[3])) | |
15522 | && ! reg_overlap_mentioned_p (operands[3], operands[0])" | |
15523 | [(set (match_dup 4) (match_dup 0)) | |
c50e5bc0 RH |
15524 | (set (strict_low_part (match_dup 5)) |
15525 | (match_dup 2))] | |
646ded90 | 15526 | { |
ff680eb1 | 15527 | operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); |
1e2115dc | 15528 | operands[5] = gen_lowpart (QImode, operands[3]); |
a8bac9ab | 15529 | ix86_expand_clear (operands[3]); |
646ded90 | 15530 | }) |
e075ae69 RH |
15531 | \f |
15532 | ;; Call instructions. | |
2bb7a0f5 | 15533 | |
cbbf65e0 RH |
15534 | ;; The predicates normally associated with named expanders are not properly |
15535 | ;; checked for calls. This is a bug in the generic code, but it isn't that | |
15536 | ;; easy to fix. Ignore it for now and be prepared to fix things up. | |
2bb7a0f5 | 15537 | |
886c62d1 JVA |
15538 | ;; Call subroutine returning no value. |
15539 | ||
2bb7a0f5 | 15540 | (define_expand "call_pop" |
cbbf65e0 RH |
15541 | [(parallel [(call (match_operand:QI 0 "" "") |
15542 | (match_operand:SI 1 "" "")) | |
8bc527af SB |
15543 | (set (reg:SI SP_REG) |
15544 | (plus:SI (reg:SI SP_REG) | |
cbbf65e0 | 15545 | (match_operand:SI 3 "" "")))])] |
1e07edd3 | 15546 | "!TARGET_64BIT" |
2bb7a0f5 | 15547 | { |
4977bab6 | 15548 | ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0); |
0e07aff3 | 15549 | DONE; |
0f40f9f7 | 15550 | }) |
2bb7a0f5 | 15551 | |
94bb5d0c | 15552 | (define_insn "*call_pop_0" |
e1ff012c | 15553 | [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) |
94bb5d0c | 15554 | (match_operand:SI 1 "" "")) |
8bc527af | 15555 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) |
90d10fb9 | 15556 | (match_operand:SI 2 "immediate_operand" "")))] |
1e07edd3 | 15557 | "!TARGET_64BIT" |
94bb5d0c RH |
15558 | { |
15559 | if (SIBLING_CALL_P (insn)) | |
0f40f9f7 | 15560 | return "jmp\t%P0"; |
94bb5d0c | 15561 | else |
0f40f9f7 ZW |
15562 | return "call\t%P0"; |
15563 | } | |
94bb5d0c | 15564 | [(set_attr "type" "call")]) |
6300f037 | 15565 | |
cbbf65e0 | 15566 | (define_insn "*call_pop_1" |
e1ff012c | 15567 | [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) |
94bb5d0c | 15568 | (match_operand:SI 1 "" "")) |
8bc527af | 15569 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) |
90d10fb9 | 15570 | (match_operand:SI 2 "immediate_operand" "i")))] |
1e07edd3 | 15571 | "!TARGET_64BIT" |
886c62d1 | 15572 | { |
e1ff012c | 15573 | if (constant_call_address_operand (operands[0], Pmode)) |
94bb5d0c RH |
15574 | { |
15575 | if (SIBLING_CALL_P (insn)) | |
0f40f9f7 | 15576 | return "jmp\t%P0"; |
94bb5d0c | 15577 | else |
0f40f9f7 | 15578 | return "call\t%P0"; |
94bb5d0c | 15579 | } |
94bb5d0c | 15580 | if (SIBLING_CALL_P (insn)) |
0f40f9f7 | 15581 | return "jmp\t%A0"; |
94bb5d0c | 15582 | else |
0f40f9f7 ZW |
15583 | return "call\t%A0"; |
15584 | } | |
e075ae69 | 15585 | [(set_attr "type" "call")]) |
886c62d1 | 15586 | |
2bb7a0f5 | 15587 | (define_expand "call" |
cbbf65e0 | 15588 | [(call (match_operand:QI 0 "" "") |
39d04363 JH |
15589 | (match_operand 1 "" "")) |
15590 | (use (match_operand 2 "" ""))] | |
2bb7a0f5 | 15591 | "" |
2bb7a0f5 | 15592 | { |
4977bab6 ZW |
15593 | ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0); |
15594 | DONE; | |
15595 | }) | |
15596 | ||
15597 | (define_expand "sibcall" | |
15598 | [(call (match_operand:QI 0 "" "") | |
15599 | (match_operand 1 "" "")) | |
15600 | (use (match_operand 2 "" ""))] | |
15601 | "" | |
15602 | { | |
15603 | ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1); | |
0e07aff3 | 15604 | DONE; |
0f40f9f7 | 15605 | }) |
2bb7a0f5 | 15606 | |
94bb5d0c | 15607 | (define_insn "*call_0" |
32ee7d1d JH |
15608 | [(call (mem:QI (match_operand 0 "constant_call_address_operand" "")) |
15609 | (match_operand 1 "" ""))] | |
94bb5d0c | 15610 | "" |
94bb5d0c RH |
15611 | { |
15612 | if (SIBLING_CALL_P (insn)) | |
0f40f9f7 | 15613 | return "jmp\t%P0"; |
94bb5d0c | 15614 | else |
0f40f9f7 ZW |
15615 | return "call\t%P0"; |
15616 | } | |
94bb5d0c RH |
15617 | [(set_attr "type" "call")]) |
15618 | ||
cbbf65e0 | 15619 | (define_insn "*call_1" |
e1ff012c | 15620 | [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) |
32ee7d1d | 15621 | (match_operand 1 "" ""))] |
4977bab6 | 15622 | "!SIBLING_CALL_P (insn) && !TARGET_64BIT" |
32ee7d1d | 15623 | { |
e427abbf | 15624 | if (constant_call_address_operand (operands[0], Pmode)) |
4977bab6 ZW |
15625 | return "call\t%P0"; |
15626 | return "call\t%A0"; | |
15627 | } | |
15628 | [(set_attr "type" "call")]) | |
15629 | ||
15630 | (define_insn "*sibcall_1" | |
15631 | [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a")) | |
15632 | (match_operand 1 "" ""))] | |
15633 | "SIBLING_CALL_P (insn) && !TARGET_64BIT" | |
15634 | { | |
e427abbf | 15635 | if (constant_call_address_operand (operands[0], Pmode)) |
4977bab6 ZW |
15636 | return "jmp\t%P0"; |
15637 | return "jmp\t%A0"; | |
0f40f9f7 | 15638 | } |
32ee7d1d JH |
15639 | [(set_attr "type" "call")]) |
15640 | ||
15641 | (define_insn "*call_1_rex64" | |
15642 | [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) | |
15643 | (match_operand 1 "" ""))] | |
dc4d7240 JH |
15644 | "!SIBLING_CALL_P (insn) && TARGET_64BIT |
15645 | && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC" | |
886c62d1 | 15646 | { |
e427abbf | 15647 | if (constant_call_address_operand (operands[0], Pmode)) |
4977bab6 ZW |
15648 | return "call\t%P0"; |
15649 | return "call\t%A0"; | |
0f40f9f7 | 15650 | } |
e075ae69 | 15651 | [(set_attr "type" "call")]) |
886c62d1 | 15652 | |
924eabec JH |
15653 | (define_insn "*call_1_rex64_ms_sysv" |
15654 | [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) | |
15655 | (match_operand 1 "" "")) | |
15656 | (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) | |
78168632 UB |
15657 | (clobber (reg:TI XMM6_REG)) |
15658 | (clobber (reg:TI XMM7_REG)) | |
15659 | (clobber (reg:TI XMM8_REG)) | |
15660 | (clobber (reg:TI XMM9_REG)) | |
15661 | (clobber (reg:TI XMM10_REG)) | |
15662 | (clobber (reg:TI XMM11_REG)) | |
15663 | (clobber (reg:TI XMM12_REG)) | |
15664 | (clobber (reg:TI XMM13_REG)) | |
15665 | (clobber (reg:TI XMM14_REG)) | |
15666 | (clobber (reg:TI XMM15_REG)) | |
924eabec JH |
15667 | (clobber (reg:DI SI_REG)) |
15668 | (clobber (reg:DI DI_REG))] | |
15669 | "!SIBLING_CALL_P (insn) && TARGET_64BIT" | |
15670 | { | |
15671 | if (constant_call_address_operand (operands[0], Pmode)) | |
15672 | return "call\t%P0"; | |
15673 | return "call\t%A0"; | |
15674 | } | |
15675 | [(set_attr "type" "call")]) | |
15676 | ||
dc4d7240 JH |
15677 | (define_insn "*call_1_rex64_large" |
15678 | [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm")) | |
15679 | (match_operand 1 "" ""))] | |
15680 | "!SIBLING_CALL_P (insn) && TARGET_64BIT" | |
15681 | "call\t%A0" | |
15682 | [(set_attr "type" "call")]) | |
15683 | ||
4977bab6 ZW |
15684 | (define_insn "*sibcall_1_rex64" |
15685 | [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" "")) | |
15686 | (match_operand 1 "" ""))] | |
15687 | "SIBLING_CALL_P (insn) && TARGET_64BIT" | |
15688 | "jmp\t%P0" | |
15689 | [(set_attr "type" "call")]) | |
15690 | ||
15691 | (define_insn "*sibcall_1_rex64_v" | |
03c259ad | 15692 | [(call (mem:QI (reg:DI R11_REG)) |
4977bab6 ZW |
15693 | (match_operand 0 "" ""))] |
15694 | "SIBLING_CALL_P (insn) && TARGET_64BIT" | |
9ad5e54f | 15695 | "jmp\t{*%%}r11" |
4977bab6 ZW |
15696 | [(set_attr "type" "call")]) |
15697 | ||
15698 | ||
886c62d1 | 15699 | ;; Call subroutine, returning value in operand 0 |
886c62d1 | 15700 | |
2bb7a0f5 RS |
15701 | (define_expand "call_value_pop" |
15702 | [(parallel [(set (match_operand 0 "" "") | |
cbbf65e0 RH |
15703 | (call (match_operand:QI 1 "" "") |
15704 | (match_operand:SI 2 "" ""))) | |
8bc527af SB |
15705 | (set (reg:SI SP_REG) |
15706 | (plus:SI (reg:SI SP_REG) | |
cbbf65e0 | 15707 | (match_operand:SI 4 "" "")))])] |
1e07edd3 | 15708 | "!TARGET_64BIT" |
2bb7a0f5 | 15709 | { |
0e07aff3 | 15710 | ix86_expand_call (operands[0], operands[1], operands[2], |
4977bab6 | 15711 | operands[3], operands[4], 0); |
0e07aff3 | 15712 | DONE; |
0f40f9f7 | 15713 | }) |
2bb7a0f5 | 15714 | |
2bb7a0f5 RS |
15715 | (define_expand "call_value" |
15716 | [(set (match_operand 0 "" "") | |
cbbf65e0 | 15717 | (call (match_operand:QI 1 "" "") |
39d04363 JH |
15718 | (match_operand:SI 2 "" ""))) |
15719 | (use (match_operand:SI 3 "" ""))] | |
2bb7a0f5 RS |
15720 | ;; Operand 2 not used on the i386. |
15721 | "" | |
2bb7a0f5 | 15722 | { |
4977bab6 ZW |
15723 | ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0); |
15724 | DONE; | |
15725 | }) | |
15726 | ||
15727 | (define_expand "sibcall_value" | |
15728 | [(set (match_operand 0 "" "") | |
15729 | (call (match_operand:QI 1 "" "") | |
15730 | (match_operand:SI 2 "" ""))) | |
15731 | (use (match_operand:SI 3 "" ""))] | |
15732 | ;; Operand 2 not used on the i386. | |
15733 | "" | |
15734 | { | |
15735 | ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1); | |
39d04363 | 15736 | DONE; |
0f40f9f7 | 15737 | }) |
2bb7a0f5 | 15738 | |
b840bfb0 MM |
15739 | ;; Call subroutine returning any type. |
15740 | ||
576182a3 | 15741 | (define_expand "untyped_call" |
b840bfb0 | 15742 | [(parallel [(call (match_operand 0 "" "") |
576182a3 | 15743 | (const_int 0)) |
b840bfb0 | 15744 | (match_operand 1 "" "") |
576182a3 TW |
15745 | (match_operand 2 "" "")])] |
15746 | "" | |
576182a3 | 15747 | { |
b840bfb0 | 15748 | int i; |
576182a3 | 15749 | |
d8b679b9 RK |
15750 | /* In order to give reg-stack an easier job in validating two |
15751 | coprocessor registers as containing a possible return value, | |
15752 | simply pretend the untyped call returns a complex long double | |
435a61d3 L |
15753 | value. |
15754 | ||
15755 | We can't use SSE_REGPARM_MAX here since callee is unprototyped | |
15756 | and should have the default ABI. */ | |
74775c7a | 15757 | |
0e07aff3 RH |
15758 | ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 |
15759 | ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), | |
7c800926 | 15760 | operands[0], const0_rtx, |
435a61d3 | 15761 | GEN_INT ((TARGET_64BIT |
51212b32 | 15762 | ? (ix86_abi == SYSV_ABI |
435a61d3 L |
15763 | ? X86_64_SSE_REGPARM_MAX |
15764 | : X64_SSE_REGPARM_MAX) | |
15765 | : X86_32_SSE_REGPARM_MAX) | |
7c800926 | 15766 | - 1), |
4977bab6 | 15767 | NULL, 0); |
576182a3 | 15768 | |
b840bfb0 | 15769 | for (i = 0; i < XVECLEN (operands[2], 0); i++) |
576182a3 | 15770 | { |
b840bfb0 MM |
15771 | rtx set = XVECEXP (operands[2], 0, i); |
15772 | emit_move_insn (SET_DEST (set), SET_SRC (set)); | |
576182a3 | 15773 | } |
576182a3 | 15774 | |
b840bfb0 MM |
15775 | /* The optimizer does not know that the call sets the function value |
15776 | registers we stored in the result block. We avoid problems by | |
15777 | claiming that all hard registers are used and clobbered at this | |
15778 | point. */ | |
6fb5fa3c | 15779 | emit_insn (gen_blockage ()); |
576182a3 TW |
15780 | |
15781 | DONE; | |
0f40f9f7 | 15782 | }) |
e075ae69 RH |
15783 | \f |
15784 | ;; Prologue and epilogue instructions | |
576182a3 | 15785 | |
b840bfb0 MM |
15786 | ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and |
15787 | ;; all of memory. This blocks insns from being moved across this point. | |
15788 | ||
15789 | (define_insn "blockage" | |
6fb5fa3c DB |
15790 | [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] |
15791 | "" | |
15792 | "" | |
15793 | [(set_attr "length" "0")]) | |
15794 | ||
b058b753 UB |
15795 | ;; Do not schedule instructions accessing memory across this point. |
15796 | ||
15797 | (define_expand "memory_blockage" | |
15798 | [(set (match_dup 0) | |
15799 | (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] | |
15800 | "" | |
15801 | { | |
15802 | operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); | |
15803 | MEM_VOLATILE_P (operands[0]) = 1; | |
15804 | }) | |
15805 | ||
15806 | (define_insn "*memory_blockage" | |
15807 | [(set (match_operand:BLK 0 "" "") | |
15808 | (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] | |
15809 | "" | |
15810 | "" | |
15811 | [(set_attr "length" "0")]) | |
15812 | ||
6fb5fa3c DB |
15813 | ;; As USE insns aren't meaningful after reload, this is used instead |
15814 | ;; to prevent deleting instructions setting registers for PIC code | |
15815 | (define_insn "prologue_use" | |
15816 | [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)] | |
576182a3 | 15817 | "" |
90aec2cf | 15818 | "" |
e075ae69 | 15819 | [(set_attr "length" "0")]) |
576182a3 | 15820 | |
886c62d1 JVA |
15821 | ;; Insn emitted into the body of a function to return from a function. |
15822 | ;; This is only done if the function's epilogue is known to be simple. | |
182a4620 | 15823 | ;; See comments for ix86_can_use_return_insn_p in i386.c. |
886c62d1 | 15824 | |
5f3d14e3 | 15825 | (define_expand "return" |
886c62d1 | 15826 | [(return)] |
5f3d14e3 | 15827 | "ix86_can_use_return_insn_p ()" |
9a7372d6 | 15828 | { |
38173d38 | 15829 | if (crtl->args.pops_args) |
9a7372d6 | 15830 | { |
38173d38 | 15831 | rtx popc = GEN_INT (crtl->args.pops_args); |
9a7372d6 RH |
15832 | emit_jump_insn (gen_return_pop_internal (popc)); |
15833 | DONE; | |
15834 | } | |
0f40f9f7 | 15835 | }) |
5f3d14e3 SC |
15836 | |
15837 | (define_insn "return_internal" | |
15838 | [(return)] | |
15839 | "reload_completed" | |
90aec2cf | 15840 | "ret" |
6ef67412 | 15841 | [(set_attr "length" "1") |
b6837b94 | 15842 | (set_attr "atom_unit" "jeu") |
6ef67412 JH |
15843 | (set_attr "length_immediate" "0") |
15844 | (set_attr "modrm" "0")]) | |
5f3d14e3 | 15845 | |
253c7a00 JH |
15846 | ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET |
15847 | ;; instruction Athlon and K8 have. | |
15848 | ||
15849 | (define_insn "return_internal_long" | |
15850 | [(return) | |
15851 | (unspec [(const_int 0)] UNSPEC_REP)] | |
15852 | "reload_completed" | |
9ad5e54f | 15853 | "rep\;ret" |
a952487c | 15854 | [(set_attr "length" "2") |
b6837b94 | 15855 | (set_attr "atom_unit" "jeu") |
253c7a00 JH |
15856 | (set_attr "length_immediate" "0") |
15857 | (set_attr "prefix_rep" "1") | |
15858 | (set_attr "modrm" "0")]) | |
15859 | ||
6cd96118 SC |
15860 | (define_insn "return_pop_internal" |
15861 | [(return) | |
15862 | (use (match_operand:SI 0 "const_int_operand" ""))] | |
15863 | "reload_completed" | |
0f40f9f7 | 15864 | "ret\t%0" |
6ef67412 | 15865 | [(set_attr "length" "3") |
b6837b94 | 15866 | (set_attr "atom_unit" "jeu") |
6ef67412 JH |
15867 | (set_attr "length_immediate" "2") |
15868 | (set_attr "modrm" "0")]) | |
6cd96118 | 15869 | |
11837777 RH |
15870 | (define_insn "return_indirect_internal" |
15871 | [(return) | |
15872 | (use (match_operand:SI 0 "register_operand" "r"))] | |
15873 | "reload_completed" | |
0f40f9f7 | 15874 | "jmp\t%A0" |
11837777 RH |
15875 | [(set_attr "type" "ibr") |
15876 | (set_attr "length_immediate" "0")]) | |
15877 | ||
5f3d14e3 SC |
15878 | (define_insn "nop" |
15879 | [(const_int 0)] | |
15880 | "" | |
90aec2cf | 15881 | "nop" |
e075ae69 | 15882 | [(set_attr "length" "1") |
6ef67412 | 15883 | (set_attr "length_immediate" "0") |
56bab446 | 15884 | (set_attr "modrm" "0")]) |
5f3d14e3 | 15885 | |
6a90d232 | 15886 | ;; Pad to 16-byte boundary, max skip in op0. Used to avoid |
9ccf9681 RH |
15887 | ;; branch prediction penalty for the third jump in a 16-byte |
15888 | ;; block on K8. | |
d2c49530 | 15889 | |
6a90d232 | 15890 | (define_insn "pad" |
d2c49530 JH |
15891 | [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] |
15892 | "" | |
15893 | { | |
6a90d232 L |
15894 | #ifdef ASM_OUTPUT_MAX_SKIP_PAD |
15895 | ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); | |
9ccf9681 | 15896 | #else |
6262f66a JH |
15897 | /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. |
15898 | The align insn is used to avoid 3 jump instructions in the row to improve | |
6fc0bb99 | 15899 | branch prediction and the benefits hardly outweigh the cost of extra 8 |
6262f66a | 15900 | nops on the average inserted by full alignment pseudo operation. */ |
d2c49530 | 15901 | #endif |
9ccf9681 | 15902 | return ""; |
d2c49530 JH |
15903 | } |
15904 | [(set_attr "length" "16")]) | |
15905 | ||
5f3d14e3 | 15906 | (define_expand "prologue" |
00188daa | 15907 | [(const_int 0)] |
5f3d14e3 | 15908 | "" |
e075ae69 | 15909 | "ix86_expand_prologue (); DONE;") |
5f3d14e3 | 15910 | |
bd09bdeb | 15911 | (define_insn "set_got" |
69404d6f | 15912 | [(set (match_operand:SI 0 "register_operand" "=r") |
c8c03509 | 15913 | (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) |
8bc527af | 15914 | (clobber (reg:CC FLAGS_REG))] |
1e07edd3 | 15915 | "!TARGET_64BIT" |
7d072037 SH |
15916 | { return output_set_got (operands[0], NULL_RTX); } |
15917 | [(set_attr "type" "multi") | |
15918 | (set_attr "length" "12")]) | |
15919 | ||
15920 | (define_insn "set_got_labelled" | |
15921 | [(set (match_operand:SI 0 "register_operand" "=r") | |
15922 | (unspec:SI [(label_ref (match_operand 1 "" ""))] | |
15923 | UNSPEC_SET_GOT)) | |
15924 | (clobber (reg:CC FLAGS_REG))] | |
15925 | "!TARGET_64BIT" | |
15926 | { return output_set_got (operands[0], operands[1]); } | |
c8c03509 RH |
15927 | [(set_attr "type" "multi") |
15928 | (set_attr "length" "12")]) | |
5f3d14e3 | 15929 | |
7dcbf659 JH |
15930 | (define_insn "set_got_rex64" |
15931 | [(set (match_operand:DI 0 "register_operand" "=r") | |
15932 | (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] | |
15933 | "TARGET_64BIT" | |
9ad5e54f | 15934 | "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" |
7dcbf659 | 15935 | [(set_attr "type" "lea") |
725fd454 JJ |
15936 | (set_attr "length_address" "4") |
15937 | (set_attr "mode" "DI")]) | |
7dcbf659 | 15938 | |
dc4d7240 JH |
15939 | (define_insn "set_rip_rex64" |
15940 | [(set (match_operand:DI 0 "register_operand" "=r") | |
bef3c57b | 15941 | (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))] |
dc4d7240 | 15942 | "TARGET_64BIT" |
9ad5e54f | 15943 | "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" |
dc4d7240 | 15944 | [(set_attr "type" "lea") |
725fd454 JJ |
15945 | (set_attr "length_address" "4") |
15946 | (set_attr "mode" "DI")]) | |
dc4d7240 JH |
15947 | |
15948 | (define_insn "set_got_offset_rex64" | |
15949 | [(set (match_operand:DI 0 "register_operand" "=r") | |
bef3c57b UB |
15950 | (unspec:DI |
15951 | [(label_ref (match_operand 1 "" ""))] | |
15952 | UNSPEC_SET_GOT_OFFSET))] | |
dc4d7240 | 15953 | "TARGET_64BIT" |
9ad5e54f | 15954 | "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" |
dc4d7240 | 15955 | [(set_attr "type" "imov") |
725fd454 JJ |
15956 | (set_attr "length_immediate" "0") |
15957 | (set_attr "length_address" "8") | |
15958 | (set_attr "mode" "DI")]) | |
dc4d7240 | 15959 | |
e075ae69 | 15960 | (define_expand "epilogue" |
00188daa | 15961 | [(const_int 0)] |
e075ae69 | 15962 | "" |
cbbf65e0 RH |
15963 | "ix86_expand_epilogue (1); DONE;") |
15964 | ||
15965 | (define_expand "sibcall_epilogue" | |
00188daa | 15966 | [(const_int 0)] |
cbbf65e0 RH |
15967 | "" |
15968 | "ix86_expand_epilogue (0); DONE;") | |
e075ae69 | 15969 | |
1020a5ab | 15970 | (define_expand "eh_return" |
34dc173c | 15971 | [(use (match_operand 0 "register_operand" ""))] |
1020a5ab | 15972 | "" |
1020a5ab | 15973 | { |
34dc173c | 15974 | rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; |
1020a5ab RH |
15975 | |
15976 | /* Tricky bit: we write the address of the handler to which we will | |
15977 | be returning into someone else's stack frame, one word below the | |
15978 | stack address we wish to restore. */ | |
15979 | tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); | |
15980 | tmp = plus_constant (tmp, -UNITS_PER_WORD); | |
15981 | tmp = gen_rtx_MEM (Pmode, tmp); | |
15982 | emit_move_insn (tmp, ra); | |
15983 | ||
cd9c1ca8 | 15984 | emit_jump_insn (gen_eh_return_internal ()); |
1020a5ab RH |
15985 | emit_barrier (); |
15986 | DONE; | |
0f40f9f7 | 15987 | }) |
1020a5ab | 15988 | |
cd9c1ca8 RH |
15989 | (define_insn_and_split "eh_return_internal" |
15990 | [(eh_return)] | |
c4fe74e0 | 15991 | "" |
1020a5ab | 15992 | "#" |
cd9c1ca8 | 15993 | "epilogue_completed" |
00188daa | 15994 | [(const_int 0)] |
1020a5ab RH |
15995 | "ix86_expand_epilogue (2); DONE;") |
15996 | ||
e075ae69 | 15997 | (define_insn "leave" |
8bc527af SB |
15998 | [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) |
15999 | (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) | |
f2042df3 | 16000 | (clobber (mem:BLK (scratch)))] |
1e07edd3 | 16001 | "!TARGET_64BIT" |
e075ae69 | 16002 | "leave" |
4977bab6 | 16003 | [(set_attr "type" "leave")]) |
8362f420 JH |
16004 | |
16005 | (define_insn "leave_rex64" | |
8bc527af SB |
16006 | [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) |
16007 | (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) | |
f2042df3 | 16008 | (clobber (mem:BLK (scratch)))] |
8362f420 JH |
16009 | "TARGET_64BIT" |
16010 | "leave" | |
4977bab6 | 16011 | [(set_attr "type" "leave")]) |
e075ae69 RH |
16012 | \f |
16013 | (define_expand "ffssi2" | |
8acfdd43 | 16014 | [(parallel |
6300f037 | 16015 | [(set (match_operand:SI 0 "register_operand" "") |
8acfdd43 RH |
16016 | (ffs:SI (match_operand:SI 1 "nonimmediate_operand" ""))) |
16017 | (clobber (match_scratch:SI 2 "")) | |
8bc527af | 16018 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 | 16019 | "" |
08024fb5 UB |
16020 | { |
16021 | if (TARGET_CMOVE) | |
16022 | { | |
16023 | emit_insn (gen_ffs_cmove (operands[0], operands[1])); | |
16024 | DONE; | |
16025 | } | |
16026 | }) | |
e075ae69 | 16027 | |
08024fb5 | 16028 | (define_expand "ffs_cmove" |
8acfdd43 | 16029 | [(set (match_dup 2) (const_int -1)) |
08024fb5 | 16030 | (parallel [(set (reg:CCZ FLAGS_REG) |
3cdf0c62 | 16031 | (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "") |
08024fb5 | 16032 | (const_int 0))) |
3cdf0c62 | 16033 | (set (match_operand:SI 0 "register_operand" "") |
08024fb5 | 16034 | (ctz:SI (match_dup 1)))]) |
8acfdd43 | 16035 | (set (match_dup 0) (if_then_else:SI |
8bc527af | 16036 | (eq (reg:CCZ FLAGS_REG) (const_int 0)) |
8acfdd43 RH |
16037 | (match_dup 2) |
16038 | (match_dup 0))) | |
16039 | (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) | |
8bc527af | 16040 | (clobber (reg:CC FLAGS_REG))])] |
08024fb5 UB |
16041 | "TARGET_CMOVE" |
16042 | "operands[2] = gen_reg_rtx (SImode);") | |
e0dc26ff | 16043 | |
8acfdd43 | 16044 | (define_insn_and_split "*ffs_no_cmove" |
3cdf0c62 | 16045 | [(set (match_operand:SI 0 "register_operand" "=r") |
8acfdd43 | 16046 | (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) |
fa543fdd | 16047 | (clobber (match_scratch:SI 2 "=&q")) |
8bc527af | 16048 | (clobber (reg:CC FLAGS_REG))] |
08024fb5 | 16049 | "!TARGET_CMOVE" |
8acfdd43 | 16050 | "#" |
08024fb5 UB |
16051 | "&& reload_completed" |
16052 | [(parallel [(set (reg:CCZ FLAGS_REG) | |
16053 | (compare:CCZ (match_dup 1) (const_int 0))) | |
8acfdd43 RH |
16054 | (set (match_dup 0) (ctz:SI (match_dup 1)))]) |
16055 | (set (strict_low_part (match_dup 3)) | |
8bc527af | 16056 | (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) |
8acfdd43 | 16057 | (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) |
8bc527af | 16058 | (clobber (reg:CC FLAGS_REG))]) |
8acfdd43 | 16059 | (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) |
8bc527af | 16060 | (clobber (reg:CC FLAGS_REG))]) |
8acfdd43 | 16061 | (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) |
8bc527af | 16062 | (clobber (reg:CC FLAGS_REG))])] |
8acfdd43 RH |
16063 | { |
16064 | operands[3] = gen_lowpart (QImode, operands[2]); | |
707e58b1 | 16065 | ix86_expand_clear (operands[2]); |
0f40f9f7 | 16066 | }) |
886c62d1 | 16067 | |
8acfdd43 | 16068 | (define_insn "*ffssi_1" |
8bc527af | 16069 | [(set (reg:CCZ FLAGS_REG) |
8acfdd43 | 16070 | (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") |
16189740 | 16071 | (const_int 0))) |
e075ae69 | 16072 | (set (match_operand:SI 0 "register_operand" "=r") |
8acfdd43 RH |
16073 | (ctz:SI (match_dup 1)))] |
16074 | "" | |
16075 | "bsf{l}\t{%1, %0|%0, %1}" | |
725fd454 JJ |
16076 | [(set_attr "type" "alu1") |
16077 | (set_attr "prefix_0f" "1") | |
16078 | (set_attr "mode" "SI")]) | |
8acfdd43 | 16079 | |
d413e3cc | 16080 | (define_expand "ffsdi2" |
d413e3cc | 16081 | [(set (match_dup 2) (const_int -1)) |
42fabf21 | 16082 | (parallel [(set (reg:CCZ FLAGS_REG) |
3cdf0c62 | 16083 | (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "") |
08024fb5 | 16084 | (const_int 0))) |
3cdf0c62 | 16085 | (set (match_operand:DI 0 "register_operand" "") |
08024fb5 | 16086 | (ctz:DI (match_dup 1)))]) |
d413e3cc | 16087 | (set (match_dup 0) (if_then_else:DI |
42fabf21 | 16088 | (eq (reg:CCZ FLAGS_REG) (const_int 0)) |
d413e3cc JJ |
16089 | (match_dup 2) |
16090 | (match_dup 0))) | |
16091 | (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) | |
42fabf21 | 16092 | (clobber (reg:CC FLAGS_REG))])] |
08024fb5 UB |
16093 | "TARGET_64BIT" |
16094 | "operands[2] = gen_reg_rtx (DImode);") | |
d413e3cc JJ |
16095 | |
16096 | (define_insn "*ffsdi_1" | |
42fabf21 | 16097 | [(set (reg:CCZ FLAGS_REG) |
d413e3cc JJ |
16098 | (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm") |
16099 | (const_int 0))) | |
16100 | (set (match_operand:DI 0 "register_operand" "=r") | |
16101 | (ctz:DI (match_dup 1)))] | |
16102 | "TARGET_64BIT" | |
16103 | "bsf{q}\t{%1, %0|%0, %1}" | |
725fd454 JJ |
16104 | [(set_attr "type" "alu1") |
16105 | (set_attr "prefix_0f" "1") | |
16106 | (set_attr "mode" "DI")]) | |
d413e3cc | 16107 | |
8acfdd43 RH |
16108 | (define_insn "ctzsi2" |
16109 | [(set (match_operand:SI 0 "register_operand" "=r") | |
16110 | (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) | |
8bc527af | 16111 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 16112 | "" |
0f40f9f7 | 16113 | "bsf{l}\t{%1, %0|%0, %1}" |
725fd454 JJ |
16114 | [(set_attr "type" "alu1") |
16115 | (set_attr "prefix_0f" "1") | |
16116 | (set_attr "mode" "SI")]) | |
e075ae69 | 16117 | |
d413e3cc JJ |
16118 | (define_insn "ctzdi2" |
16119 | [(set (match_operand:DI 0 "register_operand" "=r") | |
16120 | (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) | |
42fabf21 | 16121 | (clobber (reg:CC FLAGS_REG))] |
d413e3cc JJ |
16122 | "TARGET_64BIT" |
16123 | "bsf{q}\t{%1, %0|%0, %1}" | |
725fd454 JJ |
16124 | [(set_attr "type" "alu1") |
16125 | (set_attr "prefix_0f" "1") | |
16126 | (set_attr "mode" "DI")]) | |
d413e3cc | 16127 | |
8acfdd43 RH |
16128 | (define_expand "clzsi2" |
16129 | [(parallel | |
16130 | [(set (match_operand:SI 0 "register_operand" "") | |
16131 | (minus:SI (const_int 31) | |
16132 | (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))) | |
8bc527af | 16133 | (clobber (reg:CC FLAGS_REG))]) |
8acfdd43 RH |
16134 | (parallel |
16135 | [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31))) | |
8bc527af | 16136 | (clobber (reg:CC FLAGS_REG))])] |
8acfdd43 | 16137 | "" |
21efb4d4 HJ |
16138 | { |
16139 | if (TARGET_ABM) | |
16140 | { | |
16141 | emit_insn (gen_clzsi2_abm (operands[0], operands[1])); | |
16142 | DONE; | |
16143 | } | |
16144 | }) | |
16145 | ||
16146 | (define_insn "clzsi2_abm" | |
16147 | [(set (match_operand:SI 0 "register_operand" "=r") | |
a3d4a22b | 16148 | (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) |
21efb4d4 HJ |
16149 | (clobber (reg:CC FLAGS_REG))] |
16150 | "TARGET_ABM" | |
16151 | "lzcnt{l}\t{%1, %0|%0, %1}" | |
16152 | [(set_attr "prefix_rep" "1") | |
16153 | (set_attr "type" "bitmanip") | |
16154 | (set_attr "mode" "SI")]) | |
8acfdd43 RH |
16155 | |
16156 | (define_insn "*bsr" | |
16157 | [(set (match_operand:SI 0 "register_operand" "=r") | |
16158 | (minus:SI (const_int 31) | |
16159 | (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) | |
8bc527af | 16160 | (clobber (reg:CC FLAGS_REG))] |
8acfdd43 RH |
16161 | "" |
16162 | "bsr{l}\t{%1, %0|%0, %1}" | |
725fd454 JJ |
16163 | [(set_attr "type" "alu1") |
16164 | (set_attr "prefix_0f" "1") | |
21efb4d4 HJ |
16165 | (set_attr "mode" "SI")]) |
16166 | ||
a00ce5fe UB |
16167 | (define_insn "popcount<mode>2" |
16168 | [(set (match_operand:SWI248 0 "register_operand" "=r") | |
16169 | (popcount:SWI248 | |
16170 | (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) | |
21efb4d4 HJ |
16171 | (clobber (reg:CC FLAGS_REG))] |
16172 | "TARGET_POPCNT" | |
a00ce5fe UB |
16173 | { |
16174 | #if TARGET_MACHO | |
16175 | return "popcnt\t{%1, %0|%0, %1}"; | |
16176 | #else | |
16177 | return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; | |
16178 | #endif | |
16179 | } | |
21efb4d4 HJ |
16180 | [(set_attr "prefix_rep" "1") |
16181 | (set_attr "type" "bitmanip") | |
a00ce5fe | 16182 | (set_attr "mode" "<MODE>")]) |
21efb4d4 | 16183 | |
a00ce5fe | 16184 | (define_insn "*popcount<mode>2_cmp" |
21efb4d4 HJ |
16185 | [(set (reg FLAGS_REG) |
16186 | (compare | |
a00ce5fe UB |
16187 | (popcount:SWI248 |
16188 | (match_operand:SWI248 1 "nonimmediate_operand" "rm")) | |
21efb4d4 | 16189 | (const_int 0))) |
a00ce5fe UB |
16190 | (set (match_operand:SWI248 0 "register_operand" "=r") |
16191 | (popcount:SWI248 (match_dup 1)))] | |
21efb4d4 | 16192 | "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" |
a00ce5fe UB |
16193 | { |
16194 | #if TARGET_MACHO | |
16195 | return "popcnt\t{%1, %0|%0, %1}"; | |
16196 | #else | |
16197 | return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; | |
16198 | #endif | |
16199 | } | |
21efb4d4 HJ |
16200 | [(set_attr "prefix_rep" "1") |
16201 | (set_attr "type" "bitmanip") | |
a00ce5fe | 16202 | (set_attr "mode" "<MODE>")]) |
21efb4d4 HJ |
16203 | |
16204 | (define_insn "*popcountsi2_cmp_zext" | |
16205 | [(set (reg FLAGS_REG) | |
16206 | (compare | |
16207 | (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) | |
16208 | (const_int 0))) | |
16209 | (set (match_operand:DI 0 "register_operand" "=r") | |
16210 | (zero_extend:DI(popcount:SI (match_dup 1))))] | |
16211 | "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" | |
a00ce5fe UB |
16212 | { |
16213 | #if TARGET_MACHO | |
16214 | return "popcnt\t{%1, %0|%0, %1}"; | |
16215 | #else | |
16216 | return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; | |
16217 | #endif | |
16218 | } | |
21efb4d4 HJ |
16219 | [(set_attr "prefix_rep" "1") |
16220 | (set_attr "type" "bitmanip") | |
16221 | (set_attr "mode" "SI")]) | |
d413e3cc | 16222 | |
2e6834d3 RH |
16223 | (define_expand "bswapsi2" |
16224 | [(set (match_operand:SI 0 "register_operand" "") | |
16225 | (bswap:SI (match_operand:SI 1 "register_operand" "")))] | |
16226 | "" | |
16227 | { | |
cabf85c3 | 16228 | if (!(TARGET_BSWAP || TARGET_MOVBE)) |
2e6834d3 RH |
16229 | { |
16230 | rtx x = operands[0]; | |
16231 | ||
16232 | emit_move_insn (x, operands[1]); | |
16233 | emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); | |
16234 | emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); | |
16235 | emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); | |
16236 | DONE; | |
16237 | } | |
16238 | }) | |
16239 | ||
cabf85c3 L |
16240 | (define_insn "*bswapsi_movbe" |
16241 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m") | |
16242 | (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))] | |
16243 | "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
16244 | "@ | |
16245 | bswap\t%0 | |
16246 | movbe\t{%1, %0|%0, %1} | |
16247 | movbe\t{%1, %0|%0, %1}" | |
16248 | [(set_attr "type" "*,imov,imov") | |
16249 | (set_attr "modrm" "*,1,1") | |
16250 | (set_attr "prefix_0f" "1") | |
16251 | (set_attr "prefix_extra" "*,1,1") | |
16252 | (set_attr "length" "2,*,*") | |
16253 | (set_attr "mode" "SI")]) | |
16254 | ||
2e6834d3 | 16255 | (define_insn "*bswapsi_1" |
6300f037 | 16256 | [(set (match_operand:SI 0 "register_operand" "=r") |
2e6834d3 | 16257 | (bswap:SI (match_operand:SI 1 "register_operand" "0")))] |
6300f037 | 16258 | "TARGET_BSWAP" |
2e6834d3 | 16259 | "bswap\t%0" |
6300f037 EC |
16260 | [(set_attr "prefix_0f" "1") |
16261 | (set_attr "length" "2")]) | |
16262 | ||
fa681e39 UB |
16263 | (define_insn "*bswaphi_lowpart_1" |
16264 | [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) | |
16265 | (bswap:HI (match_dup 0))) | |
16266 | (clobber (reg:CC FLAGS_REG))] | |
3debdc1e | 16267 | "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)" |
fa681e39 UB |
16268 | "@ |
16269 | xchg{b}\t{%h0, %b0|%b0, %h0} | |
16270 | rol{w}\t{$8, %0|%0, 8}" | |
16271 | [(set_attr "length" "2,4") | |
16272 | (set_attr "mode" "QI,HI")]) | |
16273 | ||
2e6834d3 | 16274 | (define_insn "bswaphi_lowpart" |
fa681e39 UB |
16275 | [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) |
16276 | (bswap:HI (match_dup 0))) | |
16277 | (clobber (reg:CC FLAGS_REG))] | |
2e6834d3 | 16278 | "" |
fa681e39 UB |
16279 | "rol{w}\t{$8, %0|%0, 8}" |
16280 | [(set_attr "length" "4") | |
16281 | (set_attr "mode" "HI")]) | |
2e6834d3 | 16282 | |
cabf85c3 L |
16283 | (define_expand "bswapdi2" |
16284 | [(set (match_operand:DI 0 "register_operand" "") | |
16285 | (bswap:DI (match_operand:DI 1 "register_operand" "")))] | |
16286 | "TARGET_64BIT" | |
16287 | "") | |
16288 | ||
16289 | (define_insn "*bswapdi_movbe" | |
16290 | [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m") | |
16291 | (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))] | |
16292 | "TARGET_64BIT && TARGET_MOVBE | |
16293 | && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
16294 | "@ | |
16295 | bswap\t%0 | |
16296 | movbe\t{%1, %0|%0, %1} | |
16297 | movbe\t{%1, %0|%0, %1}" | |
16298 | [(set_attr "type" "*,imov,imov") | |
16299 | (set_attr "modrm" "*,1,1") | |
16300 | (set_attr "prefix_0f" "1") | |
16301 | (set_attr "prefix_extra" "*,1,1") | |
16302 | (set_attr "length" "3,*,*") | |
16303 | (set_attr "mode" "DI")]) | |
16304 | ||
16305 | (define_insn "*bswapdi_1" | |
6300f037 | 16306 | [(set (match_operand:DI 0 "register_operand" "=r") |
2e6834d3 RH |
16307 | (bswap:DI (match_operand:DI 1 "register_operand" "0")))] |
16308 | "TARGET_64BIT" | |
6300f037 EC |
16309 | "bswap\t%0" |
16310 | [(set_attr "prefix_0f" "1") | |
16311 | (set_attr "length" "3")]) | |
16312 | ||
d413e3cc JJ |
16313 | (define_expand "clzdi2" |
16314 | [(parallel | |
16315 | [(set (match_operand:DI 0 "register_operand" "") | |
16316 | (minus:DI (const_int 63) | |
16317 | (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))) | |
42fabf21 | 16318 | (clobber (reg:CC FLAGS_REG))]) |
d413e3cc JJ |
16319 | (parallel |
16320 | [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63))) | |
42fabf21 | 16321 | (clobber (reg:CC FLAGS_REG))])] |
d413e3cc | 16322 | "TARGET_64BIT" |
21efb4d4 HJ |
16323 | { |
16324 | if (TARGET_ABM) | |
16325 | { | |
16326 | emit_insn (gen_clzdi2_abm (operands[0], operands[1])); | |
16327 | DONE; | |
16328 | } | |
16329 | }) | |
16330 | ||
16331 | (define_insn "clzdi2_abm" | |
16332 | [(set (match_operand:DI 0 "register_operand" "=r") | |
a3d4a22b | 16333 | (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) |
21efb4d4 HJ |
16334 | (clobber (reg:CC FLAGS_REG))] |
16335 | "TARGET_64BIT && TARGET_ABM" | |
16336 | "lzcnt{q}\t{%1, %0|%0, %1}" | |
16337 | [(set_attr "prefix_rep" "1") | |
16338 | (set_attr "type" "bitmanip") | |
16339 | (set_attr "mode" "DI")]) | |
d413e3cc JJ |
16340 | |
16341 | (define_insn "*bsr_rex64" | |
16342 | [(set (match_operand:DI 0 "register_operand" "=r") | |
16343 | (minus:DI (const_int 63) | |
16344 | (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) | |
42fabf21 | 16345 | (clobber (reg:CC FLAGS_REG))] |
d413e3cc JJ |
16346 | "TARGET_64BIT" |
16347 | "bsr{q}\t{%1, %0|%0, %1}" | |
725fd454 JJ |
16348 | [(set_attr "type" "alu1") |
16349 | (set_attr "prefix_0f" "1") | |
21efb4d4 HJ |
16350 | (set_attr "mode" "DI")]) |
16351 | ||
21efb4d4 HJ |
16352 | (define_expand "clzhi2" |
16353 | [(parallel | |
16354 | [(set (match_operand:HI 0 "register_operand" "") | |
16355 | (minus:HI (const_int 15) | |
16356 | (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))) | |
16357 | (clobber (reg:CC FLAGS_REG))]) | |
16358 | (parallel | |
16359 | [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15))) | |
16360 | (clobber (reg:CC FLAGS_REG))])] | |
16361 | "" | |
16362 | { | |
16363 | if (TARGET_ABM) | |
16364 | { | |
16365 | emit_insn (gen_clzhi2_abm (operands[0], operands[1])); | |
16366 | DONE; | |
16367 | } | |
16368 | }) | |
16369 | ||
16370 | (define_insn "clzhi2_abm" | |
16371 | [(set (match_operand:HI 0 "register_operand" "=r") | |
a3d4a22b | 16372 | (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))) |
21efb4d4 HJ |
16373 | (clobber (reg:CC FLAGS_REG))] |
16374 | "TARGET_ABM" | |
16375 | "lzcnt{w}\t{%1, %0|%0, %1}" | |
16376 | [(set_attr "prefix_rep" "1") | |
16377 | (set_attr "type" "bitmanip") | |
16378 | (set_attr "mode" "HI")]) | |
16379 | ||
16380 | (define_insn "*bsrhi" | |
16381 | [(set (match_operand:HI 0 "register_operand" "=r") | |
16382 | (minus:HI (const_int 15) | |
16383 | (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) | |
16384 | (clobber (reg:CC FLAGS_REG))] | |
16385 | "" | |
16386 | "bsr{w}\t{%1, %0|%0, %1}" | |
725fd454 JJ |
16387 | [(set_attr "type" "alu1") |
16388 | (set_attr "prefix_0f" "1") | |
21efb4d4 HJ |
16389 | (set_attr "mode" "HI")]) |
16390 | ||
0f7b6776 UB |
16391 | (define_expand "paritydi2" |
16392 | [(set (match_operand:DI 0 "register_operand" "") | |
40cca4f9 | 16393 | (parity:DI (match_operand:DI 1 "register_operand" "")))] |
0f7b6776 UB |
16394 | "! TARGET_POPCNT" |
16395 | { | |
16396 | rtx scratch = gen_reg_rtx (QImode); | |
16397 | rtx cond; | |
16398 | ||
16399 | emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, | |
16400 | NULL_RTX, operands[1])); | |
16401 | ||
16402 | cond = gen_rtx_fmt_ee (ORDERED, QImode, | |
16403 | gen_rtx_REG (CCmode, FLAGS_REG), | |
16404 | const0_rtx); | |
16405 | emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); | |
16406 | ||
16407 | if (TARGET_64BIT) | |
16408 | emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); | |
16409 | else | |
16410 | { | |
16411 | rtx tmp = gen_reg_rtx (SImode); | |
16412 | ||
16413 | emit_insn (gen_zero_extendqisi2 (tmp, scratch)); | |
16414 | emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); | |
16415 | } | |
16416 | DONE; | |
16417 | }) | |
16418 | ||
16419 | (define_insn_and_split "paritydi2_cmp" | |
16420 | [(set (reg:CC FLAGS_REG) | |
40cca4f9 UB |
16421 | (parity:CC (match_operand:DI 3 "register_operand" "0"))) |
16422 | (clobber (match_scratch:DI 0 "=r")) | |
16423 | (clobber (match_scratch:SI 1 "=&r")) | |
16424 | (clobber (match_scratch:HI 2 "=Q"))] | |
0f7b6776 UB |
16425 | "! TARGET_POPCNT" |
16426 | "#" | |
16427 | "&& reload_completed" | |
16428 | [(parallel | |
16429 | [(set (match_dup 1) | |
16430 | (xor:SI (match_dup 1) (match_dup 4))) | |
16431 | (clobber (reg:CC FLAGS_REG))]) | |
16432 | (parallel | |
16433 | [(set (reg:CC FLAGS_REG) | |
16434 | (parity:CC (match_dup 1))) | |
16435 | (clobber (match_dup 1)) | |
16436 | (clobber (match_dup 2))])] | |
16437 | { | |
16438 | operands[4] = gen_lowpart (SImode, operands[3]); | |
16439 | ||
40cca4f9 | 16440 | if (TARGET_64BIT) |
0f7b6776 UB |
16441 | { |
16442 | emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); | |
16443 | emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); | |
16444 | } | |
40cca4f9 UB |
16445 | else |
16446 | operands[1] = gen_highpart (SImode, operands[3]); | |
0f7b6776 UB |
16447 | }) |
16448 | ||
16449 | (define_expand "paritysi2" | |
16450 | [(set (match_operand:SI 0 "register_operand" "") | |
40cca4f9 | 16451 | (parity:SI (match_operand:SI 1 "register_operand" "")))] |
0f7b6776 UB |
16452 | "! TARGET_POPCNT" |
16453 | { | |
16454 | rtx scratch = gen_reg_rtx (QImode); | |
16455 | rtx cond; | |
16456 | ||
16457 | emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); | |
16458 | ||
16459 | cond = gen_rtx_fmt_ee (ORDERED, QImode, | |
16460 | gen_rtx_REG (CCmode, FLAGS_REG), | |
16461 | const0_rtx); | |
16462 | emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); | |
16463 | ||
16464 | emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); | |
16465 | DONE; | |
16466 | }) | |
16467 | ||
16468 | (define_insn_and_split "paritysi2_cmp" | |
16469 | [(set (reg:CC FLAGS_REG) | |
40cca4f9 UB |
16470 | (parity:CC (match_operand:SI 2 "register_operand" "0"))) |
16471 | (clobber (match_scratch:SI 0 "=r")) | |
16472 | (clobber (match_scratch:HI 1 "=&Q"))] | |
0f7b6776 UB |
16473 | "! TARGET_POPCNT" |
16474 | "#" | |
16475 | "&& reload_completed" | |
16476 | [(parallel | |
16477 | [(set (match_dup 1) | |
16478 | (xor:HI (match_dup 1) (match_dup 3))) | |
16479 | (clobber (reg:CC FLAGS_REG))]) | |
16480 | (parallel | |
16481 | [(set (reg:CC FLAGS_REG) | |
16482 | (parity:CC (match_dup 1))) | |
16483 | (clobber (match_dup 1))])] | |
16484 | { | |
16485 | operands[3] = gen_lowpart (HImode, operands[2]); | |
16486 | ||
40cca4f9 UB |
16487 | emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); |
16488 | emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); | |
0f7b6776 UB |
16489 | }) |
16490 | ||
16491 | (define_insn "*parityhi2_cmp" | |
16492 | [(set (reg:CC FLAGS_REG) | |
16493 | (parity:CC (match_operand:HI 1 "register_operand" "0"))) | |
16494 | (clobber (match_scratch:HI 0 "=Q"))] | |
16495 | "! TARGET_POPCNT" | |
16496 | "xor{b}\t{%h0, %b0|%b0, %h0}" | |
16497 | [(set_attr "length" "2") | |
16498 | (set_attr "mode" "HI")]) | |
16499 | ||
16500 | (define_insn "*parityqi2_cmp" | |
16501 | [(set (reg:CC FLAGS_REG) | |
16502 | (parity:CC (match_operand:QI 0 "register_operand" "q")))] | |
16503 | "! TARGET_POPCNT" | |
16504 | "test{b}\t%0, %0" | |
16505 | [(set_attr "length" "2") | |
16506 | (set_attr "mode" "QI")]) | |
e075ae69 | 16507 | \f |
f996902d RH |
16508 | ;; Thread-local storage patterns for ELF. |
16509 | ;; | |
16510 | ;; Note that these code sequences must appear exactly as shown | |
16511 | ;; in order to allow linker relaxation. | |
16512 | ||
75d38379 | 16513 | (define_insn "*tls_global_dynamic_32_gnu" |
f996902d RH |
16514 | [(set (match_operand:SI 0 "register_operand" "=a") |
16515 | (unspec:SI [(match_operand:SI 1 "register_operand" "b") | |
16516 | (match_operand:SI 2 "tls_symbolic_operand" "") | |
16517 | (match_operand:SI 3 "call_insn_operand" "")] | |
16518 | UNSPEC_TLS_GD)) | |
16519 | (clobber (match_scratch:SI 4 "=d")) | |
16520 | (clobber (match_scratch:SI 5 "=c")) | |
8bc527af | 16521 | (clobber (reg:CC FLAGS_REG))] |
75d38379 | 16522 | "!TARGET_64BIT && TARGET_GNU_TLS" |
f996902d RH |
16523 | "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3" |
16524 | [(set_attr "type" "multi") | |
16525 | (set_attr "length" "12")]) | |
16526 | ||
75d38379 | 16527 | (define_insn "*tls_global_dynamic_32_sun" |
f996902d RH |
16528 | [(set (match_operand:SI 0 "register_operand" "=a") |
16529 | (unspec:SI [(match_operand:SI 1 "register_operand" "b") | |
16530 | (match_operand:SI 2 "tls_symbolic_operand" "") | |
16531 | (match_operand:SI 3 "call_insn_operand" "")] | |
16532 | UNSPEC_TLS_GD)) | |
16533 | (clobber (match_scratch:SI 4 "=d")) | |
16534 | (clobber (match_scratch:SI 5 "=c")) | |
8bc527af | 16535 | (clobber (reg:CC FLAGS_REG))] |
75d38379 | 16536 | "!TARGET_64BIT && TARGET_SUN_TLS" |
f996902d RH |
16537 | "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]} |
16538 | push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop" | |
16539 | [(set_attr "type" "multi") | |
16540 | (set_attr "length" "14")]) | |
16541 | ||
75d38379 | 16542 | (define_expand "tls_global_dynamic_32" |
f996902d RH |
16543 | [(parallel [(set (match_operand:SI 0 "register_operand" "") |
16544 | (unspec:SI | |
16545 | [(match_dup 2) | |
16546 | (match_operand:SI 1 "tls_symbolic_operand" "") | |
16547 | (match_dup 3)] | |
16548 | UNSPEC_TLS_GD)) | |
16549 | (clobber (match_scratch:SI 4 "")) | |
16550 | (clobber (match_scratch:SI 5 "")) | |
8bc527af | 16551 | (clobber (reg:CC FLAGS_REG))])] |
f996902d RH |
16552 | "" |
16553 | { | |
dce81a1a JJ |
16554 | if (flag_pic) |
16555 | operands[2] = pic_offset_table_rtx; | |
16556 | else | |
16557 | { | |
16558 | operands[2] = gen_reg_rtx (Pmode); | |
16559 | emit_insn (gen_set_got (operands[2])); | |
16560 | } | |
5bf5a10b AO |
16561 | if (TARGET_GNU2_TLS) |
16562 | { | |
16563 | emit_insn (gen_tls_dynamic_gnu2_32 | |
16564 | (operands[0], operands[1], operands[2])); | |
16565 | DONE; | |
16566 | } | |
f996902d RH |
16567 | operands[3] = ix86_tls_get_addr (); |
16568 | }) | |
16569 | ||
75d38379 JJ |
16570 | (define_insn "*tls_global_dynamic_64" |
16571 | [(set (match_operand:DI 0 "register_operand" "=a") | |
e347ff9e AO |
16572 | (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" "")) |
16573 | (match_operand:DI 3 "" ""))) | |
75d38379 JJ |
16574 | (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] |
16575 | UNSPEC_TLS_GD)] | |
16576 | "TARGET_64BIT" | |
9ad5e54f | 16577 | ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2" |
75d38379 JJ |
16578 | [(set_attr "type" "multi") |
16579 | (set_attr "length" "16")]) | |
16580 | ||
16581 | (define_expand "tls_global_dynamic_64" | |
16582 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
e347ff9e | 16583 | (call:DI (mem:QI (match_dup 2)) (const_int 0))) |
75d38379 JJ |
16584 | (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] |
16585 | UNSPEC_TLS_GD)])] | |
16586 | "" | |
16587 | { | |
5bf5a10b AO |
16588 | if (TARGET_GNU2_TLS) |
16589 | { | |
16590 | emit_insn (gen_tls_dynamic_gnu2_64 | |
16591 | (operands[0], operands[1])); | |
16592 | DONE; | |
16593 | } | |
75d38379 JJ |
16594 | operands[2] = ix86_tls_get_addr (); |
16595 | }) | |
16596 | ||
16597 | (define_insn "*tls_local_dynamic_base_32_gnu" | |
f996902d RH |
16598 | [(set (match_operand:SI 0 "register_operand" "=a") |
16599 | (unspec:SI [(match_operand:SI 1 "register_operand" "b") | |
16600 | (match_operand:SI 2 "call_insn_operand" "")] | |
16601 | UNSPEC_TLS_LD_BASE)) | |
16602 | (clobber (match_scratch:SI 3 "=d")) | |
16603 | (clobber (match_scratch:SI 4 "=c")) | |
8bc527af | 16604 | (clobber (reg:CC FLAGS_REG))] |
75d38379 | 16605 | "!TARGET_64BIT && TARGET_GNU_TLS" |
f996902d RH |
16606 | "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2" |
16607 | [(set_attr "type" "multi") | |
16608 | (set_attr "length" "11")]) | |
16609 | ||
75d38379 | 16610 | (define_insn "*tls_local_dynamic_base_32_sun" |
f996902d RH |
16611 | [(set (match_operand:SI 0 "register_operand" "=a") |
16612 | (unspec:SI [(match_operand:SI 1 "register_operand" "b") | |
16613 | (match_operand:SI 2 "call_insn_operand" "")] | |
16614 | UNSPEC_TLS_LD_BASE)) | |
16615 | (clobber (match_scratch:SI 3 "=d")) | |
16616 | (clobber (match_scratch:SI 4 "=c")) | |
8bc527af | 16617 | (clobber (reg:CC FLAGS_REG))] |
75d38379 | 16618 | "!TARGET_64BIT && TARGET_SUN_TLS" |
f996902d RH |
16619 | "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]} |
16620 | push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3" | |
16621 | [(set_attr "type" "multi") | |
16622 | (set_attr "length" "13")]) | |
16623 | ||
75d38379 | 16624 | (define_expand "tls_local_dynamic_base_32" |
f996902d RH |
16625 | [(parallel [(set (match_operand:SI 0 "register_operand" "") |
16626 | (unspec:SI [(match_dup 1) (match_dup 2)] | |
16627 | UNSPEC_TLS_LD_BASE)) | |
16628 | (clobber (match_scratch:SI 3 "")) | |
16629 | (clobber (match_scratch:SI 4 "")) | |
8bc527af | 16630 | (clobber (reg:CC FLAGS_REG))])] |
f996902d RH |
16631 | "" |
16632 | { | |
dce81a1a | 16633 | if (flag_pic) |
9785f1d9 | 16634 | operands[1] = pic_offset_table_rtx; |
dce81a1a JJ |
16635 | else |
16636 | { | |
9785f1d9 JJ |
16637 | operands[1] = gen_reg_rtx (Pmode); |
16638 | emit_insn (gen_set_got (operands[1])); | |
dce81a1a | 16639 | } |
5bf5a10b AO |
16640 | if (TARGET_GNU2_TLS) |
16641 | { | |
16642 | emit_insn (gen_tls_dynamic_gnu2_32 | |
16643 | (operands[0], ix86_tls_module_base (), operands[1])); | |
16644 | DONE; | |
16645 | } | |
f996902d RH |
16646 | operands[2] = ix86_tls_get_addr (); |
16647 | }) | |
16648 | ||
75d38379 JJ |
16649 | (define_insn "*tls_local_dynamic_base_64" |
16650 | [(set (match_operand:DI 0 "register_operand" "=a") | |
e347ff9e AO |
16651 | (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" "")) |
16652 | (match_operand:DI 2 "" ""))) | |
75d38379 JJ |
16653 | (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] |
16654 | "TARGET_64BIT" | |
9ad5e54f | 16655 | "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1" |
75d38379 JJ |
16656 | [(set_attr "type" "multi") |
16657 | (set_attr "length" "12")]) | |
16658 | ||
16659 | (define_expand "tls_local_dynamic_base_64" | |
16660 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
e347ff9e | 16661 | (call:DI (mem:QI (match_dup 1)) (const_int 0))) |
75d38379 JJ |
16662 | (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])] |
16663 | "" | |
16664 | { | |
5bf5a10b AO |
16665 | if (TARGET_GNU2_TLS) |
16666 | { | |
16667 | emit_insn (gen_tls_dynamic_gnu2_64 | |
16668 | (operands[0], ix86_tls_module_base ())); | |
16669 | DONE; | |
16670 | } | |
75d38379 JJ |
16671 | operands[1] = ix86_tls_get_addr (); |
16672 | }) | |
16673 | ||
f996902d RH |
16674 | ;; Local dynamic of a single variable is a lose. Show combine how |
16675 | ;; to convert that back to global dynamic. | |
16676 | ||
75d38379 | 16677 | (define_insn_and_split "*tls_local_dynamic_32_once" |
f996902d RH |
16678 | [(set (match_operand:SI 0 "register_operand" "=a") |
16679 | (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b") | |
16680 | (match_operand:SI 2 "call_insn_operand" "")] | |
16681 | UNSPEC_TLS_LD_BASE) | |
16682 | (const:SI (unspec:SI | |
16683 | [(match_operand:SI 3 "tls_symbolic_operand" "")] | |
16684 | UNSPEC_DTPOFF)))) | |
16685 | (clobber (match_scratch:SI 4 "=d")) | |
16686 | (clobber (match_scratch:SI 5 "=c")) | |
8bc527af | 16687 | (clobber (reg:CC FLAGS_REG))] |
f996902d RH |
16688 | "" |
16689 | "#" | |
16690 | "" | |
16691 | [(parallel [(set (match_dup 0) | |
16692 | (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] | |
16693 | UNSPEC_TLS_GD)) | |
16694 | (clobber (match_dup 4)) | |
16695 | (clobber (match_dup 5)) | |
8bc527af | 16696 | (clobber (reg:CC FLAGS_REG))])] |
f996902d | 16697 | "") |
74dc3e94 RH |
16698 | |
16699 | ;; Load and add the thread base pointer from %gs:0. | |
16700 | ||
16701 | (define_insn "*load_tp_si" | |
16702 | [(set (match_operand:SI 0 "register_operand" "=r") | |
16703 | (unspec:SI [(const_int 0)] UNSPEC_TP))] | |
16704 | "!TARGET_64BIT" | |
9ad5e54f | 16705 | "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}" |
74dc3e94 RH |
16706 | [(set_attr "type" "imov") |
16707 | (set_attr "modrm" "0") | |
16708 | (set_attr "length" "7") | |
16709 | (set_attr "memory" "load") | |
16710 | (set_attr "imm_disp" "false")]) | |
16711 | ||
16712 | (define_insn "*add_tp_si" | |
16713 | [(set (match_operand:SI 0 "register_operand" "=r") | |
16714 | (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) | |
16715 | (match_operand:SI 1 "register_operand" "0"))) | |
8bc527af | 16716 | (clobber (reg:CC FLAGS_REG))] |
74dc3e94 | 16717 | "!TARGET_64BIT" |
9ad5e54f | 16718 | "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}" |
74dc3e94 RH |
16719 | [(set_attr "type" "alu") |
16720 | (set_attr "modrm" "0") | |
16721 | (set_attr "length" "7") | |
16722 | (set_attr "memory" "load") | |
16723 | (set_attr "imm_disp" "false")]) | |
16724 | ||
16725 | (define_insn "*load_tp_di" | |
16726 | [(set (match_operand:DI 0 "register_operand" "=r") | |
16727 | (unspec:DI [(const_int 0)] UNSPEC_TP))] | |
16728 | "TARGET_64BIT" | |
9ad5e54f | 16729 | "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}" |
74dc3e94 RH |
16730 | [(set_attr "type" "imov") |
16731 | (set_attr "modrm" "0") | |
16732 | (set_attr "length" "7") | |
16733 | (set_attr "memory" "load") | |
16734 | (set_attr "imm_disp" "false")]) | |
16735 | ||
16736 | (define_insn "*add_tp_di" | |
16737 | [(set (match_operand:DI 0 "register_operand" "=r") | |
16738 | (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP) | |
16739 | (match_operand:DI 1 "register_operand" "0"))) | |
8bc527af | 16740 | (clobber (reg:CC FLAGS_REG))] |
74dc3e94 | 16741 | "TARGET_64BIT" |
9ad5e54f | 16742 | "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}" |
74dc3e94 RH |
16743 | [(set_attr "type" "alu") |
16744 | (set_attr "modrm" "0") | |
16745 | (set_attr "length" "7") | |
16746 | (set_attr "memory" "load") | |
16747 | (set_attr "imm_disp" "false")]) | |
5bf5a10b AO |
16748 | |
16749 | ;; GNU2 TLS patterns can be split. | |
16750 | ||
16751 | (define_expand "tls_dynamic_gnu2_32" | |
16752 | [(set (match_dup 3) | |
16753 | (plus:SI (match_operand:SI 2 "register_operand" "") | |
16754 | (const:SI | |
16755 | (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] | |
16756 | UNSPEC_TLSDESC)))) | |
16757 | (parallel | |
16758 | [(set (match_operand:SI 0 "register_operand" "") | |
16759 | (unspec:SI [(match_dup 1) (match_dup 3) | |
16760 | (match_dup 2) (reg:SI SP_REG)] | |
16761 | UNSPEC_TLSDESC)) | |
16762 | (clobber (reg:CC FLAGS_REG))])] | |
16763 | "!TARGET_64BIT && TARGET_GNU2_TLS" | |
16764 | { | |
b3a13419 | 16765 | operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode); |
5bf5a10b AO |
16766 | ix86_tls_descriptor_calls_expanded_in_cfun = true; |
16767 | }) | |
16768 | ||
16769 | (define_insn "*tls_dynamic_lea_32" | |
16770 | [(set (match_operand:SI 0 "register_operand" "=r") | |
16771 | (plus:SI (match_operand:SI 1 "register_operand" "b") | |
16772 | (const:SI | |
16773 | (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] | |
16774 | UNSPEC_TLSDESC))))] | |
16775 | "!TARGET_64BIT && TARGET_GNU2_TLS" | |
16776 | "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}" | |
16777 | [(set_attr "type" "lea") | |
16778 | (set_attr "mode" "SI") | |
16779 | (set_attr "length" "6") | |
16780 | (set_attr "length_address" "4")]) | |
16781 | ||
16782 | (define_insn "*tls_dynamic_call_32" | |
16783 | [(set (match_operand:SI 0 "register_operand" "=a") | |
16784 | (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") | |
16785 | (match_operand:SI 2 "register_operand" "0") | |
16786 | ;; we have to make sure %ebx still points to the GOT | |
16787 | (match_operand:SI 3 "register_operand" "b") | |
16788 | (reg:SI SP_REG)] | |
16789 | UNSPEC_TLSDESC)) | |
16790 | (clobber (reg:CC FLAGS_REG))] | |
16791 | "!TARGET_64BIT && TARGET_GNU2_TLS" | |
16792 | "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" | |
16793 | [(set_attr "type" "call") | |
16794 | (set_attr "length" "2") | |
16795 | (set_attr "length_address" "0")]) | |
16796 | ||
16797 | (define_insn_and_split "*tls_dynamic_gnu2_combine_32" | |
16798 | [(set (match_operand:SI 0 "register_operand" "=&a") | |
16799 | (plus:SI | |
31ebc801 AO |
16800 | (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "") |
16801 | (match_operand:SI 4 "" "") | |
16802 | (match_operand:SI 2 "register_operand" "b") | |
16803 | (reg:SI SP_REG)] | |
16804 | UNSPEC_TLSDESC) | |
5bf5a10b AO |
16805 | (const:SI (unspec:SI |
16806 | [(match_operand:SI 1 "tls_symbolic_operand" "")] | |
16807 | UNSPEC_DTPOFF)))) | |
16808 | (clobber (reg:CC FLAGS_REG))] | |
16809 | "!TARGET_64BIT && TARGET_GNU2_TLS" | |
16810 | "#" | |
16811 | "" | |
31ebc801 | 16812 | [(set (match_dup 0) (match_dup 5))] |
5bf5a10b | 16813 | { |
b3a13419 | 16814 | operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode); |
5bf5a10b AO |
16815 | emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); |
16816 | }) | |
16817 | ||
16818 | (define_expand "tls_dynamic_gnu2_64" | |
16819 | [(set (match_dup 2) | |
16820 | (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] | |
16821 | UNSPEC_TLSDESC)) | |
16822 | (parallel | |
16823 | [(set (match_operand:DI 0 "register_operand" "") | |
16824 | (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] | |
16825 | UNSPEC_TLSDESC)) | |
16826 | (clobber (reg:CC FLAGS_REG))])] | |
16827 | "TARGET_64BIT && TARGET_GNU2_TLS" | |
16828 | { | |
b3a13419 | 16829 | operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode); |
5bf5a10b AO |
16830 | ix86_tls_descriptor_calls_expanded_in_cfun = true; |
16831 | }) | |
16832 | ||
16833 | (define_insn "*tls_dynamic_lea_64" | |
16834 | [(set (match_operand:DI 0 "register_operand" "=r") | |
16835 | (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] | |
16836 | UNSPEC_TLSDESC))] | |
16837 | "TARGET_64BIT && TARGET_GNU2_TLS" | |
9ad5e54f | 16838 | "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}" |
5bf5a10b AO |
16839 | [(set_attr "type" "lea") |
16840 | (set_attr "mode" "DI") | |
16841 | (set_attr "length" "7") | |
16842 | (set_attr "length_address" "4")]) | |
16843 | ||
16844 | (define_insn "*tls_dynamic_call_64" | |
16845 | [(set (match_operand:DI 0 "register_operand" "=a") | |
16846 | (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "") | |
16847 | (match_operand:DI 2 "register_operand" "0") | |
16848 | (reg:DI SP_REG)] | |
16849 | UNSPEC_TLSDESC)) | |
16850 | (clobber (reg:CC FLAGS_REG))] | |
16851 | "TARGET_64BIT && TARGET_GNU2_TLS" | |
16852 | "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" | |
16853 | [(set_attr "type" "call") | |
16854 | (set_attr "length" "2") | |
16855 | (set_attr "length_address" "0")]) | |
16856 | ||
16857 | (define_insn_and_split "*tls_dynamic_gnu2_combine_64" | |
16858 | [(set (match_operand:DI 0 "register_operand" "=&a") | |
16859 | (plus:DI | |
31ebc801 AO |
16860 | (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "") |
16861 | (match_operand:DI 3 "" "") | |
16862 | (reg:DI SP_REG)] | |
16863 | UNSPEC_TLSDESC) | |
5bf5a10b AO |
16864 | (const:DI (unspec:DI |
16865 | [(match_operand:DI 1 "tls_symbolic_operand" "")] | |
16866 | UNSPEC_DTPOFF)))) | |
16867 | (clobber (reg:CC FLAGS_REG))] | |
16868 | "TARGET_64BIT && TARGET_GNU2_TLS" | |
16869 | "#" | |
16870 | "" | |
31ebc801 | 16871 | [(set (match_dup 0) (match_dup 4))] |
5bf5a10b | 16872 | { |
b3a13419 | 16873 | operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode); |
5bf5a10b AO |
16874 | emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); |
16875 | }) | |
16876 | ||
16877 | ;; | |
f996902d | 16878 | \f |
e075ae69 RH |
16879 | ;; These patterns match the binary 387 instructions for addM3, subM3, |
16880 | ;; mulM3 and divM3. There are three patterns for each of DFmode and | |
16881 | ;; SFmode. The first is the normal insn, the second the same insn but | |
16882 | ;; with one operand a conversion, and the third the same insn but with | |
16883 | ;; the other operand a conversion. The conversion may be SFmode or | |
16884 | ;; SImode if the target mode DFmode, but only SImode if the target mode | |
16885 | ;; is SFmode. | |
16886 | ||
caa6ec8d JH |
16887 | ;; Gcc is slightly more smart about handling normal two address instructions |
16888 | ;; so use special patterns for add and mull. | |
965f5423 | 16889 | |
95879c72 L |
16890 | (define_insn "*fop_<mode>_comm_mixed_avx" |
16891 | [(set (match_operand:MODEF 0 "register_operand" "=f,x") | |
16892 | (match_operator:MODEF 3 "binary_fp_operator" | |
16893 | [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x") | |
16894 | (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))] | |
16895 | "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 | |
16896 | && COMMUTATIVE_ARITH_P (operands[3]) | |
16897 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" | |
16898 | "* return output_387_binary_op (insn, operands);" | |
16899 | [(set (attr "type") | |
16900 | (if_then_else (eq_attr "alternative" "1") | |
16901 | (if_then_else (match_operand:MODEF 3 "mult_operator" "") | |
16902 | (const_string "ssemul") | |
16903 | (const_string "sseadd")) | |
16904 | (if_then_else (match_operand:MODEF 3 "mult_operator" "") | |
16905 | (const_string "fmul") | |
16906 | (const_string "fop")))) | |
16907 | (set_attr "prefix" "orig,maybe_vex") | |
16908 | (set_attr "mode" "<MODE>")]) | |
16909 | ||
ca3a2165 UB |
16910 | (define_insn "*fop_<mode>_comm_mixed" |
16911 | [(set (match_operand:MODEF 0 "register_operand" "=f,x") | |
16912 | (match_operator:MODEF 3 "binary_fp_operator" | |
16913 | [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0") | |
16914 | (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))] | |
16915 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 | |
ec8e098d | 16916 | && COMMUTATIVE_ARITH_P (operands[3]) |
7656aee4 | 16917 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
caa6ec8d | 16918 | "* return output_387_binary_op (insn, operands);" |
6300f037 | 16919 | [(set (attr "type") |
1deaa899 | 16920 | (if_then_else (eq_attr "alternative" "1") |
ca3a2165 | 16921 | (if_then_else (match_operand:MODEF 3 "mult_operator" "") |
3d34cd91 JH |
16922 | (const_string "ssemul") |
16923 | (const_string "sseadd")) | |
ca3a2165 | 16924 | (if_then_else (match_operand:MODEF 3 "mult_operator" "") |
1deaa899 JH |
16925 | (const_string "fmul") |
16926 | (const_string "fop")))) | |
ca3a2165 | 16927 | (set_attr "mode" "<MODE>")]) |
1deaa899 | 16928 | |
95879c72 L |
16929 | (define_insn "*fop_<mode>_comm_avx" |
16930 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
16931 | (match_operator:MODEF 3 "binary_fp_operator" | |
16932 | [(match_operand:MODEF 1 "nonimmediate_operand" "%x") | |
16933 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))] | |
16934 | "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH | |
16935 | && COMMUTATIVE_ARITH_P (operands[3]) | |
16936 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" | |
16937 | "* return output_387_binary_op (insn, operands);" | |
16938 | [(set (attr "type") | |
16939 | (if_then_else (match_operand:MODEF 3 "mult_operator" "") | |
16940 | (const_string "ssemul") | |
16941 | (const_string "sseadd"))) | |
16942 | (set_attr "prefix" "vex") | |
16943 | (set_attr "mode" "<MODE>")]) | |
16944 | ||
ca3a2165 UB |
16945 | (define_insn "*fop_<mode>_comm_sse" |
16946 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
16947 | (match_operator:MODEF 3 "binary_fp_operator" | |
16948 | [(match_operand:MODEF 1 "nonimmediate_operand" "%0") | |
16949 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))] | |
16950 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH | |
cfa185b8 | 16951 | && COMMUTATIVE_ARITH_P (operands[3]) |
7656aee4 | 16952 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
1deaa899 | 16953 | "* return output_387_binary_op (insn, operands);" |
6300f037 | 16954 | [(set (attr "type") |
ca3a2165 | 16955 | (if_then_else (match_operand:MODEF 3 "mult_operator" "") |
3d34cd91 JH |
16956 | (const_string "ssemul") |
16957 | (const_string "sseadd"))) | |
ca3a2165 | 16958 | (set_attr "mode" "<MODE>")]) |
caa6ec8d | 16959 | |
ca3a2165 UB |
16960 | (define_insn "*fop_<mode>_comm_i387" |
16961 | [(set (match_operand:MODEF 0 "register_operand" "=f") | |
16962 | (match_operator:MODEF 3 "binary_fp_operator" | |
16963 | [(match_operand:MODEF 1 "nonimmediate_operand" "%0") | |
16964 | (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))] | |
8ce94e44 | 16965 | "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) |
ec8e098d | 16966 | && COMMUTATIVE_ARITH_P (operands[3]) |
7656aee4 | 16967 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
965f5423 | 16968 | "* return output_387_binary_op (insn, operands);" |
6300f037 | 16969 | [(set (attr "type") |
ca3a2165 | 16970 | (if_then_else (match_operand:MODEF 3 "mult_operator" "") |
965f5423 JH |
16971 | (const_string "fmul") |
16972 | (const_string "fop"))) | |
ca3a2165 | 16973 | (set_attr "mode" "<MODE>")]) |
965f5423 | 16974 | |
95879c72 L |
16975 | (define_insn "*fop_<mode>_1_mixed_avx" |
16976 | [(set (match_operand:MODEF 0 "register_operand" "=f,f,x") | |
16977 | (match_operator:MODEF 3 "binary_fp_operator" | |
16978 | [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x") | |
16979 | (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))] | |
16980 | "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 | |
16981 | && !COMMUTATIVE_ARITH_P (operands[3]) | |
16982 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" | |
16983 | "* return output_387_binary_op (insn, operands);" | |
16984 | [(set (attr "type") | |
16985 | (cond [(and (eq_attr "alternative" "2") | |
16986 | (match_operand:MODEF 3 "mult_operator" "")) | |
16987 | (const_string "ssemul") | |
16988 | (and (eq_attr "alternative" "2") | |
16989 | (match_operand:MODEF 3 "div_operator" "")) | |
16990 | (const_string "ssediv") | |
16991 | (eq_attr "alternative" "2") | |
16992 | (const_string "sseadd") | |
16993 | (match_operand:MODEF 3 "mult_operator" "") | |
16994 | (const_string "fmul") | |
16995 | (match_operand:MODEF 3 "div_operator" "") | |
16996 | (const_string "fdiv") | |
16997 | ] | |
16998 | (const_string "fop"))) | |
16999 | (set_attr "prefix" "orig,orig,maybe_vex") | |
17000 | (set_attr "mode" "<MODE>")]) | |
17001 | ||
ca3a2165 UB |
17002 | (define_insn "*fop_<mode>_1_mixed" |
17003 | [(set (match_operand:MODEF 0 "register_operand" "=f,f,x") | |
17004 | (match_operator:MODEF 3 "binary_fp_operator" | |
17005 | [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0") | |
17006 | (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))] | |
17007 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 | |
ec8e098d | 17008 | && !COMMUTATIVE_ARITH_P (operands[3]) |
7656aee4 | 17009 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
e075ae69 | 17010 | "* return output_387_binary_op (insn, operands);" |
6300f037 | 17011 | [(set (attr "type") |
3d34cd91 | 17012 | (cond [(and (eq_attr "alternative" "2") |
ca3a2165 | 17013 | (match_operand:MODEF 3 "mult_operator" "")) |
3d34cd91 JH |
17014 | (const_string "ssemul") |
17015 | (and (eq_attr "alternative" "2") | |
ca3a2165 | 17016 | (match_operand:MODEF 3 "div_operator" "")) |
3d34cd91 JH |
17017 | (const_string "ssediv") |
17018 | (eq_attr "alternative" "2") | |
17019 | (const_string "sseadd") | |
ca3a2165 | 17020 | (match_operand:MODEF 3 "mult_operator" "") |
e075ae69 | 17021 | (const_string "fmul") |
ca3a2165 | 17022 | (match_operand:MODEF 3 "div_operator" "") |
e075ae69 RH |
17023 | (const_string "fdiv") |
17024 | ] | |
6ef67412 | 17025 | (const_string "fop"))) |
ca3a2165 | 17026 | (set_attr "mode" "<MODE>")]) |
e075ae69 | 17027 | |
6b889d89 UB |
17028 | (define_insn "*rcpsf2_sse" |
17029 | [(set (match_operand:SF 0 "register_operand" "=x") | |
17030 | (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] | |
17031 | UNSPEC_RCP))] | |
17032 | "TARGET_SSE_MATH" | |
95879c72 | 17033 | "%vrcpss\t{%1, %d0|%d0, %1}" |
6b889d89 | 17034 | [(set_attr "type" "sse") |
b6837b94 | 17035 | (set_attr "atom_sse_attr" "rcp") |
95879c72 | 17036 | (set_attr "prefix" "maybe_vex") |
6b889d89 UB |
17037 | (set_attr "mode" "SF")]) |
17038 | ||
95879c72 L |
17039 | (define_insn "*fop_<mode>_1_avx" |
17040 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
17041 | (match_operator:MODEF 3 "binary_fp_operator" | |
17042 | [(match_operand:MODEF 1 "register_operand" "x") | |
17043 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))] | |
17044 | "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH | |
17045 | && !COMMUTATIVE_ARITH_P (operands[3])" | |
17046 | "* return output_387_binary_op (insn, operands);" | |
17047 | [(set (attr "type") | |
17048 | (cond [(match_operand:MODEF 3 "mult_operator" "") | |
17049 | (const_string "ssemul") | |
17050 | (match_operand:MODEF 3 "div_operator" "") | |
17051 | (const_string "ssediv") | |
17052 | ] | |
17053 | (const_string "sseadd"))) | |
17054 | (set_attr "prefix" "vex") | |
17055 | (set_attr "mode" "<MODE>")]) | |
17056 | ||
ca3a2165 UB |
17057 | (define_insn "*fop_<mode>_1_sse" |
17058 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
17059 | (match_operator:MODEF 3 "binary_fp_operator" | |
17060 | [(match_operand:MODEF 1 "register_operand" "0") | |
17061 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))] | |
17062 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH | |
ec8e098d | 17063 | && !COMMUTATIVE_ARITH_P (operands[3])" |
1deaa899 | 17064 | "* return output_387_binary_op (insn, operands);" |
6300f037 | 17065 | [(set (attr "type") |
ca3a2165 | 17066 | (cond [(match_operand:MODEF 3 "mult_operator" "") |
3d34cd91 | 17067 | (const_string "ssemul") |
ca3a2165 | 17068 | (match_operand:MODEF 3 "div_operator" "") |
3d34cd91 JH |
17069 | (const_string "ssediv") |
17070 | ] | |
17071 | (const_string "sseadd"))) | |
ca3a2165 | 17072 | (set_attr "mode" "<MODE>")]) |
1deaa899 | 17073 | |
9e4ae64b | 17074 | ;; This pattern is not fully shadowed by the pattern above. |
ca3a2165 UB |
17075 | (define_insn "*fop_<mode>_1_i387" |
17076 | [(set (match_operand:MODEF 0 "register_operand" "=f,f") | |
17077 | (match_operator:MODEF 3 "binary_fp_operator" | |
17078 | [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm") | |
17079 | (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))] | |
8ce94e44 JM |
17080 | "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) |
17081 | && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
cfa185b8 | 17082 | && !COMMUTATIVE_ARITH_P (operands[3]) |
7656aee4 | 17083 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
cfa185b8 | 17084 | "* return output_387_binary_op (insn, operands);" |
6300f037 | 17085 | [(set (attr "type") |
ca3a2165 | 17086 | (cond [(match_operand:MODEF 3 "mult_operator" "") |
cfa185b8 | 17087 | (const_string "fmul") |
ca3a2165 | 17088 | (match_operand:MODEF 3 "div_operator" "") |
cfa185b8 UB |
17089 | (const_string "fdiv") |
17090 | ] | |
17091 | (const_string "fop"))) | |
0e8c2b0d | 17092 | (set_attr "mode" "<MODE>")]) |
e075ae69 | 17093 | |
1deaa899 | 17094 | ;; ??? Add SSE splitters for these! |
ca3a2165 UB |
17095 | (define_insn "*fop_<MODEF:mode>_2_i387" |
17096 | [(set (match_operand:MODEF 0 "register_operand" "=f,f") | |
17097 | (match_operator:MODEF 3 "binary_fp_operator" | |
17098 | [(float:MODEF | |
17099 | (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) | |
17100 | (match_operand:MODEF 2 "register_operand" "0,0")]))] | |
8ce94e44 JM |
17101 | "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode) |
17102 | && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) | |
3debdc1e | 17103 | && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" |
e075ae69 | 17104 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
6300f037 | 17105 | [(set (attr "type") |
ca3a2165 | 17106 | (cond [(match_operand:MODEF 3 "mult_operator" "") |
e075ae69 | 17107 | (const_string "fmul") |
ca3a2165 | 17108 | (match_operand:MODEF 3 "div_operator" "") |
e075ae69 RH |
17109 | (const_string "fdiv") |
17110 | ] | |
17111 | (const_string "fop"))) | |
17112 | (set_attr "fp_int_src" "true") | |
ca3a2165 UB |
17113 | (set_attr "mode" "<X87MODEI12:MODE>")]) |
17114 | ||
17115 | (define_insn "*fop_<MODEF:mode>_3_i387" | |
17116 | [(set (match_operand:MODEF 0 "register_operand" "=f,f") | |
17117 | (match_operator:MODEF 3 "binary_fp_operator" | |
17118 | [(match_operand:MODEF 1 "register_operand" "0,0") | |
17119 | (float:MODEF | |
17120 | (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] | |
8ce94e44 JM |
17121 | "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode) |
17122 | && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) | |
3debdc1e | 17123 | && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" |
e075ae69 | 17124 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
6300f037 | 17125 | [(set (attr "type") |
ca3a2165 | 17126 | (cond [(match_operand:MODEF 3 "mult_operator" "") |
e075ae69 | 17127 | (const_string "fmul") |
ca3a2165 | 17128 | (match_operand:MODEF 3 "div_operator" "") |
e075ae69 RH |
17129 | (const_string "fdiv") |
17130 | ] | |
17131 | (const_string "fop"))) | |
17132 | (set_attr "fp_int_src" "true") | |
0e8c2b0d | 17133 | (set_attr "mode" "<MODE>")]) |
e075ae69 | 17134 | |
cfa185b8 | 17135 | (define_insn "*fop_df_4_i387" |
e075ae69 RH |
17136 | [(set (match_operand:DF 0 "register_operand" "=f,f") |
17137 | (match_operator:DF 3 "binary_fp_operator" | |
69002843 UB |
17138 | [(float_extend:DF |
17139 | (match_operand:SF 1 "nonimmediate_operand" "fm,0")) | |
e075ae69 | 17140 | (match_operand:DF 2 "register_operand" "0,f")]))] |
8ce94e44 JM |
17141 | "TARGET_80387 && X87_ENABLE_ARITH (DFmode) |
17142 | && !(TARGET_SSE2 && TARGET_SSE_MATH) | |
7656aee4 | 17143 | && !(MEM_P (operands[1]) && MEM_P (operands[2]))" |
e075ae69 | 17144 | "* return output_387_binary_op (insn, operands);" |
6300f037 EC |
17145 | [(set (attr "type") |
17146 | (cond [(match_operand:DF 3 "mult_operator" "") | |
e075ae69 | 17147 | (const_string "fmul") |
6300f037 | 17148 | (match_operand:DF 3 "div_operator" "") |
e075ae69 RH |
17149 | (const_string "fdiv") |
17150 | ] | |
6ef67412 JH |
17151 | (const_string "fop"))) |
17152 | (set_attr "mode" "SF")]) | |
e075ae69 | 17153 | |
cfa185b8 | 17154 | (define_insn "*fop_df_5_i387" |
e075ae69 RH |
17155 | [(set (match_operand:DF 0 "register_operand" "=f,f") |
17156 | (match_operator:DF 3 "binary_fp_operator" | |
17157 | [(match_operand:DF 1 "register_operand" "0,f") | |
17158 | (float_extend:DF | |
17159 | (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] | |
8ce94e44 JM |
17160 | "TARGET_80387 && X87_ENABLE_ARITH (DFmode) |
17161 | && !(TARGET_SSE2 && TARGET_SSE_MATH)" | |
e075ae69 | 17162 | "* return output_387_binary_op (insn, operands);" |
6300f037 EC |
17163 | [(set (attr "type") |
17164 | (cond [(match_operand:DF 3 "mult_operator" "") | |
e075ae69 | 17165 | (const_string "fmul") |
6300f037 | 17166 | (match_operand:DF 3 "div_operator" "") |
e075ae69 RH |
17167 | (const_string "fdiv") |
17168 | ] | |
6ef67412 JH |
17169 | (const_string "fop"))) |
17170 | (set_attr "mode" "SF")]) | |
e075ae69 | 17171 | |
cfa185b8 | 17172 | (define_insn "*fop_df_6_i387" |
4977bab6 ZW |
17173 | [(set (match_operand:DF 0 "register_operand" "=f,f") |
17174 | (match_operator:DF 3 "binary_fp_operator" | |
17175 | [(float_extend:DF | |
17176 | (match_operand:SF 1 "register_operand" "0,f")) | |
17177 | (float_extend:DF | |
17178 | (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] | |
8ce94e44 JM |
17179 | "TARGET_80387 && X87_ENABLE_ARITH (DFmode) |
17180 | && !(TARGET_SSE2 && TARGET_SSE_MATH)" | |
4977bab6 | 17181 | "* return output_387_binary_op (insn, operands);" |
6300f037 EC |
17182 | [(set (attr "type") |
17183 | (cond [(match_operand:DF 3 "mult_operator" "") | |
4977bab6 | 17184 | (const_string "fmul") |
6300f037 | 17185 | (match_operand:DF 3 "div_operator" "") |
4977bab6 ZW |
17186 | (const_string "fdiv") |
17187 | ] | |
17188 | (const_string "fop"))) | |
17189 | (set_attr "mode" "SF")]) | |
17190 | ||
cfa185b8 UB |
17191 | (define_insn "*fop_xf_comm_i387" |
17192 | [(set (match_operand:XF 0 "register_operand" "=f") | |
17193 | (match_operator:XF 3 "binary_fp_operator" | |
17194 | [(match_operand:XF 1 "register_operand" "%0") | |
17195 | (match_operand:XF 2 "register_operand" "f")]))] | |
17196 | "TARGET_80387 | |
17197 | && COMMUTATIVE_ARITH_P (operands[3])" | |
17198 | "* return output_387_binary_op (insn, operands);" | |
6300f037 EC |
17199 | [(set (attr "type") |
17200 | (if_then_else (match_operand:XF 3 "mult_operator" "") | |
cfa185b8 UB |
17201 | (const_string "fmul") |
17202 | (const_string "fop"))) | |
17203 | (set_attr "mode" "XF")]) | |
17204 | ||
17205 | (define_insn "*fop_xf_1_i387" | |
e075ae69 RH |
17206 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
17207 | (match_operator:XF 3 "binary_fp_operator" | |
17208 | [(match_operand:XF 1 "register_operand" "0,f") | |
17209 | (match_operand:XF 2 "register_operand" "f,0")]))] | |
f8a1ebc6 | 17210 | "TARGET_80387 |
ec8e098d | 17211 | && !COMMUTATIVE_ARITH_P (operands[3])" |
e075ae69 | 17212 | "* return output_387_binary_op (insn, operands);" |
6300f037 EC |
17213 | [(set (attr "type") |
17214 | (cond [(match_operand:XF 3 "mult_operator" "") | |
e075ae69 | 17215 | (const_string "fmul") |
6300f037 | 17216 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
17217 | (const_string "fdiv") |
17218 | ] | |
6ef67412 JH |
17219 | (const_string "fop"))) |
17220 | (set_attr "mode" "XF")]) | |
e075ae69 | 17221 | |
ca3a2165 | 17222 | (define_insn "*fop_xf_2_i387" |
e075ae69 RH |
17223 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
17224 | (match_operator:XF 3 "binary_fp_operator" | |
ca3a2165 UB |
17225 | [(float:XF |
17226 | (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) | |
17227 | (match_operand:XF 2 "register_operand" "0,0")]))] | |
3debdc1e | 17228 | "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" |
2b589241 | 17229 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
6300f037 EC |
17230 | [(set (attr "type") |
17231 | (cond [(match_operand:XF 3 "mult_operator" "") | |
2b589241 | 17232 | (const_string "fmul") |
6300f037 | 17233 | (match_operand:XF 3 "div_operator" "") |
2b589241 JH |
17234 | (const_string "fdiv") |
17235 | ] | |
17236 | (const_string "fop"))) | |
17237 | (set_attr "fp_int_src" "true") | |
0e8c2b0d | 17238 | (set_attr "mode" "<MODE>")]) |
2b589241 | 17239 | |
ca3a2165 | 17240 | (define_insn "*fop_xf_3_i387" |
e075ae69 RH |
17241 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
17242 | (match_operator:XF 3 "binary_fp_operator" | |
17243 | [(match_operand:XF 1 "register_operand" "0,0") | |
ca3a2165 UB |
17244 | (float:XF |
17245 | (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] | |
3debdc1e | 17246 | "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" |
e075ae69 | 17247 | "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" |
6300f037 EC |
17248 | [(set (attr "type") |
17249 | (cond [(match_operand:XF 3 "mult_operator" "") | |
e075ae69 | 17250 | (const_string "fmul") |
6300f037 | 17251 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
17252 | (const_string "fdiv") |
17253 | ] | |
17254 | (const_string "fop"))) | |
17255 | (set_attr "fp_int_src" "true") | |
0e8c2b0d | 17256 | (set_attr "mode" "<MODE>")]) |
e075ae69 | 17257 | |
cfa185b8 | 17258 | (define_insn "*fop_xf_4_i387" |
e075ae69 RH |
17259 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
17260 | (match_operator:XF 3 "binary_fp_operator" | |
8002331e | 17261 | [(float_extend:XF |
00188daa | 17262 | (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) |
e075ae69 | 17263 | (match_operand:XF 2 "register_operand" "0,f")]))] |
f8a1ebc6 | 17264 | "TARGET_80387" |
e075ae69 | 17265 | "* return output_387_binary_op (insn, operands);" |
6300f037 EC |
17266 | [(set (attr "type") |
17267 | (cond [(match_operand:XF 3 "mult_operator" "") | |
e075ae69 | 17268 | (const_string "fmul") |
6300f037 | 17269 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
17270 | (const_string "fdiv") |
17271 | ] | |
6ef67412 | 17272 | (const_string "fop"))) |
ca3a2165 | 17273 | (set_attr "mode" "<MODE>")]) |
e075ae69 | 17274 | |
cfa185b8 | 17275 | (define_insn "*fop_xf_5_i387" |
e075ae69 RH |
17276 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
17277 | (match_operator:XF 3 "binary_fp_operator" | |
17278 | [(match_operand:XF 1 "register_operand" "0,f") | |
17279 | (float_extend:XF | |
00188daa | 17280 | (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] |
f8a1ebc6 | 17281 | "TARGET_80387" |
e075ae69 | 17282 | "* return output_387_binary_op (insn, operands);" |
6300f037 EC |
17283 | [(set (attr "type") |
17284 | (cond [(match_operand:XF 3 "mult_operator" "") | |
e075ae69 | 17285 | (const_string "fmul") |
6300f037 | 17286 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
17287 | (const_string "fdiv") |
17288 | ] | |
6ef67412 | 17289 | (const_string "fop"))) |
ca3a2165 | 17290 | (set_attr "mode" "<MODE>")]) |
e075ae69 | 17291 | |
cfa185b8 | 17292 | (define_insn "*fop_xf_6_i387" |
e075ae69 RH |
17293 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
17294 | (match_operator:XF 3 "binary_fp_operator" | |
4977bab6 | 17295 | [(float_extend:XF |
00188daa | 17296 | (match_operand:MODEF 1 "register_operand" "0,f")) |
e075ae69 | 17297 | (float_extend:XF |
00188daa | 17298 | (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] |
f8a1ebc6 | 17299 | "TARGET_80387" |
e075ae69 | 17300 | "* return output_387_binary_op (insn, operands);" |
6300f037 EC |
17301 | [(set (attr "type") |
17302 | (cond [(match_operand:XF 3 "mult_operator" "") | |
e075ae69 | 17303 | (const_string "fmul") |
6300f037 | 17304 | (match_operand:XF 3 "div_operator" "") |
e075ae69 RH |
17305 | (const_string "fdiv") |
17306 | ] | |
6ef67412 | 17307 | (const_string "fop"))) |
ca3a2165 | 17308 | (set_attr "mode" "<MODE>")]) |
e075ae69 RH |
17309 | |
17310 | (define_split | |
17311 | [(set (match_operand 0 "register_operand" "") | |
17312 | (match_operator 3 "binary_fp_operator" | |
0e8c2b0d | 17313 | [(float (match_operand:X87MODEI12 1 "register_operand" "")) |
e075ae69 | 17314 | (match_operand 2 "register_operand" "")]))] |
27ac40e2 | 17315 | "reload_completed |
8ce94e44 JM |
17316 | && X87_FLOAT_MODE_P (GET_MODE (operands[0])) |
17317 | && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))" | |
4211a8fb | 17318 | [(const_int 0)] |
6300f037 | 17319 | { |
4211a8fb JH |
17320 | operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); |
17321 | operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); | |
17322 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
17323 | gen_rtx_fmt_ee (GET_CODE (operands[3]), | |
17324 | GET_MODE (operands[3]), | |
17325 | operands[4], | |
17326 | operands[2]))); | |
17327 | ix86_free_from_memory (GET_MODE (operands[1])); | |
17328 | DONE; | |
0f40f9f7 | 17329 | }) |
e075ae69 RH |
17330 | |
17331 | (define_split | |
17332 | [(set (match_operand 0 "register_operand" "") | |
17333 | (match_operator 3 "binary_fp_operator" | |
17334 | [(match_operand 1 "register_operand" "") | |
0e8c2b0d | 17335 | (float (match_operand:X87MODEI12 2 "register_operand" ""))]))] |
27ac40e2 | 17336 | "reload_completed |
8ce94e44 JM |
17337 | && X87_FLOAT_MODE_P (GET_MODE (operands[0])) |
17338 | && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))" | |
4211a8fb | 17339 | [(const_int 0)] |
4211a8fb JH |
17340 | { |
17341 | operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); | |
17342 | operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); | |
17343 | emit_insn (gen_rtx_SET (VOIDmode, operands[0], | |
2b66da3c | 17344 | gen_rtx_fmt_ee (GET_CODE (operands[3]), |
4211a8fb JH |
17345 | GET_MODE (operands[3]), |
17346 | operands[1], | |
17347 | operands[4]))); | |
17348 | ix86_free_from_memory (GET_MODE (operands[2])); | |
17349 | DONE; | |
0f40f9f7 | 17350 | }) |
e075ae69 RH |
17351 | \f |
17352 | ;; FPU special functions. | |
17353 | ||
01302104 UB |
17354 | ;; This pattern implements a no-op XFmode truncation for |
17355 | ;; all fancy i386 XFmode math functions. | |
a8083431 | 17356 | |
01302104 | 17357 | (define_insn "truncxf<mode>2_i387_noop_unspec" |
00188daa UB |
17358 | [(set (match_operand:MODEF 0 "register_operand" "=f") |
17359 | (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] | |
01302104 | 17360 | UNSPEC_TRUNC_NOOP))] |
22b768d4 | 17361 | "TARGET_USE_FANCY_MATH_387" |
01302104 UB |
17362 | "* return output_387_reg_move (insn, operands);" |
17363 | [(set_attr "type" "fmov") | |
17364 | (set_attr "mode" "<MODE>")]) | |
e075ae69 RH |
17365 | |
17366 | (define_insn "sqrtxf2" | |
17367 | [(set (match_operand:XF 0 "register_operand" "=f") | |
17368 | (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] | |
5a4171a0 | 17369 | "TARGET_USE_FANCY_MATH_387" |
2b589241 JH |
17370 | "fsqrt" |
17371 | [(set_attr "type" "fpspc") | |
17372 | (set_attr "mode" "XF") | |
21efb4d4 HJ |
17373 | (set_attr "athlon_decode" "direct") |
17374 | (set_attr "amdfam10_decode" "direct")]) | |
2b589241 | 17375 | |
786f159e | 17376 | (define_insn "sqrt_extend<mode>xf2_i387" |
e075ae69 | 17377 | [(set (match_operand:XF 0 "register_operand" "=f") |
01302104 UB |
17378 | (sqrt:XF |
17379 | (float_extend:XF | |
00188daa | 17380 | (match_operand:MODEF 1 "register_operand" "0"))))] |
ba2baa55 | 17381 | "TARGET_USE_FANCY_MATH_387" |
2b589241 JH |
17382 | "fsqrt" |
17383 | [(set_attr "type" "fpspc") | |
17384 | (set_attr "mode" "XF") | |
4f3f76e6 | 17385 | (set_attr "athlon_decode" "direct") |
21efb4d4 | 17386 | (set_attr "amdfam10_decode" "direct")]) |
2b589241 | 17387 | |
6b889d89 UB |
17388 | (define_insn "*rsqrtsf2_sse" |
17389 | [(set (match_operand:SF 0 "register_operand" "=x") | |
17390 | (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] | |
17391 | UNSPEC_RSQRT))] | |
17392 | "TARGET_SSE_MATH" | |
95879c72 | 17393 | "%vrsqrtss\t{%1, %d0|%d0, %1}" |
6b889d89 | 17394 | [(set_attr "type" "sse") |
b6837b94 | 17395 | (set_attr "atom_sse_attr" "rcp") |
95879c72 | 17396 | (set_attr "prefix" "maybe_vex") |
6b889d89 UB |
17397 | (set_attr "mode" "SF")]) |
17398 | ||
17399 | (define_expand "rsqrtsf2" | |
00188daa UB |
17400 | [(set (match_operand:SF 0 "register_operand" "") |
17401 | (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")] | |
6b889d89 | 17402 | UNSPEC_RSQRT))] |
f1bf33ce | 17403 | "TARGET_SSE_MATH" |
6b889d89 UB |
17404 | { |
17405 | ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); | |
17406 | DONE; | |
17407 | }) | |
17408 | ||
01302104 | 17409 | (define_insn "*sqrt<mode>2_sse" |
00188daa UB |
17410 | [(set (match_operand:MODEF 0 "register_operand" "=x") |
17411 | (sqrt:MODEF | |
17412 | (match_operand:MODEF 1 "nonimmediate_operand" "xm")))] | |
01302104 | 17413 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" |
95879c72 | 17414 | "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}" |
01302104 | 17415 | [(set_attr "type" "sse") |
b6837b94 | 17416 | (set_attr "atom_sse_attr" "sqrt") |
95879c72 | 17417 | (set_attr "prefix" "maybe_vex") |
01302104 | 17418 | (set_attr "mode" "<MODE>") |
21efb4d4 HJ |
17419 | (set_attr "athlon_decode" "*") |
17420 | (set_attr "amdfam10_decode" "*")]) | |
01302104 UB |
17421 | |
17422 | (define_expand "sqrt<mode>2" | |
00188daa UB |
17423 | [(set (match_operand:MODEF 0 "register_operand" "") |
17424 | (sqrt:MODEF | |
17425 | (match_operand:MODEF 1 "nonimmediate_operand" "")))] | |
8ce94e44 | 17426 | "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) |
01302104 UB |
17427 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" |
17428 | { | |
6b889d89 | 17429 | if (<MODE>mode == SFmode |
3debdc1e | 17430 | && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun) |
6b889d89 UB |
17431 | && flag_finite_math_only && !flag_trapping_math |
17432 | && flag_unsafe_math_optimizations) | |
17433 | { | |
17434 | ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); | |
17435 | DONE; | |
17436 | } | |
17437 | ||
01302104 UB |
17438 | if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) |
17439 | { | |
17440 | rtx op0 = gen_reg_rtx (XFmode); | |
17441 | rtx op1 = force_reg (<MODE>mode, operands[1]); | |
17442 | ||
786f159e | 17443 | emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1)); |
01302104 UB |
17444 | emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); |
17445 | DONE; | |
17446 | } | |
17447 | }) | |
2b589241 | 17448 | |
786f159e | 17449 | (define_insn "fpremxf4_i387" |
5ae27cfa UB |
17450 | [(set (match_operand:XF 0 "register_operand" "=f") |
17451 | (unspec:XF [(match_operand:XF 2 "register_operand" "0") | |
17452 | (match_operand:XF 3 "register_operand" "1")] | |
17453 | UNSPEC_FPREM_F)) | |
17454 | (set (match_operand:XF 1 "register_operand" "=u") | |
17455 | (unspec:XF [(match_dup 2) (match_dup 3)] | |
17456 | UNSPEC_FPREM_U)) | |
8bc527af | 17457 | (set (reg:CCFP FPSR_REG) |
79cd820a UB |
17458 | (unspec:CCFP [(match_dup 2) (match_dup 3)] |
17459 | UNSPEC_C2_FLAG))] | |
17b98269 | 17460 | "TARGET_USE_FANCY_MATH_387" |
5ae27cfa UB |
17461 | "fprem" |
17462 | [(set_attr "type" "fpspc") | |
17463 | (set_attr "mode" "XF")]) | |
17464 | ||
786f159e UB |
17465 | (define_expand "fmodxf3" |
17466 | [(use (match_operand:XF 0 "register_operand" "")) | |
17c340e0 UB |
17467 | (use (match_operand:XF 1 "general_operand" "")) |
17468 | (use (match_operand:XF 2 "general_operand" ""))] | |
786f159e | 17469 | "TARGET_USE_FANCY_MATH_387" |
5ae27cfa UB |
17470 | { |
17471 | rtx label = gen_label_rtx (); | |
17472 | ||
17c340e0 UB |
17473 | rtx op1 = gen_reg_rtx (XFmode); |
17474 | rtx op2 = gen_reg_rtx (XFmode); | |
21da84bd | 17475 | |
17c340e0 | 17476 | emit_move_insn (op2, operands[2]); |
f2a55e41 | 17477 | emit_move_insn (op1, operands[1]); |
5ae27cfa | 17478 | |
21da84bd | 17479 | emit_label (label); |
17c340e0 | 17480 | emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); |
5ae27cfa | 17481 | ix86_emit_fp_unordered_jump (label); |
79cd820a | 17482 | LABEL_NUSES (label) = 1; |
5ae27cfa | 17483 | |
17c340e0 | 17484 | emit_move_insn (operands[0], op1); |
5ae27cfa UB |
17485 | DONE; |
17486 | }) | |
17487 | ||
786f159e | 17488 | (define_expand "fmod<mode>3" |
00188daa UB |
17489 | [(use (match_operand:MODEF 0 "register_operand" "")) |
17490 | (use (match_operand:MODEF 1 "general_operand" "")) | |
17491 | (use (match_operand:MODEF 2 "general_operand" ""))] | |
e26feb2c | 17492 | "TARGET_USE_FANCY_MATH_387" |
5ae27cfa UB |
17493 | { |
17494 | rtx label = gen_label_rtx (); | |
17495 | ||
17496 | rtx op1 = gen_reg_rtx (XFmode); | |
17497 | rtx op2 = gen_reg_rtx (XFmode); | |
17498 | ||
e26feb2c | 17499 | emit_insn (gen_extend<mode>xf2 (op2, operands[2])); |
f2a55e41 | 17500 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
5ae27cfa UB |
17501 | |
17502 | emit_label (label); | |
786f159e | 17503 | emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); |
5ae27cfa | 17504 | ix86_emit_fp_unordered_jump (label); |
79cd820a | 17505 | LABEL_NUSES (label) = 1; |
5ae27cfa | 17506 | |
e26feb2c UB |
17507 | /* Truncate the result properly for strict SSE math. */ |
17508 | if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH | |
17509 | && !TARGET_MIX_SSE_I387) | |
17510 | emit_insn (gen_truncxf<mode>2 (operands[0], op1)); | |
17511 | else | |
17512 | emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1)); | |
17513 | ||
5ae27cfa UB |
17514 | DONE; |
17515 | }) | |
17516 | ||
786f159e | 17517 | (define_insn "fprem1xf4_i387" |
5ae27cfa UB |
17518 | [(set (match_operand:XF 0 "register_operand" "=f") |
17519 | (unspec:XF [(match_operand:XF 2 "register_operand" "0") | |
17520 | (match_operand:XF 3 "register_operand" "1")] | |
17521 | UNSPEC_FPREM1_F)) | |
17522 | (set (match_operand:XF 1 "register_operand" "=u") | |
17523 | (unspec:XF [(match_dup 2) (match_dup 3)] | |
17524 | UNSPEC_FPREM1_U)) | |
8bc527af | 17525 | (set (reg:CCFP FPSR_REG) |
79cd820a UB |
17526 | (unspec:CCFP [(match_dup 2) (match_dup 3)] |
17527 | UNSPEC_C2_FLAG))] | |
17b98269 | 17528 | "TARGET_USE_FANCY_MATH_387" |
5ae27cfa UB |
17529 | "fprem1" |
17530 | [(set_attr "type" "fpspc") | |
17531 | (set_attr "mode" "XF")]) | |
17532 | ||
786f159e UB |
17533 | (define_expand "remainderxf3" |
17534 | [(use (match_operand:XF 0 "register_operand" "")) | |
17c340e0 UB |
17535 | (use (match_operand:XF 1 "general_operand" "")) |
17536 | (use (match_operand:XF 2 "general_operand" ""))] | |
786f159e | 17537 | "TARGET_USE_FANCY_MATH_387" |
5ae27cfa UB |
17538 | { |
17539 | rtx label = gen_label_rtx (); | |
17540 | ||
17c340e0 UB |
17541 | rtx op1 = gen_reg_rtx (XFmode); |
17542 | rtx op2 = gen_reg_rtx (XFmode); | |
21da84bd | 17543 | |
17c340e0 | 17544 | emit_move_insn (op2, operands[2]); |
f2a55e41 | 17545 | emit_move_insn (op1, operands[1]); |
5ae27cfa | 17546 | |
21da84bd | 17547 | emit_label (label); |
17c340e0 | 17548 | emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); |
5ae27cfa | 17549 | ix86_emit_fp_unordered_jump (label); |
79cd820a | 17550 | LABEL_NUSES (label) = 1; |
5ae27cfa | 17551 | |
17c340e0 | 17552 | emit_move_insn (operands[0], op1); |
5ae27cfa UB |
17553 | DONE; |
17554 | }) | |
17555 | ||
786f159e | 17556 | (define_expand "remainder<mode>3" |
00188daa UB |
17557 | [(use (match_operand:MODEF 0 "register_operand" "")) |
17558 | (use (match_operand:MODEF 1 "general_operand" "")) | |
17559 | (use (match_operand:MODEF 2 "general_operand" ""))] | |
e26feb2c | 17560 | "TARGET_USE_FANCY_MATH_387" |
5ae27cfa UB |
17561 | { |
17562 | rtx label = gen_label_rtx (); | |
17563 | ||
17564 | rtx op1 = gen_reg_rtx (XFmode); | |
17565 | rtx op2 = gen_reg_rtx (XFmode); | |
17566 | ||
e26feb2c | 17567 | emit_insn (gen_extend<mode>xf2 (op2, operands[2])); |
f2a55e41 | 17568 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
5ae27cfa UB |
17569 | |
17570 | emit_label (label); | |
17571 | ||
786f159e | 17572 | emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); |
5ae27cfa | 17573 | ix86_emit_fp_unordered_jump (label); |
79cd820a | 17574 | LABEL_NUSES (label) = 1; |
5ae27cfa | 17575 | |
e26feb2c UB |
17576 | /* Truncate the result properly for strict SSE math. */ |
17577 | if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH | |
17578 | && !TARGET_MIX_SSE_I387) | |
17579 | emit_insn (gen_truncxf<mode>2 (operands[0], op1)); | |
17580 | else | |
17581 | emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1)); | |
17582 | ||
5ae27cfa UB |
17583 | DONE; |
17584 | }) | |
17585 | ||
c648dedb | 17586 | (define_insn "*sinxf2_i387" |
e075ae69 | 17587 | [(set (match_operand:XF 0 "register_operand" "=f") |
8ee41eaf | 17588 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] |
ba2baa55 | 17589 | "TARGET_USE_FANCY_MATH_387 |
de6c5979 | 17590 | && flag_unsafe_math_optimizations" |
2b589241 JH |
17591 | "fsin" |
17592 | [(set_attr "type" "fpspc") | |
17593 | (set_attr "mode" "XF")]) | |
17594 | ||
c648dedb UB |
17595 | (define_insn "*sin_extend<mode>xf2_i387" |
17596 | [(set (match_operand:XF 0 "register_operand" "=f") | |
17597 | (unspec:XF [(float_extend:XF | |
00188daa | 17598 | (match_operand:MODEF 1 "register_operand" "0"))] |
c648dedb | 17599 | UNSPEC_SIN))] |
ba2baa55 | 17600 | "TARGET_USE_FANCY_MATH_387 |
c648dedb UB |
17601 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
17602 | || TARGET_MIX_SSE_I387) | |
de6c5979 | 17603 | && flag_unsafe_math_optimizations" |
c648dedb | 17604 | "fsin" |
6ef67412 | 17605 | [(set_attr "type" "fpspc") |
c648dedb | 17606 | (set_attr "mode" "XF")]) |
bca7cce2 | 17607 | |
c648dedb UB |
17608 | (define_insn "*cosxf2_i387" |
17609 | [(set (match_operand:XF 0 "register_operand" "=f") | |
17610 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] | |
ba2baa55 | 17611 | "TARGET_USE_FANCY_MATH_387 |
de6c5979 | 17612 | && flag_unsafe_math_optimizations" |
e075ae69 | 17613 | "fcos" |
6ef67412 | 17614 | [(set_attr "type" "fpspc") |
c648dedb | 17615 | (set_attr "mode" "XF")]) |
5f3d14e3 | 17616 | |
c648dedb | 17617 | (define_insn "*cos_extend<mode>xf2_i387" |
e075ae69 | 17618 | [(set (match_operand:XF 0 "register_operand" "=f") |
c648dedb | 17619 | (unspec:XF [(float_extend:XF |
00188daa | 17620 | (match_operand:MODEF 1 "register_operand" "0"))] |
c648dedb | 17621 | UNSPEC_COS))] |
ba2baa55 | 17622 | "TARGET_USE_FANCY_MATH_387 |
c648dedb UB |
17623 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
17624 | || TARGET_MIX_SSE_I387) | |
de6c5979 | 17625 | && flag_unsafe_math_optimizations" |
2b589241 JH |
17626 | "fcos" |
17627 | [(set_attr "type" "fpspc") | |
17628 | (set_attr "mode" "XF")]) | |
1fb54135 | 17629 | |
c648dedb | 17630 | ;; When sincos pattern is defined, sin and cos builtin functions will be |
6300f037 | 17631 | ;; expanded to sincos pattern with one of its outputs left unused. |
c648dedb | 17632 | ;; CSE pass will figure out if two sincos patterns can be combined, |
1ae58c30 | 17633 | ;; otherwise sincos pattern will be split back to sin or cos pattern, |
6c7cf1f0 UB |
17634 | ;; depending on the unused output. |
17635 | ||
c648dedb UB |
17636 | (define_insn "sincosxf3" |
17637 | [(set (match_operand:XF 0 "register_operand" "=f") | |
17638 | (unspec:XF [(match_operand:XF 2 "register_operand" "0")] | |
6c7cf1f0 | 17639 | UNSPEC_SINCOS_COS)) |
c648dedb UB |
17640 | (set (match_operand:XF 1 "register_operand" "=u") |
17641 | (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] | |
ba2baa55 | 17642 | "TARGET_USE_FANCY_MATH_387 |
6c7cf1f0 UB |
17643 | && flag_unsafe_math_optimizations" |
17644 | "fsincos" | |
17645 | [(set_attr "type" "fpspc") | |
c648dedb | 17646 | (set_attr "mode" "XF")]) |
6c7cf1f0 UB |
17647 | |
17648 | (define_split | |
c648dedb UB |
17649 | [(set (match_operand:XF 0 "register_operand" "") |
17650 | (unspec:XF [(match_operand:XF 2 "register_operand" "")] | |
6c7cf1f0 | 17651 | UNSPEC_SINCOS_COS)) |
c648dedb UB |
17652 | (set (match_operand:XF 1 "register_operand" "") |
17653 | (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] | |
6c7cf1f0 | 17654 | "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) |
00188daa | 17655 | && !(reload_completed || reload_in_progress)" |
c648dedb | 17656 | [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))] |
6c7cf1f0 UB |
17657 | "") |
17658 | ||
17659 | (define_split | |
c648dedb UB |
17660 | [(set (match_operand:XF 0 "register_operand" "") |
17661 | (unspec:XF [(match_operand:XF 2 "register_operand" "")] | |
6c7cf1f0 | 17662 | UNSPEC_SINCOS_COS)) |
c648dedb UB |
17663 | (set (match_operand:XF 1 "register_operand" "") |
17664 | (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] | |
6c7cf1f0 | 17665 | "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) |
00188daa | 17666 | && !(reload_completed || reload_in_progress)" |
c648dedb | 17667 | [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))] |
6c7cf1f0 UB |
17668 | "") |
17669 | ||
c648dedb | 17670 | (define_insn "sincos_extend<mode>xf3_i387" |
6c7cf1f0 | 17671 | [(set (match_operand:XF 0 "register_operand" "=f") |
c648dedb | 17672 | (unspec:XF [(float_extend:XF |
00188daa | 17673 | (match_operand:MODEF 2 "register_operand" "0"))] |
6c7cf1f0 UB |
17674 | UNSPEC_SINCOS_COS)) |
17675 | (set (match_operand:XF 1 "register_operand" "=u") | |
c648dedb | 17676 | (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] |
ba2baa55 | 17677 | "TARGET_USE_FANCY_MATH_387 |
c648dedb UB |
17678 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
17679 | || TARGET_MIX_SSE_I387) | |
6c7cf1f0 UB |
17680 | && flag_unsafe_math_optimizations" |
17681 | "fsincos" | |
17682 | [(set_attr "type" "fpspc") | |
17683 | (set_attr "mode" "XF")]) | |
17684 | ||
17685 | (define_split | |
17686 | [(set (match_operand:XF 0 "register_operand" "") | |
c648dedb | 17687 | (unspec:XF [(float_extend:XF |
00188daa | 17688 | (match_operand:MODEF 2 "register_operand" ""))] |
6c7cf1f0 UB |
17689 | UNSPEC_SINCOS_COS)) |
17690 | (set (match_operand:XF 1 "register_operand" "") | |
c648dedb | 17691 | (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] |
6c7cf1f0 | 17692 | "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) |
00188daa | 17693 | && !(reload_completed || reload_in_progress)" |
c648dedb | 17694 | [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))] |
6c7cf1f0 UB |
17695 | "") |
17696 | ||
17697 | (define_split | |
17698 | [(set (match_operand:XF 0 "register_operand" "") | |
c648dedb | 17699 | (unspec:XF [(float_extend:XF |
00188daa | 17700 | (match_operand:MODEF 2 "register_operand" ""))] |
6c7cf1f0 UB |
17701 | UNSPEC_SINCOS_COS)) |
17702 | (set (match_operand:XF 1 "register_operand" "") | |
c648dedb | 17703 | (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] |
6c7cf1f0 | 17704 | "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) |
00188daa | 17705 | && !(reload_completed || reload_in_progress)" |
c648dedb | 17706 | [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))] |
6c7cf1f0 UB |
17707 | "") |
17708 | ||
c648dedb | 17709 | (define_expand "sincos<mode>3" |
00188daa UB |
17710 | [(use (match_operand:MODEF 0 "register_operand" "")) |
17711 | (use (match_operand:MODEF 1 "register_operand" "")) | |
17712 | (use (match_operand:MODEF 2 "register_operand" ""))] | |
c648dedb UB |
17713 | "TARGET_USE_FANCY_MATH_387 |
17714 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
17715 | || TARGET_MIX_SSE_I387) | |
17716 | && flag_unsafe_math_optimizations" | |
17717 | { | |
17718 | rtx op0 = gen_reg_rtx (XFmode); | |
17719 | rtx op1 = gen_reg_rtx (XFmode); | |
17720 | ||
17721 | emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2])); | |
d85c7550 UB |
17722 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
17723 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1)); | |
c648dedb UB |
17724 | DONE; |
17725 | }) | |
17726 | ||
d85c7550 UB |
17727 | (define_insn "fptanxf4_i387" |
17728 | [(set (match_operand:XF 0 "register_operand" "=f") | |
17729 | (match_operand:XF 3 "const_double_operand" "F")) | |
17730 | (set (match_operand:XF 1 "register_operand" "=u") | |
17731 | (unspec:XF [(match_operand:XF 2 "register_operand" "0")] | |
17732 | UNSPEC_TAN))] | |
ba2baa55 | 17733 | "TARGET_USE_FANCY_MATH_387 |
d85c7550 UB |
17734 | && flag_unsafe_math_optimizations |
17735 | && standard_80387_constant_p (operands[3]) == 2" | |
a072d43b UB |
17736 | "fptan" |
17737 | [(set_attr "type" "fpspc") | |
d85c7550 | 17738 | (set_attr "mode" "XF")]) |
a072d43b | 17739 | |
d85c7550 | 17740 | (define_insn "fptan_extend<mode>xf4_i387" |
00188daa UB |
17741 | [(set (match_operand:MODEF 0 "register_operand" "=f") |
17742 | (match_operand:MODEF 3 "const_double_operand" "F")) | |
d85c7550 UB |
17743 | (set (match_operand:XF 1 "register_operand" "=u") |
17744 | (unspec:XF [(float_extend:XF | |
00188daa | 17745 | (match_operand:MODEF 2 "register_operand" "0"))] |
d85c7550 | 17746 | UNSPEC_TAN))] |
ba2baa55 | 17747 | "TARGET_USE_FANCY_MATH_387 |
d85c7550 UB |
17748 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
17749 | || TARGET_MIX_SSE_I387) | |
17750 | && flag_unsafe_math_optimizations | |
17751 | && standard_80387_constant_p (operands[3]) == 2" | |
a072d43b UB |
17752 | "fptan" |
17753 | [(set_attr "type" "fpspc") | |
d85c7550 | 17754 | (set_attr "mode" "XF")]) |
a072d43b | 17755 | |
d85c7550 UB |
17756 | (define_expand "tanxf2" |
17757 | [(use (match_operand:XF 0 "register_operand" "")) | |
17758 | (use (match_operand:XF 1 "register_operand" ""))] | |
ba2baa55 | 17759 | "TARGET_USE_FANCY_MATH_387 |
a072d43b UB |
17760 | && flag_unsafe_math_optimizations" |
17761 | { | |
d85c7550 | 17762 | rtx one = gen_reg_rtx (XFmode); |
9db27449 | 17763 | rtx op2 = CONST1_RTX (XFmode); /* fld1 */ |
d85c7550 | 17764 | |
9db27449 | 17765 | emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2)); |
d85c7550 | 17766 | DONE; |
a072d43b UB |
17767 | }) |
17768 | ||
d85c7550 | 17769 | (define_expand "tan<mode>2" |
00188daa UB |
17770 | [(use (match_operand:MODEF 0 "register_operand" "")) |
17771 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
ba2baa55 | 17772 | "TARGET_USE_FANCY_MATH_387 |
d85c7550 UB |
17773 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
17774 | || TARGET_MIX_SSE_I387) | |
a072d43b | 17775 | && flag_unsafe_math_optimizations" |
d85c7550 UB |
17776 | { |
17777 | rtx op0 = gen_reg_rtx (XFmode); | |
a072d43b | 17778 | |
d85c7550 | 17779 | rtx one = gen_reg_rtx (<MODE>mode); |
9db27449 | 17780 | rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */ |
a072d43b | 17781 | |
d85c7550 | 17782 | emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0, |
9db27449 | 17783 | operands[1], op2)); |
d85c7550 UB |
17784 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
17785 | DONE; | |
a072d43b UB |
17786 | }) |
17787 | ||
8ef4f42c UB |
17788 | (define_insn "*fpatanxf3_i387" |
17789 | [(set (match_operand:XF 0 "register_operand" "=f") | |
17790 | (unspec:XF [(match_operand:XF 1 "register_operand" "0") | |
17791 | (match_operand:XF 2 "register_operand" "u")] | |
17792 | UNSPEC_FPATAN)) | |
17793 | (clobber (match_scratch:XF 3 "=2"))] | |
ba2baa55 | 17794 | "TARGET_USE_FANCY_MATH_387 |
1fb54135 RS |
17795 | && flag_unsafe_math_optimizations" |
17796 | "fpatan" | |
17797 | [(set_attr "type" "fpspc") | |
8ef4f42c | 17798 | (set_attr "mode" "XF")]) |
a6bf61c7 | 17799 | |
8ef4f42c | 17800 | (define_insn "fpatan_extend<mode>xf3_i387" |
cb0bc263 | 17801 | [(set (match_operand:XF 0 "register_operand" "=f") |
8ef4f42c | 17802 | (unspec:XF [(float_extend:XF |
00188daa | 17803 | (match_operand:MODEF 1 "register_operand" "0")) |
8ef4f42c | 17804 | (float_extend:XF |
00188daa | 17805 | (match_operand:MODEF 2 "register_operand" "u"))] |
cb0bc263 | 17806 | UNSPEC_FPATAN)) |
8ef4f42c | 17807 | (clobber (match_scratch:XF 3 "=2"))] |
ba2baa55 | 17808 | "TARGET_USE_FANCY_MATH_387 |
8ef4f42c UB |
17809 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
17810 | || TARGET_MIX_SSE_I387) | |
f8a1ebc6 | 17811 | && flag_unsafe_math_optimizations" |
1fb54135 RS |
17812 | "fpatan" |
17813 | [(set_attr "type" "fpspc") | |
17814 | (set_attr "mode" "XF")]) | |
17815 | ||
afeeac3f | 17816 | (define_expand "atan2xf3" |
8ef4f42c UB |
17817 | [(parallel [(set (match_operand:XF 0 "register_operand" "") |
17818 | (unspec:XF [(match_operand:XF 2 "register_operand" "") | |
17819 | (match_operand:XF 1 "register_operand" "")] | |
17820 | UNSPEC_FPATAN)) | |
17821 | (clobber (match_scratch:XF 3 ""))])] | |
ba2baa55 | 17822 | "TARGET_USE_FANCY_MATH_387 |
f8a1ebc6 | 17823 | && flag_unsafe_math_optimizations" |
8ef4f42c UB |
17824 | "") |
17825 | ||
17826 | (define_expand "atan2<mode>3" | |
00188daa UB |
17827 | [(use (match_operand:MODEF 0 "register_operand" "")) |
17828 | (use (match_operand:MODEF 1 "register_operand" "")) | |
17829 | (use (match_operand:MODEF 2 "register_operand" ""))] | |
8ef4f42c UB |
17830 | "TARGET_USE_FANCY_MATH_387 |
17831 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
17832 | || TARGET_MIX_SSE_I387) | |
17833 | && flag_unsafe_math_optimizations" | |
afeeac3f | 17834 | { |
8ef4f42c UB |
17835 | rtx op0 = gen_reg_rtx (XFmode); |
17836 | ||
17837 | emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1])); | |
17838 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
afeeac3f | 17839 | DONE; |
923c4cf2 | 17840 | }) |
afeeac3f | 17841 | |
a6bf61c7 UB |
17842 | (define_expand "atanxf2" |
17843 | [(parallel [(set (match_operand:XF 0 "register_operand" "") | |
17844 | (unspec:XF [(match_dup 2) | |
17845 | (match_operand:XF 1 "register_operand" "")] | |
8ef4f42c | 17846 | UNSPEC_FPATAN)) |
a6bf61c7 | 17847 | (clobber (match_scratch:XF 3 ""))])] |
ba2baa55 | 17848 | "TARGET_USE_FANCY_MATH_387 |
a6bf61c7 UB |
17849 | && flag_unsafe_math_optimizations" |
17850 | { | |
17851 | operands[2] = gen_reg_rtx (XFmode); | |
17852 | emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ | |
17853 | }) | |
17854 | ||
8ef4f42c | 17855 | (define_expand "atan<mode>2" |
00188daa UB |
17856 | [(use (match_operand:MODEF 0 "register_operand" "")) |
17857 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
8ef4f42c UB |
17858 | "TARGET_USE_FANCY_MATH_387 |
17859 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
17860 | || TARGET_MIX_SSE_I387) | |
17861 | && flag_unsafe_math_optimizations" | |
17862 | { | |
17863 | rtx op0 = gen_reg_rtx (XFmode); | |
17864 | ||
9db27449 UB |
17865 | rtx op2 = gen_reg_rtx (<MODE>mode); |
17866 | emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */ | |
8ef4f42c | 17867 | |
9db27449 | 17868 | emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1])); |
8ef4f42c UB |
17869 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
17870 | DONE; | |
17871 | }) | |
17872 | ||
c56122d8 UB |
17873 | (define_expand "asinxf2" |
17874 | [(set (match_dup 2) | |
17875 | (mult:XF (match_operand:XF 1 "register_operand" "") | |
17876 | (match_dup 1))) | |
17877 | (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) | |
17878 | (set (match_dup 5) (sqrt:XF (match_dup 4))) | |
17879 | (parallel [(set (match_operand:XF 0 "register_operand" "") | |
17880 | (unspec:XF [(match_dup 5) (match_dup 1)] | |
17881 | UNSPEC_FPATAN)) | |
17882 | (clobber (match_scratch:XF 6 ""))])] | |
ba2baa55 | 17883 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 17884 | && flag_unsafe_math_optimizations" |
c56122d8 UB |
17885 | { |
17886 | int i; | |
17887 | ||
18bd082d JH |
17888 | if (optimize_insn_for_size_p ()) |
17889 | FAIL; | |
17890 | ||
e2fc57a3 | 17891 | for (i = 2; i < 6; i++) |
c56122d8 UB |
17892 | operands[i] = gen_reg_rtx (XFmode); |
17893 | ||
17894 | emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ | |
17895 | }) | |
17896 | ||
e2fc57a3 | 17897 | (define_expand "asin<mode>2" |
00188daa UB |
17898 | [(use (match_operand:MODEF 0 "register_operand" "")) |
17899 | (use (match_operand:MODEF 1 "general_operand" ""))] | |
e2fc57a3 UB |
17900 | "TARGET_USE_FANCY_MATH_387 |
17901 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
17902 | || TARGET_MIX_SSE_I387) | |
18bd082d | 17903 | && flag_unsafe_math_optimizations" |
c56122d8 | 17904 | { |
e2fc57a3 UB |
17905 | rtx op0 = gen_reg_rtx (XFmode); |
17906 | rtx op1 = gen_reg_rtx (XFmode); | |
c56122d8 | 17907 | |
18bd082d JH |
17908 | if (optimize_insn_for_size_p ()) |
17909 | FAIL; | |
17910 | ||
e2fc57a3 UB |
17911 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
17912 | emit_insn (gen_asinxf2 (op0, op1)); | |
17913 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
17914 | DONE; | |
c56122d8 UB |
17915 | }) |
17916 | ||
17917 | (define_expand "acosxf2" | |
17918 | [(set (match_dup 2) | |
17919 | (mult:XF (match_operand:XF 1 "register_operand" "") | |
17920 | (match_dup 1))) | |
17921 | (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) | |
17922 | (set (match_dup 5) (sqrt:XF (match_dup 4))) | |
17923 | (parallel [(set (match_operand:XF 0 "register_operand" "") | |
17924 | (unspec:XF [(match_dup 1) (match_dup 5)] | |
17925 | UNSPEC_FPATAN)) | |
17926 | (clobber (match_scratch:XF 6 ""))])] | |
ba2baa55 | 17927 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 17928 | && flag_unsafe_math_optimizations" |
c56122d8 UB |
17929 | { |
17930 | int i; | |
17931 | ||
18bd082d JH |
17932 | if (optimize_insn_for_size_p ()) |
17933 | FAIL; | |
17934 | ||
e2fc57a3 | 17935 | for (i = 2; i < 6; i++) |
c56122d8 UB |
17936 | operands[i] = gen_reg_rtx (XFmode); |
17937 | ||
17938 | emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ | |
17939 | }) | |
17940 | ||
e2fc57a3 | 17941 | (define_expand "acos<mode>2" |
00188daa UB |
17942 | [(use (match_operand:MODEF 0 "register_operand" "")) |
17943 | (use (match_operand:MODEF 1 "general_operand" ""))] | |
e2fc57a3 UB |
17944 | "TARGET_USE_FANCY_MATH_387 |
17945 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
17946 | || TARGET_MIX_SSE_I387) | |
18bd082d | 17947 | && flag_unsafe_math_optimizations" |
e2fc57a3 UB |
17948 | { |
17949 | rtx op0 = gen_reg_rtx (XFmode); | |
17950 | rtx op1 = gen_reg_rtx (XFmode); | |
17951 | ||
18bd082d JH |
17952 | if (optimize_insn_for_size_p ()) |
17953 | FAIL; | |
17954 | ||
e2fc57a3 UB |
17955 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
17956 | emit_insn (gen_acosxf2 (op0, op1)); | |
17957 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
17958 | DONE; | |
17959 | }) | |
17960 | ||
0ac45694 | 17961 | (define_insn "fyl2xxf3_i387" |
cb0bc263 | 17962 | [(set (match_operand:XF 0 "register_operand" "=f") |
0ac45694 UB |
17963 | (unspec:XF [(match_operand:XF 1 "register_operand" "0") |
17964 | (match_operand:XF 2 "register_operand" "u")] | |
cb0bc263 | 17965 | UNSPEC_FYL2X)) |
0ac45694 | 17966 | (clobber (match_scratch:XF 3 "=2"))] |
ba2baa55 | 17967 | "TARGET_USE_FANCY_MATH_387 |
f8a1ebc6 | 17968 | && flag_unsafe_math_optimizations" |
358997e2 RS |
17969 | "fyl2x" |
17970 | [(set_attr "type" "fpspc") | |
17971 | (set_attr "mode" "XF")]) | |
17972 | ||
0ac45694 UB |
17973 | (define_insn "fyl2x_extend<mode>xf3_i387" |
17974 | [(set (match_operand:XF 0 "register_operand" "=f") | |
17975 | (unspec:XF [(float_extend:XF | |
00188daa | 17976 | (match_operand:MODEF 1 "register_operand" "0")) |
0ac45694 UB |
17977 | (match_operand:XF 2 "register_operand" "u")] |
17978 | UNSPEC_FYL2X)) | |
17979 | (clobber (match_scratch:XF 3 "=2"))] | |
ba2baa55 | 17980 | "TARGET_USE_FANCY_MATH_387 |
0ac45694 UB |
17981 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
17982 | || TARGET_MIX_SSE_I387) | |
358997e2 | 17983 | && flag_unsafe_math_optimizations" |
0ac45694 UB |
17984 | "fyl2x" |
17985 | [(set_attr "type" "fpspc") | |
17986 | (set_attr "mode" "XF")]) | |
358997e2 | 17987 | |
0ac45694 UB |
17988 | (define_expand "logxf2" |
17989 | [(parallel [(set (match_operand:XF 0 "register_operand" "") | |
17990 | (unspec:XF [(match_operand:XF 1 "register_operand" "") | |
17991 | (match_dup 2)] UNSPEC_FYL2X)) | |
17992 | (clobber (match_scratch:XF 3 ""))])] | |
17993 | "TARGET_USE_FANCY_MATH_387 | |
17994 | && flag_unsafe_math_optimizations" | |
17995 | { | |
f8a1ebc6 | 17996 | operands[2] = gen_reg_rtx (XFmode); |
0ac45694 | 17997 | emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */ |
358997e2 RS |
17998 | }) |
17999 | ||
0ac45694 | 18000 | (define_expand "log<mode>2" |
00188daa UB |
18001 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18002 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
ba2baa55 | 18003 | "TARGET_USE_FANCY_MATH_387 |
0ac45694 UB |
18004 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
18005 | || TARGET_MIX_SSE_I387) | |
358997e2 RS |
18006 | && flag_unsafe_math_optimizations" |
18007 | { | |
0ac45694 | 18008 | rtx op0 = gen_reg_rtx (XFmode); |
358997e2 | 18009 | |
9db27449 UB |
18010 | rtx op2 = gen_reg_rtx (XFmode); |
18011 | emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */ | |
6adcf89d | 18012 | |
9db27449 | 18013 | emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); |
e2fc57a3 | 18014 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
0ac45694 | 18015 | DONE; |
358997e2 RS |
18016 | }) |
18017 | ||
0ac45694 | 18018 | (define_expand "log10xf2" |
e43736ad RS |
18019 | [(parallel [(set (match_operand:XF 0 "register_operand" "") |
18020 | (unspec:XF [(match_operand:XF 1 "register_operand" "") | |
18021 | (match_dup 2)] UNSPEC_FYL2X)) | |
cb0bc263 | 18022 | (clobber (match_scratch:XF 3 ""))])] |
ba2baa55 | 18023 | "TARGET_USE_FANCY_MATH_387 |
f8a1ebc6 | 18024 | && flag_unsafe_math_optimizations" |
358997e2 | 18025 | { |
3b8e0c91 | 18026 | operands[2] = gen_reg_rtx (XFmode); |
0ac45694 | 18027 | emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */ |
3b8e0c91 UB |
18028 | }) |
18029 | ||
0ac45694 | 18030 | (define_expand "log10<mode>2" |
00188daa UB |
18031 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18032 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
ba2baa55 | 18033 | "TARGET_USE_FANCY_MATH_387 |
0ac45694 UB |
18034 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
18035 | || TARGET_MIX_SSE_I387) | |
3b8e0c91 UB |
18036 | && flag_unsafe_math_optimizations" |
18037 | { | |
0ac45694 | 18038 | rtx op0 = gen_reg_rtx (XFmode); |
3b8e0c91 | 18039 | |
9db27449 UB |
18040 | rtx op2 = gen_reg_rtx (XFmode); |
18041 | emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */ | |
6adcf89d | 18042 | |
9db27449 | 18043 | emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); |
e2fc57a3 | 18044 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
0ac45694 | 18045 | DONE; |
3b8e0c91 UB |
18046 | }) |
18047 | ||
0ac45694 | 18048 | (define_expand "log2xf2" |
3b8e0c91 UB |
18049 | [(parallel [(set (match_operand:XF 0 "register_operand" "") |
18050 | (unspec:XF [(match_operand:XF 1 "register_operand" "") | |
18051 | (match_dup 2)] UNSPEC_FYL2X)) | |
18052 | (clobber (match_scratch:XF 3 ""))])] | |
ba2baa55 | 18053 | "TARGET_USE_FANCY_MATH_387 |
3b8e0c91 UB |
18054 | && flag_unsafe_math_optimizations" |
18055 | { | |
3b8e0c91 | 18056 | operands[2] = gen_reg_rtx (XFmode); |
0ac45694 | 18057 | emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ |
3b8e0c91 UB |
18058 | }) |
18059 | ||
0ac45694 | 18060 | (define_expand "log2<mode>2" |
00188daa UB |
18061 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18062 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
ba2baa55 | 18063 | "TARGET_USE_FANCY_MATH_387 |
0ac45694 UB |
18064 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
18065 | || TARGET_MIX_SSE_I387) | |
3b8e0c91 UB |
18066 | && flag_unsafe_math_optimizations" |
18067 | { | |
0ac45694 | 18068 | rtx op0 = gen_reg_rtx (XFmode); |
3b8e0c91 | 18069 | |
9db27449 UB |
18070 | rtx op2 = gen_reg_rtx (XFmode); |
18071 | emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ | |
6adcf89d | 18072 | |
9db27449 | 18073 | emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); |
e2fc57a3 | 18074 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
0ac45694 | 18075 | DONE; |
3b8e0c91 UB |
18076 | }) |
18077 | ||
0ac45694 UB |
18078 | (define_insn "fyl2xp1xf3_i387" |
18079 | [(set (match_operand:XF 0 "register_operand" "=f") | |
18080 | (unspec:XF [(match_operand:XF 1 "register_operand" "0") | |
18081 | (match_operand:XF 2 "register_operand" "u")] | |
18082 | UNSPEC_FYL2XP1)) | |
18083 | (clobber (match_scratch:XF 3 "=2"))] | |
ba2baa55 | 18084 | "TARGET_USE_FANCY_MATH_387 |
3b8e0c91 | 18085 | && flag_unsafe_math_optimizations" |
0ac45694 UB |
18086 | "fyl2xp1" |
18087 | [(set_attr "type" "fpspc") | |
18088 | (set_attr "mode" "XF")]) | |
3b8e0c91 | 18089 | |
0ac45694 | 18090 | (define_insn "fyl2xp1_extend<mode>xf3_i387" |
c2fcfa4f | 18091 | [(set (match_operand:XF 0 "register_operand" "=f") |
0ac45694 | 18092 | (unspec:XF [(float_extend:XF |
00188daa | 18093 | (match_operand:MODEF 1 "register_operand" "0")) |
0ac45694 | 18094 | (match_operand:XF 2 "register_operand" "u")] |
c2fcfa4f | 18095 | UNSPEC_FYL2XP1)) |
0ac45694 | 18096 | (clobber (match_scratch:XF 3 "=2"))] |
ba2baa55 | 18097 | "TARGET_USE_FANCY_MATH_387 |
0ac45694 UB |
18098 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
18099 | || TARGET_MIX_SSE_I387) | |
c2fcfa4f UB |
18100 | && flag_unsafe_math_optimizations" |
18101 | "fyl2xp1" | |
18102 | [(set_attr "type" "fpspc") | |
18103 | (set_attr "mode" "XF")]) | |
18104 | ||
0ac45694 UB |
18105 | (define_expand "log1pxf2" |
18106 | [(use (match_operand:XF 0 "register_operand" "")) | |
18107 | (use (match_operand:XF 1 "register_operand" ""))] | |
ba2baa55 | 18108 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 18109 | && flag_unsafe_math_optimizations" |
c2fcfa4f | 18110 | { |
18bd082d JH |
18111 | if (optimize_insn_for_size_p ()) |
18112 | FAIL; | |
18113 | ||
0ac45694 | 18114 | ix86_emit_i387_log1p (operands[0], operands[1]); |
c2fcfa4f UB |
18115 | DONE; |
18116 | }) | |
18117 | ||
0ac45694 | 18118 | (define_expand "log1p<mode>2" |
00188daa UB |
18119 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18120 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
ba2baa55 | 18121 | "TARGET_USE_FANCY_MATH_387 |
0ac45694 UB |
18122 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
18123 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18124 | && flag_unsafe_math_optimizations" |
c2fcfa4f | 18125 | { |
18bd082d JH |
18126 | rtx op0; |
18127 | ||
18128 | if (optimize_insn_for_size_p ()) | |
18129 | FAIL; | |
18130 | ||
18131 | op0 = gen_reg_rtx (XFmode); | |
c2fcfa4f | 18132 | |
0ac45694 | 18133 | operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]); |
c2fcfa4f | 18134 | |
0ac45694 | 18135 | ix86_emit_i387_log1p (op0, operands[1]); |
e2fc57a3 | 18136 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
c2fcfa4f UB |
18137 | DONE; |
18138 | }) | |
18139 | ||
eaee4464 | 18140 | (define_insn "fxtractxf3_i387" |
6adcf89d UB |
18141 | [(set (match_operand:XF 0 "register_operand" "=f") |
18142 | (unspec:XF [(match_operand:XF 2 "register_operand" "0")] | |
88b28a31 | 18143 | UNSPEC_XTRACT_FRACT)) |
6adcf89d UB |
18144 | (set (match_operand:XF 1 "register_operand" "=u") |
18145 | (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] | |
ba2baa55 | 18146 | "TARGET_USE_FANCY_MATH_387 |
88b28a31 UB |
18147 | && flag_unsafe_math_optimizations" |
18148 | "fxtract" | |
18149 | [(set_attr "type" "fpspc") | |
6adcf89d | 18150 | (set_attr "mode" "XF")]) |
88b28a31 | 18151 | |
0ac45694 UB |
18152 | (define_insn "fxtract_extend<mode>xf3_i387" |
18153 | [(set (match_operand:XF 0 "register_operand" "=f") | |
18154 | (unspec:XF [(float_extend:XF | |
00188daa | 18155 | (match_operand:MODEF 2 "register_operand" "0"))] |
0ac45694 UB |
18156 | UNSPEC_XTRACT_FRACT)) |
18157 | (set (match_operand:XF 1 "register_operand" "=u") | |
18158 | (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))] | |
ba2baa55 | 18159 | "TARGET_USE_FANCY_MATH_387 |
0ac45694 UB |
18160 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
18161 | || TARGET_MIX_SSE_I387) | |
88b28a31 | 18162 | && flag_unsafe_math_optimizations" |
0ac45694 UB |
18163 | "fxtract" |
18164 | [(set_attr "type" "fpspc") | |
18165 | (set_attr "mode" "XF")]) | |
88b28a31 | 18166 | |
88b28a31 UB |
18167 | (define_expand "logbxf2" |
18168 | [(parallel [(set (match_dup 2) | |
18169 | (unspec:XF [(match_operand:XF 1 "register_operand" "")] | |
18170 | UNSPEC_XTRACT_FRACT)) | |
18171 | (set (match_operand:XF 0 "register_operand" "") | |
18172 | (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] | |
ba2baa55 | 18173 | "TARGET_USE_FANCY_MATH_387 |
88b28a31 UB |
18174 | && flag_unsafe_math_optimizations" |
18175 | { | |
18176 | operands[2] = gen_reg_rtx (XFmode); | |
18177 | }) | |
18178 | ||
0ac45694 | 18179 | (define_expand "logb<mode>2" |
00188daa UB |
18180 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18181 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
0ac45694 UB |
18182 | "TARGET_USE_FANCY_MATH_387 |
18183 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18184 | || TARGET_MIX_SSE_I387) | |
18185 | && flag_unsafe_math_optimizations" | |
18186 | { | |
18187 | rtx op0 = gen_reg_rtx (XFmode); | |
18188 | rtx op1 = gen_reg_rtx (XFmode); | |
18189 | ||
18190 | emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); | |
e2fc57a3 | 18191 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1)); |
0ac45694 UB |
18192 | DONE; |
18193 | }) | |
18194 | ||
eaee4464 UB |
18195 | (define_expand "ilogbxf2" |
18196 | [(use (match_operand:SI 0 "register_operand" "")) | |
18197 | (use (match_operand:XF 1 "register_operand" ""))] | |
ba2baa55 | 18198 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 18199 | && flag_unsafe_math_optimizations" |
88b28a31 | 18200 | { |
18bd082d JH |
18201 | rtx op0, op1; |
18202 | ||
18203 | if (optimize_insn_for_size_p ()) | |
18204 | FAIL; | |
18205 | ||
18206 | op0 = gen_reg_rtx (XFmode); | |
18207 | op1 = gen_reg_rtx (XFmode); | |
eaee4464 UB |
18208 | |
18209 | emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); | |
18210 | emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); | |
18211 | DONE; | |
18212 | }) | |
18213 | ||
18214 | (define_expand "ilogb<mode>2" | |
18215 | [(use (match_operand:SI 0 "register_operand" "")) | |
00188daa | 18216 | (use (match_operand:MODEF 1 "register_operand" ""))] |
eaee4464 UB |
18217 | "TARGET_USE_FANCY_MATH_387 |
18218 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18219 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18220 | && flag_unsafe_math_optimizations" |
eaee4464 | 18221 | { |
18bd082d JH |
18222 | rtx op0, op1; |
18223 | ||
18224 | if (optimize_insn_for_size_p ()) | |
18225 | FAIL; | |
18226 | ||
18227 | op0 = gen_reg_rtx (XFmode); | |
18228 | op1 = gen_reg_rtx (XFmode); | |
eaee4464 UB |
18229 | |
18230 | emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); | |
18231 | emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); | |
18232 | DONE; | |
88b28a31 UB |
18233 | }) |
18234 | ||
e2fc57a3 | 18235 | (define_insn "*f2xm1xf2_i387" |
9d5b9dae RS |
18236 | [(set (match_operand:XF 0 "register_operand" "=f") |
18237 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] | |
e2fc57a3 | 18238 | UNSPEC_F2XM1))] |
ba2baa55 | 18239 | "TARGET_USE_FANCY_MATH_387 |
f8a1ebc6 | 18240 | && flag_unsafe_math_optimizations" |
9d5b9dae RS |
18241 | "f2xm1" |
18242 | [(set_attr "type" "fpspc") | |
18243 | (set_attr "mode" "XF")]) | |
18244 | ||
e2fc57a3 | 18245 | (define_insn "*fscalexf4_i387" |
f964bd29 UB |
18246 | [(set (match_operand:XF 0 "register_operand" "=f") |
18247 | (unspec:XF [(match_operand:XF 2 "register_operand" "0") | |
18248 | (match_operand:XF 3 "register_operand" "1")] | |
18249 | UNSPEC_FSCALE_FRACT)) | |
18250 | (set (match_operand:XF 1 "register_operand" "=u") | |
18251 | (unspec:XF [(match_dup 2) (match_dup 3)] | |
18252 | UNSPEC_FSCALE_EXP))] | |
ba2baa55 | 18253 | "TARGET_USE_FANCY_MATH_387 |
f964bd29 UB |
18254 | && flag_unsafe_math_optimizations" |
18255 | "fscale" | |
18256 | [(set_attr "type" "fpspc") | |
152e3565 | 18257 | (set_attr "mode" "XF")]) |
f964bd29 | 18258 | |
e2fc57a3 | 18259 | (define_expand "expNcorexf3" |
9d5b9dae | 18260 | [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") |
e2fc57a3 | 18261 | (match_operand:XF 2 "register_operand" ""))) |
9d5b9dae RS |
18262 | (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) |
18263 | (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) | |
18264 | (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) | |
18265 | (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) | |
18266 | (parallel [(set (match_operand:XF 0 "register_operand" "") | |
f964bd29 UB |
18267 | (unspec:XF [(match_dup 8) (match_dup 4)] |
18268 | UNSPEC_FSCALE_FRACT)) | |
18269 | (set (match_dup 9) | |
18270 | (unspec:XF [(match_dup 8) (match_dup 4)] | |
18271 | UNSPEC_FSCALE_EXP))])] | |
ba2baa55 | 18272 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 18273 | && flag_unsafe_math_optimizations" |
9d5b9dae | 18274 | { |
9d5b9dae RS |
18275 | int i; |
18276 | ||
18bd082d JH |
18277 | if (optimize_insn_for_size_p ()) |
18278 | FAIL; | |
18279 | ||
e2fc57a3 | 18280 | for (i = 3; i < 10; i++) |
9d5b9dae | 18281 | operands[i] = gen_reg_rtx (XFmode); |
e2fc57a3 | 18282 | |
9d5b9dae RS |
18283 | emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ |
18284 | }) | |
82d397c7 | 18285 | |
e2fc57a3 UB |
18286 | (define_expand "expxf2" |
18287 | [(use (match_operand:XF 0 "register_operand" "")) | |
18288 | (use (match_operand:XF 1 "register_operand" ""))] | |
ba2baa55 | 18289 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 18290 | && flag_unsafe_math_optimizations" |
a251102e | 18291 | { |
18bd082d JH |
18292 | rtx op2; |
18293 | ||
18294 | if (optimize_insn_for_size_p ()) | |
18295 | FAIL; | |
18296 | ||
18297 | op2 = gen_reg_rtx (XFmode); | |
9db27449 | 18298 | emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */ |
a251102e | 18299 | |
9db27449 | 18300 | emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); |
e2fc57a3 | 18301 | DONE; |
a251102e UB |
18302 | }) |
18303 | ||
e2fc57a3 | 18304 | (define_expand "exp<mode>2" |
00188daa UB |
18305 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18306 | (use (match_operand:MODEF 1 "general_operand" ""))] | |
e2fc57a3 UB |
18307 | "TARGET_USE_FANCY_MATH_387 |
18308 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18309 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18310 | && flag_unsafe_math_optimizations" |
a251102e | 18311 | { |
18bd082d JH |
18312 | rtx op0, op1; |
18313 | ||
18314 | if (optimize_insn_for_size_p ()) | |
18315 | FAIL; | |
18316 | ||
18317 | op0 = gen_reg_rtx (XFmode); | |
18318 | op1 = gen_reg_rtx (XFmode); | |
a251102e | 18319 | |
e2fc57a3 UB |
18320 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
18321 | emit_insn (gen_expxf2 (op0, op1)); | |
18322 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
18323 | DONE; | |
a251102e UB |
18324 | }) |
18325 | ||
18326 | (define_expand "exp10xf2" | |
e2fc57a3 UB |
18327 | [(use (match_operand:XF 0 "register_operand" "")) |
18328 | (use (match_operand:XF 1 "register_operand" ""))] | |
ba2baa55 | 18329 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 18330 | && flag_unsafe_math_optimizations" |
a251102e | 18331 | { |
18bd082d JH |
18332 | rtx op2; |
18333 | ||
18334 | if (optimize_insn_for_size_p ()) | |
18335 | FAIL; | |
18336 | ||
18337 | op2 = gen_reg_rtx (XFmode); | |
9db27449 | 18338 | emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */ |
a251102e | 18339 | |
9db27449 | 18340 | emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); |
e2fc57a3 | 18341 | DONE; |
a251102e UB |
18342 | }) |
18343 | ||
e2fc57a3 | 18344 | (define_expand "exp10<mode>2" |
00188daa UB |
18345 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18346 | (use (match_operand:MODEF 1 "general_operand" ""))] | |
e2fc57a3 UB |
18347 | "TARGET_USE_FANCY_MATH_387 |
18348 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18349 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18350 | && flag_unsafe_math_optimizations" |
a251102e | 18351 | { |
18bd082d JH |
18352 | rtx op0, op1; |
18353 | ||
18354 | if (optimize_insn_for_size_p ()) | |
18355 | FAIL; | |
18356 | ||
18357 | op0 = gen_reg_rtx (XFmode); | |
18358 | op1 = gen_reg_rtx (XFmode); | |
a251102e | 18359 | |
e2fc57a3 UB |
18360 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
18361 | emit_insn (gen_exp10xf2 (op0, op1)); | |
18362 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
18363 | DONE; | |
a251102e UB |
18364 | }) |
18365 | ||
18366 | (define_expand "exp2xf2" | |
e2fc57a3 UB |
18367 | [(use (match_operand:XF 0 "register_operand" "")) |
18368 | (use (match_operand:XF 1 "register_operand" ""))] | |
ba2baa55 | 18369 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 18370 | && flag_unsafe_math_optimizations" |
7a8e07c7 | 18371 | { |
18bd082d JH |
18372 | rtx op2; |
18373 | ||
18374 | if (optimize_insn_for_size_p ()) | |
18375 | FAIL; | |
18376 | ||
18377 | op2 = gen_reg_rtx (XFmode); | |
9db27449 | 18378 | emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ |
7a8e07c7 | 18379 | |
9db27449 | 18380 | emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); |
e2fc57a3 | 18381 | DONE; |
7a8e07c7 UB |
18382 | }) |
18383 | ||
e2fc57a3 | 18384 | (define_expand "exp2<mode>2" |
00188daa UB |
18385 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18386 | (use (match_operand:MODEF 1 "general_operand" ""))] | |
e2fc57a3 UB |
18387 | "TARGET_USE_FANCY_MATH_387 |
18388 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18389 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18390 | && flag_unsafe_math_optimizations" |
7a8e07c7 | 18391 | { |
18bd082d JH |
18392 | rtx op0, op1; |
18393 | ||
18394 | if (optimize_insn_for_size_p ()) | |
18395 | FAIL; | |
18396 | ||
18397 | op0 = gen_reg_rtx (XFmode); | |
18398 | op1 = gen_reg_rtx (XFmode); | |
7a8e07c7 | 18399 | |
e2fc57a3 UB |
18400 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
18401 | emit_insn (gen_exp2xf2 (op0, op1)); | |
18402 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
18403 | DONE; | |
7a8e07c7 UB |
18404 | }) |
18405 | ||
18406 | (define_expand "expm1xf2" | |
18407 | [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") | |
18408 | (match_dup 2))) | |
18409 | (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) | |
18410 | (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) | |
6bdcc60c | 18411 | (set (match_dup 9) (float_extend:XF (match_dup 13))) |
7a8e07c7 UB |
18412 | (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) |
18413 | (parallel [(set (match_dup 7) | |
18414 | (unspec:XF [(match_dup 6) (match_dup 4)] | |
18415 | UNSPEC_FSCALE_FRACT)) | |
6bdcc60c | 18416 | (set (match_dup 8) |
7a8e07c7 UB |
18417 | (unspec:XF [(match_dup 6) (match_dup 4)] |
18418 | UNSPEC_FSCALE_EXP))]) | |
18419 | (parallel [(set (match_dup 10) | |
18420 | (unspec:XF [(match_dup 9) (match_dup 8)] | |
18421 | UNSPEC_FSCALE_FRACT)) | |
18422 | (set (match_dup 11) | |
18423 | (unspec:XF [(match_dup 9) (match_dup 8)] | |
18424 | UNSPEC_FSCALE_EXP))]) | |
6bdcc60c UB |
18425 | (set (match_dup 12) (minus:XF (match_dup 10) |
18426 | (float_extend:XF (match_dup 13)))) | |
7a8e07c7 UB |
18427 | (set (match_operand:XF 0 "register_operand" "") |
18428 | (plus:XF (match_dup 12) (match_dup 7)))] | |
ba2baa55 | 18429 | "TARGET_USE_FANCY_MATH_387 |
18bd082d | 18430 | && flag_unsafe_math_optimizations" |
7a8e07c7 | 18431 | { |
7a8e07c7 UB |
18432 | int i; |
18433 | ||
18bd082d JH |
18434 | if (optimize_insn_for_size_p ()) |
18435 | FAIL; | |
18436 | ||
e2fc57a3 | 18437 | for (i = 2; i < 13; i++) |
7a8e07c7 | 18438 | operands[i] = gen_reg_rtx (XFmode); |
6bdcc60c UB |
18439 | |
18440 | operands[13] | |
18441 | = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */ | |
18442 | ||
e2fc57a3 | 18443 | emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ |
7a8e07c7 | 18444 | }) |
c94a75af | 18445 | |
e2fc57a3 | 18446 | (define_expand "expm1<mode>2" |
00188daa UB |
18447 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18448 | (use (match_operand:MODEF 1 "general_operand" ""))] | |
e2fc57a3 UB |
18449 | "TARGET_USE_FANCY_MATH_387 |
18450 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18451 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18452 | && flag_unsafe_math_optimizations" |
c94a75af | 18453 | { |
18bd082d JH |
18454 | rtx op0, op1; |
18455 | ||
18456 | if (optimize_insn_for_size_p ()) | |
18457 | FAIL; | |
18458 | ||
18459 | op0 = gen_reg_rtx (XFmode); | |
18460 | op1 = gen_reg_rtx (XFmode); | |
c94a75af | 18461 | |
e2fc57a3 UB |
18462 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
18463 | emit_insn (gen_expm1xf2 (op0, op1)); | |
18464 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
18465 | DONE; | |
c94a75af UB |
18466 | }) |
18467 | ||
18468 | (define_expand "ldexpxf3" | |
18469 | [(set (match_dup 3) | |
18470 | (float:XF (match_operand:SI 2 "register_operand" ""))) | |
18471 | (parallel [(set (match_operand:XF 0 " register_operand" "") | |
18472 | (unspec:XF [(match_operand:XF 1 "register_operand" "") | |
18473 | (match_dup 3)] | |
18474 | UNSPEC_FSCALE_FRACT)) | |
18475 | (set (match_dup 4) | |
18476 | (unspec:XF [(match_dup 1) (match_dup 3)] | |
18477 | UNSPEC_FSCALE_EXP))])] | |
18478 | "TARGET_USE_FANCY_MATH_387 | |
18bd082d | 18479 | && flag_unsafe_math_optimizations" |
c94a75af | 18480 | { |
18bd082d JH |
18481 | if (optimize_insn_for_size_p ()) |
18482 | FAIL; | |
18483 | ||
e2fc57a3 UB |
18484 | operands[3] = gen_reg_rtx (XFmode); |
18485 | operands[4] = gen_reg_rtx (XFmode); | |
18486 | }) | |
c94a75af | 18487 | |
e2fc57a3 | 18488 | (define_expand "ldexp<mode>3" |
00188daa UB |
18489 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18490 | (use (match_operand:MODEF 1 "general_operand" "")) | |
e2fc57a3 UB |
18491 | (use (match_operand:SI 2 "register_operand" ""))] |
18492 | "TARGET_USE_FANCY_MATH_387 | |
18493 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18494 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18495 | && flag_unsafe_math_optimizations" |
e2fc57a3 | 18496 | { |
18bd082d JH |
18497 | rtx op0, op1; |
18498 | ||
18499 | if (optimize_insn_for_size_p ()) | |
18500 | FAIL; | |
18501 | ||
18502 | op0 = gen_reg_rtx (XFmode); | |
18503 | op1 = gen_reg_rtx (XFmode); | |
e2fc57a3 UB |
18504 | |
18505 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); | |
18506 | emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); | |
18507 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
18508 | DONE; | |
c94a75af | 18509 | }) |
0c0d910d KG |
18510 | |
18511 | (define_expand "scalbxf3" | |
18512 | [(parallel [(set (match_operand:XF 0 " register_operand" "") | |
18513 | (unspec:XF [(match_operand:XF 1 "register_operand" "") | |
18514 | (match_operand:XF 2 "register_operand" "")] | |
18515 | UNSPEC_FSCALE_FRACT)) | |
18516 | (set (match_dup 3) | |
18517 | (unspec:XF [(match_dup 1) (match_dup 2)] | |
18518 | UNSPEC_FSCALE_EXP))])] | |
18519 | "TARGET_USE_FANCY_MATH_387 | |
18bd082d | 18520 | && flag_unsafe_math_optimizations" |
0c0d910d | 18521 | { |
18bd082d JH |
18522 | if (optimize_insn_for_size_p ()) |
18523 | FAIL; | |
18524 | ||
0c0d910d KG |
18525 | operands[3] = gen_reg_rtx (XFmode); |
18526 | }) | |
18527 | ||
18528 | (define_expand "scalb<mode>3" | |
00188daa UB |
18529 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18530 | (use (match_operand:MODEF 1 "general_operand" "")) | |
18531 | (use (match_operand:MODEF 2 "register_operand" ""))] | |
0c0d910d KG |
18532 | "TARGET_USE_FANCY_MATH_387 |
18533 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18534 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18535 | && flag_unsafe_math_optimizations" |
0c0d910d | 18536 | { |
18bd082d JH |
18537 | rtx op0, op1, op2; |
18538 | ||
18539 | if (optimize_insn_for_size_p ()) | |
18540 | FAIL; | |
18541 | ||
18542 | op0 = gen_reg_rtx (XFmode); | |
18543 | op1 = gen_reg_rtx (XFmode); | |
18544 | op2 = gen_reg_rtx (XFmode); | |
0c0d910d KG |
18545 | |
18546 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); | |
18547 | emit_insn (gen_extend<mode>xf2 (op2, operands[2])); | |
18548 | emit_insn (gen_scalbxf3 (op0, op1, op2)); | |
18549 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); | |
18550 | DONE; | |
18551 | }) | |
edeacc14 UB |
18552 | \f |
18553 | ||
f28eb39c | 18554 | (define_insn "sse4_1_round<mode>2" |
00188daa UB |
18555 | [(set (match_operand:MODEF 0 "register_operand" "=x") |
18556 | (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x") | |
18557 | (match_operand:SI 2 "const_0_to_15_operand" "n")] | |
18558 | UNSPEC_ROUND))] | |
04e1d06b | 18559 | "TARGET_ROUND" |
95879c72 | 18560 | "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}" |
f28eb39c UB |
18561 | [(set_attr "type" "ssecvt") |
18562 | (set_attr "prefix_extra" "1") | |
95879c72 | 18563 | (set_attr "prefix" "maybe_vex") |
f28eb39c UB |
18564 | (set_attr "mode" "<MODE>")]) |
18565 | ||
acaaf0c6 | 18566 | (define_insn "rintxf2" |
edeacc14 UB |
18567 | [(set (match_operand:XF 0 "register_operand" "=f") |
18568 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] | |
acaaf0c6 | 18569 | UNSPEC_FRNDINT))] |
ba2baa55 | 18570 | "TARGET_USE_FANCY_MATH_387 |
edeacc14 UB |
18571 | && flag_unsafe_math_optimizations" |
18572 | "frndint" | |
18573 | [(set_attr "type" "fpspc") | |
18574 | (set_attr "mode" "XF")]) | |
18575 | ||
acaaf0c6 | 18576 | (define_expand "rint<mode>2" |
00188daa UB |
18577 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18578 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
c7d32ff6 | 18579 | "(TARGET_USE_FANCY_MATH_387 |
acaaf0c6 UB |
18580 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
18581 | || TARGET_MIX_SSE_I387) | |
c7d32ff6 | 18582 | && flag_unsafe_math_optimizations) |
acaaf0c6 | 18583 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
18bd082d | 18584 | && !flag_trapping_math)" |
c7d32ff6 | 18585 | { |
acaaf0c6 | 18586 | if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
18bd082d | 18587 | && !flag_trapping_math) |
f28eb39c | 18588 | { |
18bd082d JH |
18589 | if (!TARGET_ROUND && optimize_insn_for_size_p ()) |
18590 | FAIL; | |
04e1d06b | 18591 | if (TARGET_ROUND) |
f28eb39c UB |
18592 | emit_insn (gen_sse4_1_round<mode>2 |
18593 | (operands[0], operands[1], GEN_INT (0x04))); | |
18594 | else | |
18595 | ix86_expand_rint (operand0, operand1); | |
18596 | } | |
c7d32ff6 RG |
18597 | else |
18598 | { | |
1d08f955 RG |
18599 | rtx op0 = gen_reg_rtx (XFmode); |
18600 | rtx op1 = gen_reg_rtx (XFmode); | |
edeacc14 | 18601 | |
acaaf0c6 UB |
18602 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
18603 | emit_insn (gen_rintxf2 (op0, op1)); | |
edeacc14 | 18604 | |
acaaf0c6 | 18605 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
c7d32ff6 | 18606 | } |
edeacc14 UB |
18607 | DONE; |
18608 | }) | |
18609 | ||
acaaf0c6 | 18610 | (define_expand "round<mode>2" |
00188daa UB |
18611 | [(match_operand:MODEF 0 "register_operand" "") |
18612 | (match_operand:MODEF 1 "nonimmediate_operand" "")] | |
acaaf0c6 | 18613 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
18bd082d | 18614 | && !flag_trapping_math && !flag_rounding_math" |
097f2964 | 18615 | { |
18bd082d JH |
18616 | if (optimize_insn_for_size_p ()) |
18617 | FAIL; | |
f28eb39c | 18618 | if (TARGET_64BIT || (<MODE>mode != DFmode)) |
097f2964 RG |
18619 | ix86_expand_round (operand0, operand1); |
18620 | else | |
18621 | ix86_expand_rounddf_32 (operand0, operand1); | |
18622 | DONE; | |
18623 | }) | |
18624 | ||
4d06b0a2 | 18625 | (define_insn_and_split "*fistdi2_1" |
00188daa UB |
18626 | [(set (match_operand:DI 0 "nonimmediate_operand" "") |
18627 | (unspec:DI [(match_operand:XF 1 "register_operand" "")] | |
acaaf0c6 | 18628 | UNSPEC_FIST))] |
87bb8864 | 18629 | "TARGET_USE_FANCY_MATH_387 |
87bb8864 UB |
18630 | && !(reload_completed || reload_in_progress)" |
18631 | "#" | |
18632 | "&& 1" | |
18633 | [(const_int 0)] | |
18634 | { | |
18635 | if (memory_operand (operands[0], VOIDmode)) | |
4d06b0a2 | 18636 | emit_insn (gen_fistdi2 (operands[0], operands[1])); |
87bb8864 UB |
18637 | else |
18638 | { | |
4d06b0a2 UB |
18639 | operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); |
18640 | emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], | |
18641 | operands[2])); | |
87bb8864 UB |
18642 | } |
18643 | DONE; | |
18644 | } | |
18645 | [(set_attr "type" "fpspc") | |
4d06b0a2 | 18646 | (set_attr "mode" "DI")]) |
87bb8864 | 18647 | |
6e858d45 UB |
18648 | (define_insn "fistdi2" |
18649 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
18650 | (unspec:DI [(match_operand:XF 1 "register_operand" "f")] | |
acaaf0c6 | 18651 | UNSPEC_FIST)) |
6e858d45 | 18652 | (clobber (match_scratch:XF 2 "=&1f"))] |
bb7f0423 | 18653 | "TARGET_USE_FANCY_MATH_387" |
6e858d45 UB |
18654 | "* return output_fix_trunc (insn, operands, 0);" |
18655 | [(set_attr "type" "fpspc") | |
18656 | (set_attr "mode" "DI")]) | |
18657 | ||
18658 | (define_insn "fistdi2_with_temp" | |
18659 | [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") | |
18660 | (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] | |
acaaf0c6 | 18661 | UNSPEC_FIST)) |
73e8165a | 18662 | (clobber (match_operand:DI 2 "memory_operand" "=X,m")) |
6e858d45 | 18663 | (clobber (match_scratch:XF 3 "=&1f,&1f"))] |
bb7f0423 | 18664 | "TARGET_USE_FANCY_MATH_387" |
6e858d45 UB |
18665 | "#" |
18666 | [(set_attr "type" "fpspc") | |
18667 | (set_attr "mode" "DI")]) | |
18668 | ||
6300f037 | 18669 | (define_split |
6e858d45 UB |
18670 | [(set (match_operand:DI 0 "register_operand" "") |
18671 | (unspec:DI [(match_operand:XF 1 "register_operand" "")] | |
acaaf0c6 | 18672 | UNSPEC_FIST)) |
6e858d45 UB |
18673 | (clobber (match_operand:DI 2 "memory_operand" "")) |
18674 | (clobber (match_scratch 3 ""))] | |
18675 | "reload_completed" | |
18676 | [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) | |
18677 | (clobber (match_dup 3))]) | |
18678 | (set (match_dup 0) (match_dup 2))] | |
18679 | "") | |
18680 | ||
6300f037 | 18681 | (define_split |
6e858d45 UB |
18682 | [(set (match_operand:DI 0 "memory_operand" "") |
18683 | (unspec:DI [(match_operand:XF 1 "register_operand" "")] | |
acaaf0c6 | 18684 | UNSPEC_FIST)) |
6e858d45 UB |
18685 | (clobber (match_operand:DI 2 "memory_operand" "")) |
18686 | (clobber (match_scratch 3 ""))] | |
18687 | "reload_completed" | |
18688 | [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) | |
18689 | (clobber (match_dup 3))])] | |
18690 | "") | |
18691 | ||
4d06b0a2 | 18692 | (define_insn_and_split "*fist<mode>2_1" |
00188daa UB |
18693 | [(set (match_operand:X87MODEI12 0 "register_operand" "") |
18694 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] | |
acaaf0c6 | 18695 | UNSPEC_FIST))] |
4d06b0a2 | 18696 | "TARGET_USE_FANCY_MATH_387 |
4d06b0a2 UB |
18697 | && !(reload_completed || reload_in_progress)" |
18698 | "#" | |
18699 | "&& 1" | |
18700 | [(const_int 0)] | |
18701 | { | |
18702 | operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); | |
18703 | emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], | |
18704 | operands[2])); | |
18705 | DONE; | |
18706 | } | |
18707 | [(set_attr "type" "fpspc") | |
18708 | (set_attr "mode" "<MODE>")]) | |
18709 | ||
6e858d45 UB |
18710 | (define_insn "fist<mode>2" |
18711 | [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") | |
18712 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] | |
acaaf0c6 | 18713 | UNSPEC_FIST))] |
bb7f0423 | 18714 | "TARGET_USE_FANCY_MATH_387" |
6e858d45 UB |
18715 | "* return output_fix_trunc (insn, operands, 0);" |
18716 | [(set_attr "type" "fpspc") | |
18717 | (set_attr "mode" "<MODE>")]) | |
18718 | ||
18719 | (define_insn "fist<mode>2_with_temp" | |
4d06b0a2 UB |
18720 | [(set (match_operand:X87MODEI12 0 "register_operand" "=r") |
18721 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] | |
acaaf0c6 | 18722 | UNSPEC_FIST)) |
4d06b0a2 | 18723 | (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))] |
bb7f0423 | 18724 | "TARGET_USE_FANCY_MATH_387" |
6e858d45 UB |
18725 | "#" |
18726 | [(set_attr "type" "fpspc") | |
18727 | (set_attr "mode" "<MODE>")]) | |
18728 | ||
6300f037 | 18729 | (define_split |
6e858d45 UB |
18730 | [(set (match_operand:X87MODEI12 0 "register_operand" "") |
18731 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] | |
acaaf0c6 | 18732 | UNSPEC_FIST)) |
6e858d45 UB |
18733 | (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] |
18734 | "reload_completed" | |
acaaf0c6 | 18735 | [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST)) |
6e858d45 UB |
18736 | (set (match_dup 0) (match_dup 2))] |
18737 | "") | |
18738 | ||
6300f037 | 18739 | (define_split |
6e858d45 UB |
18740 | [(set (match_operand:X87MODEI12 0 "memory_operand" "") |
18741 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] | |
acaaf0c6 | 18742 | UNSPEC_FIST)) |
cec471db | 18743 | (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] |
6e858d45 | 18744 | "reload_completed" |
acaaf0c6 | 18745 | [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))] |
6e858d45 UB |
18746 | "") |
18747 | ||
bb7f0423 | 18748 | (define_expand "lrintxf<mode>2" |
87bb8864 | 18749 | [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") |
bb7f0423 | 18750 | (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] |
acaaf0c6 | 18751 | UNSPEC_FIST))] |
bb7f0423 RG |
18752 | "TARGET_USE_FANCY_MATH_387" |
18753 | "") | |
18754 | ||
00188daa | 18755 | (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2" |
acaaf0c6 | 18756 | [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "") |
00188daa | 18757 | (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")] |
acaaf0c6 | 18758 | UNSPEC_FIX_NOTRUNC))] |
00188daa | 18759 | "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH |
acaaf0c6 | 18760 | && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)" |
bb7f0423 RG |
18761 | "") |
18762 | ||
00188daa | 18763 | (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2" |
acaaf0c6 | 18764 | [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "") |
00188daa UB |
18765 | (match_operand:MODEF 1 "register_operand" "")] |
18766 | "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH | |
acaaf0c6 | 18767 | && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT) |
18bd082d | 18768 | && !flag_trapping_math && !flag_rounding_math" |
4d81bf84 | 18769 | { |
18bd082d JH |
18770 | if (optimize_insn_for_size_p ()) |
18771 | FAIL; | |
4d81bf84 RG |
18772 | ix86_expand_lround (operand0, operand1); |
18773 | DONE; | |
18774 | }) | |
18775 | ||
c9d3aede UB |
18776 | ;; Rounding mode control word calculation could clobber FLAGS_REG. |
18777 | (define_insn_and_split "frndintxf2_floor" | |
00188daa UB |
18778 | [(set (match_operand:XF 0 "register_operand" "") |
18779 | (unspec:XF [(match_operand:XF 1 "register_operand" "")] | |
c9d3aede UB |
18780 | UNSPEC_FRNDINT_FLOOR)) |
18781 | (clobber (reg:CC FLAGS_REG))] | |
18782 | "TARGET_USE_FANCY_MATH_387 | |
18783 | && flag_unsafe_math_optimizations | |
18784 | && !(reload_completed || reload_in_progress)" | |
18785 | "#" | |
18786 | "&& 1" | |
18787 | [(const_int 0)] | |
18788 | { | |
ff680eb1 | 18789 | ix86_optimize_mode_switching[I387_FLOOR] = 1; |
c9d3aede | 18790 | |
ff680eb1 UB |
18791 | operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); |
18792 | operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); | |
c9d3aede UB |
18793 | |
18794 | emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], | |
18795 | operands[2], operands[3])); | |
18796 | DONE; | |
18797 | } | |
18798 | [(set_attr "type" "frndint") | |
18799 | (set_attr "i387_cw" "floor") | |
18800 | (set_attr "mode" "XF")]) | |
18801 | ||
18802 | (define_insn "frndintxf2_floor_i387" | |
edeacc14 UB |
18803 | [(set (match_operand:XF 0 "register_operand" "=f") |
18804 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] | |
18805 | UNSPEC_FRNDINT_FLOOR)) | |
18806 | (use (match_operand:HI 2 "memory_operand" "m")) | |
18807 | (use (match_operand:HI 3 "memory_operand" "m"))] | |
ba2baa55 | 18808 | "TARGET_USE_FANCY_MATH_387 |
edeacc14 UB |
18809 | && flag_unsafe_math_optimizations" |
18810 | "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" | |
18811 | [(set_attr "type" "frndint") | |
18812 | (set_attr "i387_cw" "floor") | |
18813 | (set_attr "mode" "XF")]) | |
18814 | ||
c9d3aede UB |
18815 | (define_expand "floorxf2" |
18816 | [(use (match_operand:XF 0 "register_operand" "")) | |
18817 | (use (match_operand:XF 1 "register_operand" ""))] | |
18818 | "TARGET_USE_FANCY_MATH_387 | |
18bd082d | 18819 | && flag_unsafe_math_optimizations" |
c9d3aede | 18820 | { |
18bd082d JH |
18821 | if (optimize_insn_for_size_p ()) |
18822 | FAIL; | |
c9d3aede UB |
18823 | emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); |
18824 | DONE; | |
18825 | }) | |
18826 | ||
f28eb39c | 18827 | (define_expand "floor<mode>2" |
00188daa UB |
18828 | [(use (match_operand:MODEF 0 "register_operand" "")) |
18829 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
f28eb39c UB |
18830 | "(TARGET_USE_FANCY_MATH_387 |
18831 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
18832 | || TARGET_MIX_SSE_I387) | |
18bd082d | 18833 | && flag_unsafe_math_optimizations) |
f28eb39c | 18834 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
18bd082d | 18835 | && !flag_trapping_math)" |
edeacc14 | 18836 | { |
f28eb39c UB |
18837 | if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
18838 | && !flag_trapping_math | |
18bd082d | 18839 | && (TARGET_ROUND || optimize_insn_for_speed_p ())) |
d096ecdd | 18840 | { |
18bd082d JH |
18841 | if (!TARGET_ROUND && optimize_insn_for_size_p ()) |
18842 | FAIL; | |
04e1d06b | 18843 | if (TARGET_ROUND) |
f28eb39c UB |
18844 | emit_insn (gen_sse4_1_round<mode>2 |
18845 | (operands[0], operands[1], GEN_INT (0x01))); | |
18846 | else if (TARGET_64BIT || (<MODE>mode != DFmode)) | |
d096ecdd RG |
18847 | ix86_expand_floorceil (operand0, operand1, true); |
18848 | else | |
18849 | ix86_expand_floorceildf_32 (operand0, operand1, true); | |
18850 | } | |
18851 | else | |
18852 | { | |
18bd082d JH |
18853 | rtx op0, op1; |
18854 | ||
18855 | if (optimize_insn_for_size_p ()) | |
18856 | FAIL; | |
edeacc14 | 18857 | |
18bd082d JH |
18858 | op0 = gen_reg_rtx (XFmode); |
18859 | op1 = gen_reg_rtx (XFmode); | |
f28eb39c | 18860 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
d096ecdd | 18861 | emit_insn (gen_frndintxf2_floor (op0, op1)); |
edeacc14 | 18862 | |
f28eb39c | 18863 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
d096ecdd | 18864 | } |
edeacc14 UB |
18865 | DONE; |
18866 | }) | |
18867 | ||
4a927664 | 18868 | (define_insn_and_split "*fist<mode>2_floor_1" |
00188daa UB |
18869 | [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") |
18870 | (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] | |
4a927664 UB |
18871 | UNSPEC_FIST_FLOOR)) |
18872 | (clobber (reg:CC FLAGS_REG))] | |
18873 | "TARGET_USE_FANCY_MATH_387 | |
18874 | && flag_unsafe_math_optimizations | |
18875 | && !(reload_completed || reload_in_progress)" | |
18876 | "#" | |
18877 | "&& 1" | |
18878 | [(const_int 0)] | |
18879 | { | |
ff680eb1 UB |
18880 | ix86_optimize_mode_switching[I387_FLOOR] = 1; |
18881 | ||
18882 | operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); | |
18883 | operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); | |
4a927664 UB |
18884 | if (memory_operand (operands[0], VOIDmode)) |
18885 | emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], | |
18886 | operands[2], operands[3])); | |
18887 | else | |
18888 | { | |
ff680eb1 | 18889 | operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); |
4a927664 UB |
18890 | emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], |
18891 | operands[2], operands[3], | |
18892 | operands[4])); | |
18893 | } | |
18894 | DONE; | |
18895 | } | |
18896 | [(set_attr "type" "fistp") | |
18897 | (set_attr "i387_cw" "floor") | |
18898 | (set_attr "mode" "<MODE>")]) | |
18899 | ||
18900 | (define_insn "fistdi2_floor" | |
18901 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
18902 | (unspec:DI [(match_operand:XF 1 "register_operand" "f")] | |
18903 | UNSPEC_FIST_FLOOR)) | |
18904 | (use (match_operand:HI 2 "memory_operand" "m")) | |
18905 | (use (match_operand:HI 3 "memory_operand" "m")) | |
18906 | (clobber (match_scratch:XF 4 "=&1f"))] | |
18907 | "TARGET_USE_FANCY_MATH_387 | |
18908 | && flag_unsafe_math_optimizations" | |
18909 | "* return output_fix_trunc (insn, operands, 0);" | |
18910 | [(set_attr "type" "fistp") | |
18911 | (set_attr "i387_cw" "floor") | |
18912 | (set_attr "mode" "DI")]) | |
18913 | ||
18914 | (define_insn "fistdi2_floor_with_temp" | |
18915 | [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") | |
18916 | (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] | |
18917 | UNSPEC_FIST_FLOOR)) | |
18918 | (use (match_operand:HI 2 "memory_operand" "m,m")) | |
18919 | (use (match_operand:HI 3 "memory_operand" "m,m")) | |
73e8165a | 18920 | (clobber (match_operand:DI 4 "memory_operand" "=X,m")) |
4a927664 UB |
18921 | (clobber (match_scratch:XF 5 "=&1f,&1f"))] |
18922 | "TARGET_USE_FANCY_MATH_387 | |
18923 | && flag_unsafe_math_optimizations" | |
18924 | "#" | |
18925 | [(set_attr "type" "fistp") | |
18926 | (set_attr "i387_cw" "floor") | |
18927 | (set_attr "mode" "DI")]) | |
18928 | ||
6300f037 | 18929 | (define_split |
4a927664 UB |
18930 | [(set (match_operand:DI 0 "register_operand" "") |
18931 | (unspec:DI [(match_operand:XF 1 "register_operand" "")] | |
18932 | UNSPEC_FIST_FLOOR)) | |
18933 | (use (match_operand:HI 2 "memory_operand" "")) | |
18934 | (use (match_operand:HI 3 "memory_operand" "")) | |
18935 | (clobber (match_operand:DI 4 "memory_operand" "")) | |
18936 | (clobber (match_scratch 5 ""))] | |
18937 | "reload_completed" | |
18938 | [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) | |
18939 | (use (match_dup 2)) | |
18940 | (use (match_dup 3)) | |
18941 | (clobber (match_dup 5))]) | |
18942 | (set (match_dup 0) (match_dup 4))] | |
18943 | "") | |
18944 | ||
6300f037 | 18945 | (define_split |
4a927664 UB |
18946 | [(set (match_operand:DI 0 "memory_operand" "") |
18947 | (unspec:DI [(match_operand:XF 1 "register_operand" "")] | |
18948 | UNSPEC_FIST_FLOOR)) | |
18949 | (use (match_operand:HI 2 "memory_operand" "")) | |
18950 | (use (match_operand:HI 3 "memory_operand" "")) | |
18951 | (clobber (match_operand:DI 4 "memory_operand" "")) | |
18952 | (clobber (match_scratch 5 ""))] | |
18953 | "reload_completed" | |
18954 | [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) | |
18955 | (use (match_dup 2)) | |
18956 | (use (match_dup 3)) | |
18957 | (clobber (match_dup 5))])] | |
18958 | "") | |
18959 | ||
18960 | (define_insn "fist<mode>2_floor" | |
18961 | [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") | |
18962 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] | |
18963 | UNSPEC_FIST_FLOOR)) | |
18964 | (use (match_operand:HI 2 "memory_operand" "m")) | |
18965 | (use (match_operand:HI 3 "memory_operand" "m"))] | |
18966 | "TARGET_USE_FANCY_MATH_387 | |
18967 | && flag_unsafe_math_optimizations" | |
18968 | "* return output_fix_trunc (insn, operands, 0);" | |
18969 | [(set_attr "type" "fistp") | |
18970 | (set_attr "i387_cw" "floor") | |
18971 | (set_attr "mode" "<MODE>")]) | |
18972 | ||
18973 | (define_insn "fist<mode>2_floor_with_temp" | |
18974 | [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") | |
18975 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] | |
18976 | UNSPEC_FIST_FLOOR)) | |
18977 | (use (match_operand:HI 2 "memory_operand" "m,m")) | |
18978 | (use (match_operand:HI 3 "memory_operand" "m,m")) | |
73e8165a | 18979 | (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))] |
4a927664 UB |
18980 | "TARGET_USE_FANCY_MATH_387 |
18981 | && flag_unsafe_math_optimizations" | |
18982 | "#" | |
18983 | [(set_attr "type" "fistp") | |
18984 | (set_attr "i387_cw" "floor") | |
18985 | (set_attr "mode" "<MODE>")]) | |
18986 | ||
6300f037 | 18987 | (define_split |
4a927664 UB |
18988 | [(set (match_operand:X87MODEI12 0 "register_operand" "") |
18989 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] | |
18990 | UNSPEC_FIST_FLOOR)) | |
18991 | (use (match_operand:HI 2 "memory_operand" "")) | |
18992 | (use (match_operand:HI 3 "memory_operand" "")) | |
18993 | (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] | |
18994 | "reload_completed" | |
18995 | [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] | |
18996 | UNSPEC_FIST_FLOOR)) | |
18997 | (use (match_dup 2)) | |
18998 | (use (match_dup 3))]) | |
18999 | (set (match_dup 0) (match_dup 4))] | |
19000 | "") | |
19001 | ||
6300f037 | 19002 | (define_split |
4a927664 UB |
19003 | [(set (match_operand:X87MODEI12 0 "memory_operand" "") |
19004 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] | |
19005 | UNSPEC_FIST_FLOOR)) | |
19006 | (use (match_operand:HI 2 "memory_operand" "")) | |
19007 | (use (match_operand:HI 3 "memory_operand" "")) | |
19008 | (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] | |
19009 | "reload_completed" | |
19010 | [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] | |
19011 | UNSPEC_FIST_FLOOR)) | |
19012 | (use (match_dup 2)) | |
19013 | (use (match_dup 3))])] | |
19014 | "") | |
19015 | ||
c3a4177f | 19016 | (define_expand "lfloorxf<mode>2" |
4a927664 UB |
19017 | [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") |
19018 | (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] | |
19019 | UNSPEC_FIST_FLOOR)) | |
19020 | (clobber (reg:CC FLAGS_REG))])] | |
19021 | "TARGET_USE_FANCY_MATH_387 | |
19022 | && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) | |
19023 | && flag_unsafe_math_optimizations" | |
19024 | "") | |
19025 | ||
c3a4177f RG |
19026 | (define_expand "lfloor<mode>di2" |
19027 | [(match_operand:DI 0 "nonimmediate_operand" "") | |
00188daa | 19028 | (match_operand:MODEF 1 "register_operand" "")] |
c3a4177f | 19029 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT |
18bd082d | 19030 | && !flag_trapping_math" |
c3a4177f | 19031 | { |
18bd082d JH |
19032 | if (optimize_insn_for_size_p ()) |
19033 | FAIL; | |
c3a4177f RG |
19034 | ix86_expand_lfloorceil (operand0, operand1, true); |
19035 | DONE; | |
19036 | }) | |
19037 | ||
19038 | (define_expand "lfloor<mode>si2" | |
19039 | [(match_operand:SI 0 "nonimmediate_operand" "") | |
00188daa | 19040 | (match_operand:MODEF 1 "register_operand" "")] |
c3a4177f | 19041 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
18bd082d | 19042 | && !flag_trapping_math" |
c3a4177f | 19043 | { |
18bd082d JH |
19044 | if (optimize_insn_for_size_p () && TARGET_64BIT) |
19045 | FAIL; | |
c3a4177f RG |
19046 | ix86_expand_lfloorceil (operand0, operand1, true); |
19047 | DONE; | |
19048 | }) | |
19049 | ||
c9d3aede UB |
19050 | ;; Rounding mode control word calculation could clobber FLAGS_REG. |
19051 | (define_insn_and_split "frndintxf2_ceil" | |
00188daa UB |
19052 | [(set (match_operand:XF 0 "register_operand" "") |
19053 | (unspec:XF [(match_operand:XF 1 "register_operand" "")] | |
c9d3aede UB |
19054 | UNSPEC_FRNDINT_CEIL)) |
19055 | (clobber (reg:CC FLAGS_REG))] | |
ba2baa55 | 19056 | "TARGET_USE_FANCY_MATH_387 |
c9d3aede UB |
19057 | && flag_unsafe_math_optimizations |
19058 | && !(reload_completed || reload_in_progress)" | |
19059 | "#" | |
19060 | "&& 1" | |
19061 | [(const_int 0)] | |
edeacc14 | 19062 | { |
ff680eb1 | 19063 | ix86_optimize_mode_switching[I387_CEIL] = 1; |
edeacc14 | 19064 | |
ff680eb1 UB |
19065 | operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); |
19066 | operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); | |
c9d3aede UB |
19067 | |
19068 | emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], | |
19069 | operands[2], operands[3])); | |
edeacc14 | 19070 | DONE; |
c9d3aede UB |
19071 | } |
19072 | [(set_attr "type" "frndint") | |
19073 | (set_attr "i387_cw" "ceil") | |
19074 | (set_attr "mode" "XF")]) | |
edeacc14 | 19075 | |
c9d3aede | 19076 | (define_insn "frndintxf2_ceil_i387" |
edeacc14 UB |
19077 | [(set (match_operand:XF 0 "register_operand" "=f") |
19078 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] | |
19079 | UNSPEC_FRNDINT_CEIL)) | |
19080 | (use (match_operand:HI 2 "memory_operand" "m")) | |
19081 | (use (match_operand:HI 3 "memory_operand" "m"))] | |
ba2baa55 | 19082 | "TARGET_USE_FANCY_MATH_387 |
edeacc14 UB |
19083 | && flag_unsafe_math_optimizations" |
19084 | "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" | |
19085 | [(set_attr "type" "frndint") | |
19086 | (set_attr "i387_cw" "ceil") | |
19087 | (set_attr "mode" "XF")]) | |
19088 | ||
c9d3aede UB |
19089 | (define_expand "ceilxf2" |
19090 | [(use (match_operand:XF 0 "register_operand" "")) | |
19091 | (use (match_operand:XF 1 "register_operand" ""))] | |
19092 | "TARGET_USE_FANCY_MATH_387 | |
18bd082d | 19093 | && flag_unsafe_math_optimizations" |
c9d3aede | 19094 | { |
18bd082d JH |
19095 | if (optimize_insn_for_size_p ()) |
19096 | FAIL; | |
c9d3aede UB |
19097 | emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); |
19098 | DONE; | |
19099 | }) | |
19100 | ||
f28eb39c | 19101 | (define_expand "ceil<mode>2" |
00188daa UB |
19102 | [(use (match_operand:MODEF 0 "register_operand" "")) |
19103 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
f28eb39c UB |
19104 | "(TARGET_USE_FANCY_MATH_387 |
19105 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
19106 | || TARGET_MIX_SSE_I387) | |
18bd082d | 19107 | && flag_unsafe_math_optimizations) |
f28eb39c | 19108 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
18bd082d | 19109 | && !flag_trapping_math)" |
edeacc14 | 19110 | { |
f28eb39c UB |
19111 | if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
19112 | && !flag_trapping_math | |
18bd082d | 19113 | && (TARGET_ROUND || optimize_insn_for_speed_p ())) |
d096ecdd | 19114 | { |
04e1d06b | 19115 | if (TARGET_ROUND) |
f28eb39c UB |
19116 | emit_insn (gen_sse4_1_round<mode>2 |
19117 | (operands[0], operands[1], GEN_INT (0x02))); | |
18bd082d JH |
19118 | else if (optimize_insn_for_size_p ()) |
19119 | FAIL; | |
f28eb39c | 19120 | else if (TARGET_64BIT || (<MODE>mode != DFmode)) |
d096ecdd RG |
19121 | ix86_expand_floorceil (operand0, operand1, false); |
19122 | else | |
19123 | ix86_expand_floorceildf_32 (operand0, operand1, false); | |
19124 | } | |
19125 | else | |
19126 | { | |
18bd082d JH |
19127 | rtx op0, op1; |
19128 | ||
19129 | if (optimize_insn_for_size_p ()) | |
19130 | FAIL; | |
edeacc14 | 19131 | |
18bd082d JH |
19132 | op0 = gen_reg_rtx (XFmode); |
19133 | op1 = gen_reg_rtx (XFmode); | |
f28eb39c | 19134 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
d096ecdd | 19135 | emit_insn (gen_frndintxf2_ceil (op0, op1)); |
edeacc14 | 19136 | |
f28eb39c | 19137 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
d096ecdd | 19138 | } |
edeacc14 UB |
19139 | DONE; |
19140 | }) | |
19141 | ||
4a927664 | 19142 | (define_insn_and_split "*fist<mode>2_ceil_1" |
00188daa UB |
19143 | [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") |
19144 | (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] | |
4a927664 UB |
19145 | UNSPEC_FIST_CEIL)) |
19146 | (clobber (reg:CC FLAGS_REG))] | |
19147 | "TARGET_USE_FANCY_MATH_387 | |
19148 | && flag_unsafe_math_optimizations | |
19149 | && !(reload_completed || reload_in_progress)" | |
19150 | "#" | |
19151 | "&& 1" | |
19152 | [(const_int 0)] | |
19153 | { | |
ff680eb1 UB |
19154 | ix86_optimize_mode_switching[I387_CEIL] = 1; |
19155 | ||
19156 | operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); | |
19157 | operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); | |
4a927664 UB |
19158 | if (memory_operand (operands[0], VOIDmode)) |
19159 | emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], | |
19160 | operands[2], operands[3])); | |
19161 | else | |
19162 | { | |
ff680eb1 | 19163 | operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); |
4a927664 UB |
19164 | emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], |
19165 | operands[2], operands[3], | |
19166 | operands[4])); | |
19167 | } | |
19168 | DONE; | |
19169 | } | |
19170 | [(set_attr "type" "fistp") | |
19171 | (set_attr "i387_cw" "ceil") | |
19172 | (set_attr "mode" "<MODE>")]) | |
19173 | ||
19174 | (define_insn "fistdi2_ceil" | |
19175 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
19176 | (unspec:DI [(match_operand:XF 1 "register_operand" "f")] | |
19177 | UNSPEC_FIST_CEIL)) | |
19178 | (use (match_operand:HI 2 "memory_operand" "m")) | |
19179 | (use (match_operand:HI 3 "memory_operand" "m")) | |
19180 | (clobber (match_scratch:XF 4 "=&1f"))] | |
19181 | "TARGET_USE_FANCY_MATH_387 | |
19182 | && flag_unsafe_math_optimizations" | |
19183 | "* return output_fix_trunc (insn, operands, 0);" | |
19184 | [(set_attr "type" "fistp") | |
19185 | (set_attr "i387_cw" "ceil") | |
19186 | (set_attr "mode" "DI")]) | |
19187 | ||
19188 | (define_insn "fistdi2_ceil_with_temp" | |
19189 | [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") | |
19190 | (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] | |
19191 | UNSPEC_FIST_CEIL)) | |
19192 | (use (match_operand:HI 2 "memory_operand" "m,m")) | |
19193 | (use (match_operand:HI 3 "memory_operand" "m,m")) | |
73e8165a | 19194 | (clobber (match_operand:DI 4 "memory_operand" "=X,m")) |
4a927664 UB |
19195 | (clobber (match_scratch:XF 5 "=&1f,&1f"))] |
19196 | "TARGET_USE_FANCY_MATH_387 | |
19197 | && flag_unsafe_math_optimizations" | |
19198 | "#" | |
19199 | [(set_attr "type" "fistp") | |
19200 | (set_attr "i387_cw" "ceil") | |
19201 | (set_attr "mode" "DI")]) | |
19202 | ||
6300f037 | 19203 | (define_split |
4a927664 UB |
19204 | [(set (match_operand:DI 0 "register_operand" "") |
19205 | (unspec:DI [(match_operand:XF 1 "register_operand" "")] | |
19206 | UNSPEC_FIST_CEIL)) | |
19207 | (use (match_operand:HI 2 "memory_operand" "")) | |
19208 | (use (match_operand:HI 3 "memory_operand" "")) | |
19209 | (clobber (match_operand:DI 4 "memory_operand" "")) | |
19210 | (clobber (match_scratch 5 ""))] | |
19211 | "reload_completed" | |
19212 | [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) | |
19213 | (use (match_dup 2)) | |
19214 | (use (match_dup 3)) | |
19215 | (clobber (match_dup 5))]) | |
19216 | (set (match_dup 0) (match_dup 4))] | |
19217 | "") | |
19218 | ||
6300f037 | 19219 | (define_split |
4a927664 UB |
19220 | [(set (match_operand:DI 0 "memory_operand" "") |
19221 | (unspec:DI [(match_operand:XF 1 "register_operand" "")] | |
19222 | UNSPEC_FIST_CEIL)) | |
19223 | (use (match_operand:HI 2 "memory_operand" "")) | |
19224 | (use (match_operand:HI 3 "memory_operand" "")) | |
19225 | (clobber (match_operand:DI 4 "memory_operand" "")) | |
19226 | (clobber (match_scratch 5 ""))] | |
19227 | "reload_completed" | |
19228 | [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) | |
19229 | (use (match_dup 2)) | |
19230 | (use (match_dup 3)) | |
19231 | (clobber (match_dup 5))])] | |
19232 | "") | |
19233 | ||
19234 | (define_insn "fist<mode>2_ceil" | |
19235 | [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") | |
19236 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] | |
19237 | UNSPEC_FIST_CEIL)) | |
19238 | (use (match_operand:HI 2 "memory_operand" "m")) | |
19239 | (use (match_operand:HI 3 "memory_operand" "m"))] | |
19240 | "TARGET_USE_FANCY_MATH_387 | |
19241 | && flag_unsafe_math_optimizations" | |
19242 | "* return output_fix_trunc (insn, operands, 0);" | |
19243 | [(set_attr "type" "fistp") | |
19244 | (set_attr "i387_cw" "ceil") | |
19245 | (set_attr "mode" "<MODE>")]) | |
19246 | ||
19247 | (define_insn "fist<mode>2_ceil_with_temp" | |
19248 | [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") | |
19249 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] | |
19250 | UNSPEC_FIST_CEIL)) | |
19251 | (use (match_operand:HI 2 "memory_operand" "m,m")) | |
19252 | (use (match_operand:HI 3 "memory_operand" "m,m")) | |
73e8165a | 19253 | (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))] |
4a927664 UB |
19254 | "TARGET_USE_FANCY_MATH_387 |
19255 | && flag_unsafe_math_optimizations" | |
19256 | "#" | |
19257 | [(set_attr "type" "fistp") | |
19258 | (set_attr "i387_cw" "ceil") | |
19259 | (set_attr "mode" "<MODE>")]) | |
19260 | ||
6300f037 | 19261 | (define_split |
4a927664 UB |
19262 | [(set (match_operand:X87MODEI12 0 "register_operand" "") |
19263 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] | |
19264 | UNSPEC_FIST_CEIL)) | |
19265 | (use (match_operand:HI 2 "memory_operand" "")) | |
19266 | (use (match_operand:HI 3 "memory_operand" "")) | |
19267 | (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] | |
19268 | "reload_completed" | |
19269 | [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] | |
19270 | UNSPEC_FIST_CEIL)) | |
19271 | (use (match_dup 2)) | |
19272 | (use (match_dup 3))]) | |
19273 | (set (match_dup 0) (match_dup 4))] | |
19274 | "") | |
19275 | ||
6300f037 | 19276 | (define_split |
4a927664 UB |
19277 | [(set (match_operand:X87MODEI12 0 "memory_operand" "") |
19278 | (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] | |
19279 | UNSPEC_FIST_CEIL)) | |
19280 | (use (match_operand:HI 2 "memory_operand" "")) | |
19281 | (use (match_operand:HI 3 "memory_operand" "")) | |
19282 | (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] | |
19283 | "reload_completed" | |
19284 | [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] | |
19285 | UNSPEC_FIST_CEIL)) | |
19286 | (use (match_dup 2)) | |
19287 | (use (match_dup 3))])] | |
19288 | "") | |
19289 | ||
c3a4177f | 19290 | (define_expand "lceilxf<mode>2" |
4a927664 UB |
19291 | [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") |
19292 | (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] | |
19293 | UNSPEC_FIST_CEIL)) | |
19294 | (clobber (reg:CC FLAGS_REG))])] | |
19295 | "TARGET_USE_FANCY_MATH_387 | |
19296 | && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) | |
19297 | && flag_unsafe_math_optimizations" | |
19298 | "") | |
19299 | ||
c3a4177f RG |
19300 | (define_expand "lceil<mode>di2" |
19301 | [(match_operand:DI 0 "nonimmediate_operand" "") | |
00188daa | 19302 | (match_operand:MODEF 1 "register_operand" "")] |
c3a4177f RG |
19303 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT |
19304 | && !flag_trapping_math" | |
19305 | { | |
19306 | ix86_expand_lfloorceil (operand0, operand1, false); | |
19307 | DONE; | |
19308 | }) | |
19309 | ||
19310 | (define_expand "lceil<mode>si2" | |
19311 | [(match_operand:SI 0 "nonimmediate_operand" "") | |
00188daa | 19312 | (match_operand:MODEF 1 "register_operand" "")] |
c3a4177f RG |
19313 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
19314 | && !flag_trapping_math" | |
19315 | { | |
19316 | ix86_expand_lfloorceil (operand0, operand1, false); | |
19317 | DONE; | |
19318 | }) | |
19319 | ||
c9d3aede UB |
19320 | ;; Rounding mode control word calculation could clobber FLAGS_REG. |
19321 | (define_insn_and_split "frndintxf2_trunc" | |
00188daa UB |
19322 | [(set (match_operand:XF 0 "register_operand" "") |
19323 | (unspec:XF [(match_operand:XF 1 "register_operand" "")] | |
c9d3aede UB |
19324 | UNSPEC_FRNDINT_TRUNC)) |
19325 | (clobber (reg:CC FLAGS_REG))] | |
ba2baa55 | 19326 | "TARGET_USE_FANCY_MATH_387 |
c9d3aede UB |
19327 | && flag_unsafe_math_optimizations |
19328 | && !(reload_completed || reload_in_progress)" | |
19329 | "#" | |
19330 | "&& 1" | |
19331 | [(const_int 0)] | |
edeacc14 | 19332 | { |
ff680eb1 | 19333 | ix86_optimize_mode_switching[I387_TRUNC] = 1; |
edeacc14 | 19334 | |
ff680eb1 UB |
19335 | operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); |
19336 | operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); | |
c9d3aede UB |
19337 | |
19338 | emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], | |
19339 | operands[2], operands[3])); | |
edeacc14 | 19340 | DONE; |
c9d3aede UB |
19341 | } |
19342 | [(set_attr "type" "frndint") | |
19343 | (set_attr "i387_cw" "trunc") | |
19344 | (set_attr "mode" "XF")]) | |
edeacc14 | 19345 | |
c9d3aede | 19346 | (define_insn "frndintxf2_trunc_i387" |
edeacc14 UB |
19347 | [(set (match_operand:XF 0 "register_operand" "=f") |
19348 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] | |
19349 | UNSPEC_FRNDINT_TRUNC)) | |
19350 | (use (match_operand:HI 2 "memory_operand" "m")) | |
19351 | (use (match_operand:HI 3 "memory_operand" "m"))] | |
ba2baa55 | 19352 | "TARGET_USE_FANCY_MATH_387 |
edeacc14 UB |
19353 | && flag_unsafe_math_optimizations" |
19354 | "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" | |
19355 | [(set_attr "type" "frndint") | |
19356 | (set_attr "i387_cw" "trunc") | |
19357 | (set_attr "mode" "XF")]) | |
19358 | ||
c9d3aede UB |
19359 | (define_expand "btruncxf2" |
19360 | [(use (match_operand:XF 0 "register_operand" "")) | |
19361 | (use (match_operand:XF 1 "register_operand" ""))] | |
19362 | "TARGET_USE_FANCY_MATH_387 | |
18bd082d | 19363 | && flag_unsafe_math_optimizations" |
c9d3aede | 19364 | { |
18bd082d JH |
19365 | if (optimize_insn_for_size_p ()) |
19366 | FAIL; | |
c9d3aede UB |
19367 | emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); |
19368 | DONE; | |
19369 | }) | |
19370 | ||
f28eb39c | 19371 | (define_expand "btrunc<mode>2" |
00188daa UB |
19372 | [(use (match_operand:MODEF 0 "register_operand" "")) |
19373 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
f28eb39c UB |
19374 | "(TARGET_USE_FANCY_MATH_387 |
19375 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) | |
19376 | || TARGET_MIX_SSE_I387) | |
18bd082d | 19377 | && flag_unsafe_math_optimizations) |
f28eb39c | 19378 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
18bd082d | 19379 | && !flag_trapping_math)" |
edeacc14 | 19380 | { |
f28eb39c UB |
19381 | if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH |
19382 | && !flag_trapping_math | |
18bd082d | 19383 | && (TARGET_ROUND || optimize_insn_for_speed_p ())) |
044928d6 | 19384 | { |
04e1d06b | 19385 | if (TARGET_ROUND) |
f28eb39c UB |
19386 | emit_insn (gen_sse4_1_round<mode>2 |
19387 | (operands[0], operands[1], GEN_INT (0x03))); | |
18bd082d JH |
19388 | else if (optimize_insn_for_size_p ()) |
19389 | FAIL; | |
f28eb39c | 19390 | else if (TARGET_64BIT || (<MODE>mode != DFmode)) |
044928d6 RG |
19391 | ix86_expand_trunc (operand0, operand1); |
19392 | else | |
19393 | ix86_expand_truncdf_32 (operand0, operand1); | |
19394 | } | |
19395 | else | |
19396 | { | |
18bd082d JH |
19397 | rtx op0, op1; |
19398 | ||
19399 | if (optimize_insn_for_size_p ()) | |
19400 | FAIL; | |
edeacc14 | 19401 | |
18bd082d JH |
19402 | op0 = gen_reg_rtx (XFmode); |
19403 | op1 = gen_reg_rtx (XFmode); | |
f28eb39c | 19404 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
044928d6 | 19405 | emit_insn (gen_frndintxf2_trunc (op0, op1)); |
edeacc14 | 19406 | |
f28eb39c | 19407 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
044928d6 | 19408 | } |
edeacc14 UB |
19409 | DONE; |
19410 | }) | |
19411 | ||
c9d3aede UB |
19412 | ;; Rounding mode control word calculation could clobber FLAGS_REG. |
19413 | (define_insn_and_split "frndintxf2_mask_pm" | |
00188daa UB |
19414 | [(set (match_operand:XF 0 "register_operand" "") |
19415 | (unspec:XF [(match_operand:XF 1 "register_operand" "")] | |
c9d3aede UB |
19416 | UNSPEC_FRNDINT_MASK_PM)) |
19417 | (clobber (reg:CC FLAGS_REG))] | |
ba2baa55 | 19418 | "TARGET_USE_FANCY_MATH_387 |
c9d3aede UB |
19419 | && flag_unsafe_math_optimizations |
19420 | && !(reload_completed || reload_in_progress)" | |
19421 | "#" | |
19422 | "&& 1" | |
19423 | [(const_int 0)] | |
edeacc14 | 19424 | { |
ff680eb1 | 19425 | ix86_optimize_mode_switching[I387_MASK_PM] = 1; |
edeacc14 | 19426 | |
ff680eb1 UB |
19427 | operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); |
19428 | operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); | |
c9d3aede UB |
19429 | |
19430 | emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], | |
19431 | operands[2], operands[3])); | |
edeacc14 | 19432 | DONE; |
c9d3aede UB |
19433 | } |
19434 | [(set_attr "type" "frndint") | |
19435 | (set_attr "i387_cw" "mask_pm") | |
19436 | (set_attr "mode" "XF")]) | |
edeacc14 | 19437 | |
c9d3aede | 19438 | (define_insn "frndintxf2_mask_pm_i387" |
edeacc14 UB |
19439 | [(set (match_operand:XF 0 "register_operand" "=f") |
19440 | (unspec:XF [(match_operand:XF 1 "register_operand" "0")] | |
19441 | UNSPEC_FRNDINT_MASK_PM)) | |
19442 | (use (match_operand:HI 2 "memory_operand" "m")) | |
19443 | (use (match_operand:HI 3 "memory_operand" "m"))] | |
ba2baa55 | 19444 | "TARGET_USE_FANCY_MATH_387 |
edeacc14 UB |
19445 | && flag_unsafe_math_optimizations" |
19446 | "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" | |
19447 | [(set_attr "type" "frndint") | |
19448 | (set_attr "i387_cw" "mask_pm") | |
19449 | (set_attr "mode" "XF")]) | |
19450 | ||
c9d3aede UB |
19451 | (define_expand "nearbyintxf2" |
19452 | [(use (match_operand:XF 0 "register_operand" "")) | |
19453 | (use (match_operand:XF 1 "register_operand" ""))] | |
19454 | "TARGET_USE_FANCY_MATH_387 | |
19455 | && flag_unsafe_math_optimizations" | |
19456 | { | |
19457 | emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); | |
19458 | ||
19459 | DONE; | |
19460 | }) | |
19461 | ||
00188daa UB |
19462 | (define_expand "nearbyint<mode>2" |
19463 | [(use (match_operand:MODEF 0 "register_operand" "")) | |
19464 | (use (match_operand:MODEF 1 "register_operand" ""))] | |
ba2baa55 | 19465 | "TARGET_USE_FANCY_MATH_387 |
00188daa UB |
19466 | && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) |
19467 | || TARGET_MIX_SSE_I387) | |
edeacc14 UB |
19468 | && flag_unsafe_math_optimizations" |
19469 | { | |
19470 | rtx op0 = gen_reg_rtx (XFmode); | |
19471 | rtx op1 = gen_reg_rtx (XFmode); | |
edeacc14 | 19472 | |
00188daa | 19473 | emit_insn (gen_extend<mode>xf2 (op1, operands[1])); |
c9d3aede | 19474 | emit_insn (gen_frndintxf2_mask_pm (op0, op1)); |
edeacc14 | 19475 | |
00188daa | 19476 | emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); |
edeacc14 UB |
19477 | DONE; |
19478 | }) | |
19479 | ||
9ed4207f UB |
19480 | (define_insn "fxam<mode>2_i387" |
19481 | [(set (match_operand:HI 0 "register_operand" "=a") | |
19482 | (unspec:HI | |
19483 | [(match_operand:X87MODEF 1 "register_operand" "f")] | |
19484 | UNSPEC_FXAM))] | |
19485 | "TARGET_USE_FANCY_MATH_387" | |
19486 | "fxam\n\tfnstsw\t%0" | |
19487 | [(set_attr "type" "multi") | |
725fd454 | 19488 | (set_attr "length" "4") |
9ed4207f UB |
19489 | (set_attr "unit" "i387") |
19490 | (set_attr "mode" "<MODE>")]) | |
19491 | ||
6b67572e UB |
19492 | (define_insn_and_split "fxam<mode>2_i387_with_temp" |
19493 | [(set (match_operand:HI 0 "register_operand" "") | |
19494 | (unspec:HI | |
19495 | [(match_operand:MODEF 1 "memory_operand" "")] | |
19496 | UNSPEC_FXAM_MEM))] | |
19497 | "TARGET_USE_FANCY_MATH_387 | |
19498 | && !(reload_completed || reload_in_progress)" | |
19499 | "#" | |
19500 | "&& 1" | |
19501 | [(set (match_dup 2)(match_dup 1)) | |
19502 | (set (match_dup 0) | |
19503 | (unspec:HI [(match_dup 2)] UNSPEC_FXAM))] | |
19504 | { | |
19505 | operands[2] = gen_reg_rtx (<MODE>mode); | |
19506 | ||
19507 | MEM_VOLATILE_P (operands[1]) = 1; | |
19508 | } | |
19509 | [(set_attr "type" "multi") | |
19510 | (set_attr "unit" "i387") | |
19511 | (set_attr "mode" "<MODE>")]) | |
19512 | ||
19513 | (define_expand "isinfxf2" | |
19514 | [(use (match_operand:SI 0 "register_operand" "")) | |
19515 | (use (match_operand:XF 1 "register_operand" ""))] | |
19516 | "TARGET_USE_FANCY_MATH_387 | |
19517 | && TARGET_C99_FUNCTIONS" | |
19518 | { | |
19519 | rtx mask = GEN_INT (0x45); | |
19520 | rtx val = GEN_INT (0x05); | |
19521 | ||
19522 | rtx cond; | |
19523 | ||
19524 | rtx scratch = gen_reg_rtx (HImode); | |
19525 | rtx res = gen_reg_rtx (QImode); | |
19526 | ||
19527 | emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); | |
19528 | ||
19529 | emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); | |
19530 | emit_insn (gen_cmpqi_ext_3 (scratch, val)); | |
19531 | cond = gen_rtx_fmt_ee (EQ, QImode, | |
19532 | gen_rtx_REG (CCmode, FLAGS_REG), | |
19533 | const0_rtx); | |
19534 | emit_insn (gen_rtx_SET (VOIDmode, res, cond)); | |
19535 | emit_insn (gen_zero_extendqisi2 (operands[0], res)); | |
19536 | DONE; | |
19537 | }) | |
19538 | ||
9ed4207f UB |
19539 | (define_expand "isinf<mode>2" |
19540 | [(use (match_operand:SI 0 "register_operand" "")) | |
6b67572e | 19541 | (use (match_operand:MODEF 1 "nonimmediate_operand" ""))] |
9ed4207f | 19542 | "TARGET_USE_FANCY_MATH_387 |
81e864cb | 19543 | && TARGET_C99_FUNCTIONS |
d0c9d431 | 19544 | && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" |
9ed4207f UB |
19545 | { |
19546 | rtx mask = GEN_INT (0x45); | |
19547 | rtx val = GEN_INT (0x05); | |
19548 | ||
19549 | rtx cond; | |
19550 | ||
19551 | rtx scratch = gen_reg_rtx (HImode); | |
19552 | rtx res = gen_reg_rtx (QImode); | |
19553 | ||
6b67572e UB |
19554 | /* Remove excess precision by forcing value through memory. */ |
19555 | if (memory_operand (operands[1], VOIDmode)) | |
19556 | emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1])); | |
19557 | else | |
19558 | { | |
bbbbb16a ILT |
19559 | enum ix86_stack_slot slot = (virtuals_instantiated |
19560 | ? SLOT_TEMP | |
19561 | : SLOT_VIRTUAL); | |
6b67572e UB |
19562 | rtx temp = assign_386_stack_local (<MODE>mode, slot); |
19563 | ||
19564 | emit_move_insn (temp, operands[1]); | |
19565 | emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp)); | |
19566 | } | |
19567 | ||
9ed4207f UB |
19568 | emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); |
19569 | emit_insn (gen_cmpqi_ext_3 (scratch, val)); | |
19570 | cond = gen_rtx_fmt_ee (EQ, QImode, | |
19571 | gen_rtx_REG (CCmode, FLAGS_REG), | |
19572 | const0_rtx); | |
19573 | emit_insn (gen_rtx_SET (VOIDmode, res, cond)); | |
19574 | emit_insn (gen_zero_extendqisi2 (operands[0], res)); | |
19575 | DONE; | |
19576 | }) | |
19577 | ||
d0c9d431 UB |
19578 | (define_expand "signbit<mode>2" |
19579 | [(use (match_operand:SI 0 "register_operand" "")) | |
19580 | (use (match_operand:X87MODEF 1 "register_operand" ""))] | |
19581 | "TARGET_USE_FANCY_MATH_387 | |
19582 | && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" | |
19583 | { | |
19584 | rtx mask = GEN_INT (0x0200); | |
19585 | ||
19586 | rtx scratch = gen_reg_rtx (HImode); | |
19587 | ||
19588 | emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1])); | |
19589 | emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask)); | |
19590 | DONE; | |
19591 | }) | |
e075ae69 RH |
19592 | \f |
19593 | ;; Block operation instructions | |
886c62d1 | 19594 | |
922e3e33 UB |
19595 | (define_insn "cld" |
19596 | [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] | |
19597 | "" | |
19598 | "cld" | |
19599 | [(set_attr "length" "1") | |
19600 | (set_attr "length_immediate" "0") | |
19601 | (set_attr "modrm" "0")]) | |
19602 | ||
70128ad9 | 19603 | (define_expand "movmemsi" |
f90800f8 JH |
19604 | [(use (match_operand:BLK 0 "memory_operand" "")) |
19605 | (use (match_operand:BLK 1 "memory_operand" "")) | |
79f05c19 | 19606 | (use (match_operand:SI 2 "nonmemory_operand" "")) |
079a182e JH |
19607 | (use (match_operand:SI 3 "const_int_operand" "")) |
19608 | (use (match_operand:SI 4 "const_int_operand" "")) | |
19609 | (use (match_operand:SI 5 "const_int_operand" ""))] | |
8c996513 | 19610 | "" |
886c62d1 | 19611 | { |
8c996513 | 19612 | if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3], |
079a182e | 19613 | operands[4], operands[5])) |
0945b39d JH |
19614 | DONE; |
19615 | else | |
19616 | FAIL; | |
0f40f9f7 | 19617 | }) |
79f05c19 | 19618 | |
70128ad9 | 19619 | (define_expand "movmemdi" |
0945b39d JH |
19620 | [(use (match_operand:BLK 0 "memory_operand" "")) |
19621 | (use (match_operand:BLK 1 "memory_operand" "")) | |
19622 | (use (match_operand:DI 2 "nonmemory_operand" "")) | |
079a182e JH |
19623 | (use (match_operand:DI 3 "const_int_operand" "")) |
19624 | (use (match_operand:SI 4 "const_int_operand" "")) | |
19625 | (use (match_operand:SI 5 "const_int_operand" ""))] | |
0945b39d | 19626 | "TARGET_64BIT" |
0945b39d | 19627 | { |
8c996513 | 19628 | if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3], |
079a182e | 19629 | operands[4], operands[5])) |
0945b39d JH |
19630 | DONE; |
19631 | else | |
19632 | FAIL; | |
0f40f9f7 | 19633 | }) |
79f05c19 | 19634 | |
0945b39d JH |
19635 | ;; Most CPUs don't like single string operations |
19636 | ;; Handle this case here to simplify previous expander. | |
79f05c19 | 19637 | |
4e44c1ef JJ |
19638 | (define_expand "strmov" |
19639 | [(set (match_dup 4) (match_operand 3 "memory_operand" "")) | |
19640 | (set (match_operand 1 "memory_operand" "") (match_dup 4)) | |
19641 | (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5)) | |
8bc527af | 19642 | (clobber (reg:CC FLAGS_REG))]) |
4e44c1ef | 19643 | (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6)) |
8bc527af | 19644 | (clobber (reg:CC FLAGS_REG))])] |
79f05c19 | 19645 | "" |
79f05c19 | 19646 | { |
4e44c1ef | 19647 | rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); |
79f05c19 | 19648 | |
4e44c1ef JJ |
19649 | /* If .md ever supports :P for Pmode, these can be directly |
19650 | in the pattern above. */ | |
19651 | operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); | |
19652 | operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); | |
0945b39d | 19653 | |
3c285765 | 19654 | /* Can't use this if the user has appropriated esi or edi. */ |
18bd082d | 19655 | if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) |
ec382b8c | 19656 | && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])) |
886c62d1 | 19657 | { |
4e44c1ef JJ |
19658 | emit_insn (gen_strmov_singleop (operands[0], operands[1], |
19659 | operands[2], operands[3], | |
19660 | operands[5], operands[6])); | |
f90800f8 JH |
19661 | DONE; |
19662 | } | |
886c62d1 | 19663 | |
4e44c1ef | 19664 | operands[4] = gen_reg_rtx (GET_MODE (operands[1])); |
0f40f9f7 | 19665 | }) |
f90800f8 | 19666 | |
4e44c1ef JJ |
19667 | (define_expand "strmov_singleop" |
19668 | [(parallel [(set (match_operand 1 "memory_operand" "") | |
19669 | (match_operand 3 "memory_operand" "")) | |
19670 | (set (match_operand 0 "register_operand" "") | |
19671 | (match_operand 4 "" "")) | |
19672 | (set (match_operand 2 "register_operand" "") | |
90c56b45 | 19673 | (match_operand 5 "" ""))])] |
18bd082d | 19674 | "" |
922e3e33 | 19675 | "ix86_current_function_needs_cld = 1;") |
0945b39d | 19676 | |
4e44c1ef | 19677 | (define_insn "*strmovdi_rex_1" |
0945b39d JH |
19678 | [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) |
19679 | (mem:DI (match_operand:DI 3 "register_operand" "1"))) | |
19680 | (set (match_operand:DI 0 "register_operand" "=D") | |
19681 | (plus:DI (match_dup 2) | |
19682 | (const_int 8))) | |
19683 | (set (match_operand:DI 1 "register_operand" "=S") | |
19684 | (plus:DI (match_dup 3) | |
90c56b45 | 19685 | (const_int 8)))] |
bdfd2026 | 19686 | "TARGET_64BIT" |
0945b39d JH |
19687 | "movsq" |
19688 | [(set_attr "type" "str") | |
19689 | (set_attr "mode" "DI") | |
19690 | (set_attr "memory" "both")]) | |
19691 | ||
4e44c1ef | 19692 | (define_insn "*strmovsi_1" |
79f05c19 JH |
19693 | [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) |
19694 | (mem:SI (match_operand:SI 3 "register_operand" "1"))) | |
19695 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 19696 | (plus:SI (match_dup 2) |
79f05c19 JH |
19697 | (const_int 4))) |
19698 | (set (match_operand:SI 1 "register_operand" "=S") | |
b1cdafbb | 19699 | (plus:SI (match_dup 3) |
90c56b45 | 19700 | (const_int 4)))] |
bdfd2026 | 19701 | "!TARGET_64BIT" |
62d2739a | 19702 | "movs{l|d}" |
0945b39d JH |
19703 | [(set_attr "type" "str") |
19704 | (set_attr "mode" "SI") | |
19705 | (set_attr "memory" "both")]) | |
19706 | ||
4e44c1ef | 19707 | (define_insn "*strmovsi_rex_1" |
0945b39d JH |
19708 | [(set (mem:SI (match_operand:DI 2 "register_operand" "0")) |
19709 | (mem:SI (match_operand:DI 3 "register_operand" "1"))) | |
19710 | (set (match_operand:DI 0 "register_operand" "=D") | |
19711 | (plus:DI (match_dup 2) | |
19712 | (const_int 4))) | |
19713 | (set (match_operand:DI 1 "register_operand" "=S") | |
19714 | (plus:DI (match_dup 3) | |
90c56b45 | 19715 | (const_int 4)))] |
bdfd2026 | 19716 | "TARGET_64BIT" |
62d2739a | 19717 | "movs{l|d}" |
79f05c19 | 19718 | [(set_attr "type" "str") |
6ef67412 | 19719 | (set_attr "mode" "SI") |
79f05c19 JH |
19720 | (set_attr "memory" "both")]) |
19721 | ||
4e44c1ef | 19722 | (define_insn "*strmovhi_1" |
f90800f8 JH |
19723 | [(set (mem:HI (match_operand:SI 2 "register_operand" "0")) |
19724 | (mem:HI (match_operand:SI 3 "register_operand" "1"))) | |
19725 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 19726 | (plus:SI (match_dup 2) |
f90800f8 JH |
19727 | (const_int 2))) |
19728 | (set (match_operand:SI 1 "register_operand" "=S") | |
b1cdafbb | 19729 | (plus:SI (match_dup 3) |
90c56b45 | 19730 | (const_int 2)))] |
bdfd2026 | 19731 | "!TARGET_64BIT" |
0945b39d JH |
19732 | "movsw" |
19733 | [(set_attr "type" "str") | |
19734 | (set_attr "memory" "both") | |
19735 | (set_attr "mode" "HI")]) | |
19736 | ||
4e44c1ef | 19737 | (define_insn "*strmovhi_rex_1" |
0945b39d JH |
19738 | [(set (mem:HI (match_operand:DI 2 "register_operand" "0")) |
19739 | (mem:HI (match_operand:DI 3 "register_operand" "1"))) | |
19740 | (set (match_operand:DI 0 "register_operand" "=D") | |
19741 | (plus:DI (match_dup 2) | |
19742 | (const_int 2))) | |
19743 | (set (match_operand:DI 1 "register_operand" "=S") | |
19744 | (plus:DI (match_dup 3) | |
90c56b45 | 19745 | (const_int 2)))] |
bdfd2026 | 19746 | "TARGET_64BIT" |
f90800f8 JH |
19747 | "movsw" |
19748 | [(set_attr "type" "str") | |
19749 | (set_attr "memory" "both") | |
6ef67412 | 19750 | (set_attr "mode" "HI")]) |
f90800f8 | 19751 | |
4e44c1ef | 19752 | (define_insn "*strmovqi_1" |
f90800f8 JH |
19753 | [(set (mem:QI (match_operand:SI 2 "register_operand" "0")) |
19754 | (mem:QI (match_operand:SI 3 "register_operand" "1"))) | |
19755 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 19756 | (plus:SI (match_dup 2) |
f90800f8 JH |
19757 | (const_int 1))) |
19758 | (set (match_operand:SI 1 "register_operand" "=S") | |
b1cdafbb | 19759 | (plus:SI (match_dup 3) |
90c56b45 | 19760 | (const_int 1)))] |
bdfd2026 | 19761 | "!TARGET_64BIT" |
f90800f8 JH |
19762 | "movsb" |
19763 | [(set_attr "type" "str") | |
6ef67412 JH |
19764 | (set_attr "memory" "both") |
19765 | (set_attr "mode" "QI")]) | |
f90800f8 | 19766 | |
4e44c1ef | 19767 | (define_insn "*strmovqi_rex_1" |
0945b39d JH |
19768 | [(set (mem:QI (match_operand:DI 2 "register_operand" "0")) |
19769 | (mem:QI (match_operand:DI 3 "register_operand" "1"))) | |
19770 | (set (match_operand:DI 0 "register_operand" "=D") | |
19771 | (plus:DI (match_dup 2) | |
19772 | (const_int 1))) | |
19773 | (set (match_operand:DI 1 "register_operand" "=S") | |
19774 | (plus:DI (match_dup 3) | |
90c56b45 | 19775 | (const_int 1)))] |
bdfd2026 | 19776 | "TARGET_64BIT" |
0945b39d JH |
19777 | "movsb" |
19778 | [(set_attr "type" "str") | |
19779 | (set_attr "memory" "both") | |
a952487c | 19780 | (set_attr "prefix_rex" "0") |
0945b39d JH |
19781 | (set_attr "mode" "QI")]) |
19782 | ||
4e44c1ef JJ |
19783 | (define_expand "rep_mov" |
19784 | [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0)) | |
19785 | (set (match_operand 0 "register_operand" "") | |
19786 | (match_operand 5 "" "")) | |
19787 | (set (match_operand 2 "register_operand" "") | |
19788 | (match_operand 6 "" "")) | |
19789 | (set (match_operand 1 "memory_operand" "") | |
19790 | (match_operand 3 "memory_operand" "")) | |
90c56b45 | 19791 | (use (match_dup 4))])] |
4e44c1ef | 19792 | "" |
922e3e33 | 19793 | "ix86_current_function_needs_cld = 1;") |
4e44c1ef JJ |
19794 | |
19795 | (define_insn "*rep_movdi_rex64" | |
0945b39d | 19796 | [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) |
6300f037 | 19797 | (set (match_operand:DI 0 "register_operand" "=D") |
0945b39d JH |
19798 | (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") |
19799 | (const_int 3)) | |
19800 | (match_operand:DI 3 "register_operand" "0"))) | |
6300f037 | 19801 | (set (match_operand:DI 1 "register_operand" "=S") |
0945b39d JH |
19802 | (plus:DI (ashift:DI (match_dup 5) (const_int 3)) |
19803 | (match_operand:DI 4 "register_operand" "1"))) | |
19804 | (set (mem:BLK (match_dup 3)) | |
19805 | (mem:BLK (match_dup 4))) | |
90c56b45 | 19806 | (use (match_dup 5))] |
0945b39d | 19807 | "TARGET_64BIT" |
57c2d13f | 19808 | "rep movsq" |
0945b39d JH |
19809 | [(set_attr "type" "str") |
19810 | (set_attr "prefix_rep" "1") | |
19811 | (set_attr "memory" "both") | |
19812 | (set_attr "mode" "DI")]) | |
19813 | ||
4e44c1ef | 19814 | (define_insn "*rep_movsi" |
f90800f8 | 19815 | [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) |
6300f037 | 19816 | (set (match_operand:SI 0 "register_operand" "=D") |
b1cdafbb JH |
19817 | (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2") |
19818 | (const_int 2)) | |
19819 | (match_operand:SI 3 "register_operand" "0"))) | |
6300f037 | 19820 | (set (match_operand:SI 1 "register_operand" "=S") |
b1cdafbb JH |
19821 | (plus:SI (ashift:SI (match_dup 5) (const_int 2)) |
19822 | (match_operand:SI 4 "register_operand" "1"))) | |
f90800f8 JH |
19823 | (set (mem:BLK (match_dup 3)) |
19824 | (mem:BLK (match_dup 4))) | |
90c56b45 | 19825 | (use (match_dup 5))] |
0945b39d | 19826 | "!TARGET_64BIT" |
57c2d13f | 19827 | "rep movs{l|d}" |
0945b39d JH |
19828 | [(set_attr "type" "str") |
19829 | (set_attr "prefix_rep" "1") | |
19830 | (set_attr "memory" "both") | |
19831 | (set_attr "mode" "SI")]) | |
19832 | ||
4e44c1ef | 19833 | (define_insn "*rep_movsi_rex64" |
0945b39d | 19834 | [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) |
6300f037 | 19835 | (set (match_operand:DI 0 "register_operand" "=D") |
0945b39d JH |
19836 | (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") |
19837 | (const_int 2)) | |
19838 | (match_operand:DI 3 "register_operand" "0"))) | |
6300f037 | 19839 | (set (match_operand:DI 1 "register_operand" "=S") |
0945b39d JH |
19840 | (plus:DI (ashift:DI (match_dup 5) (const_int 2)) |
19841 | (match_operand:DI 4 "register_operand" "1"))) | |
19842 | (set (mem:BLK (match_dup 3)) | |
19843 | (mem:BLK (match_dup 4))) | |
90c56b45 | 19844 | (use (match_dup 5))] |
0945b39d | 19845 | "TARGET_64BIT" |
57c2d13f | 19846 | "rep movs{l|d}" |
f90800f8 | 19847 | [(set_attr "type" "str") |
6ef67412 JH |
19848 | (set_attr "prefix_rep" "1") |
19849 | (set_attr "memory" "both") | |
19850 | (set_attr "mode" "SI")]) | |
f90800f8 | 19851 | |
4e44c1ef | 19852 | (define_insn "*rep_movqi" |
f90800f8 | 19853 | [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) |
6300f037 | 19854 | (set (match_operand:SI 0 "register_operand" "=D") |
b1cdafbb JH |
19855 | (plus:SI (match_operand:SI 3 "register_operand" "0") |
19856 | (match_operand:SI 5 "register_operand" "2"))) | |
6300f037 | 19857 | (set (match_operand:SI 1 "register_operand" "=S") |
b1cdafbb | 19858 | (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5))) |
f90800f8 JH |
19859 | (set (mem:BLK (match_dup 3)) |
19860 | (mem:BLK (match_dup 4))) | |
90c56b45 | 19861 | (use (match_dup 5))] |
0945b39d | 19862 | "!TARGET_64BIT" |
57c2d13f | 19863 | "rep movsb" |
0945b39d JH |
19864 | [(set_attr "type" "str") |
19865 | (set_attr "prefix_rep" "1") | |
19866 | (set_attr "memory" "both") | |
19867 | (set_attr "mode" "SI")]) | |
19868 | ||
4e44c1ef | 19869 | (define_insn "*rep_movqi_rex64" |
0945b39d | 19870 | [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) |
6300f037 | 19871 | (set (match_operand:DI 0 "register_operand" "=D") |
0945b39d JH |
19872 | (plus:DI (match_operand:DI 3 "register_operand" "0") |
19873 | (match_operand:DI 5 "register_operand" "2"))) | |
6300f037 | 19874 | (set (match_operand:DI 1 "register_operand" "=S") |
0945b39d JH |
19875 | (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5))) |
19876 | (set (mem:BLK (match_dup 3)) | |
19877 | (mem:BLK (match_dup 4))) | |
90c56b45 | 19878 | (use (match_dup 5))] |
0945b39d | 19879 | "TARGET_64BIT" |
57c2d13f | 19880 | "rep movsb" |
f90800f8 | 19881 | [(set_attr "type" "str") |
6ef67412 JH |
19882 | (set_attr "prefix_rep" "1") |
19883 | (set_attr "memory" "both") | |
19884 | (set_attr "mode" "SI")]) | |
886c62d1 | 19885 | |
57e84f18 | 19886 | (define_expand "setmemsi" |
e2e52e1b | 19887 | [(use (match_operand:BLK 0 "memory_operand" "")) |
79f05c19 | 19888 | (use (match_operand:SI 1 "nonmemory_operand" "")) |
57e84f18 | 19889 | (use (match_operand 2 "const_int_operand" "")) |
079a182e JH |
19890 | (use (match_operand 3 "const_int_operand" "")) |
19891 | (use (match_operand:SI 4 "const_int_operand" "")) | |
19892 | (use (match_operand:SI 5 "const_int_operand" ""))] | |
0ae40045 | 19893 | "" |
0ae40045 | 19894 | { |
8c996513 JH |
19895 | if (ix86_expand_setmem (operands[0], operands[1], |
19896 | operands[2], operands[3], | |
079a182e | 19897 | operands[4], operands[5])) |
0945b39d JH |
19898 | DONE; |
19899 | else | |
19900 | FAIL; | |
0f40f9f7 | 19901 | }) |
e2e52e1b | 19902 | |
57e84f18 | 19903 | (define_expand "setmemdi" |
0945b39d JH |
19904 | [(use (match_operand:BLK 0 "memory_operand" "")) |
19905 | (use (match_operand:DI 1 "nonmemory_operand" "")) | |
57e84f18 | 19906 | (use (match_operand 2 "const_int_operand" "")) |
8c996513 JH |
19907 | (use (match_operand 3 "const_int_operand" "")) |
19908 | (use (match_operand 4 "const_int_operand" "")) | |
19909 | (use (match_operand 5 "const_int_operand" ""))] | |
0945b39d | 19910 | "TARGET_64BIT" |
0945b39d | 19911 | { |
8c996513 JH |
19912 | if (ix86_expand_setmem (operands[0], operands[1], |
19913 | operands[2], operands[3], | |
079a182e | 19914 | operands[4], operands[5])) |
0945b39d JH |
19915 | DONE; |
19916 | else | |
19917 | FAIL; | |
0f40f9f7 | 19918 | }) |
e2e52e1b | 19919 | |
0945b39d JH |
19920 | ;; Most CPUs don't like single string operations |
19921 | ;; Handle this case here to simplify previous expander. | |
79f05c19 | 19922 | |
4e44c1ef JJ |
19923 | (define_expand "strset" |
19924 | [(set (match_operand 1 "memory_operand" "") | |
19925 | (match_operand 2 "register_operand" "")) | |
19926 | (parallel [(set (match_operand 0 "register_operand" "") | |
19927 | (match_dup 3)) | |
8bc527af | 19928 | (clobber (reg:CC FLAGS_REG))])] |
79f05c19 | 19929 | "" |
79f05c19 | 19930 | { |
4e44c1ef JJ |
19931 | if (GET_MODE (operands[1]) != GET_MODE (operands[2])) |
19932 | operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); | |
79f05c19 | 19933 | |
4e44c1ef JJ |
19934 | /* If .md ever supports :P for Pmode, this can be directly |
19935 | in the pattern above. */ | |
19936 | operands[3] = gen_rtx_PLUS (Pmode, operands[0], | |
19937 | GEN_INT (GET_MODE_SIZE (GET_MODE | |
19938 | (operands[2])))); | |
18bd082d | 19939 | if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) |
0945b39d | 19940 | { |
4e44c1ef JJ |
19941 | emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], |
19942 | operands[3])); | |
0945b39d JH |
19943 | DONE; |
19944 | } | |
0f40f9f7 | 19945 | }) |
0945b39d | 19946 | |
4e44c1ef JJ |
19947 | (define_expand "strset_singleop" |
19948 | [(parallel [(set (match_operand 1 "memory_operand" "") | |
19949 | (match_operand 2 "register_operand" "")) | |
19950 | (set (match_operand 0 "register_operand" "") | |
90c56b45 | 19951 | (match_operand 3 "" ""))])] |
bdfd2026 | 19952 | "" |
922e3e33 | 19953 | "ix86_current_function_needs_cld = 1;") |
0945b39d | 19954 | |
4e44c1ef | 19955 | (define_insn "*strsetdi_rex_1" |
22116d84 L |
19956 | [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) |
19957 | (match_operand:DI 2 "register_operand" "a")) | |
0945b39d JH |
19958 | (set (match_operand:DI 0 "register_operand" "=D") |
19959 | (plus:DI (match_dup 1) | |
90c56b45 | 19960 | (const_int 8)))] |
bdfd2026 | 19961 | "TARGET_64BIT" |
0945b39d JH |
19962 | "stosq" |
19963 | [(set_attr "type" "str") | |
19964 | (set_attr "memory" "store") | |
19965 | (set_attr "mode" "DI")]) | |
19966 | ||
4e44c1ef | 19967 | (define_insn "*strsetsi_1" |
79f05c19 JH |
19968 | [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) |
19969 | (match_operand:SI 2 "register_operand" "a")) | |
19970 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 19971 | (plus:SI (match_dup 1) |
90c56b45 | 19972 | (const_int 4)))] |
bdfd2026 | 19973 | "!TARGET_64BIT" |
62d2739a | 19974 | "stos{l|d}" |
0945b39d JH |
19975 | [(set_attr "type" "str") |
19976 | (set_attr "memory" "store") | |
19977 | (set_attr "mode" "SI")]) | |
19978 | ||
4e44c1ef | 19979 | (define_insn "*strsetsi_rex_1" |
0945b39d JH |
19980 | [(set (mem:SI (match_operand:DI 1 "register_operand" "0")) |
19981 | (match_operand:SI 2 "register_operand" "a")) | |
19982 | (set (match_operand:DI 0 "register_operand" "=D") | |
19983 | (plus:DI (match_dup 1) | |
90c56b45 | 19984 | (const_int 4)))] |
bdfd2026 | 19985 | "TARGET_64BIT" |
62d2739a | 19986 | "stos{l|d}" |
79f05c19 | 19987 | [(set_attr "type" "str") |
6ef67412 JH |
19988 | (set_attr "memory" "store") |
19989 | (set_attr "mode" "SI")]) | |
79f05c19 | 19990 | |
4e44c1ef | 19991 | (define_insn "*strsethi_1" |
e2e52e1b JH |
19992 | [(set (mem:HI (match_operand:SI 1 "register_operand" "0")) |
19993 | (match_operand:HI 2 "register_operand" "a")) | |
19994 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 19995 | (plus:SI (match_dup 1) |
90c56b45 | 19996 | (const_int 2)))] |
bdfd2026 | 19997 | "!TARGET_64BIT" |
0945b39d JH |
19998 | "stosw" |
19999 | [(set_attr "type" "str") | |
20000 | (set_attr "memory" "store") | |
20001 | (set_attr "mode" "HI")]) | |
20002 | ||
4e44c1ef | 20003 | (define_insn "*strsethi_rex_1" |
0945b39d JH |
20004 | [(set (mem:HI (match_operand:DI 1 "register_operand" "0")) |
20005 | (match_operand:HI 2 "register_operand" "a")) | |
20006 | (set (match_operand:DI 0 "register_operand" "=D") | |
20007 | (plus:DI (match_dup 1) | |
90c56b45 | 20008 | (const_int 2)))] |
bdfd2026 | 20009 | "TARGET_64BIT" |
e2e52e1b JH |
20010 | "stosw" |
20011 | [(set_attr "type" "str") | |
20012 | (set_attr "memory" "store") | |
6ef67412 | 20013 | (set_attr "mode" "HI")]) |
e2e52e1b | 20014 | |
4e44c1ef | 20015 | (define_insn "*strsetqi_1" |
e2e52e1b JH |
20016 | [(set (mem:QI (match_operand:SI 1 "register_operand" "0")) |
20017 | (match_operand:QI 2 "register_operand" "a")) | |
20018 | (set (match_operand:SI 0 "register_operand" "=D") | |
b1cdafbb | 20019 | (plus:SI (match_dup 1) |
90c56b45 | 20020 | (const_int 1)))] |
bdfd2026 | 20021 | "!TARGET_64BIT" |
0945b39d JH |
20022 | "stosb" |
20023 | [(set_attr "type" "str") | |
20024 | (set_attr "memory" "store") | |
20025 | (set_attr "mode" "QI")]) | |
20026 | ||
4e44c1ef | 20027 | (define_insn "*strsetqi_rex_1" |
0945b39d JH |
20028 | [(set (mem:QI (match_operand:DI 1 "register_operand" "0")) |
20029 | (match_operand:QI 2 "register_operand" "a")) | |
20030 | (set (match_operand:DI 0 "register_operand" "=D") | |
20031 | (plus:DI (match_dup 1) | |
90c56b45 | 20032 | (const_int 1)))] |
bdfd2026 | 20033 | "TARGET_64BIT" |
e2e52e1b JH |
20034 | "stosb" |
20035 | [(set_attr "type" "str") | |
6ef67412 | 20036 | (set_attr "memory" "store") |
a952487c | 20037 | (set_attr "prefix_rex" "0") |
6ef67412 | 20038 | (set_attr "mode" "QI")]) |
e2e52e1b | 20039 | |
4e44c1ef JJ |
20040 | (define_expand "rep_stos" |
20041 | [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0)) | |
20042 | (set (match_operand 0 "register_operand" "") | |
20043 | (match_operand 4 "" "")) | |
20044 | (set (match_operand 2 "memory_operand" "") (const_int 0)) | |
20045 | (use (match_operand 3 "register_operand" "")) | |
90c56b45 | 20046 | (use (match_dup 1))])] |
4e44c1ef | 20047 | "" |
922e3e33 | 20048 | "ix86_current_function_needs_cld = 1;") |
4e44c1ef JJ |
20049 | |
20050 | (define_insn "*rep_stosdi_rex64" | |
0945b39d | 20051 | [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) |
6300f037 | 20052 | (set (match_operand:DI 0 "register_operand" "=D") |
0945b39d JH |
20053 | (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") |
20054 | (const_int 3)) | |
20055 | (match_operand:DI 3 "register_operand" "0"))) | |
20056 | (set (mem:BLK (match_dup 3)) | |
20057 | (const_int 0)) | |
20058 | (use (match_operand:DI 2 "register_operand" "a")) | |
90c56b45 | 20059 | (use (match_dup 4))] |
0945b39d | 20060 | "TARGET_64BIT" |
57c2d13f | 20061 | "rep stosq" |
0945b39d JH |
20062 | [(set_attr "type" "str") |
20063 | (set_attr "prefix_rep" "1") | |
20064 | (set_attr "memory" "store") | |
20065 | (set_attr "mode" "DI")]) | |
20066 | ||
4e44c1ef | 20067 | (define_insn "*rep_stossi" |
e2e52e1b | 20068 | [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) |
6300f037 | 20069 | (set (match_operand:SI 0 "register_operand" "=D") |
b1cdafbb JH |
20070 | (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1") |
20071 | (const_int 2)) | |
20072 | (match_operand:SI 3 "register_operand" "0"))) | |
e2e52e1b | 20073 | (set (mem:BLK (match_dup 3)) |
0ae40045 | 20074 | (const_int 0)) |
b1cdafbb | 20075 | (use (match_operand:SI 2 "register_operand" "a")) |
90c56b45 | 20076 | (use (match_dup 4))] |
0945b39d | 20077 | "!TARGET_64BIT" |
57c2d13f | 20078 | "rep stos{l|d}" |
0945b39d JH |
20079 | [(set_attr "type" "str") |
20080 | (set_attr "prefix_rep" "1") | |
20081 | (set_attr "memory" "store") | |
20082 | (set_attr "mode" "SI")]) | |
20083 | ||
4e44c1ef | 20084 | (define_insn "*rep_stossi_rex64" |
0945b39d | 20085 | [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) |
6300f037 | 20086 | (set (match_operand:DI 0 "register_operand" "=D") |
0945b39d JH |
20087 | (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") |
20088 | (const_int 2)) | |
20089 | (match_operand:DI 3 "register_operand" "0"))) | |
20090 | (set (mem:BLK (match_dup 3)) | |
20091 | (const_int 0)) | |
20092 | (use (match_operand:SI 2 "register_operand" "a")) | |
90c56b45 | 20093 | (use (match_dup 4))] |
0945b39d | 20094 | "TARGET_64BIT" |
57c2d13f | 20095 | "rep stos{l|d}" |
e2e52e1b | 20096 | [(set_attr "type" "str") |
6ef67412 JH |
20097 | (set_attr "prefix_rep" "1") |
20098 | (set_attr "memory" "store") | |
20099 | (set_attr "mode" "SI")]) | |
0ae40045 | 20100 | |
4e44c1ef | 20101 | (define_insn "*rep_stosqi" |
e2e52e1b | 20102 | [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) |
6300f037 | 20103 | (set (match_operand:SI 0 "register_operand" "=D") |
b1cdafbb JH |
20104 | (plus:SI (match_operand:SI 3 "register_operand" "0") |
20105 | (match_operand:SI 4 "register_operand" "1"))) | |
e2e52e1b JH |
20106 | (set (mem:BLK (match_dup 3)) |
20107 | (const_int 0)) | |
b1cdafbb | 20108 | (use (match_operand:QI 2 "register_operand" "a")) |
90c56b45 | 20109 | (use (match_dup 4))] |
0945b39d | 20110 | "!TARGET_64BIT" |
57c2d13f | 20111 | "rep stosb" |
0945b39d JH |
20112 | [(set_attr "type" "str") |
20113 | (set_attr "prefix_rep" "1") | |
20114 | (set_attr "memory" "store") | |
20115 | (set_attr "mode" "QI")]) | |
20116 | ||
4e44c1ef | 20117 | (define_insn "*rep_stosqi_rex64" |
0945b39d | 20118 | [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) |
6300f037 | 20119 | (set (match_operand:DI 0 "register_operand" "=D") |
0945b39d JH |
20120 | (plus:DI (match_operand:DI 3 "register_operand" "0") |
20121 | (match_operand:DI 4 "register_operand" "1"))) | |
20122 | (set (mem:BLK (match_dup 3)) | |
20123 | (const_int 0)) | |
20124 | (use (match_operand:QI 2 "register_operand" "a")) | |
90c56b45 | 20125 | (use (match_dup 4))] |
0945b39d | 20126 | "TARGET_64BIT" |
57c2d13f | 20127 | "rep stosb" |
e2e52e1b | 20128 | [(set_attr "type" "str") |
6ef67412 JH |
20129 | (set_attr "prefix_rep" "1") |
20130 | (set_attr "memory" "store") | |
a952487c | 20131 | (set_attr "prefix_rex" "0") |
6ef67412 | 20132 | (set_attr "mode" "QI")]) |
0ae40045 | 20133 | |
40c1d5f8 | 20134 | (define_expand "cmpstrnsi" |
e075ae69 RH |
20135 | [(set (match_operand:SI 0 "register_operand" "") |
20136 | (compare:SI (match_operand:BLK 1 "general_operand" "") | |
20137 | (match_operand:BLK 2 "general_operand" ""))) | |
0945b39d JH |
20138 | (use (match_operand 3 "general_operand" "")) |
20139 | (use (match_operand 4 "immediate_operand" ""))] | |
18bd082d | 20140 | "" |
886c62d1 | 20141 | { |
e075ae69 RH |
20142 | rtx addr1, addr2, out, outlow, count, countreg, align; |
20143 | ||
18bd082d JH |
20144 | if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) |
20145 | FAIL; | |
20146 | ||
d0a5295a | 20147 | /* Can't use this if the user has appropriated esi or edi. */ |
ec382b8c | 20148 | if (fixed_regs[SI_REG] || fixed_regs[DI_REG]) |
d0a5295a RH |
20149 | FAIL; |
20150 | ||
e075ae69 | 20151 | out = operands[0]; |
7656aee4 | 20152 | if (!REG_P (out)) |
e075ae69 | 20153 | out = gen_reg_rtx (SImode); |
783cdf65 JVA |
20154 | |
20155 | addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); | |
20156 | addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); | |
4e44c1ef JJ |
20157 | if (addr1 != XEXP (operands[1], 0)) |
20158 | operands[1] = replace_equiv_address_nv (operands[1], addr1); | |
20159 | if (addr2 != XEXP (operands[2], 0)) | |
20160 | operands[2] = replace_equiv_address_nv (operands[2], addr2); | |
20161 | ||
e075ae69 | 20162 | count = operands[3]; |
d24b3457 | 20163 | countreg = ix86_zero_extend_to_Pmode (count); |
e075ae69 RH |
20164 | |
20165 | /* %%% Iff we are testing strict equality, we can use known alignment | |
20166 | to good advantage. This may be possible with combine, particularly | |
20167 | once cc0 is dead. */ | |
20168 | align = operands[4]; | |
783cdf65 | 20169 | |
7656aee4 | 20170 | if (CONST_INT_P (count)) |
e075ae69 RH |
20171 | { |
20172 | if (INTVAL (count) == 0) | |
20173 | { | |
20174 | emit_move_insn (operands[0], const0_rtx); | |
20175 | DONE; | |
20176 | } | |
40c1d5f8 AS |
20177 | emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, |
20178 | operands[1], operands[2])); | |
e075ae69 RH |
20179 | } |
20180 | else | |
e2e52e1b | 20181 | { |
0945b39d | 20182 | if (TARGET_64BIT) |
4e44c1ef | 20183 | emit_insn (gen_cmpdi_1_rex64 (countreg, countreg)); |
0945b39d | 20184 | else |
4e44c1ef | 20185 | emit_insn (gen_cmpsi_1 (countreg, countreg)); |
40c1d5f8 AS |
20186 | emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, |
20187 | operands[1], operands[2])); | |
e2e52e1b | 20188 | } |
e075ae69 RH |
20189 | |
20190 | outlow = gen_lowpart (QImode, out); | |
20191 | emit_insn (gen_cmpintqi (outlow)); | |
20192 | emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); | |
783cdf65 | 20193 | |
e075ae69 RH |
20194 | if (operands[0] != out) |
20195 | emit_move_insn (operands[0], out); | |
783cdf65 | 20196 | |
e075ae69 | 20197 | DONE; |
0f40f9f7 | 20198 | }) |
886c62d1 | 20199 | |
e075ae69 RH |
20200 | ;; Produce a tri-state integer (-1, 0, 1) from condition codes. |
20201 | ||
20202 | (define_expand "cmpintqi" | |
20203 | [(set (match_dup 1) | |
8bc527af | 20204 | (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) |
e075ae69 | 20205 | (set (match_dup 2) |
8bc527af | 20206 | (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) |
e075ae69 RH |
20207 | (parallel [(set (match_operand:QI 0 "register_operand" "") |
20208 | (minus:QI (match_dup 1) | |
20209 | (match_dup 2))) | |
8bc527af | 20210 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 RH |
20211 | "" |
20212 | "operands[1] = gen_reg_rtx (QImode); | |
20213 | operands[2] = gen_reg_rtx (QImode);") | |
20214 | ||
f76e3b05 JVA |
20215 | ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is |
20216 | ;; zero. Emit extra code to make sure that a zero-length compare is EQ. | |
56c0e8fa | 20217 | |
40c1d5f8 | 20218 | (define_expand "cmpstrnqi_nz_1" |
8bc527af | 20219 | [(parallel [(set (reg:CC FLAGS_REG) |
4e44c1ef JJ |
20220 | (compare:CC (match_operand 4 "memory_operand" "") |
20221 | (match_operand 5 "memory_operand" ""))) | |
20222 | (use (match_operand 2 "register_operand" "")) | |
20223 | (use (match_operand:SI 3 "immediate_operand" "")) | |
4e44c1ef JJ |
20224 | (clobber (match_operand 0 "register_operand" "")) |
20225 | (clobber (match_operand 1 "register_operand" "")) | |
20226 | (clobber (match_dup 2))])] | |
20227 | "" | |
922e3e33 | 20228 | "ix86_current_function_needs_cld = 1;") |
4e44c1ef | 20229 | |
40c1d5f8 | 20230 | (define_insn "*cmpstrnqi_nz_1" |
8bc527af | 20231 | [(set (reg:CC FLAGS_REG) |
b1cdafbb JH |
20232 | (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) |
20233 | (mem:BLK (match_operand:SI 5 "register_operand" "1")))) | |
20234 | (use (match_operand:SI 6 "register_operand" "2")) | |
886c62d1 | 20235 | (use (match_operand:SI 3 "immediate_operand" "i")) |
b1cdafbb JH |
20236 | (clobber (match_operand:SI 0 "register_operand" "=S")) |
20237 | (clobber (match_operand:SI 1 "register_operand" "=D")) | |
20238 | (clobber (match_operand:SI 2 "register_operand" "=c"))] | |
0945b39d | 20239 | "!TARGET_64BIT" |
57c2d13f | 20240 | "repz cmpsb" |
0945b39d JH |
20241 | [(set_attr "type" "str") |
20242 | (set_attr "mode" "QI") | |
20243 | (set_attr "prefix_rep" "1")]) | |
20244 | ||
40c1d5f8 | 20245 | (define_insn "*cmpstrnqi_nz_rex_1" |
8bc527af | 20246 | [(set (reg:CC FLAGS_REG) |
0945b39d JH |
20247 | (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) |
20248 | (mem:BLK (match_operand:DI 5 "register_operand" "1")))) | |
20249 | (use (match_operand:DI 6 "register_operand" "2")) | |
20250 | (use (match_operand:SI 3 "immediate_operand" "i")) | |
0945b39d JH |
20251 | (clobber (match_operand:DI 0 "register_operand" "=S")) |
20252 | (clobber (match_operand:DI 1 "register_operand" "=D")) | |
20253 | (clobber (match_operand:DI 2 "register_operand" "=c"))] | |
20254 | "TARGET_64BIT" | |
57c2d13f | 20255 | "repz cmpsb" |
e2e52e1b | 20256 | [(set_attr "type" "str") |
6ef67412 | 20257 | (set_attr "mode" "QI") |
a952487c | 20258 | (set_attr "prefix_rex" "0") |
6ef67412 | 20259 | (set_attr "prefix_rep" "1")]) |
886c62d1 | 20260 | |
e075ae69 | 20261 | ;; The same, but the count is not known to not be zero. |
886c62d1 | 20262 | |
40c1d5f8 | 20263 | (define_expand "cmpstrnqi_1" |
8bc527af | 20264 | [(parallel [(set (reg:CC FLAGS_REG) |
4e44c1ef JJ |
20265 | (if_then_else:CC (ne (match_operand 2 "register_operand" "") |
20266 | (const_int 0)) | |
20267 | (compare:CC (match_operand 4 "memory_operand" "") | |
20268 | (match_operand 5 "memory_operand" "")) | |
20269 | (const_int 0))) | |
20270 | (use (match_operand:SI 3 "immediate_operand" "")) | |
8bc527af | 20271 | (use (reg:CC FLAGS_REG)) |
4e44c1ef JJ |
20272 | (clobber (match_operand 0 "register_operand" "")) |
20273 | (clobber (match_operand 1 "register_operand" "")) | |
20274 | (clobber (match_dup 2))])] | |
20275 | "" | |
922e3e33 | 20276 | "ix86_current_function_needs_cld = 1;") |
4e44c1ef | 20277 | |
40c1d5f8 | 20278 | (define_insn "*cmpstrnqi_1" |
8bc527af | 20279 | [(set (reg:CC FLAGS_REG) |
b1cdafbb | 20280 | (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2") |
e075ae69 | 20281 | (const_int 0)) |
2bed3391 | 20282 | (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) |
b1cdafbb | 20283 | (mem:BLK (match_operand:SI 5 "register_operand" "1"))) |
e075ae69 RH |
20284 | (const_int 0))) |
20285 | (use (match_operand:SI 3 "immediate_operand" "i")) | |
8bc527af | 20286 | (use (reg:CC FLAGS_REG)) |
b1cdafbb JH |
20287 | (clobber (match_operand:SI 0 "register_operand" "=S")) |
20288 | (clobber (match_operand:SI 1 "register_operand" "=D")) | |
20289 | (clobber (match_operand:SI 2 "register_operand" "=c"))] | |
0945b39d | 20290 | "!TARGET_64BIT" |
57c2d13f | 20291 | "repz cmpsb" |
0945b39d JH |
20292 | [(set_attr "type" "str") |
20293 | (set_attr "mode" "QI") | |
20294 | (set_attr "prefix_rep" "1")]) | |
20295 | ||
40c1d5f8 | 20296 | (define_insn "*cmpstrnqi_rex_1" |
8bc527af | 20297 | [(set (reg:CC FLAGS_REG) |
0945b39d JH |
20298 | (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") |
20299 | (const_int 0)) | |
20300 | (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) | |
20301 | (mem:BLK (match_operand:DI 5 "register_operand" "1"))) | |
20302 | (const_int 0))) | |
20303 | (use (match_operand:SI 3 "immediate_operand" "i")) | |
8bc527af | 20304 | (use (reg:CC FLAGS_REG)) |
0945b39d JH |
20305 | (clobber (match_operand:DI 0 "register_operand" "=S")) |
20306 | (clobber (match_operand:DI 1 "register_operand" "=D")) | |
20307 | (clobber (match_operand:DI 2 "register_operand" "=c"))] | |
20308 | "TARGET_64BIT" | |
57c2d13f | 20309 | "repz cmpsb" |
e2e52e1b | 20310 | [(set_attr "type" "str") |
6ef67412 | 20311 | (set_attr "mode" "QI") |
a952487c | 20312 | (set_attr "prefix_rex" "0") |
6ef67412 | 20313 | (set_attr "prefix_rep" "1")]) |
886c62d1 | 20314 | |
e075ae69 RH |
20315 | (define_expand "strlensi" |
20316 | [(set (match_operand:SI 0 "register_operand" "") | |
20317 | (unspec:SI [(match_operand:BLK 1 "general_operand" "") | |
20318 | (match_operand:QI 2 "immediate_operand" "") | |
8ee41eaf | 20319 | (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] |
886c62d1 | 20320 | "" |
886c62d1 | 20321 | { |
0945b39d JH |
20322 | if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) |
20323 | DONE; | |
20324 | else | |
20325 | FAIL; | |
0f40f9f7 | 20326 | }) |
e075ae69 | 20327 | |
0945b39d JH |
20328 | (define_expand "strlendi" |
20329 | [(set (match_operand:DI 0 "register_operand" "") | |
20330 | (unspec:DI [(match_operand:BLK 1 "general_operand" "") | |
20331 | (match_operand:QI 2 "immediate_operand" "") | |
8ee41eaf | 20332 | (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] |
0945b39d | 20333 | "" |
0945b39d JH |
20334 | { |
20335 | if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) | |
20336 | DONE; | |
20337 | else | |
20338 | FAIL; | |
0f40f9f7 | 20339 | }) |
19c3fc24 | 20340 | |
4e44c1ef JJ |
20341 | (define_expand "strlenqi_1" |
20342 | [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" "")) | |
4e44c1ef | 20343 | (clobber (match_operand 1 "register_operand" "")) |
8bc527af | 20344 | (clobber (reg:CC FLAGS_REG))])] |
4e44c1ef | 20345 | "" |
922e3e33 | 20346 | "ix86_current_function_needs_cld = 1;") |
4e44c1ef JJ |
20347 | |
20348 | (define_insn "*strlenqi_1" | |
e075ae69 | 20349 | [(set (match_operand:SI 0 "register_operand" "=&c") |
b1cdafbb | 20350 | (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1")) |
0945b39d | 20351 | (match_operand:QI 2 "register_operand" "a") |
e075ae69 | 20352 | (match_operand:SI 3 "immediate_operand" "i") |
8ee41eaf | 20353 | (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS)) |
b1cdafbb | 20354 | (clobber (match_operand:SI 1 "register_operand" "=D")) |
8bc527af | 20355 | (clobber (reg:CC FLAGS_REG))] |
0945b39d | 20356 | "!TARGET_64BIT" |
57c2d13f | 20357 | "repnz scasb" |
0945b39d JH |
20358 | [(set_attr "type" "str") |
20359 | (set_attr "mode" "QI") | |
20360 | (set_attr "prefix_rep" "1")]) | |
20361 | ||
4e44c1ef | 20362 | (define_insn "*strlenqi_rex_1" |
0945b39d JH |
20363 | [(set (match_operand:DI 0 "register_operand" "=&c") |
20364 | (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) | |
20365 | (match_operand:QI 2 "register_operand" "a") | |
20366 | (match_operand:DI 3 "immediate_operand" "i") | |
8ee41eaf | 20367 | (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS)) |
0945b39d | 20368 | (clobber (match_operand:DI 1 "register_operand" "=D")) |
8bc527af | 20369 | (clobber (reg:CC FLAGS_REG))] |
0945b39d | 20370 | "TARGET_64BIT" |
57c2d13f | 20371 | "repnz scasb" |
e2e52e1b | 20372 | [(set_attr "type" "str") |
6ef67412 | 20373 | (set_attr "mode" "QI") |
a952487c | 20374 | (set_attr "prefix_rex" "0") |
6ef67412 | 20375 | (set_attr "prefix_rep" "1")]) |
a3e991f2 | 20376 | |
40c1d5f8 | 20377 | ;; Peephole optimizations to clean up after cmpstrn*. This should be |
a3e991f2 | 20378 | ;; handled in combine, but it is not currently up to the task. |
40c1d5f8 | 20379 | ;; When used for their truth value, the cmpstrn* expanders generate |
a3e991f2 ZW |
20380 | ;; code like this: |
20381 | ;; | |
20382 | ;; repz cmpsb | |
20383 | ;; seta %al | |
20384 | ;; setb %dl | |
20385 | ;; cmpb %al, %dl | |
20386 | ;; jcc label | |
20387 | ;; | |
20388 | ;; The intermediate three instructions are unnecessary. | |
20389 | ||
40c1d5f8 | 20390 | ;; This one handles cmpstrn*_nz_1... |
a3e991f2 ZW |
20391 | (define_peephole2 |
20392 | [(parallel[ | |
8bc527af | 20393 | (set (reg:CC FLAGS_REG) |
a3e991f2 ZW |
20394 | (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) |
20395 | (mem:BLK (match_operand 5 "register_operand" "")))) | |
20396 | (use (match_operand 6 "register_operand" "")) | |
20397 | (use (match_operand:SI 3 "immediate_operand" "")) | |
a3e991f2 ZW |
20398 | (clobber (match_operand 0 "register_operand" "")) |
20399 | (clobber (match_operand 1 "register_operand" "")) | |
20400 | (clobber (match_operand 2 "register_operand" ""))]) | |
20401 | (set (match_operand:QI 7 "register_operand" "") | |
8bc527af | 20402 | (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) |
a3e991f2 | 20403 | (set (match_operand:QI 8 "register_operand" "") |
8bc527af | 20404 | (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) |
42fabf21 | 20405 | (set (reg FLAGS_REG) |
a3e991f2 ZW |
20406 | (compare (match_dup 7) (match_dup 8))) |
20407 | ] | |
244ec848 | 20408 | "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" |
a3e991f2 | 20409 | [(parallel[ |
8bc527af | 20410 | (set (reg:CC FLAGS_REG) |
a3e991f2 ZW |
20411 | (compare:CC (mem:BLK (match_dup 4)) |
20412 | (mem:BLK (match_dup 5)))) | |
20413 | (use (match_dup 6)) | |
20414 | (use (match_dup 3)) | |
a3e991f2 ZW |
20415 | (clobber (match_dup 0)) |
20416 | (clobber (match_dup 1)) | |
244ec848 | 20417 | (clobber (match_dup 2))])] |
a3e991f2 ZW |
20418 | "") |
20419 | ||
40c1d5f8 | 20420 | ;; ...and this one handles cmpstrn*_1. |
a3e991f2 ZW |
20421 | (define_peephole2 |
20422 | [(parallel[ | |
8bc527af | 20423 | (set (reg:CC FLAGS_REG) |
a3e991f2 ZW |
20424 | (if_then_else:CC (ne (match_operand 6 "register_operand" "") |
20425 | (const_int 0)) | |
20426 | (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) | |
20427 | (mem:BLK (match_operand 5 "register_operand" ""))) | |
20428 | (const_int 0))) | |
20429 | (use (match_operand:SI 3 "immediate_operand" "")) | |
8bc527af | 20430 | (use (reg:CC FLAGS_REG)) |
a3e991f2 ZW |
20431 | (clobber (match_operand 0 "register_operand" "")) |
20432 | (clobber (match_operand 1 "register_operand" "")) | |
20433 | (clobber (match_operand 2 "register_operand" ""))]) | |
20434 | (set (match_operand:QI 7 "register_operand" "") | |
8bc527af | 20435 | (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) |
a3e991f2 | 20436 | (set (match_operand:QI 8 "register_operand" "") |
8bc527af | 20437 | (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) |
42fabf21 | 20438 | (set (reg FLAGS_REG) |
a3e991f2 ZW |
20439 | (compare (match_dup 7) (match_dup 8))) |
20440 | ] | |
244ec848 | 20441 | "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" |
a3e991f2 | 20442 | [(parallel[ |
8bc527af | 20443 | (set (reg:CC FLAGS_REG) |
a3e991f2 ZW |
20444 | (if_then_else:CC (ne (match_dup 6) |
20445 | (const_int 0)) | |
20446 | (compare:CC (mem:BLK (match_dup 4)) | |
20447 | (mem:BLK (match_dup 5))) | |
20448 | (const_int 0))) | |
20449 | (use (match_dup 3)) | |
8bc527af | 20450 | (use (reg:CC FLAGS_REG)) |
a3e991f2 ZW |
20451 | (clobber (match_dup 0)) |
20452 | (clobber (match_dup 1)) | |
244ec848 | 20453 | (clobber (match_dup 2))])] |
a3e991f2 ZW |
20454 | "") |
20455 | ||
20456 | ||
e075ae69 RH |
20457 | \f |
20458 | ;; Conditional move instructions. | |
726e2d54 | 20459 | |
44cf5b6a | 20460 | (define_expand "movdicc" |
885a70fd JH |
20461 | [(set (match_operand:DI 0 "register_operand" "") |
20462 | (if_then_else:DI (match_operand 1 "comparison_operator" "") | |
44cf5b6a JH |
20463 | (match_operand:DI 2 "general_operand" "") |
20464 | (match_operand:DI 3 "general_operand" "")))] | |
885a70fd | 20465 | "TARGET_64BIT" |
85845bb9 | 20466 | "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") |
885a70fd | 20467 | |
e74061a9 | 20468 | (define_insn "x86_movdicc_0_m1_rex64" |
885a70fd | 20469 | [(set (match_operand:DI 0 "register_operand" "=r") |
e6e81735 | 20470 | (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "") |
885a70fd JH |
20471 | (const_int -1) |
20472 | (const_int 0))) | |
8bc527af | 20473 | (clobber (reg:CC FLAGS_REG))] |
885a70fd | 20474 | "TARGET_64BIT" |
0f40f9f7 | 20475 | "sbb{q}\t%0, %0" |
885a70fd JH |
20476 | ; Since we don't have the proper number of operands for an alu insn, |
20477 | ; fill in all the blanks. | |
20478 | [(set_attr "type" "alu") | |
b6837b94 | 20479 | (set_attr "use_carry" "1") |
890d52e8 | 20480 | (set_attr "pent_pair" "pu") |
885a70fd JH |
20481 | (set_attr "memory" "none") |
20482 | (set_attr "imm_disp" "false") | |
20483 | (set_attr "mode" "DI") | |
20484 | (set_attr "length_immediate" "0")]) | |
20485 | ||
0e93e1b4 UB |
20486 | (define_insn "*x86_movdicc_0_m1_se" |
20487 | [(set (match_operand:DI 0 "register_operand" "=r") | |
20488 | (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "") | |
20489 | (const_int 1) | |
20490 | (const_int 0))) | |
20491 | (clobber (reg:CC FLAGS_REG))] | |
20492 | "" | |
20493 | "sbb{q}\t%0, %0" | |
20494 | [(set_attr "type" "alu") | |
b6837b94 | 20495 | (set_attr "use_carry" "1") |
0e93e1b4 UB |
20496 | (set_attr "pent_pair" "pu") |
20497 | (set_attr "memory" "none") | |
20498 | (set_attr "imm_disp" "false") | |
20499 | (set_attr "mode" "DI") | |
20500 | (set_attr "length_immediate" "0")]) | |
20501 | ||
eaa49b49 | 20502 | (define_insn "*movdicc_c_rex64" |
885a70fd | 20503 | [(set (match_operand:DI 0 "register_operand" "=r,r") |
6300f037 | 20504 | (if_then_else:DI (match_operator 1 "ix86_comparison_operator" |
42fabf21 | 20505 | [(reg FLAGS_REG) (const_int 0)]) |
885a70fd JH |
20506 | (match_operand:DI 2 "nonimmediate_operand" "rm,0") |
20507 | (match_operand:DI 3 "nonimmediate_operand" "0,rm")))] | |
20508 | "TARGET_64BIT && TARGET_CMOVE | |
7656aee4 | 20509 | && !(MEM_P (operands[2]) && MEM_P (operands[3]))" |
885a70fd | 20510 | "@ |
048b1c95 JJ |
20511 | cmov%O2%C1\t{%2, %0|%0, %2} |
20512 | cmov%O2%c1\t{%3, %0|%0, %3}" | |
885a70fd JH |
20513 | [(set_attr "type" "icmov") |
20514 | (set_attr "mode" "DI")]) | |
20515 | ||
e075ae69 | 20516 | (define_expand "movsicc" |
6a4a5d95 | 20517 | [(set (match_operand:SI 0 "register_operand" "") |
e075ae69 RH |
20518 | (if_then_else:SI (match_operand 1 "comparison_operator" "") |
20519 | (match_operand:SI 2 "general_operand" "") | |
20520 | (match_operand:SI 3 "general_operand" "")))] | |
20521 | "" | |
85845bb9 | 20522 | "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") |
726e2d54 | 20523 | |
e075ae69 RH |
20524 | ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing |
20525 | ;; the register first winds up with `sbbl $0,reg', which is also weird. | |
20526 | ;; So just document what we're doing explicitly. | |
20527 | ||
20528 | (define_insn "x86_movsicc_0_m1" | |
20529 | [(set (match_operand:SI 0 "register_operand" "=r") | |
e6e81735 | 20530 | (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "") |
e075ae69 RH |
20531 | (const_int -1) |
20532 | (const_int 0))) | |
8bc527af | 20533 | (clobber (reg:CC FLAGS_REG))] |
e075ae69 | 20534 | "" |
0f40f9f7 | 20535 | "sbb{l}\t%0, %0" |
e075ae69 RH |
20536 | ; Since we don't have the proper number of operands for an alu insn, |
20537 | ; fill in all the blanks. | |
20538 | [(set_attr "type" "alu") | |
b6837b94 | 20539 | (set_attr "use_carry" "1") |
890d52e8 | 20540 | (set_attr "pent_pair" "pu") |
e075ae69 RH |
20541 | (set_attr "memory" "none") |
20542 | (set_attr "imm_disp" "false") | |
6ef67412 JH |
20543 | (set_attr "mode" "SI") |
20544 | (set_attr "length_immediate" "0")]) | |
e075ae69 | 20545 | |
0e93e1b4 UB |
20546 | (define_insn "*x86_movsicc_0_m1_se" |
20547 | [(set (match_operand:SI 0 "register_operand" "=r") | |
20548 | (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "") | |
20549 | (const_int 1) | |
20550 | (const_int 0))) | |
20551 | (clobber (reg:CC FLAGS_REG))] | |
20552 | "" | |
20553 | "sbb{l}\t%0, %0" | |
20554 | [(set_attr "type" "alu") | |
b6837b94 | 20555 | (set_attr "use_carry" "1") |
0e93e1b4 UB |
20556 | (set_attr "pent_pair" "pu") |
20557 | (set_attr "memory" "none") | |
20558 | (set_attr "imm_disp" "false") | |
20559 | (set_attr "mode" "SI") | |
20560 | (set_attr "length_immediate" "0")]) | |
20561 | ||
6343a50e | 20562 | (define_insn "*movsicc_noc" |
e075ae69 | 20563 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
6300f037 | 20564 | (if_then_else:SI (match_operator 1 "ix86_comparison_operator" |
42fabf21 | 20565 | [(reg FLAGS_REG) (const_int 0)]) |
e075ae69 RH |
20566 | (match_operand:SI 2 "nonimmediate_operand" "rm,0") |
20567 | (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] | |
d525dfdf | 20568 | "TARGET_CMOVE |
7656aee4 | 20569 | && !(MEM_P (operands[2]) && MEM_P (operands[3]))" |
e075ae69 | 20570 | "@ |
048b1c95 JJ |
20571 | cmov%O2%C1\t{%2, %0|%0, %2} |
20572 | cmov%O2%c1\t{%3, %0|%0, %3}" | |
6ef67412 JH |
20573 | [(set_attr "type" "icmov") |
20574 | (set_attr "mode" "SI")]) | |
726e2d54 | 20575 | |
726e2d54 JW |
20576 | (define_expand "movhicc" |
20577 | [(set (match_operand:HI 0 "register_operand" "") | |
20578 | (if_then_else:HI (match_operand 1 "comparison_operator" "") | |
4977bab6 ZW |
20579 | (match_operand:HI 2 "general_operand" "") |
20580 | (match_operand:HI 3 "general_operand" "")))] | |
20581 | "TARGET_HIMODE_MATH" | |
85845bb9 | 20582 | "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") |
726e2d54 | 20583 | |
6343a50e | 20584 | (define_insn "*movhicc_noc" |
e075ae69 | 20585 | [(set (match_operand:HI 0 "register_operand" "=r,r") |
6300f037 | 20586 | (if_then_else:HI (match_operator 1 "ix86_comparison_operator" |
42fabf21 | 20587 | [(reg FLAGS_REG) (const_int 0)]) |
e075ae69 RH |
20588 | (match_operand:HI 2 "nonimmediate_operand" "rm,0") |
20589 | (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] | |
d525dfdf | 20590 | "TARGET_CMOVE |
7656aee4 | 20591 | && !(MEM_P (operands[2]) && MEM_P (operands[3]))" |
e075ae69 | 20592 | "@ |
048b1c95 JJ |
20593 | cmov%O2%C1\t{%2, %0|%0, %2} |
20594 | cmov%O2%c1\t{%3, %0|%0, %3}" | |
6ef67412 JH |
20595 | [(set_attr "type" "icmov") |
20596 | (set_attr "mode" "HI")]) | |
726e2d54 | 20597 | |
4977bab6 ZW |
20598 | (define_expand "movqicc" |
20599 | [(set (match_operand:QI 0 "register_operand" "") | |
20600 | (if_then_else:QI (match_operand 1 "comparison_operator" "") | |
20601 | (match_operand:QI 2 "general_operand" "") | |
20602 | (match_operand:QI 3 "general_operand" "")))] | |
20603 | "TARGET_QIMODE_MATH" | |
85845bb9 | 20604 | "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") |
4977bab6 ZW |
20605 | |
20606 | (define_insn_and_split "*movqicc_noc" | |
20607 | [(set (match_operand:QI 0 "register_operand" "=r,r") | |
6300f037 | 20608 | (if_then_else:QI (match_operator 1 "ix86_comparison_operator" |
eaa49b49 RH |
20609 | [(match_operand 4 "flags_reg_operand" "") |
20610 | (const_int 0)]) | |
4977bab6 ZW |
20611 | (match_operand:QI 2 "register_operand" "r,0") |
20612 | (match_operand:QI 3 "register_operand" "0,r")))] | |
20613 | "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" | |
20614 | "#" | |
20615 | "&& reload_completed" | |
20616 | [(set (match_dup 0) | |
20617 | (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) | |
20618 | (match_dup 2) | |
20619 | (match_dup 3)))] | |
20620 | "operands[0] = gen_lowpart (SImode, operands[0]); | |
20621 | operands[2] = gen_lowpart (SImode, operands[2]); | |
20622 | operands[3] = gen_lowpart (SImode, operands[3]);" | |
20623 | [(set_attr "type" "icmov") | |
20624 | (set_attr "mode" "SI")]) | |
20625 | ||
85845bb9 UB |
20626 | (define_expand "mov<mode>cc" |
20627 | [(set (match_operand:X87MODEF 0 "register_operand" "") | |
20628 | (if_then_else:X87MODEF | |
20629 | (match_operand 1 "comparison_operator" "") | |
20630 | (match_operand:X87MODEF 2 "register_operand" "") | |
20631 | (match_operand:X87MODEF 3 "register_operand" "")))] | |
20632 | "(TARGET_80387 && TARGET_CMOVE) | |
20633 | || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" | |
20634 | "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;") | |
726e2d54 | 20635 | |
eaa49b49 | 20636 | (define_insn "*movsfcc_1_387" |
b5c82fa1 | 20637 | [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") |
6300f037 | 20638 | (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" |
42fabf21 | 20639 | [(reg FLAGS_REG) (const_int 0)]) |
b5c82fa1 PB |
20640 | (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") |
20641 | (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] | |
eaa49b49 | 20642 | "TARGET_80387 && TARGET_CMOVE |
7656aee4 | 20643 | && !(MEM_P (operands[2]) && MEM_P (operands[3]))" |
e075ae69 | 20644 | "@ |
0f40f9f7 ZW |
20645 | fcmov%F1\t{%2, %0|%0, %2} |
20646 | fcmov%f1\t{%3, %0|%0, %3} | |
048b1c95 JJ |
20647 | cmov%O2%C1\t{%2, %0|%0, %2} |
20648 | cmov%O2%c1\t{%3, %0|%0, %3}" | |
7093c9ea JH |
20649 | [(set_attr "type" "fcmov,fcmov,icmov,icmov") |
20650 | (set_attr "mode" "SF,SF,SI,SI")]) | |
56710e42 | 20651 | |
6343a50e | 20652 | (define_insn "*movdfcc_1" |
b5c82fa1 | 20653 | [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") |
6300f037 | 20654 | (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" |
42fabf21 | 20655 | [(reg FLAGS_REG) (const_int 0)]) |
b5c82fa1 PB |
20656 | (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") |
20657 | (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] | |
eaa49b49 | 20658 | "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE |
7656aee4 | 20659 | && !(MEM_P (operands[2]) && MEM_P (operands[3]))" |
e075ae69 | 20660 | "@ |
0f40f9f7 ZW |
20661 | fcmov%F1\t{%2, %0|%0, %2} |
20662 | fcmov%f1\t{%3, %0|%0, %3} | |
7093c9ea JH |
20663 | # |
20664 | #" | |
20665 | [(set_attr "type" "fcmov,fcmov,multi,multi") | |
6ef67412 | 20666 | (set_attr "mode" "DF")]) |
56710e42 | 20667 | |
1e07edd3 | 20668 | (define_insn "*movdfcc_1_rex64" |
b5c82fa1 | 20669 | [(set (match_operand:DF 0 "register_operand" "=f,f,r,r") |
6300f037 | 20670 | (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" |
42fabf21 | 20671 | [(reg FLAGS_REG) (const_int 0)]) |
b5c82fa1 PB |
20672 | (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") |
20673 | (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] | |
eaa49b49 | 20674 | "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE |
7656aee4 | 20675 | && !(MEM_P (operands[2]) && MEM_P (operands[3]))" |
1e07edd3 | 20676 | "@ |
0f40f9f7 ZW |
20677 | fcmov%F1\t{%2, %0|%0, %2} |
20678 | fcmov%f1\t{%3, %0|%0, %3} | |
048b1c95 JJ |
20679 | cmov%O2%C1\t{%2, %0|%0, %2} |
20680 | cmov%O2%c1\t{%3, %0|%0, %3}" | |
1e07edd3 JH |
20681 | [(set_attr "type" "fcmov,fcmov,icmov,icmov") |
20682 | (set_attr "mode" "DF")]) | |
20683 | ||
7093c9ea | 20684 | (define_split |
c3c637e3 | 20685 | [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "") |
6300f037 | 20686 | (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" |
eaa49b49 RH |
20687 | [(match_operand 4 "flags_reg_operand" "") |
20688 | (const_int 0)]) | |
7093c9ea JH |
20689 | (match_operand:DF 2 "nonimmediate_operand" "") |
20690 | (match_operand:DF 3 "nonimmediate_operand" "")))] | |
c3c637e3 | 20691 | "!TARGET_64BIT && reload_completed" |
7093c9ea JH |
20692 | [(set (match_dup 2) |
20693 | (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) | |
20694 | (match_dup 5) | |
c2b814b9 | 20695 | (match_dup 6))) |
7093c9ea JH |
20696 | (set (match_dup 3) |
20697 | (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) | |
c2b814b9 | 20698 | (match_dup 7) |
7093c9ea | 20699 | (match_dup 8)))] |
c2b814b9 UB |
20700 | "split_di (&operands[2], 2, &operands[5], &operands[7]); |
20701 | split_di (&operands[0], 1, &operands[2], &operands[3]);") | |
7093c9ea | 20702 | |
6343a50e | 20703 | (define_insn "*movxfcc_1" |
3aeae608 | 20704 | [(set (match_operand:XF 0 "register_operand" "=f,f") |
6300f037 | 20705 | (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" |
42fabf21 | 20706 | [(reg FLAGS_REG) (const_int 0)]) |
3aeae608 JW |
20707 | (match_operand:XF 2 "register_operand" "f,0") |
20708 | (match_operand:XF 3 "register_operand" "0,f")))] | |
eaa49b49 | 20709 | "TARGET_80387 && TARGET_CMOVE" |
2b589241 | 20710 | "@ |
0f40f9f7 ZW |
20711 | fcmov%F1\t{%2, %0|%0, %2} |
20712 | fcmov%f1\t{%3, %0|%0, %3}" | |
2b589241 JH |
20713 | [(set_attr "type" "fcmov") |
20714 | (set_attr "mode" "XF")]) | |
7ada6625 | 20715 | |
d51fba8e DR |
20716 | ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict |
20717 | ;; the scalar versions to have only XMM registers as operands. | |
20718 | ||
04e1d06b MM |
20719 | ;; SSE5 conditional move |
20720 | (define_insn "*sse5_pcmov_<mode>" | |
d51fba8e | 20721 | [(set (match_operand:MODEF 0 "register_operand" "=x,x") |
4f3f76e6 | 20722 | (if_then_else:MODEF |
d51fba8e DR |
20723 | (match_operand:MODEF 1 "register_operand" "x,0") |
20724 | (match_operand:MODEF 2 "register_operand" "0,x") | |
20725 | (match_operand:MODEF 3 "register_operand" "x,x")))] | |
f258e5e5 | 20726 | "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)" |
04e1d06b MM |
20727 | "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}" |
20728 | [(set_attr "type" "sse4arg")]) | |
20729 | ||
eaa49b49 | 20730 | ;; These versions of the min/max patterns are intentionally ignorant of |
35fd3193 | 20731 | ;; their behavior wrt -0.0 and NaN (via the commutative operand mark). |
eaa49b49 RH |
20732 | ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator |
20733 | ;; are undefined in this condition, we're certain this is correct. | |
7ada6625 | 20734 | |
95879c72 L |
20735 | (define_insn "*avx_<code><mode>3" |
20736 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
20737 | (smaxmin:MODEF | |
20738 | (match_operand:MODEF 1 "nonimmediate_operand" "%x") | |
20739 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")))] | |
20740 | "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" | |
20741 | "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}" | |
20742 | [(set_attr "type" "sseadd") | |
20743 | (set_attr "prefix" "vex") | |
20744 | (set_attr "mode" "<MODE>")]) | |
20745 | ||
78e8956b | 20746 | (define_insn "<code><mode>3" |
d6023b50 | 20747 | [(set (match_operand:MODEF 0 "register_operand" "=x") |
78e8956b | 20748 | (smaxmin:MODEF |
d6023b50 UB |
20749 | (match_operand:MODEF 1 "nonimmediate_operand" "%0") |
20750 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")))] | |
20751 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" | |
78e8956b | 20752 | "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}" |
ab8efbd8 | 20753 | [(set_attr "type" "sseadd") |
d6023b50 | 20754 | (set_attr "mode" "<MODE>")]) |
ab8efbd8 RH |
20755 | |
20756 | ;; These versions of the min/max patterns implement exactly the operations | |
20757 | ;; min = (op1 < op2 ? op1 : op2) | |
20758 | ;; max = (!(op1 < op2) ? op1 : op2) | |
20759 | ;; Their operands are not commutative, and thus they may be used in the | |
20760 | ;; presence of -0.0 and NaN. | |
20761 | ||
95879c72 L |
20762 | (define_insn "*avx_ieee_smin<mode>3" |
20763 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
20764 | (unspec:MODEF | |
20765 | [(match_operand:MODEF 1 "register_operand" "x") | |
20766 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")] | |
20767 | UNSPEC_IEEE_MIN))] | |
20768 | "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" | |
20769 | "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}" | |
20770 | [(set_attr "type" "sseadd") | |
20771 | (set_attr "prefix" "vex") | |
20772 | (set_attr "mode" "<MODE>")]) | |
20773 | ||
d6023b50 UB |
20774 | (define_insn "*ieee_smin<mode>3" |
20775 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
20776 | (unspec:MODEF | |
20777 | [(match_operand:MODEF 1 "register_operand" "0") | |
20778 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")] | |
20779 | UNSPEC_IEEE_MIN))] | |
20780 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" | |
20781 | "mins<ssemodefsuffix>\t{%2, %0|%0, %2}" | |
ab8efbd8 | 20782 | [(set_attr "type" "sseadd") |
d6023b50 | 20783 | (set_attr "mode" "<MODE>")]) |
ab8efbd8 | 20784 | |
95879c72 L |
20785 | (define_insn "*avx_ieee_smax<mode>3" |
20786 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
20787 | (unspec:MODEF | |
20788 | [(match_operand:MODEF 1 "register_operand" "0") | |
20789 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")] | |
20790 | UNSPEC_IEEE_MAX))] | |
20791 | "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" | |
20792 | "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}" | |
20793 | [(set_attr "type" "sseadd") | |
20794 | (set_attr "prefix" "vex") | |
20795 | (set_attr "mode" "<MODE>")]) | |
20796 | ||
d6023b50 UB |
20797 | (define_insn "*ieee_smax<mode>3" |
20798 | [(set (match_operand:MODEF 0 "register_operand" "=x") | |
20799 | (unspec:MODEF | |
20800 | [(match_operand:MODEF 1 "register_operand" "0") | |
20801 | (match_operand:MODEF 2 "nonimmediate_operand" "xm")] | |
20802 | UNSPEC_IEEE_MAX))] | |
20803 | "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" | |
20804 | "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}" | |
eaa49b49 | 20805 | [(set_attr "type" "sseadd") |
d6023b50 | 20806 | (set_attr "mode" "<MODE>")]) |
7ada6625 | 20807 | |
bab1de0a PB |
20808 | ;; Make two stack loads independent: |
20809 | ;; fld aa fld aa | |
20810 | ;; fld %st(0) -> fld bb | |
20811 | ;; fmul bb fmul %st(1), %st | |
20812 | ;; | |
20813 | ;; Actually we only match the last two instructions for simplicity. | |
20814 | (define_peephole2 | |
20815 | [(set (match_operand 0 "fp_register_operand" "") | |
20816 | (match_operand 1 "fp_register_operand" "")) | |
20817 | (set (match_dup 0) | |
20818 | (match_operator 2 "binary_fp_operator" | |
20819 | [(match_dup 0) | |
20820 | (match_operand 3 "memory_operand" "")]))] | |
20821 | "REGNO (operands[0]) != REGNO (operands[1])" | |
20822 | [(set (match_dup 0) (match_dup 3)) | |
20823 | (set (match_dup 0) (match_dup 4))] | |
20824 | ||
20825 | ;; The % modifier is not operational anymore in peephole2's, so we have to | |
20826 | ;; swap the operands manually in the case of addition and multiplication. | |
20827 | "if (COMMUTATIVE_ARITH_P (operands[2])) | |
20828 | operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), | |
20829 | operands[0], operands[1]); | |
20830 | else | |
20831 | operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), | |
20832 | operands[1], operands[0]);") | |
20833 | ||
7b52eede | 20834 | ;; Conditional addition patterns |
62d2739a UB |
20835 | (define_expand "add<mode>cc" |
20836 | [(match_operand:SWI 0 "register_operand" "") | |
7b52eede | 20837 | (match_operand 1 "comparison_operator" "") |
62d2739a UB |
20838 | (match_operand:SWI 2 "register_operand" "") |
20839 | (match_operand:SWI 3 "const_int_operand" "")] | |
7b52eede | 20840 | "" |
85845bb9 | 20841 | "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;") |
7b52eede | 20842 | |
e075ae69 RH |
20843 | \f |
20844 | ;; Misc patterns (?) | |
726e2d54 | 20845 | |
f5143c46 | 20846 | ;; This pattern exists to put a dependency on all ebp-based memory accesses. |
e075ae69 | 20847 | ;; Otherwise there will be nothing to keep |
6300f037 | 20848 | ;; |
e075ae69 RH |
20849 | ;; [(set (reg ebp) (reg esp))] |
20850 | ;; [(set (reg esp) (plus (reg esp) (const_int -160000))) | |
20851 | ;; (clobber (eflags)] | |
20852 | ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] | |
20853 | ;; | |
20854 | ;; in proper program order. | |
b19ee4bd | 20855 | (define_insn "pro_epilogue_adjust_stack_1" |
1c71e60e JH |
20856 | [(set (match_operand:SI 0 "register_operand" "=r,r") |
20857 | (plus:SI (match_operand:SI 1 "register_operand" "0,r") | |
20858 | (match_operand:SI 2 "immediate_operand" "i,i"))) | |
8bc527af | 20859 | (clobber (reg:CC FLAGS_REG)) |
f2042df3 | 20860 | (clobber (mem:BLK (scratch)))] |
8362f420 | 20861 | "!TARGET_64BIT" |
e075ae69 | 20862 | { |
1c71e60e | 20863 | switch (get_attr_type (insn)) |
e075ae69 | 20864 | { |
1c71e60e | 20865 | case TYPE_IMOV: |
0f40f9f7 | 20866 | return "mov{l}\t{%1, %0|%0, %1}"; |
1c71e60e JH |
20867 | |
20868 | case TYPE_ALU: | |
7656aee4 | 20869 | if (CONST_INT_P (operands[2]) |
1c71e60e JH |
20870 | && (INTVAL (operands[2]) == 128 |
20871 | || (INTVAL (operands[2]) < 0 | |
20872 | && INTVAL (operands[2]) != -128))) | |
20873 | { | |
20874 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 20875 | return "sub{l}\t{%2, %0|%0, %2}"; |
1c71e60e | 20876 | } |
0f40f9f7 | 20877 | return "add{l}\t{%2, %0|%0, %2}"; |
1c71e60e JH |
20878 | |
20879 | case TYPE_LEA: | |
20880 | operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); | |
0f40f9f7 | 20881 | return "lea{l}\t{%a2, %0|%0, %a2}"; |
1c71e60e JH |
20882 | |
20883 | default: | |
7637e42c | 20884 | gcc_unreachable (); |
e075ae69 | 20885 | } |
0f40f9f7 | 20886 | } |
1c71e60e | 20887 | [(set (attr "type") |
b6837b94 JY |
20888 | (cond [(and (eq_attr "alternative" "0") |
20889 | (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0))) | |
1c71e60e JH |
20890 | (const_string "alu") |
20891 | (match_operand:SI 2 "const0_operand" "") | |
20892 | (const_string "imov") | |
20893 | ] | |
6ef67412 | 20894 | (const_string "lea"))) |
a952487c JJ |
20895 | (set (attr "length_immediate") |
20896 | (cond [(eq_attr "type" "imov") | |
20897 | (const_string "0") | |
20898 | (and (eq_attr "type" "alu") | |
20899 | (match_operand 2 "const128_operand" "")) | |
20900 | (const_string "1") | |
20901 | ] | |
20902 | (const_string "*"))) | |
6ef67412 | 20903 | (set_attr "mode" "SI")]) |
578b58f5 | 20904 | |
8362f420 JH |
20905 | (define_insn "pro_epilogue_adjust_stack_rex64" |
20906 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
20907 | (plus:DI (match_operand:DI 1 "register_operand" "0,r") | |
20908 | (match_operand:DI 2 "x86_64_immediate_operand" "e,e"))) | |
8bc527af | 20909 | (clobber (reg:CC FLAGS_REG)) |
f2042df3 | 20910 | (clobber (mem:BLK (scratch)))] |
8362f420 | 20911 | "TARGET_64BIT" |
8362f420 JH |
20912 | { |
20913 | switch (get_attr_type (insn)) | |
20914 | { | |
20915 | case TYPE_IMOV: | |
0f40f9f7 | 20916 | return "mov{q}\t{%1, %0|%0, %1}"; |
8362f420 JH |
20917 | |
20918 | case TYPE_ALU: | |
7656aee4 | 20919 | if (CONST_INT_P (operands[2]) |
b19ee4bd JJ |
20920 | /* Avoid overflows. */ |
20921 | && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) | |
8362f420 JH |
20922 | && (INTVAL (operands[2]) == 128 |
20923 | || (INTVAL (operands[2]) < 0 | |
20924 | && INTVAL (operands[2]) != -128))) | |
20925 | { | |
20926 | operands[2] = GEN_INT (-INTVAL (operands[2])); | |
0f40f9f7 | 20927 | return "sub{q}\t{%2, %0|%0, %2}"; |
8362f420 | 20928 | } |
0f40f9f7 | 20929 | return "add{q}\t{%2, %0|%0, %2}"; |
8362f420 JH |
20930 | |
20931 | case TYPE_LEA: | |
20932 | operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); | |
0f40f9f7 | 20933 | return "lea{q}\t{%a2, %0|%0, %a2}"; |
8362f420 JH |
20934 | |
20935 | default: | |
7637e42c | 20936 | gcc_unreachable (); |
8362f420 | 20937 | } |
0f40f9f7 | 20938 | } |
8362f420 | 20939 | [(set (attr "type") |
b6837b94 JY |
20940 | (cond [(and (eq_attr "alternative" "0") |
20941 | (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0))) | |
8362f420 JH |
20942 | (const_string "alu") |
20943 | (match_operand:DI 2 "const0_operand" "") | |
20944 | (const_string "imov") | |
20945 | ] | |
20946 | (const_string "lea"))) | |
a952487c JJ |
20947 | (set (attr "length_immediate") |
20948 | (cond [(eq_attr "type" "imov") | |
20949 | (const_string "0") | |
20950 | (and (eq_attr "type" "alu") | |
20951 | (match_operand 2 "const128_operand" "")) | |
20952 | (const_string "1") | |
20953 | ] | |
20954 | (const_string "*"))) | |
8362f420 JH |
20955 | (set_attr "mode" "DI")]) |
20956 | ||
b19ee4bd JJ |
20957 | (define_insn "pro_epilogue_adjust_stack_rex64_2" |
20958 | [(set (match_operand:DI 0 "register_operand" "=r,r") | |
20959 | (plus:DI (match_operand:DI 1 "register_operand" "0,r") | |
20960 | (match_operand:DI 3 "immediate_operand" "i,i"))) | |
20961 | (use (match_operand:DI 2 "register_operand" "r,r")) | |
8bc527af | 20962 | (clobber (reg:CC FLAGS_REG)) |
b19ee4bd JJ |
20963 | (clobber (mem:BLK (scratch)))] |
20964 | "TARGET_64BIT" | |
20965 | { | |
20966 | switch (get_attr_type (insn)) | |
20967 | { | |
20968 | case TYPE_ALU: | |
20969 | return "add{q}\t{%2, %0|%0, %2}"; | |
20970 | ||
20971 | case TYPE_LEA: | |
20972 | operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]); | |
20973 | return "lea{q}\t{%a2, %0|%0, %a2}"; | |
20974 | ||
20975 | default: | |
7637e42c | 20976 | gcc_unreachable (); |
b19ee4bd JJ |
20977 | } |
20978 | } | |
20979 | [(set_attr "type" "alu,lea") | |
20980 | (set_attr "mode" "DI")]) | |
8362f420 | 20981 | |
ccf8e764 | 20982 | (define_insn "allocate_stack_worker_32" |
6ea90eb7 JJ |
20983 | [(set (match_operand:SI 0 "register_operand" "=a") |
20984 | (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")] | |
20985 | UNSPECV_STACK_PROBE)) | |
20986 | (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1))) | |
8bc527af | 20987 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 20988 | "!TARGET_64BIT && TARGET_STACK_PROBE" |
ab65b56b | 20989 | "call\t___chkstk" |
885a70fd JH |
20990 | [(set_attr "type" "multi") |
20991 | (set_attr "length" "5")]) | |
20992 | ||
ccf8e764 | 20993 | (define_insn "allocate_stack_worker_64" |
6ea90eb7 JJ |
20994 | [(set (match_operand:DI 0 "register_operand" "=a") |
20995 | (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")] | |
20996 | UNSPECV_STACK_PROBE)) | |
20997 | (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1))) | |
ccf8e764 RH |
20998 | (clobber (reg:DI R10_REG)) |
20999 | (clobber (reg:DI R11_REG)) | |
8bc527af | 21000 | (clobber (reg:CC FLAGS_REG))] |
1b0c37d7 | 21001 | "TARGET_64BIT && TARGET_STACK_PROBE" |
ccf8e764 | 21002 | "call\t___chkstk" |
e075ae69 RH |
21003 | [(set_attr "type" "multi") |
21004 | (set_attr "length" "5")]) | |
578b58f5 RK |
21005 | |
21006 | (define_expand "allocate_stack" | |
ccf8e764 RH |
21007 | [(match_operand 0 "register_operand" "") |
21008 | (match_operand 1 "general_operand" "")] | |
e075ae69 | 21009 | "TARGET_STACK_PROBE" |
578b58f5 | 21010 | { |
ccf8e764 RH |
21011 | rtx x; |
21012 | ||
21013 | #ifndef CHECK_STACK_LIMIT | |
21014 | #define CHECK_STACK_LIMIT 0 | |
21015 | #endif | |
21016 | ||
21017 | if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1]) | |
e9a25f70 | 21018 | && INTVAL (operands[1]) < CHECK_STACK_LIMIT) |
ccf8e764 RH |
21019 | { |
21020 | x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1], | |
21021 | stack_pointer_rtx, 0, OPTAB_DIRECT); | |
21022 | if (x != stack_pointer_rtx) | |
21023 | emit_move_insn (stack_pointer_rtx, x); | |
21024 | } | |
6300f037 | 21025 | else |
ccf8e764 RH |
21026 | { |
21027 | x = copy_to_mode_reg (Pmode, operands[1]); | |
21028 | if (TARGET_64BIT) | |
6ea90eb7 | 21029 | x = gen_allocate_stack_worker_64 (x, x); |
ccf8e764 | 21030 | else |
6ea90eb7 | 21031 | x = gen_allocate_stack_worker_32 (x, x); |
ccf8e764 RH |
21032 | emit_insn (x); |
21033 | } | |
578b58f5 | 21034 | |
e9a25f70 JL |
21035 | emit_move_insn (operands[0], virtual_stack_dynamic_rtx); |
21036 | DONE; | |
0f40f9f7 | 21037 | }) |
e31ca113 | 21038 | |
fb754025 AG |
21039 | (define_expand "builtin_setjmp_receiver" |
21040 | [(label_ref (match_operand 0 "" ""))] | |
1b0c37d7 | 21041 | "!TARGET_64BIT && flag_pic" |
fb754025 | 21042 | { |
08a6a74b | 21043 | #if TARGET_MACHO |
7d072037 SH |
21044 | if (TARGET_MACHO) |
21045 | { | |
21046 | rtx xops[3]; | |
21047 | rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); | |
21048 | rtx label_rtx = gen_label_rtx (); | |
21049 | emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); | |
7d072037 | 21050 | xops[0] = xops[1] = picreg; |
08a6a74b | 21051 | xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx)); |
7d072037 SH |
21052 | ix86_expand_binary_operator (MINUS, SImode, xops); |
21053 | } | |
21054 | else | |
08a6a74b | 21055 | #endif |
7d072037 | 21056 | emit_insn (gen_set_got (pic_offset_table_rtx)); |
fb754025 | 21057 | DONE; |
0f40f9f7 | 21058 | }) |
e9e80858 JH |
21059 | \f |
21060 | ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. | |
21061 | ||
21062 | (define_split | |
21063 | [(set (match_operand 0 "register_operand" "") | |
21064 | (match_operator 3 "promotable_binary_operator" | |
21065 | [(match_operand 1 "register_operand" "") | |
2247f6ed | 21066 | (match_operand 2 "aligned_operand" "")])) |
8bc527af | 21067 | (clobber (reg:CC FLAGS_REG))] |
e9e80858 | 21068 | "! TARGET_PARTIAL_REG_STALL && reload_completed |
6300f037 | 21069 | && ((GET_MODE (operands[0]) == HImode |
3debdc1e | 21070 | && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX) |
f38840db | 21071 | /* ??? next two lines just !satisfies_constraint_K (...) */ |
7656aee4 | 21072 | || !CONST_INT_P (operands[2]) |
f38840db | 21073 | || satisfies_constraint_K (operands[2]))) |
6300f037 | 21074 | || (GET_MODE (operands[0]) == QImode |
3debdc1e | 21075 | && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))" |
e9e80858 JH |
21076 | [(parallel [(set (match_dup 0) |
21077 | (match_op_dup 3 [(match_dup 1) (match_dup 2)])) | |
8bc527af | 21078 | (clobber (reg:CC FLAGS_REG))])] |
e9e80858 JH |
21079 | "operands[0] = gen_lowpart (SImode, operands[0]); |
21080 | operands[1] = gen_lowpart (SImode, operands[1]); | |
21081 | if (GET_CODE (operands[3]) != ASHIFT) | |
21082 | operands[2] = gen_lowpart (SImode, operands[2]); | |
dbbbbf3b | 21083 | PUT_MODE (operands[3], SImode);") |
e9e80858 | 21084 | |
d2fc7725 EB |
21085 | ; Promote the QImode tests, as i386 has encoding of the AND |
21086 | ; instruction with 32-bit sign-extended immediate and thus the | |
21087 | ; instruction size is unchanged, except in the %eax case for | |
21088 | ; which it is increased by one byte, hence the ! optimize_size. | |
e9e80858 | 21089 | (define_split |
25da5dc7 RH |
21090 | [(set (match_operand 0 "flags_reg_operand" "") |
21091 | (match_operator 2 "compare_operator" | |
21092 | [(and (match_operand 3 "aligned_operand" "") | |
21093 | (match_operand 4 "const_int_operand" "")) | |
21094 | (const_int 0)])) | |
21095 | (set (match_operand 1 "register_operand" "") | |
21096 | (and (match_dup 3) (match_dup 4)))] | |
e9e80858 | 21097 | "! TARGET_PARTIAL_REG_STALL && reload_completed |
3debdc1e | 21098 | && optimize_insn_for_speed_p () |
25da5dc7 | 21099 | && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) |
d5d5d289 L |
21100 | || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode)) |
21101 | /* Ensure that the operand will remain sign-extended immediate. */ | |
21102 | && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)" | |
25da5dc7 RH |
21103 | [(parallel [(set (match_dup 0) |
21104 | (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) | |
21105 | (const_int 0)])) | |
21106 | (set (match_dup 1) | |
21107 | (and:SI (match_dup 3) (match_dup 4)))])] | |
21108 | { | |
21109 | operands[4] | |
21110 | = gen_int_mode (INTVAL (operands[4]) | |
21111 | & GET_MODE_MASK (GET_MODE (operands[1])), SImode); | |
21112 | operands[1] = gen_lowpart (SImode, operands[1]); | |
21113 | operands[3] = gen_lowpart (SImode, operands[3]); | |
21114 | }) | |
e9e80858 | 21115 | |
d2fc7725 EB |
21116 | ; Don't promote the QImode tests, as i386 doesn't have encoding of |
21117 | ; the TEST instruction with 32-bit sign-extended immediate and thus | |
21118 | ; the instruction size would at least double, which is not what we | |
21119 | ; want even with ! optimize_size. | |
e9e80858 | 21120 | (define_split |
25da5dc7 RH |
21121 | [(set (match_operand 0 "flags_reg_operand" "") |
21122 | (match_operator 1 "compare_operator" | |
21123 | [(and (match_operand:HI 2 "aligned_operand" "") | |
21124 | (match_operand:HI 3 "const_int_operand" "")) | |
21125 | (const_int 0)]))] | |
e9e80858 | 21126 | "! TARGET_PARTIAL_REG_STALL && reload_completed |
d2fc7725 | 21127 | && ! TARGET_FAST_PREFIX |
b2077fd2 | 21128 | && optimize_insn_for_speed_p () |
d5d5d289 L |
21129 | /* Ensure that the operand will remain sign-extended immediate. */ |
21130 | && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)" | |
25da5dc7 RH |
21131 | [(set (match_dup 0) |
21132 | (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) | |
21133 | (const_int 0)]))] | |
21134 | { | |
21135 | operands[3] | |
21136 | = gen_int_mode (INTVAL (operands[3]) | |
21137 | & GET_MODE_MASK (GET_MODE (operands[2])), SImode); | |
21138 | operands[2] = gen_lowpart (SImode, operands[2]); | |
21139 | }) | |
e9e80858 JH |
21140 | |
21141 | (define_split | |
21142 | [(set (match_operand 0 "register_operand" "") | |
21143 | (neg (match_operand 1 "register_operand" ""))) | |
8bc527af | 21144 | (clobber (reg:CC FLAGS_REG))] |
e9e80858 JH |
21145 | "! TARGET_PARTIAL_REG_STALL && reload_completed |
21146 | && (GET_MODE (operands[0]) == HImode | |
6300f037 | 21147 | || (GET_MODE (operands[0]) == QImode |
b2077fd2 JH |
21148 | && (TARGET_PROMOTE_QImode |
21149 | || optimize_insn_for_size_p ())))" | |
e9e80858 JH |
21150 | [(parallel [(set (match_dup 0) |
21151 | (neg:SI (match_dup 1))) | |
8bc527af | 21152 | (clobber (reg:CC FLAGS_REG))])] |
e9e80858 JH |
21153 | "operands[0] = gen_lowpart (SImode, operands[0]); |
21154 | operands[1] = gen_lowpart (SImode, operands[1]);") | |
21155 | ||
21156 | (define_split | |
21157 | [(set (match_operand 0 "register_operand" "") | |
21158 | (not (match_operand 1 "register_operand" "")))] | |
21159 | "! TARGET_PARTIAL_REG_STALL && reload_completed | |
21160 | && (GET_MODE (operands[0]) == HImode | |
6300f037 | 21161 | || (GET_MODE (operands[0]) == QImode |
b2077fd2 JH |
21162 | && (TARGET_PROMOTE_QImode |
21163 | || optimize_insn_for_size_p ())))" | |
e9e80858 JH |
21164 | [(set (match_dup 0) |
21165 | (not:SI (match_dup 1)))] | |
21166 | "operands[0] = gen_lowpart (SImode, operands[0]); | |
21167 | operands[1] = gen_lowpart (SImode, operands[1]);") | |
21168 | ||
6300f037 | 21169 | (define_split |
e9e80858 | 21170 | [(set (match_operand 0 "register_operand" "") |
6300f037 | 21171 | (if_then_else (match_operator 1 "comparison_operator" |
42fabf21 | 21172 | [(reg FLAGS_REG) (const_int 0)]) |
e9e80858 JH |
21173 | (match_operand 2 "register_operand" "") |
21174 | (match_operand 3 "register_operand" "")))] | |
21175 | "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE | |
21176 | && (GET_MODE (operands[0]) == HImode | |
6300f037 | 21177 | || (GET_MODE (operands[0]) == QImode |
b2077fd2 JH |
21178 | && (TARGET_PROMOTE_QImode |
21179 | || optimize_insn_for_size_p ())))" | |
e9e80858 JH |
21180 | [(set (match_dup 0) |
21181 | (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] | |
21182 | "operands[0] = gen_lowpart (SImode, operands[0]); | |
21183 | operands[2] = gen_lowpart (SImode, operands[2]); | |
21184 | operands[3] = gen_lowpart (SImode, operands[3]);") | |
6300f037 | 21185 | |
e075ae69 RH |
21186 | \f |
21187 | ;; RTL Peephole optimizations, run before sched2. These primarily look to | |
21188 | ;; transform a complex memory operation into two memory to register operations. | |
21189 | ||
21190 | ;; Don't push memory operands | |
21191 | (define_peephole2 | |
3071fab5 RH |
21192 | [(set (match_operand:SI 0 "push_operand" "") |
21193 | (match_operand:SI 1 "memory_operand" "")) | |
21194 | (match_scratch:SI 2 "r")] | |
b2077fd2 | 21195 | "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY |
150cdc9e | 21196 | && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" |
e075ae69 RH |
21197 | [(set (match_dup 2) (match_dup 1)) |
21198 | (set (match_dup 0) (match_dup 2))] | |
21199 | "") | |
21200 | ||
cc2e591b JH |
21201 | (define_peephole2 |
21202 | [(set (match_operand:DI 0 "push_operand" "") | |
21203 | (match_operand:DI 1 "memory_operand" "")) | |
21204 | (match_scratch:DI 2 "r")] | |
b2077fd2 | 21205 | "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY |
150cdc9e | 21206 | && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" |
cc2e591b JH |
21207 | [(set (match_dup 2) (match_dup 1)) |
21208 | (set (match_dup 0) (match_dup 2))] | |
21209 | "") | |
21210 | ||
e9e80858 JH |
21211 | ;; We need to handle SFmode only, because DFmode and XFmode is split to |
21212 | ;; SImode pushes. | |
21213 | (define_peephole2 | |
21214 | [(set (match_operand:SF 0 "push_operand" "") | |
21215 | (match_operand:SF 1 "memory_operand" "")) | |
21216 | (match_scratch:SF 2 "r")] | |
b2077fd2 | 21217 | "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY |
150cdc9e | 21218 | && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" |
e9e80858 JH |
21219 | [(set (match_dup 2) (match_dup 1)) |
21220 | (set (match_dup 0) (match_dup 2))] | |
21221 | "") | |
21222 | ||
e075ae69 | 21223 | (define_peephole2 |
3071fab5 RH |
21224 | [(set (match_operand:HI 0 "push_operand" "") |
21225 | (match_operand:HI 1 "memory_operand" "")) | |
21226 | (match_scratch:HI 2 "r")] | |
b2077fd2 | 21227 | "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY |
150cdc9e | 21228 | && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" |
e075ae69 RH |
21229 | [(set (match_dup 2) (match_dup 1)) |
21230 | (set (match_dup 0) (match_dup 2))] | |
21231 | "") | |
21232 | ||
21233 | (define_peephole2 | |
3071fab5 RH |
21234 | [(set (match_operand:QI 0 "push_operand" "") |
21235 | (match_operand:QI 1 "memory_operand" "")) | |
21236 | (match_scratch:QI 2 "q")] | |
b2077fd2 | 21237 | "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY |
150cdc9e | 21238 | && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" |
e075ae69 RH |
21239 | [(set (match_dup 2) (match_dup 1)) |
21240 | (set (match_dup 0) (match_dup 2))] | |
21241 | "") | |
21242 | ||
21243 | ;; Don't move an immediate directly to memory when the instruction | |
21244 | ;; gets too big. | |
21245 | (define_peephole2 | |
21246 | [(match_scratch:SI 1 "r") | |
21247 | (set (match_operand:SI 0 "memory_operand" "") | |
21248 | (const_int 0))] | |
b2077fd2 | 21249 | "optimize_insn_for_speed_p () |
591702de | 21250 | && ! TARGET_USE_MOV0 |
23280139 | 21251 | && TARGET_SPLIT_LONG_MOVES |
b2077fd2 | 21252 | && get_attr_length (insn) >= ix86_cur_cost ()->large_insn |
23280139 | 21253 | && peep2_regno_dead_p (0, FLAGS_REG)" |
e075ae69 | 21254 | [(parallel [(set (match_dup 1) (const_int 0)) |
8bc527af | 21255 | (clobber (reg:CC FLAGS_REG))]) |
e075ae69 RH |
21256 | (set (match_dup 0) (match_dup 1))] |
21257 | "") | |
21258 | ||
21259 | (define_peephole2 | |
21260 | [(match_scratch:HI 1 "r") | |
21261 | (set (match_operand:HI 0 "memory_operand" "") | |
21262 | (const_int 0))] | |
b2077fd2 | 21263 | "optimize_insn_for_speed_p () |
591702de | 21264 | && ! TARGET_USE_MOV0 |
23280139 | 21265 | && TARGET_SPLIT_LONG_MOVES |
b2077fd2 | 21266 | && get_attr_length (insn) >= ix86_cur_cost ()->large_insn |
23280139 | 21267 | && peep2_regno_dead_p (0, FLAGS_REG)" |
591702de | 21268 | [(parallel [(set (match_dup 2) (const_int 0)) |
8bc527af | 21269 | (clobber (reg:CC FLAGS_REG))]) |
e075ae69 | 21270 | (set (match_dup 0) (match_dup 1))] |
1e2115dc | 21271 | "operands[2] = gen_lowpart (SImode, operands[1]);") |
e075ae69 RH |
21272 | |
21273 | (define_peephole2 | |
21274 | [(match_scratch:QI 1 "q") | |
21275 | (set (match_operand:QI 0 "memory_operand" "") | |
21276 | (const_int 0))] | |
b2077fd2 | 21277 | "optimize_insn_for_speed_p () |
591702de | 21278 | && ! TARGET_USE_MOV0 |
23280139 | 21279 | && TARGET_SPLIT_LONG_MOVES |
b2077fd2 | 21280 | && get_attr_length (insn) >= ix86_cur_cost ()->large_insn |
23280139 | 21281 | && peep2_regno_dead_p (0, FLAGS_REG)" |
591702de | 21282 | [(parallel [(set (match_dup 2) (const_int 0)) |
8bc527af | 21283 | (clobber (reg:CC FLAGS_REG))]) |
e075ae69 | 21284 | (set (match_dup 0) (match_dup 1))] |
1e2115dc | 21285 | "operands[2] = gen_lowpart (SImode, operands[1]);") |
e075ae69 RH |
21286 | |
21287 | (define_peephole2 | |
21288 | [(match_scratch:SI 2 "r") | |
21289 | (set (match_operand:SI 0 "memory_operand" "") | |
21290 | (match_operand:SI 1 "immediate_operand" ""))] | |
b2077fd2 | 21291 | "optimize_insn_for_speed_p () |
d5d5d289 | 21292 | && TARGET_SPLIT_LONG_MOVES |
b2077fd2 | 21293 | && get_attr_length (insn) >= ix86_cur_cost ()->large_insn" |
e075ae69 RH |
21294 | [(set (match_dup 2) (match_dup 1)) |
21295 | (set (match_dup 0) (match_dup 2))] | |
21296 | "") | |
21297 | ||
21298 | (define_peephole2 | |
21299 | [(match_scratch:HI 2 "r") | |
21300 | (set (match_operand:HI 0 "memory_operand" "") | |
21301 | (match_operand:HI 1 "immediate_operand" ""))] | |
b2077fd2 | 21302 | "optimize_insn_for_speed_p () |
d5d5d289 | 21303 | && TARGET_SPLIT_LONG_MOVES |
b2077fd2 | 21304 | && get_attr_length (insn) >= ix86_cur_cost ()->large_insn" |
e075ae69 RH |
21305 | [(set (match_dup 2) (match_dup 1)) |
21306 | (set (match_dup 0) (match_dup 2))] | |
21307 | "") | |
21308 | ||
21309 | (define_peephole2 | |
21310 | [(match_scratch:QI 2 "q") | |
21311 | (set (match_operand:QI 0 "memory_operand" "") | |
21312 | (match_operand:QI 1 "immediate_operand" ""))] | |
b2077fd2 | 21313 | "optimize_insn_for_speed_p () |
d5d5d289 | 21314 | && TARGET_SPLIT_LONG_MOVES |
b2077fd2 | 21315 | && get_attr_length (insn) >= ix86_cur_cost ()->large_insn" |
e075ae69 RH |
21316 | [(set (match_dup 2) (match_dup 1)) |
21317 | (set (match_dup 0) (match_dup 2))] | |
21318 | "") | |
21319 | ||
21320 | ;; Don't compare memory with zero, load and use a test instead. | |
21321 | (define_peephole2 | |
25da5dc7 RH |
21322 | [(set (match_operand 0 "flags_reg_operand" "") |
21323 | (match_operator 1 "compare_operator" | |
21324 | [(match_operand:SI 2 "memory_operand" "") | |
21325 | (const_int 0)])) | |
3071fab5 | 21326 | (match_scratch:SI 3 "r")] |
b2077fd2 | 21327 | "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)" |
25da5dc7 RH |
21328 | [(set (match_dup 3) (match_dup 2)) |
21329 | (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))] | |
e075ae69 RH |
21330 | "") |
21331 | ||
6300f037 | 21332 | ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. |
e075ae69 | 21333 | ;; Don't split NOTs with a displacement operand, because resulting XOR |
d1f87653 | 21334 | ;; will not be pairable anyway. |
e075ae69 | 21335 | ;; |
1e5f1716 | 21336 | ;; On AMD K6, NOT is vector decoded with memory operand that cannot be |
e075ae69 RH |
21337 | ;; represented using a modRM byte. The XOR replacement is long decoded, |
21338 | ;; so this split helps here as well. | |
21339 | ;; | |
23280139 RH |
21340 | ;; Note: Can't do this as a regular split because we can't get proper |
21341 | ;; lifetime information then. | |
e075ae69 RH |
21342 | |
21343 | (define_peephole2 | |
d5d6a58b RH |
21344 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
21345 | (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] | |
b2077fd2 | 21346 | "optimize_insn_for_speed_p () |
ddff69b9 | 21347 | && ((TARGET_NOT_UNPAIRABLE |
7656aee4 | 21348 | && (!MEM_P (operands[0]) |
e075ae69 | 21349 | || !memory_displacement_operand (operands[0], SImode))) |
d5d5d289 L |
21350 | || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode))) |
21351 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
e075ae69 RH |
21352 | [(parallel [(set (match_dup 0) |
21353 | (xor:SI (match_dup 1) (const_int -1))) | |
8bc527af | 21354 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 RH |
21355 | "") |
21356 | ||
21357 | (define_peephole2 | |
d5d6a58b RH |
21358 | [(set (match_operand:HI 0 "nonimmediate_operand" "") |
21359 | (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] | |
b2077fd2 | 21360 | "optimize_insn_for_speed_p () |
ddff69b9 | 21361 | && ((TARGET_NOT_UNPAIRABLE |
7656aee4 | 21362 | && (!MEM_P (operands[0]) |
e075ae69 | 21363 | || !memory_displacement_operand (operands[0], HImode))) |
d5d5d289 L |
21364 | || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode))) |
21365 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
e075ae69 RH |
21366 | [(parallel [(set (match_dup 0) |
21367 | (xor:HI (match_dup 1) (const_int -1))) | |
8bc527af | 21368 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 RH |
21369 | "") |
21370 | ||
21371 | (define_peephole2 | |
d5d6a58b RH |
21372 | [(set (match_operand:QI 0 "nonimmediate_operand" "") |
21373 | (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] | |
b2077fd2 | 21374 | "optimize_insn_for_speed_p () |
ddff69b9 | 21375 | && ((TARGET_NOT_UNPAIRABLE |
7656aee4 | 21376 | && (!MEM_P (operands[0]) |
e075ae69 | 21377 | || !memory_displacement_operand (operands[0], QImode))) |
d5d5d289 L |
21378 | || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode))) |
21379 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
e075ae69 RH |
21380 | [(parallel [(set (match_dup 0) |
21381 | (xor:QI (match_dup 1) (const_int -1))) | |
8bc527af | 21382 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 RH |
21383 | "") |
21384 | ||
21385 | ;; Non pairable "test imm, reg" instructions can be translated to | |
21386 | ;; "and imm, reg" if reg dies. The "and" form is also shorter (one | |
21387 | ;; byte opcode instead of two, have a short form for byte operands), | |
21388 | ;; so do it for other CPUs as well. Given that the value was dead, | |
f5143c46 | 21389 | ;; this should not create any new dependencies. Pass on the sub-word |
e075ae69 RH |
21390 | ;; versions if we're concerned about partial register stalls. |
21391 | ||
21392 | (define_peephole2 | |
25da5dc7 RH |
21393 | [(set (match_operand 0 "flags_reg_operand" "") |
21394 | (match_operator 1 "compare_operator" | |
21395 | [(and:SI (match_operand:SI 2 "register_operand" "") | |
21396 | (match_operand:SI 3 "immediate_operand" "")) | |
21397 | (const_int 0)]))] | |
16189740 | 21398 | "ix86_match_ccmode (insn, CCNOmode) |
29b74761 | 21399 | && (true_regnum (operands[2]) != AX_REG |
f38840db | 21400 | || satisfies_constraint_K (operands[3])) |
25da5dc7 | 21401 | && peep2_reg_dead_p (1, operands[2])" |
e075ae69 | 21402 | [(parallel |
25da5dc7 RH |
21403 | [(set (match_dup 0) |
21404 | (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) | |
21405 | (const_int 0)])) | |
21406 | (set (match_dup 2) | |
21407 | (and:SI (match_dup 2) (match_dup 3)))])] | |
e075ae69 RH |
21408 | "") |
21409 | ||
e9e80858 JH |
21410 | ;; We don't need to handle HImode case, because it will be promoted to SImode |
21411 | ;; on ! TARGET_PARTIAL_REG_STALL | |
e075ae69 RH |
21412 | |
21413 | (define_peephole2 | |
25da5dc7 RH |
21414 | [(set (match_operand 0 "flags_reg_operand" "") |
21415 | (match_operator 1 "compare_operator" | |
21416 | [(and:QI (match_operand:QI 2 "register_operand" "") | |
21417 | (match_operand:QI 3 "immediate_operand" "")) | |
21418 | (const_int 0)]))] | |
e075ae69 | 21419 | "! TARGET_PARTIAL_REG_STALL |
16189740 | 21420 | && ix86_match_ccmode (insn, CCNOmode) |
29b74761 | 21421 | && true_regnum (operands[2]) != AX_REG |
25da5dc7 | 21422 | && peep2_reg_dead_p (1, operands[2])" |
e075ae69 | 21423 | [(parallel |
25da5dc7 RH |
21424 | [(set (match_dup 0) |
21425 | (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) | |
21426 | (const_int 0)])) | |
21427 | (set (match_dup 2) | |
21428 | (and:QI (match_dup 2) (match_dup 3)))])] | |
e075ae69 RH |
21429 | "") |
21430 | ||
21431 | (define_peephole2 | |
25da5dc7 RH |
21432 | [(set (match_operand 0 "flags_reg_operand" "") |
21433 | (match_operator 1 "compare_operator" | |
21434 | [(and:SI | |
21435 | (zero_extract:SI | |
21436 | (match_operand 2 "ext_register_operand" "") | |
21437 | (const_int 8) | |
21438 | (const_int 8)) | |
21439 | (match_operand 3 "const_int_operand" "")) | |
21440 | (const_int 0)]))] | |
e075ae69 | 21441 | "! TARGET_PARTIAL_REG_STALL |
16189740 | 21442 | && ix86_match_ccmode (insn, CCNOmode) |
29b74761 | 21443 | && true_regnum (operands[2]) != AX_REG |
25da5dc7 RH |
21444 | && peep2_reg_dead_p (1, operands[2])" |
21445 | [(parallel [(set (match_dup 0) | |
21446 | (match_op_dup 1 | |
21447 | [(and:SI | |
21448 | (zero_extract:SI | |
21449 | (match_dup 2) | |
21450 | (const_int 8) | |
21451 | (const_int 8)) | |
21452 | (match_dup 3)) | |
21453 | (const_int 0)])) | |
21454 | (set (zero_extract:SI (match_dup 2) | |
e075ae69 RH |
21455 | (const_int 8) |
21456 | (const_int 8)) | |
6300f037 | 21457 | (and:SI |
e075ae69 | 21458 | (zero_extract:SI |
25da5dc7 | 21459 | (match_dup 2) |
e075ae69 RH |
21460 | (const_int 8) |
21461 | (const_int 8)) | |
25da5dc7 | 21462 | (match_dup 3)))])] |
e075ae69 RH |
21463 | "") |
21464 | ||
21465 | ;; Don't do logical operations with memory inputs. | |
21466 | (define_peephole2 | |
21467 | [(match_scratch:SI 2 "r") | |
21468 | (parallel [(set (match_operand:SI 0 "register_operand" "") | |
21469 | (match_operator:SI 3 "arith_or_logical_operator" | |
21470 | [(match_dup 0) | |
21471 | (match_operand:SI 1 "memory_operand" "")])) | |
8bc527af | 21472 | (clobber (reg:CC FLAGS_REG))])] |
3cdf0c62 | 21473 | "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY" |
e075ae69 RH |
21474 | [(set (match_dup 2) (match_dup 1)) |
21475 | (parallel [(set (match_dup 0) | |
21476 | (match_op_dup 3 [(match_dup 0) (match_dup 2)])) | |
8bc527af | 21477 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 RH |
21478 | "") |
21479 | ||
21480 | (define_peephole2 | |
21481 | [(match_scratch:SI 2 "r") | |
21482 | (parallel [(set (match_operand:SI 0 "register_operand" "") | |
21483 | (match_operator:SI 3 "arith_or_logical_operator" | |
21484 | [(match_operand:SI 1 "memory_operand" "") | |
21485 | (match_dup 0)])) | |
8bc527af | 21486 | (clobber (reg:CC FLAGS_REG))])] |
b2077fd2 | 21487 | "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY" |
e075ae69 RH |
21488 | [(set (match_dup 2) (match_dup 1)) |
21489 | (parallel [(set (match_dup 0) | |
21490 | (match_op_dup 3 [(match_dup 2) (match_dup 0)])) | |
8bc527af | 21491 | (clobber (reg:CC FLAGS_REG))])] |
e075ae69 RH |
21492 | "") |
21493 | ||
bab64f23 PB |
21494 | ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address |
21495 | ;; refers to the destination of the load! | |
21496 | ||
21497 | (define_peephole2 | |
21498 | [(set (match_operand:SI 0 "register_operand" "") | |
21499 | (match_operand:SI 1 "register_operand" "")) | |
21500 | (parallel [(set (match_dup 0) | |
21501 | (match_operator:SI 3 "commutative_operator" | |
21502 | [(match_dup 0) | |
21503 | (match_operand:SI 2 "memory_operand" "")])) | |
21504 | (clobber (reg:CC FLAGS_REG))])] | |
bbb52802 | 21505 | "REGNO (operands[0]) != REGNO (operands[1]) |
72f4e3a7 L |
21506 | && GENERAL_REGNO_P (REGNO (operands[0])) |
21507 | && GENERAL_REGNO_P (REGNO (operands[1]))" | |
bab64f23 PB |
21508 | [(set (match_dup 0) (match_dup 4)) |
21509 | (parallel [(set (match_dup 0) | |
21510 | (match_op_dup 3 [(match_dup 0) (match_dup 1)])) | |
21511 | (clobber (reg:CC FLAGS_REG))])] | |
12019aec | 21512 | "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);") |
bab64f23 PB |
21513 | |
21514 | (define_peephole2 | |
21515 | [(set (match_operand 0 "register_operand" "") | |
21516 | (match_operand 1 "register_operand" "")) | |
21517 | (set (match_dup 0) | |
21518 | (match_operator 3 "commutative_operator" | |
21519 | [(match_dup 0) | |
21520 | (match_operand 2 "memory_operand" "")]))] | |
bbb52802 | 21521 | "REGNO (operands[0]) != REGNO (operands[1]) |
47f5a48f L |
21522 | && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) |
21523 | || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))" | |
bab64f23 PB |
21524 | [(set (match_dup 0) (match_dup 2)) |
21525 | (set (match_dup 0) | |
21526 | (match_op_dup 3 [(match_dup 0) (match_dup 1)]))] | |
21527 | "") | |
21528 | ||
e075ae69 RH |
21529 | ; Don't do logical operations with memory outputs |
21530 | ; | |
21531 | ; These two don't make sense for PPro/PII -- we're expanding a 4-uop | |
21532 | ; instruction into two 1-uop insns plus a 2-uop insn. That last has | |
21533 | ; the same decoder scheduling characteristics as the original. | |
21534 | ||
21535 | (define_peephole2 | |
21536 | [(match_scratch:SI 2 "r") | |
21537 | (parallel [(set (match_operand:SI 0 "memory_operand" "") | |
21538 | (match_operator:SI 3 "arith_or_logical_operator" | |
21539 | [(match_dup 0) | |
21540 | (match_operand:SI 1 "nonmemory_operand" "")])) | |
8bc527af | 21541 | (clobber (reg:CC FLAGS_REG))])] |
b2077fd2 | 21542 | "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE" |
e075ae69 RH |
21543 | [(set (match_dup 2) (match_dup 0)) |
21544 | (parallel [(set (match_dup 2) | |
21545 | (match_op_dup 3 [(match_dup 2) (match_dup 1)])) | |
8bc527af | 21546 | (clobber (reg:CC FLAGS_REG))]) |
e075ae69 RH |
21547 | (set (match_dup 0) (match_dup 2))] |
21548 | "") | |
21549 | ||
21550 | (define_peephole2 | |
21551 | [(match_scratch:SI 2 "r") | |
21552 | (parallel [(set (match_operand:SI 0 "memory_operand" "") | |
21553 | (match_operator:SI 3 "arith_or_logical_operator" | |
21554 | [(match_operand:SI 1 "nonmemory_operand" "") | |
21555 | (match_dup 0)])) | |
8bc527af | 21556 | (clobber (reg:CC FLAGS_REG))])] |
b2077fd2 | 21557 | "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE" |
e075ae69 RH |
21558 | [(set (match_dup 2) (match_dup 0)) |
21559 | (parallel [(set (match_dup 2) | |
21560 | (match_op_dup 3 [(match_dup 1) (match_dup 2)])) | |
8bc527af | 21561 | (clobber (reg:CC FLAGS_REG))]) |
e075ae69 RH |
21562 | (set (match_dup 0) (match_dup 2))] |
21563 | "") | |
21564 | ||
21565 | ;; Attempt to always use XOR for zeroing registers. | |
21566 | (define_peephole2 | |
21567 | [(set (match_operand 0 "register_operand" "") | |
b4e82619 RH |
21568 | (match_operand 1 "const0_operand" ""))] |
21569 | "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD | |
b2077fd2 | 21570 | && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) |
f75959a6 | 21571 | && GENERAL_REG_P (operands[0]) |
23280139 | 21572 | && peep2_regno_dead_p (0, FLAGS_REG)" |
e075ae69 | 21573 | [(parallel [(set (match_dup 0) (const_int 0)) |
8bc527af | 21574 | (clobber (reg:CC FLAGS_REG))])] |
b4e82619 RH |
21575 | { |
21576 | operands[0] = gen_lowpart (word_mode, operands[0]); | |
21577 | }) | |
d3a923ee | 21578 | |
6ef67412 JH |
21579 | (define_peephole2 |
21580 | [(set (strict_low_part (match_operand 0 "register_operand" "")) | |
21581 | (const_int 0))] | |
21582 | "(GET_MODE (operands[0]) == QImode | |
21583 | || GET_MODE (operands[0]) == HImode) | |
b2077fd2 | 21584 | && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) |
6ef67412 JH |
21585 | && peep2_regno_dead_p (0, FLAGS_REG)" |
21586 | [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) | |
8bc527af | 21587 | (clobber (reg:CC FLAGS_REG))])]) |
6ef67412 | 21588 | |
e075ae69 RH |
21589 | ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg. |
21590 | (define_peephole2 | |
591702de | 21591 | [(set (match_operand 0 "register_operand" "") |
e075ae69 | 21592 | (const_int -1))] |
591702de | 21593 | "(GET_MODE (operands[0]) == HImode |
6300f037 | 21594 | || GET_MODE (operands[0]) == SImode |
cc2e591b | 21595 | || (GET_MODE (operands[0]) == DImode && TARGET_64BIT)) |
b2077fd2 | 21596 | && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR) |
23280139 | 21597 | && peep2_regno_dead_p (0, FLAGS_REG)" |
591702de | 21598 | [(parallel [(set (match_dup 0) (const_int -1)) |
8bc527af | 21599 | (clobber (reg:CC FLAGS_REG))])] |
1e2115dc JZ |
21600 | "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode, |
21601 | operands[0]);") | |
1c27d4b2 JH |
21602 | |
21603 | ;; Attempt to convert simple leas to adds. These can be created by | |
21604 | ;; move expanders. | |
21605 | (define_peephole2 | |
21606 | [(set (match_operand:SI 0 "register_operand" "") | |
21607 | (plus:SI (match_dup 0) | |
21608 | (match_operand:SI 1 "nonmemory_operand" "")))] | |
23280139 | 21609 | "peep2_regno_dead_p (0, FLAGS_REG)" |
1c27d4b2 | 21610 | [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) |
8bc527af | 21611 | (clobber (reg:CC FLAGS_REG))])] |
1c27d4b2 JH |
21612 | "") |
21613 | ||
cc2e591b JH |
21614 | (define_peephole2 |
21615 | [(set (match_operand:SI 0 "register_operand" "") | |
21616 | (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") | |
21617 | (match_operand:DI 2 "nonmemory_operand" "")) 0))] | |
21618 | "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])" | |
21619 | [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) | |
8bc527af | 21620 | (clobber (reg:CC FLAGS_REG))])] |
cc2e591b JH |
21621 | "operands[2] = gen_lowpart (SImode, operands[2]);") |
21622 | ||
21623 | (define_peephole2 | |
21624 | [(set (match_operand:DI 0 "register_operand" "") | |
21625 | (plus:DI (match_dup 0) | |
21626 | (match_operand:DI 1 "x86_64_general_operand" "")))] | |
21627 | "peep2_regno_dead_p (0, FLAGS_REG)" | |
21628 | [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) | |
8bc527af | 21629 | (clobber (reg:CC FLAGS_REG))])] |
cc2e591b JH |
21630 | "") |
21631 | ||
1c27d4b2 JH |
21632 | (define_peephole2 |
21633 | [(set (match_operand:SI 0 "register_operand" "") | |
21634 | (mult:SI (match_dup 0) | |
cc2e591b | 21635 | (match_operand:SI 1 "const_int_operand" "")))] |
23280139 RH |
21636 | "exact_log2 (INTVAL (operands[1])) >= 0 |
21637 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
1c27d4b2 | 21638 | [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) |
8bc527af | 21639 | (clobber (reg:CC FLAGS_REG))])] |
1c27d4b2 | 21640 | "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") |
bdeb029c | 21641 | |
cc2e591b JH |
21642 | (define_peephole2 |
21643 | [(set (match_operand:DI 0 "register_operand" "") | |
21644 | (mult:DI (match_dup 0) | |
21645 | (match_operand:DI 1 "const_int_operand" "")))] | |
21646 | "exact_log2 (INTVAL (operands[1])) >= 0 | |
21647 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
21648 | [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) | |
8bc527af | 21649 | (clobber (reg:CC FLAGS_REG))])] |
cc2e591b JH |
21650 | "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") |
21651 | ||
21652 | (define_peephole2 | |
21653 | [(set (match_operand:SI 0 "register_operand" "") | |
21654 | (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") | |
21655 | (match_operand:DI 2 "const_int_operand" "")) 0))] | |
4c9c9a3d | 21656 | "exact_log2 (INTVAL (operands[2])) >= 0 |
cc2e591b JH |
21657 | && REGNO (operands[0]) == REGNO (operands[1]) |
21658 | && peep2_regno_dead_p (0, FLAGS_REG)" | |
21659 | [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) | |
8bc527af | 21660 | (clobber (reg:CC FLAGS_REG))])] |
cc2e591b JH |
21661 | "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") |
21662 | ||
bdeb029c JH |
21663 | ;; The ESP adjustments can be done by the push and pop instructions. Resulting |
21664 | ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On | |
21665 | ;; many CPUs it is also faster, since special hardware to avoid esp | |
f5143c46 | 21666 | ;; dependencies is present. |
bdeb029c | 21667 | |
d6a7951f | 21668 | ;; While some of these conversions may be done using splitters, we use peepholes |
bdeb029c JH |
21669 | ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL. |
21670 | ||
f5143c46 | 21671 | ;; Convert prologue esp subtractions to push. |
bdeb029c JH |
21672 | ;; We need register to push. In order to keep verify_flow_info happy we have |
21673 | ;; two choices | |
21674 | ;; - use scratch and clobber it in order to avoid dependencies | |
21675 | ;; - use already live register | |
21676 | ;; We can't use the second way right now, since there is no reliable way how to | |
21677 | ;; verify that given register is live. First choice will also most likely in | |
21678 | ;; fewer dependencies. On the place of esp adjustments it is very likely that | |
21679 | ;; call clobbered registers are dead. We may want to use base pointer as an | |
21680 | ;; alternative when no register is available later. | |
21681 | ||
21682 | (define_peephole2 | |
21683 | [(match_scratch:SI 0 "r") | |
8bc527af SB |
21684 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) |
21685 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21686 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21687 | "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4" |
bdeb029c | 21688 | [(clobber (match_dup 0)) |
8bc527af | 21689 | (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) |
f2042df3 | 21690 | (clobber (mem:BLK (scratch)))])]) |
bdeb029c JH |
21691 | |
21692 | (define_peephole2 | |
21693 | [(match_scratch:SI 0 "r") | |
8bc527af SB |
21694 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) |
21695 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21696 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21697 | "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8" |
bdeb029c | 21698 | [(clobber (match_dup 0)) |
8bc527af SB |
21699 | (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) |
21700 | (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) | |
f2042df3 | 21701 | (clobber (mem:BLK (scratch)))])]) |
bdeb029c | 21702 | |
f5143c46 | 21703 | ;; Convert esp subtractions to push. |
bdeb029c JH |
21704 | (define_peephole2 |
21705 | [(match_scratch:SI 0 "r") | |
8bc527af SB |
21706 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) |
21707 | (clobber (reg:CC FLAGS_REG))])] | |
b2077fd2 | 21708 | "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4" |
bdeb029c | 21709 | [(clobber (match_dup 0)) |
8bc527af | 21710 | (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) |
bdeb029c JH |
21711 | |
21712 | (define_peephole2 | |
21713 | [(match_scratch:SI 0 "r") | |
8bc527af SB |
21714 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) |
21715 | (clobber (reg:CC FLAGS_REG))])] | |
b2077fd2 | 21716 | "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8" |
bdeb029c | 21717 | [(clobber (match_dup 0)) |
8bc527af SB |
21718 | (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) |
21719 | (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) | |
bdeb029c JH |
21720 | |
21721 | ;; Convert epilogue deallocator to pop. | |
21722 | (define_peephole2 | |
21723 | [(match_scratch:SI 0 "r") | |
8bc527af SB |
21724 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) |
21725 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21726 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21727 | "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4" |
8bc527af SB |
21728 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) |
21729 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) | |
f2042df3 | 21730 | (clobber (mem:BLK (scratch)))])] |
bdeb029c JH |
21731 | "") |
21732 | ||
21733 | ;; Two pops case is tricky, since pop causes dependency on destination register. | |
21734 | ;; We use two registers if available. | |
21735 | (define_peephole2 | |
21736 | [(match_scratch:SI 0 "r") | |
21737 | (match_scratch:SI 1 "r") | |
8bc527af SB |
21738 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) |
21739 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21740 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21741 | "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8" |
8bc527af SB |
21742 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) |
21743 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) | |
f2042df3 | 21744 | (clobber (mem:BLK (scratch)))]) |
8bc527af SB |
21745 | (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) |
21746 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] | |
bdeb029c JH |
21747 | "") |
21748 | ||
21749 | (define_peephole2 | |
21750 | [(match_scratch:SI 0 "r") | |
8bc527af SB |
21751 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) |
21752 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21753 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21754 | "optimize_insn_for_size_p ()" |
8bc527af SB |
21755 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) |
21756 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) | |
f2042df3 | 21757 | (clobber (mem:BLK (scratch)))]) |
8bc527af SB |
21758 | (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) |
21759 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] | |
bdeb029c JH |
21760 | "") |
21761 | ||
21762 | ;; Convert esp additions to pop. | |
21763 | (define_peephole2 | |
21764 | [(match_scratch:SI 0 "r") | |
8bc527af SB |
21765 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) |
21766 | (clobber (reg:CC FLAGS_REG))])] | |
bdeb029c | 21767 | "" |
8bc527af SB |
21768 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) |
21769 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] | |
bdeb029c JH |
21770 | "") |
21771 | ||
21772 | ;; Two pops case is tricky, since pop causes dependency on destination register. | |
21773 | ;; We use two registers if available. | |
21774 | (define_peephole2 | |
21775 | [(match_scratch:SI 0 "r") | |
21776 | (match_scratch:SI 1 "r") | |
8bc527af SB |
21777 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) |
21778 | (clobber (reg:CC FLAGS_REG))])] | |
bdeb029c | 21779 | "" |
8bc527af SB |
21780 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) |
21781 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) | |
21782 | (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) | |
21783 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] | |
bdeb029c JH |
21784 | "") |
21785 | ||
21786 | (define_peephole2 | |
21787 | [(match_scratch:SI 0 "r") | |
8bc527af SB |
21788 | (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) |
21789 | (clobber (reg:CC FLAGS_REG))])] | |
b2077fd2 | 21790 | "optimize_insn_for_size_p ()" |
8bc527af SB |
21791 | [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) |
21792 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) | |
21793 | (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) | |
21794 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] | |
bdeb029c | 21795 | "") |
69404d6f | 21796 | \f |
9dcbdc7e | 21797 | ;; Convert compares with 1 to shorter inc/dec operations when CF is not |
6396547e | 21798 | ;; required and register dies. Similarly for 128 to -128. |
9dcbdc7e | 21799 | (define_peephole2 |
25da5dc7 RH |
21800 | [(set (match_operand 0 "flags_reg_operand" "") |
21801 | (match_operator 1 "compare_operator" | |
21802 | [(match_operand 2 "register_operand" "") | |
21803 | (match_operand 3 "const_int_operand" "")]))] | |
700ae70c | 21804 | "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ()) |
6396547e L |
21805 | && incdec_operand (operands[3], GET_MODE (operands[3]))) |
21806 | || (!TARGET_FUSE_CMP_AND_BRANCH | |
21807 | && INTVAL (operands[3]) == 128)) | |
25da5dc7 RH |
21808 | && ix86_match_ccmode (insn, CCGCmode) |
21809 | && peep2_reg_dead_p (1, operands[2])" | |
21810 | [(parallel [(set (match_dup 0) | |
21811 | (match_op_dup 1 [(match_dup 2) (match_dup 3)])) | |
21812 | (clobber (match_dup 2))])] | |
9dcbdc7e JH |
21813 | "") |
21814 | \f | |
cc2e591b JH |
21815 | (define_peephole2 |
21816 | [(match_scratch:DI 0 "r") | |
8bc527af SB |
21817 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) |
21818 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21819 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21820 | "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4" |
cc2e591b | 21821 | [(clobber (match_dup 0)) |
8bc527af | 21822 | (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) |
f2042df3 | 21823 | (clobber (mem:BLK (scratch)))])]) |
cc2e591b JH |
21824 | |
21825 | (define_peephole2 | |
21826 | [(match_scratch:DI 0 "r") | |
8bc527af SB |
21827 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) |
21828 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21829 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21830 | "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8" |
cc2e591b | 21831 | [(clobber (match_dup 0)) |
8bc527af SB |
21832 | (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) |
21833 | (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) | |
f2042df3 | 21834 | (clobber (mem:BLK (scratch)))])]) |
cc2e591b | 21835 | |
f5143c46 | 21836 | ;; Convert esp subtractions to push. |
cc2e591b JH |
21837 | (define_peephole2 |
21838 | [(match_scratch:DI 0 "r") | |
8bc527af SB |
21839 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) |
21840 | (clobber (reg:CC FLAGS_REG))])] | |
b2077fd2 | 21841 | "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4" |
cc2e591b | 21842 | [(clobber (match_dup 0)) |
8bc527af | 21843 | (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) |
cc2e591b JH |
21844 | |
21845 | (define_peephole2 | |
21846 | [(match_scratch:DI 0 "r") | |
8bc527af SB |
21847 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) |
21848 | (clobber (reg:CC FLAGS_REG))])] | |
b2077fd2 | 21849 | "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8" |
cc2e591b | 21850 | [(clobber (match_dup 0)) |
8bc527af SB |
21851 | (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) |
21852 | (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) | |
cc2e591b JH |
21853 | |
21854 | ;; Convert epilogue deallocator to pop. | |
21855 | (define_peephole2 | |
21856 | [(match_scratch:DI 0 "r") | |
8bc527af SB |
21857 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) |
21858 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21859 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21860 | "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4" |
8bc527af SB |
21861 | [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) |
21862 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) | |
f2042df3 | 21863 | (clobber (mem:BLK (scratch)))])] |
cc2e591b JH |
21864 | "") |
21865 | ||
21866 | ;; Two pops case is tricky, since pop causes dependency on destination register. | |
21867 | ;; We use two registers if available. | |
21868 | (define_peephole2 | |
21869 | [(match_scratch:DI 0 "r") | |
21870 | (match_scratch:DI 1 "r") | |
8bc527af SB |
21871 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) |
21872 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21873 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21874 | "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8" |
8bc527af SB |
21875 | [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) |
21876 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) | |
f2042df3 | 21877 | (clobber (mem:BLK (scratch)))]) |
8bc527af SB |
21878 | (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) |
21879 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] | |
cc2e591b JH |
21880 | "") |
21881 | ||
21882 | (define_peephole2 | |
21883 | [(match_scratch:DI 0 "r") | |
8bc527af SB |
21884 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) |
21885 | (clobber (reg:CC FLAGS_REG)) | |
f2042df3 | 21886 | (clobber (mem:BLK (scratch)))])] |
b2077fd2 | 21887 | "optimize_insn_for_size_p ()" |
8bc527af SB |
21888 | [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) |
21889 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) | |
f2042df3 | 21890 | (clobber (mem:BLK (scratch)))]) |
8bc527af SB |
21891 | (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) |
21892 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] | |
cc2e591b JH |
21893 | "") |
21894 | ||
21895 | ;; Convert esp additions to pop. | |
21896 | (define_peephole2 | |
21897 | [(match_scratch:DI 0 "r") | |
8bc527af SB |
21898 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) |
21899 | (clobber (reg:CC FLAGS_REG))])] | |
cc2e591b | 21900 | "" |
8bc527af SB |
21901 | [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) |
21902 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] | |
cc2e591b JH |
21903 | "") |
21904 | ||
21905 | ;; Two pops case is tricky, since pop causes dependency on destination register. | |
21906 | ;; We use two registers if available. | |
21907 | (define_peephole2 | |
21908 | [(match_scratch:DI 0 "r") | |
21909 | (match_scratch:DI 1 "r") | |
8bc527af SB |
21910 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) |
21911 | (clobber (reg:CC FLAGS_REG))])] | |
cc2e591b | 21912 | "" |
8bc527af SB |
21913 | [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) |
21914 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) | |
21915 | (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) | |
21916 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] | |
cc2e591b JH |
21917 | "") |
21918 | ||
21919 | (define_peephole2 | |
21920 | [(match_scratch:DI 0 "r") | |
8bc527af SB |
21921 | (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) |
21922 | (clobber (reg:CC FLAGS_REG))])] | |
b2077fd2 | 21923 | "optimize_insn_for_size_p ()" |
8bc527af SB |
21924 | [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) |
21925 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) | |
21926 | (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) | |
21927 | (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] | |
cc2e591b JH |
21928 | "") |
21929 | \f | |
cf14e33d RS |
21930 | ;; Convert imul by three, five and nine into lea |
21931 | (define_peephole2 | |
21932 | [(parallel | |
21933 | [(set (match_operand:SI 0 "register_operand" "") | |
21934 | (mult:SI (match_operand:SI 1 "register_operand" "") | |
21935 | (match_operand:SI 2 "const_int_operand" ""))) | |
21936 | (clobber (reg:CC FLAGS_REG))])] | |
21937 | "INTVAL (operands[2]) == 3 | |
21938 | || INTVAL (operands[2]) == 5 | |
21939 | || INTVAL (operands[2]) == 9" | |
21940 | [(set (match_dup 0) | |
21941 | (plus:SI (mult:SI (match_dup 1) (match_dup 2)) | |
21942 | (match_dup 1)))] | |
21943 | { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) | |
21944 | ||
21945 | (define_peephole2 | |
21946 | [(parallel | |
21947 | [(set (match_operand:SI 0 "register_operand" "") | |
21948 | (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
21949 | (match_operand:SI 2 "const_int_operand" ""))) | |
21950 | (clobber (reg:CC FLAGS_REG))])] | |
b2077fd2 | 21951 | "optimize_insn_for_speed_p () |
cf14e33d RS |
21952 | && (INTVAL (operands[2]) == 3 |
21953 | || INTVAL (operands[2]) == 5 | |
21954 | || INTVAL (operands[2]) == 9)" | |
21955 | [(set (match_dup 0) (match_dup 1)) | |
21956 | (set (match_dup 0) | |
21957 | (plus:SI (mult:SI (match_dup 0) (match_dup 2)) | |
21958 | (match_dup 0)))] | |
21959 | { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) | |
21960 | ||
21961 | (define_peephole2 | |
21962 | [(parallel | |
21963 | [(set (match_operand:DI 0 "register_operand" "") | |
21964 | (mult:DI (match_operand:DI 1 "register_operand" "") | |
21965 | (match_operand:DI 2 "const_int_operand" ""))) | |
21966 | (clobber (reg:CC FLAGS_REG))])] | |
21967 | "TARGET_64BIT | |
21968 | && (INTVAL (operands[2]) == 3 | |
21969 | || INTVAL (operands[2]) == 5 | |
21970 | || INTVAL (operands[2]) == 9)" | |
21971 | [(set (match_dup 0) | |
21972 | (plus:DI (mult:DI (match_dup 1) (match_dup 2)) | |
21973 | (match_dup 1)))] | |
21974 | { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) | |
21975 | ||
21976 | (define_peephole2 | |
21977 | [(parallel | |
21978 | [(set (match_operand:DI 0 "register_operand" "") | |
21979 | (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") | |
21980 | (match_operand:DI 2 "const_int_operand" ""))) | |
21981 | (clobber (reg:CC FLAGS_REG))])] | |
21982 | "TARGET_64BIT | |
b2077fd2 | 21983 | && optimize_insn_for_speed_p () |
cf14e33d RS |
21984 | && (INTVAL (operands[2]) == 3 |
21985 | || INTVAL (operands[2]) == 5 | |
21986 | || INTVAL (operands[2]) == 9)" | |
21987 | [(set (match_dup 0) (match_dup 1)) | |
21988 | (set (match_dup 0) | |
21989 | (plus:DI (mult:DI (match_dup 0) (match_dup 2)) | |
21990 | (match_dup 0)))] | |
21991 | { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) | |
21992 | ||
f56e86bd JH |
21993 | ;; Imul $32bit_imm, mem, reg is vector decoded, while |
21994 | ;; imul $32bit_imm, reg, reg is direct decoded. | |
21995 | (define_peephole2 | |
21996 | [(match_scratch:DI 3 "r") | |
21997 | (parallel [(set (match_operand:DI 0 "register_operand" "") | |
21998 | (mult:DI (match_operand:DI 1 "memory_operand" "") | |
21999 | (match_operand:DI 2 "immediate_operand" ""))) | |
8bc527af | 22000 | (clobber (reg:CC FLAGS_REG))])] |
b2077fd2 | 22001 | "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () |
f38840db | 22002 | && !satisfies_constraint_K (operands[2])" |
f56e86bd JH |
22003 | [(set (match_dup 3) (match_dup 1)) |
22004 | (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2))) | |
8bc527af | 22005 | (clobber (reg:CC FLAGS_REG))])] |
f56e86bd JH |
22006 | "") |
22007 | ||
22008 | (define_peephole2 | |
22009 | [(match_scratch:SI 3 "r") | |
22010 | (parallel [(set (match_operand:SI 0 "register_operand" "") | |
22011 | (mult:SI (match_operand:SI 1 "memory_operand" "") | |
22012 | (match_operand:SI 2 "immediate_operand" ""))) | |
8bc527af | 22013 | (clobber (reg:CC FLAGS_REG))])] |
b2077fd2 | 22014 | "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () |
f38840db | 22015 | && !satisfies_constraint_K (operands[2])" |
f56e86bd JH |
22016 | [(set (match_dup 3) (match_dup 1)) |
22017 | (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2))) | |
8bc527af | 22018 | (clobber (reg:CC FLAGS_REG))])] |
f56e86bd JH |
22019 | "") |
22020 | ||
22021 | (define_peephole2 | |
22022 | [(match_scratch:SI 3 "r") | |
22023 | (parallel [(set (match_operand:DI 0 "register_operand" "") | |
22024 | (zero_extend:DI | |
22025 | (mult:SI (match_operand:SI 1 "memory_operand" "") | |
22026 | (match_operand:SI 2 "immediate_operand" "")))) | |
8bc527af | 22027 | (clobber (reg:CC FLAGS_REG))])] |
b2077fd2 | 22028 | "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () |
f38840db | 22029 | && !satisfies_constraint_K (operands[2])" |
f56e86bd JH |
22030 | [(set (match_dup 3) (match_dup 1)) |
22031 | (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) | |
8bc527af | 22032 | (clobber (reg:CC FLAGS_REG))])] |
f56e86bd JH |
22033 | "") |
22034 | ||
22035 | ;; imul $8/16bit_imm, regmem, reg is vector decoded. | |
22036 | ;; Convert it into imul reg, reg | |
22037 | ;; It would be better to force assembler to encode instruction using long | |
22038 | ;; immediate, but there is apparently no way to do so. | |
22039 | (define_peephole2 | |
22040 | [(parallel [(set (match_operand:DI 0 "register_operand" "") | |
22041 | (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") | |
22042 | (match_operand:DI 2 "const_int_operand" ""))) | |
8bc527af | 22043 | (clobber (reg:CC FLAGS_REG))]) |
f56e86bd | 22044 | (match_scratch:DI 3 "r")] |
b2077fd2 | 22045 | "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () |
f38840db | 22046 | && satisfies_constraint_K (operands[2])" |
f56e86bd JH |
22047 | [(set (match_dup 3) (match_dup 2)) |
22048 | (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3))) | |
8bc527af | 22049 | (clobber (reg:CC FLAGS_REG))])] |
f56e86bd JH |
22050 | { |
22051 | if (!rtx_equal_p (operands[0], operands[1])) | |
22052 | emit_move_insn (operands[0], operands[1]); | |
22053 | }) | |
22054 | ||
22055 | (define_peephole2 | |
22056 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
22057 | (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") | |
22058 | (match_operand:SI 2 "const_int_operand" ""))) | |
8bc527af | 22059 | (clobber (reg:CC FLAGS_REG))]) |
f56e86bd | 22060 | (match_scratch:SI 3 "r")] |
b2077fd2 | 22061 | "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () |
f38840db | 22062 | && satisfies_constraint_K (operands[2])" |
f56e86bd JH |
22063 | [(set (match_dup 3) (match_dup 2)) |
22064 | (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3))) | |
8bc527af | 22065 | (clobber (reg:CC FLAGS_REG))])] |
f56e86bd JH |
22066 | { |
22067 | if (!rtx_equal_p (operands[0], operands[1])) | |
22068 | emit_move_insn (operands[0], operands[1]); | |
22069 | }) | |
22070 | ||
22071 | (define_peephole2 | |
22072 | [(parallel [(set (match_operand:HI 0 "register_operand" "") | |
22073 | (mult:HI (match_operand:HI 1 "nonimmediate_operand" "") | |
22074 | (match_operand:HI 2 "immediate_operand" ""))) | |
8bc527af | 22075 | (clobber (reg:CC FLAGS_REG))]) |
f56e86bd | 22076 | (match_scratch:HI 3 "r")] |
b2077fd2 | 22077 | "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()" |
f56e86bd JH |
22078 | [(set (match_dup 3) (match_dup 2)) |
22079 | (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3))) | |
8bc527af | 22080 | (clobber (reg:CC FLAGS_REG))])] |
f56e86bd JH |
22081 | { |
22082 | if (!rtx_equal_p (operands[0], operands[1])) | |
22083 | emit_move_insn (operands[0], operands[1]); | |
22084 | }) | |
fb530c72 JH |
22085 | |
22086 | ;; After splitting up read-modify operations, array accesses with memory | |
22087 | ;; operands might end up in form: | |
22088 | ;; sall $2, %eax | |
22089 | ;; movl 4(%esp), %edx | |
22090 | ;; addl %edx, %eax | |
22091 | ;; instead of pre-splitting: | |
22092 | ;; sall $2, %eax | |
22093 | ;; addl 4(%esp), %eax | |
22094 | ;; Turn it into: | |
22095 | ;; movl 4(%esp), %edx | |
22096 | ;; leal (%edx,%eax,4), %eax | |
22097 | ||
22098 | (define_peephole2 | |
22099 | [(parallel [(set (match_operand 0 "register_operand" "") | |
22100 | (ashift (match_operand 1 "register_operand" "") | |
22101 | (match_operand 2 "const_int_operand" ""))) | |
22102 | (clobber (reg:CC FLAGS_REG))]) | |
22103 | (set (match_operand 3 "register_operand") | |
22104 | (match_operand 4 "x86_64_general_operand" "")) | |
22105 | (parallel [(set (match_operand 5 "register_operand" "") | |
22106 | (plus (match_operand 6 "register_operand" "") | |
22107 | (match_operand 7 "register_operand" ""))) | |
22108 | (clobber (reg:CC FLAGS_REG))])] | |
22109 | "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3 | |
22110 | /* Validate MODE for lea. */ | |
22111 | && ((!TARGET_PARTIAL_REG_STALL | |
22112 | && (GET_MODE (operands[0]) == QImode | |
22113 | || GET_MODE (operands[0]) == HImode)) | |
6300f037 | 22114 | || GET_MODE (operands[0]) == SImode |
fb530c72 JH |
22115 | || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) |
22116 | /* We reorder load and the shift. */ | |
22117 | && !rtx_equal_p (operands[1], operands[3]) | |
22118 | && !reg_overlap_mentioned_p (operands[0], operands[4]) | |
22119 | /* Last PLUS must consist of operand 0 and 3. */ | |
22120 | && !rtx_equal_p (operands[0], operands[3]) | |
22121 | && (rtx_equal_p (operands[3], operands[6]) | |
22122 | || rtx_equal_p (operands[3], operands[7])) | |
22123 | && (rtx_equal_p (operands[0], operands[6]) | |
22124 | || rtx_equal_p (operands[0], operands[7])) | |
22125 | /* The intermediate operand 0 must die or be same as output. */ | |
22126 | && (rtx_equal_p (operands[0], operands[5]) | |
22127 | || peep2_reg_dead_p (3, operands[0]))" | |
22128 | [(set (match_dup 3) (match_dup 4)) | |
22129 | (set (match_dup 0) (match_dup 1))] | |
22130 | { | |
22131 | enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode; | |
22132 | int scale = 1 << INTVAL (operands[2]); | |
22133 | rtx index = gen_lowpart (Pmode, operands[1]); | |
22134 | rtx base = gen_lowpart (Pmode, operands[3]); | |
22135 | rtx dest = gen_lowpart (mode, operands[5]); | |
22136 | ||
22137 | operands[1] = gen_rtx_PLUS (Pmode, base, | |
22138 | gen_rtx_MULT (Pmode, index, GEN_INT (scale))); | |
22139 | if (mode != Pmode) | |
22140 | operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); | |
22141 | operands[0] = dest; | |
22142 | }) | |
f56e86bd | 22143 | \f |
69404d6f RH |
22144 | ;; Call-value patterns last so that the wildcard operand does not |
22145 | ;; disrupt insn-recog's switch tables. | |
22146 | ||
94bb5d0c RH |
22147 | (define_insn "*call_value_pop_0" |
22148 | [(set (match_operand 0 "" "") | |
e1ff012c | 22149 | (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) |
94bb5d0c | 22150 | (match_operand:SI 2 "" ""))) |
8bc527af | 22151 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) |
90d10fb9 | 22152 | (match_operand:SI 3 "immediate_operand" "")))] |
1e07edd3 | 22153 | "!TARGET_64BIT" |
94bb5d0c RH |
22154 | { |
22155 | if (SIBLING_CALL_P (insn)) | |
0f40f9f7 | 22156 | return "jmp\t%P1"; |
94bb5d0c | 22157 | else |
0f40f9f7 ZW |
22158 | return "call\t%P1"; |
22159 | } | |
94bb5d0c RH |
22160 | [(set_attr "type" "callv")]) |
22161 | ||
69404d6f RH |
22162 | (define_insn "*call_value_pop_1" |
22163 | [(set (match_operand 0 "" "") | |
e1ff012c | 22164 | (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) |
94bb5d0c | 22165 | (match_operand:SI 2 "" ""))) |
8bc527af | 22166 | (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) |
90d10fb9 | 22167 | (match_operand:SI 3 "immediate_operand" "i")))] |
1e07edd3 | 22168 | "!TARGET_64BIT" |
69404d6f | 22169 | { |
e427abbf | 22170 | if (constant_call_address_operand (operands[1], Pmode)) |
94bb5d0c RH |
22171 | { |
22172 | if (SIBLING_CALL_P (insn)) | |
0f40f9f7 | 22173 | return "jmp\t%P1"; |
94bb5d0c | 22174 | else |
0f40f9f7 | 22175 | return "call\t%P1"; |
94bb5d0c | 22176 | } |
94bb5d0c | 22177 | if (SIBLING_CALL_P (insn)) |
0f40f9f7 | 22178 | return "jmp\t%A1"; |
94bb5d0c | 22179 | else |
0f40f9f7 ZW |
22180 | return "call\t%A1"; |
22181 | } | |
94bb5d0c RH |
22182 | [(set_attr "type" "callv")]) |
22183 | ||
22184 | (define_insn "*call_value_0" | |
22185 | [(set (match_operand 0 "" "") | |
e1ff012c | 22186 | (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) |
94bb5d0c | 22187 | (match_operand:SI 2 "" "")))] |
32ee7d1d | 22188 | "!TARGET_64BIT" |
32ee7d1d JH |
22189 | { |
22190 | if (SIBLING_CALL_P (insn)) | |
0f40f9f7 | 22191 | return "jmp\t%P1"; |
32ee7d1d | 22192 | else |
0f40f9f7 ZW |
22193 | return "call\t%P1"; |
22194 | } | |
32ee7d1d JH |
22195 | [(set_attr "type" "callv")]) |
22196 | ||
22197 | (define_insn "*call_value_0_rex64" | |
22198 | [(set (match_operand 0 "" "") | |
22199 | (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) | |
22200 | (match_operand:DI 2 "const_int_operand" "")))] | |
22201 | "TARGET_64BIT" | |
94bb5d0c RH |
22202 | { |
22203 | if (SIBLING_CALL_P (insn)) | |
0f40f9f7 | 22204 | return "jmp\t%P1"; |
94bb5d0c | 22205 | else |
0f40f9f7 ZW |
22206 | return "call\t%P1"; |
22207 | } | |
69404d6f RH |
22208 | [(set_attr "type" "callv")]) |
22209 | ||
924eabec JH |
22210 | (define_insn "*call_value_0_rex64_ms_sysv" |
22211 | [(set (match_operand 0 "" "") | |
22212 | (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) | |
22213 | (match_operand:DI 2 "const_int_operand" ""))) | |
22214 | (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) | |
78168632 UB |
22215 | (clobber (reg:TI XMM6_REG)) |
22216 | (clobber (reg:TI XMM7_REG)) | |
22217 | (clobber (reg:TI XMM8_REG)) | |
22218 | (clobber (reg:TI XMM9_REG)) | |
22219 | (clobber (reg:TI XMM10_REG)) | |
22220 | (clobber (reg:TI XMM11_REG)) | |
22221 | (clobber (reg:TI XMM12_REG)) | |
22222 | (clobber (reg:TI XMM13_REG)) | |
22223 | (clobber (reg:TI XMM14_REG)) | |
22224 | (clobber (reg:TI XMM15_REG)) | |
924eabec JH |
22225 | (clobber (reg:DI SI_REG)) |
22226 | (clobber (reg:DI DI_REG))] | |
22227 | "!SIBLING_CALL_P (insn) && TARGET_64BIT" | |
22228 | { | |
22229 | if (SIBLING_CALL_P (insn)) | |
22230 | return "jmp\t%P1"; | |
22231 | else | |
22232 | return "call\t%P1"; | |
22233 | } | |
22234 | [(set_attr "type" "callv")]) | |
22235 | ||
69404d6f RH |
22236 | (define_insn "*call_value_1" |
22237 | [(set (match_operand 0 "" "") | |
e1ff012c | 22238 | (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) |
94bb5d0c | 22239 | (match_operand:SI 2 "" "")))] |
4977bab6 | 22240 | "!SIBLING_CALL_P (insn) && !TARGET_64BIT" |
32ee7d1d | 22241 | { |
e427abbf | 22242 | if (constant_call_address_operand (operands[1], Pmode)) |
4977bab6 | 22243 | return "call\t%P1"; |
6a46f71d | 22244 | return "call\t%A1"; |
4977bab6 ZW |
22245 | } |
22246 | [(set_attr "type" "callv")]) | |
22247 | ||
22248 | (define_insn "*sibcall_value_1" | |
22249 | [(set (match_operand 0 "" "") | |
22250 | (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a")) | |
22251 | (match_operand:SI 2 "" "")))] | |
22252 | "SIBLING_CALL_P (insn) && !TARGET_64BIT" | |
22253 | { | |
e427abbf | 22254 | if (constant_call_address_operand (operands[1], Pmode)) |
4977bab6 | 22255 | return "jmp\t%P1"; |
6a46f71d | 22256 | return "jmp\t%A1"; |
0f40f9f7 | 22257 | } |
32ee7d1d JH |
22258 | [(set_attr "type" "callv")]) |
22259 | ||
22260 | (define_insn "*call_value_1_rex64" | |
22261 | [(set (match_operand 0 "" "") | |
22262 | (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) | |
22263 | (match_operand:DI 2 "" "")))] | |
dc4d7240 JH |
22264 | "!SIBLING_CALL_P (insn) && TARGET_64BIT |
22265 | && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC" | |
924eabec JH |
22266 | { |
22267 | if (constant_call_address_operand (operands[1], Pmode)) | |
22268 | return "call\t%P1"; | |
22269 | return "call\t%A1"; | |
22270 | } | |
22271 | [(set_attr "type" "callv")]) | |
22272 | ||
22273 | (define_insn "*call_value_1_rex64_ms_sysv" | |
22274 | [(set (match_operand 0 "" "") | |
22275 | (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) | |
22276 | (match_operand:DI 2 "" ""))) | |
22277 | (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL) | |
64e4c301 JH |
22278 | (clobber (reg:TI 27)) |
22279 | (clobber (reg:TI 28)) | |
22280 | (clobber (reg:TI 45)) | |
22281 | (clobber (reg:TI 46)) | |
22282 | (clobber (reg:TI 47)) | |
22283 | (clobber (reg:TI 48)) | |
22284 | (clobber (reg:TI 49)) | |
22285 | (clobber (reg:TI 50)) | |
22286 | (clobber (reg:TI 51)) | |
22287 | (clobber (reg:TI 52)) | |
924eabec JH |
22288 | (clobber (reg:DI SI_REG)) |
22289 | (clobber (reg:DI DI_REG))] | |
22290 | "!SIBLING_CALL_P (insn) && TARGET_64BIT" | |
69404d6f | 22291 | { |
e427abbf | 22292 | if (constant_call_address_operand (operands[1], Pmode)) |
4977bab6 ZW |
22293 | return "call\t%P1"; |
22294 | return "call\t%A1"; | |
0f40f9f7 | 22295 | } |
69404d6f | 22296 | [(set_attr "type" "callv")]) |
4977bab6 | 22297 | |
dc4d7240 JH |
22298 | (define_insn "*call_value_1_rex64_large" |
22299 | [(set (match_operand 0 "" "") | |
22300 | (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm")) | |
22301 | (match_operand:DI 2 "" "")))] | |
22302 | "!SIBLING_CALL_P (insn) && TARGET_64BIT" | |
22303 | "call\t%A1" | |
22304 | [(set_attr "type" "callv")]) | |
22305 | ||
4977bab6 ZW |
22306 | (define_insn "*sibcall_value_1_rex64" |
22307 | [(set (match_operand 0 "" "") | |
22308 | (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) | |
22309 | (match_operand:DI 2 "" "")))] | |
22310 | "SIBLING_CALL_P (insn) && TARGET_64BIT" | |
22311 | "jmp\t%P1" | |
22312 | [(set_attr "type" "callv")]) | |
22313 | ||
22314 | (define_insn "*sibcall_value_1_rex64_v" | |
22315 | [(set (match_operand 0 "" "") | |
03c259ad | 22316 | (call (mem:QI (reg:DI R11_REG)) |
4977bab6 ZW |
22317 | (match_operand:DI 1 "" "")))] |
22318 | "SIBLING_CALL_P (insn) && TARGET_64BIT" | |
9ad5e54f | 22319 | "jmp\t{*%%}r11" |
4977bab6 | 22320 | [(set_attr "type" "callv")]) |
9e3e266c | 22321 | \f |
7d69de61 | 22322 | ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. |
6300f037 | 22323 | ;; That, however, is usually mapped by the OS to SIGSEGV, which is often |
7d69de61 RH |
22324 | ;; caught for use by garbage collectors and the like. Using an insn that |
22325 | ;; maps to SIGILL makes it more likely the program will rightfully die. | |
22326 | ;; Keeping with tradition, "6" is in honor of #UD. | |
9e3e266c | 22327 | (define_insn "trap" |
7d69de61 | 22328 | [(trap_if (const_int 1) (const_int 6))] |
9e3e266c | 22329 | "" |
45050557 | 22330 | { return ASM_SHORT "0x0b0f"; } |
7d69de61 | 22331 | [(set_attr "length" "2")]) |
915119a5 | 22332 | |
ef719a44 RH |
22333 | (define_expand "sse_prologue_save" |
22334 | [(parallel [(set (match_operand:BLK 0 "" "") | |
b0d95de8 UB |
22335 | (unspec:BLK [(reg:DI 21) |
22336 | (reg:DI 22) | |
ef719a44 RH |
22337 | (reg:DI 23) |
22338 | (reg:DI 24) | |
22339 | (reg:DI 25) | |
22340 | (reg:DI 26) | |
22341 | (reg:DI 27) | |
b0d95de8 | 22342 | (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) |
ef719a44 RH |
22343 | (use (match_operand:DI 1 "register_operand" "")) |
22344 | (use (match_operand:DI 2 "immediate_operand" "")) | |
22345 | (use (label_ref:DI (match_operand 3 "" "")))])] | |
22346 | "TARGET_64BIT" | |
22347 | "") | |
0703dceb | 22348 | |
ef719a44 RH |
22349 | (define_insn "*sse_prologue_save_insn" |
22350 | [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R") | |
22351 | (match_operand:DI 4 "const_int_operand" "n"))) | |
b0d95de8 UB |
22352 | (unspec:BLK [(reg:DI 21) |
22353 | (reg:DI 22) | |
ef719a44 RH |
22354 | (reg:DI 23) |
22355 | (reg:DI 24) | |
22356 | (reg:DI 25) | |
22357 | (reg:DI 26) | |
22358 | (reg:DI 27) | |
b0d95de8 | 22359 | (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) |
ef719a44 RH |
22360 | (use (match_operand:DI 1 "register_operand" "r")) |
22361 | (use (match_operand:DI 2 "const_int_operand" "i")) | |
22362 | (use (label_ref:DI (match_operand 3 "" "X")))] | |
22363 | "TARGET_64BIT | |
7c800926 | 22364 | && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128 |
ef719a44 | 22365 | && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128" |
0703dceb | 22366 | { |
ef719a44 RH |
22367 | int i; |
22368 | operands[0] = gen_rtx_MEM (Pmode, | |
22369 | gen_rtx_PLUS (Pmode, operands[0], operands[4])); | |
95879c72 L |
22370 | /* VEX instruction with a REX prefix will #UD. */ |
22371 | if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS) | |
22372 | gcc_unreachable (); | |
22373 | ||
64ef8953 | 22374 | output_asm_insn ("jmp\t%A1", operands); |
7c800926 | 22375 | for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--) |
ef719a44 RH |
22376 | { |
22377 | operands[4] = adjust_address (operands[0], DImode, i*16); | |
22378 | operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i)); | |
22379 | PUT_MODE (operands[4], TImode); | |
22380 | if (GET_CODE (XEXP (operands[0], 0)) != PLUS) | |
64ef8953 | 22381 | output_asm_insn ("rex", operands); |
95879c72 | 22382 | output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands); |
ef719a44 | 22383 | } |
64ef8953 UB |
22384 | (*targetm.asm_out.internal_label) (asm_out_file, "L", |
22385 | CODE_LABEL_NUMBER (operands[3])); | |
22386 | return ""; | |
0703dceb | 22387 | } |
ef719a44 RH |
22388 | [(set_attr "type" "other") |
22389 | (set_attr "length_immediate" "0") | |
22390 | (set_attr "length_address" "0") | |
95879c72 L |
22391 | (set (attr "length") |
22392 | (if_then_else | |
22393 | (eq (symbol_ref "TARGET_AVX") (const_int 0)) | |
22394 | (const_string "34") | |
22395 | (const_string "42"))) | |
ef719a44 RH |
22396 | (set_attr "memory" "store") |
22397 | (set_attr "modrm" "0") | |
95879c72 | 22398 | (set_attr "prefix" "maybe_vex") |
3d34cd91 | 22399 | (set_attr "mode" "DI")]) |
915119a5 | 22400 | |
ef719a44 RH |
22401 | (define_expand "prefetch" |
22402 | [(prefetch (match_operand 0 "address_operand" "") | |
22403 | (match_operand:SI 1 "const_int_operand" "") | |
22404 | (match_operand:SI 2 "const_int_operand" ""))] | |
22405 | "TARGET_PREFETCH_SSE || TARGET_3DNOW" | |
1c47af84 | 22406 | { |
ef719a44 RH |
22407 | int rw = INTVAL (operands[1]); |
22408 | int locality = INTVAL (operands[2]); | |
1c47af84 | 22409 | |
7637e42c NS |
22410 | gcc_assert (rw == 0 || rw == 1); |
22411 | gcc_assert (locality >= 0 && locality <= 3); | |
22412 | gcc_assert (GET_MODE (operands[0]) == Pmode | |
22413 | || GET_MODE (operands[0]) == VOIDmode); | |
1c47af84 | 22414 | |
ef719a44 | 22415 | /* Use 3dNOW prefetch in case we are asking for write prefetch not |
aabcd309 | 22416 | supported by SSE counterpart or the SSE prefetch is not available |
ef719a44 RH |
22417 | (K6 machines). Otherwise use SSE prefetch as it allows specifying |
22418 | of locality. */ | |
22419 | if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw)) | |
22420 | operands[2] = GEN_INT (3); | |
22421 | else | |
22422 | operands[1] = const0_rtx; | |
1c47af84 RH |
22423 | }) |
22424 | ||
ef719a44 RH |
22425 | (define_insn "*prefetch_sse" |
22426 | [(prefetch (match_operand:SI 0 "address_operand" "p") | |
22427 | (const_int 0) | |
22428 | (match_operand:SI 1 "const_int_operand" ""))] | |
22429 | "TARGET_PREFETCH_SSE && !TARGET_64BIT" | |
4977bab6 | 22430 | { |
ef719a44 RH |
22431 | static const char * const patterns[4] = { |
22432 | "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" | |
22433 | }; | |
fbe5eb6d | 22434 | |
ef719a44 | 22435 | int locality = INTVAL (operands[1]); |
7637e42c | 22436 | gcc_assert (locality >= 0 && locality <= 3); |
fbe5eb6d | 22437 | |
6300f037 | 22438 | return patterns[locality]; |
ef719a44 | 22439 | } |
fbe5eb6d | 22440 | [(set_attr "type" "sse") |
b6837b94 | 22441 | (set_attr "atom_sse_attr" "prefetch") |
725fd454 | 22442 | (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])")) |
ef719a44 | 22443 | (set_attr "memory" "none")]) |
fbe5eb6d | 22444 | |
ef719a44 RH |
22445 | (define_insn "*prefetch_sse_rex" |
22446 | [(prefetch (match_operand:DI 0 "address_operand" "p") | |
22447 | (const_int 0) | |
22448 | (match_operand:SI 1 "const_int_operand" ""))] | |
22449 | "TARGET_PREFETCH_SSE && TARGET_64BIT" | |
fbe5eb6d | 22450 | { |
ef719a44 RH |
22451 | static const char * const patterns[4] = { |
22452 | "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" | |
22453 | }; | |
22c7c85e | 22454 | |
ef719a44 | 22455 | int locality = INTVAL (operands[1]); |
7637e42c | 22456 | gcc_assert (locality >= 0 && locality <= 3); |
22c7c85e | 22457 | |
6300f037 | 22458 | return patterns[locality]; |
ef719a44 | 22459 | } |
22c7c85e | 22460 | [(set_attr "type" "sse") |
b6837b94 | 22461 | (set_attr "atom_sse_attr" "prefetch") |
725fd454 | 22462 | (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])")) |
ef719a44 | 22463 | (set_attr "memory" "none")]) |
22c7c85e | 22464 | |
ef719a44 RH |
22465 | (define_insn "*prefetch_3dnow" |
22466 | [(prefetch (match_operand:SI 0 "address_operand" "p") | |
22467 | (match_operand:SI 1 "const_int_operand" "n") | |
22468 | (const_int 3))] | |
22469 | "TARGET_3DNOW && !TARGET_64BIT" | |
22470 | { | |
22471 | if (INTVAL (operands[1]) == 0) | |
22472 | return "prefetch\t%a0"; | |
22473 | else | |
22474 | return "prefetchw\t%a0"; | |
22475 | } | |
22476 | [(set_attr "type" "mmx") | |
725fd454 | 22477 | (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])")) |
ef719a44 | 22478 | (set_attr "memory" "none")]) |
22c7c85e | 22479 | |
ef719a44 RH |
22480 | (define_insn "*prefetch_3dnow_rex" |
22481 | [(prefetch (match_operand:DI 0 "address_operand" "p") | |
22482 | (match_operand:SI 1 "const_int_operand" "n") | |
22483 | (const_int 3))] | |
22484 | "TARGET_3DNOW && TARGET_64BIT" | |
22485 | { | |
22486 | if (INTVAL (operands[1]) == 0) | |
22487 | return "prefetch\t%a0"; | |
22488 | else | |
22489 | return "prefetchw\t%a0"; | |
22490 | } | |
22491 | [(set_attr "type" "mmx") | |
725fd454 | 22492 | (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])")) |
ef719a44 | 22493 | (set_attr "memory" "none")]) |
22c7c85e | 22494 | |
7d69de61 RH |
22495 | (define_expand "stack_protect_set" |
22496 | [(match_operand 0 "memory_operand" "") | |
22497 | (match_operand 1 "memory_operand" "")] | |
22498 | "" | |
22499 | { | |
77008252 JJ |
22500 | #ifdef TARGET_THREAD_SSP_OFFSET |
22501 | if (TARGET_64BIT) | |
22502 | emit_insn (gen_stack_tls_protect_set_di (operands[0], | |
22503 | GEN_INT (TARGET_THREAD_SSP_OFFSET))); | |
22504 | else | |
22505 | emit_insn (gen_stack_tls_protect_set_si (operands[0], | |
22506 | GEN_INT (TARGET_THREAD_SSP_OFFSET))); | |
22507 | #else | |
7d69de61 RH |
22508 | if (TARGET_64BIT) |
22509 | emit_insn (gen_stack_protect_set_di (operands[0], operands[1])); | |
22510 | else | |
22511 | emit_insn (gen_stack_protect_set_si (operands[0], operands[1])); | |
77008252 | 22512 | #endif |
7d69de61 RH |
22513 | DONE; |
22514 | }) | |
22515 | ||
22516 | (define_insn "stack_protect_set_si" | |
22517 | [(set (match_operand:SI 0 "memory_operand" "=m") | |
22518 | (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) | |
7ce918c5 | 22519 | (set (match_scratch:SI 2 "=&r") (const_int 0)) |
7d69de61 RH |
22520 | (clobber (reg:CC FLAGS_REG))] |
22521 | "" | |
22522 | "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" | |
22523 | [(set_attr "type" "multi")]) | |
22524 | ||
22525 | (define_insn "stack_protect_set_di" | |
22526 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
22527 | (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) | |
7ce918c5 | 22528 | (set (match_scratch:DI 2 "=&r") (const_int 0)) |
7d69de61 RH |
22529 | (clobber (reg:CC FLAGS_REG))] |
22530 | "TARGET_64BIT" | |
7ce918c5 | 22531 | "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" |
7d69de61 RH |
22532 | [(set_attr "type" "multi")]) |
22533 | ||
77008252 JJ |
22534 | (define_insn "stack_tls_protect_set_si" |
22535 | [(set (match_operand:SI 0 "memory_operand" "=m") | |
22536 | (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) | |
22537 | (set (match_scratch:SI 2 "=&r") (const_int 0)) | |
22538 | (clobber (reg:CC FLAGS_REG))] | |
22539 | "" | |
9ad5e54f | 22540 | "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" |
77008252 JJ |
22541 | [(set_attr "type" "multi")]) |
22542 | ||
22543 | (define_insn "stack_tls_protect_set_di" | |
22544 | [(set (match_operand:DI 0 "memory_operand" "=m") | |
22545 | (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) | |
22546 | (set (match_scratch:DI 2 "=&r") (const_int 0)) | |
22547 | (clobber (reg:CC FLAGS_REG))] | |
22548 | "TARGET_64BIT" | |
fa6adcab AV |
22549 | { |
22550 | /* The kernel uses a different segment register for performance reasons; a | |
22551 | system call would not have to trash the userspace segment register, | |
22552 | which would be expensive */ | |
22553 | if (ix86_cmodel != CM_KERNEL) | |
9ad5e54f | 22554 | return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; |
fa6adcab | 22555 | else |
9ad5e54f | 22556 | return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; |
fa6adcab | 22557 | } |
77008252 JJ |
22558 | [(set_attr "type" "multi")]) |
22559 | ||
7d69de61 RH |
22560 | (define_expand "stack_protect_test" |
22561 | [(match_operand 0 "memory_operand" "") | |
3aebbe5f JJ |
22562 | (match_operand 1 "memory_operand" "") |
22563 | (match_operand 2 "" "")] | |
7d69de61 RH |
22564 | "" |
22565 | { | |
22566 | rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); | |
7d69de61 | 22567 | |
77008252 JJ |
22568 | #ifdef TARGET_THREAD_SSP_OFFSET |
22569 | if (TARGET_64BIT) | |
22570 | emit_insn (gen_stack_tls_protect_test_di (flags, operands[0], | |
22571 | GEN_INT (TARGET_THREAD_SSP_OFFSET))); | |
22572 | else | |
22573 | emit_insn (gen_stack_tls_protect_test_si (flags, operands[0], | |
22574 | GEN_INT (TARGET_THREAD_SSP_OFFSET))); | |
22575 | #else | |
7d69de61 RH |
22576 | if (TARGET_64BIT) |
22577 | emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1])); | |
22578 | else | |
22579 | emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1])); | |
77008252 | 22580 | #endif |
67b8f1c1 | 22581 | |
f90b7a5a PB |
22582 | emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx), |
22583 | flags, const0_rtx, operands[2])); | |
7d69de61 RH |
22584 | DONE; |
22585 | }) | |
22586 | ||
22587 | (define_insn "stack_protect_test_si" | |
22588 | [(set (match_operand:CCZ 0 "flags_reg_operand" "") | |
22589 | (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") | |
22590 | (match_operand:SI 2 "memory_operand" "m")] | |
22591 | UNSPEC_SP_TEST)) | |
4f856a3e | 22592 | (clobber (match_scratch:SI 3 "=&r"))] |
7d69de61 RH |
22593 | "" |
22594 | "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}" | |
22595 | [(set_attr "type" "multi")]) | |
22596 | ||
22597 | (define_insn "stack_protect_test_di" | |
22598 | [(set (match_operand:CCZ 0 "flags_reg_operand" "") | |
22599 | (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") | |
22600 | (match_operand:DI 2 "memory_operand" "m")] | |
22601 | UNSPEC_SP_TEST)) | |
4f856a3e | 22602 | (clobber (match_scratch:DI 3 "=&r"))] |
7d69de61 RH |
22603 | "TARGET_64BIT" |
22604 | "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}" | |
22605 | [(set_attr "type" "multi")]) | |
22606 | ||
77008252 JJ |
22607 | (define_insn "stack_tls_protect_test_si" |
22608 | [(set (match_operand:CCZ 0 "flags_reg_operand" "") | |
22609 | (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") | |
22610 | (match_operand:SI 2 "const_int_operand" "i")] | |
22611 | UNSPEC_SP_TLS_TEST)) | |
22612 | (clobber (match_scratch:SI 3 "=r"))] | |
22613 | "" | |
9ad5e54f | 22614 | "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}" |
77008252 JJ |
22615 | [(set_attr "type" "multi")]) |
22616 | ||
22617 | (define_insn "stack_tls_protect_test_di" | |
22618 | [(set (match_operand:CCZ 0 "flags_reg_operand" "") | |
22619 | (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") | |
22620 | (match_operand:DI 2 "const_int_operand" "i")] | |
22621 | UNSPEC_SP_TLS_TEST)) | |
22622 | (clobber (match_scratch:DI 3 "=r"))] | |
22623 | "TARGET_64BIT" | |
fa6adcab AV |
22624 | { |
22625 | /* The kernel uses a different segment register for performance reasons; a | |
22626 | system call would not have to trash the userspace segment register, | |
22627 | which would be expensive */ | |
22628 | if (ix86_cmodel != CM_KERNEL) | |
9ad5e54f | 22629 | return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}"; |
fa6adcab | 22630 | else |
9ad5e54f | 22631 | return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}"; |
fa6adcab | 22632 | } |
77008252 JJ |
22633 | [(set_attr "type" "multi")]) |
22634 | ||
3abcb3a7 | 22635 | (define_mode_iterator CRC32MODE [QI HI SI]) |
3b8dd071 L |
22636 | (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")]) |
22637 | (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")]) | |
22638 | ||
22639 | (define_insn "sse4_2_crc32<mode>" | |
22640 | [(set (match_operand:SI 0 "register_operand" "=r") | |
22641 | (unspec:SI | |
22642 | [(match_operand:SI 1 "register_operand" "0") | |
22643 | (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")] | |
22644 | UNSPEC_CRC32))] | |
22645 | "TARGET_SSE4_2" | |
22646 | "crc32<crc32modesuffix>\t{%2, %0|%0, %2}" | |
22647 | [(set_attr "type" "sselog1") | |
22648 | (set_attr "prefix_rep" "1") | |
22649 | (set_attr "prefix_extra" "1") | |
725fd454 JJ |
22650 | (set (attr "prefix_data16") |
22651 | (if_then_else (match_operand:HI 2 "" "") | |
22652 | (const_string "1") | |
22653 | (const_string "*"))) | |
22654 | (set (attr "prefix_rex") | |
22655 | (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "") | |
22656 | (const_string "1") | |
22657 | (const_string "*"))) | |
3b8dd071 L |
22658 | (set_attr "mode" "SI")]) |
22659 | ||
22660 | (define_insn "sse4_2_crc32di" | |
22661 | [(set (match_operand:DI 0 "register_operand" "=r") | |
22662 | (unspec:DI | |
22663 | [(match_operand:DI 1 "register_operand" "0") | |
22664 | (match_operand:DI 2 "nonimmediate_operand" "rm")] | |
22665 | UNSPEC_CRC32))] | |
22666 | "TARGET_SSE4_2 && TARGET_64BIT" | |
22667 | "crc32q\t{%2, %0|%0, %2}" | |
22668 | [(set_attr "type" "sselog1") | |
22669 | (set_attr "prefix_rep" "1") | |
22670 | (set_attr "prefix_extra" "1") | |
22671 | (set_attr "mode" "DI")]) | |
22672 | ||
80e8bb90 | 22673 | (include "mmx.md") |
b1875f52 | 22674 | (include "sse.md") |
1ef45b77 | 22675 | (include "sync.md") |