Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/i386/mmx.md @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 3bfb6c00c1e0 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 ;; GCC machine description for MMX and 3dNOW! instructions | |
2 ;; Copyright (C) 2005, 2007, 2008 | |
3 ;; Free Software Foundation, Inc. | |
4 ;; | |
5 ;; This file is part of GCC. | |
6 ;; | |
7 ;; GCC is free software; you can redistribute it and/or modify | |
8 ;; it under the terms of the GNU General Public License as published by | |
9 ;; the Free Software Foundation; either version 3, or (at your option) | |
10 ;; any later version. | |
11 ;; | |
12 ;; GCC is distributed in the hope that it will be useful, | |
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 ;; GNU General Public License for more details. | |
16 ;; | |
17 ;; You should have received a copy of the GNU General Public License | |
18 ;; along with GCC; see the file COPYING3. If not see | |
19 ;; <http://www.gnu.org/licenses/>. | |
20 | |
21 ;; The MMX and 3dNOW! patterns are in the same file because they use | |
22 ;; the same register file, and 3dNOW! adds a number of extensions to | |
23 ;; the base integer MMX isa. | |
24 | |
25 ;; Note! Except for the basic move instructions, *all* of these | |
26 ;; patterns are outside the normal optabs namespace. This is because | |
27 ;; use of these registers requires the insertion of emms or femms | |
28 ;; instructions to return to normal fpu mode. The compiler doesn't | |
29 ;; know how to do that itself, which means it's up to the user. Which | |
30 ;; means that we should never use any of these patterns except at the | |
31 ;; direction of the user via a builtin. | |
32 | |
33 ;; 8 byte integral modes handled by MMX (and by extension, SSE) | |
34 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI]) | |
35 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI]) | |
36 | |
37 ;; All 8-byte vector modes handled by MMX | |
38 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF]) | |
39 | |
40 ;; Mix-n-match | |
41 (define_mode_iterator MMXMODE12 [V8QI V4HI]) | |
42 (define_mode_iterator MMXMODE24 [V4HI V2SI]) | |
43 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI]) | |
44 | |
45 ;; Mapping from integer vector mode to mnemonic suffix | |
46 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")]) | |
47 | |
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
49 ;; | |
50 ;; Move patterns | |
51 ;; | |
52 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
53 | |
54 ;; All of these patterns are enabled for MMX as well as 3dNOW. | |
55 ;; This is essential for maintaining stable calling conventions. | |
56 | |
57 (define_expand "mov<mode>" | |
58 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" "") | |
59 (match_operand:MMXMODEI8 1 "nonimmediate_operand" ""))] | |
60 "TARGET_MMX" | |
61 { | |
62 ix86_expand_vector_move (<MODE>mode, operands); | |
63 DONE; | |
64 }) | |
65 | |
66 (define_insn "*mov<mode>_internal_rex64" | |
67 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" | |
68 "=rm,r,!?y,!?y ,m ,!y,*Y2,x,x ,m,r,Yi") | |
69 (match_operand:MMXMODEI8 1 "vector_move_operand" | |
70 "Cr ,m,C ,!?ym,!?y,*Y2,!y,C,xm,x,Yi,r"))] | |
71 "TARGET_64BIT && TARGET_MMX | |
72 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
73 "@ | |
74 mov{q}\t{%1, %0|%0, %1} | |
75 mov{q}\t{%1, %0|%0, %1} | |
76 pxor\t%0, %0 | |
77 movq\t{%1, %0|%0, %1} | |
78 movq\t{%1, %0|%0, %1} | |
79 movdq2q\t{%1, %0|%0, %1} | |
80 movq2dq\t{%1, %0|%0, %1} | |
81 %vpxor\t%0, %d0 | |
82 %vmovq\t{%1, %0|%0, %1} | |
83 %vmovq\t{%1, %0|%0, %1} | |
84 %vmovq\t{%1, %0|%0, %1} | |
85 %vmovq\t{%1, %0|%0, %1}" | |
86 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov") | |
87 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*") | |
88 (set (attr "prefix") | |
89 (if_then_else (eq_attr "alternative" "7,8,9,10,11") | |
90 (const_string "maybe_vex") | |
91 (const_string "orig"))) | |
92 (set_attr "mode" "DI")]) | |
93 | |
94 (define_insn "*mov<mode>_internal_avx" | |
95 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" | |
96 "=!?y,!?y,m ,!y ,*Y2,*Y2,*Y2 ,m ,r ,m") | |
97 (match_operand:MMXMODEI8 1 "vector_move_operand" | |
98 "C ,!ym,!?y,*Y2,!y ,C ,*Y2m,*Y2,irm,r"))] | |
99 "TARGET_AVX | |
100 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
101 "@ | |
102 pxor\t%0, %0 | |
103 movq\t{%1, %0|%0, %1} | |
104 movq\t{%1, %0|%0, %1} | |
105 movdq2q\t{%1, %0|%0, %1} | |
106 movq2dq\t{%1, %0|%0, %1} | |
107 vpxor\t%0, %0, %0 | |
108 vmovq\t{%1, %0|%0, %1} | |
109 vmovq\t{%1, %0|%0, %1} | |
110 # | |
111 #" | |
112 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,*,*") | |
113 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*") | |
114 (set (attr "prefix") | |
115 (if_then_else (eq_attr "alternative" "5,6,7") | |
116 (const_string "vex") | |
117 (const_string "orig"))) | |
118 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,DI,DI")]) | |
119 | |
120 (define_insn "*mov<mode>_internal" | |
121 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" | |
122 "=!?y,!?y,m ,!y ,*Y2,*Y2,*Y2 ,m ,*x,*x,*x,m ,r ,m") | |
123 (match_operand:MMXMODEI8 1 "vector_move_operand" | |
124 "C ,!ym,!?y,*Y2,!y ,C ,*Y2m,*Y2,C ,*x,m ,*x,irm,r"))] | |
125 "TARGET_MMX | |
126 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
127 "@ | |
128 pxor\t%0, %0 | |
129 movq\t{%1, %0|%0, %1} | |
130 movq\t{%1, %0|%0, %1} | |
131 movdq2q\t{%1, %0|%0, %1} | |
132 movq2dq\t{%1, %0|%0, %1} | |
133 pxor\t%0, %0 | |
134 movq\t{%1, %0|%0, %1} | |
135 movq\t{%1, %0|%0, %1} | |
136 xorps\t%0, %0 | |
137 movaps\t{%1, %0|%0, %1} | |
138 movlps\t{%1, %0|%0, %1} | |
139 movlps\t{%1, %0|%0, %1} | |
140 # | |
141 #" | |
142 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*") | |
143 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*") | |
144 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) | |
145 | |
146 (define_expand "movv2sf" | |
147 [(set (match_operand:V2SF 0 "nonimmediate_operand" "") | |
148 (match_operand:V2SF 1 "nonimmediate_operand" ""))] | |
149 "TARGET_MMX" | |
150 { | |
151 ix86_expand_vector_move (V2SFmode, operands); | |
152 DONE; | |
153 }) | |
154 | |
155 (define_insn "*movv2sf_internal_rex64_avx" | |
156 [(set (match_operand:V2SF 0 "nonimmediate_operand" | |
157 "=rm,r ,!?y,!?y ,m ,!y,Y2,x,x,x,m,r,x") | |
158 (match_operand:V2SF 1 "vector_move_operand" | |
159 "Cr ,m ,C ,!?ym,!y,Y2,!y,C,x,m,x,x,r"))] | |
160 "TARGET_64BIT && TARGET_AVX | |
161 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
162 "@ | |
163 mov{q}\t{%1, %0|%0, %1} | |
164 mov{q}\t{%1, %0|%0, %1} | |
165 pxor\t%0, %0 | |
166 movq\t{%1, %0|%0, %1} | |
167 movq\t{%1, %0|%0, %1} | |
168 movdq2q\t{%1, %0|%0, %1} | |
169 movq2dq\t{%1, %0|%0, %1} | |
170 vxorps\t%0, %0, %0 | |
171 vmovaps\t{%1, %0|%0, %1} | |
172 vmovlps\t{%1, %0, %0|%0, %0, %1} | |
173 vmovlps\t{%1, %0|%0, %1} | |
174 vmovq\t{%1, %0|%0, %1} | |
175 vmovq\t{%1, %0|%0, %1}" | |
176 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov") | |
177 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*") | |
178 (set (attr "prefix") | |
179 (if_then_else (eq_attr "alternative" "7,8,9,10,11,12") | |
180 (const_string "vex") | |
181 (const_string "orig"))) | |
182 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) | |
183 | |
184 (define_insn "*movv2sf_internal_rex64" | |
185 [(set (match_operand:V2SF 0 "nonimmediate_operand" | |
186 "=rm,r ,!?y,!?y ,m ,!y,*Y2,x,x,x,m,r,Yi") | |
187 (match_operand:V2SF 1 "vector_move_operand" | |
188 "Cr ,m ,C ,!?ym,!y,*Y2,!y,C,x,m,x,Yi,r"))] | |
189 "TARGET_64BIT && TARGET_MMX | |
190 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
191 "@ | |
192 mov{q}\t{%1, %0|%0, %1} | |
193 mov{q}\t{%1, %0|%0, %1} | |
194 pxor\t%0, %0 | |
195 movq\t{%1, %0|%0, %1} | |
196 movq\t{%1, %0|%0, %1} | |
197 movdq2q\t{%1, %0|%0, %1} | |
198 movq2dq\t{%1, %0|%0, %1} | |
199 xorps\t%0, %0 | |
200 movaps\t{%1, %0|%0, %1} | |
201 movlps\t{%1, %0|%0, %1} | |
202 movlps\t{%1, %0|%0, %1} | |
203 movd\t{%1, %0|%0, %1} | |
204 movd\t{%1, %0|%0, %1}" | |
205 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov") | |
206 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*") | |
207 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) | |
208 | |
209 (define_insn "*movv2sf_internal_avx" | |
210 [(set (match_operand:V2SF 0 "nonimmediate_operand" | |
211 "=!?y,!?y ,m ,!y ,*Y2,*x,*x,*x,m ,r ,m") | |
212 (match_operand:V2SF 1 "vector_move_operand" | |
213 "C ,!?ym,!?y,*Y2,!y ,C ,*x,m ,*x,irm,r"))] | |
214 "TARGET_AVX | |
215 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
216 "@ | |
217 pxor\t%0, %0 | |
218 movq\t{%1, %0|%0, %1} | |
219 movq\t{%1, %0|%0, %1} | |
220 movdq2q\t{%1, %0|%0, %1} | |
221 movq2dq\t{%1, %0|%0, %1} | |
222 vxorps\t%0, %0, %0 | |
223 vmovaps\t{%1, %0|%0, %1} | |
224 vmovlps\t{%1, %0, %0|%0, %0, %1} | |
225 vmovlps\t{%1, %0|%0, %1} | |
226 # | |
227 #" | |
228 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*") | |
229 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*") | |
230 (set (attr "prefix") | |
231 (if_then_else (eq_attr "alternative" "5,6,7,8") | |
232 (const_string "vex") | |
233 (const_string "orig"))) | |
234 (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) | |
235 | |
236 (define_insn "*movv2sf_internal" | |
237 [(set (match_operand:V2SF 0 "nonimmediate_operand" | |
238 "=!?y,!?y ,m ,!y ,*Y2,*x,*x,*x,m ,r ,m") | |
239 (match_operand:V2SF 1 "vector_move_operand" | |
240 "C ,!?ym,!?y,*Y2,!y ,C ,*x,m ,*x,irm,r"))] | |
241 "TARGET_MMX | |
242 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
243 "@ | |
244 pxor\t%0, %0 | |
245 movq\t{%1, %0|%0, %1} | |
246 movq\t{%1, %0|%0, %1} | |
247 movdq2q\t{%1, %0|%0, %1} | |
248 movq2dq\t{%1, %0|%0, %1} | |
249 xorps\t%0, %0 | |
250 movaps\t{%1, %0|%0, %1} | |
251 movlps\t{%1, %0|%0, %1} | |
252 movlps\t{%1, %0|%0, %1} | |
253 # | |
254 #" | |
255 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*") | |
256 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*") | |
257 (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) | |
258 | |
259 ;; %%% This multiword shite has got to go. | |
260 (define_split | |
261 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "") | |
262 (match_operand:MMXMODE 1 "general_operand" ""))] | |
263 "!TARGET_64BIT && reload_completed | |
264 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) | |
265 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" | |
266 [(const_int 0)] | |
267 "ix86_split_long_move (operands); DONE;") | |
268 | |
269 (define_expand "push<mode>1" | |
270 [(match_operand:MMXMODE 0 "register_operand" "")] | |
271 "TARGET_MMX" | |
272 { | |
273 ix86_expand_push (<MODE>mode, operands[0]); | |
274 DONE; | |
275 }) | |
276 | |
277 (define_expand "movmisalign<mode>" | |
278 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "") | |
279 (match_operand:MMXMODE 1 "nonimmediate_operand" ""))] | |
280 "TARGET_MMX" | |
281 { | |
282 ix86_expand_vector_move (<MODE>mode, operands); | |
283 DONE; | |
284 }) | |
285 | |
286 (define_insn "sse_movntdi" | |
287 [(set (match_operand:DI 0 "memory_operand" "=m") | |
288 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] | |
289 UNSPEC_MOVNT))] | |
290 "TARGET_SSE || TARGET_3DNOW_A" | |
291 "movntq\t{%1, %0|%0, %1}" | |
292 [(set_attr "type" "mmxmov") | |
293 (set_attr "mode" "DI")]) | |
294 | |
295 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
296 ;; | |
297 ;; Parallel single-precision floating point arithmetic | |
298 ;; | |
299 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
300 | |
301 (define_expand "mmx_addv2sf3" | |
302 [(set (match_operand:V2SF 0 "register_operand" "") | |
303 (plus:V2SF | |
304 (match_operand:V2SF 1 "nonimmediate_operand" "") | |
305 (match_operand:V2SF 2 "nonimmediate_operand" "")))] | |
306 "TARGET_3DNOW" | |
307 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);") | |
308 | |
309 (define_insn "*mmx_addv2sf3" | |
310 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
311 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") | |
312 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] | |
313 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)" | |
314 "pfadd\t{%2, %0|%0, %2}" | |
315 [(set_attr "type" "mmxadd") | |
316 (set_attr "mode" "V2SF")]) | |
317 | |
318 (define_expand "mmx_subv2sf3" | |
319 [(set (match_operand:V2SF 0 "register_operand" "") | |
320 (minus:V2SF (match_operand:V2SF 1 "register_operand" "") | |
321 (match_operand:V2SF 2 "nonimmediate_operand" "")))] | |
322 "TARGET_3DNOW" | |
323 "") | |
324 | |
325 (define_expand "mmx_subrv2sf3" | |
326 [(set (match_operand:V2SF 0 "register_operand" "") | |
327 (minus:V2SF (match_operand:V2SF 2 "register_operand" "") | |
328 (match_operand:V2SF 1 "nonimmediate_operand" "")))] | |
329 "TARGET_3DNOW" | |
330 "") | |
331 | |
332 (define_insn "*mmx_subv2sf3" | |
333 [(set (match_operand:V2SF 0 "register_operand" "=y,y") | |
334 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym") | |
335 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))] | |
336 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
337 "@ | |
338 pfsub\t{%2, %0|%0, %2} | |
339 pfsubr\t{%2, %0|%0, %2}" | |
340 [(set_attr "type" "mmxadd") | |
341 (set_attr "mode" "V2SF")]) | |
342 | |
343 (define_expand "mmx_mulv2sf3" | |
344 [(set (match_operand:V2SF 0 "register_operand" "") | |
345 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "") | |
346 (match_operand:V2SF 2 "nonimmediate_operand" "")))] | |
347 "TARGET_3DNOW" | |
348 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);") | |
349 | |
350 (define_insn "*mmx_mulv2sf3" | |
351 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
352 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") | |
353 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] | |
354 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)" | |
355 "pfmul\t{%2, %0|%0, %2}" | |
356 [(set_attr "type" "mmxmul") | |
357 (set_attr "mode" "V2SF")]) | |
358 | |
359 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX | |
360 ;; isn't really correct, as those rtl operators aren't defined when | |
361 ;; applied to NaNs. Hopefully the optimizers won't get too smart on us. | |
362 | |
363 (define_expand "mmx_<code>v2sf3" | |
364 [(set (match_operand:V2SF 0 "register_operand" "") | |
365 (smaxmin:V2SF | |
366 (match_operand:V2SF 1 "nonimmediate_operand" "") | |
367 (match_operand:V2SF 2 "nonimmediate_operand" "")))] | |
368 "TARGET_3DNOW" | |
369 { | |
370 if (!flag_finite_math_only) | |
371 operands[1] = force_reg (V2SFmode, operands[1]); | |
372 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands); | |
373 }) | |
374 | |
375 (define_insn "*mmx_<code>v2sf3_finite" | |
376 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
377 (smaxmin:V2SF | |
378 (match_operand:V2SF 1 "nonimmediate_operand" "%0") | |
379 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] | |
380 "TARGET_3DNOW && flag_finite_math_only | |
381 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)" | |
382 "pf<maxminfprefix>\t{%2, %0|%0, %2}" | |
383 [(set_attr "type" "mmxadd") | |
384 (set_attr "mode" "V2SF")]) | |
385 | |
386 (define_insn "*mmx_<code>v2sf3" | |
387 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
388 (smaxmin:V2SF | |
389 (match_operand:V2SF 1 "register_operand" "0") | |
390 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] | |
391 "TARGET_3DNOW" | |
392 "pf<maxminfprefix>\t{%2, %0|%0, %2}" | |
393 [(set_attr "type" "mmxadd") | |
394 (set_attr "mode" "V2SF")]) | |
395 | |
396 (define_insn "mmx_rcpv2sf2" | |
397 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
398 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] | |
399 UNSPEC_PFRCP))] | |
400 "TARGET_3DNOW" | |
401 "pfrcp\t{%1, %0|%0, %1}" | |
402 [(set_attr "type" "mmx") | |
403 (set_attr "mode" "V2SF")]) | |
404 | |
405 (define_insn "mmx_rcpit1v2sf3" | |
406 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
407 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") | |
408 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] | |
409 UNSPEC_PFRCPIT1))] | |
410 "TARGET_3DNOW" | |
411 "pfrcpit1\t{%2, %0|%0, %2}" | |
412 [(set_attr "type" "mmx") | |
413 (set_attr "mode" "V2SF")]) | |
414 | |
415 (define_insn "mmx_rcpit2v2sf3" | |
416 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
417 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") | |
418 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] | |
419 UNSPEC_PFRCPIT2))] | |
420 "TARGET_3DNOW" | |
421 "pfrcpit2\t{%2, %0|%0, %2}" | |
422 [(set_attr "type" "mmx") | |
423 (set_attr "mode" "V2SF")]) | |
424 | |
425 (define_insn "mmx_rsqrtv2sf2" | |
426 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
427 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] | |
428 UNSPEC_PFRSQRT))] | |
429 "TARGET_3DNOW" | |
430 "pfrsqrt\t{%1, %0|%0, %1}" | |
431 [(set_attr "type" "mmx") | |
432 (set_attr "mode" "V2SF")]) | |
433 | |
434 (define_insn "mmx_rsqit1v2sf3" | |
435 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
436 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") | |
437 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] | |
438 UNSPEC_PFRSQIT1))] | |
439 "TARGET_3DNOW" | |
440 "pfrsqit1\t{%2, %0|%0, %2}" | |
441 [(set_attr "type" "mmx") | |
442 (set_attr "mode" "V2SF")]) | |
443 | |
444 (define_insn "mmx_haddv2sf3" | |
445 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
446 (vec_concat:V2SF | |
447 (plus:SF | |
448 (vec_select:SF | |
449 (match_operand:V2SF 1 "register_operand" "0") | |
450 (parallel [(const_int 0)])) | |
451 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) | |
452 (plus:SF | |
453 (vec_select:SF | |
454 (match_operand:V2SF 2 "nonimmediate_operand" "ym") | |
455 (parallel [(const_int 0)])) | |
456 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] | |
457 "TARGET_3DNOW" | |
458 "pfacc\t{%2, %0|%0, %2}" | |
459 [(set_attr "type" "mmxadd") | |
460 (set_attr "mode" "V2SF")]) | |
461 | |
462 (define_insn "mmx_hsubv2sf3" | |
463 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
464 (vec_concat:V2SF | |
465 (minus:SF | |
466 (vec_select:SF | |
467 (match_operand:V2SF 1 "register_operand" "0") | |
468 (parallel [(const_int 0)])) | |
469 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) | |
470 (minus:SF | |
471 (vec_select:SF | |
472 (match_operand:V2SF 2 "nonimmediate_operand" "ym") | |
473 (parallel [(const_int 0)])) | |
474 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] | |
475 "TARGET_3DNOW_A" | |
476 "pfnacc\t{%2, %0|%0, %2}" | |
477 [(set_attr "type" "mmxadd") | |
478 (set_attr "mode" "V2SF")]) | |
479 | |
480 (define_insn "mmx_addsubv2sf3" | |
481 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
482 (vec_merge:V2SF | |
483 (plus:V2SF | |
484 (match_operand:V2SF 1 "register_operand" "0") | |
485 (match_operand:V2SF 2 "nonimmediate_operand" "ym")) | |
486 (minus:V2SF (match_dup 1) (match_dup 2)) | |
487 (const_int 1)))] | |
488 "TARGET_3DNOW_A" | |
489 "pfpnacc\t{%2, %0|%0, %2}" | |
490 [(set_attr "type" "mmxadd") | |
491 (set_attr "mode" "V2SF")]) | |
492 | |
493 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
494 ;; | |
495 ;; Parallel single-precision floating point comparisons | |
496 ;; | |
497 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
498 | |
499 (define_expand "mmx_eqv2sf3" | |
500 [(set (match_operand:V2SI 0 "register_operand" "") | |
501 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "") | |
502 (match_operand:V2SF 2 "nonimmediate_operand" "")))] | |
503 "TARGET_3DNOW" | |
504 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);") | |
505 | |
506 (define_insn "*mmx_eqv2sf3" | |
507 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
508 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0") | |
509 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] | |
510 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)" | |
511 "pfcmpeq\t{%2, %0|%0, %2}" | |
512 [(set_attr "type" "mmxcmp") | |
513 (set_attr "mode" "V2SF")]) | |
514 | |
515 (define_insn "mmx_gtv2sf3" | |
516 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
517 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0") | |
518 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] | |
519 "TARGET_3DNOW" | |
520 "pfcmpgt\t{%2, %0|%0, %2}" | |
521 [(set_attr "type" "mmxcmp") | |
522 (set_attr "mode" "V2SF")]) | |
523 | |
524 (define_insn "mmx_gev2sf3" | |
525 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
526 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0") | |
527 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] | |
528 "TARGET_3DNOW" | |
529 "pfcmpge\t{%2, %0|%0, %2}" | |
530 [(set_attr "type" "mmxcmp") | |
531 (set_attr "mode" "V2SF")]) | |
532 | |
533 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
534 ;; | |
535 ;; Parallel single-precision floating point conversion operations | |
536 ;; | |
537 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
538 | |
539 (define_insn "mmx_pf2id" | |
540 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
541 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))] | |
542 "TARGET_3DNOW" | |
543 "pf2id\t{%1, %0|%0, %1}" | |
544 [(set_attr "type" "mmxcvt") | |
545 (set_attr "mode" "V2SF")]) | |
546 | |
547 (define_insn "mmx_pf2iw" | |
548 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
549 (sign_extend:V2SI | |
550 (ss_truncate:V2HI | |
551 (fix:V2SI | |
552 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))] | |
553 "TARGET_3DNOW_A" | |
554 "pf2iw\t{%1, %0|%0, %1}" | |
555 [(set_attr "type" "mmxcvt") | |
556 (set_attr "mode" "V2SF")]) | |
557 | |
558 (define_insn "mmx_pi2fw" | |
559 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
560 (float:V2SF | |
561 (sign_extend:V2SI | |
562 (truncate:V2HI | |
563 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))] | |
564 "TARGET_3DNOW_A" | |
565 "pi2fw\t{%1, %0|%0, %1}" | |
566 [(set_attr "type" "mmxcvt") | |
567 (set_attr "mode" "V2SF")]) | |
568 | |
569 (define_insn "mmx_floatv2si2" | |
570 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
571 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))] | |
572 "TARGET_3DNOW" | |
573 "pi2fd\t{%1, %0|%0, %1}" | |
574 [(set_attr "type" "mmxcvt") | |
575 (set_attr "mode" "V2SF")]) | |
576 | |
577 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
578 ;; | |
579 ;; Parallel single-precision floating point element swizzling | |
580 ;; | |
581 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
582 | |
583 (define_insn "mmx_pswapdv2sf2" | |
584 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
585 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym") | |
586 (parallel [(const_int 1) (const_int 0)])))] | |
587 "TARGET_3DNOW_A" | |
588 "pswapd\t{%1, %0|%0, %1}" | |
589 [(set_attr "type" "mmxcvt") | |
590 (set_attr "mode" "V2SF")]) | |
591 | |
592 (define_insn "*vec_dupv2sf" | |
593 [(set (match_operand:V2SF 0 "register_operand" "=y") | |
594 (vec_duplicate:V2SF | |
595 (match_operand:SF 1 "register_operand" "0")))] | |
596 "TARGET_MMX" | |
597 "punpckldq\t%0, %0" | |
598 [(set_attr "type" "mmxcvt") | |
599 (set_attr "mode" "DI")]) | |
600 | |
601 (define_insn "*mmx_concatv2sf" | |
602 [(set (match_operand:V2SF 0 "register_operand" "=y,y") | |
603 (vec_concat:V2SF | |
604 (match_operand:SF 1 "nonimmediate_operand" " 0,rm") | |
605 (match_operand:SF 2 "vector_move_operand" "ym,C")))] | |
606 "TARGET_MMX && !TARGET_SSE" | |
607 "@ | |
608 punpckldq\t{%2, %0|%0, %2} | |
609 movd\t{%1, %0|%0, %1}" | |
610 [(set_attr "type" "mmxcvt,mmxmov") | |
611 (set_attr "mode" "DI")]) | |
612 | |
613 (define_expand "vec_setv2sf" | |
614 [(match_operand:V2SF 0 "register_operand" "") | |
615 (match_operand:SF 1 "register_operand" "") | |
616 (match_operand 2 "const_int_operand" "")] | |
617 "TARGET_MMX" | |
618 { | |
619 ix86_expand_vector_set (false, operands[0], operands[1], | |
620 INTVAL (operands[2])); | |
621 DONE; | |
622 }) | |
623 | |
624 ;; Avoid combining registers from different units in a single alternative, | |
625 ;; see comment above inline_secondary_memory_needed function in i386.c | |
626 (define_insn_and_split "*vec_extractv2sf_0" | |
627 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r") | |
628 (vec_select:SF | |
629 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m") | |
630 (parallel [(const_int 0)])))] | |
631 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
632 "#" | |
633 "&& reload_completed" | |
634 [(const_int 0)] | |
635 { | |
636 rtx op1 = operands[1]; | |
637 if (REG_P (op1)) | |
638 op1 = gen_rtx_REG (SFmode, REGNO (op1)); | |
639 else | |
640 op1 = gen_lowpart (SFmode, op1); | |
641 emit_move_insn (operands[0], op1); | |
642 DONE; | |
643 }) | |
644 | |
645 ;; Avoid combining registers from different units in a single alternative, | |
646 ;; see comment above inline_secondary_memory_needed function in i386.c | |
647 (define_insn "*vec_extractv2sf_1" | |
648 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,y,x,f,r") | |
649 (vec_select:SF | |
650 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o") | |
651 (parallel [(const_int 1)])))] | |
652 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
653 "@ | |
654 punpckhdq\t%0, %0 | |
655 unpckhps\t%0, %0 | |
656 # | |
657 # | |
658 # | |
659 #" | |
660 [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov") | |
661 (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")]) | |
662 | |
663 (define_split | |
664 [(set (match_operand:SF 0 "register_operand" "") | |
665 (vec_select:SF | |
666 (match_operand:V2SF 1 "memory_operand" "") | |
667 (parallel [(const_int 1)])))] | |
668 "TARGET_MMX && reload_completed" | |
669 [(const_int 0)] | |
670 { | |
671 operands[1] = adjust_address (operands[1], SFmode, 4); | |
672 emit_move_insn (operands[0], operands[1]); | |
673 DONE; | |
674 }) | |
675 | |
676 (define_expand "vec_extractv2sf" | |
677 [(match_operand:SF 0 "register_operand" "") | |
678 (match_operand:V2SF 1 "register_operand" "") | |
679 (match_operand 2 "const_int_operand" "")] | |
680 "TARGET_MMX" | |
681 { | |
682 ix86_expand_vector_extract (false, operands[0], operands[1], | |
683 INTVAL (operands[2])); | |
684 DONE; | |
685 }) | |
686 | |
687 (define_expand "vec_initv2sf" | |
688 [(match_operand:V2SF 0 "register_operand" "") | |
689 (match_operand 1 "" "")] | |
690 "TARGET_SSE" | |
691 { | |
692 ix86_expand_vector_init (false, operands[0], operands[1]); | |
693 DONE; | |
694 }) | |
695 | |
696 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
697 ;; | |
698 ;; Parallel integral arithmetic | |
699 ;; | |
700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
701 | |
702 (define_expand "mmx_<plusminus_insn><mode>3" | |
703 [(set (match_operand:MMXMODEI8 0 "register_operand" "") | |
704 (plusminus:MMXMODEI8 | |
705 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "") | |
706 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "")))] | |
707 "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)" | |
708 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") | |
709 | |
710 (define_insn "*mmx_<plusminus_insn><mode>3" | |
711 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y") | |
712 (plusminus:MMXMODEI8 | |
713 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0") | |
714 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))] | |
715 "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)) | |
716 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" | |
717 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}" | |
718 [(set_attr "type" "mmxadd") | |
719 (set_attr "mode" "DI")]) | |
720 | |
721 (define_expand "mmx_<plusminus_insn><mode>3" | |
722 [(set (match_operand:MMXMODE12 0 "register_operand" "") | |
723 (sat_plusminus:MMXMODE12 | |
724 (match_operand:MMXMODE12 1 "nonimmediate_operand" "") | |
725 (match_operand:MMXMODE12 2 "nonimmediate_operand" "")))] | |
726 "TARGET_MMX" | |
727 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") | |
728 | |
729 (define_insn "*mmx_<plusminus_insn><mode>3" | |
730 [(set (match_operand:MMXMODE12 0 "register_operand" "=y") | |
731 (sat_plusminus:MMXMODE12 | |
732 (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0") | |
733 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] | |
734 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" | |
735 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}" | |
736 [(set_attr "type" "mmxadd") | |
737 (set_attr "mode" "DI")]) | |
738 | |
739 (define_expand "mmx_mulv4hi3" | |
740 [(set (match_operand:V4HI 0 "register_operand" "") | |
741 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "") | |
742 (match_operand:V4HI 2 "nonimmediate_operand" "")))] | |
743 "TARGET_MMX" | |
744 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") | |
745 | |
746 (define_insn "*mmx_mulv4hi3" | |
747 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
748 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0") | |
749 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
750 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" | |
751 "pmullw\t{%2, %0|%0, %2}" | |
752 [(set_attr "type" "mmxmul") | |
753 (set_attr "mode" "DI")]) | |
754 | |
755 (define_expand "mmx_smulv4hi3_highpart" | |
756 [(set (match_operand:V4HI 0 "register_operand" "") | |
757 (truncate:V4HI | |
758 (lshiftrt:V4SI | |
759 (mult:V4SI | |
760 (sign_extend:V4SI | |
761 (match_operand:V4HI 1 "nonimmediate_operand" "")) | |
762 (sign_extend:V4SI | |
763 (match_operand:V4HI 2 "nonimmediate_operand" ""))) | |
764 (const_int 16))))] | |
765 "TARGET_MMX" | |
766 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") | |
767 | |
768 (define_insn "*mmx_smulv4hi3_highpart" | |
769 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
770 (truncate:V4HI | |
771 (lshiftrt:V4SI | |
772 (mult:V4SI | |
773 (sign_extend:V4SI | |
774 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) | |
775 (sign_extend:V4SI | |
776 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) | |
777 (const_int 16))))] | |
778 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" | |
779 "pmulhw\t{%2, %0|%0, %2}" | |
780 [(set_attr "type" "mmxmul") | |
781 (set_attr "mode" "DI")]) | |
782 | |
783 (define_expand "mmx_umulv4hi3_highpart" | |
784 [(set (match_operand:V4HI 0 "register_operand" "") | |
785 (truncate:V4HI | |
786 (lshiftrt:V4SI | |
787 (mult:V4SI | |
788 (zero_extend:V4SI | |
789 (match_operand:V4HI 1 "nonimmediate_operand" "")) | |
790 (zero_extend:V4SI | |
791 (match_operand:V4HI 2 "nonimmediate_operand" ""))) | |
792 (const_int 16))))] | |
793 "TARGET_SSE || TARGET_3DNOW_A" | |
794 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") | |
795 | |
796 (define_insn "*mmx_umulv4hi3_highpart" | |
797 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
798 (truncate:V4HI | |
799 (lshiftrt:V4SI | |
800 (mult:V4SI | |
801 (zero_extend:V4SI | |
802 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) | |
803 (zero_extend:V4SI | |
804 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) | |
805 (const_int 16))))] | |
806 "(TARGET_SSE || TARGET_3DNOW_A) | |
807 && ix86_binary_operator_ok (MULT, V4HImode, operands)" | |
808 "pmulhuw\t{%2, %0|%0, %2}" | |
809 [(set_attr "type" "mmxmul") | |
810 (set_attr "mode" "DI")]) | |
811 | |
812 (define_expand "mmx_pmaddwd" | |
813 [(set (match_operand:V2SI 0 "register_operand" "") | |
814 (plus:V2SI | |
815 (mult:V2SI | |
816 (sign_extend:V2SI | |
817 (vec_select:V2HI | |
818 (match_operand:V4HI 1 "nonimmediate_operand" "") | |
819 (parallel [(const_int 0) (const_int 2)]))) | |
820 (sign_extend:V2SI | |
821 (vec_select:V2HI | |
822 (match_operand:V4HI 2 "nonimmediate_operand" "") | |
823 (parallel [(const_int 0) (const_int 2)])))) | |
824 (mult:V2SI | |
825 (sign_extend:V2SI | |
826 (vec_select:V2HI (match_dup 1) | |
827 (parallel [(const_int 1) (const_int 3)]))) | |
828 (sign_extend:V2SI | |
829 (vec_select:V2HI (match_dup 2) | |
830 (parallel [(const_int 1) (const_int 3)]))))))] | |
831 "TARGET_MMX" | |
832 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") | |
833 | |
834 (define_insn "*mmx_pmaddwd" | |
835 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
836 (plus:V2SI | |
837 (mult:V2SI | |
838 (sign_extend:V2SI | |
839 (vec_select:V2HI | |
840 (match_operand:V4HI 1 "nonimmediate_operand" "%0") | |
841 (parallel [(const_int 0) (const_int 2)]))) | |
842 (sign_extend:V2SI | |
843 (vec_select:V2HI | |
844 (match_operand:V4HI 2 "nonimmediate_operand" "ym") | |
845 (parallel [(const_int 0) (const_int 2)])))) | |
846 (mult:V2SI | |
847 (sign_extend:V2SI | |
848 (vec_select:V2HI (match_dup 1) | |
849 (parallel [(const_int 1) (const_int 3)]))) | |
850 (sign_extend:V2SI | |
851 (vec_select:V2HI (match_dup 2) | |
852 (parallel [(const_int 1) (const_int 3)]))))))] | |
853 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" | |
854 "pmaddwd\t{%2, %0|%0, %2}" | |
855 [(set_attr "type" "mmxmul") | |
856 (set_attr "mode" "DI")]) | |
857 | |
858 (define_expand "mmx_pmulhrwv4hi3" | |
859 [(set (match_operand:V4HI 0 "register_operand" "") | |
860 (truncate:V4HI | |
861 (lshiftrt:V4SI | |
862 (plus:V4SI | |
863 (mult:V4SI | |
864 (sign_extend:V4SI | |
865 (match_operand:V4HI 1 "nonimmediate_operand" "")) | |
866 (sign_extend:V4SI | |
867 (match_operand:V4HI 2 "nonimmediate_operand" ""))) | |
868 (const_vector:V4SI [(const_int 32768) (const_int 32768) | |
869 (const_int 32768) (const_int 32768)])) | |
870 (const_int 16))))] | |
871 "TARGET_3DNOW" | |
872 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") | |
873 | |
874 (define_insn "*mmx_pmulhrwv4hi3" | |
875 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
876 (truncate:V4HI | |
877 (lshiftrt:V4SI | |
878 (plus:V4SI | |
879 (mult:V4SI | |
880 (sign_extend:V4SI | |
881 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) | |
882 (sign_extend:V4SI | |
883 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) | |
884 (const_vector:V4SI [(const_int 32768) (const_int 32768) | |
885 (const_int 32768) (const_int 32768)])) | |
886 (const_int 16))))] | |
887 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)" | |
888 "pmulhrw\t{%2, %0|%0, %2}" | |
889 [(set_attr "type" "mmxmul") | |
890 (set_attr "mode" "DI")]) | |
891 | |
892 (define_expand "sse2_umulv1siv1di3" | |
893 [(set (match_operand:V1DI 0 "register_operand" "") | |
894 (mult:V1DI | |
895 (zero_extend:V1DI | |
896 (vec_select:V1SI | |
897 (match_operand:V2SI 1 "nonimmediate_operand" "") | |
898 (parallel [(const_int 0)]))) | |
899 (zero_extend:V1DI | |
900 (vec_select:V1SI | |
901 (match_operand:V2SI 2 "nonimmediate_operand" "") | |
902 (parallel [(const_int 0)])))))] | |
903 "TARGET_SSE2" | |
904 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);") | |
905 | |
906 (define_insn "*sse2_umulv1siv1di3" | |
907 [(set (match_operand:V1DI 0 "register_operand" "=y") | |
908 (mult:V1DI | |
909 (zero_extend:V1DI | |
910 (vec_select:V1SI | |
911 (match_operand:V2SI 1 "nonimmediate_operand" "%0") | |
912 (parallel [(const_int 0)]))) | |
913 (zero_extend:V1DI | |
914 (vec_select:V1SI | |
915 (match_operand:V2SI 2 "nonimmediate_operand" "ym") | |
916 (parallel [(const_int 0)])))))] | |
917 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)" | |
918 "pmuludq\t{%2, %0|%0, %2}" | |
919 [(set_attr "type" "mmxmul") | |
920 (set_attr "mode" "DI")]) | |
921 | |
922 (define_expand "mmx_<code>v4hi3" | |
923 [(set (match_operand:V4HI 0 "register_operand" "") | |
924 (smaxmin:V4HI | |
925 (match_operand:V4HI 1 "nonimmediate_operand" "") | |
926 (match_operand:V4HI 2 "nonimmediate_operand" "")))] | |
927 "TARGET_SSE || TARGET_3DNOW_A" | |
928 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);") | |
929 | |
930 (define_insn "*mmx_<code>v4hi3" | |
931 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
932 (smaxmin:V4HI | |
933 (match_operand:V4HI 1 "nonimmediate_operand" "%0") | |
934 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] | |
935 "(TARGET_SSE || TARGET_3DNOW_A) | |
936 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)" | |
937 "p<maxminiprefix>w\t{%2, %0|%0, %2}" | |
938 [(set_attr "type" "mmxadd") | |
939 (set_attr "mode" "DI")]) | |
940 | |
941 (define_expand "mmx_<code>v8qi3" | |
942 [(set (match_operand:V8QI 0 "register_operand" "") | |
943 (umaxmin:V8QI | |
944 (match_operand:V8QI 1 "nonimmediate_operand" "") | |
945 (match_operand:V8QI 2 "nonimmediate_operand" "")))] | |
946 "TARGET_SSE || TARGET_3DNOW_A" | |
947 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);") | |
948 | |
949 (define_insn "*mmx_<code>v8qi3" | |
950 [(set (match_operand:V8QI 0 "register_operand" "=y") | |
951 (umaxmin:V8QI | |
952 (match_operand:V8QI 1 "nonimmediate_operand" "%0") | |
953 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] | |
954 "(TARGET_SSE || TARGET_3DNOW_A) | |
955 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)" | |
956 "p<maxminiprefix>b\t{%2, %0|%0, %2}" | |
957 [(set_attr "type" "mmxadd") | |
958 (set_attr "mode" "DI")]) | |
959 | |
960 (define_insn "mmx_ashr<mode>3" | |
961 [(set (match_operand:MMXMODE24 0 "register_operand" "=y") | |
962 (ashiftrt:MMXMODE24 | |
963 (match_operand:MMXMODE24 1 "register_operand" "0") | |
964 (match_operand:SI 2 "nonmemory_operand" "yN")))] | |
965 "TARGET_MMX" | |
966 "psra<mmxvecsize>\t{%2, %0|%0, %2}" | |
967 [(set_attr "type" "mmxshft") | |
968 (set_attr "mode" "DI")]) | |
969 | |
970 (define_insn "mmx_lshr<mode>3" | |
971 [(set (match_operand:MMXMODE248 0 "register_operand" "=y") | |
972 (lshiftrt:MMXMODE248 | |
973 (match_operand:MMXMODE248 1 "register_operand" "0") | |
974 (match_operand:SI 2 "nonmemory_operand" "yN")))] | |
975 "TARGET_MMX" | |
976 "psrl<mmxvecsize>\t{%2, %0|%0, %2}" | |
977 [(set_attr "type" "mmxshft") | |
978 (set_attr "mode" "DI")]) | |
979 | |
980 (define_insn "mmx_ashl<mode>3" | |
981 [(set (match_operand:MMXMODE248 0 "register_operand" "=y") | |
982 (ashift:MMXMODE248 | |
983 (match_operand:MMXMODE248 1 "register_operand" "0") | |
984 (match_operand:SI 2 "nonmemory_operand" "yN")))] | |
985 "TARGET_MMX" | |
986 "psll<mmxvecsize>\t{%2, %0|%0, %2}" | |
987 [(set_attr "type" "mmxshft") | |
988 (set_attr "mode" "DI")]) | |
989 | |
990 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
991 ;; | |
992 ;; Parallel integral comparisons | |
993 ;; | |
994 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
995 | |
996 (define_expand "mmx_eq<mode>3" | |
997 [(set (match_operand:MMXMODEI 0 "register_operand" "") | |
998 (eq:MMXMODEI | |
999 (match_operand:MMXMODEI 1 "nonimmediate_operand" "") | |
1000 (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))] | |
1001 "TARGET_MMX" | |
1002 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);") | |
1003 | |
1004 (define_insn "*mmx_eq<mode>3" | |
1005 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") | |
1006 (eq:MMXMODEI | |
1007 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") | |
1008 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] | |
1009 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)" | |
1010 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}" | |
1011 [(set_attr "type" "mmxcmp") | |
1012 (set_attr "mode" "DI")]) | |
1013 | |
1014 (define_insn "mmx_gt<mode>3" | |
1015 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") | |
1016 (gt:MMXMODEI | |
1017 (match_operand:MMXMODEI 1 "register_operand" "0") | |
1018 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] | |
1019 "TARGET_MMX" | |
1020 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}" | |
1021 [(set_attr "type" "mmxcmp") | |
1022 (set_attr "mode" "DI")]) | |
1023 | |
1024 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1025 ;; | |
1026 ;; Parallel integral logical operations | |
1027 ;; | |
1028 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1029 | |
1030 (define_insn "mmx_andnot<mode>3" | |
1031 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") | |
1032 (and:MMXMODEI | |
1033 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0")) | |
1034 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] | |
1035 "TARGET_MMX" | |
1036 "pandn\t{%2, %0|%0, %2}" | |
1037 [(set_attr "type" "mmxadd") | |
1038 (set_attr "mode" "DI")]) | |
1039 | |
1040 (define_expand "mmx_<code><mode>3" | |
1041 [(set (match_operand:MMXMODEI 0 "register_operand" "") | |
1042 (plogic:MMXMODEI | |
1043 (match_operand:MMXMODEI 1 "nonimmediate_operand" "") | |
1044 (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))] | |
1045 "TARGET_MMX" | |
1046 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") | |
1047 | |
1048 (define_insn "*mmx_<code><mode>3" | |
1049 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") | |
1050 (plogic:MMXMODEI | |
1051 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") | |
1052 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] | |
1053 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" | |
1054 "p<plogicprefix>\t{%2, %0|%0, %2}" | |
1055 [(set_attr "type" "mmxadd") | |
1056 (set_attr "mode" "DI")]) | |
1057 | |
1058 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1059 ;; | |
1060 ;; Parallel integral element swizzling | |
1061 ;; | |
1062 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1063 | |
1064 (define_insn "mmx_packsswb" | |
1065 [(set (match_operand:V8QI 0 "register_operand" "=y") | |
1066 (vec_concat:V8QI | |
1067 (ss_truncate:V4QI | |
1068 (match_operand:V4HI 1 "register_operand" "0")) | |
1069 (ss_truncate:V4QI | |
1070 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))] | |
1071 "TARGET_MMX" | |
1072 "packsswb\t{%2, %0|%0, %2}" | |
1073 [(set_attr "type" "mmxshft") | |
1074 (set_attr "mode" "DI")]) | |
1075 | |
1076 (define_insn "mmx_packssdw" | |
1077 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
1078 (vec_concat:V4HI | |
1079 (ss_truncate:V2HI | |
1080 (match_operand:V2SI 1 "register_operand" "0")) | |
1081 (ss_truncate:V2HI | |
1082 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))] | |
1083 "TARGET_MMX" | |
1084 "packssdw\t{%2, %0|%0, %2}" | |
1085 [(set_attr "type" "mmxshft") | |
1086 (set_attr "mode" "DI")]) | |
1087 | |
1088 (define_insn "mmx_packuswb" | |
1089 [(set (match_operand:V8QI 0 "register_operand" "=y") | |
1090 (vec_concat:V8QI | |
1091 (us_truncate:V4QI | |
1092 (match_operand:V4HI 1 "register_operand" "0")) | |
1093 (us_truncate:V4QI | |
1094 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))] | |
1095 "TARGET_MMX" | |
1096 "packuswb\t{%2, %0|%0, %2}" | |
1097 [(set_attr "type" "mmxshft") | |
1098 (set_attr "mode" "DI")]) | |
1099 | |
1100 (define_insn "mmx_punpckhbw" | |
1101 [(set (match_operand:V8QI 0 "register_operand" "=y") | |
1102 (vec_select:V8QI | |
1103 (vec_concat:V16QI | |
1104 (match_operand:V8QI 1 "register_operand" "0") | |
1105 (match_operand:V8QI 2 "nonimmediate_operand" "ym")) | |
1106 (parallel [(const_int 4) (const_int 12) | |
1107 (const_int 5) (const_int 13) | |
1108 (const_int 6) (const_int 14) | |
1109 (const_int 7) (const_int 15)])))] | |
1110 "TARGET_MMX" | |
1111 "punpckhbw\t{%2, %0|%0, %2}" | |
1112 [(set_attr "type" "mmxcvt") | |
1113 (set_attr "mode" "DI")]) | |
1114 | |
1115 (define_insn "mmx_punpcklbw" | |
1116 [(set (match_operand:V8QI 0 "register_operand" "=y") | |
1117 (vec_select:V8QI | |
1118 (vec_concat:V16QI | |
1119 (match_operand:V8QI 1 "register_operand" "0") | |
1120 (match_operand:V8QI 2 "nonimmediate_operand" "ym")) | |
1121 (parallel [(const_int 0) (const_int 8) | |
1122 (const_int 1) (const_int 9) | |
1123 (const_int 2) (const_int 10) | |
1124 (const_int 3) (const_int 11)])))] | |
1125 "TARGET_MMX" | |
1126 "punpcklbw\t{%2, %0|%0, %2}" | |
1127 [(set_attr "type" "mmxcvt") | |
1128 (set_attr "mode" "DI")]) | |
1129 | |
1130 (define_insn "mmx_punpckhwd" | |
1131 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
1132 (vec_select:V4HI | |
1133 (vec_concat:V8HI | |
1134 (match_operand:V4HI 1 "register_operand" "0") | |
1135 (match_operand:V4HI 2 "nonimmediate_operand" "ym")) | |
1136 (parallel [(const_int 2) (const_int 6) | |
1137 (const_int 3) (const_int 7)])))] | |
1138 "TARGET_MMX" | |
1139 "punpckhwd\t{%2, %0|%0, %2}" | |
1140 [(set_attr "type" "mmxcvt") | |
1141 (set_attr "mode" "DI")]) | |
1142 | |
1143 (define_insn "mmx_punpcklwd" | |
1144 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
1145 (vec_select:V4HI | |
1146 (vec_concat:V8HI | |
1147 (match_operand:V4HI 1 "register_operand" "0") | |
1148 (match_operand:V4HI 2 "nonimmediate_operand" "ym")) | |
1149 (parallel [(const_int 0) (const_int 4) | |
1150 (const_int 1) (const_int 5)])))] | |
1151 "TARGET_MMX" | |
1152 "punpcklwd\t{%2, %0|%0, %2}" | |
1153 [(set_attr "type" "mmxcvt") | |
1154 (set_attr "mode" "DI")]) | |
1155 | |
1156 (define_insn "mmx_punpckhdq" | |
1157 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
1158 (vec_select:V2SI | |
1159 (vec_concat:V4SI | |
1160 (match_operand:V2SI 1 "register_operand" "0") | |
1161 (match_operand:V2SI 2 "nonimmediate_operand" "ym")) | |
1162 (parallel [(const_int 1) | |
1163 (const_int 3)])))] | |
1164 "TARGET_MMX" | |
1165 "punpckhdq\t{%2, %0|%0, %2}" | |
1166 [(set_attr "type" "mmxcvt") | |
1167 (set_attr "mode" "DI")]) | |
1168 | |
1169 (define_insn "mmx_punpckldq" | |
1170 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
1171 (vec_select:V2SI | |
1172 (vec_concat:V4SI | |
1173 (match_operand:V2SI 1 "register_operand" "0") | |
1174 (match_operand:V2SI 2 "nonimmediate_operand" "ym")) | |
1175 (parallel [(const_int 0) | |
1176 (const_int 2)])))] | |
1177 "TARGET_MMX" | |
1178 "punpckldq\t{%2, %0|%0, %2}" | |
1179 [(set_attr "type" "mmxcvt") | |
1180 (set_attr "mode" "DI")]) | |
1181 | |
1182 (define_expand "mmx_pinsrw" | |
1183 [(set (match_operand:V4HI 0 "register_operand" "") | |
1184 (vec_merge:V4HI | |
1185 (vec_duplicate:V4HI | |
1186 (match_operand:SI 2 "nonimmediate_operand" "")) | |
1187 (match_operand:V4HI 1 "register_operand" "") | |
1188 (match_operand:SI 3 "const_0_to_3_operand" "")))] | |
1189 "TARGET_SSE || TARGET_3DNOW_A" | |
1190 { | |
1191 operands[2] = gen_lowpart (HImode, operands[2]); | |
1192 operands[3] = GEN_INT (1 << INTVAL (operands[3])); | |
1193 }) | |
1194 | |
1195 (define_insn "*mmx_pinsrw" | |
1196 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
1197 (vec_merge:V4HI | |
1198 (vec_duplicate:V4HI | |
1199 (match_operand:HI 2 "nonimmediate_operand" "rm")) | |
1200 (match_operand:V4HI 1 "register_operand" "0") | |
1201 (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))] | |
1202 "TARGET_SSE || TARGET_3DNOW_A" | |
1203 { | |
1204 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); | |
1205 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}"; | |
1206 } | |
1207 [(set_attr "type" "mmxcvt") | |
1208 (set_attr "mode" "DI")]) | |
1209 | |
1210 (define_insn "mmx_pextrw" | |
1211 [(set (match_operand:SI 0 "register_operand" "=r") | |
1212 (zero_extend:SI | |
1213 (vec_select:HI | |
1214 (match_operand:V4HI 1 "register_operand" "y") | |
1215 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))] | |
1216 "TARGET_SSE || TARGET_3DNOW_A" | |
1217 "pextrw\t{%2, %1, %0|%0, %1, %2}" | |
1218 [(set_attr "type" "mmxcvt") | |
1219 (set_attr "mode" "DI")]) | |
1220 | |
1221 (define_expand "mmx_pshufw" | |
1222 [(match_operand:V4HI 0 "register_operand" "") | |
1223 (match_operand:V4HI 1 "nonimmediate_operand" "") | |
1224 (match_operand:SI 2 "const_int_operand" "")] | |
1225 "TARGET_SSE || TARGET_3DNOW_A" | |
1226 { | |
1227 int mask = INTVAL (operands[2]); | |
1228 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1], | |
1229 GEN_INT ((mask >> 0) & 3), | |
1230 GEN_INT ((mask >> 2) & 3), | |
1231 GEN_INT ((mask >> 4) & 3), | |
1232 GEN_INT ((mask >> 6) & 3))); | |
1233 DONE; | |
1234 }) | |
1235 | |
1236 (define_insn "mmx_pshufw_1" | |
1237 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
1238 (vec_select:V4HI | |
1239 (match_operand:V4HI 1 "nonimmediate_operand" "ym") | |
1240 (parallel [(match_operand 2 "const_0_to_3_operand" "") | |
1241 (match_operand 3 "const_0_to_3_operand" "") | |
1242 (match_operand 4 "const_0_to_3_operand" "") | |
1243 (match_operand 5 "const_0_to_3_operand" "")])))] | |
1244 "TARGET_SSE || TARGET_3DNOW_A" | |
1245 { | |
1246 int mask = 0; | |
1247 mask |= INTVAL (operands[2]) << 0; | |
1248 mask |= INTVAL (operands[3]) << 2; | |
1249 mask |= INTVAL (operands[4]) << 4; | |
1250 mask |= INTVAL (operands[5]) << 6; | |
1251 operands[2] = GEN_INT (mask); | |
1252 | |
1253 return "pshufw\t{%2, %1, %0|%0, %1, %2}"; | |
1254 } | |
1255 [(set_attr "type" "mmxcvt") | |
1256 (set_attr "mode" "DI")]) | |
1257 | |
1258 (define_insn "mmx_pswapdv2si2" | |
1259 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
1260 (vec_select:V2SI | |
1261 (match_operand:V2SI 1 "nonimmediate_operand" "ym") | |
1262 (parallel [(const_int 1) (const_int 0)])))] | |
1263 "TARGET_3DNOW_A" | |
1264 "pswapd\t{%1, %0|%0, %1}" | |
1265 [(set_attr "type" "mmxcvt") | |
1266 (set_attr "mode" "DI")]) | |
1267 | |
1268 (define_insn "*vec_dupv4hi" | |
1269 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
1270 (vec_duplicate:V4HI | |
1271 (truncate:HI | |
1272 (match_operand:SI 1 "register_operand" "0"))))] | |
1273 "TARGET_SSE || TARGET_3DNOW_A" | |
1274 "pshufw\t{$0, %0, %0|%0, %0, 0}" | |
1275 [(set_attr "type" "mmxcvt") | |
1276 (set_attr "mode" "DI")]) | |
1277 | |
1278 (define_insn "*vec_dupv2si" | |
1279 [(set (match_operand:V2SI 0 "register_operand" "=y") | |
1280 (vec_duplicate:V2SI | |
1281 (match_operand:SI 1 "register_operand" "0")))] | |
1282 "TARGET_MMX" | |
1283 "punpckldq\t%0, %0" | |
1284 [(set_attr "type" "mmxcvt") | |
1285 (set_attr "mode" "DI")]) | |
1286 | |
1287 (define_insn "*mmx_concatv2si" | |
1288 [(set (match_operand:V2SI 0 "register_operand" "=y,y") | |
1289 (vec_concat:V2SI | |
1290 (match_operand:SI 1 "nonimmediate_operand" " 0,rm") | |
1291 (match_operand:SI 2 "vector_move_operand" "ym,C")))] | |
1292 "TARGET_MMX && !TARGET_SSE" | |
1293 "@ | |
1294 punpckldq\t{%2, %0|%0, %2} | |
1295 movd\t{%1, %0|%0, %1}" | |
1296 [(set_attr "type" "mmxcvt,mmxmov") | |
1297 (set_attr "mode" "DI")]) | |
1298 | |
1299 (define_expand "vec_setv2si" | |
1300 [(match_operand:V2SI 0 "register_operand" "") | |
1301 (match_operand:SI 1 "register_operand" "") | |
1302 (match_operand 2 "const_int_operand" "")] | |
1303 "TARGET_MMX" | |
1304 { | |
1305 ix86_expand_vector_set (false, operands[0], operands[1], | |
1306 INTVAL (operands[2])); | |
1307 DONE; | |
1308 }) | |
1309 | |
1310 ;; Avoid combining registers from different units in a single alternative, | |
1311 ;; see comment above inline_secondary_memory_needed function in i386.c | |
1312 (define_insn_and_split "*vec_extractv2si_0" | |
1313 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r") | |
1314 (vec_select:SI | |
1315 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m") | |
1316 (parallel [(const_int 0)])))] | |
1317 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
1318 "#" | |
1319 "&& reload_completed" | |
1320 [(const_int 0)] | |
1321 { | |
1322 rtx op1 = operands[1]; | |
1323 if (REG_P (op1)) | |
1324 op1 = gen_rtx_REG (SImode, REGNO (op1)); | |
1325 else | |
1326 op1 = gen_lowpart (SImode, op1); | |
1327 emit_move_insn (operands[0], op1); | |
1328 DONE; | |
1329 }) | |
1330 | |
1331 ;; Avoid combining registers from different units in a single alternative, | |
1332 ;; see comment above inline_secondary_memory_needed function in i386.c | |
1333 (define_insn "*vec_extractv2si_1" | |
1334 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y2,Y2,x,y,x,r") | |
1335 (vec_select:SI | |
1336 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o,o,o") | |
1337 (parallel [(const_int 1)])))] | |
1338 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" | |
1339 "@ | |
1340 punpckhdq\t%0, %0 | |
1341 punpckhdq\t%0, %0 | |
1342 pshufd\t{$85, %1, %0|%0, %1, 85} | |
1343 unpckhps\t%0, %0 | |
1344 # | |
1345 # | |
1346 #" | |
1347 [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov") | |
1348 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")]) | |
1349 | |
1350 (define_split | |
1351 [(set (match_operand:SI 0 "register_operand" "") | |
1352 (vec_select:SI | |
1353 (match_operand:V2SI 1 "memory_operand" "") | |
1354 (parallel [(const_int 1)])))] | |
1355 "TARGET_MMX && reload_completed" | |
1356 [(const_int 0)] | |
1357 { | |
1358 operands[1] = adjust_address (operands[1], SImode, 4); | |
1359 emit_move_insn (operands[0], operands[1]); | |
1360 DONE; | |
1361 }) | |
1362 | |
1363 (define_expand "vec_extractv2si" | |
1364 [(match_operand:SI 0 "register_operand" "") | |
1365 (match_operand:V2SI 1 "register_operand" "") | |
1366 (match_operand 2 "const_int_operand" "")] | |
1367 "TARGET_MMX" | |
1368 { | |
1369 ix86_expand_vector_extract (false, operands[0], operands[1], | |
1370 INTVAL (operands[2])); | |
1371 DONE; | |
1372 }) | |
1373 | |
1374 (define_expand "vec_initv2si" | |
1375 [(match_operand:V2SI 0 "register_operand" "") | |
1376 (match_operand 1 "" "")] | |
1377 "TARGET_SSE" | |
1378 { | |
1379 ix86_expand_vector_init (false, operands[0], operands[1]); | |
1380 DONE; | |
1381 }) | |
1382 | |
1383 (define_expand "vec_setv4hi" | |
1384 [(match_operand:V4HI 0 "register_operand" "") | |
1385 (match_operand:HI 1 "register_operand" "") | |
1386 (match_operand 2 "const_int_operand" "")] | |
1387 "TARGET_MMX" | |
1388 { | |
1389 ix86_expand_vector_set (false, operands[0], operands[1], | |
1390 INTVAL (operands[2])); | |
1391 DONE; | |
1392 }) | |
1393 | |
1394 (define_expand "vec_extractv4hi" | |
1395 [(match_operand:HI 0 "register_operand" "") | |
1396 (match_operand:V4HI 1 "register_operand" "") | |
1397 (match_operand 2 "const_int_operand" "")] | |
1398 "TARGET_MMX" | |
1399 { | |
1400 ix86_expand_vector_extract (false, operands[0], operands[1], | |
1401 INTVAL (operands[2])); | |
1402 DONE; | |
1403 }) | |
1404 | |
1405 (define_expand "vec_initv4hi" | |
1406 [(match_operand:V4HI 0 "register_operand" "") | |
1407 (match_operand 1 "" "")] | |
1408 "TARGET_SSE" | |
1409 { | |
1410 ix86_expand_vector_init (false, operands[0], operands[1]); | |
1411 DONE; | |
1412 }) | |
1413 | |
1414 (define_expand "vec_setv8qi" | |
1415 [(match_operand:V8QI 0 "register_operand" "") | |
1416 (match_operand:QI 1 "register_operand" "") | |
1417 (match_operand 2 "const_int_operand" "")] | |
1418 "TARGET_MMX" | |
1419 { | |
1420 ix86_expand_vector_set (false, operands[0], operands[1], | |
1421 INTVAL (operands[2])); | |
1422 DONE; | |
1423 }) | |
1424 | |
1425 (define_expand "vec_extractv8qi" | |
1426 [(match_operand:QI 0 "register_operand" "") | |
1427 (match_operand:V8QI 1 "register_operand" "") | |
1428 (match_operand 2 "const_int_operand" "")] | |
1429 "TARGET_MMX" | |
1430 { | |
1431 ix86_expand_vector_extract (false, operands[0], operands[1], | |
1432 INTVAL (operands[2])); | |
1433 DONE; | |
1434 }) | |
1435 | |
1436 (define_expand "vec_initv8qi" | |
1437 [(match_operand:V8QI 0 "register_operand" "") | |
1438 (match_operand 1 "" "")] | |
1439 "TARGET_SSE" | |
1440 { | |
1441 ix86_expand_vector_init (false, operands[0], operands[1]); | |
1442 DONE; | |
1443 }) | |
1444 | |
1445 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1446 ;; | |
1447 ;; Miscellaneous | |
1448 ;; | |
1449 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
1450 | |
1451 (define_expand "mmx_uavgv8qi3" | |
1452 [(set (match_operand:V8QI 0 "register_operand" "") | |
1453 (truncate:V8QI | |
1454 (lshiftrt:V8HI | |
1455 (plus:V8HI | |
1456 (plus:V8HI | |
1457 (zero_extend:V8HI | |
1458 (match_operand:V8QI 1 "nonimmediate_operand" "")) | |
1459 (zero_extend:V8HI | |
1460 (match_operand:V8QI 2 "nonimmediate_operand" ""))) | |
1461 (const_vector:V8HI [(const_int 1) (const_int 1) | |
1462 (const_int 1) (const_int 1) | |
1463 (const_int 1) (const_int 1) | |
1464 (const_int 1) (const_int 1)])) | |
1465 (const_int 1))))] | |
1466 "TARGET_SSE || TARGET_3DNOW" | |
1467 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);") | |
1468 | |
1469 (define_insn "*mmx_uavgv8qi3" | |
1470 [(set (match_operand:V8QI 0 "register_operand" "=y") | |
1471 (truncate:V8QI | |
1472 (lshiftrt:V8HI | |
1473 (plus:V8HI | |
1474 (plus:V8HI | |
1475 (zero_extend:V8HI | |
1476 (match_operand:V8QI 1 "nonimmediate_operand" "%0")) | |
1477 (zero_extend:V8HI | |
1478 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))) | |
1479 (const_vector:V8HI [(const_int 1) (const_int 1) | |
1480 (const_int 1) (const_int 1) | |
1481 (const_int 1) (const_int 1) | |
1482 (const_int 1) (const_int 1)])) | |
1483 (const_int 1))))] | |
1484 "(TARGET_SSE || TARGET_3DNOW) | |
1485 && ix86_binary_operator_ok (PLUS, V8QImode, operands)" | |
1486 { | |
1487 /* These two instructions have the same operation, but their encoding | |
1488 is different. Prefer the one that is de facto standard. */ | |
1489 if (TARGET_SSE || TARGET_3DNOW_A) | |
1490 return "pavgb\t{%2, %0|%0, %2}"; | |
1491 else | |
1492 return "pavgusb\t{%2, %0|%0, %2}"; | |
1493 } | |
1494 [(set_attr "type" "mmxshft") | |
1495 (set_attr "mode" "DI")]) | |
1496 | |
1497 (define_expand "mmx_uavgv4hi3" | |
1498 [(set (match_operand:V4HI 0 "register_operand" "") | |
1499 (truncate:V4HI | |
1500 (lshiftrt:V4SI | |
1501 (plus:V4SI | |
1502 (plus:V4SI | |
1503 (zero_extend:V4SI | |
1504 (match_operand:V4HI 1 "nonimmediate_operand" "")) | |
1505 (zero_extend:V4SI | |
1506 (match_operand:V4HI 2 "nonimmediate_operand" ""))) | |
1507 (const_vector:V4SI [(const_int 1) (const_int 1) | |
1508 (const_int 1) (const_int 1)])) | |
1509 (const_int 1))))] | |
1510 "TARGET_SSE || TARGET_3DNOW_A" | |
1511 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);") | |
1512 | |
1513 (define_insn "*mmx_uavgv4hi3" | |
1514 [(set (match_operand:V4HI 0 "register_operand" "=y") | |
1515 (truncate:V4HI | |
1516 (lshiftrt:V4SI | |
1517 (plus:V4SI | |
1518 (plus:V4SI | |
1519 (zero_extend:V4SI | |
1520 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) | |
1521 (zero_extend:V4SI | |
1522 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) | |
1523 (const_vector:V4SI [(const_int 1) (const_int 1) | |
1524 (const_int 1) (const_int 1)])) | |
1525 (const_int 1))))] | |
1526 "(TARGET_SSE || TARGET_3DNOW_A) | |
1527 && ix86_binary_operator_ok (PLUS, V4HImode, operands)" | |
1528 "pavgw\t{%2, %0|%0, %2}" | |
1529 [(set_attr "type" "mmxshft") | |
1530 (set_attr "mode" "DI")]) | |
1531 | |
1532 (define_insn "mmx_psadbw" | |
1533 [(set (match_operand:V1DI 0 "register_operand" "=y") | |
1534 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0") | |
1535 (match_operand:V8QI 2 "nonimmediate_operand" "ym")] | |
1536 UNSPEC_PSADBW))] | |
1537 "TARGET_SSE || TARGET_3DNOW_A" | |
1538 "psadbw\t{%2, %0|%0, %2}" | |
1539 [(set_attr "type" "mmxshft") | |
1540 (set_attr "mode" "DI")]) | |
1541 | |
1542 (define_insn "mmx_pmovmskb" | |
1543 [(set (match_operand:SI 0 "register_operand" "=r") | |
1544 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] | |
1545 UNSPEC_MOVMSK))] | |
1546 "TARGET_SSE || TARGET_3DNOW_A" | |
1547 "pmovmskb\t{%1, %0|%0, %1}" | |
1548 [(set_attr "type" "mmxcvt") | |
1549 (set_attr "mode" "DI")]) | |
1550 | |
1551 (define_expand "mmx_maskmovq" | |
1552 [(set (match_operand:V8QI 0 "memory_operand" "") | |
1553 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "") | |
1554 (match_operand:V8QI 2 "register_operand" "") | |
1555 (match_dup 0)] | |
1556 UNSPEC_MASKMOV))] | |
1557 "TARGET_SSE || TARGET_3DNOW_A" | |
1558 "") | |
1559 | |
1560 (define_insn "*mmx_maskmovq" | |
1561 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D")) | |
1562 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") | |
1563 (match_operand:V8QI 2 "register_operand" "y") | |
1564 (mem:V8QI (match_dup 0))] | |
1565 UNSPEC_MASKMOV))] | |
1566 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT" | |
1567 ;; @@@ check ordering of operands in intel/nonintel syntax | |
1568 "maskmovq\t{%2, %1|%1, %2}" | |
1569 [(set_attr "type" "mmxcvt") | |
1570 (set_attr "mode" "DI")]) | |
1571 | |
1572 (define_insn "*mmx_maskmovq_rex" | |
1573 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D")) | |
1574 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") | |
1575 (match_operand:V8QI 2 "register_operand" "y") | |
1576 (mem:V8QI (match_dup 0))] | |
1577 UNSPEC_MASKMOV))] | |
1578 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT" | |
1579 ;; @@@ check ordering of operands in intel/nonintel syntax | |
1580 "maskmovq\t{%2, %1|%1, %2}" | |
1581 [(set_attr "type" "mmxcvt") | |
1582 (set_attr "mode" "DI")]) | |
1583 | |
1584 (define_insn "mmx_emms" | |
1585 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS) | |
1586 (clobber (reg:XF ST0_REG)) | |
1587 (clobber (reg:XF ST1_REG)) | |
1588 (clobber (reg:XF ST2_REG)) | |
1589 (clobber (reg:XF ST3_REG)) | |
1590 (clobber (reg:XF ST4_REG)) | |
1591 (clobber (reg:XF ST5_REG)) | |
1592 (clobber (reg:XF ST6_REG)) | |
1593 (clobber (reg:XF ST7_REG)) | |
1594 (clobber (reg:DI MM0_REG)) | |
1595 (clobber (reg:DI MM1_REG)) | |
1596 (clobber (reg:DI MM2_REG)) | |
1597 (clobber (reg:DI MM3_REG)) | |
1598 (clobber (reg:DI MM4_REG)) | |
1599 (clobber (reg:DI MM5_REG)) | |
1600 (clobber (reg:DI MM6_REG)) | |
1601 (clobber (reg:DI MM7_REG))] | |
1602 "TARGET_MMX" | |
1603 "emms" | |
1604 [(set_attr "type" "mmx") | |
1605 (set_attr "memory" "unknown")]) | |
1606 | |
1607 (define_insn "mmx_femms" | |
1608 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS) | |
1609 (clobber (reg:XF ST0_REG)) | |
1610 (clobber (reg:XF ST1_REG)) | |
1611 (clobber (reg:XF ST2_REG)) | |
1612 (clobber (reg:XF ST3_REG)) | |
1613 (clobber (reg:XF ST4_REG)) | |
1614 (clobber (reg:XF ST5_REG)) | |
1615 (clobber (reg:XF ST6_REG)) | |
1616 (clobber (reg:XF ST7_REG)) | |
1617 (clobber (reg:DI MM0_REG)) | |
1618 (clobber (reg:DI MM1_REG)) | |
1619 (clobber (reg:DI MM2_REG)) | |
1620 (clobber (reg:DI MM3_REG)) | |
1621 (clobber (reg:DI MM4_REG)) | |
1622 (clobber (reg:DI MM5_REG)) | |
1623 (clobber (reg:DI MM6_REG)) | |
1624 (clobber (reg:DI MM7_REG))] | |
1625 "TARGET_3DNOW" | |
1626 "femms" | |
1627 [(set_attr "type" "mmx") | |
1628 (set_attr "memory" "none")]) |