i386.md: Typos in MMX/SSE immediate shifts.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_PROBE 10)
67 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SET_GOT 12)
69 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70
71 ; TLS support
72 (UNSPEC_TP 15)
73 (UNSPEC_TLS_GD 16)
74 (UNSPEC_TLS_LD_BASE 17)
75
76 ; Other random patterns
77 (UNSPEC_SCAS 20)
78 (UNSPEC_SIN 21)
79 (UNSPEC_COS 22)
80 (UNSPEC_FNSTSW 24)
81 (UNSPEC_SAHF 25)
82 (UNSPEC_FSTCW 26)
83 (UNSPEC_ADD_CARRY 27)
84 (UNSPEC_FLDCW 28)
85
86 ; For SSE/MMX support:
87 (UNSPEC_FIX 30)
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
119 (UNSPEC_FYL2X 66)
120 (UNSPEC_FSCALE 67)
121 (UNSPEC_FRNDINT 68)
122 (UNSPEC_F2XM1 69)
123
124 ; REP instruction
125 (UNSPEC_REP 75)
126 ])
127
128 (define_constants
129 [(UNSPECV_BLOCKAGE 0)
130 (UNSPECV_EH_RETURN 13)
131 (UNSPECV_EMMS 31)
132 (UNSPECV_LDMXCSR 37)
133 (UNSPECV_STMXCSR 40)
134 (UNSPECV_FEMMS 46)
135 (UNSPECV_CLFLUSH 57)
136 (UNSPECV_ALIGN 68)
137 (UNSPECV_MONITOR 69)
138 (UNSPECV_MWAIT 70)
139 ])
140
141 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
142 ;; from i386.c.
143
144 ;; In C guard expressions, put expressions which may be compile-time
145 ;; constants first. This allows for better optimization. For
146 ;; example, write "TARGET_64BIT && reload_completed", not
147 ;; "reload_completed && TARGET_64BIT".
148
149 \f
150 ;; Processor type. This attribute must exactly match the processor_type
151 ;; enumeration in i386.h.
152 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153 (const (symbol_ref "ix86_tune")))
154
155 ;; A basic instruction type. Refinements due to arguments to be
156 ;; provided in other attributes.
157 (define_attr "type"
158 "other,multi,
159 alu,alu1,negnot,imov,imovx,lea,
160 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161 icmp,test,ibr,setcc,icmov,
162 push,pop,call,callv,leave,
163 str,cld,
164 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165 sselog,sseiadd,sseishft,sseimul,
166 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
168 (const_string "other"))
169
170 ;; Main data type used by the insn
171 (define_attr "mode"
172 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
173 (const_string "unknown"))
174
175 ;; The CPU unit operations uses.
176 (define_attr "unit" "integer,i387,sse,mmx,unknown"
177 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178 (const_string "i387")
179 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181 (const_string "sse")
182 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183 (const_string "mmx")
184 (eq_attr "type" "other")
185 (const_string "unknown")]
186 (const_string "integer")))
187
188 ;; The (bounding maximum) length of an instruction immediate.
189 (define_attr "length_immediate" ""
190 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
191 (const_int 0)
192 (eq_attr "unit" "i387,sse,mmx")
193 (const_int 0)
194 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195 imul,icmp,push,pop")
196 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
197 (eq_attr "type" "imov,test")
198 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
199 (eq_attr "type" "call")
200 (if_then_else (match_operand 0 "constant_call_address_operand" "")
201 (const_int 4)
202 (const_int 0))
203 (eq_attr "type" "callv")
204 (if_then_else (match_operand 1 "constant_call_address_operand" "")
205 (const_int 4)
206 (const_int 0))
207 ;; We don't know the size before shorten_branches. Expect
208 ;; the instruction to fit for better scheduling.
209 (eq_attr "type" "ibr")
210 (const_int 1)
211 ]
212 (symbol_ref "/* Update immediate_length and other attributes! */
213 abort(),1")))
214
215 ;; The (bounding maximum) length of an instruction address.
216 (define_attr "length_address" ""
217 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
218 (const_int 0)
219 (and (eq_attr "type" "call")
220 (match_operand 0 "constant_call_address_operand" ""))
221 (const_int 0)
222 (and (eq_attr "type" "callv")
223 (match_operand 1 "constant_call_address_operand" ""))
224 (const_int 0)
225 ]
226 (symbol_ref "ix86_attr_length_address_default (insn)")))
227
228 ;; Set when length prefix is used.
229 (define_attr "prefix_data16" ""
230 (if_then_else (ior (eq_attr "mode" "HI")
231 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
232 (const_int 1)
233 (const_int 0)))
234
235 ;; Set when string REP prefix is used.
236 (define_attr "prefix_rep" ""
237 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238 (const_int 1)
239 (const_int 0)))
240
241 ;; Set when 0f opcode prefix is used.
242 (define_attr "prefix_0f" ""
243 (if_then_else
244 (ior (eq_attr "type" "imovx,setcc,icmov")
245 (eq_attr "unit" "sse,mmx"))
246 (const_int 1)
247 (const_int 0)))
248
249 ;; Set when 0f opcode prefix is used.
250 (define_attr "prefix_rex" ""
251 (cond [(and (eq_attr "mode" "DI")
252 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253 (const_int 1)
254 (and (eq_attr "mode" "QI")
255 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256 (const_int 0)))
257 (const_int 1)
258 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259 (const_int 0))
260 (const_int 1)
261 ]
262 (const_int 0)))
263
264 ;; Set when modrm byte is used.
265 (define_attr "modrm" ""
266 (cond [(eq_attr "type" "str,cld,leave")
267 (const_int 0)
268 (eq_attr "unit" "i387")
269 (const_int 0)
270 (and (eq_attr "type" "incdec")
271 (ior (match_operand:SI 1 "register_operand" "")
272 (match_operand:HI 1 "register_operand" "")))
273 (const_int 0)
274 (and (eq_attr "type" "push")
275 (not (match_operand 1 "memory_operand" "")))
276 (const_int 0)
277 (and (eq_attr "type" "pop")
278 (not (match_operand 0 "memory_operand" "")))
279 (const_int 0)
280 (and (eq_attr "type" "imov")
281 (and (match_operand 0 "register_operand" "")
282 (match_operand 1 "immediate_operand" "")))
283 (const_int 0)
284 (and (eq_attr "type" "call")
285 (match_operand 0 "constant_call_address_operand" ""))
286 (const_int 0)
287 (and (eq_attr "type" "callv")
288 (match_operand 1 "constant_call_address_operand" ""))
289 (const_int 0)
290 ]
291 (const_int 1)))
292
293 ;; The (bounding maximum) length of an instruction in bytes.
294 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
295 ;; to split it and compute proper length as for other insns.
296 (define_attr "length" ""
297 (cond [(eq_attr "type" "other,multi,fistp")
298 (const_int 16)
299 (eq_attr "type" "fcmp")
300 (const_int 4)
301 (eq_attr "unit" "i387")
302 (plus (const_int 2)
303 (plus (attr "prefix_data16")
304 (attr "length_address")))]
305 (plus (plus (attr "modrm")
306 (plus (attr "prefix_0f")
307 (plus (attr "prefix_rex")
308 (const_int 1))))
309 (plus (attr "prefix_rep")
310 (plus (attr "prefix_data16")
311 (plus (attr "length_immediate")
312 (attr "length_address")))))))
313
314 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
315 ;; `store' if there is a simple memory reference therein, or `unknown'
316 ;; if the instruction is complex.
317
318 (define_attr "memory" "none,load,store,both,unknown"
319 (cond [(eq_attr "type" "other,multi,str")
320 (const_string "unknown")
321 (eq_attr "type" "lea,fcmov,fpspc,cld")
322 (const_string "none")
323 (eq_attr "type" "fistp,leave")
324 (const_string "both")
325 (eq_attr "type" "push")
326 (if_then_else (match_operand 1 "memory_operand" "")
327 (const_string "both")
328 (const_string "store"))
329 (eq_attr "type" "pop")
330 (if_then_else (match_operand 0 "memory_operand" "")
331 (const_string "both")
332 (const_string "load"))
333 (eq_attr "type" "setcc")
334 (if_then_else (match_operand 0 "memory_operand" "")
335 (const_string "store")
336 (const_string "none"))
337 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
338 (if_then_else (ior (match_operand 0 "memory_operand" "")
339 (match_operand 1 "memory_operand" ""))
340 (const_string "load")
341 (const_string "none"))
342 (eq_attr "type" "ibr")
343 (if_then_else (match_operand 0 "memory_operand" "")
344 (const_string "load")
345 (const_string "none"))
346 (eq_attr "type" "call")
347 (if_then_else (match_operand 0 "constant_call_address_operand" "")
348 (const_string "none")
349 (const_string "load"))
350 (eq_attr "type" "callv")
351 (if_then_else (match_operand 1 "constant_call_address_operand" "")
352 (const_string "none")
353 (const_string "load"))
354 (and (eq_attr "type" "alu1,negnot,ishift1")
355 (match_operand 1 "memory_operand" ""))
356 (const_string "both")
357 (and (match_operand 0 "memory_operand" "")
358 (match_operand 1 "memory_operand" ""))
359 (const_string "both")
360 (match_operand 0 "memory_operand" "")
361 (const_string "store")
362 (match_operand 1 "memory_operand" "")
363 (const_string "load")
364 (and (eq_attr "type"
365 "!alu1,negnot,ishift1,
366 imov,imovx,icmp,test,
367 fmov,fcmp,fsgn,
368 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369 mmx,mmxmov,mmxcmp,mmxcvt")
370 (match_operand 2 "memory_operand" ""))
371 (const_string "load")
372 (and (eq_attr "type" "icmov")
373 (match_operand 3 "memory_operand" ""))
374 (const_string "load")
375 ]
376 (const_string "none")))
377
378 ;; Indicates if an instruction has both an immediate and a displacement.
379
380 (define_attr "imm_disp" "false,true,unknown"
381 (cond [(eq_attr "type" "other,multi")
382 (const_string "unknown")
383 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
384 (and (match_operand 0 "memory_displacement_operand" "")
385 (match_operand 1 "immediate_operand" "")))
386 (const_string "true")
387 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
388 (and (match_operand 0 "memory_displacement_operand" "")
389 (match_operand 2 "immediate_operand" "")))
390 (const_string "true")
391 ]
392 (const_string "false")))
393
394 ;; Indicates if an FP operation has an integer source.
395
396 (define_attr "fp_int_src" "false,true"
397 (const_string "false"))
398
399 ;; Describe a user's asm statement.
400 (define_asm_attributes
401 [(set_attr "length" "128")
402 (set_attr "type" "multi")])
403 \f
404 (include "pentium.md")
405 (include "ppro.md")
406 (include "k6.md")
407 (include "athlon.md")
408 \f
409 ;; Compare instructions.
410
411 ;; All compare insns have expanders that save the operands away without
412 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
413 ;; after the cmp) will actually emit the cmpM.
414
415 (define_expand "cmpdi"
416 [(set (reg:CC 17)
417 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
418 (match_operand:DI 1 "x86_64_general_operand" "")))]
419 ""
420 {
421 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
422 operands[0] = force_reg (DImode, operands[0]);
423 ix86_compare_op0 = operands[0];
424 ix86_compare_op1 = operands[1];
425 DONE;
426 })
427
428 (define_expand "cmpsi"
429 [(set (reg:CC 17)
430 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
431 (match_operand:SI 1 "general_operand" "")))]
432 ""
433 {
434 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
435 operands[0] = force_reg (SImode, operands[0]);
436 ix86_compare_op0 = operands[0];
437 ix86_compare_op1 = operands[1];
438 DONE;
439 })
440
441 (define_expand "cmphi"
442 [(set (reg:CC 17)
443 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
444 (match_operand:HI 1 "general_operand" "")))]
445 ""
446 {
447 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
448 operands[0] = force_reg (HImode, operands[0]);
449 ix86_compare_op0 = operands[0];
450 ix86_compare_op1 = operands[1];
451 DONE;
452 })
453
454 (define_expand "cmpqi"
455 [(set (reg:CC 17)
456 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
457 (match_operand:QI 1 "general_operand" "")))]
458 "TARGET_QIMODE_MATH"
459 {
460 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
461 operands[0] = force_reg (QImode, operands[0]);
462 ix86_compare_op0 = operands[0];
463 ix86_compare_op1 = operands[1];
464 DONE;
465 })
466
467 (define_insn "cmpdi_ccno_1_rex64"
468 [(set (reg 17)
469 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
470 (match_operand:DI 1 "const0_operand" "n,n")))]
471 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
472 "@
473 test{q}\t{%0, %0|%0, %0}
474 cmp{q}\t{%1, %0|%0, %1}"
475 [(set_attr "type" "test,icmp")
476 (set_attr "length_immediate" "0,1")
477 (set_attr "mode" "DI")])
478
479 (define_insn "*cmpdi_minus_1_rex64"
480 [(set (reg 17)
481 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
482 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
483 (const_int 0)))]
484 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
485 "cmp{q}\t{%1, %0|%0, %1}"
486 [(set_attr "type" "icmp")
487 (set_attr "mode" "DI")])
488
489 (define_expand "cmpdi_1_rex64"
490 [(set (reg:CC 17)
491 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
492 (match_operand:DI 1 "general_operand" "")))]
493 "TARGET_64BIT"
494 "")
495
496 (define_insn "cmpdi_1_insn_rex64"
497 [(set (reg 17)
498 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
499 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
500 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
501 "cmp{q}\t{%1, %0|%0, %1}"
502 [(set_attr "type" "icmp")
503 (set_attr "mode" "DI")])
504
505
506 (define_insn "*cmpsi_ccno_1"
507 [(set (reg 17)
508 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
509 (match_operand:SI 1 "const0_operand" "n,n")))]
510 "ix86_match_ccmode (insn, CCNOmode)"
511 "@
512 test{l}\t{%0, %0|%0, %0}
513 cmp{l}\t{%1, %0|%0, %1}"
514 [(set_attr "type" "test,icmp")
515 (set_attr "length_immediate" "0,1")
516 (set_attr "mode" "SI")])
517
518 (define_insn "*cmpsi_minus_1"
519 [(set (reg 17)
520 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
521 (match_operand:SI 1 "general_operand" "ri,mr"))
522 (const_int 0)))]
523 "ix86_match_ccmode (insn, CCGOCmode)"
524 "cmp{l}\t{%1, %0|%0, %1}"
525 [(set_attr "type" "icmp")
526 (set_attr "mode" "SI")])
527
528 (define_expand "cmpsi_1"
529 [(set (reg:CC 17)
530 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
531 (match_operand:SI 1 "general_operand" "ri,mr")))]
532 ""
533 "")
534
535 (define_insn "*cmpsi_1_insn"
536 [(set (reg 17)
537 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
538 (match_operand:SI 1 "general_operand" "ri,mr")))]
539 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
540 && ix86_match_ccmode (insn, CCmode)"
541 "cmp{l}\t{%1, %0|%0, %1}"
542 [(set_attr "type" "icmp")
543 (set_attr "mode" "SI")])
544
545 (define_insn "*cmphi_ccno_1"
546 [(set (reg 17)
547 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
548 (match_operand:HI 1 "const0_operand" "n,n")))]
549 "ix86_match_ccmode (insn, CCNOmode)"
550 "@
551 test{w}\t{%0, %0|%0, %0}
552 cmp{w}\t{%1, %0|%0, %1}"
553 [(set_attr "type" "test,icmp")
554 (set_attr "length_immediate" "0,1")
555 (set_attr "mode" "HI")])
556
557 (define_insn "*cmphi_minus_1"
558 [(set (reg 17)
559 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
560 (match_operand:HI 1 "general_operand" "ri,mr"))
561 (const_int 0)))]
562 "ix86_match_ccmode (insn, CCGOCmode)"
563 "cmp{w}\t{%1, %0|%0, %1}"
564 [(set_attr "type" "icmp")
565 (set_attr "mode" "HI")])
566
567 (define_insn "*cmphi_1"
568 [(set (reg 17)
569 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:HI 1 "general_operand" "ri,mr")))]
571 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572 && ix86_match_ccmode (insn, CCmode)"
573 "cmp{w}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "HI")])
576
577 (define_insn "*cmpqi_ccno_1"
578 [(set (reg 17)
579 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
580 (match_operand:QI 1 "const0_operand" "n,n")))]
581 "ix86_match_ccmode (insn, CCNOmode)"
582 "@
583 test{b}\t{%0, %0|%0, %0}
584 cmp{b}\t{$0, %0|%0, 0}"
585 [(set_attr "type" "test,icmp")
586 (set_attr "length_immediate" "0,1")
587 (set_attr "mode" "QI")])
588
589 (define_insn "*cmpqi_1"
590 [(set (reg 17)
591 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
592 (match_operand:QI 1 "general_operand" "qi,mq")))]
593 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
594 && ix86_match_ccmode (insn, CCmode)"
595 "cmp{b}\t{%1, %0|%0, %1}"
596 [(set_attr "type" "icmp")
597 (set_attr "mode" "QI")])
598
599 (define_insn "*cmpqi_minus_1"
600 [(set (reg 17)
601 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
602 (match_operand:QI 1 "general_operand" "qi,mq"))
603 (const_int 0)))]
604 "ix86_match_ccmode (insn, CCGOCmode)"
605 "cmp{b}\t{%1, %0|%0, %1}"
606 [(set_attr "type" "icmp")
607 (set_attr "mode" "QI")])
608
609 (define_insn "*cmpqi_ext_1"
610 [(set (reg 17)
611 (compare
612 (match_operand:QI 0 "general_operand" "Qm")
613 (subreg:QI
614 (zero_extract:SI
615 (match_operand 1 "ext_register_operand" "Q")
616 (const_int 8)
617 (const_int 8)) 0)))]
618 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
619 "cmp{b}\t{%h1, %0|%0, %h1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "QI")])
622
623 (define_insn "*cmpqi_ext_1_rex64"
624 [(set (reg 17)
625 (compare
626 (match_operand:QI 0 "register_operand" "Q")
627 (subreg:QI
628 (zero_extract:SI
629 (match_operand 1 "ext_register_operand" "Q")
630 (const_int 8)
631 (const_int 8)) 0)))]
632 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633 "cmp{b}\t{%h1, %0|%0, %h1}"
634 [(set_attr "type" "icmp")
635 (set_attr "mode" "QI")])
636
637 (define_insn "*cmpqi_ext_2"
638 [(set (reg 17)
639 (compare
640 (subreg:QI
641 (zero_extract:SI
642 (match_operand 0 "ext_register_operand" "Q")
643 (const_int 8)
644 (const_int 8)) 0)
645 (match_operand:QI 1 "const0_operand" "n")))]
646 "ix86_match_ccmode (insn, CCNOmode)"
647 "test{b}\t%h0, %h0"
648 [(set_attr "type" "test")
649 (set_attr "length_immediate" "0")
650 (set_attr "mode" "QI")])
651
652 (define_expand "cmpqi_ext_3"
653 [(set (reg:CC 17)
654 (compare:CC
655 (subreg:QI
656 (zero_extract:SI
657 (match_operand 0 "ext_register_operand" "")
658 (const_int 8)
659 (const_int 8)) 0)
660 (match_operand:QI 1 "general_operand" "")))]
661 ""
662 "")
663
664 (define_insn "cmpqi_ext_3_insn"
665 [(set (reg 17)
666 (compare
667 (subreg:QI
668 (zero_extract:SI
669 (match_operand 0 "ext_register_operand" "Q")
670 (const_int 8)
671 (const_int 8)) 0)
672 (match_operand:QI 1 "general_operand" "Qmn")))]
673 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
674 "cmp{b}\t{%1, %h0|%h0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "QI")])
677
678 (define_insn "cmpqi_ext_3_insn_rex64"
679 [(set (reg 17)
680 (compare
681 (subreg:QI
682 (zero_extract:SI
683 (match_operand 0 "ext_register_operand" "Q")
684 (const_int 8)
685 (const_int 8)) 0)
686 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{b}\t{%1, %h0|%h0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_ext_4"
693 [(set (reg 17)
694 (compare
695 (subreg:QI
696 (zero_extract:SI
697 (match_operand 0 "ext_register_operand" "Q")
698 (const_int 8)
699 (const_int 8)) 0)
700 (subreg:QI
701 (zero_extract:SI
702 (match_operand 1 "ext_register_operand" "Q")
703 (const_int 8)
704 (const_int 8)) 0)))]
705 "ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%h1, %h0|%h0, %h1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
709
710 ;; These implement float point compares.
711 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
712 ;; which would allow mix and match FP modes on the compares. Which is what
713 ;; the old patterns did, but with many more of them.
714
715 (define_expand "cmpxf"
716 [(set (reg:CC 17)
717 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
718 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
719 "TARGET_80387"
720 {
721 ix86_compare_op0 = operands[0];
722 ix86_compare_op1 = operands[1];
723 DONE;
724 })
725
726 (define_expand "cmpdf"
727 [(set (reg:CC 17)
728 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
729 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
730 "TARGET_80387 || TARGET_SSE2"
731 {
732 ix86_compare_op0 = operands[0];
733 ix86_compare_op1 = operands[1];
734 DONE;
735 })
736
737 (define_expand "cmpsf"
738 [(set (reg:CC 17)
739 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
740 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
741 "TARGET_80387 || TARGET_SSE"
742 {
743 ix86_compare_op0 = operands[0];
744 ix86_compare_op1 = operands[1];
745 DONE;
746 })
747
748 ;; FP compares, step 1:
749 ;; Set the FP condition codes.
750 ;;
751 ;; CCFPmode compare with exceptions
752 ;; CCFPUmode compare with no exceptions
753
754 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
755 ;; and that fp moves clobber the condition codes, and that there is
756 ;; currently no way to describe this fact to reg-stack. So there are
757 ;; no splitters yet for this.
758
759 ;; %%% YIKES! This scheme does not retain a strong connection between
760 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
761 ;; work! Only allow tos/mem with tos in op 0.
762 ;;
763 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
764 ;; things aren't as bad as they sound...
765
766 (define_insn "*cmpfp_0"
767 [(set (match_operand:HI 0 "register_operand" "=a")
768 (unspec:HI
769 [(compare:CCFP (match_operand 1 "register_operand" "f")
770 (match_operand 2 "const0_operand" "X"))]
771 UNSPEC_FNSTSW))]
772 "TARGET_80387
773 && FLOAT_MODE_P (GET_MODE (operands[1]))
774 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
775 {
776 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
777 return "ftst\;fnstsw\t%0\;fstp\t%y0";
778 else
779 return "ftst\;fnstsw\t%0";
780 }
781 [(set_attr "type" "multi")
782 (set (attr "mode")
783 (cond [(match_operand:SF 1 "" "")
784 (const_string "SF")
785 (match_operand:DF 1 "" "")
786 (const_string "DF")
787 ]
788 (const_string "XF")))])
789
790 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
791 ;; used to manage the reg stack popping would not be preserved.
792
793 (define_insn "*cmpfp_2_sf"
794 [(set (reg:CCFP 18)
795 (compare:CCFP
796 (match_operand:SF 0 "register_operand" "f")
797 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
798 "TARGET_80387"
799 "* return output_fp_compare (insn, operands, 0, 0);"
800 [(set_attr "type" "fcmp")
801 (set_attr "mode" "SF")])
802
803 (define_insn "*cmpfp_2_sf_1"
804 [(set (match_operand:HI 0 "register_operand" "=a")
805 (unspec:HI
806 [(compare:CCFP
807 (match_operand:SF 1 "register_operand" "f")
808 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
809 UNSPEC_FNSTSW))]
810 "TARGET_80387"
811 "* return output_fp_compare (insn, operands, 2, 0);"
812 [(set_attr "type" "fcmp")
813 (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_2_df"
816 [(set (reg:CCFP 18)
817 (compare:CCFP
818 (match_operand:DF 0 "register_operand" "f")
819 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
820 "TARGET_80387"
821 "* return output_fp_compare (insn, operands, 0, 0);"
822 [(set_attr "type" "fcmp")
823 (set_attr "mode" "DF")])
824
825 (define_insn "*cmpfp_2_df_1"
826 [(set (match_operand:HI 0 "register_operand" "=a")
827 (unspec:HI
828 [(compare:CCFP
829 (match_operand:DF 1 "register_operand" "f")
830 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
831 UNSPEC_FNSTSW))]
832 "TARGET_80387"
833 "* return output_fp_compare (insn, operands, 2, 0);"
834 [(set_attr "type" "multi")
835 (set_attr "mode" "DF")])
836
837 (define_insn "*cmpfp_2_xf"
838 [(set (reg:CCFP 18)
839 (compare:CCFP
840 (match_operand:XF 0 "register_operand" "f")
841 (match_operand:XF 1 "register_operand" "f")))]
842 "TARGET_80387"
843 "* return output_fp_compare (insn, operands, 0, 0);"
844 [(set_attr "type" "fcmp")
845 (set_attr "mode" "XF")])
846
847 (define_insn "*cmpfp_2_xf_1"
848 [(set (match_operand:HI 0 "register_operand" "=a")
849 (unspec:HI
850 [(compare:CCFP
851 (match_operand:XF 1 "register_operand" "f")
852 (match_operand:XF 2 "register_operand" "f"))]
853 UNSPEC_FNSTSW))]
854 "TARGET_80387"
855 "* return output_fp_compare (insn, operands, 2, 0);"
856 [(set_attr "type" "multi")
857 (set_attr "mode" "XF")])
858
859 (define_insn "*cmpfp_2u"
860 [(set (reg:CCFPU 18)
861 (compare:CCFPU
862 (match_operand 0 "register_operand" "f")
863 (match_operand 1 "register_operand" "f")))]
864 "TARGET_80387
865 && FLOAT_MODE_P (GET_MODE (operands[0]))
866 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
867 "* return output_fp_compare (insn, operands, 0, 1);"
868 [(set_attr "type" "fcmp")
869 (set (attr "mode")
870 (cond [(match_operand:SF 1 "" "")
871 (const_string "SF")
872 (match_operand:DF 1 "" "")
873 (const_string "DF")
874 ]
875 (const_string "XF")))])
876
877 (define_insn "*cmpfp_2u_1"
878 [(set (match_operand:HI 0 "register_operand" "=a")
879 (unspec:HI
880 [(compare:CCFPU
881 (match_operand 1 "register_operand" "f")
882 (match_operand 2 "register_operand" "f"))]
883 UNSPEC_FNSTSW))]
884 "TARGET_80387
885 && FLOAT_MODE_P (GET_MODE (operands[1]))
886 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887 "* return output_fp_compare (insn, operands, 2, 1);"
888 [(set_attr "type" "multi")
889 (set (attr "mode")
890 (cond [(match_operand:SF 1 "" "")
891 (const_string "SF")
892 (match_operand:DF 1 "" "")
893 (const_string "DF")
894 ]
895 (const_string "XF")))])
896
897 ;; Patterns to match the SImode-in-memory ficom instructions.
898 ;;
899 ;; %%% Play games with accepting gp registers, as otherwise we have to
900 ;; force them to memory during rtl generation, which is no good. We
901 ;; can get rid of this once we teach reload to do memory input reloads
902 ;; via pushes.
903
904 (define_insn "*ficom_1"
905 [(set (reg:CCFP 18)
906 (compare:CCFP
907 (match_operand 0 "register_operand" "f,f")
908 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
909 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
910 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
911 "#")
912
913 ;; Split the not-really-implemented gp register case into a
914 ;; push-op-pop sequence.
915 ;;
916 ;; %%% This is most efficient, but am I gonna get in trouble
917 ;; for separating cc0_setter and cc0_user?
918
919 (define_split
920 [(set (reg:CCFP 18)
921 (compare:CCFP
922 (match_operand:SF 0 "register_operand" "")
923 (float (match_operand:SI 1 "register_operand" ""))))]
924 "0 && TARGET_80387 && reload_completed"
925 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
926 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
927 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
928 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
929 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
930 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
931
932 ;; FP compares, step 2
933 ;; Move the fpsw to ax.
934
935 (define_insn "*x86_fnstsw_1"
936 [(set (match_operand:HI 0 "register_operand" "=a")
937 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
938 "TARGET_80387"
939 "fnstsw\t%0"
940 [(set_attr "length" "2")
941 (set_attr "mode" "SI")
942 (set_attr "unit" "i387")
943 (set_attr "ppro_uops" "few")])
944
945 ;; FP compares, step 3
946 ;; Get ax into flags, general case.
947
948 (define_insn "x86_sahf_1"
949 [(set (reg:CC 17)
950 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
951 "!TARGET_64BIT"
952 "sahf"
953 [(set_attr "length" "1")
954 (set_attr "athlon_decode" "vector")
955 (set_attr "mode" "SI")
956 (set_attr "ppro_uops" "one")])
957
958 ;; Pentium Pro can do steps 1 through 3 in one go.
959
960 (define_insn "*cmpfp_i"
961 [(set (reg:CCFP 17)
962 (compare:CCFP (match_operand 0 "register_operand" "f")
963 (match_operand 1 "register_operand" "f")))]
964 "TARGET_80387 && TARGET_CMOVE
965 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966 && FLOAT_MODE_P (GET_MODE (operands[0]))
967 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
968 "* return output_fp_compare (insn, operands, 1, 0);"
969 [(set_attr "type" "fcmp")
970 (set (attr "mode")
971 (cond [(match_operand:SF 1 "" "")
972 (const_string "SF")
973 (match_operand:DF 1 "" "")
974 (const_string "DF")
975 ]
976 (const_string "XF")))
977 (set_attr "athlon_decode" "vector")])
978
979 (define_insn "*cmpfp_i_sse"
980 [(set (reg:CCFP 17)
981 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
982 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
983 "TARGET_80387
984 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
985 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
986 "* return output_fp_compare (insn, operands, 1, 0);"
987 [(set_attr "type" "fcmp,ssecomi")
988 (set (attr "mode")
989 (if_then_else (match_operand:SF 1 "" "")
990 (const_string "SF")
991 (const_string "DF")))
992 (set_attr "athlon_decode" "vector")])
993
994 (define_insn "*cmpfp_i_sse_only"
995 [(set (reg:CCFP 17)
996 (compare:CCFP (match_operand 0 "register_operand" "x")
997 (match_operand 1 "nonimmediate_operand" "xm")))]
998 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1000 "* return output_fp_compare (insn, operands, 1, 0);"
1001 [(set_attr "type" "ssecomi")
1002 (set (attr "mode")
1003 (if_then_else (match_operand:SF 1 "" "")
1004 (const_string "SF")
1005 (const_string "DF")))
1006 (set_attr "athlon_decode" "vector")])
1007
1008 (define_insn "*cmpfp_iu"
1009 [(set (reg:CCFPU 17)
1010 (compare:CCFPU (match_operand 0 "register_operand" "f")
1011 (match_operand 1 "register_operand" "f")))]
1012 "TARGET_80387 && TARGET_CMOVE
1013 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1014 && FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 1);"
1017 [(set_attr "type" "fcmp")
1018 (set (attr "mode")
1019 (cond [(match_operand:SF 1 "" "")
1020 (const_string "SF")
1021 (match_operand:DF 1 "" "")
1022 (const_string "DF")
1023 ]
1024 (const_string "XF")))
1025 (set_attr "athlon_decode" "vector")])
1026
1027 (define_insn "*cmpfp_iu_sse"
1028 [(set (reg:CCFPU 17)
1029 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1030 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1031 "TARGET_80387
1032 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1033 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034 "* return output_fp_compare (insn, operands, 1, 1);"
1035 [(set_attr "type" "fcmp,ssecomi")
1036 (set (attr "mode")
1037 (if_then_else (match_operand:SF 1 "" "")
1038 (const_string "SF")
1039 (const_string "DF")))
1040 (set_attr "athlon_decode" "vector")])
1041
1042 (define_insn "*cmpfp_iu_sse_only"
1043 [(set (reg:CCFPU 17)
1044 (compare:CCFPU (match_operand 0 "register_operand" "x")
1045 (match_operand 1 "nonimmediate_operand" "xm")))]
1046 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048 "* return output_fp_compare (insn, operands, 1, 1);"
1049 [(set_attr "type" "ssecomi")
1050 (set (attr "mode")
1051 (if_then_else (match_operand:SF 1 "" "")
1052 (const_string "SF")
1053 (const_string "DF")))
1054 (set_attr "athlon_decode" "vector")])
1055 \f
1056 ;; Move instructions.
1057
1058 ;; General case of fullword move.
1059
1060 (define_expand "movsi"
1061 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1062 (match_operand:SI 1 "general_operand" ""))]
1063 ""
1064 "ix86_expand_move (SImode, operands); DONE;")
1065
1066 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1067 ;; general_operand.
1068 ;;
1069 ;; %%% We don't use a post-inc memory reference because x86 is not a
1070 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1071 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1072 ;; targets without our curiosities, and it is just as easy to represent
1073 ;; this differently.
1074
1075 (define_insn "*pushsi2"
1076 [(set (match_operand:SI 0 "push_operand" "=<")
1077 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1078 "!TARGET_64BIT"
1079 "push{l}\t%1"
1080 [(set_attr "type" "push")
1081 (set_attr "mode" "SI")])
1082
1083 ;; For 64BIT abi we always round up to 8 bytes.
1084 (define_insn "*pushsi2_rex64"
1085 [(set (match_operand:SI 0 "push_operand" "=X")
1086 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1087 "TARGET_64BIT"
1088 "push{q}\t%q1"
1089 [(set_attr "type" "push")
1090 (set_attr "mode" "SI")])
1091
1092 (define_insn "*pushsi2_prologue"
1093 [(set (match_operand:SI 0 "push_operand" "=<")
1094 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1095 (clobber (mem:BLK (scratch)))]
1096 "!TARGET_64BIT"
1097 "push{l}\t%1"
1098 [(set_attr "type" "push")
1099 (set_attr "mode" "SI")])
1100
1101 (define_insn "*popsi1_epilogue"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103 (mem:SI (reg:SI 7)))
1104 (set (reg:SI 7)
1105 (plus:SI (reg:SI 7) (const_int 4)))
1106 (clobber (mem:BLK (scratch)))]
1107 "!TARGET_64BIT"
1108 "pop{l}\t%0"
1109 [(set_attr "type" "pop")
1110 (set_attr "mode" "SI")])
1111
1112 (define_insn "popsi1"
1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114 (mem:SI (reg:SI 7)))
1115 (set (reg:SI 7)
1116 (plus:SI (reg:SI 7) (const_int 4)))]
1117 "!TARGET_64BIT"
1118 "pop{l}\t%0"
1119 [(set_attr "type" "pop")
1120 (set_attr "mode" "SI")])
1121
1122 (define_insn "*movsi_xor"
1123 [(set (match_operand:SI 0 "register_operand" "=r")
1124 (match_operand:SI 1 "const0_operand" "i"))
1125 (clobber (reg:CC 17))]
1126 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1127 "xor{l}\t{%0, %0|%0, %0}"
1128 [(set_attr "type" "alu1")
1129 (set_attr "mode" "SI")
1130 (set_attr "length_immediate" "0")])
1131
1132 (define_insn "*movsi_or"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (match_operand:SI 1 "immediate_operand" "i"))
1135 (clobber (reg:CC 17))]
1136 "reload_completed
1137 && operands[1] == constm1_rtx
1138 && (TARGET_PENTIUM || optimize_size)"
1139 {
1140 operands[1] = constm1_rtx;
1141 return "or{l}\t{%1, %0|%0, %1}";
1142 }
1143 [(set_attr "type" "alu1")
1144 (set_attr "mode" "SI")
1145 (set_attr "length_immediate" "1")])
1146
1147 (define_insn "*movsi_1"
1148 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1149 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1150 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1151 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1152 {
1153 switch (get_attr_type (insn))
1154 {
1155 case TYPE_SSEMOV:
1156 if (get_attr_mode (insn) == MODE_TI)
1157 return "movdqa\t{%1, %0|%0, %1}";
1158 return "movd\t{%1, %0|%0, %1}";
1159
1160 case TYPE_MMXMOV:
1161 if (get_attr_mode (insn) == MODE_DI)
1162 return "movq\t{%1, %0|%0, %1}";
1163 return "movd\t{%1, %0|%0, %1}";
1164
1165 case TYPE_LEA:
1166 return "lea{l}\t{%1, %0|%0, %1}";
1167
1168 default:
1169 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1170 abort();
1171 return "mov{l}\t{%1, %0|%0, %1}";
1172 }
1173 }
1174 [(set (attr "type")
1175 (cond [(eq_attr "alternative" "2,3,4")
1176 (const_string "mmxmov")
1177 (eq_attr "alternative" "5,6,7")
1178 (const_string "ssemov")
1179 (and (ne (symbol_ref "flag_pic") (const_int 0))
1180 (match_operand:SI 1 "symbolic_operand" ""))
1181 (const_string "lea")
1182 ]
1183 (const_string "imov")))
1184 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1185
1186 (define_insn "*movsi_1_nointernunit"
1187 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1188 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1189 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1190 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1191 {
1192 switch (get_attr_type (insn))
1193 {
1194 case TYPE_SSEMOV:
1195 if (get_attr_mode (insn) == MODE_TI)
1196 return "movdqa\t{%1, %0|%0, %1}";
1197 return "movd\t{%1, %0|%0, %1}";
1198
1199 case TYPE_MMXMOV:
1200 if (get_attr_mode (insn) == MODE_DI)
1201 return "movq\t{%1, %0|%0, %1}";
1202 return "movd\t{%1, %0|%0, %1}";
1203
1204 case TYPE_LEA:
1205 return "lea{l}\t{%1, %0|%0, %1}";
1206
1207 default:
1208 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1209 abort();
1210 return "mov{l}\t{%1, %0|%0, %1}";
1211 }
1212 }
1213 [(set (attr "type")
1214 (cond [(eq_attr "alternative" "2,3,4")
1215 (const_string "mmxmov")
1216 (eq_attr "alternative" "5,6,7")
1217 (const_string "ssemov")
1218 (and (ne (symbol_ref "flag_pic") (const_int 0))
1219 (match_operand:SI 1 "symbolic_operand" ""))
1220 (const_string "lea")
1221 ]
1222 (const_string "imov")))
1223 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1224
1225 ;; Stores and loads of ax to arbitrary constant address.
1226 ;; We fake an second form of instruction to force reload to load address
1227 ;; into register when rax is not available
1228 (define_insn "*movabssi_1_rex64"
1229 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1230 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1231 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1232 "@
1233 movabs{l}\t{%1, %P0|%P0, %1}
1234 mov{l}\t{%1, %a0|%a0, %1}"
1235 [(set_attr "type" "imov")
1236 (set_attr "modrm" "0,*")
1237 (set_attr "length_address" "8,0")
1238 (set_attr "length_immediate" "0,*")
1239 (set_attr "memory" "store")
1240 (set_attr "mode" "SI")])
1241
1242 (define_insn "*movabssi_2_rex64"
1243 [(set (match_operand:SI 0 "register_operand" "=a,r")
1244 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1245 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1246 "@
1247 movabs{l}\t{%P1, %0|%0, %P1}
1248 mov{l}\t{%a1, %0|%0, %a1}"
1249 [(set_attr "type" "imov")
1250 (set_attr "modrm" "0,*")
1251 (set_attr "length_address" "8,0")
1252 (set_attr "length_immediate" "0")
1253 (set_attr "memory" "load")
1254 (set_attr "mode" "SI")])
1255
1256 (define_insn "*swapsi"
1257 [(set (match_operand:SI 0 "register_operand" "+r")
1258 (match_operand:SI 1 "register_operand" "+r"))
1259 (set (match_dup 1)
1260 (match_dup 0))]
1261 ""
1262 "xchg{l}\t%1, %0"
1263 [(set_attr "type" "imov")
1264 (set_attr "pent_pair" "np")
1265 (set_attr "athlon_decode" "vector")
1266 (set_attr "mode" "SI")
1267 (set_attr "modrm" "0")
1268 (set_attr "ppro_uops" "few")])
1269
1270 (define_expand "movhi"
1271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272 (match_operand:HI 1 "general_operand" ""))]
1273 ""
1274 "ix86_expand_move (HImode, operands); DONE;")
1275
1276 (define_insn "*pushhi2"
1277 [(set (match_operand:HI 0 "push_operand" "=<,<")
1278 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1279 "!TARGET_64BIT"
1280 "@
1281 push{w}\t{|WORD PTR }%1
1282 push{w}\t%1"
1283 [(set_attr "type" "push")
1284 (set_attr "mode" "HI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290 "TARGET_64BIT"
1291 "push{q}\t%q1"
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "QI")])
1294
1295 (define_insn "*movhi_1"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300 switch (get_attr_type (insn))
1301 {
1302 case TYPE_IMOVX:
1303 /* movzwl is faster than movw on p2 due to partial word stalls,
1304 though not as fast as an aligned movl. */
1305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306 default:
1307 if (get_attr_mode (insn) == MODE_SI)
1308 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309 else
1310 return "mov{w}\t{%1, %0|%0, %1}";
1311 }
1312 }
1313 [(set (attr "type")
1314 (cond [(and (eq_attr "alternative" "0")
1315 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1316 (const_int 0))
1317 (eq (symbol_ref "TARGET_HIMODE_MATH")
1318 (const_int 0))))
1319 (const_string "imov")
1320 (and (eq_attr "alternative" "1,2")
1321 (match_operand:HI 1 "aligned_operand" ""))
1322 (const_string "imov")
1323 (and (ne (symbol_ref "TARGET_MOVX")
1324 (const_int 0))
1325 (eq_attr "alternative" "0,2"))
1326 (const_string "imovx")
1327 ]
1328 (const_string "imov")))
1329 (set (attr "mode")
1330 (cond [(eq_attr "type" "imovx")
1331 (const_string "SI")
1332 (and (eq_attr "alternative" "1,2")
1333 (match_operand:HI 1 "aligned_operand" ""))
1334 (const_string "SI")
1335 (and (eq_attr "alternative" "0")
1336 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1337 (const_int 0))
1338 (eq (symbol_ref "TARGET_HIMODE_MATH")
1339 (const_int 0))))
1340 (const_string "SI")
1341 ]
1342 (const_string "HI")))])
1343
1344 ;; Stores and loads of ax to arbitrary constant address.
1345 ;; We fake an second form of instruction to force reload to load address
1346 ;; into register when rax is not available
1347 (define_insn "*movabshi_1_rex64"
1348 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1349 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1350 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1351 "@
1352 movabs{w}\t{%1, %P0|%P0, %1}
1353 mov{w}\t{%1, %a0|%a0, %1}"
1354 [(set_attr "type" "imov")
1355 (set_attr "modrm" "0,*")
1356 (set_attr "length_address" "8,0")
1357 (set_attr "length_immediate" "0,*")
1358 (set_attr "memory" "store")
1359 (set_attr "mode" "HI")])
1360
1361 (define_insn "*movabshi_2_rex64"
1362 [(set (match_operand:HI 0 "register_operand" "=a,r")
1363 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1364 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1365 "@
1366 movabs{w}\t{%P1, %0|%0, %P1}
1367 mov{w}\t{%a1, %0|%0, %a1}"
1368 [(set_attr "type" "imov")
1369 (set_attr "modrm" "0,*")
1370 (set_attr "length_address" "8,0")
1371 (set_attr "length_immediate" "0")
1372 (set_attr "memory" "load")
1373 (set_attr "mode" "HI")])
1374
1375 (define_insn "*swaphi_1"
1376 [(set (match_operand:HI 0 "register_operand" "+r")
1377 (match_operand:HI 1 "register_operand" "+r"))
1378 (set (match_dup 1)
1379 (match_dup 0))]
1380 "TARGET_PARTIAL_REG_STALL"
1381 "xchg{w}\t%1, %0"
1382 [(set_attr "type" "imov")
1383 (set_attr "pent_pair" "np")
1384 (set_attr "mode" "HI")
1385 (set_attr "modrm" "0")
1386 (set_attr "ppro_uops" "few")])
1387
1388 (define_insn "*swaphi_2"
1389 [(set (match_operand:HI 0 "register_operand" "+r")
1390 (match_operand:HI 1 "register_operand" "+r"))
1391 (set (match_dup 1)
1392 (match_dup 0))]
1393 "! TARGET_PARTIAL_REG_STALL"
1394 "xchg{l}\t%k1, %k0"
1395 [(set_attr "type" "imov")
1396 (set_attr "pent_pair" "np")
1397 (set_attr "mode" "SI")
1398 (set_attr "modrm" "0")
1399 (set_attr "ppro_uops" "few")])
1400
1401 (define_expand "movstricthi"
1402 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403 (match_operand:HI 1 "general_operand" ""))]
1404 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406 /* Don't generate memory->memory moves, go through a register */
1407 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408 operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413 (match_operand:HI 1 "general_operand" "rn,m"))]
1414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416 "mov{w}\t{%1, %0|%0, %1}"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422 (match_operand:HI 1 "const0_operand" "i"))
1423 (clobber (reg:CC 17))]
1424 "reload_completed
1425 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426 "xor{w}\t{%0, %0|%0, %0}"
1427 [(set_attr "type" "alu1")
1428 (set_attr "mode" "HI")
1429 (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433 (match_operand:QI 1 "general_operand" ""))]
1434 ""
1435 "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte". But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1440
1441 (define_insn "*pushqi2"
1442 [(set (match_operand:QI 0 "push_operand" "=X,X")
1443 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1444 "!TARGET_64BIT"
1445 "@
1446 push{w}\t{|word ptr }%1
1447 push{w}\t%w1"
1448 [(set_attr "type" "push")
1449 (set_attr "mode" "HI")])
1450
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453 [(set (match_operand:QI 0 "push_operand" "=X")
1454 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455 "TARGET_64BIT"
1456 "push{q}\t%q1"
1457 [(set_attr "type" "push")
1458 (set_attr "mode" "QI")])
1459
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; instruction).
1466 ;;
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there. Then we use movzx.
1470 (define_insn "*movqi_1"
1471 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1473 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 {
1475 switch (get_attr_type (insn))
1476 {
1477 case TYPE_IMOVX:
1478 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1479 abort ();
1480 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1481 default:
1482 if (get_attr_mode (insn) == MODE_SI)
1483 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1484 else
1485 return "mov{b}\t{%1, %0|%0, %1}";
1486 }
1487 }
1488 [(set (attr "type")
1489 (cond [(and (eq_attr "alternative" "3")
1490 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1491 (const_int 0))
1492 (eq (symbol_ref "TARGET_QIMODE_MATH")
1493 (const_int 0))))
1494 (const_string "imov")
1495 (eq_attr "alternative" "3,5")
1496 (const_string "imovx")
1497 (and (ne (symbol_ref "TARGET_MOVX")
1498 (const_int 0))
1499 (eq_attr "alternative" "2"))
1500 (const_string "imovx")
1501 ]
1502 (const_string "imov")))
1503 (set (attr "mode")
1504 (cond [(eq_attr "alternative" "3,4,5")
1505 (const_string "SI")
1506 (eq_attr "alternative" "6")
1507 (const_string "QI")
1508 (eq_attr "type" "imovx")
1509 (const_string "SI")
1510 (and (eq_attr "type" "imov")
1511 (and (eq_attr "alternative" "0,1,2")
1512 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1513 (const_int 0))))
1514 (const_string "SI")
1515 ;; Avoid partial register stalls when not using QImode arithmetic
1516 (and (eq_attr "type" "imov")
1517 (and (eq_attr "alternative" "0,1,2")
1518 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519 (const_int 0))
1520 (eq (symbol_ref "TARGET_QIMODE_MATH")
1521 (const_int 0)))))
1522 (const_string "SI")
1523 ]
1524 (const_string "QI")))])
1525
1526 (define_expand "reload_outqi"
1527 [(parallel [(match_operand:QI 0 "" "=m")
1528 (match_operand:QI 1 "register_operand" "r")
1529 (match_operand:QI 2 "register_operand" "=&q")])]
1530 ""
1531 {
1532 rtx op0, op1, op2;
1533 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1534
1535 if (reg_overlap_mentioned_p (op2, op0))
1536 abort ();
1537 if (! q_regs_operand (op1, QImode))
1538 {
1539 emit_insn (gen_movqi (op2, op1));
1540 op1 = op2;
1541 }
1542 emit_insn (gen_movqi (op0, op1));
1543 DONE;
1544 })
1545
1546 (define_insn "*swapqi"
1547 [(set (match_operand:QI 0 "register_operand" "+r")
1548 (match_operand:QI 1 "register_operand" "+r"))
1549 (set (match_dup 1)
1550 (match_dup 0))]
1551 ""
1552 "xchg{b}\t%1, %0"
1553 [(set_attr "type" "imov")
1554 (set_attr "pent_pair" "np")
1555 (set_attr "mode" "QI")
1556 (set_attr "modrm" "0")
1557 (set_attr "ppro_uops" "few")])
1558
1559 (define_expand "movstrictqi"
1560 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1561 (match_operand:QI 1 "general_operand" ""))]
1562 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1563 {
1564 /* Don't generate memory->memory moves, go through a register. */
1565 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1566 operands[1] = force_reg (QImode, operands[1]);
1567 })
1568
1569 (define_insn "*movstrictqi_1"
1570 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1571 (match_operand:QI 1 "general_operand" "*qn,m"))]
1572 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1573 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1574 "mov{b}\t{%1, %0|%0, %1}"
1575 [(set_attr "type" "imov")
1576 (set_attr "mode" "QI")])
1577
1578 (define_insn "*movstrictqi_xor"
1579 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1580 (match_operand:QI 1 "const0_operand" "i"))
1581 (clobber (reg:CC 17))]
1582 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1583 "xor{b}\t{%0, %0|%0, %0}"
1584 [(set_attr "type" "alu1")
1585 (set_attr "mode" "QI")
1586 (set_attr "length_immediate" "0")])
1587
1588 (define_insn "*movsi_extv_1"
1589 [(set (match_operand:SI 0 "register_operand" "=R")
1590 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1591 (const_int 8)
1592 (const_int 8)))]
1593 ""
1594 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1595 [(set_attr "type" "imovx")
1596 (set_attr "mode" "SI")])
1597
1598 (define_insn "*movhi_extv_1"
1599 [(set (match_operand:HI 0 "register_operand" "=R")
1600 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1601 (const_int 8)
1602 (const_int 8)))]
1603 ""
1604 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1605 [(set_attr "type" "imovx")
1606 (set_attr "mode" "SI")])
1607
1608 (define_insn "*movqi_extv_1"
1609 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1610 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1611 (const_int 8)
1612 (const_int 8)))]
1613 "!TARGET_64BIT"
1614 {
1615 switch (get_attr_type (insn))
1616 {
1617 case TYPE_IMOVX:
1618 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1619 default:
1620 return "mov{b}\t{%h1, %0|%0, %h1}";
1621 }
1622 }
1623 [(set (attr "type")
1624 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1625 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1626 (ne (symbol_ref "TARGET_MOVX")
1627 (const_int 0))))
1628 (const_string "imovx")
1629 (const_string "imov")))
1630 (set (attr "mode")
1631 (if_then_else (eq_attr "type" "imovx")
1632 (const_string "SI")
1633 (const_string "QI")))])
1634
1635 (define_insn "*movqi_extv_1_rex64"
1636 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1637 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1638 (const_int 8)
1639 (const_int 8)))]
1640 "TARGET_64BIT"
1641 {
1642 switch (get_attr_type (insn))
1643 {
1644 case TYPE_IMOVX:
1645 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1646 default:
1647 return "mov{b}\t{%h1, %0|%0, %h1}";
1648 }
1649 }
1650 [(set (attr "type")
1651 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1652 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1653 (ne (symbol_ref "TARGET_MOVX")
1654 (const_int 0))))
1655 (const_string "imovx")
1656 (const_string "imov")))
1657 (set (attr "mode")
1658 (if_then_else (eq_attr "type" "imovx")
1659 (const_string "SI")
1660 (const_string "QI")))])
1661
1662 ;; Stores and loads of ax to arbitrary constant address.
1663 ;; We fake an second form of instruction to force reload to load address
1664 ;; into register when rax is not available
1665 (define_insn "*movabsqi_1_rex64"
1666 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1667 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1668 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1669 "@
1670 movabs{b}\t{%1, %P0|%P0, %1}
1671 mov{b}\t{%1, %a0|%a0, %1}"
1672 [(set_attr "type" "imov")
1673 (set_attr "modrm" "0,*")
1674 (set_attr "length_address" "8,0")
1675 (set_attr "length_immediate" "0,*")
1676 (set_attr "memory" "store")
1677 (set_attr "mode" "QI")])
1678
1679 (define_insn "*movabsqi_2_rex64"
1680 [(set (match_operand:QI 0 "register_operand" "=a,r")
1681 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1682 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1683 "@
1684 movabs{b}\t{%P1, %0|%0, %P1}
1685 mov{b}\t{%a1, %0|%0, %a1}"
1686 [(set_attr "type" "imov")
1687 (set_attr "modrm" "0,*")
1688 (set_attr "length_address" "8,0")
1689 (set_attr "length_immediate" "0")
1690 (set_attr "memory" "load")
1691 (set_attr "mode" "QI")])
1692
1693 (define_insn "*movsi_extzv_1"
1694 [(set (match_operand:SI 0 "register_operand" "=R")
1695 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1696 (const_int 8)
1697 (const_int 8)))]
1698 ""
1699 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1700 [(set_attr "type" "imovx")
1701 (set_attr "mode" "SI")])
1702
1703 (define_insn "*movqi_extzv_2"
1704 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1705 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1706 (const_int 8)
1707 (const_int 8)) 0))]
1708 "!TARGET_64BIT"
1709 {
1710 switch (get_attr_type (insn))
1711 {
1712 case TYPE_IMOVX:
1713 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1714 default:
1715 return "mov{b}\t{%h1, %0|%0, %h1}";
1716 }
1717 }
1718 [(set (attr "type")
1719 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1720 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1721 (ne (symbol_ref "TARGET_MOVX")
1722 (const_int 0))))
1723 (const_string "imovx")
1724 (const_string "imov")))
1725 (set (attr "mode")
1726 (if_then_else (eq_attr "type" "imovx")
1727 (const_string "SI")
1728 (const_string "QI")))])
1729
1730 (define_insn "*movqi_extzv_2_rex64"
1731 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733 (const_int 8)
1734 (const_int 8)) 0))]
1735 "TARGET_64BIT"
1736 {
1737 switch (get_attr_type (insn))
1738 {
1739 case TYPE_IMOVX:
1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741 default:
1742 return "mov{b}\t{%h1, %0|%0, %h1}";
1743 }
1744 }
1745 [(set (attr "type")
1746 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747 (ne (symbol_ref "TARGET_MOVX")
1748 (const_int 0)))
1749 (const_string "imovx")
1750 (const_string "imov")))
1751 (set (attr "mode")
1752 (if_then_else (eq_attr "type" "imovx")
1753 (const_string "SI")
1754 (const_string "QI")))])
1755
1756 (define_insn "movsi_insv_1"
1757 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1758 (const_int 8)
1759 (const_int 8))
1760 (match_operand:SI 1 "general_operand" "Qmn"))]
1761 "!TARGET_64BIT"
1762 "mov{b}\t{%b1, %h0|%h0, %b1}"
1763 [(set_attr "type" "imov")
1764 (set_attr "mode" "QI")])
1765
1766 (define_insn "*movsi_insv_1_rex64"
1767 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1768 (const_int 8)
1769 (const_int 8))
1770 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1771 "TARGET_64BIT"
1772 "mov{b}\t{%b1, %h0|%h0, %b1}"
1773 [(set_attr "type" "imov")
1774 (set_attr "mode" "QI")])
1775
1776 (define_insn "*movqi_insv_2"
1777 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1778 (const_int 8)
1779 (const_int 8))
1780 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1781 (const_int 8)))]
1782 ""
1783 "mov{b}\t{%h1, %h0|%h0, %h1}"
1784 [(set_attr "type" "imov")
1785 (set_attr "mode" "QI")])
1786
1787 (define_expand "movdi"
1788 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1789 (match_operand:DI 1 "general_operand" ""))]
1790 ""
1791 "ix86_expand_move (DImode, operands); DONE;")
1792
1793 (define_insn "*pushdi"
1794 [(set (match_operand:DI 0 "push_operand" "=<")
1795 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1796 "!TARGET_64BIT"
1797 "#")
1798
1799 (define_insn "pushdi2_rex64"
1800 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1801 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1802 "TARGET_64BIT"
1803 "@
1804 push{q}\t%1
1805 #"
1806 [(set_attr "type" "push,multi")
1807 (set_attr "mode" "DI")])
1808
1809 ;; Convert impossible pushes of immediate to existing instructions.
1810 ;; First try to get scratch register and go through it. In case this
1811 ;; fails, push sign extended lower part first and then overwrite
1812 ;; upper part by 32bit move.
1813 (define_peephole2
1814 [(match_scratch:DI 2 "r")
1815 (set (match_operand:DI 0 "push_operand" "")
1816 (match_operand:DI 1 "immediate_operand" ""))]
1817 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1818 && !x86_64_immediate_operand (operands[1], DImode)"
1819 [(set (match_dup 2) (match_dup 1))
1820 (set (match_dup 0) (match_dup 2))]
1821 "")
1822
1823 ;; We need to define this as both peepholer and splitter for case
1824 ;; peephole2 pass is not run.
1825 (define_peephole2
1826 [(set (match_operand:DI 0 "push_operand" "")
1827 (match_operand:DI 1 "immediate_operand" ""))]
1828 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1829 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1830 [(set (match_dup 0) (match_dup 1))
1831 (set (match_dup 2) (match_dup 3))]
1832 "split_di (operands + 1, 1, operands + 2, operands + 3);
1833 operands[1] = gen_lowpart (DImode, operands[2]);
1834 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1835 GEN_INT (4)));
1836 ")
1837
1838 (define_split
1839 [(set (match_operand:DI 0 "push_operand" "")
1840 (match_operand:DI 1 "immediate_operand" ""))]
1841 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1842 && !symbolic_operand (operands[1], DImode)
1843 && !x86_64_immediate_operand (operands[1], DImode)"
1844 [(set (match_dup 0) (match_dup 1))
1845 (set (match_dup 2) (match_dup 3))]
1846 "split_di (operands + 1, 1, operands + 2, operands + 3);
1847 operands[1] = gen_lowpart (DImode, operands[2]);
1848 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1849 GEN_INT (4)));
1850 ")
1851
1852 (define_insn "*pushdi2_prologue_rex64"
1853 [(set (match_operand:DI 0 "push_operand" "=<")
1854 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1855 (clobber (mem:BLK (scratch)))]
1856 "TARGET_64BIT"
1857 "push{q}\t%1"
1858 [(set_attr "type" "push")
1859 (set_attr "mode" "DI")])
1860
1861 (define_insn "*popdi1_epilogue_rex64"
1862 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1863 (mem:DI (reg:DI 7)))
1864 (set (reg:DI 7)
1865 (plus:DI (reg:DI 7) (const_int 8)))
1866 (clobber (mem:BLK (scratch)))]
1867 "TARGET_64BIT"
1868 "pop{q}\t%0"
1869 [(set_attr "type" "pop")
1870 (set_attr "mode" "DI")])
1871
1872 (define_insn "popdi1"
1873 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1874 (mem:DI (reg:DI 7)))
1875 (set (reg:DI 7)
1876 (plus:DI (reg:DI 7) (const_int 8)))]
1877 "TARGET_64BIT"
1878 "pop{q}\t%0"
1879 [(set_attr "type" "pop")
1880 (set_attr "mode" "DI")])
1881
1882 (define_insn "*movdi_xor_rex64"
1883 [(set (match_operand:DI 0 "register_operand" "=r")
1884 (match_operand:DI 1 "const0_operand" "i"))
1885 (clobber (reg:CC 17))]
1886 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1887 && reload_completed"
1888 "xor{l}\t{%k0, %k0|%k0, %k0}"
1889 [(set_attr "type" "alu1")
1890 (set_attr "mode" "SI")
1891 (set_attr "length_immediate" "0")])
1892
1893 (define_insn "*movdi_or_rex64"
1894 [(set (match_operand:DI 0 "register_operand" "=r")
1895 (match_operand:DI 1 "const_int_operand" "i"))
1896 (clobber (reg:CC 17))]
1897 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1898 && reload_completed
1899 && operands[1] == constm1_rtx"
1900 {
1901 operands[1] = constm1_rtx;
1902 return "or{q}\t{%1, %0|%0, %1}";
1903 }
1904 [(set_attr "type" "alu1")
1905 (set_attr "mode" "DI")
1906 (set_attr "length_immediate" "1")])
1907
1908 (define_insn "*movdi_2"
1909 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1910 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1911 "!TARGET_64BIT
1912 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1913 "@
1914 #
1915 #
1916 movq\t{%1, %0|%0, %1}
1917 movq\t{%1, %0|%0, %1}
1918 movq\t{%1, %0|%0, %1}
1919 movdqa\t{%1, %0|%0, %1}
1920 movq\t{%1, %0|%0, %1}"
1921 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1922 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1923
1924 (define_split
1925 [(set (match_operand:DI 0 "push_operand" "")
1926 (match_operand:DI 1 "general_operand" ""))]
1927 "!TARGET_64BIT && reload_completed
1928 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1929 [(const_int 0)]
1930 "ix86_split_long_move (operands); DONE;")
1931
1932 ;; %%% This multiword shite has got to go.
1933 (define_split
1934 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1935 (match_operand:DI 1 "general_operand" ""))]
1936 "!TARGET_64BIT && reload_completed
1937 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1938 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1939 [(const_int 0)]
1940 "ix86_split_long_move (operands); DONE;")
1941
1942 (define_insn "*movdi_1_rex64"
1943 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1944 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1945 "TARGET_64BIT
1946 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1947 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1948 {
1949 switch (get_attr_type (insn))
1950 {
1951 case TYPE_SSEMOV:
1952 if (get_attr_mode (insn) == MODE_TI)
1953 return "movdqa\t{%1, %0|%0, %1}";
1954 /* FALLTHRU */
1955 case TYPE_MMXMOV:
1956 /* Moves from and into integer register is done using movd opcode with
1957 REX prefix. */
1958 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1959 return "movd\t{%1, %0|%0, %1}";
1960 return "movq\t{%1, %0|%0, %1}";
1961 case TYPE_MULTI:
1962 return "#";
1963 case TYPE_LEA:
1964 return "lea{q}\t{%a1, %0|%0, %a1}";
1965 default:
1966 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1967 abort ();
1968 if (get_attr_mode (insn) == MODE_SI)
1969 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970 else if (which_alternative == 2)
1971 return "movabs{q}\t{%1, %0|%0, %1}";
1972 else
1973 return "mov{q}\t{%1, %0|%0, %1}";
1974 }
1975 }
1976 [(set (attr "type")
1977 (cond [(eq_attr "alternative" "5,6,7")
1978 (const_string "mmxmov")
1979 (eq_attr "alternative" "8,9,10")
1980 (const_string "ssemov")
1981 (eq_attr "alternative" "4")
1982 (const_string "multi")
1983 (and (ne (symbol_ref "flag_pic") (const_int 0))
1984 (match_operand:DI 1 "symbolic_operand" ""))
1985 (const_string "lea")
1986 ]
1987 (const_string "imov")))
1988 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1989 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1990 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1991
1992 (define_insn "*movdi_1_rex64_nointerunit"
1993 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1994 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1995 "TARGET_64BIT
1996 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1997 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1998 {
1999 switch (get_attr_type (insn))
2000 {
2001 case TYPE_SSEMOV:
2002 if (get_attr_mode (insn) == MODE_TI)
2003 return "movdqa\t{%1, %0|%0, %1}";
2004 /* FALLTHRU */
2005 case TYPE_MMXMOV:
2006 return "movq\t{%1, %0|%0, %1}";
2007 case TYPE_MULTI:
2008 return "#";
2009 case TYPE_LEA:
2010 return "lea{q}\t{%a1, %0|%0, %a1}";
2011 default:
2012 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2013 abort ();
2014 if (get_attr_mode (insn) == MODE_SI)
2015 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2016 else if (which_alternative == 2)
2017 return "movabs{q}\t{%1, %0|%0, %1}";
2018 else
2019 return "mov{q}\t{%1, %0|%0, %1}";
2020 }
2021 }
2022 [(set (attr "type")
2023 (cond [(eq_attr "alternative" "5,6,7")
2024 (const_string "mmxmov")
2025 (eq_attr "alternative" "8,9,10")
2026 (const_string "ssemov")
2027 (eq_attr "alternative" "4")
2028 (const_string "multi")
2029 (and (ne (symbol_ref "flag_pic") (const_int 0))
2030 (match_operand:DI 1 "symbolic_operand" ""))
2031 (const_string "lea")
2032 ]
2033 (const_string "imov")))
2034 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2035 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2036 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2037
2038 ;; Stores and loads of ax to arbitrary constant address.
2039 ;; We fake an second form of instruction to force reload to load address
2040 ;; into register when rax is not available
2041 (define_insn "*movabsdi_1_rex64"
2042 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2043 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2044 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2045 "@
2046 movabs{q}\t{%1, %P0|%P0, %1}
2047 mov{q}\t{%1, %a0|%a0, %1}"
2048 [(set_attr "type" "imov")
2049 (set_attr "modrm" "0,*")
2050 (set_attr "length_address" "8,0")
2051 (set_attr "length_immediate" "0,*")
2052 (set_attr "memory" "store")
2053 (set_attr "mode" "DI")])
2054
2055 (define_insn "*movabsdi_2_rex64"
2056 [(set (match_operand:DI 0 "register_operand" "=a,r")
2057 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2058 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2059 "@
2060 movabs{q}\t{%P1, %0|%0, %P1}
2061 mov{q}\t{%a1, %0|%0, %a1}"
2062 [(set_attr "type" "imov")
2063 (set_attr "modrm" "0,*")
2064 (set_attr "length_address" "8,0")
2065 (set_attr "length_immediate" "0")
2066 (set_attr "memory" "load")
2067 (set_attr "mode" "DI")])
2068
2069 ;; Convert impossible stores of immediate to existing instructions.
2070 ;; First try to get scratch register and go through it. In case this
2071 ;; fails, move by 32bit parts.
2072 (define_peephole2
2073 [(match_scratch:DI 2 "r")
2074 (set (match_operand:DI 0 "memory_operand" "")
2075 (match_operand:DI 1 "immediate_operand" ""))]
2076 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2077 && !x86_64_immediate_operand (operands[1], DImode)"
2078 [(set (match_dup 2) (match_dup 1))
2079 (set (match_dup 0) (match_dup 2))]
2080 "")
2081
2082 ;; We need to define this as both peepholer and splitter for case
2083 ;; peephole2 pass is not run.
2084 (define_peephole2
2085 [(set (match_operand:DI 0 "memory_operand" "")
2086 (match_operand:DI 1 "immediate_operand" ""))]
2087 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2088 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2089 [(set (match_dup 2) (match_dup 3))
2090 (set (match_dup 4) (match_dup 5))]
2091 "split_di (operands, 2, operands + 2, operands + 4);")
2092
2093 (define_split
2094 [(set (match_operand:DI 0 "memory_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2097 && !symbolic_operand (operands[1], DImode)
2098 && !x86_64_immediate_operand (operands[1], DImode)"
2099 [(set (match_dup 2) (match_dup 3))
2100 (set (match_dup 4) (match_dup 5))]
2101 "split_di (operands, 2, operands + 2, operands + 4);")
2102
2103 (define_insn "*swapdi_rex64"
2104 [(set (match_operand:DI 0 "register_operand" "+r")
2105 (match_operand:DI 1 "register_operand" "+r"))
2106 (set (match_dup 1)
2107 (match_dup 0))]
2108 "TARGET_64BIT"
2109 "xchg{q}\t%1, %0"
2110 [(set_attr "type" "imov")
2111 (set_attr "pent_pair" "np")
2112 (set_attr "athlon_decode" "vector")
2113 (set_attr "mode" "DI")
2114 (set_attr "modrm" "0")
2115 (set_attr "ppro_uops" "few")])
2116
2117
2118 (define_expand "movsf"
2119 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2120 (match_operand:SF 1 "general_operand" ""))]
2121 ""
2122 "ix86_expand_move (SFmode, operands); DONE;")
2123
2124 (define_insn "*pushsf"
2125 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2126 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2127 "!TARGET_64BIT"
2128 {
2129 switch (which_alternative)
2130 {
2131 case 1:
2132 return "push{l}\t%1";
2133
2134 default:
2135 /* This insn should be already split before reg-stack. */
2136 abort ();
2137 }
2138 }
2139 [(set_attr "type" "multi,push,multi")
2140 (set_attr "mode" "SF,SI,SF")])
2141
2142 (define_insn "*pushsf_rex64"
2143 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2144 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2145 "TARGET_64BIT"
2146 {
2147 switch (which_alternative)
2148 {
2149 case 1:
2150 return "push{q}\t%q1";
2151
2152 default:
2153 /* This insn should be already split before reg-stack. */
2154 abort ();
2155 }
2156 }
2157 [(set_attr "type" "multi,push,multi")
2158 (set_attr "mode" "SF,DI,SF")])
2159
2160 (define_split
2161 [(set (match_operand:SF 0 "push_operand" "")
2162 (match_operand:SF 1 "memory_operand" ""))]
2163 "reload_completed
2164 && GET_CODE (operands[1]) == MEM
2165 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2166 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2167 [(set (match_dup 0)
2168 (match_dup 1))]
2169 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2170
2171
2172 ;; %%% Kill this when call knows how to work this out.
2173 (define_split
2174 [(set (match_operand:SF 0 "push_operand" "")
2175 (match_operand:SF 1 "any_fp_register_operand" ""))]
2176 "!TARGET_64BIT"
2177 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2178 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2179
2180 (define_split
2181 [(set (match_operand:SF 0 "push_operand" "")
2182 (match_operand:SF 1 "any_fp_register_operand" ""))]
2183 "TARGET_64BIT"
2184 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2185 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2186
2187 (define_insn "*movsf_1"
2188 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2189 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2190 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2191 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2192 && (reload_in_progress || reload_completed
2193 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2194 || GET_CODE (operands[1]) != CONST_DOUBLE
2195 || memory_operand (operands[0], SFmode))"
2196 {
2197 switch (which_alternative)
2198 {
2199 case 0:
2200 if (REG_P (operands[1])
2201 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2202 return "fstp\t%y0";
2203 else if (STACK_TOP_P (operands[0]))
2204 return "fld%z1\t%y1";
2205 else
2206 return "fst\t%y0";
2207
2208 case 1:
2209 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2210 return "fstp%z0\t%y0";
2211 else
2212 return "fst%z0\t%y0";
2213
2214 case 2:
2215 return standard_80387_constant_opcode (operands[1]);
2216
2217 case 3:
2218 case 4:
2219 return "mov{l}\t{%1, %0|%0, %1}";
2220 case 5:
2221 if (get_attr_mode (insn) == MODE_TI)
2222 return "pxor\t%0, %0";
2223 else
2224 return "xorps\t%0, %0";
2225 case 6:
2226 if (get_attr_mode (insn) == MODE_V4SF)
2227 return "movaps\t{%1, %0|%0, %1}";
2228 else
2229 return "movss\t{%1, %0|%0, %1}";
2230 case 7:
2231 case 8:
2232 return "movss\t{%1, %0|%0, %1}";
2233
2234 case 9:
2235 case 10:
2236 return "movd\t{%1, %0|%0, %1}";
2237
2238 case 11:
2239 return "movq\t{%1, %0|%0, %1}";
2240
2241 default:
2242 abort();
2243 }
2244 }
2245 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2246 (set (attr "mode")
2247 (cond [(eq_attr "alternative" "3,4,9,10")
2248 (const_string "SI")
2249 (eq_attr "alternative" "5")
2250 (if_then_else
2251 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2252 (const_int 0))
2253 (ne (symbol_ref "TARGET_SSE2")
2254 (const_int 0)))
2255 (eq (symbol_ref "optimize_size")
2256 (const_int 0)))
2257 (const_string "TI")
2258 (const_string "V4SF"))
2259 /* For architectures resolving dependencies on
2260 whole SSE registers use APS move to break dependency
2261 chains, otherwise use short move to avoid extra work.
2262
2263 Do the same for architectures resolving dependencies on
2264 the parts. While in DF mode it is better to always handle
2265 just register parts, the SF mode is different due to lack
2266 of instructions to load just part of the register. It is
2267 better to maintain the whole registers in single format
2268 to avoid problems on using packed logical operations. */
2269 (eq_attr "alternative" "6")
2270 (if_then_else
2271 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2272 (const_int 0))
2273 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2274 (const_int 0)))
2275 (const_string "V4SF")
2276 (const_string "SF"))
2277 (eq_attr "alternative" "11")
2278 (const_string "DI")]
2279 (const_string "SF")))])
2280
2281 (define_insn "*movsf_1_nointerunit"
2282 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2283 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2284 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286 && (reload_in_progress || reload_completed
2287 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288 || GET_CODE (operands[1]) != CONST_DOUBLE
2289 || memory_operand (operands[0], SFmode))"
2290 {
2291 switch (which_alternative)
2292 {
2293 case 0:
2294 if (REG_P (operands[1])
2295 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2296 {
2297 if (REGNO (operands[0]) == FIRST_STACK_REG
2298 && TARGET_USE_FFREEP)
2299 return "ffreep\t%y0";
2300 return "fstp\t%y0";
2301 }
2302 else if (STACK_TOP_P (operands[0]))
2303 return "fld%z1\t%y1";
2304 else
2305 return "fst\t%y0";
2306
2307 case 1:
2308 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2309 return "fstp%z0\t%y0";
2310 else
2311 return "fst%z0\t%y0";
2312
2313 case 2:
2314 return standard_80387_constant_opcode (operands[1]);
2315
2316 case 3:
2317 case 4:
2318 return "mov{l}\t{%1, %0|%0, %1}";
2319 case 5:
2320 if (get_attr_mode (insn) == MODE_TI)
2321 return "pxor\t%0, %0";
2322 else
2323 return "xorps\t%0, %0";
2324 case 6:
2325 if (get_attr_mode (insn) == MODE_V4SF)
2326 return "movaps\t{%1, %0|%0, %1}";
2327 else
2328 return "movss\t{%1, %0|%0, %1}";
2329 case 7:
2330 case 8:
2331 return "movss\t{%1, %0|%0, %1}";
2332
2333 case 9:
2334 case 10:
2335 return "movd\t{%1, %0|%0, %1}";
2336
2337 case 11:
2338 return "movq\t{%1, %0|%0, %1}";
2339
2340 default:
2341 abort();
2342 }
2343 }
2344 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2345 (set (attr "mode")
2346 (cond [(eq_attr "alternative" "3,4,9,10")
2347 (const_string "SI")
2348 (eq_attr "alternative" "5")
2349 (if_then_else
2350 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2351 (const_int 0))
2352 (ne (symbol_ref "TARGET_SSE2")
2353 (const_int 0)))
2354 (eq (symbol_ref "optimize_size")
2355 (const_int 0)))
2356 (const_string "TI")
2357 (const_string "V4SF"))
2358 /* For architectures resolving dependencies on
2359 whole SSE registers use APS move to break dependency
2360 chains, otherwise use short move to avoid extra work.
2361
2362 Do the same for architectures resolving dependencies on
2363 the parts. While in DF mode it is better to always handle
2364 just register parts, the SF mode is different due to lack
2365 of instructions to load just part of the register. It is
2366 better to maintain the whole registers in single format
2367 to avoid problems on using packed logical operations. */
2368 (eq_attr "alternative" "6")
2369 (if_then_else
2370 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2371 (const_int 0))
2372 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2373 (const_int 0)))
2374 (const_string "V4SF")
2375 (const_string "SF"))
2376 (eq_attr "alternative" "11")
2377 (const_string "DI")]
2378 (const_string "SF")))])
2379
2380 (define_insn "*swapsf"
2381 [(set (match_operand:SF 0 "register_operand" "+f")
2382 (match_operand:SF 1 "register_operand" "+f"))
2383 (set (match_dup 1)
2384 (match_dup 0))]
2385 "reload_completed || !TARGET_SSE"
2386 {
2387 if (STACK_TOP_P (operands[0]))
2388 return "fxch\t%1";
2389 else
2390 return "fxch\t%0";
2391 }
2392 [(set_attr "type" "fxch")
2393 (set_attr "mode" "SF")])
2394
2395 (define_expand "movdf"
2396 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2397 (match_operand:DF 1 "general_operand" ""))]
2398 ""
2399 "ix86_expand_move (DFmode, operands); DONE;")
2400
2401 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2402 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2403 ;; On the average, pushdf using integers can be still shorter. Allow this
2404 ;; pattern for optimize_size too.
2405
2406 (define_insn "*pushdf_nointeger"
2407 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2408 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2409 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411 /* This insn should be already split before reg-stack. */
2412 abort ();
2413 }
2414 [(set_attr "type" "multi")
2415 (set_attr "mode" "DF,SI,SI,DF")])
2416
2417 (define_insn "*pushdf_integer"
2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2419 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2420 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2421 {
2422 /* This insn should be already split before reg-stack. */
2423 abort ();
2424 }
2425 [(set_attr "type" "multi")
2426 (set_attr "mode" "DF,SI,DF")])
2427
2428 ;; %%% Kill this when call knows how to work this out.
2429 (define_split
2430 [(set (match_operand:DF 0 "push_operand" "")
2431 (match_operand:DF 1 "any_fp_register_operand" ""))]
2432 "!TARGET_64BIT && reload_completed"
2433 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2434 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2435 "")
2436
2437 (define_split
2438 [(set (match_operand:DF 0 "push_operand" "")
2439 (match_operand:DF 1 "any_fp_register_operand" ""))]
2440 "TARGET_64BIT && reload_completed"
2441 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2442 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2443 "")
2444
2445 (define_split
2446 [(set (match_operand:DF 0 "push_operand" "")
2447 (match_operand:DF 1 "general_operand" ""))]
2448 "reload_completed"
2449 [(const_int 0)]
2450 "ix86_split_long_move (operands); DONE;")
2451
2452 ;; Moving is usually shorter when only FP registers are used. This separate
2453 ;; movdf pattern avoids the use of integer registers for FP operations
2454 ;; when optimizing for size.
2455
2456 (define_insn "*movdf_nointeger"
2457 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2458 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2459 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2460 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2461 && (reload_in_progress || reload_completed
2462 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2463 || GET_CODE (operands[1]) != CONST_DOUBLE
2464 || memory_operand (operands[0], DFmode))"
2465 {
2466 switch (which_alternative)
2467 {
2468 case 0:
2469 if (REG_P (operands[1])
2470 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2471 {
2472 if (REGNO (operands[0]) == FIRST_STACK_REG
2473 && TARGET_USE_FFREEP)
2474 return "ffreep\t%y0";
2475 return "fstp\t%y0";
2476 }
2477 else if (STACK_TOP_P (operands[0]))
2478 return "fld%z1\t%y1";
2479 else
2480 return "fst\t%y0";
2481
2482 case 1:
2483 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2484 return "fstp%z0\t%y0";
2485 else
2486 return "fst%z0\t%y0";
2487
2488 case 2:
2489 return standard_80387_constant_opcode (operands[1]);
2490
2491 case 3:
2492 case 4:
2493 return "#";
2494 case 5:
2495 switch (get_attr_mode (insn))
2496 {
2497 case MODE_V4SF:
2498 return "xorps\t%0, %0";
2499 case MODE_V2DF:
2500 return "xorpd\t%0, %0";
2501 case MODE_TI:
2502 return "pxor\t%0, %0";
2503 default:
2504 abort ();
2505 }
2506 case 6:
2507 switch (get_attr_mode (insn))
2508 {
2509 case MODE_V4SF:
2510 return "movaps\t{%1, %0|%0, %1}";
2511 case MODE_V2DF:
2512 return "movapd\t{%1, %0|%0, %1}";
2513 case MODE_DF:
2514 return "movsd\t{%1, %0|%0, %1}";
2515 default:
2516 abort ();
2517 }
2518 case 7:
2519 if (get_attr_mode (insn) == MODE_V2DF)
2520 return "movlpd\t{%1, %0|%0, %1}";
2521 else
2522 return "movsd\t{%1, %0|%0, %1}";
2523 case 8:
2524 return "movsd\t{%1, %0|%0, %1}";
2525
2526 default:
2527 abort();
2528 }
2529 }
2530 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2531 (set (attr "mode")
2532 (cond [(eq_attr "alternative" "3,4")
2533 (const_string "SI")
2534 /* xorps is one byte shorter. */
2535 (eq_attr "alternative" "5")
2536 (cond [(ne (symbol_ref "optimize_size")
2537 (const_int 0))
2538 (const_string "V4SF")
2539 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2540 (const_int 0))
2541 (const_string "TI")]
2542 (const_string "V2DF"))
2543 /* For architectures resolving dependencies on
2544 whole SSE registers use APD move to break dependency
2545 chains, otherwise use short move to avoid extra work.
2546
2547 movaps encodes one byte shorter. */
2548 (eq_attr "alternative" "6")
2549 (cond
2550 [(ne (symbol_ref "optimize_size")
2551 (const_int 0))
2552 (const_string "V4SF")
2553 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2554 (const_int 0))
2555 (const_string "V2DF")]
2556 (const_string "DF"))
2557 /* For architectures resolving dependencies on register
2558 parts we may avoid extra work to zero out upper part
2559 of register. */
2560 (eq_attr "alternative" "7")
2561 (if_then_else
2562 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2563 (const_int 0))
2564 (const_string "V2DF")
2565 (const_string "DF"))]
2566 (const_string "DF")))])
2567
2568 (define_insn "*movdf_integer"
2569 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2570 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2571 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2572 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2573 && (reload_in_progress || reload_completed
2574 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2575 || GET_CODE (operands[1]) != CONST_DOUBLE
2576 || memory_operand (operands[0], DFmode))"
2577 {
2578 switch (which_alternative)
2579 {
2580 case 0:
2581 if (REG_P (operands[1])
2582 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2583 {
2584 if (REGNO (operands[0]) == FIRST_STACK_REG
2585 && TARGET_USE_FFREEP)
2586 return "ffreep\t%y0";
2587 return "fstp\t%y0";
2588 }
2589 else if (STACK_TOP_P (operands[0]))
2590 return "fld%z1\t%y1";
2591 else
2592 return "fst\t%y0";
2593
2594 case 1:
2595 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2596 return "fstp%z0\t%y0";
2597 else
2598 return "fst%z0\t%y0";
2599
2600 case 2:
2601 return standard_80387_constant_opcode (operands[1]);
2602
2603 case 3:
2604 case 4:
2605 return "#";
2606
2607 case 5:
2608 switch (get_attr_mode (insn))
2609 {
2610 case MODE_V4SF:
2611 return "xorps\t%0, %0";
2612 case MODE_V2DF:
2613 return "xorpd\t%0, %0";
2614 case MODE_TI:
2615 return "pxor\t%0, %0";
2616 default:
2617 abort ();
2618 }
2619 case 6:
2620 switch (get_attr_mode (insn))
2621 {
2622 case MODE_V4SF:
2623 return "movaps\t{%1, %0|%0, %1}";
2624 case MODE_V2DF:
2625 return "movapd\t{%1, %0|%0, %1}";
2626 case MODE_DF:
2627 return "movsd\t{%1, %0|%0, %1}";
2628 default:
2629 abort ();
2630 }
2631 case 7:
2632 if (get_attr_mode (insn) == MODE_V2DF)
2633 return "movlpd\t{%1, %0|%0, %1}";
2634 else
2635 return "movsd\t{%1, %0|%0, %1}";
2636 case 8:
2637 return "movsd\t{%1, %0|%0, %1}";
2638
2639 default:
2640 abort();
2641 }
2642 }
2643 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2644 (set (attr "mode")
2645 (cond [(eq_attr "alternative" "3,4")
2646 (const_string "SI")
2647 /* xorps is one byte shorter. */
2648 (eq_attr "alternative" "5")
2649 (cond [(ne (symbol_ref "optimize_size")
2650 (const_int 0))
2651 (const_string "V4SF")
2652 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2653 (const_int 0))
2654 (const_string "TI")]
2655 (const_string "V2DF"))
2656 /* For architectures resolving dependencies on
2657 whole SSE registers use APD move to break dependency
2658 chains, otherwise use short move to avoid extra work.
2659
2660 movaps encodes one byte shorter. */
2661 (eq_attr "alternative" "6")
2662 (cond
2663 [(ne (symbol_ref "optimize_size")
2664 (const_int 0))
2665 (const_string "V4SF")
2666 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667 (const_int 0))
2668 (const_string "V2DF")]
2669 (const_string "DF"))
2670 /* For architectures resolving dependencies on register
2671 parts we may avoid extra work to zero out upper part
2672 of register. */
2673 (eq_attr "alternative" "7")
2674 (if_then_else
2675 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2676 (const_int 0))
2677 (const_string "V2DF")
2678 (const_string "DF"))]
2679 (const_string "DF")))])
2680
2681 (define_split
2682 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2683 (match_operand:DF 1 "general_operand" ""))]
2684 "reload_completed
2685 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2686 && ! (ANY_FP_REG_P (operands[0]) ||
2687 (GET_CODE (operands[0]) == SUBREG
2688 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2689 && ! (ANY_FP_REG_P (operands[1]) ||
2690 (GET_CODE (operands[1]) == SUBREG
2691 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2692 [(const_int 0)]
2693 "ix86_split_long_move (operands); DONE;")
2694
2695 (define_insn "*swapdf"
2696 [(set (match_operand:DF 0 "register_operand" "+f")
2697 (match_operand:DF 1 "register_operand" "+f"))
2698 (set (match_dup 1)
2699 (match_dup 0))]
2700 "reload_completed || !TARGET_SSE2"
2701 {
2702 if (STACK_TOP_P (operands[0]))
2703 return "fxch\t%1";
2704 else
2705 return "fxch\t%0";
2706 }
2707 [(set_attr "type" "fxch")
2708 (set_attr "mode" "DF")])
2709
2710 (define_expand "movxf"
2711 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2712 (match_operand:XF 1 "general_operand" ""))]
2713 ""
2714 "ix86_expand_move (XFmode, operands); DONE;")
2715
2716 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2717 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2718 ;; Pushing using integer instructions is longer except for constants
2719 ;; and direct memory references.
2720 ;; (assuming that any given constant is pushed only once, but this ought to be
2721 ;; handled elsewhere).
2722
2723 (define_insn "*pushxf_nointeger"
2724 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2725 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2726 "optimize_size"
2727 {
2728 /* This insn should be already split before reg-stack. */
2729 abort ();
2730 }
2731 [(set_attr "type" "multi")
2732 (set_attr "mode" "XF,SI,SI")])
2733
2734 (define_insn "*pushxf_integer"
2735 [(set (match_operand:XF 0 "push_operand" "=<,<")
2736 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2737 "!optimize_size"
2738 {
2739 /* This insn should be already split before reg-stack. */
2740 abort ();
2741 }
2742 [(set_attr "type" "multi")
2743 (set_attr "mode" "XF,SI")])
2744
2745 (define_split
2746 [(set (match_operand 0 "push_operand" "")
2747 (match_operand 1 "general_operand" ""))]
2748 "reload_completed
2749 && (GET_MODE (operands[0]) == XFmode
2750 || GET_MODE (operands[0]) == DFmode)
2751 && !ANY_FP_REG_P (operands[1])"
2752 [(const_int 0)]
2753 "ix86_split_long_move (operands); DONE;")
2754
2755 (define_split
2756 [(set (match_operand:XF 0 "push_operand" "")
2757 (match_operand:XF 1 "any_fp_register_operand" ""))]
2758 "!TARGET_64BIT"
2759 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2760 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2761 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2762
2763 (define_split
2764 [(set (match_operand:XF 0 "push_operand" "")
2765 (match_operand:XF 1 "any_fp_register_operand" ""))]
2766 "TARGET_64BIT"
2767 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2768 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2769 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2770
2771 ;; Do not use integer registers when optimizing for size
2772 (define_insn "*movxf_nointeger"
2773 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2774 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2775 "optimize_size
2776 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2777 && (reload_in_progress || reload_completed
2778 || GET_CODE (operands[1]) != CONST_DOUBLE
2779 || memory_operand (operands[0], XFmode))"
2780 {
2781 switch (which_alternative)
2782 {
2783 case 0:
2784 if (REG_P (operands[1])
2785 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2786 {
2787 if (REGNO (operands[0]) == FIRST_STACK_REG
2788 && TARGET_USE_FFREEP)
2789 return "ffreep\t%y0";
2790 return "fstp\t%y0";
2791 }
2792 else if (STACK_TOP_P (operands[0]))
2793 return "fld%z1\t%y1";
2794 else
2795 return "fst\t%y0";
2796
2797 case 1:
2798 /* There is no non-popping store to memory for XFmode. So if
2799 we need one, follow the store with a load. */
2800 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2801 return "fstp%z0\t%y0\;fld%z0\t%y0";
2802 else
2803 return "fstp%z0\t%y0";
2804
2805 case 2:
2806 return standard_80387_constant_opcode (operands[1]);
2807
2808 case 3: case 4:
2809 return "#";
2810 }
2811 abort();
2812 }
2813 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2814 (set_attr "mode" "XF,XF,XF,SI,SI")])
2815
2816 (define_insn "*movxf_integer"
2817 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2818 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2819 "!optimize_size
2820 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2821 && (reload_in_progress || reload_completed
2822 || GET_CODE (operands[1]) != CONST_DOUBLE
2823 || memory_operand (operands[0], XFmode))"
2824 {
2825 switch (which_alternative)
2826 {
2827 case 0:
2828 if (REG_P (operands[1])
2829 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2830 {
2831 if (REGNO (operands[0]) == FIRST_STACK_REG
2832 && TARGET_USE_FFREEP)
2833 return "ffreep\t%y0";
2834 return "fstp\t%y0";
2835 }
2836 else if (STACK_TOP_P (operands[0]))
2837 return "fld%z1\t%y1";
2838 else
2839 return "fst\t%y0";
2840
2841 case 1:
2842 /* There is no non-popping store to memory for XFmode. So if
2843 we need one, follow the store with a load. */
2844 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2845 return "fstp%z0\t%y0\;fld%z0\t%y0";
2846 else
2847 return "fstp%z0\t%y0";
2848
2849 case 2:
2850 return standard_80387_constant_opcode (operands[1]);
2851
2852 case 3: case 4:
2853 return "#";
2854 }
2855 abort();
2856 }
2857 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2858 (set_attr "mode" "XF,XF,XF,SI,SI")])
2859
2860 (define_split
2861 [(set (match_operand 0 "nonimmediate_operand" "")
2862 (match_operand 1 "general_operand" ""))]
2863 "reload_completed
2864 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2865 && GET_MODE (operands[0]) == XFmode
2866 && ! (ANY_FP_REG_P (operands[0]) ||
2867 (GET_CODE (operands[0]) == SUBREG
2868 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2869 && ! (ANY_FP_REG_P (operands[1]) ||
2870 (GET_CODE (operands[1]) == SUBREG
2871 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2872 [(const_int 0)]
2873 "ix86_split_long_move (operands); DONE;")
2874
2875 (define_split
2876 [(set (match_operand 0 "register_operand" "")
2877 (match_operand 1 "memory_operand" ""))]
2878 "reload_completed
2879 && GET_CODE (operands[1]) == MEM
2880 && (GET_MODE (operands[0]) == XFmode
2881 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2882 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2883 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2884 [(set (match_dup 0) (match_dup 1))]
2885 {
2886 rtx c = get_pool_constant (XEXP (operands[1], 0));
2887 rtx r = operands[0];
2888
2889 if (GET_CODE (r) == SUBREG)
2890 r = SUBREG_REG (r);
2891
2892 if (SSE_REG_P (r))
2893 {
2894 if (!standard_sse_constant_p (c))
2895 FAIL;
2896 }
2897 else if (FP_REG_P (r))
2898 {
2899 if (!standard_80387_constant_p (c))
2900 FAIL;
2901 }
2902 else if (MMX_REG_P (r))
2903 FAIL;
2904
2905 operands[1] = c;
2906 })
2907
2908 (define_insn "swapxf"
2909 [(set (match_operand:XF 0 "register_operand" "+f")
2910 (match_operand:XF 1 "register_operand" "+f"))
2911 (set (match_dup 1)
2912 (match_dup 0))]
2913 ""
2914 {
2915 if (STACK_TOP_P (operands[0]))
2916 return "fxch\t%1";
2917 else
2918 return "fxch\t%0";
2919 }
2920 [(set_attr "type" "fxch")
2921 (set_attr "mode" "XF")])
2922 \f
2923 ;; Zero extension instructions
2924
2925 (define_expand "zero_extendhisi2"
2926 [(set (match_operand:SI 0 "register_operand" "")
2927 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2928 ""
2929 {
2930 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2931 {
2932 operands[1] = force_reg (HImode, operands[1]);
2933 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2934 DONE;
2935 }
2936 })
2937
2938 (define_insn "zero_extendhisi2_and"
2939 [(set (match_operand:SI 0 "register_operand" "=r")
2940 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2941 (clobber (reg:CC 17))]
2942 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2943 "#"
2944 [(set_attr "type" "alu1")
2945 (set_attr "mode" "SI")])
2946
2947 (define_split
2948 [(set (match_operand:SI 0 "register_operand" "")
2949 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2950 (clobber (reg:CC 17))]
2951 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2952 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2953 (clobber (reg:CC 17))])]
2954 "")
2955
2956 (define_insn "*zero_extendhisi2_movzwl"
2957 [(set (match_operand:SI 0 "register_operand" "=r")
2958 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2959 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2960 "movz{wl|x}\t{%1, %0|%0, %1}"
2961 [(set_attr "type" "imovx")
2962 (set_attr "mode" "SI")])
2963
2964 (define_expand "zero_extendqihi2"
2965 [(parallel
2966 [(set (match_operand:HI 0 "register_operand" "")
2967 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2968 (clobber (reg:CC 17))])]
2969 ""
2970 "")
2971
2972 (define_insn "*zero_extendqihi2_and"
2973 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2974 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2975 (clobber (reg:CC 17))]
2976 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2977 "#"
2978 [(set_attr "type" "alu1")
2979 (set_attr "mode" "HI")])
2980
2981 (define_insn "*zero_extendqihi2_movzbw_and"
2982 [(set (match_operand:HI 0 "register_operand" "=r,r")
2983 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2984 (clobber (reg:CC 17))]
2985 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2986 "#"
2987 [(set_attr "type" "imovx,alu1")
2988 (set_attr "mode" "HI")])
2989
2990 (define_insn "*zero_extendqihi2_movzbw"
2991 [(set (match_operand:HI 0 "register_operand" "=r")
2992 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2993 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2994 "movz{bw|x}\t{%1, %0|%0, %1}"
2995 [(set_attr "type" "imovx")
2996 (set_attr "mode" "HI")])
2997
2998 ;; For the movzbw case strip only the clobber
2999 (define_split
3000 [(set (match_operand:HI 0 "register_operand" "")
3001 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3002 (clobber (reg:CC 17))]
3003 "reload_completed
3004 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3005 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3006 [(set (match_operand:HI 0 "register_operand" "")
3007 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3008
3009 ;; When source and destination does not overlap, clear destination
3010 ;; first and then do the movb
3011 (define_split
3012 [(set (match_operand:HI 0 "register_operand" "")
3013 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3014 (clobber (reg:CC 17))]
3015 "reload_completed
3016 && ANY_QI_REG_P (operands[0])
3017 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3018 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3019 [(set (match_dup 0) (const_int 0))
3020 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3021 "operands[2] = gen_lowpart (QImode, operands[0]);")
3022
3023 ;; Rest is handled by single and.
3024 (define_split
3025 [(set (match_operand:HI 0 "register_operand" "")
3026 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3027 (clobber (reg:CC 17))]
3028 "reload_completed
3029 && true_regnum (operands[0]) == true_regnum (operands[1])"
3030 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3031 (clobber (reg:CC 17))])]
3032 "")
3033
3034 (define_expand "zero_extendqisi2"
3035 [(parallel
3036 [(set (match_operand:SI 0 "register_operand" "")
3037 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3038 (clobber (reg:CC 17))])]
3039 ""
3040 "")
3041
3042 (define_insn "*zero_extendqisi2_and"
3043 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3044 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3045 (clobber (reg:CC 17))]
3046 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3047 "#"
3048 [(set_attr "type" "alu1")
3049 (set_attr "mode" "SI")])
3050
3051 (define_insn "*zero_extendqisi2_movzbw_and"
3052 [(set (match_operand:SI 0 "register_operand" "=r,r")
3053 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3054 (clobber (reg:CC 17))]
3055 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3056 "#"
3057 [(set_attr "type" "imovx,alu1")
3058 (set_attr "mode" "SI")])
3059
3060 (define_insn "*zero_extendqisi2_movzbw"
3061 [(set (match_operand:SI 0 "register_operand" "=r")
3062 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3063 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3064 "movz{bl|x}\t{%1, %0|%0, %1}"
3065 [(set_attr "type" "imovx")
3066 (set_attr "mode" "SI")])
3067
3068 ;; For the movzbl case strip only the clobber
3069 (define_split
3070 [(set (match_operand:SI 0 "register_operand" "")
3071 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3072 (clobber (reg:CC 17))]
3073 "reload_completed
3074 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3075 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3076 [(set (match_dup 0)
3077 (zero_extend:SI (match_dup 1)))])
3078
3079 ;; When source and destination does not overlap, clear destination
3080 ;; first and then do the movb
3081 (define_split
3082 [(set (match_operand:SI 0 "register_operand" "")
3083 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084 (clobber (reg:CC 17))]
3085 "reload_completed
3086 && ANY_QI_REG_P (operands[0])
3087 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3088 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3089 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3090 [(set (match_dup 0) (const_int 0))
3091 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3092 "operands[2] = gen_lowpart (QImode, operands[0]);")
3093
3094 ;; Rest is handled by single and.
3095 (define_split
3096 [(set (match_operand:SI 0 "register_operand" "")
3097 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3098 (clobber (reg:CC 17))]
3099 "reload_completed
3100 && true_regnum (operands[0]) == true_regnum (operands[1])"
3101 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3102 (clobber (reg:CC 17))])]
3103 "")
3104
3105 ;; %%% Kill me once multi-word ops are sane.
3106 (define_expand "zero_extendsidi2"
3107 [(set (match_operand:DI 0 "register_operand" "=r")
3108 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3109 ""
3110 "if (!TARGET_64BIT)
3111 {
3112 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3113 DONE;
3114 }
3115 ")
3116
3117 (define_insn "zero_extendsidi2_32"
3118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3119 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3120 (clobber (reg:CC 17))]
3121 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3122 "@
3123 #
3124 #
3125 #
3126 movd\t{%1, %0|%0, %1}
3127 movd\t{%1, %0|%0, %1}"
3128 [(set_attr "mode" "SI,SI,SI,DI,TI")
3129 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3130
3131 (define_insn "*zero_extendsidi2_32_1"
3132 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3133 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3134 (clobber (reg:CC 17))]
3135 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3136 "@
3137 #
3138 #
3139 #
3140 movd\t{%1, %0|%0, %1}
3141 movd\t{%1, %0|%0, %1}"
3142 [(set_attr "mode" "SI,SI,SI,DI,TI")
3143 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3144
3145 (define_insn "zero_extendsidi2_rex64"
3146 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3147 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3148 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3149 "@
3150 mov\t{%k1, %k0|%k0, %k1}
3151 #
3152 movd\t{%1, %0|%0, %1}
3153 movd\t{%1, %0|%0, %1}"
3154 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3155 (set_attr "mode" "SI,DI,DI,TI")])
3156
3157 (define_insn "*zero_extendsidi2_rex64_1"
3158 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3159 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3160 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3161 "@
3162 mov\t{%k1, %k0|%k0, %k1}
3163 #
3164 movd\t{%1, %0|%0, %1}
3165 movd\t{%1, %0|%0, %1}"
3166 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3167 (set_attr "mode" "SI,DI,SI,SI")])
3168
3169 (define_split
3170 [(set (match_operand:DI 0 "memory_operand" "")
3171 (zero_extend:DI (match_dup 0)))]
3172 "TARGET_64BIT"
3173 [(set (match_dup 4) (const_int 0))]
3174 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3175
3176 (define_split
3177 [(set (match_operand:DI 0 "register_operand" "")
3178 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3179 (clobber (reg:CC 17))]
3180 "!TARGET_64BIT && reload_completed
3181 && true_regnum (operands[0]) == true_regnum (operands[1])"
3182 [(set (match_dup 4) (const_int 0))]
3183 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3184
3185 (define_split
3186 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3187 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3188 (clobber (reg:CC 17))]
3189 "!TARGET_64BIT && reload_completed
3190 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3191 [(set (match_dup 3) (match_dup 1))
3192 (set (match_dup 4) (const_int 0))]
3193 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195 (define_insn "zero_extendhidi2"
3196 [(set (match_operand:DI 0 "register_operand" "=r,r")
3197 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3198 "TARGET_64BIT"
3199 "@
3200 movz{wl|x}\t{%1, %k0|%k0, %1}
3201 movz{wq|x}\t{%1, %0|%0, %1}"
3202 [(set_attr "type" "imovx")
3203 (set_attr "mode" "SI,DI")])
3204
3205 (define_insn "zero_extendqidi2"
3206 [(set (match_operand:DI 0 "register_operand" "=r,r")
3207 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3208 "TARGET_64BIT"
3209 "@
3210 movz{bl|x}\t{%1, %k0|%k0, %1}
3211 movz{bq|x}\t{%1, %0|%0, %1}"
3212 [(set_attr "type" "imovx")
3213 (set_attr "mode" "SI,DI")])
3214 \f
3215 ;; Sign extension instructions
3216
3217 (define_expand "extendsidi2"
3218 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3219 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3220 (clobber (reg:CC 17))
3221 (clobber (match_scratch:SI 2 ""))])]
3222 ""
3223 {
3224 if (TARGET_64BIT)
3225 {
3226 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3227 DONE;
3228 }
3229 })
3230
3231 (define_insn "*extendsidi2_1"
3232 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3233 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3234 (clobber (reg:CC 17))
3235 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3236 "!TARGET_64BIT"
3237 "#")
3238
3239 (define_insn "extendsidi2_rex64"
3240 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3241 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3242 "TARGET_64BIT"
3243 "@
3244 {cltq|cdqe}
3245 movs{lq|x}\t{%1,%0|%0, %1}"
3246 [(set_attr "type" "imovx")
3247 (set_attr "mode" "DI")
3248 (set_attr "prefix_0f" "0")
3249 (set_attr "modrm" "0,1")])
3250
3251 (define_insn "extendhidi2"
3252 [(set (match_operand:DI 0 "register_operand" "=r")
3253 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3254 "TARGET_64BIT"
3255 "movs{wq|x}\t{%1,%0|%0, %1}"
3256 [(set_attr "type" "imovx")
3257 (set_attr "mode" "DI")])
3258
3259 (define_insn "extendqidi2"
3260 [(set (match_operand:DI 0 "register_operand" "=r")
3261 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3262 "TARGET_64BIT"
3263 "movs{bq|x}\t{%1,%0|%0, %1}"
3264 [(set_attr "type" "imovx")
3265 (set_attr "mode" "DI")])
3266
3267 ;; Extend to memory case when source register does die.
3268 (define_split
3269 [(set (match_operand:DI 0 "memory_operand" "")
3270 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3271 (clobber (reg:CC 17))
3272 (clobber (match_operand:SI 2 "register_operand" ""))]
3273 "(reload_completed
3274 && dead_or_set_p (insn, operands[1])
3275 && !reg_mentioned_p (operands[1], operands[0]))"
3276 [(set (match_dup 3) (match_dup 1))
3277 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3278 (clobber (reg:CC 17))])
3279 (set (match_dup 4) (match_dup 1))]
3280 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3281
3282 ;; Extend to memory case when source register does not die.
3283 (define_split
3284 [(set (match_operand:DI 0 "memory_operand" "")
3285 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC 17))
3287 (clobber (match_operand:SI 2 "register_operand" ""))]
3288 "reload_completed"
3289 [(const_int 0)]
3290 {
3291 split_di (&operands[0], 1, &operands[3], &operands[4]);
3292
3293 emit_move_insn (operands[3], operands[1]);
3294
3295 /* Generate a cltd if possible and doing so it profitable. */
3296 if (true_regnum (operands[1]) == 0
3297 && true_regnum (operands[2]) == 1
3298 && (optimize_size || TARGET_USE_CLTD))
3299 {
3300 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3301 }
3302 else
3303 {
3304 emit_move_insn (operands[2], operands[1]);
3305 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3306 }
3307 emit_move_insn (operands[4], operands[2]);
3308 DONE;
3309 })
3310
3311 ;; Extend to register case. Optimize case where source and destination
3312 ;; registers match and cases where we can use cltd.
3313 (define_split
3314 [(set (match_operand:DI 0 "register_operand" "")
3315 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3316 (clobber (reg:CC 17))
3317 (clobber (match_scratch:SI 2 ""))]
3318 "reload_completed"
3319 [(const_int 0)]
3320 {
3321 split_di (&operands[0], 1, &operands[3], &operands[4]);
3322
3323 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3324 emit_move_insn (operands[3], operands[1]);
3325
3326 /* Generate a cltd if possible and doing so it profitable. */
3327 if (true_regnum (operands[3]) == 0
3328 && (optimize_size || TARGET_USE_CLTD))
3329 {
3330 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3331 DONE;
3332 }
3333
3334 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3335 emit_move_insn (operands[4], operands[1]);
3336
3337 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3338 DONE;
3339 })
3340
3341 (define_insn "extendhisi2"
3342 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3343 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3344 ""
3345 {
3346 switch (get_attr_prefix_0f (insn))
3347 {
3348 case 0:
3349 return "{cwtl|cwde}";
3350 default:
3351 return "movs{wl|x}\t{%1,%0|%0, %1}";
3352 }
3353 }
3354 [(set_attr "type" "imovx")
3355 (set_attr "mode" "SI")
3356 (set (attr "prefix_0f")
3357 ;; movsx is short decodable while cwtl is vector decoded.
3358 (if_then_else (and (eq_attr "cpu" "!k6")
3359 (eq_attr "alternative" "0"))
3360 (const_string "0")
3361 (const_string "1")))
3362 (set (attr "modrm")
3363 (if_then_else (eq_attr "prefix_0f" "0")
3364 (const_string "0")
3365 (const_string "1")))])
3366
3367 (define_insn "*extendhisi2_zext"
3368 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3369 (zero_extend:DI
3370 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3371 "TARGET_64BIT"
3372 {
3373 switch (get_attr_prefix_0f (insn))
3374 {
3375 case 0:
3376 return "{cwtl|cwde}";
3377 default:
3378 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3379 }
3380 }
3381 [(set_attr "type" "imovx")
3382 (set_attr "mode" "SI")
3383 (set (attr "prefix_0f")
3384 ;; movsx is short decodable while cwtl is vector decoded.
3385 (if_then_else (and (eq_attr "cpu" "!k6")
3386 (eq_attr "alternative" "0"))
3387 (const_string "0")
3388 (const_string "1")))
3389 (set (attr "modrm")
3390 (if_then_else (eq_attr "prefix_0f" "0")
3391 (const_string "0")
3392 (const_string "1")))])
3393
3394 (define_insn "extendqihi2"
3395 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3396 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3397 ""
3398 {
3399 switch (get_attr_prefix_0f (insn))
3400 {
3401 case 0:
3402 return "{cbtw|cbw}";
3403 default:
3404 return "movs{bw|x}\t{%1,%0|%0, %1}";
3405 }
3406 }
3407 [(set_attr "type" "imovx")
3408 (set_attr "mode" "HI")
3409 (set (attr "prefix_0f")
3410 ;; movsx is short decodable while cwtl is vector decoded.
3411 (if_then_else (and (eq_attr "cpu" "!k6")
3412 (eq_attr "alternative" "0"))
3413 (const_string "0")
3414 (const_string "1")))
3415 (set (attr "modrm")
3416 (if_then_else (eq_attr "prefix_0f" "0")
3417 (const_string "0")
3418 (const_string "1")))])
3419
3420 (define_insn "extendqisi2"
3421 [(set (match_operand:SI 0 "register_operand" "=r")
3422 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3423 ""
3424 "movs{bl|x}\t{%1,%0|%0, %1}"
3425 [(set_attr "type" "imovx")
3426 (set_attr "mode" "SI")])
3427
3428 (define_insn "*extendqisi2_zext"
3429 [(set (match_operand:DI 0 "register_operand" "=r")
3430 (zero_extend:DI
3431 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3432 "TARGET_64BIT"
3433 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3434 [(set_attr "type" "imovx")
3435 (set_attr "mode" "SI")])
3436 \f
3437 ;; Conversions between float and double.
3438
3439 ;; These are all no-ops in the model used for the 80387. So just
3440 ;; emit moves.
3441
3442 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3443 (define_insn "*dummy_extendsfdf2"
3444 [(set (match_operand:DF 0 "push_operand" "=<")
3445 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3446 "0"
3447 "#")
3448
3449 (define_split
3450 [(set (match_operand:DF 0 "push_operand" "")
3451 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3452 "!TARGET_64BIT"
3453 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3454 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3455
3456 (define_split
3457 [(set (match_operand:DF 0 "push_operand" "")
3458 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3459 "TARGET_64BIT"
3460 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3461 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3462
3463 (define_insn "*dummy_extendsfxf2"
3464 [(set (match_operand:XF 0 "push_operand" "=<")
3465 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3466 "0"
3467 "#")
3468
3469 (define_split
3470 [(set (match_operand:XF 0 "push_operand" "")
3471 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3472 ""
3473 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3474 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3475 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3476
3477 (define_split
3478 [(set (match_operand:XF 0 "push_operand" "")
3479 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3480 "TARGET_64BIT"
3481 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3482 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3483 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3484
3485 (define_split
3486 [(set (match_operand:XF 0 "push_operand" "")
3487 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3488 ""
3489 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3490 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3491 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3492
3493 (define_split
3494 [(set (match_operand:XF 0 "push_operand" "")
3495 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3496 "TARGET_64BIT"
3497 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3498 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3499 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3500
3501 (define_expand "extendsfdf2"
3502 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3503 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3504 "TARGET_80387 || TARGET_SSE2"
3505 {
3506 /* ??? Needed for compress_float_constant since all fp constants
3507 are LEGITIMATE_CONSTANT_P. */
3508 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3509 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3510 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3511 operands[1] = force_reg (SFmode, operands[1]);
3512 })
3513
3514 (define_insn "*extendsfdf2_1"
3515 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3516 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3517 "(TARGET_80387 || TARGET_SSE2)
3518 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3519 {
3520 switch (which_alternative)
3521 {
3522 case 0:
3523 if (REG_P (operands[1])
3524 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3525 return "fstp\t%y0";
3526 else if (STACK_TOP_P (operands[0]))
3527 return "fld%z1\t%y1";
3528 else
3529 return "fst\t%y0";
3530
3531 case 1:
3532 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3533 return "fstp%z0\t%y0";
3534
3535 else
3536 return "fst%z0\t%y0";
3537 case 2:
3538 return "cvtss2sd\t{%1, %0|%0, %1}";
3539
3540 default:
3541 abort ();
3542 }
3543 }
3544 [(set_attr "type" "fmov,fmov,ssecvt")
3545 (set_attr "mode" "SF,XF,DF")])
3546
3547 (define_insn "*extendsfdf2_1_sse_only"
3548 [(set (match_operand:DF 0 "register_operand" "=Y")
3549 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3550 "!TARGET_80387 && TARGET_SSE2
3551 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3552 "cvtss2sd\t{%1, %0|%0, %1}"
3553 [(set_attr "type" "ssecvt")
3554 (set_attr "mode" "DF")])
3555
3556 (define_expand "extendsfxf2"
3557 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3558 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3559 "TARGET_80387"
3560 {
3561 /* ??? Needed for compress_float_constant since all fp constants
3562 are LEGITIMATE_CONSTANT_P. */
3563 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3564 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3565 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3566 operands[1] = force_reg (SFmode, operands[1]);
3567 })
3568
3569 (define_insn "*extendsfxf2_1"
3570 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3571 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3572 "TARGET_80387
3573 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3574 {
3575 switch (which_alternative)
3576 {
3577 case 0:
3578 if (REG_P (operands[1])
3579 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580 return "fstp\t%y0";
3581 else if (STACK_TOP_P (operands[0]))
3582 return "fld%z1\t%y1";
3583 else
3584 return "fst\t%y0";
3585
3586 case 1:
3587 /* There is no non-popping store to memory for XFmode. So if
3588 we need one, follow the store with a load. */
3589 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3590 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3591 else
3592 return "fstp%z0\t%y0";
3593
3594 default:
3595 abort ();
3596 }
3597 }
3598 [(set_attr "type" "fmov")
3599 (set_attr "mode" "SF,XF")])
3600
3601 (define_expand "extenddfxf2"
3602 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3603 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3604 "TARGET_80387"
3605 {
3606 /* ??? Needed for compress_float_constant since all fp constants
3607 are LEGITIMATE_CONSTANT_P. */
3608 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3609 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3610 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3611 operands[1] = force_reg (DFmode, operands[1]);
3612 })
3613
3614 (define_insn "*extenddfxf2_1"
3615 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3616 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3617 "TARGET_80387
3618 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3619 {
3620 switch (which_alternative)
3621 {
3622 case 0:
3623 if (REG_P (operands[1])
3624 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3625 return "fstp\t%y0";
3626 else if (STACK_TOP_P (operands[0]))
3627 return "fld%z1\t%y1";
3628 else
3629 return "fst\t%y0";
3630
3631 case 1:
3632 /* There is no non-popping store to memory for XFmode. So if
3633 we need one, follow the store with a load. */
3634 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3636 else
3637 return "fstp%z0\t%y0";
3638
3639 default:
3640 abort ();
3641 }
3642 }
3643 [(set_attr "type" "fmov")
3644 (set_attr "mode" "DF,XF")])
3645
3646 ;; %%% This seems bad bad news.
3647 ;; This cannot output into an f-reg because there is no way to be sure
3648 ;; of truncating in that case. Otherwise this is just like a simple move
3649 ;; insn. So we pretend we can output to a reg in order to get better
3650 ;; register preferencing, but we really use a stack slot.
3651
3652 (define_expand "truncdfsf2"
3653 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3654 (float_truncate:SF
3655 (match_operand:DF 1 "register_operand" "")))
3656 (clobber (match_dup 2))])]
3657 "TARGET_80387 || TARGET_SSE2"
3658 "
3659 if (TARGET_80387)
3660 operands[2] = assign_386_stack_local (SFmode, 0);
3661 else
3662 {
3663 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3664 DONE;
3665 }
3666 ")
3667
3668 (define_insn "*truncdfsf2_1"
3669 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3670 (float_truncate:SF
3671 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3672 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3673 "TARGET_80387 && !TARGET_SSE2"
3674 {
3675 switch (which_alternative)
3676 {
3677 case 0:
3678 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3679 return "fstp%z0\t%y0";
3680 else
3681 return "fst%z0\t%y0";
3682 default:
3683 abort ();
3684 }
3685 }
3686 [(set_attr "type" "fmov,multi,multi,multi")
3687 (set_attr "mode" "SF,SF,SF,SF")])
3688
3689 (define_insn "*truncdfsf2_1_sse"
3690 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3691 (float_truncate:SF
3692 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3693 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3694 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3695 {
3696 switch (which_alternative)
3697 {
3698 case 0:
3699 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3700 return "fstp%z0\t%y0";
3701 else
3702 return "fst%z0\t%y0";
3703 case 4:
3704 return "#";
3705 default:
3706 abort ();
3707 }
3708 }
3709 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3710 (set_attr "mode" "SF,SF,SF,SF,DF")])
3711
3712 (define_insn "*truncdfsf2_1_sse_nooverlap"
3713 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3714 (float_truncate:SF
3715 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3716 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3717 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3718 {
3719 switch (which_alternative)
3720 {
3721 case 0:
3722 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3723 return "fstp%z0\t%y0";
3724 else
3725 return "fst%z0\t%y0";
3726 case 4:
3727 return "#";
3728 default:
3729 abort ();
3730 }
3731 }
3732 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3733 (set_attr "mode" "SF,SF,SF,SF,DF")])
3734
3735 (define_insn "*truncdfsf2_2"
3736 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3737 (float_truncate:SF
3738 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3739 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3740 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3741 {
3742 switch (which_alternative)
3743 {
3744 case 0:
3745 case 1:
3746 return "cvtsd2ss\t{%1, %0|%0, %1}";
3747 case 2:
3748 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3749 return "fstp%z0\t%y0";
3750 else
3751 return "fst%z0\t%y0";
3752 default:
3753 abort ();
3754 }
3755 }
3756 [(set_attr "type" "ssecvt,ssecvt,fmov")
3757 (set_attr "athlon_decode" "vector,double,*")
3758 (set_attr "mode" "SF,SF,SF")])
3759
3760 (define_insn "*truncdfsf2_2_nooverlap"
3761 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3762 (float_truncate:SF
3763 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3764 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3765 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3766 {
3767 switch (which_alternative)
3768 {
3769 case 0:
3770 return "#";
3771 case 1:
3772 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3773 return "fstp%z0\t%y0";
3774 else
3775 return "fst%z0\t%y0";
3776 default:
3777 abort ();
3778 }
3779 }
3780 [(set_attr "type" "ssecvt,fmov")
3781 (set_attr "mode" "DF,SF")])
3782
3783 (define_insn "*truncdfsf2_3"
3784 [(set (match_operand:SF 0 "memory_operand" "=m")
3785 (float_truncate:SF
3786 (match_operand:DF 1 "register_operand" "f")))]
3787 "TARGET_80387"
3788 {
3789 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3790 return "fstp%z0\t%y0";
3791 else
3792 return "fst%z0\t%y0";
3793 }
3794 [(set_attr "type" "fmov")
3795 (set_attr "mode" "SF")])
3796
3797 (define_insn "truncdfsf2_sse_only"
3798 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3799 (float_truncate:SF
3800 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3801 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3802 "cvtsd2ss\t{%1, %0|%0, %1}"
3803 [(set_attr "type" "ssecvt")
3804 (set_attr "athlon_decode" "vector,double")
3805 (set_attr "mode" "SF")])
3806
3807 (define_insn "*truncdfsf2_sse_only_nooverlap"
3808 [(set (match_operand:SF 0 "register_operand" "=&Y")
3809 (float_truncate:SF
3810 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3811 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3812 "#"
3813 [(set_attr "type" "ssecvt")
3814 (set_attr "mode" "DF")])
3815
3816 (define_split
3817 [(set (match_operand:SF 0 "memory_operand" "")
3818 (float_truncate:SF
3819 (match_operand:DF 1 "register_operand" "")))
3820 (clobber (match_operand:SF 2 "memory_operand" ""))]
3821 "TARGET_80387"
3822 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3823 "")
3824
3825 ; Avoid possible reformatting penalty on the destination by first
3826 ; zeroing it out
3827 (define_split
3828 [(set (match_operand:SF 0 "register_operand" "")
3829 (float_truncate:SF
3830 (match_operand:DF 1 "nonimmediate_operand" "")))
3831 (clobber (match_operand 2 "" ""))]
3832 "TARGET_80387 && reload_completed
3833 && SSE_REG_P (operands[0])
3834 && !STACK_REG_P (operands[1])"
3835 [(const_int 0)]
3836 {
3837 rtx src, dest;
3838 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3839 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3840 else
3841 {
3842 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3843 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3844 /* simplify_gen_subreg refuses to widen memory references. */
3845 if (GET_CODE (src) == SUBREG)
3846 alter_subreg (&src);
3847 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3848 abort ();
3849 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3850 emit_insn (gen_cvtsd2ss (dest, dest, src));
3851 }
3852 DONE;
3853 })
3854
3855 (define_split
3856 [(set (match_operand:SF 0 "register_operand" "")
3857 (float_truncate:SF
3858 (match_operand:DF 1 "nonimmediate_operand" "")))]
3859 "TARGET_80387 && reload_completed
3860 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3861 [(const_int 0)]
3862 {
3863 rtx src, dest;
3864 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3865 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3866 /* simplify_gen_subreg refuses to widen memory references. */
3867 if (GET_CODE (src) == SUBREG)
3868 alter_subreg (&src);
3869 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3870 abort ();
3871 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3872 emit_insn (gen_cvtsd2ss (dest, dest, src));
3873 DONE;
3874 })
3875
3876 (define_split
3877 [(set (match_operand:SF 0 "register_operand" "")
3878 (float_truncate:SF
3879 (match_operand:DF 1 "fp_register_operand" "")))
3880 (clobber (match_operand:SF 2 "memory_operand" ""))]
3881 "TARGET_80387 && reload_completed"
3882 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3883 (set (match_dup 0) (match_dup 2))]
3884 "")
3885
3886 (define_expand "truncxfsf2"
3887 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3888 (float_truncate:SF
3889 (match_operand:XF 1 "register_operand" "")))
3890 (clobber (match_dup 2))])]
3891 "TARGET_80387"
3892 "operands[2] = assign_386_stack_local (SFmode, 0);")
3893
3894 (define_insn "*truncxfsf2_1"
3895 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3896 (float_truncate:SF
3897 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3898 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3899 "TARGET_80387"
3900 {
3901 switch (which_alternative)
3902 {
3903 case 0:
3904 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3905 return "fstp%z0\t%y0";
3906 else
3907 return "fst%z0\t%y0";
3908 default:
3909 abort();
3910 }
3911 }
3912 [(set_attr "type" "fmov,multi,multi,multi")
3913 (set_attr "mode" "SF")])
3914
3915 (define_insn "*truncxfsf2_2"
3916 [(set (match_operand:SF 0 "memory_operand" "=m")
3917 (float_truncate:SF
3918 (match_operand:XF 1 "register_operand" "f")))]
3919 "TARGET_80387"
3920 {
3921 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3922 return "fstp%z0\t%y0";
3923 else
3924 return "fst%z0\t%y0";
3925 }
3926 [(set_attr "type" "fmov")
3927 (set_attr "mode" "SF")])
3928
3929 (define_split
3930 [(set (match_operand:SF 0 "memory_operand" "")
3931 (float_truncate:SF
3932 (match_operand:XF 1 "register_operand" "")))
3933 (clobber (match_operand:SF 2 "memory_operand" ""))]
3934 "TARGET_80387"
3935 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3936 "")
3937
3938 (define_split
3939 [(set (match_operand:SF 0 "register_operand" "")
3940 (float_truncate:SF
3941 (match_operand:XF 1 "register_operand" "")))
3942 (clobber (match_operand:SF 2 "memory_operand" ""))]
3943 "TARGET_80387 && reload_completed"
3944 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3945 (set (match_dup 0) (match_dup 2))]
3946 "")
3947
3948 (define_expand "truncxfdf2"
3949 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3950 (float_truncate:DF
3951 (match_operand:XF 1 "register_operand" "")))
3952 (clobber (match_dup 2))])]
3953 "TARGET_80387"
3954 "operands[2] = assign_386_stack_local (DFmode, 0);")
3955
3956 (define_insn "*truncxfdf2_1"
3957 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3958 (float_truncate:DF
3959 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3960 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3961 "TARGET_80387"
3962 {
3963 switch (which_alternative)
3964 {
3965 case 0:
3966 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3967 return "fstp%z0\t%y0";
3968 else
3969 return "fst%z0\t%y0";
3970 default:
3971 abort();
3972 }
3973 abort ();
3974 }
3975 [(set_attr "type" "fmov,multi,multi,multi")
3976 (set_attr "mode" "DF")])
3977
3978 (define_insn "*truncxfdf2_2"
3979 [(set (match_operand:DF 0 "memory_operand" "=m")
3980 (float_truncate:DF
3981 (match_operand:XF 1 "register_operand" "f")))]
3982 "TARGET_80387"
3983 {
3984 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3985 return "fstp%z0\t%y0";
3986 else
3987 return "fst%z0\t%y0";
3988 }
3989 [(set_attr "type" "fmov")
3990 (set_attr "mode" "DF")])
3991
3992 (define_split
3993 [(set (match_operand:DF 0 "memory_operand" "")
3994 (float_truncate:DF
3995 (match_operand:XF 1 "register_operand" "")))
3996 (clobber (match_operand:DF 2 "memory_operand" ""))]
3997 "TARGET_80387"
3998 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3999 "")
4000
4001 (define_split
4002 [(set (match_operand:DF 0 "register_operand" "")
4003 (float_truncate:DF
4004 (match_operand:XF 1 "register_operand" "")))
4005 (clobber (match_operand:DF 2 "memory_operand" ""))]
4006 "TARGET_80387 && reload_completed"
4007 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4008 (set (match_dup 0) (match_dup 2))]
4009 "")
4010
4011 \f
4012 ;; %%% Break up all these bad boys.
4013
4014 ;; Signed conversion to DImode.
4015
4016 (define_expand "fix_truncxfdi2"
4017 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4018 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4019 "TARGET_80387"
4020 "")
4021
4022 (define_expand "fix_truncdfdi2"
4023 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4025 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4026 {
4027 if (TARGET_64BIT && TARGET_SSE2)
4028 {
4029 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4030 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4031 if (out != operands[0])
4032 emit_move_insn (operands[0], out);
4033 DONE;
4034 }
4035 })
4036
4037 (define_expand "fix_truncsfdi2"
4038 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4039 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4040 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4041 {
4042 if (TARGET_SSE && TARGET_64BIT)
4043 {
4044 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4045 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4046 if (out != operands[0])
4047 emit_move_insn (operands[0], out);
4048 DONE;
4049 }
4050 })
4051
4052 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4053 ;; of the machinery.
4054 (define_insn_and_split "*fix_truncdi_1"
4055 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4056 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4057 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4058 && !reload_completed && !reload_in_progress
4059 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4060 "#"
4061 "&& 1"
4062 [(const_int 0)]
4063 {
4064 ix86_optimize_mode_switching = 1;
4065 operands[2] = assign_386_stack_local (HImode, 1);
4066 operands[3] = assign_386_stack_local (HImode, 2);
4067 if (memory_operand (operands[0], VOIDmode))
4068 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4069 operands[2], operands[3]));
4070 else
4071 {
4072 operands[4] = assign_386_stack_local (DImode, 0);
4073 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4074 operands[2], operands[3],
4075 operands[4]));
4076 }
4077 DONE;
4078 }
4079 [(set_attr "type" "fistp")
4080 (set_attr "mode" "DI")])
4081
4082 (define_insn "fix_truncdi_nomemory"
4083 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4084 (fix:DI (match_operand 1 "register_operand" "f,f")))
4085 (use (match_operand:HI 2 "memory_operand" "m,m"))
4086 (use (match_operand:HI 3 "memory_operand" "m,m"))
4087 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4088 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4089 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4090 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4091 "#"
4092 [(set_attr "type" "fistp")
4093 (set_attr "mode" "DI")])
4094
4095 (define_insn "fix_truncdi_memory"
4096 [(set (match_operand:DI 0 "memory_operand" "=m")
4097 (fix:DI (match_operand 1 "register_operand" "f")))
4098 (use (match_operand:HI 2 "memory_operand" "m"))
4099 (use (match_operand:HI 3 "memory_operand" "m"))
4100 (clobber (match_scratch:DF 4 "=&1f"))]
4101 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4102 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4103 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4104 [(set_attr "type" "fistp")
4105 (set_attr "mode" "DI")])
4106
4107 (define_split
4108 [(set (match_operand:DI 0 "register_operand" "")
4109 (fix:DI (match_operand 1 "register_operand" "")))
4110 (use (match_operand:HI 2 "memory_operand" ""))
4111 (use (match_operand:HI 3 "memory_operand" ""))
4112 (clobber (match_operand:DI 4 "memory_operand" ""))
4113 (clobber (match_scratch 5 ""))]
4114 "reload_completed"
4115 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4116 (use (match_dup 2))
4117 (use (match_dup 3))
4118 (clobber (match_dup 5))])
4119 (set (match_dup 0) (match_dup 4))]
4120 "")
4121
4122 (define_split
4123 [(set (match_operand:DI 0 "memory_operand" "")
4124 (fix:DI (match_operand 1 "register_operand" "")))
4125 (use (match_operand:HI 2 "memory_operand" ""))
4126 (use (match_operand:HI 3 "memory_operand" ""))
4127 (clobber (match_operand:DI 4 "memory_operand" ""))
4128 (clobber (match_scratch 5 ""))]
4129 "reload_completed"
4130 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4131 (use (match_dup 2))
4132 (use (match_dup 3))
4133 (clobber (match_dup 5))])]
4134 "")
4135
4136 ;; When SSE available, it is always faster to use it!
4137 (define_insn "fix_truncsfdi_sse"
4138 [(set (match_operand:DI 0 "register_operand" "=r,r")
4139 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4140 "TARGET_64BIT && TARGET_SSE"
4141 "cvttss2si{q}\t{%1, %0|%0, %1}"
4142 [(set_attr "type" "sseicvt")
4143 (set_attr "mode" "SF")
4144 (set_attr "athlon_decode" "double,vector")])
4145
4146 ;; Avoid vector decoded form of the instruction.
4147 (define_peephole2
4148 [(match_scratch:SF 2 "x")
4149 (set (match_operand:DI 0 "register_operand" "")
4150 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4151 "TARGET_K8 && !optimize_size"
4152 [(set (match_dup 2) (match_dup 1))
4153 (set (match_dup 0) (fix:DI (match_dup 2)))]
4154 "")
4155
4156 (define_insn "fix_truncdfdi_sse"
4157 [(set (match_operand:DI 0 "register_operand" "=r,r")
4158 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4159 "TARGET_64BIT && TARGET_SSE2"
4160 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4161 [(set_attr "type" "sseicvt,sseicvt")
4162 (set_attr "mode" "DF")
4163 (set_attr "athlon_decode" "double,vector")])
4164
4165 ;; Avoid vector decoded form of the instruction.
4166 (define_peephole2
4167 [(match_scratch:DF 2 "Y")
4168 (set (match_operand:DI 0 "register_operand" "")
4169 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4170 "TARGET_K8 && !optimize_size"
4171 [(set (match_dup 2) (match_dup 1))
4172 (set (match_dup 0) (fix:DI (match_dup 2)))]
4173 "")
4174
4175 ;; Signed conversion to SImode.
4176
4177 (define_expand "fix_truncxfsi2"
4178 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4179 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4180 "TARGET_80387"
4181 "")
4182
4183 (define_expand "fix_truncdfsi2"
4184 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4185 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4186 "TARGET_80387 || TARGET_SSE2"
4187 {
4188 if (TARGET_SSE2)
4189 {
4190 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4191 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4192 if (out != operands[0])
4193 emit_move_insn (operands[0], out);
4194 DONE;
4195 }
4196 })
4197
4198 (define_expand "fix_truncsfsi2"
4199 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4200 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4201 "TARGET_80387 || TARGET_SSE"
4202 {
4203 if (TARGET_SSE)
4204 {
4205 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4206 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4207 if (out != operands[0])
4208 emit_move_insn (operands[0], out);
4209 DONE;
4210 }
4211 })
4212
4213 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4214 ;; of the machinery.
4215 (define_insn_and_split "*fix_truncsi_1"
4216 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4217 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4218 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4219 && !reload_completed && !reload_in_progress
4220 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4221 "#"
4222 "&& 1"
4223 [(const_int 0)]
4224 {
4225 ix86_optimize_mode_switching = 1;
4226 operands[2] = assign_386_stack_local (HImode, 1);
4227 operands[3] = assign_386_stack_local (HImode, 2);
4228 if (memory_operand (operands[0], VOIDmode))
4229 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4230 operands[2], operands[3]));
4231 else
4232 {
4233 operands[4] = assign_386_stack_local (SImode, 0);
4234 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4235 operands[2], operands[3],
4236 operands[4]));
4237 }
4238 DONE;
4239 }
4240 [(set_attr "type" "fistp")
4241 (set_attr "mode" "SI")])
4242
4243 (define_insn "fix_truncsi_nomemory"
4244 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4245 (fix:SI (match_operand 1 "register_operand" "f,f")))
4246 (use (match_operand:HI 2 "memory_operand" "m,m"))
4247 (use (match_operand:HI 3 "memory_operand" "m,m"))
4248 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4249 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4250 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4251 "#"
4252 [(set_attr "type" "fistp")
4253 (set_attr "mode" "SI")])
4254
4255 (define_insn "fix_truncsi_memory"
4256 [(set (match_operand:SI 0 "memory_operand" "=m")
4257 (fix:SI (match_operand 1 "register_operand" "f")))
4258 (use (match_operand:HI 2 "memory_operand" "m"))
4259 (use (match_operand:HI 3 "memory_operand" "m"))]
4260 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4261 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4262 "* return output_fix_trunc (insn, operands);"
4263 [(set_attr "type" "fistp")
4264 (set_attr "mode" "SI")])
4265
4266 ;; When SSE available, it is always faster to use it!
4267 (define_insn "fix_truncsfsi_sse"
4268 [(set (match_operand:SI 0 "register_operand" "=r,r")
4269 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4270 "TARGET_SSE"
4271 "cvttss2si\t{%1, %0|%0, %1}"
4272 [(set_attr "type" "sseicvt")
4273 (set_attr "mode" "DF")
4274 (set_attr "athlon_decode" "double,vector")])
4275
4276 ;; Avoid vector decoded form of the instruction.
4277 (define_peephole2
4278 [(match_scratch:SF 2 "x")
4279 (set (match_operand:SI 0 "register_operand" "")
4280 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4281 "TARGET_K8 && !optimize_size"
4282 [(set (match_dup 2) (match_dup 1))
4283 (set (match_dup 0) (fix:SI (match_dup 2)))]
4284 "")
4285
4286 (define_insn "fix_truncdfsi_sse"
4287 [(set (match_operand:SI 0 "register_operand" "=r,r")
4288 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4289 "TARGET_SSE2"
4290 "cvttsd2si\t{%1, %0|%0, %1}"
4291 [(set_attr "type" "sseicvt")
4292 (set_attr "mode" "DF")
4293 (set_attr "athlon_decode" "double,vector")])
4294
4295 ;; Avoid vector decoded form of the instruction.
4296 (define_peephole2
4297 [(match_scratch:DF 2 "Y")
4298 (set (match_operand:SI 0 "register_operand" "")
4299 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4300 "TARGET_K8 && !optimize_size"
4301 [(set (match_dup 2) (match_dup 1))
4302 (set (match_dup 0) (fix:SI (match_dup 2)))]
4303 "")
4304
4305 (define_split
4306 [(set (match_operand:SI 0 "register_operand" "")
4307 (fix:SI (match_operand 1 "register_operand" "")))
4308 (use (match_operand:HI 2 "memory_operand" ""))
4309 (use (match_operand:HI 3 "memory_operand" ""))
4310 (clobber (match_operand:SI 4 "memory_operand" ""))]
4311 "reload_completed"
4312 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4313 (use (match_dup 2))
4314 (use (match_dup 3))])
4315 (set (match_dup 0) (match_dup 4))]
4316 "")
4317
4318 (define_split
4319 [(set (match_operand:SI 0 "memory_operand" "")
4320 (fix:SI (match_operand 1 "register_operand" "")))
4321 (use (match_operand:HI 2 "memory_operand" ""))
4322 (use (match_operand:HI 3 "memory_operand" ""))
4323 (clobber (match_operand:SI 4 "memory_operand" ""))]
4324 "reload_completed"
4325 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4326 (use (match_dup 2))
4327 (use (match_dup 3))])]
4328 "")
4329
4330 ;; Signed conversion to HImode.
4331
4332 (define_expand "fix_truncxfhi2"
4333 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4334 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4335 "TARGET_80387"
4336 "")
4337
4338 (define_expand "fix_truncdfhi2"
4339 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4340 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4341 "TARGET_80387 && !TARGET_SSE2"
4342 "")
4343
4344 (define_expand "fix_truncsfhi2"
4345 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4346 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4347 "TARGET_80387 && !TARGET_SSE"
4348 "")
4349
4350 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4351 ;; of the machinery.
4352 (define_insn_and_split "*fix_trunchi_1"
4353 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4354 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4355 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4356 && !reload_completed && !reload_in_progress
4357 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4358 "#"
4359 ""
4360 [(const_int 0)]
4361 {
4362 ix86_optimize_mode_switching = 1;
4363 operands[2] = assign_386_stack_local (HImode, 1);
4364 operands[3] = assign_386_stack_local (HImode, 2);
4365 if (memory_operand (operands[0], VOIDmode))
4366 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4367 operands[2], operands[3]));
4368 else
4369 {
4370 operands[4] = assign_386_stack_local (HImode, 0);
4371 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4372 operands[2], operands[3],
4373 operands[4]));
4374 }
4375 DONE;
4376 }
4377 [(set_attr "type" "fistp")
4378 (set_attr "mode" "HI")])
4379
4380 (define_insn "fix_trunchi_nomemory"
4381 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4382 (fix:HI (match_operand 1 "register_operand" "f,f")))
4383 (use (match_operand:HI 2 "memory_operand" "m,m"))
4384 (use (match_operand:HI 3 "memory_operand" "m,m"))
4385 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4386 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388 "#"
4389 [(set_attr "type" "fistp")
4390 (set_attr "mode" "HI")])
4391
4392 (define_insn "fix_trunchi_memory"
4393 [(set (match_operand:HI 0 "memory_operand" "=m")
4394 (fix:HI (match_operand 1 "register_operand" "f")))
4395 (use (match_operand:HI 2 "memory_operand" "m"))
4396 (use (match_operand:HI 3 "memory_operand" "m"))]
4397 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4398 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4399 "* return output_fix_trunc (insn, operands);"
4400 [(set_attr "type" "fistp")
4401 (set_attr "mode" "HI")])
4402
4403 (define_split
4404 [(set (match_operand:HI 0 "memory_operand" "")
4405 (fix:HI (match_operand 1 "register_operand" "")))
4406 (use (match_operand:HI 2 "memory_operand" ""))
4407 (use (match_operand:HI 3 "memory_operand" ""))
4408 (clobber (match_operand:HI 4 "memory_operand" ""))]
4409 "reload_completed"
4410 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4411 (use (match_dup 2))
4412 (use (match_dup 3))])]
4413 "")
4414
4415 (define_split
4416 [(set (match_operand:HI 0 "register_operand" "")
4417 (fix:HI (match_operand 1 "register_operand" "")))
4418 (use (match_operand:HI 2 "memory_operand" ""))
4419 (use (match_operand:HI 3 "memory_operand" ""))
4420 (clobber (match_operand:HI 4 "memory_operand" ""))]
4421 "reload_completed"
4422 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4423 (use (match_dup 2))
4424 (use (match_dup 3))
4425 (clobber (match_dup 4))])
4426 (set (match_dup 0) (match_dup 4))]
4427 "")
4428
4429 ;; %% Not used yet.
4430 (define_insn "x86_fnstcw_1"
4431 [(set (match_operand:HI 0 "memory_operand" "=m")
4432 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4433 "TARGET_80387"
4434 "fnstcw\t%0"
4435 [(set_attr "length" "2")
4436 (set_attr "mode" "HI")
4437 (set_attr "unit" "i387")
4438 (set_attr "ppro_uops" "few")])
4439
4440 (define_insn "x86_fldcw_1"
4441 [(set (reg:HI 18)
4442 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4443 "TARGET_80387"
4444 "fldcw\t%0"
4445 [(set_attr "length" "2")
4446 (set_attr "mode" "HI")
4447 (set_attr "unit" "i387")
4448 (set_attr "athlon_decode" "vector")
4449 (set_attr "ppro_uops" "few")])
4450 \f
4451 ;; Conversion between fixed point and floating point.
4452
4453 ;; Even though we only accept memory inputs, the backend _really_
4454 ;; wants to be able to do this between registers.
4455
4456 (define_expand "floathisf2"
4457 [(set (match_operand:SF 0 "register_operand" "")
4458 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4459 "TARGET_SSE || TARGET_80387"
4460 {
4461 if (TARGET_SSE && TARGET_SSE_MATH)
4462 {
4463 emit_insn (gen_floatsisf2 (operands[0],
4464 convert_to_mode (SImode, operands[1], 0)));
4465 DONE;
4466 }
4467 })
4468
4469 (define_insn "*floathisf2_1"
4470 [(set (match_operand:SF 0 "register_operand" "=f,f")
4471 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4472 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4473 "@
4474 fild%z1\t%1
4475 #"
4476 [(set_attr "type" "fmov,multi")
4477 (set_attr "mode" "SF")
4478 (set_attr "fp_int_src" "true")])
4479
4480 (define_expand "floatsisf2"
4481 [(set (match_operand:SF 0 "register_operand" "")
4482 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4483 "TARGET_SSE || TARGET_80387"
4484 "")
4485
4486 (define_insn "*floatsisf2_i387"
4487 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4488 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4489 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4490 "@
4491 fild%z1\t%1
4492 #
4493 cvtsi2ss\t{%1, %0|%0, %1}
4494 cvtsi2ss\t{%1, %0|%0, %1}"
4495 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4496 (set_attr "mode" "SF")
4497 (set_attr "athlon_decode" "*,*,vector,double")
4498 (set_attr "fp_int_src" "true")])
4499
4500 (define_insn "*floatsisf2_sse"
4501 [(set (match_operand:SF 0 "register_operand" "=x,x")
4502 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4503 "TARGET_SSE"
4504 "cvtsi2ss\t{%1, %0|%0, %1}"
4505 [(set_attr "type" "sseicvt")
4506 (set_attr "mode" "SF")
4507 (set_attr "athlon_decode" "vector,double")
4508 (set_attr "fp_int_src" "true")])
4509
4510 ; Avoid possible reformatting penalty on the destination by first
4511 ; zeroing it out
4512 (define_split
4513 [(set (match_operand:SF 0 "register_operand" "")
4514 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4515 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4516 && SSE_REG_P (operands[0])"
4517 [(const_int 0)]
4518 {
4519 rtx dest;
4520 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4521 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4522 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4523 DONE;
4524 })
4525
4526 (define_expand "floatdisf2"
4527 [(set (match_operand:SF 0 "register_operand" "")
4528 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4529 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4530 "")
4531
4532 (define_insn "*floatdisf2_i387_only"
4533 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4534 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4535 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4536 "@
4537 fild%z1\t%1
4538 #"
4539 [(set_attr "type" "fmov,multi")
4540 (set_attr "mode" "SF")
4541 (set_attr "fp_int_src" "true")])
4542
4543 (define_insn "*floatdisf2_i387"
4544 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4545 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4546 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4547 "@
4548 fild%z1\t%1
4549 #
4550 cvtsi2ss{q}\t{%1, %0|%0, %1}
4551 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4552 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4553 (set_attr "mode" "SF")
4554 (set_attr "athlon_decode" "*,*,vector,double")
4555 (set_attr "fp_int_src" "true")])
4556
4557 (define_insn "*floatdisf2_sse"
4558 [(set (match_operand:SF 0 "register_operand" "=x,x")
4559 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4560 "TARGET_64BIT && TARGET_SSE"
4561 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562 [(set_attr "type" "sseicvt")
4563 (set_attr "mode" "SF")
4564 (set_attr "athlon_decode" "vector,double")
4565 (set_attr "fp_int_src" "true")])
4566
4567 ; Avoid possible reformatting penalty on the destination by first
4568 ; zeroing it out
4569 (define_split
4570 [(set (match_operand:SF 0 "register_operand" "")
4571 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4572 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4573 && SSE_REG_P (operands[0])"
4574 [(const_int 0)]
4575 {
4576 rtx dest;
4577 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4578 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4579 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4580 DONE;
4581 })
4582
4583 (define_expand "floathidf2"
4584 [(set (match_operand:DF 0 "register_operand" "")
4585 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4586 "TARGET_SSE2 || TARGET_80387"
4587 {
4588 if (TARGET_SSE && TARGET_SSE_MATH)
4589 {
4590 emit_insn (gen_floatsidf2 (operands[0],
4591 convert_to_mode (SImode, operands[1], 0)));
4592 DONE;
4593 }
4594 })
4595
4596 (define_insn "*floathidf2_1"
4597 [(set (match_operand:DF 0 "register_operand" "=f,f")
4598 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4599 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4600 "@
4601 fild%z1\t%1
4602 #"
4603 [(set_attr "type" "fmov,multi")
4604 (set_attr "mode" "DF")
4605 (set_attr "fp_int_src" "true")])
4606
4607 (define_expand "floatsidf2"
4608 [(set (match_operand:DF 0 "register_operand" "")
4609 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4610 "TARGET_80387 || TARGET_SSE2"
4611 "")
4612
4613 (define_insn "*floatsidf2_i387"
4614 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4615 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4616 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4617 "@
4618 fild%z1\t%1
4619 #
4620 cvtsi2sd\t{%1, %0|%0, %1}
4621 cvtsi2sd\t{%1, %0|%0, %1}"
4622 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4623 (set_attr "mode" "DF")
4624 (set_attr "athlon_decode" "*,*,double,direct")
4625 (set_attr "fp_int_src" "true")])
4626
4627 (define_insn "*floatsidf2_sse"
4628 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4629 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4630 "TARGET_SSE2"
4631 "cvtsi2sd\t{%1, %0|%0, %1}"
4632 [(set_attr "type" "sseicvt")
4633 (set_attr "mode" "DF")
4634 (set_attr "athlon_decode" "double,direct")
4635 (set_attr "fp_int_src" "true")])
4636
4637 (define_expand "floatdidf2"
4638 [(set (match_operand:DF 0 "register_operand" "")
4639 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4640 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4641 "")
4642
4643 (define_insn "*floatdidf2_i387_only"
4644 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4645 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4646 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4647 "@
4648 fild%z1\t%1
4649 #"
4650 [(set_attr "type" "fmov,multi")
4651 (set_attr "mode" "DF")
4652 (set_attr "fp_int_src" "true")])
4653
4654 (define_insn "*floatdidf2_i387"
4655 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4656 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4657 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4658 "@
4659 fild%z1\t%1
4660 #
4661 cvtsi2sd{q}\t{%1, %0|%0, %1}
4662 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4663 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4664 (set_attr "mode" "DF")
4665 (set_attr "athlon_decode" "*,*,double,direct")
4666 (set_attr "fp_int_src" "true")])
4667
4668 (define_insn "*floatdidf2_sse"
4669 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4670 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4671 "TARGET_SSE2"
4672 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "sseicvt")
4674 (set_attr "mode" "DF")
4675 (set_attr "athlon_decode" "double,direct")
4676 (set_attr "fp_int_src" "true")])
4677
4678 (define_insn "floathixf2"
4679 [(set (match_operand:XF 0 "register_operand" "=f,f")
4680 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4681 "TARGET_80387"
4682 "@
4683 fild%z1\t%1
4684 #"
4685 [(set_attr "type" "fmov,multi")
4686 (set_attr "mode" "XF")
4687 (set_attr "fp_int_src" "true")])
4688
4689 (define_insn "floatsixf2"
4690 [(set (match_operand:XF 0 "register_operand" "=f,f")
4691 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4692 "TARGET_80387"
4693 "@
4694 fild%z1\t%1
4695 #"
4696 [(set_attr "type" "fmov,multi")
4697 (set_attr "mode" "XF")
4698 (set_attr "fp_int_src" "true")])
4699
4700 (define_insn "floatdixf2"
4701 [(set (match_operand:XF 0 "register_operand" "=f,f")
4702 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4703 "TARGET_80387"
4704 "@
4705 fild%z1\t%1
4706 #"
4707 [(set_attr "type" "fmov,multi")
4708 (set_attr "mode" "XF")
4709 (set_attr "fp_int_src" "true")])
4710
4711 ;; %%% Kill these when reload knows how to do it.
4712 (define_split
4713 [(set (match_operand 0 "fp_register_operand" "")
4714 (float (match_operand 1 "register_operand" "")))]
4715 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4716 [(const_int 0)]
4717 {
4718 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4719 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4720 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4721 ix86_free_from_memory (GET_MODE (operands[1]));
4722 DONE;
4723 })
4724
4725 (define_expand "floatunssisf2"
4726 [(use (match_operand:SF 0 "register_operand" ""))
4727 (use (match_operand:SI 1 "register_operand" ""))]
4728 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4729 "x86_emit_floatuns (operands); DONE;")
4730
4731 (define_expand "floatunsdisf2"
4732 [(use (match_operand:SF 0 "register_operand" ""))
4733 (use (match_operand:DI 1 "register_operand" ""))]
4734 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4735 "x86_emit_floatuns (operands); DONE;")
4736
4737 (define_expand "floatunsdidf2"
4738 [(use (match_operand:DF 0 "register_operand" ""))
4739 (use (match_operand:DI 1 "register_operand" ""))]
4740 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4741 "x86_emit_floatuns (operands); DONE;")
4742 \f
4743 ;; SSE extract/set expanders
4744
4745 (define_expand "vec_setv2df"
4746 [(match_operand:V2DF 0 "register_operand" "")
4747 (match_operand:DF 1 "register_operand" "")
4748 (match_operand 2 "const_int_operand" "")]
4749 "TARGET_SSE2"
4750 {
4751 switch (INTVAL (operands[2]))
4752 {
4753 case 0:
4754 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4755 simplify_gen_subreg (V2DFmode, operands[1],
4756 DFmode, 0)));
4757 break;
4758 case 1:
4759 {
4760 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4761
4762 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4763 }
4764 break;
4765 default:
4766 abort ();
4767 }
4768 DONE;
4769 })
4770
4771 (define_expand "vec_extractv2df"
4772 [(match_operand:DF 0 "register_operand" "")
4773 (match_operand:V2DF 1 "register_operand" "")
4774 (match_operand 2 "const_int_operand" "")]
4775 "TARGET_SSE2"
4776 {
4777 switch (INTVAL (operands[2]))
4778 {
4779 case 0:
4780 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4781 break;
4782 case 1:
4783 {
4784 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4785
4786 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4787 }
4788 break;
4789 default:
4790 abort ();
4791 }
4792 DONE;
4793 })
4794
4795 (define_expand "vec_initv2df"
4796 [(match_operand:V2DF 0 "register_operand" "")
4797 (match_operand 1 "" "")]
4798 "TARGET_SSE2"
4799 {
4800 ix86_expand_vector_init (operands[0], operands[1]);
4801 DONE;
4802 })
4803
4804 (define_expand "vec_setv4sf"
4805 [(match_operand:V4SF 0 "register_operand" "")
4806 (match_operand:SF 1 "register_operand" "")
4807 (match_operand 2 "const_int_operand" "")]
4808 "TARGET_SSE"
4809 {
4810 switch (INTVAL (operands[2]))
4811 {
4812 case 0:
4813 emit_insn (gen_sse_movss (operands[0], operands[0],
4814 simplify_gen_subreg (V4SFmode, operands[1],
4815 SFmode, 0)));
4816 break;
4817 case 1:
4818 {
4819 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4820 rtx tmp = gen_reg_rtx (V4SFmode);
4821
4822 emit_move_insn (tmp, operands[0]);
4823 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4824 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4825 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4826 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4827 }
4828 case 2:
4829 {
4830 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4831 rtx tmp = gen_reg_rtx (V4SFmode);
4832
4833 emit_move_insn (tmp, operands[0]);
4834 emit_insn (gen_sse_movss (tmp, tmp, op1));
4835 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4837 }
4838 break;
4839 case 3:
4840 {
4841 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4842 rtx tmp = gen_reg_rtx (V4SFmode);
4843
4844 emit_move_insn (tmp, operands[0]);
4845 emit_insn (gen_sse_movss (tmp, tmp, op1));
4846 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4847 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4848 }
4849 break;
4850 default:
4851 abort ();
4852 }
4853 DONE;
4854 })
4855
4856 (define_expand "vec_extractv4sf"
4857 [(match_operand:SF 0 "register_operand" "")
4858 (match_operand:V4SF 1 "register_operand" "")
4859 (match_operand 2 "const_int_operand" "")]
4860 "TARGET_SSE"
4861 {
4862 switch (INTVAL (operands[2]))
4863 {
4864 case 0:
4865 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4866 break;
4867 case 1:
4868 {
4869 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4870 rtx tmp = gen_reg_rtx (V4SFmode);
4871
4872 emit_move_insn (tmp, operands[1]);
4873 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4874 GEN_INT (1)));
4875 }
4876 case 2:
4877 {
4878 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4879 rtx tmp = gen_reg_rtx (V4SFmode);
4880
4881 emit_move_insn (tmp, operands[1]);
4882 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4883 }
4884 case 3:
4885 {
4886 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4887 rtx tmp = gen_reg_rtx (V4SFmode);
4888
4889 emit_move_insn (tmp, operands[1]);
4890 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4891 GEN_INT (3)));
4892 }
4893 default:
4894 abort ();
4895 }
4896 DONE;
4897 })
4898
4899 (define_expand "vec_initv4sf"
4900 [(match_operand:V4SF 0 "register_operand" "")
4901 (match_operand 1 "" "")]
4902 "TARGET_SSE"
4903 {
4904 ix86_expand_vector_init (operands[0], operands[1]);
4905 DONE;
4906 })
4907 \f
4908 ;; Add instructions
4909
4910 ;; %%% splits for addsidi3
4911 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4912 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4913 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4914
4915 (define_expand "adddi3"
4916 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4917 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4918 (match_operand:DI 2 "x86_64_general_operand" "")))
4919 (clobber (reg:CC 17))]
4920 ""
4921 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4922
4923 (define_insn "*adddi3_1"
4924 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4925 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4926 (match_operand:DI 2 "general_operand" "roiF,riF")))
4927 (clobber (reg:CC 17))]
4928 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4929 "#")
4930
4931 (define_split
4932 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4933 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4934 (match_operand:DI 2 "general_operand" "")))
4935 (clobber (reg:CC 17))]
4936 "!TARGET_64BIT && reload_completed"
4937 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4938 UNSPEC_ADD_CARRY))
4939 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4940 (parallel [(set (match_dup 3)
4941 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4942 (match_dup 4))
4943 (match_dup 5)))
4944 (clobber (reg:CC 17))])]
4945 "split_di (operands+0, 1, operands+0, operands+3);
4946 split_di (operands+1, 1, operands+1, operands+4);
4947 split_di (operands+2, 1, operands+2, operands+5);")
4948
4949 (define_insn "adddi3_carry_rex64"
4950 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4951 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4952 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4953 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4954 (clobber (reg:CC 17))]
4955 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4956 "adc{q}\t{%2, %0|%0, %2}"
4957 [(set_attr "type" "alu")
4958 (set_attr "pent_pair" "pu")
4959 (set_attr "mode" "DI")
4960 (set_attr "ppro_uops" "few")])
4961
4962 (define_insn "*adddi3_cc_rex64"
4963 [(set (reg:CC 17)
4964 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4965 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4966 UNSPEC_ADD_CARRY))
4967 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4968 (plus:DI (match_dup 1) (match_dup 2)))]
4969 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4970 "add{q}\t{%2, %0|%0, %2}"
4971 [(set_attr "type" "alu")
4972 (set_attr "mode" "DI")])
4973
4974 (define_insn "addqi3_carry"
4975 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4976 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4977 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4978 (match_operand:QI 2 "general_operand" "qi,qm")))
4979 (clobber (reg:CC 17))]
4980 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4981 "adc{b}\t{%2, %0|%0, %2}"
4982 [(set_attr "type" "alu")
4983 (set_attr "pent_pair" "pu")
4984 (set_attr "mode" "QI")
4985 (set_attr "ppro_uops" "few")])
4986
4987 (define_insn "addhi3_carry"
4988 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4989 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4990 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4991 (match_operand:HI 2 "general_operand" "ri,rm")))
4992 (clobber (reg:CC 17))]
4993 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4994 "adc{w}\t{%2, %0|%0, %2}"
4995 [(set_attr "type" "alu")
4996 (set_attr "pent_pair" "pu")
4997 (set_attr "mode" "HI")
4998 (set_attr "ppro_uops" "few")])
4999
5000 (define_insn "addsi3_carry"
5001 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5002 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5003 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5004 (match_operand:SI 2 "general_operand" "ri,rm")))
5005 (clobber (reg:CC 17))]
5006 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5007 "adc{l}\t{%2, %0|%0, %2}"
5008 [(set_attr "type" "alu")
5009 (set_attr "pent_pair" "pu")
5010 (set_attr "mode" "SI")
5011 (set_attr "ppro_uops" "few")])
5012
5013 (define_insn "*addsi3_carry_zext"
5014 [(set (match_operand:DI 0 "register_operand" "=r")
5015 (zero_extend:DI
5016 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5017 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5018 (match_operand:SI 2 "general_operand" "rim"))))
5019 (clobber (reg:CC 17))]
5020 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5021 "adc{l}\t{%2, %k0|%k0, %2}"
5022 [(set_attr "type" "alu")
5023 (set_attr "pent_pair" "pu")
5024 (set_attr "mode" "SI")
5025 (set_attr "ppro_uops" "few")])
5026
5027 (define_insn "*addsi3_cc"
5028 [(set (reg:CC 17)
5029 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5030 (match_operand:SI 2 "general_operand" "ri,rm")]
5031 UNSPEC_ADD_CARRY))
5032 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5033 (plus:SI (match_dup 1) (match_dup 2)))]
5034 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5035 "add{l}\t{%2, %0|%0, %2}"
5036 [(set_attr "type" "alu")
5037 (set_attr "mode" "SI")])
5038
5039 (define_insn "addqi3_cc"
5040 [(set (reg:CC 17)
5041 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5042 (match_operand:QI 2 "general_operand" "qi,qm")]
5043 UNSPEC_ADD_CARRY))
5044 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5045 (plus:QI (match_dup 1) (match_dup 2)))]
5046 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5047 "add{b}\t{%2, %0|%0, %2}"
5048 [(set_attr "type" "alu")
5049 (set_attr "mode" "QI")])
5050
5051 (define_expand "addsi3"
5052 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5053 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5054 (match_operand:SI 2 "general_operand" "")))
5055 (clobber (reg:CC 17))])]
5056 ""
5057 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5058
5059 (define_insn "*lea_1"
5060 [(set (match_operand:SI 0 "register_operand" "=r")
5061 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5062 "!TARGET_64BIT"
5063 "lea{l}\t{%a1, %0|%0, %a1}"
5064 [(set_attr "type" "lea")
5065 (set_attr "mode" "SI")])
5066
5067 (define_insn "*lea_1_rex64"
5068 [(set (match_operand:SI 0 "register_operand" "=r")
5069 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5070 "TARGET_64BIT"
5071 "lea{l}\t{%a1, %0|%0, %a1}"
5072 [(set_attr "type" "lea")
5073 (set_attr "mode" "SI")])
5074
5075 (define_insn "*lea_1_zext"
5076 [(set (match_operand:DI 0 "register_operand" "=r")
5077 (zero_extend:DI
5078 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5079 "TARGET_64BIT"
5080 "lea{l}\t{%a1, %k0|%k0, %a1}"
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "SI")])
5083
5084 (define_insn "*lea_2_rex64"
5085 [(set (match_operand:DI 0 "register_operand" "=r")
5086 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5087 "TARGET_64BIT"
5088 "lea{q}\t{%a1, %0|%0, %a1}"
5089 [(set_attr "type" "lea")
5090 (set_attr "mode" "DI")])
5091
5092 ;; The lea patterns for non-Pmodes needs to be matched by several
5093 ;; insns converted to real lea by splitters.
5094
5095 (define_insn_and_split "*lea_general_1"
5096 [(set (match_operand 0 "register_operand" "=r")
5097 (plus (plus (match_operand 1 "index_register_operand" "r")
5098 (match_operand 2 "register_operand" "r"))
5099 (match_operand 3 "immediate_operand" "i")))]
5100 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5101 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5102 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5103 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5104 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5105 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5106 || GET_MODE (operands[3]) == VOIDmode)"
5107 "#"
5108 "&& reload_completed"
5109 [(const_int 0)]
5110 {
5111 rtx pat;
5112 operands[0] = gen_lowpart (SImode, operands[0]);
5113 operands[1] = gen_lowpart (Pmode, operands[1]);
5114 operands[2] = gen_lowpart (Pmode, operands[2]);
5115 operands[3] = gen_lowpart (Pmode, operands[3]);
5116 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5117 operands[3]);
5118 if (Pmode != SImode)
5119 pat = gen_rtx_SUBREG (SImode, pat, 0);
5120 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5121 DONE;
5122 }
5123 [(set_attr "type" "lea")
5124 (set_attr "mode" "SI")])
5125
5126 (define_insn_and_split "*lea_general_1_zext"
5127 [(set (match_operand:DI 0 "register_operand" "=r")
5128 (zero_extend:DI
5129 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5130 (match_operand:SI 2 "register_operand" "r"))
5131 (match_operand:SI 3 "immediate_operand" "i"))))]
5132 "TARGET_64BIT"
5133 "#"
5134 "&& reload_completed"
5135 [(set (match_dup 0)
5136 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5137 (match_dup 2))
5138 (match_dup 3)) 0)))]
5139 {
5140 operands[1] = gen_lowpart (Pmode, operands[1]);
5141 operands[2] = gen_lowpart (Pmode, operands[2]);
5142 operands[3] = gen_lowpart (Pmode, operands[3]);
5143 }
5144 [(set_attr "type" "lea")
5145 (set_attr "mode" "SI")])
5146
5147 (define_insn_and_split "*lea_general_2"
5148 [(set (match_operand 0 "register_operand" "=r")
5149 (plus (mult (match_operand 1 "index_register_operand" "r")
5150 (match_operand 2 "const248_operand" "i"))
5151 (match_operand 3 "nonmemory_operand" "ri")))]
5152 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5153 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5154 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5155 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5156 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5157 || GET_MODE (operands[3]) == VOIDmode)"
5158 "#"
5159 "&& reload_completed"
5160 [(const_int 0)]
5161 {
5162 rtx pat;
5163 operands[0] = gen_lowpart (SImode, operands[0]);
5164 operands[1] = gen_lowpart (Pmode, operands[1]);
5165 operands[3] = gen_lowpart (Pmode, operands[3]);
5166 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5167 operands[3]);
5168 if (Pmode != SImode)
5169 pat = gen_rtx_SUBREG (SImode, pat, 0);
5170 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5171 DONE;
5172 }
5173 [(set_attr "type" "lea")
5174 (set_attr "mode" "SI")])
5175
5176 (define_insn_and_split "*lea_general_2_zext"
5177 [(set (match_operand:DI 0 "register_operand" "=r")
5178 (zero_extend:DI
5179 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5180 (match_operand:SI 2 "const248_operand" "n"))
5181 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5182 "TARGET_64BIT"
5183 "#"
5184 "&& reload_completed"
5185 [(set (match_dup 0)
5186 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5187 (match_dup 2))
5188 (match_dup 3)) 0)))]
5189 {
5190 operands[1] = gen_lowpart (Pmode, operands[1]);
5191 operands[3] = gen_lowpart (Pmode, operands[3]);
5192 }
5193 [(set_attr "type" "lea")
5194 (set_attr "mode" "SI")])
5195
5196 (define_insn_and_split "*lea_general_3"
5197 [(set (match_operand 0 "register_operand" "=r")
5198 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5199 (match_operand 2 "const248_operand" "i"))
5200 (match_operand 3 "register_operand" "r"))
5201 (match_operand 4 "immediate_operand" "i")))]
5202 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5203 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5204 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5205 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5206 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5207 "#"
5208 "&& reload_completed"
5209 [(const_int 0)]
5210 {
5211 rtx pat;
5212 operands[0] = gen_lowpart (SImode, operands[0]);
5213 operands[1] = gen_lowpart (Pmode, operands[1]);
5214 operands[3] = gen_lowpart (Pmode, operands[3]);
5215 operands[4] = gen_lowpart (Pmode, operands[4]);
5216 pat = gen_rtx_PLUS (Pmode,
5217 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5218 operands[2]),
5219 operands[3]),
5220 operands[4]);
5221 if (Pmode != SImode)
5222 pat = gen_rtx_SUBREG (SImode, pat, 0);
5223 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5224 DONE;
5225 }
5226 [(set_attr "type" "lea")
5227 (set_attr "mode" "SI")])
5228
5229 (define_insn_and_split "*lea_general_3_zext"
5230 [(set (match_operand:DI 0 "register_operand" "=r")
5231 (zero_extend:DI
5232 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5233 (match_operand:SI 2 "const248_operand" "n"))
5234 (match_operand:SI 3 "register_operand" "r"))
5235 (match_operand:SI 4 "immediate_operand" "i"))))]
5236 "TARGET_64BIT"
5237 "#"
5238 "&& reload_completed"
5239 [(set (match_dup 0)
5240 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5241 (match_dup 2))
5242 (match_dup 3))
5243 (match_dup 4)) 0)))]
5244 {
5245 operands[1] = gen_lowpart (Pmode, operands[1]);
5246 operands[3] = gen_lowpart (Pmode, operands[3]);
5247 operands[4] = gen_lowpart (Pmode, operands[4]);
5248 }
5249 [(set_attr "type" "lea")
5250 (set_attr "mode" "SI")])
5251
5252 (define_insn "*adddi_1_rex64"
5253 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5254 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5255 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5256 (clobber (reg:CC 17))]
5257 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5258 {
5259 switch (get_attr_type (insn))
5260 {
5261 case TYPE_LEA:
5262 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5263 return "lea{q}\t{%a2, %0|%0, %a2}";
5264
5265 case TYPE_INCDEC:
5266 if (! rtx_equal_p (operands[0], operands[1]))
5267 abort ();
5268 if (operands[2] == const1_rtx)
5269 return "inc{q}\t%0";
5270 else if (operands[2] == constm1_rtx)
5271 return "dec{q}\t%0";
5272 else
5273 abort ();
5274
5275 default:
5276 if (! rtx_equal_p (operands[0], operands[1]))
5277 abort ();
5278
5279 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5280 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5281 if (GET_CODE (operands[2]) == CONST_INT
5282 /* Avoid overflows. */
5283 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5284 && (INTVAL (operands[2]) == 128
5285 || (INTVAL (operands[2]) < 0
5286 && INTVAL (operands[2]) != -128)))
5287 {
5288 operands[2] = GEN_INT (-INTVAL (operands[2]));
5289 return "sub{q}\t{%2, %0|%0, %2}";
5290 }
5291 return "add{q}\t{%2, %0|%0, %2}";
5292 }
5293 }
5294 [(set (attr "type")
5295 (cond [(eq_attr "alternative" "2")
5296 (const_string "lea")
5297 ; Current assemblers are broken and do not allow @GOTOFF in
5298 ; ought but a memory context.
5299 (match_operand:DI 2 "pic_symbolic_operand" "")
5300 (const_string "lea")
5301 (match_operand:DI 2 "incdec_operand" "")
5302 (const_string "incdec")
5303 ]
5304 (const_string "alu")))
5305 (set_attr "mode" "DI")])
5306
5307 ;; Convert lea to the lea pattern to avoid flags dependency.
5308 (define_split
5309 [(set (match_operand:DI 0 "register_operand" "")
5310 (plus:DI (match_operand:DI 1 "register_operand" "")
5311 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5312 (clobber (reg:CC 17))]
5313 "TARGET_64BIT && reload_completed
5314 && true_regnum (operands[0]) != true_regnum (operands[1])"
5315 [(set (match_dup 0)
5316 (plus:DI (match_dup 1)
5317 (match_dup 2)))]
5318 "")
5319
5320 (define_insn "*adddi_2_rex64"
5321 [(set (reg 17)
5322 (compare
5323 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5324 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5325 (const_int 0)))
5326 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5327 (plus:DI (match_dup 1) (match_dup 2)))]
5328 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5329 && ix86_binary_operator_ok (PLUS, DImode, operands)
5330 /* Current assemblers are broken and do not allow @GOTOFF in
5331 ought but a memory context. */
5332 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5333 {
5334 switch (get_attr_type (insn))
5335 {
5336 case TYPE_INCDEC:
5337 if (! rtx_equal_p (operands[0], operands[1]))
5338 abort ();
5339 if (operands[2] == const1_rtx)
5340 return "inc{q}\t%0";
5341 else if (operands[2] == constm1_rtx)
5342 return "dec{q}\t%0";
5343 else
5344 abort ();
5345
5346 default:
5347 if (! rtx_equal_p (operands[0], operands[1]))
5348 abort ();
5349 /* ???? We ought to handle there the 32bit case too
5350 - do we need new constraint? */
5351 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5352 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5353 if (GET_CODE (operands[2]) == CONST_INT
5354 /* Avoid overflows. */
5355 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5356 && (INTVAL (operands[2]) == 128
5357 || (INTVAL (operands[2]) < 0
5358 && INTVAL (operands[2]) != -128)))
5359 {
5360 operands[2] = GEN_INT (-INTVAL (operands[2]));
5361 return "sub{q}\t{%2, %0|%0, %2}";
5362 }
5363 return "add{q}\t{%2, %0|%0, %2}";
5364 }
5365 }
5366 [(set (attr "type")
5367 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5368 (const_string "incdec")
5369 (const_string "alu")))
5370 (set_attr "mode" "DI")])
5371
5372 (define_insn "*adddi_3_rex64"
5373 [(set (reg 17)
5374 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5375 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5376 (clobber (match_scratch:DI 0 "=r"))]
5377 "TARGET_64BIT
5378 && ix86_match_ccmode (insn, CCZmode)
5379 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5380 /* Current assemblers are broken and do not allow @GOTOFF in
5381 ought but a memory context. */
5382 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5383 {
5384 switch (get_attr_type (insn))
5385 {
5386 case TYPE_INCDEC:
5387 if (! rtx_equal_p (operands[0], operands[1]))
5388 abort ();
5389 if (operands[2] == const1_rtx)
5390 return "inc{q}\t%0";
5391 else if (operands[2] == constm1_rtx)
5392 return "dec{q}\t%0";
5393 else
5394 abort ();
5395
5396 default:
5397 if (! rtx_equal_p (operands[0], operands[1]))
5398 abort ();
5399 /* ???? We ought to handle there the 32bit case too
5400 - do we need new constraint? */
5401 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5402 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5403 if (GET_CODE (operands[2]) == CONST_INT
5404 /* Avoid overflows. */
5405 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5406 && (INTVAL (operands[2]) == 128
5407 || (INTVAL (operands[2]) < 0
5408 && INTVAL (operands[2]) != -128)))
5409 {
5410 operands[2] = GEN_INT (-INTVAL (operands[2]));
5411 return "sub{q}\t{%2, %0|%0, %2}";
5412 }
5413 return "add{q}\t{%2, %0|%0, %2}";
5414 }
5415 }
5416 [(set (attr "type")
5417 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5418 (const_string "incdec")
5419 (const_string "alu")))
5420 (set_attr "mode" "DI")])
5421
5422 ; For comparisons against 1, -1 and 128, we may generate better code
5423 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5424 ; is matched then. We can't accept general immediate, because for
5425 ; case of overflows, the result is messed up.
5426 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5427 ; when negated.
5428 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5429 ; only for comparisons not depending on it.
5430 (define_insn "*adddi_4_rex64"
5431 [(set (reg 17)
5432 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5433 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5434 (clobber (match_scratch:DI 0 "=rm"))]
5435 "TARGET_64BIT
5436 && ix86_match_ccmode (insn, CCGCmode)"
5437 {
5438 switch (get_attr_type (insn))
5439 {
5440 case TYPE_INCDEC:
5441 if (operands[2] == constm1_rtx)
5442 return "inc{q}\t%0";
5443 else if (operands[2] == const1_rtx)
5444 return "dec{q}\t%0";
5445 else
5446 abort();
5447
5448 default:
5449 if (! rtx_equal_p (operands[0], operands[1]))
5450 abort ();
5451 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5453 if ((INTVAL (operands[2]) == -128
5454 || (INTVAL (operands[2]) > 0
5455 && INTVAL (operands[2]) != 128))
5456 /* Avoid overflows. */
5457 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5458 return "sub{q}\t{%2, %0|%0, %2}";
5459 operands[2] = GEN_INT (-INTVAL (operands[2]));
5460 return "add{q}\t{%2, %0|%0, %2}";
5461 }
5462 }
5463 [(set (attr "type")
5464 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5465 (const_string "incdec")
5466 (const_string "alu")))
5467 (set_attr "mode" "DI")])
5468
5469 (define_insn "*adddi_5_rex64"
5470 [(set (reg 17)
5471 (compare
5472 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5473 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5474 (const_int 0)))
5475 (clobber (match_scratch:DI 0 "=r"))]
5476 "TARGET_64BIT
5477 && ix86_match_ccmode (insn, CCGOCmode)
5478 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5479 /* Current assemblers are broken and do not allow @GOTOFF in
5480 ought but a memory context. */
5481 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5482 {
5483 switch (get_attr_type (insn))
5484 {
5485 case TYPE_INCDEC:
5486 if (! rtx_equal_p (operands[0], operands[1]))
5487 abort ();
5488 if (operands[2] == const1_rtx)
5489 return "inc{q}\t%0";
5490 else if (operands[2] == constm1_rtx)
5491 return "dec{q}\t%0";
5492 else
5493 abort();
5494
5495 default:
5496 if (! rtx_equal_p (operands[0], operands[1]))
5497 abort ();
5498 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5499 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5500 if (GET_CODE (operands[2]) == CONST_INT
5501 /* Avoid overflows. */
5502 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5503 && (INTVAL (operands[2]) == 128
5504 || (INTVAL (operands[2]) < 0
5505 && INTVAL (operands[2]) != -128)))
5506 {
5507 operands[2] = GEN_INT (-INTVAL (operands[2]));
5508 return "sub{q}\t{%2, %0|%0, %2}";
5509 }
5510 return "add{q}\t{%2, %0|%0, %2}";
5511 }
5512 }
5513 [(set (attr "type")
5514 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5515 (const_string "incdec")
5516 (const_string "alu")))
5517 (set_attr "mode" "DI")])
5518
5519
5520 (define_insn "*addsi_1"
5521 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5522 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5523 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5524 (clobber (reg:CC 17))]
5525 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5526 {
5527 switch (get_attr_type (insn))
5528 {
5529 case TYPE_LEA:
5530 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5531 return "lea{l}\t{%a2, %0|%0, %a2}";
5532
5533 case TYPE_INCDEC:
5534 if (! rtx_equal_p (operands[0], operands[1]))
5535 abort ();
5536 if (operands[2] == const1_rtx)
5537 return "inc{l}\t%0";
5538 else if (operands[2] == constm1_rtx)
5539 return "dec{l}\t%0";
5540 else
5541 abort();
5542
5543 default:
5544 if (! rtx_equal_p (operands[0], operands[1]))
5545 abort ();
5546
5547 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5548 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5549 if (GET_CODE (operands[2]) == CONST_INT
5550 && (INTVAL (operands[2]) == 128
5551 || (INTVAL (operands[2]) < 0
5552 && INTVAL (operands[2]) != -128)))
5553 {
5554 operands[2] = GEN_INT (-INTVAL (operands[2]));
5555 return "sub{l}\t{%2, %0|%0, %2}";
5556 }
5557 return "add{l}\t{%2, %0|%0, %2}";
5558 }
5559 }
5560 [(set (attr "type")
5561 (cond [(eq_attr "alternative" "2")
5562 (const_string "lea")
5563 ; Current assemblers are broken and do not allow @GOTOFF in
5564 ; ought but a memory context.
5565 (match_operand:SI 2 "pic_symbolic_operand" "")
5566 (const_string "lea")
5567 (match_operand:SI 2 "incdec_operand" "")
5568 (const_string "incdec")
5569 ]
5570 (const_string "alu")))
5571 (set_attr "mode" "SI")])
5572
5573 ;; Convert lea to the lea pattern to avoid flags dependency.
5574 (define_split
5575 [(set (match_operand 0 "register_operand" "")
5576 (plus (match_operand 1 "register_operand" "")
5577 (match_operand 2 "nonmemory_operand" "")))
5578 (clobber (reg:CC 17))]
5579 "reload_completed
5580 && true_regnum (operands[0]) != true_regnum (operands[1])"
5581 [(const_int 0)]
5582 {
5583 rtx pat;
5584 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5585 may confuse gen_lowpart. */
5586 if (GET_MODE (operands[0]) != Pmode)
5587 {
5588 operands[1] = gen_lowpart (Pmode, operands[1]);
5589 operands[2] = gen_lowpart (Pmode, operands[2]);
5590 }
5591 operands[0] = gen_lowpart (SImode, operands[0]);
5592 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5593 if (Pmode != SImode)
5594 pat = gen_rtx_SUBREG (SImode, pat, 0);
5595 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5596 DONE;
5597 })
5598
5599 ;; It may seem that nonimmediate operand is proper one for operand 1.
5600 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5601 ;; we take care in ix86_binary_operator_ok to not allow two memory
5602 ;; operands so proper swapping will be done in reload. This allow
5603 ;; patterns constructed from addsi_1 to match.
5604 (define_insn "addsi_1_zext"
5605 [(set (match_operand:DI 0 "register_operand" "=r,r")
5606 (zero_extend:DI
5607 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5608 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5609 (clobber (reg:CC 17))]
5610 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5611 {
5612 switch (get_attr_type (insn))
5613 {
5614 case TYPE_LEA:
5615 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5616 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5617
5618 case TYPE_INCDEC:
5619 if (operands[2] == const1_rtx)
5620 return "inc{l}\t%k0";
5621 else if (operands[2] == constm1_rtx)
5622 return "dec{l}\t%k0";
5623 else
5624 abort();
5625
5626 default:
5627 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5628 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5629 if (GET_CODE (operands[2]) == CONST_INT
5630 && (INTVAL (operands[2]) == 128
5631 || (INTVAL (operands[2]) < 0
5632 && INTVAL (operands[2]) != -128)))
5633 {
5634 operands[2] = GEN_INT (-INTVAL (operands[2]));
5635 return "sub{l}\t{%2, %k0|%k0, %2}";
5636 }
5637 return "add{l}\t{%2, %k0|%k0, %2}";
5638 }
5639 }
5640 [(set (attr "type")
5641 (cond [(eq_attr "alternative" "1")
5642 (const_string "lea")
5643 ; Current assemblers are broken and do not allow @GOTOFF in
5644 ; ought but a memory context.
5645 (match_operand:SI 2 "pic_symbolic_operand" "")
5646 (const_string "lea")
5647 (match_operand:SI 2 "incdec_operand" "")
5648 (const_string "incdec")
5649 ]
5650 (const_string "alu")))
5651 (set_attr "mode" "SI")])
5652
5653 ;; Convert lea to the lea pattern to avoid flags dependency.
5654 (define_split
5655 [(set (match_operand:DI 0 "register_operand" "")
5656 (zero_extend:DI
5657 (plus:SI (match_operand:SI 1 "register_operand" "")
5658 (match_operand:SI 2 "nonmemory_operand" ""))))
5659 (clobber (reg:CC 17))]
5660 "TARGET_64BIT && reload_completed
5661 && true_regnum (operands[0]) != true_regnum (operands[1])"
5662 [(set (match_dup 0)
5663 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5664 {
5665 operands[1] = gen_lowpart (Pmode, operands[1]);
5666 operands[2] = gen_lowpart (Pmode, operands[2]);
5667 })
5668
5669 (define_insn "*addsi_2"
5670 [(set (reg 17)
5671 (compare
5672 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5673 (match_operand:SI 2 "general_operand" "rmni,rni"))
5674 (const_int 0)))
5675 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5676 (plus:SI (match_dup 1) (match_dup 2)))]
5677 "ix86_match_ccmode (insn, CCGOCmode)
5678 && ix86_binary_operator_ok (PLUS, SImode, operands)
5679 /* Current assemblers are broken and do not allow @GOTOFF in
5680 ought but a memory context. */
5681 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5682 {
5683 switch (get_attr_type (insn))
5684 {
5685 case TYPE_INCDEC:
5686 if (! rtx_equal_p (operands[0], operands[1]))
5687 abort ();
5688 if (operands[2] == const1_rtx)
5689 return "inc{l}\t%0";
5690 else if (operands[2] == constm1_rtx)
5691 return "dec{l}\t%0";
5692 else
5693 abort();
5694
5695 default:
5696 if (! rtx_equal_p (operands[0], operands[1]))
5697 abort ();
5698 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5699 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5700 if (GET_CODE (operands[2]) == CONST_INT
5701 && (INTVAL (operands[2]) == 128
5702 || (INTVAL (operands[2]) < 0
5703 && INTVAL (operands[2]) != -128)))
5704 {
5705 operands[2] = GEN_INT (-INTVAL (operands[2]));
5706 return "sub{l}\t{%2, %0|%0, %2}";
5707 }
5708 return "add{l}\t{%2, %0|%0, %2}";
5709 }
5710 }
5711 [(set (attr "type")
5712 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5713 (const_string "incdec")
5714 (const_string "alu")))
5715 (set_attr "mode" "SI")])
5716
5717 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5718 (define_insn "*addsi_2_zext"
5719 [(set (reg 17)
5720 (compare
5721 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5722 (match_operand:SI 2 "general_operand" "rmni"))
5723 (const_int 0)))
5724 (set (match_operand:DI 0 "register_operand" "=r")
5725 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5726 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5727 && ix86_binary_operator_ok (PLUS, SImode, operands)
5728 /* Current assemblers are broken and do not allow @GOTOFF in
5729 ought but a memory context. */
5730 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 {
5732 switch (get_attr_type (insn))
5733 {
5734 case TYPE_INCDEC:
5735 if (operands[2] == const1_rtx)
5736 return "inc{l}\t%k0";
5737 else if (operands[2] == constm1_rtx)
5738 return "dec{l}\t%k0";
5739 else
5740 abort();
5741
5742 default:
5743 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5745 if (GET_CODE (operands[2]) == CONST_INT
5746 && (INTVAL (operands[2]) == 128
5747 || (INTVAL (operands[2]) < 0
5748 && INTVAL (operands[2]) != -128)))
5749 {
5750 operands[2] = GEN_INT (-INTVAL (operands[2]));
5751 return "sub{l}\t{%2, %k0|%k0, %2}";
5752 }
5753 return "add{l}\t{%2, %k0|%k0, %2}";
5754 }
5755 }
5756 [(set (attr "type")
5757 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5758 (const_string "incdec")
5759 (const_string "alu")))
5760 (set_attr "mode" "SI")])
5761
5762 (define_insn "*addsi_3"
5763 [(set (reg 17)
5764 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5765 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5766 (clobber (match_scratch:SI 0 "=r"))]
5767 "ix86_match_ccmode (insn, CCZmode)
5768 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5769 /* Current assemblers are broken and do not allow @GOTOFF in
5770 ought but a memory context. */
5771 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5772 {
5773 switch (get_attr_type (insn))
5774 {
5775 case TYPE_INCDEC:
5776 if (! rtx_equal_p (operands[0], operands[1]))
5777 abort ();
5778 if (operands[2] == const1_rtx)
5779 return "inc{l}\t%0";
5780 else if (operands[2] == constm1_rtx)
5781 return "dec{l}\t%0";
5782 else
5783 abort();
5784
5785 default:
5786 if (! rtx_equal_p (operands[0], operands[1]))
5787 abort ();
5788 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5789 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5790 if (GET_CODE (operands[2]) == CONST_INT
5791 && (INTVAL (operands[2]) == 128
5792 || (INTVAL (operands[2]) < 0
5793 && INTVAL (operands[2]) != -128)))
5794 {
5795 operands[2] = GEN_INT (-INTVAL (operands[2]));
5796 return "sub{l}\t{%2, %0|%0, %2}";
5797 }
5798 return "add{l}\t{%2, %0|%0, %2}";
5799 }
5800 }
5801 [(set (attr "type")
5802 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5803 (const_string "incdec")
5804 (const_string "alu")))
5805 (set_attr "mode" "SI")])
5806
5807 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5808 (define_insn "*addsi_3_zext"
5809 [(set (reg 17)
5810 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5811 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5812 (set (match_operand:DI 0 "register_operand" "=r")
5813 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5814 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5815 && ix86_binary_operator_ok (PLUS, SImode, operands)
5816 /* Current assemblers are broken and do not allow @GOTOFF in
5817 ought but a memory context. */
5818 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5819 {
5820 switch (get_attr_type (insn))
5821 {
5822 case TYPE_INCDEC:
5823 if (operands[2] == const1_rtx)
5824 return "inc{l}\t%k0";
5825 else if (operands[2] == constm1_rtx)
5826 return "dec{l}\t%k0";
5827 else
5828 abort();
5829
5830 default:
5831 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5832 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5833 if (GET_CODE (operands[2]) == CONST_INT
5834 && (INTVAL (operands[2]) == 128
5835 || (INTVAL (operands[2]) < 0
5836 && INTVAL (operands[2]) != -128)))
5837 {
5838 operands[2] = GEN_INT (-INTVAL (operands[2]));
5839 return "sub{l}\t{%2, %k0|%k0, %2}";
5840 }
5841 return "add{l}\t{%2, %k0|%k0, %2}";
5842 }
5843 }
5844 [(set (attr "type")
5845 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5846 (const_string "incdec")
5847 (const_string "alu")))
5848 (set_attr "mode" "SI")])
5849
5850 ; For comparisons against 1, -1 and 128, we may generate better code
5851 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5852 ; is matched then. We can't accept general immediate, because for
5853 ; case of overflows, the result is messed up.
5854 ; This pattern also don't hold of 0x80000000, since the value overflows
5855 ; when negated.
5856 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5857 ; only for comparisons not depending on it.
5858 (define_insn "*addsi_4"
5859 [(set (reg 17)
5860 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5861 (match_operand:SI 2 "const_int_operand" "n")))
5862 (clobber (match_scratch:SI 0 "=rm"))]
5863 "ix86_match_ccmode (insn, CCGCmode)
5864 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5865 {
5866 switch (get_attr_type (insn))
5867 {
5868 case TYPE_INCDEC:
5869 if (operands[2] == constm1_rtx)
5870 return "inc{l}\t%0";
5871 else if (operands[2] == const1_rtx)
5872 return "dec{l}\t%0";
5873 else
5874 abort();
5875
5876 default:
5877 if (! rtx_equal_p (operands[0], operands[1]))
5878 abort ();
5879 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5881 if ((INTVAL (operands[2]) == -128
5882 || (INTVAL (operands[2]) > 0
5883 && INTVAL (operands[2]) != 128)))
5884 return "sub{l}\t{%2, %0|%0, %2}";
5885 operands[2] = GEN_INT (-INTVAL (operands[2]));
5886 return "add{l}\t{%2, %0|%0, %2}";
5887 }
5888 }
5889 [(set (attr "type")
5890 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5891 (const_string "incdec")
5892 (const_string "alu")))
5893 (set_attr "mode" "SI")])
5894
5895 (define_insn "*addsi_5"
5896 [(set (reg 17)
5897 (compare
5898 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5899 (match_operand:SI 2 "general_operand" "rmni"))
5900 (const_int 0)))
5901 (clobber (match_scratch:SI 0 "=r"))]
5902 "ix86_match_ccmode (insn, CCGOCmode)
5903 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5904 /* Current assemblers are broken and do not allow @GOTOFF in
5905 ought but a memory context. */
5906 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5907 {
5908 switch (get_attr_type (insn))
5909 {
5910 case TYPE_INCDEC:
5911 if (! rtx_equal_p (operands[0], operands[1]))
5912 abort ();
5913 if (operands[2] == const1_rtx)
5914 return "inc{l}\t%0";
5915 else if (operands[2] == constm1_rtx)
5916 return "dec{l}\t%0";
5917 else
5918 abort();
5919
5920 default:
5921 if (! rtx_equal_p (operands[0], operands[1]))
5922 abort ();
5923 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5924 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5925 if (GET_CODE (operands[2]) == CONST_INT
5926 && (INTVAL (operands[2]) == 128
5927 || (INTVAL (operands[2]) < 0
5928 && INTVAL (operands[2]) != -128)))
5929 {
5930 operands[2] = GEN_INT (-INTVAL (operands[2]));
5931 return "sub{l}\t{%2, %0|%0, %2}";
5932 }
5933 return "add{l}\t{%2, %0|%0, %2}";
5934 }
5935 }
5936 [(set (attr "type")
5937 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5938 (const_string "incdec")
5939 (const_string "alu")))
5940 (set_attr "mode" "SI")])
5941
5942 (define_expand "addhi3"
5943 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5944 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5945 (match_operand:HI 2 "general_operand" "")))
5946 (clobber (reg:CC 17))])]
5947 "TARGET_HIMODE_MATH"
5948 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5949
5950 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5951 ;; type optimizations enabled by define-splits. This is not important
5952 ;; for PII, and in fact harmful because of partial register stalls.
5953
5954 (define_insn "*addhi_1_lea"
5955 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5956 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5957 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5958 (clobber (reg:CC 17))]
5959 "!TARGET_PARTIAL_REG_STALL
5960 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5961 {
5962 switch (get_attr_type (insn))
5963 {
5964 case TYPE_LEA:
5965 return "#";
5966 case TYPE_INCDEC:
5967 if (operands[2] == const1_rtx)
5968 return "inc{w}\t%0";
5969 else if (operands[2] == constm1_rtx)
5970 return "dec{w}\t%0";
5971 abort();
5972
5973 default:
5974 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5976 if (GET_CODE (operands[2]) == CONST_INT
5977 && (INTVAL (operands[2]) == 128
5978 || (INTVAL (operands[2]) < 0
5979 && INTVAL (operands[2]) != -128)))
5980 {
5981 operands[2] = GEN_INT (-INTVAL (operands[2]));
5982 return "sub{w}\t{%2, %0|%0, %2}";
5983 }
5984 return "add{w}\t{%2, %0|%0, %2}";
5985 }
5986 }
5987 [(set (attr "type")
5988 (if_then_else (eq_attr "alternative" "2")
5989 (const_string "lea")
5990 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5991 (const_string "incdec")
5992 (const_string "alu"))))
5993 (set_attr "mode" "HI,HI,SI")])
5994
5995 (define_insn "*addhi_1"
5996 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5997 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5998 (match_operand:HI 2 "general_operand" "ri,rm")))
5999 (clobber (reg:CC 17))]
6000 "TARGET_PARTIAL_REG_STALL
6001 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6002 {
6003 switch (get_attr_type (insn))
6004 {
6005 case TYPE_INCDEC:
6006 if (operands[2] == const1_rtx)
6007 return "inc{w}\t%0";
6008 else if (operands[2] == constm1_rtx)
6009 return "dec{w}\t%0";
6010 abort();
6011
6012 default:
6013 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6014 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6015 if (GET_CODE (operands[2]) == CONST_INT
6016 && (INTVAL (operands[2]) == 128
6017 || (INTVAL (operands[2]) < 0
6018 && INTVAL (operands[2]) != -128)))
6019 {
6020 operands[2] = GEN_INT (-INTVAL (operands[2]));
6021 return "sub{w}\t{%2, %0|%0, %2}";
6022 }
6023 return "add{w}\t{%2, %0|%0, %2}";
6024 }
6025 }
6026 [(set (attr "type")
6027 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6028 (const_string "incdec")
6029 (const_string "alu")))
6030 (set_attr "mode" "HI")])
6031
6032 (define_insn "*addhi_2"
6033 [(set (reg 17)
6034 (compare
6035 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6036 (match_operand:HI 2 "general_operand" "rmni,rni"))
6037 (const_int 0)))
6038 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6039 (plus:HI (match_dup 1) (match_dup 2)))]
6040 "ix86_match_ccmode (insn, CCGOCmode)
6041 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6042 {
6043 switch (get_attr_type (insn))
6044 {
6045 case TYPE_INCDEC:
6046 if (operands[2] == const1_rtx)
6047 return "inc{w}\t%0";
6048 else if (operands[2] == constm1_rtx)
6049 return "dec{w}\t%0";
6050 abort();
6051
6052 default:
6053 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6055 if (GET_CODE (operands[2]) == CONST_INT
6056 && (INTVAL (operands[2]) == 128
6057 || (INTVAL (operands[2]) < 0
6058 && INTVAL (operands[2]) != -128)))
6059 {
6060 operands[2] = GEN_INT (-INTVAL (operands[2]));
6061 return "sub{w}\t{%2, %0|%0, %2}";
6062 }
6063 return "add{w}\t{%2, %0|%0, %2}";
6064 }
6065 }
6066 [(set (attr "type")
6067 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6068 (const_string "incdec")
6069 (const_string "alu")))
6070 (set_attr "mode" "HI")])
6071
6072 (define_insn "*addhi_3"
6073 [(set (reg 17)
6074 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6075 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6076 (clobber (match_scratch:HI 0 "=r"))]
6077 "ix86_match_ccmode (insn, CCZmode)
6078 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6079 {
6080 switch (get_attr_type (insn))
6081 {
6082 case TYPE_INCDEC:
6083 if (operands[2] == const1_rtx)
6084 return "inc{w}\t%0";
6085 else if (operands[2] == constm1_rtx)
6086 return "dec{w}\t%0";
6087 abort();
6088
6089 default:
6090 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6091 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6092 if (GET_CODE (operands[2]) == CONST_INT
6093 && (INTVAL (operands[2]) == 128
6094 || (INTVAL (operands[2]) < 0
6095 && INTVAL (operands[2]) != -128)))
6096 {
6097 operands[2] = GEN_INT (-INTVAL (operands[2]));
6098 return "sub{w}\t{%2, %0|%0, %2}";
6099 }
6100 return "add{w}\t{%2, %0|%0, %2}";
6101 }
6102 }
6103 [(set (attr "type")
6104 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6105 (const_string "incdec")
6106 (const_string "alu")))
6107 (set_attr "mode" "HI")])
6108
6109 ; See comments above addsi_3_imm for details.
6110 (define_insn "*addhi_4"
6111 [(set (reg 17)
6112 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6113 (match_operand:HI 2 "const_int_operand" "n")))
6114 (clobber (match_scratch:HI 0 "=rm"))]
6115 "ix86_match_ccmode (insn, CCGCmode)
6116 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6117 {
6118 switch (get_attr_type (insn))
6119 {
6120 case TYPE_INCDEC:
6121 if (operands[2] == constm1_rtx)
6122 return "inc{w}\t%0";
6123 else if (operands[2] == const1_rtx)
6124 return "dec{w}\t%0";
6125 else
6126 abort();
6127
6128 default:
6129 if (! rtx_equal_p (operands[0], operands[1]))
6130 abort ();
6131 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6132 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6133 if ((INTVAL (operands[2]) == -128
6134 || (INTVAL (operands[2]) > 0
6135 && INTVAL (operands[2]) != 128)))
6136 return "sub{w}\t{%2, %0|%0, %2}";
6137 operands[2] = GEN_INT (-INTVAL (operands[2]));
6138 return "add{w}\t{%2, %0|%0, %2}";
6139 }
6140 }
6141 [(set (attr "type")
6142 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6143 (const_string "incdec")
6144 (const_string "alu")))
6145 (set_attr "mode" "SI")])
6146
6147
6148 (define_insn "*addhi_5"
6149 [(set (reg 17)
6150 (compare
6151 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6152 (match_operand:HI 2 "general_operand" "rmni"))
6153 (const_int 0)))
6154 (clobber (match_scratch:HI 0 "=r"))]
6155 "ix86_match_ccmode (insn, CCGOCmode)
6156 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6157 {
6158 switch (get_attr_type (insn))
6159 {
6160 case TYPE_INCDEC:
6161 if (operands[2] == const1_rtx)
6162 return "inc{w}\t%0";
6163 else if (operands[2] == constm1_rtx)
6164 return "dec{w}\t%0";
6165 abort();
6166
6167 default:
6168 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6169 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6170 if (GET_CODE (operands[2]) == CONST_INT
6171 && (INTVAL (operands[2]) == 128
6172 || (INTVAL (operands[2]) < 0
6173 && INTVAL (operands[2]) != -128)))
6174 {
6175 operands[2] = GEN_INT (-INTVAL (operands[2]));
6176 return "sub{w}\t{%2, %0|%0, %2}";
6177 }
6178 return "add{w}\t{%2, %0|%0, %2}";
6179 }
6180 }
6181 [(set (attr "type")
6182 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6183 (const_string "incdec")
6184 (const_string "alu")))
6185 (set_attr "mode" "HI")])
6186
6187 (define_expand "addqi3"
6188 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6189 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6190 (match_operand:QI 2 "general_operand" "")))
6191 (clobber (reg:CC 17))])]
6192 "TARGET_QIMODE_MATH"
6193 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6194
6195 ;; %%% Potential partial reg stall on alternative 2. What to do?
6196 (define_insn "*addqi_1_lea"
6197 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6198 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6199 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6200 (clobber (reg:CC 17))]
6201 "!TARGET_PARTIAL_REG_STALL
6202 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6203 {
6204 int widen = (which_alternative == 2);
6205 switch (get_attr_type (insn))
6206 {
6207 case TYPE_LEA:
6208 return "#";
6209 case TYPE_INCDEC:
6210 if (operands[2] == const1_rtx)
6211 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6212 else if (operands[2] == constm1_rtx)
6213 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6214 abort();
6215
6216 default:
6217 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6218 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6219 if (GET_CODE (operands[2]) == CONST_INT
6220 && (INTVAL (operands[2]) == 128
6221 || (INTVAL (operands[2]) < 0
6222 && INTVAL (operands[2]) != -128)))
6223 {
6224 operands[2] = GEN_INT (-INTVAL (operands[2]));
6225 if (widen)
6226 return "sub{l}\t{%2, %k0|%k0, %2}";
6227 else
6228 return "sub{b}\t{%2, %0|%0, %2}";
6229 }
6230 if (widen)
6231 return "add{l}\t{%k2, %k0|%k0, %k2}";
6232 else
6233 return "add{b}\t{%2, %0|%0, %2}";
6234 }
6235 }
6236 [(set (attr "type")
6237 (if_then_else (eq_attr "alternative" "3")
6238 (const_string "lea")
6239 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240 (const_string "incdec")
6241 (const_string "alu"))))
6242 (set_attr "mode" "QI,QI,SI,SI")])
6243
6244 (define_insn "*addqi_1"
6245 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6246 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6247 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6248 (clobber (reg:CC 17))]
6249 "TARGET_PARTIAL_REG_STALL
6250 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6251 {
6252 int widen = (which_alternative == 2);
6253 switch (get_attr_type (insn))
6254 {
6255 case TYPE_INCDEC:
6256 if (operands[2] == const1_rtx)
6257 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6258 else if (operands[2] == constm1_rtx)
6259 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6260 abort();
6261
6262 default:
6263 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6265 if (GET_CODE (operands[2]) == CONST_INT
6266 && (INTVAL (operands[2]) == 128
6267 || (INTVAL (operands[2]) < 0
6268 && INTVAL (operands[2]) != -128)))
6269 {
6270 operands[2] = GEN_INT (-INTVAL (operands[2]));
6271 if (widen)
6272 return "sub{l}\t{%2, %k0|%k0, %2}";
6273 else
6274 return "sub{b}\t{%2, %0|%0, %2}";
6275 }
6276 if (widen)
6277 return "add{l}\t{%k2, %k0|%k0, %k2}";
6278 else
6279 return "add{b}\t{%2, %0|%0, %2}";
6280 }
6281 }
6282 [(set (attr "type")
6283 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6284 (const_string "incdec")
6285 (const_string "alu")))
6286 (set_attr "mode" "QI,QI,SI")])
6287
6288 (define_insn "*addqi_1_slp"
6289 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6290 (plus:QI (match_dup 0)
6291 (match_operand:QI 1 "general_operand" "qn,qnm")))
6292 (clobber (reg:CC 17))]
6293 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6294 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6295 {
6296 switch (get_attr_type (insn))
6297 {
6298 case TYPE_INCDEC:
6299 if (operands[1] == const1_rtx)
6300 return "inc{b}\t%0";
6301 else if (operands[1] == constm1_rtx)
6302 return "dec{b}\t%0";
6303 abort();
6304
6305 default:
6306 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6307 if (GET_CODE (operands[1]) == CONST_INT
6308 && INTVAL (operands[1]) < 0)
6309 {
6310 operands[2] = GEN_INT (-INTVAL (operands[2]));
6311 return "sub{b}\t{%1, %0|%0, %1}";
6312 }
6313 return "add{b}\t{%1, %0|%0, %1}";
6314 }
6315 }
6316 [(set (attr "type")
6317 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6318 (const_string "incdec")
6319 (const_string "alu1")))
6320 (set_attr "mode" "QI")])
6321
6322 (define_insn "*addqi_2"
6323 [(set (reg 17)
6324 (compare
6325 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6326 (match_operand:QI 2 "general_operand" "qmni,qni"))
6327 (const_int 0)))
6328 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6329 (plus:QI (match_dup 1) (match_dup 2)))]
6330 "ix86_match_ccmode (insn, CCGOCmode)
6331 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6332 {
6333 switch (get_attr_type (insn))
6334 {
6335 case TYPE_INCDEC:
6336 if (operands[2] == const1_rtx)
6337 return "inc{b}\t%0";
6338 else if (operands[2] == constm1_rtx
6339 || (GET_CODE (operands[2]) == CONST_INT
6340 && INTVAL (operands[2]) == 255))
6341 return "dec{b}\t%0";
6342 abort();
6343
6344 default:
6345 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6346 if (GET_CODE (operands[2]) == CONST_INT
6347 && INTVAL (operands[2]) < 0)
6348 {
6349 operands[2] = GEN_INT (-INTVAL (operands[2]));
6350 return "sub{b}\t{%2, %0|%0, %2}";
6351 }
6352 return "add{b}\t{%2, %0|%0, %2}";
6353 }
6354 }
6355 [(set (attr "type")
6356 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6357 (const_string "incdec")
6358 (const_string "alu")))
6359 (set_attr "mode" "QI")])
6360
6361 (define_insn "*addqi_3"
6362 [(set (reg 17)
6363 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6364 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6365 (clobber (match_scratch:QI 0 "=q"))]
6366 "ix86_match_ccmode (insn, CCZmode)
6367 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6368 {
6369 switch (get_attr_type (insn))
6370 {
6371 case TYPE_INCDEC:
6372 if (operands[2] == const1_rtx)
6373 return "inc{b}\t%0";
6374 else if (operands[2] == constm1_rtx
6375 || (GET_CODE (operands[2]) == CONST_INT
6376 && INTVAL (operands[2]) == 255))
6377 return "dec{b}\t%0";
6378 abort();
6379
6380 default:
6381 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6382 if (GET_CODE (operands[2]) == CONST_INT
6383 && INTVAL (operands[2]) < 0)
6384 {
6385 operands[2] = GEN_INT (-INTVAL (operands[2]));
6386 return "sub{b}\t{%2, %0|%0, %2}";
6387 }
6388 return "add{b}\t{%2, %0|%0, %2}";
6389 }
6390 }
6391 [(set (attr "type")
6392 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6393 (const_string "incdec")
6394 (const_string "alu")))
6395 (set_attr "mode" "QI")])
6396
6397 ; See comments above addsi_3_imm for details.
6398 (define_insn "*addqi_4"
6399 [(set (reg 17)
6400 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6401 (match_operand:QI 2 "const_int_operand" "n")))
6402 (clobber (match_scratch:QI 0 "=qm"))]
6403 "ix86_match_ccmode (insn, CCGCmode)
6404 && (INTVAL (operands[2]) & 0xff) != 0x80"
6405 {
6406 switch (get_attr_type (insn))
6407 {
6408 case TYPE_INCDEC:
6409 if (operands[2] == constm1_rtx
6410 || (GET_CODE (operands[2]) == CONST_INT
6411 && INTVAL (operands[2]) == 255))
6412 return "inc{b}\t%0";
6413 else if (operands[2] == const1_rtx)
6414 return "dec{b}\t%0";
6415 else
6416 abort();
6417
6418 default:
6419 if (! rtx_equal_p (operands[0], operands[1]))
6420 abort ();
6421 if (INTVAL (operands[2]) < 0)
6422 {
6423 operands[2] = GEN_INT (-INTVAL (operands[2]));
6424 return "add{b}\t{%2, %0|%0, %2}";
6425 }
6426 return "sub{b}\t{%2, %0|%0, %2}";
6427 }
6428 }
6429 [(set (attr "type")
6430 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6431 (const_string "incdec")
6432 (const_string "alu")))
6433 (set_attr "mode" "QI")])
6434
6435
6436 (define_insn "*addqi_5"
6437 [(set (reg 17)
6438 (compare
6439 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6440 (match_operand:QI 2 "general_operand" "qmni"))
6441 (const_int 0)))
6442 (clobber (match_scratch:QI 0 "=q"))]
6443 "ix86_match_ccmode (insn, CCGOCmode)
6444 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6445 {
6446 switch (get_attr_type (insn))
6447 {
6448 case TYPE_INCDEC:
6449 if (operands[2] == const1_rtx)
6450 return "inc{b}\t%0";
6451 else if (operands[2] == constm1_rtx
6452 || (GET_CODE (operands[2]) == CONST_INT
6453 && INTVAL (operands[2]) == 255))
6454 return "dec{b}\t%0";
6455 abort();
6456
6457 default:
6458 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6459 if (GET_CODE (operands[2]) == CONST_INT
6460 && INTVAL (operands[2]) < 0)
6461 {
6462 operands[2] = GEN_INT (-INTVAL (operands[2]));
6463 return "sub{b}\t{%2, %0|%0, %2}";
6464 }
6465 return "add{b}\t{%2, %0|%0, %2}";
6466 }
6467 }
6468 [(set (attr "type")
6469 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6470 (const_string "incdec")
6471 (const_string "alu")))
6472 (set_attr "mode" "QI")])
6473
6474
6475 (define_insn "addqi_ext_1"
6476 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6477 (const_int 8)
6478 (const_int 8))
6479 (plus:SI
6480 (zero_extract:SI
6481 (match_operand 1 "ext_register_operand" "0")
6482 (const_int 8)
6483 (const_int 8))
6484 (match_operand:QI 2 "general_operand" "Qmn")))
6485 (clobber (reg:CC 17))]
6486 "!TARGET_64BIT"
6487 {
6488 switch (get_attr_type (insn))
6489 {
6490 case TYPE_INCDEC:
6491 if (operands[2] == const1_rtx)
6492 return "inc{b}\t%h0";
6493 else if (operands[2] == constm1_rtx
6494 || (GET_CODE (operands[2]) == CONST_INT
6495 && INTVAL (operands[2]) == 255))
6496 return "dec{b}\t%h0";
6497 abort();
6498
6499 default:
6500 return "add{b}\t{%2, %h0|%h0, %2}";
6501 }
6502 }
6503 [(set (attr "type")
6504 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6505 (const_string "incdec")
6506 (const_string "alu")))
6507 (set_attr "mode" "QI")])
6508
6509 (define_insn "*addqi_ext_1_rex64"
6510 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6511 (const_int 8)
6512 (const_int 8))
6513 (plus:SI
6514 (zero_extract:SI
6515 (match_operand 1 "ext_register_operand" "0")
6516 (const_int 8)
6517 (const_int 8))
6518 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6519 (clobber (reg:CC 17))]
6520 "TARGET_64BIT"
6521 {
6522 switch (get_attr_type (insn))
6523 {
6524 case TYPE_INCDEC:
6525 if (operands[2] == const1_rtx)
6526 return "inc{b}\t%h0";
6527 else if (operands[2] == constm1_rtx
6528 || (GET_CODE (operands[2]) == CONST_INT
6529 && INTVAL (operands[2]) == 255))
6530 return "dec{b}\t%h0";
6531 abort();
6532
6533 default:
6534 return "add{b}\t{%2, %h0|%h0, %2}";
6535 }
6536 }
6537 [(set (attr "type")
6538 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6539 (const_string "incdec")
6540 (const_string "alu")))
6541 (set_attr "mode" "QI")])
6542
6543 (define_insn "*addqi_ext_2"
6544 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6545 (const_int 8)
6546 (const_int 8))
6547 (plus:SI
6548 (zero_extract:SI
6549 (match_operand 1 "ext_register_operand" "%0")
6550 (const_int 8)
6551 (const_int 8))
6552 (zero_extract:SI
6553 (match_operand 2 "ext_register_operand" "Q")
6554 (const_int 8)
6555 (const_int 8))))
6556 (clobber (reg:CC 17))]
6557 ""
6558 "add{b}\t{%h2, %h0|%h0, %h2}"
6559 [(set_attr "type" "alu")
6560 (set_attr "mode" "QI")])
6561
6562 ;; The patterns that match these are at the end of this file.
6563
6564 (define_expand "addxf3"
6565 [(set (match_operand:XF 0 "register_operand" "")
6566 (plus:XF (match_operand:XF 1 "register_operand" "")
6567 (match_operand:XF 2 "register_operand" "")))]
6568 "TARGET_80387"
6569 "")
6570
6571 (define_expand "adddf3"
6572 [(set (match_operand:DF 0 "register_operand" "")
6573 (plus:DF (match_operand:DF 1 "register_operand" "")
6574 (match_operand:DF 2 "nonimmediate_operand" "")))]
6575 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6576 "")
6577
6578 (define_expand "addsf3"
6579 [(set (match_operand:SF 0 "register_operand" "")
6580 (plus:SF (match_operand:SF 1 "register_operand" "")
6581 (match_operand:SF 2 "nonimmediate_operand" "")))]
6582 "TARGET_80387 || TARGET_SSE_MATH"
6583 "")
6584 \f
6585 ;; Subtract instructions
6586
6587 ;; %%% splits for subsidi3
6588
6589 (define_expand "subdi3"
6590 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6591 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6592 (match_operand:DI 2 "x86_64_general_operand" "")))
6593 (clobber (reg:CC 17))])]
6594 ""
6595 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6596
6597 (define_insn "*subdi3_1"
6598 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6599 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6600 (match_operand:DI 2 "general_operand" "roiF,riF")))
6601 (clobber (reg:CC 17))]
6602 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6603 "#")
6604
6605 (define_split
6606 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6607 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6608 (match_operand:DI 2 "general_operand" "")))
6609 (clobber (reg:CC 17))]
6610 "!TARGET_64BIT && reload_completed"
6611 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6612 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6613 (parallel [(set (match_dup 3)
6614 (minus:SI (match_dup 4)
6615 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6616 (match_dup 5))))
6617 (clobber (reg:CC 17))])]
6618 "split_di (operands+0, 1, operands+0, operands+3);
6619 split_di (operands+1, 1, operands+1, operands+4);
6620 split_di (operands+2, 1, operands+2, operands+5);")
6621
6622 (define_insn "subdi3_carry_rex64"
6623 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6625 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6626 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6627 (clobber (reg:CC 17))]
6628 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6629 "sbb{q}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "pent_pair" "pu")
6632 (set_attr "ppro_uops" "few")
6633 (set_attr "mode" "DI")])
6634
6635 (define_insn "*subdi_1_rex64"
6636 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6637 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6638 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6639 (clobber (reg:CC 17))]
6640 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6641 "sub{q}\t{%2, %0|%0, %2}"
6642 [(set_attr "type" "alu")
6643 (set_attr "mode" "DI")])
6644
6645 (define_insn "*subdi_2_rex64"
6646 [(set (reg 17)
6647 (compare
6648 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6649 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6650 (const_int 0)))
6651 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6652 (minus:DI (match_dup 1) (match_dup 2)))]
6653 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6654 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6655 "sub{q}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "mode" "DI")])
6658
6659 (define_insn "*subdi_3_rex63"
6660 [(set (reg 17)
6661 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6662 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6663 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6664 (minus:DI (match_dup 1) (match_dup 2)))]
6665 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6666 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6667 "sub{q}\t{%2, %0|%0, %2}"
6668 [(set_attr "type" "alu")
6669 (set_attr "mode" "DI")])
6670
6671 (define_insn "subqi3_carry"
6672 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6673 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6674 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6675 (match_operand:QI 2 "general_operand" "qi,qm"))))
6676 (clobber (reg:CC 17))]
6677 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6678 "sbb{b}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "pent_pair" "pu")
6681 (set_attr "ppro_uops" "few")
6682 (set_attr "mode" "QI")])
6683
6684 (define_insn "subhi3_carry"
6685 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6686 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6687 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6688 (match_operand:HI 2 "general_operand" "ri,rm"))))
6689 (clobber (reg:CC 17))]
6690 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6691 "sbb{w}\t{%2, %0|%0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "pent_pair" "pu")
6694 (set_attr "ppro_uops" "few")
6695 (set_attr "mode" "HI")])
6696
6697 (define_insn "subsi3_carry"
6698 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6699 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6700 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6701 (match_operand:SI 2 "general_operand" "ri,rm"))))
6702 (clobber (reg:CC 17))]
6703 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6704 "sbb{l}\t{%2, %0|%0, %2}"
6705 [(set_attr "type" "alu")
6706 (set_attr "pent_pair" "pu")
6707 (set_attr "ppro_uops" "few")
6708 (set_attr "mode" "SI")])
6709
6710 (define_insn "subsi3_carry_zext"
6711 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6712 (zero_extend:DI
6713 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6714 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6715 (match_operand:SI 2 "general_operand" "ri,rm")))))
6716 (clobber (reg:CC 17))]
6717 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6718 "sbb{l}\t{%2, %k0|%k0, %2}"
6719 [(set_attr "type" "alu")
6720 (set_attr "pent_pair" "pu")
6721 (set_attr "ppro_uops" "few")
6722 (set_attr "mode" "SI")])
6723
6724 (define_expand "subsi3"
6725 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6726 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6727 (match_operand:SI 2 "general_operand" "")))
6728 (clobber (reg:CC 17))])]
6729 ""
6730 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6731
6732 (define_insn "*subsi_1"
6733 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6734 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6735 (match_operand:SI 2 "general_operand" "ri,rm")))
6736 (clobber (reg:CC 17))]
6737 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6738 "sub{l}\t{%2, %0|%0, %2}"
6739 [(set_attr "type" "alu")
6740 (set_attr "mode" "SI")])
6741
6742 (define_insn "*subsi_1_zext"
6743 [(set (match_operand:DI 0 "register_operand" "=r")
6744 (zero_extend:DI
6745 (minus:SI (match_operand:SI 1 "register_operand" "0")
6746 (match_operand:SI 2 "general_operand" "rim"))))
6747 (clobber (reg:CC 17))]
6748 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6749 "sub{l}\t{%2, %k0|%k0, %2}"
6750 [(set_attr "type" "alu")
6751 (set_attr "mode" "SI")])
6752
6753 (define_insn "*subsi_2"
6754 [(set (reg 17)
6755 (compare
6756 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6757 (match_operand:SI 2 "general_operand" "ri,rm"))
6758 (const_int 0)))
6759 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6760 (minus:SI (match_dup 1) (match_dup 2)))]
6761 "ix86_match_ccmode (insn, CCGOCmode)
6762 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763 "sub{l}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "SI")])
6766
6767 (define_insn "*subsi_2_zext"
6768 [(set (reg 17)
6769 (compare
6770 (minus:SI (match_operand:SI 1 "register_operand" "0")
6771 (match_operand:SI 2 "general_operand" "rim"))
6772 (const_int 0)))
6773 (set (match_operand:DI 0 "register_operand" "=r")
6774 (zero_extend:DI
6775 (minus:SI (match_dup 1)
6776 (match_dup 2))))]
6777 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6778 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779 "sub{l}\t{%2, %k0|%k0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "SI")])
6782
6783 (define_insn "*subsi_3"
6784 [(set (reg 17)
6785 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:SI 2 "general_operand" "ri,rm")))
6787 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6788 (minus:SI (match_dup 1) (match_dup 2)))]
6789 "ix86_match_ccmode (insn, CCmode)
6790 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6791 "sub{l}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "SI")])
6794
6795 (define_insn "*subsi_3_zext"
6796 [(set (reg 17)
6797 (compare (match_operand:SI 1 "register_operand" "0")
6798 (match_operand:SI 2 "general_operand" "rim")))
6799 (set (match_operand:DI 0 "register_operand" "=r")
6800 (zero_extend:DI
6801 (minus:SI (match_dup 1)
6802 (match_dup 2))))]
6803 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6804 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805 "sub{q}\t{%2, %0|%0, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "DI")])
6808
6809 (define_expand "subhi3"
6810 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6811 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6812 (match_operand:HI 2 "general_operand" "")))
6813 (clobber (reg:CC 17))])]
6814 "TARGET_HIMODE_MATH"
6815 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6816
6817 (define_insn "*subhi_1"
6818 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6819 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6820 (match_operand:HI 2 "general_operand" "ri,rm")))
6821 (clobber (reg:CC 17))]
6822 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6823 "sub{w}\t{%2, %0|%0, %2}"
6824 [(set_attr "type" "alu")
6825 (set_attr "mode" "HI")])
6826
6827 (define_insn "*subhi_2"
6828 [(set (reg 17)
6829 (compare
6830 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6831 (match_operand:HI 2 "general_operand" "ri,rm"))
6832 (const_int 0)))
6833 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6834 (minus:HI (match_dup 1) (match_dup 2)))]
6835 "ix86_match_ccmode (insn, CCGOCmode)
6836 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6837 "sub{w}\t{%2, %0|%0, %2}"
6838 [(set_attr "type" "alu")
6839 (set_attr "mode" "HI")])
6840
6841 (define_insn "*subhi_3"
6842 [(set (reg 17)
6843 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6844 (match_operand:HI 2 "general_operand" "ri,rm")))
6845 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6846 (minus:HI (match_dup 1) (match_dup 2)))]
6847 "ix86_match_ccmode (insn, CCmode)
6848 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6849 "sub{w}\t{%2, %0|%0, %2}"
6850 [(set_attr "type" "alu")
6851 (set_attr "mode" "HI")])
6852
6853 (define_expand "subqi3"
6854 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6855 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6856 (match_operand:QI 2 "general_operand" "")))
6857 (clobber (reg:CC 17))])]
6858 "TARGET_QIMODE_MATH"
6859 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6860
6861 (define_insn "*subqi_1"
6862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6863 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6864 (match_operand:QI 2 "general_operand" "qn,qmn")))
6865 (clobber (reg:CC 17))]
6866 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6867 "sub{b}\t{%2, %0|%0, %2}"
6868 [(set_attr "type" "alu")
6869 (set_attr "mode" "QI")])
6870
6871 (define_insn "*subqi_1_slp"
6872 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6873 (minus:QI (match_dup 0)
6874 (match_operand:QI 1 "general_operand" "qn,qmn")))
6875 (clobber (reg:CC 17))]
6876 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6877 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6878 "sub{b}\t{%1, %0|%0, %1}"
6879 [(set_attr "type" "alu1")
6880 (set_attr "mode" "QI")])
6881
6882 (define_insn "*subqi_2"
6883 [(set (reg 17)
6884 (compare
6885 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6886 (match_operand:QI 2 "general_operand" "qi,qm"))
6887 (const_int 0)))
6888 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6889 (minus:HI (match_dup 1) (match_dup 2)))]
6890 "ix86_match_ccmode (insn, CCGOCmode)
6891 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6892 "sub{b}\t{%2, %0|%0, %2}"
6893 [(set_attr "type" "alu")
6894 (set_attr "mode" "QI")])
6895
6896 (define_insn "*subqi_3"
6897 [(set (reg 17)
6898 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6899 (match_operand:QI 2 "general_operand" "qi,qm")))
6900 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6901 (minus:HI (match_dup 1) (match_dup 2)))]
6902 "ix86_match_ccmode (insn, CCmode)
6903 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6904 "sub{b}\t{%2, %0|%0, %2}"
6905 [(set_attr "type" "alu")
6906 (set_attr "mode" "QI")])
6907
6908 ;; The patterns that match these are at the end of this file.
6909
6910 (define_expand "subxf3"
6911 [(set (match_operand:XF 0 "register_operand" "")
6912 (minus:XF (match_operand:XF 1 "register_operand" "")
6913 (match_operand:XF 2 "register_operand" "")))]
6914 "TARGET_80387"
6915 "")
6916
6917 (define_expand "subdf3"
6918 [(set (match_operand:DF 0 "register_operand" "")
6919 (minus:DF (match_operand:DF 1 "register_operand" "")
6920 (match_operand:DF 2 "nonimmediate_operand" "")))]
6921 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6922 "")
6923
6924 (define_expand "subsf3"
6925 [(set (match_operand:SF 0 "register_operand" "")
6926 (minus:SF (match_operand:SF 1 "register_operand" "")
6927 (match_operand:SF 2 "nonimmediate_operand" "")))]
6928 "TARGET_80387 || TARGET_SSE_MATH"
6929 "")
6930 \f
6931 ;; Multiply instructions
6932
6933 (define_expand "muldi3"
6934 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6935 (mult:DI (match_operand:DI 1 "register_operand" "")
6936 (match_operand:DI 2 "x86_64_general_operand" "")))
6937 (clobber (reg:CC 17))])]
6938 "TARGET_64BIT"
6939 "")
6940
6941 (define_insn "*muldi3_1_rex64"
6942 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6943 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6944 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6945 (clobber (reg:CC 17))]
6946 "TARGET_64BIT
6947 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6948 "@
6949 imul{q}\t{%2, %1, %0|%0, %1, %2}
6950 imul{q}\t{%2, %1, %0|%0, %1, %2}
6951 imul{q}\t{%2, %0|%0, %2}"
6952 [(set_attr "type" "imul")
6953 (set_attr "prefix_0f" "0,0,1")
6954 (set (attr "athlon_decode")
6955 (cond [(eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (eq_attr "alternative" "1")
6958 (const_string "vector")
6959 (and (eq_attr "alternative" "2")
6960 (match_operand 1 "memory_operand" ""))
6961 (const_string "vector")]
6962 (const_string "direct")))
6963 (set_attr "mode" "DI")])
6964
6965 (define_expand "mulsi3"
6966 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6967 (mult:SI (match_operand:SI 1 "register_operand" "")
6968 (match_operand:SI 2 "general_operand" "")))
6969 (clobber (reg:CC 17))])]
6970 ""
6971 "")
6972
6973 (define_insn "*mulsi3_1"
6974 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6975 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6976 (match_operand:SI 2 "general_operand" "K,i,mr")))
6977 (clobber (reg:CC 17))]
6978 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6979 "@
6980 imul{l}\t{%2, %1, %0|%0, %1, %2}
6981 imul{l}\t{%2, %1, %0|%0, %1, %2}
6982 imul{l}\t{%2, %0|%0, %2}"
6983 [(set_attr "type" "imul")
6984 (set_attr "prefix_0f" "0,0,1")
6985 (set (attr "athlon_decode")
6986 (cond [(eq_attr "cpu" "athlon")
6987 (const_string "vector")
6988 (eq_attr "alternative" "1")
6989 (const_string "vector")
6990 (and (eq_attr "alternative" "2")
6991 (match_operand 1 "memory_operand" ""))
6992 (const_string "vector")]
6993 (const_string "direct")))
6994 (set_attr "mode" "SI")])
6995
6996 (define_insn "*mulsi3_1_zext"
6997 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6998 (zero_extend:DI
6999 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7000 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7001 (clobber (reg:CC 17))]
7002 "TARGET_64BIT
7003 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7004 "@
7005 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7006 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7007 imul{l}\t{%2, %k0|%k0, %2}"
7008 [(set_attr "type" "imul")
7009 (set_attr "prefix_0f" "0,0,1")
7010 (set (attr "athlon_decode")
7011 (cond [(eq_attr "cpu" "athlon")
7012 (const_string "vector")
7013 (eq_attr "alternative" "1")
7014 (const_string "vector")
7015 (and (eq_attr "alternative" "2")
7016 (match_operand 1 "memory_operand" ""))
7017 (const_string "vector")]
7018 (const_string "direct")))
7019 (set_attr "mode" "SI")])
7020
7021 (define_expand "mulhi3"
7022 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7023 (mult:HI (match_operand:HI 1 "register_operand" "")
7024 (match_operand:HI 2 "general_operand" "")))
7025 (clobber (reg:CC 17))])]
7026 "TARGET_HIMODE_MATH"
7027 "")
7028
7029 (define_insn "*mulhi3_1"
7030 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7031 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7032 (match_operand:HI 2 "general_operand" "K,i,mr")))
7033 (clobber (reg:CC 17))]
7034 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7035 "@
7036 imul{w}\t{%2, %1, %0|%0, %1, %2}
7037 imul{w}\t{%2, %1, %0|%0, %1, %2}
7038 imul{w}\t{%2, %0|%0, %2}"
7039 [(set_attr "type" "imul")
7040 (set_attr "prefix_0f" "0,0,1")
7041 (set (attr "athlon_decode")
7042 (cond [(eq_attr "cpu" "athlon")
7043 (const_string "vector")
7044 (eq_attr "alternative" "1,2")
7045 (const_string "vector")]
7046 (const_string "direct")))
7047 (set_attr "mode" "HI")])
7048
7049 (define_expand "mulqi3"
7050 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7051 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7052 (match_operand:QI 2 "register_operand" "")))
7053 (clobber (reg:CC 17))])]
7054 "TARGET_QIMODE_MATH"
7055 "")
7056
7057 (define_insn "*mulqi3_1"
7058 [(set (match_operand:QI 0 "register_operand" "=a")
7059 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7060 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7061 (clobber (reg:CC 17))]
7062 "TARGET_QIMODE_MATH
7063 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7064 "mul{b}\t%2"
7065 [(set_attr "type" "imul")
7066 (set_attr "length_immediate" "0")
7067 (set (attr "athlon_decode")
7068 (if_then_else (eq_attr "cpu" "athlon")
7069 (const_string "vector")
7070 (const_string "direct")))
7071 (set_attr "mode" "QI")])
7072
7073 (define_expand "umulqihi3"
7074 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7075 (mult:HI (zero_extend:HI
7076 (match_operand:QI 1 "nonimmediate_operand" ""))
7077 (zero_extend:HI
7078 (match_operand:QI 2 "register_operand" ""))))
7079 (clobber (reg:CC 17))])]
7080 "TARGET_QIMODE_MATH"
7081 "")
7082
7083 (define_insn "*umulqihi3_1"
7084 [(set (match_operand:HI 0 "register_operand" "=a")
7085 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7086 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7087 (clobber (reg:CC 17))]
7088 "TARGET_QIMODE_MATH
7089 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7090 "mul{b}\t%2"
7091 [(set_attr "type" "imul")
7092 (set_attr "length_immediate" "0")
7093 (set (attr "athlon_decode")
7094 (if_then_else (eq_attr "cpu" "athlon")
7095 (const_string "vector")
7096 (const_string "direct")))
7097 (set_attr "mode" "QI")])
7098
7099 (define_expand "mulqihi3"
7100 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7101 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7102 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7103 (clobber (reg:CC 17))])]
7104 "TARGET_QIMODE_MATH"
7105 "")
7106
7107 (define_insn "*mulqihi3_insn"
7108 [(set (match_operand:HI 0 "register_operand" "=a")
7109 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7110 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7111 (clobber (reg:CC 17))]
7112 "TARGET_QIMODE_MATH
7113 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7114 "imul{b}\t%2"
7115 [(set_attr "type" "imul")
7116 (set_attr "length_immediate" "0")
7117 (set (attr "athlon_decode")
7118 (if_then_else (eq_attr "cpu" "athlon")
7119 (const_string "vector")
7120 (const_string "direct")))
7121 (set_attr "mode" "QI")])
7122
7123 (define_expand "umulditi3"
7124 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7125 (mult:TI (zero_extend:TI
7126 (match_operand:DI 1 "nonimmediate_operand" ""))
7127 (zero_extend:TI
7128 (match_operand:DI 2 "register_operand" ""))))
7129 (clobber (reg:CC 17))])]
7130 "TARGET_64BIT"
7131 "")
7132
7133 (define_insn "*umulditi3_insn"
7134 [(set (match_operand:TI 0 "register_operand" "=A")
7135 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7136 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7137 (clobber (reg:CC 17))]
7138 "TARGET_64BIT
7139 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7140 "mul{q}\t%2"
7141 [(set_attr "type" "imul")
7142 (set_attr "ppro_uops" "few")
7143 (set_attr "length_immediate" "0")
7144 (set (attr "athlon_decode")
7145 (if_then_else (eq_attr "cpu" "athlon")
7146 (const_string "vector")
7147 (const_string "double")))
7148 (set_attr "mode" "DI")])
7149
7150 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7151 (define_expand "umulsidi3"
7152 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7153 (mult:DI (zero_extend:DI
7154 (match_operand:SI 1 "nonimmediate_operand" ""))
7155 (zero_extend:DI
7156 (match_operand:SI 2 "register_operand" ""))))
7157 (clobber (reg:CC 17))])]
7158 "!TARGET_64BIT"
7159 "")
7160
7161 (define_insn "*umulsidi3_insn"
7162 [(set (match_operand:DI 0 "register_operand" "=A")
7163 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7164 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7165 (clobber (reg:CC 17))]
7166 "!TARGET_64BIT
7167 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7168 "mul{l}\t%2"
7169 [(set_attr "type" "imul")
7170 (set_attr "ppro_uops" "few")
7171 (set_attr "length_immediate" "0")
7172 (set (attr "athlon_decode")
7173 (if_then_else (eq_attr "cpu" "athlon")
7174 (const_string "vector")
7175 (const_string "double")))
7176 (set_attr "mode" "SI")])
7177
7178 (define_expand "mulditi3"
7179 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7180 (mult:TI (sign_extend:TI
7181 (match_operand:DI 1 "nonimmediate_operand" ""))
7182 (sign_extend:TI
7183 (match_operand:DI 2 "register_operand" ""))))
7184 (clobber (reg:CC 17))])]
7185 "TARGET_64BIT"
7186 "")
7187
7188 (define_insn "*mulditi3_insn"
7189 [(set (match_operand:TI 0 "register_operand" "=A")
7190 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7191 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7192 (clobber (reg:CC 17))]
7193 "TARGET_64BIT
7194 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195 "imul{q}\t%2"
7196 [(set_attr "type" "imul")
7197 (set_attr "length_immediate" "0")
7198 (set (attr "athlon_decode")
7199 (if_then_else (eq_attr "cpu" "athlon")
7200 (const_string "vector")
7201 (const_string "double")))
7202 (set_attr "mode" "DI")])
7203
7204 (define_expand "mulsidi3"
7205 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7206 (mult:DI (sign_extend:DI
7207 (match_operand:SI 1 "nonimmediate_operand" ""))
7208 (sign_extend:DI
7209 (match_operand:SI 2 "register_operand" ""))))
7210 (clobber (reg:CC 17))])]
7211 "!TARGET_64BIT"
7212 "")
7213
7214 (define_insn "*mulsidi3_insn"
7215 [(set (match_operand:DI 0 "register_operand" "=A")
7216 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7217 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7218 (clobber (reg:CC 17))]
7219 "!TARGET_64BIT
7220 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7221 "imul{l}\t%2"
7222 [(set_attr "type" "imul")
7223 (set_attr "length_immediate" "0")
7224 (set (attr "athlon_decode")
7225 (if_then_else (eq_attr "cpu" "athlon")
7226 (const_string "vector")
7227 (const_string "double")))
7228 (set_attr "mode" "SI")])
7229
7230 (define_expand "umuldi3_highpart"
7231 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7232 (truncate:DI
7233 (lshiftrt:TI
7234 (mult:TI (zero_extend:TI
7235 (match_operand:DI 1 "nonimmediate_operand" ""))
7236 (zero_extend:TI
7237 (match_operand:DI 2 "register_operand" "")))
7238 (const_int 64))))
7239 (clobber (match_scratch:DI 3 ""))
7240 (clobber (reg:CC 17))])]
7241 "TARGET_64BIT"
7242 "")
7243
7244 (define_insn "*umuldi3_highpart_rex64"
7245 [(set (match_operand:DI 0 "register_operand" "=d")
7246 (truncate:DI
7247 (lshiftrt:TI
7248 (mult:TI (zero_extend:TI
7249 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7250 (zero_extend:TI
7251 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7252 (const_int 64))))
7253 (clobber (match_scratch:DI 3 "=1"))
7254 (clobber (reg:CC 17))]
7255 "TARGET_64BIT
7256 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7257 "mul{q}\t%2"
7258 [(set_attr "type" "imul")
7259 (set_attr "ppro_uops" "few")
7260 (set_attr "length_immediate" "0")
7261 (set (attr "athlon_decode")
7262 (if_then_else (eq_attr "cpu" "athlon")
7263 (const_string "vector")
7264 (const_string "double")))
7265 (set_attr "mode" "DI")])
7266
7267 (define_expand "umulsi3_highpart"
7268 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7269 (truncate:SI
7270 (lshiftrt:DI
7271 (mult:DI (zero_extend:DI
7272 (match_operand:SI 1 "nonimmediate_operand" ""))
7273 (zero_extend:DI
7274 (match_operand:SI 2 "register_operand" "")))
7275 (const_int 32))))
7276 (clobber (match_scratch:SI 3 ""))
7277 (clobber (reg:CC 17))])]
7278 ""
7279 "")
7280
7281 (define_insn "*umulsi3_highpart_insn"
7282 [(set (match_operand:SI 0 "register_operand" "=d")
7283 (truncate:SI
7284 (lshiftrt:DI
7285 (mult:DI (zero_extend:DI
7286 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7287 (zero_extend:DI
7288 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7289 (const_int 32))))
7290 (clobber (match_scratch:SI 3 "=1"))
7291 (clobber (reg:CC 17))]
7292 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7293 "mul{l}\t%2"
7294 [(set_attr "type" "imul")
7295 (set_attr "ppro_uops" "few")
7296 (set_attr "length_immediate" "0")
7297 (set (attr "athlon_decode")
7298 (if_then_else (eq_attr "cpu" "athlon")
7299 (const_string "vector")
7300 (const_string "double")))
7301 (set_attr "mode" "SI")])
7302
7303 (define_insn "*umulsi3_highpart_zext"
7304 [(set (match_operand:DI 0 "register_operand" "=d")
7305 (zero_extend:DI (truncate:SI
7306 (lshiftrt:DI
7307 (mult:DI (zero_extend:DI
7308 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7309 (zero_extend:DI
7310 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7311 (const_int 32)))))
7312 (clobber (match_scratch:SI 3 "=1"))
7313 (clobber (reg:CC 17))]
7314 "TARGET_64BIT
7315 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7316 "mul{l}\t%2"
7317 [(set_attr "type" "imul")
7318 (set_attr "ppro_uops" "few")
7319 (set_attr "length_immediate" "0")
7320 (set (attr "athlon_decode")
7321 (if_then_else (eq_attr "cpu" "athlon")
7322 (const_string "vector")
7323 (const_string "double")))
7324 (set_attr "mode" "SI")])
7325
7326 (define_expand "smuldi3_highpart"
7327 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7328 (truncate:DI
7329 (lshiftrt:TI
7330 (mult:TI (sign_extend:TI
7331 (match_operand:DI 1 "nonimmediate_operand" ""))
7332 (sign_extend:TI
7333 (match_operand:DI 2 "register_operand" "")))
7334 (const_int 64))))
7335 (clobber (match_scratch:DI 3 ""))
7336 (clobber (reg:CC 17))])]
7337 "TARGET_64BIT"
7338 "")
7339
7340 (define_insn "*smuldi3_highpart_rex64"
7341 [(set (match_operand:DI 0 "register_operand" "=d")
7342 (truncate:DI
7343 (lshiftrt:TI
7344 (mult:TI (sign_extend:TI
7345 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7346 (sign_extend:TI
7347 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7348 (const_int 64))))
7349 (clobber (match_scratch:DI 3 "=1"))
7350 (clobber (reg:CC 17))]
7351 "TARGET_64BIT
7352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7353 "imul{q}\t%2"
7354 [(set_attr "type" "imul")
7355 (set_attr "ppro_uops" "few")
7356 (set (attr "athlon_decode")
7357 (if_then_else (eq_attr "cpu" "athlon")
7358 (const_string "vector")
7359 (const_string "double")))
7360 (set_attr "mode" "DI")])
7361
7362 (define_expand "smulsi3_highpart"
7363 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7364 (truncate:SI
7365 (lshiftrt:DI
7366 (mult:DI (sign_extend:DI
7367 (match_operand:SI 1 "nonimmediate_operand" ""))
7368 (sign_extend:DI
7369 (match_operand:SI 2 "register_operand" "")))
7370 (const_int 32))))
7371 (clobber (match_scratch:SI 3 ""))
7372 (clobber (reg:CC 17))])]
7373 ""
7374 "")
7375
7376 (define_insn "*smulsi3_highpart_insn"
7377 [(set (match_operand:SI 0 "register_operand" "=d")
7378 (truncate:SI
7379 (lshiftrt:DI
7380 (mult:DI (sign_extend:DI
7381 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7382 (sign_extend:DI
7383 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7384 (const_int 32))))
7385 (clobber (match_scratch:SI 3 "=1"))
7386 (clobber (reg:CC 17))]
7387 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7388 "imul{l}\t%2"
7389 [(set_attr "type" "imul")
7390 (set_attr "ppro_uops" "few")
7391 (set (attr "athlon_decode")
7392 (if_then_else (eq_attr "cpu" "athlon")
7393 (const_string "vector")
7394 (const_string "double")))
7395 (set_attr "mode" "SI")])
7396
7397 (define_insn "*smulsi3_highpart_zext"
7398 [(set (match_operand:DI 0 "register_operand" "=d")
7399 (zero_extend:DI (truncate:SI
7400 (lshiftrt:DI
7401 (mult:DI (sign_extend:DI
7402 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7403 (sign_extend:DI
7404 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7405 (const_int 32)))))
7406 (clobber (match_scratch:SI 3 "=1"))
7407 (clobber (reg:CC 17))]
7408 "TARGET_64BIT
7409 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7410 "imul{l}\t%2"
7411 [(set_attr "type" "imul")
7412 (set_attr "ppro_uops" "few")
7413 (set (attr "athlon_decode")
7414 (if_then_else (eq_attr "cpu" "athlon")
7415 (const_string "vector")
7416 (const_string "double")))
7417 (set_attr "mode" "SI")])
7418
7419 ;; The patterns that match these are at the end of this file.
7420
7421 (define_expand "mulxf3"
7422 [(set (match_operand:XF 0 "register_operand" "")
7423 (mult:XF (match_operand:XF 1 "register_operand" "")
7424 (match_operand:XF 2 "register_operand" "")))]
7425 "TARGET_80387"
7426 "")
7427
7428 (define_expand "muldf3"
7429 [(set (match_operand:DF 0 "register_operand" "")
7430 (mult:DF (match_operand:DF 1 "register_operand" "")
7431 (match_operand:DF 2 "nonimmediate_operand" "")))]
7432 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7433 "")
7434
7435 (define_expand "mulsf3"
7436 [(set (match_operand:SF 0 "register_operand" "")
7437 (mult:SF (match_operand:SF 1 "register_operand" "")
7438 (match_operand:SF 2 "nonimmediate_operand" "")))]
7439 "TARGET_80387 || TARGET_SSE_MATH"
7440 "")
7441 \f
7442 ;; Divide instructions
7443
7444 (define_insn "divqi3"
7445 [(set (match_operand:QI 0 "register_operand" "=a")
7446 (div:QI (match_operand:HI 1 "register_operand" "0")
7447 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7448 (clobber (reg:CC 17))]
7449 "TARGET_QIMODE_MATH"
7450 "idiv{b}\t%2"
7451 [(set_attr "type" "idiv")
7452 (set_attr "mode" "QI")
7453 (set_attr "ppro_uops" "few")])
7454
7455 (define_insn "udivqi3"
7456 [(set (match_operand:QI 0 "register_operand" "=a")
7457 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7458 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7459 (clobber (reg:CC 17))]
7460 "TARGET_QIMODE_MATH"
7461 "div{b}\t%2"
7462 [(set_attr "type" "idiv")
7463 (set_attr "mode" "QI")
7464 (set_attr "ppro_uops" "few")])
7465
7466 ;; The patterns that match these are at the end of this file.
7467
7468 (define_expand "divxf3"
7469 [(set (match_operand:XF 0 "register_operand" "")
7470 (div:XF (match_operand:XF 1 "register_operand" "")
7471 (match_operand:XF 2 "register_operand" "")))]
7472 "TARGET_80387"
7473 "")
7474
7475 (define_expand "divdf3"
7476 [(set (match_operand:DF 0 "register_operand" "")
7477 (div:DF (match_operand:DF 1 "register_operand" "")
7478 (match_operand:DF 2 "nonimmediate_operand" "")))]
7479 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7480 "")
7481
7482 (define_expand "divsf3"
7483 [(set (match_operand:SF 0 "register_operand" "")
7484 (div:SF (match_operand:SF 1 "register_operand" "")
7485 (match_operand:SF 2 "nonimmediate_operand" "")))]
7486 "TARGET_80387 || TARGET_SSE_MATH"
7487 "")
7488 \f
7489 ;; Remainder instructions.
7490
7491 (define_expand "divmoddi4"
7492 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7493 (div:DI (match_operand:DI 1 "register_operand" "")
7494 (match_operand:DI 2 "nonimmediate_operand" "")))
7495 (set (match_operand:DI 3 "register_operand" "")
7496 (mod:DI (match_dup 1) (match_dup 2)))
7497 (clobber (reg:CC 17))])]
7498 "TARGET_64BIT"
7499 "")
7500
7501 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7502 ;; Penalize eax case slightly because it results in worse scheduling
7503 ;; of code.
7504 (define_insn "*divmoddi4_nocltd_rex64"
7505 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7506 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7507 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7508 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7509 (mod:DI (match_dup 2) (match_dup 3)))
7510 (clobber (reg:CC 17))]
7511 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7512 "#"
7513 [(set_attr "type" "multi")])
7514
7515 (define_insn "*divmoddi4_cltd_rex64"
7516 [(set (match_operand:DI 0 "register_operand" "=a")
7517 (div:DI (match_operand:DI 2 "register_operand" "a")
7518 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7519 (set (match_operand:DI 1 "register_operand" "=&d")
7520 (mod:DI (match_dup 2) (match_dup 3)))
7521 (clobber (reg:CC 17))]
7522 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7523 "#"
7524 [(set_attr "type" "multi")])
7525
7526 (define_insn "*divmoddi_noext_rex64"
7527 [(set (match_operand:DI 0 "register_operand" "=a")
7528 (div:DI (match_operand:DI 1 "register_operand" "0")
7529 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7530 (set (match_operand:DI 3 "register_operand" "=d")
7531 (mod:DI (match_dup 1) (match_dup 2)))
7532 (use (match_operand:DI 4 "register_operand" "3"))
7533 (clobber (reg:CC 17))]
7534 "TARGET_64BIT"
7535 "idiv{q}\t%2"
7536 [(set_attr "type" "idiv")
7537 (set_attr "mode" "DI")
7538 (set_attr "ppro_uops" "few")])
7539
7540 (define_split
7541 [(set (match_operand:DI 0 "register_operand" "")
7542 (div:DI (match_operand:DI 1 "register_operand" "")
7543 (match_operand:DI 2 "nonimmediate_operand" "")))
7544 (set (match_operand:DI 3 "register_operand" "")
7545 (mod:DI (match_dup 1) (match_dup 2)))
7546 (clobber (reg:CC 17))]
7547 "TARGET_64BIT && reload_completed"
7548 [(parallel [(set (match_dup 3)
7549 (ashiftrt:DI (match_dup 4) (const_int 63)))
7550 (clobber (reg:CC 17))])
7551 (parallel [(set (match_dup 0)
7552 (div:DI (reg:DI 0) (match_dup 2)))
7553 (set (match_dup 3)
7554 (mod:DI (reg:DI 0) (match_dup 2)))
7555 (use (match_dup 3))
7556 (clobber (reg:CC 17))])]
7557 {
7558 /* Avoid use of cltd in favor of a mov+shift. */
7559 if (!TARGET_USE_CLTD && !optimize_size)
7560 {
7561 if (true_regnum (operands[1]))
7562 emit_move_insn (operands[0], operands[1]);
7563 else
7564 emit_move_insn (operands[3], operands[1]);
7565 operands[4] = operands[3];
7566 }
7567 else
7568 {
7569 if (true_regnum (operands[1]))
7570 abort();
7571 operands[4] = operands[1];
7572 }
7573 })
7574
7575
7576 (define_expand "divmodsi4"
7577 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7578 (div:SI (match_operand:SI 1 "register_operand" "")
7579 (match_operand:SI 2 "nonimmediate_operand" "")))
7580 (set (match_operand:SI 3 "register_operand" "")
7581 (mod:SI (match_dup 1) (match_dup 2)))
7582 (clobber (reg:CC 17))])]
7583 ""
7584 "")
7585
7586 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7587 ;; Penalize eax case slightly because it results in worse scheduling
7588 ;; of code.
7589 (define_insn "*divmodsi4_nocltd"
7590 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7591 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7592 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7593 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7594 (mod:SI (match_dup 2) (match_dup 3)))
7595 (clobber (reg:CC 17))]
7596 "!optimize_size && !TARGET_USE_CLTD"
7597 "#"
7598 [(set_attr "type" "multi")])
7599
7600 (define_insn "*divmodsi4_cltd"
7601 [(set (match_operand:SI 0 "register_operand" "=a")
7602 (div:SI (match_operand:SI 2 "register_operand" "a")
7603 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7604 (set (match_operand:SI 1 "register_operand" "=&d")
7605 (mod:SI (match_dup 2) (match_dup 3)))
7606 (clobber (reg:CC 17))]
7607 "optimize_size || TARGET_USE_CLTD"
7608 "#"
7609 [(set_attr "type" "multi")])
7610
7611 (define_insn "*divmodsi_noext"
7612 [(set (match_operand:SI 0 "register_operand" "=a")
7613 (div:SI (match_operand:SI 1 "register_operand" "0")
7614 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7615 (set (match_operand:SI 3 "register_operand" "=d")
7616 (mod:SI (match_dup 1) (match_dup 2)))
7617 (use (match_operand:SI 4 "register_operand" "3"))
7618 (clobber (reg:CC 17))]
7619 ""
7620 "idiv{l}\t%2"
7621 [(set_attr "type" "idiv")
7622 (set_attr "mode" "SI")
7623 (set_attr "ppro_uops" "few")])
7624
7625 (define_split
7626 [(set (match_operand:SI 0 "register_operand" "")
7627 (div:SI (match_operand:SI 1 "register_operand" "")
7628 (match_operand:SI 2 "nonimmediate_operand" "")))
7629 (set (match_operand:SI 3 "register_operand" "")
7630 (mod:SI (match_dup 1) (match_dup 2)))
7631 (clobber (reg:CC 17))]
7632 "reload_completed"
7633 [(parallel [(set (match_dup 3)
7634 (ashiftrt:SI (match_dup 4) (const_int 31)))
7635 (clobber (reg:CC 17))])
7636 (parallel [(set (match_dup 0)
7637 (div:SI (reg:SI 0) (match_dup 2)))
7638 (set (match_dup 3)
7639 (mod:SI (reg:SI 0) (match_dup 2)))
7640 (use (match_dup 3))
7641 (clobber (reg:CC 17))])]
7642 {
7643 /* Avoid use of cltd in favor of a mov+shift. */
7644 if (!TARGET_USE_CLTD && !optimize_size)
7645 {
7646 if (true_regnum (operands[1]))
7647 emit_move_insn (operands[0], operands[1]);
7648 else
7649 emit_move_insn (operands[3], operands[1]);
7650 operands[4] = operands[3];
7651 }
7652 else
7653 {
7654 if (true_regnum (operands[1]))
7655 abort();
7656 operands[4] = operands[1];
7657 }
7658 })
7659 ;; %%% Split me.
7660 (define_insn "divmodhi4"
7661 [(set (match_operand:HI 0 "register_operand" "=a")
7662 (div:HI (match_operand:HI 1 "register_operand" "0")
7663 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7664 (set (match_operand:HI 3 "register_operand" "=&d")
7665 (mod:HI (match_dup 1) (match_dup 2)))
7666 (clobber (reg:CC 17))]
7667 "TARGET_HIMODE_MATH"
7668 "cwtd\;idiv{w}\t%2"
7669 [(set_attr "type" "multi")
7670 (set_attr "length_immediate" "0")
7671 (set_attr "mode" "SI")])
7672
7673 (define_insn "udivmoddi4"
7674 [(set (match_operand:DI 0 "register_operand" "=a")
7675 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7676 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7677 (set (match_operand:DI 3 "register_operand" "=&d")
7678 (umod:DI (match_dup 1) (match_dup 2)))
7679 (clobber (reg:CC 17))]
7680 "TARGET_64BIT"
7681 "xor{q}\t%3, %3\;div{q}\t%2"
7682 [(set_attr "type" "multi")
7683 (set_attr "length_immediate" "0")
7684 (set_attr "mode" "DI")])
7685
7686 (define_insn "*udivmoddi4_noext"
7687 [(set (match_operand:DI 0 "register_operand" "=a")
7688 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7689 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7690 (set (match_operand:DI 3 "register_operand" "=d")
7691 (umod:DI (match_dup 1) (match_dup 2)))
7692 (use (match_dup 3))
7693 (clobber (reg:CC 17))]
7694 "TARGET_64BIT"
7695 "div{q}\t%2"
7696 [(set_attr "type" "idiv")
7697 (set_attr "ppro_uops" "few")
7698 (set_attr "mode" "DI")])
7699
7700 (define_split
7701 [(set (match_operand:DI 0 "register_operand" "")
7702 (udiv:DI (match_operand:DI 1 "register_operand" "")
7703 (match_operand:DI 2 "nonimmediate_operand" "")))
7704 (set (match_operand:DI 3 "register_operand" "")
7705 (umod:DI (match_dup 1) (match_dup 2)))
7706 (clobber (reg:CC 17))]
7707 "TARGET_64BIT && reload_completed"
7708 [(set (match_dup 3) (const_int 0))
7709 (parallel [(set (match_dup 0)
7710 (udiv:DI (match_dup 1) (match_dup 2)))
7711 (set (match_dup 3)
7712 (umod:DI (match_dup 1) (match_dup 2)))
7713 (use (match_dup 3))
7714 (clobber (reg:CC 17))])]
7715 "")
7716
7717 (define_insn "udivmodsi4"
7718 [(set (match_operand:SI 0 "register_operand" "=a")
7719 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7720 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7721 (set (match_operand:SI 3 "register_operand" "=&d")
7722 (umod:SI (match_dup 1) (match_dup 2)))
7723 (clobber (reg:CC 17))]
7724 ""
7725 "xor{l}\t%3, %3\;div{l}\t%2"
7726 [(set_attr "type" "multi")
7727 (set_attr "length_immediate" "0")
7728 (set_attr "mode" "SI")])
7729
7730 (define_insn "*udivmodsi4_noext"
7731 [(set (match_operand:SI 0 "register_operand" "=a")
7732 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7733 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7734 (set (match_operand:SI 3 "register_operand" "=d")
7735 (umod:SI (match_dup 1) (match_dup 2)))
7736 (use (match_dup 3))
7737 (clobber (reg:CC 17))]
7738 ""
7739 "div{l}\t%2"
7740 [(set_attr "type" "idiv")
7741 (set_attr "ppro_uops" "few")
7742 (set_attr "mode" "SI")])
7743
7744 (define_split
7745 [(set (match_operand:SI 0 "register_operand" "")
7746 (udiv:SI (match_operand:SI 1 "register_operand" "")
7747 (match_operand:SI 2 "nonimmediate_operand" "")))
7748 (set (match_operand:SI 3 "register_operand" "")
7749 (umod:SI (match_dup 1) (match_dup 2)))
7750 (clobber (reg:CC 17))]
7751 "reload_completed"
7752 [(set (match_dup 3) (const_int 0))
7753 (parallel [(set (match_dup 0)
7754 (udiv:SI (match_dup 1) (match_dup 2)))
7755 (set (match_dup 3)
7756 (umod:SI (match_dup 1) (match_dup 2)))
7757 (use (match_dup 3))
7758 (clobber (reg:CC 17))])]
7759 "")
7760
7761 (define_expand "udivmodhi4"
7762 [(set (match_dup 4) (const_int 0))
7763 (parallel [(set (match_operand:HI 0 "register_operand" "")
7764 (udiv:HI (match_operand:HI 1 "register_operand" "")
7765 (match_operand:HI 2 "nonimmediate_operand" "")))
7766 (set (match_operand:HI 3 "register_operand" "")
7767 (umod:HI (match_dup 1) (match_dup 2)))
7768 (use (match_dup 4))
7769 (clobber (reg:CC 17))])]
7770 "TARGET_HIMODE_MATH"
7771 "operands[4] = gen_reg_rtx (HImode);")
7772
7773 (define_insn "*udivmodhi_noext"
7774 [(set (match_operand:HI 0 "register_operand" "=a")
7775 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7776 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7777 (set (match_operand:HI 3 "register_operand" "=d")
7778 (umod:HI (match_dup 1) (match_dup 2)))
7779 (use (match_operand:HI 4 "register_operand" "3"))
7780 (clobber (reg:CC 17))]
7781 ""
7782 "div{w}\t%2"
7783 [(set_attr "type" "idiv")
7784 (set_attr "mode" "HI")
7785 (set_attr "ppro_uops" "few")])
7786
7787 ;; We can not use div/idiv for double division, because it causes
7788 ;; "division by zero" on the overflow and that's not what we expect
7789 ;; from truncate. Because true (non truncating) double division is
7790 ;; never generated, we can't create this insn anyway.
7791 ;
7792 ;(define_insn ""
7793 ; [(set (match_operand:SI 0 "register_operand" "=a")
7794 ; (truncate:SI
7795 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7796 ; (zero_extend:DI
7797 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7798 ; (set (match_operand:SI 3 "register_operand" "=d")
7799 ; (truncate:SI
7800 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7801 ; (clobber (reg:CC 17))]
7802 ; ""
7803 ; "div{l}\t{%2, %0|%0, %2}"
7804 ; [(set_attr "type" "idiv")
7805 ; (set_attr "ppro_uops" "few")])
7806 \f
7807 ;;- Logical AND instructions
7808
7809 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7810 ;; Note that this excludes ah.
7811
7812 (define_insn "*testdi_1_rex64"
7813 [(set (reg 17)
7814 (compare
7815 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7816 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7817 (const_int 0)))]
7818 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7820 "@
7821 test{l}\t{%k1, %k0|%k0, %k1}
7822 test{l}\t{%k1, %k0|%k0, %k1}
7823 test{q}\t{%1, %0|%0, %1}
7824 test{q}\t{%1, %0|%0, %1}
7825 test{q}\t{%1, %0|%0, %1}"
7826 [(set_attr "type" "test")
7827 (set_attr "modrm" "0,1,0,1,1")
7828 (set_attr "mode" "SI,SI,DI,DI,DI")
7829 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7830
7831 (define_insn "testsi_1"
7832 [(set (reg 17)
7833 (compare
7834 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7835 (match_operand:SI 1 "general_operand" "in,in,rin"))
7836 (const_int 0)))]
7837 "ix86_match_ccmode (insn, CCNOmode)
7838 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7839 "test{l}\t{%1, %0|%0, %1}"
7840 [(set_attr "type" "test")
7841 (set_attr "modrm" "0,1,1")
7842 (set_attr "mode" "SI")
7843 (set_attr "pent_pair" "uv,np,uv")])
7844
7845 (define_expand "testsi_ccno_1"
7846 [(set (reg:CCNO 17)
7847 (compare:CCNO
7848 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7849 (match_operand:SI 1 "nonmemory_operand" ""))
7850 (const_int 0)))]
7851 ""
7852 "")
7853
7854 (define_insn "*testhi_1"
7855 [(set (reg 17)
7856 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7857 (match_operand:HI 1 "general_operand" "n,n,rn"))
7858 (const_int 0)))]
7859 "ix86_match_ccmode (insn, CCNOmode)
7860 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7861 "test{w}\t{%1, %0|%0, %1}"
7862 [(set_attr "type" "test")
7863 (set_attr "modrm" "0,1,1")
7864 (set_attr "mode" "HI")
7865 (set_attr "pent_pair" "uv,np,uv")])
7866
7867 (define_expand "testqi_ccz_1"
7868 [(set (reg:CCZ 17)
7869 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7870 (match_operand:QI 1 "nonmemory_operand" ""))
7871 (const_int 0)))]
7872 ""
7873 "")
7874
7875 (define_insn "*testqi_1"
7876 [(set (reg 17)
7877 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7878 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7879 (const_int 0)))]
7880 "ix86_match_ccmode (insn, CCNOmode)
7881 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7882 {
7883 if (which_alternative == 3)
7884 {
7885 if (GET_CODE (operands[1]) == CONST_INT
7886 && (INTVAL (operands[1]) & 0xffffff00))
7887 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7888 return "test{l}\t{%1, %k0|%k0, %1}";
7889 }
7890 return "test{b}\t{%1, %0|%0, %1}";
7891 }
7892 [(set_attr "type" "test")
7893 (set_attr "modrm" "0,1,1,1")
7894 (set_attr "mode" "QI,QI,QI,SI")
7895 (set_attr "pent_pair" "uv,np,uv,np")])
7896
7897 (define_expand "testqi_ext_ccno_0"
7898 [(set (reg:CCNO 17)
7899 (compare:CCNO
7900 (and:SI
7901 (zero_extract:SI
7902 (match_operand 0 "ext_register_operand" "")
7903 (const_int 8)
7904 (const_int 8))
7905 (match_operand 1 "const_int_operand" ""))
7906 (const_int 0)))]
7907 ""
7908 "")
7909
7910 (define_insn "*testqi_ext_0"
7911 [(set (reg 17)
7912 (compare
7913 (and:SI
7914 (zero_extract:SI
7915 (match_operand 0 "ext_register_operand" "Q")
7916 (const_int 8)
7917 (const_int 8))
7918 (match_operand 1 "const_int_operand" "n"))
7919 (const_int 0)))]
7920 "ix86_match_ccmode (insn, CCNOmode)"
7921 "test{b}\t{%1, %h0|%h0, %1}"
7922 [(set_attr "type" "test")
7923 (set_attr "mode" "QI")
7924 (set_attr "length_immediate" "1")
7925 (set_attr "pent_pair" "np")])
7926
7927 (define_insn "*testqi_ext_1"
7928 [(set (reg 17)
7929 (compare
7930 (and:SI
7931 (zero_extract:SI
7932 (match_operand 0 "ext_register_operand" "Q")
7933 (const_int 8)
7934 (const_int 8))
7935 (zero_extend:SI
7936 (match_operand:QI 1 "general_operand" "Qm")))
7937 (const_int 0)))]
7938 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7939 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7940 "test{b}\t{%1, %h0|%h0, %1}"
7941 [(set_attr "type" "test")
7942 (set_attr "mode" "QI")])
7943
7944 (define_insn "*testqi_ext_1_rex64"
7945 [(set (reg 17)
7946 (compare
7947 (and:SI
7948 (zero_extract:SI
7949 (match_operand 0 "ext_register_operand" "Q")
7950 (const_int 8)
7951 (const_int 8))
7952 (zero_extend:SI
7953 (match_operand:QI 1 "register_operand" "Q")))
7954 (const_int 0)))]
7955 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7956 "test{b}\t{%1, %h0|%h0, %1}"
7957 [(set_attr "type" "test")
7958 (set_attr "mode" "QI")])
7959
7960 (define_insn "*testqi_ext_2"
7961 [(set (reg 17)
7962 (compare
7963 (and:SI
7964 (zero_extract:SI
7965 (match_operand 0 "ext_register_operand" "Q")
7966 (const_int 8)
7967 (const_int 8))
7968 (zero_extract:SI
7969 (match_operand 1 "ext_register_operand" "Q")
7970 (const_int 8)
7971 (const_int 8)))
7972 (const_int 0)))]
7973 "ix86_match_ccmode (insn, CCNOmode)"
7974 "test{b}\t{%h1, %h0|%h0, %h1}"
7975 [(set_attr "type" "test")
7976 (set_attr "mode" "QI")])
7977
7978 ;; Combine likes to form bit extractions for some tests. Humor it.
7979 (define_insn "*testqi_ext_3"
7980 [(set (reg 17)
7981 (compare (zero_extract:SI
7982 (match_operand 0 "nonimmediate_operand" "rm")
7983 (match_operand:SI 1 "const_int_operand" "")
7984 (match_operand:SI 2 "const_int_operand" ""))
7985 (const_int 0)))]
7986 "ix86_match_ccmode (insn, CCNOmode)
7987 && (GET_MODE (operands[0]) == SImode
7988 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7989 || GET_MODE (operands[0]) == HImode
7990 || GET_MODE (operands[0]) == QImode)"
7991 "#")
7992
7993 (define_insn "*testqi_ext_3_rex64"
7994 [(set (reg 17)
7995 (compare (zero_extract:DI
7996 (match_operand 0 "nonimmediate_operand" "rm")
7997 (match_operand:DI 1 "const_int_operand" "")
7998 (match_operand:DI 2 "const_int_operand" ""))
7999 (const_int 0)))]
8000 "TARGET_64BIT
8001 && ix86_match_ccmode (insn, CCNOmode)
8002 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8003 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8004 /* Ensure that resulting mask is zero or sign extended operand. */
8005 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8006 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8007 && INTVAL (operands[1]) > 32))
8008 && (GET_MODE (operands[0]) == SImode
8009 || GET_MODE (operands[0]) == DImode
8010 || GET_MODE (operands[0]) == HImode
8011 || GET_MODE (operands[0]) == QImode)"
8012 "#")
8013
8014 (define_split
8015 [(set (reg 17)
8016 (compare (zero_extract
8017 (match_operand 0 "nonimmediate_operand" "")
8018 (match_operand 1 "const_int_operand" "")
8019 (match_operand 2 "const_int_operand" ""))
8020 (const_int 0)))]
8021 "ix86_match_ccmode (insn, CCNOmode)"
8022 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8023 {
8024 HOST_WIDE_INT len = INTVAL (operands[1]);
8025 HOST_WIDE_INT pos = INTVAL (operands[2]);
8026 HOST_WIDE_INT mask;
8027 enum machine_mode mode, submode;
8028
8029 mode = GET_MODE (operands[0]);
8030 if (GET_CODE (operands[0]) == MEM)
8031 {
8032 /* ??? Combine likes to put non-volatile mem extractions in QImode
8033 no matter the size of the test. So find a mode that works. */
8034 if (! MEM_VOLATILE_P (operands[0]))
8035 {
8036 mode = smallest_mode_for_size (pos + len, MODE_INT);
8037 operands[0] = adjust_address (operands[0], mode, 0);
8038 }
8039 }
8040 else if (GET_CODE (operands[0]) == SUBREG
8041 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8042 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8043 && pos + len <= GET_MODE_BITSIZE (submode))
8044 {
8045 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8046 mode = submode;
8047 operands[0] = SUBREG_REG (operands[0]);
8048 }
8049 else if (mode == HImode && pos + len <= 8)
8050 {
8051 /* Small HImode tests can be converted to QImode. */
8052 mode = QImode;
8053 operands[0] = gen_lowpart (QImode, operands[0]);
8054 }
8055
8056 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8057 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8058
8059 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8060 })
8061
8062 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8063 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8064 ;; this is relatively important trick.
8065 ;; Do the conversion only post-reload to avoid limiting of the register class
8066 ;; to QI regs.
8067 (define_split
8068 [(set (reg 17)
8069 (compare
8070 (and (match_operand 0 "register_operand" "")
8071 (match_operand 1 "const_int_operand" ""))
8072 (const_int 0)))]
8073 "reload_completed
8074 && QI_REG_P (operands[0])
8075 && ((ix86_match_ccmode (insn, CCZmode)
8076 && !(INTVAL (operands[1]) & ~(255 << 8)))
8077 || (ix86_match_ccmode (insn, CCNOmode)
8078 && !(INTVAL (operands[1]) & ~(127 << 8))))
8079 && GET_MODE (operands[0]) != QImode"
8080 [(set (reg:CCNO 17)
8081 (compare:CCNO
8082 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8083 (match_dup 1))
8084 (const_int 0)))]
8085 "operands[0] = gen_lowpart (SImode, operands[0]);
8086 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8087
8088 (define_split
8089 [(set (reg 17)
8090 (compare
8091 (and (match_operand 0 "nonimmediate_operand" "")
8092 (match_operand 1 "const_int_operand" ""))
8093 (const_int 0)))]
8094 "reload_completed
8095 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8096 && ((ix86_match_ccmode (insn, CCZmode)
8097 && !(INTVAL (operands[1]) & ~255))
8098 || (ix86_match_ccmode (insn, CCNOmode)
8099 && !(INTVAL (operands[1]) & ~127)))
8100 && GET_MODE (operands[0]) != QImode"
8101 [(set (reg:CCNO 17)
8102 (compare:CCNO
8103 (and:QI (match_dup 0)
8104 (match_dup 1))
8105 (const_int 0)))]
8106 "operands[0] = gen_lowpart (QImode, operands[0]);
8107 operands[1] = gen_lowpart (QImode, operands[1]);")
8108
8109
8110 ;; %%% This used to optimize known byte-wide and operations to memory,
8111 ;; and sometimes to QImode registers. If this is considered useful,
8112 ;; it should be done with splitters.
8113
8114 (define_expand "anddi3"
8115 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8116 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8117 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8118 (clobber (reg:CC 17))]
8119 "TARGET_64BIT"
8120 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8121
8122 (define_insn "*anddi_1_rex64"
8123 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8124 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8125 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8126 (clobber (reg:CC 17))]
8127 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8128 {
8129 switch (get_attr_type (insn))
8130 {
8131 case TYPE_IMOVX:
8132 {
8133 enum machine_mode mode;
8134
8135 if (GET_CODE (operands[2]) != CONST_INT)
8136 abort ();
8137 if (INTVAL (operands[2]) == 0xff)
8138 mode = QImode;
8139 else if (INTVAL (operands[2]) == 0xffff)
8140 mode = HImode;
8141 else
8142 abort ();
8143
8144 operands[1] = gen_lowpart (mode, operands[1]);
8145 if (mode == QImode)
8146 return "movz{bq|x}\t{%1,%0|%0, %1}";
8147 else
8148 return "movz{wq|x}\t{%1,%0|%0, %1}";
8149 }
8150
8151 default:
8152 if (! rtx_equal_p (operands[0], operands[1]))
8153 abort ();
8154 if (get_attr_mode (insn) == MODE_SI)
8155 return "and{l}\t{%k2, %k0|%k0, %k2}";
8156 else
8157 return "and{q}\t{%2, %0|%0, %2}";
8158 }
8159 }
8160 [(set_attr "type" "alu,alu,alu,imovx")
8161 (set_attr "length_immediate" "*,*,*,0")
8162 (set_attr "mode" "SI,DI,DI,DI")])
8163
8164 (define_insn "*anddi_2"
8165 [(set (reg 17)
8166 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8167 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8168 (const_int 0)))
8169 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8170 (and:DI (match_dup 1) (match_dup 2)))]
8171 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8172 && ix86_binary_operator_ok (AND, DImode, operands)"
8173 "@
8174 and{l}\t{%k2, %k0|%k0, %k2}
8175 and{q}\t{%2, %0|%0, %2}
8176 and{q}\t{%2, %0|%0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "mode" "SI,DI,DI")])
8179
8180 (define_expand "andsi3"
8181 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8182 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8183 (match_operand:SI 2 "general_operand" "")))
8184 (clobber (reg:CC 17))]
8185 ""
8186 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8187
8188 (define_insn "*andsi_1"
8189 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8190 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8191 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8192 (clobber (reg:CC 17))]
8193 "ix86_binary_operator_ok (AND, SImode, operands)"
8194 {
8195 switch (get_attr_type (insn))
8196 {
8197 case TYPE_IMOVX:
8198 {
8199 enum machine_mode mode;
8200
8201 if (GET_CODE (operands[2]) != CONST_INT)
8202 abort ();
8203 if (INTVAL (operands[2]) == 0xff)
8204 mode = QImode;
8205 else if (INTVAL (operands[2]) == 0xffff)
8206 mode = HImode;
8207 else
8208 abort ();
8209
8210 operands[1] = gen_lowpart (mode, operands[1]);
8211 if (mode == QImode)
8212 return "movz{bl|x}\t{%1,%0|%0, %1}";
8213 else
8214 return "movz{wl|x}\t{%1,%0|%0, %1}";
8215 }
8216
8217 default:
8218 if (! rtx_equal_p (operands[0], operands[1]))
8219 abort ();
8220 return "and{l}\t{%2, %0|%0, %2}";
8221 }
8222 }
8223 [(set_attr "type" "alu,alu,imovx")
8224 (set_attr "length_immediate" "*,*,0")
8225 (set_attr "mode" "SI")])
8226
8227 (define_split
8228 [(set (match_operand 0 "register_operand" "")
8229 (and (match_dup 0)
8230 (const_int -65536)))
8231 (clobber (reg:CC 17))]
8232 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8233 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8234 "operands[1] = gen_lowpart (HImode, operands[0]);")
8235
8236 (define_split
8237 [(set (match_operand 0 "ext_register_operand" "")
8238 (and (match_dup 0)
8239 (const_int -256)))
8240 (clobber (reg:CC 17))]
8241 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8242 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8243 "operands[1] = gen_lowpart (QImode, operands[0]);")
8244
8245 (define_split
8246 [(set (match_operand 0 "ext_register_operand" "")
8247 (and (match_dup 0)
8248 (const_int -65281)))
8249 (clobber (reg:CC 17))]
8250 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8251 [(parallel [(set (zero_extract:SI (match_dup 0)
8252 (const_int 8)
8253 (const_int 8))
8254 (xor:SI
8255 (zero_extract:SI (match_dup 0)
8256 (const_int 8)
8257 (const_int 8))
8258 (zero_extract:SI (match_dup 0)
8259 (const_int 8)
8260 (const_int 8))))
8261 (clobber (reg:CC 17))])]
8262 "operands[0] = gen_lowpart (SImode, operands[0]);")
8263
8264 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8265 (define_insn "*andsi_1_zext"
8266 [(set (match_operand:DI 0 "register_operand" "=r")
8267 (zero_extend:DI
8268 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8269 (match_operand:SI 2 "general_operand" "rim"))))
8270 (clobber (reg:CC 17))]
8271 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8272 "and{l}\t{%2, %k0|%k0, %2}"
8273 [(set_attr "type" "alu")
8274 (set_attr "mode" "SI")])
8275
8276 (define_insn "*andsi_2"
8277 [(set (reg 17)
8278 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8279 (match_operand:SI 2 "general_operand" "rim,ri"))
8280 (const_int 0)))
8281 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8282 (and:SI (match_dup 1) (match_dup 2)))]
8283 "ix86_match_ccmode (insn, CCNOmode)
8284 && ix86_binary_operator_ok (AND, SImode, operands)"
8285 "and{l}\t{%2, %0|%0, %2}"
8286 [(set_attr "type" "alu")
8287 (set_attr "mode" "SI")])
8288
8289 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8290 (define_insn "*andsi_2_zext"
8291 [(set (reg 17)
8292 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8293 (match_operand:SI 2 "general_operand" "rim"))
8294 (const_int 0)))
8295 (set (match_operand:DI 0 "register_operand" "=r")
8296 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8297 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8298 && ix86_binary_operator_ok (AND, SImode, operands)"
8299 "and{l}\t{%2, %k0|%k0, %2}"
8300 [(set_attr "type" "alu")
8301 (set_attr "mode" "SI")])
8302
8303 (define_expand "andhi3"
8304 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8305 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8306 (match_operand:HI 2 "general_operand" "")))
8307 (clobber (reg:CC 17))]
8308 "TARGET_HIMODE_MATH"
8309 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8310
8311 (define_insn "*andhi_1"
8312 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8313 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8314 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8315 (clobber (reg:CC 17))]
8316 "ix86_binary_operator_ok (AND, HImode, operands)"
8317 {
8318 switch (get_attr_type (insn))
8319 {
8320 case TYPE_IMOVX:
8321 if (GET_CODE (operands[2]) != CONST_INT)
8322 abort ();
8323 if (INTVAL (operands[2]) == 0xff)
8324 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8325 abort ();
8326
8327 default:
8328 if (! rtx_equal_p (operands[0], operands[1]))
8329 abort ();
8330
8331 return "and{w}\t{%2, %0|%0, %2}";
8332 }
8333 }
8334 [(set_attr "type" "alu,alu,imovx")
8335 (set_attr "length_immediate" "*,*,0")
8336 (set_attr "mode" "HI,HI,SI")])
8337
8338 (define_insn "*andhi_2"
8339 [(set (reg 17)
8340 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8341 (match_operand:HI 2 "general_operand" "rim,ri"))
8342 (const_int 0)))
8343 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8344 (and:HI (match_dup 1) (match_dup 2)))]
8345 "ix86_match_ccmode (insn, CCNOmode)
8346 && ix86_binary_operator_ok (AND, HImode, operands)"
8347 "and{w}\t{%2, %0|%0, %2}"
8348 [(set_attr "type" "alu")
8349 (set_attr "mode" "HI")])
8350
8351 (define_expand "andqi3"
8352 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8353 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8354 (match_operand:QI 2 "general_operand" "")))
8355 (clobber (reg:CC 17))]
8356 "TARGET_QIMODE_MATH"
8357 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8358
8359 ;; %%% Potential partial reg stall on alternative 2. What to do?
8360 (define_insn "*andqi_1"
8361 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8362 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8363 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8364 (clobber (reg:CC 17))]
8365 "ix86_binary_operator_ok (AND, QImode, operands)"
8366 "@
8367 and{b}\t{%2, %0|%0, %2}
8368 and{b}\t{%2, %0|%0, %2}
8369 and{l}\t{%k2, %k0|%k0, %k2}"
8370 [(set_attr "type" "alu")
8371 (set_attr "mode" "QI,QI,SI")])
8372
8373 (define_insn "*andqi_1_slp"
8374 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8375 (and:QI (match_dup 0)
8376 (match_operand:QI 1 "general_operand" "qi,qmi")))
8377 (clobber (reg:CC 17))]
8378 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8379 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8380 "and{b}\t{%1, %0|%0, %1}"
8381 [(set_attr "type" "alu1")
8382 (set_attr "mode" "QI")])
8383
8384 (define_insn "*andqi_2"
8385 [(set (reg 17)
8386 (compare (and:QI
8387 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8388 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8389 (const_int 0)))
8390 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8391 (and:QI (match_dup 1) (match_dup 2)))]
8392 "ix86_match_ccmode (insn, CCNOmode)
8393 && ix86_binary_operator_ok (AND, QImode, operands)"
8394 {
8395 if (which_alternative == 2)
8396 {
8397 if (GET_CODE (operands[2]) == CONST_INT
8398 && (INTVAL (operands[2]) & 0xffffff00))
8399 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8400 return "and{l}\t{%2, %k0|%k0, %2}";
8401 }
8402 return "and{b}\t{%2, %0|%0, %2}";
8403 }
8404 [(set_attr "type" "alu")
8405 (set_attr "mode" "QI,QI,SI")])
8406
8407 (define_insn "*andqi_2_slp"
8408 [(set (reg 17)
8409 (compare (and:QI
8410 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8411 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8412 (const_int 0)))
8413 (set (strict_low_part (match_dup 0))
8414 (and:QI (match_dup 0) (match_dup 1)))]
8415 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8416 && ix86_match_ccmode (insn, CCNOmode)
8417 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8418 "and{b}\t{%1, %0|%0, %1}"
8419 [(set_attr "type" "alu1")
8420 (set_attr "mode" "QI")])
8421
8422 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8423 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8424 ;; for a QImode operand, which of course failed.
8425
8426 (define_insn "andqi_ext_0"
8427 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8428 (const_int 8)
8429 (const_int 8))
8430 (and:SI
8431 (zero_extract:SI
8432 (match_operand 1 "ext_register_operand" "0")
8433 (const_int 8)
8434 (const_int 8))
8435 (match_operand 2 "const_int_operand" "n")))
8436 (clobber (reg:CC 17))]
8437 ""
8438 "and{b}\t{%2, %h0|%h0, %2}"
8439 [(set_attr "type" "alu")
8440 (set_attr "length_immediate" "1")
8441 (set_attr "mode" "QI")])
8442
8443 ;; Generated by peephole translating test to and. This shows up
8444 ;; often in fp comparisons.
8445
8446 (define_insn "*andqi_ext_0_cc"
8447 [(set (reg 17)
8448 (compare
8449 (and:SI
8450 (zero_extract:SI
8451 (match_operand 1 "ext_register_operand" "0")
8452 (const_int 8)
8453 (const_int 8))
8454 (match_operand 2 "const_int_operand" "n"))
8455 (const_int 0)))
8456 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8457 (const_int 8)
8458 (const_int 8))
8459 (and:SI
8460 (zero_extract:SI
8461 (match_dup 1)
8462 (const_int 8)
8463 (const_int 8))
8464 (match_dup 2)))]
8465 "ix86_match_ccmode (insn, CCNOmode)"
8466 "and{b}\t{%2, %h0|%h0, %2}"
8467 [(set_attr "type" "alu")
8468 (set_attr "length_immediate" "1")
8469 (set_attr "mode" "QI")])
8470
8471 (define_insn "*andqi_ext_1"
8472 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8473 (const_int 8)
8474 (const_int 8))
8475 (and:SI
8476 (zero_extract:SI
8477 (match_operand 1 "ext_register_operand" "0")
8478 (const_int 8)
8479 (const_int 8))
8480 (zero_extend:SI
8481 (match_operand:QI 2 "general_operand" "Qm"))))
8482 (clobber (reg:CC 17))]
8483 "!TARGET_64BIT"
8484 "and{b}\t{%2, %h0|%h0, %2}"
8485 [(set_attr "type" "alu")
8486 (set_attr "length_immediate" "0")
8487 (set_attr "mode" "QI")])
8488
8489 (define_insn "*andqi_ext_1_rex64"
8490 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8491 (const_int 8)
8492 (const_int 8))
8493 (and:SI
8494 (zero_extract:SI
8495 (match_operand 1 "ext_register_operand" "0")
8496 (const_int 8)
8497 (const_int 8))
8498 (zero_extend:SI
8499 (match_operand 2 "ext_register_operand" "Q"))))
8500 (clobber (reg:CC 17))]
8501 "TARGET_64BIT"
8502 "and{b}\t{%2, %h0|%h0, %2}"
8503 [(set_attr "type" "alu")
8504 (set_attr "length_immediate" "0")
8505 (set_attr "mode" "QI")])
8506
8507 (define_insn "*andqi_ext_2"
8508 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8509 (const_int 8)
8510 (const_int 8))
8511 (and:SI
8512 (zero_extract:SI
8513 (match_operand 1 "ext_register_operand" "%0")
8514 (const_int 8)
8515 (const_int 8))
8516 (zero_extract:SI
8517 (match_operand 2 "ext_register_operand" "Q")
8518 (const_int 8)
8519 (const_int 8))))
8520 (clobber (reg:CC 17))]
8521 ""
8522 "and{b}\t{%h2, %h0|%h0, %h2}"
8523 [(set_attr "type" "alu")
8524 (set_attr "length_immediate" "0")
8525 (set_attr "mode" "QI")])
8526
8527 ;; Convert wide AND instructions with immediate operand to shorter QImode
8528 ;; equivalents when possible.
8529 ;; Don't do the splitting with memory operands, since it introduces risk
8530 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8531 ;; for size, but that can (should?) be handled by generic code instead.
8532 (define_split
8533 [(set (match_operand 0 "register_operand" "")
8534 (and (match_operand 1 "register_operand" "")
8535 (match_operand 2 "const_int_operand" "")))
8536 (clobber (reg:CC 17))]
8537 "reload_completed
8538 && QI_REG_P (operands[0])
8539 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8540 && !(~INTVAL (operands[2]) & ~(255 << 8))
8541 && GET_MODE (operands[0]) != QImode"
8542 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8543 (and:SI (zero_extract:SI (match_dup 1)
8544 (const_int 8) (const_int 8))
8545 (match_dup 2)))
8546 (clobber (reg:CC 17))])]
8547 "operands[0] = gen_lowpart (SImode, operands[0]);
8548 operands[1] = gen_lowpart (SImode, operands[1]);
8549 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8550
8551 ;; Since AND can be encoded with sign extended immediate, this is only
8552 ;; profitable when 7th bit is not set.
8553 (define_split
8554 [(set (match_operand 0 "register_operand" "")
8555 (and (match_operand 1 "general_operand" "")
8556 (match_operand 2 "const_int_operand" "")))
8557 (clobber (reg:CC 17))]
8558 "reload_completed
8559 && ANY_QI_REG_P (operands[0])
8560 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8561 && !(~INTVAL (operands[2]) & ~255)
8562 && !(INTVAL (operands[2]) & 128)
8563 && GET_MODE (operands[0]) != QImode"
8564 [(parallel [(set (strict_low_part (match_dup 0))
8565 (and:QI (match_dup 1)
8566 (match_dup 2)))
8567 (clobber (reg:CC 17))])]
8568 "operands[0] = gen_lowpart (QImode, operands[0]);
8569 operands[1] = gen_lowpart (QImode, operands[1]);
8570 operands[2] = gen_lowpart (QImode, operands[2]);")
8571 \f
8572 ;; Logical inclusive OR instructions
8573
8574 ;; %%% This used to optimize known byte-wide and operations to memory.
8575 ;; If this is considered useful, it should be done with splitters.
8576
8577 (define_expand "iordi3"
8578 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8579 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8580 (match_operand:DI 2 "x86_64_general_operand" "")))
8581 (clobber (reg:CC 17))]
8582 "TARGET_64BIT"
8583 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8584
8585 (define_insn "*iordi_1_rex64"
8586 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8587 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8588 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8589 (clobber (reg:CC 17))]
8590 "TARGET_64BIT
8591 && ix86_binary_operator_ok (IOR, DImode, operands)"
8592 "or{q}\t{%2, %0|%0, %2}"
8593 [(set_attr "type" "alu")
8594 (set_attr "mode" "DI")])
8595
8596 (define_insn "*iordi_2_rex64"
8597 [(set (reg 17)
8598 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8599 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8600 (const_int 0)))
8601 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8602 (ior:DI (match_dup 1) (match_dup 2)))]
8603 "TARGET_64BIT
8604 && ix86_match_ccmode (insn, CCNOmode)
8605 && ix86_binary_operator_ok (IOR, DImode, operands)"
8606 "or{q}\t{%2, %0|%0, %2}"
8607 [(set_attr "type" "alu")
8608 (set_attr "mode" "DI")])
8609
8610 (define_insn "*iordi_3_rex64"
8611 [(set (reg 17)
8612 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8613 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8614 (const_int 0)))
8615 (clobber (match_scratch:DI 0 "=r"))]
8616 "TARGET_64BIT
8617 && ix86_match_ccmode (insn, CCNOmode)
8618 && ix86_binary_operator_ok (IOR, DImode, operands)"
8619 "or{q}\t{%2, %0|%0, %2}"
8620 [(set_attr "type" "alu")
8621 (set_attr "mode" "DI")])
8622
8623
8624 (define_expand "iorsi3"
8625 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8626 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8627 (match_operand:SI 2 "general_operand" "")))
8628 (clobber (reg:CC 17))]
8629 ""
8630 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8631
8632 (define_insn "*iorsi_1"
8633 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8634 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:SI 2 "general_operand" "ri,rmi")))
8636 (clobber (reg:CC 17))]
8637 "ix86_binary_operator_ok (IOR, SImode, operands)"
8638 "or{l}\t{%2, %0|%0, %2}"
8639 [(set_attr "type" "alu")
8640 (set_attr "mode" "SI")])
8641
8642 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8643 (define_insn "*iorsi_1_zext"
8644 [(set (match_operand:DI 0 "register_operand" "=rm")
8645 (zero_extend:DI
8646 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8647 (match_operand:SI 2 "general_operand" "rim"))))
8648 (clobber (reg:CC 17))]
8649 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8650 "or{l}\t{%2, %k0|%k0, %2}"
8651 [(set_attr "type" "alu")
8652 (set_attr "mode" "SI")])
8653
8654 (define_insn "*iorsi_1_zext_imm"
8655 [(set (match_operand:DI 0 "register_operand" "=rm")
8656 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8657 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8658 (clobber (reg:CC 17))]
8659 "TARGET_64BIT"
8660 "or{l}\t{%2, %k0|%k0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8663
8664 (define_insn "*iorsi_2"
8665 [(set (reg 17)
8666 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8667 (match_operand:SI 2 "general_operand" "rim,ri"))
8668 (const_int 0)))
8669 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8670 (ior:SI (match_dup 1) (match_dup 2)))]
8671 "ix86_match_ccmode (insn, CCNOmode)
8672 && ix86_binary_operator_ok (IOR, SImode, operands)"
8673 "or{l}\t{%2, %0|%0, %2}"
8674 [(set_attr "type" "alu")
8675 (set_attr "mode" "SI")])
8676
8677 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8678 ;; ??? Special case for immediate operand is missing - it is tricky.
8679 (define_insn "*iorsi_2_zext"
8680 [(set (reg 17)
8681 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682 (match_operand:SI 2 "general_operand" "rim"))
8683 (const_int 0)))
8684 (set (match_operand:DI 0 "register_operand" "=r")
8685 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8686 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8687 && ix86_binary_operator_ok (IOR, SImode, operands)"
8688 "or{l}\t{%2, %k0|%k0, %2}"
8689 [(set_attr "type" "alu")
8690 (set_attr "mode" "SI")])
8691
8692 (define_insn "*iorsi_2_zext_imm"
8693 [(set (reg 17)
8694 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8695 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8696 (const_int 0)))
8697 (set (match_operand:DI 0 "register_operand" "=r")
8698 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8699 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8700 && ix86_binary_operator_ok (IOR, SImode, operands)"
8701 "or{l}\t{%2, %k0|%k0, %2}"
8702 [(set_attr "type" "alu")
8703 (set_attr "mode" "SI")])
8704
8705 (define_insn "*iorsi_3"
8706 [(set (reg 17)
8707 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8708 (match_operand:SI 2 "general_operand" "rim"))
8709 (const_int 0)))
8710 (clobber (match_scratch:SI 0 "=r"))]
8711 "ix86_match_ccmode (insn, CCNOmode)
8712 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8713 "or{l}\t{%2, %0|%0, %2}"
8714 [(set_attr "type" "alu")
8715 (set_attr "mode" "SI")])
8716
8717 (define_expand "iorhi3"
8718 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8719 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8720 (match_operand:HI 2 "general_operand" "")))
8721 (clobber (reg:CC 17))]
8722 "TARGET_HIMODE_MATH"
8723 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8724
8725 (define_insn "*iorhi_1"
8726 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8727 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8728 (match_operand:HI 2 "general_operand" "rmi,ri")))
8729 (clobber (reg:CC 17))]
8730 "ix86_binary_operator_ok (IOR, HImode, operands)"
8731 "or{w}\t{%2, %0|%0, %2}"
8732 [(set_attr "type" "alu")
8733 (set_attr "mode" "HI")])
8734
8735 (define_insn "*iorhi_2"
8736 [(set (reg 17)
8737 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8738 (match_operand:HI 2 "general_operand" "rim,ri"))
8739 (const_int 0)))
8740 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8741 (ior:HI (match_dup 1) (match_dup 2)))]
8742 "ix86_match_ccmode (insn, CCNOmode)
8743 && ix86_binary_operator_ok (IOR, HImode, operands)"
8744 "or{w}\t{%2, %0|%0, %2}"
8745 [(set_attr "type" "alu")
8746 (set_attr "mode" "HI")])
8747
8748 (define_insn "*iorhi_3"
8749 [(set (reg 17)
8750 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8751 (match_operand:HI 2 "general_operand" "rim"))
8752 (const_int 0)))
8753 (clobber (match_scratch:HI 0 "=r"))]
8754 "ix86_match_ccmode (insn, CCNOmode)
8755 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8756 "or{w}\t{%2, %0|%0, %2}"
8757 [(set_attr "type" "alu")
8758 (set_attr "mode" "HI")])
8759
8760 (define_expand "iorqi3"
8761 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8762 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8763 (match_operand:QI 2 "general_operand" "")))
8764 (clobber (reg:CC 17))]
8765 "TARGET_QIMODE_MATH"
8766 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8767
8768 ;; %%% Potential partial reg stall on alternative 2. What to do?
8769 (define_insn "*iorqi_1"
8770 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8771 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8772 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8773 (clobber (reg:CC 17))]
8774 "ix86_binary_operator_ok (IOR, QImode, operands)"
8775 "@
8776 or{b}\t{%2, %0|%0, %2}
8777 or{b}\t{%2, %0|%0, %2}
8778 or{l}\t{%k2, %k0|%k0, %k2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "mode" "QI,QI,SI")])
8781
8782 (define_insn "*iorqi_1_slp"
8783 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8784 (ior:QI (match_dup 0)
8785 (match_operand:QI 1 "general_operand" "qmi,qi")))
8786 (clobber (reg:CC 17))]
8787 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8788 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8789 "or{b}\t{%1, %0|%0, %1}"
8790 [(set_attr "type" "alu1")
8791 (set_attr "mode" "QI")])
8792
8793 (define_insn "*iorqi_2"
8794 [(set (reg 17)
8795 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8796 (match_operand:QI 2 "general_operand" "qim,qi"))
8797 (const_int 0)))
8798 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8799 (ior:QI (match_dup 1) (match_dup 2)))]
8800 "ix86_match_ccmode (insn, CCNOmode)
8801 && ix86_binary_operator_ok (IOR, QImode, operands)"
8802 "or{b}\t{%2, %0|%0, %2}"
8803 [(set_attr "type" "alu")
8804 (set_attr "mode" "QI")])
8805
8806 (define_insn "*iorqi_2_slp"
8807 [(set (reg 17)
8808 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8809 (match_operand:QI 1 "general_operand" "qim,qi"))
8810 (const_int 0)))
8811 (set (strict_low_part (match_dup 0))
8812 (ior:QI (match_dup 0) (match_dup 1)))]
8813 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8814 && ix86_match_ccmode (insn, CCNOmode)
8815 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8816 "or{b}\t{%1, %0|%0, %1}"
8817 [(set_attr "type" "alu1")
8818 (set_attr "mode" "QI")])
8819
8820 (define_insn "*iorqi_3"
8821 [(set (reg 17)
8822 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8823 (match_operand:QI 2 "general_operand" "qim"))
8824 (const_int 0)))
8825 (clobber (match_scratch:QI 0 "=q"))]
8826 "ix86_match_ccmode (insn, CCNOmode)
8827 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8828 "or{b}\t{%2, %0|%0, %2}"
8829 [(set_attr "type" "alu")
8830 (set_attr "mode" "QI")])
8831
8832 (define_insn "iorqi_ext_0"
8833 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8834 (const_int 8)
8835 (const_int 8))
8836 (ior:SI
8837 (zero_extract:SI
8838 (match_operand 1 "ext_register_operand" "0")
8839 (const_int 8)
8840 (const_int 8))
8841 (match_operand 2 "const_int_operand" "n")))
8842 (clobber (reg:CC 17))]
8843 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8844 "or{b}\t{%2, %h0|%h0, %2}"
8845 [(set_attr "type" "alu")
8846 (set_attr "length_immediate" "1")
8847 (set_attr "mode" "QI")])
8848
8849 (define_insn "*iorqi_ext_1"
8850 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8851 (const_int 8)
8852 (const_int 8))
8853 (ior:SI
8854 (zero_extract:SI
8855 (match_operand 1 "ext_register_operand" "0")
8856 (const_int 8)
8857 (const_int 8))
8858 (zero_extend:SI
8859 (match_operand:QI 2 "general_operand" "Qm"))))
8860 (clobber (reg:CC 17))]
8861 "!TARGET_64BIT
8862 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8863 "or{b}\t{%2, %h0|%h0, %2}"
8864 [(set_attr "type" "alu")
8865 (set_attr "length_immediate" "0")
8866 (set_attr "mode" "QI")])
8867
8868 (define_insn "*iorqi_ext_1_rex64"
8869 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8870 (const_int 8)
8871 (const_int 8))
8872 (ior:SI
8873 (zero_extract:SI
8874 (match_operand 1 "ext_register_operand" "0")
8875 (const_int 8)
8876 (const_int 8))
8877 (zero_extend:SI
8878 (match_operand 2 "ext_register_operand" "Q"))))
8879 (clobber (reg:CC 17))]
8880 "TARGET_64BIT
8881 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8882 "or{b}\t{%2, %h0|%h0, %2}"
8883 [(set_attr "type" "alu")
8884 (set_attr "length_immediate" "0")
8885 (set_attr "mode" "QI")])
8886
8887 (define_insn "*iorqi_ext_2"
8888 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8889 (const_int 8)
8890 (const_int 8))
8891 (ior:SI
8892 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8893 (const_int 8)
8894 (const_int 8))
8895 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8896 (const_int 8)
8897 (const_int 8))))
8898 (clobber (reg:CC 17))]
8899 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8900 "ior{b}\t{%h2, %h0|%h0, %h2}"
8901 [(set_attr "type" "alu")
8902 (set_attr "length_immediate" "0")
8903 (set_attr "mode" "QI")])
8904
8905 (define_split
8906 [(set (match_operand 0 "register_operand" "")
8907 (ior (match_operand 1 "register_operand" "")
8908 (match_operand 2 "const_int_operand" "")))
8909 (clobber (reg:CC 17))]
8910 "reload_completed
8911 && QI_REG_P (operands[0])
8912 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8913 && !(INTVAL (operands[2]) & ~(255 << 8))
8914 && GET_MODE (operands[0]) != QImode"
8915 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8916 (ior:SI (zero_extract:SI (match_dup 1)
8917 (const_int 8) (const_int 8))
8918 (match_dup 2)))
8919 (clobber (reg:CC 17))])]
8920 "operands[0] = gen_lowpart (SImode, operands[0]);
8921 operands[1] = gen_lowpart (SImode, operands[1]);
8922 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8923
8924 ;; Since OR can be encoded with sign extended immediate, this is only
8925 ;; profitable when 7th bit is set.
8926 (define_split
8927 [(set (match_operand 0 "register_operand" "")
8928 (ior (match_operand 1 "general_operand" "")
8929 (match_operand 2 "const_int_operand" "")))
8930 (clobber (reg:CC 17))]
8931 "reload_completed
8932 && ANY_QI_REG_P (operands[0])
8933 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8934 && !(INTVAL (operands[2]) & ~255)
8935 && (INTVAL (operands[2]) & 128)
8936 && GET_MODE (operands[0]) != QImode"
8937 [(parallel [(set (strict_low_part (match_dup 0))
8938 (ior:QI (match_dup 1)
8939 (match_dup 2)))
8940 (clobber (reg:CC 17))])]
8941 "operands[0] = gen_lowpart (QImode, operands[0]);
8942 operands[1] = gen_lowpart (QImode, operands[1]);
8943 operands[2] = gen_lowpart (QImode, operands[2]);")
8944 \f
8945 ;; Logical XOR instructions
8946
8947 ;; %%% This used to optimize known byte-wide and operations to memory.
8948 ;; If this is considered useful, it should be done with splitters.
8949
8950 (define_expand "xordi3"
8951 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8952 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8953 (match_operand:DI 2 "x86_64_general_operand" "")))
8954 (clobber (reg:CC 17))]
8955 "TARGET_64BIT"
8956 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8957
8958 (define_insn "*xordi_1_rex64"
8959 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8960 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8961 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8962 (clobber (reg:CC 17))]
8963 "TARGET_64BIT
8964 && ix86_binary_operator_ok (XOR, DImode, operands)"
8965 "@
8966 xor{q}\t{%2, %0|%0, %2}
8967 xor{q}\t{%2, %0|%0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "DI,DI")])
8970
8971 (define_insn "*xordi_2_rex64"
8972 [(set (reg 17)
8973 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8974 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8975 (const_int 0)))
8976 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8977 (xor:DI (match_dup 1) (match_dup 2)))]
8978 "TARGET_64BIT
8979 && ix86_match_ccmode (insn, CCNOmode)
8980 && ix86_binary_operator_ok (XOR, DImode, operands)"
8981 "@
8982 xor{q}\t{%2, %0|%0, %2}
8983 xor{q}\t{%2, %0|%0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "mode" "DI,DI")])
8986
8987 (define_insn "*xordi_3_rex64"
8988 [(set (reg 17)
8989 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8990 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8991 (const_int 0)))
8992 (clobber (match_scratch:DI 0 "=r"))]
8993 "TARGET_64BIT
8994 && ix86_match_ccmode (insn, CCNOmode)
8995 && ix86_binary_operator_ok (XOR, DImode, operands)"
8996 "xor{q}\t{%2, %0|%0, %2}"
8997 [(set_attr "type" "alu")
8998 (set_attr "mode" "DI")])
8999
9000 (define_expand "xorsi3"
9001 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9002 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9003 (match_operand:SI 2 "general_operand" "")))
9004 (clobber (reg:CC 17))]
9005 ""
9006 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9007
9008 (define_insn "*xorsi_1"
9009 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9010 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9011 (match_operand:SI 2 "general_operand" "ri,rm")))
9012 (clobber (reg:CC 17))]
9013 "ix86_binary_operator_ok (XOR, SImode, operands)"
9014 "xor{l}\t{%2, %0|%0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "SI")])
9017
9018 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9019 ;; Add speccase for immediates
9020 (define_insn "*xorsi_1_zext"
9021 [(set (match_operand:DI 0 "register_operand" "=r")
9022 (zero_extend:DI
9023 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9024 (match_operand:SI 2 "general_operand" "rim"))))
9025 (clobber (reg:CC 17))]
9026 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9027 "xor{l}\t{%2, %k0|%k0, %2}"
9028 [(set_attr "type" "alu")
9029 (set_attr "mode" "SI")])
9030
9031 (define_insn "*xorsi_1_zext_imm"
9032 [(set (match_operand:DI 0 "register_operand" "=r")
9033 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9034 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9035 (clobber (reg:CC 17))]
9036 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9037 "xor{l}\t{%2, %k0|%k0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9040
9041 (define_insn "*xorsi_2"
9042 [(set (reg 17)
9043 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9044 (match_operand:SI 2 "general_operand" "rim,ri"))
9045 (const_int 0)))
9046 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9047 (xor:SI (match_dup 1) (match_dup 2)))]
9048 "ix86_match_ccmode (insn, CCNOmode)
9049 && ix86_binary_operator_ok (XOR, SImode, operands)"
9050 "xor{l}\t{%2, %0|%0, %2}"
9051 [(set_attr "type" "alu")
9052 (set_attr "mode" "SI")])
9053
9054 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9055 ;; ??? Special case for immediate operand is missing - it is tricky.
9056 (define_insn "*xorsi_2_zext"
9057 [(set (reg 17)
9058 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059 (match_operand:SI 2 "general_operand" "rim"))
9060 (const_int 0)))
9061 (set (match_operand:DI 0 "register_operand" "=r")
9062 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9063 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_binary_operator_ok (XOR, SImode, operands)"
9065 "xor{l}\t{%2, %k0|%k0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "SI")])
9068
9069 (define_insn "*xorsi_2_zext_imm"
9070 [(set (reg 17)
9071 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9072 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9073 (const_int 0)))
9074 (set (match_operand:DI 0 "register_operand" "=r")
9075 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9076 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9077 && ix86_binary_operator_ok (XOR, SImode, operands)"
9078 "xor{l}\t{%2, %k0|%k0, %2}"
9079 [(set_attr "type" "alu")
9080 (set_attr "mode" "SI")])
9081
9082 (define_insn "*xorsi_3"
9083 [(set (reg 17)
9084 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9085 (match_operand:SI 2 "general_operand" "rim"))
9086 (const_int 0)))
9087 (clobber (match_scratch:SI 0 "=r"))]
9088 "ix86_match_ccmode (insn, CCNOmode)
9089 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9090 "xor{l}\t{%2, %0|%0, %2}"
9091 [(set_attr "type" "alu")
9092 (set_attr "mode" "SI")])
9093
9094 (define_expand "xorhi3"
9095 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9096 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9097 (match_operand:HI 2 "general_operand" "")))
9098 (clobber (reg:CC 17))]
9099 "TARGET_HIMODE_MATH"
9100 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9101
9102 (define_insn "*xorhi_1"
9103 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9104 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9105 (match_operand:HI 2 "general_operand" "rmi,ri")))
9106 (clobber (reg:CC 17))]
9107 "ix86_binary_operator_ok (XOR, HImode, operands)"
9108 "xor{w}\t{%2, %0|%0, %2}"
9109 [(set_attr "type" "alu")
9110 (set_attr "mode" "HI")])
9111
9112 (define_insn "*xorhi_2"
9113 [(set (reg 17)
9114 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9115 (match_operand:HI 2 "general_operand" "rim,ri"))
9116 (const_int 0)))
9117 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9118 (xor:HI (match_dup 1) (match_dup 2)))]
9119 "ix86_match_ccmode (insn, CCNOmode)
9120 && ix86_binary_operator_ok (XOR, HImode, operands)"
9121 "xor{w}\t{%2, %0|%0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "mode" "HI")])
9124
9125 (define_insn "*xorhi_3"
9126 [(set (reg 17)
9127 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9128 (match_operand:HI 2 "general_operand" "rim"))
9129 (const_int 0)))
9130 (clobber (match_scratch:HI 0 "=r"))]
9131 "ix86_match_ccmode (insn, CCNOmode)
9132 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9133 "xor{w}\t{%2, %0|%0, %2}"
9134 [(set_attr "type" "alu")
9135 (set_attr "mode" "HI")])
9136
9137 (define_expand "xorqi3"
9138 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9139 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9140 (match_operand:QI 2 "general_operand" "")))
9141 (clobber (reg:CC 17))]
9142 "TARGET_QIMODE_MATH"
9143 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9144
9145 ;; %%% Potential partial reg stall on alternative 2. What to do?
9146 (define_insn "*xorqi_1"
9147 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9148 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9149 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9150 (clobber (reg:CC 17))]
9151 "ix86_binary_operator_ok (XOR, QImode, operands)"
9152 "@
9153 xor{b}\t{%2, %0|%0, %2}
9154 xor{b}\t{%2, %0|%0, %2}
9155 xor{l}\t{%k2, %k0|%k0, %k2}"
9156 [(set_attr "type" "alu")
9157 (set_attr "mode" "QI,QI,SI")])
9158
9159 (define_insn "*xorqi_1_slp"
9160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9161 (xor:QI (match_dup 0)
9162 (match_operand:QI 1 "general_operand" "qi,qmi")))
9163 (clobber (reg:CC 17))]
9164 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9165 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9166 "xor{b}\t{%1, %0|%0, %1}"
9167 [(set_attr "type" "alu1")
9168 (set_attr "mode" "QI")])
9169
9170 (define_insn "xorqi_ext_0"
9171 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9172 (const_int 8)
9173 (const_int 8))
9174 (xor:SI
9175 (zero_extract:SI
9176 (match_operand 1 "ext_register_operand" "0")
9177 (const_int 8)
9178 (const_int 8))
9179 (match_operand 2 "const_int_operand" "n")))
9180 (clobber (reg:CC 17))]
9181 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9182 "xor{b}\t{%2, %h0|%h0, %2}"
9183 [(set_attr "type" "alu")
9184 (set_attr "length_immediate" "1")
9185 (set_attr "mode" "QI")])
9186
9187 (define_insn "*xorqi_ext_1"
9188 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9189 (const_int 8)
9190 (const_int 8))
9191 (xor:SI
9192 (zero_extract:SI
9193 (match_operand 1 "ext_register_operand" "0")
9194 (const_int 8)
9195 (const_int 8))
9196 (zero_extend:SI
9197 (match_operand:QI 2 "general_operand" "Qm"))))
9198 (clobber (reg:CC 17))]
9199 "!TARGET_64BIT
9200 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9201 "xor{b}\t{%2, %h0|%h0, %2}"
9202 [(set_attr "type" "alu")
9203 (set_attr "length_immediate" "0")
9204 (set_attr "mode" "QI")])
9205
9206 (define_insn "*xorqi_ext_1_rex64"
9207 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9208 (const_int 8)
9209 (const_int 8))
9210 (xor:SI
9211 (zero_extract:SI
9212 (match_operand 1 "ext_register_operand" "0")
9213 (const_int 8)
9214 (const_int 8))
9215 (zero_extend:SI
9216 (match_operand 2 "ext_register_operand" "Q"))))
9217 (clobber (reg:CC 17))]
9218 "TARGET_64BIT
9219 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9220 "xor{b}\t{%2, %h0|%h0, %2}"
9221 [(set_attr "type" "alu")
9222 (set_attr "length_immediate" "0")
9223 (set_attr "mode" "QI")])
9224
9225 (define_insn "*xorqi_ext_2"
9226 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9227 (const_int 8)
9228 (const_int 8))
9229 (xor:SI
9230 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9231 (const_int 8)
9232 (const_int 8))
9233 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9234 (const_int 8)
9235 (const_int 8))))
9236 (clobber (reg:CC 17))]
9237 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9238 "xor{b}\t{%h2, %h0|%h0, %h2}"
9239 [(set_attr "type" "alu")
9240 (set_attr "length_immediate" "0")
9241 (set_attr "mode" "QI")])
9242
9243 (define_insn "*xorqi_cc_1"
9244 [(set (reg 17)
9245 (compare
9246 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9247 (match_operand:QI 2 "general_operand" "qim,qi"))
9248 (const_int 0)))
9249 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9250 (xor:QI (match_dup 1) (match_dup 2)))]
9251 "ix86_match_ccmode (insn, CCNOmode)
9252 && ix86_binary_operator_ok (XOR, QImode, operands)"
9253 "xor{b}\t{%2, %0|%0, %2}"
9254 [(set_attr "type" "alu")
9255 (set_attr "mode" "QI")])
9256
9257 (define_insn "*xorqi_2_slp"
9258 [(set (reg 17)
9259 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9260 (match_operand:QI 1 "general_operand" "qim,qi"))
9261 (const_int 0)))
9262 (set (strict_low_part (match_dup 0))
9263 (xor:QI (match_dup 0) (match_dup 1)))]
9264 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9265 && ix86_match_ccmode (insn, CCNOmode)
9266 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9267 "xor{b}\t{%1, %0|%0, %1}"
9268 [(set_attr "type" "alu1")
9269 (set_attr "mode" "QI")])
9270
9271 (define_insn "*xorqi_cc_2"
9272 [(set (reg 17)
9273 (compare
9274 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9275 (match_operand:QI 2 "general_operand" "qim"))
9276 (const_int 0)))
9277 (clobber (match_scratch:QI 0 "=q"))]
9278 "ix86_match_ccmode (insn, CCNOmode)
9279 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9280 "xor{b}\t{%2, %0|%0, %2}"
9281 [(set_attr "type" "alu")
9282 (set_attr "mode" "QI")])
9283
9284 (define_insn "*xorqi_cc_ext_1"
9285 [(set (reg 17)
9286 (compare
9287 (xor:SI
9288 (zero_extract:SI
9289 (match_operand 1 "ext_register_operand" "0")
9290 (const_int 8)
9291 (const_int 8))
9292 (match_operand:QI 2 "general_operand" "qmn"))
9293 (const_int 0)))
9294 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9295 (const_int 8)
9296 (const_int 8))
9297 (xor:SI
9298 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9299 (match_dup 2)))]
9300 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9301 "xor{b}\t{%2, %h0|%h0, %2}"
9302 [(set_attr "type" "alu")
9303 (set_attr "mode" "QI")])
9304
9305 (define_insn "*xorqi_cc_ext_1_rex64"
9306 [(set (reg 17)
9307 (compare
9308 (xor:SI
9309 (zero_extract:SI
9310 (match_operand 1 "ext_register_operand" "0")
9311 (const_int 8)
9312 (const_int 8))
9313 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9314 (const_int 0)))
9315 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9316 (const_int 8)
9317 (const_int 8))
9318 (xor:SI
9319 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9320 (match_dup 2)))]
9321 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9322 "xor{b}\t{%2, %h0|%h0, %2}"
9323 [(set_attr "type" "alu")
9324 (set_attr "mode" "QI")])
9325
9326 (define_expand "xorqi_cc_ext_1"
9327 [(parallel [
9328 (set (reg:CCNO 17)
9329 (compare:CCNO
9330 (xor:SI
9331 (zero_extract:SI
9332 (match_operand 1 "ext_register_operand" "")
9333 (const_int 8)
9334 (const_int 8))
9335 (match_operand:QI 2 "general_operand" ""))
9336 (const_int 0)))
9337 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9338 (const_int 8)
9339 (const_int 8))
9340 (xor:SI
9341 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9342 (match_dup 2)))])]
9343 ""
9344 "")
9345
9346 (define_split
9347 [(set (match_operand 0 "register_operand" "")
9348 (xor (match_operand 1 "register_operand" "")
9349 (match_operand 2 "const_int_operand" "")))
9350 (clobber (reg:CC 17))]
9351 "reload_completed
9352 && QI_REG_P (operands[0])
9353 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9354 && !(INTVAL (operands[2]) & ~(255 << 8))
9355 && GET_MODE (operands[0]) != QImode"
9356 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9357 (xor:SI (zero_extract:SI (match_dup 1)
9358 (const_int 8) (const_int 8))
9359 (match_dup 2)))
9360 (clobber (reg:CC 17))])]
9361 "operands[0] = gen_lowpart (SImode, operands[0]);
9362 operands[1] = gen_lowpart (SImode, operands[1]);
9363 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9364
9365 ;; Since XOR can be encoded with sign extended immediate, this is only
9366 ;; profitable when 7th bit is set.
9367 (define_split
9368 [(set (match_operand 0 "register_operand" "")
9369 (xor (match_operand 1 "general_operand" "")
9370 (match_operand 2 "const_int_operand" "")))
9371 (clobber (reg:CC 17))]
9372 "reload_completed
9373 && ANY_QI_REG_P (operands[0])
9374 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9375 && !(INTVAL (operands[2]) & ~255)
9376 && (INTVAL (operands[2]) & 128)
9377 && GET_MODE (operands[0]) != QImode"
9378 [(parallel [(set (strict_low_part (match_dup 0))
9379 (xor:QI (match_dup 1)
9380 (match_dup 2)))
9381 (clobber (reg:CC 17))])]
9382 "operands[0] = gen_lowpart (QImode, operands[0]);
9383 operands[1] = gen_lowpart (QImode, operands[1]);
9384 operands[2] = gen_lowpart (QImode, operands[2]);")
9385 \f
9386 ;; Negation instructions
9387
9388 (define_expand "negdi2"
9389 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9390 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9391 (clobber (reg:CC 17))])]
9392 ""
9393 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9394
9395 (define_insn "*negdi2_1"
9396 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9397 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9398 (clobber (reg:CC 17))]
9399 "!TARGET_64BIT
9400 && ix86_unary_operator_ok (NEG, DImode, operands)"
9401 "#")
9402
9403 (define_split
9404 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9405 (neg:DI (match_operand:DI 1 "general_operand" "")))
9406 (clobber (reg:CC 17))]
9407 "!TARGET_64BIT && reload_completed"
9408 [(parallel
9409 [(set (reg:CCZ 17)
9410 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9411 (set (match_dup 0) (neg:SI (match_dup 2)))])
9412 (parallel
9413 [(set (match_dup 1)
9414 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9415 (match_dup 3))
9416 (const_int 0)))
9417 (clobber (reg:CC 17))])
9418 (parallel
9419 [(set (match_dup 1)
9420 (neg:SI (match_dup 1)))
9421 (clobber (reg:CC 17))])]
9422 "split_di (operands+1, 1, operands+2, operands+3);
9423 split_di (operands+0, 1, operands+0, operands+1);")
9424
9425 (define_insn "*negdi2_1_rex64"
9426 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9427 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9428 (clobber (reg:CC 17))]
9429 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9430 "neg{q}\t%0"
9431 [(set_attr "type" "negnot")
9432 (set_attr "mode" "DI")])
9433
9434 ;; The problem with neg is that it does not perform (compare x 0),
9435 ;; it really performs (compare 0 x), which leaves us with the zero
9436 ;; flag being the only useful item.
9437
9438 (define_insn "*negdi2_cmpz_rex64"
9439 [(set (reg:CCZ 17)
9440 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9441 (const_int 0)))
9442 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9443 (neg:DI (match_dup 1)))]
9444 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9445 "neg{q}\t%0"
9446 [(set_attr "type" "negnot")
9447 (set_attr "mode" "DI")])
9448
9449
9450 (define_expand "negsi2"
9451 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9452 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9453 (clobber (reg:CC 17))])]
9454 ""
9455 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9456
9457 (define_insn "*negsi2_1"
9458 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9459 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9460 (clobber (reg:CC 17))]
9461 "ix86_unary_operator_ok (NEG, SImode, operands)"
9462 "neg{l}\t%0"
9463 [(set_attr "type" "negnot")
9464 (set_attr "mode" "SI")])
9465
9466 ;; Combine is quite creative about this pattern.
9467 (define_insn "*negsi2_1_zext"
9468 [(set (match_operand:DI 0 "register_operand" "=r")
9469 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9470 (const_int 32)))
9471 (const_int 32)))
9472 (clobber (reg:CC 17))]
9473 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9474 "neg{l}\t%k0"
9475 [(set_attr "type" "negnot")
9476 (set_attr "mode" "SI")])
9477
9478 ;; The problem with neg is that it does not perform (compare x 0),
9479 ;; it really performs (compare 0 x), which leaves us with the zero
9480 ;; flag being the only useful item.
9481
9482 (define_insn "*negsi2_cmpz"
9483 [(set (reg:CCZ 17)
9484 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9485 (const_int 0)))
9486 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9487 (neg:SI (match_dup 1)))]
9488 "ix86_unary_operator_ok (NEG, SImode, operands)"
9489 "neg{l}\t%0"
9490 [(set_attr "type" "negnot")
9491 (set_attr "mode" "SI")])
9492
9493 (define_insn "*negsi2_cmpz_zext"
9494 [(set (reg:CCZ 17)
9495 (compare:CCZ (lshiftrt:DI
9496 (neg:DI (ashift:DI
9497 (match_operand:DI 1 "register_operand" "0")
9498 (const_int 32)))
9499 (const_int 32))
9500 (const_int 0)))
9501 (set (match_operand:DI 0 "register_operand" "=r")
9502 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9503 (const_int 32)))
9504 (const_int 32)))]
9505 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9506 "neg{l}\t%k0"
9507 [(set_attr "type" "negnot")
9508 (set_attr "mode" "SI")])
9509
9510 (define_expand "neghi2"
9511 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9512 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9513 (clobber (reg:CC 17))])]
9514 "TARGET_HIMODE_MATH"
9515 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9516
9517 (define_insn "*neghi2_1"
9518 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9519 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9520 (clobber (reg:CC 17))]
9521 "ix86_unary_operator_ok (NEG, HImode, operands)"
9522 "neg{w}\t%0"
9523 [(set_attr "type" "negnot")
9524 (set_attr "mode" "HI")])
9525
9526 (define_insn "*neghi2_cmpz"
9527 [(set (reg:CCZ 17)
9528 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9529 (const_int 0)))
9530 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9531 (neg:HI (match_dup 1)))]
9532 "ix86_unary_operator_ok (NEG, HImode, operands)"
9533 "neg{w}\t%0"
9534 [(set_attr "type" "negnot")
9535 (set_attr "mode" "HI")])
9536
9537 (define_expand "negqi2"
9538 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9539 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9540 (clobber (reg:CC 17))])]
9541 "TARGET_QIMODE_MATH"
9542 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9543
9544 (define_insn "*negqi2_1"
9545 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9546 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9547 (clobber (reg:CC 17))]
9548 "ix86_unary_operator_ok (NEG, QImode, operands)"
9549 "neg{b}\t%0"
9550 [(set_attr "type" "negnot")
9551 (set_attr "mode" "QI")])
9552
9553 (define_insn "*negqi2_cmpz"
9554 [(set (reg:CCZ 17)
9555 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9556 (const_int 0)))
9557 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9558 (neg:QI (match_dup 1)))]
9559 "ix86_unary_operator_ok (NEG, QImode, operands)"
9560 "neg{b}\t%0"
9561 [(set_attr "type" "negnot")
9562 (set_attr "mode" "QI")])
9563
9564 ;; Changing of sign for FP values is doable using integer unit too.
9565
9566 (define_expand "negsf2"
9567 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9568 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9569 (clobber (reg:CC 17))])]
9570 "TARGET_80387"
9571 "if (TARGET_SSE)
9572 {
9573 /* In case operand is in memory, we will not use SSE. */
9574 if (memory_operand (operands[0], VOIDmode)
9575 && rtx_equal_p (operands[0], operands[1]))
9576 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9577 else
9578 {
9579 /* Using SSE is tricky, since we need bitwise negation of -0
9580 in register. */
9581 rtx reg = gen_reg_rtx (SFmode);
9582 rtx dest = operands[0];
9583 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9584
9585 operands[1] = force_reg (SFmode, operands[1]);
9586 operands[0] = force_reg (SFmode, operands[0]);
9587 reg = force_reg (V4SFmode,
9588 gen_rtx_CONST_VECTOR (V4SFmode,
9589 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9590 CONST0_RTX (SFmode),
9591 CONST0_RTX (SFmode))));
9592 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9593 if (dest != operands[0])
9594 emit_move_insn (dest, operands[0]);
9595 }
9596 DONE;
9597 }
9598 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9599
9600 (define_insn "negsf2_memory"
9601 [(set (match_operand:SF 0 "memory_operand" "=m")
9602 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9603 (clobber (reg:CC 17))]
9604 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9605 "#")
9606
9607 (define_insn "negsf2_ifs"
9608 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9609 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9610 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9611 (clobber (reg:CC 17))]
9612 "TARGET_SSE
9613 && (reload_in_progress || reload_completed
9614 || (register_operand (operands[0], VOIDmode)
9615 && register_operand (operands[1], VOIDmode)))"
9616 "#")
9617
9618 (define_split
9619 [(set (match_operand:SF 0 "memory_operand" "")
9620 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9621 (use (match_operand:SF 2 "" ""))
9622 (clobber (reg:CC 17))]
9623 ""
9624 [(parallel [(set (match_dup 0)
9625 (neg:SF (match_dup 1)))
9626 (clobber (reg:CC 17))])])
9627
9628 (define_split
9629 [(set (match_operand:SF 0 "register_operand" "")
9630 (neg:SF (match_operand:SF 1 "register_operand" "")))
9631 (use (match_operand:V4SF 2 "" ""))
9632 (clobber (reg:CC 17))]
9633 "reload_completed && !SSE_REG_P (operands[0])"
9634 [(parallel [(set (match_dup 0)
9635 (neg:SF (match_dup 1)))
9636 (clobber (reg:CC 17))])])
9637
9638 (define_split
9639 [(set (match_operand:SF 0 "register_operand" "")
9640 (neg:SF (match_operand:SF 1 "register_operand" "")))
9641 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9642 (clobber (reg:CC 17))]
9643 "reload_completed && SSE_REG_P (operands[0])"
9644 [(set (subreg:TI (match_dup 0) 0)
9645 (xor:TI (match_dup 1)
9646 (match_dup 2)))]
9647 {
9648 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9649 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9650 if (operands_match_p (operands[0], operands[2]))
9651 {
9652 rtx tmp;
9653 tmp = operands[1];
9654 operands[1] = operands[2];
9655 operands[2] = tmp;
9656 }
9657 })
9658
9659
9660 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9661 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9662 ;; to itself.
9663 (define_insn "*negsf2_if"
9664 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9665 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9666 (clobber (reg:CC 17))]
9667 "TARGET_80387 && !TARGET_SSE
9668 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9669 "#")
9670
9671 (define_split
9672 [(set (match_operand:SF 0 "fp_register_operand" "")
9673 (neg:SF (match_operand:SF 1 "register_operand" "")))
9674 (clobber (reg:CC 17))]
9675 "TARGET_80387 && reload_completed"
9676 [(set (match_dup 0)
9677 (neg:SF (match_dup 1)))]
9678 "")
9679
9680 (define_split
9681 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9682 (neg:SF (match_operand:SF 1 "register_operand" "")))
9683 (clobber (reg:CC 17))]
9684 "TARGET_80387 && reload_completed"
9685 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9686 (clobber (reg:CC 17))])]
9687 "operands[1] = gen_int_mode (0x80000000, SImode);
9688 operands[0] = gen_lowpart (SImode, operands[0]);")
9689
9690 (define_split
9691 [(set (match_operand 0 "memory_operand" "")
9692 (neg (match_operand 1 "memory_operand" "")))
9693 (clobber (reg:CC 17))]
9694 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9695 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9696 (clobber (reg:CC 17))])]
9697 {
9698 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9699
9700 if (GET_MODE (operands[1]) == XFmode)
9701 size = 10;
9702 operands[0] = adjust_address (operands[0], QImode, size - 1);
9703 operands[1] = gen_int_mode (0x80, QImode);
9704 })
9705
9706 (define_expand "negdf2"
9707 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9708 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9709 (clobber (reg:CC 17))])]
9710 "TARGET_80387"
9711 "if (TARGET_SSE2)
9712 {
9713 /* In case operand is in memory, we will not use SSE. */
9714 if (memory_operand (operands[0], VOIDmode)
9715 && rtx_equal_p (operands[0], operands[1]))
9716 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9717 else
9718 {
9719 /* Using SSE is tricky, since we need bitwise negation of -0
9720 in register. */
9721 rtx reg;
9722 #if HOST_BITS_PER_WIDE_INT >= 64
9723 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9724 #else
9725 rtx imm = immed_double_const (0, 0x80000000, DImode);
9726 #endif
9727 rtx dest = operands[0];
9728
9729 operands[1] = force_reg (DFmode, operands[1]);
9730 operands[0] = force_reg (DFmode, operands[0]);
9731 imm = gen_lowpart (DFmode, imm);
9732 reg = force_reg (V2DFmode,
9733 gen_rtx_CONST_VECTOR (V2DFmode,
9734 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9735 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9736 if (dest != operands[0])
9737 emit_move_insn (dest, operands[0]);
9738 }
9739 DONE;
9740 }
9741 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9742
9743 (define_insn "negdf2_memory"
9744 [(set (match_operand:DF 0 "memory_operand" "=m")
9745 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9746 (clobber (reg:CC 17))]
9747 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9748 "#")
9749
9750 (define_insn "negdf2_ifs"
9751 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9752 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9753 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9754 (clobber (reg:CC 17))]
9755 "!TARGET_64BIT && TARGET_SSE2
9756 && (reload_in_progress || reload_completed
9757 || (register_operand (operands[0], VOIDmode)
9758 && register_operand (operands[1], VOIDmode)))"
9759 "#")
9760
9761 (define_insn "*negdf2_ifs_rex64"
9762 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9763 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9764 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9765 (clobber (reg:CC 17))]
9766 "TARGET_64BIT && TARGET_SSE2
9767 && (reload_in_progress || reload_completed
9768 || (register_operand (operands[0], VOIDmode)
9769 && register_operand (operands[1], VOIDmode)))"
9770 "#")
9771
9772 (define_split
9773 [(set (match_operand:DF 0 "memory_operand" "")
9774 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9775 (use (match_operand:V2DF 2 "" ""))
9776 (clobber (reg:CC 17))]
9777 ""
9778 [(parallel [(set (match_dup 0)
9779 (neg:DF (match_dup 1)))
9780 (clobber (reg:CC 17))])])
9781
9782 (define_split
9783 [(set (match_operand:DF 0 "register_operand" "")
9784 (neg:DF (match_operand:DF 1 "register_operand" "")))
9785 (use (match_operand:V2DF 2 "" ""))
9786 (clobber (reg:CC 17))]
9787 "reload_completed && !SSE_REG_P (operands[0])
9788 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9789 [(parallel [(set (match_dup 0)
9790 (neg:DF (match_dup 1)))
9791 (clobber (reg:CC 17))])])
9792
9793 (define_split
9794 [(set (match_operand:DF 0 "register_operand" "")
9795 (neg:DF (match_operand:DF 1 "register_operand" "")))
9796 (use (match_operand:V2DF 2 "" ""))
9797 (clobber (reg:CC 17))]
9798 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9799 [(parallel [(set (match_dup 0)
9800 (xor:DI (match_dup 1) (match_dup 2)))
9801 (clobber (reg:CC 17))])]
9802 "operands[0] = gen_lowpart (DImode, operands[0]);
9803 operands[1] = gen_lowpart (DImode, operands[1]);
9804 operands[2] = gen_lowpart (DImode, operands[2]);")
9805
9806 (define_split
9807 [(set (match_operand:DF 0 "register_operand" "")
9808 (neg:DF (match_operand:DF 1 "register_operand" "")))
9809 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9810 (clobber (reg:CC 17))]
9811 "reload_completed && SSE_REG_P (operands[0])"
9812 [(set (subreg:TI (match_dup 0) 0)
9813 (xor:TI (match_dup 1)
9814 (match_dup 2)))]
9815 {
9816 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9817 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
9818 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
9819 /* Avoid possible reformatting on the operands. */
9820 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9821 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9822 if (operands_match_p (operands[0], operands[2]))
9823 {
9824 rtx tmp;
9825 tmp = operands[1];
9826 operands[1] = operands[2];
9827 operands[2] = tmp;
9828 }
9829 })
9830
9831 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9832 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9833 ;; to itself.
9834 (define_insn "*negdf2_if"
9835 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9836 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9837 (clobber (reg:CC 17))]
9838 "!TARGET_64BIT && TARGET_80387
9839 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9840 "#")
9841
9842 ;; FIXME: We should to allow integer registers here. Problem is that
9843 ;; we need another scratch register to get constant from.
9844 ;; Forcing constant to mem if no register available in peep2 should be
9845 ;; safe even for PIC mode, because of RIP relative addressing.
9846 (define_insn "*negdf2_if_rex64"
9847 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9848 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9849 (clobber (reg:CC 17))]
9850 "TARGET_64BIT && TARGET_80387
9851 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9852 "#")
9853
9854 (define_split
9855 [(set (match_operand:DF 0 "fp_register_operand" "")
9856 (neg:DF (match_operand:DF 1 "register_operand" "")))
9857 (clobber (reg:CC 17))]
9858 "TARGET_80387 && reload_completed"
9859 [(set (match_dup 0)
9860 (neg:DF (match_dup 1)))]
9861 "")
9862
9863 (define_split
9864 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9865 (neg:DF (match_operand:DF 1 "register_operand" "")))
9866 (clobber (reg:CC 17))]
9867 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9868 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9869 (clobber (reg:CC 17))])]
9870 "operands[4] = gen_int_mode (0x80000000, SImode);
9871 split_di (operands+0, 1, operands+2, operands+3);")
9872
9873 (define_expand "negxf2"
9874 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9875 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9876 (clobber (reg:CC 17))])]
9877 "TARGET_80387"
9878 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9879
9880 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9881 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9882 ;; to itself.
9883 (define_insn "*negxf2_if"
9884 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9885 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9886 (clobber (reg:CC 17))]
9887 "TARGET_80387
9888 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9889 "#")
9890
9891 (define_split
9892 [(set (match_operand:XF 0 "fp_register_operand" "")
9893 (neg:XF (match_operand:XF 1 "register_operand" "")))
9894 (clobber (reg:CC 17))]
9895 "TARGET_80387 && reload_completed"
9896 [(set (match_dup 0)
9897 (neg:XF (match_dup 1)))]
9898 "")
9899
9900 (define_split
9901 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9902 (neg:XF (match_operand:XF 1 "register_operand" "")))
9903 (clobber (reg:CC 17))]
9904 "TARGET_80387 && reload_completed"
9905 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9906 (clobber (reg:CC 17))])]
9907 "operands[1] = GEN_INT (0x8000);
9908 operands[0] = gen_rtx_REG (SImode,
9909 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9910
9911 ;; Conditionalize these after reload. If they matches before reload, we
9912 ;; lose the clobber and ability to use integer instructions.
9913
9914 (define_insn "*negsf2_1"
9915 [(set (match_operand:SF 0 "register_operand" "=f")
9916 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9917 "TARGET_80387 && reload_completed"
9918 "fchs"
9919 [(set_attr "type" "fsgn")
9920 (set_attr "mode" "SF")
9921 (set_attr "ppro_uops" "few")])
9922
9923 (define_insn "*negdf2_1"
9924 [(set (match_operand:DF 0 "register_operand" "=f")
9925 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9926 "TARGET_80387 && reload_completed"
9927 "fchs"
9928 [(set_attr "type" "fsgn")
9929 (set_attr "mode" "DF")
9930 (set_attr "ppro_uops" "few")])
9931
9932 (define_insn "*negextendsfdf2"
9933 [(set (match_operand:DF 0 "register_operand" "=f")
9934 (neg:DF (float_extend:DF
9935 (match_operand:SF 1 "register_operand" "0"))))]
9936 "TARGET_80387"
9937 "fchs"
9938 [(set_attr "type" "fsgn")
9939 (set_attr "mode" "DF")
9940 (set_attr "ppro_uops" "few")])
9941
9942 (define_insn "*negxf2_1"
9943 [(set (match_operand:XF 0 "register_operand" "=f")
9944 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9945 "TARGET_80387 && reload_completed"
9946 "fchs"
9947 [(set_attr "type" "fsgn")
9948 (set_attr "mode" "XF")
9949 (set_attr "ppro_uops" "few")])
9950
9951 (define_insn "*negextenddfxf2"
9952 [(set (match_operand:XF 0 "register_operand" "=f")
9953 (neg:XF (float_extend:XF
9954 (match_operand:DF 1 "register_operand" "0"))))]
9955 "TARGET_80387"
9956 "fchs"
9957 [(set_attr "type" "fsgn")
9958 (set_attr "mode" "XF")
9959 (set_attr "ppro_uops" "few")])
9960
9961 (define_insn "*negextendsfxf2"
9962 [(set (match_operand:XF 0 "register_operand" "=f")
9963 (neg:XF (float_extend:XF
9964 (match_operand:SF 1 "register_operand" "0"))))]
9965 "TARGET_80387"
9966 "fchs"
9967 [(set_attr "type" "fsgn")
9968 (set_attr "mode" "XF")
9969 (set_attr "ppro_uops" "few")])
9970 \f
9971 ;; Absolute value instructions
9972
9973 (define_expand "abssf2"
9974 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9975 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9976 (clobber (reg:CC 17))])]
9977 "TARGET_80387"
9978 "if (TARGET_SSE)
9979 {
9980 /* In case operand is in memory, we will not use SSE. */
9981 if (memory_operand (operands[0], VOIDmode)
9982 && rtx_equal_p (operands[0], operands[1]))
9983 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9984 else
9985 {
9986 /* Using SSE is tricky, since we need bitwise negation of -0
9987 in register. */
9988 rtx reg = gen_reg_rtx (V4SFmode);
9989 rtx dest = operands[0];
9990 rtx imm;
9991
9992 operands[1] = force_reg (SFmode, operands[1]);
9993 operands[0] = force_reg (SFmode, operands[0]);
9994 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9995 reg = force_reg (V4SFmode,
9996 gen_rtx_CONST_VECTOR (V4SFmode,
9997 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9998 CONST0_RTX (SFmode),
9999 CONST0_RTX (SFmode))));
10000 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10001 if (dest != operands[0])
10002 emit_move_insn (dest, operands[0]);
10003 }
10004 DONE;
10005 }
10006 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10007
10008 (define_insn "abssf2_memory"
10009 [(set (match_operand:SF 0 "memory_operand" "=m")
10010 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10011 (clobber (reg:CC 17))]
10012 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10013 "#")
10014
10015 (define_insn "abssf2_ifs"
10016 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10017 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10018 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10019 (clobber (reg:CC 17))]
10020 "TARGET_SSE
10021 && (reload_in_progress || reload_completed
10022 || (register_operand (operands[0], VOIDmode)
10023 && register_operand (operands[1], VOIDmode)))"
10024 "#")
10025
10026 (define_split
10027 [(set (match_operand:SF 0 "memory_operand" "")
10028 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10029 (use (match_operand:V4SF 2 "" ""))
10030 (clobber (reg:CC 17))]
10031 ""
10032 [(parallel [(set (match_dup 0)
10033 (abs:SF (match_dup 1)))
10034 (clobber (reg:CC 17))])])
10035
10036 (define_split
10037 [(set (match_operand:SF 0 "register_operand" "")
10038 (abs:SF (match_operand:SF 1 "register_operand" "")))
10039 (use (match_operand:V4SF 2 "" ""))
10040 (clobber (reg:CC 17))]
10041 "reload_completed && !SSE_REG_P (operands[0])"
10042 [(parallel [(set (match_dup 0)
10043 (abs:SF (match_dup 1)))
10044 (clobber (reg:CC 17))])])
10045
10046 (define_split
10047 [(set (match_operand:SF 0 "register_operand" "")
10048 (abs:SF (match_operand:SF 1 "register_operand" "")))
10049 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10050 (clobber (reg:CC 17))]
10051 "reload_completed && SSE_REG_P (operands[0])"
10052 [(set (subreg:TI (match_dup 0) 0)
10053 (and:TI (match_dup 1)
10054 (match_dup 2)))]
10055 {
10056 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10057 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10058 if (operands_match_p (operands[0], operands[2]))
10059 {
10060 rtx tmp;
10061 tmp = operands[1];
10062 operands[1] = operands[2];
10063 operands[2] = tmp;
10064 }
10065 })
10066
10067 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10068 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10069 ;; to itself.
10070 (define_insn "*abssf2_if"
10071 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10072 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10073 (clobber (reg:CC 17))]
10074 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10075 "#")
10076
10077 (define_split
10078 [(set (match_operand:SF 0 "fp_register_operand" "")
10079 (abs:SF (match_operand:SF 1 "register_operand" "")))
10080 (clobber (reg:CC 17))]
10081 "TARGET_80387 && reload_completed"
10082 [(set (match_dup 0)
10083 (abs:SF (match_dup 1)))]
10084 "")
10085
10086 (define_split
10087 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10088 (abs:SF (match_operand:SF 1 "register_operand" "")))
10089 (clobber (reg:CC 17))]
10090 "TARGET_80387 && reload_completed"
10091 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10092 (clobber (reg:CC 17))])]
10093 "operands[1] = gen_int_mode (~0x80000000, SImode);
10094 operands[0] = gen_lowpart (SImode, operands[0]);")
10095
10096 (define_split
10097 [(set (match_operand 0 "memory_operand" "")
10098 (abs (match_operand 1 "memory_operand" "")))
10099 (clobber (reg:CC 17))]
10100 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10101 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10102 (clobber (reg:CC 17))])]
10103 {
10104 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10105
10106 if (GET_MODE (operands[1]) == XFmode)
10107 size = 10;
10108 operands[0] = adjust_address (operands[0], QImode, size - 1);
10109 operands[1] = gen_int_mode (~0x80, QImode);
10110 })
10111
10112 (define_expand "absdf2"
10113 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10114 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10115 (clobber (reg:CC 17))])]
10116 "TARGET_80387"
10117 "if (TARGET_SSE2)
10118 {
10119 /* In case operand is in memory, we will not use SSE. */
10120 if (memory_operand (operands[0], VOIDmode)
10121 && rtx_equal_p (operands[0], operands[1]))
10122 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10123 else
10124 {
10125 /* Using SSE is tricky, since we need bitwise negation of -0
10126 in register. */
10127 rtx reg = gen_reg_rtx (V2DFmode);
10128 #if HOST_BITS_PER_WIDE_INT >= 64
10129 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10130 #else
10131 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10132 #endif
10133 rtx dest = operands[0];
10134
10135 operands[1] = force_reg (DFmode, operands[1]);
10136 operands[0] = force_reg (DFmode, operands[0]);
10137
10138 /* Produce LONG_DOUBLE with the proper immediate argument. */
10139 imm = gen_lowpart (DFmode, imm);
10140 reg = force_reg (V2DFmode,
10141 gen_rtx_CONST_VECTOR (V2DFmode,
10142 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10143 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10144 if (dest != operands[0])
10145 emit_move_insn (dest, operands[0]);
10146 }
10147 DONE;
10148 }
10149 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10150
10151 (define_insn "absdf2_memory"
10152 [(set (match_operand:DF 0 "memory_operand" "=m")
10153 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10154 (clobber (reg:CC 17))]
10155 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10156 "#")
10157
10158 (define_insn "absdf2_ifs"
10159 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10160 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10161 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10162 (clobber (reg:CC 17))]
10163 "!TARGET_64BIT && TARGET_SSE2
10164 && (reload_in_progress || reload_completed
10165 || (register_operand (operands[0], VOIDmode)
10166 && register_operand (operands[1], VOIDmode)))"
10167 "#")
10168
10169 (define_insn "*absdf2_ifs_rex64"
10170 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10171 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10172 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10173 (clobber (reg:CC 17))]
10174 "TARGET_64BIT && TARGET_SSE2
10175 && (reload_in_progress || reload_completed
10176 || (register_operand (operands[0], VOIDmode)
10177 && register_operand (operands[1], VOIDmode)))"
10178 "#")
10179
10180 (define_split
10181 [(set (match_operand:DF 0 "memory_operand" "")
10182 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10183 (use (match_operand:V2DF 2 "" ""))
10184 (clobber (reg:CC 17))]
10185 ""
10186 [(parallel [(set (match_dup 0)
10187 (abs:DF (match_dup 1)))
10188 (clobber (reg:CC 17))])])
10189
10190 (define_split
10191 [(set (match_operand:DF 0 "register_operand" "")
10192 (abs:DF (match_operand:DF 1 "register_operand" "")))
10193 (use (match_operand:V2DF 2 "" ""))
10194 (clobber (reg:CC 17))]
10195 "reload_completed && !SSE_REG_P (operands[0])"
10196 [(parallel [(set (match_dup 0)
10197 (abs:DF (match_dup 1)))
10198 (clobber (reg:CC 17))])])
10199
10200 (define_split
10201 [(set (match_operand:DF 0 "register_operand" "")
10202 (abs:DF (match_operand:DF 1 "register_operand" "")))
10203 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10204 (clobber (reg:CC 17))]
10205 "reload_completed && SSE_REG_P (operands[0])"
10206 [(set (subreg:TI (match_dup 0) 0)
10207 (and:TI (match_dup 1)
10208 (match_dup 2)))]
10209 {
10210 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10211 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10212 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10213 /* Avoid possible reformatting on the operands. */
10214 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10215 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10216 if (operands_match_p (operands[0], operands[2]))
10217 {
10218 rtx tmp;
10219 tmp = operands[1];
10220 operands[1] = operands[2];
10221 operands[2] = tmp;
10222 }
10223 })
10224
10225
10226 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10227 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10228 ;; to itself.
10229 (define_insn "*absdf2_if"
10230 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10231 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10232 (clobber (reg:CC 17))]
10233 "!TARGET_64BIT && TARGET_80387
10234 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10235 "#")
10236
10237 ;; FIXME: We should to allow integer registers here. Problem is that
10238 ;; we need another scratch register to get constant from.
10239 ;; Forcing constant to mem if no register available in peep2 should be
10240 ;; safe even for PIC mode, because of RIP relative addressing.
10241 (define_insn "*absdf2_if_rex64"
10242 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10243 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10244 (clobber (reg:CC 17))]
10245 "TARGET_64BIT && TARGET_80387
10246 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10247 "#")
10248
10249 (define_split
10250 [(set (match_operand:DF 0 "fp_register_operand" "")
10251 (abs:DF (match_operand:DF 1 "register_operand" "")))
10252 (clobber (reg:CC 17))]
10253 "TARGET_80387 && reload_completed"
10254 [(set (match_dup 0)
10255 (abs:DF (match_dup 1)))]
10256 "")
10257
10258 (define_split
10259 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10260 (abs:DF (match_operand:DF 1 "register_operand" "")))
10261 (clobber (reg:CC 17))]
10262 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10263 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10264 (clobber (reg:CC 17))])]
10265 "operands[4] = gen_int_mode (~0x80000000, SImode);
10266 split_di (operands+0, 1, operands+2, operands+3);")
10267
10268 (define_expand "absxf2"
10269 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10270 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10271 (clobber (reg:CC 17))])]
10272 "TARGET_80387"
10273 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10274
10275 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10276 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10277 ;; to itself.
10278 (define_insn "*absxf2_if"
10279 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10280 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10281 (clobber (reg:CC 17))]
10282 "TARGET_80387
10283 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10284 "#")
10285
10286 (define_split
10287 [(set (match_operand:XF 0 "fp_register_operand" "")
10288 (abs:XF (match_operand:XF 1 "register_operand" "")))
10289 (clobber (reg:CC 17))]
10290 "TARGET_80387 && reload_completed"
10291 [(set (match_dup 0)
10292 (abs:XF (match_dup 1)))]
10293 "")
10294
10295 (define_split
10296 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10297 (abs:XF (match_operand:XF 1 "register_operand" "")))
10298 (clobber (reg:CC 17))]
10299 "TARGET_80387 && reload_completed"
10300 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10301 (clobber (reg:CC 17))])]
10302 "operands[1] = GEN_INT (~0x8000);
10303 operands[0] = gen_rtx_REG (SImode,
10304 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10305
10306 (define_insn "*abssf2_1"
10307 [(set (match_operand:SF 0 "register_operand" "=f")
10308 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10309 "TARGET_80387 && reload_completed"
10310 "fabs"
10311 [(set_attr "type" "fsgn")
10312 (set_attr "mode" "SF")])
10313
10314 (define_insn "*absdf2_1"
10315 [(set (match_operand:DF 0 "register_operand" "=f")
10316 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10317 "TARGET_80387 && reload_completed"
10318 "fabs"
10319 [(set_attr "type" "fsgn")
10320 (set_attr "mode" "DF")])
10321
10322 (define_insn "*absextendsfdf2"
10323 [(set (match_operand:DF 0 "register_operand" "=f")
10324 (abs:DF (float_extend:DF
10325 (match_operand:SF 1 "register_operand" "0"))))]
10326 "TARGET_80387"
10327 "fabs"
10328 [(set_attr "type" "fsgn")
10329 (set_attr "mode" "DF")])
10330
10331 (define_insn "*absxf2_1"
10332 [(set (match_operand:XF 0 "register_operand" "=f")
10333 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10334 "TARGET_80387 && reload_completed"
10335 "fabs"
10336 [(set_attr "type" "fsgn")
10337 (set_attr "mode" "DF")])
10338
10339 (define_insn "*absextenddfxf2"
10340 [(set (match_operand:XF 0 "register_operand" "=f")
10341 (abs:XF (float_extend:XF
10342 (match_operand:DF 1 "register_operand" "0"))))]
10343 "TARGET_80387"
10344 "fabs"
10345 [(set_attr "type" "fsgn")
10346 (set_attr "mode" "XF")])
10347
10348 (define_insn "*absextendsfxf2"
10349 [(set (match_operand:XF 0 "register_operand" "=f")
10350 (abs:XF (float_extend:XF
10351 (match_operand:SF 1 "register_operand" "0"))))]
10352 "TARGET_80387"
10353 "fabs"
10354 [(set_attr "type" "fsgn")
10355 (set_attr "mode" "XF")])
10356 \f
10357 ;; One complement instructions
10358
10359 (define_expand "one_cmpldi2"
10360 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10361 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10362 "TARGET_64BIT"
10363 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10364
10365 (define_insn "*one_cmpldi2_1_rex64"
10366 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10367 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10368 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10369 "not{q}\t%0"
10370 [(set_attr "type" "negnot")
10371 (set_attr "mode" "DI")])
10372
10373 (define_insn "*one_cmpldi2_2_rex64"
10374 [(set (reg 17)
10375 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10376 (const_int 0)))
10377 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10378 (not:DI (match_dup 1)))]
10379 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10380 && ix86_unary_operator_ok (NOT, DImode, operands)"
10381 "#"
10382 [(set_attr "type" "alu1")
10383 (set_attr "mode" "DI")])
10384
10385 (define_split
10386 [(set (reg 17)
10387 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10388 (const_int 0)))
10389 (set (match_operand:DI 0 "nonimmediate_operand" "")
10390 (not:DI (match_dup 1)))]
10391 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10392 [(parallel [(set (reg:CCNO 17)
10393 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10394 (const_int 0)))
10395 (set (match_dup 0)
10396 (xor:DI (match_dup 1) (const_int -1)))])]
10397 "")
10398
10399 (define_expand "one_cmplsi2"
10400 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10401 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10402 ""
10403 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10404
10405 (define_insn "*one_cmplsi2_1"
10406 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10407 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10408 "ix86_unary_operator_ok (NOT, SImode, operands)"
10409 "not{l}\t%0"
10410 [(set_attr "type" "negnot")
10411 (set_attr "mode" "SI")])
10412
10413 ;; ??? Currently never generated - xor is used instead.
10414 (define_insn "*one_cmplsi2_1_zext"
10415 [(set (match_operand:DI 0 "register_operand" "=r")
10416 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10417 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10418 "not{l}\t%k0"
10419 [(set_attr "type" "negnot")
10420 (set_attr "mode" "SI")])
10421
10422 (define_insn "*one_cmplsi2_2"
10423 [(set (reg 17)
10424 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10425 (const_int 0)))
10426 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10427 (not:SI (match_dup 1)))]
10428 "ix86_match_ccmode (insn, CCNOmode)
10429 && ix86_unary_operator_ok (NOT, SImode, operands)"
10430 "#"
10431 [(set_attr "type" "alu1")
10432 (set_attr "mode" "SI")])
10433
10434 (define_split
10435 [(set (reg 17)
10436 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10437 (const_int 0)))
10438 (set (match_operand:SI 0 "nonimmediate_operand" "")
10439 (not:SI (match_dup 1)))]
10440 "ix86_match_ccmode (insn, CCNOmode)"
10441 [(parallel [(set (reg:CCNO 17)
10442 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10443 (const_int 0)))
10444 (set (match_dup 0)
10445 (xor:SI (match_dup 1) (const_int -1)))])]
10446 "")
10447
10448 ;; ??? Currently never generated - xor is used instead.
10449 (define_insn "*one_cmplsi2_2_zext"
10450 [(set (reg 17)
10451 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10452 (const_int 0)))
10453 (set (match_operand:DI 0 "register_operand" "=r")
10454 (zero_extend:DI (not:SI (match_dup 1))))]
10455 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10456 && ix86_unary_operator_ok (NOT, SImode, operands)"
10457 "#"
10458 [(set_attr "type" "alu1")
10459 (set_attr "mode" "SI")])
10460
10461 (define_split
10462 [(set (reg 17)
10463 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10464 (const_int 0)))
10465 (set (match_operand:DI 0 "register_operand" "")
10466 (zero_extend:DI (not:SI (match_dup 1))))]
10467 "ix86_match_ccmode (insn, CCNOmode)"
10468 [(parallel [(set (reg:CCNO 17)
10469 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10470 (const_int 0)))
10471 (set (match_dup 0)
10472 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10473 "")
10474
10475 (define_expand "one_cmplhi2"
10476 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10477 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10478 "TARGET_HIMODE_MATH"
10479 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10480
10481 (define_insn "*one_cmplhi2_1"
10482 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10483 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10484 "ix86_unary_operator_ok (NOT, HImode, operands)"
10485 "not{w}\t%0"
10486 [(set_attr "type" "negnot")
10487 (set_attr "mode" "HI")])
10488
10489 (define_insn "*one_cmplhi2_2"
10490 [(set (reg 17)
10491 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10492 (const_int 0)))
10493 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10494 (not:HI (match_dup 1)))]
10495 "ix86_match_ccmode (insn, CCNOmode)
10496 && ix86_unary_operator_ok (NEG, HImode, operands)"
10497 "#"
10498 [(set_attr "type" "alu1")
10499 (set_attr "mode" "HI")])
10500
10501 (define_split
10502 [(set (reg 17)
10503 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10504 (const_int 0)))
10505 (set (match_operand:HI 0 "nonimmediate_operand" "")
10506 (not:HI (match_dup 1)))]
10507 "ix86_match_ccmode (insn, CCNOmode)"
10508 [(parallel [(set (reg:CCNO 17)
10509 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10510 (const_int 0)))
10511 (set (match_dup 0)
10512 (xor:HI (match_dup 1) (const_int -1)))])]
10513 "")
10514
10515 ;; %%% Potential partial reg stall on alternative 1. What to do?
10516 (define_expand "one_cmplqi2"
10517 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10518 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10519 "TARGET_QIMODE_MATH"
10520 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10521
10522 (define_insn "*one_cmplqi2_1"
10523 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10524 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10525 "ix86_unary_operator_ok (NOT, QImode, operands)"
10526 "@
10527 not{b}\t%0
10528 not{l}\t%k0"
10529 [(set_attr "type" "negnot")
10530 (set_attr "mode" "QI,SI")])
10531
10532 (define_insn "*one_cmplqi2_2"
10533 [(set (reg 17)
10534 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10535 (const_int 0)))
10536 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10537 (not:QI (match_dup 1)))]
10538 "ix86_match_ccmode (insn, CCNOmode)
10539 && ix86_unary_operator_ok (NOT, QImode, operands)"
10540 "#"
10541 [(set_attr "type" "alu1")
10542 (set_attr "mode" "QI")])
10543
10544 (define_split
10545 [(set (reg 17)
10546 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10547 (const_int 0)))
10548 (set (match_operand:QI 0 "nonimmediate_operand" "")
10549 (not:QI (match_dup 1)))]
10550 "ix86_match_ccmode (insn, CCNOmode)"
10551 [(parallel [(set (reg:CCNO 17)
10552 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10553 (const_int 0)))
10554 (set (match_dup 0)
10555 (xor:QI (match_dup 1) (const_int -1)))])]
10556 "")
10557 \f
10558 ;; Arithmetic shift instructions
10559
10560 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10561 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10562 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10563 ;; from the assembler input.
10564 ;;
10565 ;; This instruction shifts the target reg/mem as usual, but instead of
10566 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10567 ;; is a left shift double, bits are taken from the high order bits of
10568 ;; reg, else if the insn is a shift right double, bits are taken from the
10569 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10570 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10571 ;;
10572 ;; Since sh[lr]d does not change the `reg' operand, that is done
10573 ;; separately, making all shifts emit pairs of shift double and normal
10574 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10575 ;; support a 63 bit shift, each shift where the count is in a reg expands
10576 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10577 ;;
10578 ;; If the shift count is a constant, we need never emit more than one
10579 ;; shift pair, instead using moves and sign extension for counts greater
10580 ;; than 31.
10581
10582 (define_expand "ashldi3"
10583 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10584 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10585 (match_operand:QI 2 "nonmemory_operand" "")))
10586 (clobber (reg:CC 17))])]
10587 ""
10588 {
10589 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10590 {
10591 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10592 DONE;
10593 }
10594 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10595 DONE;
10596 })
10597
10598 (define_insn "*ashldi3_1_rex64"
10599 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10600 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10601 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10602 (clobber (reg:CC 17))]
10603 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10604 {
10605 switch (get_attr_type (insn))
10606 {
10607 case TYPE_ALU:
10608 if (operands[2] != const1_rtx)
10609 abort ();
10610 if (!rtx_equal_p (operands[0], operands[1]))
10611 abort ();
10612 return "add{q}\t{%0, %0|%0, %0}";
10613
10614 case TYPE_LEA:
10615 if (GET_CODE (operands[2]) != CONST_INT
10616 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10617 abort ();
10618 operands[1] = gen_rtx_MULT (DImode, operands[1],
10619 GEN_INT (1 << INTVAL (operands[2])));
10620 return "lea{q}\t{%a1, %0|%0, %a1}";
10621
10622 default:
10623 if (REG_P (operands[2]))
10624 return "sal{q}\t{%b2, %0|%0, %b2}";
10625 else if (GET_CODE (operands[2]) == CONST_INT
10626 && INTVAL (operands[2]) == 1
10627 && (TARGET_SHIFT1 || optimize_size))
10628 return "sal{q}\t%0";
10629 else
10630 return "sal{q}\t{%2, %0|%0, %2}";
10631 }
10632 }
10633 [(set (attr "type")
10634 (cond [(eq_attr "alternative" "1")
10635 (const_string "lea")
10636 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10637 (const_int 0))
10638 (match_operand 0 "register_operand" ""))
10639 (match_operand 2 "const1_operand" ""))
10640 (const_string "alu")
10641 ]
10642 (const_string "ishift")))
10643 (set_attr "mode" "DI")])
10644
10645 ;; Convert lea to the lea pattern to avoid flags dependency.
10646 (define_split
10647 [(set (match_operand:DI 0 "register_operand" "")
10648 (ashift:DI (match_operand:DI 1 "register_operand" "")
10649 (match_operand:QI 2 "immediate_operand" "")))
10650 (clobber (reg:CC 17))]
10651 "TARGET_64BIT && reload_completed
10652 && true_regnum (operands[0]) != true_regnum (operands[1])"
10653 [(set (match_dup 0)
10654 (mult:DI (match_dup 1)
10655 (match_dup 2)))]
10656 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10657
10658 ;; This pattern can't accept a variable shift count, since shifts by
10659 ;; zero don't affect the flags. We assume that shifts by constant
10660 ;; zero are optimized away.
10661 (define_insn "*ashldi3_cmp_rex64"
10662 [(set (reg 17)
10663 (compare
10664 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10665 (match_operand:QI 2 "immediate_operand" "e"))
10666 (const_int 0)))
10667 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10668 (ashift:DI (match_dup 1) (match_dup 2)))]
10669 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10670 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10671 {
10672 switch (get_attr_type (insn))
10673 {
10674 case TYPE_ALU:
10675 if (operands[2] != const1_rtx)
10676 abort ();
10677 return "add{q}\t{%0, %0|%0, %0}";
10678
10679 default:
10680 if (REG_P (operands[2]))
10681 return "sal{q}\t{%b2, %0|%0, %b2}";
10682 else if (GET_CODE (operands[2]) == CONST_INT
10683 && INTVAL (operands[2]) == 1
10684 && (TARGET_SHIFT1 || optimize_size))
10685 return "sal{q}\t%0";
10686 else
10687 return "sal{q}\t{%2, %0|%0, %2}";
10688 }
10689 }
10690 [(set (attr "type")
10691 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10692 (const_int 0))
10693 (match_operand 0 "register_operand" ""))
10694 (match_operand 2 "const1_operand" ""))
10695 (const_string "alu")
10696 ]
10697 (const_string "ishift")))
10698 (set_attr "mode" "DI")])
10699
10700 (define_insn "ashldi3_1"
10701 [(set (match_operand:DI 0 "register_operand" "=r")
10702 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10703 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10704 (clobber (match_scratch:SI 3 "=&r"))
10705 (clobber (reg:CC 17))]
10706 "!TARGET_64BIT && TARGET_CMOVE"
10707 "#"
10708 [(set_attr "type" "multi")])
10709
10710 (define_insn "*ashldi3_2"
10711 [(set (match_operand:DI 0 "register_operand" "=r")
10712 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10713 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10714 (clobber (reg:CC 17))]
10715 "!TARGET_64BIT"
10716 "#"
10717 [(set_attr "type" "multi")])
10718
10719 (define_split
10720 [(set (match_operand:DI 0 "register_operand" "")
10721 (ashift:DI (match_operand:DI 1 "register_operand" "")
10722 (match_operand:QI 2 "nonmemory_operand" "")))
10723 (clobber (match_scratch:SI 3 ""))
10724 (clobber (reg:CC 17))]
10725 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10726 [(const_int 0)]
10727 "ix86_split_ashldi (operands, operands[3]); DONE;")
10728
10729 (define_split
10730 [(set (match_operand:DI 0 "register_operand" "")
10731 (ashift:DI (match_operand:DI 1 "register_operand" "")
10732 (match_operand:QI 2 "nonmemory_operand" "")))
10733 (clobber (reg:CC 17))]
10734 "!TARGET_64BIT && reload_completed"
10735 [(const_int 0)]
10736 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10737
10738 (define_insn "x86_shld_1"
10739 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10740 (ior:SI (ashift:SI (match_dup 0)
10741 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10742 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10743 (minus:QI (const_int 32) (match_dup 2)))))
10744 (clobber (reg:CC 17))]
10745 ""
10746 "@
10747 shld{l}\t{%2, %1, %0|%0, %1, %2}
10748 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10749 [(set_attr "type" "ishift")
10750 (set_attr "prefix_0f" "1")
10751 (set_attr "mode" "SI")
10752 (set_attr "pent_pair" "np")
10753 (set_attr "athlon_decode" "vector")
10754 (set_attr "ppro_uops" "few")])
10755
10756 (define_expand "x86_shift_adj_1"
10757 [(set (reg:CCZ 17)
10758 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10759 (const_int 32))
10760 (const_int 0)))
10761 (set (match_operand:SI 0 "register_operand" "")
10762 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10763 (match_operand:SI 1 "register_operand" "")
10764 (match_dup 0)))
10765 (set (match_dup 1)
10766 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10767 (match_operand:SI 3 "register_operand" "r")
10768 (match_dup 1)))]
10769 "TARGET_CMOVE"
10770 "")
10771
10772 (define_expand "x86_shift_adj_2"
10773 [(use (match_operand:SI 0 "register_operand" ""))
10774 (use (match_operand:SI 1 "register_operand" ""))
10775 (use (match_operand:QI 2 "register_operand" ""))]
10776 ""
10777 {
10778 rtx label = gen_label_rtx ();
10779 rtx tmp;
10780
10781 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10782
10783 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10784 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10785 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10786 gen_rtx_LABEL_REF (VOIDmode, label),
10787 pc_rtx);
10788 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10789 JUMP_LABEL (tmp) = label;
10790
10791 emit_move_insn (operands[0], operands[1]);
10792 emit_move_insn (operands[1], const0_rtx);
10793
10794 emit_label (label);
10795 LABEL_NUSES (label) = 1;
10796
10797 DONE;
10798 })
10799
10800 (define_expand "ashlsi3"
10801 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10802 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10803 (match_operand:QI 2 "nonmemory_operand" "")))
10804 (clobber (reg:CC 17))]
10805 ""
10806 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10807
10808 (define_insn "*ashlsi3_1"
10809 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10810 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10811 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10812 (clobber (reg:CC 17))]
10813 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10814 {
10815 switch (get_attr_type (insn))
10816 {
10817 case TYPE_ALU:
10818 if (operands[2] != const1_rtx)
10819 abort ();
10820 if (!rtx_equal_p (operands[0], operands[1]))
10821 abort ();
10822 return "add{l}\t{%0, %0|%0, %0}";
10823
10824 case TYPE_LEA:
10825 return "#";
10826
10827 default:
10828 if (REG_P (operands[2]))
10829 return "sal{l}\t{%b2, %0|%0, %b2}";
10830 else if (GET_CODE (operands[2]) == CONST_INT
10831 && INTVAL (operands[2]) == 1
10832 && (TARGET_SHIFT1 || optimize_size))
10833 return "sal{l}\t%0";
10834 else
10835 return "sal{l}\t{%2, %0|%0, %2}";
10836 }
10837 }
10838 [(set (attr "type")
10839 (cond [(eq_attr "alternative" "1")
10840 (const_string "lea")
10841 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10842 (const_int 0))
10843 (match_operand 0 "register_operand" ""))
10844 (match_operand 2 "const1_operand" ""))
10845 (const_string "alu")
10846 ]
10847 (const_string "ishift")))
10848 (set_attr "mode" "SI")])
10849
10850 ;; Convert lea to the lea pattern to avoid flags dependency.
10851 (define_split
10852 [(set (match_operand 0 "register_operand" "")
10853 (ashift (match_operand 1 "index_register_operand" "")
10854 (match_operand:QI 2 "const_int_operand" "")))
10855 (clobber (reg:CC 17))]
10856 "reload_completed
10857 && true_regnum (operands[0]) != true_regnum (operands[1])"
10858 [(const_int 0)]
10859 {
10860 rtx pat;
10861 operands[0] = gen_lowpart (SImode, operands[0]);
10862 operands[1] = gen_lowpart (Pmode, operands[1]);
10863 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10864 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10865 if (Pmode != SImode)
10866 pat = gen_rtx_SUBREG (SImode, pat, 0);
10867 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10868 DONE;
10869 })
10870
10871 ;; Rare case of shifting RSP is handled by generating move and shift
10872 (define_split
10873 [(set (match_operand 0 "register_operand" "")
10874 (ashift (match_operand 1 "register_operand" "")
10875 (match_operand:QI 2 "const_int_operand" "")))
10876 (clobber (reg:CC 17))]
10877 "reload_completed
10878 && true_regnum (operands[0]) != true_regnum (operands[1])"
10879 [(const_int 0)]
10880 {
10881 rtx pat, clob;
10882 emit_move_insn (operands[1], operands[0]);
10883 pat = gen_rtx_SET (VOIDmode, operands[0],
10884 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10885 operands[0], operands[2]));
10886 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10887 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10888 DONE;
10889 })
10890
10891 (define_insn "*ashlsi3_1_zext"
10892 [(set (match_operand:DI 0 "register_operand" "=r,r")
10893 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10894 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10895 (clobber (reg:CC 17))]
10896 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10897 {
10898 switch (get_attr_type (insn))
10899 {
10900 case TYPE_ALU:
10901 if (operands[2] != const1_rtx)
10902 abort ();
10903 return "add{l}\t{%k0, %k0|%k0, %k0}";
10904
10905 case TYPE_LEA:
10906 return "#";
10907
10908 default:
10909 if (REG_P (operands[2]))
10910 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10911 else if (GET_CODE (operands[2]) == CONST_INT
10912 && INTVAL (operands[2]) == 1
10913 && (TARGET_SHIFT1 || optimize_size))
10914 return "sal{l}\t%k0";
10915 else
10916 return "sal{l}\t{%2, %k0|%k0, %2}";
10917 }
10918 }
10919 [(set (attr "type")
10920 (cond [(eq_attr "alternative" "1")
10921 (const_string "lea")
10922 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10923 (const_int 0))
10924 (match_operand 2 "const1_operand" ""))
10925 (const_string "alu")
10926 ]
10927 (const_string "ishift")))
10928 (set_attr "mode" "SI")])
10929
10930 ;; Convert lea to the lea pattern to avoid flags dependency.
10931 (define_split
10932 [(set (match_operand:DI 0 "register_operand" "")
10933 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10934 (match_operand:QI 2 "const_int_operand" ""))))
10935 (clobber (reg:CC 17))]
10936 "TARGET_64BIT && reload_completed
10937 && true_regnum (operands[0]) != true_regnum (operands[1])"
10938 [(set (match_dup 0) (zero_extend:DI
10939 (subreg:SI (mult:SI (match_dup 1)
10940 (match_dup 2)) 0)))]
10941 {
10942 operands[1] = gen_lowpart (Pmode, operands[1]);
10943 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10944 })
10945
10946 ;; This pattern can't accept a variable shift count, since shifts by
10947 ;; zero don't affect the flags. We assume that shifts by constant
10948 ;; zero are optimized away.
10949 (define_insn "*ashlsi3_cmp"
10950 [(set (reg 17)
10951 (compare
10952 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10953 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10954 (const_int 0)))
10955 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10956 (ashift:SI (match_dup 1) (match_dup 2)))]
10957 "ix86_match_ccmode (insn, CCGOCmode)
10958 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10959 {
10960 switch (get_attr_type (insn))
10961 {
10962 case TYPE_ALU:
10963 if (operands[2] != const1_rtx)
10964 abort ();
10965 return "add{l}\t{%0, %0|%0, %0}";
10966
10967 default:
10968 if (REG_P (operands[2]))
10969 return "sal{l}\t{%b2, %0|%0, %b2}";
10970 else if (GET_CODE (operands[2]) == CONST_INT
10971 && INTVAL (operands[2]) == 1
10972 && (TARGET_SHIFT1 || optimize_size))
10973 return "sal{l}\t%0";
10974 else
10975 return "sal{l}\t{%2, %0|%0, %2}";
10976 }
10977 }
10978 [(set (attr "type")
10979 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980 (const_int 0))
10981 (match_operand 0 "register_operand" ""))
10982 (match_operand 2 "const1_operand" ""))
10983 (const_string "alu")
10984 ]
10985 (const_string "ishift")))
10986 (set_attr "mode" "SI")])
10987
10988 (define_insn "*ashlsi3_cmp_zext"
10989 [(set (reg 17)
10990 (compare
10991 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10992 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10993 (const_int 0)))
10994 (set (match_operand:DI 0 "register_operand" "=r")
10995 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10996 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10997 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10998 {
10999 switch (get_attr_type (insn))
11000 {
11001 case TYPE_ALU:
11002 if (operands[2] != const1_rtx)
11003 abort ();
11004 return "add{l}\t{%k0, %k0|%k0, %k0}";
11005
11006 default:
11007 if (REG_P (operands[2]))
11008 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11009 else if (GET_CODE (operands[2]) == CONST_INT
11010 && INTVAL (operands[2]) == 1
11011 && (TARGET_SHIFT1 || optimize_size))
11012 return "sal{l}\t%k0";
11013 else
11014 return "sal{l}\t{%2, %k0|%k0, %2}";
11015 }
11016 }
11017 [(set (attr "type")
11018 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11019 (const_int 0))
11020 (match_operand 2 "const1_operand" ""))
11021 (const_string "alu")
11022 ]
11023 (const_string "ishift")))
11024 (set_attr "mode" "SI")])
11025
11026 (define_expand "ashlhi3"
11027 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11028 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11029 (match_operand:QI 2 "nonmemory_operand" "")))
11030 (clobber (reg:CC 17))]
11031 "TARGET_HIMODE_MATH"
11032 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11033
11034 (define_insn "*ashlhi3_1_lea"
11035 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11036 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11037 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11038 (clobber (reg:CC 17))]
11039 "!TARGET_PARTIAL_REG_STALL
11040 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11041 {
11042 switch (get_attr_type (insn))
11043 {
11044 case TYPE_LEA:
11045 return "#";
11046 case TYPE_ALU:
11047 if (operands[2] != const1_rtx)
11048 abort ();
11049 return "add{w}\t{%0, %0|%0, %0}";
11050
11051 default:
11052 if (REG_P (operands[2]))
11053 return "sal{w}\t{%b2, %0|%0, %b2}";
11054 else if (GET_CODE (operands[2]) == CONST_INT
11055 && INTVAL (operands[2]) == 1
11056 && (TARGET_SHIFT1 || optimize_size))
11057 return "sal{w}\t%0";
11058 else
11059 return "sal{w}\t{%2, %0|%0, %2}";
11060 }
11061 }
11062 [(set (attr "type")
11063 (cond [(eq_attr "alternative" "1")
11064 (const_string "lea")
11065 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11066 (const_int 0))
11067 (match_operand 0 "register_operand" ""))
11068 (match_operand 2 "const1_operand" ""))
11069 (const_string "alu")
11070 ]
11071 (const_string "ishift")))
11072 (set_attr "mode" "HI,SI")])
11073
11074 (define_insn "*ashlhi3_1"
11075 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11076 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11077 (match_operand:QI 2 "nonmemory_operand" "cI")))
11078 (clobber (reg:CC 17))]
11079 "TARGET_PARTIAL_REG_STALL
11080 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11081 {
11082 switch (get_attr_type (insn))
11083 {
11084 case TYPE_ALU:
11085 if (operands[2] != const1_rtx)
11086 abort ();
11087 return "add{w}\t{%0, %0|%0, %0}";
11088
11089 default:
11090 if (REG_P (operands[2]))
11091 return "sal{w}\t{%b2, %0|%0, %b2}";
11092 else if (GET_CODE (operands[2]) == CONST_INT
11093 && INTVAL (operands[2]) == 1
11094 && (TARGET_SHIFT1 || optimize_size))
11095 return "sal{w}\t%0";
11096 else
11097 return "sal{w}\t{%2, %0|%0, %2}";
11098 }
11099 }
11100 [(set (attr "type")
11101 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11102 (const_int 0))
11103 (match_operand 0 "register_operand" ""))
11104 (match_operand 2 "const1_operand" ""))
11105 (const_string "alu")
11106 ]
11107 (const_string "ishift")))
11108 (set_attr "mode" "HI")])
11109
11110 ;; This pattern can't accept a variable shift count, since shifts by
11111 ;; zero don't affect the flags. We assume that shifts by constant
11112 ;; zero are optimized away.
11113 (define_insn "*ashlhi3_cmp"
11114 [(set (reg 17)
11115 (compare
11116 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11117 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11118 (const_int 0)))
11119 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11120 (ashift:HI (match_dup 1) (match_dup 2)))]
11121 "ix86_match_ccmode (insn, CCGOCmode)
11122 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11123 {
11124 switch (get_attr_type (insn))
11125 {
11126 case TYPE_ALU:
11127 if (operands[2] != const1_rtx)
11128 abort ();
11129 return "add{w}\t{%0, %0|%0, %0}";
11130
11131 default:
11132 if (REG_P (operands[2]))
11133 return "sal{w}\t{%b2, %0|%0, %b2}";
11134 else if (GET_CODE (operands[2]) == CONST_INT
11135 && INTVAL (operands[2]) == 1
11136 && (TARGET_SHIFT1 || optimize_size))
11137 return "sal{w}\t%0";
11138 else
11139 return "sal{w}\t{%2, %0|%0, %2}";
11140 }
11141 }
11142 [(set (attr "type")
11143 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11144 (const_int 0))
11145 (match_operand 0 "register_operand" ""))
11146 (match_operand 2 "const1_operand" ""))
11147 (const_string "alu")
11148 ]
11149 (const_string "ishift")))
11150 (set_attr "mode" "HI")])
11151
11152 (define_expand "ashlqi3"
11153 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11154 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11155 (match_operand:QI 2 "nonmemory_operand" "")))
11156 (clobber (reg:CC 17))]
11157 "TARGET_QIMODE_MATH"
11158 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11159
11160 ;; %%% Potential partial reg stall on alternative 2. What to do?
11161
11162 (define_insn "*ashlqi3_1_lea"
11163 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11164 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11165 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11166 (clobber (reg:CC 17))]
11167 "!TARGET_PARTIAL_REG_STALL
11168 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11169 {
11170 switch (get_attr_type (insn))
11171 {
11172 case TYPE_LEA:
11173 return "#";
11174 case TYPE_ALU:
11175 if (operands[2] != const1_rtx)
11176 abort ();
11177 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11178 return "add{l}\t{%k0, %k0|%k0, %k0}";
11179 else
11180 return "add{b}\t{%0, %0|%0, %0}";
11181
11182 default:
11183 if (REG_P (operands[2]))
11184 {
11185 if (get_attr_mode (insn) == MODE_SI)
11186 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11187 else
11188 return "sal{b}\t{%b2, %0|%0, %b2}";
11189 }
11190 else if (GET_CODE (operands[2]) == CONST_INT
11191 && INTVAL (operands[2]) == 1
11192 && (TARGET_SHIFT1 || optimize_size))
11193 {
11194 if (get_attr_mode (insn) == MODE_SI)
11195 return "sal{l}\t%0";
11196 else
11197 return "sal{b}\t%0";
11198 }
11199 else
11200 {
11201 if (get_attr_mode (insn) == MODE_SI)
11202 return "sal{l}\t{%2, %k0|%k0, %2}";
11203 else
11204 return "sal{b}\t{%2, %0|%0, %2}";
11205 }
11206 }
11207 }
11208 [(set (attr "type")
11209 (cond [(eq_attr "alternative" "2")
11210 (const_string "lea")
11211 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11212 (const_int 0))
11213 (match_operand 0 "register_operand" ""))
11214 (match_operand 2 "const1_operand" ""))
11215 (const_string "alu")
11216 ]
11217 (const_string "ishift")))
11218 (set_attr "mode" "QI,SI,SI")])
11219
11220 (define_insn "*ashlqi3_1"
11221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11222 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11223 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11224 (clobber (reg:CC 17))]
11225 "TARGET_PARTIAL_REG_STALL
11226 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11227 {
11228 switch (get_attr_type (insn))
11229 {
11230 case TYPE_ALU:
11231 if (operands[2] != const1_rtx)
11232 abort ();
11233 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11234 return "add{l}\t{%k0, %k0|%k0, %k0}";
11235 else
11236 return "add{b}\t{%0, %0|%0, %0}";
11237
11238 default:
11239 if (REG_P (operands[2]))
11240 {
11241 if (get_attr_mode (insn) == MODE_SI)
11242 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11243 else
11244 return "sal{b}\t{%b2, %0|%0, %b2}";
11245 }
11246 else if (GET_CODE (operands[2]) == CONST_INT
11247 && INTVAL (operands[2]) == 1
11248 && (TARGET_SHIFT1 || optimize_size))
11249 {
11250 if (get_attr_mode (insn) == MODE_SI)
11251 return "sal{l}\t%0";
11252 else
11253 return "sal{b}\t%0";
11254 }
11255 else
11256 {
11257 if (get_attr_mode (insn) == MODE_SI)
11258 return "sal{l}\t{%2, %k0|%k0, %2}";
11259 else
11260 return "sal{b}\t{%2, %0|%0, %2}";
11261 }
11262 }
11263 }
11264 [(set (attr "type")
11265 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11266 (const_int 0))
11267 (match_operand 0 "register_operand" ""))
11268 (match_operand 2 "const1_operand" ""))
11269 (const_string "alu")
11270 ]
11271 (const_string "ishift")))
11272 (set_attr "mode" "QI,SI")])
11273
11274 ;; This pattern can't accept a variable shift count, since shifts by
11275 ;; zero don't affect the flags. We assume that shifts by constant
11276 ;; zero are optimized away.
11277 (define_insn "*ashlqi3_cmp"
11278 [(set (reg 17)
11279 (compare
11280 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11281 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11282 (const_int 0)))
11283 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11284 (ashift:QI (match_dup 1) (match_dup 2)))]
11285 "ix86_match_ccmode (insn, CCGOCmode)
11286 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11287 {
11288 switch (get_attr_type (insn))
11289 {
11290 case TYPE_ALU:
11291 if (operands[2] != const1_rtx)
11292 abort ();
11293 return "add{b}\t{%0, %0|%0, %0}";
11294
11295 default:
11296 if (REG_P (operands[2]))
11297 return "sal{b}\t{%b2, %0|%0, %b2}";
11298 else if (GET_CODE (operands[2]) == CONST_INT
11299 && INTVAL (operands[2]) == 1
11300 && (TARGET_SHIFT1 || optimize_size))
11301 return "sal{b}\t%0";
11302 else
11303 return "sal{b}\t{%2, %0|%0, %2}";
11304 }
11305 }
11306 [(set (attr "type")
11307 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11308 (const_int 0))
11309 (match_operand 0 "register_operand" ""))
11310 (match_operand 2 "const1_operand" ""))
11311 (const_string "alu")
11312 ]
11313 (const_string "ishift")))
11314 (set_attr "mode" "QI")])
11315
11316 ;; See comment above `ashldi3' about how this works.
11317
11318 (define_expand "ashrdi3"
11319 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11320 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11321 (match_operand:QI 2 "nonmemory_operand" "")))
11322 (clobber (reg:CC 17))])]
11323 ""
11324 {
11325 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11326 {
11327 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11328 DONE;
11329 }
11330 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11331 DONE;
11332 })
11333
11334 (define_insn "ashrdi3_63_rex64"
11335 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11336 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11337 (match_operand:DI 2 "const_int_operand" "i,i")))
11338 (clobber (reg:CC 17))]
11339 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11340 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11341 "@
11342 {cqto|cqo}
11343 sar{q}\t{%2, %0|%0, %2}"
11344 [(set_attr "type" "imovx,ishift")
11345 (set_attr "prefix_0f" "0,*")
11346 (set_attr "length_immediate" "0,*")
11347 (set_attr "modrm" "0,1")
11348 (set_attr "mode" "DI")])
11349
11350 (define_insn "*ashrdi3_1_one_bit_rex64"
11351 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11352 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11353 (match_operand:QI 2 "const1_operand" "")))
11354 (clobber (reg:CC 17))]
11355 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11356 && (TARGET_SHIFT1 || optimize_size)"
11357 "sar{q}\t%0"
11358 [(set_attr "type" "ishift")
11359 (set (attr "length")
11360 (if_then_else (match_operand:DI 0 "register_operand" "")
11361 (const_string "2")
11362 (const_string "*")))])
11363
11364 (define_insn "*ashrdi3_1_rex64"
11365 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11366 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11367 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11368 (clobber (reg:CC 17))]
11369 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11370 "@
11371 sar{q}\t{%2, %0|%0, %2}
11372 sar{q}\t{%b2, %0|%0, %b2}"
11373 [(set_attr "type" "ishift")
11374 (set_attr "mode" "DI")])
11375
11376 ;; This pattern can't accept a variable shift count, since shifts by
11377 ;; zero don't affect the flags. We assume that shifts by constant
11378 ;; zero are optimized away.
11379 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11380 [(set (reg 17)
11381 (compare
11382 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11383 (match_operand:QI 2 "const1_operand" ""))
11384 (const_int 0)))
11385 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11386 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11387 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11388 && (TARGET_SHIFT1 || optimize_size)
11389 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11390 "sar{q}\t%0"
11391 [(set_attr "type" "ishift")
11392 (set (attr "length")
11393 (if_then_else (match_operand:DI 0 "register_operand" "")
11394 (const_string "2")
11395 (const_string "*")))])
11396
11397 ;; This pattern can't accept a variable shift count, since shifts by
11398 ;; zero don't affect the flags. We assume that shifts by constant
11399 ;; zero are optimized away.
11400 (define_insn "*ashrdi3_cmp_rex64"
11401 [(set (reg 17)
11402 (compare
11403 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404 (match_operand:QI 2 "const_int_operand" "n"))
11405 (const_int 0)))
11406 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11407 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11408 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11409 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11410 "sar{q}\t{%2, %0|%0, %2}"
11411 [(set_attr "type" "ishift")
11412 (set_attr "mode" "DI")])
11413
11414
11415 (define_insn "ashrdi3_1"
11416 [(set (match_operand:DI 0 "register_operand" "=r")
11417 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11418 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11419 (clobber (match_scratch:SI 3 "=&r"))
11420 (clobber (reg:CC 17))]
11421 "!TARGET_64BIT && TARGET_CMOVE"
11422 "#"
11423 [(set_attr "type" "multi")])
11424
11425 (define_insn "*ashrdi3_2"
11426 [(set (match_operand:DI 0 "register_operand" "=r")
11427 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11428 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11429 (clobber (reg:CC 17))]
11430 "!TARGET_64BIT"
11431 "#"
11432 [(set_attr "type" "multi")])
11433
11434 (define_split
11435 [(set (match_operand:DI 0 "register_operand" "")
11436 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11437 (match_operand:QI 2 "nonmemory_operand" "")))
11438 (clobber (match_scratch:SI 3 ""))
11439 (clobber (reg:CC 17))]
11440 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11441 [(const_int 0)]
11442 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11443
11444 (define_split
11445 [(set (match_operand:DI 0 "register_operand" "")
11446 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11447 (match_operand:QI 2 "nonmemory_operand" "")))
11448 (clobber (reg:CC 17))]
11449 "!TARGET_64BIT && reload_completed"
11450 [(const_int 0)]
11451 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11452
11453 (define_insn "x86_shrd_1"
11454 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11455 (ior:SI (ashiftrt:SI (match_dup 0)
11456 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11457 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11458 (minus:QI (const_int 32) (match_dup 2)))))
11459 (clobber (reg:CC 17))]
11460 ""
11461 "@
11462 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11463 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11464 [(set_attr "type" "ishift")
11465 (set_attr "prefix_0f" "1")
11466 (set_attr "pent_pair" "np")
11467 (set_attr "ppro_uops" "few")
11468 (set_attr "mode" "SI")])
11469
11470 (define_expand "x86_shift_adj_3"
11471 [(use (match_operand:SI 0 "register_operand" ""))
11472 (use (match_operand:SI 1 "register_operand" ""))
11473 (use (match_operand:QI 2 "register_operand" ""))]
11474 ""
11475 {
11476 rtx label = gen_label_rtx ();
11477 rtx tmp;
11478
11479 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11480
11481 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11482 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11483 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11484 gen_rtx_LABEL_REF (VOIDmode, label),
11485 pc_rtx);
11486 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11487 JUMP_LABEL (tmp) = label;
11488
11489 emit_move_insn (operands[0], operands[1]);
11490 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11491
11492 emit_label (label);
11493 LABEL_NUSES (label) = 1;
11494
11495 DONE;
11496 })
11497
11498 (define_insn "ashrsi3_31"
11499 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11500 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11501 (match_operand:SI 2 "const_int_operand" "i,i")))
11502 (clobber (reg:CC 17))]
11503 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11504 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11505 "@
11506 {cltd|cdq}
11507 sar{l}\t{%2, %0|%0, %2}"
11508 [(set_attr "type" "imovx,ishift")
11509 (set_attr "prefix_0f" "0,*")
11510 (set_attr "length_immediate" "0,*")
11511 (set_attr "modrm" "0,1")
11512 (set_attr "mode" "SI")])
11513
11514 (define_insn "*ashrsi3_31_zext"
11515 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11516 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11517 (match_operand:SI 2 "const_int_operand" "i,i"))))
11518 (clobber (reg:CC 17))]
11519 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11520 && INTVAL (operands[2]) == 31
11521 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11522 "@
11523 {cltd|cdq}
11524 sar{l}\t{%2, %k0|%k0, %2}"
11525 [(set_attr "type" "imovx,ishift")
11526 (set_attr "prefix_0f" "0,*")
11527 (set_attr "length_immediate" "0,*")
11528 (set_attr "modrm" "0,1")
11529 (set_attr "mode" "SI")])
11530
11531 (define_expand "ashrsi3"
11532 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11533 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11534 (match_operand:QI 2 "nonmemory_operand" "")))
11535 (clobber (reg:CC 17))]
11536 ""
11537 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11538
11539 (define_insn "*ashrsi3_1_one_bit"
11540 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11541 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11542 (match_operand:QI 2 "const1_operand" "")))
11543 (clobber (reg:CC 17))]
11544 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11545 && (TARGET_SHIFT1 || optimize_size)"
11546 "sar{l}\t%0"
11547 [(set_attr "type" "ishift")
11548 (set (attr "length")
11549 (if_then_else (match_operand:SI 0 "register_operand" "")
11550 (const_string "2")
11551 (const_string "*")))])
11552
11553 (define_insn "*ashrsi3_1_one_bit_zext"
11554 [(set (match_operand:DI 0 "register_operand" "=r")
11555 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11556 (match_operand:QI 2 "const1_operand" ""))))
11557 (clobber (reg:CC 17))]
11558 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11559 && (TARGET_SHIFT1 || optimize_size)"
11560 "sar{l}\t%k0"
11561 [(set_attr "type" "ishift")
11562 (set_attr "length" "2")])
11563
11564 (define_insn "*ashrsi3_1"
11565 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11566 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11567 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11568 (clobber (reg:CC 17))]
11569 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11570 "@
11571 sar{l}\t{%2, %0|%0, %2}
11572 sar{l}\t{%b2, %0|%0, %b2}"
11573 [(set_attr "type" "ishift")
11574 (set_attr "mode" "SI")])
11575
11576 (define_insn "*ashrsi3_1_zext"
11577 [(set (match_operand:DI 0 "register_operand" "=r,r")
11578 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11579 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11580 (clobber (reg:CC 17))]
11581 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11582 "@
11583 sar{l}\t{%2, %k0|%k0, %2}
11584 sar{l}\t{%b2, %k0|%k0, %b2}"
11585 [(set_attr "type" "ishift")
11586 (set_attr "mode" "SI")])
11587
11588 ;; This pattern can't accept a variable shift count, since shifts by
11589 ;; zero don't affect the flags. We assume that shifts by constant
11590 ;; zero are optimized away.
11591 (define_insn "*ashrsi3_one_bit_cmp"
11592 [(set (reg 17)
11593 (compare
11594 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11595 (match_operand:QI 2 "const1_operand" ""))
11596 (const_int 0)))
11597 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11598 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11599 "ix86_match_ccmode (insn, CCGOCmode)
11600 && (TARGET_SHIFT1 || optimize_size)
11601 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11602 "sar{l}\t%0"
11603 [(set_attr "type" "ishift")
11604 (set (attr "length")
11605 (if_then_else (match_operand:SI 0 "register_operand" "")
11606 (const_string "2")
11607 (const_string "*")))])
11608
11609 (define_insn "*ashrsi3_one_bit_cmp_zext"
11610 [(set (reg 17)
11611 (compare
11612 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11613 (match_operand:QI 2 "const1_operand" ""))
11614 (const_int 0)))
11615 (set (match_operand:DI 0 "register_operand" "=r")
11616 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11617 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11618 && (TARGET_SHIFT1 || optimize_size)
11619 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620 "sar{l}\t%k0"
11621 [(set_attr "type" "ishift")
11622 (set_attr "length" "2")])
11623
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags. We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrsi3_cmp"
11628 [(set (reg 17)
11629 (compare
11630 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11632 (const_int 0)))
11633 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11634 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11635 "ix86_match_ccmode (insn, CCGOCmode)
11636 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11637 "sar{l}\t{%2, %0|%0, %2}"
11638 [(set_attr "type" "ishift")
11639 (set_attr "mode" "SI")])
11640
11641 (define_insn "*ashrsi3_cmp_zext"
11642 [(set (reg 17)
11643 (compare
11644 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11645 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11646 (const_int 0)))
11647 (set (match_operand:DI 0 "register_operand" "=r")
11648 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11649 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11650 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11651 "sar{l}\t{%2, %k0|%k0, %2}"
11652 [(set_attr "type" "ishift")
11653 (set_attr "mode" "SI")])
11654
11655 (define_expand "ashrhi3"
11656 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11657 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11658 (match_operand:QI 2 "nonmemory_operand" "")))
11659 (clobber (reg:CC 17))]
11660 "TARGET_HIMODE_MATH"
11661 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11662
11663 (define_insn "*ashrhi3_1_one_bit"
11664 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11665 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const1_operand" "")))
11667 (clobber (reg:CC 17))]
11668 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11669 && (TARGET_SHIFT1 || optimize_size)"
11670 "sar{w}\t%0"
11671 [(set_attr "type" "ishift")
11672 (set (attr "length")
11673 (if_then_else (match_operand 0 "register_operand" "")
11674 (const_string "2")
11675 (const_string "*")))])
11676
11677 (define_insn "*ashrhi3_1"
11678 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11679 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11680 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11681 (clobber (reg:CC 17))]
11682 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11683 "@
11684 sar{w}\t{%2, %0|%0, %2}
11685 sar{w}\t{%b2, %0|%0, %b2}"
11686 [(set_attr "type" "ishift")
11687 (set_attr "mode" "HI")])
11688
11689 ;; This pattern can't accept a variable shift count, since shifts by
11690 ;; zero don't affect the flags. We assume that shifts by constant
11691 ;; zero are optimized away.
11692 (define_insn "*ashrhi3_one_bit_cmp"
11693 [(set (reg 17)
11694 (compare
11695 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11696 (match_operand:QI 2 "const1_operand" ""))
11697 (const_int 0)))
11698 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11699 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11700 "ix86_match_ccmode (insn, CCGOCmode)
11701 && (TARGET_SHIFT1 || optimize_size)
11702 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11703 "sar{w}\t%0"
11704 [(set_attr "type" "ishift")
11705 (set (attr "length")
11706 (if_then_else (match_operand 0 "register_operand" "")
11707 (const_string "2")
11708 (const_string "*")))])
11709
11710 ;; This pattern can't accept a variable shift count, since shifts by
11711 ;; zero don't affect the flags. We assume that shifts by constant
11712 ;; zero are optimized away.
11713 (define_insn "*ashrhi3_cmp"
11714 [(set (reg 17)
11715 (compare
11716 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11718 (const_int 0)))
11719 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11720 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11721 "ix86_match_ccmode (insn, CCGOCmode)
11722 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11723 "sar{w}\t{%2, %0|%0, %2}"
11724 [(set_attr "type" "ishift")
11725 (set_attr "mode" "HI")])
11726
11727 (define_expand "ashrqi3"
11728 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11729 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11730 (match_operand:QI 2 "nonmemory_operand" "")))
11731 (clobber (reg:CC 17))]
11732 "TARGET_QIMODE_MATH"
11733 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11734
11735 (define_insn "*ashrqi3_1_one_bit"
11736 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11737 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11738 (match_operand:QI 2 "const1_operand" "")))
11739 (clobber (reg:CC 17))]
11740 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11741 && (TARGET_SHIFT1 || optimize_size)"
11742 "sar{b}\t%0"
11743 [(set_attr "type" "ishift")
11744 (set (attr "length")
11745 (if_then_else (match_operand 0 "register_operand" "")
11746 (const_string "2")
11747 (const_string "*")))])
11748
11749 (define_insn "*ashrqi3_1_one_bit_slp"
11750 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11751 (ashiftrt:QI (match_dup 0)
11752 (match_operand:QI 1 "const1_operand" "")))
11753 (clobber (reg:CC 17))]
11754 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11755 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11756 && (TARGET_SHIFT1 || optimize_size)"
11757 "sar{b}\t%0"
11758 [(set_attr "type" "ishift1")
11759 (set (attr "length")
11760 (if_then_else (match_operand 0 "register_operand" "")
11761 (const_string "2")
11762 (const_string "*")))])
11763
11764 (define_insn "*ashrqi3_1"
11765 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11766 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11767 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11768 (clobber (reg:CC 17))]
11769 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11770 "@
11771 sar{b}\t{%2, %0|%0, %2}
11772 sar{b}\t{%b2, %0|%0, %b2}"
11773 [(set_attr "type" "ishift")
11774 (set_attr "mode" "QI")])
11775
11776 (define_insn "*ashrqi3_1_slp"
11777 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11778 (ashiftrt:QI (match_dup 0)
11779 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11780 (clobber (reg:CC 17))]
11781 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11783 "@
11784 sar{b}\t{%1, %0|%0, %1}
11785 sar{b}\t{%b1, %0|%0, %b1}"
11786 [(set_attr "type" "ishift1")
11787 (set_attr "mode" "QI")])
11788
11789 ;; This pattern can't accept a variable shift count, since shifts by
11790 ;; zero don't affect the flags. We assume that shifts by constant
11791 ;; zero are optimized away.
11792 (define_insn "*ashrqi3_one_bit_cmp"
11793 [(set (reg 17)
11794 (compare
11795 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11796 (match_operand:QI 2 "const1_operand" "I"))
11797 (const_int 0)))
11798 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11799 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11800 "ix86_match_ccmode (insn, CCGOCmode)
11801 && (TARGET_SHIFT1 || optimize_size)
11802 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11803 "sar{b}\t%0"
11804 [(set_attr "type" "ishift")
11805 (set (attr "length")
11806 (if_then_else (match_operand 0 "register_operand" "")
11807 (const_string "2")
11808 (const_string "*")))])
11809
11810 ;; This pattern can't accept a variable shift count, since shifts by
11811 ;; zero don't affect the flags. We assume that shifts by constant
11812 ;; zero are optimized away.
11813 (define_insn "*ashrqi3_cmp"
11814 [(set (reg 17)
11815 (compare
11816 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11817 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11818 (const_int 0)))
11819 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11820 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11821 "ix86_match_ccmode (insn, CCGOCmode)
11822 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11823 "sar{b}\t{%2, %0|%0, %2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "QI")])
11826 \f
11827 ;; Logical shift instructions
11828
11829 ;; See comment above `ashldi3' about how this works.
11830
11831 (define_expand "lshrdi3"
11832 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11833 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11834 (match_operand:QI 2 "nonmemory_operand" "")))
11835 (clobber (reg:CC 17))])]
11836 ""
11837 {
11838 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11839 {
11840 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11841 DONE;
11842 }
11843 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11844 DONE;
11845 })
11846
11847 (define_insn "*lshrdi3_1_one_bit_rex64"
11848 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11849 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11850 (match_operand:QI 2 "const1_operand" "")))
11851 (clobber (reg:CC 17))]
11852 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11853 && (TARGET_SHIFT1 || optimize_size)"
11854 "shr{q}\t%0"
11855 [(set_attr "type" "ishift")
11856 (set (attr "length")
11857 (if_then_else (match_operand:DI 0 "register_operand" "")
11858 (const_string "2")
11859 (const_string "*")))])
11860
11861 (define_insn "*lshrdi3_1_rex64"
11862 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11863 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11864 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11865 (clobber (reg:CC 17))]
11866 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11867 "@
11868 shr{q}\t{%2, %0|%0, %2}
11869 shr{q}\t{%b2, %0|%0, %b2}"
11870 [(set_attr "type" "ishift")
11871 (set_attr "mode" "DI")])
11872
11873 ;; This pattern can't accept a variable shift count, since shifts by
11874 ;; zero don't affect the flags. We assume that shifts by constant
11875 ;; zero are optimized away.
11876 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11877 [(set (reg 17)
11878 (compare
11879 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11880 (match_operand:QI 2 "const1_operand" ""))
11881 (const_int 0)))
11882 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11883 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11884 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11885 && (TARGET_SHIFT1 || optimize_size)
11886 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11887 "shr{q}\t%0"
11888 [(set_attr "type" "ishift")
11889 (set (attr "length")
11890 (if_then_else (match_operand:DI 0 "register_operand" "")
11891 (const_string "2")
11892 (const_string "*")))])
11893
11894 ;; This pattern can't accept a variable shift count, since shifts by
11895 ;; zero don't affect the flags. We assume that shifts by constant
11896 ;; zero are optimized away.
11897 (define_insn "*lshrdi3_cmp_rex64"
11898 [(set (reg 17)
11899 (compare
11900 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11901 (match_operand:QI 2 "const_int_operand" "e"))
11902 (const_int 0)))
11903 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11904 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11905 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11906 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11907 "shr{q}\t{%2, %0|%0, %2}"
11908 [(set_attr "type" "ishift")
11909 (set_attr "mode" "DI")])
11910
11911 (define_insn "lshrdi3_1"
11912 [(set (match_operand:DI 0 "register_operand" "=r")
11913 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11914 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11915 (clobber (match_scratch:SI 3 "=&r"))
11916 (clobber (reg:CC 17))]
11917 "!TARGET_64BIT && TARGET_CMOVE"
11918 "#"
11919 [(set_attr "type" "multi")])
11920
11921 (define_insn "*lshrdi3_2"
11922 [(set (match_operand:DI 0 "register_operand" "=r")
11923 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11924 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11925 (clobber (reg:CC 17))]
11926 "!TARGET_64BIT"
11927 "#"
11928 [(set_attr "type" "multi")])
11929
11930 (define_split
11931 [(set (match_operand:DI 0 "register_operand" "")
11932 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11933 (match_operand:QI 2 "nonmemory_operand" "")))
11934 (clobber (match_scratch:SI 3 ""))
11935 (clobber (reg:CC 17))]
11936 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11937 [(const_int 0)]
11938 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11939
11940 (define_split
11941 [(set (match_operand:DI 0 "register_operand" "")
11942 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11943 (match_operand:QI 2 "nonmemory_operand" "")))
11944 (clobber (reg:CC 17))]
11945 "!TARGET_64BIT && reload_completed"
11946 [(const_int 0)]
11947 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11948
11949 (define_expand "lshrsi3"
11950 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11951 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11952 (match_operand:QI 2 "nonmemory_operand" "")))
11953 (clobber (reg:CC 17))]
11954 ""
11955 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11956
11957 (define_insn "*lshrsi3_1_one_bit"
11958 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11959 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11960 (match_operand:QI 2 "const1_operand" "")))
11961 (clobber (reg:CC 17))]
11962 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11963 && (TARGET_SHIFT1 || optimize_size)"
11964 "shr{l}\t%0"
11965 [(set_attr "type" "ishift")
11966 (set (attr "length")
11967 (if_then_else (match_operand:SI 0 "register_operand" "")
11968 (const_string "2")
11969 (const_string "*")))])
11970
11971 (define_insn "*lshrsi3_1_one_bit_zext"
11972 [(set (match_operand:DI 0 "register_operand" "=r")
11973 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11974 (match_operand:QI 2 "const1_operand" "")))
11975 (clobber (reg:CC 17))]
11976 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11977 && (TARGET_SHIFT1 || optimize_size)"
11978 "shr{l}\t%k0"
11979 [(set_attr "type" "ishift")
11980 (set_attr "length" "2")])
11981
11982 (define_insn "*lshrsi3_1"
11983 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11984 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11985 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11986 (clobber (reg:CC 17))]
11987 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11988 "@
11989 shr{l}\t{%2, %0|%0, %2}
11990 shr{l}\t{%b2, %0|%0, %b2}"
11991 [(set_attr "type" "ishift")
11992 (set_attr "mode" "SI")])
11993
11994 (define_insn "*lshrsi3_1_zext"
11995 [(set (match_operand:DI 0 "register_operand" "=r,r")
11996 (zero_extend:DI
11997 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11998 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11999 (clobber (reg:CC 17))]
12000 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12001 "@
12002 shr{l}\t{%2, %k0|%k0, %2}
12003 shr{l}\t{%b2, %k0|%k0, %b2}"
12004 [(set_attr "type" "ishift")
12005 (set_attr "mode" "SI")])
12006
12007 ;; This pattern can't accept a variable shift count, since shifts by
12008 ;; zero don't affect the flags. We assume that shifts by constant
12009 ;; zero are optimized away.
12010 (define_insn "*lshrsi3_one_bit_cmp"
12011 [(set (reg 17)
12012 (compare
12013 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12014 (match_operand:QI 2 "const1_operand" ""))
12015 (const_int 0)))
12016 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12017 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12018 "ix86_match_ccmode (insn, CCGOCmode)
12019 && (TARGET_SHIFT1 || optimize_size)
12020 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12021 "shr{l}\t%0"
12022 [(set_attr "type" "ishift")
12023 (set (attr "length")
12024 (if_then_else (match_operand:SI 0 "register_operand" "")
12025 (const_string "2")
12026 (const_string "*")))])
12027
12028 (define_insn "*lshrsi3_cmp_one_bit_zext"
12029 [(set (reg 17)
12030 (compare
12031 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12032 (match_operand:QI 2 "const1_operand" ""))
12033 (const_int 0)))
12034 (set (match_operand:DI 0 "register_operand" "=r")
12035 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12036 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12037 && (TARGET_SHIFT1 || optimize_size)
12038 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12039 "shr{l}\t%k0"
12040 [(set_attr "type" "ishift")
12041 (set_attr "length" "2")])
12042
12043 ;; This pattern can't accept a variable shift count, since shifts by
12044 ;; zero don't affect the flags. We assume that shifts by constant
12045 ;; zero are optimized away.
12046 (define_insn "*lshrsi3_cmp"
12047 [(set (reg 17)
12048 (compare
12049 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12050 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12051 (const_int 0)))
12052 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12053 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12054 "ix86_match_ccmode (insn, CCGOCmode)
12055 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12056 "shr{l}\t{%2, %0|%0, %2}"
12057 [(set_attr "type" "ishift")
12058 (set_attr "mode" "SI")])
12059
12060 (define_insn "*lshrsi3_cmp_zext"
12061 [(set (reg 17)
12062 (compare
12063 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12064 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12065 (const_int 0)))
12066 (set (match_operand:DI 0 "register_operand" "=r")
12067 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12068 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12069 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12070 "shr{l}\t{%2, %k0|%k0, %2}"
12071 [(set_attr "type" "ishift")
12072 (set_attr "mode" "SI")])
12073
12074 (define_expand "lshrhi3"
12075 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12076 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12077 (match_operand:QI 2 "nonmemory_operand" "")))
12078 (clobber (reg:CC 17))]
12079 "TARGET_HIMODE_MATH"
12080 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12081
12082 (define_insn "*lshrhi3_1_one_bit"
12083 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12084 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12085 (match_operand:QI 2 "const1_operand" "")))
12086 (clobber (reg:CC 17))]
12087 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12088 && (TARGET_SHIFT1 || optimize_size)"
12089 "shr{w}\t%0"
12090 [(set_attr "type" "ishift")
12091 (set (attr "length")
12092 (if_then_else (match_operand 0 "register_operand" "")
12093 (const_string "2")
12094 (const_string "*")))])
12095
12096 (define_insn "*lshrhi3_1"
12097 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12098 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12099 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12100 (clobber (reg:CC 17))]
12101 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12102 "@
12103 shr{w}\t{%2, %0|%0, %2}
12104 shr{w}\t{%b2, %0|%0, %b2}"
12105 [(set_attr "type" "ishift")
12106 (set_attr "mode" "HI")])
12107
12108 ;; This pattern can't accept a variable shift count, since shifts by
12109 ;; zero don't affect the flags. We assume that shifts by constant
12110 ;; zero are optimized away.
12111 (define_insn "*lshrhi3_one_bit_cmp"
12112 [(set (reg 17)
12113 (compare
12114 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12115 (match_operand:QI 2 "const1_operand" ""))
12116 (const_int 0)))
12117 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12118 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12119 "ix86_match_ccmode (insn, CCGOCmode)
12120 && (TARGET_SHIFT1 || optimize_size)
12121 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12122 "shr{w}\t%0"
12123 [(set_attr "type" "ishift")
12124 (set (attr "length")
12125 (if_then_else (match_operand:SI 0 "register_operand" "")
12126 (const_string "2")
12127 (const_string "*")))])
12128
12129 ;; This pattern can't accept a variable shift count, since shifts by
12130 ;; zero don't affect the flags. We assume that shifts by constant
12131 ;; zero are optimized away.
12132 (define_insn "*lshrhi3_cmp"
12133 [(set (reg 17)
12134 (compare
12135 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12137 (const_int 0)))
12138 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12139 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12140 "ix86_match_ccmode (insn, CCGOCmode)
12141 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12142 "shr{w}\t{%2, %0|%0, %2}"
12143 [(set_attr "type" "ishift")
12144 (set_attr "mode" "HI")])
12145
12146 (define_expand "lshrqi3"
12147 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12148 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12149 (match_operand:QI 2 "nonmemory_operand" "")))
12150 (clobber (reg:CC 17))]
12151 "TARGET_QIMODE_MATH"
12152 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12153
12154 (define_insn "*lshrqi3_1_one_bit"
12155 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12156 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12157 (match_operand:QI 2 "const1_operand" "")))
12158 (clobber (reg:CC 17))]
12159 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12160 && (TARGET_SHIFT1 || optimize_size)"
12161 "shr{b}\t%0"
12162 [(set_attr "type" "ishift")
12163 (set (attr "length")
12164 (if_then_else (match_operand 0 "register_operand" "")
12165 (const_string "2")
12166 (const_string "*")))])
12167
12168 (define_insn "*lshrqi3_1_one_bit_slp"
12169 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12170 (lshiftrt:QI (match_dup 0)
12171 (match_operand:QI 1 "const1_operand" "")))
12172 (clobber (reg:CC 17))]
12173 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12174 && (TARGET_SHIFT1 || optimize_size)"
12175 "shr{b}\t%0"
12176 [(set_attr "type" "ishift1")
12177 (set (attr "length")
12178 (if_then_else (match_operand 0 "register_operand" "")
12179 (const_string "2")
12180 (const_string "*")))])
12181
12182 (define_insn "*lshrqi3_1"
12183 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12184 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12185 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12186 (clobber (reg:CC 17))]
12187 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12188 "@
12189 shr{b}\t{%2, %0|%0, %2}
12190 shr{b}\t{%b2, %0|%0, %b2}"
12191 [(set_attr "type" "ishift")
12192 (set_attr "mode" "QI")])
12193
12194 (define_insn "*lshrqi3_1_slp"
12195 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12196 (lshiftrt:QI (match_dup 0)
12197 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12198 (clobber (reg:CC 17))]
12199 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12200 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12201 "@
12202 shr{b}\t{%1, %0|%0, %1}
12203 shr{b}\t{%b1, %0|%0, %b1}"
12204 [(set_attr "type" "ishift1")
12205 (set_attr "mode" "QI")])
12206
12207 ;; This pattern can't accept a variable shift count, since shifts by
12208 ;; zero don't affect the flags. We assume that shifts by constant
12209 ;; zero are optimized away.
12210 (define_insn "*lshrqi2_one_bit_cmp"
12211 [(set (reg 17)
12212 (compare
12213 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12214 (match_operand:QI 2 "const1_operand" ""))
12215 (const_int 0)))
12216 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12217 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12218 "ix86_match_ccmode (insn, CCGOCmode)
12219 && (TARGET_SHIFT1 || optimize_size)
12220 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12221 "shr{b}\t%0"
12222 [(set_attr "type" "ishift")
12223 (set (attr "length")
12224 (if_then_else (match_operand:SI 0 "register_operand" "")
12225 (const_string "2")
12226 (const_string "*")))])
12227
12228 ;; This pattern can't accept a variable shift count, since shifts by
12229 ;; zero don't affect the flags. We assume that shifts by constant
12230 ;; zero are optimized away.
12231 (define_insn "*lshrqi2_cmp"
12232 [(set (reg 17)
12233 (compare
12234 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12235 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12236 (const_int 0)))
12237 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12238 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12239 "ix86_match_ccmode (insn, CCGOCmode)
12240 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12241 "shr{b}\t{%2, %0|%0, %2}"
12242 [(set_attr "type" "ishift")
12243 (set_attr "mode" "QI")])
12244 \f
12245 ;; Rotate instructions
12246
12247 (define_expand "rotldi3"
12248 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12249 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12250 (match_operand:QI 2 "nonmemory_operand" "")))
12251 (clobber (reg:CC 17))]
12252 "TARGET_64BIT"
12253 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12254
12255 (define_insn "*rotlsi3_1_one_bit_rex64"
12256 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12257 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12258 (match_operand:QI 2 "const1_operand" "")))
12259 (clobber (reg:CC 17))]
12260 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12261 && (TARGET_SHIFT1 || optimize_size)"
12262 "rol{q}\t%0"
12263 [(set_attr "type" "rotate")
12264 (set (attr "length")
12265 (if_then_else (match_operand:DI 0 "register_operand" "")
12266 (const_string "2")
12267 (const_string "*")))])
12268
12269 (define_insn "*rotldi3_1_rex64"
12270 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12271 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12272 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12273 (clobber (reg:CC 17))]
12274 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12275 "@
12276 rol{q}\t{%2, %0|%0, %2}
12277 rol{q}\t{%b2, %0|%0, %b2}"
12278 [(set_attr "type" "rotate")
12279 (set_attr "mode" "DI")])
12280
12281 (define_expand "rotlsi3"
12282 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12283 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12284 (match_operand:QI 2 "nonmemory_operand" "")))
12285 (clobber (reg:CC 17))]
12286 ""
12287 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12288
12289 (define_insn "*rotlsi3_1_one_bit"
12290 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12291 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12292 (match_operand:QI 2 "const1_operand" "")))
12293 (clobber (reg:CC 17))]
12294 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12295 && (TARGET_SHIFT1 || optimize_size)"
12296 "rol{l}\t%0"
12297 [(set_attr "type" "rotate")
12298 (set (attr "length")
12299 (if_then_else (match_operand:SI 0 "register_operand" "")
12300 (const_string "2")
12301 (const_string "*")))])
12302
12303 (define_insn "*rotlsi3_1_one_bit_zext"
12304 [(set (match_operand:DI 0 "register_operand" "=r")
12305 (zero_extend:DI
12306 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12307 (match_operand:QI 2 "const1_operand" ""))))
12308 (clobber (reg:CC 17))]
12309 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12310 && (TARGET_SHIFT1 || optimize_size)"
12311 "rol{l}\t%k0"
12312 [(set_attr "type" "rotate")
12313 (set_attr "length" "2")])
12314
12315 (define_insn "*rotlsi3_1"
12316 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12317 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12318 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12319 (clobber (reg:CC 17))]
12320 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12321 "@
12322 rol{l}\t{%2, %0|%0, %2}
12323 rol{l}\t{%b2, %0|%0, %b2}"
12324 [(set_attr "type" "rotate")
12325 (set_attr "mode" "SI")])
12326
12327 (define_insn "*rotlsi3_1_zext"
12328 [(set (match_operand:DI 0 "register_operand" "=r,r")
12329 (zero_extend:DI
12330 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12331 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12332 (clobber (reg:CC 17))]
12333 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12334 "@
12335 rol{l}\t{%2, %k0|%k0, %2}
12336 rol{l}\t{%b2, %k0|%k0, %b2}"
12337 [(set_attr "type" "rotate")
12338 (set_attr "mode" "SI")])
12339
12340 (define_expand "rotlhi3"
12341 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12342 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12343 (match_operand:QI 2 "nonmemory_operand" "")))
12344 (clobber (reg:CC 17))]
12345 "TARGET_HIMODE_MATH"
12346 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12347
12348 (define_insn "*rotlhi3_1_one_bit"
12349 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12350 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351 (match_operand:QI 2 "const1_operand" "")))
12352 (clobber (reg:CC 17))]
12353 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12354 && (TARGET_SHIFT1 || optimize_size)"
12355 "rol{w}\t%0"
12356 [(set_attr "type" "rotate")
12357 (set (attr "length")
12358 (if_then_else (match_operand 0 "register_operand" "")
12359 (const_string "2")
12360 (const_string "*")))])
12361
12362 (define_insn "*rotlhi3_1"
12363 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12364 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12365 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12366 (clobber (reg:CC 17))]
12367 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12368 "@
12369 rol{w}\t{%2, %0|%0, %2}
12370 rol{w}\t{%b2, %0|%0, %b2}"
12371 [(set_attr "type" "rotate")
12372 (set_attr "mode" "HI")])
12373
12374 (define_expand "rotlqi3"
12375 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12376 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12377 (match_operand:QI 2 "nonmemory_operand" "")))
12378 (clobber (reg:CC 17))]
12379 "TARGET_QIMODE_MATH"
12380 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12381
12382 (define_insn "*rotlqi3_1_one_bit_slp"
12383 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12384 (rotate:QI (match_dup 0)
12385 (match_operand:QI 1 "const1_operand" "")))
12386 (clobber (reg:CC 17))]
12387 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12388 && (TARGET_SHIFT1 || optimize_size)"
12389 "rol{b}\t%0"
12390 [(set_attr "type" "rotate1")
12391 (set (attr "length")
12392 (if_then_else (match_operand 0 "register_operand" "")
12393 (const_string "2")
12394 (const_string "*")))])
12395
12396 (define_insn "*rotlqi3_1_one_bit"
12397 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12398 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12399 (match_operand:QI 2 "const1_operand" "")))
12400 (clobber (reg:CC 17))]
12401 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12402 && (TARGET_SHIFT1 || optimize_size)"
12403 "rol{b}\t%0"
12404 [(set_attr "type" "rotate")
12405 (set (attr "length")
12406 (if_then_else (match_operand 0 "register_operand" "")
12407 (const_string "2")
12408 (const_string "*")))])
12409
12410 (define_insn "*rotlqi3_1_slp"
12411 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12412 (rotate:QI (match_dup 0)
12413 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12414 (clobber (reg:CC 17))]
12415 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12416 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12417 "@
12418 rol{b}\t{%1, %0|%0, %1}
12419 rol{b}\t{%b1, %0|%0, %b1}"
12420 [(set_attr "type" "rotate1")
12421 (set_attr "mode" "QI")])
12422
12423 (define_insn "*rotlqi3_1"
12424 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12425 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12426 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12427 (clobber (reg:CC 17))]
12428 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12429 "@
12430 rol{b}\t{%2, %0|%0, %2}
12431 rol{b}\t{%b2, %0|%0, %b2}"
12432 [(set_attr "type" "rotate")
12433 (set_attr "mode" "QI")])
12434
12435 (define_expand "rotrdi3"
12436 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12437 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12438 (match_operand:QI 2 "nonmemory_operand" "")))
12439 (clobber (reg:CC 17))]
12440 "TARGET_64BIT"
12441 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12442
12443 (define_insn "*rotrdi3_1_one_bit_rex64"
12444 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12445 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12446 (match_operand:QI 2 "const1_operand" "")))
12447 (clobber (reg:CC 17))]
12448 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12449 && (TARGET_SHIFT1 || optimize_size)"
12450 "ror{q}\t%0"
12451 [(set_attr "type" "rotate")
12452 (set (attr "length")
12453 (if_then_else (match_operand:DI 0 "register_operand" "")
12454 (const_string "2")
12455 (const_string "*")))])
12456
12457 (define_insn "*rotrdi3_1_rex64"
12458 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12459 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12460 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12461 (clobber (reg:CC 17))]
12462 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12463 "@
12464 ror{q}\t{%2, %0|%0, %2}
12465 ror{q}\t{%b2, %0|%0, %b2}"
12466 [(set_attr "type" "rotate")
12467 (set_attr "mode" "DI")])
12468
12469 (define_expand "rotrsi3"
12470 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12471 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12472 (match_operand:QI 2 "nonmemory_operand" "")))
12473 (clobber (reg:CC 17))]
12474 ""
12475 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12476
12477 (define_insn "*rotrsi3_1_one_bit"
12478 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12479 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12480 (match_operand:QI 2 "const1_operand" "")))
12481 (clobber (reg:CC 17))]
12482 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12483 && (TARGET_SHIFT1 || optimize_size)"
12484 "ror{l}\t%0"
12485 [(set_attr "type" "rotate")
12486 (set (attr "length")
12487 (if_then_else (match_operand:SI 0 "register_operand" "")
12488 (const_string "2")
12489 (const_string "*")))])
12490
12491 (define_insn "*rotrsi3_1_one_bit_zext"
12492 [(set (match_operand:DI 0 "register_operand" "=r")
12493 (zero_extend:DI
12494 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12495 (match_operand:QI 2 "const1_operand" ""))))
12496 (clobber (reg:CC 17))]
12497 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12498 && (TARGET_SHIFT1 || optimize_size)"
12499 "ror{l}\t%k0"
12500 [(set_attr "type" "rotate")
12501 (set (attr "length")
12502 (if_then_else (match_operand:SI 0 "register_operand" "")
12503 (const_string "2")
12504 (const_string "*")))])
12505
12506 (define_insn "*rotrsi3_1"
12507 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12508 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12509 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12510 (clobber (reg:CC 17))]
12511 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12512 "@
12513 ror{l}\t{%2, %0|%0, %2}
12514 ror{l}\t{%b2, %0|%0, %b2}"
12515 [(set_attr "type" "rotate")
12516 (set_attr "mode" "SI")])
12517
12518 (define_insn "*rotrsi3_1_zext"
12519 [(set (match_operand:DI 0 "register_operand" "=r,r")
12520 (zero_extend:DI
12521 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12522 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12523 (clobber (reg:CC 17))]
12524 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12525 "@
12526 ror{l}\t{%2, %k0|%k0, %2}
12527 ror{l}\t{%b2, %k0|%k0, %b2}"
12528 [(set_attr "type" "rotate")
12529 (set_attr "mode" "SI")])
12530
12531 (define_expand "rotrhi3"
12532 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12533 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12534 (match_operand:QI 2 "nonmemory_operand" "")))
12535 (clobber (reg:CC 17))]
12536 "TARGET_HIMODE_MATH"
12537 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12538
12539 (define_insn "*rotrhi3_one_bit"
12540 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12541 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12542 (match_operand:QI 2 "const1_operand" "")))
12543 (clobber (reg:CC 17))]
12544 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12545 && (TARGET_SHIFT1 || optimize_size)"
12546 "ror{w}\t%0"
12547 [(set_attr "type" "rotate")
12548 (set (attr "length")
12549 (if_then_else (match_operand 0 "register_operand" "")
12550 (const_string "2")
12551 (const_string "*")))])
12552
12553 (define_insn "*rotrhi3"
12554 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12555 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12556 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12557 (clobber (reg:CC 17))]
12558 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12559 "@
12560 ror{w}\t{%2, %0|%0, %2}
12561 ror{w}\t{%b2, %0|%0, %b2}"
12562 [(set_attr "type" "rotate")
12563 (set_attr "mode" "HI")])
12564
12565 (define_expand "rotrqi3"
12566 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12567 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12568 (match_operand:QI 2 "nonmemory_operand" "")))
12569 (clobber (reg:CC 17))]
12570 "TARGET_QIMODE_MATH"
12571 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12572
12573 (define_insn "*rotrqi3_1_one_bit"
12574 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12575 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12576 (match_operand:QI 2 "const1_operand" "")))
12577 (clobber (reg:CC 17))]
12578 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12579 && (TARGET_SHIFT1 || optimize_size)"
12580 "ror{b}\t%0"
12581 [(set_attr "type" "rotate")
12582 (set (attr "length")
12583 (if_then_else (match_operand 0 "register_operand" "")
12584 (const_string "2")
12585 (const_string "*")))])
12586
12587 (define_insn "*rotrqi3_1_one_bit_slp"
12588 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12589 (rotatert:QI (match_dup 0)
12590 (match_operand:QI 1 "const1_operand" "")))
12591 (clobber (reg:CC 17))]
12592 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12593 && (TARGET_SHIFT1 || optimize_size)"
12594 "ror{b}\t%0"
12595 [(set_attr "type" "rotate1")
12596 (set (attr "length")
12597 (if_then_else (match_operand 0 "register_operand" "")
12598 (const_string "2")
12599 (const_string "*")))])
12600
12601 (define_insn "*rotrqi3_1"
12602 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12603 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12604 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12605 (clobber (reg:CC 17))]
12606 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12607 "@
12608 ror{b}\t{%2, %0|%0, %2}
12609 ror{b}\t{%b2, %0|%0, %b2}"
12610 [(set_attr "type" "rotate")
12611 (set_attr "mode" "QI")])
12612
12613 (define_insn "*rotrqi3_1_slp"
12614 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12615 (rotatert:QI (match_dup 0)
12616 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12617 (clobber (reg:CC 17))]
12618 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12619 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12620 "@
12621 ror{b}\t{%1, %0|%0, %1}
12622 ror{b}\t{%b1, %0|%0, %b1}"
12623 [(set_attr "type" "rotate1")
12624 (set_attr "mode" "QI")])
12625 \f
12626 ;; Bit set / bit test instructions
12627
12628 (define_expand "extv"
12629 [(set (match_operand:SI 0 "register_operand" "")
12630 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12631 (match_operand:SI 2 "immediate_operand" "")
12632 (match_operand:SI 3 "immediate_operand" "")))]
12633 ""
12634 {
12635 /* Handle extractions from %ah et al. */
12636 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12637 FAIL;
12638
12639 /* From mips.md: extract_bit_field doesn't verify that our source
12640 matches the predicate, so check it again here. */
12641 if (! register_operand (operands[1], VOIDmode))
12642 FAIL;
12643 })
12644
12645 (define_expand "extzv"
12646 [(set (match_operand:SI 0 "register_operand" "")
12647 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12648 (match_operand:SI 2 "immediate_operand" "")
12649 (match_operand:SI 3 "immediate_operand" "")))]
12650 ""
12651 {
12652 /* Handle extractions from %ah et al. */
12653 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12654 FAIL;
12655
12656 /* From mips.md: extract_bit_field doesn't verify that our source
12657 matches the predicate, so check it again here. */
12658 if (! register_operand (operands[1], VOIDmode))
12659 FAIL;
12660 })
12661
12662 (define_expand "insv"
12663 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12664 (match_operand:SI 1 "immediate_operand" "")
12665 (match_operand:SI 2 "immediate_operand" ""))
12666 (match_operand:SI 3 "register_operand" ""))]
12667 ""
12668 {
12669 /* Handle extractions from %ah et al. */
12670 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12671 FAIL;
12672
12673 /* From mips.md: insert_bit_field doesn't verify that our source
12674 matches the predicate, so check it again here. */
12675 if (! register_operand (operands[0], VOIDmode))
12676 FAIL;
12677 })
12678
12679 ;; %%% bts, btr, btc, bt.
12680 \f
12681 ;; Store-flag instructions.
12682
12683 ;; For all sCOND expanders, also expand the compare or test insn that
12684 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12685
12686 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12687 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12688 ;; way, which can later delete the movzx if only QImode is needed.
12689
12690 (define_expand "seq"
12691 [(set (match_operand:QI 0 "register_operand" "")
12692 (eq:QI (reg:CC 17) (const_int 0)))]
12693 ""
12694 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12695
12696 (define_expand "sne"
12697 [(set (match_operand:QI 0 "register_operand" "")
12698 (ne:QI (reg:CC 17) (const_int 0)))]
12699 ""
12700 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12701
12702 (define_expand "sgt"
12703 [(set (match_operand:QI 0 "register_operand" "")
12704 (gt:QI (reg:CC 17) (const_int 0)))]
12705 ""
12706 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12707
12708 (define_expand "sgtu"
12709 [(set (match_operand:QI 0 "register_operand" "")
12710 (gtu:QI (reg:CC 17) (const_int 0)))]
12711 ""
12712 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12713
12714 (define_expand "slt"
12715 [(set (match_operand:QI 0 "register_operand" "")
12716 (lt:QI (reg:CC 17) (const_int 0)))]
12717 ""
12718 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12719
12720 (define_expand "sltu"
12721 [(set (match_operand:QI 0 "register_operand" "")
12722 (ltu:QI (reg:CC 17) (const_int 0)))]
12723 ""
12724 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12725
12726 (define_expand "sge"
12727 [(set (match_operand:QI 0 "register_operand" "")
12728 (ge:QI (reg:CC 17) (const_int 0)))]
12729 ""
12730 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12731
12732 (define_expand "sgeu"
12733 [(set (match_operand:QI 0 "register_operand" "")
12734 (geu:QI (reg:CC 17) (const_int 0)))]
12735 ""
12736 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12737
12738 (define_expand "sle"
12739 [(set (match_operand:QI 0 "register_operand" "")
12740 (le:QI (reg:CC 17) (const_int 0)))]
12741 ""
12742 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12743
12744 (define_expand "sleu"
12745 [(set (match_operand:QI 0 "register_operand" "")
12746 (leu:QI (reg:CC 17) (const_int 0)))]
12747 ""
12748 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12749
12750 (define_expand "sunordered"
12751 [(set (match_operand:QI 0 "register_operand" "")
12752 (unordered:QI (reg:CC 17) (const_int 0)))]
12753 "TARGET_80387 || TARGET_SSE"
12754 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12755
12756 (define_expand "sordered"
12757 [(set (match_operand:QI 0 "register_operand" "")
12758 (ordered:QI (reg:CC 17) (const_int 0)))]
12759 "TARGET_80387"
12760 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12761
12762 (define_expand "suneq"
12763 [(set (match_operand:QI 0 "register_operand" "")
12764 (uneq:QI (reg:CC 17) (const_int 0)))]
12765 "TARGET_80387 || TARGET_SSE"
12766 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12767
12768 (define_expand "sunge"
12769 [(set (match_operand:QI 0 "register_operand" "")
12770 (unge:QI (reg:CC 17) (const_int 0)))]
12771 "TARGET_80387 || TARGET_SSE"
12772 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12773
12774 (define_expand "sungt"
12775 [(set (match_operand:QI 0 "register_operand" "")
12776 (ungt:QI (reg:CC 17) (const_int 0)))]
12777 "TARGET_80387 || TARGET_SSE"
12778 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12779
12780 (define_expand "sunle"
12781 [(set (match_operand:QI 0 "register_operand" "")
12782 (unle:QI (reg:CC 17) (const_int 0)))]
12783 "TARGET_80387 || TARGET_SSE"
12784 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12785
12786 (define_expand "sunlt"
12787 [(set (match_operand:QI 0 "register_operand" "")
12788 (unlt:QI (reg:CC 17) (const_int 0)))]
12789 "TARGET_80387 || TARGET_SSE"
12790 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12791
12792 (define_expand "sltgt"
12793 [(set (match_operand:QI 0 "register_operand" "")
12794 (ltgt:QI (reg:CC 17) (const_int 0)))]
12795 "TARGET_80387 || TARGET_SSE"
12796 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12797
12798 (define_insn "*setcc_1"
12799 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12800 (match_operator:QI 1 "ix86_comparison_operator"
12801 [(reg 17) (const_int 0)]))]
12802 ""
12803 "set%C1\t%0"
12804 [(set_attr "type" "setcc")
12805 (set_attr "mode" "QI")])
12806
12807 (define_insn "setcc_2"
12808 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12809 (match_operator:QI 1 "ix86_comparison_operator"
12810 [(reg 17) (const_int 0)]))]
12811 ""
12812 "set%C1\t%0"
12813 [(set_attr "type" "setcc")
12814 (set_attr "mode" "QI")])
12815
12816 ;; In general it is not safe to assume too much about CCmode registers,
12817 ;; so simplify-rtx stops when it sees a second one. Under certain
12818 ;; conditions this is safe on x86, so help combine not create
12819 ;;
12820 ;; seta %al
12821 ;; testb %al, %al
12822 ;; sete %al
12823
12824 (define_split
12825 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12826 (ne:QI (match_operator 1 "ix86_comparison_operator"
12827 [(reg 17) (const_int 0)])
12828 (const_int 0)))]
12829 ""
12830 [(set (match_dup 0) (match_dup 1))]
12831 {
12832 PUT_MODE (operands[1], QImode);
12833 })
12834
12835 (define_split
12836 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12837 (ne:QI (match_operator 1 "ix86_comparison_operator"
12838 [(reg 17) (const_int 0)])
12839 (const_int 0)))]
12840 ""
12841 [(set (match_dup 0) (match_dup 1))]
12842 {
12843 PUT_MODE (operands[1], QImode);
12844 })
12845
12846 (define_split
12847 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12848 (eq:QI (match_operator 1 "ix86_comparison_operator"
12849 [(reg 17) (const_int 0)])
12850 (const_int 0)))]
12851 ""
12852 [(set (match_dup 0) (match_dup 1))]
12853 {
12854 rtx new_op1 = copy_rtx (operands[1]);
12855 operands[1] = new_op1;
12856 PUT_MODE (new_op1, QImode);
12857 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12858 GET_MODE (XEXP (new_op1, 0))));
12859
12860 /* Make sure that (a) the CCmode we have for the flags is strong
12861 enough for the reversed compare or (b) we have a valid FP compare. */
12862 if (! ix86_comparison_operator (new_op1, VOIDmode))
12863 FAIL;
12864 })
12865
12866 (define_split
12867 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12868 (eq:QI (match_operator 1 "ix86_comparison_operator"
12869 [(reg 17) (const_int 0)])
12870 (const_int 0)))]
12871 ""
12872 [(set (match_dup 0) (match_dup 1))]
12873 {
12874 rtx new_op1 = copy_rtx (operands[1]);
12875 operands[1] = new_op1;
12876 PUT_MODE (new_op1, QImode);
12877 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12878 GET_MODE (XEXP (new_op1, 0))));
12879
12880 /* Make sure that (a) the CCmode we have for the flags is strong
12881 enough for the reversed compare or (b) we have a valid FP compare. */
12882 if (! ix86_comparison_operator (new_op1, VOIDmode))
12883 FAIL;
12884 })
12885
12886 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12887 ;; subsequent logical operations are used to imitate conditional moves.
12888 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12889 ;; it directly. Further holding this value in pseudo register might bring
12890 ;; problem in implicit normalization in spill code.
12891 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12892 ;; instructions after reload by splitting the conditional move patterns.
12893
12894 (define_insn "*sse_setccsf"
12895 [(set (match_operand:SF 0 "register_operand" "=x")
12896 (match_operator:SF 1 "sse_comparison_operator"
12897 [(match_operand:SF 2 "register_operand" "0")
12898 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12899 "TARGET_SSE && reload_completed"
12900 "cmp%D1ss\t{%3, %0|%0, %3}"
12901 [(set_attr "type" "ssecmp")
12902 (set_attr "mode" "SF")])
12903
12904 (define_insn "*sse_setccdf"
12905 [(set (match_operand:DF 0 "register_operand" "=Y")
12906 (match_operator:DF 1 "sse_comparison_operator"
12907 [(match_operand:DF 2 "register_operand" "0")
12908 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12909 "TARGET_SSE2 && reload_completed"
12910 "cmp%D1sd\t{%3, %0|%0, %3}"
12911 [(set_attr "type" "ssecmp")
12912 (set_attr "mode" "DF")])
12913 \f
12914 ;; Basic conditional jump instructions.
12915 ;; We ignore the overflow flag for signed branch instructions.
12916
12917 ;; For all bCOND expanders, also expand the compare or test insn that
12918 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12919
12920 (define_expand "beq"
12921 [(set (pc)
12922 (if_then_else (match_dup 1)
12923 (label_ref (match_operand 0 "" ""))
12924 (pc)))]
12925 ""
12926 "ix86_expand_branch (EQ, operands[0]); DONE;")
12927
12928 (define_expand "bne"
12929 [(set (pc)
12930 (if_then_else (match_dup 1)
12931 (label_ref (match_operand 0 "" ""))
12932 (pc)))]
12933 ""
12934 "ix86_expand_branch (NE, operands[0]); DONE;")
12935
12936 (define_expand "bgt"
12937 [(set (pc)
12938 (if_then_else (match_dup 1)
12939 (label_ref (match_operand 0 "" ""))
12940 (pc)))]
12941 ""
12942 "ix86_expand_branch (GT, operands[0]); DONE;")
12943
12944 (define_expand "bgtu"
12945 [(set (pc)
12946 (if_then_else (match_dup 1)
12947 (label_ref (match_operand 0 "" ""))
12948 (pc)))]
12949 ""
12950 "ix86_expand_branch (GTU, operands[0]); DONE;")
12951
12952 (define_expand "blt"
12953 [(set (pc)
12954 (if_then_else (match_dup 1)
12955 (label_ref (match_operand 0 "" ""))
12956 (pc)))]
12957 ""
12958 "ix86_expand_branch (LT, operands[0]); DONE;")
12959
12960 (define_expand "bltu"
12961 [(set (pc)
12962 (if_then_else (match_dup 1)
12963 (label_ref (match_operand 0 "" ""))
12964 (pc)))]
12965 ""
12966 "ix86_expand_branch (LTU, operands[0]); DONE;")
12967
12968 (define_expand "bge"
12969 [(set (pc)
12970 (if_then_else (match_dup 1)
12971 (label_ref (match_operand 0 "" ""))
12972 (pc)))]
12973 ""
12974 "ix86_expand_branch (GE, operands[0]); DONE;")
12975
12976 (define_expand "bgeu"
12977 [(set (pc)
12978 (if_then_else (match_dup 1)
12979 (label_ref (match_operand 0 "" ""))
12980 (pc)))]
12981 ""
12982 "ix86_expand_branch (GEU, operands[0]); DONE;")
12983
12984 (define_expand "ble"
12985 [(set (pc)
12986 (if_then_else (match_dup 1)
12987 (label_ref (match_operand 0 "" ""))
12988 (pc)))]
12989 ""
12990 "ix86_expand_branch (LE, operands[0]); DONE;")
12991
12992 (define_expand "bleu"
12993 [(set (pc)
12994 (if_then_else (match_dup 1)
12995 (label_ref (match_operand 0 "" ""))
12996 (pc)))]
12997 ""
12998 "ix86_expand_branch (LEU, operands[0]); DONE;")
12999
13000 (define_expand "bunordered"
13001 [(set (pc)
13002 (if_then_else (match_dup 1)
13003 (label_ref (match_operand 0 "" ""))
13004 (pc)))]
13005 "TARGET_80387 || TARGET_SSE"
13006 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13007
13008 (define_expand "bordered"
13009 [(set (pc)
13010 (if_then_else (match_dup 1)
13011 (label_ref (match_operand 0 "" ""))
13012 (pc)))]
13013 "TARGET_80387 || TARGET_SSE"
13014 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13015
13016 (define_expand "buneq"
13017 [(set (pc)
13018 (if_then_else (match_dup 1)
13019 (label_ref (match_operand 0 "" ""))
13020 (pc)))]
13021 "TARGET_80387 || TARGET_SSE"
13022 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13023
13024 (define_expand "bunge"
13025 [(set (pc)
13026 (if_then_else (match_dup 1)
13027 (label_ref (match_operand 0 "" ""))
13028 (pc)))]
13029 "TARGET_80387 || TARGET_SSE"
13030 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13031
13032 (define_expand "bungt"
13033 [(set (pc)
13034 (if_then_else (match_dup 1)
13035 (label_ref (match_operand 0 "" ""))
13036 (pc)))]
13037 "TARGET_80387 || TARGET_SSE"
13038 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13039
13040 (define_expand "bunle"
13041 [(set (pc)
13042 (if_then_else (match_dup 1)
13043 (label_ref (match_operand 0 "" ""))
13044 (pc)))]
13045 "TARGET_80387 || TARGET_SSE"
13046 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13047
13048 (define_expand "bunlt"
13049 [(set (pc)
13050 (if_then_else (match_dup 1)
13051 (label_ref (match_operand 0 "" ""))
13052 (pc)))]
13053 "TARGET_80387 || TARGET_SSE"
13054 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13055
13056 (define_expand "bltgt"
13057 [(set (pc)
13058 (if_then_else (match_dup 1)
13059 (label_ref (match_operand 0 "" ""))
13060 (pc)))]
13061 "TARGET_80387 || TARGET_SSE"
13062 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13063
13064 (define_insn "*jcc_1"
13065 [(set (pc)
13066 (if_then_else (match_operator 1 "ix86_comparison_operator"
13067 [(reg 17) (const_int 0)])
13068 (label_ref (match_operand 0 "" ""))
13069 (pc)))]
13070 ""
13071 "%+j%C1\t%l0"
13072 [(set_attr "type" "ibr")
13073 (set_attr "modrm" "0")
13074 (set (attr "length")
13075 (if_then_else (and (ge (minus (match_dup 0) (pc))
13076 (const_int -126))
13077 (lt (minus (match_dup 0) (pc))
13078 (const_int 128)))
13079 (const_int 2)
13080 (const_int 6)))])
13081
13082 (define_insn "*jcc_2"
13083 [(set (pc)
13084 (if_then_else (match_operator 1 "ix86_comparison_operator"
13085 [(reg 17) (const_int 0)])
13086 (pc)
13087 (label_ref (match_operand 0 "" ""))))]
13088 ""
13089 "%+j%c1\t%l0"
13090 [(set_attr "type" "ibr")
13091 (set_attr "modrm" "0")
13092 (set (attr "length")
13093 (if_then_else (and (ge (minus (match_dup 0) (pc))
13094 (const_int -126))
13095 (lt (minus (match_dup 0) (pc))
13096 (const_int 128)))
13097 (const_int 2)
13098 (const_int 6)))])
13099
13100 ;; In general it is not safe to assume too much about CCmode registers,
13101 ;; so simplify-rtx stops when it sees a second one. Under certain
13102 ;; conditions this is safe on x86, so help combine not create
13103 ;;
13104 ;; seta %al
13105 ;; testb %al, %al
13106 ;; je Lfoo
13107
13108 (define_split
13109 [(set (pc)
13110 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13111 [(reg 17) (const_int 0)])
13112 (const_int 0))
13113 (label_ref (match_operand 1 "" ""))
13114 (pc)))]
13115 ""
13116 [(set (pc)
13117 (if_then_else (match_dup 0)
13118 (label_ref (match_dup 1))
13119 (pc)))]
13120 {
13121 PUT_MODE (operands[0], VOIDmode);
13122 })
13123
13124 (define_split
13125 [(set (pc)
13126 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13127 [(reg 17) (const_int 0)])
13128 (const_int 0))
13129 (label_ref (match_operand 1 "" ""))
13130 (pc)))]
13131 ""
13132 [(set (pc)
13133 (if_then_else (match_dup 0)
13134 (label_ref (match_dup 1))
13135 (pc)))]
13136 {
13137 rtx new_op0 = copy_rtx (operands[0]);
13138 operands[0] = new_op0;
13139 PUT_MODE (new_op0, VOIDmode);
13140 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13141 GET_MODE (XEXP (new_op0, 0))));
13142
13143 /* Make sure that (a) the CCmode we have for the flags is strong
13144 enough for the reversed compare or (b) we have a valid FP compare. */
13145 if (! ix86_comparison_operator (new_op0, VOIDmode))
13146 FAIL;
13147 })
13148
13149 ;; Define combination compare-and-branch fp compare instructions to use
13150 ;; during early optimization. Splitting the operation apart early makes
13151 ;; for bad code when we want to reverse the operation.
13152
13153 (define_insn "*fp_jcc_1"
13154 [(set (pc)
13155 (if_then_else (match_operator 0 "comparison_operator"
13156 [(match_operand 1 "register_operand" "f")
13157 (match_operand 2 "register_operand" "f")])
13158 (label_ref (match_operand 3 "" ""))
13159 (pc)))
13160 (clobber (reg:CCFP 18))
13161 (clobber (reg:CCFP 17))]
13162 "TARGET_CMOVE && TARGET_80387
13163 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13164 && FLOAT_MODE_P (GET_MODE (operands[1]))
13165 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13166 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13167 "#")
13168
13169 (define_insn "*fp_jcc_1_sse"
13170 [(set (pc)
13171 (if_then_else (match_operator 0 "comparison_operator"
13172 [(match_operand 1 "register_operand" "f#x,x#f")
13173 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13174 (label_ref (match_operand 3 "" ""))
13175 (pc)))
13176 (clobber (reg:CCFP 18))
13177 (clobber (reg:CCFP 17))]
13178 "TARGET_80387
13179 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13180 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13181 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13182 "#")
13183
13184 (define_insn "*fp_jcc_1_sse_only"
13185 [(set (pc)
13186 (if_then_else (match_operator 0 "comparison_operator"
13187 [(match_operand 1 "register_operand" "x")
13188 (match_operand 2 "nonimmediate_operand" "xm")])
13189 (label_ref (match_operand 3 "" ""))
13190 (pc)))
13191 (clobber (reg:CCFP 18))
13192 (clobber (reg:CCFP 17))]
13193 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13194 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13195 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13196 "#")
13197
13198 (define_insn "*fp_jcc_2"
13199 [(set (pc)
13200 (if_then_else (match_operator 0 "comparison_operator"
13201 [(match_operand 1 "register_operand" "f")
13202 (match_operand 2 "register_operand" "f")])
13203 (pc)
13204 (label_ref (match_operand 3 "" ""))))
13205 (clobber (reg:CCFP 18))
13206 (clobber (reg:CCFP 17))]
13207 "TARGET_CMOVE && TARGET_80387
13208 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13209 && FLOAT_MODE_P (GET_MODE (operands[1]))
13210 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13211 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13212 "#")
13213
13214 (define_insn "*fp_jcc_2_sse"
13215 [(set (pc)
13216 (if_then_else (match_operator 0 "comparison_operator"
13217 [(match_operand 1 "register_operand" "f#x,x#f")
13218 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13219 (pc)
13220 (label_ref (match_operand 3 "" ""))))
13221 (clobber (reg:CCFP 18))
13222 (clobber (reg:CCFP 17))]
13223 "TARGET_80387
13224 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13225 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13226 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227 "#")
13228
13229 (define_insn "*fp_jcc_2_sse_only"
13230 [(set (pc)
13231 (if_then_else (match_operator 0 "comparison_operator"
13232 [(match_operand 1 "register_operand" "x")
13233 (match_operand 2 "nonimmediate_operand" "xm")])
13234 (pc)
13235 (label_ref (match_operand 3 "" ""))))
13236 (clobber (reg:CCFP 18))
13237 (clobber (reg:CCFP 17))]
13238 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13239 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13240 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13241 "#")
13242
13243 (define_insn "*fp_jcc_3"
13244 [(set (pc)
13245 (if_then_else (match_operator 0 "comparison_operator"
13246 [(match_operand 1 "register_operand" "f")
13247 (match_operand 2 "nonimmediate_operand" "fm")])
13248 (label_ref (match_operand 3 "" ""))
13249 (pc)))
13250 (clobber (reg:CCFP 18))
13251 (clobber (reg:CCFP 17))
13252 (clobber (match_scratch:HI 4 "=a"))]
13253 "TARGET_80387
13254 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13255 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13256 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13257 && SELECT_CC_MODE (GET_CODE (operands[0]),
13258 operands[1], operands[2]) == CCFPmode
13259 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13260 "#")
13261
13262 (define_insn "*fp_jcc_4"
13263 [(set (pc)
13264 (if_then_else (match_operator 0 "comparison_operator"
13265 [(match_operand 1 "register_operand" "f")
13266 (match_operand 2 "nonimmediate_operand" "fm")])
13267 (pc)
13268 (label_ref (match_operand 3 "" ""))))
13269 (clobber (reg:CCFP 18))
13270 (clobber (reg:CCFP 17))
13271 (clobber (match_scratch:HI 4 "=a"))]
13272 "TARGET_80387
13273 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13274 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13275 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13276 && SELECT_CC_MODE (GET_CODE (operands[0]),
13277 operands[1], operands[2]) == CCFPmode
13278 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13279 "#")
13280
13281 (define_insn "*fp_jcc_5"
13282 [(set (pc)
13283 (if_then_else (match_operator 0 "comparison_operator"
13284 [(match_operand 1 "register_operand" "f")
13285 (match_operand 2 "register_operand" "f")])
13286 (label_ref (match_operand 3 "" ""))
13287 (pc)))
13288 (clobber (reg:CCFP 18))
13289 (clobber (reg:CCFP 17))
13290 (clobber (match_scratch:HI 4 "=a"))]
13291 "TARGET_80387
13292 && FLOAT_MODE_P (GET_MODE (operands[1]))
13293 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13294 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13295 "#")
13296
13297 (define_insn "*fp_jcc_6"
13298 [(set (pc)
13299 (if_then_else (match_operator 0 "comparison_operator"
13300 [(match_operand 1 "register_operand" "f")
13301 (match_operand 2 "register_operand" "f")])
13302 (pc)
13303 (label_ref (match_operand 3 "" ""))))
13304 (clobber (reg:CCFP 18))
13305 (clobber (reg:CCFP 17))
13306 (clobber (match_scratch:HI 4 "=a"))]
13307 "TARGET_80387
13308 && FLOAT_MODE_P (GET_MODE (operands[1]))
13309 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13310 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13311 "#")
13312
13313 (define_split
13314 [(set (pc)
13315 (if_then_else (match_operator 0 "comparison_operator"
13316 [(match_operand 1 "register_operand" "")
13317 (match_operand 2 "nonimmediate_operand" "")])
13318 (match_operand 3 "" "")
13319 (match_operand 4 "" "")))
13320 (clobber (reg:CCFP 18))
13321 (clobber (reg:CCFP 17))]
13322 "reload_completed"
13323 [(const_int 0)]
13324 {
13325 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13326 operands[3], operands[4], NULL_RTX);
13327 DONE;
13328 })
13329
13330 (define_split
13331 [(set (pc)
13332 (if_then_else (match_operator 0 "comparison_operator"
13333 [(match_operand 1 "register_operand" "")
13334 (match_operand 2 "nonimmediate_operand" "")])
13335 (match_operand 3 "" "")
13336 (match_operand 4 "" "")))
13337 (clobber (reg:CCFP 18))
13338 (clobber (reg:CCFP 17))
13339 (clobber (match_scratch:HI 5 "=a"))]
13340 "reload_completed"
13341 [(set (pc)
13342 (if_then_else (match_dup 6)
13343 (match_dup 3)
13344 (match_dup 4)))]
13345 {
13346 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13347 operands[3], operands[4], operands[5]);
13348 DONE;
13349 })
13350 \f
13351 ;; Unconditional and other jump instructions
13352
13353 (define_insn "jump"
13354 [(set (pc)
13355 (label_ref (match_operand 0 "" "")))]
13356 ""
13357 "jmp\t%l0"
13358 [(set_attr "type" "ibr")
13359 (set (attr "length")
13360 (if_then_else (and (ge (minus (match_dup 0) (pc))
13361 (const_int -126))
13362 (lt (minus (match_dup 0) (pc))
13363 (const_int 128)))
13364 (const_int 2)
13365 (const_int 5)))
13366 (set_attr "modrm" "0")])
13367
13368 (define_expand "indirect_jump"
13369 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13370 ""
13371 "")
13372
13373 (define_insn "*indirect_jump"
13374 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13375 "!TARGET_64BIT"
13376 "jmp\t%A0"
13377 [(set_attr "type" "ibr")
13378 (set_attr "length_immediate" "0")])
13379
13380 (define_insn "*indirect_jump_rtx64"
13381 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13382 "TARGET_64BIT"
13383 "jmp\t%A0"
13384 [(set_attr "type" "ibr")
13385 (set_attr "length_immediate" "0")])
13386
13387 (define_expand "tablejump"
13388 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13389 (use (label_ref (match_operand 1 "" "")))])]
13390 ""
13391 {
13392 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13393 relative. Convert the relative address to an absolute address. */
13394 if (flag_pic)
13395 {
13396 rtx op0, op1;
13397 enum rtx_code code;
13398
13399 if (TARGET_64BIT)
13400 {
13401 code = PLUS;
13402 op0 = operands[0];
13403 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13404 }
13405 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13406 {
13407 code = PLUS;
13408 op0 = operands[0];
13409 op1 = pic_offset_table_rtx;
13410 }
13411 else
13412 {
13413 code = MINUS;
13414 op0 = pic_offset_table_rtx;
13415 op1 = operands[0];
13416 }
13417
13418 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13419 OPTAB_DIRECT);
13420 }
13421 })
13422
13423 (define_insn "*tablejump_1"
13424 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13425 (use (label_ref (match_operand 1 "" "")))]
13426 "!TARGET_64BIT"
13427 "jmp\t%A0"
13428 [(set_attr "type" "ibr")
13429 (set_attr "length_immediate" "0")])
13430
13431 (define_insn "*tablejump_1_rtx64"
13432 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13433 (use (label_ref (match_operand 1 "" "")))]
13434 "TARGET_64BIT"
13435 "jmp\t%A0"
13436 [(set_attr "type" "ibr")
13437 (set_attr "length_immediate" "0")])
13438 \f
13439 ;; Loop instruction
13440 ;;
13441 ;; This is all complicated by the fact that since this is a jump insn
13442 ;; we must handle our own reloads.
13443
13444 (define_expand "doloop_end"
13445 [(use (match_operand 0 "" "")) ; loop pseudo
13446 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13447 (use (match_operand 2 "" "")) ; max iterations
13448 (use (match_operand 3 "" "")) ; loop level
13449 (use (match_operand 4 "" ""))] ; label
13450 "!TARGET_64BIT && TARGET_USE_LOOP"
13451 "
13452 {
13453 /* Only use cloop on innermost loops. */
13454 if (INTVAL (operands[3]) > 1)
13455 FAIL;
13456 if (GET_MODE (operands[0]) != SImode)
13457 FAIL;
13458 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13459 operands[0]));
13460 DONE;
13461 }")
13462
13463 (define_insn "doloop_end_internal"
13464 [(set (pc)
13465 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13466 (const_int 1))
13467 (label_ref (match_operand 0 "" ""))
13468 (pc)))
13469 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13470 (plus:SI (match_dup 1)
13471 (const_int -1)))
13472 (clobber (match_scratch:SI 3 "=X,X,r"))
13473 (clobber (reg:CC 17))]
13474 "!TARGET_64BIT && TARGET_USE_LOOP"
13475 {
13476 if (which_alternative != 0)
13477 return "#";
13478 if (get_attr_length (insn) == 2)
13479 return "%+loop\t%l0";
13480 else
13481 return "dec{l}\t%1\;%+jne\t%l0";
13482 }
13483 [(set_attr "ppro_uops" "many")
13484 (set (attr "length")
13485 (if_then_else (and (eq_attr "alternative" "0")
13486 (and (ge (minus (match_dup 0) (pc))
13487 (const_int -126))
13488 (lt (minus (match_dup 0) (pc))
13489 (const_int 128))))
13490 (const_int 2)
13491 (const_int 16)))
13492 ;; We don't know the type before shorten branches. Optimistically expect
13493 ;; the loop instruction to match.
13494 (set (attr "type") (const_string "ibr"))])
13495
13496 (define_split
13497 [(set (pc)
13498 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13499 (const_int 1))
13500 (match_operand 0 "" "")
13501 (pc)))
13502 (set (match_dup 1)
13503 (plus:SI (match_dup 1)
13504 (const_int -1)))
13505 (clobber (match_scratch:SI 2 ""))
13506 (clobber (reg:CC 17))]
13507 "!TARGET_64BIT && TARGET_USE_LOOP
13508 && reload_completed
13509 && REGNO (operands[1]) != 2"
13510 [(parallel [(set (reg:CCZ 17)
13511 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13512 (const_int 0)))
13513 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13514 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13515 (match_dup 0)
13516 (pc)))]
13517 "")
13518
13519 (define_split
13520 [(set (pc)
13521 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13522 (const_int 1))
13523 (match_operand 0 "" "")
13524 (pc)))
13525 (set (match_operand:SI 2 "nonimmediate_operand" "")
13526 (plus:SI (match_dup 1)
13527 (const_int -1)))
13528 (clobber (match_scratch:SI 3 ""))
13529 (clobber (reg:CC 17))]
13530 "!TARGET_64BIT && TARGET_USE_LOOP
13531 && reload_completed
13532 && (! REG_P (operands[2])
13533 || ! rtx_equal_p (operands[1], operands[2]))"
13534 [(set (match_dup 3) (match_dup 1))
13535 (parallel [(set (reg:CCZ 17)
13536 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13537 (const_int 0)))
13538 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13539 (set (match_dup 2) (match_dup 3))
13540 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13541 (match_dup 0)
13542 (pc)))]
13543 "")
13544
13545 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13546
13547 (define_peephole2
13548 [(set (reg 17) (match_operand 0 "" ""))
13549 (set (match_operand:QI 1 "register_operand" "")
13550 (match_operator:QI 2 "ix86_comparison_operator"
13551 [(reg 17) (const_int 0)]))
13552 (set (match_operand 3 "q_regs_operand" "")
13553 (zero_extend (match_dup 1)))]
13554 "(peep2_reg_dead_p (3, operands[1])
13555 || operands_match_p (operands[1], operands[3]))
13556 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13557 [(set (match_dup 4) (match_dup 0))
13558 (set (strict_low_part (match_dup 5))
13559 (match_dup 2))]
13560 {
13561 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13562 operands[5] = gen_lowpart (QImode, operands[3]);
13563 ix86_expand_clear (operands[3]);
13564 })
13565
13566 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13567
13568 (define_peephole2
13569 [(set (reg 17) (match_operand 0 "" ""))
13570 (set (match_operand:QI 1 "register_operand" "")
13571 (match_operator:QI 2 "ix86_comparison_operator"
13572 [(reg 17) (const_int 0)]))
13573 (parallel [(set (match_operand 3 "q_regs_operand" "")
13574 (zero_extend (match_dup 1)))
13575 (clobber (reg:CC 17))])]
13576 "(peep2_reg_dead_p (3, operands[1])
13577 || operands_match_p (operands[1], operands[3]))
13578 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13579 [(set (match_dup 4) (match_dup 0))
13580 (set (strict_low_part (match_dup 5))
13581 (match_dup 2))]
13582 {
13583 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13584 operands[5] = gen_lowpart (QImode, operands[3]);
13585 ix86_expand_clear (operands[3]);
13586 })
13587 \f
13588 ;; Call instructions.
13589
13590 ;; The predicates normally associated with named expanders are not properly
13591 ;; checked for calls. This is a bug in the generic code, but it isn't that
13592 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13593
13594 ;; Call subroutine returning no value.
13595
13596 (define_expand "call_pop"
13597 [(parallel [(call (match_operand:QI 0 "" "")
13598 (match_operand:SI 1 "" ""))
13599 (set (reg:SI 7)
13600 (plus:SI (reg:SI 7)
13601 (match_operand:SI 3 "" "")))])]
13602 "!TARGET_64BIT"
13603 {
13604 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13605 DONE;
13606 })
13607
13608 (define_insn "*call_pop_0"
13609 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13610 (match_operand:SI 1 "" ""))
13611 (set (reg:SI 7) (plus:SI (reg:SI 7)
13612 (match_operand:SI 2 "immediate_operand" "")))]
13613 "!TARGET_64BIT"
13614 {
13615 if (SIBLING_CALL_P (insn))
13616 return "jmp\t%P0";
13617 else
13618 return "call\t%P0";
13619 }
13620 [(set_attr "type" "call")])
13621
13622 (define_insn "*call_pop_1"
13623 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13624 (match_operand:SI 1 "" ""))
13625 (set (reg:SI 7) (plus:SI (reg:SI 7)
13626 (match_operand:SI 2 "immediate_operand" "i")))]
13627 "!TARGET_64BIT"
13628 {
13629 if (constant_call_address_operand (operands[0], Pmode))
13630 {
13631 if (SIBLING_CALL_P (insn))
13632 return "jmp\t%P0";
13633 else
13634 return "call\t%P0";
13635 }
13636 if (SIBLING_CALL_P (insn))
13637 return "jmp\t%A0";
13638 else
13639 return "call\t%A0";
13640 }
13641 [(set_attr "type" "call")])
13642
13643 (define_expand "call"
13644 [(call (match_operand:QI 0 "" "")
13645 (match_operand 1 "" ""))
13646 (use (match_operand 2 "" ""))]
13647 ""
13648 {
13649 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13650 DONE;
13651 })
13652
13653 (define_expand "sibcall"
13654 [(call (match_operand:QI 0 "" "")
13655 (match_operand 1 "" ""))
13656 (use (match_operand 2 "" ""))]
13657 ""
13658 {
13659 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13660 DONE;
13661 })
13662
13663 (define_insn "*call_0"
13664 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13665 (match_operand 1 "" ""))]
13666 ""
13667 {
13668 if (SIBLING_CALL_P (insn))
13669 return "jmp\t%P0";
13670 else
13671 return "call\t%P0";
13672 }
13673 [(set_attr "type" "call")])
13674
13675 (define_insn "*call_1"
13676 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13677 (match_operand 1 "" ""))]
13678 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13679 {
13680 if (constant_call_address_operand (operands[0], QImode))
13681 return "call\t%P0";
13682 return "call\t%A0";
13683 }
13684 [(set_attr "type" "call")])
13685
13686 (define_insn "*sibcall_1"
13687 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13688 (match_operand 1 "" ""))]
13689 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13690 {
13691 if (constant_call_address_operand (operands[0], QImode))
13692 return "jmp\t%P0";
13693 return "jmp\t%A0";
13694 }
13695 [(set_attr "type" "call")])
13696
13697 (define_insn "*call_1_rex64"
13698 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13699 (match_operand 1 "" ""))]
13700 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13701 {
13702 if (constant_call_address_operand (operands[0], QImode))
13703 return "call\t%P0";
13704 return "call\t%A0";
13705 }
13706 [(set_attr "type" "call")])
13707
13708 (define_insn "*sibcall_1_rex64"
13709 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13710 (match_operand 1 "" ""))]
13711 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13712 "jmp\t%P0"
13713 [(set_attr "type" "call")])
13714
13715 (define_insn "*sibcall_1_rex64_v"
13716 [(call (mem:QI (reg:DI 40))
13717 (match_operand 0 "" ""))]
13718 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13719 "jmp\t*%%r11"
13720 [(set_attr "type" "call")])
13721
13722
13723 ;; Call subroutine, returning value in operand 0
13724
13725 (define_expand "call_value_pop"
13726 [(parallel [(set (match_operand 0 "" "")
13727 (call (match_operand:QI 1 "" "")
13728 (match_operand:SI 2 "" "")))
13729 (set (reg:SI 7)
13730 (plus:SI (reg:SI 7)
13731 (match_operand:SI 4 "" "")))])]
13732 "!TARGET_64BIT"
13733 {
13734 ix86_expand_call (operands[0], operands[1], operands[2],
13735 operands[3], operands[4], 0);
13736 DONE;
13737 })
13738
13739 (define_expand "call_value"
13740 [(set (match_operand 0 "" "")
13741 (call (match_operand:QI 1 "" "")
13742 (match_operand:SI 2 "" "")))
13743 (use (match_operand:SI 3 "" ""))]
13744 ;; Operand 2 not used on the i386.
13745 ""
13746 {
13747 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13748 DONE;
13749 })
13750
13751 (define_expand "sibcall_value"
13752 [(set (match_operand 0 "" "")
13753 (call (match_operand:QI 1 "" "")
13754 (match_operand:SI 2 "" "")))
13755 (use (match_operand:SI 3 "" ""))]
13756 ;; Operand 2 not used on the i386.
13757 ""
13758 {
13759 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13760 DONE;
13761 })
13762
13763 ;; Call subroutine returning any type.
13764
13765 (define_expand "untyped_call"
13766 [(parallel [(call (match_operand 0 "" "")
13767 (const_int 0))
13768 (match_operand 1 "" "")
13769 (match_operand 2 "" "")])]
13770 ""
13771 {
13772 int i;
13773
13774 /* In order to give reg-stack an easier job in validating two
13775 coprocessor registers as containing a possible return value,
13776 simply pretend the untyped call returns a complex long double
13777 value. */
13778
13779 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13780 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13781 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13782 NULL, 0);
13783
13784 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13785 {
13786 rtx set = XVECEXP (operands[2], 0, i);
13787 emit_move_insn (SET_DEST (set), SET_SRC (set));
13788 }
13789
13790 /* The optimizer does not know that the call sets the function value
13791 registers we stored in the result block. We avoid problems by
13792 claiming that all hard registers are used and clobbered at this
13793 point. */
13794 emit_insn (gen_blockage (const0_rtx));
13795
13796 DONE;
13797 })
13798 \f
13799 ;; Prologue and epilogue instructions
13800
13801 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13802 ;; all of memory. This blocks insns from being moved across this point.
13803
13804 (define_insn "blockage"
13805 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13806 ""
13807 ""
13808 [(set_attr "length" "0")])
13809
13810 ;; Insn emitted into the body of a function to return from a function.
13811 ;; This is only done if the function's epilogue is known to be simple.
13812 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13813
13814 (define_expand "return"
13815 [(return)]
13816 "ix86_can_use_return_insn_p ()"
13817 {
13818 if (current_function_pops_args)
13819 {
13820 rtx popc = GEN_INT (current_function_pops_args);
13821 emit_jump_insn (gen_return_pop_internal (popc));
13822 DONE;
13823 }
13824 })
13825
13826 (define_insn "return_internal"
13827 [(return)]
13828 "reload_completed"
13829 "ret"
13830 [(set_attr "length" "1")
13831 (set_attr "length_immediate" "0")
13832 (set_attr "modrm" "0")])
13833
13834 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13835 ;; instruction Athlon and K8 have.
13836
13837 (define_insn "return_internal_long"
13838 [(return)
13839 (unspec [(const_int 0)] UNSPEC_REP)]
13840 "reload_completed"
13841 "rep {;} ret"
13842 [(set_attr "length" "1")
13843 (set_attr "length_immediate" "0")
13844 (set_attr "prefix_rep" "1")
13845 (set_attr "modrm" "0")])
13846
13847 (define_insn "return_pop_internal"
13848 [(return)
13849 (use (match_operand:SI 0 "const_int_operand" ""))]
13850 "reload_completed"
13851 "ret\t%0"
13852 [(set_attr "length" "3")
13853 (set_attr "length_immediate" "2")
13854 (set_attr "modrm" "0")])
13855
13856 (define_insn "return_indirect_internal"
13857 [(return)
13858 (use (match_operand:SI 0 "register_operand" "r"))]
13859 "reload_completed"
13860 "jmp\t%A0"
13861 [(set_attr "type" "ibr")
13862 (set_attr "length_immediate" "0")])
13863
13864 (define_insn "nop"
13865 [(const_int 0)]
13866 ""
13867 "nop"
13868 [(set_attr "length" "1")
13869 (set_attr "length_immediate" "0")
13870 (set_attr "modrm" "0")
13871 (set_attr "ppro_uops" "one")])
13872
13873 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13874 ;; branch prediction penalty for the third jump in a 16-byte
13875 ;; block on K8.
13876
13877 (define_insn "align"
13878 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13879 ""
13880 {
13881 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13882 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13883 #else
13884 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13885 The align insn is used to avoid 3 jump instructions in the row to improve
13886 branch prediction and the benefits hardly outweight the cost of extra 8
13887 nops on the average inserted by full alignment pseudo operation. */
13888 #endif
13889 return "";
13890 }
13891 [(set_attr "length" "16")])
13892
13893 (define_expand "prologue"
13894 [(const_int 1)]
13895 ""
13896 "ix86_expand_prologue (); DONE;")
13897
13898 (define_insn "set_got"
13899 [(set (match_operand:SI 0 "register_operand" "=r")
13900 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13901 (clobber (reg:CC 17))]
13902 "!TARGET_64BIT"
13903 { return output_set_got (operands[0]); }
13904 [(set_attr "type" "multi")
13905 (set_attr "length" "12")])
13906
13907 (define_expand "epilogue"
13908 [(const_int 1)]
13909 ""
13910 "ix86_expand_epilogue (1); DONE;")
13911
13912 (define_expand "sibcall_epilogue"
13913 [(const_int 1)]
13914 ""
13915 "ix86_expand_epilogue (0); DONE;")
13916
13917 (define_expand "eh_return"
13918 [(use (match_operand 0 "register_operand" ""))]
13919 ""
13920 {
13921 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13922
13923 /* Tricky bit: we write the address of the handler to which we will
13924 be returning into someone else's stack frame, one word below the
13925 stack address we wish to restore. */
13926 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13927 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13928 tmp = gen_rtx_MEM (Pmode, tmp);
13929 emit_move_insn (tmp, ra);
13930
13931 if (Pmode == SImode)
13932 emit_insn (gen_eh_return_si (sa));
13933 else
13934 emit_insn (gen_eh_return_di (sa));
13935 emit_barrier ();
13936 DONE;
13937 })
13938
13939 (define_insn_and_split "eh_return_si"
13940 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13941 UNSPECV_EH_RETURN)]
13942 "!TARGET_64BIT"
13943 "#"
13944 "reload_completed"
13945 [(const_int 1)]
13946 "ix86_expand_epilogue (2); DONE;")
13947
13948 (define_insn_and_split "eh_return_di"
13949 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13950 UNSPECV_EH_RETURN)]
13951 "TARGET_64BIT"
13952 "#"
13953 "reload_completed"
13954 [(const_int 1)]
13955 "ix86_expand_epilogue (2); DONE;")
13956
13957 (define_insn "leave"
13958 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13959 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13960 (clobber (mem:BLK (scratch)))]
13961 "!TARGET_64BIT"
13962 "leave"
13963 [(set_attr "type" "leave")])
13964
13965 (define_insn "leave_rex64"
13966 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13967 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13968 (clobber (mem:BLK (scratch)))]
13969 "TARGET_64BIT"
13970 "leave"
13971 [(set_attr "type" "leave")])
13972 \f
13973 (define_expand "ffssi2"
13974 [(parallel
13975 [(set (match_operand:SI 0 "register_operand" "")
13976 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13977 (clobber (match_scratch:SI 2 ""))
13978 (clobber (reg:CC 17))])]
13979 ""
13980 "")
13981
13982 (define_insn_and_split "*ffs_cmove"
13983 [(set (match_operand:SI 0 "register_operand" "=r")
13984 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13985 (clobber (match_scratch:SI 2 "=&r"))
13986 (clobber (reg:CC 17))]
13987 "TARGET_CMOVE"
13988 "#"
13989 "&& reload_completed"
13990 [(set (match_dup 2) (const_int -1))
13991 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13992 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13993 (set (match_dup 0) (if_then_else:SI
13994 (eq (reg:CCZ 17) (const_int 0))
13995 (match_dup 2)
13996 (match_dup 0)))
13997 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13998 (clobber (reg:CC 17))])]
13999 "")
14000
14001 (define_insn_and_split "*ffs_no_cmove"
14002 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14003 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14004 (clobber (match_scratch:SI 2 "=&q"))
14005 (clobber (reg:CC 17))]
14006 ""
14007 "#"
14008 "reload_completed"
14009 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14010 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14011 (set (strict_low_part (match_dup 3))
14012 (eq:QI (reg:CCZ 17) (const_int 0)))
14013 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14014 (clobber (reg:CC 17))])
14015 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14016 (clobber (reg:CC 17))])
14017 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14018 (clobber (reg:CC 17))])]
14019 {
14020 operands[3] = gen_lowpart (QImode, operands[2]);
14021 ix86_expand_clear (operands[2]);
14022 })
14023
14024 (define_insn "*ffssi_1"
14025 [(set (reg:CCZ 17)
14026 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14027 (const_int 0)))
14028 (set (match_operand:SI 0 "register_operand" "=r")
14029 (ctz:SI (match_dup 1)))]
14030 ""
14031 "bsf{l}\t{%1, %0|%0, %1}"
14032 [(set_attr "prefix_0f" "1")
14033 (set_attr "ppro_uops" "few")])
14034
14035 (define_insn "ctzsi2"
14036 [(set (match_operand:SI 0 "register_operand" "=r")
14037 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14038 (clobber (reg:CC 17))]
14039 ""
14040 "bsf{l}\t{%1, %0|%0, %1}"
14041 [(set_attr "prefix_0f" "1")
14042 (set_attr "ppro_uops" "few")])
14043
14044 (define_expand "clzsi2"
14045 [(parallel
14046 [(set (match_operand:SI 0 "register_operand" "")
14047 (minus:SI (const_int 31)
14048 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14049 (clobber (reg:CC 17))])
14050 (parallel
14051 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14052 (clobber (reg:CC 17))])]
14053 ""
14054 "")
14055
14056 (define_insn "*bsr"
14057 [(set (match_operand:SI 0 "register_operand" "=r")
14058 (minus:SI (const_int 31)
14059 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14060 (clobber (reg:CC 17))]
14061 ""
14062 "bsr{l}\t{%1, %0|%0, %1}"
14063 [(set_attr "prefix_0f" "1")
14064 (set_attr "ppro_uops" "few")])
14065 \f
14066 ;; Thread-local storage patterns for ELF.
14067 ;;
14068 ;; Note that these code sequences must appear exactly as shown
14069 ;; in order to allow linker relaxation.
14070
14071 (define_insn "*tls_global_dynamic_32_gnu"
14072 [(set (match_operand:SI 0 "register_operand" "=a")
14073 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14074 (match_operand:SI 2 "tls_symbolic_operand" "")
14075 (match_operand:SI 3 "call_insn_operand" "")]
14076 UNSPEC_TLS_GD))
14077 (clobber (match_scratch:SI 4 "=d"))
14078 (clobber (match_scratch:SI 5 "=c"))
14079 (clobber (reg:CC 17))]
14080 "!TARGET_64BIT && TARGET_GNU_TLS"
14081 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14082 [(set_attr "type" "multi")
14083 (set_attr "length" "12")])
14084
14085 (define_insn "*tls_global_dynamic_32_sun"
14086 [(set (match_operand:SI 0 "register_operand" "=a")
14087 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14088 (match_operand:SI 2 "tls_symbolic_operand" "")
14089 (match_operand:SI 3 "call_insn_operand" "")]
14090 UNSPEC_TLS_GD))
14091 (clobber (match_scratch:SI 4 "=d"))
14092 (clobber (match_scratch:SI 5 "=c"))
14093 (clobber (reg:CC 17))]
14094 "!TARGET_64BIT && TARGET_SUN_TLS"
14095 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14096 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14097 [(set_attr "type" "multi")
14098 (set_attr "length" "14")])
14099
14100 (define_expand "tls_global_dynamic_32"
14101 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14102 (unspec:SI
14103 [(match_dup 2)
14104 (match_operand:SI 1 "tls_symbolic_operand" "")
14105 (match_dup 3)]
14106 UNSPEC_TLS_GD))
14107 (clobber (match_scratch:SI 4 ""))
14108 (clobber (match_scratch:SI 5 ""))
14109 (clobber (reg:CC 17))])]
14110 ""
14111 {
14112 if (flag_pic)
14113 operands[2] = pic_offset_table_rtx;
14114 else
14115 {
14116 operands[2] = gen_reg_rtx (Pmode);
14117 emit_insn (gen_set_got (operands[2]));
14118 }
14119 operands[3] = ix86_tls_get_addr ();
14120 })
14121
14122 (define_insn "*tls_global_dynamic_64"
14123 [(set (match_operand:DI 0 "register_operand" "=a")
14124 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14125 (match_operand:DI 3 "" "")))
14126 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14127 UNSPEC_TLS_GD)]
14128 "TARGET_64BIT"
14129 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14130 [(set_attr "type" "multi")
14131 (set_attr "length" "16")])
14132
14133 (define_expand "tls_global_dynamic_64"
14134 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14135 (call (mem:QI (match_dup 2)) (const_int 0)))
14136 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14137 UNSPEC_TLS_GD)])]
14138 ""
14139 {
14140 operands[2] = ix86_tls_get_addr ();
14141 })
14142
14143 (define_insn "*tls_local_dynamic_base_32_gnu"
14144 [(set (match_operand:SI 0 "register_operand" "=a")
14145 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14146 (match_operand:SI 2 "call_insn_operand" "")]
14147 UNSPEC_TLS_LD_BASE))
14148 (clobber (match_scratch:SI 3 "=d"))
14149 (clobber (match_scratch:SI 4 "=c"))
14150 (clobber (reg:CC 17))]
14151 "!TARGET_64BIT && TARGET_GNU_TLS"
14152 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14153 [(set_attr "type" "multi")
14154 (set_attr "length" "11")])
14155
14156 (define_insn "*tls_local_dynamic_base_32_sun"
14157 [(set (match_operand:SI 0 "register_operand" "=a")
14158 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14159 (match_operand:SI 2 "call_insn_operand" "")]
14160 UNSPEC_TLS_LD_BASE))
14161 (clobber (match_scratch:SI 3 "=d"))
14162 (clobber (match_scratch:SI 4 "=c"))
14163 (clobber (reg:CC 17))]
14164 "!TARGET_64BIT && TARGET_SUN_TLS"
14165 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14166 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14167 [(set_attr "type" "multi")
14168 (set_attr "length" "13")])
14169
14170 (define_expand "tls_local_dynamic_base_32"
14171 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14172 (unspec:SI [(match_dup 1) (match_dup 2)]
14173 UNSPEC_TLS_LD_BASE))
14174 (clobber (match_scratch:SI 3 ""))
14175 (clobber (match_scratch:SI 4 ""))
14176 (clobber (reg:CC 17))])]
14177 ""
14178 {
14179 if (flag_pic)
14180 operands[1] = pic_offset_table_rtx;
14181 else
14182 {
14183 operands[1] = gen_reg_rtx (Pmode);
14184 emit_insn (gen_set_got (operands[1]));
14185 }
14186 operands[2] = ix86_tls_get_addr ();
14187 })
14188
14189 (define_insn "*tls_local_dynamic_base_64"
14190 [(set (match_operand:DI 0 "register_operand" "=a")
14191 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14192 (match_operand:DI 2 "" "")))
14193 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14194 "TARGET_64BIT"
14195 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14196 [(set_attr "type" "multi")
14197 (set_attr "length" "12")])
14198
14199 (define_expand "tls_local_dynamic_base_64"
14200 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14201 (call (mem:QI (match_dup 1)) (const_int 0)))
14202 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14203 ""
14204 {
14205 operands[1] = ix86_tls_get_addr ();
14206 })
14207
14208 ;; Local dynamic of a single variable is a lose. Show combine how
14209 ;; to convert that back to global dynamic.
14210
14211 (define_insn_and_split "*tls_local_dynamic_32_once"
14212 [(set (match_operand:SI 0 "register_operand" "=a")
14213 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14214 (match_operand:SI 2 "call_insn_operand" "")]
14215 UNSPEC_TLS_LD_BASE)
14216 (const:SI (unspec:SI
14217 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14218 UNSPEC_DTPOFF))))
14219 (clobber (match_scratch:SI 4 "=d"))
14220 (clobber (match_scratch:SI 5 "=c"))
14221 (clobber (reg:CC 17))]
14222 ""
14223 "#"
14224 ""
14225 [(parallel [(set (match_dup 0)
14226 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14227 UNSPEC_TLS_GD))
14228 (clobber (match_dup 4))
14229 (clobber (match_dup 5))
14230 (clobber (reg:CC 17))])]
14231 "")
14232
14233 ;; Load and add the thread base pointer from %gs:0.
14234
14235 (define_insn "*load_tp_si"
14236 [(set (match_operand:SI 0 "register_operand" "=r")
14237 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14238 "!TARGET_64BIT"
14239 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14240 [(set_attr "type" "imov")
14241 (set_attr "modrm" "0")
14242 (set_attr "length" "7")
14243 (set_attr "memory" "load")
14244 (set_attr "imm_disp" "false")])
14245
14246 (define_insn "*add_tp_si"
14247 [(set (match_operand:SI 0 "register_operand" "=r")
14248 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14249 (match_operand:SI 1 "register_operand" "0")))
14250 (clobber (reg:CC 17))]
14251 "!TARGET_64BIT"
14252 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14253 [(set_attr "type" "alu")
14254 (set_attr "modrm" "0")
14255 (set_attr "length" "7")
14256 (set_attr "memory" "load")
14257 (set_attr "imm_disp" "false")])
14258
14259 (define_insn "*load_tp_di"
14260 [(set (match_operand:DI 0 "register_operand" "=r")
14261 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14262 "TARGET_64BIT"
14263 "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14264 [(set_attr "type" "imov")
14265 (set_attr "modrm" "0")
14266 (set_attr "length" "7")
14267 (set_attr "memory" "load")
14268 (set_attr "imm_disp" "false")])
14269
14270 (define_insn "*add_tp_di"
14271 [(set (match_operand:DI 0 "register_operand" "=r")
14272 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14273 (match_operand:DI 1 "register_operand" "0")))
14274 (clobber (reg:CC 17))]
14275 "TARGET_64BIT"
14276 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14277 [(set_attr "type" "alu")
14278 (set_attr "modrm" "0")
14279 (set_attr "length" "7")
14280 (set_attr "memory" "load")
14281 (set_attr "imm_disp" "false")])
14282 \f
14283 ;; These patterns match the binary 387 instructions for addM3, subM3,
14284 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14285 ;; SFmode. The first is the normal insn, the second the same insn but
14286 ;; with one operand a conversion, and the third the same insn but with
14287 ;; the other operand a conversion. The conversion may be SFmode or
14288 ;; SImode if the target mode DFmode, but only SImode if the target mode
14289 ;; is SFmode.
14290
14291 ;; Gcc is slightly more smart about handling normal two address instructions
14292 ;; so use special patterns for add and mull.
14293 (define_insn "*fop_sf_comm_nosse"
14294 [(set (match_operand:SF 0 "register_operand" "=f")
14295 (match_operator:SF 3 "binary_fp_operator"
14296 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14297 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14298 "TARGET_80387 && !TARGET_SSE_MATH
14299 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14300 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14301 "* return output_387_binary_op (insn, operands);"
14302 [(set (attr "type")
14303 (if_then_else (match_operand:SF 3 "mult_operator" "")
14304 (const_string "fmul")
14305 (const_string "fop")))
14306 (set_attr "mode" "SF")])
14307
14308 (define_insn "*fop_sf_comm"
14309 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14310 (match_operator:SF 3 "binary_fp_operator"
14311 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14312 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14313 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14314 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14315 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14316 "* return output_387_binary_op (insn, operands);"
14317 [(set (attr "type")
14318 (if_then_else (eq_attr "alternative" "1")
14319 (if_then_else (match_operand:SF 3 "mult_operator" "")
14320 (const_string "ssemul")
14321 (const_string "sseadd"))
14322 (if_then_else (match_operand:SF 3 "mult_operator" "")
14323 (const_string "fmul")
14324 (const_string "fop"))))
14325 (set_attr "mode" "SF")])
14326
14327 (define_insn "*fop_sf_comm_sse"
14328 [(set (match_operand:SF 0 "register_operand" "=x")
14329 (match_operator:SF 3 "binary_fp_operator"
14330 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14331 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14332 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14333 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14334 "* return output_387_binary_op (insn, operands);"
14335 [(set (attr "type")
14336 (if_then_else (match_operand:SF 3 "mult_operator" "")
14337 (const_string "ssemul")
14338 (const_string "sseadd")))
14339 (set_attr "mode" "SF")])
14340
14341 (define_insn "*fop_df_comm_nosse"
14342 [(set (match_operand:DF 0 "register_operand" "=f")
14343 (match_operator:DF 3 "binary_fp_operator"
14344 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14345 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14346 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14347 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14348 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14349 "* return output_387_binary_op (insn, operands);"
14350 [(set (attr "type")
14351 (if_then_else (match_operand:SF 3 "mult_operator" "")
14352 (const_string "fmul")
14353 (const_string "fop")))
14354 (set_attr "mode" "DF")])
14355
14356 (define_insn "*fop_df_comm"
14357 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14358 (match_operator:DF 3 "binary_fp_operator"
14359 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14360 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14361 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14362 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14363 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14364 "* return output_387_binary_op (insn, operands);"
14365 [(set (attr "type")
14366 (if_then_else (eq_attr "alternative" "1")
14367 (if_then_else (match_operand:SF 3 "mult_operator" "")
14368 (const_string "ssemul")
14369 (const_string "sseadd"))
14370 (if_then_else (match_operand:SF 3 "mult_operator" "")
14371 (const_string "fmul")
14372 (const_string "fop"))))
14373 (set_attr "mode" "DF")])
14374
14375 (define_insn "*fop_df_comm_sse"
14376 [(set (match_operand:DF 0 "register_operand" "=Y")
14377 (match_operator:DF 3 "binary_fp_operator"
14378 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14379 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14380 "TARGET_SSE2 && TARGET_SSE_MATH
14381 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14382 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14383 "* return output_387_binary_op (insn, operands);"
14384 [(set (attr "type")
14385 (if_then_else (match_operand:SF 3 "mult_operator" "")
14386 (const_string "ssemul")
14387 (const_string "sseadd")))
14388 (set_attr "mode" "DF")])
14389
14390 (define_insn "*fop_xf_comm"
14391 [(set (match_operand:XF 0 "register_operand" "=f")
14392 (match_operator:XF 3 "binary_fp_operator"
14393 [(match_operand:XF 1 "register_operand" "%0")
14394 (match_operand:XF 2 "register_operand" "f")]))]
14395 "TARGET_80387
14396 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14397 "* return output_387_binary_op (insn, operands);"
14398 [(set (attr "type")
14399 (if_then_else (match_operand:XF 3 "mult_operator" "")
14400 (const_string "fmul")
14401 (const_string "fop")))
14402 (set_attr "mode" "XF")])
14403
14404 (define_insn "*fop_sf_1_nosse"
14405 [(set (match_operand:SF 0 "register_operand" "=f,f")
14406 (match_operator:SF 3 "binary_fp_operator"
14407 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14408 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14409 "TARGET_80387 && !TARGET_SSE_MATH
14410 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14411 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14412 "* return output_387_binary_op (insn, operands);"
14413 [(set (attr "type")
14414 (cond [(match_operand:SF 3 "mult_operator" "")
14415 (const_string "fmul")
14416 (match_operand:SF 3 "div_operator" "")
14417 (const_string "fdiv")
14418 ]
14419 (const_string "fop")))
14420 (set_attr "mode" "SF")])
14421
14422 (define_insn "*fop_sf_1"
14423 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14424 (match_operator:SF 3 "binary_fp_operator"
14425 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14426 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14427 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14428 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14429 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14430 "* return output_387_binary_op (insn, operands);"
14431 [(set (attr "type")
14432 (cond [(and (eq_attr "alternative" "2")
14433 (match_operand:SF 3 "mult_operator" ""))
14434 (const_string "ssemul")
14435 (and (eq_attr "alternative" "2")
14436 (match_operand:SF 3 "div_operator" ""))
14437 (const_string "ssediv")
14438 (eq_attr "alternative" "2")
14439 (const_string "sseadd")
14440 (match_operand:SF 3 "mult_operator" "")
14441 (const_string "fmul")
14442 (match_operand:SF 3 "div_operator" "")
14443 (const_string "fdiv")
14444 ]
14445 (const_string "fop")))
14446 (set_attr "mode" "SF")])
14447
14448 (define_insn "*fop_sf_1_sse"
14449 [(set (match_operand:SF 0 "register_operand" "=x")
14450 (match_operator:SF 3 "binary_fp_operator"
14451 [(match_operand:SF 1 "register_operand" "0")
14452 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14453 "TARGET_SSE_MATH
14454 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14455 "* return output_387_binary_op (insn, operands);"
14456 [(set (attr "type")
14457 (cond [(match_operand:SF 3 "mult_operator" "")
14458 (const_string "ssemul")
14459 (match_operand:SF 3 "div_operator" "")
14460 (const_string "ssediv")
14461 ]
14462 (const_string "sseadd")))
14463 (set_attr "mode" "SF")])
14464
14465 ;; ??? Add SSE splitters for these!
14466 (define_insn "*fop_sf_2"
14467 [(set (match_operand:SF 0 "register_operand" "=f,f")
14468 (match_operator:SF 3 "binary_fp_operator"
14469 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14470 (match_operand:SF 2 "register_operand" "0,0")]))]
14471 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14472 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14473 [(set (attr "type")
14474 (cond [(match_operand:SF 3 "mult_operator" "")
14475 (const_string "fmul")
14476 (match_operand:SF 3 "div_operator" "")
14477 (const_string "fdiv")
14478 ]
14479 (const_string "fop")))
14480 (set_attr "fp_int_src" "true")
14481 (set_attr "ppro_uops" "many")
14482 (set_attr "mode" "SI")])
14483
14484 (define_insn "*fop_sf_3"
14485 [(set (match_operand:SF 0 "register_operand" "=f,f")
14486 (match_operator:SF 3 "binary_fp_operator"
14487 [(match_operand:SF 1 "register_operand" "0,0")
14488 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14489 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14490 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14491 [(set (attr "type")
14492 (cond [(match_operand:SF 3 "mult_operator" "")
14493 (const_string "fmul")
14494 (match_operand:SF 3 "div_operator" "")
14495 (const_string "fdiv")
14496 ]
14497 (const_string "fop")))
14498 (set_attr "fp_int_src" "true")
14499 (set_attr "ppro_uops" "many")
14500 (set_attr "mode" "SI")])
14501
14502 (define_insn "*fop_df_1_nosse"
14503 [(set (match_operand:DF 0 "register_operand" "=f,f")
14504 (match_operator:DF 3 "binary_fp_operator"
14505 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14506 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14507 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14508 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14509 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14510 "* return output_387_binary_op (insn, operands);"
14511 [(set (attr "type")
14512 (cond [(match_operand:DF 3 "mult_operator" "")
14513 (const_string "fmul")
14514 (match_operand:DF 3 "div_operator" "")
14515 (const_string "fdiv")
14516 ]
14517 (const_string "fop")))
14518 (set_attr "mode" "DF")])
14519
14520
14521 (define_insn "*fop_df_1"
14522 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14523 (match_operator:DF 3 "binary_fp_operator"
14524 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14525 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14526 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14527 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14528 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14529 "* return output_387_binary_op (insn, operands);"
14530 [(set (attr "type")
14531 (cond [(and (eq_attr "alternative" "2")
14532 (match_operand:SF 3 "mult_operator" ""))
14533 (const_string "ssemul")
14534 (and (eq_attr "alternative" "2")
14535 (match_operand:SF 3 "div_operator" ""))
14536 (const_string "ssediv")
14537 (eq_attr "alternative" "2")
14538 (const_string "sseadd")
14539 (match_operand:DF 3 "mult_operator" "")
14540 (const_string "fmul")
14541 (match_operand:DF 3 "div_operator" "")
14542 (const_string "fdiv")
14543 ]
14544 (const_string "fop")))
14545 (set_attr "mode" "DF")])
14546
14547 (define_insn "*fop_df_1_sse"
14548 [(set (match_operand:DF 0 "register_operand" "=Y")
14549 (match_operator:DF 3 "binary_fp_operator"
14550 [(match_operand:DF 1 "register_operand" "0")
14551 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14552 "TARGET_SSE2 && TARGET_SSE_MATH
14553 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14554 "* return output_387_binary_op (insn, operands);"
14555 [(set_attr "mode" "DF")
14556 (set (attr "type")
14557 (cond [(match_operand:SF 3 "mult_operator" "")
14558 (const_string "ssemul")
14559 (match_operand:SF 3 "div_operator" "")
14560 (const_string "ssediv")
14561 ]
14562 (const_string "sseadd")))])
14563
14564 ;; ??? Add SSE splitters for these!
14565 (define_insn "*fop_df_2"
14566 [(set (match_operand:DF 0 "register_operand" "=f,f")
14567 (match_operator:DF 3 "binary_fp_operator"
14568 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14569 (match_operand:DF 2 "register_operand" "0,0")]))]
14570 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14571 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14572 [(set (attr "type")
14573 (cond [(match_operand:DF 3 "mult_operator" "")
14574 (const_string "fmul")
14575 (match_operand:DF 3 "div_operator" "")
14576 (const_string "fdiv")
14577 ]
14578 (const_string "fop")))
14579 (set_attr "fp_int_src" "true")
14580 (set_attr "ppro_uops" "many")
14581 (set_attr "mode" "SI")])
14582
14583 (define_insn "*fop_df_3"
14584 [(set (match_operand:DF 0 "register_operand" "=f,f")
14585 (match_operator:DF 3 "binary_fp_operator"
14586 [(match_operand:DF 1 "register_operand" "0,0")
14587 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14588 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14589 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14590 [(set (attr "type")
14591 (cond [(match_operand:DF 3 "mult_operator" "")
14592 (const_string "fmul")
14593 (match_operand:DF 3 "div_operator" "")
14594 (const_string "fdiv")
14595 ]
14596 (const_string "fop")))
14597 (set_attr "fp_int_src" "true")
14598 (set_attr "ppro_uops" "many")
14599 (set_attr "mode" "SI")])
14600
14601 (define_insn "*fop_df_4"
14602 [(set (match_operand:DF 0 "register_operand" "=f,f")
14603 (match_operator:DF 3 "binary_fp_operator"
14604 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14605 (match_operand:DF 2 "register_operand" "0,f")]))]
14606 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14607 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14608 "* return output_387_binary_op (insn, operands);"
14609 [(set (attr "type")
14610 (cond [(match_operand:DF 3 "mult_operator" "")
14611 (const_string "fmul")
14612 (match_operand:DF 3 "div_operator" "")
14613 (const_string "fdiv")
14614 ]
14615 (const_string "fop")))
14616 (set_attr "mode" "SF")])
14617
14618 (define_insn "*fop_df_5"
14619 [(set (match_operand:DF 0 "register_operand" "=f,f")
14620 (match_operator:DF 3 "binary_fp_operator"
14621 [(match_operand:DF 1 "register_operand" "0,f")
14622 (float_extend:DF
14623 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14624 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14625 "* return output_387_binary_op (insn, operands);"
14626 [(set (attr "type")
14627 (cond [(match_operand:DF 3 "mult_operator" "")
14628 (const_string "fmul")
14629 (match_operand:DF 3 "div_operator" "")
14630 (const_string "fdiv")
14631 ]
14632 (const_string "fop")))
14633 (set_attr "mode" "SF")])
14634
14635 (define_insn "*fop_df_6"
14636 [(set (match_operand:DF 0 "register_operand" "=f,f")
14637 (match_operator:DF 3 "binary_fp_operator"
14638 [(float_extend:DF
14639 (match_operand:SF 1 "register_operand" "0,f"))
14640 (float_extend:DF
14641 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14642 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14643 "* return output_387_binary_op (insn, operands);"
14644 [(set (attr "type")
14645 (cond [(match_operand:DF 3 "mult_operator" "")
14646 (const_string "fmul")
14647 (match_operand:DF 3 "div_operator" "")
14648 (const_string "fdiv")
14649 ]
14650 (const_string "fop")))
14651 (set_attr "mode" "SF")])
14652
14653 (define_insn "*fop_xf_1"
14654 [(set (match_operand:XF 0 "register_operand" "=f,f")
14655 (match_operator:XF 3 "binary_fp_operator"
14656 [(match_operand:XF 1 "register_operand" "0,f")
14657 (match_operand:XF 2 "register_operand" "f,0")]))]
14658 "TARGET_80387
14659 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14660 "* return output_387_binary_op (insn, operands);"
14661 [(set (attr "type")
14662 (cond [(match_operand:XF 3 "mult_operator" "")
14663 (const_string "fmul")
14664 (match_operand:XF 3 "div_operator" "")
14665 (const_string "fdiv")
14666 ]
14667 (const_string "fop")))
14668 (set_attr "mode" "XF")])
14669
14670 (define_insn "*fop_xf_2"
14671 [(set (match_operand:XF 0 "register_operand" "=f,f")
14672 (match_operator:XF 3 "binary_fp_operator"
14673 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14674 (match_operand:XF 2 "register_operand" "0,0")]))]
14675 "TARGET_80387 && TARGET_USE_FIOP"
14676 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14677 [(set (attr "type")
14678 (cond [(match_operand:XF 3 "mult_operator" "")
14679 (const_string "fmul")
14680 (match_operand:XF 3 "div_operator" "")
14681 (const_string "fdiv")
14682 ]
14683 (const_string "fop")))
14684 (set_attr "fp_int_src" "true")
14685 (set_attr "mode" "SI")
14686 (set_attr "ppro_uops" "many")])
14687
14688 (define_insn "*fop_xf_3"
14689 [(set (match_operand:XF 0 "register_operand" "=f,f")
14690 (match_operator:XF 3 "binary_fp_operator"
14691 [(match_operand:XF 1 "register_operand" "0,0")
14692 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14693 "TARGET_80387 && TARGET_USE_FIOP"
14694 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14695 [(set (attr "type")
14696 (cond [(match_operand:XF 3 "mult_operator" "")
14697 (const_string "fmul")
14698 (match_operand:XF 3 "div_operator" "")
14699 (const_string "fdiv")
14700 ]
14701 (const_string "fop")))
14702 (set_attr "fp_int_src" "true")
14703 (set_attr "mode" "SI")
14704 (set_attr "ppro_uops" "many")])
14705
14706 (define_insn "*fop_xf_4"
14707 [(set (match_operand:XF 0 "register_operand" "=f,f")
14708 (match_operator:XF 3 "binary_fp_operator"
14709 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14710 (match_operand:XF 2 "register_operand" "0,f")]))]
14711 "TARGET_80387"
14712 "* return output_387_binary_op (insn, operands);"
14713 [(set (attr "type")
14714 (cond [(match_operand:XF 3 "mult_operator" "")
14715 (const_string "fmul")
14716 (match_operand:XF 3 "div_operator" "")
14717 (const_string "fdiv")
14718 ]
14719 (const_string "fop")))
14720 (set_attr "mode" "SF")])
14721
14722 (define_insn "*fop_xf_5"
14723 [(set (match_operand:XF 0 "register_operand" "=f,f")
14724 (match_operator:XF 3 "binary_fp_operator"
14725 [(match_operand:XF 1 "register_operand" "0,f")
14726 (float_extend:XF
14727 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14728 "TARGET_80387"
14729 "* return output_387_binary_op (insn, operands);"
14730 [(set (attr "type")
14731 (cond [(match_operand:XF 3 "mult_operator" "")
14732 (const_string "fmul")
14733 (match_operand:XF 3 "div_operator" "")
14734 (const_string "fdiv")
14735 ]
14736 (const_string "fop")))
14737 (set_attr "mode" "SF")])
14738
14739 (define_insn "*fop_xf_6"
14740 [(set (match_operand:XF 0 "register_operand" "=f,f")
14741 (match_operator:XF 3 "binary_fp_operator"
14742 [(float_extend:XF
14743 (match_operand 1 "register_operand" "0,f"))
14744 (float_extend:XF
14745 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14746 "TARGET_80387"
14747 "* return output_387_binary_op (insn, operands);"
14748 [(set (attr "type")
14749 (cond [(match_operand:XF 3 "mult_operator" "")
14750 (const_string "fmul")
14751 (match_operand:XF 3 "div_operator" "")
14752 (const_string "fdiv")
14753 ]
14754 (const_string "fop")))
14755 (set_attr "mode" "SF")])
14756
14757 (define_split
14758 [(set (match_operand 0 "register_operand" "")
14759 (match_operator 3 "binary_fp_operator"
14760 [(float (match_operand:SI 1 "register_operand" ""))
14761 (match_operand 2 "register_operand" "")]))]
14762 "TARGET_80387 && reload_completed
14763 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14764 [(const_int 0)]
14765 {
14766 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14767 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14768 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14769 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14770 GET_MODE (operands[3]),
14771 operands[4],
14772 operands[2])));
14773 ix86_free_from_memory (GET_MODE (operands[1]));
14774 DONE;
14775 })
14776
14777 (define_split
14778 [(set (match_operand 0 "register_operand" "")
14779 (match_operator 3 "binary_fp_operator"
14780 [(match_operand 1 "register_operand" "")
14781 (float (match_operand:SI 2 "register_operand" ""))]))]
14782 "TARGET_80387 && reload_completed
14783 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14784 [(const_int 0)]
14785 {
14786 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14787 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14788 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14789 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14790 GET_MODE (operands[3]),
14791 operands[1],
14792 operands[4])));
14793 ix86_free_from_memory (GET_MODE (operands[2]));
14794 DONE;
14795 })
14796 \f
14797 ;; FPU special functions.
14798
14799 (define_expand "sqrtsf2"
14800 [(set (match_operand:SF 0 "register_operand" "")
14801 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14802 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14803 {
14804 if (!TARGET_SSE_MATH)
14805 operands[1] = force_reg (SFmode, operands[1]);
14806 })
14807
14808 (define_insn "sqrtsf2_1"
14809 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14810 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14811 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14812 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14813 "@
14814 fsqrt
14815 sqrtss\t{%1, %0|%0, %1}"
14816 [(set_attr "type" "fpspc,sse")
14817 (set_attr "mode" "SF,SF")
14818 (set_attr "athlon_decode" "direct,*")])
14819
14820 (define_insn "sqrtsf2_1_sse_only"
14821 [(set (match_operand:SF 0 "register_operand" "=x")
14822 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14823 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14824 "sqrtss\t{%1, %0|%0, %1}"
14825 [(set_attr "type" "sse")
14826 (set_attr "mode" "SF")
14827 (set_attr "athlon_decode" "*")])
14828
14829 (define_insn "sqrtsf2_i387"
14830 [(set (match_operand:SF 0 "register_operand" "=f")
14831 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14832 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14833 && !TARGET_SSE_MATH"
14834 "fsqrt"
14835 [(set_attr "type" "fpspc")
14836 (set_attr "mode" "SF")
14837 (set_attr "athlon_decode" "direct")])
14838
14839 (define_expand "sqrtdf2"
14840 [(set (match_operand:DF 0 "register_operand" "")
14841 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14842 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14843 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14844 {
14845 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14846 operands[1] = force_reg (DFmode, operands[1]);
14847 })
14848
14849 (define_insn "sqrtdf2_1"
14850 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14851 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14852 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14853 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14854 "@
14855 fsqrt
14856 sqrtsd\t{%1, %0|%0, %1}"
14857 [(set_attr "type" "fpspc,sse")
14858 (set_attr "mode" "DF,DF")
14859 (set_attr "athlon_decode" "direct,*")])
14860
14861 (define_insn "sqrtdf2_1_sse_only"
14862 [(set (match_operand:DF 0 "register_operand" "=Y")
14863 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14864 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14865 "sqrtsd\t{%1, %0|%0, %1}"
14866 [(set_attr "type" "sse")
14867 (set_attr "mode" "DF")
14868 (set_attr "athlon_decode" "*")])
14869
14870 (define_insn "sqrtdf2_i387"
14871 [(set (match_operand:DF 0 "register_operand" "=f")
14872 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14873 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14874 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14875 "fsqrt"
14876 [(set_attr "type" "fpspc")
14877 (set_attr "mode" "DF")
14878 (set_attr "athlon_decode" "direct")])
14879
14880 (define_insn "*sqrtextendsfdf2"
14881 [(set (match_operand:DF 0 "register_operand" "=f")
14882 (sqrt:DF (float_extend:DF
14883 (match_operand:SF 1 "register_operand" "0"))))]
14884 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14885 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14886 "fsqrt"
14887 [(set_attr "type" "fpspc")
14888 (set_attr "mode" "DF")
14889 (set_attr "athlon_decode" "direct")])
14890
14891 (define_insn "sqrtxf2"
14892 [(set (match_operand:XF 0 "register_operand" "=f")
14893 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14894 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14895 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14896 "fsqrt"
14897 [(set_attr "type" "fpspc")
14898 (set_attr "mode" "XF")
14899 (set_attr "athlon_decode" "direct")])
14900
14901 (define_insn "*sqrtextenddfxf2"
14902 [(set (match_operand:XF 0 "register_operand" "=f")
14903 (sqrt:XF (float_extend:XF
14904 (match_operand:DF 1 "register_operand" "0"))))]
14905 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14906 "fsqrt"
14907 [(set_attr "type" "fpspc")
14908 (set_attr "mode" "XF")
14909 (set_attr "athlon_decode" "direct")])
14910
14911 (define_insn "*sqrtextendsfxf2"
14912 [(set (match_operand:XF 0 "register_operand" "=f")
14913 (sqrt:XF (float_extend:XF
14914 (match_operand:SF 1 "register_operand" "0"))))]
14915 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14916 "fsqrt"
14917 [(set_attr "type" "fpspc")
14918 (set_attr "mode" "XF")
14919 (set_attr "athlon_decode" "direct")])
14920
14921 (define_insn "sindf2"
14922 [(set (match_operand:DF 0 "register_operand" "=f")
14923 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14924 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14925 && flag_unsafe_math_optimizations"
14926 "fsin"
14927 [(set_attr "type" "fpspc")
14928 (set_attr "mode" "DF")])
14929
14930 (define_insn "sinsf2"
14931 [(set (match_operand:SF 0 "register_operand" "=f")
14932 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14933 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14934 && flag_unsafe_math_optimizations"
14935 "fsin"
14936 [(set_attr "type" "fpspc")
14937 (set_attr "mode" "SF")])
14938
14939 (define_insn "*sinextendsfdf2"
14940 [(set (match_operand:DF 0 "register_operand" "=f")
14941 (unspec:DF [(float_extend:DF
14942 (match_operand:SF 1 "register_operand" "0"))]
14943 UNSPEC_SIN))]
14944 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14945 && flag_unsafe_math_optimizations"
14946 "fsin"
14947 [(set_attr "type" "fpspc")
14948 (set_attr "mode" "DF")])
14949
14950 (define_insn "sinxf2"
14951 [(set (match_operand:XF 0 "register_operand" "=f")
14952 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14953 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14955 "fsin"
14956 [(set_attr "type" "fpspc")
14957 (set_attr "mode" "XF")])
14958
14959 (define_insn "cosdf2"
14960 [(set (match_operand:DF 0 "register_operand" "=f")
14961 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14962 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14963 && flag_unsafe_math_optimizations"
14964 "fcos"
14965 [(set_attr "type" "fpspc")
14966 (set_attr "mode" "DF")])
14967
14968 (define_insn "cossf2"
14969 [(set (match_operand:SF 0 "register_operand" "=f")
14970 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14971 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14972 && flag_unsafe_math_optimizations"
14973 "fcos"
14974 [(set_attr "type" "fpspc")
14975 (set_attr "mode" "SF")])
14976
14977 (define_insn "*cosextendsfdf2"
14978 [(set (match_operand:DF 0 "register_operand" "=f")
14979 (unspec:DF [(float_extend:DF
14980 (match_operand:SF 1 "register_operand" "0"))]
14981 UNSPEC_COS))]
14982 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14983 && flag_unsafe_math_optimizations"
14984 "fcos"
14985 [(set_attr "type" "fpspc")
14986 (set_attr "mode" "DF")])
14987
14988 (define_insn "cosxf2"
14989 [(set (match_operand:XF 0 "register_operand" "=f")
14990 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14991 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14992 && flag_unsafe_math_optimizations"
14993 "fcos"
14994 [(set_attr "type" "fpspc")
14995 (set_attr "mode" "XF")])
14996
14997 (define_insn "atan2df3_1"
14998 [(set (match_operand:DF 0 "register_operand" "=f")
14999 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15000 (match_operand:DF 1 "register_operand" "u")]
15001 UNSPEC_FPATAN))
15002 (clobber (match_scratch:DF 3 "=1"))]
15003 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15004 && flag_unsafe_math_optimizations"
15005 "fpatan"
15006 [(set_attr "type" "fpspc")
15007 (set_attr "mode" "DF")])
15008
15009 (define_expand "atan2df3"
15010 [(use (match_operand:DF 0 "register_operand" "=f"))
15011 (use (match_operand:DF 2 "register_operand" "0"))
15012 (use (match_operand:DF 1 "register_operand" "u"))]
15013 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15014 && flag_unsafe_math_optimizations"
15015 {
15016 rtx copy = gen_reg_rtx (DFmode);
15017 emit_move_insn (copy, operands[1]);
15018 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15019 DONE;
15020 })
15021
15022 (define_insn "atan2sf3_1"
15023 [(set (match_operand:SF 0 "register_operand" "=f")
15024 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15025 (match_operand:SF 1 "register_operand" "u")]
15026 UNSPEC_FPATAN))
15027 (clobber (match_scratch:SF 3 "=1"))]
15028 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15029 && flag_unsafe_math_optimizations"
15030 "fpatan"
15031 [(set_attr "type" "fpspc")
15032 (set_attr "mode" "SF")])
15033
15034 (define_expand "atan2sf3"
15035 [(use (match_operand:SF 0 "register_operand" "=f"))
15036 (use (match_operand:SF 2 "register_operand" "0"))
15037 (use (match_operand:SF 1 "register_operand" "u"))]
15038 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15039 && flag_unsafe_math_optimizations"
15040 {
15041 rtx copy = gen_reg_rtx (SFmode);
15042 emit_move_insn (copy, operands[1]);
15043 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15044 DONE;
15045 })
15046
15047 (define_insn "atan2xf3_1"
15048 [(set (match_operand:XF 0 "register_operand" "=f")
15049 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15050 (match_operand:XF 1 "register_operand" "u")]
15051 UNSPEC_FPATAN))
15052 (clobber (match_scratch:XF 3 "=1"))]
15053 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15054 && flag_unsafe_math_optimizations"
15055 "fpatan"
15056 [(set_attr "type" "fpspc")
15057 (set_attr "mode" "XF")])
15058
15059 (define_expand "atan2xf3"
15060 [(use (match_operand:XF 0 "register_operand" "=f"))
15061 (use (match_operand:XF 2 "register_operand" "0"))
15062 (use (match_operand:XF 1 "register_operand" "u"))]
15063 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15064 && flag_unsafe_math_optimizations"
15065 {
15066 rtx copy = gen_reg_rtx (XFmode);
15067 emit_move_insn (copy, operands[1]);
15068 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15069 DONE;
15070 })
15071
15072 (define_insn "*fyl2x_sfxf3"
15073 [(set (match_operand:SF 0 "register_operand" "=f")
15074 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15075 (match_operand:XF 1 "register_operand" "u")]
15076 UNSPEC_FYL2X))
15077 (clobber (match_scratch:SF 3 "=1"))]
15078 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15079 && flag_unsafe_math_optimizations"
15080 "fyl2x"
15081 [(set_attr "type" "fpspc")
15082 (set_attr "mode" "SF")])
15083
15084 (define_insn "*fyl2x_dfxf3"
15085 [(set (match_operand:DF 0 "register_operand" "=f")
15086 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15087 (match_operand:XF 1 "register_operand" "u")]
15088 UNSPEC_FYL2X))
15089 (clobber (match_scratch:DF 3 "=1"))]
15090 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15091 && flag_unsafe_math_optimizations"
15092 "fyl2x"
15093 [(set_attr "type" "fpspc")
15094 (set_attr "mode" "DF")])
15095
15096 (define_insn "*fyl2x_xf3"
15097 [(set (match_operand:XF 0 "register_operand" "=f")
15098 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15099 (match_operand:XF 1 "register_operand" "u")]
15100 UNSPEC_FYL2X))
15101 (clobber (match_scratch:XF 3 "=1"))]
15102 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15103 && flag_unsafe_math_optimizations"
15104 "fyl2x"
15105 [(set_attr "type" "fpspc")
15106 (set_attr "mode" "XF")])
15107
15108 (define_expand "logsf2"
15109 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15110 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15111 (match_dup 2)] UNSPEC_FYL2X))
15112 (clobber (match_scratch:SF 3 ""))])]
15113 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15114 && flag_unsafe_math_optimizations"
15115 {
15116 rtx temp;
15117
15118 operands[2] = gen_reg_rtx (XFmode);
15119 temp = standard_80387_constant_rtx (4); /* fldln2 */
15120 emit_move_insn (operands[2], temp);
15121 })
15122
15123 (define_expand "logdf2"
15124 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15125 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15126 (match_dup 2)] UNSPEC_FYL2X))
15127 (clobber (match_scratch:DF 3 ""))])]
15128 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15129 && flag_unsafe_math_optimizations"
15130 {
15131 rtx temp;
15132
15133 operands[2] = gen_reg_rtx (XFmode);
15134 temp = standard_80387_constant_rtx (4); /* fldln2 */
15135 emit_move_insn (operands[2], temp);
15136 })
15137
15138 (define_expand "logxf2"
15139 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15140 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15141 (match_dup 2)] UNSPEC_FYL2X))
15142 (clobber (match_scratch:XF 3 ""))])]
15143 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15144 && flag_unsafe_math_optimizations"
15145 {
15146 rtx temp;
15147
15148 operands[2] = gen_reg_rtx (XFmode);
15149 temp = standard_80387_constant_rtx (4); /* fldln2 */
15150 emit_move_insn (operands[2], temp);
15151 })
15152
15153 (define_insn "*fscale_sfxf3"
15154 [(set (match_operand:SF 0 "register_operand" "=f")
15155 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15156 (match_operand:XF 1 "register_operand" "u")]
15157 UNSPEC_FSCALE))
15158 (clobber (match_scratch:SF 3 "=1"))]
15159 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15160 && flag_unsafe_math_optimizations"
15161 "fscale\;fstp\t%y1"
15162 [(set_attr "type" "fpspc")
15163 (set_attr "mode" "SF")])
15164
15165 (define_insn "*fscale_dfxf3"
15166 [(set (match_operand:DF 0 "register_operand" "=f")
15167 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15168 (match_operand:XF 1 "register_operand" "u")]
15169 UNSPEC_FSCALE))
15170 (clobber (match_scratch:DF 3 "=1"))]
15171 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15172 && flag_unsafe_math_optimizations"
15173 "fscale\;fstp\t%y1"
15174 [(set_attr "type" "fpspc")
15175 (set_attr "mode" "DF")])
15176
15177 (define_insn "*fscale_xf3"
15178 [(set (match_operand:XF 0 "register_operand" "=f")
15179 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15180 (match_operand:XF 1 "register_operand" "u")]
15181 UNSPEC_FSCALE))
15182 (clobber (match_scratch:XF 3 "=1"))]
15183 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15184 && flag_unsafe_math_optimizations"
15185 "fscale\;fstp\t%y1"
15186 [(set_attr "type" "fpspc")
15187 (set_attr "mode" "XF")])
15188
15189 (define_insn "*frndintxf2"
15190 [(set (match_operand:XF 0 "register_operand" "=f")
15191 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15192 UNSPEC_FRNDINT))]
15193 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15194 && flag_unsafe_math_optimizations"
15195 "frndint"
15196 [(set_attr "type" "fpspc")
15197 (set_attr "mode" "XF")])
15198
15199 (define_insn "*f2xm1xf2"
15200 [(set (match_operand:XF 0 "register_operand" "=f")
15201 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15202 UNSPEC_F2XM1))]
15203 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15204 && flag_unsafe_math_optimizations"
15205 "f2xm1"
15206 [(set_attr "type" "fpspc")
15207 (set_attr "mode" "XF")])
15208
15209 (define_expand "expsf2"
15210 [(set (match_dup 2)
15211 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15212 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15213 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15214 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15215 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15216 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15217 (parallel [(set (match_operand:SF 0 "register_operand" "")
15218 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15219 (clobber (match_scratch:SF 5 ""))])]
15220 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15221 && flag_unsafe_math_optimizations"
15222 {
15223 rtx temp;
15224 int i;
15225
15226 for (i=2; i<10; i++)
15227 operands[i] = gen_reg_rtx (XFmode);
15228 temp = standard_80387_constant_rtx (5); /* fldl2e */
15229 emit_move_insn (operands[3], temp);
15230 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15231 })
15232
15233 (define_expand "expdf2"
15234 [(set (match_dup 2)
15235 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15236 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15237 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15238 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15239 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15240 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15241 (parallel [(set (match_operand:DF 0 "register_operand" "")
15242 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15243 (clobber (match_scratch:DF 5 ""))])]
15244 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15245 && flag_unsafe_math_optimizations"
15246 {
15247 rtx temp;
15248 int i;
15249
15250 for (i=2; i<10; i++)
15251 operands[i] = gen_reg_rtx (XFmode);
15252 temp = standard_80387_constant_rtx (5); /* fldl2e */
15253 emit_move_insn (operands[3], temp);
15254 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15255 })
15256
15257 (define_expand "expxf2"
15258 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15259 (match_dup 2)))
15260 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15261 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15262 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15263 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15264 (parallel [(set (match_operand:XF 0 "register_operand" "")
15265 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15266 (clobber (match_scratch:XF 5 ""))])]
15267 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15268 && flag_unsafe_math_optimizations"
15269 {
15270 rtx temp;
15271 int i;
15272
15273 for (i=2; i<9; i++)
15274 operands[i] = gen_reg_rtx (XFmode);
15275 temp = standard_80387_constant_rtx (5); /* fldl2e */
15276 emit_move_insn (operands[2], temp);
15277 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15278 })
15279
15280 (define_expand "atansf2"
15281 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15282 (unspec:SF [(match_dup 2)
15283 (match_operand:SF 1 "register_operand" "")]
15284 UNSPEC_FPATAN))
15285 (clobber (match_scratch:SF 3 ""))])]
15286 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15287 && flag_unsafe_math_optimizations"
15288 {
15289 operands[2] = gen_reg_rtx (SFmode);
15290 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15291 })
15292
15293 (define_expand "atandf2"
15294 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15295 (unspec:DF [(match_dup 2)
15296 (match_operand:DF 1 "register_operand" "")]
15297 UNSPEC_FPATAN))
15298 (clobber (match_scratch:DF 3 ""))])]
15299 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15300 && flag_unsafe_math_optimizations"
15301 {
15302 operands[2] = gen_reg_rtx (DFmode);
15303 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15304 })
15305
15306 (define_expand "atanxf2"
15307 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15308 (unspec:XF [(match_dup 2)
15309 (match_operand:XF 1 "register_operand" "")]
15310 UNSPEC_FPATAN))
15311 (clobber (match_scratch:XF 3 ""))])]
15312 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15313 && flag_unsafe_math_optimizations"
15314 {
15315 operands[2] = gen_reg_rtx (XFmode);
15316 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15317 })
15318 \f
15319 ;; Block operation instructions
15320
15321 (define_insn "cld"
15322 [(set (reg:SI 19) (const_int 0))]
15323 ""
15324 "cld"
15325 [(set_attr "type" "cld")])
15326
15327 (define_expand "movstrsi"
15328 [(use (match_operand:BLK 0 "memory_operand" ""))
15329 (use (match_operand:BLK 1 "memory_operand" ""))
15330 (use (match_operand:SI 2 "nonmemory_operand" ""))
15331 (use (match_operand:SI 3 "const_int_operand" ""))]
15332 "! optimize_size"
15333 {
15334 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15335 DONE;
15336 else
15337 FAIL;
15338 })
15339
15340 (define_expand "movstrdi"
15341 [(use (match_operand:BLK 0 "memory_operand" ""))
15342 (use (match_operand:BLK 1 "memory_operand" ""))
15343 (use (match_operand:DI 2 "nonmemory_operand" ""))
15344 (use (match_operand:DI 3 "const_int_operand" ""))]
15345 "TARGET_64BIT"
15346 {
15347 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15348 DONE;
15349 else
15350 FAIL;
15351 })
15352
15353 ;; Most CPUs don't like single string operations
15354 ;; Handle this case here to simplify previous expander.
15355
15356 (define_expand "strmovdi_rex64"
15357 [(set (match_dup 2)
15358 (mem:DI (match_operand:DI 1 "register_operand" "")))
15359 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15360 (match_dup 2))
15361 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15362 (clobber (reg:CC 17))])
15363 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15364 (clobber (reg:CC 17))])]
15365 "TARGET_64BIT"
15366 {
15367 if (TARGET_SINGLE_STRINGOP || optimize_size)
15368 {
15369 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15370 operands[1]));
15371 DONE;
15372 }
15373 else
15374 operands[2] = gen_reg_rtx (DImode);
15375 })
15376
15377
15378 (define_expand "strmovsi"
15379 [(set (match_dup 2)
15380 (mem:SI (match_operand:SI 1 "register_operand" "")))
15381 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15382 (match_dup 2))
15383 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15384 (clobber (reg:CC 17))])
15385 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15386 (clobber (reg:CC 17))])]
15387 ""
15388 {
15389 if (TARGET_64BIT)
15390 {
15391 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15392 DONE;
15393 }
15394 if (TARGET_SINGLE_STRINGOP || optimize_size)
15395 {
15396 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15397 operands[1]));
15398 DONE;
15399 }
15400 else
15401 operands[2] = gen_reg_rtx (SImode);
15402 })
15403
15404 (define_expand "strmovsi_rex64"
15405 [(set (match_dup 2)
15406 (mem:SI (match_operand:DI 1 "register_operand" "")))
15407 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15408 (match_dup 2))
15409 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15410 (clobber (reg:CC 17))])
15411 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15412 (clobber (reg:CC 17))])]
15413 "TARGET_64BIT"
15414 {
15415 if (TARGET_SINGLE_STRINGOP || optimize_size)
15416 {
15417 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15418 operands[1]));
15419 DONE;
15420 }
15421 else
15422 operands[2] = gen_reg_rtx (SImode);
15423 })
15424
15425 (define_expand "strmovhi"
15426 [(set (match_dup 2)
15427 (mem:HI (match_operand:SI 1 "register_operand" "")))
15428 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15429 (match_dup 2))
15430 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15431 (clobber (reg:CC 17))])
15432 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15433 (clobber (reg:CC 17))])]
15434 ""
15435 {
15436 if (TARGET_64BIT)
15437 {
15438 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15439 DONE;
15440 }
15441 if (TARGET_SINGLE_STRINGOP || optimize_size)
15442 {
15443 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15444 operands[1]));
15445 DONE;
15446 }
15447 else
15448 operands[2] = gen_reg_rtx (HImode);
15449 })
15450
15451 (define_expand "strmovhi_rex64"
15452 [(set (match_dup 2)
15453 (mem:HI (match_operand:DI 1 "register_operand" "")))
15454 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15455 (match_dup 2))
15456 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15457 (clobber (reg:CC 17))])
15458 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15459 (clobber (reg:CC 17))])]
15460 "TARGET_64BIT"
15461 {
15462 if (TARGET_SINGLE_STRINGOP || optimize_size)
15463 {
15464 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15465 operands[1]));
15466 DONE;
15467 }
15468 else
15469 operands[2] = gen_reg_rtx (HImode);
15470 })
15471
15472 (define_expand "strmovqi"
15473 [(set (match_dup 2)
15474 (mem:QI (match_operand:SI 1 "register_operand" "")))
15475 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15476 (match_dup 2))
15477 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15478 (clobber (reg:CC 17))])
15479 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15480 (clobber (reg:CC 17))])]
15481 ""
15482 {
15483 if (TARGET_64BIT)
15484 {
15485 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15486 DONE;
15487 }
15488 if (TARGET_SINGLE_STRINGOP || optimize_size)
15489 {
15490 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15491 operands[1]));
15492 DONE;
15493 }
15494 else
15495 operands[2] = gen_reg_rtx (QImode);
15496 })
15497
15498 (define_expand "strmovqi_rex64"
15499 [(set (match_dup 2)
15500 (mem:QI (match_operand:DI 1 "register_operand" "")))
15501 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15502 (match_dup 2))
15503 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15504 (clobber (reg:CC 17))])
15505 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15506 (clobber (reg:CC 17))])]
15507 "TARGET_64BIT"
15508 {
15509 if (TARGET_SINGLE_STRINGOP || optimize_size)
15510 {
15511 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15512 operands[1]));
15513 DONE;
15514 }
15515 else
15516 operands[2] = gen_reg_rtx (QImode);
15517 })
15518
15519 (define_insn "strmovdi_rex_1"
15520 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15521 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15522 (set (match_operand:DI 0 "register_operand" "=D")
15523 (plus:DI (match_dup 2)
15524 (const_int 8)))
15525 (set (match_operand:DI 1 "register_operand" "=S")
15526 (plus:DI (match_dup 3)
15527 (const_int 8)))
15528 (use (reg:SI 19))]
15529 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15530 "movsq"
15531 [(set_attr "type" "str")
15532 (set_attr "mode" "DI")
15533 (set_attr "memory" "both")])
15534
15535 (define_insn "strmovsi_1"
15536 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15537 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15538 (set (match_operand:SI 0 "register_operand" "=D")
15539 (plus:SI (match_dup 2)
15540 (const_int 4)))
15541 (set (match_operand:SI 1 "register_operand" "=S")
15542 (plus:SI (match_dup 3)
15543 (const_int 4)))
15544 (use (reg:SI 19))]
15545 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15546 "{movsl|movsd}"
15547 [(set_attr "type" "str")
15548 (set_attr "mode" "SI")
15549 (set_attr "memory" "both")])
15550
15551 (define_insn "strmovsi_rex_1"
15552 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15553 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15554 (set (match_operand:DI 0 "register_operand" "=D")
15555 (plus:DI (match_dup 2)
15556 (const_int 4)))
15557 (set (match_operand:DI 1 "register_operand" "=S")
15558 (plus:DI (match_dup 3)
15559 (const_int 4)))
15560 (use (reg:SI 19))]
15561 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15562 "{movsl|movsd}"
15563 [(set_attr "type" "str")
15564 (set_attr "mode" "SI")
15565 (set_attr "memory" "both")])
15566
15567 (define_insn "strmovhi_1"
15568 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15569 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15570 (set (match_operand:SI 0 "register_operand" "=D")
15571 (plus:SI (match_dup 2)
15572 (const_int 2)))
15573 (set (match_operand:SI 1 "register_operand" "=S")
15574 (plus:SI (match_dup 3)
15575 (const_int 2)))
15576 (use (reg:SI 19))]
15577 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15578 "movsw"
15579 [(set_attr "type" "str")
15580 (set_attr "memory" "both")
15581 (set_attr "mode" "HI")])
15582
15583 (define_insn "strmovhi_rex_1"
15584 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15585 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15586 (set (match_operand:DI 0 "register_operand" "=D")
15587 (plus:DI (match_dup 2)
15588 (const_int 2)))
15589 (set (match_operand:DI 1 "register_operand" "=S")
15590 (plus:DI (match_dup 3)
15591 (const_int 2)))
15592 (use (reg:SI 19))]
15593 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15594 "movsw"
15595 [(set_attr "type" "str")
15596 (set_attr "memory" "both")
15597 (set_attr "mode" "HI")])
15598
15599 (define_insn "strmovqi_1"
15600 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15601 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15602 (set (match_operand:SI 0 "register_operand" "=D")
15603 (plus:SI (match_dup 2)
15604 (const_int 1)))
15605 (set (match_operand:SI 1 "register_operand" "=S")
15606 (plus:SI (match_dup 3)
15607 (const_int 1)))
15608 (use (reg:SI 19))]
15609 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15610 "movsb"
15611 [(set_attr "type" "str")
15612 (set_attr "memory" "both")
15613 (set_attr "mode" "QI")])
15614
15615 (define_insn "strmovqi_rex_1"
15616 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15617 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15618 (set (match_operand:DI 0 "register_operand" "=D")
15619 (plus:DI (match_dup 2)
15620 (const_int 1)))
15621 (set (match_operand:DI 1 "register_operand" "=S")
15622 (plus:DI (match_dup 3)
15623 (const_int 1)))
15624 (use (reg:SI 19))]
15625 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15626 "movsb"
15627 [(set_attr "type" "str")
15628 (set_attr "memory" "both")
15629 (set_attr "mode" "QI")])
15630
15631 (define_insn "rep_movdi_rex64"
15632 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15633 (set (match_operand:DI 0 "register_operand" "=D")
15634 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15635 (const_int 3))
15636 (match_operand:DI 3 "register_operand" "0")))
15637 (set (match_operand:DI 1 "register_operand" "=S")
15638 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15639 (match_operand:DI 4 "register_operand" "1")))
15640 (set (mem:BLK (match_dup 3))
15641 (mem:BLK (match_dup 4)))
15642 (use (match_dup 5))
15643 (use (reg:SI 19))]
15644 "TARGET_64BIT"
15645 "{rep\;movsq|rep movsq}"
15646 [(set_attr "type" "str")
15647 (set_attr "prefix_rep" "1")
15648 (set_attr "memory" "both")
15649 (set_attr "mode" "DI")])
15650
15651 (define_insn "rep_movsi"
15652 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15653 (set (match_operand:SI 0 "register_operand" "=D")
15654 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15655 (const_int 2))
15656 (match_operand:SI 3 "register_operand" "0")))
15657 (set (match_operand:SI 1 "register_operand" "=S")
15658 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15659 (match_operand:SI 4 "register_operand" "1")))
15660 (set (mem:BLK (match_dup 3))
15661 (mem:BLK (match_dup 4)))
15662 (use (match_dup 5))
15663 (use (reg:SI 19))]
15664 "!TARGET_64BIT"
15665 "{rep\;movsl|rep movsd}"
15666 [(set_attr "type" "str")
15667 (set_attr "prefix_rep" "1")
15668 (set_attr "memory" "both")
15669 (set_attr "mode" "SI")])
15670
15671 (define_insn "rep_movsi_rex64"
15672 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15673 (set (match_operand:DI 0 "register_operand" "=D")
15674 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15675 (const_int 2))
15676 (match_operand:DI 3 "register_operand" "0")))
15677 (set (match_operand:DI 1 "register_operand" "=S")
15678 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15679 (match_operand:DI 4 "register_operand" "1")))
15680 (set (mem:BLK (match_dup 3))
15681 (mem:BLK (match_dup 4)))
15682 (use (match_dup 5))
15683 (use (reg:SI 19))]
15684 "TARGET_64BIT"
15685 "{rep\;movsl|rep movsd}"
15686 [(set_attr "type" "str")
15687 (set_attr "prefix_rep" "1")
15688 (set_attr "memory" "both")
15689 (set_attr "mode" "SI")])
15690
15691 (define_insn "rep_movqi"
15692 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15693 (set (match_operand:SI 0 "register_operand" "=D")
15694 (plus:SI (match_operand:SI 3 "register_operand" "0")
15695 (match_operand:SI 5 "register_operand" "2")))
15696 (set (match_operand:SI 1 "register_operand" "=S")
15697 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15698 (set (mem:BLK (match_dup 3))
15699 (mem:BLK (match_dup 4)))
15700 (use (match_dup 5))
15701 (use (reg:SI 19))]
15702 "!TARGET_64BIT"
15703 "{rep\;movsb|rep movsb}"
15704 [(set_attr "type" "str")
15705 (set_attr "prefix_rep" "1")
15706 (set_attr "memory" "both")
15707 (set_attr "mode" "SI")])
15708
15709 (define_insn "rep_movqi_rex64"
15710 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15711 (set (match_operand:DI 0 "register_operand" "=D")
15712 (plus:DI (match_operand:DI 3 "register_operand" "0")
15713 (match_operand:DI 5 "register_operand" "2")))
15714 (set (match_operand:DI 1 "register_operand" "=S")
15715 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15716 (set (mem:BLK (match_dup 3))
15717 (mem:BLK (match_dup 4)))
15718 (use (match_dup 5))
15719 (use (reg:SI 19))]
15720 "TARGET_64BIT"
15721 "{rep\;movsb|rep movsb}"
15722 [(set_attr "type" "str")
15723 (set_attr "prefix_rep" "1")
15724 (set_attr "memory" "both")
15725 (set_attr "mode" "SI")])
15726
15727 (define_expand "clrstrsi"
15728 [(use (match_operand:BLK 0 "memory_operand" ""))
15729 (use (match_operand:SI 1 "nonmemory_operand" ""))
15730 (use (match_operand 2 "const_int_operand" ""))]
15731 ""
15732 {
15733 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15734 DONE;
15735 else
15736 FAIL;
15737 })
15738
15739 (define_expand "clrstrdi"
15740 [(use (match_operand:BLK 0 "memory_operand" ""))
15741 (use (match_operand:DI 1 "nonmemory_operand" ""))
15742 (use (match_operand 2 "const_int_operand" ""))]
15743 "TARGET_64BIT"
15744 {
15745 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15746 DONE;
15747 else
15748 FAIL;
15749 })
15750
15751 ;; Most CPUs don't like single string operations
15752 ;; Handle this case here to simplify previous expander.
15753
15754 (define_expand "strsetdi_rex64"
15755 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15756 (match_operand:DI 1 "register_operand" ""))
15757 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15758 (clobber (reg:CC 17))])]
15759 "TARGET_64BIT"
15760 {
15761 if (TARGET_SINGLE_STRINGOP || optimize_size)
15762 {
15763 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15764 DONE;
15765 }
15766 })
15767
15768 (define_expand "strsetsi"
15769 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15770 (match_operand:SI 1 "register_operand" ""))
15771 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15772 (clobber (reg:CC 17))])]
15773 ""
15774 {
15775 if (TARGET_64BIT)
15776 {
15777 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15778 DONE;
15779 }
15780 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15781 {
15782 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15783 DONE;
15784 }
15785 })
15786
15787 (define_expand "strsetsi_rex64"
15788 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15789 (match_operand:SI 1 "register_operand" ""))
15790 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15791 (clobber (reg:CC 17))])]
15792 "TARGET_64BIT"
15793 {
15794 if (TARGET_SINGLE_STRINGOP || optimize_size)
15795 {
15796 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15797 DONE;
15798 }
15799 })
15800
15801 (define_expand "strsethi"
15802 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15803 (match_operand:HI 1 "register_operand" ""))
15804 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15805 (clobber (reg:CC 17))])]
15806 ""
15807 {
15808 if (TARGET_64BIT)
15809 {
15810 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15811 DONE;
15812 }
15813 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15814 {
15815 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15816 DONE;
15817 }
15818 })
15819
15820 (define_expand "strsethi_rex64"
15821 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15822 (match_operand:HI 1 "register_operand" ""))
15823 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15824 (clobber (reg:CC 17))])]
15825 "TARGET_64BIT"
15826 {
15827 if (TARGET_SINGLE_STRINGOP || optimize_size)
15828 {
15829 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15830 DONE;
15831 }
15832 })
15833
15834 (define_expand "strsetqi"
15835 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15836 (match_operand:QI 1 "register_operand" ""))
15837 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15838 (clobber (reg:CC 17))])]
15839 ""
15840 {
15841 if (TARGET_64BIT)
15842 {
15843 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
15844 DONE;
15845 }
15846 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15847 {
15848 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
15849 DONE;
15850 }
15851 })
15852
15853 (define_expand "strsetqi_rex64"
15854 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
15855 (match_operand:QI 1 "register_operand" ""))
15856 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15857 (clobber (reg:CC 17))])]
15858 "TARGET_64BIT"
15859 {
15860 if (TARGET_SINGLE_STRINGOP || optimize_size)
15861 {
15862 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15863 DONE;
15864 }
15865 })
15866
15867 (define_insn "strsetdi_rex_1"
15868 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15869 (match_operand:SI 2 "register_operand" "a"))
15870 (set (match_operand:DI 0 "register_operand" "=D")
15871 (plus:DI (match_dup 1)
15872 (const_int 8)))
15873 (use (reg:SI 19))]
15874 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15875 "stosq"
15876 [(set_attr "type" "str")
15877 (set_attr "memory" "store")
15878 (set_attr "mode" "DI")])
15879
15880 (define_insn "strsetsi_1"
15881 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15882 (match_operand:SI 2 "register_operand" "a"))
15883 (set (match_operand:SI 0 "register_operand" "=D")
15884 (plus:SI (match_dup 1)
15885 (const_int 4)))
15886 (use (reg:SI 19))]
15887 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15888 "{stosl|stosd}"
15889 [(set_attr "type" "str")
15890 (set_attr "memory" "store")
15891 (set_attr "mode" "SI")])
15892
15893 (define_insn "strsetsi_rex_1"
15894 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15895 (match_operand:SI 2 "register_operand" "a"))
15896 (set (match_operand:DI 0 "register_operand" "=D")
15897 (plus:DI (match_dup 1)
15898 (const_int 4)))
15899 (use (reg:SI 19))]
15900 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15901 "{stosl|stosd}"
15902 [(set_attr "type" "str")
15903 (set_attr "memory" "store")
15904 (set_attr "mode" "SI")])
15905
15906 (define_insn "strsethi_1"
15907 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15908 (match_operand:HI 2 "register_operand" "a"))
15909 (set (match_operand:SI 0 "register_operand" "=D")
15910 (plus:SI (match_dup 1)
15911 (const_int 2)))
15912 (use (reg:SI 19))]
15913 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15914 "stosw"
15915 [(set_attr "type" "str")
15916 (set_attr "memory" "store")
15917 (set_attr "mode" "HI")])
15918
15919 (define_insn "strsethi_rex_1"
15920 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15921 (match_operand:HI 2 "register_operand" "a"))
15922 (set (match_operand:DI 0 "register_operand" "=D")
15923 (plus:DI (match_dup 1)
15924 (const_int 2)))
15925 (use (reg:SI 19))]
15926 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15927 "stosw"
15928 [(set_attr "type" "str")
15929 (set_attr "memory" "store")
15930 (set_attr "mode" "HI")])
15931
15932 (define_insn "strsetqi_1"
15933 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15934 (match_operand:QI 2 "register_operand" "a"))
15935 (set (match_operand:SI 0 "register_operand" "=D")
15936 (plus:SI (match_dup 1)
15937 (const_int 1)))
15938 (use (reg:SI 19))]
15939 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15940 "stosb"
15941 [(set_attr "type" "str")
15942 (set_attr "memory" "store")
15943 (set_attr "mode" "QI")])
15944
15945 (define_insn "strsetqi_rex_1"
15946 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15947 (match_operand:QI 2 "register_operand" "a"))
15948 (set (match_operand:DI 0 "register_operand" "=D")
15949 (plus:DI (match_dup 1)
15950 (const_int 1)))
15951 (use (reg:SI 19))]
15952 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15953 "stosb"
15954 [(set_attr "type" "str")
15955 (set_attr "memory" "store")
15956 (set_attr "mode" "QI")])
15957
15958 (define_insn "rep_stosdi_rex64"
15959 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15960 (set (match_operand:DI 0 "register_operand" "=D")
15961 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15962 (const_int 3))
15963 (match_operand:DI 3 "register_operand" "0")))
15964 (set (mem:BLK (match_dup 3))
15965 (const_int 0))
15966 (use (match_operand:DI 2 "register_operand" "a"))
15967 (use (match_dup 4))
15968 (use (reg:SI 19))]
15969 "TARGET_64BIT"
15970 "{rep\;stosq|rep stosq}"
15971 [(set_attr "type" "str")
15972 (set_attr "prefix_rep" "1")
15973 (set_attr "memory" "store")
15974 (set_attr "mode" "DI")])
15975
15976 (define_insn "rep_stossi"
15977 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15978 (set (match_operand:SI 0 "register_operand" "=D")
15979 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15980 (const_int 2))
15981 (match_operand:SI 3 "register_operand" "0")))
15982 (set (mem:BLK (match_dup 3))
15983 (const_int 0))
15984 (use (match_operand:SI 2 "register_operand" "a"))
15985 (use (match_dup 4))
15986 (use (reg:SI 19))]
15987 "!TARGET_64BIT"
15988 "{rep\;stosl|rep stosd}"
15989 [(set_attr "type" "str")
15990 (set_attr "prefix_rep" "1")
15991 (set_attr "memory" "store")
15992 (set_attr "mode" "SI")])
15993
15994 (define_insn "rep_stossi_rex64"
15995 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15996 (set (match_operand:DI 0 "register_operand" "=D")
15997 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15998 (const_int 2))
15999 (match_operand:DI 3 "register_operand" "0")))
16000 (set (mem:BLK (match_dup 3))
16001 (const_int 0))
16002 (use (match_operand:SI 2 "register_operand" "a"))
16003 (use (match_dup 4))
16004 (use (reg:SI 19))]
16005 "TARGET_64BIT"
16006 "{rep\;stosl|rep stosd}"
16007 [(set_attr "type" "str")
16008 (set_attr "prefix_rep" "1")
16009 (set_attr "memory" "store")
16010 (set_attr "mode" "SI")])
16011
16012 (define_insn "rep_stosqi"
16013 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16014 (set (match_operand:SI 0 "register_operand" "=D")
16015 (plus:SI (match_operand:SI 3 "register_operand" "0")
16016 (match_operand:SI 4 "register_operand" "1")))
16017 (set (mem:BLK (match_dup 3))
16018 (const_int 0))
16019 (use (match_operand:QI 2 "register_operand" "a"))
16020 (use (match_dup 4))
16021 (use (reg:SI 19))]
16022 "!TARGET_64BIT"
16023 "{rep\;stosb|rep stosb}"
16024 [(set_attr "type" "str")
16025 (set_attr "prefix_rep" "1")
16026 (set_attr "memory" "store")
16027 (set_attr "mode" "QI")])
16028
16029 (define_insn "rep_stosqi_rex64"
16030 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16031 (set (match_operand:DI 0 "register_operand" "=D")
16032 (plus:DI (match_operand:DI 3 "register_operand" "0")
16033 (match_operand:DI 4 "register_operand" "1")))
16034 (set (mem:BLK (match_dup 3))
16035 (const_int 0))
16036 (use (match_operand:QI 2 "register_operand" "a"))
16037 (use (match_dup 4))
16038 (use (reg:DI 19))]
16039 "TARGET_64BIT"
16040 "{rep\;stosb|rep stosb}"
16041 [(set_attr "type" "str")
16042 (set_attr "prefix_rep" "1")
16043 (set_attr "memory" "store")
16044 (set_attr "mode" "QI")])
16045
16046 (define_expand "cmpstrsi"
16047 [(set (match_operand:SI 0 "register_operand" "")
16048 (compare:SI (match_operand:BLK 1 "general_operand" "")
16049 (match_operand:BLK 2 "general_operand" "")))
16050 (use (match_operand 3 "general_operand" ""))
16051 (use (match_operand 4 "immediate_operand" ""))]
16052 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16053 {
16054 rtx addr1, addr2, out, outlow, count, countreg, align;
16055
16056 /* Can't use this if the user has appropriated esi or edi. */
16057 if (global_regs[4] || global_regs[5])
16058 FAIL;
16059
16060 out = operands[0];
16061 if (GET_CODE (out) != REG)
16062 out = gen_reg_rtx (SImode);
16063
16064 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16065 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16066
16067 count = operands[3];
16068 countreg = ix86_zero_extend_to_Pmode (count);
16069
16070 /* %%% Iff we are testing strict equality, we can use known alignment
16071 to good advantage. This may be possible with combine, particularly
16072 once cc0 is dead. */
16073 align = operands[4];
16074
16075 emit_insn (gen_cld ());
16076 if (GET_CODE (count) == CONST_INT)
16077 {
16078 if (INTVAL (count) == 0)
16079 {
16080 emit_move_insn (operands[0], const0_rtx);
16081 DONE;
16082 }
16083 if (TARGET_64BIT)
16084 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16085 addr1, addr2, countreg));
16086 else
16087 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16088 addr1, addr2, countreg));
16089 }
16090 else
16091 {
16092 if (TARGET_64BIT)
16093 {
16094 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16095 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16096 addr1, addr2, countreg));
16097 }
16098 else
16099 {
16100 emit_insn (gen_cmpsi_1 (countreg, countreg));
16101 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16102 addr1, addr2, countreg));
16103 }
16104 }
16105
16106 outlow = gen_lowpart (QImode, out);
16107 emit_insn (gen_cmpintqi (outlow));
16108 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16109
16110 if (operands[0] != out)
16111 emit_move_insn (operands[0], out);
16112
16113 DONE;
16114 })
16115
16116 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16117
16118 (define_expand "cmpintqi"
16119 [(set (match_dup 1)
16120 (gtu:QI (reg:CC 17) (const_int 0)))
16121 (set (match_dup 2)
16122 (ltu:QI (reg:CC 17) (const_int 0)))
16123 (parallel [(set (match_operand:QI 0 "register_operand" "")
16124 (minus:QI (match_dup 1)
16125 (match_dup 2)))
16126 (clobber (reg:CC 17))])]
16127 ""
16128 "operands[1] = gen_reg_rtx (QImode);
16129 operands[2] = gen_reg_rtx (QImode);")
16130
16131 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16132 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16133
16134 (define_insn "cmpstrqi_nz_1"
16135 [(set (reg:CC 17)
16136 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16137 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16138 (use (match_operand:SI 6 "register_operand" "2"))
16139 (use (match_operand:SI 3 "immediate_operand" "i"))
16140 (use (reg:SI 19))
16141 (clobber (match_operand:SI 0 "register_operand" "=S"))
16142 (clobber (match_operand:SI 1 "register_operand" "=D"))
16143 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16144 "!TARGET_64BIT"
16145 "repz{\;| }cmpsb"
16146 [(set_attr "type" "str")
16147 (set_attr "mode" "QI")
16148 (set_attr "prefix_rep" "1")])
16149
16150 (define_insn "cmpstrqi_nz_rex_1"
16151 [(set (reg:CC 17)
16152 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16153 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16154 (use (match_operand:DI 6 "register_operand" "2"))
16155 (use (match_operand:SI 3 "immediate_operand" "i"))
16156 (use (reg:SI 19))
16157 (clobber (match_operand:DI 0 "register_operand" "=S"))
16158 (clobber (match_operand:DI 1 "register_operand" "=D"))
16159 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16160 "TARGET_64BIT"
16161 "repz{\;| }cmpsb"
16162 [(set_attr "type" "str")
16163 (set_attr "mode" "QI")
16164 (set_attr "prefix_rep" "1")])
16165
16166 ;; The same, but the count is not known to not be zero.
16167
16168 (define_insn "cmpstrqi_1"
16169 [(set (reg:CC 17)
16170 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16171 (const_int 0))
16172 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16173 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16174 (const_int 0)))
16175 (use (match_operand:SI 3 "immediate_operand" "i"))
16176 (use (reg:CC 17))
16177 (use (reg:SI 19))
16178 (clobber (match_operand:SI 0 "register_operand" "=S"))
16179 (clobber (match_operand:SI 1 "register_operand" "=D"))
16180 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16181 "!TARGET_64BIT"
16182 "repz{\;| }cmpsb"
16183 [(set_attr "type" "str")
16184 (set_attr "mode" "QI")
16185 (set_attr "prefix_rep" "1")])
16186
16187 (define_insn "cmpstrqi_rex_1"
16188 [(set (reg:CC 17)
16189 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16190 (const_int 0))
16191 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16192 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16193 (const_int 0)))
16194 (use (match_operand:SI 3 "immediate_operand" "i"))
16195 (use (reg:CC 17))
16196 (use (reg:SI 19))
16197 (clobber (match_operand:DI 0 "register_operand" "=S"))
16198 (clobber (match_operand:DI 1 "register_operand" "=D"))
16199 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16200 "TARGET_64BIT"
16201 "repz{\;| }cmpsb"
16202 [(set_attr "type" "str")
16203 (set_attr "mode" "QI")
16204 (set_attr "prefix_rep" "1")])
16205
16206 (define_expand "strlensi"
16207 [(set (match_operand:SI 0 "register_operand" "")
16208 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16209 (match_operand:QI 2 "immediate_operand" "")
16210 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16211 ""
16212 {
16213 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16214 DONE;
16215 else
16216 FAIL;
16217 })
16218
16219 (define_expand "strlendi"
16220 [(set (match_operand:DI 0 "register_operand" "")
16221 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16222 (match_operand:QI 2 "immediate_operand" "")
16223 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16224 ""
16225 {
16226 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16227 DONE;
16228 else
16229 FAIL;
16230 })
16231
16232 (define_insn "strlenqi_1"
16233 [(set (match_operand:SI 0 "register_operand" "=&c")
16234 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16235 (match_operand:QI 2 "register_operand" "a")
16236 (match_operand:SI 3 "immediate_operand" "i")
16237 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16238 (use (reg:SI 19))
16239 (clobber (match_operand:SI 1 "register_operand" "=D"))
16240 (clobber (reg:CC 17))]
16241 "!TARGET_64BIT"
16242 "repnz{\;| }scasb"
16243 [(set_attr "type" "str")
16244 (set_attr "mode" "QI")
16245 (set_attr "prefix_rep" "1")])
16246
16247 (define_insn "strlenqi_rex_1"
16248 [(set (match_operand:DI 0 "register_operand" "=&c")
16249 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16250 (match_operand:QI 2 "register_operand" "a")
16251 (match_operand:DI 3 "immediate_operand" "i")
16252 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16253 (use (reg:SI 19))
16254 (clobber (match_operand:DI 1 "register_operand" "=D"))
16255 (clobber (reg:CC 17))]
16256 "TARGET_64BIT"
16257 "repnz{\;| }scasb"
16258 [(set_attr "type" "str")
16259 (set_attr "mode" "QI")
16260 (set_attr "prefix_rep" "1")])
16261
16262 ;; Peephole optimizations to clean up after cmpstr*. This should be
16263 ;; handled in combine, but it is not currently up to the task.
16264 ;; When used for their truth value, the cmpstr* expanders generate
16265 ;; code like this:
16266 ;;
16267 ;; repz cmpsb
16268 ;; seta %al
16269 ;; setb %dl
16270 ;; cmpb %al, %dl
16271 ;; jcc label
16272 ;;
16273 ;; The intermediate three instructions are unnecessary.
16274
16275 ;; This one handles cmpstr*_nz_1...
16276 (define_peephole2
16277 [(parallel[
16278 (set (reg:CC 17)
16279 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16280 (mem:BLK (match_operand 5 "register_operand" ""))))
16281 (use (match_operand 6 "register_operand" ""))
16282 (use (match_operand:SI 3 "immediate_operand" ""))
16283 (use (reg:SI 19))
16284 (clobber (match_operand 0 "register_operand" ""))
16285 (clobber (match_operand 1 "register_operand" ""))
16286 (clobber (match_operand 2 "register_operand" ""))])
16287 (set (match_operand:QI 7 "register_operand" "")
16288 (gtu:QI (reg:CC 17) (const_int 0)))
16289 (set (match_operand:QI 8 "register_operand" "")
16290 (ltu:QI (reg:CC 17) (const_int 0)))
16291 (set (reg 17)
16292 (compare (match_dup 7) (match_dup 8)))
16293 ]
16294 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16295 [(parallel[
16296 (set (reg:CC 17)
16297 (compare:CC (mem:BLK (match_dup 4))
16298 (mem:BLK (match_dup 5))))
16299 (use (match_dup 6))
16300 (use (match_dup 3))
16301 (use (reg:SI 19))
16302 (clobber (match_dup 0))
16303 (clobber (match_dup 1))
16304 (clobber (match_dup 2))])]
16305 "")
16306
16307 ;; ...and this one handles cmpstr*_1.
16308 (define_peephole2
16309 [(parallel[
16310 (set (reg:CC 17)
16311 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16312 (const_int 0))
16313 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16314 (mem:BLK (match_operand 5 "register_operand" "")))
16315 (const_int 0)))
16316 (use (match_operand:SI 3 "immediate_operand" ""))
16317 (use (reg:CC 17))
16318 (use (reg:SI 19))
16319 (clobber (match_operand 0 "register_operand" ""))
16320 (clobber (match_operand 1 "register_operand" ""))
16321 (clobber (match_operand 2 "register_operand" ""))])
16322 (set (match_operand:QI 7 "register_operand" "")
16323 (gtu:QI (reg:CC 17) (const_int 0)))
16324 (set (match_operand:QI 8 "register_operand" "")
16325 (ltu:QI (reg:CC 17) (const_int 0)))
16326 (set (reg 17)
16327 (compare (match_dup 7) (match_dup 8)))
16328 ]
16329 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16330 [(parallel[
16331 (set (reg:CC 17)
16332 (if_then_else:CC (ne (match_dup 6)
16333 (const_int 0))
16334 (compare:CC (mem:BLK (match_dup 4))
16335 (mem:BLK (match_dup 5)))
16336 (const_int 0)))
16337 (use (match_dup 3))
16338 (use (reg:CC 17))
16339 (use (reg:SI 19))
16340 (clobber (match_dup 0))
16341 (clobber (match_dup 1))
16342 (clobber (match_dup 2))])]
16343 "")
16344
16345
16346 \f
16347 ;; Conditional move instructions.
16348
16349 (define_expand "movdicc"
16350 [(set (match_operand:DI 0 "register_operand" "")
16351 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16352 (match_operand:DI 2 "general_operand" "")
16353 (match_operand:DI 3 "general_operand" "")))]
16354 "TARGET_64BIT"
16355 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16356
16357 (define_insn "x86_movdicc_0_m1_rex64"
16358 [(set (match_operand:DI 0 "register_operand" "=r")
16359 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16360 (const_int -1)
16361 (const_int 0)))
16362 (clobber (reg:CC 17))]
16363 "TARGET_64BIT"
16364 "sbb{q}\t%0, %0"
16365 ; Since we don't have the proper number of operands for an alu insn,
16366 ; fill in all the blanks.
16367 [(set_attr "type" "alu")
16368 (set_attr "pent_pair" "pu")
16369 (set_attr "memory" "none")
16370 (set_attr "imm_disp" "false")
16371 (set_attr "mode" "DI")
16372 (set_attr "length_immediate" "0")])
16373
16374 (define_insn "movdicc_c_rex64"
16375 [(set (match_operand:DI 0 "register_operand" "=r,r")
16376 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16377 [(reg 17) (const_int 0)])
16378 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16379 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16380 "TARGET_64BIT && TARGET_CMOVE
16381 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16382 "@
16383 cmov%O2%C1\t{%2, %0|%0, %2}
16384 cmov%O2%c1\t{%3, %0|%0, %3}"
16385 [(set_attr "type" "icmov")
16386 (set_attr "mode" "DI")])
16387
16388 (define_expand "movsicc"
16389 [(set (match_operand:SI 0 "register_operand" "")
16390 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16391 (match_operand:SI 2 "general_operand" "")
16392 (match_operand:SI 3 "general_operand" "")))]
16393 ""
16394 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16395
16396 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16397 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16398 ;; So just document what we're doing explicitly.
16399
16400 (define_insn "x86_movsicc_0_m1"
16401 [(set (match_operand:SI 0 "register_operand" "=r")
16402 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16403 (const_int -1)
16404 (const_int 0)))
16405 (clobber (reg:CC 17))]
16406 ""
16407 "sbb{l}\t%0, %0"
16408 ; Since we don't have the proper number of operands for an alu insn,
16409 ; fill in all the blanks.
16410 [(set_attr "type" "alu")
16411 (set_attr "pent_pair" "pu")
16412 (set_attr "memory" "none")
16413 (set_attr "imm_disp" "false")
16414 (set_attr "mode" "SI")
16415 (set_attr "length_immediate" "0")])
16416
16417 (define_insn "*movsicc_noc"
16418 [(set (match_operand:SI 0 "register_operand" "=r,r")
16419 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16420 [(reg 17) (const_int 0)])
16421 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16422 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16423 "TARGET_CMOVE
16424 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16425 "@
16426 cmov%O2%C1\t{%2, %0|%0, %2}
16427 cmov%O2%c1\t{%3, %0|%0, %3}"
16428 [(set_attr "type" "icmov")
16429 (set_attr "mode" "SI")])
16430
16431 (define_expand "movhicc"
16432 [(set (match_operand:HI 0 "register_operand" "")
16433 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16434 (match_operand:HI 2 "general_operand" "")
16435 (match_operand:HI 3 "general_operand" "")))]
16436 "TARGET_HIMODE_MATH"
16437 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16438
16439 (define_insn "*movhicc_noc"
16440 [(set (match_operand:HI 0 "register_operand" "=r,r")
16441 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16442 [(reg 17) (const_int 0)])
16443 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16444 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16445 "TARGET_CMOVE
16446 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16447 "@
16448 cmov%O2%C1\t{%2, %0|%0, %2}
16449 cmov%O2%c1\t{%3, %0|%0, %3}"
16450 [(set_attr "type" "icmov")
16451 (set_attr "mode" "HI")])
16452
16453 (define_expand "movqicc"
16454 [(set (match_operand:QI 0 "register_operand" "")
16455 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16456 (match_operand:QI 2 "general_operand" "")
16457 (match_operand:QI 3 "general_operand" "")))]
16458 "TARGET_QIMODE_MATH"
16459 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16460
16461 (define_insn_and_split "*movqicc_noc"
16462 [(set (match_operand:QI 0 "register_operand" "=r,r")
16463 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16464 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16465 (match_operand:QI 2 "register_operand" "r,0")
16466 (match_operand:QI 3 "register_operand" "0,r")))]
16467 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16468 "#"
16469 "&& reload_completed"
16470 [(set (match_dup 0)
16471 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16472 (match_dup 2)
16473 (match_dup 3)))]
16474 "operands[0] = gen_lowpart (SImode, operands[0]);
16475 operands[2] = gen_lowpart (SImode, operands[2]);
16476 operands[3] = gen_lowpart (SImode, operands[3]);"
16477 [(set_attr "type" "icmov")
16478 (set_attr "mode" "SI")])
16479
16480 (define_expand "movsfcc"
16481 [(set (match_operand:SF 0 "register_operand" "")
16482 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16483 (match_operand:SF 2 "register_operand" "")
16484 (match_operand:SF 3 "register_operand" "")))]
16485 "TARGET_CMOVE"
16486 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16487
16488 (define_insn "*movsfcc_1"
16489 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16490 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16491 [(reg 17) (const_int 0)])
16492 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16493 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16494 "TARGET_CMOVE
16495 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16496 "@
16497 fcmov%F1\t{%2, %0|%0, %2}
16498 fcmov%f1\t{%3, %0|%0, %3}
16499 cmov%O2%C1\t{%2, %0|%0, %2}
16500 cmov%O2%c1\t{%3, %0|%0, %3}"
16501 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16502 (set_attr "mode" "SF,SF,SI,SI")])
16503
16504 (define_expand "movdfcc"
16505 [(set (match_operand:DF 0 "register_operand" "")
16506 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16507 (match_operand:DF 2 "register_operand" "")
16508 (match_operand:DF 3 "register_operand" "")))]
16509 "TARGET_CMOVE"
16510 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16511
16512 (define_insn "*movdfcc_1"
16513 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16514 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16515 [(reg 17) (const_int 0)])
16516 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16517 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16518 "!TARGET_64BIT && TARGET_CMOVE
16519 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16520 "@
16521 fcmov%F1\t{%2, %0|%0, %2}
16522 fcmov%f1\t{%3, %0|%0, %3}
16523 #
16524 #"
16525 [(set_attr "type" "fcmov,fcmov,multi,multi")
16526 (set_attr "mode" "DF")])
16527
16528 (define_insn "*movdfcc_1_rex64"
16529 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16530 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16531 [(reg 17) (const_int 0)])
16532 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16533 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16534 "TARGET_64BIT && TARGET_CMOVE
16535 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16536 "@
16537 fcmov%F1\t{%2, %0|%0, %2}
16538 fcmov%f1\t{%3, %0|%0, %3}
16539 cmov%O2%C1\t{%2, %0|%0, %2}
16540 cmov%O2%c1\t{%3, %0|%0, %3}"
16541 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16542 (set_attr "mode" "DF")])
16543
16544 (define_split
16545 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16546 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16547 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16548 (match_operand:DF 2 "nonimmediate_operand" "")
16549 (match_operand:DF 3 "nonimmediate_operand" "")))]
16550 "!TARGET_64BIT && reload_completed"
16551 [(set (match_dup 2)
16552 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16553 (match_dup 5)
16554 (match_dup 7)))
16555 (set (match_dup 3)
16556 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16557 (match_dup 6)
16558 (match_dup 8)))]
16559 "split_di (operands+2, 1, operands+5, operands+6);
16560 split_di (operands+3, 1, operands+7, operands+8);
16561 split_di (operands, 1, operands+2, operands+3);")
16562
16563 (define_expand "movxfcc"
16564 [(set (match_operand:XF 0 "register_operand" "")
16565 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16566 (match_operand:XF 2 "register_operand" "")
16567 (match_operand:XF 3 "register_operand" "")))]
16568 "TARGET_CMOVE"
16569 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16570
16571 (define_insn "*movxfcc_1"
16572 [(set (match_operand:XF 0 "register_operand" "=f,f")
16573 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16574 [(reg 17) (const_int 0)])
16575 (match_operand:XF 2 "register_operand" "f,0")
16576 (match_operand:XF 3 "register_operand" "0,f")))]
16577 "TARGET_CMOVE"
16578 "@
16579 fcmov%F1\t{%2, %0|%0, %2}
16580 fcmov%f1\t{%3, %0|%0, %3}"
16581 [(set_attr "type" "fcmov")
16582 (set_attr "mode" "XF")])
16583
16584 (define_expand "minsf3"
16585 [(parallel [
16586 (set (match_operand:SF 0 "register_operand" "")
16587 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16588 (match_operand:SF 2 "nonimmediate_operand" ""))
16589 (match_dup 1)
16590 (match_dup 2)))
16591 (clobber (reg:CC 17))])]
16592 "TARGET_SSE"
16593 "")
16594
16595 (define_insn "*minsf"
16596 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16597 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16598 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16599 (match_dup 1)
16600 (match_dup 2)))
16601 (clobber (reg:CC 17))]
16602 "TARGET_SSE && TARGET_IEEE_FP"
16603 "#")
16604
16605 (define_insn "*minsf_nonieee"
16606 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16607 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16608 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16609 (match_dup 1)
16610 (match_dup 2)))
16611 (clobber (reg:CC 17))]
16612 "TARGET_SSE && !TARGET_IEEE_FP
16613 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16614 "#")
16615
16616 (define_split
16617 [(set (match_operand:SF 0 "register_operand" "")
16618 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16619 (match_operand:SF 2 "nonimmediate_operand" ""))
16620 (match_operand:SF 3 "register_operand" "")
16621 (match_operand:SF 4 "nonimmediate_operand" "")))
16622 (clobber (reg:CC 17))]
16623 "SSE_REG_P (operands[0]) && reload_completed
16624 && ((operands_match_p (operands[1], operands[3])
16625 && operands_match_p (operands[2], operands[4]))
16626 || (operands_match_p (operands[1], operands[4])
16627 && operands_match_p (operands[2], operands[3])))"
16628 [(set (match_dup 0)
16629 (if_then_else:SF (lt (match_dup 1)
16630 (match_dup 2))
16631 (match_dup 1)
16632 (match_dup 2)))])
16633
16634 ;; Conditional addition patterns
16635 (define_expand "addqicc"
16636 [(match_operand:QI 0 "register_operand" "")
16637 (match_operand 1 "comparison_operator" "")
16638 (match_operand:QI 2 "register_operand" "")
16639 (match_operand:QI 3 "const_int_operand" "")]
16640 ""
16641 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16642
16643 (define_expand "addhicc"
16644 [(match_operand:HI 0 "register_operand" "")
16645 (match_operand 1 "comparison_operator" "")
16646 (match_operand:HI 2 "register_operand" "")
16647 (match_operand:HI 3 "const_int_operand" "")]
16648 ""
16649 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16650
16651 (define_expand "addsicc"
16652 [(match_operand:SI 0 "register_operand" "")
16653 (match_operand 1 "comparison_operator" "")
16654 (match_operand:SI 2 "register_operand" "")
16655 (match_operand:SI 3 "const_int_operand" "")]
16656 ""
16657 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16658
16659 (define_expand "adddicc"
16660 [(match_operand:DI 0 "register_operand" "")
16661 (match_operand 1 "comparison_operator" "")
16662 (match_operand:DI 2 "register_operand" "")
16663 (match_operand:DI 3 "const_int_operand" "")]
16664 "TARGET_64BIT"
16665 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16666
16667 ;; We can't represent the LT test directly. Do this by swapping the operands.
16668
16669 (define_split
16670 [(set (match_operand:SF 0 "fp_register_operand" "")
16671 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16672 (match_operand:SF 2 "register_operand" ""))
16673 (match_operand:SF 3 "register_operand" "")
16674 (match_operand:SF 4 "register_operand" "")))
16675 (clobber (reg:CC 17))]
16676 "reload_completed
16677 && ((operands_match_p (operands[1], operands[3])
16678 && operands_match_p (operands[2], operands[4]))
16679 || (operands_match_p (operands[1], operands[4])
16680 && operands_match_p (operands[2], operands[3])))"
16681 [(set (reg:CCFP 17)
16682 (compare:CCFP (match_dup 2)
16683 (match_dup 1)))
16684 (set (match_dup 0)
16685 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16686 (match_dup 1)
16687 (match_dup 2)))])
16688
16689 (define_insn "*minsf_sse"
16690 [(set (match_operand:SF 0 "register_operand" "=x")
16691 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16692 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16693 (match_dup 1)
16694 (match_dup 2)))]
16695 "TARGET_SSE && reload_completed"
16696 "minss\t{%2, %0|%0, %2}"
16697 [(set_attr "type" "sse")
16698 (set_attr "mode" "SF")])
16699
16700 (define_expand "mindf3"
16701 [(parallel [
16702 (set (match_operand:DF 0 "register_operand" "")
16703 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16704 (match_operand:DF 2 "nonimmediate_operand" ""))
16705 (match_dup 1)
16706 (match_dup 2)))
16707 (clobber (reg:CC 17))])]
16708 "TARGET_SSE2 && TARGET_SSE_MATH"
16709 "#")
16710
16711 (define_insn "*mindf"
16712 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16713 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16714 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16715 (match_dup 1)
16716 (match_dup 2)))
16717 (clobber (reg:CC 17))]
16718 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16719 "#")
16720
16721 (define_insn "*mindf_nonieee"
16722 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16723 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16724 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16725 (match_dup 1)
16726 (match_dup 2)))
16727 (clobber (reg:CC 17))]
16728 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16729 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16730 "#")
16731
16732 (define_split
16733 [(set (match_operand:DF 0 "register_operand" "")
16734 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16735 (match_operand:DF 2 "nonimmediate_operand" ""))
16736 (match_operand:DF 3 "register_operand" "")
16737 (match_operand:DF 4 "nonimmediate_operand" "")))
16738 (clobber (reg:CC 17))]
16739 "SSE_REG_P (operands[0]) && reload_completed
16740 && ((operands_match_p (operands[1], operands[3])
16741 && operands_match_p (operands[2], operands[4]))
16742 || (operands_match_p (operands[1], operands[4])
16743 && operands_match_p (operands[2], operands[3])))"
16744 [(set (match_dup 0)
16745 (if_then_else:DF (lt (match_dup 1)
16746 (match_dup 2))
16747 (match_dup 1)
16748 (match_dup 2)))])
16749
16750 ;; We can't represent the LT test directly. Do this by swapping the operands.
16751 (define_split
16752 [(set (match_operand:DF 0 "fp_register_operand" "")
16753 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16754 (match_operand:DF 2 "register_operand" ""))
16755 (match_operand:DF 3 "register_operand" "")
16756 (match_operand:DF 4 "register_operand" "")))
16757 (clobber (reg:CC 17))]
16758 "reload_completed
16759 && ((operands_match_p (operands[1], operands[3])
16760 && operands_match_p (operands[2], operands[4]))
16761 || (operands_match_p (operands[1], operands[4])
16762 && operands_match_p (operands[2], operands[3])))"
16763 [(set (reg:CCFP 17)
16764 (compare:CCFP (match_dup 2)
16765 (match_dup 1)))
16766 (set (match_dup 0)
16767 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16768 (match_dup 1)
16769 (match_dup 2)))])
16770
16771 (define_insn "*mindf_sse"
16772 [(set (match_operand:DF 0 "register_operand" "=Y")
16773 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16774 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16775 (match_dup 1)
16776 (match_dup 2)))]
16777 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16778 "minsd\t{%2, %0|%0, %2}"
16779 [(set_attr "type" "sse")
16780 (set_attr "mode" "DF")])
16781
16782 (define_expand "maxsf3"
16783 [(parallel [
16784 (set (match_operand:SF 0 "register_operand" "")
16785 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16786 (match_operand:SF 2 "nonimmediate_operand" ""))
16787 (match_dup 1)
16788 (match_dup 2)))
16789 (clobber (reg:CC 17))])]
16790 "TARGET_SSE"
16791 "#")
16792
16793 (define_insn "*maxsf"
16794 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16795 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16796 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16797 (match_dup 1)
16798 (match_dup 2)))
16799 (clobber (reg:CC 17))]
16800 "TARGET_SSE && TARGET_IEEE_FP"
16801 "#")
16802
16803 (define_insn "*maxsf_nonieee"
16804 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16805 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16806 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16807 (match_dup 1)
16808 (match_dup 2)))
16809 (clobber (reg:CC 17))]
16810 "TARGET_SSE && !TARGET_IEEE_FP
16811 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16812 "#")
16813
16814 (define_split
16815 [(set (match_operand:SF 0 "register_operand" "")
16816 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16817 (match_operand:SF 2 "nonimmediate_operand" ""))
16818 (match_operand:SF 3 "register_operand" "")
16819 (match_operand:SF 4 "nonimmediate_operand" "")))
16820 (clobber (reg:CC 17))]
16821 "SSE_REG_P (operands[0]) && reload_completed
16822 && ((operands_match_p (operands[1], operands[3])
16823 && operands_match_p (operands[2], operands[4]))
16824 || (operands_match_p (operands[1], operands[4])
16825 && operands_match_p (operands[2], operands[3])))"
16826 [(set (match_dup 0)
16827 (if_then_else:SF (gt (match_dup 1)
16828 (match_dup 2))
16829 (match_dup 1)
16830 (match_dup 2)))])
16831
16832 (define_split
16833 [(set (match_operand:SF 0 "fp_register_operand" "")
16834 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16835 (match_operand:SF 2 "register_operand" ""))
16836 (match_operand:SF 3 "register_operand" "")
16837 (match_operand:SF 4 "register_operand" "")))
16838 (clobber (reg:CC 17))]
16839 "reload_completed
16840 && ((operands_match_p (operands[1], operands[3])
16841 && operands_match_p (operands[2], operands[4]))
16842 || (operands_match_p (operands[1], operands[4])
16843 && operands_match_p (operands[2], operands[3])))"
16844 [(set (reg:CCFP 17)
16845 (compare:CCFP (match_dup 1)
16846 (match_dup 2)))
16847 (set (match_dup 0)
16848 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16849 (match_dup 1)
16850 (match_dup 2)))])
16851
16852 (define_insn "*maxsf_sse"
16853 [(set (match_operand:SF 0 "register_operand" "=x")
16854 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16855 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16856 (match_dup 1)
16857 (match_dup 2)))]
16858 "TARGET_SSE && reload_completed"
16859 "maxss\t{%2, %0|%0, %2}"
16860 [(set_attr "type" "sse")
16861 (set_attr "mode" "SF")])
16862
16863 (define_expand "maxdf3"
16864 [(parallel [
16865 (set (match_operand:DF 0 "register_operand" "")
16866 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16867 (match_operand:DF 2 "nonimmediate_operand" ""))
16868 (match_dup 1)
16869 (match_dup 2)))
16870 (clobber (reg:CC 17))])]
16871 "TARGET_SSE2 && TARGET_SSE_MATH"
16872 "#")
16873
16874 (define_insn "*maxdf"
16875 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16876 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16877 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16878 (match_dup 1)
16879 (match_dup 2)))
16880 (clobber (reg:CC 17))]
16881 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16882 "#")
16883
16884 (define_insn "*maxdf_nonieee"
16885 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16886 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16887 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16888 (match_dup 1)
16889 (match_dup 2)))
16890 (clobber (reg:CC 17))]
16891 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16892 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16893 "#")
16894
16895 (define_split
16896 [(set (match_operand:DF 0 "register_operand" "")
16897 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16898 (match_operand:DF 2 "nonimmediate_operand" ""))
16899 (match_operand:DF 3 "register_operand" "")
16900 (match_operand:DF 4 "nonimmediate_operand" "")))
16901 (clobber (reg:CC 17))]
16902 "SSE_REG_P (operands[0]) && reload_completed
16903 && ((operands_match_p (operands[1], operands[3])
16904 && operands_match_p (operands[2], operands[4]))
16905 || (operands_match_p (operands[1], operands[4])
16906 && operands_match_p (operands[2], operands[3])))"
16907 [(set (match_dup 0)
16908 (if_then_else:DF (gt (match_dup 1)
16909 (match_dup 2))
16910 (match_dup 1)
16911 (match_dup 2)))])
16912
16913 (define_split
16914 [(set (match_operand:DF 0 "fp_register_operand" "")
16915 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16916 (match_operand:DF 2 "register_operand" ""))
16917 (match_operand:DF 3 "register_operand" "")
16918 (match_operand:DF 4 "register_operand" "")))
16919 (clobber (reg:CC 17))]
16920 "reload_completed
16921 && ((operands_match_p (operands[1], operands[3])
16922 && operands_match_p (operands[2], operands[4]))
16923 || (operands_match_p (operands[1], operands[4])
16924 && operands_match_p (operands[2], operands[3])))"
16925 [(set (reg:CCFP 17)
16926 (compare:CCFP (match_dup 1)
16927 (match_dup 2)))
16928 (set (match_dup 0)
16929 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16930 (match_dup 1)
16931 (match_dup 2)))])
16932
16933 (define_insn "*maxdf_sse"
16934 [(set (match_operand:DF 0 "register_operand" "=Y")
16935 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16936 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16937 (match_dup 1)
16938 (match_dup 2)))]
16939 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16940 "maxsd\t{%2, %0|%0, %2}"
16941 [(set_attr "type" "sse")
16942 (set_attr "mode" "DF")])
16943 \f
16944 ;; Misc patterns (?)
16945
16946 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16947 ;; Otherwise there will be nothing to keep
16948 ;;
16949 ;; [(set (reg ebp) (reg esp))]
16950 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16951 ;; (clobber (eflags)]
16952 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16953 ;;
16954 ;; in proper program order.
16955 (define_insn "pro_epilogue_adjust_stack_1"
16956 [(set (match_operand:SI 0 "register_operand" "=r,r")
16957 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16958 (match_operand:SI 2 "immediate_operand" "i,i")))
16959 (clobber (reg:CC 17))
16960 (clobber (mem:BLK (scratch)))]
16961 "!TARGET_64BIT"
16962 {
16963 switch (get_attr_type (insn))
16964 {
16965 case TYPE_IMOV:
16966 return "mov{l}\t{%1, %0|%0, %1}";
16967
16968 case TYPE_ALU:
16969 if (GET_CODE (operands[2]) == CONST_INT
16970 && (INTVAL (operands[2]) == 128
16971 || (INTVAL (operands[2]) < 0
16972 && INTVAL (operands[2]) != -128)))
16973 {
16974 operands[2] = GEN_INT (-INTVAL (operands[2]));
16975 return "sub{l}\t{%2, %0|%0, %2}";
16976 }
16977 return "add{l}\t{%2, %0|%0, %2}";
16978
16979 case TYPE_LEA:
16980 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16981 return "lea{l}\t{%a2, %0|%0, %a2}";
16982
16983 default:
16984 abort ();
16985 }
16986 }
16987 [(set (attr "type")
16988 (cond [(eq_attr "alternative" "0")
16989 (const_string "alu")
16990 (match_operand:SI 2 "const0_operand" "")
16991 (const_string "imov")
16992 ]
16993 (const_string "lea")))
16994 (set_attr "mode" "SI")])
16995
16996 (define_insn "pro_epilogue_adjust_stack_rex64"
16997 [(set (match_operand:DI 0 "register_operand" "=r,r")
16998 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16999 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17000 (clobber (reg:CC 17))
17001 (clobber (mem:BLK (scratch)))]
17002 "TARGET_64BIT"
17003 {
17004 switch (get_attr_type (insn))
17005 {
17006 case TYPE_IMOV:
17007 return "mov{q}\t{%1, %0|%0, %1}";
17008
17009 case TYPE_ALU:
17010 if (GET_CODE (operands[2]) == CONST_INT
17011 /* Avoid overflows. */
17012 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17013 && (INTVAL (operands[2]) == 128
17014 || (INTVAL (operands[2]) < 0
17015 && INTVAL (operands[2]) != -128)))
17016 {
17017 operands[2] = GEN_INT (-INTVAL (operands[2]));
17018 return "sub{q}\t{%2, %0|%0, %2}";
17019 }
17020 return "add{q}\t{%2, %0|%0, %2}";
17021
17022 case TYPE_LEA:
17023 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17024 return "lea{q}\t{%a2, %0|%0, %a2}";
17025
17026 default:
17027 abort ();
17028 }
17029 }
17030 [(set (attr "type")
17031 (cond [(eq_attr "alternative" "0")
17032 (const_string "alu")
17033 (match_operand:DI 2 "const0_operand" "")
17034 (const_string "imov")
17035 ]
17036 (const_string "lea")))
17037 (set_attr "mode" "DI")])
17038
17039 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17040 [(set (match_operand:DI 0 "register_operand" "=r,r")
17041 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17042 (match_operand:DI 3 "immediate_operand" "i,i")))
17043 (use (match_operand:DI 2 "register_operand" "r,r"))
17044 (clobber (reg:CC 17))
17045 (clobber (mem:BLK (scratch)))]
17046 "TARGET_64BIT"
17047 {
17048 switch (get_attr_type (insn))
17049 {
17050 case TYPE_ALU:
17051 return "add{q}\t{%2, %0|%0, %2}";
17052
17053 case TYPE_LEA:
17054 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17055 return "lea{q}\t{%a2, %0|%0, %a2}";
17056
17057 default:
17058 abort ();
17059 }
17060 }
17061 [(set_attr "type" "alu,lea")
17062 (set_attr "mode" "DI")])
17063
17064 ;; Placeholder for the conditional moves. This one is split either to SSE
17065 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17066 ;; fact is that compares supported by the cmp??ss instructions are exactly
17067 ;; swapped of those supported by cmove sequence.
17068 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17069 ;; supported by i387 comparisons and we do need to emit two conditional moves
17070 ;; in tandem.
17071
17072 (define_insn "sse_movsfcc"
17073 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
17074 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17075 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
17076 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
17077 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
17078 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
17079 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17080 (clobber (reg:CC 17))]
17081 "TARGET_SSE
17082 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17083 /* Avoid combine from being smart and converting min/max
17084 instruction patterns into conditional moves. */
17085 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17086 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17087 || !rtx_equal_p (operands[4], operands[2])
17088 || !rtx_equal_p (operands[5], operands[3]))
17089 && (!TARGET_IEEE_FP
17090 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17091 "#")
17092
17093 (define_insn "sse_movsfcc_eq"
17094 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17095 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17096 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17097 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17098 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17099 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17100 (clobber (reg:CC 17))]
17101 "TARGET_SSE
17102 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17103 "#")
17104
17105 (define_insn "sse_movdfcc"
17106 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
17107 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17108 [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
17109 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
17110 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
17111 (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
17112 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17113 (clobber (reg:CC 17))]
17114 "TARGET_SSE2
17115 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17116 /* Avoid combine from being smart and converting min/max
17117 instruction patterns into conditional moves. */
17118 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17119 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17120 || !rtx_equal_p (operands[4], operands[2])
17121 || !rtx_equal_p (operands[5], operands[3]))
17122 && (!TARGET_IEEE_FP
17123 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17124 "#")
17125
17126 (define_insn "sse_movdfcc_eq"
17127 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17128 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17129 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17130 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17131 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17132 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17133 (clobber (reg:CC 17))]
17134 "TARGET_SSE
17135 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17136 "#")
17137
17138 ;; For non-sse moves just expand the usual cmove sequence.
17139 (define_split
17140 [(set (match_operand 0 "register_operand" "")
17141 (if_then_else (match_operator 1 "comparison_operator"
17142 [(match_operand 4 "nonimmediate_operand" "")
17143 (match_operand 5 "register_operand" "")])
17144 (match_operand 2 "nonimmediate_operand" "")
17145 (match_operand 3 "nonimmediate_operand" "")))
17146 (clobber (match_operand 6 "" ""))
17147 (clobber (reg:CC 17))]
17148 "!SSE_REG_P (operands[0]) && reload_completed
17149 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17150 [(const_int 0)]
17151 {
17152 ix86_compare_op0 = operands[5];
17153 ix86_compare_op1 = operands[4];
17154 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17155 VOIDmode, operands[5], operands[4]);
17156 ix86_expand_fp_movcc (operands);
17157 DONE;
17158 })
17159
17160 ;; Split SSE based conditional move into sequence:
17161 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17162 ;; and op2, op0 - zero op2 if comparison was false
17163 ;; nand op0, op3 - load op3 to op0 if comparison was false
17164 ;; or op2, op0 - get the nonzero one into the result.
17165 (define_split
17166 [(set (match_operand 0 "register_operand" "")
17167 (if_then_else (match_operator 1 "sse_comparison_operator"
17168 [(match_operand 4 "register_operand" "")
17169 (match_operand 5 "nonimmediate_operand" "")])
17170 (match_operand 2 "register_operand" "")
17171 (match_operand 3 "register_operand" "")))
17172 (clobber (match_operand 6 "" ""))
17173 (clobber (reg:CC 17))]
17174 "SSE_REG_P (operands[0]) && reload_completed"
17175 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17176 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17177 (subreg:TI (match_dup 4) 0)))
17178 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17179 (subreg:TI (match_dup 3) 0)))
17180 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17181 (subreg:TI (match_dup 7) 0)))]
17182 {
17183 if (GET_MODE (operands[2]) == DFmode
17184 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17185 {
17186 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17187 emit_insn (gen_sse2_unpcklpd (op, op, op));
17188 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17189 emit_insn (gen_sse2_unpcklpd (op, op, op));
17190 }
17191
17192 /* If op2 == op3, op3 would be clobbered before it is used. */
17193 if (operands_match_p (operands[2], operands[3]))
17194 {
17195 emit_move_insn (operands[0], operands[2]);
17196 DONE;
17197 }
17198
17199 PUT_MODE (operands[1], GET_MODE (operands[0]));
17200 if (operands_match_p (operands[0], operands[4]))
17201 operands[6] = operands[4], operands[7] = operands[2];
17202 else
17203 operands[6] = operands[2], operands[7] = operands[4];
17204 })
17205
17206 ;; Special case of conditional move we can handle effectively.
17207 ;; Do not brother with the integer/floating point case, since these are
17208 ;; bot considerably slower, unlike in the generic case.
17209 (define_insn "*sse_movsfcc_const0_1"
17210 [(set (match_operand:SF 0 "register_operand" "=&x")
17211 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17212 [(match_operand:SF 4 "register_operand" "0")
17213 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17214 (match_operand:SF 2 "register_operand" "x")
17215 (match_operand:SF 3 "const0_operand" "X")))]
17216 "TARGET_SSE"
17217 "#")
17218
17219 (define_insn "*sse_movsfcc_const0_2"
17220 [(set (match_operand:SF 0 "register_operand" "=&x")
17221 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17222 [(match_operand:SF 4 "register_operand" "0")
17223 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17224 (match_operand:SF 2 "const0_operand" "X")
17225 (match_operand:SF 3 "register_operand" "x")))]
17226 "TARGET_SSE"
17227 "#")
17228
17229 (define_insn "*sse_movsfcc_const0_3"
17230 [(set (match_operand:SF 0 "register_operand" "=&x")
17231 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17232 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17233 (match_operand:SF 5 "register_operand" "0")])
17234 (match_operand:SF 2 "register_operand" "x")
17235 (match_operand:SF 3 "const0_operand" "X")))]
17236 "TARGET_SSE"
17237 "#")
17238
17239 (define_insn "*sse_movsfcc_const0_4"
17240 [(set (match_operand:SF 0 "register_operand" "=&x")
17241 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17242 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17243 (match_operand:SF 5 "register_operand" "0")])
17244 (match_operand:SF 2 "const0_operand" "X")
17245 (match_operand:SF 3 "register_operand" "x")))]
17246 "TARGET_SSE"
17247 "#")
17248
17249 (define_insn "*sse_movdfcc_const0_1"
17250 [(set (match_operand:DF 0 "register_operand" "=&Y")
17251 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17252 [(match_operand:DF 4 "register_operand" "0")
17253 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17254 (match_operand:DF 2 "register_operand" "Y")
17255 (match_operand:DF 3 "const0_operand" "X")))]
17256 "TARGET_SSE2"
17257 "#")
17258
17259 (define_insn "*sse_movdfcc_const0_2"
17260 [(set (match_operand:DF 0 "register_operand" "=&Y")
17261 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17262 [(match_operand:DF 4 "register_operand" "0")
17263 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17264 (match_operand:DF 2 "const0_operand" "X")
17265 (match_operand:DF 3 "register_operand" "Y")))]
17266 "TARGET_SSE2"
17267 "#")
17268
17269 (define_insn "*sse_movdfcc_const0_3"
17270 [(set (match_operand:DF 0 "register_operand" "=&Y")
17271 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17272 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17273 (match_operand:DF 5 "register_operand" "0")])
17274 (match_operand:DF 2 "register_operand" "Y")
17275 (match_operand:DF 3 "const0_operand" "X")))]
17276 "TARGET_SSE2"
17277 "#")
17278
17279 (define_insn "*sse_movdfcc_const0_4"
17280 [(set (match_operand:DF 0 "register_operand" "=&Y")
17281 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17282 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17283 (match_operand:DF 5 "register_operand" "0")])
17284 (match_operand:DF 2 "const0_operand" "X")
17285 (match_operand:DF 3 "register_operand" "Y")))]
17286 "TARGET_SSE2"
17287 "#")
17288
17289 (define_split
17290 [(set (match_operand 0 "register_operand" "")
17291 (if_then_else (match_operator 1 "comparison_operator"
17292 [(match_operand 4 "nonimmediate_operand" "")
17293 (match_operand 5 "nonimmediate_operand" "")])
17294 (match_operand 2 "nonmemory_operand" "")
17295 (match_operand 3 "nonmemory_operand" "")))]
17296 "SSE_REG_P (operands[0]) && reload_completed
17297 && (const0_operand (operands[2], GET_MODE (operands[0]))
17298 || const0_operand (operands[3], GET_MODE (operands[0])))"
17299 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17300 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17301 (match_dup 7)))]
17302 {
17303 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17304 && GET_MODE (operands[2]) == DFmode)
17305 {
17306 if (REG_P (operands[2]))
17307 {
17308 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17309 emit_insn (gen_sse2_unpcklpd (op, op, op));
17310 }
17311 if (REG_P (operands[3]))
17312 {
17313 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17314 emit_insn (gen_sse2_unpcklpd (op, op, op));
17315 }
17316 }
17317 PUT_MODE (operands[1], GET_MODE (operands[0]));
17318 if (!sse_comparison_operator (operands[1], VOIDmode)
17319 || !rtx_equal_p (operands[0], operands[4]))
17320 {
17321 rtx tmp = operands[5];
17322 operands[5] = operands[4];
17323 operands[4] = tmp;
17324 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17325 }
17326 if (!rtx_equal_p (operands[0], operands[4]))
17327 abort ();
17328 if (const0_operand (operands[2], GET_MODE (operands[0])))
17329 {
17330 operands[7] = operands[3];
17331 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17332 0));
17333 }
17334 else
17335 {
17336 operands[7] = operands[2];
17337 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17338 }
17339 operands[7] = simplify_gen_subreg (TImode, operands[7],
17340 GET_MODE (operands[7]), 0);
17341 })
17342
17343 (define_expand "allocate_stack_worker"
17344 [(match_operand:SI 0 "register_operand" "")]
17345 "TARGET_STACK_PROBE"
17346 {
17347 if (reload_completed)
17348 {
17349 if (TARGET_64BIT)
17350 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17351 else
17352 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17353 }
17354 else
17355 {
17356 if (TARGET_64BIT)
17357 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17358 else
17359 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17360 }
17361 DONE;
17362 })
17363
17364 (define_insn "allocate_stack_worker_1"
17365 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17366 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17367 (clobber (match_scratch:SI 1 "=0"))
17368 (clobber (reg:CC 17))]
17369 "!TARGET_64BIT && TARGET_STACK_PROBE"
17370 "call\t__alloca"
17371 [(set_attr "type" "multi")
17372 (set_attr "length" "5")])
17373
17374 (define_expand "allocate_stack_worker_postreload"
17375 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17376 UNSPEC_STACK_PROBE)
17377 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17378 (clobber (match_dup 0))
17379 (clobber (reg:CC 17))])]
17380 ""
17381 "")
17382
17383 (define_insn "allocate_stack_worker_rex64"
17384 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17385 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17386 (clobber (match_scratch:DI 1 "=0"))
17387 (clobber (reg:CC 17))]
17388 "TARGET_64BIT && TARGET_STACK_PROBE"
17389 "call\t__alloca"
17390 [(set_attr "type" "multi")
17391 (set_attr "length" "5")])
17392
17393 (define_expand "allocate_stack_worker_rex64_postreload"
17394 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17395 UNSPEC_STACK_PROBE)
17396 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17397 (clobber (match_dup 0))
17398 (clobber (reg:CC 17))])]
17399 ""
17400 "")
17401
17402 (define_expand "allocate_stack"
17403 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17404 (minus:SI (reg:SI 7)
17405 (match_operand:SI 1 "general_operand" "")))
17406 (clobber (reg:CC 17))])
17407 (parallel [(set (reg:SI 7)
17408 (minus:SI (reg:SI 7) (match_dup 1)))
17409 (clobber (reg:CC 17))])]
17410 "TARGET_STACK_PROBE"
17411 {
17412 #ifdef CHECK_STACK_LIMIT
17413 if (GET_CODE (operands[1]) == CONST_INT
17414 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17415 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17416 operands[1]));
17417 else
17418 #endif
17419 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17420 operands[1])));
17421
17422 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17423 DONE;
17424 })
17425
17426 (define_expand "builtin_setjmp_receiver"
17427 [(label_ref (match_operand 0 "" ""))]
17428 "!TARGET_64BIT && flag_pic"
17429 {
17430 emit_insn (gen_set_got (pic_offset_table_rtx));
17431 DONE;
17432 })
17433 \f
17434 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17435
17436 (define_split
17437 [(set (match_operand 0 "register_operand" "")
17438 (match_operator 3 "promotable_binary_operator"
17439 [(match_operand 1 "register_operand" "")
17440 (match_operand 2 "aligned_operand" "")]))
17441 (clobber (reg:CC 17))]
17442 "! TARGET_PARTIAL_REG_STALL && reload_completed
17443 && ((GET_MODE (operands[0]) == HImode
17444 && ((!optimize_size && !TARGET_FAST_PREFIX)
17445 || GET_CODE (operands[2]) != CONST_INT
17446 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17447 || (GET_MODE (operands[0]) == QImode
17448 && (TARGET_PROMOTE_QImode || optimize_size)))"
17449 [(parallel [(set (match_dup 0)
17450 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17451 (clobber (reg:CC 17))])]
17452 "operands[0] = gen_lowpart (SImode, operands[0]);
17453 operands[1] = gen_lowpart (SImode, operands[1]);
17454 if (GET_CODE (operands[3]) != ASHIFT)
17455 operands[2] = gen_lowpart (SImode, operands[2]);
17456 PUT_MODE (operands[3], SImode);")
17457
17458 ; Promote the QImode tests, as i386 has encoding of the AND
17459 ; instruction with 32-bit sign-extended immediate and thus the
17460 ; instruction size is unchanged, except in the %eax case for
17461 ; which it is increased by one byte, hence the ! optimize_size.
17462 (define_split
17463 [(set (reg 17)
17464 (compare (and (match_operand 1 "aligned_operand" "")
17465 (match_operand 2 "const_int_operand" ""))
17466 (const_int 0)))
17467 (set (match_operand 0 "register_operand" "")
17468 (and (match_dup 1) (match_dup 2)))]
17469 "! TARGET_PARTIAL_REG_STALL && reload_completed
17470 /* Ensure that the operand will remain sign-extended immediate. */
17471 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17472 && ! optimize_size
17473 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17474 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17475 [(parallel [(set (reg:CCNO 17)
17476 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17477 (const_int 0)))
17478 (set (match_dup 0)
17479 (and:SI (match_dup 1) (match_dup 2)))])]
17480 "operands[2]
17481 = gen_int_mode (INTVAL (operands[2])
17482 & GET_MODE_MASK (GET_MODE (operands[0])),
17483 SImode);
17484 operands[0] = gen_lowpart (SImode, operands[0]);
17485 operands[1] = gen_lowpart (SImode, operands[1]);")
17486
17487 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17488 ; the TEST instruction with 32-bit sign-extended immediate and thus
17489 ; the instruction size would at least double, which is not what we
17490 ; want even with ! optimize_size.
17491 (define_split
17492 [(set (reg 17)
17493 (compare (and (match_operand:HI 0 "aligned_operand" "")
17494 (match_operand:HI 1 "const_int_operand" ""))
17495 (const_int 0)))]
17496 "! TARGET_PARTIAL_REG_STALL && reload_completed
17497 /* Ensure that the operand will remain sign-extended immediate. */
17498 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17499 && ! TARGET_FAST_PREFIX
17500 && ! optimize_size"
17501 [(set (reg:CCNO 17)
17502 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17503 (const_int 0)))]
17504 "operands[1]
17505 = gen_int_mode (INTVAL (operands[1])
17506 & GET_MODE_MASK (GET_MODE (operands[0])),
17507 SImode);
17508 operands[0] = gen_lowpart (SImode, operands[0]);")
17509
17510 (define_split
17511 [(set (match_operand 0 "register_operand" "")
17512 (neg (match_operand 1 "register_operand" "")))
17513 (clobber (reg:CC 17))]
17514 "! TARGET_PARTIAL_REG_STALL && reload_completed
17515 && (GET_MODE (operands[0]) == HImode
17516 || (GET_MODE (operands[0]) == QImode
17517 && (TARGET_PROMOTE_QImode || optimize_size)))"
17518 [(parallel [(set (match_dup 0)
17519 (neg:SI (match_dup 1)))
17520 (clobber (reg:CC 17))])]
17521 "operands[0] = gen_lowpart (SImode, operands[0]);
17522 operands[1] = gen_lowpart (SImode, operands[1]);")
17523
17524 (define_split
17525 [(set (match_operand 0 "register_operand" "")
17526 (not (match_operand 1 "register_operand" "")))]
17527 "! TARGET_PARTIAL_REG_STALL && reload_completed
17528 && (GET_MODE (operands[0]) == HImode
17529 || (GET_MODE (operands[0]) == QImode
17530 && (TARGET_PROMOTE_QImode || optimize_size)))"
17531 [(set (match_dup 0)
17532 (not:SI (match_dup 1)))]
17533 "operands[0] = gen_lowpart (SImode, operands[0]);
17534 operands[1] = gen_lowpart (SImode, operands[1]);")
17535
17536 (define_split
17537 [(set (match_operand 0 "register_operand" "")
17538 (if_then_else (match_operator 1 "comparison_operator"
17539 [(reg 17) (const_int 0)])
17540 (match_operand 2 "register_operand" "")
17541 (match_operand 3 "register_operand" "")))]
17542 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17543 && (GET_MODE (operands[0]) == HImode
17544 || (GET_MODE (operands[0]) == QImode
17545 && (TARGET_PROMOTE_QImode || optimize_size)))"
17546 [(set (match_dup 0)
17547 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17548 "operands[0] = gen_lowpart (SImode, operands[0]);
17549 operands[2] = gen_lowpart (SImode, operands[2]);
17550 operands[3] = gen_lowpart (SImode, operands[3]);")
17551
17552 \f
17553 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17554 ;; transform a complex memory operation into two memory to register operations.
17555
17556 ;; Don't push memory operands
17557 (define_peephole2
17558 [(set (match_operand:SI 0 "push_operand" "")
17559 (match_operand:SI 1 "memory_operand" ""))
17560 (match_scratch:SI 2 "r")]
17561 "! optimize_size && ! TARGET_PUSH_MEMORY"
17562 [(set (match_dup 2) (match_dup 1))
17563 (set (match_dup 0) (match_dup 2))]
17564 "")
17565
17566 (define_peephole2
17567 [(set (match_operand:DI 0 "push_operand" "")
17568 (match_operand:DI 1 "memory_operand" ""))
17569 (match_scratch:DI 2 "r")]
17570 "! optimize_size && ! TARGET_PUSH_MEMORY"
17571 [(set (match_dup 2) (match_dup 1))
17572 (set (match_dup 0) (match_dup 2))]
17573 "")
17574
17575 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17576 ;; SImode pushes.
17577 (define_peephole2
17578 [(set (match_operand:SF 0 "push_operand" "")
17579 (match_operand:SF 1 "memory_operand" ""))
17580 (match_scratch:SF 2 "r")]
17581 "! optimize_size && ! TARGET_PUSH_MEMORY"
17582 [(set (match_dup 2) (match_dup 1))
17583 (set (match_dup 0) (match_dup 2))]
17584 "")
17585
17586 (define_peephole2
17587 [(set (match_operand:HI 0 "push_operand" "")
17588 (match_operand:HI 1 "memory_operand" ""))
17589 (match_scratch:HI 2 "r")]
17590 "! optimize_size && ! TARGET_PUSH_MEMORY"
17591 [(set (match_dup 2) (match_dup 1))
17592 (set (match_dup 0) (match_dup 2))]
17593 "")
17594
17595 (define_peephole2
17596 [(set (match_operand:QI 0 "push_operand" "")
17597 (match_operand:QI 1 "memory_operand" ""))
17598 (match_scratch:QI 2 "q")]
17599 "! optimize_size && ! TARGET_PUSH_MEMORY"
17600 [(set (match_dup 2) (match_dup 1))
17601 (set (match_dup 0) (match_dup 2))]
17602 "")
17603
17604 ;; Don't move an immediate directly to memory when the instruction
17605 ;; gets too big.
17606 (define_peephole2
17607 [(match_scratch:SI 1 "r")
17608 (set (match_operand:SI 0 "memory_operand" "")
17609 (const_int 0))]
17610 "! optimize_size
17611 && ! TARGET_USE_MOV0
17612 && TARGET_SPLIT_LONG_MOVES
17613 && get_attr_length (insn) >= ix86_cost->large_insn
17614 && peep2_regno_dead_p (0, FLAGS_REG)"
17615 [(parallel [(set (match_dup 1) (const_int 0))
17616 (clobber (reg:CC 17))])
17617 (set (match_dup 0) (match_dup 1))]
17618 "")
17619
17620 (define_peephole2
17621 [(match_scratch:HI 1 "r")
17622 (set (match_operand:HI 0 "memory_operand" "")
17623 (const_int 0))]
17624 "! optimize_size
17625 && ! TARGET_USE_MOV0
17626 && TARGET_SPLIT_LONG_MOVES
17627 && get_attr_length (insn) >= ix86_cost->large_insn
17628 && peep2_regno_dead_p (0, FLAGS_REG)"
17629 [(parallel [(set (match_dup 2) (const_int 0))
17630 (clobber (reg:CC 17))])
17631 (set (match_dup 0) (match_dup 1))]
17632 "operands[2] = gen_lowpart (SImode, operands[1]);")
17633
17634 (define_peephole2
17635 [(match_scratch:QI 1 "q")
17636 (set (match_operand:QI 0 "memory_operand" "")
17637 (const_int 0))]
17638 "! optimize_size
17639 && ! TARGET_USE_MOV0
17640 && TARGET_SPLIT_LONG_MOVES
17641 && get_attr_length (insn) >= ix86_cost->large_insn
17642 && peep2_regno_dead_p (0, FLAGS_REG)"
17643 [(parallel [(set (match_dup 2) (const_int 0))
17644 (clobber (reg:CC 17))])
17645 (set (match_dup 0) (match_dup 1))]
17646 "operands[2] = gen_lowpart (SImode, operands[1]);")
17647
17648 (define_peephole2
17649 [(match_scratch:SI 2 "r")
17650 (set (match_operand:SI 0 "memory_operand" "")
17651 (match_operand:SI 1 "immediate_operand" ""))]
17652 "! optimize_size
17653 && get_attr_length (insn) >= ix86_cost->large_insn
17654 && TARGET_SPLIT_LONG_MOVES"
17655 [(set (match_dup 2) (match_dup 1))
17656 (set (match_dup 0) (match_dup 2))]
17657 "")
17658
17659 (define_peephole2
17660 [(match_scratch:HI 2 "r")
17661 (set (match_operand:HI 0 "memory_operand" "")
17662 (match_operand:HI 1 "immediate_operand" ""))]
17663 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17664 && TARGET_SPLIT_LONG_MOVES"
17665 [(set (match_dup 2) (match_dup 1))
17666 (set (match_dup 0) (match_dup 2))]
17667 "")
17668
17669 (define_peephole2
17670 [(match_scratch:QI 2 "q")
17671 (set (match_operand:QI 0 "memory_operand" "")
17672 (match_operand:QI 1 "immediate_operand" ""))]
17673 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17674 && TARGET_SPLIT_LONG_MOVES"
17675 [(set (match_dup 2) (match_dup 1))
17676 (set (match_dup 0) (match_dup 2))]
17677 "")
17678
17679 ;; Don't compare memory with zero, load and use a test instead.
17680 (define_peephole2
17681 [(set (reg 17)
17682 (compare (match_operand:SI 0 "memory_operand" "")
17683 (const_int 0)))
17684 (match_scratch:SI 3 "r")]
17685 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17686 [(set (match_dup 3) (match_dup 0))
17687 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17688 "")
17689
17690 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17691 ;; Don't split NOTs with a displacement operand, because resulting XOR
17692 ;; will not be pairable anyway.
17693 ;;
17694 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17695 ;; represented using a modRM byte. The XOR replacement is long decoded,
17696 ;; so this split helps here as well.
17697 ;;
17698 ;; Note: Can't do this as a regular split because we can't get proper
17699 ;; lifetime information then.
17700
17701 (define_peephole2
17702 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17703 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17704 "!optimize_size
17705 && peep2_regno_dead_p (0, FLAGS_REG)
17706 && ((TARGET_PENTIUM
17707 && (GET_CODE (operands[0]) != MEM
17708 || !memory_displacement_operand (operands[0], SImode)))
17709 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17710 [(parallel [(set (match_dup 0)
17711 (xor:SI (match_dup 1) (const_int -1)))
17712 (clobber (reg:CC 17))])]
17713 "")
17714
17715 (define_peephole2
17716 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17717 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17718 "!optimize_size
17719 && peep2_regno_dead_p (0, FLAGS_REG)
17720 && ((TARGET_PENTIUM
17721 && (GET_CODE (operands[0]) != MEM
17722 || !memory_displacement_operand (operands[0], HImode)))
17723 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17724 [(parallel [(set (match_dup 0)
17725 (xor:HI (match_dup 1) (const_int -1)))
17726 (clobber (reg:CC 17))])]
17727 "")
17728
17729 (define_peephole2
17730 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17731 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17732 "!optimize_size
17733 && peep2_regno_dead_p (0, FLAGS_REG)
17734 && ((TARGET_PENTIUM
17735 && (GET_CODE (operands[0]) != MEM
17736 || !memory_displacement_operand (operands[0], QImode)))
17737 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17738 [(parallel [(set (match_dup 0)
17739 (xor:QI (match_dup 1) (const_int -1)))
17740 (clobber (reg:CC 17))])]
17741 "")
17742
17743 ;; Non pairable "test imm, reg" instructions can be translated to
17744 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17745 ;; byte opcode instead of two, have a short form for byte operands),
17746 ;; so do it for other CPUs as well. Given that the value was dead,
17747 ;; this should not create any new dependencies. Pass on the sub-word
17748 ;; versions if we're concerned about partial register stalls.
17749
17750 (define_peephole2
17751 [(set (reg 17)
17752 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17753 (match_operand:SI 1 "immediate_operand" ""))
17754 (const_int 0)))]
17755 "ix86_match_ccmode (insn, CCNOmode)
17756 && (true_regnum (operands[0]) != 0
17757 || (GET_CODE (operands[1]) == CONST_INT
17758 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17759 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17760 [(parallel
17761 [(set (reg:CCNO 17)
17762 (compare:CCNO (and:SI (match_dup 0)
17763 (match_dup 1))
17764 (const_int 0)))
17765 (set (match_dup 0)
17766 (and:SI (match_dup 0) (match_dup 1)))])]
17767 "")
17768
17769 ;; We don't need to handle HImode case, because it will be promoted to SImode
17770 ;; on ! TARGET_PARTIAL_REG_STALL
17771
17772 (define_peephole2
17773 [(set (reg 17)
17774 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17775 (match_operand:QI 1 "immediate_operand" ""))
17776 (const_int 0)))]
17777 "! TARGET_PARTIAL_REG_STALL
17778 && ix86_match_ccmode (insn, CCNOmode)
17779 && true_regnum (operands[0]) != 0
17780 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17781 [(parallel
17782 [(set (reg:CCNO 17)
17783 (compare:CCNO (and:QI (match_dup 0)
17784 (match_dup 1))
17785 (const_int 0)))
17786 (set (match_dup 0)
17787 (and:QI (match_dup 0) (match_dup 1)))])]
17788 "")
17789
17790 (define_peephole2
17791 [(set (reg 17)
17792 (compare
17793 (and:SI
17794 (zero_extract:SI
17795 (match_operand 0 "ext_register_operand" "")
17796 (const_int 8)
17797 (const_int 8))
17798 (match_operand 1 "const_int_operand" ""))
17799 (const_int 0)))]
17800 "! TARGET_PARTIAL_REG_STALL
17801 && ix86_match_ccmode (insn, CCNOmode)
17802 && true_regnum (operands[0]) != 0
17803 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17804 [(parallel [(set (reg:CCNO 17)
17805 (compare:CCNO
17806 (and:SI
17807 (zero_extract:SI
17808 (match_dup 0)
17809 (const_int 8)
17810 (const_int 8))
17811 (match_dup 1))
17812 (const_int 0)))
17813 (set (zero_extract:SI (match_dup 0)
17814 (const_int 8)
17815 (const_int 8))
17816 (and:SI
17817 (zero_extract:SI
17818 (match_dup 0)
17819 (const_int 8)
17820 (const_int 8))
17821 (match_dup 1)))])]
17822 "")
17823
17824 ;; Don't do logical operations with memory inputs.
17825 (define_peephole2
17826 [(match_scratch:SI 2 "r")
17827 (parallel [(set (match_operand:SI 0 "register_operand" "")
17828 (match_operator:SI 3 "arith_or_logical_operator"
17829 [(match_dup 0)
17830 (match_operand:SI 1 "memory_operand" "")]))
17831 (clobber (reg:CC 17))])]
17832 "! optimize_size && ! TARGET_READ_MODIFY"
17833 [(set (match_dup 2) (match_dup 1))
17834 (parallel [(set (match_dup 0)
17835 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17836 (clobber (reg:CC 17))])]
17837 "")
17838
17839 (define_peephole2
17840 [(match_scratch:SI 2 "r")
17841 (parallel [(set (match_operand:SI 0 "register_operand" "")
17842 (match_operator:SI 3 "arith_or_logical_operator"
17843 [(match_operand:SI 1 "memory_operand" "")
17844 (match_dup 0)]))
17845 (clobber (reg:CC 17))])]
17846 "! optimize_size && ! TARGET_READ_MODIFY"
17847 [(set (match_dup 2) (match_dup 1))
17848 (parallel [(set (match_dup 0)
17849 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17850 (clobber (reg:CC 17))])]
17851 "")
17852
17853 ; Don't do logical operations with memory outputs
17854 ;
17855 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17856 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17857 ; the same decoder scheduling characteristics as the original.
17858
17859 (define_peephole2
17860 [(match_scratch:SI 2 "r")
17861 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17862 (match_operator:SI 3 "arith_or_logical_operator"
17863 [(match_dup 0)
17864 (match_operand:SI 1 "nonmemory_operand" "")]))
17865 (clobber (reg:CC 17))])]
17866 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17867 [(set (match_dup 2) (match_dup 0))
17868 (parallel [(set (match_dup 2)
17869 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17870 (clobber (reg:CC 17))])
17871 (set (match_dup 0) (match_dup 2))]
17872 "")
17873
17874 (define_peephole2
17875 [(match_scratch:SI 2 "r")
17876 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17877 (match_operator:SI 3 "arith_or_logical_operator"
17878 [(match_operand:SI 1 "nonmemory_operand" "")
17879 (match_dup 0)]))
17880 (clobber (reg:CC 17))])]
17881 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17882 [(set (match_dup 2) (match_dup 0))
17883 (parallel [(set (match_dup 2)
17884 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17885 (clobber (reg:CC 17))])
17886 (set (match_dup 0) (match_dup 2))]
17887 "")
17888
17889 ;; Attempt to always use XOR for zeroing registers.
17890 (define_peephole2
17891 [(set (match_operand 0 "register_operand" "")
17892 (const_int 0))]
17893 "(GET_MODE (operands[0]) == QImode
17894 || GET_MODE (operands[0]) == HImode
17895 || GET_MODE (operands[0]) == SImode
17896 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17897 && (! TARGET_USE_MOV0 || optimize_size)
17898 && peep2_regno_dead_p (0, FLAGS_REG)"
17899 [(parallel [(set (match_dup 0) (const_int 0))
17900 (clobber (reg:CC 17))])]
17901 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17902 operands[0]);")
17903
17904 (define_peephole2
17905 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17906 (const_int 0))]
17907 "(GET_MODE (operands[0]) == QImode
17908 || GET_MODE (operands[0]) == HImode)
17909 && (! TARGET_USE_MOV0 || optimize_size)
17910 && peep2_regno_dead_p (0, FLAGS_REG)"
17911 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17912 (clobber (reg:CC 17))])])
17913
17914 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17915 (define_peephole2
17916 [(set (match_operand 0 "register_operand" "")
17917 (const_int -1))]
17918 "(GET_MODE (operands[0]) == HImode
17919 || GET_MODE (operands[0]) == SImode
17920 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17921 && (optimize_size || TARGET_PENTIUM)
17922 && peep2_regno_dead_p (0, FLAGS_REG)"
17923 [(parallel [(set (match_dup 0) (const_int -1))
17924 (clobber (reg:CC 17))])]
17925 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17926 operands[0]);")
17927
17928 ;; Attempt to convert simple leas to adds. These can be created by
17929 ;; move expanders.
17930 (define_peephole2
17931 [(set (match_operand:SI 0 "register_operand" "")
17932 (plus:SI (match_dup 0)
17933 (match_operand:SI 1 "nonmemory_operand" "")))]
17934 "peep2_regno_dead_p (0, FLAGS_REG)"
17935 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17936 (clobber (reg:CC 17))])]
17937 "")
17938
17939 (define_peephole2
17940 [(set (match_operand:SI 0 "register_operand" "")
17941 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17942 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17943 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17944 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17945 (clobber (reg:CC 17))])]
17946 "operands[2] = gen_lowpart (SImode, operands[2]);")
17947
17948 (define_peephole2
17949 [(set (match_operand:DI 0 "register_operand" "")
17950 (plus:DI (match_dup 0)
17951 (match_operand:DI 1 "x86_64_general_operand" "")))]
17952 "peep2_regno_dead_p (0, FLAGS_REG)"
17953 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17954 (clobber (reg:CC 17))])]
17955 "")
17956
17957 (define_peephole2
17958 [(set (match_operand:SI 0 "register_operand" "")
17959 (mult:SI (match_dup 0)
17960 (match_operand:SI 1 "const_int_operand" "")))]
17961 "exact_log2 (INTVAL (operands[1])) >= 0
17962 && peep2_regno_dead_p (0, FLAGS_REG)"
17963 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17964 (clobber (reg:CC 17))])]
17965 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17966
17967 (define_peephole2
17968 [(set (match_operand:DI 0 "register_operand" "")
17969 (mult:DI (match_dup 0)
17970 (match_operand:DI 1 "const_int_operand" "")))]
17971 "exact_log2 (INTVAL (operands[1])) >= 0
17972 && peep2_regno_dead_p (0, FLAGS_REG)"
17973 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17974 (clobber (reg:CC 17))])]
17975 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17976
17977 (define_peephole2
17978 [(set (match_operand:SI 0 "register_operand" "")
17979 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17980 (match_operand:DI 2 "const_int_operand" "")) 0))]
17981 "exact_log2 (INTVAL (operands[2])) >= 0
17982 && REGNO (operands[0]) == REGNO (operands[1])
17983 && peep2_regno_dead_p (0, FLAGS_REG)"
17984 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17985 (clobber (reg:CC 17))])]
17986 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17987
17988 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17989 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17990 ;; many CPUs it is also faster, since special hardware to avoid esp
17991 ;; dependencies is present.
17992
17993 ;; While some of these conversions may be done using splitters, we use peepholes
17994 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17995
17996 ;; Convert prologue esp subtractions to push.
17997 ;; We need register to push. In order to keep verify_flow_info happy we have
17998 ;; two choices
17999 ;; - use scratch and clobber it in order to avoid dependencies
18000 ;; - use already live register
18001 ;; We can't use the second way right now, since there is no reliable way how to
18002 ;; verify that given register is live. First choice will also most likely in
18003 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18004 ;; call clobbered registers are dead. We may want to use base pointer as an
18005 ;; alternative when no register is available later.
18006
18007 (define_peephole2
18008 [(match_scratch:SI 0 "r")
18009 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18010 (clobber (reg:CC 17))
18011 (clobber (mem:BLK (scratch)))])]
18012 "optimize_size || !TARGET_SUB_ESP_4"
18013 [(clobber (match_dup 0))
18014 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18015 (clobber (mem:BLK (scratch)))])])
18016
18017 (define_peephole2
18018 [(match_scratch:SI 0 "r")
18019 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18020 (clobber (reg:CC 17))
18021 (clobber (mem:BLK (scratch)))])]
18022 "optimize_size || !TARGET_SUB_ESP_8"
18023 [(clobber (match_dup 0))
18024 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18025 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18026 (clobber (mem:BLK (scratch)))])])
18027
18028 ;; Convert esp subtractions to push.
18029 (define_peephole2
18030 [(match_scratch:SI 0 "r")
18031 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18032 (clobber (reg:CC 17))])]
18033 "optimize_size || !TARGET_SUB_ESP_4"
18034 [(clobber (match_dup 0))
18035 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18036
18037 (define_peephole2
18038 [(match_scratch:SI 0 "r")
18039 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18040 (clobber (reg:CC 17))])]
18041 "optimize_size || !TARGET_SUB_ESP_8"
18042 [(clobber (match_dup 0))
18043 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18044 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18045
18046 ;; Convert epilogue deallocator to pop.
18047 (define_peephole2
18048 [(match_scratch:SI 0 "r")
18049 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18050 (clobber (reg:CC 17))
18051 (clobber (mem:BLK (scratch)))])]
18052 "optimize_size || !TARGET_ADD_ESP_4"
18053 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18054 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18055 (clobber (mem:BLK (scratch)))])]
18056 "")
18057
18058 ;; Two pops case is tricky, since pop causes dependency on destination register.
18059 ;; We use two registers if available.
18060 (define_peephole2
18061 [(match_scratch:SI 0 "r")
18062 (match_scratch:SI 1 "r")
18063 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18064 (clobber (reg:CC 17))
18065 (clobber (mem:BLK (scratch)))])]
18066 "optimize_size || !TARGET_ADD_ESP_8"
18067 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18068 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18069 (clobber (mem:BLK (scratch)))])
18070 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18071 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18072 "")
18073
18074 (define_peephole2
18075 [(match_scratch:SI 0 "r")
18076 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18077 (clobber (reg:CC 17))
18078 (clobber (mem:BLK (scratch)))])]
18079 "optimize_size"
18080 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18081 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18082 (clobber (mem:BLK (scratch)))])
18083 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18084 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18085 "")
18086
18087 ;; Convert esp additions to pop.
18088 (define_peephole2
18089 [(match_scratch:SI 0 "r")
18090 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18091 (clobber (reg:CC 17))])]
18092 ""
18093 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18094 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18095 "")
18096
18097 ;; Two pops case is tricky, since pop causes dependency on destination register.
18098 ;; We use two registers if available.
18099 (define_peephole2
18100 [(match_scratch:SI 0 "r")
18101 (match_scratch:SI 1 "r")
18102 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18103 (clobber (reg:CC 17))])]
18104 ""
18105 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18106 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18107 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18108 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18109 "")
18110
18111 (define_peephole2
18112 [(match_scratch:SI 0 "r")
18113 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18114 (clobber (reg:CC 17))])]
18115 "optimize_size"
18116 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18117 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18118 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18119 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18120 "")
18121 \f
18122 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18123 ;; required and register dies.
18124 (define_peephole2
18125 [(set (reg 17)
18126 (compare (match_operand:SI 0 "register_operand" "")
18127 (match_operand:SI 1 "incdec_operand" "")))]
18128 "ix86_match_ccmode (insn, CCGCmode)
18129 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18130 [(parallel [(set (reg:CCGC 17)
18131 (compare:CCGC (match_dup 0)
18132 (match_dup 1)))
18133 (clobber (match_dup 0))])]
18134 "")
18135
18136 (define_peephole2
18137 [(set (reg 17)
18138 (compare (match_operand:HI 0 "register_operand" "")
18139 (match_operand:HI 1 "incdec_operand" "")))]
18140 "ix86_match_ccmode (insn, CCGCmode)
18141 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18142 [(parallel [(set (reg:CCGC 17)
18143 (compare:CCGC (match_dup 0)
18144 (match_dup 1)))
18145 (clobber (match_dup 0))])]
18146 "")
18147
18148 (define_peephole2
18149 [(set (reg 17)
18150 (compare (match_operand:QI 0 "register_operand" "")
18151 (match_operand:QI 1 "incdec_operand" "")))]
18152 "ix86_match_ccmode (insn, CCGCmode)
18153 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18154 [(parallel [(set (reg:CCGC 17)
18155 (compare:CCGC (match_dup 0)
18156 (match_dup 1)))
18157 (clobber (match_dup 0))])]
18158 "")
18159
18160 ;; Convert compares with 128 to shorter add -128
18161 (define_peephole2
18162 [(set (reg 17)
18163 (compare (match_operand:SI 0 "register_operand" "")
18164 (const_int 128)))]
18165 "ix86_match_ccmode (insn, CCGCmode)
18166 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18167 [(parallel [(set (reg:CCGC 17)
18168 (compare:CCGC (match_dup 0)
18169 (const_int 128)))
18170 (clobber (match_dup 0))])]
18171 "")
18172
18173 (define_peephole2
18174 [(set (reg 17)
18175 (compare (match_operand:HI 0 "register_operand" "")
18176 (const_int 128)))]
18177 "ix86_match_ccmode (insn, CCGCmode)
18178 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18179 [(parallel [(set (reg:CCGC 17)
18180 (compare:CCGC (match_dup 0)
18181 (const_int 128)))
18182 (clobber (match_dup 0))])]
18183 "")
18184 \f
18185 (define_peephole2
18186 [(match_scratch:DI 0 "r")
18187 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18188 (clobber (reg:CC 17))
18189 (clobber (mem:BLK (scratch)))])]
18190 "optimize_size || !TARGET_SUB_ESP_4"
18191 [(clobber (match_dup 0))
18192 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18193 (clobber (mem:BLK (scratch)))])])
18194
18195 (define_peephole2
18196 [(match_scratch:DI 0 "r")
18197 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18198 (clobber (reg:CC 17))
18199 (clobber (mem:BLK (scratch)))])]
18200 "optimize_size || !TARGET_SUB_ESP_8"
18201 [(clobber (match_dup 0))
18202 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18203 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18204 (clobber (mem:BLK (scratch)))])])
18205
18206 ;; Convert esp subtractions to push.
18207 (define_peephole2
18208 [(match_scratch:DI 0 "r")
18209 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18210 (clobber (reg:CC 17))])]
18211 "optimize_size || !TARGET_SUB_ESP_4"
18212 [(clobber (match_dup 0))
18213 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18214
18215 (define_peephole2
18216 [(match_scratch:DI 0 "r")
18217 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18218 (clobber (reg:CC 17))])]
18219 "optimize_size || !TARGET_SUB_ESP_8"
18220 [(clobber (match_dup 0))
18221 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18222 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18223
18224 ;; Convert epilogue deallocator to pop.
18225 (define_peephole2
18226 [(match_scratch:DI 0 "r")
18227 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18228 (clobber (reg:CC 17))
18229 (clobber (mem:BLK (scratch)))])]
18230 "optimize_size || !TARGET_ADD_ESP_4"
18231 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18232 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18233 (clobber (mem:BLK (scratch)))])]
18234 "")
18235
18236 ;; Two pops case is tricky, since pop causes dependency on destination register.
18237 ;; We use two registers if available.
18238 (define_peephole2
18239 [(match_scratch:DI 0 "r")
18240 (match_scratch:DI 1 "r")
18241 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18242 (clobber (reg:CC 17))
18243 (clobber (mem:BLK (scratch)))])]
18244 "optimize_size || !TARGET_ADD_ESP_8"
18245 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18246 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18247 (clobber (mem:BLK (scratch)))])
18248 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18249 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18250 "")
18251
18252 (define_peephole2
18253 [(match_scratch:DI 0 "r")
18254 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18255 (clobber (reg:CC 17))
18256 (clobber (mem:BLK (scratch)))])]
18257 "optimize_size"
18258 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18259 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18260 (clobber (mem:BLK (scratch)))])
18261 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18262 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18263 "")
18264
18265 ;; Convert esp additions to pop.
18266 (define_peephole2
18267 [(match_scratch:DI 0 "r")
18268 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18269 (clobber (reg:CC 17))])]
18270 ""
18271 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18272 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18273 "")
18274
18275 ;; Two pops case is tricky, since pop causes dependency on destination register.
18276 ;; We use two registers if available.
18277 (define_peephole2
18278 [(match_scratch:DI 0 "r")
18279 (match_scratch:DI 1 "r")
18280 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18281 (clobber (reg:CC 17))])]
18282 ""
18283 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18284 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18285 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18286 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18287 "")
18288
18289 (define_peephole2
18290 [(match_scratch:DI 0 "r")
18291 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18292 (clobber (reg:CC 17))])]
18293 "optimize_size"
18294 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18295 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18296 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18297 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18298 "")
18299 \f
18300 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18301 ;; imul $32bit_imm, reg, reg is direct decoded.
18302 (define_peephole2
18303 [(match_scratch:DI 3 "r")
18304 (parallel [(set (match_operand:DI 0 "register_operand" "")
18305 (mult:DI (match_operand:DI 1 "memory_operand" "")
18306 (match_operand:DI 2 "immediate_operand" "")))
18307 (clobber (reg:CC 17))])]
18308 "TARGET_K8 && !optimize_size
18309 && (GET_CODE (operands[2]) != CONST_INT
18310 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18311 [(set (match_dup 3) (match_dup 1))
18312 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18313 (clobber (reg:CC 17))])]
18314 "")
18315
18316 (define_peephole2
18317 [(match_scratch:SI 3 "r")
18318 (parallel [(set (match_operand:SI 0 "register_operand" "")
18319 (mult:SI (match_operand:SI 1 "memory_operand" "")
18320 (match_operand:SI 2 "immediate_operand" "")))
18321 (clobber (reg:CC 17))])]
18322 "TARGET_K8 && !optimize_size
18323 && (GET_CODE (operands[2]) != CONST_INT
18324 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18325 [(set (match_dup 3) (match_dup 1))
18326 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18327 (clobber (reg:CC 17))])]
18328 "")
18329
18330 (define_peephole2
18331 [(match_scratch:SI 3 "r")
18332 (parallel [(set (match_operand:DI 0 "register_operand" "")
18333 (zero_extend:DI
18334 (mult:SI (match_operand:SI 1 "memory_operand" "")
18335 (match_operand:SI 2 "immediate_operand" ""))))
18336 (clobber (reg:CC 17))])]
18337 "TARGET_K8 && !optimize_size
18338 && (GET_CODE (operands[2]) != CONST_INT
18339 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18340 [(set (match_dup 3) (match_dup 1))
18341 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18342 (clobber (reg:CC 17))])]
18343 "")
18344
18345 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18346 ;; Convert it into imul reg, reg
18347 ;; It would be better to force assembler to encode instruction using long
18348 ;; immediate, but there is apparently no way to do so.
18349 (define_peephole2
18350 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18351 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18352 (match_operand:DI 2 "const_int_operand" "")))
18353 (clobber (reg:CC 17))])
18354 (match_scratch:DI 3 "r")]
18355 "TARGET_K8 && !optimize_size
18356 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18357 [(set (match_dup 3) (match_dup 2))
18358 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18359 (clobber (reg:CC 17))])]
18360 {
18361 if (!rtx_equal_p (operands[0], operands[1]))
18362 emit_move_insn (operands[0], operands[1]);
18363 })
18364
18365 (define_peephole2
18366 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18367 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18368 (match_operand:SI 2 "const_int_operand" "")))
18369 (clobber (reg:CC 17))])
18370 (match_scratch:SI 3 "r")]
18371 "TARGET_K8 && !optimize_size
18372 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18373 [(set (match_dup 3) (match_dup 2))
18374 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18375 (clobber (reg:CC 17))])]
18376 {
18377 if (!rtx_equal_p (operands[0], operands[1]))
18378 emit_move_insn (operands[0], operands[1]);
18379 })
18380
18381 (define_peephole2
18382 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18383 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18384 (match_operand:HI 2 "immediate_operand" "")))
18385 (clobber (reg:CC 17))])
18386 (match_scratch:HI 3 "r")]
18387 "TARGET_K8 && !optimize_size"
18388 [(set (match_dup 3) (match_dup 2))
18389 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18390 (clobber (reg:CC 17))])]
18391 {
18392 if (!rtx_equal_p (operands[0], operands[1]))
18393 emit_move_insn (operands[0], operands[1]);
18394 })
18395 \f
18396 ;; Call-value patterns last so that the wildcard operand does not
18397 ;; disrupt insn-recog's switch tables.
18398
18399 (define_insn "*call_value_pop_0"
18400 [(set (match_operand 0 "" "")
18401 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18402 (match_operand:SI 2 "" "")))
18403 (set (reg:SI 7) (plus:SI (reg:SI 7)
18404 (match_operand:SI 3 "immediate_operand" "")))]
18405 "!TARGET_64BIT"
18406 {
18407 if (SIBLING_CALL_P (insn))
18408 return "jmp\t%P1";
18409 else
18410 return "call\t%P1";
18411 }
18412 [(set_attr "type" "callv")])
18413
18414 (define_insn "*call_value_pop_1"
18415 [(set (match_operand 0 "" "")
18416 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18417 (match_operand:SI 2 "" "")))
18418 (set (reg:SI 7) (plus:SI (reg:SI 7)
18419 (match_operand:SI 3 "immediate_operand" "i")))]
18420 "!TARGET_64BIT"
18421 {
18422 if (constant_call_address_operand (operands[1], QImode))
18423 {
18424 if (SIBLING_CALL_P (insn))
18425 return "jmp\t%P1";
18426 else
18427 return "call\t%P1";
18428 }
18429 if (SIBLING_CALL_P (insn))
18430 return "jmp\t%A1";
18431 else
18432 return "call\t%A1";
18433 }
18434 [(set_attr "type" "callv")])
18435
18436 (define_insn "*call_value_0"
18437 [(set (match_operand 0 "" "")
18438 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18439 (match_operand:SI 2 "" "")))]
18440 "!TARGET_64BIT"
18441 {
18442 if (SIBLING_CALL_P (insn))
18443 return "jmp\t%P1";
18444 else
18445 return "call\t%P1";
18446 }
18447 [(set_attr "type" "callv")])
18448
18449 (define_insn "*call_value_0_rex64"
18450 [(set (match_operand 0 "" "")
18451 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18452 (match_operand:DI 2 "const_int_operand" "")))]
18453 "TARGET_64BIT"
18454 {
18455 if (SIBLING_CALL_P (insn))
18456 return "jmp\t%P1";
18457 else
18458 return "call\t%P1";
18459 }
18460 [(set_attr "type" "callv")])
18461
18462 (define_insn "*call_value_1"
18463 [(set (match_operand 0 "" "")
18464 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18465 (match_operand:SI 2 "" "")))]
18466 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18467 {
18468 if (constant_call_address_operand (operands[1], QImode))
18469 return "call\t%P1";
18470 return "call\t%*%1";
18471 }
18472 [(set_attr "type" "callv")])
18473
18474 (define_insn "*sibcall_value_1"
18475 [(set (match_operand 0 "" "")
18476 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18477 (match_operand:SI 2 "" "")))]
18478 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18479 {
18480 if (constant_call_address_operand (operands[1], QImode))
18481 return "jmp\t%P1";
18482 return "jmp\t%*%1";
18483 }
18484 [(set_attr "type" "callv")])
18485
18486 (define_insn "*call_value_1_rex64"
18487 [(set (match_operand 0 "" "")
18488 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18489 (match_operand:DI 2 "" "")))]
18490 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18491 {
18492 if (constant_call_address_operand (operands[1], QImode))
18493 return "call\t%P1";
18494 return "call\t%A1";
18495 }
18496 [(set_attr "type" "callv")])
18497
18498 (define_insn "*sibcall_value_1_rex64"
18499 [(set (match_operand 0 "" "")
18500 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18501 (match_operand:DI 2 "" "")))]
18502 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18503 "jmp\t%P1"
18504 [(set_attr "type" "callv")])
18505
18506 (define_insn "*sibcall_value_1_rex64_v"
18507 [(set (match_operand 0 "" "")
18508 (call (mem:QI (reg:DI 40))
18509 (match_operand:DI 1 "" "")))]
18510 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18511 "jmp\t*%%r11"
18512 [(set_attr "type" "callv")])
18513 \f
18514 (define_insn "trap"
18515 [(trap_if (const_int 1) (const_int 5))]
18516 ""
18517 "int\t$5")
18518
18519 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18520 ;;; for the sake of bounds checking. By emitting bounds checks as
18521 ;;; conditional traps rather than as conditional jumps around
18522 ;;; unconditional traps we avoid introducing spurious basic-block
18523 ;;; boundaries and facilitate elimination of redundant checks. In
18524 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18525 ;;; interrupt 5.
18526 ;;;
18527 ;;; FIXME: Static branch prediction rules for ix86 are such that
18528 ;;; forward conditional branches predict as untaken. As implemented
18529 ;;; below, pseudo conditional traps violate that rule. We should use
18530 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18531 ;;; section loaded at the end of the text segment and branch forward
18532 ;;; there on bounds-failure, and then jump back immediately (in case
18533 ;;; the system chooses to ignore bounds violations, or to report
18534 ;;; violations and continue execution).
18535
18536 (define_expand "conditional_trap"
18537 [(trap_if (match_operator 0 "comparison_operator"
18538 [(match_dup 2) (const_int 0)])
18539 (match_operand 1 "const_int_operand" ""))]
18540 ""
18541 {
18542 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18543 ix86_expand_compare (GET_CODE (operands[0]),
18544 NULL, NULL),
18545 operands[1]));
18546 DONE;
18547 })
18548
18549 (define_insn "*conditional_trap_1"
18550 [(trap_if (match_operator 0 "comparison_operator"
18551 [(reg 17) (const_int 0)])
18552 (match_operand 1 "const_int_operand" ""))]
18553 ""
18554 {
18555 operands[2] = gen_label_rtx ();
18556 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18557 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18558 CODE_LABEL_NUMBER (operands[2]));
18559 RET;
18560 })
18561
18562 ;; Pentium III SIMD instructions.
18563
18564 ;; Moves for SSE/MMX regs.
18565
18566 (define_insn "movv4sf_internal"
18567 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18568 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18569 "TARGET_SSE"
18570 "@
18571 xorps\t%0, %0
18572 movaps\t{%1, %0|%0, %1}
18573 movaps\t{%1, %0|%0, %1}"
18574 [(set_attr "type" "ssemov")
18575 (set_attr "mode" "V4SF")])
18576
18577 (define_split
18578 [(set (match_operand:V4SF 0 "register_operand" "")
18579 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18580 "TARGET_SSE"
18581 [(set (match_dup 0)
18582 (vec_merge:V4SF
18583 (vec_duplicate:V4SF (match_dup 1))
18584 (match_dup 2)
18585 (const_int 1)))]
18586 {
18587 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18588 operands[2] = CONST0_RTX (V4SFmode);
18589 })
18590
18591 (define_insn "movv4si_internal"
18592 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18593 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18594 "TARGET_SSE"
18595 {
18596 switch (which_alternative)
18597 {
18598 case 0:
18599 if (get_attr_mode (insn) == MODE_V4SF)
18600 return "xorps\t%0, %0";
18601 else
18602 return "pxor\t%0, %0";
18603 case 1:
18604 case 2:
18605 if (get_attr_mode (insn) == MODE_V4SF)
18606 return "movaps\t{%1, %0|%0, %1}";
18607 else
18608 return "movdqa\t{%1, %0|%0, %1}";
18609 default:
18610 abort ();
18611 }
18612 }
18613 [(set_attr "type" "ssemov")
18614 (set (attr "mode")
18615 (cond [(eq_attr "alternative" "0,1")
18616 (if_then_else
18617 (ne (symbol_ref "optimize_size")
18618 (const_int 0))
18619 (const_string "V4SF")
18620 (const_string "TI"))
18621 (eq_attr "alternative" "2")
18622 (if_then_else
18623 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18624 (const_int 0))
18625 (ne (symbol_ref "optimize_size")
18626 (const_int 0)))
18627 (const_string "V4SF")
18628 (const_string "TI"))]
18629 (const_string "TI")))])
18630
18631 (define_insn "movv2di_internal"
18632 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18633 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18634 "TARGET_SSE2"
18635 {
18636 switch (which_alternative)
18637 {
18638 case 0:
18639 if (get_attr_mode (insn) == MODE_V4SF)
18640 return "xorps\t%0, %0";
18641 else
18642 return "pxor\t%0, %0";
18643 case 1:
18644 case 2:
18645 if (get_attr_mode (insn) == MODE_V4SF)
18646 return "movaps\t{%1, %0|%0, %1}";
18647 else
18648 return "movdqa\t{%1, %0|%0, %1}";
18649 default:
18650 abort ();
18651 }
18652 }
18653 [(set_attr "type" "ssemov")
18654 (set (attr "mode")
18655 (cond [(eq_attr "alternative" "0,1")
18656 (if_then_else
18657 (ne (symbol_ref "optimize_size")
18658 (const_int 0))
18659 (const_string "V4SF")
18660 (const_string "TI"))
18661 (eq_attr "alternative" "2")
18662 (if_then_else
18663 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18664 (const_int 0))
18665 (ne (symbol_ref "optimize_size")
18666 (const_int 0)))
18667 (const_string "V4SF")
18668 (const_string "TI"))]
18669 (const_string "TI")))])
18670
18671 (define_split
18672 [(set (match_operand:V2DF 0 "register_operand" "")
18673 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18674 "TARGET_SSE2"
18675 [(set (match_dup 0)
18676 (vec_merge:V2DF
18677 (vec_duplicate:V2DF (match_dup 1))
18678 (match_dup 2)
18679 (const_int 1)))]
18680 {
18681 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18682 operands[2] = CONST0_RTX (V2DFmode);
18683 })
18684
18685 (define_insn "movv8qi_internal"
18686 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18687 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18688 "TARGET_MMX
18689 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18690 "@
18691 pxor\t%0, %0
18692 movq\t{%1, %0|%0, %1}
18693 movq\t{%1, %0|%0, %1}"
18694 [(set_attr "type" "mmxmov")
18695 (set_attr "mode" "DI")])
18696
18697 (define_insn "movv4hi_internal"
18698 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18699 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18700 "TARGET_MMX
18701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18702 "@
18703 pxor\t%0, %0
18704 movq\t{%1, %0|%0, %1}
18705 movq\t{%1, %0|%0, %1}"
18706 [(set_attr "type" "mmxmov")
18707 (set_attr "mode" "DI")])
18708
18709 (define_insn "movv2si_internal"
18710 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18711 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18712 "TARGET_MMX
18713 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18714 "@
18715 pxor\t%0, %0
18716 movq\t{%1, %0|%0, %1}
18717 movq\t{%1, %0|%0, %1}"
18718 [(set_attr "type" "mmxcvt")
18719 (set_attr "mode" "DI")])
18720
18721 (define_insn "movv2sf_internal"
18722 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18723 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18724 "TARGET_3DNOW
18725 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18726 "@
18727 pxor\t%0, %0
18728 movq\t{%1, %0|%0, %1}
18729 movq\t{%1, %0|%0, %1}"
18730 [(set_attr "type" "mmxcvt")
18731 (set_attr "mode" "DI")])
18732
18733 (define_expand "movti"
18734 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18735 (match_operand:TI 1 "nonimmediate_operand" ""))]
18736 "TARGET_SSE || TARGET_64BIT"
18737 {
18738 if (TARGET_64BIT)
18739 ix86_expand_move (TImode, operands);
18740 else
18741 ix86_expand_vector_move (TImode, operands);
18742 DONE;
18743 })
18744
18745 (define_expand "movtf"
18746 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18747 (match_operand:TF 1 "nonimmediate_operand" ""))]
18748 "TARGET_64BIT"
18749 {
18750 if (TARGET_64BIT)
18751 ix86_expand_move (TFmode, operands);
18752 else
18753 ix86_expand_vector_move (TFmode, operands);
18754 DONE;
18755 })
18756
18757 (define_insn "movv2df_internal"
18758 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18759 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18760 "TARGET_SSE2
18761 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18762 {
18763 switch (which_alternative)
18764 {
18765 case 0:
18766 if (get_attr_mode (insn) == MODE_V4SF)
18767 return "xorps\t%0, %0";
18768 else
18769 return "xorpd\t%0, %0";
18770 case 1:
18771 case 2:
18772 if (get_attr_mode (insn) == MODE_V4SF)
18773 return "movaps\t{%1, %0|%0, %1}";
18774 else
18775 return "movapd\t{%1, %0|%0, %1}";
18776 default:
18777 abort ();
18778 }
18779 }
18780 [(set_attr "type" "ssemov")
18781 (set (attr "mode")
18782 (cond [(eq_attr "alternative" "0,1")
18783 (if_then_else
18784 (ne (symbol_ref "optimize_size")
18785 (const_int 0))
18786 (const_string "V4SF")
18787 (const_string "V2DF"))
18788 (eq_attr "alternative" "2")
18789 (if_then_else
18790 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18791 (const_int 0))
18792 (ne (symbol_ref "optimize_size")
18793 (const_int 0)))
18794 (const_string "V4SF")
18795 (const_string "V2DF"))]
18796 (const_string "V2DF")))])
18797
18798 (define_insn "movv8hi_internal"
18799 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18800 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18801 "TARGET_SSE2
18802 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18803 {
18804 switch (which_alternative)
18805 {
18806 case 0:
18807 if (get_attr_mode (insn) == MODE_V4SF)
18808 return "xorps\t%0, %0";
18809 else
18810 return "pxor\t%0, %0";
18811 case 1:
18812 case 2:
18813 if (get_attr_mode (insn) == MODE_V4SF)
18814 return "movaps\t{%1, %0|%0, %1}";
18815 else
18816 return "movdqa\t{%1, %0|%0, %1}";
18817 default:
18818 abort ();
18819 }
18820 }
18821 [(set_attr "type" "ssemov")
18822 (set (attr "mode")
18823 (cond [(eq_attr "alternative" "0,1")
18824 (if_then_else
18825 (ne (symbol_ref "optimize_size")
18826 (const_int 0))
18827 (const_string "V4SF")
18828 (const_string "TI"))
18829 (eq_attr "alternative" "2")
18830 (if_then_else
18831 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18832 (const_int 0))
18833 (ne (symbol_ref "optimize_size")
18834 (const_int 0)))
18835 (const_string "V4SF")
18836 (const_string "TI"))]
18837 (const_string "TI")))])
18838
18839 (define_insn "movv16qi_internal"
18840 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18841 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18842 "TARGET_SSE2
18843 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18844 {
18845 switch (which_alternative)
18846 {
18847 case 0:
18848 if (get_attr_mode (insn) == MODE_V4SF)
18849 return "xorps\t%0, %0";
18850 else
18851 return "pxor\t%0, %0";
18852 case 1:
18853 case 2:
18854 if (get_attr_mode (insn) == MODE_V4SF)
18855 return "movaps\t{%1, %0|%0, %1}";
18856 else
18857 return "movdqa\t{%1, %0|%0, %1}";
18858 default:
18859 abort ();
18860 }
18861 }
18862 [(set_attr "type" "ssemov")
18863 (set (attr "mode")
18864 (cond [(eq_attr "alternative" "0,1")
18865 (if_then_else
18866 (ne (symbol_ref "optimize_size")
18867 (const_int 0))
18868 (const_string "V4SF")
18869 (const_string "TI"))
18870 (eq_attr "alternative" "2")
18871 (if_then_else
18872 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18873 (const_int 0))
18874 (ne (symbol_ref "optimize_size")
18875 (const_int 0)))
18876 (const_string "V4SF")
18877 (const_string "TI"))]
18878 (const_string "TI")))])
18879
18880 (define_expand "movv2df"
18881 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18882 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18883 "TARGET_SSE2"
18884 {
18885 ix86_expand_vector_move (V2DFmode, operands);
18886 DONE;
18887 })
18888
18889 (define_expand "movv8hi"
18890 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18891 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18892 "TARGET_SSE2"
18893 {
18894 ix86_expand_vector_move (V8HImode, operands);
18895 DONE;
18896 })
18897
18898 (define_expand "movv16qi"
18899 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18900 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18901 "TARGET_SSE2"
18902 {
18903 ix86_expand_vector_move (V16QImode, operands);
18904 DONE;
18905 })
18906
18907 (define_expand "movv4sf"
18908 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18909 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18910 "TARGET_SSE"
18911 {
18912 ix86_expand_vector_move (V4SFmode, operands);
18913 DONE;
18914 })
18915
18916 (define_expand "movv4si"
18917 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18918 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18919 "TARGET_SSE"
18920 {
18921 ix86_expand_vector_move (V4SImode, operands);
18922 DONE;
18923 })
18924
18925 (define_expand "movv2di"
18926 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18927 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18928 "TARGET_SSE"
18929 {
18930 ix86_expand_vector_move (V2DImode, operands);
18931 DONE;
18932 })
18933
18934 (define_expand "movv2si"
18935 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18936 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18937 "TARGET_MMX"
18938 {
18939 ix86_expand_vector_move (V2SImode, operands);
18940 DONE;
18941 })
18942
18943 (define_expand "movv4hi"
18944 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18945 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18946 "TARGET_MMX"
18947 {
18948 ix86_expand_vector_move (V4HImode, operands);
18949 DONE;
18950 })
18951
18952 (define_expand "movv8qi"
18953 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18954 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18955 "TARGET_MMX"
18956 {
18957 ix86_expand_vector_move (V8QImode, operands);
18958 DONE;
18959 })
18960
18961 (define_expand "movv2sf"
18962 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18963 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18964 "TARGET_3DNOW"
18965 {
18966 ix86_expand_vector_move (V2SFmode, operands);
18967 DONE;
18968 })
18969
18970 (define_insn "*pushti"
18971 [(set (match_operand:TI 0 "push_operand" "=<")
18972 (match_operand:TI 1 "register_operand" "x"))]
18973 "TARGET_SSE"
18974 "#")
18975
18976 (define_insn "*pushv2df"
18977 [(set (match_operand:V2DF 0 "push_operand" "=<")
18978 (match_operand:V2DF 1 "register_operand" "x"))]
18979 "TARGET_SSE"
18980 "#")
18981
18982 (define_insn "*pushv2di"
18983 [(set (match_operand:V2DI 0 "push_operand" "=<")
18984 (match_operand:V2DI 1 "register_operand" "x"))]
18985 "TARGET_SSE2"
18986 "#")
18987
18988 (define_insn "*pushv8hi"
18989 [(set (match_operand:V8HI 0 "push_operand" "=<")
18990 (match_operand:V8HI 1 "register_operand" "x"))]
18991 "TARGET_SSE2"
18992 "#")
18993
18994 (define_insn "*pushv16qi"
18995 [(set (match_operand:V16QI 0 "push_operand" "=<")
18996 (match_operand:V16QI 1 "register_operand" "x"))]
18997 "TARGET_SSE2"
18998 "#")
18999
19000 (define_insn "*pushv4sf"
19001 [(set (match_operand:V4SF 0 "push_operand" "=<")
19002 (match_operand:V4SF 1 "register_operand" "x"))]
19003 "TARGET_SSE"
19004 "#")
19005
19006 (define_insn "*pushv4si"
19007 [(set (match_operand:V4SI 0 "push_operand" "=<")
19008 (match_operand:V4SI 1 "register_operand" "x"))]
19009 "TARGET_SSE2"
19010 "#")
19011
19012 (define_insn "*pushv2si"
19013 [(set (match_operand:V2SI 0 "push_operand" "=<")
19014 (match_operand:V2SI 1 "register_operand" "y"))]
19015 "TARGET_MMX"
19016 "#")
19017
19018 (define_insn "*pushv4hi"
19019 [(set (match_operand:V4HI 0 "push_operand" "=<")
19020 (match_operand:V4HI 1 "register_operand" "y"))]
19021 "TARGET_MMX"
19022 "#")
19023
19024 (define_insn "*pushv8qi"
19025 [(set (match_operand:V8QI 0 "push_operand" "=<")
19026 (match_operand:V8QI 1 "register_operand" "y"))]
19027 "TARGET_MMX"
19028 "#")
19029
19030 (define_insn "*pushv2sf"
19031 [(set (match_operand:V2SF 0 "push_operand" "=<")
19032 (match_operand:V2SF 1 "register_operand" "y"))]
19033 "TARGET_3DNOW"
19034 "#")
19035
19036 (define_split
19037 [(set (match_operand 0 "push_operand" "")
19038 (match_operand 1 "register_operand" ""))]
19039 "!TARGET_64BIT && reload_completed
19040 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19041 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19042 (set (match_dup 2) (match_dup 1))]
19043 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19044 stack_pointer_rtx);
19045 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19046
19047 (define_split
19048 [(set (match_operand 0 "push_operand" "")
19049 (match_operand 1 "register_operand" ""))]
19050 "TARGET_64BIT && reload_completed
19051 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19052 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19053 (set (match_dup 2) (match_dup 1))]
19054 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19055 stack_pointer_rtx);
19056 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19057
19058
19059 (define_insn "movti_internal"
19060 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19061 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19062 "TARGET_SSE && !TARGET_64BIT
19063 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19064 {
19065 switch (which_alternative)
19066 {
19067 case 0:
19068 if (get_attr_mode (insn) == MODE_V4SF)
19069 return "xorps\t%0, %0";
19070 else
19071 return "pxor\t%0, %0";
19072 case 1:
19073 case 2:
19074 if (get_attr_mode (insn) == MODE_V4SF)
19075 return "movaps\t{%1, %0|%0, %1}";
19076 else
19077 return "movdqa\t{%1, %0|%0, %1}";
19078 default:
19079 abort ();
19080 }
19081 }
19082 [(set_attr "type" "ssemov,ssemov,ssemov")
19083 (set (attr "mode")
19084 (cond [(eq_attr "alternative" "0,1")
19085 (if_then_else
19086 (ne (symbol_ref "optimize_size")
19087 (const_int 0))
19088 (const_string "V4SF")
19089 (const_string "TI"))
19090 (eq_attr "alternative" "2")
19091 (if_then_else
19092 (ne (symbol_ref "optimize_size")
19093 (const_int 0))
19094 (const_string "V4SF")
19095 (const_string "TI"))]
19096 (const_string "TI")))])
19097
19098 (define_insn "*movti_rex64"
19099 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19100 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19101 "TARGET_64BIT
19102 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19103 {
19104 switch (which_alternative)
19105 {
19106 case 0:
19107 case 1:
19108 return "#";
19109 case 2:
19110 if (get_attr_mode (insn) == MODE_V4SF)
19111 return "xorps\t%0, %0";
19112 else
19113 return "pxor\t%0, %0";
19114 case 3:
19115 case 4:
19116 if (get_attr_mode (insn) == MODE_V4SF)
19117 return "movaps\t{%1, %0|%0, %1}";
19118 else
19119 return "movdqa\t{%1, %0|%0, %1}";
19120 default:
19121 abort ();
19122 }
19123 }
19124 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19125 (set (attr "mode")
19126 (cond [(eq_attr "alternative" "2,3")
19127 (if_then_else
19128 (ne (symbol_ref "optimize_size")
19129 (const_int 0))
19130 (const_string "V4SF")
19131 (const_string "TI"))
19132 (eq_attr "alternative" "4")
19133 (if_then_else
19134 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19135 (const_int 0))
19136 (ne (symbol_ref "optimize_size")
19137 (const_int 0)))
19138 (const_string "V4SF")
19139 (const_string "TI"))]
19140 (const_string "DI")))])
19141
19142 (define_insn "*movtf_rex64"
19143 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19144 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19145 "TARGET_64BIT
19146 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19147 {
19148 switch (which_alternative)
19149 {
19150 case 0:
19151 case 1:
19152 return "#";
19153 case 2:
19154 if (get_attr_mode (insn) == MODE_V4SF)
19155 return "xorps\t%0, %0";
19156 else
19157 return "pxor\t%0, %0";
19158 case 3:
19159 case 4:
19160 if (get_attr_mode (insn) == MODE_V4SF)
19161 return "movaps\t{%1, %0|%0, %1}";
19162 else
19163 return "movdqa\t{%1, %0|%0, %1}";
19164 default:
19165 abort ();
19166 }
19167 }
19168 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19169 (set (attr "mode")
19170 (cond [(eq_attr "alternative" "2,3")
19171 (if_then_else
19172 (ne (symbol_ref "optimize_size")
19173 (const_int 0))
19174 (const_string "V4SF")
19175 (const_string "TI"))
19176 (eq_attr "alternative" "4")
19177 (if_then_else
19178 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19179 (const_int 0))
19180 (ne (symbol_ref "optimize_size")
19181 (const_int 0)))
19182 (const_string "V4SF")
19183 (const_string "TI"))]
19184 (const_string "DI")))])
19185
19186 (define_split
19187 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19188 (match_operand:TI 1 "general_operand" ""))]
19189 "reload_completed && !SSE_REG_P (operands[0])
19190 && !SSE_REG_P (operands[1])"
19191 [(const_int 0)]
19192 "ix86_split_long_move (operands); DONE;")
19193
19194 (define_split
19195 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19196 (match_operand:TF 1 "general_operand" ""))]
19197 "reload_completed && !SSE_REG_P (operands[0])
19198 && !SSE_REG_P (operands[1])"
19199 [(const_int 0)]
19200 "ix86_split_long_move (operands); DONE;")
19201
19202 ;; These two patterns are useful for specifying exactly whether to use
19203 ;; movaps or movups
19204 (define_expand "sse_movaps"
19205 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19206 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19207 UNSPEC_MOVA))]
19208 "TARGET_SSE"
19209 {
19210 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19211 {
19212 rtx tmp = gen_reg_rtx (V4SFmode);
19213 emit_insn (gen_sse_movaps (tmp, operands[1]));
19214 emit_move_insn (operands[0], tmp);
19215 DONE;
19216 }
19217 })
19218
19219 (define_insn "*sse_movaps_1"
19220 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19221 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19222 UNSPEC_MOVA))]
19223 "TARGET_SSE
19224 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19225 "movaps\t{%1, %0|%0, %1}"
19226 [(set_attr "type" "ssemov,ssemov")
19227 (set_attr "mode" "V4SF")])
19228
19229 (define_expand "sse_movups"
19230 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19231 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19232 UNSPEC_MOVU))]
19233 "TARGET_SSE"
19234 {
19235 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19236 {
19237 rtx tmp = gen_reg_rtx (V4SFmode);
19238 emit_insn (gen_sse_movups (tmp, operands[1]));
19239 emit_move_insn (operands[0], tmp);
19240 DONE;
19241 }
19242 })
19243
19244 (define_insn "*sse_movups_1"
19245 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19246 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19247 UNSPEC_MOVU))]
19248 "TARGET_SSE
19249 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19250 "movups\t{%1, %0|%0, %1}"
19251 [(set_attr "type" "ssecvt,ssecvt")
19252 (set_attr "mode" "V4SF")])
19253
19254 ;; SSE Strange Moves.
19255
19256 (define_insn "sse_movmskps"
19257 [(set (match_operand:SI 0 "register_operand" "=r")
19258 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19259 UNSPEC_MOVMSK))]
19260 "TARGET_SSE"
19261 "movmskps\t{%1, %0|%0, %1}"
19262 [(set_attr "type" "ssecvt")
19263 (set_attr "mode" "V4SF")])
19264
19265 (define_insn "mmx_pmovmskb"
19266 [(set (match_operand:SI 0 "register_operand" "=r")
19267 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19268 UNSPEC_MOVMSK))]
19269 "TARGET_SSE || TARGET_3DNOW_A"
19270 "pmovmskb\t{%1, %0|%0, %1}"
19271 [(set_attr "type" "ssecvt")
19272 (set_attr "mode" "V4SF")])
19273
19274
19275 (define_insn "mmx_maskmovq"
19276 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19277 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19278 (match_operand:V8QI 2 "register_operand" "y")]
19279 UNSPEC_MASKMOV))]
19280 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19281 ;; @@@ check ordering of operands in intel/nonintel syntax
19282 "maskmovq\t{%2, %1|%1, %2}"
19283 [(set_attr "type" "mmxcvt")
19284 (set_attr "mode" "DI")])
19285
19286 (define_insn "mmx_maskmovq_rex"
19287 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19288 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19289 (match_operand:V8QI 2 "register_operand" "y")]
19290 UNSPEC_MASKMOV))]
19291 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19292 ;; @@@ check ordering of operands in intel/nonintel syntax
19293 "maskmovq\t{%2, %1|%1, %2}"
19294 [(set_attr "type" "mmxcvt")
19295 (set_attr "mode" "DI")])
19296
19297 (define_insn "sse_movntv4sf"
19298 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19299 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19300 UNSPEC_MOVNT))]
19301 "TARGET_SSE"
19302 "movntps\t{%1, %0|%0, %1}"
19303 [(set_attr "type" "ssemov")
19304 (set_attr "mode" "V4SF")])
19305
19306 (define_insn "sse_movntdi"
19307 [(set (match_operand:DI 0 "memory_operand" "=m")
19308 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19309 UNSPEC_MOVNT))]
19310 "TARGET_SSE || TARGET_3DNOW_A"
19311 "movntq\t{%1, %0|%0, %1}"
19312 [(set_attr "type" "mmxmov")
19313 (set_attr "mode" "DI")])
19314
19315 (define_insn "sse_movhlps"
19316 [(set (match_operand:V4SF 0 "register_operand" "=x")
19317 (vec_merge:V4SF
19318 (match_operand:V4SF 1 "register_operand" "0")
19319 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19320 (parallel [(const_int 2)
19321 (const_int 3)
19322 (const_int 0)
19323 (const_int 1)]))
19324 (const_int 3)))]
19325 "TARGET_SSE"
19326 "movhlps\t{%2, %0|%0, %2}"
19327 [(set_attr "type" "ssecvt")
19328 (set_attr "mode" "V4SF")])
19329
19330 (define_insn "sse_movlhps"
19331 [(set (match_operand:V4SF 0 "register_operand" "=x")
19332 (vec_merge:V4SF
19333 (match_operand:V4SF 1 "register_operand" "0")
19334 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19335 (parallel [(const_int 2)
19336 (const_int 3)
19337 (const_int 0)
19338 (const_int 1)]))
19339 (const_int 12)))]
19340 "TARGET_SSE"
19341 "movlhps\t{%2, %0|%0, %2}"
19342 [(set_attr "type" "ssecvt")
19343 (set_attr "mode" "V4SF")])
19344
19345 (define_insn "sse_movhps"
19346 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19347 (vec_merge:V4SF
19348 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19349 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19350 (const_int 12)))]
19351 "TARGET_SSE
19352 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19353 "movhps\t{%2, %0|%0, %2}"
19354 [(set_attr "type" "ssecvt")
19355 (set_attr "mode" "V4SF")])
19356
19357 (define_insn "sse_movlps"
19358 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19359 (vec_merge:V4SF
19360 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19361 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19362 (const_int 3)))]
19363 "TARGET_SSE
19364 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19365 "movlps\t{%2, %0|%0, %2}"
19366 [(set_attr "type" "ssecvt")
19367 (set_attr "mode" "V4SF")])
19368
19369 (define_expand "sse_loadss"
19370 [(match_operand:V4SF 0 "register_operand" "")
19371 (match_operand:SF 1 "memory_operand" "")]
19372 "TARGET_SSE"
19373 {
19374 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19375 CONST0_RTX (V4SFmode)));
19376 DONE;
19377 })
19378
19379 (define_insn "sse_loadss_1"
19380 [(set (match_operand:V4SF 0 "register_operand" "=x")
19381 (vec_merge:V4SF
19382 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19383 (match_operand:V4SF 2 "const0_operand" "X")
19384 (const_int 1)))]
19385 "TARGET_SSE"
19386 "movss\t{%1, %0|%0, %1}"
19387 [(set_attr "type" "ssemov")
19388 (set_attr "mode" "SF")])
19389
19390 (define_insn "sse_movss"
19391 [(set (match_operand:V4SF 0 "register_operand" "=x")
19392 (vec_merge:V4SF
19393 (match_operand:V4SF 1 "register_operand" "0")
19394 (match_operand:V4SF 2 "register_operand" "x")
19395 (const_int 1)))]
19396 "TARGET_SSE"
19397 "movss\t{%2, %0|%0, %2}"
19398 [(set_attr "type" "ssemov")
19399 (set_attr "mode" "SF")])
19400
19401 (define_insn "sse_storess"
19402 [(set (match_operand:SF 0 "memory_operand" "=m")
19403 (vec_select:SF
19404 (match_operand:V4SF 1 "register_operand" "x")
19405 (parallel [(const_int 0)])))]
19406 "TARGET_SSE"
19407 "movss\t{%1, %0|%0, %1}"
19408 [(set_attr "type" "ssemov")
19409 (set_attr "mode" "SF")])
19410
19411 (define_insn "sse_shufps"
19412 [(set (match_operand:V4SF 0 "register_operand" "=x")
19413 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19414 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19415 (match_operand:SI 3 "immediate_operand" "i")]
19416 UNSPEC_SHUFFLE))]
19417 "TARGET_SSE"
19418 ;; @@@ check operand order for intel/nonintel syntax
19419 "shufps\t{%3, %2, %0|%0, %2, %3}"
19420 [(set_attr "type" "ssecvt")
19421 (set_attr "mode" "V4SF")])
19422
19423
19424 ;; SSE arithmetic
19425
19426 (define_insn "addv4sf3"
19427 [(set (match_operand:V4SF 0 "register_operand" "=x")
19428 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19429 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19430 "TARGET_SSE"
19431 "addps\t{%2, %0|%0, %2}"
19432 [(set_attr "type" "sseadd")
19433 (set_attr "mode" "V4SF")])
19434
19435 (define_insn "vmaddv4sf3"
19436 [(set (match_operand:V4SF 0 "register_operand" "=x")
19437 (vec_merge:V4SF
19438 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19439 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19440 (match_dup 1)
19441 (const_int 1)))]
19442 "TARGET_SSE"
19443 "addss\t{%2, %0|%0, %2}"
19444 [(set_attr "type" "sseadd")
19445 (set_attr "mode" "SF")])
19446
19447 (define_insn "subv4sf3"
19448 [(set (match_operand:V4SF 0 "register_operand" "=x")
19449 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19450 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19451 "TARGET_SSE"
19452 "subps\t{%2, %0|%0, %2}"
19453 [(set_attr "type" "sseadd")
19454 (set_attr "mode" "V4SF")])
19455
19456 (define_insn "vmsubv4sf3"
19457 [(set (match_operand:V4SF 0 "register_operand" "=x")
19458 (vec_merge:V4SF
19459 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19460 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19461 (match_dup 1)
19462 (const_int 1)))]
19463 "TARGET_SSE"
19464 "subss\t{%2, %0|%0, %2}"
19465 [(set_attr "type" "sseadd")
19466 (set_attr "mode" "SF")])
19467
19468 (define_insn "mulv4sf3"
19469 [(set (match_operand:V4SF 0 "register_operand" "=x")
19470 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19471 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19472 "TARGET_SSE"
19473 "mulps\t{%2, %0|%0, %2}"
19474 [(set_attr "type" "ssemul")
19475 (set_attr "mode" "V4SF")])
19476
19477 (define_insn "vmmulv4sf3"
19478 [(set (match_operand:V4SF 0 "register_operand" "=x")
19479 (vec_merge:V4SF
19480 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19481 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19482 (match_dup 1)
19483 (const_int 1)))]
19484 "TARGET_SSE"
19485 "mulss\t{%2, %0|%0, %2}"
19486 [(set_attr "type" "ssemul")
19487 (set_attr "mode" "SF")])
19488
19489 (define_insn "divv4sf3"
19490 [(set (match_operand:V4SF 0 "register_operand" "=x")
19491 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19492 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19493 "TARGET_SSE"
19494 "divps\t{%2, %0|%0, %2}"
19495 [(set_attr "type" "ssediv")
19496 (set_attr "mode" "V4SF")])
19497
19498 (define_insn "vmdivv4sf3"
19499 [(set (match_operand:V4SF 0 "register_operand" "=x")
19500 (vec_merge:V4SF
19501 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19502 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19503 (match_dup 1)
19504 (const_int 1)))]
19505 "TARGET_SSE"
19506 "divss\t{%2, %0|%0, %2}"
19507 [(set_attr "type" "ssediv")
19508 (set_attr "mode" "SF")])
19509
19510
19511 ;; SSE square root/reciprocal
19512
19513 (define_insn "rcpv4sf2"
19514 [(set (match_operand:V4SF 0 "register_operand" "=x")
19515 (unspec:V4SF
19516 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19517 "TARGET_SSE"
19518 "rcpps\t{%1, %0|%0, %1}"
19519 [(set_attr "type" "sse")
19520 (set_attr "mode" "V4SF")])
19521
19522 (define_insn "vmrcpv4sf2"
19523 [(set (match_operand:V4SF 0 "register_operand" "=x")
19524 (vec_merge:V4SF
19525 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19526 UNSPEC_RCP)
19527 (match_operand:V4SF 2 "register_operand" "0")
19528 (const_int 1)))]
19529 "TARGET_SSE"
19530 "rcpss\t{%1, %0|%0, %1}"
19531 [(set_attr "type" "sse")
19532 (set_attr "mode" "SF")])
19533
19534 (define_insn "rsqrtv4sf2"
19535 [(set (match_operand:V4SF 0 "register_operand" "=x")
19536 (unspec:V4SF
19537 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19538 "TARGET_SSE"
19539 "rsqrtps\t{%1, %0|%0, %1}"
19540 [(set_attr "type" "sse")
19541 (set_attr "mode" "V4SF")])
19542
19543 (define_insn "vmrsqrtv4sf2"
19544 [(set (match_operand:V4SF 0 "register_operand" "=x")
19545 (vec_merge:V4SF
19546 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19547 UNSPEC_RSQRT)
19548 (match_operand:V4SF 2 "register_operand" "0")
19549 (const_int 1)))]
19550 "TARGET_SSE"
19551 "rsqrtss\t{%1, %0|%0, %1}"
19552 [(set_attr "type" "sse")
19553 (set_attr "mode" "SF")])
19554
19555 (define_insn "sqrtv4sf2"
19556 [(set (match_operand:V4SF 0 "register_operand" "=x")
19557 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19558 "TARGET_SSE"
19559 "sqrtps\t{%1, %0|%0, %1}"
19560 [(set_attr "type" "sse")
19561 (set_attr "mode" "V4SF")])
19562
19563 (define_insn "vmsqrtv4sf2"
19564 [(set (match_operand:V4SF 0 "register_operand" "=x")
19565 (vec_merge:V4SF
19566 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19567 (match_operand:V4SF 2 "register_operand" "0")
19568 (const_int 1)))]
19569 "TARGET_SSE"
19570 "sqrtss\t{%1, %0|%0, %1}"
19571 [(set_attr "type" "sse")
19572 (set_attr "mode" "SF")])
19573
19574 ;; SSE logical operations.
19575
19576 ;; SSE defines logical operations on floating point values. This brings
19577 ;; interesting challenge to RTL representation where logicals are only valid
19578 ;; on integral types. We deal with this by representing the floating point
19579 ;; logical as logical on arguments casted to TImode as this is what hardware
19580 ;; really does. Unfortunately hardware requires the type information to be
19581 ;; present and thus we must avoid subregs from being simplified and eliminated
19582 ;; in later compilation phases.
19583 ;;
19584 ;; We have following variants from each instruction:
19585 ;; sse_andsf3 - the operation taking V4SF vector operands
19586 ;; and doing TImode cast on them
19587 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19588 ;; TImode, since backend insist on eliminating casts
19589 ;; on memory operands
19590 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19591 ;; We can not accept memory operand here as instruction reads
19592 ;; whole scalar. This is generated only post reload by GCC
19593 ;; scalar float operations that expands to logicals (fabs)
19594 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19595 ;; memory operand. Eventually combine can be able
19596 ;; to synthesize these using splitter.
19597 ;; sse2_anddf3, *sse2_anddf3_memory
19598 ;;
19599 ;;
19600 ;; These are not called andti3 etc. because we really really don't want
19601 ;; the compiler to widen DImode ands to TImode ands and then try to move
19602 ;; into DImode subregs of SSE registers, and them together, and move out
19603 ;; of DImode subregs again!
19604 ;; SSE1 single precision floating point logical operation
19605 (define_expand "sse_andv4sf3"
19606 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19607 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19608 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19609 "TARGET_SSE"
19610 "")
19611
19612 (define_insn "*sse_andv4sf3"
19613 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19614 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19615 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19616 "TARGET_SSE
19617 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19618 "andps\t{%2, %0|%0, %2}"
19619 [(set_attr "type" "sselog")
19620 (set_attr "mode" "V4SF")])
19621
19622 (define_insn "*sse_andsf3"
19623 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19624 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19625 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19626 "TARGET_SSE
19627 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19628 "andps\t{%2, %0|%0, %2}"
19629 [(set_attr "type" "sselog")
19630 (set_attr "mode" "V4SF")])
19631
19632 (define_expand "sse_nandv4sf3"
19633 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19634 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19635 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19636 "TARGET_SSE"
19637 "")
19638
19639 (define_insn "*sse_nandv4sf3"
19640 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19641 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19642 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19643 "TARGET_SSE"
19644 "andnps\t{%2, %0|%0, %2}"
19645 [(set_attr "type" "sselog")
19646 (set_attr "mode" "V4SF")])
19647
19648 (define_insn "*sse_nandsf3"
19649 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19650 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19651 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19652 "TARGET_SSE"
19653 "andnps\t{%2, %0|%0, %2}"
19654 [(set_attr "type" "sselog")
19655 (set_attr "mode" "V4SF")])
19656
19657 (define_expand "sse_iorv4sf3"
19658 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19659 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19660 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19661 "TARGET_SSE"
19662 "")
19663
19664 (define_insn "*sse_iorv4sf3"
19665 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19666 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19667 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19668 "TARGET_SSE
19669 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19670 "orps\t{%2, %0|%0, %2}"
19671 [(set_attr "type" "sselog")
19672 (set_attr "mode" "V4SF")])
19673
19674 (define_insn "*sse_iorsf3"
19675 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19676 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19677 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19678 "TARGET_SSE
19679 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19680 "orps\t{%2, %0|%0, %2}"
19681 [(set_attr "type" "sselog")
19682 (set_attr "mode" "V4SF")])
19683
19684 (define_expand "sse_xorv4sf3"
19685 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19686 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19687 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19688 "TARGET_SSE
19689 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19690 "")
19691
19692 (define_insn "*sse_xorv4sf3"
19693 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19694 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19695 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19696 "TARGET_SSE
19697 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19698 "xorps\t{%2, %0|%0, %2}"
19699 [(set_attr "type" "sselog")
19700 (set_attr "mode" "V4SF")])
19701
19702 (define_insn "*sse_xorsf3"
19703 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19704 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19705 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19706 "TARGET_SSE
19707 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19708 "xorps\t{%2, %0|%0, %2}"
19709 [(set_attr "type" "sselog")
19710 (set_attr "mode" "V4SF")])
19711
19712 ;; SSE2 double precision floating point logical operation
19713
19714 (define_expand "sse2_andv2df3"
19715 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19716 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19717 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19718 "TARGET_SSE2"
19719 "")
19720
19721 (define_insn "*sse2_andv2df3"
19722 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19723 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19724 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19725 "TARGET_SSE2
19726 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19727 "andpd\t{%2, %0|%0, %2}"
19728 [(set_attr "type" "sselog")
19729 (set_attr "mode" "V2DF")])
19730
19731 (define_insn "*sse2_andv2df3"
19732 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19733 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19734 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19735 "TARGET_SSE2
19736 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19737 "andpd\t{%2, %0|%0, %2}"
19738 [(set_attr "type" "sselog")
19739 (set_attr "mode" "V2DF")])
19740
19741 (define_expand "sse2_nandv2df3"
19742 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19743 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19744 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19745 "TARGET_SSE2"
19746 "")
19747
19748 (define_insn "*sse2_nandv2df3"
19749 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19750 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19751 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19752 "TARGET_SSE2"
19753 "andnpd\t{%2, %0|%0, %2}"
19754 [(set_attr "type" "sselog")
19755 (set_attr "mode" "V2DF")])
19756
19757 (define_insn "*sse_nandti3_df"
19758 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19759 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19760 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19761 "TARGET_SSE2"
19762 "andnpd\t{%2, %0|%0, %2}"
19763 [(set_attr "type" "sselog")
19764 (set_attr "mode" "V2DF")])
19765
19766 (define_expand "sse2_iorv2df3"
19767 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19768 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19769 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19770 "TARGET_SSE2"
19771 "")
19772
19773 (define_insn "*sse2_iorv2df3"
19774 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19775 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19776 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19777 "TARGET_SSE2
19778 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19779 "orpd\t{%2, %0|%0, %2}"
19780 [(set_attr "type" "sselog")
19781 (set_attr "mode" "V2DF")])
19782
19783 (define_insn "*sse2_iordf3"
19784 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19785 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19786 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19787 "TARGET_SSE2
19788 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19789 "orpd\t{%2, %0|%0, %2}"
19790 [(set_attr "type" "sselog")
19791 (set_attr "mode" "V2DF")])
19792
19793 (define_expand "sse2_xorv2df3"
19794 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19795 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19796 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19797 "TARGET_SSE2"
19798 "")
19799
19800 (define_insn "*sse2_xorv2df3"
19801 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19802 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19803 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19804 "TARGET_SSE2
19805 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19806 "xorpd\t{%2, %0|%0, %2}"
19807 [(set_attr "type" "sselog")
19808 (set_attr "mode" "V2DF")])
19809
19810 (define_insn "*sse2_xordf3"
19811 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19812 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19813 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19814 "TARGET_SSE2
19815 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19816 "xorpd\t{%2, %0|%0, %2}"
19817 [(set_attr "type" "sselog")
19818 (set_attr "mode" "V2DF")])
19819
19820 ;; SSE2 integral logicals. These patterns must always come after floating
19821 ;; point ones since we don't want compiler to use integer opcodes on floating
19822 ;; point SSE values to avoid matching of subregs in the match_operand.
19823 (define_insn "*sse2_andti3"
19824 [(set (match_operand:TI 0 "register_operand" "=x")
19825 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19826 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19827 "TARGET_SSE2
19828 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19829 "pand\t{%2, %0|%0, %2}"
19830 [(set_attr "type" "sselog")
19831 (set_attr "mode" "TI")])
19832
19833 (define_insn "sse2_andv2di3"
19834 [(set (match_operand:V2DI 0 "register_operand" "=x")
19835 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19836 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19837 "TARGET_SSE2
19838 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19839 "pand\t{%2, %0|%0, %2}"
19840 [(set_attr "type" "sselog")
19841 (set_attr "mode" "TI")])
19842
19843 (define_insn "*sse2_nandti3"
19844 [(set (match_operand:TI 0 "register_operand" "=x")
19845 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19846 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19847 "TARGET_SSE2"
19848 "pandn\t{%2, %0|%0, %2}"
19849 [(set_attr "type" "sselog")
19850 (set_attr "mode" "TI")])
19851
19852 (define_insn "sse2_nandv2di3"
19853 [(set (match_operand:V2DI 0 "register_operand" "=x")
19854 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19855 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19856 "TARGET_SSE2
19857 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19858 "pandn\t{%2, %0|%0, %2}"
19859 [(set_attr "type" "sselog")
19860 (set_attr "mode" "TI")])
19861
19862 (define_insn "*sse2_iorti3"
19863 [(set (match_operand:TI 0 "register_operand" "=x")
19864 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19865 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19866 "TARGET_SSE2
19867 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19868 "por\t{%2, %0|%0, %2}"
19869 [(set_attr "type" "sselog")
19870 (set_attr "mode" "TI")])
19871
19872 (define_insn "sse2_iorv2di3"
19873 [(set (match_operand:V2DI 0 "register_operand" "=x")
19874 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19875 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19876 "TARGET_SSE2
19877 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19878 "por\t{%2, %0|%0, %2}"
19879 [(set_attr "type" "sselog")
19880 (set_attr "mode" "TI")])
19881
19882 (define_insn "*sse2_xorti3"
19883 [(set (match_operand:TI 0 "register_operand" "=x")
19884 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19885 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19886 "TARGET_SSE2
19887 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19888 "pxor\t{%2, %0|%0, %2}"
19889 [(set_attr "type" "sselog")
19890 (set_attr "mode" "TI")])
19891
19892 (define_insn "sse2_xorv2di3"
19893 [(set (match_operand:V2DI 0 "register_operand" "=x")
19894 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19895 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19896 "TARGET_SSE2
19897 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19898 "pxor\t{%2, %0|%0, %2}"
19899 [(set_attr "type" "sselog")
19900 (set_attr "mode" "TI")])
19901
19902 ;; Use xor, but don't show input operands so they aren't live before
19903 ;; this insn.
19904 (define_insn "sse_clrv4sf"
19905 [(set (match_operand:V4SF 0 "register_operand" "=x")
19906 (match_operand:V4SF 1 "const0_operand" "X"))]
19907 "TARGET_SSE"
19908 {
19909 if (get_attr_mode (insn) == MODE_TI)
19910 return "pxor\t{%0, %0|%0, %0}";
19911 else
19912 return "xorps\t{%0, %0|%0, %0}";
19913 }
19914 [(set_attr "type" "sselog")
19915 (set_attr "memory" "none")
19916 (set (attr "mode")
19917 (if_then_else
19918 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19919 (const_int 0))
19920 (ne (symbol_ref "TARGET_SSE2")
19921 (const_int 0)))
19922 (eq (symbol_ref "optimize_size")
19923 (const_int 0)))
19924 (const_string "TI")
19925 (const_string "V4SF")))])
19926
19927 ;; Use xor, but don't show input operands so they aren't live before
19928 ;; this insn.
19929 (define_insn "sse_clrv2df"
19930 [(set (match_operand:V2DF 0 "register_operand" "=x")
19931 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19932 "TARGET_SSE2"
19933 "xorpd\t{%0, %0|%0, %0}"
19934 [(set_attr "type" "sselog")
19935 (set_attr "memory" "none")
19936 (set_attr "mode" "V4SF")])
19937
19938 ;; SSE mask-generating compares
19939
19940 (define_insn "maskcmpv4sf3"
19941 [(set (match_operand:V4SI 0 "register_operand" "=x")
19942 (match_operator:V4SI 3 "sse_comparison_operator"
19943 [(match_operand:V4SF 1 "register_operand" "0")
19944 (match_operand:V4SF 2 "register_operand" "x")]))]
19945 "TARGET_SSE"
19946 "cmp%D3ps\t{%2, %0|%0, %2}"
19947 [(set_attr "type" "ssecmp")
19948 (set_attr "mode" "V4SF")])
19949
19950 (define_insn "maskncmpv4sf3"
19951 [(set (match_operand:V4SI 0 "register_operand" "=x")
19952 (not:V4SI
19953 (match_operator:V4SI 3 "sse_comparison_operator"
19954 [(match_operand:V4SF 1 "register_operand" "0")
19955 (match_operand:V4SF 2 "register_operand" "x")])))]
19956 "TARGET_SSE"
19957 {
19958 if (GET_CODE (operands[3]) == UNORDERED)
19959 return "cmpordps\t{%2, %0|%0, %2}";
19960 else
19961 return "cmpn%D3ps\t{%2, %0|%0, %2}";
19962 }
19963 [(set_attr "type" "ssecmp")
19964 (set_attr "mode" "V4SF")])
19965
19966 (define_insn "vmmaskcmpv4sf3"
19967 [(set (match_operand:V4SI 0 "register_operand" "=x")
19968 (vec_merge:V4SI
19969 (match_operator:V4SI 3 "sse_comparison_operator"
19970 [(match_operand:V4SF 1 "register_operand" "0")
19971 (match_operand:V4SF 2 "register_operand" "x")])
19972 (subreg:V4SI (match_dup 1) 0)
19973 (const_int 1)))]
19974 "TARGET_SSE"
19975 "cmp%D3ss\t{%2, %0|%0, %2}"
19976 [(set_attr "type" "ssecmp")
19977 (set_attr "mode" "SF")])
19978
19979 (define_insn "vmmaskncmpv4sf3"
19980 [(set (match_operand:V4SI 0 "register_operand" "=x")
19981 (vec_merge:V4SI
19982 (not:V4SI
19983 (match_operator:V4SI 3 "sse_comparison_operator"
19984 [(match_operand:V4SF 1 "register_operand" "0")
19985 (match_operand:V4SF 2 "register_operand" "x")]))
19986 (subreg:V4SI (match_dup 1) 0)
19987 (const_int 1)))]
19988 "TARGET_SSE"
19989 {
19990 if (GET_CODE (operands[3]) == UNORDERED)
19991 return "cmpordss\t{%2, %0|%0, %2}";
19992 else
19993 return "cmpn%D3ss\t{%2, %0|%0, %2}";
19994 }
19995 [(set_attr "type" "ssecmp")
19996 (set_attr "mode" "SF")])
19997
19998 (define_insn "sse_comi"
19999 [(set (reg:CCFP 17)
20000 (compare:CCFP (vec_select:SF
20001 (match_operand:V4SF 0 "register_operand" "x")
20002 (parallel [(const_int 0)]))
20003 (vec_select:SF
20004 (match_operand:V4SF 1 "register_operand" "x")
20005 (parallel [(const_int 0)]))))]
20006 "TARGET_SSE"
20007 "comiss\t{%1, %0|%0, %1}"
20008 [(set_attr "type" "ssecomi")
20009 (set_attr "mode" "SF")])
20010
20011 (define_insn "sse_ucomi"
20012 [(set (reg:CCFPU 17)
20013 (compare:CCFPU (vec_select:SF
20014 (match_operand:V4SF 0 "register_operand" "x")
20015 (parallel [(const_int 0)]))
20016 (vec_select:SF
20017 (match_operand:V4SF 1 "register_operand" "x")
20018 (parallel [(const_int 0)]))))]
20019 "TARGET_SSE"
20020 "ucomiss\t{%1, %0|%0, %1}"
20021 [(set_attr "type" "ssecomi")
20022 (set_attr "mode" "SF")])
20023
20024
20025 ;; SSE unpack
20026
20027 (define_insn "sse_unpckhps"
20028 [(set (match_operand:V4SF 0 "register_operand" "=x")
20029 (vec_merge:V4SF
20030 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20031 (parallel [(const_int 2)
20032 (const_int 0)
20033 (const_int 3)
20034 (const_int 1)]))
20035 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20036 (parallel [(const_int 0)
20037 (const_int 2)
20038 (const_int 1)
20039 (const_int 3)]))
20040 (const_int 5)))]
20041 "TARGET_SSE"
20042 "unpckhps\t{%2, %0|%0, %2}"
20043 [(set_attr "type" "ssecvt")
20044 (set_attr "mode" "V4SF")])
20045
20046 (define_insn "sse_unpcklps"
20047 [(set (match_operand:V4SF 0 "register_operand" "=x")
20048 (vec_merge:V4SF
20049 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20050 (parallel [(const_int 0)
20051 (const_int 2)
20052 (const_int 1)
20053 (const_int 3)]))
20054 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20055 (parallel [(const_int 2)
20056 (const_int 0)
20057 (const_int 3)
20058 (const_int 1)]))
20059 (const_int 5)))]
20060 "TARGET_SSE"
20061 "unpcklps\t{%2, %0|%0, %2}"
20062 [(set_attr "type" "ssecvt")
20063 (set_attr "mode" "V4SF")])
20064
20065
20066 ;; SSE min/max
20067
20068 (define_insn "smaxv4sf3"
20069 [(set (match_operand:V4SF 0 "register_operand" "=x")
20070 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20071 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20072 "TARGET_SSE"
20073 "maxps\t{%2, %0|%0, %2}"
20074 [(set_attr "type" "sse")
20075 (set_attr "mode" "V4SF")])
20076
20077 (define_insn "vmsmaxv4sf3"
20078 [(set (match_operand:V4SF 0 "register_operand" "=x")
20079 (vec_merge:V4SF
20080 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20081 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20082 (match_dup 1)
20083 (const_int 1)))]
20084 "TARGET_SSE"
20085 "maxss\t{%2, %0|%0, %2}"
20086 [(set_attr "type" "sse")
20087 (set_attr "mode" "SF")])
20088
20089 (define_insn "sminv4sf3"
20090 [(set (match_operand:V4SF 0 "register_operand" "=x")
20091 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20092 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20093 "TARGET_SSE"
20094 "minps\t{%2, %0|%0, %2}"
20095 [(set_attr "type" "sse")
20096 (set_attr "mode" "V4SF")])
20097
20098 (define_insn "vmsminv4sf3"
20099 [(set (match_operand:V4SF 0 "register_operand" "=x")
20100 (vec_merge:V4SF
20101 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20102 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20103 (match_dup 1)
20104 (const_int 1)))]
20105 "TARGET_SSE"
20106 "minss\t{%2, %0|%0, %2}"
20107 [(set_attr "type" "sse")
20108 (set_attr "mode" "SF")])
20109
20110 ;; SSE <-> integer/MMX conversions
20111
20112 (define_insn "cvtpi2ps"
20113 [(set (match_operand:V4SF 0 "register_operand" "=x")
20114 (vec_merge:V4SF
20115 (match_operand:V4SF 1 "register_operand" "0")
20116 (vec_duplicate:V4SF
20117 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20118 (const_int 12)))]
20119 "TARGET_SSE"
20120 "cvtpi2ps\t{%2, %0|%0, %2}"
20121 [(set_attr "type" "ssecvt")
20122 (set_attr "mode" "V4SF")])
20123
20124 (define_insn "cvtps2pi"
20125 [(set (match_operand:V2SI 0 "register_operand" "=y")
20126 (vec_select:V2SI
20127 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20128 (parallel [(const_int 0) (const_int 1)])))]
20129 "TARGET_SSE"
20130 "cvtps2pi\t{%1, %0|%0, %1}"
20131 [(set_attr "type" "ssecvt")
20132 (set_attr "mode" "V4SF")])
20133
20134 (define_insn "cvttps2pi"
20135 [(set (match_operand:V2SI 0 "register_operand" "=y")
20136 (vec_select:V2SI
20137 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20138 UNSPEC_FIX)
20139 (parallel [(const_int 0) (const_int 1)])))]
20140 "TARGET_SSE"
20141 "cvttps2pi\t{%1, %0|%0, %1}"
20142 [(set_attr "type" "ssecvt")
20143 (set_attr "mode" "SF")])
20144
20145 (define_insn "cvtsi2ss"
20146 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20147 (vec_merge:V4SF
20148 (match_operand:V4SF 1 "register_operand" "0,0")
20149 (vec_duplicate:V4SF
20150 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20151 (const_int 14)))]
20152 "TARGET_SSE"
20153 "cvtsi2ss\t{%2, %0|%0, %2}"
20154 [(set_attr "type" "sseicvt")
20155 (set_attr "athlon_decode" "vector,double")
20156 (set_attr "mode" "SF")])
20157
20158 (define_insn "cvtsi2ssq"
20159 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20160 (vec_merge:V4SF
20161 (match_operand:V4SF 1 "register_operand" "0,0")
20162 (vec_duplicate:V4SF
20163 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20164 (const_int 14)))]
20165 "TARGET_SSE && TARGET_64BIT"
20166 "cvtsi2ssq\t{%2, %0|%0, %2}"
20167 [(set_attr "type" "sseicvt")
20168 (set_attr "athlon_decode" "vector,double")
20169 (set_attr "mode" "SF")])
20170
20171 (define_insn "cvtss2si"
20172 [(set (match_operand:SI 0 "register_operand" "=r,r")
20173 (vec_select:SI
20174 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20175 (parallel [(const_int 0)])))]
20176 "TARGET_SSE"
20177 "cvtss2si\t{%1, %0|%0, %1}"
20178 [(set_attr "type" "sseicvt")
20179 (set_attr "athlon_decode" "double,vector")
20180 (set_attr "mode" "SI")])
20181
20182 (define_insn "cvtss2siq"
20183 [(set (match_operand:DI 0 "register_operand" "=r,r")
20184 (vec_select:DI
20185 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20186 (parallel [(const_int 0)])))]
20187 "TARGET_SSE"
20188 "cvtss2siq\t{%1, %0|%0, %1}"
20189 [(set_attr "type" "sseicvt")
20190 (set_attr "athlon_decode" "double,vector")
20191 (set_attr "mode" "DI")])
20192
20193 (define_insn "cvttss2si"
20194 [(set (match_operand:SI 0 "register_operand" "=r,r")
20195 (vec_select:SI
20196 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20197 UNSPEC_FIX)
20198 (parallel [(const_int 0)])))]
20199 "TARGET_SSE"
20200 "cvttss2si\t{%1, %0|%0, %1}"
20201 [(set_attr "type" "sseicvt")
20202 (set_attr "mode" "SF")
20203 (set_attr "athlon_decode" "double,vector")])
20204
20205 (define_insn "cvttss2siq"
20206 [(set (match_operand:DI 0 "register_operand" "=r,r")
20207 (vec_select:DI
20208 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20209 UNSPEC_FIX)
20210 (parallel [(const_int 0)])))]
20211 "TARGET_SSE && TARGET_64BIT"
20212 "cvttss2siq\t{%1, %0|%0, %1}"
20213 [(set_attr "type" "sseicvt")
20214 (set_attr "mode" "SF")
20215 (set_attr "athlon_decode" "double,vector")])
20216
20217
20218 ;; MMX insns
20219
20220 ;; MMX arithmetic
20221
20222 (define_insn "addv8qi3"
20223 [(set (match_operand:V8QI 0 "register_operand" "=y")
20224 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20225 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20226 "TARGET_MMX"
20227 "paddb\t{%2, %0|%0, %2}"
20228 [(set_attr "type" "mmxadd")
20229 (set_attr "mode" "DI")])
20230
20231 (define_insn "addv4hi3"
20232 [(set (match_operand:V4HI 0 "register_operand" "=y")
20233 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20234 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20235 "TARGET_MMX"
20236 "paddw\t{%2, %0|%0, %2}"
20237 [(set_attr "type" "mmxadd")
20238 (set_attr "mode" "DI")])
20239
20240 (define_insn "addv2si3"
20241 [(set (match_operand:V2SI 0 "register_operand" "=y")
20242 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20243 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20244 "TARGET_MMX"
20245 "paddd\t{%2, %0|%0, %2}"
20246 [(set_attr "type" "mmxadd")
20247 (set_attr "mode" "DI")])
20248
20249 (define_insn "mmx_adddi3"
20250 [(set (match_operand:DI 0 "register_operand" "=y")
20251 (unspec:DI
20252 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20253 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20254 UNSPEC_NOP))]
20255 "TARGET_MMX"
20256 "paddq\t{%2, %0|%0, %2}"
20257 [(set_attr "type" "mmxadd")
20258 (set_attr "mode" "DI")])
20259
20260 (define_insn "ssaddv8qi3"
20261 [(set (match_operand:V8QI 0 "register_operand" "=y")
20262 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20263 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20264 "TARGET_MMX"
20265 "paddsb\t{%2, %0|%0, %2}"
20266 [(set_attr "type" "mmxadd")
20267 (set_attr "mode" "DI")])
20268
20269 (define_insn "ssaddv4hi3"
20270 [(set (match_operand:V4HI 0 "register_operand" "=y")
20271 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20272 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20273 "TARGET_MMX"
20274 "paddsw\t{%2, %0|%0, %2}"
20275 [(set_attr "type" "mmxadd")
20276 (set_attr "mode" "DI")])
20277
20278 (define_insn "usaddv8qi3"
20279 [(set (match_operand:V8QI 0 "register_operand" "=y")
20280 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20281 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20282 "TARGET_MMX"
20283 "paddusb\t{%2, %0|%0, %2}"
20284 [(set_attr "type" "mmxadd")
20285 (set_attr "mode" "DI")])
20286
20287 (define_insn "usaddv4hi3"
20288 [(set (match_operand:V4HI 0 "register_operand" "=y")
20289 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20290 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20291 "TARGET_MMX"
20292 "paddusw\t{%2, %0|%0, %2}"
20293 [(set_attr "type" "mmxadd")
20294 (set_attr "mode" "DI")])
20295
20296 (define_insn "subv8qi3"
20297 [(set (match_operand:V8QI 0 "register_operand" "=y")
20298 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20299 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20300 "TARGET_MMX"
20301 "psubb\t{%2, %0|%0, %2}"
20302 [(set_attr "type" "mmxadd")
20303 (set_attr "mode" "DI")])
20304
20305 (define_insn "subv4hi3"
20306 [(set (match_operand:V4HI 0 "register_operand" "=y")
20307 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20308 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20309 "TARGET_MMX"
20310 "psubw\t{%2, %0|%0, %2}"
20311 [(set_attr "type" "mmxadd")
20312 (set_attr "mode" "DI")])
20313
20314 (define_insn "subv2si3"
20315 [(set (match_operand:V2SI 0 "register_operand" "=y")
20316 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20317 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20318 "TARGET_MMX"
20319 "psubd\t{%2, %0|%0, %2}"
20320 [(set_attr "type" "mmxadd")
20321 (set_attr "mode" "DI")])
20322
20323 (define_insn "mmx_subdi3"
20324 [(set (match_operand:DI 0 "register_operand" "=y")
20325 (unspec:DI
20326 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20327 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20328 UNSPEC_NOP))]
20329 "TARGET_MMX"
20330 "psubq\t{%2, %0|%0, %2}"
20331 [(set_attr "type" "mmxadd")
20332 (set_attr "mode" "DI")])
20333
20334 (define_insn "sssubv8qi3"
20335 [(set (match_operand:V8QI 0 "register_operand" "=y")
20336 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20337 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20338 "TARGET_MMX"
20339 "psubsb\t{%2, %0|%0, %2}"
20340 [(set_attr "type" "mmxadd")
20341 (set_attr "mode" "DI")])
20342
20343 (define_insn "sssubv4hi3"
20344 [(set (match_operand:V4HI 0 "register_operand" "=y")
20345 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20346 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20347 "TARGET_MMX"
20348 "psubsw\t{%2, %0|%0, %2}"
20349 [(set_attr "type" "mmxadd")
20350 (set_attr "mode" "DI")])
20351
20352 (define_insn "ussubv8qi3"
20353 [(set (match_operand:V8QI 0 "register_operand" "=y")
20354 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20355 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20356 "TARGET_MMX"
20357 "psubusb\t{%2, %0|%0, %2}"
20358 [(set_attr "type" "mmxadd")
20359 (set_attr "mode" "DI")])
20360
20361 (define_insn "ussubv4hi3"
20362 [(set (match_operand:V4HI 0 "register_operand" "=y")
20363 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20364 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20365 "TARGET_MMX"
20366 "psubusw\t{%2, %0|%0, %2}"
20367 [(set_attr "type" "mmxadd")
20368 (set_attr "mode" "DI")])
20369
20370 (define_insn "mulv4hi3"
20371 [(set (match_operand:V4HI 0 "register_operand" "=y")
20372 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20373 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20374 "TARGET_MMX"
20375 "pmullw\t{%2, %0|%0, %2}"
20376 [(set_attr "type" "mmxmul")
20377 (set_attr "mode" "DI")])
20378
20379 (define_insn "smulv4hi3_highpart"
20380 [(set (match_operand:V4HI 0 "register_operand" "=y")
20381 (truncate:V4HI
20382 (lshiftrt:V4SI
20383 (mult:V4SI (sign_extend:V4SI
20384 (match_operand:V4HI 1 "register_operand" "0"))
20385 (sign_extend:V4SI
20386 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20387 (const_int 16))))]
20388 "TARGET_MMX"
20389 "pmulhw\t{%2, %0|%0, %2}"
20390 [(set_attr "type" "mmxmul")
20391 (set_attr "mode" "DI")])
20392
20393 (define_insn "umulv4hi3_highpart"
20394 [(set (match_operand:V4HI 0 "register_operand" "=y")
20395 (truncate:V4HI
20396 (lshiftrt:V4SI
20397 (mult:V4SI (zero_extend:V4SI
20398 (match_operand:V4HI 1 "register_operand" "0"))
20399 (zero_extend:V4SI
20400 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20401 (const_int 16))))]
20402 "TARGET_SSE || TARGET_3DNOW_A"
20403 "pmulhuw\t{%2, %0|%0, %2}"
20404 [(set_attr "type" "mmxmul")
20405 (set_attr "mode" "DI")])
20406
20407 (define_insn "mmx_pmaddwd"
20408 [(set (match_operand:V2SI 0 "register_operand" "=y")
20409 (plus:V2SI
20410 (mult:V2SI
20411 (sign_extend:V2SI
20412 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20413 (parallel [(const_int 0) (const_int 2)])))
20414 (sign_extend:V2SI
20415 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20416 (parallel [(const_int 0) (const_int 2)]))))
20417 (mult:V2SI
20418 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20419 (parallel [(const_int 1)
20420 (const_int 3)])))
20421 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20422 (parallel [(const_int 1)
20423 (const_int 3)]))))))]
20424 "TARGET_MMX"
20425 "pmaddwd\t{%2, %0|%0, %2}"
20426 [(set_attr "type" "mmxmul")
20427 (set_attr "mode" "DI")])
20428
20429
20430 ;; MMX logical operations
20431 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20432 ;; normal code that also wants to use the FPU from getting broken.
20433 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20434 (define_insn "mmx_iordi3"
20435 [(set (match_operand:DI 0 "register_operand" "=y")
20436 (unspec:DI
20437 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20438 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20439 UNSPEC_NOP))]
20440 "TARGET_MMX"
20441 "por\t{%2, %0|%0, %2}"
20442 [(set_attr "type" "mmxadd")
20443 (set_attr "mode" "DI")])
20444
20445 (define_insn "mmx_xordi3"
20446 [(set (match_operand:DI 0 "register_operand" "=y")
20447 (unspec:DI
20448 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20449 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20450 UNSPEC_NOP))]
20451 "TARGET_MMX"
20452 "pxor\t{%2, %0|%0, %2}"
20453 [(set_attr "type" "mmxadd")
20454 (set_attr "mode" "DI")
20455 (set_attr "memory" "none")])
20456
20457 ;; Same as pxor, but don't show input operands so that we don't think
20458 ;; they are live.
20459 (define_insn "mmx_clrdi"
20460 [(set (match_operand:DI 0 "register_operand" "=y")
20461 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20462 "TARGET_MMX"
20463 "pxor\t{%0, %0|%0, %0}"
20464 [(set_attr "type" "mmxadd")
20465 (set_attr "mode" "DI")
20466 (set_attr "memory" "none")])
20467
20468 (define_insn "mmx_anddi3"
20469 [(set (match_operand:DI 0 "register_operand" "=y")
20470 (unspec:DI
20471 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20472 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20473 UNSPEC_NOP))]
20474 "TARGET_MMX"
20475 "pand\t{%2, %0|%0, %2}"
20476 [(set_attr "type" "mmxadd")
20477 (set_attr "mode" "DI")])
20478
20479 (define_insn "mmx_nanddi3"
20480 [(set (match_operand:DI 0 "register_operand" "=y")
20481 (unspec:DI
20482 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20483 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20484 UNSPEC_NOP))]
20485 "TARGET_MMX"
20486 "pandn\t{%2, %0|%0, %2}"
20487 [(set_attr "type" "mmxadd")
20488 (set_attr "mode" "DI")])
20489
20490
20491 ;; MMX unsigned averages/sum of absolute differences
20492
20493 (define_insn "mmx_uavgv8qi3"
20494 [(set (match_operand:V8QI 0 "register_operand" "=y")
20495 (ashiftrt:V8QI
20496 (plus:V8QI (plus:V8QI
20497 (match_operand:V8QI 1 "register_operand" "0")
20498 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20499 (const_vector:V8QI [(const_int 1)
20500 (const_int 1)
20501 (const_int 1)
20502 (const_int 1)
20503 (const_int 1)
20504 (const_int 1)
20505 (const_int 1)
20506 (const_int 1)]))
20507 (const_int 1)))]
20508 "TARGET_SSE || TARGET_3DNOW_A"
20509 "pavgb\t{%2, %0|%0, %2}"
20510 [(set_attr "type" "mmxshft")
20511 (set_attr "mode" "DI")])
20512
20513 (define_insn "mmx_uavgv4hi3"
20514 [(set (match_operand:V4HI 0 "register_operand" "=y")
20515 (ashiftrt:V4HI
20516 (plus:V4HI (plus:V4HI
20517 (match_operand:V4HI 1 "register_operand" "0")
20518 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20519 (const_vector:V4HI [(const_int 1)
20520 (const_int 1)
20521 (const_int 1)
20522 (const_int 1)]))
20523 (const_int 1)))]
20524 "TARGET_SSE || TARGET_3DNOW_A"
20525 "pavgw\t{%2, %0|%0, %2}"
20526 [(set_attr "type" "mmxshft")
20527 (set_attr "mode" "DI")])
20528
20529 (define_insn "mmx_psadbw"
20530 [(set (match_operand:DI 0 "register_operand" "=y")
20531 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20532 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20533 UNSPEC_PSADBW))]
20534 "TARGET_SSE || TARGET_3DNOW_A"
20535 "psadbw\t{%2, %0|%0, %2}"
20536 [(set_attr "type" "mmxshft")
20537 (set_attr "mode" "DI")])
20538
20539
20540 ;; MMX insert/extract/shuffle
20541
20542 (define_insn "mmx_pinsrw"
20543 [(set (match_operand:V4HI 0 "register_operand" "=y")
20544 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20545 (vec_duplicate:V4HI
20546 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20547 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20548 "TARGET_SSE || TARGET_3DNOW_A"
20549 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20550 [(set_attr "type" "mmxcvt")
20551 (set_attr "mode" "DI")])
20552
20553 (define_insn "mmx_pextrw"
20554 [(set (match_operand:SI 0 "register_operand" "=r")
20555 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20556 (parallel
20557 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20558 "TARGET_SSE || TARGET_3DNOW_A"
20559 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20560 [(set_attr "type" "mmxcvt")
20561 (set_attr "mode" "DI")])
20562
20563 (define_insn "mmx_pshufw"
20564 [(set (match_operand:V4HI 0 "register_operand" "=y")
20565 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20566 (match_operand:SI 2 "immediate_operand" "i")]
20567 UNSPEC_SHUFFLE))]
20568 "TARGET_SSE || TARGET_3DNOW_A"
20569 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20570 [(set_attr "type" "mmxcvt")
20571 (set_attr "mode" "DI")])
20572
20573
20574 ;; MMX mask-generating comparisons
20575
20576 (define_insn "eqv8qi3"
20577 [(set (match_operand:V8QI 0 "register_operand" "=y")
20578 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20579 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20580 "TARGET_MMX"
20581 "pcmpeqb\t{%2, %0|%0, %2}"
20582 [(set_attr "type" "mmxcmp")
20583 (set_attr "mode" "DI")])
20584
20585 (define_insn "eqv4hi3"
20586 [(set (match_operand:V4HI 0 "register_operand" "=y")
20587 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20588 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20589 "TARGET_MMX"
20590 "pcmpeqw\t{%2, %0|%0, %2}"
20591 [(set_attr "type" "mmxcmp")
20592 (set_attr "mode" "DI")])
20593
20594 (define_insn "eqv2si3"
20595 [(set (match_operand:V2SI 0 "register_operand" "=y")
20596 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20597 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20598 "TARGET_MMX"
20599 "pcmpeqd\t{%2, %0|%0, %2}"
20600 [(set_attr "type" "mmxcmp")
20601 (set_attr "mode" "DI")])
20602
20603 (define_insn "gtv8qi3"
20604 [(set (match_operand:V8QI 0 "register_operand" "=y")
20605 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20606 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20607 "TARGET_MMX"
20608 "pcmpgtb\t{%2, %0|%0, %2}"
20609 [(set_attr "type" "mmxcmp")
20610 (set_attr "mode" "DI")])
20611
20612 (define_insn "gtv4hi3"
20613 [(set (match_operand:V4HI 0 "register_operand" "=y")
20614 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20615 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20616 "TARGET_MMX"
20617 "pcmpgtw\t{%2, %0|%0, %2}"
20618 [(set_attr "type" "mmxcmp")
20619 (set_attr "mode" "DI")])
20620
20621 (define_insn "gtv2si3"
20622 [(set (match_operand:V2SI 0 "register_operand" "=y")
20623 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20624 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20625 "TARGET_MMX"
20626 "pcmpgtd\t{%2, %0|%0, %2}"
20627 [(set_attr "type" "mmxcmp")
20628 (set_attr "mode" "DI")])
20629
20630
20631 ;; MMX max/min insns
20632
20633 (define_insn "umaxv8qi3"
20634 [(set (match_operand:V8QI 0 "register_operand" "=y")
20635 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20636 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20637 "TARGET_SSE || TARGET_3DNOW_A"
20638 "pmaxub\t{%2, %0|%0, %2}"
20639 [(set_attr "type" "mmxadd")
20640 (set_attr "mode" "DI")])
20641
20642 (define_insn "smaxv4hi3"
20643 [(set (match_operand:V4HI 0 "register_operand" "=y")
20644 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20645 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20646 "TARGET_SSE || TARGET_3DNOW_A"
20647 "pmaxsw\t{%2, %0|%0, %2}"
20648 [(set_attr "type" "mmxadd")
20649 (set_attr "mode" "DI")])
20650
20651 (define_insn "uminv8qi3"
20652 [(set (match_operand:V8QI 0 "register_operand" "=y")
20653 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20654 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20655 "TARGET_SSE || TARGET_3DNOW_A"
20656 "pminub\t{%2, %0|%0, %2}"
20657 [(set_attr "type" "mmxadd")
20658 (set_attr "mode" "DI")])
20659
20660 (define_insn "sminv4hi3"
20661 [(set (match_operand:V4HI 0 "register_operand" "=y")
20662 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20663 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20664 "TARGET_SSE || TARGET_3DNOW_A"
20665 "pminsw\t{%2, %0|%0, %2}"
20666 [(set_attr "type" "mmxadd")
20667 (set_attr "mode" "DI")])
20668
20669
20670 ;; MMX shifts
20671
20672 (define_insn "ashrv4hi3"
20673 [(set (match_operand:V4HI 0 "register_operand" "=y")
20674 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20675 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20676 "TARGET_MMX"
20677 "psraw\t{%2, %0|%0, %2}"
20678 [(set_attr "type" "mmxshft")
20679 (set_attr "mode" "DI")])
20680
20681 (define_insn "ashrv2si3"
20682 [(set (match_operand:V2SI 0 "register_operand" "=y")
20683 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20684 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20685 "TARGET_MMX"
20686 "psrad\t{%2, %0|%0, %2}"
20687 [(set_attr "type" "mmxshft")
20688 (set_attr "mode" "DI")])
20689
20690 (define_insn "lshrv4hi3"
20691 [(set (match_operand:V4HI 0 "register_operand" "=y")
20692 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20693 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20694 "TARGET_MMX"
20695 "psrlw\t{%2, %0|%0, %2}"
20696 [(set_attr "type" "mmxshft")
20697 (set_attr "mode" "DI")])
20698
20699 (define_insn "lshrv2si3"
20700 [(set (match_operand:V2SI 0 "register_operand" "=y")
20701 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20702 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20703 "TARGET_MMX"
20704 "psrld\t{%2, %0|%0, %2}"
20705 [(set_attr "type" "mmxshft")
20706 (set_attr "mode" "DI")])
20707
20708 ;; See logical MMX insns.
20709 (define_insn "mmx_lshrdi3"
20710 [(set (match_operand:DI 0 "register_operand" "=y")
20711 (unspec:DI
20712 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20713 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20714 UNSPEC_NOP))]
20715 "TARGET_MMX"
20716 "psrlq\t{%2, %0|%0, %2}"
20717 [(set_attr "type" "mmxshft")
20718 (set_attr "mode" "DI")])
20719
20720 (define_insn "ashlv4hi3"
20721 [(set (match_operand:V4HI 0 "register_operand" "=y")
20722 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20723 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20724 "TARGET_MMX"
20725 "psllw\t{%2, %0|%0, %2}"
20726 [(set_attr "type" "mmxshft")
20727 (set_attr "mode" "DI")])
20728
20729 (define_insn "ashlv2si3"
20730 [(set (match_operand:V2SI 0 "register_operand" "=y")
20731 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20732 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20733 "TARGET_MMX"
20734 "pslld\t{%2, %0|%0, %2}"
20735 [(set_attr "type" "mmxshft")
20736 (set_attr "mode" "DI")])
20737
20738 ;; See logical MMX insns.
20739 (define_insn "mmx_ashldi3"
20740 [(set (match_operand:DI 0 "register_operand" "=y")
20741 (unspec:DI
20742 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20743 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20744 UNSPEC_NOP))]
20745 "TARGET_MMX"
20746 "psllq\t{%2, %0|%0, %2}"
20747 [(set_attr "type" "mmxshft")
20748 (set_attr "mode" "DI")])
20749
20750
20751 ;; MMX pack/unpack insns.
20752
20753 (define_insn "mmx_packsswb"
20754 [(set (match_operand:V8QI 0 "register_operand" "=y")
20755 (vec_concat:V8QI
20756 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20757 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20758 "TARGET_MMX"
20759 "packsswb\t{%2, %0|%0, %2}"
20760 [(set_attr "type" "mmxshft")
20761 (set_attr "mode" "DI")])
20762
20763 (define_insn "mmx_packssdw"
20764 [(set (match_operand:V4HI 0 "register_operand" "=y")
20765 (vec_concat:V4HI
20766 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20767 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20768 "TARGET_MMX"
20769 "packssdw\t{%2, %0|%0, %2}"
20770 [(set_attr "type" "mmxshft")
20771 (set_attr "mode" "DI")])
20772
20773 (define_insn "mmx_packuswb"
20774 [(set (match_operand:V8QI 0 "register_operand" "=y")
20775 (vec_concat:V8QI
20776 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20777 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20778 "TARGET_MMX"
20779 "packuswb\t{%2, %0|%0, %2}"
20780 [(set_attr "type" "mmxshft")
20781 (set_attr "mode" "DI")])
20782
20783 (define_insn "mmx_punpckhbw"
20784 [(set (match_operand:V8QI 0 "register_operand" "=y")
20785 (vec_merge:V8QI
20786 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20787 (parallel [(const_int 4)
20788 (const_int 0)
20789 (const_int 5)
20790 (const_int 1)
20791 (const_int 6)
20792 (const_int 2)
20793 (const_int 7)
20794 (const_int 3)]))
20795 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20796 (parallel [(const_int 0)
20797 (const_int 4)
20798 (const_int 1)
20799 (const_int 5)
20800 (const_int 2)
20801 (const_int 6)
20802 (const_int 3)
20803 (const_int 7)]))
20804 (const_int 85)))]
20805 "TARGET_MMX"
20806 "punpckhbw\t{%2, %0|%0, %2}"
20807 [(set_attr "type" "mmxcvt")
20808 (set_attr "mode" "DI")])
20809
20810 (define_insn "mmx_punpckhwd"
20811 [(set (match_operand:V4HI 0 "register_operand" "=y")
20812 (vec_merge:V4HI
20813 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20814 (parallel [(const_int 0)
20815 (const_int 2)
20816 (const_int 1)
20817 (const_int 3)]))
20818 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20819 (parallel [(const_int 2)
20820 (const_int 0)
20821 (const_int 3)
20822 (const_int 1)]))
20823 (const_int 5)))]
20824 "TARGET_MMX"
20825 "punpckhwd\t{%2, %0|%0, %2}"
20826 [(set_attr "type" "mmxcvt")
20827 (set_attr "mode" "DI")])
20828
20829 (define_insn "mmx_punpckhdq"
20830 [(set (match_operand:V2SI 0 "register_operand" "=y")
20831 (vec_merge:V2SI
20832 (match_operand:V2SI 1 "register_operand" "0")
20833 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20834 (parallel [(const_int 1)
20835 (const_int 0)]))
20836 (const_int 1)))]
20837 "TARGET_MMX"
20838 "punpckhdq\t{%2, %0|%0, %2}"
20839 [(set_attr "type" "mmxcvt")
20840 (set_attr "mode" "DI")])
20841
20842 (define_insn "mmx_punpcklbw"
20843 [(set (match_operand:V8QI 0 "register_operand" "=y")
20844 (vec_merge:V8QI
20845 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20846 (parallel [(const_int 0)
20847 (const_int 4)
20848 (const_int 1)
20849 (const_int 5)
20850 (const_int 2)
20851 (const_int 6)
20852 (const_int 3)
20853 (const_int 7)]))
20854 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20855 (parallel [(const_int 4)
20856 (const_int 0)
20857 (const_int 5)
20858 (const_int 1)
20859 (const_int 6)
20860 (const_int 2)
20861 (const_int 7)
20862 (const_int 3)]))
20863 (const_int 85)))]
20864 "TARGET_MMX"
20865 "punpcklbw\t{%2, %0|%0, %2}"
20866 [(set_attr "type" "mmxcvt")
20867 (set_attr "mode" "DI")])
20868
20869 (define_insn "mmx_punpcklwd"
20870 [(set (match_operand:V4HI 0 "register_operand" "=y")
20871 (vec_merge:V4HI
20872 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20873 (parallel [(const_int 2)
20874 (const_int 0)
20875 (const_int 3)
20876 (const_int 1)]))
20877 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20878 (parallel [(const_int 0)
20879 (const_int 2)
20880 (const_int 1)
20881 (const_int 3)]))
20882 (const_int 5)))]
20883 "TARGET_MMX"
20884 "punpcklwd\t{%2, %0|%0, %2}"
20885 [(set_attr "type" "mmxcvt")
20886 (set_attr "mode" "DI")])
20887
20888 (define_insn "mmx_punpckldq"
20889 [(set (match_operand:V2SI 0 "register_operand" "=y")
20890 (vec_merge:V2SI
20891 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20892 (parallel [(const_int 1)
20893 (const_int 0)]))
20894 (match_operand:V2SI 2 "register_operand" "y")
20895 (const_int 1)))]
20896 "TARGET_MMX"
20897 "punpckldq\t{%2, %0|%0, %2}"
20898 [(set_attr "type" "mmxcvt")
20899 (set_attr "mode" "DI")])
20900
20901
20902 ;; Miscellaneous stuff
20903
20904 (define_insn "emms"
20905 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20906 (clobber (reg:XF 8))
20907 (clobber (reg:XF 9))
20908 (clobber (reg:XF 10))
20909 (clobber (reg:XF 11))
20910 (clobber (reg:XF 12))
20911 (clobber (reg:XF 13))
20912 (clobber (reg:XF 14))
20913 (clobber (reg:XF 15))
20914 (clobber (reg:DI 29))
20915 (clobber (reg:DI 30))
20916 (clobber (reg:DI 31))
20917 (clobber (reg:DI 32))
20918 (clobber (reg:DI 33))
20919 (clobber (reg:DI 34))
20920 (clobber (reg:DI 35))
20921 (clobber (reg:DI 36))]
20922 "TARGET_MMX"
20923 "emms"
20924 [(set_attr "type" "mmx")
20925 (set_attr "memory" "unknown")])
20926
20927 (define_insn "ldmxcsr"
20928 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20929 UNSPECV_LDMXCSR)]
20930 "TARGET_SSE"
20931 "ldmxcsr\t%0"
20932 [(set_attr "type" "sse")
20933 (set_attr "memory" "load")])
20934
20935 (define_insn "stmxcsr"
20936 [(set (match_operand:SI 0 "memory_operand" "=m")
20937 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20938 "TARGET_SSE"
20939 "stmxcsr\t%0"
20940 [(set_attr "type" "sse")
20941 (set_attr "memory" "store")])
20942
20943 (define_expand "sfence"
20944 [(set (match_dup 0)
20945 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20946 "TARGET_SSE || TARGET_3DNOW_A"
20947 {
20948 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20949 MEM_VOLATILE_P (operands[0]) = 1;
20950 })
20951
20952 (define_insn "*sfence_insn"
20953 [(set (match_operand:BLK 0 "" "")
20954 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20955 "TARGET_SSE || TARGET_3DNOW_A"
20956 "sfence"
20957 [(set_attr "type" "sse")
20958 (set_attr "memory" "unknown")])
20959
20960 (define_expand "sse_prologue_save"
20961 [(parallel [(set (match_operand:BLK 0 "" "")
20962 (unspec:BLK [(reg:DI 21)
20963 (reg:DI 22)
20964 (reg:DI 23)
20965 (reg:DI 24)
20966 (reg:DI 25)
20967 (reg:DI 26)
20968 (reg:DI 27)
20969 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20970 (use (match_operand:DI 1 "register_operand" ""))
20971 (use (match_operand:DI 2 "immediate_operand" ""))
20972 (use (label_ref:DI (match_operand 3 "" "")))])]
20973 "TARGET_64BIT"
20974 "")
20975
20976 (define_insn "*sse_prologue_save_insn"
20977 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20978 (match_operand:DI 4 "const_int_operand" "n")))
20979 (unspec:BLK [(reg:DI 21)
20980 (reg:DI 22)
20981 (reg:DI 23)
20982 (reg:DI 24)
20983 (reg:DI 25)
20984 (reg:DI 26)
20985 (reg:DI 27)
20986 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20987 (use (match_operand:DI 1 "register_operand" "r"))
20988 (use (match_operand:DI 2 "const_int_operand" "i"))
20989 (use (label_ref:DI (match_operand 3 "" "X")))]
20990 "TARGET_64BIT
20991 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20992 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20993 "*
20994 {
20995 int i;
20996 operands[0] = gen_rtx_MEM (Pmode,
20997 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20998 output_asm_insn (\"jmp\\t%A1\", operands);
20999 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21000 {
21001 operands[4] = adjust_address (operands[0], DImode, i*16);
21002 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21003 PUT_MODE (operands[4], TImode);
21004 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21005 output_asm_insn (\"rex\", operands);
21006 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21007 }
21008 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21009 CODE_LABEL_NUMBER (operands[3]));
21010 RET;
21011 }
21012 "
21013 [(set_attr "type" "other")
21014 (set_attr "length_immediate" "0")
21015 (set_attr "length_address" "0")
21016 (set_attr "length" "135")
21017 (set_attr "memory" "store")
21018 (set_attr "modrm" "0")
21019 (set_attr "mode" "DI")])
21020
21021 ;; 3Dnow! instructions
21022
21023 (define_insn "addv2sf3"
21024 [(set (match_operand:V2SF 0 "register_operand" "=y")
21025 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21026 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21027 "TARGET_3DNOW"
21028 "pfadd\\t{%2, %0|%0, %2}"
21029 [(set_attr "type" "mmxadd")
21030 (set_attr "mode" "V2SF")])
21031
21032 (define_insn "subv2sf3"
21033 [(set (match_operand:V2SF 0 "register_operand" "=y")
21034 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21035 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21036 "TARGET_3DNOW"
21037 "pfsub\\t{%2, %0|%0, %2}"
21038 [(set_attr "type" "mmxadd")
21039 (set_attr "mode" "V2SF")])
21040
21041 (define_insn "subrv2sf3"
21042 [(set (match_operand:V2SF 0 "register_operand" "=y")
21043 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21044 (match_operand:V2SF 1 "register_operand" "0")))]
21045 "TARGET_3DNOW"
21046 "pfsubr\\t{%2, %0|%0, %2}"
21047 [(set_attr "type" "mmxadd")
21048 (set_attr "mode" "V2SF")])
21049
21050 (define_insn "gtv2sf3"
21051 [(set (match_operand:V2SI 0 "register_operand" "=y")
21052 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21053 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21054 "TARGET_3DNOW"
21055 "pfcmpgt\\t{%2, %0|%0, %2}"
21056 [(set_attr "type" "mmxcmp")
21057 (set_attr "mode" "V2SF")])
21058
21059 (define_insn "gev2sf3"
21060 [(set (match_operand:V2SI 0 "register_operand" "=y")
21061 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21062 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21063 "TARGET_3DNOW"
21064 "pfcmpge\\t{%2, %0|%0, %2}"
21065 [(set_attr "type" "mmxcmp")
21066 (set_attr "mode" "V2SF")])
21067
21068 (define_insn "eqv2sf3"
21069 [(set (match_operand:V2SI 0 "register_operand" "=y")
21070 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21071 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21072 "TARGET_3DNOW"
21073 "pfcmpeq\\t{%2, %0|%0, %2}"
21074 [(set_attr "type" "mmxcmp")
21075 (set_attr "mode" "V2SF")])
21076
21077 (define_insn "pfmaxv2sf3"
21078 [(set (match_operand:V2SF 0 "register_operand" "=y")
21079 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21080 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21081 "TARGET_3DNOW"
21082 "pfmax\\t{%2, %0|%0, %2}"
21083 [(set_attr "type" "mmxadd")
21084 (set_attr "mode" "V2SF")])
21085
21086 (define_insn "pfminv2sf3"
21087 [(set (match_operand:V2SF 0 "register_operand" "=y")
21088 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21089 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21090 "TARGET_3DNOW"
21091 "pfmin\\t{%2, %0|%0, %2}"
21092 [(set_attr "type" "mmxadd")
21093 (set_attr "mode" "V2SF")])
21094
21095 (define_insn "mulv2sf3"
21096 [(set (match_operand:V2SF 0 "register_operand" "=y")
21097 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21098 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21099 "TARGET_3DNOW"
21100 "pfmul\\t{%2, %0|%0, %2}"
21101 [(set_attr "type" "mmxmul")
21102 (set_attr "mode" "V2SF")])
21103
21104 (define_insn "femms"
21105 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21106 (clobber (reg:XF 8))
21107 (clobber (reg:XF 9))
21108 (clobber (reg:XF 10))
21109 (clobber (reg:XF 11))
21110 (clobber (reg:XF 12))
21111 (clobber (reg:XF 13))
21112 (clobber (reg:XF 14))
21113 (clobber (reg:XF 15))
21114 (clobber (reg:DI 29))
21115 (clobber (reg:DI 30))
21116 (clobber (reg:DI 31))
21117 (clobber (reg:DI 32))
21118 (clobber (reg:DI 33))
21119 (clobber (reg:DI 34))
21120 (clobber (reg:DI 35))
21121 (clobber (reg:DI 36))]
21122 "TARGET_3DNOW"
21123 "femms"
21124 [(set_attr "type" "mmx")
21125 (set_attr "memory" "none")])
21126
21127 (define_insn "pf2id"
21128 [(set (match_operand:V2SI 0 "register_operand" "=y")
21129 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21130 "TARGET_3DNOW"
21131 "pf2id\\t{%1, %0|%0, %1}"
21132 [(set_attr "type" "mmxcvt")
21133 (set_attr "mode" "V2SF")])
21134
21135 (define_insn "pf2iw"
21136 [(set (match_operand:V2SI 0 "register_operand" "=y")
21137 (sign_extend:V2SI
21138 (ss_truncate:V2HI
21139 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21140 "TARGET_3DNOW_A"
21141 "pf2iw\\t{%1, %0|%0, %1}"
21142 [(set_attr "type" "mmxcvt")
21143 (set_attr "mode" "V2SF")])
21144
21145 (define_insn "pfacc"
21146 [(set (match_operand:V2SF 0 "register_operand" "=y")
21147 (vec_concat:V2SF
21148 (plus:SF
21149 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21150 (parallel [(const_int 0)]))
21151 (vec_select:SF (match_dup 1)
21152 (parallel [(const_int 1)])))
21153 (plus:SF
21154 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21155 (parallel [(const_int 0)]))
21156 (vec_select:SF (match_dup 2)
21157 (parallel [(const_int 1)])))))]
21158 "TARGET_3DNOW"
21159 "pfacc\\t{%2, %0|%0, %2}"
21160 [(set_attr "type" "mmxadd")
21161 (set_attr "mode" "V2SF")])
21162
21163 (define_insn "pfnacc"
21164 [(set (match_operand:V2SF 0 "register_operand" "=y")
21165 (vec_concat:V2SF
21166 (minus:SF
21167 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21168 (parallel [(const_int 0)]))
21169 (vec_select:SF (match_dup 1)
21170 (parallel [(const_int 1)])))
21171 (minus:SF
21172 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21173 (parallel [(const_int 0)]))
21174 (vec_select:SF (match_dup 2)
21175 (parallel [(const_int 1)])))))]
21176 "TARGET_3DNOW_A"
21177 "pfnacc\\t{%2, %0|%0, %2}"
21178 [(set_attr "type" "mmxadd")
21179 (set_attr "mode" "V2SF")])
21180
21181 (define_insn "pfpnacc"
21182 [(set (match_operand:V2SF 0 "register_operand" "=y")
21183 (vec_concat:V2SF
21184 (minus:SF
21185 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21186 (parallel [(const_int 0)]))
21187 (vec_select:SF (match_dup 1)
21188 (parallel [(const_int 1)])))
21189 (plus:SF
21190 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21191 (parallel [(const_int 0)]))
21192 (vec_select:SF (match_dup 2)
21193 (parallel [(const_int 1)])))))]
21194 "TARGET_3DNOW_A"
21195 "pfpnacc\\t{%2, %0|%0, %2}"
21196 [(set_attr "type" "mmxadd")
21197 (set_attr "mode" "V2SF")])
21198
21199 (define_insn "pi2fw"
21200 [(set (match_operand:V2SF 0 "register_operand" "=y")
21201 (float:V2SF
21202 (vec_concat:V2SI
21203 (sign_extend:SI
21204 (truncate:HI
21205 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21206 (parallel [(const_int 0)]))))
21207 (sign_extend:SI
21208 (truncate:HI
21209 (vec_select:SI (match_dup 1)
21210 (parallel [(const_int 1)])))))))]
21211 "TARGET_3DNOW_A"
21212 "pi2fw\\t{%1, %0|%0, %1}"
21213 [(set_attr "type" "mmxcvt")
21214 (set_attr "mode" "V2SF")])
21215
21216 (define_insn "floatv2si2"
21217 [(set (match_operand:V2SF 0 "register_operand" "=y")
21218 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21219 "TARGET_3DNOW"
21220 "pi2fd\\t{%1, %0|%0, %1}"
21221 [(set_attr "type" "mmxcvt")
21222 (set_attr "mode" "V2SF")])
21223
21224 ;; This insn is identical to pavgb in operation, but the opcode is
21225 ;; different. To avoid accidentally matching pavgb, use an unspec.
21226
21227 (define_insn "pavgusb"
21228 [(set (match_operand:V8QI 0 "register_operand" "=y")
21229 (unspec:V8QI
21230 [(match_operand:V8QI 1 "register_operand" "0")
21231 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21232 UNSPEC_PAVGUSB))]
21233 "TARGET_3DNOW"
21234 "pavgusb\\t{%2, %0|%0, %2}"
21235 [(set_attr "type" "mmxshft")
21236 (set_attr "mode" "TI")])
21237
21238 ;; 3DNow reciprocal and sqrt
21239
21240 (define_insn "pfrcpv2sf2"
21241 [(set (match_operand:V2SF 0 "register_operand" "=y")
21242 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21243 UNSPEC_PFRCP))]
21244 "TARGET_3DNOW"
21245 "pfrcp\\t{%1, %0|%0, %1}"
21246 [(set_attr "type" "mmx")
21247 (set_attr "mode" "TI")])
21248
21249 (define_insn "pfrcpit1v2sf3"
21250 [(set (match_operand:V2SF 0 "register_operand" "=y")
21251 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21252 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21253 UNSPEC_PFRCPIT1))]
21254 "TARGET_3DNOW"
21255 "pfrcpit1\\t{%2, %0|%0, %2}"
21256 [(set_attr "type" "mmx")
21257 (set_attr "mode" "TI")])
21258
21259 (define_insn "pfrcpit2v2sf3"
21260 [(set (match_operand:V2SF 0 "register_operand" "=y")
21261 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21262 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21263 UNSPEC_PFRCPIT2))]
21264 "TARGET_3DNOW"
21265 "pfrcpit2\\t{%2, %0|%0, %2}"
21266 [(set_attr "type" "mmx")
21267 (set_attr "mode" "TI")])
21268
21269 (define_insn "pfrsqrtv2sf2"
21270 [(set (match_operand:V2SF 0 "register_operand" "=y")
21271 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21272 UNSPEC_PFRSQRT))]
21273 "TARGET_3DNOW"
21274 "pfrsqrt\\t{%1, %0|%0, %1}"
21275 [(set_attr "type" "mmx")
21276 (set_attr "mode" "TI")])
21277
21278 (define_insn "pfrsqit1v2sf3"
21279 [(set (match_operand:V2SF 0 "register_operand" "=y")
21280 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21281 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21282 UNSPEC_PFRSQIT1))]
21283 "TARGET_3DNOW"
21284 "pfrsqit1\\t{%2, %0|%0, %2}"
21285 [(set_attr "type" "mmx")
21286 (set_attr "mode" "TI")])
21287
21288 (define_insn "pmulhrwv4hi3"
21289 [(set (match_operand:V4HI 0 "register_operand" "=y")
21290 (truncate:V4HI
21291 (lshiftrt:V4SI
21292 (plus:V4SI
21293 (mult:V4SI
21294 (sign_extend:V4SI
21295 (match_operand:V4HI 1 "register_operand" "0"))
21296 (sign_extend:V4SI
21297 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21298 (const_vector:V4SI [(const_int 32768)
21299 (const_int 32768)
21300 (const_int 32768)
21301 (const_int 32768)]))
21302 (const_int 16))))]
21303 "TARGET_3DNOW"
21304 "pmulhrw\\t{%2, %0|%0, %2}"
21305 [(set_attr "type" "mmxmul")
21306 (set_attr "mode" "TI")])
21307
21308 (define_insn "pswapdv2si2"
21309 [(set (match_operand:V2SI 0 "register_operand" "=y")
21310 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21311 (parallel [(const_int 1) (const_int 0)])))]
21312 "TARGET_3DNOW_A"
21313 "pswapd\\t{%1, %0|%0, %1}"
21314 [(set_attr "type" "mmxcvt")
21315 (set_attr "mode" "TI")])
21316
21317 (define_insn "pswapdv2sf2"
21318 [(set (match_operand:V2SF 0 "register_operand" "=y")
21319 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21320 (parallel [(const_int 1) (const_int 0)])))]
21321 "TARGET_3DNOW_A"
21322 "pswapd\\t{%1, %0|%0, %1}"
21323 [(set_attr "type" "mmxcvt")
21324 (set_attr "mode" "TI")])
21325
21326 (define_expand "prefetch"
21327 [(prefetch (match_operand 0 "address_operand" "")
21328 (match_operand:SI 1 "const_int_operand" "")
21329 (match_operand:SI 2 "const_int_operand" ""))]
21330 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21331 {
21332 int rw = INTVAL (operands[1]);
21333 int locality = INTVAL (operands[2]);
21334
21335 if (rw != 0 && rw != 1)
21336 abort ();
21337 if (locality < 0 || locality > 3)
21338 abort ();
21339 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21340 abort ();
21341
21342 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21343 suported by SSE counterpart or the SSE prefetch is not available
21344 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21345 of locality. */
21346 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21347 operands[2] = GEN_INT (3);
21348 else
21349 operands[1] = const0_rtx;
21350 })
21351
21352 (define_insn "*prefetch_sse"
21353 [(prefetch (match_operand:SI 0 "address_operand" "p")
21354 (const_int 0)
21355 (match_operand:SI 1 "const_int_operand" ""))]
21356 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21357 {
21358 static const char * const patterns[4] = {
21359 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21360 };
21361
21362 int locality = INTVAL (operands[1]);
21363 if (locality < 0 || locality > 3)
21364 abort ();
21365
21366 return patterns[locality];
21367 }
21368 [(set_attr "type" "sse")
21369 (set_attr "memory" "none")])
21370
21371 (define_insn "*prefetch_sse_rex"
21372 [(prefetch (match_operand:DI 0 "address_operand" "p")
21373 (const_int 0)
21374 (match_operand:SI 1 "const_int_operand" ""))]
21375 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21376 {
21377 static const char * const patterns[4] = {
21378 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21379 };
21380
21381 int locality = INTVAL (operands[1]);
21382 if (locality < 0 || locality > 3)
21383 abort ();
21384
21385 return patterns[locality];
21386 }
21387 [(set_attr "type" "sse")
21388 (set_attr "memory" "none")])
21389
21390 (define_insn "*prefetch_3dnow"
21391 [(prefetch (match_operand:SI 0 "address_operand" "p")
21392 (match_operand:SI 1 "const_int_operand" "n")
21393 (const_int 3))]
21394 "TARGET_3DNOW && !TARGET_64BIT"
21395 {
21396 if (INTVAL (operands[1]) == 0)
21397 return "prefetch\t%a0";
21398 else
21399 return "prefetchw\t%a0";
21400 }
21401 [(set_attr "type" "mmx")
21402 (set_attr "memory" "none")])
21403
21404 (define_insn "*prefetch_3dnow_rex"
21405 [(prefetch (match_operand:DI 0 "address_operand" "p")
21406 (match_operand:SI 1 "const_int_operand" "n")
21407 (const_int 3))]
21408 "TARGET_3DNOW && TARGET_64BIT"
21409 {
21410 if (INTVAL (operands[1]) == 0)
21411 return "prefetch\t%a0";
21412 else
21413 return "prefetchw\t%a0";
21414 }
21415 [(set_attr "type" "mmx")
21416 (set_attr "memory" "none")])
21417
21418 ;; SSE2 support
21419
21420 (define_insn "addv2df3"
21421 [(set (match_operand:V2DF 0 "register_operand" "=x")
21422 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21423 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21424 "TARGET_SSE2"
21425 "addpd\t{%2, %0|%0, %2}"
21426 [(set_attr "type" "sseadd")
21427 (set_attr "mode" "V2DF")])
21428
21429 (define_insn "vmaddv2df3"
21430 [(set (match_operand:V2DF 0 "register_operand" "=x")
21431 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21432 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21433 (match_dup 1)
21434 (const_int 1)))]
21435 "TARGET_SSE2"
21436 "addsd\t{%2, %0|%0, %2}"
21437 [(set_attr "type" "sseadd")
21438 (set_attr "mode" "DF")])
21439
21440 (define_insn "subv2df3"
21441 [(set (match_operand:V2DF 0 "register_operand" "=x")
21442 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21443 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21444 "TARGET_SSE2"
21445 "subpd\t{%2, %0|%0, %2}"
21446 [(set_attr "type" "sseadd")
21447 (set_attr "mode" "V2DF")])
21448
21449 (define_insn "vmsubv2df3"
21450 [(set (match_operand:V2DF 0 "register_operand" "=x")
21451 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21452 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21453 (match_dup 1)
21454 (const_int 1)))]
21455 "TARGET_SSE2"
21456 "subsd\t{%2, %0|%0, %2}"
21457 [(set_attr "type" "sseadd")
21458 (set_attr "mode" "DF")])
21459
21460 (define_insn "mulv2df3"
21461 [(set (match_operand:V2DF 0 "register_operand" "=x")
21462 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21463 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21464 "TARGET_SSE2"
21465 "mulpd\t{%2, %0|%0, %2}"
21466 [(set_attr "type" "ssemul")
21467 (set_attr "mode" "V2DF")])
21468
21469 (define_insn "vmmulv2df3"
21470 [(set (match_operand:V2DF 0 "register_operand" "=x")
21471 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21472 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21473 (match_dup 1)
21474 (const_int 1)))]
21475 "TARGET_SSE2"
21476 "mulsd\t{%2, %0|%0, %2}"
21477 [(set_attr "type" "ssemul")
21478 (set_attr "mode" "DF")])
21479
21480 (define_insn "divv2df3"
21481 [(set (match_operand:V2DF 0 "register_operand" "=x")
21482 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21483 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21484 "TARGET_SSE2"
21485 "divpd\t{%2, %0|%0, %2}"
21486 [(set_attr "type" "ssediv")
21487 (set_attr "mode" "V2DF")])
21488
21489 (define_insn "vmdivv2df3"
21490 [(set (match_operand:V2DF 0 "register_operand" "=x")
21491 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21492 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21493 (match_dup 1)
21494 (const_int 1)))]
21495 "TARGET_SSE2"
21496 "divsd\t{%2, %0|%0, %2}"
21497 [(set_attr "type" "ssediv")
21498 (set_attr "mode" "DF")])
21499
21500 ;; SSE min/max
21501
21502 (define_insn "smaxv2df3"
21503 [(set (match_operand:V2DF 0 "register_operand" "=x")
21504 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21505 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21506 "TARGET_SSE2"
21507 "maxpd\t{%2, %0|%0, %2}"
21508 [(set_attr "type" "sseadd")
21509 (set_attr "mode" "V2DF")])
21510
21511 (define_insn "vmsmaxv2df3"
21512 [(set (match_operand:V2DF 0 "register_operand" "=x")
21513 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21514 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21515 (match_dup 1)
21516 (const_int 1)))]
21517 "TARGET_SSE2"
21518 "maxsd\t{%2, %0|%0, %2}"
21519 [(set_attr "type" "sseadd")
21520 (set_attr "mode" "DF")])
21521
21522 (define_insn "sminv2df3"
21523 [(set (match_operand:V2DF 0 "register_operand" "=x")
21524 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21525 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21526 "TARGET_SSE2"
21527 "minpd\t{%2, %0|%0, %2}"
21528 [(set_attr "type" "sseadd")
21529 (set_attr "mode" "V2DF")])
21530
21531 (define_insn "vmsminv2df3"
21532 [(set (match_operand:V2DF 0 "register_operand" "=x")
21533 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21534 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21535 (match_dup 1)
21536 (const_int 1)))]
21537 "TARGET_SSE2"
21538 "minsd\t{%2, %0|%0, %2}"
21539 [(set_attr "type" "sseadd")
21540 (set_attr "mode" "DF")])
21541 ;; SSE2 square root. There doesn't appear to be an extension for the
21542 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21543
21544 (define_insn "sqrtv2df2"
21545 [(set (match_operand:V2DF 0 "register_operand" "=x")
21546 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21547 "TARGET_SSE2"
21548 "sqrtpd\t{%1, %0|%0, %1}"
21549 [(set_attr "type" "sse")
21550 (set_attr "mode" "V2DF")])
21551
21552 (define_insn "vmsqrtv2df2"
21553 [(set (match_operand:V2DF 0 "register_operand" "=x")
21554 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21555 (match_operand:V2DF 2 "register_operand" "0")
21556 (const_int 1)))]
21557 "TARGET_SSE2"
21558 "sqrtsd\t{%1, %0|%0, %1}"
21559 [(set_attr "type" "sse")
21560 (set_attr "mode" "SF")])
21561
21562 ;; SSE mask-generating compares
21563
21564 (define_insn "maskcmpv2df3"
21565 [(set (match_operand:V2DI 0 "register_operand" "=x")
21566 (match_operator:V2DI 3 "sse_comparison_operator"
21567 [(match_operand:V2DF 1 "register_operand" "0")
21568 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21569 "TARGET_SSE2"
21570 "cmp%D3pd\t{%2, %0|%0, %2}"
21571 [(set_attr "type" "ssecmp")
21572 (set_attr "mode" "V2DF")])
21573
21574 (define_insn "maskncmpv2df3"
21575 [(set (match_operand:V2DI 0 "register_operand" "=x")
21576 (not:V2DI
21577 (match_operator:V2DI 3 "sse_comparison_operator"
21578 [(match_operand:V2DF 1 "register_operand" "0")
21579 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21580 "TARGET_SSE2"
21581 {
21582 if (GET_CODE (operands[3]) == UNORDERED)
21583 return "cmpordps\t{%2, %0|%0, %2}";
21584 else
21585 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21586 }
21587 [(set_attr "type" "ssecmp")
21588 (set_attr "mode" "V2DF")])
21589
21590 (define_insn "vmmaskcmpv2df3"
21591 [(set (match_operand:V2DI 0 "register_operand" "=x")
21592 (vec_merge:V2DI
21593 (match_operator:V2DI 3 "sse_comparison_operator"
21594 [(match_operand:V2DF 1 "register_operand" "0")
21595 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21596 (subreg:V2DI (match_dup 1) 0)
21597 (const_int 1)))]
21598 "TARGET_SSE2"
21599 "cmp%D3sd\t{%2, %0|%0, %2}"
21600 [(set_attr "type" "ssecmp")
21601 (set_attr "mode" "DF")])
21602
21603 (define_insn "vmmaskncmpv2df3"
21604 [(set (match_operand:V2DI 0 "register_operand" "=x")
21605 (vec_merge:V2DI
21606 (not:V2DI
21607 (match_operator:V2DI 3 "sse_comparison_operator"
21608 [(match_operand:V2DF 1 "register_operand" "0")
21609 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21610 (subreg:V2DI (match_dup 1) 0)
21611 (const_int 1)))]
21612 "TARGET_SSE2"
21613 {
21614 if (GET_CODE (operands[3]) == UNORDERED)
21615 return "cmpordsd\t{%2, %0|%0, %2}";
21616 else
21617 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21618 }
21619 [(set_attr "type" "ssecmp")
21620 (set_attr "mode" "DF")])
21621
21622 (define_insn "sse2_comi"
21623 [(set (reg:CCFP 17)
21624 (compare:CCFP (vec_select:DF
21625 (match_operand:V2DF 0 "register_operand" "x")
21626 (parallel [(const_int 0)]))
21627 (vec_select:DF
21628 (match_operand:V2DF 1 "register_operand" "x")
21629 (parallel [(const_int 0)]))))]
21630 "TARGET_SSE2"
21631 "comisd\t{%1, %0|%0, %1}"
21632 [(set_attr "type" "ssecomi")
21633 (set_attr "mode" "DF")])
21634
21635 (define_insn "sse2_ucomi"
21636 [(set (reg:CCFPU 17)
21637 (compare:CCFPU (vec_select:DF
21638 (match_operand:V2DF 0 "register_operand" "x")
21639 (parallel [(const_int 0)]))
21640 (vec_select:DF
21641 (match_operand:V2DF 1 "register_operand" "x")
21642 (parallel [(const_int 0)]))))]
21643 "TARGET_SSE2"
21644 "ucomisd\t{%1, %0|%0, %1}"
21645 [(set_attr "type" "ssecomi")
21646 (set_attr "mode" "DF")])
21647
21648 ;; SSE Strange Moves.
21649
21650 (define_insn "sse2_movmskpd"
21651 [(set (match_operand:SI 0 "register_operand" "=r")
21652 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21653 UNSPEC_MOVMSK))]
21654 "TARGET_SSE2"
21655 "movmskpd\t{%1, %0|%0, %1}"
21656 [(set_attr "type" "ssecvt")
21657 (set_attr "mode" "V2DF")])
21658
21659 (define_insn "sse2_pmovmskb"
21660 [(set (match_operand:SI 0 "register_operand" "=r")
21661 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21662 UNSPEC_MOVMSK))]
21663 "TARGET_SSE2"
21664 "pmovmskb\t{%1, %0|%0, %1}"
21665 [(set_attr "type" "ssecvt")
21666 (set_attr "mode" "V2DF")])
21667
21668 (define_insn "sse2_maskmovdqu"
21669 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21670 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21671 (match_operand:V16QI 2 "register_operand" "x")]
21672 UNSPEC_MASKMOV))]
21673 "TARGET_SSE2"
21674 ;; @@@ check ordering of operands in intel/nonintel syntax
21675 "maskmovdqu\t{%2, %1|%1, %2}"
21676 [(set_attr "type" "ssecvt")
21677 (set_attr "mode" "TI")])
21678
21679 (define_insn "sse2_maskmovdqu_rex64"
21680 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21681 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21682 (match_operand:V16QI 2 "register_operand" "x")]
21683 UNSPEC_MASKMOV))]
21684 "TARGET_SSE2"
21685 ;; @@@ check ordering of operands in intel/nonintel syntax
21686 "maskmovdqu\t{%2, %1|%1, %2}"
21687 [(set_attr "type" "ssecvt")
21688 (set_attr "mode" "TI")])
21689
21690 (define_insn "sse2_movntv2df"
21691 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21692 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21693 UNSPEC_MOVNT))]
21694 "TARGET_SSE2"
21695 "movntpd\t{%1, %0|%0, %1}"
21696 [(set_attr "type" "ssecvt")
21697 (set_attr "mode" "V2DF")])
21698
21699 (define_insn "sse2_movntv2di"
21700 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21701 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21702 UNSPEC_MOVNT))]
21703 "TARGET_SSE2"
21704 "movntdq\t{%1, %0|%0, %1}"
21705 [(set_attr "type" "ssecvt")
21706 (set_attr "mode" "TI")])
21707
21708 (define_insn "sse2_movntsi"
21709 [(set (match_operand:SI 0 "memory_operand" "=m")
21710 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21711 UNSPEC_MOVNT))]
21712 "TARGET_SSE2"
21713 "movnti\t{%1, %0|%0, %1}"
21714 [(set_attr "type" "ssecvt")
21715 (set_attr "mode" "V2DF")])
21716
21717 ;; SSE <-> integer/MMX conversions
21718
21719 ;; Conversions between SI and SF
21720
21721 (define_insn "cvtdq2ps"
21722 [(set (match_operand:V4SF 0 "register_operand" "=x")
21723 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21724 "TARGET_SSE2"
21725 "cvtdq2ps\t{%1, %0|%0, %1}"
21726 [(set_attr "type" "ssecvt")
21727 (set_attr "mode" "V2DF")])
21728
21729 (define_insn "cvtps2dq"
21730 [(set (match_operand:V4SI 0 "register_operand" "=x")
21731 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21732 "TARGET_SSE2"
21733 "cvtps2dq\t{%1, %0|%0, %1}"
21734 [(set_attr "type" "ssecvt")
21735 (set_attr "mode" "TI")])
21736
21737 (define_insn "cvttps2dq"
21738 [(set (match_operand:V4SI 0 "register_operand" "=x")
21739 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21740 UNSPEC_FIX))]
21741 "TARGET_SSE2"
21742 "cvttps2dq\t{%1, %0|%0, %1}"
21743 [(set_attr "type" "ssecvt")
21744 (set_attr "mode" "TI")])
21745
21746 ;; Conversions between SI and DF
21747
21748 (define_insn "cvtdq2pd"
21749 [(set (match_operand:V2DF 0 "register_operand" "=x")
21750 (float:V2DF (vec_select:V2SI
21751 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21752 (parallel
21753 [(const_int 0)
21754 (const_int 1)]))))]
21755 "TARGET_SSE2"
21756 "cvtdq2pd\t{%1, %0|%0, %1}"
21757 [(set_attr "type" "ssecvt")
21758 (set_attr "mode" "V2DF")])
21759
21760 (define_insn "cvtpd2dq"
21761 [(set (match_operand:V4SI 0 "register_operand" "=x")
21762 (vec_concat:V4SI
21763 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21764 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21765 "TARGET_SSE2"
21766 "cvtpd2dq\t{%1, %0|%0, %1}"
21767 [(set_attr "type" "ssecvt")
21768 (set_attr "mode" "TI")])
21769
21770 (define_insn "cvttpd2dq"
21771 [(set (match_operand:V4SI 0 "register_operand" "=x")
21772 (vec_concat:V4SI
21773 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21774 UNSPEC_FIX)
21775 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21776 "TARGET_SSE2"
21777 "cvttpd2dq\t{%1, %0|%0, %1}"
21778 [(set_attr "type" "ssecvt")
21779 (set_attr "mode" "TI")])
21780
21781 (define_insn "cvtpd2pi"
21782 [(set (match_operand:V2SI 0 "register_operand" "=y")
21783 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21784 "TARGET_SSE2"
21785 "cvtpd2pi\t{%1, %0|%0, %1}"
21786 [(set_attr "type" "ssecvt")
21787 (set_attr "mode" "TI")])
21788
21789 (define_insn "cvttpd2pi"
21790 [(set (match_operand:V2SI 0 "register_operand" "=y")
21791 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21792 UNSPEC_FIX))]
21793 "TARGET_SSE2"
21794 "cvttpd2pi\t{%1, %0|%0, %1}"
21795 [(set_attr "type" "ssecvt")
21796 (set_attr "mode" "TI")])
21797
21798 (define_insn "cvtpi2pd"
21799 [(set (match_operand:V2DF 0 "register_operand" "=x")
21800 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21801 "TARGET_SSE2"
21802 "cvtpi2pd\t{%1, %0|%0, %1}"
21803 [(set_attr "type" "ssecvt")
21804 (set_attr "mode" "TI")])
21805
21806 ;; Conversions between SI and DF
21807
21808 (define_insn "cvtsd2si"
21809 [(set (match_operand:SI 0 "register_operand" "=r,r")
21810 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21811 (parallel [(const_int 0)]))))]
21812 "TARGET_SSE2"
21813 "cvtsd2si\t{%1, %0|%0, %1}"
21814 [(set_attr "type" "sseicvt")
21815 (set_attr "athlon_decode" "double,vector")
21816 (set_attr "mode" "SI")])
21817
21818 (define_insn "cvtsd2siq"
21819 [(set (match_operand:DI 0 "register_operand" "=r,r")
21820 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21821 (parallel [(const_int 0)]))))]
21822 "TARGET_SSE2 && TARGET_64BIT"
21823 "cvtsd2siq\t{%1, %0|%0, %1}"
21824 [(set_attr "type" "sseicvt")
21825 (set_attr "athlon_decode" "double,vector")
21826 (set_attr "mode" "DI")])
21827
21828 (define_insn "cvttsd2si"
21829 [(set (match_operand:SI 0 "register_operand" "=r,r")
21830 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21831 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21832 "TARGET_SSE2"
21833 "cvttsd2si\t{%1, %0|%0, %1}"
21834 [(set_attr "type" "sseicvt")
21835 (set_attr "mode" "SI")
21836 (set_attr "athlon_decode" "double,vector")])
21837
21838 (define_insn "cvttsd2siq"
21839 [(set (match_operand:DI 0 "register_operand" "=r,r")
21840 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21841 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21842 "TARGET_SSE2 && TARGET_64BIT"
21843 "cvttsd2siq\t{%1, %0|%0, %1}"
21844 [(set_attr "type" "sseicvt")
21845 (set_attr "mode" "DI")
21846 (set_attr "athlon_decode" "double,vector")])
21847
21848 (define_insn "cvtsi2sd"
21849 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21850 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21851 (vec_duplicate:V2DF
21852 (float:DF
21853 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21854 (const_int 2)))]
21855 "TARGET_SSE2"
21856 "cvtsi2sd\t{%2, %0|%0, %2}"
21857 [(set_attr "type" "sseicvt")
21858 (set_attr "mode" "DF")
21859 (set_attr "athlon_decode" "double,direct")])
21860
21861 (define_insn "cvtsi2sdq"
21862 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21863 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21864 (vec_duplicate:V2DF
21865 (float:DF
21866 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21867 (const_int 2)))]
21868 "TARGET_SSE2 && TARGET_64BIT"
21869 "cvtsi2sdq\t{%2, %0|%0, %2}"
21870 [(set_attr "type" "sseicvt")
21871 (set_attr "mode" "DF")
21872 (set_attr "athlon_decode" "double,direct")])
21873
21874 ;; Conversions between SF and DF
21875
21876 (define_insn "cvtsd2ss"
21877 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21878 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21879 (vec_duplicate:V4SF
21880 (float_truncate:V2SF
21881 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21882 (const_int 14)))]
21883 "TARGET_SSE2"
21884 "cvtsd2ss\t{%2, %0|%0, %2}"
21885 [(set_attr "type" "ssecvt")
21886 (set_attr "athlon_decode" "vector,double")
21887 (set_attr "mode" "SF")])
21888
21889 (define_insn "cvtss2sd"
21890 [(set (match_operand:V2DF 0 "register_operand" "=x")
21891 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21892 (float_extend:V2DF
21893 (vec_select:V2SF
21894 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21895 (parallel [(const_int 0)
21896 (const_int 1)])))
21897 (const_int 2)))]
21898 "TARGET_SSE2"
21899 "cvtss2sd\t{%2, %0|%0, %2}"
21900 [(set_attr "type" "ssecvt")
21901 (set_attr "mode" "DF")])
21902
21903 (define_insn "cvtpd2ps"
21904 [(set (match_operand:V4SF 0 "register_operand" "=x")
21905 (subreg:V4SF
21906 (vec_concat:V4SI
21907 (subreg:V2SI (float_truncate:V2SF
21908 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21909 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21910 "TARGET_SSE2"
21911 "cvtpd2ps\t{%1, %0|%0, %1}"
21912 [(set_attr "type" "ssecvt")
21913 (set_attr "mode" "V4SF")])
21914
21915 (define_insn "cvtps2pd"
21916 [(set (match_operand:V2DF 0 "register_operand" "=x")
21917 (float_extend:V2DF
21918 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21919 (parallel [(const_int 0)
21920 (const_int 1)]))))]
21921 "TARGET_SSE2"
21922 "cvtps2pd\t{%1, %0|%0, %1}"
21923 [(set_attr "type" "ssecvt")
21924 (set_attr "mode" "V2DF")])
21925
21926 ;; SSE2 variants of MMX insns
21927
21928 ;; MMX arithmetic
21929
21930 (define_insn "addv16qi3"
21931 [(set (match_operand:V16QI 0 "register_operand" "=x")
21932 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21933 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21934 "TARGET_SSE2"
21935 "paddb\t{%2, %0|%0, %2}"
21936 [(set_attr "type" "sseiadd")
21937 (set_attr "mode" "TI")])
21938
21939 (define_insn "addv8hi3"
21940 [(set (match_operand:V8HI 0 "register_operand" "=x")
21941 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21942 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21943 "TARGET_SSE2"
21944 "paddw\t{%2, %0|%0, %2}"
21945 [(set_attr "type" "sseiadd")
21946 (set_attr "mode" "TI")])
21947
21948 (define_insn "addv4si3"
21949 [(set (match_operand:V4SI 0 "register_operand" "=x")
21950 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21951 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21952 "TARGET_SSE2"
21953 "paddd\t{%2, %0|%0, %2}"
21954 [(set_attr "type" "sseiadd")
21955 (set_attr "mode" "TI")])
21956
21957 (define_insn "addv2di3"
21958 [(set (match_operand:V2DI 0 "register_operand" "=x")
21959 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21960 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21961 "TARGET_SSE2"
21962 "paddq\t{%2, %0|%0, %2}"
21963 [(set_attr "type" "sseiadd")
21964 (set_attr "mode" "TI")])
21965
21966 (define_insn "ssaddv16qi3"
21967 [(set (match_operand:V16QI 0 "register_operand" "=x")
21968 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21969 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21970 "TARGET_SSE2"
21971 "paddsb\t{%2, %0|%0, %2}"
21972 [(set_attr "type" "sseiadd")
21973 (set_attr "mode" "TI")])
21974
21975 (define_insn "ssaddv8hi3"
21976 [(set (match_operand:V8HI 0 "register_operand" "=x")
21977 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21978 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21979 "TARGET_SSE2"
21980 "paddsw\t{%2, %0|%0, %2}"
21981 [(set_attr "type" "sseiadd")
21982 (set_attr "mode" "TI")])
21983
21984 (define_insn "usaddv16qi3"
21985 [(set (match_operand:V16QI 0 "register_operand" "=x")
21986 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21987 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21988 "TARGET_SSE2"
21989 "paddusb\t{%2, %0|%0, %2}"
21990 [(set_attr "type" "sseiadd")
21991 (set_attr "mode" "TI")])
21992
21993 (define_insn "usaddv8hi3"
21994 [(set (match_operand:V8HI 0 "register_operand" "=x")
21995 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21996 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21997 "TARGET_SSE2"
21998 "paddusw\t{%2, %0|%0, %2}"
21999 [(set_attr "type" "sseiadd")
22000 (set_attr "mode" "TI")])
22001
22002 (define_insn "subv16qi3"
22003 [(set (match_operand:V16QI 0 "register_operand" "=x")
22004 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22005 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22006 "TARGET_SSE2"
22007 "psubb\t{%2, %0|%0, %2}"
22008 [(set_attr "type" "sseiadd")
22009 (set_attr "mode" "TI")])
22010
22011 (define_insn "subv8hi3"
22012 [(set (match_operand:V8HI 0 "register_operand" "=x")
22013 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22014 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22015 "TARGET_SSE2"
22016 "psubw\t{%2, %0|%0, %2}"
22017 [(set_attr "type" "sseiadd")
22018 (set_attr "mode" "TI")])
22019
22020 (define_insn "subv4si3"
22021 [(set (match_operand:V4SI 0 "register_operand" "=x")
22022 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22023 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22024 "TARGET_SSE2"
22025 "psubd\t{%2, %0|%0, %2}"
22026 [(set_attr "type" "sseiadd")
22027 (set_attr "mode" "TI")])
22028
22029 (define_insn "subv2di3"
22030 [(set (match_operand:V2DI 0 "register_operand" "=x")
22031 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22032 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22033 "TARGET_SSE2"
22034 "psubq\t{%2, %0|%0, %2}"
22035 [(set_attr "type" "sseiadd")
22036 (set_attr "mode" "TI")])
22037
22038 (define_insn "sssubv16qi3"
22039 [(set (match_operand:V16QI 0 "register_operand" "=x")
22040 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22041 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22042 "TARGET_SSE2"
22043 "psubsb\t{%2, %0|%0, %2}"
22044 [(set_attr "type" "sseiadd")
22045 (set_attr "mode" "TI")])
22046
22047 (define_insn "sssubv8hi3"
22048 [(set (match_operand:V8HI 0 "register_operand" "=x")
22049 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22050 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22051 "TARGET_SSE2"
22052 "psubsw\t{%2, %0|%0, %2}"
22053 [(set_attr "type" "sseiadd")
22054 (set_attr "mode" "TI")])
22055
22056 (define_insn "ussubv16qi3"
22057 [(set (match_operand:V16QI 0 "register_operand" "=x")
22058 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22059 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22060 "TARGET_SSE2"
22061 "psubusb\t{%2, %0|%0, %2}"
22062 [(set_attr "type" "sseiadd")
22063 (set_attr "mode" "TI")])
22064
22065 (define_insn "ussubv8hi3"
22066 [(set (match_operand:V8HI 0 "register_operand" "=x")
22067 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22068 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22069 "TARGET_SSE2"
22070 "psubusw\t{%2, %0|%0, %2}"
22071 [(set_attr "type" "sseiadd")
22072 (set_attr "mode" "TI")])
22073
22074 (define_insn "mulv8hi3"
22075 [(set (match_operand:V8HI 0 "register_operand" "=x")
22076 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22077 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22078 "TARGET_SSE2"
22079 "pmullw\t{%2, %0|%0, %2}"
22080 [(set_attr "type" "sseimul")
22081 (set_attr "mode" "TI")])
22082
22083 (define_insn "smulv8hi3_highpart"
22084 [(set (match_operand:V8HI 0 "register_operand" "=x")
22085 (truncate:V8HI
22086 (lshiftrt:V8SI
22087 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22088 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22089 (const_int 16))))]
22090 "TARGET_SSE2"
22091 "pmulhw\t{%2, %0|%0, %2}"
22092 [(set_attr "type" "sseimul")
22093 (set_attr "mode" "TI")])
22094
22095 (define_insn "umulv8hi3_highpart"
22096 [(set (match_operand:V8HI 0 "register_operand" "=x")
22097 (truncate:V8HI
22098 (lshiftrt:V8SI
22099 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22100 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22101 (const_int 16))))]
22102 "TARGET_SSE2"
22103 "pmulhuw\t{%2, %0|%0, %2}"
22104 [(set_attr "type" "sseimul")
22105 (set_attr "mode" "TI")])
22106
22107 (define_insn "sse2_umulsidi3"
22108 [(set (match_operand:DI 0 "register_operand" "=y")
22109 (mult:DI (zero_extend:DI (vec_select:SI
22110 (match_operand:V2SI 1 "register_operand" "0")
22111 (parallel [(const_int 0)])))
22112 (zero_extend:DI (vec_select:SI
22113 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22114 (parallel [(const_int 0)])))))]
22115 "TARGET_SSE2"
22116 "pmuludq\t{%2, %0|%0, %2}"
22117 [(set_attr "type" "sseimul")
22118 (set_attr "mode" "TI")])
22119
22120 (define_insn "sse2_umulv2siv2di3"
22121 [(set (match_operand:V2DI 0 "register_operand" "=x")
22122 (mult:V2DI (zero_extend:V2DI
22123 (vec_select:V2SI
22124 (match_operand:V4SI 1 "register_operand" "0")
22125 (parallel [(const_int 0) (const_int 2)])))
22126 (zero_extend:V2DI
22127 (vec_select:V2SI
22128 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22129 (parallel [(const_int 0) (const_int 2)])))))]
22130 "TARGET_SSE2"
22131 "pmuludq\t{%2, %0|%0, %2}"
22132 [(set_attr "type" "sseimul")
22133 (set_attr "mode" "TI")])
22134
22135 (define_insn "sse2_pmaddwd"
22136 [(set (match_operand:V4SI 0 "register_operand" "=x")
22137 (plus:V4SI
22138 (mult:V4SI
22139 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22140 (parallel [(const_int 0)
22141 (const_int 2)
22142 (const_int 4)
22143 (const_int 6)])))
22144 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22145 (parallel [(const_int 0)
22146 (const_int 2)
22147 (const_int 4)
22148 (const_int 6)]))))
22149 (mult:V4SI
22150 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22151 (parallel [(const_int 1)
22152 (const_int 3)
22153 (const_int 5)
22154 (const_int 7)])))
22155 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22156 (parallel [(const_int 1)
22157 (const_int 3)
22158 (const_int 5)
22159 (const_int 7)]))))))]
22160 "TARGET_SSE2"
22161 "pmaddwd\t{%2, %0|%0, %2}"
22162 [(set_attr "type" "sseiadd")
22163 (set_attr "mode" "TI")])
22164
22165 ;; Same as pxor, but don't show input operands so that we don't think
22166 ;; they are live.
22167 (define_insn "sse2_clrti"
22168 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22169 "TARGET_SSE2"
22170 {
22171 if (get_attr_mode (insn) == MODE_TI)
22172 return "pxor\t%0, %0";
22173 else
22174 return "xorps\t%0, %0";
22175 }
22176 [(set_attr "type" "ssemov")
22177 (set_attr "memory" "none")
22178 (set (attr "mode")
22179 (if_then_else
22180 (ne (symbol_ref "optimize_size")
22181 (const_int 0))
22182 (const_string "V4SF")
22183 (const_string "TI")))])
22184
22185 ;; MMX unsigned averages/sum of absolute differences
22186
22187 (define_insn "sse2_uavgv16qi3"
22188 [(set (match_operand:V16QI 0 "register_operand" "=x")
22189 (ashiftrt:V16QI
22190 (plus:V16QI (plus:V16QI
22191 (match_operand:V16QI 1 "register_operand" "0")
22192 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22193 (const_vector:V16QI [(const_int 1) (const_int 1)
22194 (const_int 1) (const_int 1)
22195 (const_int 1) (const_int 1)
22196 (const_int 1) (const_int 1)
22197 (const_int 1) (const_int 1)
22198 (const_int 1) (const_int 1)
22199 (const_int 1) (const_int 1)
22200 (const_int 1) (const_int 1)]))
22201 (const_int 1)))]
22202 "TARGET_SSE2"
22203 "pavgb\t{%2, %0|%0, %2}"
22204 [(set_attr "type" "sseiadd")
22205 (set_attr "mode" "TI")])
22206
22207 (define_insn "sse2_uavgv8hi3"
22208 [(set (match_operand:V8HI 0 "register_operand" "=x")
22209 (ashiftrt:V8HI
22210 (plus:V8HI (plus:V8HI
22211 (match_operand:V8HI 1 "register_operand" "0")
22212 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22213 (const_vector:V8HI [(const_int 1) (const_int 1)
22214 (const_int 1) (const_int 1)
22215 (const_int 1) (const_int 1)
22216 (const_int 1) (const_int 1)]))
22217 (const_int 1)))]
22218 "TARGET_SSE2"
22219 "pavgw\t{%2, %0|%0, %2}"
22220 [(set_attr "type" "sseiadd")
22221 (set_attr "mode" "TI")])
22222
22223 ;; @@@ this isn't the right representation.
22224 (define_insn "sse2_psadbw"
22225 [(set (match_operand:V2DI 0 "register_operand" "=x")
22226 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22227 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22228 UNSPEC_PSADBW))]
22229 "TARGET_SSE2"
22230 "psadbw\t{%2, %0|%0, %2}"
22231 [(set_attr "type" "sseiadd")
22232 (set_attr "mode" "TI")])
22233
22234
22235 ;; MMX insert/extract/shuffle
22236
22237 (define_insn "sse2_pinsrw"
22238 [(set (match_operand:V8HI 0 "register_operand" "=x")
22239 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22240 (vec_duplicate:V8HI
22241 (truncate:HI
22242 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22243 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22244 "TARGET_SSE2"
22245 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22246 [(set_attr "type" "ssecvt")
22247 (set_attr "mode" "TI")])
22248
22249 (define_insn "sse2_pextrw"
22250 [(set (match_operand:SI 0 "register_operand" "=r")
22251 (zero_extend:SI
22252 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22253 (parallel
22254 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22255 "TARGET_SSE2"
22256 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22257 [(set_attr "type" "ssecvt")
22258 (set_attr "mode" "TI")])
22259
22260 (define_insn "sse2_pshufd"
22261 [(set (match_operand:V4SI 0 "register_operand" "=x")
22262 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22263 (match_operand:SI 2 "immediate_operand" "i")]
22264 UNSPEC_SHUFFLE))]
22265 "TARGET_SSE2"
22266 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22267 [(set_attr "type" "ssecvt")
22268 (set_attr "mode" "TI")])
22269
22270 (define_insn "sse2_pshuflw"
22271 [(set (match_operand:V8HI 0 "register_operand" "=x")
22272 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22273 (match_operand:SI 2 "immediate_operand" "i")]
22274 UNSPEC_PSHUFLW))]
22275 "TARGET_SSE2"
22276 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22277 [(set_attr "type" "ssecvt")
22278 (set_attr "mode" "TI")])
22279
22280 (define_insn "sse2_pshufhw"
22281 [(set (match_operand:V8HI 0 "register_operand" "=x")
22282 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22283 (match_operand:SI 2 "immediate_operand" "i")]
22284 UNSPEC_PSHUFHW))]
22285 "TARGET_SSE2"
22286 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22287 [(set_attr "type" "ssecvt")
22288 (set_attr "mode" "TI")])
22289
22290 ;; MMX mask-generating comparisons
22291
22292 (define_insn "eqv16qi3"
22293 [(set (match_operand:V16QI 0 "register_operand" "=x")
22294 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22295 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22296 "TARGET_SSE2"
22297 "pcmpeqb\t{%2, %0|%0, %2}"
22298 [(set_attr "type" "ssecmp")
22299 (set_attr "mode" "TI")])
22300
22301 (define_insn "eqv8hi3"
22302 [(set (match_operand:V8HI 0 "register_operand" "=x")
22303 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22304 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22305 "TARGET_SSE2"
22306 "pcmpeqw\t{%2, %0|%0, %2}"
22307 [(set_attr "type" "ssecmp")
22308 (set_attr "mode" "TI")])
22309
22310 (define_insn "eqv4si3"
22311 [(set (match_operand:V4SI 0 "register_operand" "=x")
22312 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22313 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22314 "TARGET_SSE2"
22315 "pcmpeqd\t{%2, %0|%0, %2}"
22316 [(set_attr "type" "ssecmp")
22317 (set_attr "mode" "TI")])
22318
22319 (define_insn "gtv16qi3"
22320 [(set (match_operand:V16QI 0 "register_operand" "=x")
22321 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22322 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22323 "TARGET_SSE2"
22324 "pcmpgtb\t{%2, %0|%0, %2}"
22325 [(set_attr "type" "ssecmp")
22326 (set_attr "mode" "TI")])
22327
22328 (define_insn "gtv8hi3"
22329 [(set (match_operand:V8HI 0 "register_operand" "=x")
22330 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22331 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22332 "TARGET_SSE2"
22333 "pcmpgtw\t{%2, %0|%0, %2}"
22334 [(set_attr "type" "ssecmp")
22335 (set_attr "mode" "TI")])
22336
22337 (define_insn "gtv4si3"
22338 [(set (match_operand:V4SI 0 "register_operand" "=x")
22339 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22340 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22341 "TARGET_SSE2"
22342 "pcmpgtd\t{%2, %0|%0, %2}"
22343 [(set_attr "type" "ssecmp")
22344 (set_attr "mode" "TI")])
22345
22346
22347 ;; MMX max/min insns
22348
22349 (define_insn "umaxv16qi3"
22350 [(set (match_operand:V16QI 0 "register_operand" "=x")
22351 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22352 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22353 "TARGET_SSE2"
22354 "pmaxub\t{%2, %0|%0, %2}"
22355 [(set_attr "type" "sseiadd")
22356 (set_attr "mode" "TI")])
22357
22358 (define_insn "smaxv8hi3"
22359 [(set (match_operand:V8HI 0 "register_operand" "=x")
22360 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22361 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22362 "TARGET_SSE2"
22363 "pmaxsw\t{%2, %0|%0, %2}"
22364 [(set_attr "type" "sseiadd")
22365 (set_attr "mode" "TI")])
22366
22367 (define_insn "uminv16qi3"
22368 [(set (match_operand:V16QI 0 "register_operand" "=x")
22369 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22370 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22371 "TARGET_SSE2"
22372 "pminub\t{%2, %0|%0, %2}"
22373 [(set_attr "type" "sseiadd")
22374 (set_attr "mode" "TI")])
22375
22376 (define_insn "sminv8hi3"
22377 [(set (match_operand:V8HI 0 "register_operand" "=x")
22378 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22379 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22380 "TARGET_SSE2"
22381 "pminsw\t{%2, %0|%0, %2}"
22382 [(set_attr "type" "sseiadd")
22383 (set_attr "mode" "TI")])
22384
22385
22386 ;; MMX shifts
22387
22388 (define_insn "ashrv8hi3"
22389 [(set (match_operand:V8HI 0 "register_operand" "=x")
22390 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22391 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22392 "TARGET_SSE2"
22393 "psraw\t{%2, %0|%0, %2}"
22394 [(set_attr "type" "sseishft")
22395 (set_attr "mode" "TI")])
22396
22397 (define_insn "ashrv4si3"
22398 [(set (match_operand:V4SI 0 "register_operand" "=x")
22399 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22400 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22401 "TARGET_SSE2"
22402 "psrad\t{%2, %0|%0, %2}"
22403 [(set_attr "type" "sseishft")
22404 (set_attr "mode" "TI")])
22405
22406 (define_insn "lshrv8hi3"
22407 [(set (match_operand:V8HI 0 "register_operand" "=x")
22408 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22409 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22410 "TARGET_SSE2"
22411 "psrlw\t{%2, %0|%0, %2}"
22412 [(set_attr "type" "sseishft")
22413 (set_attr "mode" "TI")])
22414
22415 (define_insn "lshrv4si3"
22416 [(set (match_operand:V4SI 0 "register_operand" "=x")
22417 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22418 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22419 "TARGET_SSE2"
22420 "psrld\t{%2, %0|%0, %2}"
22421 [(set_attr "type" "sseishft")
22422 (set_attr "mode" "TI")])
22423
22424 (define_insn "lshrv2di3"
22425 [(set (match_operand:V2DI 0 "register_operand" "=x")
22426 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22427 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22428 "TARGET_SSE2"
22429 "psrlq\t{%2, %0|%0, %2}"
22430 [(set_attr "type" "sseishft")
22431 (set_attr "mode" "TI")])
22432
22433 (define_insn "ashlv8hi3"
22434 [(set (match_operand:V8HI 0 "register_operand" "=x")
22435 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22436 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22437 "TARGET_SSE2"
22438 "psllw\t{%2, %0|%0, %2}"
22439 [(set_attr "type" "sseishft")
22440 (set_attr "mode" "TI")])
22441
22442 (define_insn "ashlv4si3"
22443 [(set (match_operand:V4SI 0 "register_operand" "=x")
22444 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22445 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22446 "TARGET_SSE2"
22447 "pslld\t{%2, %0|%0, %2}"
22448 [(set_attr "type" "sseishft")
22449 (set_attr "mode" "TI")])
22450
22451 (define_insn "ashlv2di3"
22452 [(set (match_operand:V2DI 0 "register_operand" "=x")
22453 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22454 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22455 "TARGET_SSE2"
22456 "psllq\t{%2, %0|%0, %2}"
22457 [(set_attr "type" "sseishft")
22458 (set_attr "mode" "TI")])
22459
22460 (define_insn "ashrv8hi3_ti"
22461 [(set (match_operand:V8HI 0 "register_operand" "=x")
22462 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22463 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22464 "TARGET_SSE2"
22465 "psraw\t{%2, %0|%0, %2}"
22466 [(set_attr "type" "sseishft")
22467 (set_attr "mode" "TI")])
22468
22469 (define_insn "ashrv4si3_ti"
22470 [(set (match_operand:V4SI 0 "register_operand" "=x")
22471 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22472 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22473 "TARGET_SSE2"
22474 "psrad\t{%2, %0|%0, %2}"
22475 [(set_attr "type" "sseishft")
22476 (set_attr "mode" "TI")])
22477
22478 (define_insn "lshrv8hi3_ti"
22479 [(set (match_operand:V8HI 0 "register_operand" "=x")
22480 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22481 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22482 "TARGET_SSE2"
22483 "psrlw\t{%2, %0|%0, %2}"
22484 [(set_attr "type" "sseishft")
22485 (set_attr "mode" "TI")])
22486
22487 (define_insn "lshrv4si3_ti"
22488 [(set (match_operand:V4SI 0 "register_operand" "=x")
22489 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22490 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22491 "TARGET_SSE2"
22492 "psrld\t{%2, %0|%0, %2}"
22493 [(set_attr "type" "sseishft")
22494 (set_attr "mode" "TI")])
22495
22496 (define_insn "lshrv2di3_ti"
22497 [(set (match_operand:V2DI 0 "register_operand" "=x")
22498 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22499 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22500 "TARGET_SSE2"
22501 "psrlq\t{%2, %0|%0, %2}"
22502 [(set_attr "type" "sseishft")
22503 (set_attr "mode" "TI")])
22504
22505 (define_insn "ashlv8hi3_ti"
22506 [(set (match_operand:V8HI 0 "register_operand" "=x")
22507 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22508 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22509 "TARGET_SSE2"
22510 "psllw\t{%2, %0|%0, %2}"
22511 [(set_attr "type" "sseishft")
22512 (set_attr "mode" "TI")])
22513
22514 (define_insn "ashlv4si3_ti"
22515 [(set (match_operand:V4SI 0 "register_operand" "=x")
22516 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22517 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22518 "TARGET_SSE2"
22519 "pslld\t{%2, %0|%0, %2}"
22520 [(set_attr "type" "sseishft")
22521 (set_attr "mode" "TI")])
22522
22523 (define_insn "ashlv2di3_ti"
22524 [(set (match_operand:V2DI 0 "register_operand" "=x")
22525 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22526 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22527 "TARGET_SSE2"
22528 "psllq\t{%2, %0|%0, %2}"
22529 [(set_attr "type" "sseishft")
22530 (set_attr "mode" "TI")])
22531
22532 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22533 ;; we wouldn't need here it since we never generate TImode arithmetic.
22534
22535 ;; There has to be some kind of prize for the weirdest new instruction...
22536 (define_insn "sse2_ashlti3"
22537 [(set (match_operand:TI 0 "register_operand" "=x")
22538 (unspec:TI
22539 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22540 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22541 (const_int 8)))] UNSPEC_NOP))]
22542 "TARGET_SSE2"
22543 "pslldq\t{%2, %0|%0, %2}"
22544 [(set_attr "type" "sseishft")
22545 (set_attr "mode" "TI")])
22546
22547 (define_insn "sse2_lshrti3"
22548 [(set (match_operand:TI 0 "register_operand" "=x")
22549 (unspec:TI
22550 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22551 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22552 (const_int 8)))] UNSPEC_NOP))]
22553 "TARGET_SSE2"
22554 "psrldq\t{%2, %0|%0, %2}"
22555 [(set_attr "type" "sseishft")
22556 (set_attr "mode" "TI")])
22557
22558 ;; SSE unpack
22559
22560 (define_insn "sse2_unpckhpd"
22561 [(set (match_operand:V2DF 0 "register_operand" "=x")
22562 (vec_concat:V2DF
22563 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22564 (parallel [(const_int 1)]))
22565 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22566 (parallel [(const_int 1)]))))]
22567 "TARGET_SSE2"
22568 "unpckhpd\t{%2, %0|%0, %2}"
22569 [(set_attr "type" "ssecvt")
22570 (set_attr "mode" "V2DF")])
22571
22572 (define_insn "sse2_unpcklpd"
22573 [(set (match_operand:V2DF 0 "register_operand" "=x")
22574 (vec_concat:V2DF
22575 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22576 (parallel [(const_int 0)]))
22577 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22578 (parallel [(const_int 0)]))))]
22579 "TARGET_SSE2"
22580 "unpcklpd\t{%2, %0|%0, %2}"
22581 [(set_attr "type" "ssecvt")
22582 (set_attr "mode" "V2DF")])
22583
22584 ;; MMX pack/unpack insns.
22585
22586 (define_insn "sse2_packsswb"
22587 [(set (match_operand:V16QI 0 "register_operand" "=x")
22588 (vec_concat:V16QI
22589 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22590 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22591 "TARGET_SSE2"
22592 "packsswb\t{%2, %0|%0, %2}"
22593 [(set_attr "type" "ssecvt")
22594 (set_attr "mode" "TI")])
22595
22596 (define_insn "sse2_packssdw"
22597 [(set (match_operand:V8HI 0 "register_operand" "=x")
22598 (vec_concat:V8HI
22599 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22600 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22601 "TARGET_SSE2"
22602 "packssdw\t{%2, %0|%0, %2}"
22603 [(set_attr "type" "ssecvt")
22604 (set_attr "mode" "TI")])
22605
22606 (define_insn "sse2_packuswb"
22607 [(set (match_operand:V16QI 0 "register_operand" "=x")
22608 (vec_concat:V16QI
22609 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22610 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22611 "TARGET_SSE2"
22612 "packuswb\t{%2, %0|%0, %2}"
22613 [(set_attr "type" "ssecvt")
22614 (set_attr "mode" "TI")])
22615
22616 (define_insn "sse2_punpckhbw"
22617 [(set (match_operand:V16QI 0 "register_operand" "=x")
22618 (vec_merge:V16QI
22619 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22620 (parallel [(const_int 8) (const_int 0)
22621 (const_int 9) (const_int 1)
22622 (const_int 10) (const_int 2)
22623 (const_int 11) (const_int 3)
22624 (const_int 12) (const_int 4)
22625 (const_int 13) (const_int 5)
22626 (const_int 14) (const_int 6)
22627 (const_int 15) (const_int 7)]))
22628 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22629 (parallel [(const_int 0) (const_int 8)
22630 (const_int 1) (const_int 9)
22631 (const_int 2) (const_int 10)
22632 (const_int 3) (const_int 11)
22633 (const_int 4) (const_int 12)
22634 (const_int 5) (const_int 13)
22635 (const_int 6) (const_int 14)
22636 (const_int 7) (const_int 15)]))
22637 (const_int 21845)))]
22638 "TARGET_SSE2"
22639 "punpckhbw\t{%2, %0|%0, %2}"
22640 [(set_attr "type" "ssecvt")
22641 (set_attr "mode" "TI")])
22642
22643 (define_insn "sse2_punpckhwd"
22644 [(set (match_operand:V8HI 0 "register_operand" "=x")
22645 (vec_merge:V8HI
22646 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22647 (parallel [(const_int 4) (const_int 0)
22648 (const_int 5) (const_int 1)
22649 (const_int 6) (const_int 2)
22650 (const_int 7) (const_int 3)]))
22651 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22652 (parallel [(const_int 0) (const_int 4)
22653 (const_int 1) (const_int 5)
22654 (const_int 2) (const_int 6)
22655 (const_int 3) (const_int 7)]))
22656 (const_int 85)))]
22657 "TARGET_SSE2"
22658 "punpckhwd\t{%2, %0|%0, %2}"
22659 [(set_attr "type" "ssecvt")
22660 (set_attr "mode" "TI")])
22661
22662 (define_insn "sse2_punpckhdq"
22663 [(set (match_operand:V4SI 0 "register_operand" "=x")
22664 (vec_merge:V4SI
22665 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22666 (parallel [(const_int 2) (const_int 0)
22667 (const_int 3) (const_int 1)]))
22668 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22669 (parallel [(const_int 0) (const_int 2)
22670 (const_int 1) (const_int 3)]))
22671 (const_int 5)))]
22672 "TARGET_SSE2"
22673 "punpckhdq\t{%2, %0|%0, %2}"
22674 [(set_attr "type" "ssecvt")
22675 (set_attr "mode" "TI")])
22676
22677 (define_insn "sse2_punpcklbw"
22678 [(set (match_operand:V16QI 0 "register_operand" "=x")
22679 (vec_merge:V16QI
22680 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22681 (parallel [(const_int 0) (const_int 8)
22682 (const_int 1) (const_int 9)
22683 (const_int 2) (const_int 10)
22684 (const_int 3) (const_int 11)
22685 (const_int 4) (const_int 12)
22686 (const_int 5) (const_int 13)
22687 (const_int 6) (const_int 14)
22688 (const_int 7) (const_int 15)]))
22689 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22690 (parallel [(const_int 8) (const_int 0)
22691 (const_int 9) (const_int 1)
22692 (const_int 10) (const_int 2)
22693 (const_int 11) (const_int 3)
22694 (const_int 12) (const_int 4)
22695 (const_int 13) (const_int 5)
22696 (const_int 14) (const_int 6)
22697 (const_int 15) (const_int 7)]))
22698 (const_int 21845)))]
22699 "TARGET_SSE2"
22700 "punpcklbw\t{%2, %0|%0, %2}"
22701 [(set_attr "type" "ssecvt")
22702 (set_attr "mode" "TI")])
22703
22704 (define_insn "sse2_punpcklwd"
22705 [(set (match_operand:V8HI 0 "register_operand" "=x")
22706 (vec_merge:V8HI
22707 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22708 (parallel [(const_int 0) (const_int 4)
22709 (const_int 1) (const_int 5)
22710 (const_int 2) (const_int 6)
22711 (const_int 3) (const_int 7)]))
22712 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22713 (parallel [(const_int 4) (const_int 0)
22714 (const_int 5) (const_int 1)
22715 (const_int 6) (const_int 2)
22716 (const_int 7) (const_int 3)]))
22717 (const_int 85)))]
22718 "TARGET_SSE2"
22719 "punpcklwd\t{%2, %0|%0, %2}"
22720 [(set_attr "type" "ssecvt")
22721 (set_attr "mode" "TI")])
22722
22723 (define_insn "sse2_punpckldq"
22724 [(set (match_operand:V4SI 0 "register_operand" "=x")
22725 (vec_merge:V4SI
22726 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22727 (parallel [(const_int 0) (const_int 2)
22728 (const_int 1) (const_int 3)]))
22729 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22730 (parallel [(const_int 2) (const_int 0)
22731 (const_int 3) (const_int 1)]))
22732 (const_int 5)))]
22733 "TARGET_SSE2"
22734 "punpckldq\t{%2, %0|%0, %2}"
22735 [(set_attr "type" "ssecvt")
22736 (set_attr "mode" "TI")])
22737
22738 (define_insn "sse2_punpcklqdq"
22739 [(set (match_operand:V2DI 0 "register_operand" "=x")
22740 (vec_merge:V2DI
22741 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22742 (parallel [(const_int 1)
22743 (const_int 0)]))
22744 (match_operand:V2DI 1 "register_operand" "0")
22745 (const_int 1)))]
22746 "TARGET_SSE2"
22747 "punpcklqdq\t{%2, %0|%0, %2}"
22748 [(set_attr "type" "ssecvt")
22749 (set_attr "mode" "TI")])
22750
22751 (define_insn "sse2_punpckhqdq"
22752 [(set (match_operand:V2DI 0 "register_operand" "=x")
22753 (vec_merge:V2DI
22754 (match_operand:V2DI 1 "register_operand" "0")
22755 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22756 (parallel [(const_int 1)
22757 (const_int 0)]))
22758 (const_int 1)))]
22759 "TARGET_SSE2"
22760 "punpckhqdq\t{%2, %0|%0, %2}"
22761 [(set_attr "type" "ssecvt")
22762 (set_attr "mode" "TI")])
22763
22764 ;; SSE2 moves
22765
22766 (define_insn "sse2_movapd"
22767 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22768 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22769 UNSPEC_MOVA))]
22770 "TARGET_SSE2
22771 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22772 "movapd\t{%1, %0|%0, %1}"
22773 [(set_attr "type" "ssemov")
22774 (set_attr "mode" "V2DF")])
22775
22776 (define_insn "sse2_movupd"
22777 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22778 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22779 UNSPEC_MOVU))]
22780 "TARGET_SSE2
22781 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22782 "movupd\t{%1, %0|%0, %1}"
22783 [(set_attr "type" "ssecvt")
22784 (set_attr "mode" "V2DF")])
22785
22786 (define_insn "sse2_movdqa"
22787 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22788 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22789 UNSPEC_MOVA))]
22790 "TARGET_SSE2
22791 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22792 "movdqa\t{%1, %0|%0, %1}"
22793 [(set_attr "type" "ssemov")
22794 (set_attr "mode" "TI")])
22795
22796 (define_insn "sse2_movdqu"
22797 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22798 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22799 UNSPEC_MOVU))]
22800 "TARGET_SSE2
22801 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22802 "movdqu\t{%1, %0|%0, %1}"
22803 [(set_attr "type" "ssecvt")
22804 (set_attr "mode" "TI")])
22805
22806 (define_insn "sse2_movdq2q"
22807 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22808 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22809 (parallel [(const_int 0)])))]
22810 "TARGET_SSE2 && !TARGET_64BIT"
22811 "@
22812 movq\t{%1, %0|%0, %1}
22813 movdq2q\t{%1, %0|%0, %1}"
22814 [(set_attr "type" "ssecvt")
22815 (set_attr "mode" "TI")])
22816
22817 (define_insn "sse2_movdq2q_rex64"
22818 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22819 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22820 (parallel [(const_int 0)])))]
22821 "TARGET_SSE2 && TARGET_64BIT"
22822 "@
22823 movq\t{%1, %0|%0, %1}
22824 movdq2q\t{%1, %0|%0, %1}
22825 movd\t{%1, %0|%0, %1}"
22826 [(set_attr "type" "ssecvt")
22827 (set_attr "mode" "TI")])
22828
22829 (define_insn "sse2_movq2dq"
22830 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22831 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22832 (const_int 0)))]
22833 "TARGET_SSE2 && !TARGET_64BIT"
22834 "@
22835 movq\t{%1, %0|%0, %1}
22836 movq2dq\t{%1, %0|%0, %1}"
22837 [(set_attr "type" "ssecvt,ssemov")
22838 (set_attr "mode" "TI")])
22839
22840 (define_insn "sse2_movq2dq_rex64"
22841 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22842 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22843 (const_int 0)))]
22844 "TARGET_SSE2 && TARGET_64BIT"
22845 "@
22846 movq\t{%1, %0|%0, %1}
22847 movq2dq\t{%1, %0|%0, %1}
22848 movd\t{%1, %0|%0, %1}"
22849 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22850 (set_attr "mode" "TI")])
22851
22852 (define_insn "sse2_movq"
22853 [(set (match_operand:V2DI 0 "register_operand" "=x")
22854 (vec_concat:V2DI (vec_select:DI
22855 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22856 (parallel [(const_int 0)]))
22857 (const_int 0)))]
22858 "TARGET_SSE2"
22859 "movq\t{%1, %0|%0, %1}"
22860 [(set_attr "type" "ssemov")
22861 (set_attr "mode" "TI")])
22862
22863 (define_insn "sse2_loadd"
22864 [(set (match_operand:V4SI 0 "register_operand" "=x")
22865 (vec_merge:V4SI
22866 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22867 (const_vector:V4SI [(const_int 0)
22868 (const_int 0)
22869 (const_int 0)
22870 (const_int 0)])
22871 (const_int 1)))]
22872 "TARGET_SSE2"
22873 "movd\t{%1, %0|%0, %1}"
22874 [(set_attr "type" "ssemov")
22875 (set_attr "mode" "TI")])
22876
22877 (define_insn "sse2_stored"
22878 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22879 (vec_select:SI
22880 (match_operand:V4SI 1 "register_operand" "x")
22881 (parallel [(const_int 0)])))]
22882 "TARGET_SSE2"
22883 "movd\t{%1, %0|%0, %1}"
22884 [(set_attr "type" "ssemov")
22885 (set_attr "mode" "TI")])
22886
22887 (define_insn "sse2_movhpd"
22888 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22889 (vec_merge:V2DF
22890 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22891 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22892 (const_int 2)))]
22893 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22894 "movhpd\t{%2, %0|%0, %2}"
22895 [(set_attr "type" "ssecvt")
22896 (set_attr "mode" "V2DF")])
22897
22898 (define_expand "sse2_loadsd"
22899 [(match_operand:V2DF 0 "register_operand" "")
22900 (match_operand:DF 1 "memory_operand" "")]
22901 "TARGET_SSE2"
22902 {
22903 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22904 CONST0_RTX (V2DFmode)));
22905 DONE;
22906 })
22907
22908 (define_insn "sse2_loadsd_1"
22909 [(set (match_operand:V2DF 0 "register_operand" "=x")
22910 (vec_merge:V2DF
22911 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22912 (match_operand:V2DF 2 "const0_operand" "X")
22913 (const_int 1)))]
22914 "TARGET_SSE2"
22915 "movsd\t{%1, %0|%0, %1}"
22916 [(set_attr "type" "ssecvt")
22917 (set_attr "mode" "DF")])
22918
22919 (define_insn "sse2_movsd"
22920 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22921 (vec_merge:V2DF
22922 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22923 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22924 (const_int 1)))]
22925 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22926 "@movsd\t{%2, %0|%0, %2}
22927 movlpd\t{%2, %0|%0, %2}
22928 movlpd\t{%2, %0|%0, %2}"
22929 [(set_attr "type" "ssecvt")
22930 (set_attr "mode" "DF,V2DF,V2DF")])
22931
22932 (define_insn "sse2_storesd"
22933 [(set (match_operand:DF 0 "memory_operand" "=m")
22934 (vec_select:DF
22935 (match_operand:V2DF 1 "register_operand" "x")
22936 (parallel [(const_int 0)])))]
22937 "TARGET_SSE2"
22938 "movsd\t{%1, %0|%0, %1}"
22939 [(set_attr "type" "ssecvt")
22940 (set_attr "mode" "DF")])
22941
22942 (define_insn "sse2_shufpd"
22943 [(set (match_operand:V2DF 0 "register_operand" "=x")
22944 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22945 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22946 (match_operand:SI 3 "immediate_operand" "i")]
22947 UNSPEC_SHUFFLE))]
22948 "TARGET_SSE2"
22949 ;; @@@ check operand order for intel/nonintel syntax
22950 "shufpd\t{%3, %2, %0|%0, %2, %3}"
22951 [(set_attr "type" "ssecvt")
22952 (set_attr "mode" "V2DF")])
22953
22954 (define_insn "sse2_clflush"
22955 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22956 UNSPECV_CLFLUSH)]
22957 "TARGET_SSE2"
22958 "clflush %0"
22959 [(set_attr "type" "sse")
22960 (set_attr "memory" "unknown")])
22961
22962 (define_expand "sse2_mfence"
22963 [(set (match_dup 0)
22964 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22965 "TARGET_SSE2"
22966 {
22967 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22968 MEM_VOLATILE_P (operands[0]) = 1;
22969 })
22970
22971 (define_insn "*mfence_insn"
22972 [(set (match_operand:BLK 0 "" "")
22973 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22974 "TARGET_SSE2"
22975 "mfence"
22976 [(set_attr "type" "sse")
22977 (set_attr "memory" "unknown")])
22978
22979 (define_expand "sse2_lfence"
22980 [(set (match_dup 0)
22981 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22982 "TARGET_SSE2"
22983 {
22984 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22985 MEM_VOLATILE_P (operands[0]) = 1;
22986 })
22987
22988 (define_insn "*lfence_insn"
22989 [(set (match_operand:BLK 0 "" "")
22990 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22991 "TARGET_SSE2"
22992 "lfence"
22993 [(set_attr "type" "sse")
22994 (set_attr "memory" "unknown")])
22995
22996 ;; PNI
22997
22998 (define_insn "mwait"
22999 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23000 (match_operand:SI 1 "register_operand" "c")]
23001 UNSPECV_MWAIT)]
23002 "TARGET_PNI"
23003 "mwait\t%0, %1"
23004 [(set_attr "length" "3")])
23005
23006 (define_insn "monitor"
23007 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23008 (match_operand:SI 1 "register_operand" "c")
23009 (match_operand:SI 2 "register_operand" "d")]
23010 UNSPECV_MONITOR)]
23011 "TARGET_PNI"
23012 "monitor\t%0, %1, %2"
23013 [(set_attr "length" "3")])
23014
23015 ;; PNI arithmetic
23016
23017 (define_insn "addsubv4sf3"
23018 [(set (match_operand:V4SF 0 "register_operand" "=x")
23019 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23020 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23021 UNSPEC_ADDSUB))]
23022 "TARGET_PNI"
23023 "addsubps\t{%2, %0|%0, %2}"
23024 [(set_attr "type" "sseadd")
23025 (set_attr "mode" "V4SF")])
23026
23027 (define_insn "addsubv2df3"
23028 [(set (match_operand:V2DF 0 "register_operand" "=x")
23029 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23030 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23031 UNSPEC_ADDSUB))]
23032 "TARGET_PNI"
23033 "addsubpd\t{%2, %0|%0, %2}"
23034 [(set_attr "type" "sseadd")
23035 (set_attr "mode" "V2DF")])
23036
23037 (define_insn "haddv4sf3"
23038 [(set (match_operand:V4SF 0 "register_operand" "=x")
23039 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23040 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23041 UNSPEC_HADD))]
23042 "TARGET_PNI"
23043 "haddps\t{%2, %0|%0, %2}"
23044 [(set_attr "type" "sseadd")
23045 (set_attr "mode" "V4SF")])
23046
23047 (define_insn "haddv2df3"
23048 [(set (match_operand:V2DF 0 "register_operand" "=x")
23049 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23050 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23051 UNSPEC_HADD))]
23052 "TARGET_PNI"
23053 "haddpd\t{%2, %0|%0, %2}"
23054 [(set_attr "type" "sseadd")
23055 (set_attr "mode" "V2DF")])
23056
23057 (define_insn "hsubv4sf3"
23058 [(set (match_operand:V4SF 0 "register_operand" "=x")
23059 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23060 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23061 UNSPEC_HSUB))]
23062 "TARGET_PNI"
23063 "hsubps\t{%2, %0|%0, %2}"
23064 [(set_attr "type" "sseadd")
23065 (set_attr "mode" "V4SF")])
23066
23067 (define_insn "hsubv2df3"
23068 [(set (match_operand:V2DF 0 "register_operand" "=x")
23069 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23070 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23071 UNSPEC_HSUB))]
23072 "TARGET_PNI"
23073 "hsubpd\t{%2, %0|%0, %2}"
23074 [(set_attr "type" "sseadd")
23075 (set_attr "mode" "V2DF")])
23076
23077 (define_insn "movshdup"
23078 [(set (match_operand:V4SF 0 "register_operand" "=x")
23079 (unspec:V4SF
23080 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23081 "TARGET_PNI"
23082 "movshdup\t{%1, %0|%0, %1}"
23083 [(set_attr "type" "sse")
23084 (set_attr "mode" "V4SF")])
23085
23086 (define_insn "movsldup"
23087 [(set (match_operand:V4SF 0 "register_operand" "=x")
23088 (unspec:V4SF
23089 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23090 "TARGET_PNI"
23091 "movsldup\t{%1, %0|%0, %1}"
23092 [(set_attr "type" "sse")
23093 (set_attr "mode" "V4SF")])
23094
23095 (define_insn "lddqu"
23096 [(set (match_operand:V16QI 0 "register_operand" "=x")
23097 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23098 UNSPEC_LDQQU))]
23099 "TARGET_PNI"
23100 "lddqu\t{%1, %0|%0, %1}"
23101 [(set_attr "type" "ssecvt")
23102 (set_attr "mode" "TI")])
23103
23104 (define_insn "loadddup"
23105 [(set (match_operand:V2DF 0 "register_operand" "=x")
23106 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23107 "TARGET_PNI"
23108 "movddup\t{%1, %0|%0, %1}"
23109 [(set_attr "type" "ssecvt")
23110 (set_attr "mode" "DF")])
23111
23112 (define_insn "movddup"
23113 [(set (match_operand:V2DF 0 "register_operand" "=x")
23114 (vec_duplicate:V2DF
23115 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23116 (parallel [(const_int 0)]))))]
23117 "TARGET_PNI"
23118 "movddup\t{%1, %0|%0, %1}"
23119 [(set_attr "type" "ssecvt")
23120 (set_attr "mode" "DF")])