1f7369b59647882327a897fe488621cf6a1463d0
[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, 2005, 2006, 2007, 2008, 2009, 2010
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 3, 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 COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; delimiter.
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 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62
63 ;; UNSPEC usage:
64
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
67 UNSPEC_GOT
68 UNSPEC_GOTOFF
69 UNSPEC_GOTPCREL
70 UNSPEC_GOTTPOFF
71 UNSPEC_TPOFF
72 UNSPEC_NTPOFF
73 UNSPEC_DTPOFF
74 UNSPEC_GOTNTPOFF
75 UNSPEC_INDNTPOFF
76 UNSPEC_PLTOFF
77 UNSPEC_MACHOPIC_OFFSET
78
79 ;; Prologue support
80 UNSPEC_STACK_ALLOC
81 UNSPEC_SET_GOT
82 UNSPEC_SSE_PROLOGUE_SAVE
83 UNSPEC_REG_SAVE
84 UNSPEC_DEF_CFA
85 UNSPEC_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_SSE_PROLOGUE_SAVE_LOW
89
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
95
96 ;; Other random patterns
97 UNSPEC_SCAS
98 UNSPEC_FNSTSW
99 UNSPEC_SAHF
100 UNSPEC_PARITY
101 UNSPEC_FSTCW
102 UNSPEC_ADD_CARRY
103 UNSPEC_FLDCW
104 UNSPEC_REP
105 UNSPEC_LD_MPIC ; load_macho_picbase
106 UNSPEC_TRUNC_NOOP
107
108 ;; For SSE/MMX support:
109 UNSPEC_FIX_NOTRUNC
110 UNSPEC_MASKMOV
111 UNSPEC_MOVMSK
112 UNSPEC_MOVNT
113 UNSPEC_MOVU
114 UNSPEC_RCP
115 UNSPEC_RSQRT
116 UNSPEC_SFENCE
117 UNSPEC_PFRCP
118 UNSPEC_PFRCPIT1
119 UNSPEC_PFRCPIT2
120 UNSPEC_PFRSQRT
121 UNSPEC_PFRSQIT1
122 UNSPEC_MFENCE
123 UNSPEC_LFENCE
124 UNSPEC_PSADBW
125 UNSPEC_LDDQU
126 UNSPEC_MS_TO_SYSV_CALL
127
128 ;; Generic math support
129 UNSPEC_COPYSIGN
130 UNSPEC_IEEE_MIN ; not commutative
131 UNSPEC_IEEE_MAX ; not commutative
132
133 ;; x87 Floating point
134 UNSPEC_SIN
135 UNSPEC_COS
136 UNSPEC_FPATAN
137 UNSPEC_FYL2X
138 UNSPEC_FYL2XP1
139 UNSPEC_FRNDINT
140 UNSPEC_FIST
141 UNSPEC_F2XM1
142 UNSPEC_TAN
143 UNSPEC_FXAM
144
145 ;; x87 Rounding
146 UNSPEC_FRNDINT_FLOOR
147 UNSPEC_FRNDINT_CEIL
148 UNSPEC_FRNDINT_TRUNC
149 UNSPEC_FRNDINT_MASK_PM
150 UNSPEC_FIST_FLOOR
151 UNSPEC_FIST_CEIL
152
153 ;; x87 Double output FP
154 UNSPEC_SINCOS_COS
155 UNSPEC_SINCOS_SIN
156 UNSPEC_XTRACT_FRACT
157 UNSPEC_XTRACT_EXP
158 UNSPEC_FSCALE_FRACT
159 UNSPEC_FSCALE_EXP
160 UNSPEC_FPREM_F
161 UNSPEC_FPREM_U
162 UNSPEC_FPREM1_F
163 UNSPEC_FPREM1_U
164
165 UNSPEC_C2_FLAG
166 UNSPEC_FXAM_MEM
167
168 ;; SSP patterns
169 UNSPEC_SP_SET
170 UNSPEC_SP_TEST
171 UNSPEC_SP_TLS_SET
172 UNSPEC_SP_TLS_TEST
173
174 ;; SSSE3
175 UNSPEC_PSHUFB
176 UNSPEC_PSIGN
177 UNSPEC_PALIGNR
178
179 ;; For SSE4A support
180 UNSPEC_EXTRQI
181 UNSPEC_EXTRQ
182 UNSPEC_INSERTQI
183 UNSPEC_INSERTQ
184
185 ;; For SSE4.1 support
186 UNSPEC_BLENDV
187 UNSPEC_INSERTPS
188 UNSPEC_DP
189 UNSPEC_MOVNTDQA
190 UNSPEC_MPSADBW
191 UNSPEC_PHMINPOSUW
192 UNSPEC_PTEST
193 UNSPEC_ROUND
194
195 ;; For SSE4.2 support
196 UNSPEC_CRC32
197 UNSPEC_PCMPESTR
198 UNSPEC_PCMPISTR
199
200 ;; For FMA4 support
201 UNSPEC_FMA4_INTRINSIC
202 UNSPEC_FMA4_FMADDSUB
203 UNSPEC_FMA4_FMSUBADD
204 UNSPEC_XOP_UNSIGNED_CMP
205 UNSPEC_XOP_TRUEFALSE
206 UNSPEC_XOP_PERMUTE
207 UNSPEC_FRCZ
208
209 ;; For AES support
210 UNSPEC_AESENC
211 UNSPEC_AESENCLAST
212 UNSPEC_AESDEC
213 UNSPEC_AESDECLAST
214 UNSPEC_AESIMC
215 UNSPEC_AESKEYGENASSIST
216
217 ;; For PCLMUL support
218 UNSPEC_PCLMUL
219
220 ;; For AVX support
221 UNSPEC_PCMP
222 UNSPEC_VPERMIL
223 UNSPEC_VPERMIL2
224 UNSPEC_VPERMIL2F128
225 UNSPEC_MASKLOAD
226 UNSPEC_MASKSTORE
227 UNSPEC_CAST
228 UNSPEC_VTESTP
229 ])
230
231 (define_c_enum "unspecv" [
232 UNSPECV_BLOCKAGE
233 UNSPECV_STACK_PROBE
234 UNSPECV_EMMS
235 UNSPECV_LDMXCSR
236 UNSPECV_STMXCSR
237 UNSPECV_FEMMS
238 UNSPECV_CLFLUSH
239 UNSPECV_ALIGN
240 UNSPECV_MONITOR
241 UNSPECV_MWAIT
242 UNSPECV_CMPXCHG
243 UNSPECV_XCHG
244 UNSPECV_LOCK
245 UNSPECV_PROLOGUE_USE
246 UNSPECV_CLD
247 UNSPECV_VZEROALL
248 UNSPECV_VZEROUPPER
249 UNSPECV_RDTSC
250 UNSPECV_RDTSCP
251 UNSPECV_RDPMC
252 UNSPECV_VSWAPMOV
253 UNSPECV_LLWP_INTRINSIC
254 UNSPECV_SLWP_INTRINSIC
255 UNSPECV_LWPVAL_INTRINSIC
256 UNSPECV_LWPINS_INTRINSIC
257 ])
258
259 ;; Constants to represent pcomtrue/pcomfalse variants
260 (define_constants
261 [(PCOM_FALSE 0)
262 (PCOM_TRUE 1)
263 (COM_FALSE_S 2)
264 (COM_FALSE_P 3)
265 (COM_TRUE_S 4)
266 (COM_TRUE_P 5)
267 ])
268
269 ;; Constants used in the XOP pperm instruction
270 (define_constants
271 [(PPERM_SRC 0x00) /* copy source */
272 (PPERM_INVERT 0x20) /* invert source */
273 (PPERM_REVERSE 0x40) /* bit reverse source */
274 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
275 (PPERM_ZERO 0x80) /* all 0's */
276 (PPERM_ONES 0xa0) /* all 1's */
277 (PPERM_SIGN 0xc0) /* propagate sign bit */
278 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
279 (PPERM_SRC1 0x00) /* use first source byte */
280 (PPERM_SRC2 0x10) /* use second source byte */
281 ])
282
283 ;; Registers by name.
284 (define_constants
285 [(AX_REG 0)
286 (DX_REG 1)
287 (CX_REG 2)
288 (BX_REG 3)
289 (SI_REG 4)
290 (DI_REG 5)
291 (BP_REG 6)
292 (SP_REG 7)
293 (ST0_REG 8)
294 (ST1_REG 9)
295 (ST2_REG 10)
296 (ST3_REG 11)
297 (ST4_REG 12)
298 (ST5_REG 13)
299 (ST6_REG 14)
300 (ST7_REG 15)
301 (FLAGS_REG 17)
302 (FPSR_REG 18)
303 (FPCR_REG 19)
304 (XMM0_REG 21)
305 (XMM1_REG 22)
306 (XMM2_REG 23)
307 (XMM3_REG 24)
308 (XMM4_REG 25)
309 (XMM5_REG 26)
310 (XMM6_REG 27)
311 (XMM7_REG 28)
312 (MM0_REG 29)
313 (MM1_REG 30)
314 (MM2_REG 31)
315 (MM3_REG 32)
316 (MM4_REG 33)
317 (MM5_REG 34)
318 (MM6_REG 35)
319 (MM7_REG 36)
320 (R8_REG 37)
321 (R9_REG 38)
322 (R10_REG 39)
323 (R11_REG 40)
324 (R12_REG 41)
325 (R13_REG 42)
326 (XMM8_REG 45)
327 (XMM9_REG 46)
328 (XMM10_REG 47)
329 (XMM11_REG 48)
330 (XMM12_REG 49)
331 (XMM13_REG 50)
332 (XMM14_REG 51)
333 (XMM15_REG 52)
334 ])
335
336 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337 ;; from i386.c.
338
339 ;; In C guard expressions, put expressions which may be compile-time
340 ;; constants first. This allows for better optimization. For
341 ;; example, write "TARGET_64BIT && reload_completed", not
342 ;; "reload_completed && TARGET_64BIT".
343
344 \f
345 ;; Processor type.
346 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347 generic64,amdfam10,bdver1"
348 (const (symbol_ref "ix86_schedule")))
349
350 ;; A basic instruction type. Refinements due to arguments to be
351 ;; provided in other attributes.
352 (define_attr "type"
353 "other,multi,
354 alu,alu1,negnot,imov,imovx,lea,
355 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
356 icmp,test,ibr,setcc,icmov,
357 push,pop,call,callv,leave,
358 str,bitmanip,
359 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
360 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
361 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
362 ssemuladd,sse4arg,lwp,
363 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
364 (const_string "other"))
365
366 ;; Main data type used by the insn
367 (define_attr "mode"
368 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
369 (const_string "unknown"))
370
371 ;; The CPU unit operations uses.
372 (define_attr "unit" "integer,i387,sse,mmx,unknown"
373 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
374 (const_string "i387")
375 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
376 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
377 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
378 (const_string "sse")
379 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
380 (const_string "mmx")
381 (eq_attr "type" "other")
382 (const_string "unknown")]
383 (const_string "integer")))
384
385 ;; The (bounding maximum) length of an instruction immediate.
386 (define_attr "length_immediate" ""
387 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388 bitmanip")
389 (const_int 0)
390 (eq_attr "unit" "i387,sse,mmx")
391 (const_int 0)
392 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
393 imul,icmp,push,pop")
394 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
395 (eq_attr "type" "imov,test")
396 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
397 (eq_attr "type" "call")
398 (if_then_else (match_operand 0 "constant_call_address_operand" "")
399 (const_int 4)
400 (const_int 0))
401 (eq_attr "type" "callv")
402 (if_then_else (match_operand 1 "constant_call_address_operand" "")
403 (const_int 4)
404 (const_int 0))
405 ;; We don't know the size before shorten_branches. Expect
406 ;; the instruction to fit for better scheduling.
407 (eq_attr "type" "ibr")
408 (const_int 1)
409 ]
410 (symbol_ref "/* Update immediate_length and other attributes! */
411 gcc_unreachable (),1")))
412
413 ;; The (bounding maximum) length of an instruction address.
414 (define_attr "length_address" ""
415 (cond [(eq_attr "type" "str,other,multi,fxch")
416 (const_int 0)
417 (and (eq_attr "type" "call")
418 (match_operand 0 "constant_call_address_operand" ""))
419 (const_int 0)
420 (and (eq_attr "type" "callv")
421 (match_operand 1 "constant_call_address_operand" ""))
422 (const_int 0)
423 ]
424 (symbol_ref "ix86_attr_length_address_default (insn)")))
425
426 ;; Set when length prefix is used.
427 (define_attr "prefix_data16" ""
428 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
429 (const_int 0)
430 (eq_attr "mode" "HI")
431 (const_int 1)
432 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
433 (const_int 1)
434 ]
435 (const_int 0)))
436
437 ;; Set when string REP prefix is used.
438 (define_attr "prefix_rep" ""
439 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
440 (const_int 0)
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
442 (const_int 1)
443 ]
444 (const_int 0)))
445
446 ;; Set when 0f opcode prefix is used.
447 (define_attr "prefix_0f" ""
448 (if_then_else
449 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
450 (eq_attr "unit" "sse,mmx"))
451 (const_int 1)
452 (const_int 0)))
453
454 ;; Set when REX opcode prefix is used.
455 (define_attr "prefix_rex" ""
456 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
457 (const_int 0)
458 (and (eq_attr "mode" "DI")
459 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
460 (eq_attr "unit" "!mmx")))
461 (const_int 1)
462 (and (eq_attr "mode" "QI")
463 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464 (const_int 0)))
465 (const_int 1)
466 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467 (const_int 0))
468 (const_int 1)
469 (and (eq_attr "type" "imovx")
470 (match_operand:QI 1 "ext_QIreg_operand" ""))
471 (const_int 1)
472 ]
473 (const_int 0)))
474
475 ;; There are also additional prefixes in 3DNOW, SSSE3.
476 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
477 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
478 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
479 (define_attr "prefix_extra" ""
480 (cond [(eq_attr "type" "ssemuladd,sse4arg")
481 (const_int 2)
482 (eq_attr "type" "sseiadd1,ssecvt1")
483 (const_int 1)
484 ]
485 (const_int 0)))
486
487 ;; Prefix used: original, VEX or maybe VEX.
488 (define_attr "prefix" "orig,vex,maybe_vex"
489 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
490 (const_string "vex")
491 (const_string "orig")))
492
493 ;; VEX W bit is used.
494 (define_attr "prefix_vex_w" "" (const_int 0))
495
496 ;; The length of VEX prefix
497 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
498 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
499 ;; still prefix_0f 1, with prefix_extra 1.
500 (define_attr "length_vex" ""
501 (if_then_else (and (eq_attr "prefix_0f" "1")
502 (eq_attr "prefix_extra" "0"))
503 (if_then_else (eq_attr "prefix_vex_w" "1")
504 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
506 (if_then_else (eq_attr "prefix_vex_w" "1")
507 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
508 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
509
510 ;; Set when modrm byte is used.
511 (define_attr "modrm" ""
512 (cond [(eq_attr "type" "str,leave")
513 (const_int 0)
514 (eq_attr "unit" "i387")
515 (const_int 0)
516 (and (eq_attr "type" "incdec")
517 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
518 (ior (match_operand:SI 1 "register_operand" "")
519 (match_operand:HI 1 "register_operand" ""))))
520 (const_int 0)
521 (and (eq_attr "type" "push")
522 (not (match_operand 1 "memory_operand" "")))
523 (const_int 0)
524 (and (eq_attr "type" "pop")
525 (not (match_operand 0 "memory_operand" "")))
526 (const_int 0)
527 (and (eq_attr "type" "imov")
528 (and (not (eq_attr "mode" "DI"))
529 (ior (and (match_operand 0 "register_operand" "")
530 (match_operand 1 "immediate_operand" ""))
531 (ior (and (match_operand 0 "ax_reg_operand" "")
532 (match_operand 1 "memory_displacement_only_operand" ""))
533 (and (match_operand 0 "memory_displacement_only_operand" "")
534 (match_operand 1 "ax_reg_operand" ""))))))
535 (const_int 0)
536 (and (eq_attr "type" "call")
537 (match_operand 0 "constant_call_address_operand" ""))
538 (const_int 0)
539 (and (eq_attr "type" "callv")
540 (match_operand 1 "constant_call_address_operand" ""))
541 (const_int 0)
542 (and (eq_attr "type" "alu,alu1,icmp,test")
543 (match_operand 0 "ax_reg_operand" ""))
544 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
545 ]
546 (const_int 1)))
547
548 ;; The (bounding maximum) length of an instruction in bytes.
549 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
550 ;; Later we may want to split them and compute proper length as for
551 ;; other insns.
552 (define_attr "length" ""
553 (cond [(eq_attr "type" "other,multi,fistp,frndint")
554 (const_int 16)
555 (eq_attr "type" "fcmp")
556 (const_int 4)
557 (eq_attr "unit" "i387")
558 (plus (const_int 2)
559 (plus (attr "prefix_data16")
560 (attr "length_address")))
561 (ior (eq_attr "prefix" "vex")
562 (and (eq_attr "prefix" "maybe_vex")
563 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
564 (plus (attr "length_vex")
565 (plus (attr "length_immediate")
566 (plus (attr "modrm")
567 (attr "length_address"))))]
568 (plus (plus (attr "modrm")
569 (plus (attr "prefix_0f")
570 (plus (attr "prefix_rex")
571 (plus (attr "prefix_extra")
572 (const_int 1)))))
573 (plus (attr "prefix_rep")
574 (plus (attr "prefix_data16")
575 (plus (attr "length_immediate")
576 (attr "length_address")))))))
577
578 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
579 ;; `store' if there is a simple memory reference therein, or `unknown'
580 ;; if the instruction is complex.
581
582 (define_attr "memory" "none,load,store,both,unknown"
583 (cond [(eq_attr "type" "other,multi,str,lwp")
584 (const_string "unknown")
585 (eq_attr "type" "lea,fcmov,fpspc")
586 (const_string "none")
587 (eq_attr "type" "fistp,leave")
588 (const_string "both")
589 (eq_attr "type" "frndint")
590 (const_string "load")
591 (eq_attr "type" "push")
592 (if_then_else (match_operand 1 "memory_operand" "")
593 (const_string "both")
594 (const_string "store"))
595 (eq_attr "type" "pop")
596 (if_then_else (match_operand 0 "memory_operand" "")
597 (const_string "both")
598 (const_string "load"))
599 (eq_attr "type" "setcc")
600 (if_then_else (match_operand 0 "memory_operand" "")
601 (const_string "store")
602 (const_string "none"))
603 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
604 (if_then_else (ior (match_operand 0 "memory_operand" "")
605 (match_operand 1 "memory_operand" ""))
606 (const_string "load")
607 (const_string "none"))
608 (eq_attr "type" "ibr")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "load")
611 (const_string "none"))
612 (eq_attr "type" "call")
613 (if_then_else (match_operand 0 "constant_call_address_operand" "")
614 (const_string "none")
615 (const_string "load"))
616 (eq_attr "type" "callv")
617 (if_then_else (match_operand 1 "constant_call_address_operand" "")
618 (const_string "none")
619 (const_string "load"))
620 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
621 (match_operand 1 "memory_operand" ""))
622 (const_string "both")
623 (and (match_operand 0 "memory_operand" "")
624 (match_operand 1 "memory_operand" ""))
625 (const_string "both")
626 (match_operand 0 "memory_operand" "")
627 (const_string "store")
628 (match_operand 1 "memory_operand" "")
629 (const_string "load")
630 (and (eq_attr "type"
631 "!alu1,negnot,ishift1,
632 imov,imovx,icmp,test,bitmanip,
633 fmov,fcmp,fsgn,
634 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
635 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
636 (match_operand 2 "memory_operand" ""))
637 (const_string "load")
638 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
639 (match_operand 3 "memory_operand" ""))
640 (const_string "load")
641 ]
642 (const_string "none")))
643
644 ;; Indicates if an instruction has both an immediate and a displacement.
645
646 (define_attr "imm_disp" "false,true,unknown"
647 (cond [(eq_attr "type" "other,multi")
648 (const_string "unknown")
649 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
650 (and (match_operand 0 "memory_displacement_operand" "")
651 (match_operand 1 "immediate_operand" "")))
652 (const_string "true")
653 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
654 (and (match_operand 0 "memory_displacement_operand" "")
655 (match_operand 2 "immediate_operand" "")))
656 (const_string "true")
657 ]
658 (const_string "false")))
659
660 ;; Indicates if an FP operation has an integer source.
661
662 (define_attr "fp_int_src" "false,true"
663 (const_string "false"))
664
665 ;; Defines rounding mode of an FP operation.
666
667 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
668 (const_string "any"))
669
670 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
671 (define_attr "use_carry" "0,1" (const_string "0"))
672
673 ;; Define attribute to indicate unaligned ssemov insns
674 (define_attr "movu" "0,1" (const_string "0"))
675
676 ;; Describe a user's asm statement.
677 (define_asm_attributes
678 [(set_attr "length" "128")
679 (set_attr "type" "multi")])
680
681 ;; All integer comparison codes.
682 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
683
684 ;; All floating-point comparison codes.
685 (define_code_iterator fp_cond [unordered ordered
686 uneq unge ungt unle unlt ltgt])
687
688 (define_code_iterator plusminus [plus minus])
689
690 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691
692 ;; Base name for define_insn
693 (define_code_attr plusminus_insn
694 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
695 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696
697 ;; Base name for insn mnemonic.
698 (define_code_attr plusminus_mnemonic
699 [(plus "add") (ss_plus "adds") (us_plus "addus")
700 (minus "sub") (ss_minus "subs") (us_minus "subus")])
701 (define_code_attr plusminus_carry_mnemonic
702 [(plus "adc") (minus "sbb")])
703
704 ;; Mark commutative operators as such in constraints.
705 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
706 (minus "") (ss_minus "") (us_minus "")])
707
708 ;; Mapping of signed max and min
709 (define_code_iterator smaxmin [smax smin])
710
711 ;; Mapping of unsigned max and min
712 (define_code_iterator umaxmin [umax umin])
713
714 ;; Mapping of signed/unsigned max and min
715 (define_code_iterator maxmin [smax smin umax umin])
716
717 ;; Base name for integer and FP insn mnemonic
718 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
719 (umax "maxu") (umin "minu")])
720 (define_code_attr maxmin_float [(smax "max") (smin "min")])
721
722 ;; Mapping of logic operators
723 (define_code_iterator any_logic [and ior xor])
724 (define_code_iterator any_or [ior xor])
725
726 ;; Base name for insn mnemonic.
727 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
728
729 ;; Mapping of shift-right operators
730 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
731
732 ;; Base name for define_insn
733 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
734
735 ;; Base name for insn mnemonic.
736 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
737
738 ;; Mapping of rotate operators
739 (define_code_iterator any_rotate [rotate rotatert])
740
741 ;; Base name for define_insn
742 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
743
744 ;; Base name for insn mnemonic.
745 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
746
747 ;; Mapping of abs neg operators
748 (define_code_iterator absneg [abs neg])
749
750 ;; Base name for x87 insn mnemonic.
751 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
752
753 ;; Used in signed and unsigned widening multiplications.
754 (define_code_iterator any_extend [sign_extend zero_extend])
755
756 ;; Various insn prefixes for signed and unsigned operations.
757 (define_code_attr u [(sign_extend "") (zero_extend "u")
758 (div "") (udiv "u")])
759 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
760
761 ;; Used in signed and unsigned divisions.
762 (define_code_iterator any_div [div udiv])
763
764 ;; Instruction prefix for signed and unsigned operations.
765 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
766 (div "i") (udiv "")])
767
768 ;; 64bit single word integer modes.
769 (define_mode_iterator SWI1248x [QI HI SI DI])
770
771 ;; 64bit single word integer modes without QImode and HImode.
772 (define_mode_iterator SWI48x [SI DI])
773
774 ;; Single word integer modes.
775 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
776
777 ;; Single word integer modes without SImode and DImode.
778 (define_mode_iterator SWI12 [QI HI])
779
780 ;; Single word integer modes without DImode.
781 (define_mode_iterator SWI124 [QI HI SI])
782
783 ;; Single word integer modes without QImode and DImode.
784 (define_mode_iterator SWI24 [HI SI])
785
786 ;; Single word integer modes without QImode.
787 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
788
789 ;; Single word integer modes without QImode and HImode.
790 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
791
792 ;; All math-dependant single and double word integer modes.
793 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
794 (HI "TARGET_HIMODE_MATH")
795 SI DI (TI "TARGET_64BIT")])
796
797 ;; Math-dependant single word integer modes.
798 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
799 (HI "TARGET_HIMODE_MATH")
800 SI (DI "TARGET_64BIT")])
801
802 ;; Math-dependant single word integer modes without DImode.
803 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
804 (HI "TARGET_HIMODE_MATH")
805 SI])
806
807 ;; Math-dependant single word integer modes without QImode.
808 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
809 SI (DI "TARGET_64BIT")])
810
811 ;; Double word integer modes.
812 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
813 (TI "TARGET_64BIT")])
814
815 ;; Double word integer modes as mode attribute.
816 (define_mode_attr DWI [(SI "DI") (DI "TI")])
817 (define_mode_attr dwi [(SI "di") (DI "ti")])
818
819 ;; Half mode for double word integer modes.
820 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
821 (DI "TARGET_64BIT")])
822
823 ;; Instruction suffix for integer modes.
824 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
825
826 ;; Register class for integer modes.
827 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
828
829 ;; Immediate operand constraint for integer modes.
830 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
831
832 ;; General operand constraint for word modes.
833 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
834
835 ;; Immediate operand constraint for double integer modes.
836 (define_mode_attr di [(SI "iF") (DI "e")])
837
838 ;; Immediate operand constraint for shifts.
839 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
840
841 ;; General operand predicate for integer modes.
842 (define_mode_attr general_operand
843 [(QI "general_operand")
844 (HI "general_operand")
845 (SI "general_operand")
846 (DI "x86_64_general_operand")
847 (TI "x86_64_general_operand")])
848
849 ;; General sign/zero extend operand predicate for integer modes.
850 (define_mode_attr general_szext_operand
851 [(QI "general_operand")
852 (HI "general_operand")
853 (SI "general_operand")
854 (DI "x86_64_szext_general_operand")])
855
856 ;; Operand predicate for shifts.
857 (define_mode_attr shift_operand
858 [(QI "nonimmediate_operand")
859 (HI "nonimmediate_operand")
860 (SI "nonimmediate_operand")
861 (DI "shiftdi_operand")
862 (TI "register_operand")])
863
864 ;; Operand predicate for shift argument.
865 (define_mode_attr shift_immediate_operand
866 [(QI "const_1_to_31_operand")
867 (HI "const_1_to_31_operand")
868 (SI "const_1_to_31_operand")
869 (DI "const_1_to_63_operand")])
870
871 ;; Input operand predicate for arithmetic left shifts.
872 (define_mode_attr ashl_input_operand
873 [(QI "nonimmediate_operand")
874 (HI "nonimmediate_operand")
875 (SI "nonimmediate_operand")
876 (DI "ashldi_input_operand")
877 (TI "reg_or_pm1_operand")])
878
879 ;; SSE and x87 SFmode and DFmode floating point modes
880 (define_mode_iterator MODEF [SF DF])
881
882 ;; All x87 floating point modes
883 (define_mode_iterator X87MODEF [SF DF XF])
884
885 ;; All integer modes handled by x87 fisttp operator.
886 (define_mode_iterator X87MODEI [HI SI DI])
887
888 ;; All integer modes handled by integer x87 operators.
889 (define_mode_iterator X87MODEI12 [HI SI])
890
891 ;; All integer modes handled by SSE cvtts?2si* operators.
892 (define_mode_iterator SSEMODEI24 [SI DI])
893
894 ;; SSE asm suffix for floating point modes
895 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
896
897 ;; SSE vector mode corresponding to a scalar mode
898 (define_mode_attr ssevecmode
899 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
900
901 ;; Instruction suffix for REX 64bit operators.
902 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
903
904 ;; This mode iterator allows :P to be used for patterns that operate on
905 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
906 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
907 \f
908 ;; Scheduling descriptions
909
910 (include "pentium.md")
911 (include "ppro.md")
912 (include "k6.md")
913 (include "athlon.md")
914 (include "geode.md")
915 (include "atom.md")
916
917 \f
918 ;; Operand and operator predicates and constraints
919
920 (include "predicates.md")
921 (include "constraints.md")
922
923 \f
924 ;; Compare and branch/compare and store instructions.
925
926 (define_expand "cbranch<mode>4"
927 [(set (reg:CC FLAGS_REG)
928 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
929 (match_operand:SDWIM 2 "<general_operand>" "")))
930 (set (pc) (if_then_else
931 (match_operator 0 "comparison_operator"
932 [(reg:CC FLAGS_REG) (const_int 0)])
933 (label_ref (match_operand 3 "" ""))
934 (pc)))]
935 ""
936 {
937 if (MEM_P (operands[1]) && MEM_P (operands[2]))
938 operands[1] = force_reg (<MODE>mode, operands[1]);
939 ix86_compare_op0 = operands[1];
940 ix86_compare_op1 = operands[2];
941 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
942 DONE;
943 })
944
945 (define_expand "cstore<mode>4"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
948 (match_operand:SWIM 3 "<general_operand>" "")))
949 (set (match_operand:QI 0 "register_operand" "")
950 (match_operator 1 "comparison_operator"
951 [(reg:CC FLAGS_REG) (const_int 0)]))]
952 ""
953 {
954 if (MEM_P (operands[2]) && MEM_P (operands[3]))
955 operands[2] = force_reg (<MODE>mode, operands[2]);
956 ix86_compare_op0 = operands[2];
957 ix86_compare_op1 = operands[3];
958 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
959 DONE;
960 })
961
962 (define_expand "cmp<mode>_1"
963 [(set (reg:CC FLAGS_REG)
964 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
965 (match_operand:SWI48 1 "<general_operand>" "")))]
966 ""
967 "")
968
969 (define_insn "*cmp<mode>_ccno_1"
970 [(set (reg FLAGS_REG)
971 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
972 (match_operand:SWI 1 "const0_operand" "")))]
973 "ix86_match_ccmode (insn, CCNOmode)"
974 "@
975 test{<imodesuffix>}\t%0, %0
976 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977 [(set_attr "type" "test,icmp")
978 (set_attr "length_immediate" "0,1")
979 (set_attr "mode" "<MODE>")])
980
981 (define_insn "*cmp<mode>_1"
982 [(set (reg FLAGS_REG)
983 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
985 "ix86_match_ccmode (insn, CCmode)"
986 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987 [(set_attr "type" "icmp")
988 (set_attr "mode" "<MODE>")])
989
990 (define_insn "*cmp<mode>_minus_1"
991 [(set (reg FLAGS_REG)
992 (compare
993 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
995 (const_int 0)))]
996 "ix86_match_ccmode (insn, CCGOCmode)"
997 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "<MODE>")])
1000
1001 (define_insn "*cmpqi_ext_1"
1002 [(set (reg FLAGS_REG)
1003 (compare
1004 (match_operand:QI 0 "general_operand" "Qm")
1005 (subreg:QI
1006 (zero_extract:SI
1007 (match_operand 1 "ext_register_operand" "Q")
1008 (const_int 8)
1009 (const_int 8)) 0)))]
1010 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011 "cmp{b}\t{%h1, %0|%0, %h1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "QI")])
1014
1015 (define_insn "*cmpqi_ext_1_rex64"
1016 [(set (reg FLAGS_REG)
1017 (compare
1018 (match_operand:QI 0 "register_operand" "Q")
1019 (subreg:QI
1020 (zero_extract:SI
1021 (match_operand 1 "ext_register_operand" "Q")
1022 (const_int 8)
1023 (const_int 8)) 0)))]
1024 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1025 "cmp{b}\t{%h1, %0|%0, %h1}"
1026 [(set_attr "type" "icmp")
1027 (set_attr "mode" "QI")])
1028
1029 (define_insn "*cmpqi_ext_2"
1030 [(set (reg FLAGS_REG)
1031 (compare
1032 (subreg:QI
1033 (zero_extract:SI
1034 (match_operand 0 "ext_register_operand" "Q")
1035 (const_int 8)
1036 (const_int 8)) 0)
1037 (match_operand:QI 1 "const0_operand" "")))]
1038 "ix86_match_ccmode (insn, CCNOmode)"
1039 "test{b}\t%h0, %h0"
1040 [(set_attr "type" "test")
1041 (set_attr "length_immediate" "0")
1042 (set_attr "mode" "QI")])
1043
1044 (define_expand "cmpqi_ext_3"
1045 [(set (reg:CC FLAGS_REG)
1046 (compare:CC
1047 (subreg:QI
1048 (zero_extract:SI
1049 (match_operand 0 "ext_register_operand" "")
1050 (const_int 8)
1051 (const_int 8)) 0)
1052 (match_operand:QI 1 "immediate_operand" "")))]
1053 ""
1054 "")
1055
1056 (define_insn "*cmpqi_ext_3_insn"
1057 [(set (reg FLAGS_REG)
1058 (compare
1059 (subreg:QI
1060 (zero_extract:SI
1061 (match_operand 0 "ext_register_operand" "Q")
1062 (const_int 8)
1063 (const_int 8)) 0)
1064 (match_operand:QI 1 "general_operand" "Qmn")))]
1065 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1066 "cmp{b}\t{%1, %h0|%h0, %1}"
1067 [(set_attr "type" "icmp")
1068 (set_attr "modrm" "1")
1069 (set_attr "mode" "QI")])
1070
1071 (define_insn "*cmpqi_ext_3_insn_rex64"
1072 [(set (reg FLAGS_REG)
1073 (compare
1074 (subreg:QI
1075 (zero_extract:SI
1076 (match_operand 0 "ext_register_operand" "Q")
1077 (const_int 8)
1078 (const_int 8)) 0)
1079 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1080 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1081 "cmp{b}\t{%1, %h0|%h0, %1}"
1082 [(set_attr "type" "icmp")
1083 (set_attr "modrm" "1")
1084 (set_attr "mode" "QI")])
1085
1086 (define_insn "*cmpqi_ext_4"
1087 [(set (reg FLAGS_REG)
1088 (compare
1089 (subreg:QI
1090 (zero_extract:SI
1091 (match_operand 0 "ext_register_operand" "Q")
1092 (const_int 8)
1093 (const_int 8)) 0)
1094 (subreg:QI
1095 (zero_extract:SI
1096 (match_operand 1 "ext_register_operand" "Q")
1097 (const_int 8)
1098 (const_int 8)) 0)))]
1099 "ix86_match_ccmode (insn, CCmode)"
1100 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1101 [(set_attr "type" "icmp")
1102 (set_attr "mode" "QI")])
1103
1104 ;; These implement float point compares.
1105 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1106 ;; which would allow mix and match FP modes on the compares. Which is what
1107 ;; the old patterns did, but with many more of them.
1108
1109 (define_expand "cbranchxf4"
1110 [(set (reg:CC FLAGS_REG)
1111 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1112 (match_operand:XF 2 "nonmemory_operand" "")))
1113 (set (pc) (if_then_else
1114 (match_operator 0 "ix86_fp_comparison_operator"
1115 [(reg:CC FLAGS_REG)
1116 (const_int 0)])
1117 (label_ref (match_operand 3 "" ""))
1118 (pc)))]
1119 "TARGET_80387"
1120 {
1121 ix86_compare_op0 = operands[1];
1122 ix86_compare_op1 = operands[2];
1123 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1124 DONE;
1125 })
1126
1127 (define_expand "cstorexf4"
1128 [(set (reg:CC FLAGS_REG)
1129 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1130 (match_operand:XF 3 "nonmemory_operand" "")))
1131 (set (match_operand:QI 0 "register_operand" "")
1132 (match_operator 1 "ix86_fp_comparison_operator"
1133 [(reg:CC FLAGS_REG)
1134 (const_int 0)]))]
1135 "TARGET_80387"
1136 {
1137 ix86_compare_op0 = operands[2];
1138 ix86_compare_op1 = operands[3];
1139 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1140 DONE;
1141 })
1142
1143 (define_expand "cbranch<mode>4"
1144 [(set (reg:CC FLAGS_REG)
1145 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1146 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1147 (set (pc) (if_then_else
1148 (match_operator 0 "ix86_fp_comparison_operator"
1149 [(reg:CC FLAGS_REG)
1150 (const_int 0)])
1151 (label_ref (match_operand 3 "" ""))
1152 (pc)))]
1153 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1154 {
1155 ix86_compare_op0 = operands[1];
1156 ix86_compare_op1 = operands[2];
1157 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1158 DONE;
1159 })
1160
1161 (define_expand "cstore<mode>4"
1162 [(set (reg:CC FLAGS_REG)
1163 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1164 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1165 (set (match_operand:QI 0 "register_operand" "")
1166 (match_operator 1 "ix86_fp_comparison_operator"
1167 [(reg:CC FLAGS_REG)
1168 (const_int 0)]))]
1169 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1170 {
1171 ix86_compare_op0 = operands[2];
1172 ix86_compare_op1 = operands[3];
1173 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1174 DONE;
1175 })
1176
1177 (define_expand "cbranchcc4"
1178 [(set (pc) (if_then_else
1179 (match_operator 0 "comparison_operator"
1180 [(match_operand 1 "flags_reg_operand" "")
1181 (match_operand 2 "const0_operand" "")])
1182 (label_ref (match_operand 3 "" ""))
1183 (pc)))]
1184 ""
1185 {
1186 ix86_compare_op0 = operands[1];
1187 ix86_compare_op1 = operands[2];
1188 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1189 DONE;
1190 })
1191
1192 (define_expand "cstorecc4"
1193 [(set (match_operand:QI 0 "register_operand" "")
1194 (match_operator 1 "comparison_operator"
1195 [(match_operand 2 "flags_reg_operand" "")
1196 (match_operand 3 "const0_operand" "")]))]
1197 ""
1198 {
1199 ix86_compare_op0 = operands[2];
1200 ix86_compare_op1 = operands[3];
1201 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1202 DONE;
1203 })
1204
1205
1206 ;; FP compares, step 1:
1207 ;; Set the FP condition codes.
1208 ;;
1209 ;; CCFPmode compare with exceptions
1210 ;; CCFPUmode compare with no exceptions
1211
1212 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1213 ;; used to manage the reg stack popping would not be preserved.
1214
1215 (define_insn "*cmpfp_0"
1216 [(set (match_operand:HI 0 "register_operand" "=a")
1217 (unspec:HI
1218 [(compare:CCFP
1219 (match_operand 1 "register_operand" "f")
1220 (match_operand 2 "const0_operand" ""))]
1221 UNSPEC_FNSTSW))]
1222 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1223 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1224 "* return output_fp_compare (insn, operands, 0, 0);"
1225 [(set_attr "type" "multi")
1226 (set_attr "unit" "i387")
1227 (set (attr "mode")
1228 (cond [(match_operand:SF 1 "" "")
1229 (const_string "SF")
1230 (match_operand:DF 1 "" "")
1231 (const_string "DF")
1232 ]
1233 (const_string "XF")))])
1234
1235 (define_insn_and_split "*cmpfp_0_cc"
1236 [(set (reg:CCFP FLAGS_REG)
1237 (compare:CCFP
1238 (match_operand 1 "register_operand" "f")
1239 (match_operand 2 "const0_operand" "")))
1240 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1241 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1242 && TARGET_SAHF && !TARGET_CMOVE
1243 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1244 "#"
1245 "&& reload_completed"
1246 [(set (match_dup 0)
1247 (unspec:HI
1248 [(compare:CCFP (match_dup 1)(match_dup 2))]
1249 UNSPEC_FNSTSW))
1250 (set (reg:CC FLAGS_REG)
1251 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1252 ""
1253 [(set_attr "type" "multi")
1254 (set_attr "unit" "i387")
1255 (set (attr "mode")
1256 (cond [(match_operand:SF 1 "" "")
1257 (const_string "SF")
1258 (match_operand:DF 1 "" "")
1259 (const_string "DF")
1260 ]
1261 (const_string "XF")))])
1262
1263 (define_insn "*cmpfp_xf"
1264 [(set (match_operand:HI 0 "register_operand" "=a")
1265 (unspec:HI
1266 [(compare:CCFP
1267 (match_operand:XF 1 "register_operand" "f")
1268 (match_operand:XF 2 "register_operand" "f"))]
1269 UNSPEC_FNSTSW))]
1270 "TARGET_80387"
1271 "* return output_fp_compare (insn, operands, 0, 0);"
1272 [(set_attr "type" "multi")
1273 (set_attr "unit" "i387")
1274 (set_attr "mode" "XF")])
1275
1276 (define_insn_and_split "*cmpfp_xf_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1278 (compare:CCFP
1279 (match_operand:XF 1 "register_operand" "f")
1280 (match_operand:XF 2 "register_operand" "f")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282 "TARGET_80387
1283 && TARGET_SAHF && !TARGET_CMOVE"
1284 "#"
1285 "&& reload_completed"
1286 [(set (match_dup 0)
1287 (unspec:HI
1288 [(compare:CCFP (match_dup 1)(match_dup 2))]
1289 UNSPEC_FNSTSW))
1290 (set (reg:CC FLAGS_REG)
1291 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1292 ""
1293 [(set_attr "type" "multi")
1294 (set_attr "unit" "i387")
1295 (set_attr "mode" "XF")])
1296
1297 (define_insn "*cmpfp_<mode>"
1298 [(set (match_operand:HI 0 "register_operand" "=a")
1299 (unspec:HI
1300 [(compare:CCFP
1301 (match_operand:MODEF 1 "register_operand" "f")
1302 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1303 UNSPEC_FNSTSW))]
1304 "TARGET_80387"
1305 "* return output_fp_compare (insn, operands, 0, 0);"
1306 [(set_attr "type" "multi")
1307 (set_attr "unit" "i387")
1308 (set_attr "mode" "<MODE>")])
1309
1310 (define_insn_and_split "*cmpfp_<mode>_cc"
1311 [(set (reg:CCFP FLAGS_REG)
1312 (compare:CCFP
1313 (match_operand:MODEF 1 "register_operand" "f")
1314 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1315 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1316 "TARGET_80387
1317 && TARGET_SAHF && !TARGET_CMOVE"
1318 "#"
1319 "&& reload_completed"
1320 [(set (match_dup 0)
1321 (unspec:HI
1322 [(compare:CCFP (match_dup 1)(match_dup 2))]
1323 UNSPEC_FNSTSW))
1324 (set (reg:CC FLAGS_REG)
1325 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1326 ""
1327 [(set_attr "type" "multi")
1328 (set_attr "unit" "i387")
1329 (set_attr "mode" "<MODE>")])
1330
1331 (define_insn "*cmpfp_u"
1332 [(set (match_operand:HI 0 "register_operand" "=a")
1333 (unspec:HI
1334 [(compare:CCFPU
1335 (match_operand 1 "register_operand" "f")
1336 (match_operand 2 "register_operand" "f"))]
1337 UNSPEC_FNSTSW))]
1338 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1339 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1340 "* return output_fp_compare (insn, operands, 0, 1);"
1341 [(set_attr "type" "multi")
1342 (set_attr "unit" "i387")
1343 (set (attr "mode")
1344 (cond [(match_operand:SF 1 "" "")
1345 (const_string "SF")
1346 (match_operand:DF 1 "" "")
1347 (const_string "DF")
1348 ]
1349 (const_string "XF")))])
1350
1351 (define_insn_and_split "*cmpfp_u_cc"
1352 [(set (reg:CCFPU FLAGS_REG)
1353 (compare:CCFPU
1354 (match_operand 1 "register_operand" "f")
1355 (match_operand 2 "register_operand" "f")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1357 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1358 && TARGET_SAHF && !TARGET_CMOVE
1359 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1360 "#"
1361 "&& reload_completed"
1362 [(set (match_dup 0)
1363 (unspec:HI
1364 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1365 UNSPEC_FNSTSW))
1366 (set (reg:CC FLAGS_REG)
1367 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1368 ""
1369 [(set_attr "type" "multi")
1370 (set_attr "unit" "i387")
1371 (set (attr "mode")
1372 (cond [(match_operand:SF 1 "" "")
1373 (const_string "SF")
1374 (match_operand:DF 1 "" "")
1375 (const_string "DF")
1376 ]
1377 (const_string "XF")))])
1378
1379 (define_insn "*cmpfp_<mode>"
1380 [(set (match_operand:HI 0 "register_operand" "=a")
1381 (unspec:HI
1382 [(compare:CCFP
1383 (match_operand 1 "register_operand" "f")
1384 (match_operator 3 "float_operator"
1385 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1386 UNSPEC_FNSTSW))]
1387 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1388 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1389 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1390 "* return output_fp_compare (insn, operands, 0, 0);"
1391 [(set_attr "type" "multi")
1392 (set_attr "unit" "i387")
1393 (set_attr "fp_int_src" "true")
1394 (set_attr "mode" "<MODE>")])
1395
1396 (define_insn_and_split "*cmpfp_<mode>_cc"
1397 [(set (reg:CCFP FLAGS_REG)
1398 (compare:CCFP
1399 (match_operand 1 "register_operand" "f")
1400 (match_operator 3 "float_operator"
1401 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1402 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1403 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1404 && TARGET_SAHF && !TARGET_CMOVE
1405 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1406 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1407 "#"
1408 "&& reload_completed"
1409 [(set (match_dup 0)
1410 (unspec:HI
1411 [(compare:CCFP
1412 (match_dup 1)
1413 (match_op_dup 3 [(match_dup 2)]))]
1414 UNSPEC_FNSTSW))
1415 (set (reg:CC FLAGS_REG)
1416 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1417 ""
1418 [(set_attr "type" "multi")
1419 (set_attr "unit" "i387")
1420 (set_attr "fp_int_src" "true")
1421 (set_attr "mode" "<MODE>")])
1422
1423 ;; FP compares, step 2
1424 ;; Move the fpsw to ax.
1425
1426 (define_insn "x86_fnstsw_1"
1427 [(set (match_operand:HI 0 "register_operand" "=a")
1428 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1429 "TARGET_80387"
1430 "fnstsw\t%0"
1431 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1432 (set_attr "mode" "SI")
1433 (set_attr "unit" "i387")])
1434
1435 ;; FP compares, step 3
1436 ;; Get ax into flags, general case.
1437
1438 (define_insn "x86_sahf_1"
1439 [(set (reg:CC FLAGS_REG)
1440 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1441 UNSPEC_SAHF))]
1442 "TARGET_SAHF"
1443 {
1444 #ifndef HAVE_AS_IX86_SAHF
1445 if (TARGET_64BIT)
1446 return ASM_BYTE "0x9e";
1447 else
1448 #endif
1449 return "sahf";
1450 }
1451 [(set_attr "length" "1")
1452 (set_attr "athlon_decode" "vector")
1453 (set_attr "amdfam10_decode" "direct")
1454 (set_attr "mode" "SI")])
1455
1456 ;; Pentium Pro can do steps 1 through 3 in one go.
1457 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1458 (define_insn "*cmpfp_i_mixed"
1459 [(set (reg:CCFP FLAGS_REG)
1460 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1461 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1462 "TARGET_MIX_SSE_I387
1463 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1464 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1465 "* return output_fp_compare (insn, operands, 1, 0);"
1466 [(set_attr "type" "fcmp,ssecomi")
1467 (set_attr "prefix" "orig,maybe_vex")
1468 (set (attr "mode")
1469 (if_then_else (match_operand:SF 1 "" "")
1470 (const_string "SF")
1471 (const_string "DF")))
1472 (set (attr "prefix_rep")
1473 (if_then_else (eq_attr "type" "ssecomi")
1474 (const_string "0")
1475 (const_string "*")))
1476 (set (attr "prefix_data16")
1477 (cond [(eq_attr "type" "fcmp")
1478 (const_string "*")
1479 (eq_attr "mode" "DF")
1480 (const_string "1")
1481 ]
1482 (const_string "0")))
1483 (set_attr "athlon_decode" "vector")
1484 (set_attr "amdfam10_decode" "direct")])
1485
1486 (define_insn "*cmpfp_i_sse"
1487 [(set (reg:CCFP FLAGS_REG)
1488 (compare:CCFP (match_operand 0 "register_operand" "x")
1489 (match_operand 1 "nonimmediate_operand" "xm")))]
1490 "TARGET_SSE_MATH
1491 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1492 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1493 "* return output_fp_compare (insn, operands, 1, 0);"
1494 [(set_attr "type" "ssecomi")
1495 (set_attr "prefix" "maybe_vex")
1496 (set (attr "mode")
1497 (if_then_else (match_operand:SF 1 "" "")
1498 (const_string "SF")
1499 (const_string "DF")))
1500 (set_attr "prefix_rep" "0")
1501 (set (attr "prefix_data16")
1502 (if_then_else (eq_attr "mode" "DF")
1503 (const_string "1")
1504 (const_string "0")))
1505 (set_attr "athlon_decode" "vector")
1506 (set_attr "amdfam10_decode" "direct")])
1507
1508 (define_insn "*cmpfp_i_i387"
1509 [(set (reg:CCFP FLAGS_REG)
1510 (compare:CCFP (match_operand 0 "register_operand" "f")
1511 (match_operand 1 "register_operand" "f")))]
1512 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1513 && TARGET_CMOVE
1514 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1515 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1516 "* return output_fp_compare (insn, operands, 1, 0);"
1517 [(set_attr "type" "fcmp")
1518 (set (attr "mode")
1519 (cond [(match_operand:SF 1 "" "")
1520 (const_string "SF")
1521 (match_operand:DF 1 "" "")
1522 (const_string "DF")
1523 ]
1524 (const_string "XF")))
1525 (set_attr "athlon_decode" "vector")
1526 (set_attr "amdfam10_decode" "direct")])
1527
1528 (define_insn "*cmpfp_iu_mixed"
1529 [(set (reg:CCFPU FLAGS_REG)
1530 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1531 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1532 "TARGET_MIX_SSE_I387
1533 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1534 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1535 "* return output_fp_compare (insn, operands, 1, 1);"
1536 [(set_attr "type" "fcmp,ssecomi")
1537 (set_attr "prefix" "orig,maybe_vex")
1538 (set (attr "mode")
1539 (if_then_else (match_operand:SF 1 "" "")
1540 (const_string "SF")
1541 (const_string "DF")))
1542 (set (attr "prefix_rep")
1543 (if_then_else (eq_attr "type" "ssecomi")
1544 (const_string "0")
1545 (const_string "*")))
1546 (set (attr "prefix_data16")
1547 (cond [(eq_attr "type" "fcmp")
1548 (const_string "*")
1549 (eq_attr "mode" "DF")
1550 (const_string "1")
1551 ]
1552 (const_string "0")))
1553 (set_attr "athlon_decode" "vector")
1554 (set_attr "amdfam10_decode" "direct")])
1555
1556 (define_insn "*cmpfp_iu_sse"
1557 [(set (reg:CCFPU FLAGS_REG)
1558 (compare:CCFPU (match_operand 0 "register_operand" "x")
1559 (match_operand 1 "nonimmediate_operand" "xm")))]
1560 "TARGET_SSE_MATH
1561 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1562 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1563 "* return output_fp_compare (insn, operands, 1, 1);"
1564 [(set_attr "type" "ssecomi")
1565 (set_attr "prefix" "maybe_vex")
1566 (set (attr "mode")
1567 (if_then_else (match_operand:SF 1 "" "")
1568 (const_string "SF")
1569 (const_string "DF")))
1570 (set_attr "prefix_rep" "0")
1571 (set (attr "prefix_data16")
1572 (if_then_else (eq_attr "mode" "DF")
1573 (const_string "1")
1574 (const_string "0")))
1575 (set_attr "athlon_decode" "vector")
1576 (set_attr "amdfam10_decode" "direct")])
1577
1578 (define_insn "*cmpfp_iu_387"
1579 [(set (reg:CCFPU FLAGS_REG)
1580 (compare:CCFPU (match_operand 0 "register_operand" "f")
1581 (match_operand 1 "register_operand" "f")))]
1582 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1583 && TARGET_CMOVE
1584 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1585 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1586 "* return output_fp_compare (insn, operands, 1, 1);"
1587 [(set_attr "type" "fcmp")
1588 (set (attr "mode")
1589 (cond [(match_operand:SF 1 "" "")
1590 (const_string "SF")
1591 (match_operand:DF 1 "" "")
1592 (const_string "DF")
1593 ]
1594 (const_string "XF")))
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "direct")])
1597 \f
1598 ;; Move instructions.
1599
1600 (define_expand "movoi"
1601 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1602 (match_operand:OI 1 "general_operand" ""))]
1603 "TARGET_AVX"
1604 "ix86_expand_move (OImode, operands); DONE;")
1605
1606 (define_expand "movti"
1607 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1608 (match_operand:TI 1 "nonimmediate_operand" ""))]
1609 "TARGET_64BIT || TARGET_SSE"
1610 {
1611 if (TARGET_64BIT)
1612 ix86_expand_move (TImode, operands);
1613 else if (push_operand (operands[0], TImode))
1614 ix86_expand_push (TImode, operands[1]);
1615 else
1616 ix86_expand_vector_move (TImode, operands);
1617 DONE;
1618 })
1619
1620 ;; This expands to what emit_move_complex would generate if we didn't
1621 ;; have a movti pattern. Having this avoids problems with reload on
1622 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1623 ;; to have around all the time.
1624 (define_expand "movcdi"
1625 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1626 (match_operand:CDI 1 "general_operand" ""))]
1627 ""
1628 {
1629 if (push_operand (operands[0], CDImode))
1630 emit_move_complex_push (CDImode, operands[0], operands[1]);
1631 else
1632 emit_move_complex_parts (operands[0], operands[1]);
1633 DONE;
1634 })
1635
1636 (define_expand "mov<mode>"
1637 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1638 (match_operand:SWI1248x 1 "general_operand" ""))]
1639 ""
1640 "ix86_expand_move (<MODE>mode, operands); DONE;")
1641
1642 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1643 ;; general_operand.
1644 ;;
1645 ;; %%% We don't use a post-inc memory reference because x86 is not a
1646 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1647 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1648 ;; targets without our curiosities, and it is just as easy to represent
1649 ;; this differently.
1650
1651 (define_insn "*pushdi2_rex64"
1652 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1653 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1654 "TARGET_64BIT"
1655 "@
1656 push{q}\t%1
1657 #"
1658 [(set_attr "type" "push,multi")
1659 (set_attr "mode" "DI")])
1660
1661 ;; Convert impossible pushes of immediate to existing instructions.
1662 ;; First try to get scratch register and go through it. In case this
1663 ;; fails, push sign extended lower part first and then overwrite
1664 ;; upper part by 32bit move.
1665 (define_peephole2
1666 [(match_scratch:DI 2 "r")
1667 (set (match_operand:DI 0 "push_operand" "")
1668 (match_operand:DI 1 "immediate_operand" ""))]
1669 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1670 && !x86_64_immediate_operand (operands[1], DImode)"
1671 [(set (match_dup 2) (match_dup 1))
1672 (set (match_dup 0) (match_dup 2))]
1673 "")
1674
1675 ;; We need to define this as both peepholer and splitter for case
1676 ;; peephole2 pass is not run.
1677 ;; "&& 1" is needed to keep it from matching the previous pattern.
1678 (define_peephole2
1679 [(set (match_operand:DI 0 "push_operand" "")
1680 (match_operand:DI 1 "immediate_operand" ""))]
1681 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1682 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1683 [(set (match_dup 0) (match_dup 1))
1684 (set (match_dup 2) (match_dup 3))]
1685 {
1686 split_di (&operands[1], 1, &operands[2], &operands[3]);
1687
1688 operands[1] = gen_lowpart (DImode, operands[2]);
1689 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1690 GEN_INT (4)));
1691 })
1692
1693 (define_split
1694 [(set (match_operand:DI 0 "push_operand" "")
1695 (match_operand:DI 1 "immediate_operand" ""))]
1696 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1697 ? epilogue_completed : reload_completed)
1698 && !symbolic_operand (operands[1], DImode)
1699 && !x86_64_immediate_operand (operands[1], DImode)"
1700 [(set (match_dup 0) (match_dup 1))
1701 (set (match_dup 2) (match_dup 3))]
1702 {
1703 split_di (&operands[1], 1, &operands[2], &operands[3]);
1704
1705 operands[1] = gen_lowpart (DImode, operands[2]);
1706 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1707 GEN_INT (4)));
1708 })
1709
1710 (define_insn "*pushdi2"
1711 [(set (match_operand:DI 0 "push_operand" "=<")
1712 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1713 "!TARGET_64BIT"
1714 "#")
1715
1716 (define_split
1717 [(set (match_operand:DI 0 "push_operand" "")
1718 (match_operand:DI 1 "general_operand" ""))]
1719 "!TARGET_64BIT && reload_completed
1720 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1721 [(const_int 0)]
1722 "ix86_split_long_move (operands); DONE;")
1723
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1727 "!TARGET_64BIT"
1728 "push{l}\t%1"
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1731
1732 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1733 ;; "push a byte/word". But actually we use pushl, which has the effect
1734 ;; of rounding the amount pushed up to a word.
1735
1736 ;; For 64BIT abi we always round up to 8 bytes.
1737 (define_insn "*push<mode>2_rex64"
1738 [(set (match_operand:SWI124 0 "push_operand" "=X")
1739 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1740 "TARGET_64BIT"
1741 "push{q}\t%q1"
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "DI")])
1744
1745 (define_insn "*push<mode>2"
1746 [(set (match_operand:SWI12 0 "push_operand" "=X")
1747 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1748 "!TARGET_64BIT"
1749 "push{l}\t%k1"
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "SI")])
1752
1753 (define_insn "*push<mode>2_prologue"
1754 [(set (match_operand:P 0 "push_operand" "=<")
1755 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1756 (clobber (mem:BLK (scratch)))]
1757 ""
1758 "push{<imodesuffix>}\t%1"
1759 [(set_attr "type" "push")
1760 (set_attr "mode" "<MODE>")])
1761
1762 (define_insn "popdi1"
1763 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1764 (mem:DI (reg:DI SP_REG)))
1765 (set (reg:DI SP_REG)
1766 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1767 "TARGET_64BIT"
1768 "pop{q}\t%0"
1769 [(set_attr "type" "pop")
1770 (set_attr "mode" "DI")])
1771
1772 (define_insn "popsi1"
1773 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1774 (mem:SI (reg:SI SP_REG)))
1775 (set (reg:SI SP_REG)
1776 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1777 "!TARGET_64BIT"
1778 "pop{l}\t%0"
1779 [(set_attr "type" "pop")
1780 (set_attr "mode" "SI")])
1781
1782 (define_insn "*popdi1_epilogue"
1783 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1784 (mem:DI (reg:DI SP_REG)))
1785 (set (reg:DI SP_REG)
1786 (plus:DI (reg:DI SP_REG) (const_int 8)))
1787 (clobber (mem:BLK (scratch)))]
1788 "TARGET_64BIT"
1789 "pop{q}\t%0"
1790 [(set_attr "type" "pop")
1791 (set_attr "mode" "DI")])
1792
1793 (define_insn "*popsi1_epilogue"
1794 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1795 (mem:SI (reg:SI SP_REG)))
1796 (set (reg:SI SP_REG)
1797 (plus:SI (reg:SI SP_REG) (const_int 4)))
1798 (clobber (mem:BLK (scratch)))]
1799 "!TARGET_64BIT"
1800 "pop{l}\t%0"
1801 [(set_attr "type" "pop")
1802 (set_attr "mode" "SI")])
1803
1804 (define_insn "*mov<mode>_xor"
1805 [(set (match_operand:SWI48 0 "register_operand" "=r")
1806 (match_operand:SWI48 1 "const0_operand" ""))
1807 (clobber (reg:CC FLAGS_REG))]
1808 "reload_completed"
1809 "xor{l}\t%k0, %k0"
1810 [(set_attr "type" "alu1")
1811 (set_attr "mode" "SI")
1812 (set_attr "length_immediate" "0")])
1813
1814 (define_insn "*mov<mode>_or"
1815 [(set (match_operand:SWI48 0 "register_operand" "=r")
1816 (match_operand:SWI48 1 "const_int_operand" ""))
1817 (clobber (reg:CC FLAGS_REG))]
1818 "reload_completed
1819 && operands[1] == constm1_rtx"
1820 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1821 [(set_attr "type" "alu1")
1822 (set_attr "mode" "<MODE>")
1823 (set_attr "length_immediate" "1")])
1824
1825 (define_insn "*movoi_internal_avx"
1826 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1827 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1828 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1829 {
1830 switch (which_alternative)
1831 {
1832 case 0:
1833 return "vxorps\t%0, %0, %0";
1834 case 1:
1835 case 2:
1836 if (misaligned_operand (operands[0], OImode)
1837 || misaligned_operand (operands[1], OImode))
1838 return "vmovdqu\t{%1, %0|%0, %1}";
1839 else
1840 return "vmovdqa\t{%1, %0|%0, %1}";
1841 default:
1842 gcc_unreachable ();
1843 }
1844 }
1845 [(set_attr "type" "sselog1,ssemov,ssemov")
1846 (set_attr "prefix" "vex")
1847 (set_attr "mode" "OI")])
1848
1849 (define_insn "*movti_internal_rex64"
1850 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1851 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1852 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1853 {
1854 switch (which_alternative)
1855 {
1856 case 0:
1857 case 1:
1858 return "#";
1859 case 2:
1860 if (get_attr_mode (insn) == MODE_V4SF)
1861 return "%vxorps\t%0, %d0";
1862 else
1863 return "%vpxor\t%0, %d0";
1864 case 3:
1865 case 4:
1866 /* TDmode values are passed as TImode on the stack. Moving them
1867 to stack may result in unaligned memory access. */
1868 if (misaligned_operand (operands[0], TImode)
1869 || misaligned_operand (operands[1], TImode))
1870 {
1871 if (get_attr_mode (insn) == MODE_V4SF)
1872 return "%vmovups\t{%1, %0|%0, %1}";
1873 else
1874 return "%vmovdqu\t{%1, %0|%0, %1}";
1875 }
1876 else
1877 {
1878 if (get_attr_mode (insn) == MODE_V4SF)
1879 return "%vmovaps\t{%1, %0|%0, %1}";
1880 else
1881 return "%vmovdqa\t{%1, %0|%0, %1}";
1882 }
1883 default:
1884 gcc_unreachable ();
1885 }
1886 }
1887 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1888 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1889 (set (attr "mode")
1890 (cond [(eq_attr "alternative" "2,3")
1891 (if_then_else
1892 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1893 (const_int 0))
1894 (const_string "V4SF")
1895 (const_string "TI"))
1896 (eq_attr "alternative" "4")
1897 (if_then_else
1898 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1899 (const_int 0))
1900 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1901 (const_int 0)))
1902 (const_string "V4SF")
1903 (const_string "TI"))]
1904 (const_string "DI")))])
1905
1906 (define_split
1907 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1908 (match_operand:TI 1 "general_operand" ""))]
1909 "reload_completed
1910 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1911 [(const_int 0)]
1912 "ix86_split_long_move (operands); DONE;")
1913
1914 (define_insn "*movti_internal_sse"
1915 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1916 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1917 "TARGET_SSE && !TARGET_64BIT
1918 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1919 {
1920 switch (which_alternative)
1921 {
1922 case 0:
1923 if (get_attr_mode (insn) == MODE_V4SF)
1924 return "%vxorps\t%0, %d0";
1925 else
1926 return "%vpxor\t%0, %d0";
1927 case 1:
1928 case 2:
1929 /* TDmode values are passed as TImode on the stack. Moving them
1930 to stack may result in unaligned memory access. */
1931 if (misaligned_operand (operands[0], TImode)
1932 || misaligned_operand (operands[1], TImode))
1933 {
1934 if (get_attr_mode (insn) == MODE_V4SF)
1935 return "%vmovups\t{%1, %0|%0, %1}";
1936 else
1937 return "%vmovdqu\t{%1, %0|%0, %1}";
1938 }
1939 else
1940 {
1941 if (get_attr_mode (insn) == MODE_V4SF)
1942 return "%vmovaps\t{%1, %0|%0, %1}";
1943 else
1944 return "%vmovdqa\t{%1, %0|%0, %1}";
1945 }
1946 default:
1947 gcc_unreachable ();
1948 }
1949 }
1950 [(set_attr "type" "sselog1,ssemov,ssemov")
1951 (set_attr "prefix" "maybe_vex")
1952 (set (attr "mode")
1953 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1954 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1955 (const_int 0)))
1956 (const_string "V4SF")
1957 (and (eq_attr "alternative" "2")
1958 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1959 (const_int 0)))
1960 (const_string "V4SF")]
1961 (const_string "TI")))])
1962
1963 (define_insn "*movdi_internal_rex64"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1966 (match_operand:DI 1 "general_operand"
1967 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1968 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969 {
1970 switch (get_attr_type (insn))
1971 {
1972 case TYPE_SSECVT:
1973 if (SSE_REG_P (operands[0]))
1974 return "movq2dq\t{%1, %0|%0, %1}";
1975 else
1976 return "movdq2q\t{%1, %0|%0, %1}";
1977
1978 case TYPE_SSEMOV:
1979 if (TARGET_AVX)
1980 {
1981 if (get_attr_mode (insn) == MODE_TI)
1982 return "vmovdqa\t{%1, %0|%0, %1}";
1983 else
1984 return "vmovq\t{%1, %0|%0, %1}";
1985 }
1986
1987 if (get_attr_mode (insn) == MODE_TI)
1988 return "movdqa\t{%1, %0|%0, %1}";
1989 /* FALLTHRU */
1990
1991 case TYPE_MMXMOV:
1992 /* Moves from and into integer register is done using movd
1993 opcode with REX prefix. */
1994 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1995 return "movd\t{%1, %0|%0, %1}";
1996 return "movq\t{%1, %0|%0, %1}";
1997
1998 case TYPE_SSELOG1:
1999 return "%vpxor\t%0, %d0";
2000
2001 case TYPE_MMX:
2002 return "pxor\t%0, %0";
2003
2004 case TYPE_MULTI:
2005 return "#";
2006
2007 case TYPE_LEA:
2008 return "lea{q}\t{%a1, %0|%0, %a1}";
2009
2010 default:
2011 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2012 if (get_attr_mode (insn) == MODE_SI)
2013 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2014 else if (which_alternative == 2)
2015 return "movabs{q}\t{%1, %0|%0, %1}";
2016 else
2017 return "mov{q}\t{%1, %0|%0, %1}";
2018 }
2019 }
2020 [(set (attr "type")
2021 (cond [(eq_attr "alternative" "5")
2022 (const_string "mmx")
2023 (eq_attr "alternative" "6,7,8,9,10")
2024 (const_string "mmxmov")
2025 (eq_attr "alternative" "11")
2026 (const_string "sselog1")
2027 (eq_attr "alternative" "12,13,14,15,16")
2028 (const_string "ssemov")
2029 (eq_attr "alternative" "17,18")
2030 (const_string "ssecvt")
2031 (eq_attr "alternative" "4")
2032 (const_string "multi")
2033 (match_operand:DI 1 "pic_32bit_operand" "")
2034 (const_string "lea")
2035 ]
2036 (const_string "imov")))
2037 (set (attr "modrm")
2038 (if_then_else
2039 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2040 (const_string "0")
2041 (const_string "*")))
2042 (set (attr "length_immediate")
2043 (if_then_else
2044 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2045 (const_string "8")
2046 (const_string "*")))
2047 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2048 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2049 (set (attr "prefix")
2050 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2051 (const_string "maybe_vex")
2052 (const_string "orig")))
2053 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2054
2055 ;; Convert impossible stores of immediate to existing instructions.
2056 ;; First try to get scratch register and go through it. In case this
2057 ;; fails, move by 32bit parts.
2058 (define_peephole2
2059 [(match_scratch:DI 2 "r")
2060 (set (match_operand:DI 0 "memory_operand" "")
2061 (match_operand:DI 1 "immediate_operand" ""))]
2062 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2063 && !x86_64_immediate_operand (operands[1], DImode)"
2064 [(set (match_dup 2) (match_dup 1))
2065 (set (match_dup 0) (match_dup 2))]
2066 "")
2067
2068 ;; We need to define this as both peepholer and splitter for case
2069 ;; peephole2 pass is not run.
2070 ;; "&& 1" is needed to keep it from matching the previous pattern.
2071 (define_peephole2
2072 [(set (match_operand:DI 0 "memory_operand" "")
2073 (match_operand:DI 1 "immediate_operand" ""))]
2074 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2075 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2076 [(set (match_dup 2) (match_dup 3))
2077 (set (match_dup 4) (match_dup 5))]
2078 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2079
2080 (define_split
2081 [(set (match_operand:DI 0 "memory_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2084 ? epilogue_completed : reload_completed)
2085 && !symbolic_operand (operands[1], DImode)
2086 && !x86_64_immediate_operand (operands[1], DImode)"
2087 [(set (match_dup 2) (match_dup 3))
2088 (set (match_dup 4) (match_dup 5))]
2089 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2090
2091 (define_insn "*movdi_internal"
2092 [(set (match_operand:DI 0 "nonimmediate_operand"
2093 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2094 (match_operand:DI 1 "general_operand"
2095 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2096 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2097 "@
2098 #
2099 #
2100 pxor\t%0, %0
2101 movq\t{%1, %0|%0, %1}
2102 movq\t{%1, %0|%0, %1}
2103 %vpxor\t%0, %d0
2104 %vmovq\t{%1, %0|%0, %1}
2105 %vmovdqa\t{%1, %0|%0, %1}
2106 %vmovq\t{%1, %0|%0, %1}
2107 xorps\t%0, %0
2108 movlps\t{%1, %0|%0, %1}
2109 movaps\t{%1, %0|%0, %1}
2110 movlps\t{%1, %0|%0, %1}"
2111 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2112 (set (attr "prefix")
2113 (if_then_else (eq_attr "alternative" "5,6,7,8")
2114 (const_string "vex")
2115 (const_string "orig")))
2116 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2117
2118 (define_split
2119 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2120 (match_operand:DI 1 "general_operand" ""))]
2121 "!TARGET_64BIT && reload_completed
2122 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2123 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2124 [(const_int 0)]
2125 "ix86_split_long_move (operands); DONE;")
2126
2127 (define_insn "*movsi_internal"
2128 [(set (match_operand:SI 0 "nonimmediate_operand"
2129 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2130 (match_operand:SI 1 "general_operand"
2131 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2132 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2133 {
2134 switch (get_attr_type (insn))
2135 {
2136 case TYPE_SSELOG1:
2137 if (get_attr_mode (insn) == MODE_TI)
2138 return "%vpxor\t%0, %d0";
2139 return "%vxorps\t%0, %d0";
2140
2141 case TYPE_SSEMOV:
2142 switch (get_attr_mode (insn))
2143 {
2144 case MODE_TI:
2145 return "%vmovdqa\t{%1, %0|%0, %1}";
2146 case MODE_V4SF:
2147 return "%vmovaps\t{%1, %0|%0, %1}";
2148 case MODE_SI:
2149 return "%vmovd\t{%1, %0|%0, %1}";
2150 case MODE_SF:
2151 return "%vmovss\t{%1, %0|%0, %1}";
2152 default:
2153 gcc_unreachable ();
2154 }
2155
2156 case TYPE_MMX:
2157 return "pxor\t%0, %0";
2158
2159 case TYPE_MMXMOV:
2160 if (get_attr_mode (insn) == MODE_DI)
2161 return "movq\t{%1, %0|%0, %1}";
2162 return "movd\t{%1, %0|%0, %1}";
2163
2164 case TYPE_LEA:
2165 return "lea{l}\t{%a1, %0|%0, %a1}";
2166
2167 default:
2168 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2169 return "mov{l}\t{%1, %0|%0, %1}";
2170 }
2171 }
2172 [(set (attr "type")
2173 (cond [(eq_attr "alternative" "2")
2174 (const_string "mmx")
2175 (eq_attr "alternative" "3,4,5")
2176 (const_string "mmxmov")
2177 (eq_attr "alternative" "6")
2178 (const_string "sselog1")
2179 (eq_attr "alternative" "7,8,9,10,11")
2180 (const_string "ssemov")
2181 (match_operand:DI 1 "pic_32bit_operand" "")
2182 (const_string "lea")
2183 ]
2184 (const_string "imov")))
2185 (set (attr "prefix")
2186 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2187 (const_string "orig")
2188 (const_string "maybe_vex")))
2189 (set (attr "prefix_data16")
2190 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2191 (const_string "1")
2192 (const_string "*")))
2193 (set (attr "mode")
2194 (cond [(eq_attr "alternative" "2,3")
2195 (const_string "DI")
2196 (eq_attr "alternative" "6,7")
2197 (if_then_else
2198 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2199 (const_string "V4SF")
2200 (const_string "TI"))
2201 (and (eq_attr "alternative" "8,9,10,11")
2202 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2203 (const_string "SF")
2204 ]
2205 (const_string "SI")))])
2206
2207 (define_insn "*movhi_internal"
2208 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2209 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2210 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2211 {
2212 switch (get_attr_type (insn))
2213 {
2214 case TYPE_IMOVX:
2215 /* movzwl is faster than movw on p2 due to partial word stalls,
2216 though not as fast as an aligned movl. */
2217 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2218 default:
2219 if (get_attr_mode (insn) == MODE_SI)
2220 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2221 else
2222 return "mov{w}\t{%1, %0|%0, %1}";
2223 }
2224 }
2225 [(set (attr "type")
2226 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2227 (const_int 0))
2228 (const_string "imov")
2229 (and (eq_attr "alternative" "0")
2230 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2231 (const_int 0))
2232 (eq (symbol_ref "TARGET_HIMODE_MATH")
2233 (const_int 0))))
2234 (const_string "imov")
2235 (and (eq_attr "alternative" "1,2")
2236 (match_operand:HI 1 "aligned_operand" ""))
2237 (const_string "imov")
2238 (and (ne (symbol_ref "TARGET_MOVX")
2239 (const_int 0))
2240 (eq_attr "alternative" "0,2"))
2241 (const_string "imovx")
2242 ]
2243 (const_string "imov")))
2244 (set (attr "mode")
2245 (cond [(eq_attr "type" "imovx")
2246 (const_string "SI")
2247 (and (eq_attr "alternative" "1,2")
2248 (match_operand:HI 1 "aligned_operand" ""))
2249 (const_string "SI")
2250 (and (eq_attr "alternative" "0")
2251 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2252 (const_int 0))
2253 (eq (symbol_ref "TARGET_HIMODE_MATH")
2254 (const_int 0))))
2255 (const_string "SI")
2256 ]
2257 (const_string "HI")))])
2258
2259 ;; Situation is quite tricky about when to choose full sized (SImode) move
2260 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2261 ;; partial register dependency machines (such as AMD Athlon), where QImode
2262 ;; moves issue extra dependency and for partial register stalls machines
2263 ;; that don't use QImode patterns (and QImode move cause stall on the next
2264 ;; instruction).
2265 ;;
2266 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2267 ;; register stall machines with, where we use QImode instructions, since
2268 ;; partial register stall can be caused there. Then we use movzx.
2269 (define_insn "*movqi_internal"
2270 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2271 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2272 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2273 {
2274 switch (get_attr_type (insn))
2275 {
2276 case TYPE_IMOVX:
2277 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2278 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2279 default:
2280 if (get_attr_mode (insn) == MODE_SI)
2281 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2282 else
2283 return "mov{b}\t{%1, %0|%0, %1}";
2284 }
2285 }
2286 [(set (attr "type")
2287 (cond [(and (eq_attr "alternative" "5")
2288 (not (match_operand:QI 1 "aligned_operand" "")))
2289 (const_string "imovx")
2290 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2291 (const_int 0))
2292 (const_string "imov")
2293 (and (eq_attr "alternative" "3")
2294 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2295 (const_int 0))
2296 (eq (symbol_ref "TARGET_QIMODE_MATH")
2297 (const_int 0))))
2298 (const_string "imov")
2299 (eq_attr "alternative" "3,5")
2300 (const_string "imovx")
2301 (and (ne (symbol_ref "TARGET_MOVX")
2302 (const_int 0))
2303 (eq_attr "alternative" "2"))
2304 (const_string "imovx")
2305 ]
2306 (const_string "imov")))
2307 (set (attr "mode")
2308 (cond [(eq_attr "alternative" "3,4,5")
2309 (const_string "SI")
2310 (eq_attr "alternative" "6")
2311 (const_string "QI")
2312 (eq_attr "type" "imovx")
2313 (const_string "SI")
2314 (and (eq_attr "type" "imov")
2315 (and (eq_attr "alternative" "0,1")
2316 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2317 (const_int 0))
2318 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2319 (const_int 0))
2320 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2321 (const_int 0))))))
2322 (const_string "SI")
2323 ;; Avoid partial register stalls when not using QImode arithmetic
2324 (and (eq_attr "type" "imov")
2325 (and (eq_attr "alternative" "0,1")
2326 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2327 (const_int 0))
2328 (eq (symbol_ref "TARGET_QIMODE_MATH")
2329 (const_int 0)))))
2330 (const_string "SI")
2331 ]
2332 (const_string "QI")))])
2333
2334 ;; Stores and loads of ax to arbitrary constant address.
2335 ;; We fake an second form of instruction to force reload to load address
2336 ;; into register when rax is not available
2337 (define_insn "*movabs<mode>_1"
2338 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2339 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2340 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2341 "@
2342 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2343 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2344 [(set_attr "type" "imov")
2345 (set_attr "modrm" "0,*")
2346 (set_attr "length_address" "8,0")
2347 (set_attr "length_immediate" "0,*")
2348 (set_attr "memory" "store")
2349 (set_attr "mode" "<MODE>")])
2350
2351 (define_insn "*movabs<mode>_2"
2352 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2353 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2354 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2355 "@
2356 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2357 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2358 [(set_attr "type" "imov")
2359 (set_attr "modrm" "0,*")
2360 (set_attr "length_address" "8,0")
2361 (set_attr "length_immediate" "0")
2362 (set_attr "memory" "load")
2363 (set_attr "mode" "<MODE>")])
2364
2365 (define_insn "*swap<mode>"
2366 [(set (match_operand:SWI48 0 "register_operand" "+r")
2367 (match_operand:SWI48 1 "register_operand" "+r"))
2368 (set (match_dup 1)
2369 (match_dup 0))]
2370 ""
2371 "xchg{<imodesuffix>}\t%1, %0"
2372 [(set_attr "type" "imov")
2373 (set_attr "mode" "<MODE>")
2374 (set_attr "pent_pair" "np")
2375 (set_attr "athlon_decode" "vector")
2376 (set_attr "amdfam10_decode" "double")])
2377
2378 (define_insn "*swap<mode>_1"
2379 [(set (match_operand:SWI12 0 "register_operand" "+r")
2380 (match_operand:SWI12 1 "register_operand" "+r"))
2381 (set (match_dup 1)
2382 (match_dup 0))]
2383 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2384 "xchg{l}\t%k1, %k0"
2385 [(set_attr "type" "imov")
2386 (set_attr "mode" "SI")
2387 (set_attr "pent_pair" "np")
2388 (set_attr "athlon_decode" "vector")
2389 (set_attr "amdfam10_decode" "double")])
2390
2391 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2392 ;; is disabled for AMDFAM10
2393 (define_insn "*swap<mode>_2"
2394 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2395 (match_operand:SWI12 1 "register_operand" "+<r>"))
2396 (set (match_dup 1)
2397 (match_dup 0))]
2398 "TARGET_PARTIAL_REG_STALL"
2399 "xchg{<imodesuffix>}\t%1, %0"
2400 [(set_attr "type" "imov")
2401 (set_attr "mode" "<MODE>")
2402 (set_attr "pent_pair" "np")
2403 (set_attr "athlon_decode" "vector")])
2404
2405 (define_expand "movstrict<mode>"
2406 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2407 (match_operand:SWI12 1 "general_operand" ""))]
2408 ""
2409 {
2410 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2411 FAIL;
2412 /* Don't generate memory->memory moves, go through a register */
2413 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2414 operands[1] = force_reg (<MODE>mode, operands[1]);
2415 })
2416
2417 (define_insn "*movstrict<mode>_1"
2418 [(set (strict_low_part
2419 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2420 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2421 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2423 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2424 [(set_attr "type" "imov")
2425 (set_attr "mode" "<MODE>")])
2426
2427 (define_insn "*movstrict<mode>_xor"
2428 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2429 (match_operand:SWI12 1 "const0_operand" ""))
2430 (clobber (reg:CC FLAGS_REG))]
2431 "reload_completed"
2432 "xor{<imodesuffix>}\t%0, %0"
2433 [(set_attr "type" "alu1")
2434 (set_attr "mode" "<MODE>")
2435 (set_attr "length_immediate" "0")])
2436
2437 (define_insn "*mov<mode>_extv_1"
2438 [(set (match_operand:SWI24 0 "register_operand" "=R")
2439 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2440 (const_int 8)
2441 (const_int 8)))]
2442 ""
2443 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2444 [(set_attr "type" "imovx")
2445 (set_attr "mode" "SI")])
2446
2447 (define_insn "*movqi_extv_1_rex64"
2448 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2449 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2450 (const_int 8)
2451 (const_int 8)))]
2452 "TARGET_64BIT"
2453 {
2454 switch (get_attr_type (insn))
2455 {
2456 case TYPE_IMOVX:
2457 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2458 default:
2459 return "mov{b}\t{%h1, %0|%0, %h1}";
2460 }
2461 }
2462 [(set (attr "type")
2463 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2464 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2465 (ne (symbol_ref "TARGET_MOVX")
2466 (const_int 0))))
2467 (const_string "imovx")
2468 (const_string "imov")))
2469 (set (attr "mode")
2470 (if_then_else (eq_attr "type" "imovx")
2471 (const_string "SI")
2472 (const_string "QI")))])
2473
2474 (define_insn "*movqi_extv_1"
2475 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2476 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2477 (const_int 8)
2478 (const_int 8)))]
2479 "!TARGET_64BIT"
2480 {
2481 switch (get_attr_type (insn))
2482 {
2483 case TYPE_IMOVX:
2484 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2485 default:
2486 return "mov{b}\t{%h1, %0|%0, %h1}";
2487 }
2488 }
2489 [(set (attr "type")
2490 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2491 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2492 (ne (symbol_ref "TARGET_MOVX")
2493 (const_int 0))))
2494 (const_string "imovx")
2495 (const_string "imov")))
2496 (set (attr "mode")
2497 (if_then_else (eq_attr "type" "imovx")
2498 (const_string "SI")
2499 (const_string "QI")))])
2500
2501 (define_insn "*mov<mode>_extzv_1"
2502 [(set (match_operand:SWI48 0 "register_operand" "=R")
2503 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2504 (const_int 8)
2505 (const_int 8)))]
2506 ""
2507 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2508 [(set_attr "type" "imovx")
2509 (set_attr "mode" "SI")])
2510
2511 (define_insn "*movqi_extzv_2_rex64"
2512 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2513 (subreg:QI
2514 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2515 (const_int 8)
2516 (const_int 8)) 0))]
2517 "TARGET_64BIT"
2518 {
2519 switch (get_attr_type (insn))
2520 {
2521 case TYPE_IMOVX:
2522 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2523 default:
2524 return "mov{b}\t{%h1, %0|%0, %h1}";
2525 }
2526 }
2527 [(set (attr "type")
2528 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2529 (ne (symbol_ref "TARGET_MOVX")
2530 (const_int 0)))
2531 (const_string "imovx")
2532 (const_string "imov")))
2533 (set (attr "mode")
2534 (if_then_else (eq_attr "type" "imovx")
2535 (const_string "SI")
2536 (const_string "QI")))])
2537
2538 (define_insn "*movqi_extzv_2"
2539 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2540 (subreg:QI
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2542 (const_int 8)
2543 (const_int 8)) 0))]
2544 "!TARGET_64BIT"
2545 {
2546 switch (get_attr_type (insn))
2547 {
2548 case TYPE_IMOVX:
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2550 default:
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2552 }
2553 }
2554 [(set (attr "type")
2555 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2556 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2557 (ne (symbol_ref "TARGET_MOVX")
2558 (const_int 0))))
2559 (const_string "imovx")
2560 (const_string "imov")))
2561 (set (attr "mode")
2562 (if_then_else (eq_attr "type" "imovx")
2563 (const_string "SI")
2564 (const_string "QI")))])
2565
2566 (define_expand "mov<mode>_insv_1"
2567 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2568 (const_int 8)
2569 (const_int 8))
2570 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2571 ""
2572 "")
2573
2574 (define_insn "*mov<mode>_insv_1_rex64"
2575 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2576 (const_int 8)
2577 (const_int 8))
2578 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2579 "TARGET_64BIT"
2580 "mov{b}\t{%b1, %h0|%h0, %b1}"
2581 [(set_attr "type" "imov")
2582 (set_attr "mode" "QI")])
2583
2584 (define_insn "*movsi_insv_1"
2585 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2586 (const_int 8)
2587 (const_int 8))
2588 (match_operand:SI 1 "general_operand" "Qmn"))]
2589 "!TARGET_64BIT"
2590 "mov{b}\t{%b1, %h0|%h0, %b1}"
2591 [(set_attr "type" "imov")
2592 (set_attr "mode" "QI")])
2593
2594 (define_insn "*movqi_insv_2"
2595 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2596 (const_int 8)
2597 (const_int 8))
2598 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2599 (const_int 8)))]
2600 ""
2601 "mov{b}\t{%h1, %h0|%h0, %h1}"
2602 [(set_attr "type" "imov")
2603 (set_attr "mode" "QI")])
2604 \f
2605 ;; Floating point move instructions.
2606
2607 (define_expand "movtf"
2608 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2609 (match_operand:TF 1 "nonimmediate_operand" ""))]
2610 "TARGET_SSE2"
2611 {
2612 ix86_expand_move (TFmode, operands);
2613 DONE;
2614 })
2615
2616 (define_expand "mov<mode>"
2617 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2618 (match_operand:X87MODEF 1 "general_operand" ""))]
2619 ""
2620 "ix86_expand_move (<MODE>mode, operands); DONE;")
2621
2622 (define_insn "*pushtf"
2623 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2624 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2625 "TARGET_SSE2"
2626 {
2627 /* This insn should be already split before reg-stack. */
2628 gcc_unreachable ();
2629 }
2630 [(set_attr "type" "multi")
2631 (set_attr "unit" "sse,*,*")
2632 (set_attr "mode" "TF,SI,SI")])
2633
2634 (define_split
2635 [(set (match_operand:TF 0 "push_operand" "")
2636 (match_operand:TF 1 "general_operand" ""))]
2637 "TARGET_SSE2 && reload_completed
2638 && !SSE_REG_P (operands[1])"
2639 [(const_int 0)]
2640 "ix86_split_long_move (operands); DONE;")
2641
2642 (define_split
2643 [(set (match_operand:TF 0 "push_operand" "")
2644 (match_operand:TF 1 "any_fp_register_operand" ""))]
2645 "TARGET_SSE2"
2646 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2647 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
2648 "")
2649
2650 (define_insn "*pushxf"
2651 [(set (match_operand:XF 0 "push_operand" "=<,<")
2652 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2653 "optimize_function_for_speed_p (cfun)"
2654 {
2655 /* This insn should be already split before reg-stack. */
2656 gcc_unreachable ();
2657 }
2658 [(set_attr "type" "multi")
2659 (set_attr "unit" "i387,*")
2660 (set_attr "mode" "XF,SI")])
2661
2662 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references (assuming that any given constant is pushed
2666 ;; only once, but this ought to be handled elsewhere).
2667
2668 (define_insn "*pushxf_nointeger"
2669 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2670 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2671 "optimize_function_for_size_p (cfun)"
2672 {
2673 /* This insn should be already split before reg-stack. */
2674 gcc_unreachable ();
2675 }
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*,*")
2678 (set_attr "mode" "XF,SI,SI")])
2679
2680 (define_split
2681 [(set (match_operand:XF 0 "push_operand" "")
2682 (match_operand:XF 1 "any_fp_register_operand" ""))]
2683 "reload_completed"
2684 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2685 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2686 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2687
2688 (define_split
2689 [(set (match_operand:XF 0 "push_operand" "")
2690 (match_operand:XF 1 "general_operand" ""))]
2691 "reload_completed
2692 && !ANY_FP_REG_P (operands[1])"
2693 [(const_int 0)]
2694 "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*pushdf"
2697 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2698 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2699 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2700 {
2701 /* This insn should be already split before reg-stack. */
2702 gcc_unreachable ();
2703 }
2704 [(set_attr "type" "multi")
2705 (set_attr "unit" "i387,*,*")
2706 (set_attr "mode" "DF,SI,DF")])
2707
2708 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2709 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2710 ;; On the average, pushdf using integers can be still shorter. Allow this
2711 ;; pattern for optimize_size too.
2712
2713 (define_insn "*pushdf_nointeger"
2714 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2715 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2716 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2717 {
2718 /* This insn should be already split before reg-stack. */
2719 gcc_unreachable ();
2720 }
2721 [(set_attr "type" "multi")
2722 (set_attr "unit" "i387,*,*,*")
2723 (set_attr "mode" "DF,SI,SI,DF")])
2724
2725 ;; %%% Kill this when call knows how to work this out.
2726 (define_split
2727 [(set (match_operand:DF 0 "push_operand" "")
2728 (match_operand:DF 1 "any_fp_register_operand" ""))]
2729 "reload_completed"
2730 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2731 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2732 "")
2733
2734 (define_split
2735 [(set (match_operand:DF 0 "push_operand" "")
2736 (match_operand:DF 1 "general_operand" ""))]
2737 "reload_completed
2738 && !ANY_FP_REG_P (operands[1])"
2739 [(const_int 0)]
2740 "ix86_split_long_move (operands); DONE;")
2741
2742 (define_insn "*pushsf_rex64"
2743 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2744 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2745 "TARGET_64BIT"
2746 {
2747 /* Anything else should be already split before reg-stack. */
2748 gcc_assert (which_alternative == 1);
2749 return "push{q}\t%q1";
2750 }
2751 [(set_attr "type" "multi,push,multi")
2752 (set_attr "unit" "i387,*,*")
2753 (set_attr "mode" "SF,DI,SF")])
2754
2755 (define_insn "*pushsf"
2756 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2757 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2758 "!TARGET_64BIT"
2759 {
2760 /* Anything else should be already split before reg-stack. */
2761 gcc_assert (which_alternative == 1);
2762 return "push{l}\t%1";
2763 }
2764 [(set_attr "type" "multi,push,multi")
2765 (set_attr "unit" "i387,*,*")
2766 (set_attr "mode" "SF,SI,SF")])
2767
2768 (define_split
2769 [(set (match_operand:SF 0 "push_operand" "")
2770 (match_operand:SF 1 "memory_operand" ""))]
2771 "reload_completed
2772 && MEM_P (operands[1])
2773 && (operands[2] = find_constant_src (insn))"
2774 [(set (match_dup 0)
2775 (match_dup 2))])
2776
2777 ;; %%% Kill this when call knows how to work this out.
2778 (define_split
2779 [(set (match_operand:SF 0 "push_operand" "")
2780 (match_operand:SF 1 "any_fp_register_operand" ""))]
2781 "reload_completed"
2782 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2783 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2784 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2785
2786 (define_insn "*movtf_internal"
2787 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2788 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2789 "TARGET_SSE2
2790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2791 {
2792 switch (which_alternative)
2793 {
2794 case 0:
2795 case 1:
2796 if (get_attr_mode (insn) == MODE_V4SF)
2797 return "%vmovaps\t{%1, %0|%0, %1}";
2798 else
2799 return "%vmovdqa\t{%1, %0|%0, %1}";
2800 case 2:
2801 if (get_attr_mode (insn) == MODE_V4SF)
2802 return "%vxorps\t%0, %d0";
2803 else
2804 return "%vpxor\t%0, %d0";
2805 case 3:
2806 case 4:
2807 return "#";
2808 default:
2809 gcc_unreachable ();
2810 }
2811 }
2812 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2813 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2814 (set (attr "mode")
2815 (cond [(eq_attr "alternative" "0,2")
2816 (if_then_else
2817 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2818 (const_int 0))
2819 (const_string "V4SF")
2820 (const_string "TI"))
2821 (eq_attr "alternative" "1")
2822 (if_then_else
2823 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2824 (const_int 0))
2825 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2826 (const_int 0)))
2827 (const_string "V4SF")
2828 (const_string "TI"))]
2829 (const_string "DI")))])
2830
2831 (define_split
2832 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2833 (match_operand:TF 1 "general_operand" ""))]
2834 "reload_completed
2835 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2836 [(const_int 0)]
2837 "ix86_split_long_move (operands); DONE;")
2838
2839 (define_insn "*movxf_internal"
2840 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2841 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2842 "optimize_function_for_speed_p (cfun)
2843 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2844 && (reload_in_progress || reload_completed
2845 || GET_CODE (operands[1]) != CONST_DOUBLE
2846 || memory_operand (operands[0], XFmode))"
2847 {
2848 switch (which_alternative)
2849 {
2850 case 0:
2851 case 1:
2852 return output_387_reg_move (insn, operands);
2853
2854 case 2:
2855 return standard_80387_constant_opcode (operands[1]);
2856
2857 case 3: case 4:
2858 return "#";
2859
2860 default:
2861 gcc_unreachable ();
2862 }
2863 }
2864 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2865 (set_attr "mode" "XF,XF,XF,SI,SI")])
2866
2867 ;; Do not use integer registers when optimizing for size
2868 (define_insn "*movxf_internal_nointeger"
2869 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2870 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2871 "optimize_function_for_size_p (cfun)
2872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873 && (reload_in_progress || reload_completed
2874 || standard_80387_constant_p (operands[1])
2875 || GET_CODE (operands[1]) != CONST_DOUBLE
2876 || memory_operand (operands[0], XFmode))"
2877 {
2878 switch (which_alternative)
2879 {
2880 case 0:
2881 case 1:
2882 return output_387_reg_move (insn, operands);
2883
2884 case 2:
2885 return standard_80387_constant_opcode (operands[1]);
2886
2887 case 3: case 4:
2888 return "#";
2889 default:
2890 gcc_unreachable ();
2891 }
2892 }
2893 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2894 (set_attr "mode" "XF,XF,XF,SI,SI")])
2895
2896 (define_split
2897 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2898 (match_operand:XF 1 "general_operand" ""))]
2899 "reload_completed
2900 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2901 && ! (ANY_FP_REG_P (operands[0]) ||
2902 (GET_CODE (operands[0]) == SUBREG
2903 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2904 && ! (ANY_FP_REG_P (operands[1]) ||
2905 (GET_CODE (operands[1]) == SUBREG
2906 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2907 [(const_int 0)]
2908 "ix86_split_long_move (operands); DONE;")
2909
2910 (define_insn "*movdf_internal_rex64"
2911 [(set (match_operand:DF 0 "nonimmediate_operand"
2912 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2913 (match_operand:DF 1 "general_operand"
2914 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2915 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2916 && (reload_in_progress || reload_completed
2917 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2918 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2919 && optimize_function_for_size_p (cfun)
2920 && standard_80387_constant_p (operands[1]))
2921 || GET_CODE (operands[1]) != CONST_DOUBLE
2922 || memory_operand (operands[0], DFmode))"
2923 {
2924 switch (which_alternative)
2925 {
2926 case 0:
2927 case 1:
2928 return output_387_reg_move (insn, operands);
2929
2930 case 2:
2931 return standard_80387_constant_opcode (operands[1]);
2932
2933 case 3:
2934 case 4:
2935 return "#";
2936
2937 case 5:
2938 switch (get_attr_mode (insn))
2939 {
2940 case MODE_V4SF:
2941 return "%vxorps\t%0, %d0";
2942 case MODE_V2DF:
2943 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2944 return "%vxorps\t%0, %d0";
2945 else
2946 return "%vxorpd\t%0, %d0";
2947 case MODE_TI:
2948 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2949 return "%vxorps\t%0, %d0";
2950 else
2951 return "%vpxor\t%0, %d0";
2952 default:
2953 gcc_unreachable ();
2954 }
2955 case 6:
2956 case 7:
2957 case 8:
2958 switch (get_attr_mode (insn))
2959 {
2960 case MODE_V4SF:
2961 return "%vmovaps\t{%1, %0|%0, %1}";
2962 case MODE_V2DF:
2963 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2964 return "%vmovaps\t{%1, %0|%0, %1}";
2965 else
2966 return "%vmovapd\t{%1, %0|%0, %1}";
2967 case MODE_TI:
2968 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2969 return "%vmovaps\t{%1, %0|%0, %1}";
2970 else
2971 return "%vmovdqa\t{%1, %0|%0, %1}";
2972 case MODE_DI:
2973 return "%vmovq\t{%1, %0|%0, %1}";
2974 case MODE_DF:
2975 if (TARGET_AVX)
2976 {
2977 if (REG_P (operands[0]) && REG_P (operands[1]))
2978 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2979 else
2980 return "vmovsd\t{%1, %0|%0, %1}";
2981 }
2982 else
2983 return "movsd\t{%1, %0|%0, %1}";
2984 case MODE_V1DF:
2985 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2986 case MODE_V2SF:
2987 return "%vmovlps\t{%1, %d0|%d0, %1}";
2988 default:
2989 gcc_unreachable ();
2990 }
2991
2992 case 9:
2993 case 10:
2994 return "%vmovd\t{%1, %0|%0, %1}";
2995
2996 default:
2997 gcc_unreachable();
2998 }
2999 }
3000 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3001 (set (attr "prefix")
3002 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3003 (const_string "orig")
3004 (const_string "maybe_vex")))
3005 (set (attr "prefix_data16")
3006 (if_then_else (eq_attr "mode" "V1DF")
3007 (const_string "1")
3008 (const_string "*")))
3009 (set (attr "mode")
3010 (cond [(eq_attr "alternative" "0,1,2")
3011 (const_string "DF")
3012 (eq_attr "alternative" "3,4,9,10")
3013 (const_string "DI")
3014
3015 /* For SSE1, we have many fewer alternatives. */
3016 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3017 (cond [(eq_attr "alternative" "5,6")
3018 (const_string "V4SF")
3019 ]
3020 (const_string "V2SF"))
3021
3022 /* xorps is one byte shorter. */
3023 (eq_attr "alternative" "5")
3024 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3025 (const_int 0))
3026 (const_string "V4SF")
3027 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3028 (const_int 0))
3029 (const_string "TI")
3030 ]
3031 (const_string "V2DF"))
3032
3033 /* For architectures resolving dependencies on
3034 whole SSE registers use APD move to break dependency
3035 chains, otherwise use short move to avoid extra work.
3036
3037 movaps encodes one byte shorter. */
3038 (eq_attr "alternative" "6")
3039 (cond
3040 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3041 (const_int 0))
3042 (const_string "V4SF")
3043 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3044 (const_int 0))
3045 (const_string "V2DF")
3046 ]
3047 (const_string "DF"))
3048 /* For architectures resolving dependencies on register
3049 parts we may avoid extra work to zero out upper part
3050 of register. */
3051 (eq_attr "alternative" "7")
3052 (if_then_else
3053 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3054 (const_int 0))
3055 (const_string "V1DF")
3056 (const_string "DF"))
3057 ]
3058 (const_string "DF")))])
3059
3060 (define_insn "*movdf_internal"
3061 [(set (match_operand:DF 0 "nonimmediate_operand"
3062 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3063 (match_operand:DF 1 "general_operand"
3064 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3065 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3066 && optimize_function_for_speed_p (cfun)
3067 && TARGET_INTEGER_DFMODE_MOVES
3068 && (reload_in_progress || reload_completed
3069 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3070 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3071 && optimize_function_for_size_p (cfun)
3072 && standard_80387_constant_p (operands[1]))
3073 || GET_CODE (operands[1]) != CONST_DOUBLE
3074 || memory_operand (operands[0], DFmode))"
3075 {
3076 switch (which_alternative)
3077 {
3078 case 0:
3079 case 1:
3080 return output_387_reg_move (insn, operands);
3081
3082 case 2:
3083 return standard_80387_constant_opcode (operands[1]);
3084
3085 case 3:
3086 case 4:
3087 return "#";
3088
3089 case 5:
3090 switch (get_attr_mode (insn))
3091 {
3092 case MODE_V4SF:
3093 return "xorps\t%0, %0";
3094 case MODE_V2DF:
3095 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3096 return "xorps\t%0, %0";
3097 else
3098 return "xorpd\t%0, %0";
3099 case MODE_TI:
3100 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3101 return "xorps\t%0, %0";
3102 else
3103 return "pxor\t%0, %0";
3104 default:
3105 gcc_unreachable ();
3106 }
3107 case 6:
3108 case 7:
3109 case 8:
3110 switch (get_attr_mode (insn))
3111 {
3112 case MODE_V4SF:
3113 return "movaps\t{%1, %0|%0, %1}";
3114 case MODE_V2DF:
3115 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3116 return "movaps\t{%1, %0|%0, %1}";
3117 else
3118 return "movapd\t{%1, %0|%0, %1}";
3119 case MODE_TI:
3120 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3121 return "movaps\t{%1, %0|%0, %1}";
3122 else
3123 return "movdqa\t{%1, %0|%0, %1}";
3124 case MODE_DI:
3125 return "movq\t{%1, %0|%0, %1}";
3126 case MODE_DF:
3127 return "movsd\t{%1, %0|%0, %1}";
3128 case MODE_V1DF:
3129 return "movlpd\t{%1, %0|%0, %1}";
3130 case MODE_V2SF:
3131 return "movlps\t{%1, %0|%0, %1}";
3132 default:
3133 gcc_unreachable ();
3134 }
3135
3136 default:
3137 gcc_unreachable();
3138 }
3139 }
3140 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3141 (set (attr "prefix_data16")
3142 (if_then_else (eq_attr "mode" "V1DF")
3143 (const_string "1")
3144 (const_string "*")))
3145 (set (attr "mode")
3146 (cond [(eq_attr "alternative" "0,1,2")
3147 (const_string "DF")
3148 (eq_attr "alternative" "3,4")
3149 (const_string "SI")
3150
3151 /* For SSE1, we have many fewer alternatives. */
3152 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3153 (cond [(eq_attr "alternative" "5,6")
3154 (const_string "V4SF")
3155 ]
3156 (const_string "V2SF"))
3157
3158 /* xorps is one byte shorter. */
3159 (eq_attr "alternative" "5")
3160 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3161 (const_int 0))
3162 (const_string "V4SF")
3163 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3164 (const_int 0))
3165 (const_string "TI")
3166 ]
3167 (const_string "V2DF"))
3168
3169 /* For architectures resolving dependencies on
3170 whole SSE registers use APD move to break dependency
3171 chains, otherwise use short move to avoid extra work.
3172
3173 movaps encodes one byte shorter. */
3174 (eq_attr "alternative" "6")
3175 (cond
3176 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3177 (const_int 0))
3178 (const_string "V4SF")
3179 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3180 (const_int 0))
3181 (const_string "V2DF")
3182 ]
3183 (const_string "DF"))
3184 /* For architectures resolving dependencies on register
3185 parts we may avoid extra work to zero out upper part
3186 of register. */
3187 (eq_attr "alternative" "7")
3188 (if_then_else
3189 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3190 (const_int 0))
3191 (const_string "V1DF")
3192 (const_string "DF"))
3193 ]
3194 (const_string "DF")))])
3195
3196 ;; Moving is usually shorter when only FP registers are used. This separate
3197 ;; movdf pattern avoids the use of integer registers for FP operations
3198 ;; when optimizing for size.
3199
3200 (define_insn "*movdf_internal_nointeger"
3201 [(set (match_operand:DF 0 "nonimmediate_operand"
3202 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3203 (match_operand:DF 1 "general_operand"
3204 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3205 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3206 && ((optimize_function_for_size_p (cfun)
3207 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3208 && (reload_in_progress || reload_completed
3209 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3211 && optimize_function_for_size_p (cfun)
3212 && !memory_operand (operands[0], DFmode)
3213 && standard_80387_constant_p (operands[1]))
3214 || GET_CODE (operands[1]) != CONST_DOUBLE
3215 || ((optimize_function_for_size_p (cfun)
3216 || !TARGET_MEMORY_MISMATCH_STALL
3217 || reload_in_progress || reload_completed)
3218 && memory_operand (operands[0], DFmode)))"
3219 {
3220 switch (which_alternative)
3221 {
3222 case 0:
3223 case 1:
3224 return output_387_reg_move (insn, operands);
3225
3226 case 2:
3227 return standard_80387_constant_opcode (operands[1]);
3228
3229 case 3:
3230 case 4:
3231 return "#";
3232 case 5:
3233 switch (get_attr_mode (insn))
3234 {
3235 case MODE_V4SF:
3236 return "%vxorps\t%0, %d0";
3237 case MODE_V2DF:
3238 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3239 return "%vxorps\t%0, %d0";
3240 else
3241 return "%vxorpd\t%0, %d0";
3242 case MODE_TI:
3243 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3244 return "%vxorps\t%0, %d0";
3245 else
3246 return "%vpxor\t%0, %d0";
3247 default:
3248 gcc_unreachable ();
3249 }
3250 case 6:
3251 case 7:
3252 case 8:
3253 switch (get_attr_mode (insn))
3254 {
3255 case MODE_V4SF:
3256 return "%vmovaps\t{%1, %0|%0, %1}";
3257 case MODE_V2DF:
3258 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3259 return "%vmovaps\t{%1, %0|%0, %1}";
3260 else
3261 return "%vmovapd\t{%1, %0|%0, %1}";
3262 case MODE_TI:
3263 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3264 return "%vmovaps\t{%1, %0|%0, %1}";
3265 else
3266 return "%vmovdqa\t{%1, %0|%0, %1}";
3267 case MODE_DI:
3268 return "%vmovq\t{%1, %0|%0, %1}";
3269 case MODE_DF:
3270 if (TARGET_AVX)
3271 {
3272 if (REG_P (operands[0]) && REG_P (operands[1]))
3273 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3274 else
3275 return "vmovsd\t{%1, %0|%0, %1}";
3276 }
3277 else
3278 return "movsd\t{%1, %0|%0, %1}";
3279 case MODE_V1DF:
3280 if (TARGET_AVX)
3281 {
3282 if (REG_P (operands[0]))
3283 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3284 else
3285 return "vmovlpd\t{%1, %0|%0, %1}";
3286 }
3287 else
3288 return "movlpd\t{%1, %0|%0, %1}";
3289 case MODE_V2SF:
3290 if (TARGET_AVX)
3291 {
3292 if (REG_P (operands[0]))
3293 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3294 else
3295 return "vmovlps\t{%1, %0|%0, %1}";
3296 }
3297 else
3298 return "movlps\t{%1, %0|%0, %1}";
3299 default:
3300 gcc_unreachable ();
3301 }
3302
3303 default:
3304 gcc_unreachable ();
3305 }
3306 }
3307 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3308 (set (attr "prefix")
3309 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3310 (const_string "orig")
3311 (const_string "maybe_vex")))
3312 (set (attr "prefix_data16")
3313 (if_then_else (eq_attr "mode" "V1DF")
3314 (const_string "1")
3315 (const_string "*")))
3316 (set (attr "mode")
3317 (cond [(eq_attr "alternative" "0,1,2")
3318 (const_string "DF")
3319 (eq_attr "alternative" "3,4")
3320 (const_string "SI")
3321
3322 /* For SSE1, we have many fewer alternatives. */
3323 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3324 (cond [(eq_attr "alternative" "5,6")
3325 (const_string "V4SF")
3326 ]
3327 (const_string "V2SF"))
3328
3329 /* xorps is one byte shorter. */
3330 (eq_attr "alternative" "5")
3331 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3332 (const_int 0))
3333 (const_string "V4SF")
3334 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3335 (const_int 0))
3336 (const_string "TI")
3337 ]
3338 (const_string "V2DF"))
3339
3340 /* For architectures resolving dependencies on
3341 whole SSE registers use APD move to break dependency
3342 chains, otherwise use short move to avoid extra work.
3343
3344 movaps encodes one byte shorter. */
3345 (eq_attr "alternative" "6")
3346 (cond
3347 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3348 (const_int 0))
3349 (const_string "V4SF")
3350 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3351 (const_int 0))
3352 (const_string "V2DF")
3353 ]
3354 (const_string "DF"))
3355 /* For architectures resolving dependencies on register
3356 parts we may avoid extra work to zero out upper part
3357 of register. */
3358 (eq_attr "alternative" "7")
3359 (if_then_else
3360 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3361 (const_int 0))
3362 (const_string "V1DF")
3363 (const_string "DF"))
3364 ]
3365 (const_string "DF")))])
3366
3367 (define_split
3368 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3369 (match_operand:DF 1 "general_operand" ""))]
3370 "reload_completed
3371 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3372 && ! (ANY_FP_REG_P (operands[0]) ||
3373 (GET_CODE (operands[0]) == SUBREG
3374 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3375 && ! (ANY_FP_REG_P (operands[1]) ||
3376 (GET_CODE (operands[1]) == SUBREG
3377 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3378 [(const_int 0)]
3379 "ix86_split_long_move (operands); DONE;")
3380
3381 (define_insn "*movsf_internal"
3382 [(set (match_operand:SF 0 "nonimmediate_operand"
3383 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3384 (match_operand:SF 1 "general_operand"
3385 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3386 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3387 && (reload_in_progress || reload_completed
3388 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3389 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3390 && standard_80387_constant_p (operands[1]))
3391 || GET_CODE (operands[1]) != CONST_DOUBLE
3392 || memory_operand (operands[0], SFmode))"
3393 {
3394 switch (which_alternative)
3395 {
3396 case 0:
3397 case 1:
3398 return output_387_reg_move (insn, operands);
3399
3400 case 2:
3401 return standard_80387_constant_opcode (operands[1]);
3402
3403 case 3:
3404 case 4:
3405 return "mov{l}\t{%1, %0|%0, %1}";
3406 case 5:
3407 if (get_attr_mode (insn) == MODE_TI)
3408 return "%vpxor\t%0, %d0";
3409 else
3410 return "%vxorps\t%0, %d0";
3411 case 6:
3412 if (get_attr_mode (insn) == MODE_V4SF)
3413 return "%vmovaps\t{%1, %0|%0, %1}";
3414 else
3415 return "%vmovss\t{%1, %d0|%d0, %1}";
3416 case 7:
3417 if (TARGET_AVX)
3418 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3419 : "vmovss\t{%1, %0|%0, %1}";
3420 else
3421 return "movss\t{%1, %0|%0, %1}";
3422 case 8:
3423 return "%vmovss\t{%1, %0|%0, %1}";
3424
3425 case 9: case 10: case 14: case 15:
3426 return "movd\t{%1, %0|%0, %1}";
3427 case 12: case 13:
3428 return "%vmovd\t{%1, %0|%0, %1}";
3429
3430 case 11:
3431 return "movq\t{%1, %0|%0, %1}";
3432
3433 default:
3434 gcc_unreachable ();
3435 }
3436 }
3437 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3438 (set (attr "prefix")
3439 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3440 (const_string "maybe_vex")
3441 (const_string "orig")))
3442 (set (attr "mode")
3443 (cond [(eq_attr "alternative" "3,4,9,10")
3444 (const_string "SI")
3445 (eq_attr "alternative" "5")
3446 (if_then_else
3447 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3448 (const_int 0))
3449 (ne (symbol_ref "TARGET_SSE2")
3450 (const_int 0)))
3451 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3452 (const_int 0)))
3453 (const_string "TI")
3454 (const_string "V4SF"))
3455 /* For architectures resolving dependencies on
3456 whole SSE registers use APS move to break dependency
3457 chains, otherwise use short move to avoid extra work.
3458
3459 Do the same for architectures resolving dependencies on
3460 the parts. While in DF mode it is better to always handle
3461 just register parts, the SF mode is different due to lack
3462 of instructions to load just part of the register. It is
3463 better to maintain the whole registers in single format
3464 to avoid problems on using packed logical operations. */
3465 (eq_attr "alternative" "6")
3466 (if_then_else
3467 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3468 (const_int 0))
3469 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3470 (const_int 0)))
3471 (const_string "V4SF")
3472 (const_string "SF"))
3473 (eq_attr "alternative" "11")
3474 (const_string "DI")]
3475 (const_string "SF")))])
3476
3477 (define_split
3478 [(set (match_operand 0 "register_operand" "")
3479 (match_operand 1 "memory_operand" ""))]
3480 "reload_completed
3481 && MEM_P (operands[1])
3482 && (GET_MODE (operands[0]) == TFmode
3483 || GET_MODE (operands[0]) == XFmode
3484 || GET_MODE (operands[0]) == DFmode
3485 || GET_MODE (operands[0]) == SFmode)
3486 && (operands[2] = find_constant_src (insn))"
3487 [(set (match_dup 0) (match_dup 2))]
3488 {
3489 rtx c = operands[2];
3490 rtx r = operands[0];
3491
3492 if (GET_CODE (r) == SUBREG)
3493 r = SUBREG_REG (r);
3494
3495 if (SSE_REG_P (r))
3496 {
3497 if (!standard_sse_constant_p (c))
3498 FAIL;
3499 }
3500 else if (FP_REG_P (r))
3501 {
3502 if (!standard_80387_constant_p (c))
3503 FAIL;
3504 }
3505 else if (MMX_REG_P (r))
3506 FAIL;
3507 })
3508
3509 (define_split
3510 [(set (match_operand 0 "register_operand" "")
3511 (float_extend (match_operand 1 "memory_operand" "")))]
3512 "reload_completed
3513 && MEM_P (operands[1])
3514 && (GET_MODE (operands[0]) == TFmode
3515 || GET_MODE (operands[0]) == XFmode
3516 || GET_MODE (operands[0]) == DFmode
3517 || GET_MODE (operands[0]) == SFmode)
3518 && (operands[2] = find_constant_src (insn))"
3519 [(set (match_dup 0) (match_dup 2))]
3520 {
3521 rtx c = operands[2];
3522 rtx r = operands[0];
3523
3524 if (GET_CODE (r) == SUBREG)
3525 r = SUBREG_REG (r);
3526
3527 if (SSE_REG_P (r))
3528 {
3529 if (!standard_sse_constant_p (c))
3530 FAIL;
3531 }
3532 else if (FP_REG_P (r))
3533 {
3534 if (!standard_80387_constant_p (c))
3535 FAIL;
3536 }
3537 else if (MMX_REG_P (r))
3538 FAIL;
3539 })
3540
3541 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3542 (define_split
3543 [(set (match_operand:X87MODEF 0 "register_operand" "")
3544 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3545 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3546 && (standard_80387_constant_p (operands[1]) == 8
3547 || standard_80387_constant_p (operands[1]) == 9)"
3548 [(set (match_dup 0)(match_dup 1))
3549 (set (match_dup 0)
3550 (neg:X87MODEF (match_dup 0)))]
3551 {
3552 REAL_VALUE_TYPE r;
3553
3554 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3555 if (real_isnegzero (&r))
3556 operands[1] = CONST0_RTX (<MODE>mode);
3557 else
3558 operands[1] = CONST1_RTX (<MODE>mode);
3559 })
3560
3561 (define_insn "swapxf"
3562 [(set (match_operand:XF 0 "register_operand" "+f")
3563 (match_operand:XF 1 "register_operand" "+f"))
3564 (set (match_dup 1)
3565 (match_dup 0))]
3566 "TARGET_80387"
3567 {
3568 if (STACK_TOP_P (operands[0]))
3569 return "fxch\t%1";
3570 else
3571 return "fxch\t%0";
3572 }
3573 [(set_attr "type" "fxch")
3574 (set_attr "mode" "XF")])
3575
3576 (define_insn "*swap<mode>"
3577 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3578 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3579 (set (match_dup 1)
3580 (match_dup 0))]
3581 "TARGET_80387 || reload_completed"
3582 {
3583 if (STACK_TOP_P (operands[0]))
3584 return "fxch\t%1";
3585 else
3586 return "fxch\t%0";
3587 }
3588 [(set_attr "type" "fxch")
3589 (set_attr "mode" "<MODE>")])
3590 \f
3591 ;; Zero extension instructions
3592
3593 (define_expand "zero_extendhisi2"
3594 [(set (match_operand:SI 0 "register_operand" "")
3595 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3596 ""
3597 {
3598 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3599 {
3600 operands[1] = force_reg (HImode, operands[1]);
3601 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3602 DONE;
3603 }
3604 })
3605
3606 (define_insn "zero_extendhisi2_and"
3607 [(set (match_operand:SI 0 "register_operand" "=r")
3608 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3609 (clobber (reg:CC FLAGS_REG))]
3610 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3611 "#"
3612 [(set_attr "type" "alu1")
3613 (set_attr "mode" "SI")])
3614
3615 (define_split
3616 [(set (match_operand:SI 0 "register_operand" "")
3617 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3618 (clobber (reg:CC FLAGS_REG))]
3619 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3620 && optimize_function_for_speed_p (cfun)"
3621 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3622 (clobber (reg:CC FLAGS_REG))])]
3623 "")
3624
3625 (define_insn "*zero_extendhisi2_movzwl"
3626 [(set (match_operand:SI 0 "register_operand" "=r")
3627 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3628 "!TARGET_ZERO_EXTEND_WITH_AND
3629 || optimize_function_for_size_p (cfun)"
3630 "movz{wl|x}\t{%1, %0|%0, %1}"
3631 [(set_attr "type" "imovx")
3632 (set_attr "mode" "SI")])
3633
3634 (define_expand "zero_extendqihi2"
3635 [(parallel
3636 [(set (match_operand:HI 0 "register_operand" "")
3637 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3638 (clobber (reg:CC FLAGS_REG))])]
3639 ""
3640 "")
3641
3642 (define_insn "*zero_extendqihi2_and"
3643 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3644 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3645 (clobber (reg:CC FLAGS_REG))]
3646 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3647 "#"
3648 [(set_attr "type" "alu1")
3649 (set_attr "mode" "HI")])
3650
3651 (define_insn "*zero_extendqihi2_movzbw_and"
3652 [(set (match_operand:HI 0 "register_operand" "=r,r")
3653 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3654 (clobber (reg:CC FLAGS_REG))]
3655 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3656 "#"
3657 [(set_attr "type" "imovx,alu1")
3658 (set_attr "mode" "HI")])
3659
3660 ; zero extend to SImode here to avoid partial register stalls
3661 (define_insn "*zero_extendqihi2_movzbl"
3662 [(set (match_operand:HI 0 "register_operand" "=r")
3663 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3664 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3665 && reload_completed"
3666 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3667 [(set_attr "type" "imovx")
3668 (set_attr "mode" "SI")])
3669
3670 ;; For the movzbw case strip only the clobber
3671 (define_split
3672 [(set (match_operand:HI 0 "register_operand" "")
3673 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3674 (clobber (reg:CC FLAGS_REG))]
3675 "reload_completed
3676 && (!TARGET_ZERO_EXTEND_WITH_AND
3677 || optimize_function_for_size_p (cfun))
3678 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3679 [(set (match_operand:HI 0 "register_operand" "")
3680 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3681
3682 ;; When source and destination does not overlap, clear destination
3683 ;; first and then do the movb
3684 (define_split
3685 [(set (match_operand:HI 0 "register_operand" "")
3686 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3687 (clobber (reg:CC FLAGS_REG))]
3688 "reload_completed
3689 && ANY_QI_REG_P (operands[0])
3690 && (TARGET_ZERO_EXTEND_WITH_AND
3691 && optimize_function_for_speed_p (cfun))
3692 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3693 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3694 {
3695 operands[2] = gen_lowpart (QImode, operands[0]);
3696 ix86_expand_clear (operands[0]);
3697 })
3698
3699 ;; Rest is handled by single and.
3700 (define_split
3701 [(set (match_operand:HI 0 "register_operand" "")
3702 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3703 (clobber (reg:CC FLAGS_REG))]
3704 "reload_completed
3705 && true_regnum (operands[0]) == true_regnum (operands[1])"
3706 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3707 (clobber (reg:CC FLAGS_REG))])]
3708 "")
3709
3710 (define_expand "zero_extendqisi2"
3711 [(parallel
3712 [(set (match_operand:SI 0 "register_operand" "")
3713 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3714 (clobber (reg:CC FLAGS_REG))])]
3715 ""
3716 "")
3717
3718 (define_insn "*zero_extendqisi2_and"
3719 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3720 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3721 (clobber (reg:CC FLAGS_REG))]
3722 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3723 "#"
3724 [(set_attr "type" "alu1")
3725 (set_attr "mode" "SI")])
3726
3727 (define_insn "*zero_extendqisi2_movzbl_and"
3728 [(set (match_operand:SI 0 "register_operand" "=r,r")
3729 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3730 (clobber (reg:CC FLAGS_REG))]
3731 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3732 "#"
3733 [(set_attr "type" "imovx,alu1")
3734 (set_attr "mode" "SI")])
3735
3736 (define_insn "*zero_extendqisi2_movzbl"
3737 [(set (match_operand:SI 0 "register_operand" "=r")
3738 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3740 && reload_completed"
3741 "movz{bl|x}\t{%1, %0|%0, %1}"
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "SI")])
3744
3745 ;; For the movzbl case strip only the clobber
3746 (define_split
3747 [(set (match_operand:SI 0 "register_operand" "")
3748 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3749 (clobber (reg:CC FLAGS_REG))]
3750 "reload_completed
3751 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3752 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3753 [(set (match_dup 0)
3754 (zero_extend:SI (match_dup 1)))])
3755
3756 ;; When source and destination does not overlap, clear destination
3757 ;; first and then do the movb
3758 (define_split
3759 [(set (match_operand:SI 0 "register_operand" "")
3760 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3761 (clobber (reg:CC FLAGS_REG))]
3762 "reload_completed
3763 && ANY_QI_REG_P (operands[0])
3764 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3765 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3766 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3767 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3768 {
3769 operands[2] = gen_lowpart (QImode, operands[0]);
3770 ix86_expand_clear (operands[0]);
3771 })
3772
3773 ;; Rest is handled by single and.
3774 (define_split
3775 [(set (match_operand:SI 0 "register_operand" "")
3776 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3777 (clobber (reg:CC FLAGS_REG))]
3778 "reload_completed
3779 && true_regnum (operands[0]) == true_regnum (operands[1])"
3780 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3781 (clobber (reg:CC FLAGS_REG))])]
3782 "")
3783
3784 ;; %%% Kill me once multi-word ops are sane.
3785 (define_expand "zero_extendsidi2"
3786 [(set (match_operand:DI 0 "register_operand" "")
3787 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3788 ""
3789 {
3790 if (!TARGET_64BIT)
3791 {
3792 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3793 DONE;
3794 }
3795 })
3796
3797 (define_insn "zero_extendsidi2_32"
3798 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3799 (zero_extend:DI
3800 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3801 (clobber (reg:CC FLAGS_REG))]
3802 "!TARGET_64BIT"
3803 "@
3804 #
3805 #
3806 #
3807 movd\t{%1, %0|%0, %1}
3808 movd\t{%1, %0|%0, %1}
3809 %vmovd\t{%1, %0|%0, %1}
3810 %vmovd\t{%1, %0|%0, %1}"
3811 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3812 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3813 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3814
3815 (define_insn "zero_extendsidi2_rex64"
3816 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3817 (zero_extend:DI
3818 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3819 "TARGET_64BIT"
3820 "@
3821 mov\t{%k1, %k0|%k0, %k1}
3822 #
3823 movd\t{%1, %0|%0, %1}
3824 movd\t{%1, %0|%0, %1}
3825 %vmovd\t{%1, %0|%0, %1}
3826 %vmovd\t{%1, %0|%0, %1}"
3827 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3828 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3829 (set_attr "prefix_0f" "0,*,*,*,*,*")
3830 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3831
3832 (define_split
3833 [(set (match_operand:DI 0 "memory_operand" "")
3834 (zero_extend:DI (match_dup 0)))]
3835 "TARGET_64BIT"
3836 [(set (match_dup 4) (const_int 0))]
3837 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3838
3839 (define_split
3840 [(set (match_operand:DI 0 "register_operand" "")
3841 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3842 (clobber (reg:CC FLAGS_REG))]
3843 "!TARGET_64BIT && reload_completed
3844 && true_regnum (operands[0]) == true_regnum (operands[1])"
3845 [(set (match_dup 4) (const_int 0))]
3846 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3847
3848 (define_split
3849 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3850 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3851 (clobber (reg:CC FLAGS_REG))]
3852 "!TARGET_64BIT && reload_completed
3853 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3854 [(set (match_dup 3) (match_dup 1))
3855 (set (match_dup 4) (const_int 0))]
3856 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3857
3858 (define_insn "zero_extendhidi2"
3859 [(set (match_operand:DI 0 "register_operand" "=r")
3860 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3861 "TARGET_64BIT"
3862 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3863 [(set_attr "type" "imovx")
3864 (set_attr "mode" "SI")])
3865
3866 (define_insn "zero_extendqidi2"
3867 [(set (match_operand:DI 0 "register_operand" "=r")
3868 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3869 "TARGET_64BIT"
3870 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3871 [(set_attr "type" "imovx")
3872 (set_attr "mode" "SI")])
3873 \f
3874 ;; Sign extension instructions
3875
3876 (define_expand "extendsidi2"
3877 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3878 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3879 (clobber (reg:CC FLAGS_REG))
3880 (clobber (match_scratch:SI 2 ""))])]
3881 ""
3882 {
3883 if (TARGET_64BIT)
3884 {
3885 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3886 DONE;
3887 }
3888 })
3889
3890 (define_insn "*extendsidi2_1"
3891 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3892 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3893 (clobber (reg:CC FLAGS_REG))
3894 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3895 "!TARGET_64BIT"
3896 "#")
3897
3898 (define_insn "extendsidi2_rex64"
3899 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3900 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3901 "TARGET_64BIT"
3902 "@
3903 {cltq|cdqe}
3904 movs{lq|x}\t{%1, %0|%0, %1}"
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "DI")
3907 (set_attr "prefix_0f" "0")
3908 (set_attr "modrm" "0,1")])
3909
3910 (define_insn "extendhidi2"
3911 [(set (match_operand:DI 0 "register_operand" "=r")
3912 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3913 "TARGET_64BIT"
3914 "movs{wq|x}\t{%1, %0|%0, %1}"
3915 [(set_attr "type" "imovx")
3916 (set_attr "mode" "DI")])
3917
3918 (define_insn "extendqidi2"
3919 [(set (match_operand:DI 0 "register_operand" "=r")
3920 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3921 "TARGET_64BIT"
3922 "movs{bq|x}\t{%1, %0|%0, %1}"
3923 [(set_attr "type" "imovx")
3924 (set_attr "mode" "DI")])
3925
3926 ;; Extend to memory case when source register does die.
3927 (define_split
3928 [(set (match_operand:DI 0 "memory_operand" "")
3929 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3930 (clobber (reg:CC FLAGS_REG))
3931 (clobber (match_operand:SI 2 "register_operand" ""))]
3932 "(reload_completed
3933 && dead_or_set_p (insn, operands[1])
3934 && !reg_mentioned_p (operands[1], operands[0]))"
3935 [(set (match_dup 3) (match_dup 1))
3936 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3937 (clobber (reg:CC FLAGS_REG))])
3938 (set (match_dup 4) (match_dup 1))]
3939 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3940
3941 ;; Extend to memory case when source register does not die.
3942 (define_split
3943 [(set (match_operand:DI 0 "memory_operand" "")
3944 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3945 (clobber (reg:CC FLAGS_REG))
3946 (clobber (match_operand:SI 2 "register_operand" ""))]
3947 "reload_completed"
3948 [(const_int 0)]
3949 {
3950 split_di (&operands[0], 1, &operands[3], &operands[4]);
3951
3952 emit_move_insn (operands[3], operands[1]);
3953
3954 /* Generate a cltd if possible and doing so it profitable. */
3955 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3956 && true_regnum (operands[1]) == AX_REG
3957 && true_regnum (operands[2]) == DX_REG)
3958 {
3959 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3960 }
3961 else
3962 {
3963 emit_move_insn (operands[2], operands[1]);
3964 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3965 }
3966 emit_move_insn (operands[4], operands[2]);
3967 DONE;
3968 })
3969
3970 ;; Extend to register case. Optimize case where source and destination
3971 ;; registers match and cases where we can use cltd.
3972 (define_split
3973 [(set (match_operand:DI 0 "register_operand" "")
3974 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3975 (clobber (reg:CC FLAGS_REG))
3976 (clobber (match_scratch:SI 2 ""))]
3977 "reload_completed"
3978 [(const_int 0)]
3979 {
3980 split_di (&operands[0], 1, &operands[3], &operands[4]);
3981
3982 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3983 emit_move_insn (operands[3], operands[1]);
3984
3985 /* Generate a cltd if possible and doing so it profitable. */
3986 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3987 && true_regnum (operands[3]) == AX_REG
3988 && true_regnum (operands[4]) == DX_REG)
3989 {
3990 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3991 DONE;
3992 }
3993
3994 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3995 emit_move_insn (operands[4], operands[1]);
3996
3997 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3998 DONE;
3999 })
4000
4001 (define_insn "extendhisi2"
4002 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4003 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4004 ""
4005 {
4006 switch (get_attr_prefix_0f (insn))
4007 {
4008 case 0:
4009 return "{cwtl|cwde}";
4010 default:
4011 return "movs{wl|x}\t{%1, %0|%0, %1}";
4012 }
4013 }
4014 [(set_attr "type" "imovx")
4015 (set_attr "mode" "SI")
4016 (set (attr "prefix_0f")
4017 ;; movsx is short decodable while cwtl is vector decoded.
4018 (if_then_else (and (eq_attr "cpu" "!k6")
4019 (eq_attr "alternative" "0"))
4020 (const_string "0")
4021 (const_string "1")))
4022 (set (attr "modrm")
4023 (if_then_else (eq_attr "prefix_0f" "0")
4024 (const_string "0")
4025 (const_string "1")))])
4026
4027 (define_insn "*extendhisi2_zext"
4028 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4029 (zero_extend:DI
4030 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4031 "TARGET_64BIT"
4032 {
4033 switch (get_attr_prefix_0f (insn))
4034 {
4035 case 0:
4036 return "{cwtl|cwde}";
4037 default:
4038 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4039 }
4040 }
4041 [(set_attr "type" "imovx")
4042 (set_attr "mode" "SI")
4043 (set (attr "prefix_0f")
4044 ;; movsx is short decodable while cwtl is vector decoded.
4045 (if_then_else (and (eq_attr "cpu" "!k6")
4046 (eq_attr "alternative" "0"))
4047 (const_string "0")
4048 (const_string "1")))
4049 (set (attr "modrm")
4050 (if_then_else (eq_attr "prefix_0f" "0")
4051 (const_string "0")
4052 (const_string "1")))])
4053
4054 (define_insn "extendqihi2"
4055 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4056 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4057 ""
4058 {
4059 switch (get_attr_prefix_0f (insn))
4060 {
4061 case 0:
4062 return "{cbtw|cbw}";
4063 default:
4064 return "movs{bw|x}\t{%1, %0|%0, %1}";
4065 }
4066 }
4067 [(set_attr "type" "imovx")
4068 (set_attr "mode" "HI")
4069 (set (attr "prefix_0f")
4070 ;; movsx is short decodable while cwtl is vector decoded.
4071 (if_then_else (and (eq_attr "cpu" "!k6")
4072 (eq_attr "alternative" "0"))
4073 (const_string "0")
4074 (const_string "1")))
4075 (set (attr "modrm")
4076 (if_then_else (eq_attr "prefix_0f" "0")
4077 (const_string "0")
4078 (const_string "1")))])
4079
4080 (define_insn "extendqisi2"
4081 [(set (match_operand:SI 0 "register_operand" "=r")
4082 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4083 ""
4084 "movs{bl|x}\t{%1, %0|%0, %1}"
4085 [(set_attr "type" "imovx")
4086 (set_attr "mode" "SI")])
4087
4088 (define_insn "*extendqisi2_zext"
4089 [(set (match_operand:DI 0 "register_operand" "=r")
4090 (zero_extend:DI
4091 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4092 "TARGET_64BIT"
4093 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4094 [(set_attr "type" "imovx")
4095 (set_attr "mode" "SI")])
4096 \f
4097 ;; Conversions between float and double.
4098
4099 ;; These are all no-ops in the model used for the 80387. So just
4100 ;; emit moves.
4101
4102 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4103 (define_insn "*dummy_extendsfdf2"
4104 [(set (match_operand:DF 0 "push_operand" "=<")
4105 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4106 "0"
4107 "#")
4108
4109 (define_split
4110 [(set (match_operand:DF 0 "push_operand" "")
4111 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4112 ""
4113 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4114 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4115
4116 (define_insn "*dummy_extendsfxf2"
4117 [(set (match_operand:XF 0 "push_operand" "=<")
4118 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4119 "0"
4120 "#")
4121
4122 (define_split
4123 [(set (match_operand:XF 0 "push_operand" "")
4124 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4125 ""
4126 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4127 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4128 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4129
4130 (define_split
4131 [(set (match_operand:XF 0 "push_operand" "")
4132 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4133 ""
4134 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4135 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4136 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4137
4138 (define_expand "extendsfdf2"
4139 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4140 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4141 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4142 {
4143 /* ??? Needed for compress_float_constant since all fp constants
4144 are LEGITIMATE_CONSTANT_P. */
4145 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4146 {
4147 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4148 && standard_80387_constant_p (operands[1]) > 0)
4149 {
4150 operands[1] = simplify_const_unary_operation
4151 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4152 emit_move_insn_1 (operands[0], operands[1]);
4153 DONE;
4154 }
4155 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4156 }
4157 })
4158
4159 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4160 cvtss2sd:
4161 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4162 cvtps2pd xmm2,xmm1
4163 We do the conversion post reload to avoid producing of 128bit spills
4164 that might lead to ICE on 32bit target. The sequence unlikely combine
4165 anyway. */
4166 (define_split
4167 [(set (match_operand:DF 0 "register_operand" "")
4168 (float_extend:DF
4169 (match_operand:SF 1 "nonimmediate_operand" "")))]
4170 "TARGET_USE_VECTOR_FP_CONVERTS
4171 && optimize_insn_for_speed_p ()
4172 && reload_completed && SSE_REG_P (operands[0])"
4173 [(set (match_dup 2)
4174 (float_extend:V2DF
4175 (vec_select:V2SF
4176 (match_dup 3)
4177 (parallel [(const_int 0) (const_int 1)]))))]
4178 {
4179 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4180 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4181 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4182 Try to avoid move when unpacking can be done in source. */
4183 if (REG_P (operands[1]))
4184 {
4185 /* If it is unsafe to overwrite upper half of source, we need
4186 to move to destination and unpack there. */
4187 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4188 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4189 && true_regnum (operands[0]) != true_regnum (operands[1]))
4190 {
4191 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4192 emit_move_insn (tmp, operands[1]);
4193 }
4194 else
4195 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4196 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4197 operands[3]));
4198 }
4199 else
4200 emit_insn (gen_vec_setv4sf_0 (operands[3],
4201 CONST0_RTX (V4SFmode), operands[1]));
4202 })
4203
4204 (define_insn "*extendsfdf2_mixed"
4205 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4206 (float_extend:DF
4207 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4208 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4209 {
4210 switch (which_alternative)
4211 {
4212 case 0:
4213 case 1:
4214 return output_387_reg_move (insn, operands);
4215
4216 case 2:
4217 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4218
4219 default:
4220 gcc_unreachable ();
4221 }
4222 }
4223 [(set_attr "type" "fmov,fmov,ssecvt")
4224 (set_attr "prefix" "orig,orig,maybe_vex")
4225 (set_attr "mode" "SF,XF,DF")])
4226
4227 (define_insn "*extendsfdf2_sse"
4228 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4229 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4230 "TARGET_SSE2 && TARGET_SSE_MATH"
4231 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4232 [(set_attr "type" "ssecvt")
4233 (set_attr "prefix" "maybe_vex")
4234 (set_attr "mode" "DF")])
4235
4236 (define_insn "*extendsfdf2_i387"
4237 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4238 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4239 "TARGET_80387"
4240 "* return output_387_reg_move (insn, operands);"
4241 [(set_attr "type" "fmov")
4242 (set_attr "mode" "SF,XF")])
4243
4244 (define_expand "extend<mode>xf2"
4245 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4246 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4247 "TARGET_80387"
4248 {
4249 /* ??? Needed for compress_float_constant since all fp constants
4250 are LEGITIMATE_CONSTANT_P. */
4251 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4252 {
4253 if (standard_80387_constant_p (operands[1]) > 0)
4254 {
4255 operands[1] = simplify_const_unary_operation
4256 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4257 emit_move_insn_1 (operands[0], operands[1]);
4258 DONE;
4259 }
4260 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4261 }
4262 })
4263
4264 (define_insn "*extend<mode>xf2_i387"
4265 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4266 (float_extend:XF
4267 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4268 "TARGET_80387"
4269 "* return output_387_reg_move (insn, operands);"
4270 [(set_attr "type" "fmov")
4271 (set_attr "mode" "<MODE>,XF")])
4272
4273 ;; %%% This seems bad bad news.
4274 ;; This cannot output into an f-reg because there is no way to be sure
4275 ;; of truncating in that case. Otherwise this is just like a simple move
4276 ;; insn. So we pretend we can output to a reg in order to get better
4277 ;; register preferencing, but we really use a stack slot.
4278
4279 ;; Conversion from DFmode to SFmode.
4280
4281 (define_expand "truncdfsf2"
4282 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4283 (float_truncate:SF
4284 (match_operand:DF 1 "nonimmediate_operand" "")))]
4285 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4286 {
4287 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4288 ;
4289 else if (flag_unsafe_math_optimizations)
4290 ;
4291 else
4292 {
4293 enum ix86_stack_slot slot = (virtuals_instantiated
4294 ? SLOT_TEMP
4295 : SLOT_VIRTUAL);
4296 rtx temp = assign_386_stack_local (SFmode, slot);
4297 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4298 DONE;
4299 }
4300 })
4301
4302 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4303 cvtsd2ss:
4304 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4305 cvtpd2ps xmm2,xmm1
4306 We do the conversion post reload to avoid producing of 128bit spills
4307 that might lead to ICE on 32bit target. The sequence unlikely combine
4308 anyway. */
4309 (define_split
4310 [(set (match_operand:SF 0 "register_operand" "")
4311 (float_truncate:SF
4312 (match_operand:DF 1 "nonimmediate_operand" "")))]
4313 "TARGET_USE_VECTOR_FP_CONVERTS
4314 && optimize_insn_for_speed_p ()
4315 && reload_completed && SSE_REG_P (operands[0])"
4316 [(set (match_dup 2)
4317 (vec_concat:V4SF
4318 (float_truncate:V2SF
4319 (match_dup 4))
4320 (match_dup 3)))]
4321 {
4322 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4323 operands[3] = CONST0_RTX (V2SFmode);
4324 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4325 /* Use movsd for loading from memory, unpcklpd for registers.
4326 Try to avoid move when unpacking can be done in source, or SSE3
4327 movddup is available. */
4328 if (REG_P (operands[1]))
4329 {
4330 if (!TARGET_SSE3
4331 && true_regnum (operands[0]) != true_regnum (operands[1])
4332 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4333 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4334 {
4335 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4336 emit_move_insn (tmp, operands[1]);
4337 operands[1] = tmp;
4338 }
4339 else if (!TARGET_SSE3)
4340 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4341 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4342 }
4343 else
4344 emit_insn (gen_sse2_loadlpd (operands[4],
4345 CONST0_RTX (V2DFmode), operands[1]));
4346 })
4347
4348 (define_expand "truncdfsf2_with_temp"
4349 [(parallel [(set (match_operand:SF 0 "" "")
4350 (float_truncate:SF (match_operand:DF 1 "" "")))
4351 (clobber (match_operand:SF 2 "" ""))])]
4352 "")
4353
4354 (define_insn "*truncdfsf_fast_mixed"
4355 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4356 (float_truncate:SF
4357 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4358 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4359 {
4360 switch (which_alternative)
4361 {
4362 case 0:
4363 return output_387_reg_move (insn, operands);
4364 case 1:
4365 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4366 default:
4367 gcc_unreachable ();
4368 }
4369 }
4370 [(set_attr "type" "fmov,ssecvt")
4371 (set_attr "prefix" "orig,maybe_vex")
4372 (set_attr "mode" "SF")])
4373
4374 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4375 ;; because nothing we do here is unsafe.
4376 (define_insn "*truncdfsf_fast_sse"
4377 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4378 (float_truncate:SF
4379 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4380 "TARGET_SSE2 && TARGET_SSE_MATH"
4381 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4382 [(set_attr "type" "ssecvt")
4383 (set_attr "prefix" "maybe_vex")
4384 (set_attr "mode" "SF")])
4385
4386 (define_insn "*truncdfsf_fast_i387"
4387 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4388 (float_truncate:SF
4389 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4390 "TARGET_80387 && flag_unsafe_math_optimizations"
4391 "* return output_387_reg_move (insn, operands);"
4392 [(set_attr "type" "fmov")
4393 (set_attr "mode" "SF")])
4394
4395 (define_insn "*truncdfsf_mixed"
4396 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4397 (float_truncate:SF
4398 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4399 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4400 "TARGET_MIX_SSE_I387"
4401 {
4402 switch (which_alternative)
4403 {
4404 case 0:
4405 return output_387_reg_move (insn, operands);
4406 case 1:
4407 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4408
4409 default:
4410 return "#";
4411 }
4412 }
4413 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4414 (set_attr "unit" "*,*,i387,i387,i387")
4415 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4416 (set_attr "mode" "SF")])
4417
4418 (define_insn "*truncdfsf_i387"
4419 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4420 (float_truncate:SF
4421 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4422 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4423 "TARGET_80387"
4424 {
4425 switch (which_alternative)
4426 {
4427 case 0:
4428 return output_387_reg_move (insn, operands);
4429
4430 default:
4431 return "#";
4432 }
4433 }
4434 [(set_attr "type" "fmov,multi,multi,multi")
4435 (set_attr "unit" "*,i387,i387,i387")
4436 (set_attr "mode" "SF")])
4437
4438 (define_insn "*truncdfsf2_i387_1"
4439 [(set (match_operand:SF 0 "memory_operand" "=m")
4440 (float_truncate:SF
4441 (match_operand:DF 1 "register_operand" "f")))]
4442 "TARGET_80387
4443 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4444 && !TARGET_MIX_SSE_I387"
4445 "* return output_387_reg_move (insn, operands);"
4446 [(set_attr "type" "fmov")
4447 (set_attr "mode" "SF")])
4448
4449 (define_split
4450 [(set (match_operand:SF 0 "register_operand" "")
4451 (float_truncate:SF
4452 (match_operand:DF 1 "fp_register_operand" "")))
4453 (clobber (match_operand 2 "" ""))]
4454 "reload_completed"
4455 [(set (match_dup 2) (match_dup 1))
4456 (set (match_dup 0) (match_dup 2))]
4457 {
4458 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4459 })
4460
4461 ;; Conversion from XFmode to {SF,DF}mode
4462
4463 (define_expand "truncxf<mode>2"
4464 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4465 (float_truncate:MODEF
4466 (match_operand:XF 1 "register_operand" "")))
4467 (clobber (match_dup 2))])]
4468 "TARGET_80387"
4469 {
4470 if (flag_unsafe_math_optimizations)
4471 {
4472 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4473 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4474 if (reg != operands[0])
4475 emit_move_insn (operands[0], reg);
4476 DONE;
4477 }
4478 else
4479 {
4480 enum ix86_stack_slot slot = (virtuals_instantiated
4481 ? SLOT_TEMP
4482 : SLOT_VIRTUAL);
4483 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4484 }
4485 })
4486
4487 (define_insn "*truncxfsf2_mixed"
4488 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4489 (float_truncate:SF
4490 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4491 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4492 "TARGET_80387"
4493 {
4494 gcc_assert (!which_alternative);
4495 return output_387_reg_move (insn, operands);
4496 }
4497 [(set_attr "type" "fmov,multi,multi,multi")
4498 (set_attr "unit" "*,i387,i387,i387")
4499 (set_attr "mode" "SF")])
4500
4501 (define_insn "*truncxfdf2_mixed"
4502 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4503 (float_truncate:DF
4504 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4505 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4506 "TARGET_80387"
4507 {
4508 gcc_assert (!which_alternative);
4509 return output_387_reg_move (insn, operands);
4510 }
4511 [(set_attr "type" "fmov,multi,multi,multi")
4512 (set_attr "unit" "*,i387,i387,i387")
4513 (set_attr "mode" "DF")])
4514
4515 (define_insn "truncxf<mode>2_i387_noop"
4516 [(set (match_operand:MODEF 0 "register_operand" "=f")
4517 (float_truncate:MODEF
4518 (match_operand:XF 1 "register_operand" "f")))]
4519 "TARGET_80387 && flag_unsafe_math_optimizations"
4520 "* return output_387_reg_move (insn, operands);"
4521 [(set_attr "type" "fmov")
4522 (set_attr "mode" "<MODE>")])
4523
4524 (define_insn "*truncxf<mode>2_i387"
4525 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4526 (float_truncate:MODEF
4527 (match_operand:XF 1 "register_operand" "f")))]
4528 "TARGET_80387"
4529 "* return output_387_reg_move (insn, operands);"
4530 [(set_attr "type" "fmov")
4531 (set_attr "mode" "<MODE>")])
4532
4533 (define_split
4534 [(set (match_operand:MODEF 0 "register_operand" "")
4535 (float_truncate:MODEF
4536 (match_operand:XF 1 "register_operand" "")))
4537 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4538 "TARGET_80387 && reload_completed"
4539 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4540 (set (match_dup 0) (match_dup 2))]
4541 "")
4542
4543 (define_split
4544 [(set (match_operand:MODEF 0 "memory_operand" "")
4545 (float_truncate:MODEF
4546 (match_operand:XF 1 "register_operand" "")))
4547 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4548 "TARGET_80387"
4549 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4550 "")
4551 \f
4552 ;; Signed conversion to DImode.
4553
4554 (define_expand "fix_truncxfdi2"
4555 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4556 (fix:DI (match_operand:XF 1 "register_operand" "")))
4557 (clobber (reg:CC FLAGS_REG))])]
4558 "TARGET_80387"
4559 {
4560 if (TARGET_FISTTP)
4561 {
4562 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4563 DONE;
4564 }
4565 })
4566
4567 (define_expand "fix_trunc<mode>di2"
4568 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4569 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4570 (clobber (reg:CC FLAGS_REG))])]
4571 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4572 {
4573 if (TARGET_FISTTP
4574 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4575 {
4576 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4577 DONE;
4578 }
4579 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4580 {
4581 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4582 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4583 if (out != operands[0])
4584 emit_move_insn (operands[0], out);
4585 DONE;
4586 }
4587 })
4588
4589 ;; Signed conversion to SImode.
4590
4591 (define_expand "fix_truncxfsi2"
4592 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4593 (fix:SI (match_operand:XF 1 "register_operand" "")))
4594 (clobber (reg:CC FLAGS_REG))])]
4595 "TARGET_80387"
4596 {
4597 if (TARGET_FISTTP)
4598 {
4599 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4600 DONE;
4601 }
4602 })
4603
4604 (define_expand "fix_trunc<mode>si2"
4605 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4606 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4607 (clobber (reg:CC FLAGS_REG))])]
4608 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4609 {
4610 if (TARGET_FISTTP
4611 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4612 {
4613 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4614 DONE;
4615 }
4616 if (SSE_FLOAT_MODE_P (<MODE>mode))
4617 {
4618 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4619 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4620 if (out != operands[0])
4621 emit_move_insn (operands[0], out);
4622 DONE;
4623 }
4624 })
4625
4626 ;; Signed conversion to HImode.
4627
4628 (define_expand "fix_trunc<mode>hi2"
4629 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4630 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4631 (clobber (reg:CC FLAGS_REG))])]
4632 "TARGET_80387
4633 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4634 {
4635 if (TARGET_FISTTP)
4636 {
4637 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4638 DONE;
4639 }
4640 })
4641
4642 ;; Unsigned conversion to SImode.
4643
4644 (define_expand "fixuns_trunc<mode>si2"
4645 [(parallel
4646 [(set (match_operand:SI 0 "register_operand" "")
4647 (unsigned_fix:SI
4648 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4649 (use (match_dup 2))
4650 (clobber (match_scratch:<ssevecmode> 3 ""))
4651 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4652 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4653 {
4654 enum machine_mode mode = <MODE>mode;
4655 enum machine_mode vecmode = <ssevecmode>mode;
4656 REAL_VALUE_TYPE TWO31r;
4657 rtx two31;
4658
4659 if (optimize_insn_for_size_p ())
4660 FAIL;
4661
4662 real_ldexp (&TWO31r, &dconst1, 31);
4663 two31 = const_double_from_real_value (TWO31r, mode);
4664 two31 = ix86_build_const_vector (mode, true, two31);
4665 operands[2] = force_reg (vecmode, two31);
4666 })
4667
4668 (define_insn_and_split "*fixuns_trunc<mode>_1"
4669 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4670 (unsigned_fix:SI
4671 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4672 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4673 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4674 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4675 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4676 && optimize_function_for_speed_p (cfun)"
4677 "#"
4678 "&& reload_completed"
4679 [(const_int 0)]
4680 {
4681 ix86_split_convert_uns_si_sse (operands);
4682 DONE;
4683 })
4684
4685 ;; Unsigned conversion to HImode.
4686 ;; Without these patterns, we'll try the unsigned SI conversion which
4687 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4688
4689 (define_expand "fixuns_trunc<mode>hi2"
4690 [(set (match_dup 2)
4691 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4692 (set (match_operand:HI 0 "nonimmediate_operand" "")
4693 (subreg:HI (match_dup 2) 0))]
4694 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4695 "operands[2] = gen_reg_rtx (SImode);")
4696
4697 ;; When SSE is available, it is always faster to use it!
4698 (define_insn "fix_trunc<mode>di_sse"
4699 [(set (match_operand:DI 0 "register_operand" "=r,r")
4700 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4701 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4702 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4703 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4704 [(set_attr "type" "sseicvt")
4705 (set_attr "prefix" "maybe_vex")
4706 (set_attr "prefix_rex" "1")
4707 (set_attr "mode" "<MODE>")
4708 (set_attr "athlon_decode" "double,vector")
4709 (set_attr "amdfam10_decode" "double,double")])
4710
4711 (define_insn "fix_trunc<mode>si_sse"
4712 [(set (match_operand:SI 0 "register_operand" "=r,r")
4713 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4714 "SSE_FLOAT_MODE_P (<MODE>mode)
4715 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4716 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4717 [(set_attr "type" "sseicvt")
4718 (set_attr "prefix" "maybe_vex")
4719 (set_attr "mode" "<MODE>")
4720 (set_attr "athlon_decode" "double,vector")
4721 (set_attr "amdfam10_decode" "double,double")])
4722
4723 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4724 (define_peephole2
4725 [(set (match_operand:MODEF 0 "register_operand" "")
4726 (match_operand:MODEF 1 "memory_operand" ""))
4727 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4728 (fix:SSEMODEI24 (match_dup 0)))]
4729 "TARGET_SHORTEN_X87_SSE
4730 && peep2_reg_dead_p (2, operands[0])"
4731 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4732 "")
4733
4734 ;; Avoid vector decoded forms of the instruction.
4735 (define_peephole2
4736 [(match_scratch:DF 2 "Y2")
4737 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4738 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4739 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4740 [(set (match_dup 2) (match_dup 1))
4741 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4742 "")
4743
4744 (define_peephole2
4745 [(match_scratch:SF 2 "x")
4746 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4747 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4748 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4749 [(set (match_dup 2) (match_dup 1))
4750 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4751 "")
4752
4753 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4754 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4755 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4756 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4757 && TARGET_FISTTP
4758 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4759 && (TARGET_64BIT || <MODE>mode != DImode))
4760 && TARGET_SSE_MATH)
4761 && can_create_pseudo_p ()"
4762 "#"
4763 "&& 1"
4764 [(const_int 0)]
4765 {
4766 if (memory_operand (operands[0], VOIDmode))
4767 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4768 else
4769 {
4770 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4771 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4772 operands[1],
4773 operands[2]));
4774 }
4775 DONE;
4776 }
4777 [(set_attr "type" "fisttp")
4778 (set_attr "mode" "<MODE>")])
4779
4780 (define_insn "fix_trunc<mode>_i387_fisttp"
4781 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4782 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4783 (clobber (match_scratch:XF 2 "=&1f"))]
4784 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4785 && TARGET_FISTTP
4786 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4787 && (TARGET_64BIT || <MODE>mode != DImode))
4788 && TARGET_SSE_MATH)"
4789 "* return output_fix_trunc (insn, operands, 1);"
4790 [(set_attr "type" "fisttp")
4791 (set_attr "mode" "<MODE>")])
4792
4793 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4794 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4795 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4796 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4797 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4798 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4799 && TARGET_FISTTP
4800 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4801 && (TARGET_64BIT || <MODE>mode != DImode))
4802 && TARGET_SSE_MATH)"
4803 "#"
4804 [(set_attr "type" "fisttp")
4805 (set_attr "mode" "<MODE>")])
4806
4807 (define_split
4808 [(set (match_operand:X87MODEI 0 "register_operand" "")
4809 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4810 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4811 (clobber (match_scratch 3 ""))]
4812 "reload_completed"
4813 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4814 (clobber (match_dup 3))])
4815 (set (match_dup 0) (match_dup 2))]
4816 "")
4817
4818 (define_split
4819 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4820 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4821 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4822 (clobber (match_scratch 3 ""))]
4823 "reload_completed"
4824 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4825 (clobber (match_dup 3))])]
4826 "")
4827
4828 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4829 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4830 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4831 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4832 ;; function in i386.c.
4833 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4834 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4835 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4836 (clobber (reg:CC FLAGS_REG))]
4837 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4838 && !TARGET_FISTTP
4839 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4840 && (TARGET_64BIT || <MODE>mode != DImode))
4841 && can_create_pseudo_p ()"
4842 "#"
4843 "&& 1"
4844 [(const_int 0)]
4845 {
4846 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4847
4848 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4849 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4850 if (memory_operand (operands[0], VOIDmode))
4851 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4852 operands[2], operands[3]));
4853 else
4854 {
4855 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4856 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4857 operands[2], operands[3],
4858 operands[4]));
4859 }
4860 DONE;
4861 }
4862 [(set_attr "type" "fistp")
4863 (set_attr "i387_cw" "trunc")
4864 (set_attr "mode" "<MODE>")])
4865
4866 (define_insn "fix_truncdi_i387"
4867 [(set (match_operand:DI 0 "memory_operand" "=m")
4868 (fix:DI (match_operand 1 "register_operand" "f")))
4869 (use (match_operand:HI 2 "memory_operand" "m"))
4870 (use (match_operand:HI 3 "memory_operand" "m"))
4871 (clobber (match_scratch:XF 4 "=&1f"))]
4872 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4873 && !TARGET_FISTTP
4874 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4875 "* return output_fix_trunc (insn, operands, 0);"
4876 [(set_attr "type" "fistp")
4877 (set_attr "i387_cw" "trunc")
4878 (set_attr "mode" "DI")])
4879
4880 (define_insn "fix_truncdi_i387_with_temp"
4881 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4882 (fix:DI (match_operand 1 "register_operand" "f,f")))
4883 (use (match_operand:HI 2 "memory_operand" "m,m"))
4884 (use (match_operand:HI 3 "memory_operand" "m,m"))
4885 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4886 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4887 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4888 && !TARGET_FISTTP
4889 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4890 "#"
4891 [(set_attr "type" "fistp")
4892 (set_attr "i387_cw" "trunc")
4893 (set_attr "mode" "DI")])
4894
4895 (define_split
4896 [(set (match_operand:DI 0 "register_operand" "")
4897 (fix:DI (match_operand 1 "register_operand" "")))
4898 (use (match_operand:HI 2 "memory_operand" ""))
4899 (use (match_operand:HI 3 "memory_operand" ""))
4900 (clobber (match_operand:DI 4 "memory_operand" ""))
4901 (clobber (match_scratch 5 ""))]
4902 "reload_completed"
4903 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4904 (use (match_dup 2))
4905 (use (match_dup 3))
4906 (clobber (match_dup 5))])
4907 (set (match_dup 0) (match_dup 4))]
4908 "")
4909
4910 (define_split
4911 [(set (match_operand:DI 0 "memory_operand" "")
4912 (fix:DI (match_operand 1 "register_operand" "")))
4913 (use (match_operand:HI 2 "memory_operand" ""))
4914 (use (match_operand:HI 3 "memory_operand" ""))
4915 (clobber (match_operand:DI 4 "memory_operand" ""))
4916 (clobber (match_scratch 5 ""))]
4917 "reload_completed"
4918 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4919 (use (match_dup 2))
4920 (use (match_dup 3))
4921 (clobber (match_dup 5))])]
4922 "")
4923
4924 (define_insn "fix_trunc<mode>_i387"
4925 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4926 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4927 (use (match_operand:HI 2 "memory_operand" "m"))
4928 (use (match_operand:HI 3 "memory_operand" "m"))]
4929 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4930 && !TARGET_FISTTP
4931 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4932 "* return output_fix_trunc (insn, operands, 0);"
4933 [(set_attr "type" "fistp")
4934 (set_attr "i387_cw" "trunc")
4935 (set_attr "mode" "<MODE>")])
4936
4937 (define_insn "fix_trunc<mode>_i387_with_temp"
4938 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4939 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4940 (use (match_operand:HI 2 "memory_operand" "m,m"))
4941 (use (match_operand:HI 3 "memory_operand" "m,m"))
4942 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4943 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4944 && !TARGET_FISTTP
4945 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4946 "#"
4947 [(set_attr "type" "fistp")
4948 (set_attr "i387_cw" "trunc")
4949 (set_attr "mode" "<MODE>")])
4950
4951 (define_split
4952 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4953 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4954 (use (match_operand:HI 2 "memory_operand" ""))
4955 (use (match_operand:HI 3 "memory_operand" ""))
4956 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4957 "reload_completed"
4958 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4959 (use (match_dup 2))
4960 (use (match_dup 3))])
4961 (set (match_dup 0) (match_dup 4))]
4962 "")
4963
4964 (define_split
4965 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4966 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4967 (use (match_operand:HI 2 "memory_operand" ""))
4968 (use (match_operand:HI 3 "memory_operand" ""))
4969 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4970 "reload_completed"
4971 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4972 (use (match_dup 2))
4973 (use (match_dup 3))])]
4974 "")
4975
4976 (define_insn "x86_fnstcw_1"
4977 [(set (match_operand:HI 0 "memory_operand" "=m")
4978 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4979 "TARGET_80387"
4980 "fnstcw\t%0"
4981 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4982 (set_attr "mode" "HI")
4983 (set_attr "unit" "i387")])
4984
4985 (define_insn "x86_fldcw_1"
4986 [(set (reg:HI FPCR_REG)
4987 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4988 "TARGET_80387"
4989 "fldcw\t%0"
4990 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4991 (set_attr "mode" "HI")
4992 (set_attr "unit" "i387")
4993 (set_attr "athlon_decode" "vector")
4994 (set_attr "amdfam10_decode" "vector")])
4995 \f
4996 ;; Conversion between fixed point and floating point.
4997
4998 ;; Even though we only accept memory inputs, the backend _really_
4999 ;; wants to be able to do this between registers.
5000
5001 (define_expand "floathi<mode>2"
5002 [(set (match_operand:X87MODEF 0 "register_operand" "")
5003 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5004 "TARGET_80387
5005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5006 || TARGET_MIX_SSE_I387)"
5007 "")
5008
5009 ;; Pre-reload splitter to add memory clobber to the pattern.
5010 (define_insn_and_split "*floathi<mode>2_1"
5011 [(set (match_operand:X87MODEF 0 "register_operand" "")
5012 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5013 "TARGET_80387
5014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5015 || TARGET_MIX_SSE_I387)
5016 && can_create_pseudo_p ()"
5017 "#"
5018 "&& 1"
5019 [(parallel [(set (match_dup 0)
5020 (float:X87MODEF (match_dup 1)))
5021 (clobber (match_dup 2))])]
5022 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5023
5024 (define_insn "*floathi<mode>2_i387_with_temp"
5025 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5026 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5027 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5028 "TARGET_80387
5029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5030 || TARGET_MIX_SSE_I387)"
5031 "#"
5032 [(set_attr "type" "fmov,multi")
5033 (set_attr "mode" "<MODE>")
5034 (set_attr "unit" "*,i387")
5035 (set_attr "fp_int_src" "true")])
5036
5037 (define_insn "*floathi<mode>2_i387"
5038 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5039 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5040 "TARGET_80387
5041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5042 || TARGET_MIX_SSE_I387)"
5043 "fild%Z1\t%1"
5044 [(set_attr "type" "fmov")
5045 (set_attr "mode" "<MODE>")
5046 (set_attr "fp_int_src" "true")])
5047
5048 (define_split
5049 [(set (match_operand:X87MODEF 0 "register_operand" "")
5050 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5051 (clobber (match_operand:HI 2 "memory_operand" ""))]
5052 "TARGET_80387
5053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5054 || TARGET_MIX_SSE_I387)
5055 && reload_completed"
5056 [(set (match_dup 2) (match_dup 1))
5057 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5058 "")
5059
5060 (define_split
5061 [(set (match_operand:X87MODEF 0 "register_operand" "")
5062 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5063 (clobber (match_operand:HI 2 "memory_operand" ""))]
5064 "TARGET_80387
5065 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5066 || TARGET_MIX_SSE_I387)
5067 && reload_completed"
5068 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5069 "")
5070
5071 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5072 [(set (match_operand:X87MODEF 0 "register_operand" "")
5073 (float:X87MODEF
5074 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5075 "TARGET_80387
5076 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5077 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5078 {
5079 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5080 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5081 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5082 {
5083 rtx reg = gen_reg_rtx (XFmode);
5084 rtx insn;
5085
5086 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5087
5088 if (<X87MODEF:MODE>mode == SFmode)
5089 insn = gen_truncxfsf2 (operands[0], reg);
5090 else if (<X87MODEF:MODE>mode == DFmode)
5091 insn = gen_truncxfdf2 (operands[0], reg);
5092 else
5093 gcc_unreachable ();
5094
5095 emit_insn (insn);
5096 DONE;
5097 }
5098 })
5099
5100 ;; Pre-reload splitter to add memory clobber to the pattern.
5101 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5102 [(set (match_operand:X87MODEF 0 "register_operand" "")
5103 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5104 "((TARGET_80387
5105 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5106 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5107 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5108 || TARGET_MIX_SSE_I387))
5109 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5110 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5111 && ((<SSEMODEI24:MODE>mode == SImode
5112 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5113 && optimize_function_for_speed_p (cfun)
5114 && flag_trapping_math)
5115 || !(TARGET_INTER_UNIT_CONVERSIONS
5116 || optimize_function_for_size_p (cfun)))))
5117 && can_create_pseudo_p ()"
5118 "#"
5119 "&& 1"
5120 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5121 (clobber (match_dup 2))])]
5122 {
5123 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5124
5125 /* Avoid store forwarding (partial memory) stall penalty
5126 by passing DImode value through XMM registers. */
5127 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5128 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5129 && optimize_function_for_speed_p (cfun))
5130 {
5131 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5132 operands[1],
5133 operands[2]));
5134 DONE;
5135 }
5136 })
5137
5138 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5139 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5140 (float:MODEF
5141 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5142 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5143 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5144 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5145 "#"
5146 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5147 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5148 (set_attr "unit" "*,i387,*,*,*")
5149 (set_attr "athlon_decode" "*,*,double,direct,double")
5150 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5151 (set_attr "fp_int_src" "true")])
5152
5153 (define_insn "*floatsi<mode>2_vector_mixed"
5154 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5155 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5156 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5157 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5158 "@
5159 fild%Z1\t%1
5160 #"
5161 [(set_attr "type" "fmov,sseicvt")
5162 (set_attr "mode" "<MODE>,<ssevecmode>")
5163 (set_attr "unit" "i387,*")
5164 (set_attr "athlon_decode" "*,direct")
5165 (set_attr "amdfam10_decode" "*,double")
5166 (set_attr "fp_int_src" "true")])
5167
5168 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5169 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5170 (float:MODEF
5171 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5172 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5173 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5174 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5175 "#"
5176 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5177 (set_attr "mode" "<MODEF:MODE>")
5178 (set_attr "unit" "*,i387,*,*")
5179 (set_attr "athlon_decode" "*,*,double,direct")
5180 (set_attr "amdfam10_decode" "*,*,vector,double")
5181 (set_attr "fp_int_src" "true")])
5182
5183 (define_split
5184 [(set (match_operand:MODEF 0 "register_operand" "")
5185 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5186 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5187 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5188 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5189 && TARGET_INTER_UNIT_CONVERSIONS
5190 && reload_completed
5191 && (SSE_REG_P (operands[0])
5192 || (GET_CODE (operands[0]) == SUBREG
5193 && SSE_REG_P (operands[0])))"
5194 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5195 "")
5196
5197 (define_split
5198 [(set (match_operand:MODEF 0 "register_operand" "")
5199 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5200 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5201 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5203 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5204 && reload_completed
5205 && (SSE_REG_P (operands[0])
5206 || (GET_CODE (operands[0]) == SUBREG
5207 && SSE_REG_P (operands[0])))"
5208 [(set (match_dup 2) (match_dup 1))
5209 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5210 "")
5211
5212 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5213 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5214 (float:MODEF
5215 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5216 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5217 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5218 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5219 "@
5220 fild%Z1\t%1
5221 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5222 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5223 [(set_attr "type" "fmov,sseicvt,sseicvt")
5224 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5225 (set_attr "mode" "<MODEF:MODE>")
5226 (set (attr "prefix_rex")
5227 (if_then_else
5228 (and (eq_attr "prefix" "maybe_vex")
5229 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5230 (const_string "1")
5231 (const_string "*")))
5232 (set_attr "unit" "i387,*,*")
5233 (set_attr "athlon_decode" "*,double,direct")
5234 (set_attr "amdfam10_decode" "*,vector,double")
5235 (set_attr "fp_int_src" "true")])
5236
5237 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5238 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5239 (float:MODEF
5240 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5241 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5242 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5243 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5244 "@
5245 fild%Z1\t%1
5246 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5247 [(set_attr "type" "fmov,sseicvt")
5248 (set_attr "prefix" "orig,maybe_vex")
5249 (set_attr "mode" "<MODEF:MODE>")
5250 (set (attr "prefix_rex")
5251 (if_then_else
5252 (and (eq_attr "prefix" "maybe_vex")
5253 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5254 (const_string "1")
5255 (const_string "*")))
5256 (set_attr "athlon_decode" "*,direct")
5257 (set_attr "amdfam10_decode" "*,double")
5258 (set_attr "fp_int_src" "true")])
5259
5260 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5261 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5262 (float:MODEF
5263 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5264 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5265 "TARGET_SSE2 && TARGET_SSE_MATH
5266 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5267 "#"
5268 [(set_attr "type" "sseicvt")
5269 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5270 (set_attr "athlon_decode" "double,direct,double")
5271 (set_attr "amdfam10_decode" "vector,double,double")
5272 (set_attr "fp_int_src" "true")])
5273
5274 (define_insn "*floatsi<mode>2_vector_sse"
5275 [(set (match_operand:MODEF 0 "register_operand" "=x")
5276 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5277 "TARGET_SSE2 && TARGET_SSE_MATH
5278 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5279 "#"
5280 [(set_attr "type" "sseicvt")
5281 (set_attr "mode" "<MODE>")
5282 (set_attr "athlon_decode" "direct")
5283 (set_attr "amdfam10_decode" "double")
5284 (set_attr "fp_int_src" "true")])
5285
5286 (define_split
5287 [(set (match_operand:MODEF 0 "register_operand" "")
5288 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5289 (clobber (match_operand:SI 2 "memory_operand" ""))]
5290 "TARGET_SSE2 && TARGET_SSE_MATH
5291 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5292 && reload_completed
5293 && (SSE_REG_P (operands[0])
5294 || (GET_CODE (operands[0]) == SUBREG
5295 && SSE_REG_P (operands[0])))"
5296 [(const_int 0)]
5297 {
5298 rtx op1 = operands[1];
5299
5300 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5301 <MODE>mode, 0);
5302 if (GET_CODE (op1) == SUBREG)
5303 op1 = SUBREG_REG (op1);
5304
5305 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5306 {
5307 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5308 emit_insn (gen_sse2_loadld (operands[4],
5309 CONST0_RTX (V4SImode), operands[1]));
5310 }
5311 /* We can ignore possible trapping value in the
5312 high part of SSE register for non-trapping math. */
5313 else if (SSE_REG_P (op1) && !flag_trapping_math)
5314 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5315 else
5316 {
5317 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5318 emit_move_insn (operands[2], operands[1]);
5319 emit_insn (gen_sse2_loadld (operands[4],
5320 CONST0_RTX (V4SImode), operands[2]));
5321 }
5322 emit_insn
5323 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5324 DONE;
5325 })
5326
5327 (define_split
5328 [(set (match_operand:MODEF 0 "register_operand" "")
5329 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5330 (clobber (match_operand:SI 2 "memory_operand" ""))]
5331 "TARGET_SSE2 && TARGET_SSE_MATH
5332 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5333 && reload_completed
5334 && (SSE_REG_P (operands[0])
5335 || (GET_CODE (operands[0]) == SUBREG
5336 && SSE_REG_P (operands[0])))"
5337 [(const_int 0)]
5338 {
5339 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5340 <MODE>mode, 0);
5341 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5342
5343 emit_insn (gen_sse2_loadld (operands[4],
5344 CONST0_RTX (V4SImode), operands[1]));
5345 emit_insn
5346 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5347 DONE;
5348 })
5349
5350 (define_split
5351 [(set (match_operand:MODEF 0 "register_operand" "")
5352 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5353 "TARGET_SSE2 && TARGET_SSE_MATH
5354 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5355 && reload_completed
5356 && (SSE_REG_P (operands[0])
5357 || (GET_CODE (operands[0]) == SUBREG
5358 && SSE_REG_P (operands[0])))"
5359 [(const_int 0)]
5360 {
5361 rtx op1 = operands[1];
5362
5363 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5364 <MODE>mode, 0);
5365 if (GET_CODE (op1) == SUBREG)
5366 op1 = SUBREG_REG (op1);
5367
5368 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5369 {
5370 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5371 emit_insn (gen_sse2_loadld (operands[4],
5372 CONST0_RTX (V4SImode), operands[1]));
5373 }
5374 /* We can ignore possible trapping value in the
5375 high part of SSE register for non-trapping math. */
5376 else if (SSE_REG_P (op1) && !flag_trapping_math)
5377 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5378 else
5379 gcc_unreachable ();
5380 emit_insn
5381 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5382 DONE;
5383 })
5384
5385 (define_split
5386 [(set (match_operand:MODEF 0 "register_operand" "")
5387 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5388 "TARGET_SSE2 && TARGET_SSE_MATH
5389 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5390 && reload_completed
5391 && (SSE_REG_P (operands[0])
5392 || (GET_CODE (operands[0]) == SUBREG
5393 && SSE_REG_P (operands[0])))"
5394 [(const_int 0)]
5395 {
5396 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5397 <MODE>mode, 0);
5398 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5399
5400 emit_insn (gen_sse2_loadld (operands[4],
5401 CONST0_RTX (V4SImode), operands[1]));
5402 emit_insn
5403 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5404 DONE;
5405 })
5406
5407 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5408 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5409 (float:MODEF
5410 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5411 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5412 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5413 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5414 "#"
5415 [(set_attr "type" "sseicvt")
5416 (set_attr "mode" "<MODEF:MODE>")
5417 (set_attr "athlon_decode" "double,direct")
5418 (set_attr "amdfam10_decode" "vector,double")
5419 (set_attr "fp_int_src" "true")])
5420
5421 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5422 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5423 (float:MODEF
5424 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5425 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5426 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5427 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5428 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5429 [(set_attr "type" "sseicvt")
5430 (set_attr "prefix" "maybe_vex")
5431 (set_attr "mode" "<MODEF:MODE>")
5432 (set (attr "prefix_rex")
5433 (if_then_else
5434 (and (eq_attr "prefix" "maybe_vex")
5435 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5436 (const_string "1")
5437 (const_string "*")))
5438 (set_attr "athlon_decode" "double,direct")
5439 (set_attr "amdfam10_decode" "vector,double")
5440 (set_attr "fp_int_src" "true")])
5441
5442 (define_split
5443 [(set (match_operand:MODEF 0 "register_operand" "")
5444 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5445 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5446 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5447 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5448 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5449 && reload_completed
5450 && (SSE_REG_P (operands[0])
5451 || (GET_CODE (operands[0]) == SUBREG
5452 && SSE_REG_P (operands[0])))"
5453 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5454 "")
5455
5456 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5457 [(set (match_operand:MODEF 0 "register_operand" "=x")
5458 (float:MODEF
5459 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5460 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5462 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5463 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5464 [(set_attr "type" "sseicvt")
5465 (set_attr "prefix" "maybe_vex")
5466 (set_attr "mode" "<MODEF:MODE>")
5467 (set (attr "prefix_rex")
5468 (if_then_else
5469 (and (eq_attr "prefix" "maybe_vex")
5470 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5471 (const_string "1")
5472 (const_string "*")))
5473 (set_attr "athlon_decode" "direct")
5474 (set_attr "amdfam10_decode" "double")
5475 (set_attr "fp_int_src" "true")])
5476
5477 (define_split
5478 [(set (match_operand:MODEF 0 "register_operand" "")
5479 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5480 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5481 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5482 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5483 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5484 && reload_completed
5485 && (SSE_REG_P (operands[0])
5486 || (GET_CODE (operands[0]) == SUBREG
5487 && SSE_REG_P (operands[0])))"
5488 [(set (match_dup 2) (match_dup 1))
5489 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5490 "")
5491
5492 (define_split
5493 [(set (match_operand:MODEF 0 "register_operand" "")
5494 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5495 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5496 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5497 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5498 && reload_completed
5499 && (SSE_REG_P (operands[0])
5500 || (GET_CODE (operands[0]) == SUBREG
5501 && SSE_REG_P (operands[0])))"
5502 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5503 "")
5504
5505 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5506 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5507 (float:X87MODEF
5508 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5509 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5510 "TARGET_80387
5511 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5512 "@
5513 fild%Z1\t%1
5514 #"
5515 [(set_attr "type" "fmov,multi")
5516 (set_attr "mode" "<X87MODEF:MODE>")
5517 (set_attr "unit" "*,i387")
5518 (set_attr "fp_int_src" "true")])
5519
5520 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5521 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5522 (float:X87MODEF
5523 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5524 "TARGET_80387
5525 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5526 "fild%Z1\t%1"
5527 [(set_attr "type" "fmov")
5528 (set_attr "mode" "<X87MODEF:MODE>")
5529 (set_attr "fp_int_src" "true")])
5530
5531 (define_split
5532 [(set (match_operand:X87MODEF 0 "register_operand" "")
5533 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5534 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5535 "TARGET_80387
5536 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5537 && reload_completed
5538 && FP_REG_P (operands[0])"
5539 [(set (match_dup 2) (match_dup 1))
5540 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5541 "")
5542
5543 (define_split
5544 [(set (match_operand:X87MODEF 0 "register_operand" "")
5545 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5546 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5547 "TARGET_80387
5548 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5549 && reload_completed
5550 && FP_REG_P (operands[0])"
5551 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5552 "")
5553
5554 ;; Avoid store forwarding (partial memory) stall penalty
5555 ;; by passing DImode value through XMM registers. */
5556
5557 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5558 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5559 (float:X87MODEF
5560 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5561 (clobber (match_scratch:V4SI 3 "=X,x"))
5562 (clobber (match_scratch:V4SI 4 "=X,x"))
5563 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5564 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5565 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5566 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5567 "#"
5568 [(set_attr "type" "multi")
5569 (set_attr "mode" "<X87MODEF:MODE>")
5570 (set_attr "unit" "i387")
5571 (set_attr "fp_int_src" "true")])
5572
5573 (define_split
5574 [(set (match_operand:X87MODEF 0 "register_operand" "")
5575 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5576 (clobber (match_scratch:V4SI 3 ""))
5577 (clobber (match_scratch:V4SI 4 ""))
5578 (clobber (match_operand:DI 2 "memory_operand" ""))]
5579 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5580 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5581 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5582 && reload_completed
5583 && FP_REG_P (operands[0])"
5584 [(set (match_dup 2) (match_dup 3))
5585 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5586 {
5587 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5588 Assemble the 64-bit DImode value in an xmm register. */
5589 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5590 gen_rtx_SUBREG (SImode, operands[1], 0)));
5591 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5592 gen_rtx_SUBREG (SImode, operands[1], 4)));
5593 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5594 operands[4]));
5595
5596 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5597 })
5598
5599 (define_split
5600 [(set (match_operand:X87MODEF 0 "register_operand" "")
5601 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5602 (clobber (match_scratch:V4SI 3 ""))
5603 (clobber (match_scratch:V4SI 4 ""))
5604 (clobber (match_operand:DI 2 "memory_operand" ""))]
5605 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5606 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5607 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5608 && reload_completed
5609 && FP_REG_P (operands[0])"
5610 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5611 "")
5612
5613 ;; Avoid store forwarding (partial memory) stall penalty by extending
5614 ;; SImode value to DImode through XMM register instead of pushing two
5615 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5616 ;; targets benefit from this optimization. Also note that fild
5617 ;; loads from memory only.
5618
5619 (define_insn "*floatunssi<mode>2_1"
5620 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5621 (unsigned_float:X87MODEF
5622 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5623 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5624 (clobber (match_scratch:SI 3 "=X,x"))]
5625 "!TARGET_64BIT
5626 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5627 && TARGET_SSE"
5628 "#"
5629 [(set_attr "type" "multi")
5630 (set_attr "mode" "<MODE>")])
5631
5632 (define_split
5633 [(set (match_operand:X87MODEF 0 "register_operand" "")
5634 (unsigned_float:X87MODEF
5635 (match_operand:SI 1 "register_operand" "")))
5636 (clobber (match_operand:DI 2 "memory_operand" ""))
5637 (clobber (match_scratch:SI 3 ""))]
5638 "!TARGET_64BIT
5639 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5640 && TARGET_SSE
5641 && reload_completed"
5642 [(set (match_dup 2) (match_dup 1))
5643 (set (match_dup 0)
5644 (float:X87MODEF (match_dup 2)))]
5645 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5646
5647 (define_split
5648 [(set (match_operand:X87MODEF 0 "register_operand" "")
5649 (unsigned_float:X87MODEF
5650 (match_operand:SI 1 "memory_operand" "")))
5651 (clobber (match_operand:DI 2 "memory_operand" ""))
5652 (clobber (match_scratch:SI 3 ""))]
5653 "!TARGET_64BIT
5654 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5655 && TARGET_SSE
5656 && reload_completed"
5657 [(set (match_dup 2) (match_dup 3))
5658 (set (match_dup 0)
5659 (float:X87MODEF (match_dup 2)))]
5660 {
5661 emit_move_insn (operands[3], operands[1]);
5662 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5663 })
5664
5665 (define_expand "floatunssi<mode>2"
5666 [(parallel
5667 [(set (match_operand:X87MODEF 0 "register_operand" "")
5668 (unsigned_float:X87MODEF
5669 (match_operand:SI 1 "nonimmediate_operand" "")))
5670 (clobber (match_dup 2))
5671 (clobber (match_scratch:SI 3 ""))])]
5672 "!TARGET_64BIT
5673 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5674 && TARGET_SSE)
5675 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5676 {
5677 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5678 {
5679 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5680 DONE;
5681 }
5682 else
5683 {
5684 enum ix86_stack_slot slot = (virtuals_instantiated
5685 ? SLOT_TEMP
5686 : SLOT_VIRTUAL);
5687 operands[2] = assign_386_stack_local (DImode, slot);
5688 }
5689 })
5690
5691 (define_expand "floatunsdisf2"
5692 [(use (match_operand:SF 0 "register_operand" ""))
5693 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5694 "TARGET_64BIT && TARGET_SSE_MATH"
5695 "x86_emit_floatuns (operands); DONE;")
5696
5697 (define_expand "floatunsdidf2"
5698 [(use (match_operand:DF 0 "register_operand" ""))
5699 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5700 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5701 && TARGET_SSE2 && TARGET_SSE_MATH"
5702 {
5703 if (TARGET_64BIT)
5704 x86_emit_floatuns (operands);
5705 else
5706 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5707 DONE;
5708 })
5709 \f
5710 ;; Add instructions
5711
5712 (define_expand "add<mode>3"
5713 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5714 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5715 (match_operand:SDWIM 2 "<general_operand>" "")))]
5716 ""
5717 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5718
5719 (define_insn_and_split "*add<dwi>3_doubleword"
5720 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5721 (plus:<DWI>
5722 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5723 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5724 (clobber (reg:CC FLAGS_REG))]
5725 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5726 "#"
5727 "reload_completed"
5728 [(parallel [(set (reg:CC FLAGS_REG)
5729 (unspec:CC [(match_dup 1) (match_dup 2)]
5730 UNSPEC_ADD_CARRY))
5731 (set (match_dup 0)
5732 (plus:DWIH (match_dup 1) (match_dup 2)))])
5733 (parallel [(set (match_dup 3)
5734 (plus:DWIH
5735 (match_dup 4)
5736 (plus:DWIH
5737 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5738 (match_dup 5))))
5739 (clobber (reg:CC FLAGS_REG))])]
5740 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5741
5742 (define_insn "*add<mode>3_cc"
5743 [(set (reg:CC FLAGS_REG)
5744 (unspec:CC
5745 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5746 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5747 UNSPEC_ADD_CARRY))
5748 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5749 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5750 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5751 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5752 [(set_attr "type" "alu")
5753 (set_attr "mode" "<MODE>")])
5754
5755 (define_insn "addqi3_cc"
5756 [(set (reg:CC FLAGS_REG)
5757 (unspec:CC
5758 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5759 (match_operand:QI 2 "general_operand" "qn,qm")]
5760 UNSPEC_ADD_CARRY))
5761 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5762 (plus:QI (match_dup 1) (match_dup 2)))]
5763 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5764 "add{b}\t{%2, %0|%0, %2}"
5765 [(set_attr "type" "alu")
5766 (set_attr "mode" "QI")])
5767
5768 (define_insn "*lea_1"
5769 [(set (match_operand:DWIH 0 "register_operand" "=r")
5770 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5771 ""
5772 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5773 [(set_attr "type" "lea")
5774 (set_attr "mode" "<MODE>")])
5775
5776 (define_insn "*lea_2"
5777 [(set (match_operand:SI 0 "register_operand" "=r")
5778 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5779 "TARGET_64BIT"
5780 "lea{l}\t{%a1, %0|%0, %a1}"
5781 [(set_attr "type" "lea")
5782 (set_attr "mode" "SI")])
5783
5784 (define_insn "*lea_2_zext"
5785 [(set (match_operand:DI 0 "register_operand" "=r")
5786 (zero_extend:DI
5787 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5788 "TARGET_64BIT"
5789 "lea{l}\t{%a1, %k0|%k0, %a1}"
5790 [(set_attr "type" "lea")
5791 (set_attr "mode" "SI")])
5792
5793 (define_insn "*add<mode>_1"
5794 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5795 (plus:SWI48
5796 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5797 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5798 (clobber (reg:CC FLAGS_REG))]
5799 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5800 {
5801 switch (get_attr_type (insn))
5802 {
5803 case TYPE_LEA:
5804 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5805 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5806
5807 case TYPE_INCDEC:
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (operands[2] == const1_rtx)
5810 return "inc{<imodesuffix>}\t%0";
5811 else
5812 {
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{<imodesuffix>}\t%0";
5815 }
5816
5817 default:
5818 /* Use add as much as possible to replace lea for AGU optimization. */
5819 if (which_alternative == 2 && TARGET_OPT_AGU)
5820 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
5821
5822 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5823 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5824 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5825
5826 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5827 }
5828 }
5829 [(set (attr "type")
5830 (cond [(and (eq_attr "alternative" "2")
5831 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
5832 (const_string "lea")
5833 (eq_attr "alternative" "3")
5834 (const_string "lea")
5835 (match_operand:SWI48 2 "incdec_operand" "")
5836 (const_string "incdec")
5837 ]
5838 (const_string "alu")))
5839 (set (attr "length_immediate")
5840 (if_then_else
5841 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5842 (const_string "1")
5843 (const_string "*")))
5844 (set_attr "mode" "<MODE>")])
5845
5846 ;; It may seem that nonimmediate operand is proper one for operand 1.
5847 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5848 ;; we take care in ix86_binary_operator_ok to not allow two memory
5849 ;; operands so proper swapping will be done in reload. This allow
5850 ;; patterns constructed from addsi_1 to match.
5851
5852 (define_insn "*addsi_1_zext"
5853 [(set (match_operand:DI 0 "register_operand" "=r,r")
5854 (zero_extend:DI
5855 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5856 (match_operand:SI 2 "general_operand" "g,li"))))
5857 (clobber (reg:CC FLAGS_REG))]
5858 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5859 {
5860 switch (get_attr_type (insn))
5861 {
5862 case TYPE_LEA:
5863 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
5864 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5865
5866 case TYPE_INCDEC:
5867 if (operands[2] == const1_rtx)
5868 return "inc{l}\t%k0";
5869 else
5870 {
5871 gcc_assert (operands[2] == constm1_rtx);
5872 return "dec{l}\t%k0";
5873 }
5874
5875 default:
5876 if (x86_maybe_negate_const_int (&operands[2], SImode))
5877 return "sub{l}\t{%2, %k0|%k0, %2}";
5878
5879 return "add{l}\t{%2, %k0|%k0, %2}";
5880 }
5881 }
5882 [(set (attr "type")
5883 (cond [(eq_attr "alternative" "1")
5884 (const_string "lea")
5885 (match_operand:SI 2 "incdec_operand" "")
5886 (const_string "incdec")
5887 ]
5888 (const_string "alu")))
5889 (set (attr "length_immediate")
5890 (if_then_else
5891 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5892 (const_string "1")
5893 (const_string "*")))
5894 (set_attr "mode" "SI")])
5895
5896 (define_insn "*addhi_1"
5897 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5898 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5899 (match_operand:HI 2 "general_operand" "rn,rm")))
5900 (clobber (reg:CC FLAGS_REG))]
5901 "TARGET_PARTIAL_REG_STALL
5902 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5903 {
5904 switch (get_attr_type (insn))
5905 {
5906 case TYPE_INCDEC:
5907 if (operands[2] == const1_rtx)
5908 return "inc{w}\t%0";
5909 else
5910 {
5911 gcc_assert (operands[2] == constm1_rtx);
5912 return "dec{w}\t%0";
5913 }
5914
5915 default:
5916 if (x86_maybe_negate_const_int (&operands[2], HImode))
5917 return "sub{w}\t{%2, %0|%0, %2}";
5918
5919 return "add{w}\t{%2, %0|%0, %2}";
5920 }
5921 }
5922 [(set (attr "type")
5923 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5924 (const_string "incdec")
5925 (const_string "alu")))
5926 (set (attr "length_immediate")
5927 (if_then_else
5928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5929 (const_string "1")
5930 (const_string "*")))
5931 (set_attr "mode" "HI")])
5932
5933 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5934 ;; type optimizations enabled by define-splits. This is not important
5935 ;; for PII, and in fact harmful because of partial register stalls.
5936
5937 (define_insn "*addhi_1_lea"
5938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5939 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5940 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
5941 (clobber (reg:CC FLAGS_REG))]
5942 "!TARGET_PARTIAL_REG_STALL
5943 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5944 {
5945 switch (get_attr_type (insn))
5946 {
5947 case TYPE_LEA:
5948 return "#";
5949
5950 case TYPE_INCDEC:
5951 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5952 if (operands[2] == const1_rtx)
5953 return "inc{w}\t%0";
5954 else
5955 {
5956 gcc_assert (operands[2] == constm1_rtx);
5957 return "dec{w}\t%0";
5958 }
5959
5960 default:
5961 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962 if (x86_maybe_negate_const_int (&operands[2], HImode))
5963 return "sub{w}\t{%2, %0|%0, %2}";
5964
5965 return "add{w}\t{%2, %0|%0, %2}";
5966 }
5967 }
5968 [(set (attr "type")
5969 (if_then_else (eq_attr "alternative" "2")
5970 (const_string "lea")
5971 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5972 (const_string "incdec")
5973 (const_string "alu"))))
5974 (set (attr "length_immediate")
5975 (if_then_else
5976 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5977 (const_string "1")
5978 (const_string "*")))
5979 (set_attr "mode" "HI,HI,SI")])
5980
5981 (define_insn "*addqi_1"
5982 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5983 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5984 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5985 (clobber (reg:CC FLAGS_REG))]
5986 "TARGET_PARTIAL_REG_STALL
5987 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5988 {
5989 int widen = (which_alternative == 2);
5990 switch (get_attr_type (insn))
5991 {
5992 case TYPE_INCDEC:
5993 if (operands[2] == const1_rtx)
5994 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5995 else
5996 {
5997 gcc_assert (operands[2] == constm1_rtx);
5998 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5999 }
6000
6001 default:
6002 if (x86_maybe_negate_const_int (&operands[2], QImode))
6003 {
6004 if (widen)
6005 return "sub{l}\t{%2, %k0|%k0, %2}";
6006 else
6007 return "sub{b}\t{%2, %0|%0, %2}";
6008 }
6009 if (widen)
6010 return "add{l}\t{%k2, %k0|%k0, %k2}";
6011 else
6012 return "add{b}\t{%2, %0|%0, %2}";
6013 }
6014 }
6015 [(set (attr "type")
6016 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6017 (const_string "incdec")
6018 (const_string "alu")))
6019 (set (attr "length_immediate")
6020 (if_then_else
6021 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6022 (const_string "1")
6023 (const_string "*")))
6024 (set_attr "mode" "QI,QI,SI")])
6025
6026 ;; %%% Potential partial reg stall on alternative 2. What to do?
6027 (define_insn "*addqi_1_lea"
6028 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6029 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6030 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6031 (clobber (reg:CC FLAGS_REG))]
6032 "!TARGET_PARTIAL_REG_STALL
6033 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6034 {
6035 int widen = (which_alternative == 2);
6036 switch (get_attr_type (insn))
6037 {
6038 case TYPE_LEA:
6039 return "#";
6040
6041 case TYPE_INCDEC:
6042 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6043 if (operands[2] == const1_rtx)
6044 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6045 else
6046 {
6047 gcc_assert (operands[2] == constm1_rtx);
6048 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6049 }
6050
6051 default:
6052 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6053 if (x86_maybe_negate_const_int (&operands[2], QImode))
6054 {
6055 if (widen)
6056 return "sub{l}\t{%2, %k0|%k0, %2}";
6057 else
6058 return "sub{b}\t{%2, %0|%0, %2}";
6059 }
6060 if (widen)
6061 return "add{l}\t{%k2, %k0|%k0, %k2}";
6062 else
6063 return "add{b}\t{%2, %0|%0, %2}";
6064 }
6065 }
6066 [(set (attr "type")
6067 (if_then_else (eq_attr "alternative" "3")
6068 (const_string "lea")
6069 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6070 (const_string "incdec")
6071 (const_string "alu"))))
6072 (set (attr "length_immediate")
6073 (if_then_else
6074 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6075 (const_string "1")
6076 (const_string "*")))
6077 (set_attr "mode" "QI,QI,SI,SI")])
6078
6079 (define_insn "*addqi_1_slp"
6080 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6081 (plus:QI (match_dup 0)
6082 (match_operand:QI 1 "general_operand" "qn,qnm")))
6083 (clobber (reg:CC FLAGS_REG))]
6084 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6085 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6086 {
6087 switch (get_attr_type (insn))
6088 {
6089 case TYPE_INCDEC:
6090 if (operands[1] == const1_rtx)
6091 return "inc{b}\t%0";
6092 else
6093 {
6094 gcc_assert (operands[1] == constm1_rtx);
6095 return "dec{b}\t%0";
6096 }
6097
6098 default:
6099 if (x86_maybe_negate_const_int (&operands[1], QImode))
6100 return "sub{b}\t{%1, %0|%0, %1}";
6101
6102 return "add{b}\t{%1, %0|%0, %1}";
6103 }
6104 }
6105 [(set (attr "type")
6106 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6107 (const_string "incdec")
6108 (const_string "alu1")))
6109 (set (attr "memory")
6110 (if_then_else (match_operand 1 "memory_operand" "")
6111 (const_string "load")
6112 (const_string "none")))
6113 (set_attr "mode" "QI")])
6114
6115 (define_insn "*add<mode>_2"
6116 [(set (reg FLAGS_REG)
6117 (compare
6118 (plus:SWI
6119 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6120 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6121 (const_int 0)))
6122 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6123 (plus:SWI (match_dup 1) (match_dup 2)))]
6124 "ix86_match_ccmode (insn, CCGOCmode)
6125 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6126 {
6127 switch (get_attr_type (insn))
6128 {
6129 case TYPE_INCDEC:
6130 if (operands[2] == const1_rtx)
6131 return "inc{<imodesuffix>}\t%0";
6132 else
6133 {
6134 gcc_assert (operands[2] == constm1_rtx);
6135 return "dec{<imodesuffix>}\t%0";
6136 }
6137
6138 default:
6139 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6140 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6141
6142 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6143 }
6144 }
6145 [(set (attr "type")
6146 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6147 (const_string "incdec")
6148 (const_string "alu")))
6149 (set (attr "length_immediate")
6150 (if_then_else
6151 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6152 (const_string "1")
6153 (const_string "*")))
6154 (set_attr "mode" "<MODE>")])
6155
6156 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6157 (define_insn "*addsi_2_zext"
6158 [(set (reg FLAGS_REG)
6159 (compare
6160 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6161 (match_operand:SI 2 "general_operand" "g"))
6162 (const_int 0)))
6163 (set (match_operand:DI 0 "register_operand" "=r")
6164 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6165 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6166 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6167 {
6168 switch (get_attr_type (insn))
6169 {
6170 case TYPE_INCDEC:
6171 if (operands[2] == const1_rtx)
6172 return "inc{l}\t%k0";
6173 else
6174 {
6175 gcc_assert (operands[2] == constm1_rtx);
6176 return "dec{l}\t%k0";
6177 }
6178
6179 default:
6180 if (x86_maybe_negate_const_int (&operands[2], SImode))
6181 return "sub{l}\t{%2, %k0|%k0, %2}";
6182
6183 return "add{l}\t{%2, %k0|%k0, %2}";
6184 }
6185 }
6186 [(set (attr "type")
6187 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6188 (const_string "incdec")
6189 (const_string "alu")))
6190 (set (attr "length_immediate")
6191 (if_then_else
6192 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6193 (const_string "1")
6194 (const_string "*")))
6195 (set_attr "mode" "SI")])
6196
6197 (define_insn "*add<mode>_3"
6198 [(set (reg FLAGS_REG)
6199 (compare
6200 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6201 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6202 (clobber (match_scratch:SWI 0 "=<r>"))]
6203 "ix86_match_ccmode (insn, CCZmode)
6204 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6205 {
6206 switch (get_attr_type (insn))
6207 {
6208 case TYPE_INCDEC:
6209 if (operands[2] == const1_rtx)
6210 return "inc{<imodesuffix>}\t%0";
6211 else
6212 {
6213 gcc_assert (operands[2] == constm1_rtx);
6214 return "dec{<imodesuffix>}\t%0";
6215 }
6216
6217 default:
6218 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6219 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6220
6221 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6222 }
6223 }
6224 [(set (attr "type")
6225 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu")))
6228 (set (attr "length_immediate")
6229 (if_then_else
6230 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6231 (const_string "1")
6232 (const_string "*")))
6233 (set_attr "mode" "<MODE>")])
6234
6235 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6236 (define_insn "*addsi_3_zext"
6237 [(set (reg FLAGS_REG)
6238 (compare
6239 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6240 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6241 (set (match_operand:DI 0 "register_operand" "=r")
6242 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6243 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6244 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6245 {
6246 switch (get_attr_type (insn))
6247 {
6248 case TYPE_INCDEC:
6249 if (operands[2] == const1_rtx)
6250 return "inc{l}\t%k0";
6251 else
6252 {
6253 gcc_assert (operands[2] == constm1_rtx);
6254 return "dec{l}\t%k0";
6255 }
6256
6257 default:
6258 if (x86_maybe_negate_const_int (&operands[2], SImode))
6259 return "sub{l}\t{%2, %k0|%k0, %2}";
6260
6261 return "add{l}\t{%2, %k0|%k0, %2}";
6262 }
6263 }
6264 [(set (attr "type")
6265 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6266 (const_string "incdec")
6267 (const_string "alu")))
6268 (set (attr "length_immediate")
6269 (if_then_else
6270 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6271 (const_string "1")
6272 (const_string "*")))
6273 (set_attr "mode" "SI")])
6274
6275 ; For comparisons against 1, -1 and 128, we may generate better code
6276 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6277 ; is matched then. We can't accept general immediate, because for
6278 ; case of overflows, the result is messed up.
6279 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6280 ; only for comparisons not depending on it.
6281
6282 (define_insn "*adddi_4"
6283 [(set (reg FLAGS_REG)
6284 (compare
6285 (match_operand:DI 1 "nonimmediate_operand" "0")
6286 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6287 (clobber (match_scratch:DI 0 "=rm"))]
6288 "TARGET_64BIT
6289 && ix86_match_ccmode (insn, CCGCmode)"
6290 {
6291 switch (get_attr_type (insn))
6292 {
6293 case TYPE_INCDEC:
6294 if (operands[2] == constm1_rtx)
6295 return "inc{q}\t%0";
6296 else
6297 {
6298 gcc_assert (operands[2] == const1_rtx);
6299 return "dec{q}\t%0";
6300 }
6301
6302 default:
6303 if (x86_maybe_negate_const_int (&operands[2], DImode))
6304 return "add{q}\t{%2, %0|%0, %2}";
6305
6306 return "sub{q}\t{%2, %0|%0, %2}";
6307 }
6308 }
6309 [(set (attr "type")
6310 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6311 (const_string "incdec")
6312 (const_string "alu")))
6313 (set (attr "length_immediate")
6314 (if_then_else
6315 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6316 (const_string "1")
6317 (const_string "*")))
6318 (set_attr "mode" "DI")])
6319
6320 ; For comparisons against 1, -1 and 128, we may generate better code
6321 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6322 ; is matched then. We can't accept general immediate, because for
6323 ; case of overflows, the result is messed up.
6324 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6325 ; only for comparisons not depending on it.
6326
6327 (define_insn "*add<mode>_4"
6328 [(set (reg FLAGS_REG)
6329 (compare
6330 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6331 (match_operand:SWI124 2 "const_int_operand" "n")))
6332 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6333 "ix86_match_ccmode (insn, CCGCmode)"
6334 {
6335 switch (get_attr_type (insn))
6336 {
6337 case TYPE_INCDEC:
6338 if (operands[2] == constm1_rtx)
6339 return "inc{<imodesuffix>}\t%0";
6340 else
6341 {
6342 gcc_assert (operands[2] == const1_rtx);
6343 return "dec{<imodesuffix>}\t%0";
6344 }
6345
6346 default:
6347 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6348 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6349
6350 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6351 }
6352 }
6353 [(set (attr "type")
6354 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6355 (const_string "incdec")
6356 (const_string "alu")))
6357 (set (attr "length_immediate")
6358 (if_then_else
6359 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6360 (const_string "1")
6361 (const_string "*")))
6362 (set_attr "mode" "<MODE>")])
6363
6364 (define_insn "*add<mode>_5"
6365 [(set (reg FLAGS_REG)
6366 (compare
6367 (plus:SWI
6368 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6369 (match_operand:SWI 2 "<general_operand>" "<g>"))
6370 (const_int 0)))
6371 (clobber (match_scratch:SWI 0 "=<r>"))]
6372 "ix86_match_ccmode (insn, CCGOCmode)
6373 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6374 {
6375 switch (get_attr_type (insn))
6376 {
6377 case TYPE_INCDEC:
6378 if (operands[2] == const1_rtx)
6379 return "inc{<imodesuffix>}\t%0";
6380 else
6381 {
6382 gcc_assert (operands[2] == constm1_rtx);
6383 return "dec{<imodesuffix>}\t%0";
6384 }
6385
6386 default:
6387 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6388 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6389
6390 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6391 }
6392 }
6393 [(set (attr "type")
6394 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6395 (const_string "incdec")
6396 (const_string "alu")))
6397 (set (attr "length_immediate")
6398 (if_then_else
6399 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6400 (const_string "1")
6401 (const_string "*")))
6402 (set_attr "mode" "<MODE>")])
6403
6404 (define_insn "*addqi_ext_1_rex64"
6405 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6406 (const_int 8)
6407 (const_int 8))
6408 (plus:SI
6409 (zero_extract:SI
6410 (match_operand 1 "ext_register_operand" "0")
6411 (const_int 8)
6412 (const_int 8))
6413 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6414 (clobber (reg:CC FLAGS_REG))]
6415 "TARGET_64BIT"
6416 {
6417 switch (get_attr_type (insn))
6418 {
6419 case TYPE_INCDEC:
6420 if (operands[2] == const1_rtx)
6421 return "inc{b}\t%h0";
6422 else
6423 {
6424 gcc_assert (operands[2] == constm1_rtx);
6425 return "dec{b}\t%h0";
6426 }
6427
6428 default:
6429 return "add{b}\t{%2, %h0|%h0, %2}";
6430 }
6431 }
6432 [(set (attr "type")
6433 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6434 (const_string "incdec")
6435 (const_string "alu")))
6436 (set_attr "modrm" "1")
6437 (set_attr "mode" "QI")])
6438
6439 (define_insn "addqi_ext_1"
6440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6441 (const_int 8)
6442 (const_int 8))
6443 (plus:SI
6444 (zero_extract:SI
6445 (match_operand 1 "ext_register_operand" "0")
6446 (const_int 8)
6447 (const_int 8))
6448 (match_operand:QI 2 "general_operand" "Qmn")))
6449 (clobber (reg:CC FLAGS_REG))]
6450 "!TARGET_64BIT"
6451 {
6452 switch (get_attr_type (insn))
6453 {
6454 case TYPE_INCDEC:
6455 if (operands[2] == const1_rtx)
6456 return "inc{b}\t%h0";
6457 else
6458 {
6459 gcc_assert (operands[2] == constm1_rtx);
6460 return "dec{b}\t%h0";
6461 }
6462
6463 default:
6464 return "add{b}\t{%2, %h0|%h0, %2}";
6465 }
6466 }
6467 [(set (attr "type")
6468 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6469 (const_string "incdec")
6470 (const_string "alu")))
6471 (set_attr "modrm" "1")
6472 (set_attr "mode" "QI")])
6473
6474 (define_insn "*addqi_ext_2"
6475 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6476 (const_int 8)
6477 (const_int 8))
6478 (plus:SI
6479 (zero_extract:SI
6480 (match_operand 1 "ext_register_operand" "%0")
6481 (const_int 8)
6482 (const_int 8))
6483 (zero_extract:SI
6484 (match_operand 2 "ext_register_operand" "Q")
6485 (const_int 8)
6486 (const_int 8))))
6487 (clobber (reg:CC FLAGS_REG))]
6488 ""
6489 "add{b}\t{%h2, %h0|%h0, %h2}"
6490 [(set_attr "type" "alu")
6491 (set_attr "mode" "QI")])
6492
6493 ;; The lea patterns for non-Pmodes needs to be matched by
6494 ;; several insns converted to real lea by splitters.
6495
6496 (define_insn_and_split "*lea_general_1"
6497 [(set (match_operand 0 "register_operand" "=r")
6498 (plus (plus (match_operand 1 "index_register_operand" "l")
6499 (match_operand 2 "register_operand" "r"))
6500 (match_operand 3 "immediate_operand" "i")))]
6501 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6502 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6503 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6504 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6505 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6506 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6507 || GET_MODE (operands[3]) == VOIDmode)"
6508 "#"
6509 "&& reload_completed"
6510 [(const_int 0)]
6511 {
6512 rtx pat;
6513 operands[0] = gen_lowpart (SImode, operands[0]);
6514 operands[1] = gen_lowpart (Pmode, operands[1]);
6515 operands[2] = gen_lowpart (Pmode, operands[2]);
6516 operands[3] = gen_lowpart (Pmode, operands[3]);
6517 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6518 operands[3]);
6519 if (Pmode != SImode)
6520 pat = gen_rtx_SUBREG (SImode, pat, 0);
6521 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6522 DONE;
6523 }
6524 [(set_attr "type" "lea")
6525 (set_attr "mode" "SI")])
6526
6527 (define_insn_and_split "*lea_general_1_zext"
6528 [(set (match_operand:DI 0 "register_operand" "=r")
6529 (zero_extend:DI
6530 (plus:SI (plus:SI
6531 (match_operand:SI 1 "index_register_operand" "l")
6532 (match_operand:SI 2 "register_operand" "r"))
6533 (match_operand:SI 3 "immediate_operand" "i"))))]
6534 "TARGET_64BIT"
6535 "#"
6536 "&& reload_completed"
6537 [(set (match_dup 0)
6538 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6539 (match_dup 2))
6540 (match_dup 3)) 0)))]
6541 {
6542 operands[1] = gen_lowpart (Pmode, operands[1]);
6543 operands[2] = gen_lowpart (Pmode, operands[2]);
6544 operands[3] = gen_lowpart (Pmode, operands[3]);
6545 }
6546 [(set_attr "type" "lea")
6547 (set_attr "mode" "SI")])
6548
6549 (define_insn_and_split "*lea_general_2"
6550 [(set (match_operand 0 "register_operand" "=r")
6551 (plus (mult (match_operand 1 "index_register_operand" "l")
6552 (match_operand 2 "const248_operand" "i"))
6553 (match_operand 3 "nonmemory_operand" "ri")))]
6554 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6555 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6556 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6557 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6558 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6559 || GET_MODE (operands[3]) == VOIDmode)"
6560 "#"
6561 "&& reload_completed"
6562 [(const_int 0)]
6563 {
6564 rtx pat;
6565 operands[0] = gen_lowpart (SImode, operands[0]);
6566 operands[1] = gen_lowpart (Pmode, operands[1]);
6567 operands[3] = gen_lowpart (Pmode, operands[3]);
6568 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6569 operands[3]);
6570 if (Pmode != SImode)
6571 pat = gen_rtx_SUBREG (SImode, pat, 0);
6572 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6573 DONE;
6574 }
6575 [(set_attr "type" "lea")
6576 (set_attr "mode" "SI")])
6577
6578 (define_insn_and_split "*lea_general_2_zext"
6579 [(set (match_operand:DI 0 "register_operand" "=r")
6580 (zero_extend:DI
6581 (plus:SI (mult:SI
6582 (match_operand:SI 1 "index_register_operand" "l")
6583 (match_operand:SI 2 "const248_operand" "n"))
6584 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6585 "TARGET_64BIT"
6586 "#"
6587 "&& reload_completed"
6588 [(set (match_dup 0)
6589 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6590 (match_dup 2))
6591 (match_dup 3)) 0)))]
6592 {
6593 operands[1] = gen_lowpart (Pmode, operands[1]);
6594 operands[3] = gen_lowpart (Pmode, operands[3]);
6595 }
6596 [(set_attr "type" "lea")
6597 (set_attr "mode" "SI")])
6598
6599 (define_insn_and_split "*lea_general_3"
6600 [(set (match_operand 0 "register_operand" "=r")
6601 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6602 (match_operand 2 "const248_operand" "i"))
6603 (match_operand 3 "register_operand" "r"))
6604 (match_operand 4 "immediate_operand" "i")))]
6605 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6606 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6607 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6608 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6609 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6610 "#"
6611 "&& reload_completed"
6612 [(const_int 0)]
6613 {
6614 rtx pat;
6615 operands[0] = gen_lowpart (SImode, operands[0]);
6616 operands[1] = gen_lowpart (Pmode, operands[1]);
6617 operands[3] = gen_lowpart (Pmode, operands[3]);
6618 operands[4] = gen_lowpart (Pmode, operands[4]);
6619 pat = gen_rtx_PLUS (Pmode,
6620 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6621 operands[2]),
6622 operands[3]),
6623 operands[4]);
6624 if (Pmode != SImode)
6625 pat = gen_rtx_SUBREG (SImode, pat, 0);
6626 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6627 DONE;
6628 }
6629 [(set_attr "type" "lea")
6630 (set_attr "mode" "SI")])
6631
6632 (define_insn_and_split "*lea_general_3_zext"
6633 [(set (match_operand:DI 0 "register_operand" "=r")
6634 (zero_extend:DI
6635 (plus:SI (plus:SI
6636 (mult:SI
6637 (match_operand:SI 1 "index_register_operand" "l")
6638 (match_operand:SI 2 "const248_operand" "n"))
6639 (match_operand:SI 3 "register_operand" "r"))
6640 (match_operand:SI 4 "immediate_operand" "i"))))]
6641 "TARGET_64BIT"
6642 "#"
6643 "&& reload_completed"
6644 [(set (match_dup 0)
6645 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6646 (match_dup 2))
6647 (match_dup 3))
6648 (match_dup 4)) 0)))]
6649 {
6650 operands[1] = gen_lowpart (Pmode, operands[1]);
6651 operands[3] = gen_lowpart (Pmode, operands[3]);
6652 operands[4] = gen_lowpart (Pmode, operands[4]);
6653 }
6654 [(set_attr "type" "lea")
6655 (set_attr "mode" "SI")])
6656
6657 ;; Convert lea to the lea pattern to avoid flags dependency.
6658 (define_split
6659 [(set (match_operand:DI 0 "register_operand" "")
6660 (plus:DI (match_operand:DI 1 "register_operand" "")
6661 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6662 (clobber (reg:CC FLAGS_REG))]
6663 "TARGET_64BIT && reload_completed
6664 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6665 [(set (match_dup 0)
6666 (plus:DI (match_dup 1)
6667 (match_dup 2)))]
6668 "")
6669
6670 ;; Convert lea to the lea pattern to avoid flags dependency.
6671 (define_split
6672 [(set (match_operand 0 "register_operand" "")
6673 (plus (match_operand 1 "register_operand" "")
6674 (match_operand 2 "nonmemory_operand" "")))
6675 (clobber (reg:CC FLAGS_REG))]
6676 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6677 [(const_int 0)]
6678 {
6679 rtx pat;
6680 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6681 may confuse gen_lowpart. */
6682 if (GET_MODE (operands[0]) != Pmode)
6683 {
6684 operands[1] = gen_lowpart (Pmode, operands[1]);
6685 operands[2] = gen_lowpart (Pmode, operands[2]);
6686 }
6687 operands[0] = gen_lowpart (SImode, operands[0]);
6688 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6689 if (Pmode != SImode)
6690 pat = gen_rtx_SUBREG (SImode, pat, 0);
6691 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6692 DONE;
6693 })
6694
6695 ;; Convert lea to the lea pattern to avoid flags dependency.
6696 (define_split
6697 [(set (match_operand:DI 0 "register_operand" "")
6698 (zero_extend:DI
6699 (plus:SI (match_operand:SI 1 "register_operand" "")
6700 (match_operand:SI 2 "nonmemory_operand" ""))))
6701 (clobber (reg:CC FLAGS_REG))]
6702 "TARGET_64BIT && reload_completed
6703 && true_regnum (operands[0]) != true_regnum (operands[1])"
6704 [(set (match_dup 0)
6705 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6706 {
6707 operands[1] = gen_lowpart (Pmode, operands[1]);
6708 operands[2] = gen_lowpart (Pmode, operands[2]);
6709 })
6710 \f
6711 ;; Subtract instructions
6712
6713 (define_expand "sub<mode>3"
6714 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6715 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6716 (match_operand:SDWIM 2 "<general_operand>" "")))]
6717 ""
6718 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6719
6720 (define_insn_and_split "*sub<dwi>3_doubleword"
6721 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6722 (minus:<DWI>
6723 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6724 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6725 (clobber (reg:CC FLAGS_REG))]
6726 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6727 "#"
6728 "reload_completed"
6729 [(parallel [(set (reg:CC FLAGS_REG)
6730 (compare:CC (match_dup 1) (match_dup 2)))
6731 (set (match_dup 0)
6732 (minus:DWIH (match_dup 1) (match_dup 2)))])
6733 (parallel [(set (match_dup 3)
6734 (minus:DWIH
6735 (match_dup 4)
6736 (plus:DWIH
6737 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6738 (match_dup 5))))
6739 (clobber (reg:CC FLAGS_REG))])]
6740 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6741
6742 (define_insn "*sub<mode>_1"
6743 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6744 (minus:SWI
6745 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6746 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6747 (clobber (reg:CC FLAGS_REG))]
6748 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6749 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6750 [(set_attr "type" "alu")
6751 (set_attr "mode" "<MODE>")])
6752
6753 (define_insn "*subsi_1_zext"
6754 [(set (match_operand:DI 0 "register_operand" "=r")
6755 (zero_extend:DI
6756 (minus:SI (match_operand:SI 1 "register_operand" "0")
6757 (match_operand:SI 2 "general_operand" "g"))))
6758 (clobber (reg:CC FLAGS_REG))]
6759 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6760 "sub{l}\t{%2, %k0|%k0, %2}"
6761 [(set_attr "type" "alu")
6762 (set_attr "mode" "SI")])
6763
6764 (define_insn "*subqi_1_slp"
6765 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6766 (minus:QI (match_dup 0)
6767 (match_operand:QI 1 "general_operand" "qn,qm")))
6768 (clobber (reg:CC FLAGS_REG))]
6769 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6771 "sub{b}\t{%1, %0|%0, %1}"
6772 [(set_attr "type" "alu1")
6773 (set_attr "mode" "QI")])
6774
6775 (define_insn "*sub<mode>_2"
6776 [(set (reg FLAGS_REG)
6777 (compare
6778 (minus:SWI
6779 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6780 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6781 (const_int 0)))
6782 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6783 (minus:SWI (match_dup 1) (match_dup 2)))]
6784 "ix86_match_ccmode (insn, CCGOCmode)
6785 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6786 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6787 [(set_attr "type" "alu")
6788 (set_attr "mode" "<MODE>")])
6789
6790 (define_insn "*subsi_2_zext"
6791 [(set (reg FLAGS_REG)
6792 (compare
6793 (minus:SI (match_operand:SI 1 "register_operand" "0")
6794 (match_operand:SI 2 "general_operand" "g"))
6795 (const_int 0)))
6796 (set (match_operand:DI 0 "register_operand" "=r")
6797 (zero_extend:DI
6798 (minus:SI (match_dup 1)
6799 (match_dup 2))))]
6800 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6801 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6802 "sub{l}\t{%2, %k0|%k0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "SI")])
6805
6806 (define_insn "*sub<mode>_3"
6807 [(set (reg FLAGS_REG)
6808 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6809 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6810 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6811 (minus:SWI (match_dup 1) (match_dup 2)))]
6812 "ix86_match_ccmode (insn, CCmode)
6813 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6814 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6815 [(set_attr "type" "alu")
6816 (set_attr "mode" "<MODE>")])
6817
6818 (define_insn "*subsi_3_zext"
6819 [(set (reg FLAGS_REG)
6820 (compare (match_operand:SI 1 "register_operand" "0")
6821 (match_operand:SI 2 "general_operand" "g")))
6822 (set (match_operand:DI 0 "register_operand" "=r")
6823 (zero_extend:DI
6824 (minus:SI (match_dup 1)
6825 (match_dup 2))))]
6826 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6827 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6828 "sub{l}\t{%2, %1|%1, %2}"
6829 [(set_attr "type" "alu")
6830 (set_attr "mode" "SI")])
6831 \f
6832 ;; Add with carry and subtract with borrow
6833
6834 (define_expand "<plusminus_insn><mode>3_carry"
6835 [(parallel
6836 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6837 (plusminus:SWI
6838 (match_operand:SWI 1 "nonimmediate_operand" "")
6839 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6840 [(match_operand 3 "flags_reg_operand" "")
6841 (const_int 0)])
6842 (match_operand:SWI 2 "<general_operand>" ""))))
6843 (clobber (reg:CC FLAGS_REG))])]
6844 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6845 "")
6846
6847 (define_insn "*<plusminus_insn><mode>3_carry"
6848 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6849 (plusminus:SWI
6850 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6851 (plus:SWI
6852 (match_operator 3 "ix86_carry_flag_operator"
6853 [(reg FLAGS_REG) (const_int 0)])
6854 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6855 (clobber (reg:CC FLAGS_REG))]
6856 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6857 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6858 [(set_attr "type" "alu")
6859 (set_attr "use_carry" "1")
6860 (set_attr "pent_pair" "pu")
6861 (set_attr "mode" "<MODE>")])
6862
6863 (define_insn "*addsi3_carry_zext"
6864 [(set (match_operand:DI 0 "register_operand" "=r")
6865 (zero_extend:DI
6866 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6867 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6868 [(reg FLAGS_REG) (const_int 0)])
6869 (match_operand:SI 2 "general_operand" "g")))))
6870 (clobber (reg:CC FLAGS_REG))]
6871 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6872 "adc{l}\t{%2, %k0|%k0, %2}"
6873 [(set_attr "type" "alu")
6874 (set_attr "use_carry" "1")
6875 (set_attr "pent_pair" "pu")
6876 (set_attr "mode" "SI")])
6877
6878 (define_insn "*subsi3_carry_zext"
6879 [(set (match_operand:DI 0 "register_operand" "=r")
6880 (zero_extend:DI
6881 (minus:SI (match_operand:SI 1 "register_operand" "0")
6882 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6883 [(reg FLAGS_REG) (const_int 0)])
6884 (match_operand:SI 2 "general_operand" "g")))))
6885 (clobber (reg:CC FLAGS_REG))]
6886 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6887 "sbb{l}\t{%2, %k0|%k0, %2}"
6888 [(set_attr "type" "alu")
6889 (set_attr "pent_pair" "pu")
6890 (set_attr "mode" "SI")])
6891 \f
6892 ;; Overflow setting add and subtract instructions
6893
6894 (define_insn "*add<mode>3_cconly_overflow"
6895 [(set (reg:CCC FLAGS_REG)
6896 (compare:CCC
6897 (plus:SWI
6898 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6899 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6900 (match_dup 1)))
6901 (clobber (match_scratch:SWI 0 "=<r>"))]
6902 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6903 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6904 [(set_attr "type" "alu")
6905 (set_attr "mode" "<MODE>")])
6906
6907 (define_insn "*sub<mode>3_cconly_overflow"
6908 [(set (reg:CCC FLAGS_REG)
6909 (compare:CCC
6910 (minus:SWI
6911 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6912 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6913 (match_dup 0)))]
6914 ""
6915 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6916 [(set_attr "type" "icmp")
6917 (set_attr "mode" "<MODE>")])
6918
6919 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6920 [(set (reg:CCC FLAGS_REG)
6921 (compare:CCC
6922 (plusminus:SWI
6923 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6924 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6925 (match_dup 1)))
6926 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6927 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6928 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6929 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "alu")
6931 (set_attr "mode" "<MODE>")])
6932
6933 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6934 [(set (reg:CCC FLAGS_REG)
6935 (compare:CCC
6936 (plusminus:SI
6937 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6938 (match_operand:SI 2 "general_operand" "g"))
6939 (match_dup 1)))
6940 (set (match_operand:DI 0 "register_operand" "=r")
6941 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6942 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6943 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6944 [(set_attr "type" "alu")
6945 (set_attr "mode" "SI")])
6946
6947 ;; The patterns that match these are at the end of this file.
6948
6949 (define_expand "<plusminus_insn>xf3"
6950 [(set (match_operand:XF 0 "register_operand" "")
6951 (plusminus:XF
6952 (match_operand:XF 1 "register_operand" "")
6953 (match_operand:XF 2 "register_operand" "")))]
6954 "TARGET_80387"
6955 "")
6956
6957 (define_expand "<plusminus_insn><mode>3"
6958 [(set (match_operand:MODEF 0 "register_operand" "")
6959 (plusminus:MODEF
6960 (match_operand:MODEF 1 "register_operand" "")
6961 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6962 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6963 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6964 "")
6965 \f
6966 ;; Multiply instructions
6967
6968 (define_expand "mul<mode>3"
6969 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6970 (mult:SWIM248
6971 (match_operand:SWIM248 1 "register_operand" "")
6972 (match_operand:SWIM248 2 "<general_operand>" "")))
6973 (clobber (reg:CC FLAGS_REG))])]
6974 ""
6975 "")
6976
6977 (define_expand "mulqi3"
6978 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6979 (mult:QI
6980 (match_operand:QI 1 "register_operand" "")
6981 (match_operand:QI 2 "nonimmediate_operand" "")))
6982 (clobber (reg:CC FLAGS_REG))])]
6983 "TARGET_QIMODE_MATH"
6984 "")
6985
6986 ;; On AMDFAM10
6987 ;; IMUL reg32/64, reg32/64, imm8 Direct
6988 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6989 ;; IMUL reg32/64, reg32/64, imm32 Direct
6990 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6991 ;; IMUL reg32/64, reg32/64 Direct
6992 ;; IMUL reg32/64, mem32/64 Direct
6993
6994 (define_insn "*mul<mode>3_1"
6995 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6996 (mult:SWI48
6997 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6998 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6999 (clobber (reg:CC FLAGS_REG))]
7000 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7001 "@
7002 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7003 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7004 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7005 [(set_attr "type" "imul")
7006 (set_attr "prefix_0f" "0,0,1")
7007 (set (attr "athlon_decode")
7008 (cond [(eq_attr "cpu" "athlon")
7009 (const_string "vector")
7010 (eq_attr "alternative" "1")
7011 (const_string "vector")
7012 (and (eq_attr "alternative" "2")
7013 (match_operand 1 "memory_operand" ""))
7014 (const_string "vector")]
7015 (const_string "direct")))
7016 (set (attr "amdfam10_decode")
7017 (cond [(and (eq_attr "alternative" "0,1")
7018 (match_operand 1 "memory_operand" ""))
7019 (const_string "vector")]
7020 (const_string "direct")))
7021 (set_attr "mode" "<MODE>")])
7022
7023 (define_insn "*mulsi3_1_zext"
7024 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7025 (zero_extend:DI
7026 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7027 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7028 (clobber (reg:CC FLAGS_REG))]
7029 "TARGET_64BIT
7030 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7031 "@
7032 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7033 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7034 imul{l}\t{%2, %k0|%k0, %2}"
7035 [(set_attr "type" "imul")
7036 (set_attr "prefix_0f" "0,0,1")
7037 (set (attr "athlon_decode")
7038 (cond [(eq_attr "cpu" "athlon")
7039 (const_string "vector")
7040 (eq_attr "alternative" "1")
7041 (const_string "vector")
7042 (and (eq_attr "alternative" "2")
7043 (match_operand 1 "memory_operand" ""))
7044 (const_string "vector")]
7045 (const_string "direct")))
7046 (set (attr "amdfam10_decode")
7047 (cond [(and (eq_attr "alternative" "0,1")
7048 (match_operand 1 "memory_operand" ""))
7049 (const_string "vector")]
7050 (const_string "direct")))
7051 (set_attr "mode" "SI")])
7052
7053 ;; On AMDFAM10
7054 ;; IMUL reg16, reg16, imm8 VectorPath
7055 ;; IMUL reg16, mem16, imm8 VectorPath
7056 ;; IMUL reg16, reg16, imm16 VectorPath
7057 ;; IMUL reg16, mem16, imm16 VectorPath
7058 ;; IMUL reg16, reg16 Direct
7059 ;; IMUL reg16, mem16 Direct
7060
7061 (define_insn "*mulhi3_1"
7062 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7063 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7064 (match_operand:HI 2 "general_operand" "K,n,mr")))
7065 (clobber (reg:CC FLAGS_REG))]
7066 "TARGET_HIMODE_MATH
7067 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7068 "@
7069 imul{w}\t{%2, %1, %0|%0, %1, %2}
7070 imul{w}\t{%2, %1, %0|%0, %1, %2}
7071 imul{w}\t{%2, %0|%0, %2}"
7072 [(set_attr "type" "imul")
7073 (set_attr "prefix_0f" "0,0,1")
7074 (set (attr "athlon_decode")
7075 (cond [(eq_attr "cpu" "athlon")
7076 (const_string "vector")
7077 (eq_attr "alternative" "1,2")
7078 (const_string "vector")]
7079 (const_string "direct")))
7080 (set (attr "amdfam10_decode")
7081 (cond [(eq_attr "alternative" "0,1")
7082 (const_string "vector")]
7083 (const_string "direct")))
7084 (set_attr "mode" "HI")])
7085
7086 ;;On AMDFAM10
7087 ;; MUL reg8 Direct
7088 ;; MUL mem8 Direct
7089
7090 (define_insn "*mulqi3_1"
7091 [(set (match_operand:QI 0 "register_operand" "=a")
7092 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7093 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7094 (clobber (reg:CC FLAGS_REG))]
7095 "TARGET_QIMODE_MATH
7096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7097 "mul{b}\t%2"
7098 [(set_attr "type" "imul")
7099 (set_attr "length_immediate" "0")
7100 (set (attr "athlon_decode")
7101 (if_then_else (eq_attr "cpu" "athlon")
7102 (const_string "vector")
7103 (const_string "direct")))
7104 (set_attr "amdfam10_decode" "direct")
7105 (set_attr "mode" "QI")])
7106
7107 (define_expand "<u>mul<mode><dwi>3"
7108 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7109 (mult:<DWI>
7110 (any_extend:<DWI>
7111 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7112 (any_extend:<DWI>
7113 (match_operand:DWIH 2 "register_operand" ""))))
7114 (clobber (reg:CC FLAGS_REG))])]
7115 ""
7116 "")
7117
7118 (define_expand "<u>mulqihi3"
7119 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7120 (mult:HI
7121 (any_extend:HI
7122 (match_operand:QI 1 "nonimmediate_operand" ""))
7123 (any_extend:HI
7124 (match_operand:QI 2 "register_operand" ""))))
7125 (clobber (reg:CC FLAGS_REG))])]
7126 "TARGET_QIMODE_MATH"
7127 "")
7128
7129 (define_insn "*<u>mul<mode><dwi>3_1"
7130 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7131 (mult:<DWI>
7132 (any_extend:<DWI>
7133 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7134 (any_extend:<DWI>
7135 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7136 (clobber (reg:CC FLAGS_REG))]
7137 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7138 "<sgnprefix>mul{<imodesuffix>}\t%2"
7139 [(set_attr "type" "imul")
7140 (set_attr "length_immediate" "0")
7141 (set (attr "athlon_decode")
7142 (if_then_else (eq_attr "cpu" "athlon")
7143 (const_string "vector")
7144 (const_string "double")))
7145 (set_attr "amdfam10_decode" "double")
7146 (set_attr "mode" "<MODE>")])
7147
7148 (define_insn "*<u>mulqihi3_1"
7149 [(set (match_operand:HI 0 "register_operand" "=a")
7150 (mult:HI
7151 (any_extend:HI
7152 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7153 (any_extend:HI
7154 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7155 (clobber (reg:CC FLAGS_REG))]
7156 "TARGET_QIMODE_MATH
7157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7158 "<sgnprefix>mul{b}\t%2"
7159 [(set_attr "type" "imul")
7160 (set_attr "length_immediate" "0")
7161 (set (attr "athlon_decode")
7162 (if_then_else (eq_attr "cpu" "athlon")
7163 (const_string "vector")
7164 (const_string "direct")))
7165 (set_attr "amdfam10_decode" "direct")
7166 (set_attr "mode" "QI")])
7167
7168 (define_expand "<s>mul<mode>3_highpart"
7169 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7170 (truncate:SWI48
7171 (lshiftrt:<DWI>
7172 (mult:<DWI>
7173 (any_extend:<DWI>
7174 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7175 (any_extend:<DWI>
7176 (match_operand:SWI48 2 "register_operand" "")))
7177 (match_dup 4))))
7178 (clobber (match_scratch:SWI48 3 ""))
7179 (clobber (reg:CC FLAGS_REG))])]
7180 ""
7181 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7182
7183 (define_insn "*<s>muldi3_highpart_1"
7184 [(set (match_operand:DI 0 "register_operand" "=d")
7185 (truncate:DI
7186 (lshiftrt:TI
7187 (mult:TI
7188 (any_extend:TI
7189 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7190 (any_extend:TI
7191 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7192 (const_int 64))))
7193 (clobber (match_scratch:DI 3 "=1"))
7194 (clobber (reg:CC FLAGS_REG))]
7195 "TARGET_64BIT
7196 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7197 "<sgnprefix>mul{q}\t%2"
7198 [(set_attr "type" "imul")
7199 (set_attr "length_immediate" "0")
7200 (set (attr "athlon_decode")
7201 (if_then_else (eq_attr "cpu" "athlon")
7202 (const_string "vector")
7203 (const_string "double")))
7204 (set_attr "amdfam10_decode" "double")
7205 (set_attr "mode" "DI")])
7206
7207 (define_insn "*<s>mulsi3_highpart_1"
7208 [(set (match_operand:SI 0 "register_operand" "=d")
7209 (truncate:SI
7210 (lshiftrt:DI
7211 (mult:DI
7212 (any_extend:DI
7213 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7214 (any_extend:DI
7215 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7216 (const_int 32))))
7217 (clobber (match_scratch:SI 3 "=1"))
7218 (clobber (reg:CC FLAGS_REG))]
7219 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7220 "<sgnprefix>mul{l}\t%2"
7221 [(set_attr "type" "imul")
7222 (set_attr "length_immediate" "0")
7223 (set (attr "athlon_decode")
7224 (if_then_else (eq_attr "cpu" "athlon")
7225 (const_string "vector")
7226 (const_string "double")))
7227 (set_attr "amdfam10_decode" "double")
7228 (set_attr "mode" "SI")])
7229
7230 (define_insn "*<s>mulsi3_highpart_zext"
7231 [(set (match_operand:DI 0 "register_operand" "=d")
7232 (zero_extend:DI (truncate:SI
7233 (lshiftrt:DI
7234 (mult:DI (any_extend:DI
7235 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7236 (any_extend:DI
7237 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7238 (const_int 32)))))
7239 (clobber (match_scratch:SI 3 "=1"))
7240 (clobber (reg:CC FLAGS_REG))]
7241 "TARGET_64BIT
7242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7243 "<sgnprefix>mul{l}\t%2"
7244 [(set_attr "type" "imul")
7245 (set_attr "length_immediate" "0")
7246 (set (attr "athlon_decode")
7247 (if_then_else (eq_attr "cpu" "athlon")
7248 (const_string "vector")
7249 (const_string "double")))
7250 (set_attr "amdfam10_decode" "double")
7251 (set_attr "mode" "SI")])
7252
7253 ;; The patterns that match these are at the end of this file.
7254
7255 (define_expand "mulxf3"
7256 [(set (match_operand:XF 0 "register_operand" "")
7257 (mult:XF (match_operand:XF 1 "register_operand" "")
7258 (match_operand:XF 2 "register_operand" "")))]
7259 "TARGET_80387"
7260 "")
7261
7262 (define_expand "mul<mode>3"
7263 [(set (match_operand:MODEF 0 "register_operand" "")
7264 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7265 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7266 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7267 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7268 "")
7269 \f
7270 ;; Divide instructions
7271
7272 (define_insn "<u>divqi3"
7273 [(set (match_operand:QI 0 "register_operand" "=a")
7274 (any_div:QI
7275 (match_operand:HI 1 "register_operand" "0")
7276 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7277 (clobber (reg:CC FLAGS_REG))]
7278 "TARGET_QIMODE_MATH"
7279 "<sgnprefix>div{b}\t%2"
7280 [(set_attr "type" "idiv")
7281 (set_attr "mode" "QI")])
7282
7283 ;; The patterns that match these are at the end of this file.
7284
7285 (define_expand "divxf3"
7286 [(set (match_operand:XF 0 "register_operand" "")
7287 (div:XF (match_operand:XF 1 "register_operand" "")
7288 (match_operand:XF 2 "register_operand" "")))]
7289 "TARGET_80387"
7290 "")
7291
7292 (define_expand "divdf3"
7293 [(set (match_operand:DF 0 "register_operand" "")
7294 (div:DF (match_operand:DF 1 "register_operand" "")
7295 (match_operand:DF 2 "nonimmediate_operand" "")))]
7296 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7297 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7298 "")
7299
7300 (define_expand "divsf3"
7301 [(set (match_operand:SF 0 "register_operand" "")
7302 (div:SF (match_operand:SF 1 "register_operand" "")
7303 (match_operand:SF 2 "nonimmediate_operand" "")))]
7304 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7305 || TARGET_SSE_MATH"
7306 {
7307 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7308 && flag_finite_math_only && !flag_trapping_math
7309 && flag_unsafe_math_optimizations)
7310 {
7311 ix86_emit_swdivsf (operands[0], operands[1],
7312 operands[2], SFmode);
7313 DONE;
7314 }
7315 })
7316 \f
7317 ;; Divmod instructions.
7318
7319 (define_expand "divmod<mode>4"
7320 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7321 (div:SWIM248
7322 (match_operand:SWIM248 1 "register_operand" "")
7323 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7324 (set (match_operand:SWIM248 3 "register_operand" "")
7325 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7326 (clobber (reg:CC FLAGS_REG))])]
7327 ""
7328 "")
7329
7330 (define_insn_and_split "*divmod<mode>4"
7331 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7332 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7333 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7334 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7335 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7336 (clobber (reg:CC FLAGS_REG))]
7337 ""
7338 "#"
7339 "reload_completed"
7340 [(parallel [(set (match_dup 1)
7341 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7342 (clobber (reg:CC FLAGS_REG))])
7343 (parallel [(set (match_dup 0)
7344 (div:SWIM248 (match_dup 2) (match_dup 3)))
7345 (set (match_dup 1)
7346 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7347 (use (match_dup 1))
7348 (clobber (reg:CC FLAGS_REG))])]
7349 {
7350 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7351
7352 if (<MODE>mode != HImode
7353 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7354 operands[4] = operands[2];
7355 else
7356 {
7357 /* Avoid use of cltd in favor of a mov+shift. */
7358 emit_move_insn (operands[1], operands[2]);
7359 operands[4] = operands[1];
7360 }
7361 }
7362 [(set_attr "type" "multi")
7363 (set_attr "mode" "<MODE>")])
7364
7365 (define_insn "*divmod<mode>4_noext"
7366 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7367 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7368 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7369 (set (match_operand:SWIM248 1 "register_operand" "=d")
7370 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7371 (use (match_operand:SWIM248 4 "register_operand" "1"))
7372 (clobber (reg:CC FLAGS_REG))]
7373 ""
7374 "idiv{<imodesuffix>}\t%3"
7375 [(set_attr "type" "idiv")
7376 (set_attr "mode" "<MODE>")])
7377
7378 (define_expand "udivmod<mode>4"
7379 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7380 (udiv:SWIM248
7381 (match_operand:SWIM248 1 "register_operand" "")
7382 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7383 (set (match_operand:SWIM248 3 "register_operand" "")
7384 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7385 (clobber (reg:CC FLAGS_REG))])]
7386 ""
7387 "")
7388
7389 (define_insn_and_split "*udivmod<mode>4"
7390 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7391 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7392 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7393 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7394 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7395 (clobber (reg:CC FLAGS_REG))]
7396 ""
7397 "#"
7398 "reload_completed"
7399 [(set (match_dup 1) (const_int 0))
7400 (parallel [(set (match_dup 0)
7401 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7402 (set (match_dup 1)
7403 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7404 (use (match_dup 1))
7405 (clobber (reg:CC FLAGS_REG))])]
7406 ""
7407 [(set_attr "type" "multi")
7408 (set_attr "mode" "<MODE>")])
7409
7410 (define_insn "*udivmod<mode>4_noext"
7411 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7412 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7413 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7414 (set (match_operand:SWIM248 1 "register_operand" "=d")
7415 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7416 (use (match_operand:SWIM248 4 "register_operand" "1"))
7417 (clobber (reg:CC FLAGS_REG))]
7418 ""
7419 "div{<imodesuffix>}\t%3"
7420 [(set_attr "type" "idiv")
7421 (set_attr "mode" "<MODE>")])
7422
7423 ;; We cannot use div/idiv for double division, because it causes
7424 ;; "division by zero" on the overflow and that's not what we expect
7425 ;; from truncate. Because true (non truncating) double division is
7426 ;; never generated, we can't create this insn anyway.
7427 ;
7428 ;(define_insn ""
7429 ; [(set (match_operand:SI 0 "register_operand" "=a")
7430 ; (truncate:SI
7431 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7432 ; (zero_extend:DI
7433 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7434 ; (set (match_operand:SI 3 "register_operand" "=d")
7435 ; (truncate:SI
7436 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7437 ; (clobber (reg:CC FLAGS_REG))]
7438 ; ""
7439 ; "div{l}\t{%2, %0|%0, %2}"
7440 ; [(set_attr "type" "idiv")])
7441 \f
7442 ;;- Logical AND instructions
7443
7444 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7445 ;; Note that this excludes ah.
7446
7447 (define_expand "testsi_ccno_1"
7448 [(set (reg:CCNO FLAGS_REG)
7449 (compare:CCNO
7450 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7451 (match_operand:SI 1 "nonmemory_operand" ""))
7452 (const_int 0)))]
7453 ""
7454 "")
7455
7456 (define_expand "testqi_ccz_1"
7457 [(set (reg:CCZ FLAGS_REG)
7458 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7459 (match_operand:QI 1 "nonmemory_operand" ""))
7460 (const_int 0)))]
7461 ""
7462 "")
7463
7464 (define_insn "*testdi_1"
7465 [(set (reg FLAGS_REG)
7466 (compare
7467 (and:DI
7468 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7469 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7470 (const_int 0)))]
7471 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7472 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7473 "@
7474 test{l}\t{%k1, %k0|%k0, %k1}
7475 test{l}\t{%k1, %k0|%k0, %k1}
7476 test{q}\t{%1, %0|%0, %1}
7477 test{q}\t{%1, %0|%0, %1}
7478 test{q}\t{%1, %0|%0, %1}"
7479 [(set_attr "type" "test")
7480 (set_attr "modrm" "0,1,0,1,1")
7481 (set_attr "mode" "SI,SI,DI,DI,DI")])
7482
7483 (define_insn "*testqi_1_maybe_si"
7484 [(set (reg FLAGS_REG)
7485 (compare
7486 (and:QI
7487 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7488 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7489 (const_int 0)))]
7490 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7491 && ix86_match_ccmode (insn,
7492 CONST_INT_P (operands[1])
7493 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7494 {
7495 if (which_alternative == 3)
7496 {
7497 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7498 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7499 return "test{l}\t{%1, %k0|%k0, %1}";
7500 }
7501 return "test{b}\t{%1, %0|%0, %1}";
7502 }
7503 [(set_attr "type" "test")
7504 (set_attr "modrm" "0,1,1,1")
7505 (set_attr "mode" "QI,QI,QI,SI")
7506 (set_attr "pent_pair" "uv,np,uv,np")])
7507
7508 (define_insn "*test<mode>_1"
7509 [(set (reg FLAGS_REG)
7510 (compare
7511 (and:SWI124
7512 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7513 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7514 (const_int 0)))]
7515 "ix86_match_ccmode (insn, CCNOmode)
7516 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7517 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7518 [(set_attr "type" "test")
7519 (set_attr "modrm" "0,1,1")
7520 (set_attr "mode" "<MODE>")
7521 (set_attr "pent_pair" "uv,np,uv")])
7522
7523 (define_expand "testqi_ext_ccno_0"
7524 [(set (reg:CCNO FLAGS_REG)
7525 (compare:CCNO
7526 (and:SI
7527 (zero_extract:SI
7528 (match_operand 0 "ext_register_operand" "")
7529 (const_int 8)
7530 (const_int 8))
7531 (match_operand 1 "const_int_operand" ""))
7532 (const_int 0)))]
7533 ""
7534 "")
7535
7536 (define_insn "*testqi_ext_0"
7537 [(set (reg FLAGS_REG)
7538 (compare
7539 (and:SI
7540 (zero_extract:SI
7541 (match_operand 0 "ext_register_operand" "Q")
7542 (const_int 8)
7543 (const_int 8))
7544 (match_operand 1 "const_int_operand" "n"))
7545 (const_int 0)))]
7546 "ix86_match_ccmode (insn, CCNOmode)"
7547 "test{b}\t{%1, %h0|%h0, %1}"
7548 [(set_attr "type" "test")
7549 (set_attr "mode" "QI")
7550 (set_attr "length_immediate" "1")
7551 (set_attr "modrm" "1")
7552 (set_attr "pent_pair" "np")])
7553
7554 (define_insn "*testqi_ext_1_rex64"
7555 [(set (reg FLAGS_REG)
7556 (compare
7557 (and:SI
7558 (zero_extract:SI
7559 (match_operand 0 "ext_register_operand" "Q")
7560 (const_int 8)
7561 (const_int 8))
7562 (zero_extend:SI
7563 (match_operand:QI 1 "register_operand" "Q")))
7564 (const_int 0)))]
7565 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7566 "test{b}\t{%1, %h0|%h0, %1}"
7567 [(set_attr "type" "test")
7568 (set_attr "mode" "QI")])
7569
7570 (define_insn "*testqi_ext_1"
7571 [(set (reg FLAGS_REG)
7572 (compare
7573 (and:SI
7574 (zero_extract:SI
7575 (match_operand 0 "ext_register_operand" "Q")
7576 (const_int 8)
7577 (const_int 8))
7578 (zero_extend:SI
7579 (match_operand:QI 1 "general_operand" "Qm")))
7580 (const_int 0)))]
7581 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7582 "test{b}\t{%1, %h0|%h0, %1}"
7583 [(set_attr "type" "test")
7584 (set_attr "mode" "QI")])
7585
7586 (define_insn "*testqi_ext_2"
7587 [(set (reg FLAGS_REG)
7588 (compare
7589 (and:SI
7590 (zero_extract:SI
7591 (match_operand 0 "ext_register_operand" "Q")
7592 (const_int 8)
7593 (const_int 8))
7594 (zero_extract:SI
7595 (match_operand 1 "ext_register_operand" "Q")
7596 (const_int 8)
7597 (const_int 8)))
7598 (const_int 0)))]
7599 "ix86_match_ccmode (insn, CCNOmode)"
7600 "test{b}\t{%h1, %h0|%h0, %h1}"
7601 [(set_attr "type" "test")
7602 (set_attr "mode" "QI")])
7603
7604 (define_insn "*testqi_ext_3_rex64"
7605 [(set (reg FLAGS_REG)
7606 (compare (zero_extract:DI
7607 (match_operand 0 "nonimmediate_operand" "rm")
7608 (match_operand:DI 1 "const_int_operand" "")
7609 (match_operand:DI 2 "const_int_operand" ""))
7610 (const_int 0)))]
7611 "TARGET_64BIT
7612 && ix86_match_ccmode (insn, CCNOmode)
7613 && INTVAL (operands[1]) > 0
7614 && INTVAL (operands[2]) >= 0
7615 /* Ensure that resulting mask is zero or sign extended operand. */
7616 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7617 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7618 && INTVAL (operands[1]) > 32))
7619 && (GET_MODE (operands[0]) == SImode
7620 || GET_MODE (operands[0]) == DImode
7621 || GET_MODE (operands[0]) == HImode
7622 || GET_MODE (operands[0]) == QImode)"
7623 "#")
7624
7625 ;; Combine likes to form bit extractions for some tests. Humor it.
7626 (define_insn "*testqi_ext_3"
7627 [(set (reg FLAGS_REG)
7628 (compare (zero_extract:SI
7629 (match_operand 0 "nonimmediate_operand" "rm")
7630 (match_operand:SI 1 "const_int_operand" "")
7631 (match_operand:SI 2 "const_int_operand" ""))
7632 (const_int 0)))]
7633 "ix86_match_ccmode (insn, CCNOmode)
7634 && INTVAL (operands[1]) > 0
7635 && INTVAL (operands[2]) >= 0
7636 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7637 && (GET_MODE (operands[0]) == SImode
7638 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7639 || GET_MODE (operands[0]) == HImode
7640 || GET_MODE (operands[0]) == QImode)"
7641 "#")
7642
7643 (define_split
7644 [(set (match_operand 0 "flags_reg_operand" "")
7645 (match_operator 1 "compare_operator"
7646 [(zero_extract
7647 (match_operand 2 "nonimmediate_operand" "")
7648 (match_operand 3 "const_int_operand" "")
7649 (match_operand 4 "const_int_operand" ""))
7650 (const_int 0)]))]
7651 "ix86_match_ccmode (insn, CCNOmode)"
7652 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7653 {
7654 rtx val = operands[2];
7655 HOST_WIDE_INT len = INTVAL (operands[3]);
7656 HOST_WIDE_INT pos = INTVAL (operands[4]);
7657 HOST_WIDE_INT mask;
7658 enum machine_mode mode, submode;
7659
7660 mode = GET_MODE (val);
7661 if (MEM_P (val))
7662 {
7663 /* ??? Combine likes to put non-volatile mem extractions in QImode
7664 no matter the size of the test. So find a mode that works. */
7665 if (! MEM_VOLATILE_P (val))
7666 {
7667 mode = smallest_mode_for_size (pos + len, MODE_INT);
7668 val = adjust_address (val, mode, 0);
7669 }
7670 }
7671 else if (GET_CODE (val) == SUBREG
7672 && (submode = GET_MODE (SUBREG_REG (val)),
7673 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7674 && pos + len <= GET_MODE_BITSIZE (submode)
7675 && GET_MODE_CLASS (submode) == MODE_INT)
7676 {
7677 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7678 mode = submode;
7679 val = SUBREG_REG (val);
7680 }
7681 else if (mode == HImode && pos + len <= 8)
7682 {
7683 /* Small HImode tests can be converted to QImode. */
7684 mode = QImode;
7685 val = gen_lowpart (QImode, val);
7686 }
7687
7688 if (len == HOST_BITS_PER_WIDE_INT)
7689 mask = -1;
7690 else
7691 mask = ((HOST_WIDE_INT)1 << len) - 1;
7692 mask <<= pos;
7693
7694 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7695 })
7696
7697 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7698 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7699 ;; this is relatively important trick.
7700 ;; Do the conversion only post-reload to avoid limiting of the register class
7701 ;; to QI regs.
7702 (define_split
7703 [(set (match_operand 0 "flags_reg_operand" "")
7704 (match_operator 1 "compare_operator"
7705 [(and (match_operand 2 "register_operand" "")
7706 (match_operand 3 "const_int_operand" ""))
7707 (const_int 0)]))]
7708 "reload_completed
7709 && QI_REG_P (operands[2])
7710 && GET_MODE (operands[2]) != QImode
7711 && ((ix86_match_ccmode (insn, CCZmode)
7712 && !(INTVAL (operands[3]) & ~(255 << 8)))
7713 || (ix86_match_ccmode (insn, CCNOmode)
7714 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7715 [(set (match_dup 0)
7716 (match_op_dup 1
7717 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7718 (match_dup 3))
7719 (const_int 0)]))]
7720 "operands[2] = gen_lowpart (SImode, operands[2]);
7721 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7722
7723 (define_split
7724 [(set (match_operand 0 "flags_reg_operand" "")
7725 (match_operator 1 "compare_operator"
7726 [(and (match_operand 2 "nonimmediate_operand" "")
7727 (match_operand 3 "const_int_operand" ""))
7728 (const_int 0)]))]
7729 "reload_completed
7730 && GET_MODE (operands[2]) != QImode
7731 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7732 && ((ix86_match_ccmode (insn, CCZmode)
7733 && !(INTVAL (operands[3]) & ~255))
7734 || (ix86_match_ccmode (insn, CCNOmode)
7735 && !(INTVAL (operands[3]) & ~127)))"
7736 [(set (match_dup 0)
7737 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7738 (const_int 0)]))]
7739 "operands[2] = gen_lowpart (QImode, operands[2]);
7740 operands[3] = gen_lowpart (QImode, operands[3]);")
7741
7742 ;; %%% This used to optimize known byte-wide and operations to memory,
7743 ;; and sometimes to QImode registers. If this is considered useful,
7744 ;; it should be done with splitters.
7745
7746 (define_expand "and<mode>3"
7747 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7748 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7749 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7750 ""
7751 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7752
7753 (define_insn "*anddi_1"
7754 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7755 (and:DI
7756 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7757 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7758 (clobber (reg:CC FLAGS_REG))]
7759 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7760 {
7761 switch (get_attr_type (insn))
7762 {
7763 case TYPE_IMOVX:
7764 {
7765 enum machine_mode mode;
7766
7767 gcc_assert (CONST_INT_P (operands[2]));
7768 if (INTVAL (operands[2]) == 0xff)
7769 mode = QImode;
7770 else
7771 {
7772 gcc_assert (INTVAL (operands[2]) == 0xffff);
7773 mode = HImode;
7774 }
7775
7776 operands[1] = gen_lowpart (mode, operands[1]);
7777 if (mode == QImode)
7778 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7779 else
7780 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7781 }
7782
7783 default:
7784 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7785 if (get_attr_mode (insn) == MODE_SI)
7786 return "and{l}\t{%k2, %k0|%k0, %k2}";
7787 else
7788 return "and{q}\t{%2, %0|%0, %2}";
7789 }
7790 }
7791 [(set_attr "type" "alu,alu,alu,imovx")
7792 (set_attr "length_immediate" "*,*,*,0")
7793 (set (attr "prefix_rex")
7794 (if_then_else
7795 (and (eq_attr "type" "imovx")
7796 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7797 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7798 (const_string "1")
7799 (const_string "*")))
7800 (set_attr "mode" "SI,DI,DI,SI")])
7801
7802 (define_insn "*andsi_1"
7803 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7804 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7805 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7806 (clobber (reg:CC FLAGS_REG))]
7807 "ix86_binary_operator_ok (AND, SImode, operands)"
7808 {
7809 switch (get_attr_type (insn))
7810 {
7811 case TYPE_IMOVX:
7812 {
7813 enum machine_mode mode;
7814
7815 gcc_assert (CONST_INT_P (operands[2]));
7816 if (INTVAL (operands[2]) == 0xff)
7817 mode = QImode;
7818 else
7819 {
7820 gcc_assert (INTVAL (operands[2]) == 0xffff);
7821 mode = HImode;
7822 }
7823
7824 operands[1] = gen_lowpart (mode, operands[1]);
7825 if (mode == QImode)
7826 return "movz{bl|x}\t{%1, %0|%0, %1}";
7827 else
7828 return "movz{wl|x}\t{%1, %0|%0, %1}";
7829 }
7830
7831 default:
7832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7833 return "and{l}\t{%2, %0|%0, %2}";
7834 }
7835 }
7836 [(set_attr "type" "alu,alu,imovx")
7837 (set (attr "prefix_rex")
7838 (if_then_else
7839 (and (eq_attr "type" "imovx")
7840 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7841 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7842 (const_string "1")
7843 (const_string "*")))
7844 (set_attr "length_immediate" "*,*,0")
7845 (set_attr "mode" "SI")])
7846
7847 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7848 (define_insn "*andsi_1_zext"
7849 [(set (match_operand:DI 0 "register_operand" "=r")
7850 (zero_extend:DI
7851 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7852 (match_operand:SI 2 "general_operand" "g"))))
7853 (clobber (reg:CC FLAGS_REG))]
7854 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7855 "and{l}\t{%2, %k0|%k0, %2}"
7856 [(set_attr "type" "alu")
7857 (set_attr "mode" "SI")])
7858
7859 (define_insn "*andhi_1"
7860 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7861 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7862 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7863 (clobber (reg:CC FLAGS_REG))]
7864 "ix86_binary_operator_ok (AND, HImode, operands)"
7865 {
7866 switch (get_attr_type (insn))
7867 {
7868 case TYPE_IMOVX:
7869 gcc_assert (CONST_INT_P (operands[2]));
7870 gcc_assert (INTVAL (operands[2]) == 0xff);
7871 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7872
7873 default:
7874 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7875
7876 return "and{w}\t{%2, %0|%0, %2}";
7877 }
7878 }
7879 [(set_attr "type" "alu,alu,imovx")
7880 (set_attr "length_immediate" "*,*,0")
7881 (set (attr "prefix_rex")
7882 (if_then_else
7883 (and (eq_attr "type" "imovx")
7884 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7885 (const_string "1")
7886 (const_string "*")))
7887 (set_attr "mode" "HI,HI,SI")])
7888
7889 ;; %%% Potential partial reg stall on alternative 2. What to do?
7890 (define_insn "*andqi_1"
7891 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7892 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7893 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "ix86_binary_operator_ok (AND, QImode, operands)"
7896 "@
7897 and{b}\t{%2, %0|%0, %2}
7898 and{b}\t{%2, %0|%0, %2}
7899 and{l}\t{%k2, %k0|%k0, %k2}"
7900 [(set_attr "type" "alu")
7901 (set_attr "mode" "QI,QI,SI")])
7902
7903 (define_insn "*andqi_1_slp"
7904 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7905 (and:QI (match_dup 0)
7906 (match_operand:QI 1 "general_operand" "qn,qmn")))
7907 (clobber (reg:CC FLAGS_REG))]
7908 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7909 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7910 "and{b}\t{%1, %0|%0, %1}"
7911 [(set_attr "type" "alu1")
7912 (set_attr "mode" "QI")])
7913
7914 (define_split
7915 [(set (match_operand 0 "register_operand" "")
7916 (and (match_dup 0)
7917 (const_int -65536)))
7918 (clobber (reg:CC FLAGS_REG))]
7919 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7920 || optimize_function_for_size_p (cfun)"
7921 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7922 "operands[1] = gen_lowpart (HImode, operands[0]);")
7923
7924 (define_split
7925 [(set (match_operand 0 "ext_register_operand" "")
7926 (and (match_dup 0)
7927 (const_int -256)))
7928 (clobber (reg:CC FLAGS_REG))]
7929 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7930 && reload_completed"
7931 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7932 "operands[1] = gen_lowpart (QImode, operands[0]);")
7933
7934 (define_split
7935 [(set (match_operand 0 "ext_register_operand" "")
7936 (and (match_dup 0)
7937 (const_int -65281)))
7938 (clobber (reg:CC FLAGS_REG))]
7939 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7940 && reload_completed"
7941 [(parallel [(set (zero_extract:SI (match_dup 0)
7942 (const_int 8)
7943 (const_int 8))
7944 (xor:SI
7945 (zero_extract:SI (match_dup 0)
7946 (const_int 8)
7947 (const_int 8))
7948 (zero_extract:SI (match_dup 0)
7949 (const_int 8)
7950 (const_int 8))))
7951 (clobber (reg:CC FLAGS_REG))])]
7952 "operands[0] = gen_lowpart (SImode, operands[0]);")
7953
7954 (define_insn "*anddi_2"
7955 [(set (reg FLAGS_REG)
7956 (compare
7957 (and:DI
7958 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7959 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7960 (const_int 0)))
7961 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7962 (and:DI (match_dup 1) (match_dup 2)))]
7963 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7964 && ix86_binary_operator_ok (AND, DImode, operands)"
7965 "@
7966 and{l}\t{%k2, %k0|%k0, %k2}
7967 and{q}\t{%2, %0|%0, %2}
7968 and{q}\t{%2, %0|%0, %2}"
7969 [(set_attr "type" "alu")
7970 (set_attr "mode" "SI,DI,DI")])
7971
7972 (define_insn "*andqi_2_maybe_si"
7973 [(set (reg FLAGS_REG)
7974 (compare (and:QI
7975 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7976 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7977 (const_int 0)))
7978 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7979 (and:QI (match_dup 1) (match_dup 2)))]
7980 "ix86_binary_operator_ok (AND, QImode, operands)
7981 && ix86_match_ccmode (insn,
7982 CONST_INT_P (operands[2])
7983 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7984 {
7985 if (which_alternative == 2)
7986 {
7987 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7988 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7989 return "and{l}\t{%2, %k0|%k0, %2}";
7990 }
7991 return "and{b}\t{%2, %0|%0, %2}";
7992 }
7993 [(set_attr "type" "alu")
7994 (set_attr "mode" "QI,QI,SI")])
7995
7996 (define_insn "*and<mode>_2"
7997 [(set (reg FLAGS_REG)
7998 (compare (and:SWI124
7999 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8000 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8001 (const_int 0)))
8002 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8003 (and:SWI124 (match_dup 1) (match_dup 2)))]
8004 "ix86_match_ccmode (insn, CCNOmode)
8005 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8006 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8007 [(set_attr "type" "alu")
8008 (set_attr "mode" "<MODE>")])
8009
8010 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8011 (define_insn "*andsi_2_zext"
8012 [(set (reg FLAGS_REG)
8013 (compare (and:SI
8014 (match_operand:SI 1 "nonimmediate_operand" "%0")
8015 (match_operand:SI 2 "general_operand" "g"))
8016 (const_int 0)))
8017 (set (match_operand:DI 0 "register_operand" "=r")
8018 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8019 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8020 && ix86_binary_operator_ok (AND, SImode, operands)"
8021 "and{l}\t{%2, %k0|%k0, %2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "mode" "SI")])
8024
8025 (define_insn "*andqi_2_slp"
8026 [(set (reg FLAGS_REG)
8027 (compare (and:QI
8028 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8029 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8030 (const_int 0)))
8031 (set (strict_low_part (match_dup 0))
8032 (and:QI (match_dup 0) (match_dup 1)))]
8033 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8034 && ix86_match_ccmode (insn, CCNOmode)
8035 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8036 "and{b}\t{%1, %0|%0, %1}"
8037 [(set_attr "type" "alu1")
8038 (set_attr "mode" "QI")])
8039
8040 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8041 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8042 ;; for a QImode operand, which of course failed.
8043 (define_insn "andqi_ext_0"
8044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8045 (const_int 8)
8046 (const_int 8))
8047 (and:SI
8048 (zero_extract:SI
8049 (match_operand 1 "ext_register_operand" "0")
8050 (const_int 8)
8051 (const_int 8))
8052 (match_operand 2 "const_int_operand" "n")))
8053 (clobber (reg:CC FLAGS_REG))]
8054 ""
8055 "and{b}\t{%2, %h0|%h0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "length_immediate" "1")
8058 (set_attr "modrm" "1")
8059 (set_attr "mode" "QI")])
8060
8061 ;; Generated by peephole translating test to and. This shows up
8062 ;; often in fp comparisons.
8063 (define_insn "*andqi_ext_0_cc"
8064 [(set (reg FLAGS_REG)
8065 (compare
8066 (and:SI
8067 (zero_extract:SI
8068 (match_operand 1 "ext_register_operand" "0")
8069 (const_int 8)
8070 (const_int 8))
8071 (match_operand 2 "const_int_operand" "n"))
8072 (const_int 0)))
8073 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8074 (const_int 8)
8075 (const_int 8))
8076 (and:SI
8077 (zero_extract:SI
8078 (match_dup 1)
8079 (const_int 8)
8080 (const_int 8))
8081 (match_dup 2)))]
8082 "ix86_match_ccmode (insn, CCNOmode)"
8083 "and{b}\t{%2, %h0|%h0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "length_immediate" "1")
8086 (set_attr "modrm" "1")
8087 (set_attr "mode" "QI")])
8088
8089 (define_insn "*andqi_ext_1_rex64"
8090 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8091 (const_int 8)
8092 (const_int 8))
8093 (and:SI
8094 (zero_extract:SI
8095 (match_operand 1 "ext_register_operand" "0")
8096 (const_int 8)
8097 (const_int 8))
8098 (zero_extend:SI
8099 (match_operand 2 "ext_register_operand" "Q"))))
8100 (clobber (reg:CC FLAGS_REG))]
8101 "TARGET_64BIT"
8102 "and{b}\t{%2, %h0|%h0, %2}"
8103 [(set_attr "type" "alu")
8104 (set_attr "length_immediate" "0")
8105 (set_attr "mode" "QI")])
8106
8107 (define_insn "*andqi_ext_1"
8108 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8109 (const_int 8)
8110 (const_int 8))
8111 (and:SI
8112 (zero_extract:SI
8113 (match_operand 1 "ext_register_operand" "0")
8114 (const_int 8)
8115 (const_int 8))
8116 (zero_extend:SI
8117 (match_operand:QI 2 "general_operand" "Qm"))))
8118 (clobber (reg:CC FLAGS_REG))]
8119 "!TARGET_64BIT"
8120 "and{b}\t{%2, %h0|%h0, %2}"
8121 [(set_attr "type" "alu")
8122 (set_attr "length_immediate" "0")
8123 (set_attr "mode" "QI")])
8124
8125 (define_insn "*andqi_ext_2"
8126 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8127 (const_int 8)
8128 (const_int 8))
8129 (and:SI
8130 (zero_extract:SI
8131 (match_operand 1 "ext_register_operand" "%0")
8132 (const_int 8)
8133 (const_int 8))
8134 (zero_extract:SI
8135 (match_operand 2 "ext_register_operand" "Q")
8136 (const_int 8)
8137 (const_int 8))))
8138 (clobber (reg:CC FLAGS_REG))]
8139 ""
8140 "and{b}\t{%h2, %h0|%h0, %h2}"
8141 [(set_attr "type" "alu")
8142 (set_attr "length_immediate" "0")
8143 (set_attr "mode" "QI")])
8144
8145 ;; Convert wide AND instructions with immediate operand to shorter QImode
8146 ;; equivalents when possible.
8147 ;; Don't do the splitting with memory operands, since it introduces risk
8148 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8149 ;; for size, but that can (should?) be handled by generic code instead.
8150 (define_split
8151 [(set (match_operand 0 "register_operand" "")
8152 (and (match_operand 1 "register_operand" "")
8153 (match_operand 2 "const_int_operand" "")))
8154 (clobber (reg:CC FLAGS_REG))]
8155 "reload_completed
8156 && QI_REG_P (operands[0])
8157 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8158 && !(~INTVAL (operands[2]) & ~(255 << 8))
8159 && GET_MODE (operands[0]) != QImode"
8160 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8161 (and:SI (zero_extract:SI (match_dup 1)
8162 (const_int 8) (const_int 8))
8163 (match_dup 2)))
8164 (clobber (reg:CC FLAGS_REG))])]
8165 "operands[0] = gen_lowpart (SImode, operands[0]);
8166 operands[1] = gen_lowpart (SImode, operands[1]);
8167 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8168
8169 ;; Since AND can be encoded with sign extended immediate, this is only
8170 ;; profitable when 7th bit is not set.
8171 (define_split
8172 [(set (match_operand 0 "register_operand" "")
8173 (and (match_operand 1 "general_operand" "")
8174 (match_operand 2 "const_int_operand" "")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "reload_completed
8177 && ANY_QI_REG_P (operands[0])
8178 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8179 && !(~INTVAL (operands[2]) & ~255)
8180 && !(INTVAL (operands[2]) & 128)
8181 && GET_MODE (operands[0]) != QImode"
8182 [(parallel [(set (strict_low_part (match_dup 0))
8183 (and:QI (match_dup 1)
8184 (match_dup 2)))
8185 (clobber (reg:CC FLAGS_REG))])]
8186 "operands[0] = gen_lowpart (QImode, operands[0]);
8187 operands[1] = gen_lowpart (QImode, operands[1]);
8188 operands[2] = gen_lowpart (QImode, operands[2]);")
8189 \f
8190 ;; Logical inclusive and exclusive OR instructions
8191
8192 ;; %%% This used to optimize known byte-wide and operations to memory.
8193 ;; If this is considered useful, it should be done with splitters.
8194
8195 (define_expand "<code><mode>3"
8196 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8197 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8198 (match_operand:SWIM 2 "<general_operand>" "")))]
8199 ""
8200 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8201
8202 (define_insn "*<code><mode>_1"
8203 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8204 (any_or:SWI248
8205 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8206 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8207 (clobber (reg:CC FLAGS_REG))]
8208 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8209 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8210 [(set_attr "type" "alu")
8211 (set_attr "mode" "<MODE>")])
8212
8213 ;; %%% Potential partial reg stall on alternative 2. What to do?
8214 (define_insn "*<code>qi_1"
8215 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8216 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8217 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8218 (clobber (reg:CC FLAGS_REG))]
8219 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8220 "@
8221 <logic>{b}\t{%2, %0|%0, %2}
8222 <logic>{b}\t{%2, %0|%0, %2}
8223 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8224 [(set_attr "type" "alu")
8225 (set_attr "mode" "QI,QI,SI")])
8226
8227 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8228 (define_insn "*<code>si_1_zext"
8229 [(set (match_operand:DI 0 "register_operand" "=r")
8230 (zero_extend:DI
8231 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8232 (match_operand:SI 2 "general_operand" "g"))))
8233 (clobber (reg:CC FLAGS_REG))]
8234 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8235 "<logic>{l}\t{%2, %k0|%k0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "mode" "SI")])
8238
8239 (define_insn "*<code>si_1_zext_imm"
8240 [(set (match_operand:DI 0 "register_operand" "=r")
8241 (any_or:DI
8242 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8243 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8244 (clobber (reg:CC FLAGS_REG))]
8245 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8246 "<logic>{l}\t{%2, %k0|%k0, %2}"
8247 [(set_attr "type" "alu")
8248 (set_attr "mode" "SI")])
8249
8250 (define_insn "*<code>qi_1_slp"
8251 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8252 (any_or:QI (match_dup 0)
8253 (match_operand:QI 1 "general_operand" "qmn,qn")))
8254 (clobber (reg:CC FLAGS_REG))]
8255 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8256 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8257 "<logic>{b}\t{%1, %0|%0, %1}"
8258 [(set_attr "type" "alu1")
8259 (set_attr "mode" "QI")])
8260
8261 (define_insn "*<code><mode>_2"
8262 [(set (reg FLAGS_REG)
8263 (compare (any_or:SWI
8264 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8265 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8266 (const_int 0)))
8267 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8268 (any_or:SWI (match_dup 1) (match_dup 2)))]
8269 "ix86_match_ccmode (insn, CCNOmode)
8270 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8271 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8272 [(set_attr "type" "alu")
8273 (set_attr "mode" "<MODE>")])
8274
8275 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8276 ;; ??? Special case for immediate operand is missing - it is tricky.
8277 (define_insn "*<code>si_2_zext"
8278 [(set (reg FLAGS_REG)
8279 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8280 (match_operand:SI 2 "general_operand" "g"))
8281 (const_int 0)))
8282 (set (match_operand:DI 0 "register_operand" "=r")
8283 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8284 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8285 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8286 "<logic>{l}\t{%2, %k0|%k0, %2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "SI")])
8289
8290 (define_insn "*<code>si_2_zext_imm"
8291 [(set (reg FLAGS_REG)
8292 (compare (any_or:SI
8293 (match_operand:SI 1 "nonimmediate_operand" "%0")
8294 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8295 (const_int 0)))
8296 (set (match_operand:DI 0 "register_operand" "=r")
8297 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8298 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8299 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8300 "<logic>{l}\t{%2, %k0|%k0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "SI")])
8303
8304 (define_insn "*<code>qi_2_slp"
8305 [(set (reg FLAGS_REG)
8306 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8307 (match_operand:QI 1 "general_operand" "qmn,qn"))
8308 (const_int 0)))
8309 (set (strict_low_part (match_dup 0))
8310 (any_or:QI (match_dup 0) (match_dup 1)))]
8311 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8312 && ix86_match_ccmode (insn, CCNOmode)
8313 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8314 "<logic>{b}\t{%1, %0|%0, %1}"
8315 [(set_attr "type" "alu1")
8316 (set_attr "mode" "QI")])
8317
8318 (define_insn "*<code><mode>_3"
8319 [(set (reg FLAGS_REG)
8320 (compare (any_or:SWI
8321 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8322 (match_operand:SWI 2 "<general_operand>" "<g>"))
8323 (const_int 0)))
8324 (clobber (match_scratch:SWI 0 "=<r>"))]
8325 "ix86_match_ccmode (insn, CCNOmode)
8326 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8327 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "<MODE>")])
8330
8331 (define_insn "*<code>qi_ext_0"
8332 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8333 (const_int 8)
8334 (const_int 8))
8335 (any_or:SI
8336 (zero_extract:SI
8337 (match_operand 1 "ext_register_operand" "0")
8338 (const_int 8)
8339 (const_int 8))
8340 (match_operand 2 "const_int_operand" "n")))
8341 (clobber (reg:CC FLAGS_REG))]
8342 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8343 "<logic>{b}\t{%2, %h0|%h0, %2}"
8344 [(set_attr "type" "alu")
8345 (set_attr "length_immediate" "1")
8346 (set_attr "modrm" "1")
8347 (set_attr "mode" "QI")])
8348
8349 (define_insn "*<code>qi_ext_1_rex64"
8350 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8351 (const_int 8)
8352 (const_int 8))
8353 (any_or:SI
8354 (zero_extract:SI
8355 (match_operand 1 "ext_register_operand" "0")
8356 (const_int 8)
8357 (const_int 8))
8358 (zero_extend:SI
8359 (match_operand 2 "ext_register_operand" "Q"))))
8360 (clobber (reg:CC FLAGS_REG))]
8361 "TARGET_64BIT
8362 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8363 "<logic>{b}\t{%2, %h0|%h0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "length_immediate" "0")
8366 (set_attr "mode" "QI")])
8367
8368 (define_insn "*<code>qi_ext_1"
8369 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8370 (const_int 8)
8371 (const_int 8))
8372 (any_or:SI
8373 (zero_extract:SI
8374 (match_operand 1 "ext_register_operand" "0")
8375 (const_int 8)
8376 (const_int 8))
8377 (zero_extend:SI
8378 (match_operand:QI 2 "general_operand" "Qm"))))
8379 (clobber (reg:CC FLAGS_REG))]
8380 "!TARGET_64BIT
8381 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8382 "<logic>{b}\t{%2, %h0|%h0, %2}"
8383 [(set_attr "type" "alu")
8384 (set_attr "length_immediate" "0")
8385 (set_attr "mode" "QI")])
8386
8387 (define_insn "*<code>qi_ext_2"
8388 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8389 (const_int 8)
8390 (const_int 8))
8391 (any_or:SI
8392 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8393 (const_int 8)
8394 (const_int 8))
8395 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8396 (const_int 8)
8397 (const_int 8))))
8398 (clobber (reg:CC FLAGS_REG))]
8399 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8400 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8401 [(set_attr "type" "alu")
8402 (set_attr "length_immediate" "0")
8403 (set_attr "mode" "QI")])
8404
8405 (define_split
8406 [(set (match_operand 0 "register_operand" "")
8407 (any_or (match_operand 1 "register_operand" "")
8408 (match_operand 2 "const_int_operand" "")))
8409 (clobber (reg:CC FLAGS_REG))]
8410 "reload_completed
8411 && QI_REG_P (operands[0])
8412 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413 && !(INTVAL (operands[2]) & ~(255 << 8))
8414 && GET_MODE (operands[0]) != QImode"
8415 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8416 (any_or:SI (zero_extract:SI (match_dup 1)
8417 (const_int 8) (const_int 8))
8418 (match_dup 2)))
8419 (clobber (reg:CC FLAGS_REG))])]
8420 "operands[0] = gen_lowpart (SImode, operands[0]);
8421 operands[1] = gen_lowpart (SImode, operands[1]);
8422 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8423
8424 ;; Since OR can be encoded with sign extended immediate, this is only
8425 ;; profitable when 7th bit is set.
8426 (define_split
8427 [(set (match_operand 0 "register_operand" "")
8428 (any_or (match_operand 1 "general_operand" "")
8429 (match_operand 2 "const_int_operand" "")))
8430 (clobber (reg:CC FLAGS_REG))]
8431 "reload_completed
8432 && ANY_QI_REG_P (operands[0])
8433 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8434 && !(INTVAL (operands[2]) & ~255)
8435 && (INTVAL (operands[2]) & 128)
8436 && GET_MODE (operands[0]) != QImode"
8437 [(parallel [(set (strict_low_part (match_dup 0))
8438 (any_or:QI (match_dup 1)
8439 (match_dup 2)))
8440 (clobber (reg:CC FLAGS_REG))])]
8441 "operands[0] = gen_lowpart (QImode, operands[0]);
8442 operands[1] = gen_lowpart (QImode, operands[1]);
8443 operands[2] = gen_lowpart (QImode, operands[2]);")
8444
8445 (define_expand "xorqi_cc_ext_1"
8446 [(parallel [
8447 (set (reg:CCNO FLAGS_REG)
8448 (compare:CCNO
8449 (xor:SI
8450 (zero_extract:SI
8451 (match_operand 1 "ext_register_operand" "")
8452 (const_int 8)
8453 (const_int 8))
8454 (match_operand:QI 2 "general_operand" ""))
8455 (const_int 0)))
8456 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8457 (const_int 8)
8458 (const_int 8))
8459 (xor:SI
8460 (zero_extract:SI
8461 (match_dup 1)
8462 (const_int 8)
8463 (const_int 8))
8464 (match_dup 2)))])]
8465 ""
8466 "")
8467
8468 (define_insn "*xorqi_cc_ext_1_rex64"
8469 [(set (reg FLAGS_REG)
8470 (compare
8471 (xor:SI
8472 (zero_extract:SI
8473 (match_operand 1 "ext_register_operand" "0")
8474 (const_int 8)
8475 (const_int 8))
8476 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8477 (const_int 0)))
8478 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479 (const_int 8)
8480 (const_int 8))
8481 (xor:SI
8482 (zero_extract:SI
8483 (match_dup 1)
8484 (const_int 8)
8485 (const_int 8))
8486 (match_dup 2)))]
8487 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8488 "xor{b}\t{%2, %h0|%h0, %2}"
8489 [(set_attr "type" "alu")
8490 (set_attr "modrm" "1")
8491 (set_attr "mode" "QI")])
8492
8493 (define_insn "*xorqi_cc_ext_1"
8494 [(set (reg FLAGS_REG)
8495 (compare
8496 (xor:SI
8497 (zero_extract:SI
8498 (match_operand 1 "ext_register_operand" "0")
8499 (const_int 8)
8500 (const_int 8))
8501 (match_operand:QI 2 "general_operand" "qmn"))
8502 (const_int 0)))
8503 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8504 (const_int 8)
8505 (const_int 8))
8506 (xor:SI
8507 (zero_extract:SI
8508 (match_dup 1)
8509 (const_int 8)
8510 (const_int 8))
8511 (match_dup 2)))]
8512 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8513 "xor{b}\t{%2, %h0|%h0, %2}"
8514 [(set_attr "type" "alu")
8515 (set_attr "modrm" "1")
8516 (set_attr "mode" "QI")])
8517 \f
8518 ;; Negation instructions
8519
8520 (define_expand "neg<mode>2"
8521 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8522 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8523 ""
8524 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8525
8526 (define_insn_and_split "*neg<dwi>2_doubleword"
8527 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8528 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8529 (clobber (reg:CC FLAGS_REG))]
8530 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8531 "#"
8532 "reload_completed"
8533 [(parallel
8534 [(set (reg:CCZ FLAGS_REG)
8535 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8536 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8537 (parallel
8538 [(set (match_dup 2)
8539 (plus:DWIH (match_dup 3)
8540 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8541 (const_int 0))))
8542 (clobber (reg:CC FLAGS_REG))])
8543 (parallel
8544 [(set (match_dup 2)
8545 (neg:DWIH (match_dup 2)))
8546 (clobber (reg:CC FLAGS_REG))])]
8547 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8548
8549 (define_insn "*neg<mode>2_1"
8550 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8551 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8552 (clobber (reg:CC FLAGS_REG))]
8553 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8554 "neg{<imodesuffix>}\t%0"
8555 [(set_attr "type" "negnot")
8556 (set_attr "mode" "<MODE>")])
8557
8558 ;; Combine is quite creative about this pattern.
8559 (define_insn "*negsi2_1_zext"
8560 [(set (match_operand:DI 0 "register_operand" "=r")
8561 (lshiftrt:DI
8562 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8563 (const_int 32)))
8564 (const_int 32)))
8565 (clobber (reg:CC FLAGS_REG))]
8566 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8567 "neg{l}\t%k0"
8568 [(set_attr "type" "negnot")
8569 (set_attr "mode" "SI")])
8570
8571 ;; The problem with neg is that it does not perform (compare x 0),
8572 ;; it really performs (compare 0 x), which leaves us with the zero
8573 ;; flag being the only useful item.
8574
8575 (define_insn "*neg<mode>2_cmpz"
8576 [(set (reg:CCZ FLAGS_REG)
8577 (compare:CCZ
8578 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8579 (const_int 0)))
8580 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8581 (neg:SWI (match_dup 1)))]
8582 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8583 "neg{<imodesuffix>}\t%0"
8584 [(set_attr "type" "negnot")
8585 (set_attr "mode" "<MODE>")])
8586
8587 (define_insn "*negsi2_cmpz_zext"
8588 [(set (reg:CCZ FLAGS_REG)
8589 (compare:CCZ
8590 (lshiftrt:DI
8591 (neg:DI (ashift:DI
8592 (match_operand:DI 1 "register_operand" "0")
8593 (const_int 32)))
8594 (const_int 32))
8595 (const_int 0)))
8596 (set (match_operand:DI 0 "register_operand" "=r")
8597 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8598 (const_int 32)))
8599 (const_int 32)))]
8600 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8601 "neg{l}\t%k0"
8602 [(set_attr "type" "negnot")
8603 (set_attr "mode" "SI")])
8604
8605 ;; Changing of sign for FP values is doable using integer unit too.
8606
8607 (define_expand "<code><mode>2"
8608 [(set (match_operand:X87MODEF 0 "register_operand" "")
8609 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8610 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8611 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8612
8613 (define_insn "*absneg<mode>2_mixed"
8614 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8615 (match_operator:MODEF 3 "absneg_operator"
8616 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8617 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8618 (clobber (reg:CC FLAGS_REG))]
8619 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8620 "#")
8621
8622 (define_insn "*absneg<mode>2_sse"
8623 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8624 (match_operator:MODEF 3 "absneg_operator"
8625 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8626 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8627 (clobber (reg:CC FLAGS_REG))]
8628 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8629 "#")
8630
8631 (define_insn "*absneg<mode>2_i387"
8632 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8633 (match_operator:X87MODEF 3 "absneg_operator"
8634 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8635 (use (match_operand 2 "" ""))
8636 (clobber (reg:CC FLAGS_REG))]
8637 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8638 "#")
8639
8640 (define_expand "<code>tf2"
8641 [(set (match_operand:TF 0 "register_operand" "")
8642 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8643 "TARGET_SSE2"
8644 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8645
8646 (define_insn "*absnegtf2_sse"
8647 [(set (match_operand:TF 0 "register_operand" "=x,x")
8648 (match_operator:TF 3 "absneg_operator"
8649 [(match_operand:TF 1 "register_operand" "0,x")]))
8650 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8651 (clobber (reg:CC FLAGS_REG))]
8652 "TARGET_SSE2"
8653 "#")
8654
8655 ;; Splitters for fp abs and neg.
8656
8657 (define_split
8658 [(set (match_operand 0 "fp_register_operand" "")
8659 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8660 (use (match_operand 2 "" ""))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "reload_completed"
8663 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8664
8665 (define_split
8666 [(set (match_operand 0 "register_operand" "")
8667 (match_operator 3 "absneg_operator"
8668 [(match_operand 1 "register_operand" "")]))
8669 (use (match_operand 2 "nonimmediate_operand" ""))
8670 (clobber (reg:CC FLAGS_REG))]
8671 "reload_completed && SSE_REG_P (operands[0])"
8672 [(set (match_dup 0) (match_dup 3))]
8673 {
8674 enum machine_mode mode = GET_MODE (operands[0]);
8675 enum machine_mode vmode = GET_MODE (operands[2]);
8676 rtx tmp;
8677
8678 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8679 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8680 if (operands_match_p (operands[0], operands[2]))
8681 {
8682 tmp = operands[1];
8683 operands[1] = operands[2];
8684 operands[2] = tmp;
8685 }
8686 if (GET_CODE (operands[3]) == ABS)
8687 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8688 else
8689 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8690 operands[3] = tmp;
8691 })
8692
8693 (define_split
8694 [(set (match_operand:SF 0 "register_operand" "")
8695 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8696 (use (match_operand:V4SF 2 "" ""))
8697 (clobber (reg:CC FLAGS_REG))]
8698 "reload_completed"
8699 [(parallel [(set (match_dup 0) (match_dup 1))
8700 (clobber (reg:CC FLAGS_REG))])]
8701 {
8702 rtx tmp;
8703 operands[0] = gen_lowpart (SImode, operands[0]);
8704 if (GET_CODE (operands[1]) == ABS)
8705 {
8706 tmp = gen_int_mode (0x7fffffff, SImode);
8707 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8708 }
8709 else
8710 {
8711 tmp = gen_int_mode (0x80000000, SImode);
8712 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8713 }
8714 operands[1] = tmp;
8715 })
8716
8717 (define_split
8718 [(set (match_operand:DF 0 "register_operand" "")
8719 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8720 (use (match_operand 2 "" ""))
8721 (clobber (reg:CC FLAGS_REG))]
8722 "reload_completed"
8723 [(parallel [(set (match_dup 0) (match_dup 1))
8724 (clobber (reg:CC FLAGS_REG))])]
8725 {
8726 rtx tmp;
8727 if (TARGET_64BIT)
8728 {
8729 tmp = gen_lowpart (DImode, operands[0]);
8730 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8731 operands[0] = tmp;
8732
8733 if (GET_CODE (operands[1]) == ABS)
8734 tmp = const0_rtx;
8735 else
8736 tmp = gen_rtx_NOT (DImode, tmp);
8737 }
8738 else
8739 {
8740 operands[0] = gen_highpart (SImode, operands[0]);
8741 if (GET_CODE (operands[1]) == ABS)
8742 {
8743 tmp = gen_int_mode (0x7fffffff, SImode);
8744 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8745 }
8746 else
8747 {
8748 tmp = gen_int_mode (0x80000000, SImode);
8749 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8750 }
8751 }
8752 operands[1] = tmp;
8753 })
8754
8755 (define_split
8756 [(set (match_operand:XF 0 "register_operand" "")
8757 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8758 (use (match_operand 2 "" ""))
8759 (clobber (reg:CC FLAGS_REG))]
8760 "reload_completed"
8761 [(parallel [(set (match_dup 0) (match_dup 1))
8762 (clobber (reg:CC FLAGS_REG))])]
8763 {
8764 rtx tmp;
8765 operands[0] = gen_rtx_REG (SImode,
8766 true_regnum (operands[0])
8767 + (TARGET_64BIT ? 1 : 2));
8768 if (GET_CODE (operands[1]) == ABS)
8769 {
8770 tmp = GEN_INT (0x7fff);
8771 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8772 }
8773 else
8774 {
8775 tmp = GEN_INT (0x8000);
8776 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8777 }
8778 operands[1] = tmp;
8779 })
8780
8781 ;; Conditionalize these after reload. If they match before reload, we
8782 ;; lose the clobber and ability to use integer instructions.
8783
8784 (define_insn "*<code><mode>2_1"
8785 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8786 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8787 "TARGET_80387
8788 && (reload_completed
8789 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8790 "f<absneg_mnemonic>"
8791 [(set_attr "type" "fsgn")
8792 (set_attr "mode" "<MODE>")])
8793
8794 (define_insn "*<code>extendsfdf2"
8795 [(set (match_operand:DF 0 "register_operand" "=f")
8796 (absneg:DF (float_extend:DF
8797 (match_operand:SF 1 "register_operand" "0"))))]
8798 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8799 "f<absneg_mnemonic>"
8800 [(set_attr "type" "fsgn")
8801 (set_attr "mode" "DF")])
8802
8803 (define_insn "*<code>extendsfxf2"
8804 [(set (match_operand:XF 0 "register_operand" "=f")
8805 (absneg:XF (float_extend:XF
8806 (match_operand:SF 1 "register_operand" "0"))))]
8807 "TARGET_80387"
8808 "f<absneg_mnemonic>"
8809 [(set_attr "type" "fsgn")
8810 (set_attr "mode" "XF")])
8811
8812 (define_insn "*<code>extenddfxf2"
8813 [(set (match_operand:XF 0 "register_operand" "=f")
8814 (absneg:XF (float_extend:XF
8815 (match_operand:DF 1 "register_operand" "0"))))]
8816 "TARGET_80387"
8817 "f<absneg_mnemonic>"
8818 [(set_attr "type" "fsgn")
8819 (set_attr "mode" "XF")])
8820
8821 ;; Copysign instructions
8822
8823 (define_mode_iterator CSGNMODE [SF DF TF])
8824 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8825
8826 (define_expand "copysign<mode>3"
8827 [(match_operand:CSGNMODE 0 "register_operand" "")
8828 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8829 (match_operand:CSGNMODE 2 "register_operand" "")]
8830 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8831 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8832 {
8833 ix86_expand_copysign (operands);
8834 DONE;
8835 })
8836
8837 (define_insn_and_split "copysign<mode>3_const"
8838 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8839 (unspec:CSGNMODE
8840 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8841 (match_operand:CSGNMODE 2 "register_operand" "0")
8842 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8843 UNSPEC_COPYSIGN))]
8844 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8845 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8846 "#"
8847 "&& reload_completed"
8848 [(const_int 0)]
8849 {
8850 ix86_split_copysign_const (operands);
8851 DONE;
8852 })
8853
8854 (define_insn "copysign<mode>3_var"
8855 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8856 (unspec:CSGNMODE
8857 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8858 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8859 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8860 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8861 UNSPEC_COPYSIGN))
8862 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8863 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8864 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8865 "#")
8866
8867 (define_split
8868 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8869 (unspec:CSGNMODE
8870 [(match_operand:CSGNMODE 2 "register_operand" "")
8871 (match_operand:CSGNMODE 3 "register_operand" "")
8872 (match_operand:<CSGNVMODE> 4 "" "")
8873 (match_operand:<CSGNVMODE> 5 "" "")]
8874 UNSPEC_COPYSIGN))
8875 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8876 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8877 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8878 && reload_completed"
8879 [(const_int 0)]
8880 {
8881 ix86_split_copysign_var (operands);
8882 DONE;
8883 })
8884 \f
8885 ;; One complement instructions
8886
8887 (define_expand "one_cmpl<mode>2"
8888 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8889 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8890 ""
8891 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8892
8893 (define_insn "*one_cmpl<mode>2_1"
8894 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8895 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8896 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8897 "not{<imodesuffix>}\t%0"
8898 [(set_attr "type" "negnot")
8899 (set_attr "mode" "<MODE>")])
8900
8901 ;; %%% Potential partial reg stall on alternative 1. What to do?
8902 (define_insn "*one_cmplqi2_1"
8903 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8904 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8905 "ix86_unary_operator_ok (NOT, QImode, operands)"
8906 "@
8907 not{b}\t%0
8908 not{l}\t%k0"
8909 [(set_attr "type" "negnot")
8910 (set_attr "mode" "QI,SI")])
8911
8912 ;; ??? Currently never generated - xor is used instead.
8913 (define_insn "*one_cmplsi2_1_zext"
8914 [(set (match_operand:DI 0 "register_operand" "=r")
8915 (zero_extend:DI
8916 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8917 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8918 "not{l}\t%k0"
8919 [(set_attr "type" "negnot")
8920 (set_attr "mode" "SI")])
8921
8922 (define_insn "*one_cmpl<mode>2_2"
8923 [(set (reg FLAGS_REG)
8924 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8925 (const_int 0)))
8926 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8927 (not:SWI (match_dup 1)))]
8928 "ix86_match_ccmode (insn, CCNOmode)
8929 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8930 "#"
8931 [(set_attr "type" "alu1")
8932 (set_attr "mode" "<MODE>")])
8933
8934 (define_split
8935 [(set (match_operand 0 "flags_reg_operand" "")
8936 (match_operator 2 "compare_operator"
8937 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8938 (const_int 0)]))
8939 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8940 (not:SWI (match_dup 3)))]
8941 "ix86_match_ccmode (insn, CCNOmode)"
8942 [(parallel [(set (match_dup 0)
8943 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8944 (const_int 0)]))
8945 (set (match_dup 1)
8946 (xor:SWI (match_dup 3) (const_int -1)))])]
8947 "")
8948
8949 ;; ??? Currently never generated - xor is used instead.
8950 (define_insn "*one_cmplsi2_2_zext"
8951 [(set (reg FLAGS_REG)
8952 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8953 (const_int 0)))
8954 (set (match_operand:DI 0 "register_operand" "=r")
8955 (zero_extend:DI (not:SI (match_dup 1))))]
8956 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8957 && ix86_unary_operator_ok (NOT, SImode, operands)"
8958 "#"
8959 [(set_attr "type" "alu1")
8960 (set_attr "mode" "SI")])
8961
8962 (define_split
8963 [(set (match_operand 0 "flags_reg_operand" "")
8964 (match_operator 2 "compare_operator"
8965 [(not:SI (match_operand:SI 3 "register_operand" ""))
8966 (const_int 0)]))
8967 (set (match_operand:DI 1 "register_operand" "")
8968 (zero_extend:DI (not:SI (match_dup 3))))]
8969 "ix86_match_ccmode (insn, CCNOmode)"
8970 [(parallel [(set (match_dup 0)
8971 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8972 (const_int 0)]))
8973 (set (match_dup 1)
8974 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
8975 "")
8976 \f
8977 ;; Shift instructions
8978
8979 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8980 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8981 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8982 ;; from the assembler input.
8983 ;;
8984 ;; This instruction shifts the target reg/mem as usual, but instead of
8985 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8986 ;; is a left shift double, bits are taken from the high order bits of
8987 ;; reg, else if the insn is a shift right double, bits are taken from the
8988 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8989 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8990 ;;
8991 ;; Since sh[lr]d does not change the `reg' operand, that is done
8992 ;; separately, making all shifts emit pairs of shift double and normal
8993 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8994 ;; support a 63 bit shift, each shift where the count is in a reg expands
8995 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8996 ;;
8997 ;; If the shift count is a constant, we need never emit more than one
8998 ;; shift pair, instead using moves and sign extension for counts greater
8999 ;; than 31.
9000
9001 (define_expand "ashl<mode>3"
9002 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9003 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9004 (match_operand:QI 2 "nonmemory_operand" "")))]
9005 ""
9006 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9007
9008 (define_insn "*ashl<mode>3_doubleword"
9009 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9010 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9011 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9012 (clobber (reg:CC FLAGS_REG))]
9013 ""
9014 "#"
9015 [(set_attr "type" "multi")])
9016
9017 (define_split
9018 [(set (match_operand:DWI 0 "register_operand" "")
9019 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9020 (match_operand:QI 2 "nonmemory_operand" "")))
9021 (clobber (reg:CC FLAGS_REG))]
9022 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9023 [(const_int 0)]
9024 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9025
9026 ;; By default we don't ask for a scratch register, because when DWImode
9027 ;; values are manipulated, registers are already at a premium. But if
9028 ;; we have one handy, we won't turn it away.
9029
9030 (define_peephole2
9031 [(match_scratch:DWIH 3 "r")
9032 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9033 (ashift:<DWI>
9034 (match_operand:<DWI> 1 "nonmemory_operand" "")
9035 (match_operand:QI 2 "nonmemory_operand" "")))
9036 (clobber (reg:CC FLAGS_REG))])
9037 (match_dup 3)]
9038 "TARGET_CMOVE"
9039 [(const_int 0)]
9040 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9041
9042 (define_insn "x86_64_shld"
9043 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9044 (ior:DI (ashift:DI (match_dup 0)
9045 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9046 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9047 (minus:QI (const_int 64) (match_dup 2)))))
9048 (clobber (reg:CC FLAGS_REG))]
9049 "TARGET_64BIT"
9050 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9051 [(set_attr "type" "ishift")
9052 (set_attr "prefix_0f" "1")
9053 (set_attr "mode" "DI")
9054 (set_attr "athlon_decode" "vector")
9055 (set_attr "amdfam10_decode" "vector")])
9056
9057 (define_insn "x86_shld"
9058 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9059 (ior:SI (ashift:SI (match_dup 0)
9060 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9061 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9062 (minus:QI (const_int 32) (match_dup 2)))))
9063 (clobber (reg:CC FLAGS_REG))]
9064 ""
9065 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9066 [(set_attr "type" "ishift")
9067 (set_attr "prefix_0f" "1")
9068 (set_attr "mode" "SI")
9069 (set_attr "pent_pair" "np")
9070 (set_attr "athlon_decode" "vector")
9071 (set_attr "amdfam10_decode" "vector")])
9072
9073 (define_expand "x86_shift<mode>_adj_1"
9074 [(set (reg:CCZ FLAGS_REG)
9075 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9076 (match_dup 4))
9077 (const_int 0)))
9078 (set (match_operand:SWI48 0 "register_operand" "")
9079 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9080 (match_operand:SWI48 1 "register_operand" "")
9081 (match_dup 0)))
9082 (set (match_dup 1)
9083 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9084 (match_operand:SWI48 3 "register_operand" "r")
9085 (match_dup 1)))]
9086 "TARGET_CMOVE"
9087 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9088
9089 (define_expand "x86_shift<mode>_adj_2"
9090 [(use (match_operand:SWI48 0 "register_operand" ""))
9091 (use (match_operand:SWI48 1 "register_operand" ""))
9092 (use (match_operand:QI 2 "register_operand" ""))]
9093 ""
9094 {
9095 rtx label = gen_label_rtx ();
9096 rtx tmp;
9097
9098 emit_insn (gen_testqi_ccz_1 (operands[2],
9099 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9100
9101 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9102 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9103 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9104 gen_rtx_LABEL_REF (VOIDmode, label),
9105 pc_rtx);
9106 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9107 JUMP_LABEL (tmp) = label;
9108
9109 emit_move_insn (operands[0], operands[1]);
9110 ix86_expand_clear (operands[1]);
9111
9112 emit_label (label);
9113 LABEL_NUSES (label) = 1;
9114
9115 DONE;
9116 })
9117
9118 (define_insn "*ashl<mode>3_1"
9119 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9120 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9121 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9122 (clobber (reg:CC FLAGS_REG))]
9123 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9124 {
9125 switch (get_attr_type (insn))
9126 {
9127 case TYPE_LEA:
9128 return "#";
9129
9130 case TYPE_ALU:
9131 gcc_assert (operands[2] == const1_rtx);
9132 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9133 return "add{<imodesuffix>}\t%0, %0";
9134
9135 default:
9136 if (operands[2] == const1_rtx
9137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9138 return "sal{<imodesuffix>}\t%0";
9139 else
9140 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9141 }
9142 }
9143 [(set (attr "type")
9144 (cond [(eq_attr "alternative" "1")
9145 (const_string "lea")
9146 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9147 (const_int 0))
9148 (match_operand 0 "register_operand" ""))
9149 (match_operand 2 "const1_operand" ""))
9150 (const_string "alu")
9151 ]
9152 (const_string "ishift")))
9153 (set (attr "length_immediate")
9154 (if_then_else
9155 (ior (eq_attr "type" "alu")
9156 (and (eq_attr "type" "ishift")
9157 (and (match_operand 2 "const1_operand" "")
9158 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9159 (const_int 0)))))
9160 (const_string "0")
9161 (const_string "*")))
9162 (set_attr "mode" "<MODE>")])
9163
9164 (define_insn "*ashlsi3_1_zext"
9165 [(set (match_operand:DI 0 "register_operand" "=r,r")
9166 (zero_extend:DI
9167 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9168 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9169 (clobber (reg:CC FLAGS_REG))]
9170 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9171 {
9172 switch (get_attr_type (insn))
9173 {
9174 case TYPE_LEA:
9175 return "#";
9176
9177 case TYPE_ALU:
9178 gcc_assert (operands[2] == const1_rtx);
9179 return "add{l}\t%k0, %k0";
9180
9181 default:
9182 if (operands[2] == const1_rtx
9183 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9184 return "sal{l}\t%k0";
9185 else
9186 return "sal{l}\t{%2, %k0|%k0, %2}";
9187 }
9188 }
9189 [(set (attr "type")
9190 (cond [(eq_attr "alternative" "1")
9191 (const_string "lea")
9192 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9193 (const_int 0))
9194 (match_operand 2 "const1_operand" ""))
9195 (const_string "alu")
9196 ]
9197 (const_string "ishift")))
9198 (set (attr "length_immediate")
9199 (if_then_else
9200 (ior (eq_attr "type" "alu")
9201 (and (eq_attr "type" "ishift")
9202 (and (match_operand 2 "const1_operand" "")
9203 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9204 (const_int 0)))))
9205 (const_string "0")
9206 (const_string "*")))
9207 (set_attr "mode" "SI")])
9208
9209 (define_insn "*ashlhi3_1"
9210 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9211 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9212 (match_operand:QI 2 "nonmemory_operand" "cI")))
9213 (clobber (reg:CC FLAGS_REG))]
9214 "TARGET_PARTIAL_REG_STALL
9215 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9216 {
9217 switch (get_attr_type (insn))
9218 {
9219 case TYPE_ALU:
9220 gcc_assert (operands[2] == const1_rtx);
9221 return "add{w}\t%0, %0";
9222
9223 default:
9224 if (operands[2] == const1_rtx
9225 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9226 return "sal{w}\t%0";
9227 else
9228 return "sal{w}\t{%2, %0|%0, %2}";
9229 }
9230 }
9231 [(set (attr "type")
9232 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9233 (const_int 0))
9234 (match_operand 0 "register_operand" ""))
9235 (match_operand 2 "const1_operand" ""))
9236 (const_string "alu")
9237 ]
9238 (const_string "ishift")))
9239 (set (attr "length_immediate")
9240 (if_then_else
9241 (ior (eq_attr "type" "alu")
9242 (and (eq_attr "type" "ishift")
9243 (and (match_operand 2 "const1_operand" "")
9244 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9245 (const_int 0)))))
9246 (const_string "0")
9247 (const_string "*")))
9248 (set_attr "mode" "HI")])
9249
9250 (define_insn "*ashlhi3_1_lea"
9251 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9252 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9253 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9254 (clobber (reg:CC FLAGS_REG))]
9255 "!TARGET_PARTIAL_REG_STALL
9256 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9257 {
9258 switch (get_attr_type (insn))
9259 {
9260 case TYPE_LEA:
9261 return "#";
9262
9263 case TYPE_ALU:
9264 gcc_assert (operands[2] == const1_rtx);
9265 return "add{w}\t%0, %0";
9266
9267 default:
9268 if (operands[2] == const1_rtx
9269 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9270 return "sal{w}\t%0";
9271 else
9272 return "sal{w}\t{%2, %0|%0, %2}";
9273 }
9274 }
9275 [(set (attr "type")
9276 (cond [(eq_attr "alternative" "1")
9277 (const_string "lea")
9278 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9279 (const_int 0))
9280 (match_operand 0 "register_operand" ""))
9281 (match_operand 2 "const1_operand" ""))
9282 (const_string "alu")
9283 ]
9284 (const_string "ishift")))
9285 (set (attr "length_immediate")
9286 (if_then_else
9287 (ior (eq_attr "type" "alu")
9288 (and (eq_attr "type" "ishift")
9289 (and (match_operand 2 "const1_operand" "")
9290 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9291 (const_int 0)))))
9292 (const_string "0")
9293 (const_string "*")))
9294 (set_attr "mode" "HI,SI")])
9295
9296 (define_insn "*ashlqi3_1"
9297 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9298 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9299 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9300 (clobber (reg:CC FLAGS_REG))]
9301 "TARGET_PARTIAL_REG_STALL
9302 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9303 {
9304 switch (get_attr_type (insn))
9305 {
9306 case TYPE_ALU:
9307 gcc_assert (operands[2] == const1_rtx);
9308 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9309 return "add{l}\t%k0, %k0";
9310 else
9311 return "add{b}\t%0, %0";
9312
9313 default:
9314 if (operands[2] == const1_rtx
9315 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9316 {
9317 if (get_attr_mode (insn) == MODE_SI)
9318 return "sal{l}\t%k0";
9319 else
9320 return "sal{b}\t%0";
9321 }
9322 else
9323 {
9324 if (get_attr_mode (insn) == MODE_SI)
9325 return "sal{l}\t{%2, %k0|%k0, %2}";
9326 else
9327 return "sal{b}\t{%2, %0|%0, %2}";
9328 }
9329 }
9330 }
9331 [(set (attr "type")
9332 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9333 (const_int 0))
9334 (match_operand 0 "register_operand" ""))
9335 (match_operand 2 "const1_operand" ""))
9336 (const_string "alu")
9337 ]
9338 (const_string "ishift")))
9339 (set (attr "length_immediate")
9340 (if_then_else
9341 (ior (eq_attr "type" "alu")
9342 (and (eq_attr "type" "ishift")
9343 (and (match_operand 2 "const1_operand" "")
9344 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9345 (const_int 0)))))
9346 (const_string "0")
9347 (const_string "*")))
9348 (set_attr "mode" "QI,SI")])
9349
9350 ;; %%% Potential partial reg stall on alternative 2. What to do?
9351 (define_insn "*ashlqi3_1_lea"
9352 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9353 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9354 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9355 (clobber (reg:CC FLAGS_REG))]
9356 "!TARGET_PARTIAL_REG_STALL
9357 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9358 {
9359 switch (get_attr_type (insn))
9360 {
9361 case TYPE_LEA:
9362 return "#";
9363
9364 case TYPE_ALU:
9365 gcc_assert (operands[2] == const1_rtx);
9366 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9367 return "add{l}\t%k0, %k0";
9368 else
9369 return "add{b}\t%0, %0";
9370
9371 default:
9372 if (operands[2] == const1_rtx
9373 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9374 {
9375 if (get_attr_mode (insn) == MODE_SI)
9376 return "sal{l}\t%k0";
9377 else
9378 return "sal{b}\t%0";
9379 }
9380 else
9381 {
9382 if (get_attr_mode (insn) == MODE_SI)
9383 return "sal{l}\t{%2, %k0|%k0, %2}";
9384 else
9385 return "sal{b}\t{%2, %0|%0, %2}";
9386 }
9387 }
9388 }
9389 [(set (attr "type")
9390 (cond [(eq_attr "alternative" "2")
9391 (const_string "lea")
9392 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9393 (const_int 0))
9394 (match_operand 0 "register_operand" ""))
9395 (match_operand 2 "const1_operand" ""))
9396 (const_string "alu")
9397 ]
9398 (const_string "ishift")))
9399 (set (attr "length_immediate")
9400 (if_then_else
9401 (ior (eq_attr "type" "alu")
9402 (and (eq_attr "type" "ishift")
9403 (and (match_operand 2 "const1_operand" "")
9404 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9405 (const_int 0)))))
9406 (const_string "0")
9407 (const_string "*")))
9408 (set_attr "mode" "QI,SI,SI")])
9409
9410 (define_insn "*ashlqi3_1_slp"
9411 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9412 (ashift:QI (match_dup 0)
9413 (match_operand:QI 1 "nonmemory_operand" "cI")))
9414 (clobber (reg:CC FLAGS_REG))]
9415 "(optimize_function_for_size_p (cfun)
9416 || !TARGET_PARTIAL_FLAG_REG_STALL
9417 || (operands[1] == const1_rtx
9418 && (TARGET_SHIFT1
9419 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9420 {
9421 switch (get_attr_type (insn))
9422 {
9423 case TYPE_ALU:
9424 gcc_assert (operands[1] == const1_rtx);
9425 return "add{b}\t%0, %0";
9426
9427 default:
9428 if (operands[1] == const1_rtx
9429 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9430 return "sal{b}\t%0";
9431 else
9432 return "sal{b}\t{%1, %0|%0, %1}";
9433 }
9434 }
9435 [(set (attr "type")
9436 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9437 (const_int 0))
9438 (match_operand 0 "register_operand" ""))
9439 (match_operand 1 "const1_operand" ""))
9440 (const_string "alu")
9441 ]
9442 (const_string "ishift1")))
9443 (set (attr "length_immediate")
9444 (if_then_else
9445 (ior (eq_attr "type" "alu")
9446 (and (eq_attr "type" "ishift1")
9447 (and (match_operand 1 "const1_operand" "")
9448 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9449 (const_int 0)))))
9450 (const_string "0")
9451 (const_string "*")))
9452 (set_attr "mode" "QI")])
9453
9454 ;; Convert lea to the lea pattern to avoid flags dependency.
9455 (define_split
9456 [(set (match_operand:DI 0 "register_operand" "")
9457 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9458 (match_operand:QI 2 "const_int_operand" "")))
9459 (clobber (reg:CC FLAGS_REG))]
9460 "TARGET_64BIT && reload_completed
9461 && true_regnum (operands[0]) != true_regnum (operands[1])"
9462 [(set (match_dup 0)
9463 (mult:DI (match_dup 1)
9464 (match_dup 2)))]
9465 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9466
9467 ;; Convert lea to the lea pattern to avoid flags dependency.
9468 (define_split
9469 [(set (match_operand 0 "register_operand" "")
9470 (ashift (match_operand 1 "index_register_operand" "")
9471 (match_operand:QI 2 "const_int_operand" "")))
9472 (clobber (reg:CC FLAGS_REG))]
9473 "reload_completed
9474 && true_regnum (operands[0]) != true_regnum (operands[1])
9475 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9476 [(const_int 0)]
9477 {
9478 rtx pat;
9479 enum machine_mode mode = GET_MODE (operands[0]);
9480
9481 if (GET_MODE_SIZE (mode) < 4)
9482 operands[0] = gen_lowpart (SImode, operands[0]);
9483 if (mode != Pmode)
9484 operands[1] = gen_lowpart (Pmode, operands[1]);
9485 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9486
9487 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9488 if (Pmode != SImode)
9489 pat = gen_rtx_SUBREG (SImode, pat, 0);
9490 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9491 DONE;
9492 })
9493
9494 ;; Rare case of shifting RSP is handled by generating move and shift
9495 (define_split
9496 [(set (match_operand 0 "register_operand" "")
9497 (ashift (match_operand 1 "register_operand" "")
9498 (match_operand:QI 2 "const_int_operand" "")))
9499 (clobber (reg:CC FLAGS_REG))]
9500 "reload_completed
9501 && true_regnum (operands[0]) != true_regnum (operands[1])"
9502 [(const_int 0)]
9503 {
9504 rtx pat, clob;
9505 emit_move_insn (operands[0], operands[1]);
9506 pat = gen_rtx_SET (VOIDmode, operands[0],
9507 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9508 operands[0], operands[2]));
9509 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9510 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9511 DONE;
9512 })
9513
9514 ;; Convert lea to the lea pattern to avoid flags dependency.
9515 (define_split
9516 [(set (match_operand:DI 0 "register_operand" "")
9517 (zero_extend:DI
9518 (ashift:SI (match_operand:SI 1 "register_operand" "")
9519 (match_operand:QI 2 "const_int_operand" ""))))
9520 (clobber (reg:CC FLAGS_REG))]
9521 "TARGET_64BIT && reload_completed
9522 && true_regnum (operands[0]) != true_regnum (operands[1])"
9523 [(set (match_dup 0)
9524 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9525 {
9526 operands[1] = gen_lowpart (Pmode, operands[1]);
9527 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9528 })
9529
9530 ;; This pattern can't accept a variable shift count, since shifts by
9531 ;; zero don't affect the flags. We assume that shifts by constant
9532 ;; zero are optimized away.
9533 (define_insn "*ashl<mode>3_cmp"
9534 [(set (reg FLAGS_REG)
9535 (compare
9536 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9537 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9538 (const_int 0)))
9539 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9540 (ashift:SWI (match_dup 1) (match_dup 2)))]
9541 "(optimize_function_for_size_p (cfun)
9542 || !TARGET_PARTIAL_FLAG_REG_STALL
9543 || (operands[2] == const1_rtx
9544 && (TARGET_SHIFT1
9545 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9546 && ix86_match_ccmode (insn, CCGOCmode)
9547 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9548 {
9549 switch (get_attr_type (insn))
9550 {
9551 case TYPE_ALU:
9552 gcc_assert (operands[2] == const1_rtx);
9553 return "add{<imodesuffix>}\t%0, %0";
9554
9555 default:
9556 if (operands[2] == const1_rtx
9557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9558 return "sal{<imodesuffix>}\t%0";
9559 else
9560 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9561 }
9562 }
9563 [(set (attr "type")
9564 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9565 (const_int 0))
9566 (match_operand 0 "register_operand" ""))
9567 (match_operand 2 "const1_operand" ""))
9568 (const_string "alu")
9569 ]
9570 (const_string "ishift")))
9571 (set (attr "length_immediate")
9572 (if_then_else
9573 (ior (eq_attr "type" "alu")
9574 (and (eq_attr "type" "ishift")
9575 (and (match_operand 2 "const1_operand" "")
9576 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9577 (const_int 0)))))
9578 (const_string "0")
9579 (const_string "*")))
9580 (set_attr "mode" "<MODE>")])
9581
9582 (define_insn "*ashlsi3_cmp_zext"
9583 [(set (reg FLAGS_REG)
9584 (compare
9585 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9586 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9587 (const_int 0)))
9588 (set (match_operand:DI 0 "register_operand" "=r")
9589 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9590 "TARGET_64BIT
9591 && (optimize_function_for_size_p (cfun)
9592 || !TARGET_PARTIAL_FLAG_REG_STALL
9593 || (operands[2] == const1_rtx
9594 && (TARGET_SHIFT1
9595 || TARGET_DOUBLE_WITH_ADD)))
9596 && ix86_match_ccmode (insn, CCGOCmode)
9597 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9598 {
9599 switch (get_attr_type (insn))
9600 {
9601 case TYPE_ALU:
9602 gcc_assert (operands[2] == const1_rtx);
9603 return "add{l}\t%k0, %k0";
9604
9605 default:
9606 if (operands[2] == const1_rtx
9607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9608 return "sal{l}\t%k0";
9609 else
9610 return "sal{l}\t{%2, %k0|%k0, %2}";
9611 }
9612 }
9613 [(set (attr "type")
9614 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9615 (const_int 0))
9616 (match_operand 2 "const1_operand" ""))
9617 (const_string "alu")
9618 ]
9619 (const_string "ishift")))
9620 (set (attr "length_immediate")
9621 (if_then_else
9622 (ior (eq_attr "type" "alu")
9623 (and (eq_attr "type" "ishift")
9624 (and (match_operand 2 "const1_operand" "")
9625 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9626 (const_int 0)))))
9627 (const_string "0")
9628 (const_string "*")))
9629 (set_attr "mode" "SI")])
9630
9631 (define_insn "*ashl<mode>3_cconly"
9632 [(set (reg FLAGS_REG)
9633 (compare
9634 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9635 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9636 (const_int 0)))
9637 (clobber (match_scratch:SWI 0 "=<r>"))]
9638 "(optimize_function_for_size_p (cfun)
9639 || !TARGET_PARTIAL_FLAG_REG_STALL
9640 || (operands[2] == const1_rtx
9641 && (TARGET_SHIFT1
9642 || TARGET_DOUBLE_WITH_ADD)))
9643 && ix86_match_ccmode (insn, CCGOCmode)
9644 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9645 {
9646 switch (get_attr_type (insn))
9647 {
9648 case TYPE_ALU:
9649 gcc_assert (operands[2] == const1_rtx);
9650 return "add{<imodesuffix>}\t%0, %0";
9651
9652 default:
9653 if (operands[2] == const1_rtx
9654 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9655 return "sal{<imodesuffix>}\t%0";
9656 else
9657 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9658 }
9659 }
9660 [(set (attr "type")
9661 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9662 (const_int 0))
9663 (match_operand 0 "register_operand" ""))
9664 (match_operand 2 "const1_operand" ""))
9665 (const_string "alu")
9666 ]
9667 (const_string "ishift")))
9668 (set (attr "length_immediate")
9669 (if_then_else
9670 (ior (eq_attr "type" "alu")
9671 (and (eq_attr "type" "ishift")
9672 (and (match_operand 2 "const1_operand" "")
9673 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9674 (const_int 0)))))
9675 (const_string "0")
9676 (const_string "*")))
9677 (set_attr "mode" "<MODE>")])
9678
9679 ;; See comment above `ashl<mode>3' about how this works.
9680
9681 (define_expand "<shiftrt_insn><mode>3"
9682 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9683 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9684 (match_operand:QI 2 "nonmemory_operand" "")))]
9685 ""
9686 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9687
9688 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9689 [(set (match_operand:DWI 0 "register_operand" "=r")
9690 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9691 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9692 (clobber (reg:CC FLAGS_REG))]
9693 ""
9694 "#"
9695 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9696 [(const_int 0)]
9697 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9698 [(set_attr "type" "multi")])
9699
9700 ;; By default we don't ask for a scratch register, because when DWImode
9701 ;; values are manipulated, registers are already at a premium. But if
9702 ;; we have one handy, we won't turn it away.
9703
9704 (define_peephole2
9705 [(match_scratch:DWIH 3 "r")
9706 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9707 (any_shiftrt:<DWI>
9708 (match_operand:<DWI> 1 "register_operand" "")
9709 (match_operand:QI 2 "nonmemory_operand" "")))
9710 (clobber (reg:CC FLAGS_REG))])
9711 (match_dup 3)]
9712 "TARGET_CMOVE"
9713 [(const_int 0)]
9714 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9715
9716 (define_insn "x86_64_shrd"
9717 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9718 (ior:DI (ashiftrt:DI (match_dup 0)
9719 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9720 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9721 (minus:QI (const_int 64) (match_dup 2)))))
9722 (clobber (reg:CC FLAGS_REG))]
9723 "TARGET_64BIT"
9724 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9725 [(set_attr "type" "ishift")
9726 (set_attr "prefix_0f" "1")
9727 (set_attr "mode" "DI")
9728 (set_attr "athlon_decode" "vector")
9729 (set_attr "amdfam10_decode" "vector")])
9730
9731 (define_insn "x86_shrd"
9732 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9733 (ior:SI (ashiftrt:SI (match_dup 0)
9734 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9735 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9736 (minus:QI (const_int 32) (match_dup 2)))))
9737 (clobber (reg:CC FLAGS_REG))]
9738 ""
9739 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9740 [(set_attr "type" "ishift")
9741 (set_attr "prefix_0f" "1")
9742 (set_attr "mode" "SI")
9743 (set_attr "pent_pair" "np")
9744 (set_attr "athlon_decode" "vector")
9745 (set_attr "amdfam10_decode" "vector")])
9746
9747 (define_insn "ashrdi3_cvt"
9748 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9749 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9750 (match_operand:QI 2 "const_int_operand" "")))
9751 (clobber (reg:CC FLAGS_REG))]
9752 "TARGET_64BIT && INTVAL (operands[2]) == 63
9753 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9754 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9755 "@
9756 {cqto|cqo}
9757 sar{q}\t{%2, %0|%0, %2}"
9758 [(set_attr "type" "imovx,ishift")
9759 (set_attr "prefix_0f" "0,*")
9760 (set_attr "length_immediate" "0,*")
9761 (set_attr "modrm" "0,1")
9762 (set_attr "mode" "DI")])
9763
9764 (define_insn "ashrsi3_cvt"
9765 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9766 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9767 (match_operand:QI 2 "const_int_operand" "")))
9768 (clobber (reg:CC FLAGS_REG))]
9769 "INTVAL (operands[2]) == 31
9770 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9771 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9772 "@
9773 {cltd|cdq}
9774 sar{l}\t{%2, %0|%0, %2}"
9775 [(set_attr "type" "imovx,ishift")
9776 (set_attr "prefix_0f" "0,*")
9777 (set_attr "length_immediate" "0,*")
9778 (set_attr "modrm" "0,1")
9779 (set_attr "mode" "SI")])
9780
9781 (define_insn "*ashrsi3_cvt_zext"
9782 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9783 (zero_extend:DI
9784 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9785 (match_operand:QI 2 "const_int_operand" ""))))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_64BIT && INTVAL (operands[2]) == 31
9788 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9789 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9790 "@
9791 {cltd|cdq}
9792 sar{l}\t{%2, %k0|%k0, %2}"
9793 [(set_attr "type" "imovx,ishift")
9794 (set_attr "prefix_0f" "0,*")
9795 (set_attr "length_immediate" "0,*")
9796 (set_attr "modrm" "0,1")
9797 (set_attr "mode" "SI")])
9798
9799 (define_expand "x86_shift<mode>_adj_3"
9800 [(use (match_operand:SWI48 0 "register_operand" ""))
9801 (use (match_operand:SWI48 1 "register_operand" ""))
9802 (use (match_operand:QI 2 "register_operand" ""))]
9803 ""
9804 {
9805 rtx label = gen_label_rtx ();
9806 rtx tmp;
9807
9808 emit_insn (gen_testqi_ccz_1 (operands[2],
9809 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9810
9811 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9812 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9813 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9814 gen_rtx_LABEL_REF (VOIDmode, label),
9815 pc_rtx);
9816 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9817 JUMP_LABEL (tmp) = label;
9818
9819 emit_move_insn (operands[0], operands[1]);
9820 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9821 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9822 emit_label (label);
9823 LABEL_NUSES (label) = 1;
9824
9825 DONE;
9826 })
9827
9828 (define_insn "*<shiftrt_insn><mode>3_1"
9829 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9830 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9831 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9832 (clobber (reg:CC FLAGS_REG))]
9833 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9834 {
9835 if (operands[2] == const1_rtx
9836 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9837 return "<shiftrt>{<imodesuffix>}\t%0";
9838 else
9839 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9840 }
9841 [(set_attr "type" "ishift")
9842 (set (attr "length_immediate")
9843 (if_then_else
9844 (and (match_operand 2 "const1_operand" "")
9845 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9846 (const_int 0)))
9847 (const_string "0")
9848 (const_string "*")))
9849 (set_attr "mode" "<MODE>")])
9850
9851 (define_insn "*<shiftrt_insn>si3_1_zext"
9852 [(set (match_operand:DI 0 "register_operand" "=r")
9853 (zero_extend:DI
9854 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9855 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9856 (clobber (reg:CC FLAGS_REG))]
9857 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9858 {
9859 if (operands[2] == const1_rtx
9860 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9861 return "<shiftrt>{l}\t%k0";
9862 else
9863 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9864 }
9865 [(set_attr "type" "ishift")
9866 (set (attr "length_immediate")
9867 (if_then_else
9868 (and (match_operand 2 "const1_operand" "")
9869 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9870 (const_int 0)))
9871 (const_string "0")
9872 (const_string "*")))
9873 (set_attr "mode" "SI")])
9874
9875 (define_insn "*<shiftrt_insn>qi3_1_slp"
9876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9877 (any_shiftrt:QI (match_dup 0)
9878 (match_operand:QI 1 "nonmemory_operand" "cI")))
9879 (clobber (reg:CC FLAGS_REG))]
9880 "(optimize_function_for_size_p (cfun)
9881 || !TARGET_PARTIAL_REG_STALL
9882 || (operands[1] == const1_rtx
9883 && TARGET_SHIFT1))"
9884 {
9885 if (operands[1] == const1_rtx
9886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887 return "<shiftrt>{b}\t%0";
9888 else
9889 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9890 }
9891 [(set_attr "type" "ishift1")
9892 (set (attr "length_immediate")
9893 (if_then_else
9894 (and (match_operand 1 "const1_operand" "")
9895 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9896 (const_int 0)))
9897 (const_string "0")
9898 (const_string "*")))
9899 (set_attr "mode" "QI")])
9900
9901 ;; This pattern can't accept a variable shift count, since shifts by
9902 ;; zero don't affect the flags. We assume that shifts by constant
9903 ;; zero are optimized away.
9904 (define_insn "*<shiftrt_insn><mode>3_cmp"
9905 [(set (reg FLAGS_REG)
9906 (compare
9907 (any_shiftrt:SWI
9908 (match_operand:SWI 1 "nonimmediate_operand" "0")
9909 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9910 (const_int 0)))
9911 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9912 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9913 "(optimize_function_for_size_p (cfun)
9914 || !TARGET_PARTIAL_FLAG_REG_STALL
9915 || (operands[2] == const1_rtx
9916 && TARGET_SHIFT1))
9917 && ix86_match_ccmode (insn, CCGOCmode)
9918 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9919 {
9920 if (operands[2] == const1_rtx
9921 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9922 return "<shiftrt>{<imodesuffix>}\t%0";
9923 else
9924 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9925 }
9926 [(set_attr "type" "ishift")
9927 (set (attr "length_immediate")
9928 (if_then_else
9929 (and (match_operand 2 "const1_operand" "")
9930 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9931 (const_int 0)))
9932 (const_string "0")
9933 (const_string "*")))
9934 (set_attr "mode" "<MODE>")])
9935
9936 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9937 [(set (reg FLAGS_REG)
9938 (compare
9939 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9940 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9941 (const_int 0)))
9942 (set (match_operand:DI 0 "register_operand" "=r")
9943 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9944 "TARGET_64BIT
9945 && (optimize_function_for_size_p (cfun)
9946 || !TARGET_PARTIAL_FLAG_REG_STALL
9947 || (operands[2] == const1_rtx
9948 && TARGET_SHIFT1))
9949 && ix86_match_ccmode (insn, CCGOCmode)
9950 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9951 {
9952 if (operands[2] == const1_rtx
9953 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9954 return "<shiftrt>{l}\t%k0";
9955 else
9956 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9957 }
9958 [(set_attr "type" "ishift")
9959 (set (attr "length_immediate")
9960 (if_then_else
9961 (and (match_operand 2 "const1_operand" "")
9962 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9963 (const_int 0)))
9964 (const_string "0")
9965 (const_string "*")))
9966 (set_attr "mode" "SI")])
9967
9968 (define_insn "*<shiftrt_insn><mode>3_cconly"
9969 [(set (reg FLAGS_REG)
9970 (compare
9971 (any_shiftrt:SWI
9972 (match_operand:SWI 1 "nonimmediate_operand" "0")
9973 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9974 (const_int 0)))
9975 (clobber (match_scratch:SWI 0 "=<r>"))]
9976 "(optimize_function_for_size_p (cfun)
9977 || !TARGET_PARTIAL_FLAG_REG_STALL
9978 || (operands[2] == const1_rtx
9979 && TARGET_SHIFT1))
9980 && ix86_match_ccmode (insn, CCGOCmode)
9981 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9982 {
9983 if (operands[2] == const1_rtx
9984 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9985 return "<shiftrt>{<imodesuffix>}\t%0";
9986 else
9987 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9988 }
9989 [(set_attr "type" "ishift")
9990 (set (attr "length_immediate")
9991 (if_then_else
9992 (and (match_operand 2 "const1_operand" "")
9993 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9994 (const_int 0)))
9995 (const_string "0")
9996 (const_string "*")))
9997 (set_attr "mode" "<MODE>")])
9998 \f
9999 ;; Rotate instructions
10000
10001 (define_expand "<rotate_insn>ti3"
10002 [(set (match_operand:TI 0 "register_operand" "")
10003 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10004 (match_operand:QI 2 "nonmemory_operand" "")))]
10005 "TARGET_64BIT"
10006 {
10007 if (const_1_to_63_operand (operands[2], VOIDmode))
10008 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10009 (operands[0], operands[1], operands[2]));
10010 else
10011 FAIL;
10012
10013 DONE;
10014 })
10015
10016 (define_expand "<rotate_insn>di3"
10017 [(set (match_operand:DI 0 "shiftdi_operand" "")
10018 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10019 (match_operand:QI 2 "nonmemory_operand" "")))]
10020 ""
10021 {
10022 if (TARGET_64BIT)
10023 ix86_expand_binary_operator (<CODE>, DImode, operands);
10024 else if (const_1_to_31_operand (operands[2], VOIDmode))
10025 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10026 (operands[0], operands[1], operands[2]));
10027 else
10028 FAIL;
10029
10030 DONE;
10031 })
10032
10033 (define_expand "<rotate_insn><mode>3"
10034 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10035 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10036 (match_operand:QI 2 "nonmemory_operand" "")))]
10037 ""
10038 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10039
10040 ;; Implement rotation using two double-precision
10041 ;; shift instructions and a scratch register.
10042
10043 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10044 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10045 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10046 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10047 (clobber (reg:CC FLAGS_REG))
10048 (clobber (match_scratch:DWIH 3 "=&r"))]
10049 ""
10050 "#"
10051 "reload_completed"
10052 [(set (match_dup 3) (match_dup 4))
10053 (parallel
10054 [(set (match_dup 4)
10055 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10056 (lshiftrt:DWIH (match_dup 5)
10057 (minus:QI (match_dup 6) (match_dup 2)))))
10058 (clobber (reg:CC FLAGS_REG))])
10059 (parallel
10060 [(set (match_dup 5)
10061 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10062 (lshiftrt:DWIH (match_dup 3)
10063 (minus:QI (match_dup 6) (match_dup 2)))))
10064 (clobber (reg:CC FLAGS_REG))])]
10065 {
10066 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10067
10068 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10069 })
10070
10071 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10072 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10073 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10074 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10075 (clobber (reg:CC FLAGS_REG))
10076 (clobber (match_scratch:DWIH 3 "=&r"))]
10077 ""
10078 "#"
10079 "reload_completed"
10080 [(set (match_dup 3) (match_dup 4))
10081 (parallel
10082 [(set (match_dup 4)
10083 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10084 (ashift:DWIH (match_dup 5)
10085 (minus:QI (match_dup 6) (match_dup 2)))))
10086 (clobber (reg:CC FLAGS_REG))])
10087 (parallel
10088 [(set (match_dup 5)
10089 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10090 (ashift:DWIH (match_dup 3)
10091 (minus:QI (match_dup 6) (match_dup 2)))))
10092 (clobber (reg:CC FLAGS_REG))])]
10093 {
10094 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10095
10096 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10097 })
10098
10099 (define_insn "*<rotate_insn><mode>3_1"
10100 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10101 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10102 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10103 (clobber (reg:CC FLAGS_REG))]
10104 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10105 {
10106 if (operands[2] == const1_rtx
10107 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10108 return "<rotate>{<imodesuffix>}\t%0";
10109 else
10110 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10111 }
10112 [(set_attr "type" "rotate")
10113 (set (attr "length_immediate")
10114 (if_then_else
10115 (and (match_operand 2 "const1_operand" "")
10116 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10117 (const_int 0)))
10118 (const_string "0")
10119 (const_string "*")))
10120 (set_attr "mode" "<MODE>")])
10121
10122 (define_insn "*<rotate_insn>si3_1_zext"
10123 [(set (match_operand:DI 0 "register_operand" "=r")
10124 (zero_extend:DI
10125 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10126 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10127 (clobber (reg:CC FLAGS_REG))]
10128 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10129 {
10130 if (operands[2] == const1_rtx
10131 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10132 return "<rotate>{l}\t%k0";
10133 else
10134 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10135 }
10136 [(set_attr "type" "rotate")
10137 (set (attr "length_immediate")
10138 (if_then_else
10139 (and (match_operand 2 "const1_operand" "")
10140 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10141 (const_int 0)))
10142 (const_string "0")
10143 (const_string "*")))
10144 (set_attr "mode" "SI")])
10145
10146 (define_insn "*<rotate_insn>qi3_1_slp"
10147 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10148 (any_rotate:QI (match_dup 0)
10149 (match_operand:QI 1 "nonmemory_operand" "cI")))
10150 (clobber (reg:CC FLAGS_REG))]
10151 "(optimize_function_for_size_p (cfun)
10152 || !TARGET_PARTIAL_REG_STALL
10153 || (operands[1] == const1_rtx
10154 && TARGET_SHIFT1))"
10155 {
10156 if (operands[1] == const1_rtx
10157 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10158 return "<rotate>{b}\t%0";
10159 else
10160 return "<rotate>{b}\t{%1, %0|%0, %1}";
10161 }
10162 [(set_attr "type" "rotate1")
10163 (set (attr "length_immediate")
10164 (if_then_else
10165 (and (match_operand 1 "const1_operand" "")
10166 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10167 (const_int 0)))
10168 (const_string "0")
10169 (const_string "*")))
10170 (set_attr "mode" "QI")])
10171
10172 (define_split
10173 [(set (match_operand:HI 0 "register_operand" "")
10174 (any_rotate:HI (match_dup 0) (const_int 8)))
10175 (clobber (reg:CC FLAGS_REG))]
10176 "reload_completed
10177 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10178 [(parallel [(set (strict_low_part (match_dup 0))
10179 (bswap:HI (match_dup 0)))
10180 (clobber (reg:CC FLAGS_REG))])]
10181 "")
10182 \f
10183 ;; Bit set / bit test instructions
10184
10185 (define_expand "extv"
10186 [(set (match_operand:SI 0 "register_operand" "")
10187 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10188 (match_operand:SI 2 "const8_operand" "")
10189 (match_operand:SI 3 "const8_operand" "")))]
10190 ""
10191 {
10192 /* Handle extractions from %ah et al. */
10193 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10194 FAIL;
10195
10196 /* From mips.md: extract_bit_field doesn't verify that our source
10197 matches the predicate, so check it again here. */
10198 if (! ext_register_operand (operands[1], VOIDmode))
10199 FAIL;
10200 })
10201
10202 (define_expand "extzv"
10203 [(set (match_operand:SI 0 "register_operand" "")
10204 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10205 (match_operand:SI 2 "const8_operand" "")
10206 (match_operand:SI 3 "const8_operand" "")))]
10207 ""
10208 {
10209 /* Handle extractions from %ah et al. */
10210 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10211 FAIL;
10212
10213 /* From mips.md: extract_bit_field doesn't verify that our source
10214 matches the predicate, so check it again here. */
10215 if (! ext_register_operand (operands[1], VOIDmode))
10216 FAIL;
10217 })
10218
10219 (define_expand "insv"
10220 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10221 (match_operand 1 "const8_operand" "")
10222 (match_operand 2 "const8_operand" ""))
10223 (match_operand 3 "register_operand" ""))]
10224 ""
10225 {
10226 /* Handle insertions to %ah et al. */
10227 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10228 FAIL;
10229
10230 /* From mips.md: insert_bit_field doesn't verify that our source
10231 matches the predicate, so check it again here. */
10232 if (! ext_register_operand (operands[0], VOIDmode))
10233 FAIL;
10234
10235 if (TARGET_64BIT)
10236 emit_insn (gen_movdi_insv_1 (operands[0], operands[3]));
10237 else
10238 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10239
10240 DONE;
10241 })
10242
10243 ;; %%% bts, btr, btc, bt.
10244 ;; In general these instructions are *slow* when applied to memory,
10245 ;; since they enforce atomic operation. When applied to registers,
10246 ;; it depends on the cpu implementation. They're never faster than
10247 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10248 ;; no point. But in 64-bit, we can't hold the relevant immediates
10249 ;; within the instruction itself, so operating on bits in the high
10250 ;; 32-bits of a register becomes easier.
10251 ;;
10252 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10253 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10254 ;; negdf respectively, so they can never be disabled entirely.
10255
10256 (define_insn "*btsq"
10257 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10258 (const_int 1)
10259 (match_operand:DI 1 "const_0_to_63_operand" ""))
10260 (const_int 1))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10263 "bts{q}\t{%1, %0|%0, %1}"
10264 [(set_attr "type" "alu1")
10265 (set_attr "prefix_0f" "1")
10266 (set_attr "mode" "DI")])
10267
10268 (define_insn "*btrq"
10269 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10270 (const_int 1)
10271 (match_operand:DI 1 "const_0_to_63_operand" ""))
10272 (const_int 0))
10273 (clobber (reg:CC FLAGS_REG))]
10274 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10275 "btr{q}\t{%1, %0|%0, %1}"
10276 [(set_attr "type" "alu1")
10277 (set_attr "prefix_0f" "1")
10278 (set_attr "mode" "DI")])
10279
10280 (define_insn "*btcq"
10281 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10282 (const_int 1)
10283 (match_operand:DI 1 "const_0_to_63_operand" ""))
10284 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10285 (clobber (reg:CC FLAGS_REG))]
10286 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10287 "btc{q}\t{%1, %0|%0, %1}"
10288 [(set_attr "type" "alu1")
10289 (set_attr "prefix_0f" "1")
10290 (set_attr "mode" "DI")])
10291
10292 ;; Allow Nocona to avoid these instructions if a register is available.
10293
10294 (define_peephole2
10295 [(match_scratch:DI 2 "r")
10296 (parallel [(set (zero_extract:DI
10297 (match_operand:DI 0 "register_operand" "")
10298 (const_int 1)
10299 (match_operand:DI 1 "const_0_to_63_operand" ""))
10300 (const_int 1))
10301 (clobber (reg:CC FLAGS_REG))])]
10302 "TARGET_64BIT && !TARGET_USE_BT"
10303 [(const_int 0)]
10304 {
10305 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10306 rtx op1;
10307
10308 if (HOST_BITS_PER_WIDE_INT >= 64)
10309 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10310 else if (i < HOST_BITS_PER_WIDE_INT)
10311 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10312 else
10313 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10314
10315 op1 = immed_double_const (lo, hi, DImode);
10316 if (i >= 31)
10317 {
10318 emit_move_insn (operands[2], op1);
10319 op1 = operands[2];
10320 }
10321
10322 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10323 DONE;
10324 })
10325
10326 (define_peephole2
10327 [(match_scratch:DI 2 "r")
10328 (parallel [(set (zero_extract:DI
10329 (match_operand:DI 0 "register_operand" "")
10330 (const_int 1)
10331 (match_operand:DI 1 "const_0_to_63_operand" ""))
10332 (const_int 0))
10333 (clobber (reg:CC FLAGS_REG))])]
10334 "TARGET_64BIT && !TARGET_USE_BT"
10335 [(const_int 0)]
10336 {
10337 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10338 rtx op1;
10339
10340 if (HOST_BITS_PER_WIDE_INT >= 64)
10341 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10342 else if (i < HOST_BITS_PER_WIDE_INT)
10343 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10344 else
10345 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10346
10347 op1 = immed_double_const (~lo, ~hi, DImode);
10348 if (i >= 32)
10349 {
10350 emit_move_insn (operands[2], op1);
10351 op1 = operands[2];
10352 }
10353
10354 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10355 DONE;
10356 })
10357
10358 (define_peephole2
10359 [(match_scratch:DI 2 "r")
10360 (parallel [(set (zero_extract:DI
10361 (match_operand:DI 0 "register_operand" "")
10362 (const_int 1)
10363 (match_operand:DI 1 "const_0_to_63_operand" ""))
10364 (not:DI (zero_extract:DI
10365 (match_dup 0) (const_int 1) (match_dup 1))))
10366 (clobber (reg:CC FLAGS_REG))])]
10367 "TARGET_64BIT && !TARGET_USE_BT"
10368 [(const_int 0)]
10369 {
10370 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10371 rtx op1;
10372
10373 if (HOST_BITS_PER_WIDE_INT >= 64)
10374 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10375 else if (i < HOST_BITS_PER_WIDE_INT)
10376 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10377 else
10378 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10379
10380 op1 = immed_double_const (lo, hi, DImode);
10381 if (i >= 31)
10382 {
10383 emit_move_insn (operands[2], op1);
10384 op1 = operands[2];
10385 }
10386
10387 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10388 DONE;
10389 })
10390
10391 (define_insn "*bt<mode>"
10392 [(set (reg:CCC FLAGS_REG)
10393 (compare:CCC
10394 (zero_extract:SWI48
10395 (match_operand:SWI48 0 "register_operand" "r")
10396 (const_int 1)
10397 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10398 (const_int 0)))]
10399 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10400 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10401 [(set_attr "type" "alu1")
10402 (set_attr "prefix_0f" "1")
10403 (set_attr "mode" "<MODE>")])
10404 \f
10405 ;; Store-flag instructions.
10406
10407 ;; For all sCOND expanders, also expand the compare or test insn that
10408 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10409
10410 (define_insn_and_split "*setcc_di_1"
10411 [(set (match_operand:DI 0 "register_operand" "=q")
10412 (match_operator:DI 1 "ix86_comparison_operator"
10413 [(reg FLAGS_REG) (const_int 0)]))]
10414 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10415 "#"
10416 "&& reload_completed"
10417 [(set (match_dup 2) (match_dup 1))
10418 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10419 {
10420 PUT_MODE (operands[1], QImode);
10421 operands[2] = gen_lowpart (QImode, operands[0]);
10422 })
10423
10424 (define_insn_and_split "*setcc_si_1_and"
10425 [(set (match_operand:SI 0 "register_operand" "=q")
10426 (match_operator:SI 1 "ix86_comparison_operator"
10427 [(reg FLAGS_REG) (const_int 0)]))
10428 (clobber (reg:CC FLAGS_REG))]
10429 "!TARGET_PARTIAL_REG_STALL
10430 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10431 "#"
10432 "&& reload_completed"
10433 [(set (match_dup 2) (match_dup 1))
10434 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10435 (clobber (reg:CC FLAGS_REG))])]
10436 {
10437 PUT_MODE (operands[1], QImode);
10438 operands[2] = gen_lowpart (QImode, operands[0]);
10439 })
10440
10441 (define_insn_and_split "*setcc_si_1_movzbl"
10442 [(set (match_operand:SI 0 "register_operand" "=q")
10443 (match_operator:SI 1 "ix86_comparison_operator"
10444 [(reg FLAGS_REG) (const_int 0)]))]
10445 "!TARGET_PARTIAL_REG_STALL
10446 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10447 "#"
10448 "&& reload_completed"
10449 [(set (match_dup 2) (match_dup 1))
10450 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10451 {
10452 PUT_MODE (operands[1], QImode);
10453 operands[2] = gen_lowpart (QImode, operands[0]);
10454 })
10455
10456 (define_insn "*setcc_qi"
10457 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10458 (match_operator:QI 1 "ix86_comparison_operator"
10459 [(reg FLAGS_REG) (const_int 0)]))]
10460 ""
10461 "set%C1\t%0"
10462 [(set_attr "type" "setcc")
10463 (set_attr "mode" "QI")])
10464
10465 (define_insn "*setcc_qi_slp"
10466 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10467 (match_operator:QI 1 "ix86_comparison_operator"
10468 [(reg FLAGS_REG) (const_int 0)]))]
10469 ""
10470 "set%C1\t%0"
10471 [(set_attr "type" "setcc")
10472 (set_attr "mode" "QI")])
10473
10474 ;; In general it is not safe to assume too much about CCmode registers,
10475 ;; so simplify-rtx stops when it sees a second one. Under certain
10476 ;; conditions this is safe on x86, so help combine not create
10477 ;;
10478 ;; seta %al
10479 ;; testb %al, %al
10480 ;; sete %al
10481
10482 (define_split
10483 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10484 (ne:QI (match_operator 1 "ix86_comparison_operator"
10485 [(reg FLAGS_REG) (const_int 0)])
10486 (const_int 0)))]
10487 ""
10488 [(set (match_dup 0) (match_dup 1))]
10489 {
10490 PUT_MODE (operands[1], QImode);
10491 })
10492
10493 (define_split
10494 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10495 (ne:QI (match_operator 1 "ix86_comparison_operator"
10496 [(reg FLAGS_REG) (const_int 0)])
10497 (const_int 0)))]
10498 ""
10499 [(set (match_dup 0) (match_dup 1))]
10500 {
10501 PUT_MODE (operands[1], QImode);
10502 })
10503
10504 (define_split
10505 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10506 (eq:QI (match_operator 1 "ix86_comparison_operator"
10507 [(reg FLAGS_REG) (const_int 0)])
10508 (const_int 0)))]
10509 ""
10510 [(set (match_dup 0) (match_dup 1))]
10511 {
10512 rtx new_op1 = copy_rtx (operands[1]);
10513 operands[1] = new_op1;
10514 PUT_MODE (new_op1, QImode);
10515 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10516 GET_MODE (XEXP (new_op1, 0))));
10517
10518 /* Make sure that (a) the CCmode we have for the flags is strong
10519 enough for the reversed compare or (b) we have a valid FP compare. */
10520 if (! ix86_comparison_operator (new_op1, VOIDmode))
10521 FAIL;
10522 })
10523
10524 (define_split
10525 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10526 (eq:QI (match_operator 1 "ix86_comparison_operator"
10527 [(reg FLAGS_REG) (const_int 0)])
10528 (const_int 0)))]
10529 ""
10530 [(set (match_dup 0) (match_dup 1))]
10531 {
10532 rtx new_op1 = copy_rtx (operands[1]);
10533 operands[1] = new_op1;
10534 PUT_MODE (new_op1, QImode);
10535 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10536 GET_MODE (XEXP (new_op1, 0))));
10537
10538 /* Make sure that (a) the CCmode we have for the flags is strong
10539 enough for the reversed compare or (b) we have a valid FP compare. */
10540 if (! ix86_comparison_operator (new_op1, VOIDmode))
10541 FAIL;
10542 })
10543
10544 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10545 ;; subsequent logical operations are used to imitate conditional moves.
10546 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10547 ;; it directly.
10548
10549 (define_insn "*avx_setcc<mode>"
10550 [(set (match_operand:MODEF 0 "register_operand" "=x")
10551 (match_operator:MODEF 1 "avx_comparison_float_operator"
10552 [(match_operand:MODEF 2 "register_operand" "x")
10553 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10554 "TARGET_AVX"
10555 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10556 [(set_attr "type" "ssecmp")
10557 (set_attr "prefix" "vex")
10558 (set_attr "length_immediate" "1")
10559 (set_attr "mode" "<MODE>")])
10560
10561 (define_insn "*sse_setcc<mode>"
10562 [(set (match_operand:MODEF 0 "register_operand" "=x")
10563 (match_operator:MODEF 1 "sse_comparison_operator"
10564 [(match_operand:MODEF 2 "register_operand" "0")
10565 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10566 "SSE_FLOAT_MODE_P (<MODE>mode)"
10567 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10568 [(set_attr "type" "ssecmp")
10569 (set_attr "length_immediate" "1")
10570 (set_attr "mode" "<MODE>")])
10571 \f
10572 ;; Basic conditional jump instructions.
10573 ;; We ignore the overflow flag for signed branch instructions.
10574
10575 (define_insn "*jcc_1"
10576 [(set (pc)
10577 (if_then_else (match_operator 1 "ix86_comparison_operator"
10578 [(reg FLAGS_REG) (const_int 0)])
10579 (label_ref (match_operand 0 "" ""))
10580 (pc)))]
10581 ""
10582 "%+j%C1\t%l0"
10583 [(set_attr "type" "ibr")
10584 (set_attr "modrm" "0")
10585 (set (attr "length")
10586 (if_then_else (and (ge (minus (match_dup 0) (pc))
10587 (const_int -126))
10588 (lt (minus (match_dup 0) (pc))
10589 (const_int 128)))
10590 (const_int 2)
10591 (const_int 6)))])
10592
10593 (define_insn "*jcc_2"
10594 [(set (pc)
10595 (if_then_else (match_operator 1 "ix86_comparison_operator"
10596 [(reg FLAGS_REG) (const_int 0)])
10597 (pc)
10598 (label_ref (match_operand 0 "" ""))))]
10599 ""
10600 "%+j%c1\t%l0"
10601 [(set_attr "type" "ibr")
10602 (set_attr "modrm" "0")
10603 (set (attr "length")
10604 (if_then_else (and (ge (minus (match_dup 0) (pc))
10605 (const_int -126))
10606 (lt (minus (match_dup 0) (pc))
10607 (const_int 128)))
10608 (const_int 2)
10609 (const_int 6)))])
10610
10611 ;; In general it is not safe to assume too much about CCmode registers,
10612 ;; so simplify-rtx stops when it sees a second one. Under certain
10613 ;; conditions this is safe on x86, so help combine not create
10614 ;;
10615 ;; seta %al
10616 ;; testb %al, %al
10617 ;; je Lfoo
10618
10619 (define_split
10620 [(set (pc)
10621 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10622 [(reg FLAGS_REG) (const_int 0)])
10623 (const_int 0))
10624 (label_ref (match_operand 1 "" ""))
10625 (pc)))]
10626 ""
10627 [(set (pc)
10628 (if_then_else (match_dup 0)
10629 (label_ref (match_dup 1))
10630 (pc)))]
10631 {
10632 PUT_MODE (operands[0], VOIDmode);
10633 })
10634
10635 (define_split
10636 [(set (pc)
10637 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10638 [(reg FLAGS_REG) (const_int 0)])
10639 (const_int 0))
10640 (label_ref (match_operand 1 "" ""))
10641 (pc)))]
10642 ""
10643 [(set (pc)
10644 (if_then_else (match_dup 0)
10645 (label_ref (match_dup 1))
10646 (pc)))]
10647 {
10648 rtx new_op0 = copy_rtx (operands[0]);
10649 operands[0] = new_op0;
10650 PUT_MODE (new_op0, VOIDmode);
10651 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10652 GET_MODE (XEXP (new_op0, 0))));
10653
10654 /* Make sure that (a) the CCmode we have for the flags is strong
10655 enough for the reversed compare or (b) we have a valid FP compare. */
10656 if (! ix86_comparison_operator (new_op0, VOIDmode))
10657 FAIL;
10658 })
10659
10660 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10661 ;; pass generates from shift insn with QImode operand. Actually, the mode
10662 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10663 ;; appropriate modulo of the bit offset value.
10664
10665 (define_insn_and_split "*jcc_bt<mode>"
10666 [(set (pc)
10667 (if_then_else (match_operator 0 "bt_comparison_operator"
10668 [(zero_extract:SWI48
10669 (match_operand:SWI48 1 "register_operand" "r")
10670 (const_int 1)
10671 (zero_extend:SI
10672 (match_operand:QI 2 "register_operand" "r")))
10673 (const_int 0)])
10674 (label_ref (match_operand 3 "" ""))
10675 (pc)))
10676 (clobber (reg:CC FLAGS_REG))]
10677 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10678 "#"
10679 "&& 1"
10680 [(set (reg:CCC FLAGS_REG)
10681 (compare:CCC
10682 (zero_extract:SWI48
10683 (match_dup 1)
10684 (const_int 1)
10685 (match_dup 2))
10686 (const_int 0)))
10687 (set (pc)
10688 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10689 (label_ref (match_dup 3))
10690 (pc)))]
10691 {
10692 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10693
10694 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10695 })
10696
10697 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10698 ;; also for DImode, this is what combine produces.
10699 (define_insn_and_split "*jcc_bt<mode>_mask"
10700 [(set (pc)
10701 (if_then_else (match_operator 0 "bt_comparison_operator"
10702 [(zero_extract:SWI48
10703 (match_operand:SWI48 1 "register_operand" "r")
10704 (const_int 1)
10705 (and:SI
10706 (match_operand:SI 2 "register_operand" "r")
10707 (match_operand:SI 3 "const_int_operand" "n")))])
10708 (label_ref (match_operand 4 "" ""))
10709 (pc)))
10710 (clobber (reg:CC FLAGS_REG))]
10711 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10712 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10713 == GET_MODE_BITSIZE (<MODE>mode)-1"
10714 "#"
10715 "&& 1"
10716 [(set (reg:CCC FLAGS_REG)
10717 (compare:CCC
10718 (zero_extract:SWI48
10719 (match_dup 1)
10720 (const_int 1)
10721 (match_dup 2))
10722 (const_int 0)))
10723 (set (pc)
10724 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10725 (label_ref (match_dup 4))
10726 (pc)))]
10727 {
10728 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10729
10730 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10731 })
10732
10733 (define_insn_and_split "*jcc_btsi_1"
10734 [(set (pc)
10735 (if_then_else (match_operator 0 "bt_comparison_operator"
10736 [(and:SI
10737 (lshiftrt:SI
10738 (match_operand:SI 1 "register_operand" "r")
10739 (match_operand:QI 2 "register_operand" "r"))
10740 (const_int 1))
10741 (const_int 0)])
10742 (label_ref (match_operand 3 "" ""))
10743 (pc)))
10744 (clobber (reg:CC FLAGS_REG))]
10745 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10746 "#"
10747 "&& 1"
10748 [(set (reg:CCC FLAGS_REG)
10749 (compare:CCC
10750 (zero_extract:SI
10751 (match_dup 1)
10752 (const_int 1)
10753 (match_dup 2))
10754 (const_int 0)))
10755 (set (pc)
10756 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10757 (label_ref (match_dup 3))
10758 (pc)))]
10759 {
10760 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10761
10762 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10763 })
10764
10765 ;; avoid useless masking of bit offset operand
10766 (define_insn_and_split "*jcc_btsi_mask_1"
10767 [(set (pc)
10768 (if_then_else
10769 (match_operator 0 "bt_comparison_operator"
10770 [(and:SI
10771 (lshiftrt:SI
10772 (match_operand:SI 1 "register_operand" "r")
10773 (subreg:QI
10774 (and:SI
10775 (match_operand:SI 2 "register_operand" "r")
10776 (match_operand:SI 3 "const_int_operand" "n")) 0))
10777 (const_int 1))
10778 (const_int 0)])
10779 (label_ref (match_operand 4 "" ""))
10780 (pc)))
10781 (clobber (reg:CC FLAGS_REG))]
10782 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10783 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10784 "#"
10785 "&& 1"
10786 [(set (reg:CCC FLAGS_REG)
10787 (compare:CCC
10788 (zero_extract:SI
10789 (match_dup 1)
10790 (const_int 1)
10791 (match_dup 2))
10792 (const_int 0)))
10793 (set (pc)
10794 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10795 (label_ref (match_dup 4))
10796 (pc)))]
10797 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10798
10799 ;; Define combination compare-and-branch fp compare instructions to help
10800 ;; combine.
10801
10802 (define_insn "*fp_jcc_1_387"
10803 [(set (pc)
10804 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10805 [(match_operand 1 "register_operand" "f")
10806 (match_operand 2 "nonimmediate_operand" "fm")])
10807 (label_ref (match_operand 3 "" ""))
10808 (pc)))
10809 (clobber (reg:CCFP FPSR_REG))
10810 (clobber (reg:CCFP FLAGS_REG))
10811 (clobber (match_scratch:HI 4 "=a"))]
10812 "TARGET_80387
10813 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10814 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10815 && SELECT_CC_MODE (GET_CODE (operands[0]),
10816 operands[1], operands[2]) == CCFPmode
10817 && !TARGET_CMOVE"
10818 "#")
10819
10820 (define_insn "*fp_jcc_1r_387"
10821 [(set (pc)
10822 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10823 [(match_operand 1 "register_operand" "f")
10824 (match_operand 2 "nonimmediate_operand" "fm")])
10825 (pc)
10826 (label_ref (match_operand 3 "" ""))))
10827 (clobber (reg:CCFP FPSR_REG))
10828 (clobber (reg:CCFP FLAGS_REG))
10829 (clobber (match_scratch:HI 4 "=a"))]
10830 "TARGET_80387
10831 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10832 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10833 && SELECT_CC_MODE (GET_CODE (operands[0]),
10834 operands[1], operands[2]) == CCFPmode
10835 && !TARGET_CMOVE"
10836 "#")
10837
10838 (define_insn "*fp_jcc_2_387"
10839 [(set (pc)
10840 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10841 [(match_operand 1 "register_operand" "f")
10842 (match_operand 2 "register_operand" "f")])
10843 (label_ref (match_operand 3 "" ""))
10844 (pc)))
10845 (clobber (reg:CCFP FPSR_REG))
10846 (clobber (reg:CCFP FLAGS_REG))
10847 (clobber (match_scratch:HI 4 "=a"))]
10848 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10849 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10850 && !TARGET_CMOVE"
10851 "#")
10852
10853 (define_insn "*fp_jcc_2r_387"
10854 [(set (pc)
10855 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10856 [(match_operand 1 "register_operand" "f")
10857 (match_operand 2 "register_operand" "f")])
10858 (pc)
10859 (label_ref (match_operand 3 "" ""))))
10860 (clobber (reg:CCFP FPSR_REG))
10861 (clobber (reg:CCFP FLAGS_REG))
10862 (clobber (match_scratch:HI 4 "=a"))]
10863 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10864 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10865 && !TARGET_CMOVE"
10866 "#")
10867
10868 (define_insn "*fp_jcc_3_387"
10869 [(set (pc)
10870 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10871 [(match_operand 1 "register_operand" "f")
10872 (match_operand 2 "const0_operand" "")])
10873 (label_ref (match_operand 3 "" ""))
10874 (pc)))
10875 (clobber (reg:CCFP FPSR_REG))
10876 (clobber (reg:CCFP FLAGS_REG))
10877 (clobber (match_scratch:HI 4 "=a"))]
10878 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10879 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10880 && SELECT_CC_MODE (GET_CODE (operands[0]),
10881 operands[1], operands[2]) == CCFPmode
10882 && !TARGET_CMOVE"
10883 "#")
10884
10885 (define_split
10886 [(set (pc)
10887 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10888 [(match_operand 1 "register_operand" "")
10889 (match_operand 2 "nonimmediate_operand" "")])
10890 (match_operand 3 "" "")
10891 (match_operand 4 "" "")))
10892 (clobber (reg:CCFP FPSR_REG))
10893 (clobber (reg:CCFP FLAGS_REG))]
10894 "reload_completed"
10895 [(const_int 0)]
10896 {
10897 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10898 operands[3], operands[4], NULL_RTX, NULL_RTX);
10899 DONE;
10900 })
10901
10902 (define_split
10903 [(set (pc)
10904 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10905 [(match_operand 1 "register_operand" "")
10906 (match_operand 2 "general_operand" "")])
10907 (match_operand 3 "" "")
10908 (match_operand 4 "" "")))
10909 (clobber (reg:CCFP FPSR_REG))
10910 (clobber (reg:CCFP FLAGS_REG))
10911 (clobber (match_scratch:HI 5 "=a"))]
10912 "reload_completed"
10913 [(const_int 0)]
10914 {
10915 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10916 operands[3], operands[4], operands[5], NULL_RTX);
10917 DONE;
10918 })
10919
10920 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10921 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10922 ;; with a precedence over other operators and is always put in the first
10923 ;; place. Swap condition and operands to match ficom instruction.
10924
10925 (define_insn "*fp_jcc_4_<mode>_387"
10926 [(set (pc)
10927 (if_then_else
10928 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10929 [(match_operator 1 "float_operator"
10930 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10931 (match_operand 3 "register_operand" "f,f")])
10932 (label_ref (match_operand 4 "" ""))
10933 (pc)))
10934 (clobber (reg:CCFP FPSR_REG))
10935 (clobber (reg:CCFP FLAGS_REG))
10936 (clobber (match_scratch:HI 5 "=a,a"))]
10937 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10938 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10939 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10940 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10941 && !TARGET_CMOVE"
10942 "#")
10943
10944 (define_split
10945 [(set (pc)
10946 (if_then_else
10947 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10948 [(match_operator 1 "float_operator"
10949 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10950 (match_operand 3 "register_operand" "")])
10951 (match_operand 4 "" "")
10952 (match_operand 5 "" "")))
10953 (clobber (reg:CCFP FPSR_REG))
10954 (clobber (reg:CCFP FLAGS_REG))
10955 (clobber (match_scratch:HI 6 "=a"))]
10956 "reload_completed"
10957 [(const_int 0)]
10958 {
10959 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10960
10961 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10962 operands[3], operands[7],
10963 operands[4], operands[5], operands[6], NULL_RTX);
10964 DONE;
10965 })
10966
10967 ;; %%% Kill this when reload knows how to do it.
10968 (define_split
10969 [(set (pc)
10970 (if_then_else
10971 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10972 [(match_operator 1 "float_operator"
10973 [(match_operand:X87MODEI12 2 "register_operand" "")])
10974 (match_operand 3 "register_operand" "")])
10975 (match_operand 4 "" "")
10976 (match_operand 5 "" "")))
10977 (clobber (reg:CCFP FPSR_REG))
10978 (clobber (reg:CCFP FLAGS_REG))
10979 (clobber (match_scratch:HI 6 "=a"))]
10980 "reload_completed"
10981 [(const_int 0)]
10982 {
10983 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10984 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10985
10986 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10987 operands[3], operands[7],
10988 operands[4], operands[5], operands[6], operands[2]);
10989 DONE;
10990 })
10991 \f
10992 ;; Unconditional and other jump instructions
10993
10994 (define_insn "jump"
10995 [(set (pc)
10996 (label_ref (match_operand 0 "" "")))]
10997 ""
10998 "jmp\t%l0"
10999 [(set_attr "type" "ibr")
11000 (set (attr "length")
11001 (if_then_else (and (ge (minus (match_dup 0) (pc))
11002 (const_int -126))
11003 (lt (minus (match_dup 0) (pc))
11004 (const_int 128)))
11005 (const_int 2)
11006 (const_int 5)))
11007 (set_attr "modrm" "0")])
11008
11009 (define_expand "indirect_jump"
11010 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11011 ""
11012 "")
11013
11014 (define_insn "*indirect_jump"
11015 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11016 ""
11017 "jmp\t%A0"
11018 [(set_attr "type" "ibr")
11019 (set_attr "length_immediate" "0")])
11020
11021 (define_expand "tablejump"
11022 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11023 (use (label_ref (match_operand 1 "" "")))])]
11024 ""
11025 {
11026 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11027 relative. Convert the relative address to an absolute address. */
11028 if (flag_pic)
11029 {
11030 rtx op0, op1;
11031 enum rtx_code code;
11032
11033 /* We can't use @GOTOFF for text labels on VxWorks;
11034 see gotoff_operand. */
11035 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11036 {
11037 code = PLUS;
11038 op0 = operands[0];
11039 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11040 }
11041 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11042 {
11043 code = PLUS;
11044 op0 = operands[0];
11045 op1 = pic_offset_table_rtx;
11046 }
11047 else
11048 {
11049 code = MINUS;
11050 op0 = pic_offset_table_rtx;
11051 op1 = operands[0];
11052 }
11053
11054 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11055 OPTAB_DIRECT);
11056 }
11057 })
11058
11059 (define_insn "*tablejump_1"
11060 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11061 (use (label_ref (match_operand 1 "" "")))]
11062 ""
11063 "jmp\t%A0"
11064 [(set_attr "type" "ibr")
11065 (set_attr "length_immediate" "0")])
11066 \f
11067 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11068
11069 (define_peephole2
11070 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11071 (set (match_operand:QI 1 "register_operand" "")
11072 (match_operator:QI 2 "ix86_comparison_operator"
11073 [(reg FLAGS_REG) (const_int 0)]))
11074 (set (match_operand 3 "q_regs_operand" "")
11075 (zero_extend (match_dup 1)))]
11076 "(peep2_reg_dead_p (3, operands[1])
11077 || operands_match_p (operands[1], operands[3]))
11078 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11079 [(set (match_dup 4) (match_dup 0))
11080 (set (strict_low_part (match_dup 5))
11081 (match_dup 2))]
11082 {
11083 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11084 operands[5] = gen_lowpart (QImode, operands[3]);
11085 ix86_expand_clear (operands[3]);
11086 })
11087
11088 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11089
11090 (define_peephole2
11091 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11092 (set (match_operand:QI 1 "register_operand" "")
11093 (match_operator:QI 2 "ix86_comparison_operator"
11094 [(reg FLAGS_REG) (const_int 0)]))
11095 (parallel [(set (match_operand 3 "q_regs_operand" "")
11096 (zero_extend (match_dup 1)))
11097 (clobber (reg:CC FLAGS_REG))])]
11098 "(peep2_reg_dead_p (3, operands[1])
11099 || operands_match_p (operands[1], operands[3]))
11100 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11101 [(set (match_dup 4) (match_dup 0))
11102 (set (strict_low_part (match_dup 5))
11103 (match_dup 2))]
11104 {
11105 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11106 operands[5] = gen_lowpart (QImode, operands[3]);
11107 ix86_expand_clear (operands[3]);
11108 })
11109 \f
11110 ;; Call instructions.
11111
11112 ;; The predicates normally associated with named expanders are not properly
11113 ;; checked for calls. This is a bug in the generic code, but it isn't that
11114 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11115
11116 ;; P6 processors will jump to the address after the decrement when %esp
11117 ;; is used as a call operand, so they will execute return address as a code.
11118 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11119
11120 ;; Call subroutine returning no value.
11121
11122 (define_expand "call_pop"
11123 [(parallel [(call (match_operand:QI 0 "" "")
11124 (match_operand:SI 1 "" ""))
11125 (set (reg:SI SP_REG)
11126 (plus:SI (reg:SI SP_REG)
11127 (match_operand:SI 3 "" "")))])]
11128 "!TARGET_64BIT"
11129 {
11130 ix86_expand_call (NULL, operands[0], operands[1],
11131 operands[2], operands[3], 0);
11132 DONE;
11133 })
11134
11135 (define_insn "*call_pop_0"
11136 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11137 (match_operand:SI 1 "" ""))
11138 (set (reg:SI SP_REG)
11139 (plus:SI (reg:SI SP_REG)
11140 (match_operand:SI 2 "immediate_operand" "")))]
11141 "!TARGET_64BIT"
11142 {
11143 if (SIBLING_CALL_P (insn))
11144 return "jmp\t%P0";
11145 else
11146 return "call\t%P0";
11147 }
11148 [(set_attr "type" "call")])
11149
11150 (define_insn "*call_pop_1"
11151 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11152 (match_operand:SI 1 "" ""))
11153 (set (reg:SI SP_REG)
11154 (plus:SI (reg:SI SP_REG)
11155 (match_operand:SI 2 "immediate_operand" "i")))]
11156 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11157 {
11158 if (constant_call_address_operand (operands[0], Pmode))
11159 return "call\t%P0";
11160 return "call\t%A0";
11161 }
11162 [(set_attr "type" "call")])
11163
11164 (define_insn "*sibcall_pop_1"
11165 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11166 (match_operand:SI 1 "" ""))
11167 (set (reg:SI SP_REG)
11168 (plus:SI (reg:SI SP_REG)
11169 (match_operand:SI 2 "immediate_operand" "i,i")))]
11170 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11171 "@
11172 jmp\t%P0
11173 jmp\t%A0"
11174 [(set_attr "type" "call")])
11175
11176 (define_expand "call"
11177 [(call (match_operand:QI 0 "" "")
11178 (match_operand 1 "" ""))
11179 (use (match_operand 2 "" ""))]
11180 ""
11181 {
11182 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11183 DONE;
11184 })
11185
11186 (define_expand "sibcall"
11187 [(call (match_operand:QI 0 "" "")
11188 (match_operand 1 "" ""))
11189 (use (match_operand 2 "" ""))]
11190 ""
11191 {
11192 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11193 DONE;
11194 })
11195
11196 (define_insn "*call_0"
11197 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11198 (match_operand 1 "" ""))]
11199 ""
11200 {
11201 if (SIBLING_CALL_P (insn))
11202 return "jmp\t%P0";
11203 else
11204 return "call\t%P0";
11205 }
11206 [(set_attr "type" "call")])
11207
11208 (define_insn "*call_1"
11209 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11210 (match_operand 1 "" ""))]
11211 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11212 {
11213 if (constant_call_address_operand (operands[0], Pmode))
11214 return "call\t%P0";
11215 return "call\t%A0";
11216 }
11217 [(set_attr "type" "call")])
11218
11219 (define_insn "*sibcall_1"
11220 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11221 (match_operand 1 "" ""))]
11222 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11223 "@
11224 jmp\t%P0
11225 jmp\t%A0"
11226 [(set_attr "type" "call")])
11227
11228 (define_insn "*call_1_rex64"
11229 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11230 (match_operand 1 "" ""))]
11231 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11232 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11233 {
11234 if (constant_call_address_operand (operands[0], Pmode))
11235 return "call\t%P0";
11236 return "call\t%A0";
11237 }
11238 [(set_attr "type" "call")])
11239
11240 (define_insn "*call_1_rex64_ms_sysv"
11241 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11242 (match_operand 1 "" ""))
11243 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11244 (clobber (reg:TI XMM6_REG))
11245 (clobber (reg:TI XMM7_REG))
11246 (clobber (reg:TI XMM8_REG))
11247 (clobber (reg:TI XMM9_REG))
11248 (clobber (reg:TI XMM10_REG))
11249 (clobber (reg:TI XMM11_REG))
11250 (clobber (reg:TI XMM12_REG))
11251 (clobber (reg:TI XMM13_REG))
11252 (clobber (reg:TI XMM14_REG))
11253 (clobber (reg:TI XMM15_REG))
11254 (clobber (reg:DI SI_REG))
11255 (clobber (reg:DI DI_REG))]
11256 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11257 {
11258 if (constant_call_address_operand (operands[0], Pmode))
11259 return "call\t%P0";
11260 return "call\t%A0";
11261 }
11262 [(set_attr "type" "call")])
11263
11264 (define_insn "*call_1_rex64_large"
11265 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11266 (match_operand 1 "" ""))]
11267 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11268 "call\t%A0"
11269 [(set_attr "type" "call")])
11270
11271 (define_insn "*sibcall_1_rex64"
11272 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11273 (match_operand 1 "" ""))]
11274 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11275 "@
11276 jmp\t%P0
11277 jmp\t%A0"
11278 [(set_attr "type" "call")])
11279
11280 ;; Call subroutine, returning value in operand 0
11281 (define_expand "call_value_pop"
11282 [(parallel [(set (match_operand 0 "" "")
11283 (call (match_operand:QI 1 "" "")
11284 (match_operand:SI 2 "" "")))
11285 (set (reg:SI SP_REG)
11286 (plus:SI (reg:SI SP_REG)
11287 (match_operand:SI 4 "" "")))])]
11288 "!TARGET_64BIT"
11289 {
11290 ix86_expand_call (operands[0], operands[1], operands[2],
11291 operands[3], operands[4], 0);
11292 DONE;
11293 })
11294
11295 (define_expand "call_value"
11296 [(set (match_operand 0 "" "")
11297 (call (match_operand:QI 1 "" "")
11298 (match_operand:SI 2 "" "")))
11299 (use (match_operand:SI 3 "" ""))]
11300 ;; Operand 3 is not used on the i386.
11301 ""
11302 {
11303 ix86_expand_call (operands[0], operands[1], operands[2],
11304 operands[3], NULL, 0);
11305 DONE;
11306 })
11307
11308 (define_expand "sibcall_value"
11309 [(set (match_operand 0 "" "")
11310 (call (match_operand:QI 1 "" "")
11311 (match_operand:SI 2 "" "")))
11312 (use (match_operand:SI 3 "" ""))]
11313 ;; Operand 3 is not used on the i386.
11314 ""
11315 {
11316 ix86_expand_call (operands[0], operands[1], operands[2],
11317 operands[3], NULL, 1);
11318 DONE;
11319 })
11320
11321 ;; Call subroutine returning any type.
11322
11323 (define_expand "untyped_call"
11324 [(parallel [(call (match_operand 0 "" "")
11325 (const_int 0))
11326 (match_operand 1 "" "")
11327 (match_operand 2 "" "")])]
11328 ""
11329 {
11330 int i;
11331
11332 /* In order to give reg-stack an easier job in validating two
11333 coprocessor registers as containing a possible return value,
11334 simply pretend the untyped call returns a complex long double
11335 value.
11336
11337 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11338 and should have the default ABI. */
11339
11340 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11341 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11342 operands[0], const0_rtx,
11343 GEN_INT ((TARGET_64BIT
11344 ? (ix86_abi == SYSV_ABI
11345 ? X86_64_SSE_REGPARM_MAX
11346 : X86_64_MS_SSE_REGPARM_MAX)
11347 : X86_32_SSE_REGPARM_MAX)
11348 - 1),
11349 NULL, 0);
11350
11351 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11352 {
11353 rtx set = XVECEXP (operands[2], 0, i);
11354 emit_move_insn (SET_DEST (set), SET_SRC (set));
11355 }
11356
11357 /* The optimizer does not know that the call sets the function value
11358 registers we stored in the result block. We avoid problems by
11359 claiming that all hard registers are used and clobbered at this
11360 point. */
11361 emit_insn (gen_blockage ());
11362
11363 DONE;
11364 })
11365 \f
11366 ;; Prologue and epilogue instructions
11367
11368 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11369 ;; all of memory. This blocks insns from being moved across this point.
11370
11371 (define_insn "blockage"
11372 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11373 ""
11374 ""
11375 [(set_attr "length" "0")])
11376
11377 ;; Do not schedule instructions accessing memory across this point.
11378
11379 (define_expand "memory_blockage"
11380 [(set (match_dup 0)
11381 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11382 ""
11383 {
11384 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11385 MEM_VOLATILE_P (operands[0]) = 1;
11386 })
11387
11388 (define_insn "*memory_blockage"
11389 [(set (match_operand:BLK 0 "" "")
11390 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11391 ""
11392 ""
11393 [(set_attr "length" "0")])
11394
11395 ;; As USE insns aren't meaningful after reload, this is used instead
11396 ;; to prevent deleting instructions setting registers for PIC code
11397 (define_insn "prologue_use"
11398 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11399 ""
11400 ""
11401 [(set_attr "length" "0")])
11402
11403 ;; Insn emitted into the body of a function to return from a function.
11404 ;; This is only done if the function's epilogue is known to be simple.
11405 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11406
11407 (define_expand "return"
11408 [(return)]
11409 "ix86_can_use_return_insn_p ()"
11410 {
11411 if (crtl->args.pops_args)
11412 {
11413 rtx popc = GEN_INT (crtl->args.pops_args);
11414 emit_jump_insn (gen_return_pop_internal (popc));
11415 DONE;
11416 }
11417 })
11418
11419 (define_insn "return_internal"
11420 [(return)]
11421 "reload_completed"
11422 "ret"
11423 [(set_attr "length" "1")
11424 (set_attr "atom_unit" "jeu")
11425 (set_attr "length_immediate" "0")
11426 (set_attr "modrm" "0")])
11427
11428 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11429 ;; instruction Athlon and K8 have.
11430
11431 (define_insn "return_internal_long"
11432 [(return)
11433 (unspec [(const_int 0)] UNSPEC_REP)]
11434 "reload_completed"
11435 "rep\;ret"
11436 [(set_attr "length" "2")
11437 (set_attr "atom_unit" "jeu")
11438 (set_attr "length_immediate" "0")
11439 (set_attr "prefix_rep" "1")
11440 (set_attr "modrm" "0")])
11441
11442 (define_insn "return_pop_internal"
11443 [(return)
11444 (use (match_operand:SI 0 "const_int_operand" ""))]
11445 "reload_completed"
11446 "ret\t%0"
11447 [(set_attr "length" "3")
11448 (set_attr "atom_unit" "jeu")
11449 (set_attr "length_immediate" "2")
11450 (set_attr "modrm" "0")])
11451
11452 (define_insn "return_indirect_internal"
11453 [(return)
11454 (use (match_operand:SI 0 "register_operand" "r"))]
11455 "reload_completed"
11456 "jmp\t%A0"
11457 [(set_attr "type" "ibr")
11458 (set_attr "length_immediate" "0")])
11459
11460 (define_insn "nop"
11461 [(const_int 0)]
11462 ""
11463 "nop"
11464 [(set_attr "length" "1")
11465 (set_attr "length_immediate" "0")
11466 (set_attr "modrm" "0")])
11467
11468 (define_insn "vswapmov"
11469 [(set (match_operand:SI 0 "register_operand" "=r")
11470 (match_operand:SI 1 "register_operand" "r"))
11471 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11472 ""
11473 "movl.s\t{%1, %0|%0, %1}"
11474 [(set_attr "length" "2")
11475 (set_attr "length_immediate" "0")
11476 (set_attr "modrm" "0")])
11477
11478 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11479 ;; branch prediction penalty for the third jump in a 16-byte
11480 ;; block on K8.
11481
11482 (define_insn "pad"
11483 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11484 ""
11485 {
11486 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11487 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11488 #else
11489 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11490 The align insn is used to avoid 3 jump instructions in the row to improve
11491 branch prediction and the benefits hardly outweigh the cost of extra 8
11492 nops on the average inserted by full alignment pseudo operation. */
11493 #endif
11494 return "";
11495 }
11496 [(set_attr "length" "16")])
11497
11498 (define_expand "prologue"
11499 [(const_int 0)]
11500 ""
11501 "ix86_expand_prologue (); DONE;")
11502
11503 (define_insn "set_got"
11504 [(set (match_operand:SI 0 "register_operand" "=r")
11505 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11506 (clobber (reg:CC FLAGS_REG))]
11507 "!TARGET_64BIT"
11508 { return output_set_got (operands[0], NULL_RTX); }
11509 [(set_attr "type" "multi")
11510 (set_attr "length" "12")])
11511
11512 (define_insn "set_got_labelled"
11513 [(set (match_operand:SI 0 "register_operand" "=r")
11514 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11515 UNSPEC_SET_GOT))
11516 (clobber (reg:CC FLAGS_REG))]
11517 "!TARGET_64BIT"
11518 { return output_set_got (operands[0], operands[1]); }
11519 [(set_attr "type" "multi")
11520 (set_attr "length" "12")])
11521
11522 (define_insn "set_got_rex64"
11523 [(set (match_operand:DI 0 "register_operand" "=r")
11524 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11525 "TARGET_64BIT"
11526 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11527 [(set_attr "type" "lea")
11528 (set_attr "length_address" "4")
11529 (set_attr "mode" "DI")])
11530
11531 (define_insn "set_rip_rex64"
11532 [(set (match_operand:DI 0 "register_operand" "=r")
11533 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11534 "TARGET_64BIT"
11535 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11536 [(set_attr "type" "lea")
11537 (set_attr "length_address" "4")
11538 (set_attr "mode" "DI")])
11539
11540 (define_insn "set_got_offset_rex64"
11541 [(set (match_operand:DI 0 "register_operand" "=r")
11542 (unspec:DI
11543 [(label_ref (match_operand 1 "" ""))]
11544 UNSPEC_SET_GOT_OFFSET))]
11545 "TARGET_64BIT"
11546 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11547 [(set_attr "type" "imov")
11548 (set_attr "length_immediate" "0")
11549 (set_attr "length_address" "8")
11550 (set_attr "mode" "DI")])
11551
11552 (define_expand "epilogue"
11553 [(const_int 0)]
11554 ""
11555 "ix86_expand_epilogue (1); DONE;")
11556
11557 (define_expand "sibcall_epilogue"
11558 [(const_int 0)]
11559 ""
11560 "ix86_expand_epilogue (0); DONE;")
11561
11562 (define_expand "eh_return"
11563 [(use (match_operand 0 "register_operand" ""))]
11564 ""
11565 {
11566 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11567
11568 /* Tricky bit: we write the address of the handler to which we will
11569 be returning into someone else's stack frame, one word below the
11570 stack address we wish to restore. */
11571 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11572 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11573 tmp = gen_rtx_MEM (Pmode, tmp);
11574 emit_move_insn (tmp, ra);
11575
11576 emit_jump_insn (gen_eh_return_internal ());
11577 emit_barrier ();
11578 DONE;
11579 })
11580
11581 (define_insn_and_split "eh_return_internal"
11582 [(eh_return)]
11583 ""
11584 "#"
11585 "epilogue_completed"
11586 [(const_int 0)]
11587 "ix86_expand_epilogue (2); DONE;")
11588
11589 (define_insn "leave"
11590 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11591 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11592 (clobber (mem:BLK (scratch)))]
11593 "!TARGET_64BIT"
11594 "leave"
11595 [(set_attr "type" "leave")])
11596
11597 (define_insn "leave_rex64"
11598 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11599 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11600 (clobber (mem:BLK (scratch)))]
11601 "TARGET_64BIT"
11602 "leave"
11603 [(set_attr "type" "leave")])
11604 \f
11605 ;; Bit manipulation instructions.
11606
11607 (define_expand "ffs<mode>2"
11608 [(set (match_dup 2) (const_int -1))
11609 (parallel [(set (reg:CCZ FLAGS_REG)
11610 (compare:CCZ
11611 (match_operand:SWI48 1 "nonimmediate_operand" "")
11612 (const_int 0)))
11613 (set (match_operand:SWI48 0 "register_operand" "")
11614 (ctz:SWI48 (match_dup 1)))])
11615 (set (match_dup 0) (if_then_else:SWI48
11616 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11617 (match_dup 2)
11618 (match_dup 0)))
11619 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11620 (clobber (reg:CC FLAGS_REG))])]
11621 ""
11622 {
11623 if (<MODE>mode == SImode && !TARGET_CMOVE)
11624 {
11625 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11626 DONE;
11627 }
11628 operands[2] = gen_reg_rtx (<MODE>mode);
11629 })
11630
11631 (define_insn_and_split "ffssi2_no_cmove"
11632 [(set (match_operand:SI 0 "register_operand" "=r")
11633 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11634 (clobber (match_scratch:SI 2 "=&q"))
11635 (clobber (reg:CC FLAGS_REG))]
11636 "!TARGET_CMOVE"
11637 "#"
11638 "&& reload_completed"
11639 [(parallel [(set (reg:CCZ FLAGS_REG)
11640 (compare:CCZ (match_dup 1) (const_int 0)))
11641 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11642 (set (strict_low_part (match_dup 3))
11643 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11644 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11645 (clobber (reg:CC FLAGS_REG))])
11646 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11647 (clobber (reg:CC FLAGS_REG))])
11648 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11649 (clobber (reg:CC FLAGS_REG))])]
11650 {
11651 operands[3] = gen_lowpart (QImode, operands[2]);
11652 ix86_expand_clear (operands[2]);
11653 })
11654
11655 (define_insn "*ffs<mode>_1"
11656 [(set (reg:CCZ FLAGS_REG)
11657 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11658 (const_int 0)))
11659 (set (match_operand:SWI48 0 "register_operand" "=r")
11660 (ctz:SWI48 (match_dup 1)))]
11661 ""
11662 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11663 [(set_attr "type" "alu1")
11664 (set_attr "prefix_0f" "1")
11665 (set_attr "mode" "<MODE>")])
11666
11667 (define_insn "ctz<mode>2"
11668 [(set (match_operand:SWI48 0 "register_operand" "=r")
11669 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11670 (clobber (reg:CC FLAGS_REG))]
11671 ""
11672 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11673 [(set_attr "type" "alu1")
11674 (set_attr "prefix_0f" "1")
11675 (set_attr "mode" "<MODE>")])
11676
11677 (define_expand "clz<mode>2"
11678 [(parallel
11679 [(set (match_operand:SWI248 0 "register_operand" "")
11680 (minus:SWI248
11681 (match_dup 2)
11682 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11683 (clobber (reg:CC FLAGS_REG))])
11684 (parallel
11685 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11686 (clobber (reg:CC FLAGS_REG))])]
11687 ""
11688 {
11689 if (TARGET_ABM)
11690 {
11691 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11692 DONE;
11693 }
11694 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11695 })
11696
11697 (define_insn "clz<mode>2_abm"
11698 [(set (match_operand:SWI248 0 "register_operand" "=r")
11699 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11700 (clobber (reg:CC FLAGS_REG))]
11701 "TARGET_ABM"
11702 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11703 [(set_attr "prefix_rep" "1")
11704 (set_attr "type" "bitmanip")
11705 (set_attr "mode" "<MODE>")])
11706
11707 (define_insn "bsr_rex64"
11708 [(set (match_operand:DI 0 "register_operand" "=r")
11709 (minus:DI (const_int 63)
11710 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11711 (clobber (reg:CC FLAGS_REG))]
11712 "TARGET_64BIT"
11713 "bsr{q}\t{%1, %0|%0, %1}"
11714 [(set_attr "type" "alu1")
11715 (set_attr "prefix_0f" "1")
11716 (set_attr "mode" "DI")])
11717
11718 (define_insn "bsr"
11719 [(set (match_operand:SI 0 "register_operand" "=r")
11720 (minus:SI (const_int 31)
11721 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11722 (clobber (reg:CC FLAGS_REG))]
11723 ""
11724 "bsr{l}\t{%1, %0|%0, %1}"
11725 [(set_attr "type" "alu1")
11726 (set_attr "prefix_0f" "1")
11727 (set_attr "mode" "SI")])
11728
11729 (define_insn "*bsrhi"
11730 [(set (match_operand:HI 0 "register_operand" "=r")
11731 (minus:HI (const_int 15)
11732 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11733 (clobber (reg:CC FLAGS_REG))]
11734 ""
11735 "bsr{w}\t{%1, %0|%0, %1}"
11736 [(set_attr "type" "alu1")
11737 (set_attr "prefix_0f" "1")
11738 (set_attr "mode" "HI")])
11739
11740 (define_insn "popcount<mode>2"
11741 [(set (match_operand:SWI248 0 "register_operand" "=r")
11742 (popcount:SWI248
11743 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11744 (clobber (reg:CC FLAGS_REG))]
11745 "TARGET_POPCNT"
11746 {
11747 #if TARGET_MACHO
11748 return "popcnt\t{%1, %0|%0, %1}";
11749 #else
11750 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11751 #endif
11752 }
11753 [(set_attr "prefix_rep" "1")
11754 (set_attr "type" "bitmanip")
11755 (set_attr "mode" "<MODE>")])
11756
11757 (define_insn "*popcount<mode>2_cmp"
11758 [(set (reg FLAGS_REG)
11759 (compare
11760 (popcount:SWI248
11761 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11762 (const_int 0)))
11763 (set (match_operand:SWI248 0 "register_operand" "=r")
11764 (popcount:SWI248 (match_dup 1)))]
11765 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11766 {
11767 #if TARGET_MACHO
11768 return "popcnt\t{%1, %0|%0, %1}";
11769 #else
11770 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11771 #endif
11772 }
11773 [(set_attr "prefix_rep" "1")
11774 (set_attr "type" "bitmanip")
11775 (set_attr "mode" "<MODE>")])
11776
11777 (define_insn "*popcountsi2_cmp_zext"
11778 [(set (reg FLAGS_REG)
11779 (compare
11780 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11781 (const_int 0)))
11782 (set (match_operand:DI 0 "register_operand" "=r")
11783 (zero_extend:DI(popcount:SI (match_dup 1))))]
11784 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11785 {
11786 #if TARGET_MACHO
11787 return "popcnt\t{%1, %0|%0, %1}";
11788 #else
11789 return "popcnt{l}\t{%1, %0|%0, %1}";
11790 #endif
11791 }
11792 [(set_attr "prefix_rep" "1")
11793 (set_attr "type" "bitmanip")
11794 (set_attr "mode" "SI")])
11795
11796 (define_expand "bswap<mode>2"
11797 [(set (match_operand:SWI48 0 "register_operand" "")
11798 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11799 ""
11800 {
11801 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11802 {
11803 rtx x = operands[0];
11804
11805 emit_move_insn (x, operands[1]);
11806 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11807 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11808 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11809 DONE;
11810 }
11811 })
11812
11813 (define_insn "*bswap<mode>2_movbe"
11814 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11815 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11816 "TARGET_MOVBE
11817 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11818 "@
11819 bswap\t%0
11820 movbe\t{%1, %0|%0, %1}
11821 movbe\t{%1, %0|%0, %1}"
11822 [(set_attr "type" "bitmanip,imov,imov")
11823 (set_attr "modrm" "0,1,1")
11824 (set_attr "prefix_0f" "*,1,1")
11825 (set_attr "prefix_extra" "*,1,1")
11826 (set_attr "mode" "<MODE>")])
11827
11828 (define_insn "*bswap<mode>2_1"
11829 [(set (match_operand:SWI48 0 "register_operand" "=r")
11830 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11831 "TARGET_BSWAP"
11832 "bswap\t%0"
11833 [(set_attr "type" "bitmanip")
11834 (set_attr "modrm" "0")
11835 (set_attr "mode" "<MODE>")])
11836
11837 (define_insn "*bswaphi_lowpart_1"
11838 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11839 (bswap:HI (match_dup 0)))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11842 "@
11843 xchg{b}\t{%h0, %b0|%b0, %h0}
11844 rol{w}\t{$8, %0|%0, 8}"
11845 [(set_attr "length" "2,4")
11846 (set_attr "mode" "QI,HI")])
11847
11848 (define_insn "bswaphi_lowpart"
11849 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11850 (bswap:HI (match_dup 0)))
11851 (clobber (reg:CC FLAGS_REG))]
11852 ""
11853 "rol{w}\t{$8, %0|%0, 8}"
11854 [(set_attr "length" "4")
11855 (set_attr "mode" "HI")])
11856
11857 (define_expand "paritydi2"
11858 [(set (match_operand:DI 0 "register_operand" "")
11859 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11860 "! TARGET_POPCNT"
11861 {
11862 rtx scratch = gen_reg_rtx (QImode);
11863 rtx cond;
11864
11865 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11866 NULL_RTX, operands[1]));
11867
11868 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11869 gen_rtx_REG (CCmode, FLAGS_REG),
11870 const0_rtx);
11871 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11872
11873 if (TARGET_64BIT)
11874 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11875 else
11876 {
11877 rtx tmp = gen_reg_rtx (SImode);
11878
11879 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11880 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11881 }
11882 DONE;
11883 })
11884
11885 (define_expand "paritysi2"
11886 [(set (match_operand:SI 0 "register_operand" "")
11887 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11888 "! TARGET_POPCNT"
11889 {
11890 rtx scratch = gen_reg_rtx (QImode);
11891 rtx cond;
11892
11893 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11894
11895 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11896 gen_rtx_REG (CCmode, FLAGS_REG),
11897 const0_rtx);
11898 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11899
11900 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11901 DONE;
11902 })
11903
11904 (define_insn_and_split "paritydi2_cmp"
11905 [(set (reg:CC FLAGS_REG)
11906 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11907 UNSPEC_PARITY))
11908 (clobber (match_scratch:DI 0 "=r"))
11909 (clobber (match_scratch:SI 1 "=&r"))
11910 (clobber (match_scratch:HI 2 "=Q"))]
11911 "! TARGET_POPCNT"
11912 "#"
11913 "&& reload_completed"
11914 [(parallel
11915 [(set (match_dup 1)
11916 (xor:SI (match_dup 1) (match_dup 4)))
11917 (clobber (reg:CC FLAGS_REG))])
11918 (parallel
11919 [(set (reg:CC FLAGS_REG)
11920 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11921 (clobber (match_dup 1))
11922 (clobber (match_dup 2))])]
11923 {
11924 operands[4] = gen_lowpart (SImode, operands[3]);
11925
11926 if (TARGET_64BIT)
11927 {
11928 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11929 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11930 }
11931 else
11932 operands[1] = gen_highpart (SImode, operands[3]);
11933 })
11934
11935 (define_insn_and_split "paritysi2_cmp"
11936 [(set (reg:CC FLAGS_REG)
11937 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
11938 UNSPEC_PARITY))
11939 (clobber (match_scratch:SI 0 "=r"))
11940 (clobber (match_scratch:HI 1 "=&Q"))]
11941 "! TARGET_POPCNT"
11942 "#"
11943 "&& reload_completed"
11944 [(parallel
11945 [(set (match_dup 1)
11946 (xor:HI (match_dup 1) (match_dup 3)))
11947 (clobber (reg:CC FLAGS_REG))])
11948 (parallel
11949 [(set (reg:CC FLAGS_REG)
11950 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11951 (clobber (match_dup 1))])]
11952 {
11953 operands[3] = gen_lowpart (HImode, operands[2]);
11954
11955 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
11956 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
11957 })
11958
11959 (define_insn "*parityhi2_cmp"
11960 [(set (reg:CC FLAGS_REG)
11961 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
11962 UNSPEC_PARITY))
11963 (clobber (match_scratch:HI 0 "=Q"))]
11964 "! TARGET_POPCNT"
11965 "xor{b}\t{%h0, %b0|%b0, %h0}"
11966 [(set_attr "length" "2")
11967 (set_attr "mode" "HI")])
11968 \f
11969 ;; Thread-local storage patterns for ELF.
11970 ;;
11971 ;; Note that these code sequences must appear exactly as shown
11972 ;; in order to allow linker relaxation.
11973
11974 (define_insn "*tls_global_dynamic_32_gnu"
11975 [(set (match_operand:SI 0 "register_operand" "=a")
11976 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11977 (match_operand:SI 2 "tls_symbolic_operand" "")
11978 (match_operand:SI 3 "call_insn_operand" "")]
11979 UNSPEC_TLS_GD))
11980 (clobber (match_scratch:SI 4 "=d"))
11981 (clobber (match_scratch:SI 5 "=c"))
11982 (clobber (reg:CC FLAGS_REG))]
11983 "!TARGET_64BIT && TARGET_GNU_TLS"
11984 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
11985 [(set_attr "type" "multi")
11986 (set_attr "length" "12")])
11987
11988 (define_expand "tls_global_dynamic_32"
11989 [(parallel [(set (match_operand:SI 0 "register_operand" "")
11990 (unspec:SI
11991 [(match_dup 2)
11992 (match_operand:SI 1 "tls_symbolic_operand" "")
11993 (match_dup 3)]
11994 UNSPEC_TLS_GD))
11995 (clobber (match_scratch:SI 4 ""))
11996 (clobber (match_scratch:SI 5 ""))
11997 (clobber (reg:CC FLAGS_REG))])]
11998 ""
11999 {
12000 if (flag_pic)
12001 operands[2] = pic_offset_table_rtx;
12002 else
12003 {
12004 operands[2] = gen_reg_rtx (Pmode);
12005 emit_insn (gen_set_got (operands[2]));
12006 }
12007 if (TARGET_GNU2_TLS)
12008 {
12009 emit_insn (gen_tls_dynamic_gnu2_32
12010 (operands[0], operands[1], operands[2]));
12011 DONE;
12012 }
12013 operands[3] = ix86_tls_get_addr ();
12014 })
12015
12016 (define_insn "*tls_global_dynamic_64"
12017 [(set (match_operand:DI 0 "register_operand" "=a")
12018 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12019 (match_operand:DI 3 "" "")))
12020 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12021 UNSPEC_TLS_GD)]
12022 "TARGET_64BIT"
12023 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12024 [(set_attr "type" "multi")
12025 (set_attr "length" "16")])
12026
12027 (define_expand "tls_global_dynamic_64"
12028 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12029 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12030 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12031 UNSPEC_TLS_GD)])]
12032 ""
12033 {
12034 if (TARGET_GNU2_TLS)
12035 {
12036 emit_insn (gen_tls_dynamic_gnu2_64
12037 (operands[0], operands[1]));
12038 DONE;
12039 }
12040 operands[2] = ix86_tls_get_addr ();
12041 })
12042
12043 (define_insn "*tls_local_dynamic_base_32_gnu"
12044 [(set (match_operand:SI 0 "register_operand" "=a")
12045 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12046 (match_operand:SI 2 "call_insn_operand" "")]
12047 UNSPEC_TLS_LD_BASE))
12048 (clobber (match_scratch:SI 3 "=d"))
12049 (clobber (match_scratch:SI 4 "=c"))
12050 (clobber (reg:CC FLAGS_REG))]
12051 "!TARGET_64BIT && TARGET_GNU_TLS"
12052 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12053 [(set_attr "type" "multi")
12054 (set_attr "length" "11")])
12055
12056 (define_expand "tls_local_dynamic_base_32"
12057 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12058 (unspec:SI [(match_dup 1) (match_dup 2)]
12059 UNSPEC_TLS_LD_BASE))
12060 (clobber (match_scratch:SI 3 ""))
12061 (clobber (match_scratch:SI 4 ""))
12062 (clobber (reg:CC FLAGS_REG))])]
12063 ""
12064 {
12065 if (flag_pic)
12066 operands[1] = pic_offset_table_rtx;
12067 else
12068 {
12069 operands[1] = gen_reg_rtx (Pmode);
12070 emit_insn (gen_set_got (operands[1]));
12071 }
12072 if (TARGET_GNU2_TLS)
12073 {
12074 emit_insn (gen_tls_dynamic_gnu2_32
12075 (operands[0], ix86_tls_module_base (), operands[1]));
12076 DONE;
12077 }
12078 operands[2] = ix86_tls_get_addr ();
12079 })
12080
12081 (define_insn "*tls_local_dynamic_base_64"
12082 [(set (match_operand:DI 0 "register_operand" "=a")
12083 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12084 (match_operand:DI 2 "" "")))
12085 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12086 "TARGET_64BIT"
12087 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12088 [(set_attr "type" "multi")
12089 (set_attr "length" "12")])
12090
12091 (define_expand "tls_local_dynamic_base_64"
12092 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12093 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12094 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12095 ""
12096 {
12097 if (TARGET_GNU2_TLS)
12098 {
12099 emit_insn (gen_tls_dynamic_gnu2_64
12100 (operands[0], ix86_tls_module_base ()));
12101 DONE;
12102 }
12103 operands[1] = ix86_tls_get_addr ();
12104 })
12105
12106 ;; Local dynamic of a single variable is a lose. Show combine how
12107 ;; to convert that back to global dynamic.
12108
12109 (define_insn_and_split "*tls_local_dynamic_32_once"
12110 [(set (match_operand:SI 0 "register_operand" "=a")
12111 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12112 (match_operand:SI 2 "call_insn_operand" "")]
12113 UNSPEC_TLS_LD_BASE)
12114 (const:SI (unspec:SI
12115 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12116 UNSPEC_DTPOFF))))
12117 (clobber (match_scratch:SI 4 "=d"))
12118 (clobber (match_scratch:SI 5 "=c"))
12119 (clobber (reg:CC FLAGS_REG))]
12120 ""
12121 "#"
12122 ""
12123 [(parallel [(set (match_dup 0)
12124 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12125 UNSPEC_TLS_GD))
12126 (clobber (match_dup 4))
12127 (clobber (match_dup 5))
12128 (clobber (reg:CC FLAGS_REG))])]
12129 "")
12130
12131 ;; Load and add the thread base pointer from %gs:0.
12132
12133 (define_insn "*load_tp_si"
12134 [(set (match_operand:SI 0 "register_operand" "=r")
12135 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12136 "!TARGET_64BIT"
12137 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12138 [(set_attr "type" "imov")
12139 (set_attr "modrm" "0")
12140 (set_attr "length" "7")
12141 (set_attr "memory" "load")
12142 (set_attr "imm_disp" "false")])
12143
12144 (define_insn "*add_tp_si"
12145 [(set (match_operand:SI 0 "register_operand" "=r")
12146 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12147 (match_operand:SI 1 "register_operand" "0")))
12148 (clobber (reg:CC FLAGS_REG))]
12149 "!TARGET_64BIT"
12150 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12151 [(set_attr "type" "alu")
12152 (set_attr "modrm" "0")
12153 (set_attr "length" "7")
12154 (set_attr "memory" "load")
12155 (set_attr "imm_disp" "false")])
12156
12157 (define_insn "*load_tp_di"
12158 [(set (match_operand:DI 0 "register_operand" "=r")
12159 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12160 "TARGET_64BIT"
12161 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12162 [(set_attr "type" "imov")
12163 (set_attr "modrm" "0")
12164 (set_attr "length" "7")
12165 (set_attr "memory" "load")
12166 (set_attr "imm_disp" "false")])
12167
12168 (define_insn "*add_tp_di"
12169 [(set (match_operand:DI 0 "register_operand" "=r")
12170 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12171 (match_operand:DI 1 "register_operand" "0")))
12172 (clobber (reg:CC FLAGS_REG))]
12173 "TARGET_64BIT"
12174 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12175 [(set_attr "type" "alu")
12176 (set_attr "modrm" "0")
12177 (set_attr "length" "7")
12178 (set_attr "memory" "load")
12179 (set_attr "imm_disp" "false")])
12180
12181 ;; GNU2 TLS patterns can be split.
12182
12183 (define_expand "tls_dynamic_gnu2_32"
12184 [(set (match_dup 3)
12185 (plus:SI (match_operand:SI 2 "register_operand" "")
12186 (const:SI
12187 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12188 UNSPEC_TLSDESC))))
12189 (parallel
12190 [(set (match_operand:SI 0 "register_operand" "")
12191 (unspec:SI [(match_dup 1) (match_dup 3)
12192 (match_dup 2) (reg:SI SP_REG)]
12193 UNSPEC_TLSDESC))
12194 (clobber (reg:CC FLAGS_REG))])]
12195 "!TARGET_64BIT && TARGET_GNU2_TLS"
12196 {
12197 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12198 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12199 })
12200
12201 (define_insn "*tls_dynamic_lea_32"
12202 [(set (match_operand:SI 0 "register_operand" "=r")
12203 (plus:SI (match_operand:SI 1 "register_operand" "b")
12204 (const:SI
12205 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12206 UNSPEC_TLSDESC))))]
12207 "!TARGET_64BIT && TARGET_GNU2_TLS"
12208 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12209 [(set_attr "type" "lea")
12210 (set_attr "mode" "SI")
12211 (set_attr "length" "6")
12212 (set_attr "length_address" "4")])
12213
12214 (define_insn "*tls_dynamic_call_32"
12215 [(set (match_operand:SI 0 "register_operand" "=a")
12216 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12217 (match_operand:SI 2 "register_operand" "0")
12218 ;; we have to make sure %ebx still points to the GOT
12219 (match_operand:SI 3 "register_operand" "b")
12220 (reg:SI SP_REG)]
12221 UNSPEC_TLSDESC))
12222 (clobber (reg:CC FLAGS_REG))]
12223 "!TARGET_64BIT && TARGET_GNU2_TLS"
12224 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12225 [(set_attr "type" "call")
12226 (set_attr "length" "2")
12227 (set_attr "length_address" "0")])
12228
12229 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12230 [(set (match_operand:SI 0 "register_operand" "=&a")
12231 (plus:SI
12232 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12233 (match_operand:SI 4 "" "")
12234 (match_operand:SI 2 "register_operand" "b")
12235 (reg:SI SP_REG)]
12236 UNSPEC_TLSDESC)
12237 (const:SI (unspec:SI
12238 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12239 UNSPEC_DTPOFF))))
12240 (clobber (reg:CC FLAGS_REG))]
12241 "!TARGET_64BIT && TARGET_GNU2_TLS"
12242 "#"
12243 ""
12244 [(set (match_dup 0) (match_dup 5))]
12245 {
12246 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12247 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12248 })
12249
12250 (define_expand "tls_dynamic_gnu2_64"
12251 [(set (match_dup 2)
12252 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12253 UNSPEC_TLSDESC))
12254 (parallel
12255 [(set (match_operand:DI 0 "register_operand" "")
12256 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12257 UNSPEC_TLSDESC))
12258 (clobber (reg:CC FLAGS_REG))])]
12259 "TARGET_64BIT && TARGET_GNU2_TLS"
12260 {
12261 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12262 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12263 })
12264
12265 (define_insn "*tls_dynamic_lea_64"
12266 [(set (match_operand:DI 0 "register_operand" "=r")
12267 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12268 UNSPEC_TLSDESC))]
12269 "TARGET_64BIT && TARGET_GNU2_TLS"
12270 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12271 [(set_attr "type" "lea")
12272 (set_attr "mode" "DI")
12273 (set_attr "length" "7")
12274 (set_attr "length_address" "4")])
12275
12276 (define_insn "*tls_dynamic_call_64"
12277 [(set (match_operand:DI 0 "register_operand" "=a")
12278 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12279 (match_operand:DI 2 "register_operand" "0")
12280 (reg:DI SP_REG)]
12281 UNSPEC_TLSDESC))
12282 (clobber (reg:CC FLAGS_REG))]
12283 "TARGET_64BIT && TARGET_GNU2_TLS"
12284 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12285 [(set_attr "type" "call")
12286 (set_attr "length" "2")
12287 (set_attr "length_address" "0")])
12288
12289 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12290 [(set (match_operand:DI 0 "register_operand" "=&a")
12291 (plus:DI
12292 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12293 (match_operand:DI 3 "" "")
12294 (reg:DI SP_REG)]
12295 UNSPEC_TLSDESC)
12296 (const:DI (unspec:DI
12297 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12298 UNSPEC_DTPOFF))))
12299 (clobber (reg:CC FLAGS_REG))]
12300 "TARGET_64BIT && TARGET_GNU2_TLS"
12301 "#"
12302 ""
12303 [(set (match_dup 0) (match_dup 4))]
12304 {
12305 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12306 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12307 })
12308
12309 ;;
12310 \f
12311 ;; These patterns match the binary 387 instructions for addM3, subM3,
12312 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12313 ;; SFmode. The first is the normal insn, the second the same insn but
12314 ;; with one operand a conversion, and the third the same insn but with
12315 ;; the other operand a conversion. The conversion may be SFmode or
12316 ;; SImode if the target mode DFmode, but only SImode if the target mode
12317 ;; is SFmode.
12318
12319 ;; Gcc is slightly more smart about handling normal two address instructions
12320 ;; so use special patterns for add and mull.
12321
12322 (define_insn "*fop_<mode>_comm_mixed_avx"
12323 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12324 (match_operator:MODEF 3 "binary_fp_operator"
12325 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12326 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12327 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12328 && COMMUTATIVE_ARITH_P (operands[3])
12329 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12330 "* return output_387_binary_op (insn, operands);"
12331 [(set (attr "type")
12332 (if_then_else (eq_attr "alternative" "1")
12333 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12334 (const_string "ssemul")
12335 (const_string "sseadd"))
12336 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12337 (const_string "fmul")
12338 (const_string "fop"))))
12339 (set_attr "prefix" "orig,maybe_vex")
12340 (set_attr "mode" "<MODE>")])
12341
12342 (define_insn "*fop_<mode>_comm_mixed"
12343 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12344 (match_operator:MODEF 3 "binary_fp_operator"
12345 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12346 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12347 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12348 && COMMUTATIVE_ARITH_P (operands[3])
12349 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12350 "* return output_387_binary_op (insn, operands);"
12351 [(set (attr "type")
12352 (if_then_else (eq_attr "alternative" "1")
12353 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12354 (const_string "ssemul")
12355 (const_string "sseadd"))
12356 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12357 (const_string "fmul")
12358 (const_string "fop"))))
12359 (set_attr "mode" "<MODE>")])
12360
12361 (define_insn "*fop_<mode>_comm_avx"
12362 [(set (match_operand:MODEF 0 "register_operand" "=x")
12363 (match_operator:MODEF 3 "binary_fp_operator"
12364 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12365 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12366 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12367 && COMMUTATIVE_ARITH_P (operands[3])
12368 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12369 "* return output_387_binary_op (insn, operands);"
12370 [(set (attr "type")
12371 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12372 (const_string "ssemul")
12373 (const_string "sseadd")))
12374 (set_attr "prefix" "vex")
12375 (set_attr "mode" "<MODE>")])
12376
12377 (define_insn "*fop_<mode>_comm_sse"
12378 [(set (match_operand:MODEF 0 "register_operand" "=x")
12379 (match_operator:MODEF 3 "binary_fp_operator"
12380 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12381 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12382 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12383 && COMMUTATIVE_ARITH_P (operands[3])
12384 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12385 "* return output_387_binary_op (insn, operands);"
12386 [(set (attr "type")
12387 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12388 (const_string "ssemul")
12389 (const_string "sseadd")))
12390 (set_attr "mode" "<MODE>")])
12391
12392 (define_insn "*fop_<mode>_comm_i387"
12393 [(set (match_operand:MODEF 0 "register_operand" "=f")
12394 (match_operator:MODEF 3 "binary_fp_operator"
12395 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12396 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12397 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12398 && COMMUTATIVE_ARITH_P (operands[3])
12399 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12400 "* return output_387_binary_op (insn, operands);"
12401 [(set (attr "type")
12402 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12403 (const_string "fmul")
12404 (const_string "fop")))
12405 (set_attr "mode" "<MODE>")])
12406
12407 (define_insn "*fop_<mode>_1_mixed_avx"
12408 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12409 (match_operator:MODEF 3 "binary_fp_operator"
12410 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12411 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12412 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12413 && !COMMUTATIVE_ARITH_P (operands[3])
12414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12415 "* return output_387_binary_op (insn, operands);"
12416 [(set (attr "type")
12417 (cond [(and (eq_attr "alternative" "2")
12418 (match_operand:MODEF 3 "mult_operator" ""))
12419 (const_string "ssemul")
12420 (and (eq_attr "alternative" "2")
12421 (match_operand:MODEF 3 "div_operator" ""))
12422 (const_string "ssediv")
12423 (eq_attr "alternative" "2")
12424 (const_string "sseadd")
12425 (match_operand:MODEF 3 "mult_operator" "")
12426 (const_string "fmul")
12427 (match_operand:MODEF 3 "div_operator" "")
12428 (const_string "fdiv")
12429 ]
12430 (const_string "fop")))
12431 (set_attr "prefix" "orig,orig,maybe_vex")
12432 (set_attr "mode" "<MODE>")])
12433
12434 (define_insn "*fop_<mode>_1_mixed"
12435 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12436 (match_operator:MODEF 3 "binary_fp_operator"
12437 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12438 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12439 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12440 && !COMMUTATIVE_ARITH_P (operands[3])
12441 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12442 "* return output_387_binary_op (insn, operands);"
12443 [(set (attr "type")
12444 (cond [(and (eq_attr "alternative" "2")
12445 (match_operand:MODEF 3 "mult_operator" ""))
12446 (const_string "ssemul")
12447 (and (eq_attr "alternative" "2")
12448 (match_operand:MODEF 3 "div_operator" ""))
12449 (const_string "ssediv")
12450 (eq_attr "alternative" "2")
12451 (const_string "sseadd")
12452 (match_operand:MODEF 3 "mult_operator" "")
12453 (const_string "fmul")
12454 (match_operand:MODEF 3 "div_operator" "")
12455 (const_string "fdiv")
12456 ]
12457 (const_string "fop")))
12458 (set_attr "mode" "<MODE>")])
12459
12460 (define_insn "*rcpsf2_sse"
12461 [(set (match_operand:SF 0 "register_operand" "=x")
12462 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12463 UNSPEC_RCP))]
12464 "TARGET_SSE_MATH"
12465 "%vrcpss\t{%1, %d0|%d0, %1}"
12466 [(set_attr "type" "sse")
12467 (set_attr "atom_sse_attr" "rcp")
12468 (set_attr "prefix" "maybe_vex")
12469 (set_attr "mode" "SF")])
12470
12471 (define_insn "*fop_<mode>_1_avx"
12472 [(set (match_operand:MODEF 0 "register_operand" "=x")
12473 (match_operator:MODEF 3 "binary_fp_operator"
12474 [(match_operand:MODEF 1 "register_operand" "x")
12475 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12476 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12477 && !COMMUTATIVE_ARITH_P (operands[3])"
12478 "* return output_387_binary_op (insn, operands);"
12479 [(set (attr "type")
12480 (cond [(match_operand:MODEF 3 "mult_operator" "")
12481 (const_string "ssemul")
12482 (match_operand:MODEF 3 "div_operator" "")
12483 (const_string "ssediv")
12484 ]
12485 (const_string "sseadd")))
12486 (set_attr "prefix" "vex")
12487 (set_attr "mode" "<MODE>")])
12488
12489 (define_insn "*fop_<mode>_1_sse"
12490 [(set (match_operand:MODEF 0 "register_operand" "=x")
12491 (match_operator:MODEF 3 "binary_fp_operator"
12492 [(match_operand:MODEF 1 "register_operand" "0")
12493 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12494 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12495 && !COMMUTATIVE_ARITH_P (operands[3])"
12496 "* return output_387_binary_op (insn, operands);"
12497 [(set (attr "type")
12498 (cond [(match_operand:MODEF 3 "mult_operator" "")
12499 (const_string "ssemul")
12500 (match_operand:MODEF 3 "div_operator" "")
12501 (const_string "ssediv")
12502 ]
12503 (const_string "sseadd")))
12504 (set_attr "mode" "<MODE>")])
12505
12506 ;; This pattern is not fully shadowed by the pattern above.
12507 (define_insn "*fop_<mode>_1_i387"
12508 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12509 (match_operator:MODEF 3 "binary_fp_operator"
12510 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12511 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12512 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12513 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12514 && !COMMUTATIVE_ARITH_P (operands[3])
12515 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12516 "* return output_387_binary_op (insn, operands);"
12517 [(set (attr "type")
12518 (cond [(match_operand:MODEF 3 "mult_operator" "")
12519 (const_string "fmul")
12520 (match_operand:MODEF 3 "div_operator" "")
12521 (const_string "fdiv")
12522 ]
12523 (const_string "fop")))
12524 (set_attr "mode" "<MODE>")])
12525
12526 ;; ??? Add SSE splitters for these!
12527 (define_insn "*fop_<MODEF:mode>_2_i387"
12528 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12529 (match_operator:MODEF 3 "binary_fp_operator"
12530 [(float:MODEF
12531 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12532 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12533 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12534 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12535 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12536 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12537 [(set (attr "type")
12538 (cond [(match_operand:MODEF 3 "mult_operator" "")
12539 (const_string "fmul")
12540 (match_operand:MODEF 3 "div_operator" "")
12541 (const_string "fdiv")
12542 ]
12543 (const_string "fop")))
12544 (set_attr "fp_int_src" "true")
12545 (set_attr "mode" "<X87MODEI12:MODE>")])
12546
12547 (define_insn "*fop_<MODEF:mode>_3_i387"
12548 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12549 (match_operator:MODEF 3 "binary_fp_operator"
12550 [(match_operand:MODEF 1 "register_operand" "0,0")
12551 (float:MODEF
12552 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12553 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12554 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12555 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12556 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12557 [(set (attr "type")
12558 (cond [(match_operand:MODEF 3 "mult_operator" "")
12559 (const_string "fmul")
12560 (match_operand:MODEF 3 "div_operator" "")
12561 (const_string "fdiv")
12562 ]
12563 (const_string "fop")))
12564 (set_attr "fp_int_src" "true")
12565 (set_attr "mode" "<MODE>")])
12566
12567 (define_insn "*fop_df_4_i387"
12568 [(set (match_operand:DF 0 "register_operand" "=f,f")
12569 (match_operator:DF 3 "binary_fp_operator"
12570 [(float_extend:DF
12571 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12572 (match_operand:DF 2 "register_operand" "0,f")]))]
12573 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12574 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12575 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12576 "* return output_387_binary_op (insn, operands);"
12577 [(set (attr "type")
12578 (cond [(match_operand:DF 3 "mult_operator" "")
12579 (const_string "fmul")
12580 (match_operand:DF 3 "div_operator" "")
12581 (const_string "fdiv")
12582 ]
12583 (const_string "fop")))
12584 (set_attr "mode" "SF")])
12585
12586 (define_insn "*fop_df_5_i387"
12587 [(set (match_operand:DF 0 "register_operand" "=f,f")
12588 (match_operator:DF 3 "binary_fp_operator"
12589 [(match_operand:DF 1 "register_operand" "0,f")
12590 (float_extend:DF
12591 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12592 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12593 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12594 "* return output_387_binary_op (insn, operands);"
12595 [(set (attr "type")
12596 (cond [(match_operand:DF 3 "mult_operator" "")
12597 (const_string "fmul")
12598 (match_operand:DF 3 "div_operator" "")
12599 (const_string "fdiv")
12600 ]
12601 (const_string "fop")))
12602 (set_attr "mode" "SF")])
12603
12604 (define_insn "*fop_df_6_i387"
12605 [(set (match_operand:DF 0 "register_operand" "=f,f")
12606 (match_operator:DF 3 "binary_fp_operator"
12607 [(float_extend:DF
12608 (match_operand:SF 1 "register_operand" "0,f"))
12609 (float_extend:DF
12610 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12611 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12612 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12613 "* return output_387_binary_op (insn, operands);"
12614 [(set (attr "type")
12615 (cond [(match_operand:DF 3 "mult_operator" "")
12616 (const_string "fmul")
12617 (match_operand:DF 3 "div_operator" "")
12618 (const_string "fdiv")
12619 ]
12620 (const_string "fop")))
12621 (set_attr "mode" "SF")])
12622
12623 (define_insn "*fop_xf_comm_i387"
12624 [(set (match_operand:XF 0 "register_operand" "=f")
12625 (match_operator:XF 3 "binary_fp_operator"
12626 [(match_operand:XF 1 "register_operand" "%0")
12627 (match_operand:XF 2 "register_operand" "f")]))]
12628 "TARGET_80387
12629 && COMMUTATIVE_ARITH_P (operands[3])"
12630 "* return output_387_binary_op (insn, operands);"
12631 [(set (attr "type")
12632 (if_then_else (match_operand:XF 3 "mult_operator" "")
12633 (const_string "fmul")
12634 (const_string "fop")))
12635 (set_attr "mode" "XF")])
12636
12637 (define_insn "*fop_xf_1_i387"
12638 [(set (match_operand:XF 0 "register_operand" "=f,f")
12639 (match_operator:XF 3 "binary_fp_operator"
12640 [(match_operand:XF 1 "register_operand" "0,f")
12641 (match_operand:XF 2 "register_operand" "f,0")]))]
12642 "TARGET_80387
12643 && !COMMUTATIVE_ARITH_P (operands[3])"
12644 "* return output_387_binary_op (insn, operands);"
12645 [(set (attr "type")
12646 (cond [(match_operand:XF 3 "mult_operator" "")
12647 (const_string "fmul")
12648 (match_operand:XF 3 "div_operator" "")
12649 (const_string "fdiv")
12650 ]
12651 (const_string "fop")))
12652 (set_attr "mode" "XF")])
12653
12654 (define_insn "*fop_xf_2_i387"
12655 [(set (match_operand:XF 0 "register_operand" "=f,f")
12656 (match_operator:XF 3 "binary_fp_operator"
12657 [(float:XF
12658 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12659 (match_operand:XF 2 "register_operand" "0,0")]))]
12660 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12661 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12662 [(set (attr "type")
12663 (cond [(match_operand:XF 3 "mult_operator" "")
12664 (const_string "fmul")
12665 (match_operand:XF 3 "div_operator" "")
12666 (const_string "fdiv")
12667 ]
12668 (const_string "fop")))
12669 (set_attr "fp_int_src" "true")
12670 (set_attr "mode" "<MODE>")])
12671
12672 (define_insn "*fop_xf_3_i387"
12673 [(set (match_operand:XF 0 "register_operand" "=f,f")
12674 (match_operator:XF 3 "binary_fp_operator"
12675 [(match_operand:XF 1 "register_operand" "0,0")
12676 (float:XF
12677 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12678 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12679 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12680 [(set (attr "type")
12681 (cond [(match_operand:XF 3 "mult_operator" "")
12682 (const_string "fmul")
12683 (match_operand:XF 3 "div_operator" "")
12684 (const_string "fdiv")
12685 ]
12686 (const_string "fop")))
12687 (set_attr "fp_int_src" "true")
12688 (set_attr "mode" "<MODE>")])
12689
12690 (define_insn "*fop_xf_4_i387"
12691 [(set (match_operand:XF 0 "register_operand" "=f,f")
12692 (match_operator:XF 3 "binary_fp_operator"
12693 [(float_extend:XF
12694 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12695 (match_operand:XF 2 "register_operand" "0,f")]))]
12696 "TARGET_80387"
12697 "* return output_387_binary_op (insn, operands);"
12698 [(set (attr "type")
12699 (cond [(match_operand:XF 3 "mult_operator" "")
12700 (const_string "fmul")
12701 (match_operand:XF 3 "div_operator" "")
12702 (const_string "fdiv")
12703 ]
12704 (const_string "fop")))
12705 (set_attr "mode" "<MODE>")])
12706
12707 (define_insn "*fop_xf_5_i387"
12708 [(set (match_operand:XF 0 "register_operand" "=f,f")
12709 (match_operator:XF 3 "binary_fp_operator"
12710 [(match_operand:XF 1 "register_operand" "0,f")
12711 (float_extend:XF
12712 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12713 "TARGET_80387"
12714 "* return output_387_binary_op (insn, operands);"
12715 [(set (attr "type")
12716 (cond [(match_operand:XF 3 "mult_operator" "")
12717 (const_string "fmul")
12718 (match_operand:XF 3 "div_operator" "")
12719 (const_string "fdiv")
12720 ]
12721 (const_string "fop")))
12722 (set_attr "mode" "<MODE>")])
12723
12724 (define_insn "*fop_xf_6_i387"
12725 [(set (match_operand:XF 0 "register_operand" "=f,f")
12726 (match_operator:XF 3 "binary_fp_operator"
12727 [(float_extend:XF
12728 (match_operand:MODEF 1 "register_operand" "0,f"))
12729 (float_extend:XF
12730 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12731 "TARGET_80387"
12732 "* return output_387_binary_op (insn, operands);"
12733 [(set (attr "type")
12734 (cond [(match_operand:XF 3 "mult_operator" "")
12735 (const_string "fmul")
12736 (match_operand:XF 3 "div_operator" "")
12737 (const_string "fdiv")
12738 ]
12739 (const_string "fop")))
12740 (set_attr "mode" "<MODE>")])
12741
12742 (define_split
12743 [(set (match_operand 0 "register_operand" "")
12744 (match_operator 3 "binary_fp_operator"
12745 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12746 (match_operand 2 "register_operand" "")]))]
12747 "reload_completed
12748 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12749 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12750 [(const_int 0)]
12751 {
12752 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12753 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12754 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12755 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12756 GET_MODE (operands[3]),
12757 operands[4],
12758 operands[2])));
12759 ix86_free_from_memory (GET_MODE (operands[1]));
12760 DONE;
12761 })
12762
12763 (define_split
12764 [(set (match_operand 0 "register_operand" "")
12765 (match_operator 3 "binary_fp_operator"
12766 [(match_operand 1 "register_operand" "")
12767 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12768 "reload_completed
12769 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12770 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12771 [(const_int 0)]
12772 {
12773 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12774 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12775 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12776 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12777 GET_MODE (operands[3]),
12778 operands[1],
12779 operands[4])));
12780 ix86_free_from_memory (GET_MODE (operands[2]));
12781 DONE;
12782 })
12783 \f
12784 ;; FPU special functions.
12785
12786 ;; This pattern implements a no-op XFmode truncation for
12787 ;; all fancy i386 XFmode math functions.
12788
12789 (define_insn "truncxf<mode>2_i387_noop_unspec"
12790 [(set (match_operand:MODEF 0 "register_operand" "=f")
12791 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12792 UNSPEC_TRUNC_NOOP))]
12793 "TARGET_USE_FANCY_MATH_387"
12794 "* return output_387_reg_move (insn, operands);"
12795 [(set_attr "type" "fmov")
12796 (set_attr "mode" "<MODE>")])
12797
12798 (define_insn "sqrtxf2"
12799 [(set (match_operand:XF 0 "register_operand" "=f")
12800 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12801 "TARGET_USE_FANCY_MATH_387"
12802 "fsqrt"
12803 [(set_attr "type" "fpspc")
12804 (set_attr "mode" "XF")
12805 (set_attr "athlon_decode" "direct")
12806 (set_attr "amdfam10_decode" "direct")])
12807
12808 (define_insn "sqrt_extend<mode>xf2_i387"
12809 [(set (match_operand:XF 0 "register_operand" "=f")
12810 (sqrt:XF
12811 (float_extend:XF
12812 (match_operand:MODEF 1 "register_operand" "0"))))]
12813 "TARGET_USE_FANCY_MATH_387"
12814 "fsqrt"
12815 [(set_attr "type" "fpspc")
12816 (set_attr "mode" "XF")
12817 (set_attr "athlon_decode" "direct")
12818 (set_attr "amdfam10_decode" "direct")])
12819
12820 (define_insn "*rsqrtsf2_sse"
12821 [(set (match_operand:SF 0 "register_operand" "=x")
12822 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12823 UNSPEC_RSQRT))]
12824 "TARGET_SSE_MATH"
12825 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12826 [(set_attr "type" "sse")
12827 (set_attr "atom_sse_attr" "rcp")
12828 (set_attr "prefix" "maybe_vex")
12829 (set_attr "mode" "SF")])
12830
12831 (define_expand "rsqrtsf2"
12832 [(set (match_operand:SF 0 "register_operand" "")
12833 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12834 UNSPEC_RSQRT))]
12835 "TARGET_SSE_MATH"
12836 {
12837 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12838 DONE;
12839 })
12840
12841 (define_insn "*sqrt<mode>2_sse"
12842 [(set (match_operand:MODEF 0 "register_operand" "=x")
12843 (sqrt:MODEF
12844 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12845 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12846 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12847 [(set_attr "type" "sse")
12848 (set_attr "atom_sse_attr" "sqrt")
12849 (set_attr "prefix" "maybe_vex")
12850 (set_attr "mode" "<MODE>")
12851 (set_attr "athlon_decode" "*")
12852 (set_attr "amdfam10_decode" "*")])
12853
12854 (define_expand "sqrt<mode>2"
12855 [(set (match_operand:MODEF 0 "register_operand" "")
12856 (sqrt:MODEF
12857 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12858 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12859 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12860 {
12861 if (<MODE>mode == SFmode
12862 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12863 && flag_finite_math_only && !flag_trapping_math
12864 && flag_unsafe_math_optimizations)
12865 {
12866 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12867 DONE;
12868 }
12869
12870 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12871 {
12872 rtx op0 = gen_reg_rtx (XFmode);
12873 rtx op1 = force_reg (<MODE>mode, operands[1]);
12874
12875 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12876 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12877 DONE;
12878 }
12879 })
12880
12881 (define_insn "fpremxf4_i387"
12882 [(set (match_operand:XF 0 "register_operand" "=f")
12883 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12884 (match_operand:XF 3 "register_operand" "1")]
12885 UNSPEC_FPREM_F))
12886 (set (match_operand:XF 1 "register_operand" "=u")
12887 (unspec:XF [(match_dup 2) (match_dup 3)]
12888 UNSPEC_FPREM_U))
12889 (set (reg:CCFP FPSR_REG)
12890 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12891 UNSPEC_C2_FLAG))]
12892 "TARGET_USE_FANCY_MATH_387"
12893 "fprem"
12894 [(set_attr "type" "fpspc")
12895 (set_attr "mode" "XF")])
12896
12897 (define_expand "fmodxf3"
12898 [(use (match_operand:XF 0 "register_operand" ""))
12899 (use (match_operand:XF 1 "general_operand" ""))
12900 (use (match_operand:XF 2 "general_operand" ""))]
12901 "TARGET_USE_FANCY_MATH_387"
12902 {
12903 rtx label = gen_label_rtx ();
12904
12905 rtx op1 = gen_reg_rtx (XFmode);
12906 rtx op2 = gen_reg_rtx (XFmode);
12907
12908 emit_move_insn (op2, operands[2]);
12909 emit_move_insn (op1, operands[1]);
12910
12911 emit_label (label);
12912 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12913 ix86_emit_fp_unordered_jump (label);
12914 LABEL_NUSES (label) = 1;
12915
12916 emit_move_insn (operands[0], op1);
12917 DONE;
12918 })
12919
12920 (define_expand "fmod<mode>3"
12921 [(use (match_operand:MODEF 0 "register_operand" ""))
12922 (use (match_operand:MODEF 1 "general_operand" ""))
12923 (use (match_operand:MODEF 2 "general_operand" ""))]
12924 "TARGET_USE_FANCY_MATH_387"
12925 {
12926 rtx label = gen_label_rtx ();
12927
12928 rtx op1 = gen_reg_rtx (XFmode);
12929 rtx op2 = gen_reg_rtx (XFmode);
12930
12931 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12932 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12933
12934 emit_label (label);
12935 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12936 ix86_emit_fp_unordered_jump (label);
12937 LABEL_NUSES (label) = 1;
12938
12939 /* Truncate the result properly for strict SSE math. */
12940 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12941 && !TARGET_MIX_SSE_I387)
12942 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
12943 else
12944 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
12945
12946 DONE;
12947 })
12948
12949 (define_insn "fprem1xf4_i387"
12950 [(set (match_operand:XF 0 "register_operand" "=f")
12951 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12952 (match_operand:XF 3 "register_operand" "1")]
12953 UNSPEC_FPREM1_F))
12954 (set (match_operand:XF 1 "register_operand" "=u")
12955 (unspec:XF [(match_dup 2) (match_dup 3)]
12956 UNSPEC_FPREM1_U))
12957 (set (reg:CCFP FPSR_REG)
12958 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12959 UNSPEC_C2_FLAG))]
12960 "TARGET_USE_FANCY_MATH_387"
12961 "fprem1"
12962 [(set_attr "type" "fpspc")
12963 (set_attr "mode" "XF")])
12964
12965 (define_expand "remainderxf3"
12966 [(use (match_operand:XF 0 "register_operand" ""))
12967 (use (match_operand:XF 1 "general_operand" ""))
12968 (use (match_operand:XF 2 "general_operand" ""))]
12969 "TARGET_USE_FANCY_MATH_387"
12970 {
12971 rtx label = gen_label_rtx ();
12972
12973 rtx op1 = gen_reg_rtx (XFmode);
12974 rtx op2 = gen_reg_rtx (XFmode);
12975
12976 emit_move_insn (op2, operands[2]);
12977 emit_move_insn (op1, operands[1]);
12978
12979 emit_label (label);
12980 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12981 ix86_emit_fp_unordered_jump (label);
12982 LABEL_NUSES (label) = 1;
12983
12984 emit_move_insn (operands[0], op1);
12985 DONE;
12986 })
12987
12988 (define_expand "remainder<mode>3"
12989 [(use (match_operand:MODEF 0 "register_operand" ""))
12990 (use (match_operand:MODEF 1 "general_operand" ""))
12991 (use (match_operand:MODEF 2 "general_operand" ""))]
12992 "TARGET_USE_FANCY_MATH_387"
12993 {
12994 rtx label = gen_label_rtx ();
12995
12996 rtx op1 = gen_reg_rtx (XFmode);
12997 rtx op2 = gen_reg_rtx (XFmode);
12998
12999 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13000 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13001
13002 emit_label (label);
13003
13004 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13005 ix86_emit_fp_unordered_jump (label);
13006 LABEL_NUSES (label) = 1;
13007
13008 /* Truncate the result properly for strict SSE math. */
13009 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13010 && !TARGET_MIX_SSE_I387)
13011 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13012 else
13013 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13014
13015 DONE;
13016 })
13017
13018 (define_insn "*sinxf2_i387"
13019 [(set (match_operand:XF 0 "register_operand" "=f")
13020 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13021 "TARGET_USE_FANCY_MATH_387
13022 && flag_unsafe_math_optimizations"
13023 "fsin"
13024 [(set_attr "type" "fpspc")
13025 (set_attr "mode" "XF")])
13026
13027 (define_insn "*sin_extend<mode>xf2_i387"
13028 [(set (match_operand:XF 0 "register_operand" "=f")
13029 (unspec:XF [(float_extend:XF
13030 (match_operand:MODEF 1 "register_operand" "0"))]
13031 UNSPEC_SIN))]
13032 "TARGET_USE_FANCY_MATH_387
13033 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13034 || TARGET_MIX_SSE_I387)
13035 && flag_unsafe_math_optimizations"
13036 "fsin"
13037 [(set_attr "type" "fpspc")
13038 (set_attr "mode" "XF")])
13039
13040 (define_insn "*cosxf2_i387"
13041 [(set (match_operand:XF 0 "register_operand" "=f")
13042 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13043 "TARGET_USE_FANCY_MATH_387
13044 && flag_unsafe_math_optimizations"
13045 "fcos"
13046 [(set_attr "type" "fpspc")
13047 (set_attr "mode" "XF")])
13048
13049 (define_insn "*cos_extend<mode>xf2_i387"
13050 [(set (match_operand:XF 0 "register_operand" "=f")
13051 (unspec:XF [(float_extend:XF
13052 (match_operand:MODEF 1 "register_operand" "0"))]
13053 UNSPEC_COS))]
13054 "TARGET_USE_FANCY_MATH_387
13055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13056 || TARGET_MIX_SSE_I387)
13057 && flag_unsafe_math_optimizations"
13058 "fcos"
13059 [(set_attr "type" "fpspc")
13060 (set_attr "mode" "XF")])
13061
13062 ;; When sincos pattern is defined, sin and cos builtin functions will be
13063 ;; expanded to sincos pattern with one of its outputs left unused.
13064 ;; CSE pass will figure out if two sincos patterns can be combined,
13065 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13066 ;; depending on the unused output.
13067
13068 (define_insn "sincosxf3"
13069 [(set (match_operand:XF 0 "register_operand" "=f")
13070 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13071 UNSPEC_SINCOS_COS))
13072 (set (match_operand:XF 1 "register_operand" "=u")
13073 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13074 "TARGET_USE_FANCY_MATH_387
13075 && flag_unsafe_math_optimizations"
13076 "fsincos"
13077 [(set_attr "type" "fpspc")
13078 (set_attr "mode" "XF")])
13079
13080 (define_split
13081 [(set (match_operand:XF 0 "register_operand" "")
13082 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13083 UNSPEC_SINCOS_COS))
13084 (set (match_operand:XF 1 "register_operand" "")
13085 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13086 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13087 && !(reload_completed || reload_in_progress)"
13088 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13089 "")
13090
13091 (define_split
13092 [(set (match_operand:XF 0 "register_operand" "")
13093 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13094 UNSPEC_SINCOS_COS))
13095 (set (match_operand:XF 1 "register_operand" "")
13096 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13097 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13098 && !(reload_completed || reload_in_progress)"
13099 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13100 "")
13101
13102 (define_insn "sincos_extend<mode>xf3_i387"
13103 [(set (match_operand:XF 0 "register_operand" "=f")
13104 (unspec:XF [(float_extend:XF
13105 (match_operand:MODEF 2 "register_operand" "0"))]
13106 UNSPEC_SINCOS_COS))
13107 (set (match_operand:XF 1 "register_operand" "=u")
13108 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13109 "TARGET_USE_FANCY_MATH_387
13110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13111 || TARGET_MIX_SSE_I387)
13112 && flag_unsafe_math_optimizations"
13113 "fsincos"
13114 [(set_attr "type" "fpspc")
13115 (set_attr "mode" "XF")])
13116
13117 (define_split
13118 [(set (match_operand:XF 0 "register_operand" "")
13119 (unspec:XF [(float_extend:XF
13120 (match_operand:MODEF 2 "register_operand" ""))]
13121 UNSPEC_SINCOS_COS))
13122 (set (match_operand:XF 1 "register_operand" "")
13123 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13124 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13125 && !(reload_completed || reload_in_progress)"
13126 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13127 "")
13128
13129 (define_split
13130 [(set (match_operand:XF 0 "register_operand" "")
13131 (unspec:XF [(float_extend:XF
13132 (match_operand:MODEF 2 "register_operand" ""))]
13133 UNSPEC_SINCOS_COS))
13134 (set (match_operand:XF 1 "register_operand" "")
13135 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13136 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13137 && !(reload_completed || reload_in_progress)"
13138 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13139 "")
13140
13141 (define_expand "sincos<mode>3"
13142 [(use (match_operand:MODEF 0 "register_operand" ""))
13143 (use (match_operand:MODEF 1 "register_operand" ""))
13144 (use (match_operand:MODEF 2 "register_operand" ""))]
13145 "TARGET_USE_FANCY_MATH_387
13146 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13147 || TARGET_MIX_SSE_I387)
13148 && flag_unsafe_math_optimizations"
13149 {
13150 rtx op0 = gen_reg_rtx (XFmode);
13151 rtx op1 = gen_reg_rtx (XFmode);
13152
13153 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13154 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13155 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13156 DONE;
13157 })
13158
13159 (define_insn "fptanxf4_i387"
13160 [(set (match_operand:XF 0 "register_operand" "=f")
13161 (match_operand:XF 3 "const_double_operand" "F"))
13162 (set (match_operand:XF 1 "register_operand" "=u")
13163 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13164 UNSPEC_TAN))]
13165 "TARGET_USE_FANCY_MATH_387
13166 && flag_unsafe_math_optimizations
13167 && standard_80387_constant_p (operands[3]) == 2"
13168 "fptan"
13169 [(set_attr "type" "fpspc")
13170 (set_attr "mode" "XF")])
13171
13172 (define_insn "fptan_extend<mode>xf4_i387"
13173 [(set (match_operand:MODEF 0 "register_operand" "=f")
13174 (match_operand:MODEF 3 "const_double_operand" "F"))
13175 (set (match_operand:XF 1 "register_operand" "=u")
13176 (unspec:XF [(float_extend:XF
13177 (match_operand:MODEF 2 "register_operand" "0"))]
13178 UNSPEC_TAN))]
13179 "TARGET_USE_FANCY_MATH_387
13180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13181 || TARGET_MIX_SSE_I387)
13182 && flag_unsafe_math_optimizations
13183 && standard_80387_constant_p (operands[3]) == 2"
13184 "fptan"
13185 [(set_attr "type" "fpspc")
13186 (set_attr "mode" "XF")])
13187
13188 (define_expand "tanxf2"
13189 [(use (match_operand:XF 0 "register_operand" ""))
13190 (use (match_operand:XF 1 "register_operand" ""))]
13191 "TARGET_USE_FANCY_MATH_387
13192 && flag_unsafe_math_optimizations"
13193 {
13194 rtx one = gen_reg_rtx (XFmode);
13195 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13196
13197 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13198 DONE;
13199 })
13200
13201 (define_expand "tan<mode>2"
13202 [(use (match_operand:MODEF 0 "register_operand" ""))
13203 (use (match_operand:MODEF 1 "register_operand" ""))]
13204 "TARGET_USE_FANCY_MATH_387
13205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13206 || TARGET_MIX_SSE_I387)
13207 && flag_unsafe_math_optimizations"
13208 {
13209 rtx op0 = gen_reg_rtx (XFmode);
13210
13211 rtx one = gen_reg_rtx (<MODE>mode);
13212 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13213
13214 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13215 operands[1], op2));
13216 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13217 DONE;
13218 })
13219
13220 (define_insn "*fpatanxf3_i387"
13221 [(set (match_operand:XF 0 "register_operand" "=f")
13222 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13223 (match_operand:XF 2 "register_operand" "u")]
13224 UNSPEC_FPATAN))
13225 (clobber (match_scratch:XF 3 "=2"))]
13226 "TARGET_USE_FANCY_MATH_387
13227 && flag_unsafe_math_optimizations"
13228 "fpatan"
13229 [(set_attr "type" "fpspc")
13230 (set_attr "mode" "XF")])
13231
13232 (define_insn "fpatan_extend<mode>xf3_i387"
13233 [(set (match_operand:XF 0 "register_operand" "=f")
13234 (unspec:XF [(float_extend:XF
13235 (match_operand:MODEF 1 "register_operand" "0"))
13236 (float_extend:XF
13237 (match_operand:MODEF 2 "register_operand" "u"))]
13238 UNSPEC_FPATAN))
13239 (clobber (match_scratch:XF 3 "=2"))]
13240 "TARGET_USE_FANCY_MATH_387
13241 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13242 || TARGET_MIX_SSE_I387)
13243 && flag_unsafe_math_optimizations"
13244 "fpatan"
13245 [(set_attr "type" "fpspc")
13246 (set_attr "mode" "XF")])
13247
13248 (define_expand "atan2xf3"
13249 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13250 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13251 (match_operand:XF 1 "register_operand" "")]
13252 UNSPEC_FPATAN))
13253 (clobber (match_scratch:XF 3 ""))])]
13254 "TARGET_USE_FANCY_MATH_387
13255 && flag_unsafe_math_optimizations"
13256 "")
13257
13258 (define_expand "atan2<mode>3"
13259 [(use (match_operand:MODEF 0 "register_operand" ""))
13260 (use (match_operand:MODEF 1 "register_operand" ""))
13261 (use (match_operand:MODEF 2 "register_operand" ""))]
13262 "TARGET_USE_FANCY_MATH_387
13263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13264 || TARGET_MIX_SSE_I387)
13265 && flag_unsafe_math_optimizations"
13266 {
13267 rtx op0 = gen_reg_rtx (XFmode);
13268
13269 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13270 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13271 DONE;
13272 })
13273
13274 (define_expand "atanxf2"
13275 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13276 (unspec:XF [(match_dup 2)
13277 (match_operand:XF 1 "register_operand" "")]
13278 UNSPEC_FPATAN))
13279 (clobber (match_scratch:XF 3 ""))])]
13280 "TARGET_USE_FANCY_MATH_387
13281 && flag_unsafe_math_optimizations"
13282 {
13283 operands[2] = gen_reg_rtx (XFmode);
13284 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13285 })
13286
13287 (define_expand "atan<mode>2"
13288 [(use (match_operand:MODEF 0 "register_operand" ""))
13289 (use (match_operand:MODEF 1 "register_operand" ""))]
13290 "TARGET_USE_FANCY_MATH_387
13291 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13292 || TARGET_MIX_SSE_I387)
13293 && flag_unsafe_math_optimizations"
13294 {
13295 rtx op0 = gen_reg_rtx (XFmode);
13296
13297 rtx op2 = gen_reg_rtx (<MODE>mode);
13298 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13299
13300 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13301 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13302 DONE;
13303 })
13304
13305 (define_expand "asinxf2"
13306 [(set (match_dup 2)
13307 (mult:XF (match_operand:XF 1 "register_operand" "")
13308 (match_dup 1)))
13309 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13310 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13311 (parallel [(set (match_operand:XF 0 "register_operand" "")
13312 (unspec:XF [(match_dup 5) (match_dup 1)]
13313 UNSPEC_FPATAN))
13314 (clobber (match_scratch:XF 6 ""))])]
13315 "TARGET_USE_FANCY_MATH_387
13316 && flag_unsafe_math_optimizations"
13317 {
13318 int i;
13319
13320 if (optimize_insn_for_size_p ())
13321 FAIL;
13322
13323 for (i = 2; i < 6; i++)
13324 operands[i] = gen_reg_rtx (XFmode);
13325
13326 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13327 })
13328
13329 (define_expand "asin<mode>2"
13330 [(use (match_operand:MODEF 0 "register_operand" ""))
13331 (use (match_operand:MODEF 1 "general_operand" ""))]
13332 "TARGET_USE_FANCY_MATH_387
13333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13334 || TARGET_MIX_SSE_I387)
13335 && flag_unsafe_math_optimizations"
13336 {
13337 rtx op0 = gen_reg_rtx (XFmode);
13338 rtx op1 = gen_reg_rtx (XFmode);
13339
13340 if (optimize_insn_for_size_p ())
13341 FAIL;
13342
13343 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13344 emit_insn (gen_asinxf2 (op0, op1));
13345 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13346 DONE;
13347 })
13348
13349 (define_expand "acosxf2"
13350 [(set (match_dup 2)
13351 (mult:XF (match_operand:XF 1 "register_operand" "")
13352 (match_dup 1)))
13353 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13354 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13355 (parallel [(set (match_operand:XF 0 "register_operand" "")
13356 (unspec:XF [(match_dup 1) (match_dup 5)]
13357 UNSPEC_FPATAN))
13358 (clobber (match_scratch:XF 6 ""))])]
13359 "TARGET_USE_FANCY_MATH_387
13360 && flag_unsafe_math_optimizations"
13361 {
13362 int i;
13363
13364 if (optimize_insn_for_size_p ())
13365 FAIL;
13366
13367 for (i = 2; i < 6; i++)
13368 operands[i] = gen_reg_rtx (XFmode);
13369
13370 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13371 })
13372
13373 (define_expand "acos<mode>2"
13374 [(use (match_operand:MODEF 0 "register_operand" ""))
13375 (use (match_operand:MODEF 1 "general_operand" ""))]
13376 "TARGET_USE_FANCY_MATH_387
13377 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13378 || TARGET_MIX_SSE_I387)
13379 && flag_unsafe_math_optimizations"
13380 {
13381 rtx op0 = gen_reg_rtx (XFmode);
13382 rtx op1 = gen_reg_rtx (XFmode);
13383
13384 if (optimize_insn_for_size_p ())
13385 FAIL;
13386
13387 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13388 emit_insn (gen_acosxf2 (op0, op1));
13389 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13390 DONE;
13391 })
13392
13393 (define_insn "fyl2xxf3_i387"
13394 [(set (match_operand:XF 0 "register_operand" "=f")
13395 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13396 (match_operand:XF 2 "register_operand" "u")]
13397 UNSPEC_FYL2X))
13398 (clobber (match_scratch:XF 3 "=2"))]
13399 "TARGET_USE_FANCY_MATH_387
13400 && flag_unsafe_math_optimizations"
13401 "fyl2x"
13402 [(set_attr "type" "fpspc")
13403 (set_attr "mode" "XF")])
13404
13405 (define_insn "fyl2x_extend<mode>xf3_i387"
13406 [(set (match_operand:XF 0 "register_operand" "=f")
13407 (unspec:XF [(float_extend:XF
13408 (match_operand:MODEF 1 "register_operand" "0"))
13409 (match_operand:XF 2 "register_operand" "u")]
13410 UNSPEC_FYL2X))
13411 (clobber (match_scratch:XF 3 "=2"))]
13412 "TARGET_USE_FANCY_MATH_387
13413 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13414 || TARGET_MIX_SSE_I387)
13415 && flag_unsafe_math_optimizations"
13416 "fyl2x"
13417 [(set_attr "type" "fpspc")
13418 (set_attr "mode" "XF")])
13419
13420 (define_expand "logxf2"
13421 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13422 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13423 (match_dup 2)] UNSPEC_FYL2X))
13424 (clobber (match_scratch:XF 3 ""))])]
13425 "TARGET_USE_FANCY_MATH_387
13426 && flag_unsafe_math_optimizations"
13427 {
13428 operands[2] = gen_reg_rtx (XFmode);
13429 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13430 })
13431
13432 (define_expand "log<mode>2"
13433 [(use (match_operand:MODEF 0 "register_operand" ""))
13434 (use (match_operand:MODEF 1 "register_operand" ""))]
13435 "TARGET_USE_FANCY_MATH_387
13436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13437 || TARGET_MIX_SSE_I387)
13438 && flag_unsafe_math_optimizations"
13439 {
13440 rtx op0 = gen_reg_rtx (XFmode);
13441
13442 rtx op2 = gen_reg_rtx (XFmode);
13443 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13444
13445 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13446 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13447 DONE;
13448 })
13449
13450 (define_expand "log10xf2"
13451 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13452 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13453 (match_dup 2)] UNSPEC_FYL2X))
13454 (clobber (match_scratch:XF 3 ""))])]
13455 "TARGET_USE_FANCY_MATH_387
13456 && flag_unsafe_math_optimizations"
13457 {
13458 operands[2] = gen_reg_rtx (XFmode);
13459 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13460 })
13461
13462 (define_expand "log10<mode>2"
13463 [(use (match_operand:MODEF 0 "register_operand" ""))
13464 (use (match_operand:MODEF 1 "register_operand" ""))]
13465 "TARGET_USE_FANCY_MATH_387
13466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13467 || TARGET_MIX_SSE_I387)
13468 && flag_unsafe_math_optimizations"
13469 {
13470 rtx op0 = gen_reg_rtx (XFmode);
13471
13472 rtx op2 = gen_reg_rtx (XFmode);
13473 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13474
13475 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13476 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13477 DONE;
13478 })
13479
13480 (define_expand "log2xf2"
13481 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13482 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13483 (match_dup 2)] UNSPEC_FYL2X))
13484 (clobber (match_scratch:XF 3 ""))])]
13485 "TARGET_USE_FANCY_MATH_387
13486 && flag_unsafe_math_optimizations"
13487 {
13488 operands[2] = gen_reg_rtx (XFmode);
13489 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13490 })
13491
13492 (define_expand "log2<mode>2"
13493 [(use (match_operand:MODEF 0 "register_operand" ""))
13494 (use (match_operand:MODEF 1 "register_operand" ""))]
13495 "TARGET_USE_FANCY_MATH_387
13496 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13497 || TARGET_MIX_SSE_I387)
13498 && flag_unsafe_math_optimizations"
13499 {
13500 rtx op0 = gen_reg_rtx (XFmode);
13501
13502 rtx op2 = gen_reg_rtx (XFmode);
13503 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13504
13505 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13506 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13507 DONE;
13508 })
13509
13510 (define_insn "fyl2xp1xf3_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f")
13512 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13513 (match_operand:XF 2 "register_operand" "u")]
13514 UNSPEC_FYL2XP1))
13515 (clobber (match_scratch:XF 3 "=2"))]
13516 "TARGET_USE_FANCY_MATH_387
13517 && flag_unsafe_math_optimizations"
13518 "fyl2xp1"
13519 [(set_attr "type" "fpspc")
13520 (set_attr "mode" "XF")])
13521
13522 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13523 [(set (match_operand:XF 0 "register_operand" "=f")
13524 (unspec:XF [(float_extend:XF
13525 (match_operand:MODEF 1 "register_operand" "0"))
13526 (match_operand:XF 2 "register_operand" "u")]
13527 UNSPEC_FYL2XP1))
13528 (clobber (match_scratch:XF 3 "=2"))]
13529 "TARGET_USE_FANCY_MATH_387
13530 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13531 || TARGET_MIX_SSE_I387)
13532 && flag_unsafe_math_optimizations"
13533 "fyl2xp1"
13534 [(set_attr "type" "fpspc")
13535 (set_attr "mode" "XF")])
13536
13537 (define_expand "log1pxf2"
13538 [(use (match_operand:XF 0 "register_operand" ""))
13539 (use (match_operand:XF 1 "register_operand" ""))]
13540 "TARGET_USE_FANCY_MATH_387
13541 && flag_unsafe_math_optimizations"
13542 {
13543 if (optimize_insn_for_size_p ())
13544 FAIL;
13545
13546 ix86_emit_i387_log1p (operands[0], operands[1]);
13547 DONE;
13548 })
13549
13550 (define_expand "log1p<mode>2"
13551 [(use (match_operand:MODEF 0 "register_operand" ""))
13552 (use (match_operand:MODEF 1 "register_operand" ""))]
13553 "TARGET_USE_FANCY_MATH_387
13554 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13555 || TARGET_MIX_SSE_I387)
13556 && flag_unsafe_math_optimizations"
13557 {
13558 rtx op0;
13559
13560 if (optimize_insn_for_size_p ())
13561 FAIL;
13562
13563 op0 = gen_reg_rtx (XFmode);
13564
13565 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13566
13567 ix86_emit_i387_log1p (op0, operands[1]);
13568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13569 DONE;
13570 })
13571
13572 (define_insn "fxtractxf3_i387"
13573 [(set (match_operand:XF 0 "register_operand" "=f")
13574 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13575 UNSPEC_XTRACT_FRACT))
13576 (set (match_operand:XF 1 "register_operand" "=u")
13577 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13578 "TARGET_USE_FANCY_MATH_387
13579 && flag_unsafe_math_optimizations"
13580 "fxtract"
13581 [(set_attr "type" "fpspc")
13582 (set_attr "mode" "XF")])
13583
13584 (define_insn "fxtract_extend<mode>xf3_i387"
13585 [(set (match_operand:XF 0 "register_operand" "=f")
13586 (unspec:XF [(float_extend:XF
13587 (match_operand:MODEF 2 "register_operand" "0"))]
13588 UNSPEC_XTRACT_FRACT))
13589 (set (match_operand:XF 1 "register_operand" "=u")
13590 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13591 "TARGET_USE_FANCY_MATH_387
13592 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13593 || TARGET_MIX_SSE_I387)
13594 && flag_unsafe_math_optimizations"
13595 "fxtract"
13596 [(set_attr "type" "fpspc")
13597 (set_attr "mode" "XF")])
13598
13599 (define_expand "logbxf2"
13600 [(parallel [(set (match_dup 2)
13601 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13602 UNSPEC_XTRACT_FRACT))
13603 (set (match_operand:XF 0 "register_operand" "")
13604 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13605 "TARGET_USE_FANCY_MATH_387
13606 && flag_unsafe_math_optimizations"
13607 {
13608 operands[2] = gen_reg_rtx (XFmode);
13609 })
13610
13611 (define_expand "logb<mode>2"
13612 [(use (match_operand:MODEF 0 "register_operand" ""))
13613 (use (match_operand:MODEF 1 "register_operand" ""))]
13614 "TARGET_USE_FANCY_MATH_387
13615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13616 || TARGET_MIX_SSE_I387)
13617 && flag_unsafe_math_optimizations"
13618 {
13619 rtx op0 = gen_reg_rtx (XFmode);
13620 rtx op1 = gen_reg_rtx (XFmode);
13621
13622 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13623 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13624 DONE;
13625 })
13626
13627 (define_expand "ilogbxf2"
13628 [(use (match_operand:SI 0 "register_operand" ""))
13629 (use (match_operand:XF 1 "register_operand" ""))]
13630 "TARGET_USE_FANCY_MATH_387
13631 && flag_unsafe_math_optimizations"
13632 {
13633 rtx op0, op1;
13634
13635 if (optimize_insn_for_size_p ())
13636 FAIL;
13637
13638 op0 = gen_reg_rtx (XFmode);
13639 op1 = gen_reg_rtx (XFmode);
13640
13641 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13642 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13643 DONE;
13644 })
13645
13646 (define_expand "ilogb<mode>2"
13647 [(use (match_operand:SI 0 "register_operand" ""))
13648 (use (match_operand:MODEF 1 "register_operand" ""))]
13649 "TARGET_USE_FANCY_MATH_387
13650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13651 || TARGET_MIX_SSE_I387)
13652 && flag_unsafe_math_optimizations"
13653 {
13654 rtx op0, op1;
13655
13656 if (optimize_insn_for_size_p ())
13657 FAIL;
13658
13659 op0 = gen_reg_rtx (XFmode);
13660 op1 = gen_reg_rtx (XFmode);
13661
13662 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13663 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13664 DONE;
13665 })
13666
13667 (define_insn "*f2xm1xf2_i387"
13668 [(set (match_operand:XF 0 "register_operand" "=f")
13669 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13670 UNSPEC_F2XM1))]
13671 "TARGET_USE_FANCY_MATH_387
13672 && flag_unsafe_math_optimizations"
13673 "f2xm1"
13674 [(set_attr "type" "fpspc")
13675 (set_attr "mode" "XF")])
13676
13677 (define_insn "*fscalexf4_i387"
13678 [(set (match_operand:XF 0 "register_operand" "=f")
13679 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13680 (match_operand:XF 3 "register_operand" "1")]
13681 UNSPEC_FSCALE_FRACT))
13682 (set (match_operand:XF 1 "register_operand" "=u")
13683 (unspec:XF [(match_dup 2) (match_dup 3)]
13684 UNSPEC_FSCALE_EXP))]
13685 "TARGET_USE_FANCY_MATH_387
13686 && flag_unsafe_math_optimizations"
13687 "fscale"
13688 [(set_attr "type" "fpspc")
13689 (set_attr "mode" "XF")])
13690
13691 (define_expand "expNcorexf3"
13692 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13693 (match_operand:XF 2 "register_operand" "")))
13694 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13695 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13696 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13697 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13698 (parallel [(set (match_operand:XF 0 "register_operand" "")
13699 (unspec:XF [(match_dup 8) (match_dup 4)]
13700 UNSPEC_FSCALE_FRACT))
13701 (set (match_dup 9)
13702 (unspec:XF [(match_dup 8) (match_dup 4)]
13703 UNSPEC_FSCALE_EXP))])]
13704 "TARGET_USE_FANCY_MATH_387
13705 && flag_unsafe_math_optimizations"
13706 {
13707 int i;
13708
13709 if (optimize_insn_for_size_p ())
13710 FAIL;
13711
13712 for (i = 3; i < 10; i++)
13713 operands[i] = gen_reg_rtx (XFmode);
13714
13715 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13716 })
13717
13718 (define_expand "expxf2"
13719 [(use (match_operand:XF 0 "register_operand" ""))
13720 (use (match_operand:XF 1 "register_operand" ""))]
13721 "TARGET_USE_FANCY_MATH_387
13722 && flag_unsafe_math_optimizations"
13723 {
13724 rtx op2;
13725
13726 if (optimize_insn_for_size_p ())
13727 FAIL;
13728
13729 op2 = gen_reg_rtx (XFmode);
13730 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13731
13732 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13733 DONE;
13734 })
13735
13736 (define_expand "exp<mode>2"
13737 [(use (match_operand:MODEF 0 "register_operand" ""))
13738 (use (match_operand:MODEF 1 "general_operand" ""))]
13739 "TARGET_USE_FANCY_MATH_387
13740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13741 || TARGET_MIX_SSE_I387)
13742 && flag_unsafe_math_optimizations"
13743 {
13744 rtx op0, op1;
13745
13746 if (optimize_insn_for_size_p ())
13747 FAIL;
13748
13749 op0 = gen_reg_rtx (XFmode);
13750 op1 = gen_reg_rtx (XFmode);
13751
13752 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13753 emit_insn (gen_expxf2 (op0, op1));
13754 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13755 DONE;
13756 })
13757
13758 (define_expand "exp10xf2"
13759 [(use (match_operand:XF 0 "register_operand" ""))
13760 (use (match_operand:XF 1 "register_operand" ""))]
13761 "TARGET_USE_FANCY_MATH_387
13762 && flag_unsafe_math_optimizations"
13763 {
13764 rtx op2;
13765
13766 if (optimize_insn_for_size_p ())
13767 FAIL;
13768
13769 op2 = gen_reg_rtx (XFmode);
13770 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13771
13772 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13773 DONE;
13774 })
13775
13776 (define_expand "exp10<mode>2"
13777 [(use (match_operand:MODEF 0 "register_operand" ""))
13778 (use (match_operand:MODEF 1 "general_operand" ""))]
13779 "TARGET_USE_FANCY_MATH_387
13780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781 || TARGET_MIX_SSE_I387)
13782 && flag_unsafe_math_optimizations"
13783 {
13784 rtx op0, op1;
13785
13786 if (optimize_insn_for_size_p ())
13787 FAIL;
13788
13789 op0 = gen_reg_rtx (XFmode);
13790 op1 = gen_reg_rtx (XFmode);
13791
13792 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13793 emit_insn (gen_exp10xf2 (op0, op1));
13794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13795 DONE;
13796 })
13797
13798 (define_expand "exp2xf2"
13799 [(use (match_operand:XF 0 "register_operand" ""))
13800 (use (match_operand:XF 1 "register_operand" ""))]
13801 "TARGET_USE_FANCY_MATH_387
13802 && flag_unsafe_math_optimizations"
13803 {
13804 rtx op2;
13805
13806 if (optimize_insn_for_size_p ())
13807 FAIL;
13808
13809 op2 = gen_reg_rtx (XFmode);
13810 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13811
13812 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13813 DONE;
13814 })
13815
13816 (define_expand "exp2<mode>2"
13817 [(use (match_operand:MODEF 0 "register_operand" ""))
13818 (use (match_operand:MODEF 1 "general_operand" ""))]
13819 "TARGET_USE_FANCY_MATH_387
13820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821 || TARGET_MIX_SSE_I387)
13822 && flag_unsafe_math_optimizations"
13823 {
13824 rtx op0, op1;
13825
13826 if (optimize_insn_for_size_p ())
13827 FAIL;
13828
13829 op0 = gen_reg_rtx (XFmode);
13830 op1 = gen_reg_rtx (XFmode);
13831
13832 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13833 emit_insn (gen_exp2xf2 (op0, op1));
13834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13835 DONE;
13836 })
13837
13838 (define_expand "expm1xf2"
13839 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13840 (match_dup 2)))
13841 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13842 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13843 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13844 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13845 (parallel [(set (match_dup 7)
13846 (unspec:XF [(match_dup 6) (match_dup 4)]
13847 UNSPEC_FSCALE_FRACT))
13848 (set (match_dup 8)
13849 (unspec:XF [(match_dup 6) (match_dup 4)]
13850 UNSPEC_FSCALE_EXP))])
13851 (parallel [(set (match_dup 10)
13852 (unspec:XF [(match_dup 9) (match_dup 8)]
13853 UNSPEC_FSCALE_FRACT))
13854 (set (match_dup 11)
13855 (unspec:XF [(match_dup 9) (match_dup 8)]
13856 UNSPEC_FSCALE_EXP))])
13857 (set (match_dup 12) (minus:XF (match_dup 10)
13858 (float_extend:XF (match_dup 13))))
13859 (set (match_operand:XF 0 "register_operand" "")
13860 (plus:XF (match_dup 12) (match_dup 7)))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && flag_unsafe_math_optimizations"
13863 {
13864 int i;
13865
13866 if (optimize_insn_for_size_p ())
13867 FAIL;
13868
13869 for (i = 2; i < 13; i++)
13870 operands[i] = gen_reg_rtx (XFmode);
13871
13872 operands[13]
13873 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13874
13875 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13876 })
13877
13878 (define_expand "expm1<mode>2"
13879 [(use (match_operand:MODEF 0 "register_operand" ""))
13880 (use (match_operand:MODEF 1 "general_operand" ""))]
13881 "TARGET_USE_FANCY_MATH_387
13882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13883 || TARGET_MIX_SSE_I387)
13884 && flag_unsafe_math_optimizations"
13885 {
13886 rtx op0, op1;
13887
13888 if (optimize_insn_for_size_p ())
13889 FAIL;
13890
13891 op0 = gen_reg_rtx (XFmode);
13892 op1 = gen_reg_rtx (XFmode);
13893
13894 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13895 emit_insn (gen_expm1xf2 (op0, op1));
13896 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13897 DONE;
13898 })
13899
13900 (define_expand "ldexpxf3"
13901 [(set (match_dup 3)
13902 (float:XF (match_operand:SI 2 "register_operand" "")))
13903 (parallel [(set (match_operand:XF 0 " register_operand" "")
13904 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13905 (match_dup 3)]
13906 UNSPEC_FSCALE_FRACT))
13907 (set (match_dup 4)
13908 (unspec:XF [(match_dup 1) (match_dup 3)]
13909 UNSPEC_FSCALE_EXP))])]
13910 "TARGET_USE_FANCY_MATH_387
13911 && flag_unsafe_math_optimizations"
13912 {
13913 if (optimize_insn_for_size_p ())
13914 FAIL;
13915
13916 operands[3] = gen_reg_rtx (XFmode);
13917 operands[4] = gen_reg_rtx (XFmode);
13918 })
13919
13920 (define_expand "ldexp<mode>3"
13921 [(use (match_operand:MODEF 0 "register_operand" ""))
13922 (use (match_operand:MODEF 1 "general_operand" ""))
13923 (use (match_operand:SI 2 "register_operand" ""))]
13924 "TARGET_USE_FANCY_MATH_387
13925 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13926 || TARGET_MIX_SSE_I387)
13927 && flag_unsafe_math_optimizations"
13928 {
13929 rtx op0, op1;
13930
13931 if (optimize_insn_for_size_p ())
13932 FAIL;
13933
13934 op0 = gen_reg_rtx (XFmode);
13935 op1 = gen_reg_rtx (XFmode);
13936
13937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13938 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13939 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13940 DONE;
13941 })
13942
13943 (define_expand "scalbxf3"
13944 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13945 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13946 (match_operand:XF 2 "register_operand" "")]
13947 UNSPEC_FSCALE_FRACT))
13948 (set (match_dup 3)
13949 (unspec:XF [(match_dup 1) (match_dup 2)]
13950 UNSPEC_FSCALE_EXP))])]
13951 "TARGET_USE_FANCY_MATH_387
13952 && flag_unsafe_math_optimizations"
13953 {
13954 if (optimize_insn_for_size_p ())
13955 FAIL;
13956
13957 operands[3] = gen_reg_rtx (XFmode);
13958 })
13959
13960 (define_expand "scalb<mode>3"
13961 [(use (match_operand:MODEF 0 "register_operand" ""))
13962 (use (match_operand:MODEF 1 "general_operand" ""))
13963 (use (match_operand:MODEF 2 "general_operand" ""))]
13964 "TARGET_USE_FANCY_MATH_387
13965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13966 || TARGET_MIX_SSE_I387)
13967 && flag_unsafe_math_optimizations"
13968 {
13969 rtx op0, op1, op2;
13970
13971 if (optimize_insn_for_size_p ())
13972 FAIL;
13973
13974 op0 = gen_reg_rtx (XFmode);
13975 op1 = gen_reg_rtx (XFmode);
13976 op2 = gen_reg_rtx (XFmode);
13977
13978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13979 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13980 emit_insn (gen_scalbxf3 (op0, op1, op2));
13981 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13982 DONE;
13983 })
13984
13985 (define_expand "significandxf2"
13986 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13987 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13988 UNSPEC_XTRACT_FRACT))
13989 (set (match_dup 2)
13990 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13991 "TARGET_USE_FANCY_MATH_387
13992 && flag_unsafe_math_optimizations"
13993 {
13994 operands[2] = gen_reg_rtx (XFmode);
13995 })
13996
13997 (define_expand "significand<mode>2"
13998 [(use (match_operand:MODEF 0 "register_operand" ""))
13999 (use (match_operand:MODEF 1 "register_operand" ""))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14002 || TARGET_MIX_SSE_I387)
14003 && flag_unsafe_math_optimizations"
14004 {
14005 rtx op0 = gen_reg_rtx (XFmode);
14006 rtx op1 = gen_reg_rtx (XFmode);
14007
14008 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14009 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14010 DONE;
14011 })
14012 \f
14013
14014 (define_insn "sse4_1_round<mode>2"
14015 [(set (match_operand:MODEF 0 "register_operand" "=x")
14016 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14017 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14018 UNSPEC_ROUND))]
14019 "TARGET_ROUND"
14020 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14021 [(set_attr "type" "ssecvt")
14022 (set_attr "prefix_extra" "1")
14023 (set_attr "prefix" "maybe_vex")
14024 (set_attr "mode" "<MODE>")])
14025
14026 (define_insn "rintxf2"
14027 [(set (match_operand:XF 0 "register_operand" "=f")
14028 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14029 UNSPEC_FRNDINT))]
14030 "TARGET_USE_FANCY_MATH_387
14031 && flag_unsafe_math_optimizations"
14032 "frndint"
14033 [(set_attr "type" "fpspc")
14034 (set_attr "mode" "XF")])
14035
14036 (define_expand "rint<mode>2"
14037 [(use (match_operand:MODEF 0 "register_operand" ""))
14038 (use (match_operand:MODEF 1 "register_operand" ""))]
14039 "(TARGET_USE_FANCY_MATH_387
14040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14041 || TARGET_MIX_SSE_I387)
14042 && flag_unsafe_math_optimizations)
14043 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14044 && !flag_trapping_math)"
14045 {
14046 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14047 && !flag_trapping_math)
14048 {
14049 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14050 FAIL;
14051 if (TARGET_ROUND)
14052 emit_insn (gen_sse4_1_round<mode>2
14053 (operands[0], operands[1], GEN_INT (0x04)));
14054 else
14055 ix86_expand_rint (operand0, operand1);
14056 }
14057 else
14058 {
14059 rtx op0 = gen_reg_rtx (XFmode);
14060 rtx op1 = gen_reg_rtx (XFmode);
14061
14062 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14063 emit_insn (gen_rintxf2 (op0, op1));
14064
14065 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14066 }
14067 DONE;
14068 })
14069
14070 (define_expand "round<mode>2"
14071 [(match_operand:MODEF 0 "register_operand" "")
14072 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14073 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14074 && !flag_trapping_math && !flag_rounding_math"
14075 {
14076 if (optimize_insn_for_size_p ())
14077 FAIL;
14078 if (TARGET_64BIT || (<MODE>mode != DFmode))
14079 ix86_expand_round (operand0, operand1);
14080 else
14081 ix86_expand_rounddf_32 (operand0, operand1);
14082 DONE;
14083 })
14084
14085 (define_insn_and_split "*fistdi2_1"
14086 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14087 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14088 UNSPEC_FIST))]
14089 "TARGET_USE_FANCY_MATH_387
14090 && can_create_pseudo_p ()"
14091 "#"
14092 "&& 1"
14093 [(const_int 0)]
14094 {
14095 if (memory_operand (operands[0], VOIDmode))
14096 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14097 else
14098 {
14099 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14100 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14101 operands[2]));
14102 }
14103 DONE;
14104 }
14105 [(set_attr "type" "fpspc")
14106 (set_attr "mode" "DI")])
14107
14108 (define_insn "fistdi2"
14109 [(set (match_operand:DI 0 "memory_operand" "=m")
14110 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14111 UNSPEC_FIST))
14112 (clobber (match_scratch:XF 2 "=&1f"))]
14113 "TARGET_USE_FANCY_MATH_387"
14114 "* return output_fix_trunc (insn, operands, 0);"
14115 [(set_attr "type" "fpspc")
14116 (set_attr "mode" "DI")])
14117
14118 (define_insn "fistdi2_with_temp"
14119 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14120 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14121 UNSPEC_FIST))
14122 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14123 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14124 "TARGET_USE_FANCY_MATH_387"
14125 "#"
14126 [(set_attr "type" "fpspc")
14127 (set_attr "mode" "DI")])
14128
14129 (define_split
14130 [(set (match_operand:DI 0 "register_operand" "")
14131 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14132 UNSPEC_FIST))
14133 (clobber (match_operand:DI 2 "memory_operand" ""))
14134 (clobber (match_scratch 3 ""))]
14135 "reload_completed"
14136 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14137 (clobber (match_dup 3))])
14138 (set (match_dup 0) (match_dup 2))]
14139 "")
14140
14141 (define_split
14142 [(set (match_operand:DI 0 "memory_operand" "")
14143 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14144 UNSPEC_FIST))
14145 (clobber (match_operand:DI 2 "memory_operand" ""))
14146 (clobber (match_scratch 3 ""))]
14147 "reload_completed"
14148 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14149 (clobber (match_dup 3))])]
14150 "")
14151
14152 (define_insn_and_split "*fist<mode>2_1"
14153 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14154 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14155 UNSPEC_FIST))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && can_create_pseudo_p ()"
14158 "#"
14159 "&& 1"
14160 [(const_int 0)]
14161 {
14162 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14163 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14164 operands[2]));
14165 DONE;
14166 }
14167 [(set_attr "type" "fpspc")
14168 (set_attr "mode" "<MODE>")])
14169
14170 (define_insn "fist<mode>2"
14171 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14172 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14173 UNSPEC_FIST))]
14174 "TARGET_USE_FANCY_MATH_387"
14175 "* return output_fix_trunc (insn, operands, 0);"
14176 [(set_attr "type" "fpspc")
14177 (set_attr "mode" "<MODE>")])
14178
14179 (define_insn "fist<mode>2_with_temp"
14180 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14181 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14182 UNSPEC_FIST))
14183 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14184 "TARGET_USE_FANCY_MATH_387"
14185 "#"
14186 [(set_attr "type" "fpspc")
14187 (set_attr "mode" "<MODE>")])
14188
14189 (define_split
14190 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14191 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14192 UNSPEC_FIST))
14193 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14194 "reload_completed"
14195 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14196 (set (match_dup 0) (match_dup 2))]
14197 "")
14198
14199 (define_split
14200 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14201 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14202 UNSPEC_FIST))
14203 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14204 "reload_completed"
14205 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14206 "")
14207
14208 (define_expand "lrintxf<mode>2"
14209 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14210 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14211 UNSPEC_FIST))]
14212 "TARGET_USE_FANCY_MATH_387"
14213 "")
14214
14215 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14216 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14217 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14218 UNSPEC_FIX_NOTRUNC))]
14219 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14220 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14221 "")
14222
14223 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14224 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14225 (match_operand:MODEF 1 "register_operand" "")]
14226 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14227 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14228 && !flag_trapping_math && !flag_rounding_math"
14229 {
14230 if (optimize_insn_for_size_p ())
14231 FAIL;
14232 ix86_expand_lround (operand0, operand1);
14233 DONE;
14234 })
14235
14236 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14237 (define_insn_and_split "frndintxf2_floor"
14238 [(set (match_operand:XF 0 "register_operand" "")
14239 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14240 UNSPEC_FRNDINT_FLOOR))
14241 (clobber (reg:CC FLAGS_REG))]
14242 "TARGET_USE_FANCY_MATH_387
14243 && flag_unsafe_math_optimizations
14244 && can_create_pseudo_p ()"
14245 "#"
14246 "&& 1"
14247 [(const_int 0)]
14248 {
14249 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14250
14251 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14252 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14253
14254 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14255 operands[2], operands[3]));
14256 DONE;
14257 }
14258 [(set_attr "type" "frndint")
14259 (set_attr "i387_cw" "floor")
14260 (set_attr "mode" "XF")])
14261
14262 (define_insn "frndintxf2_floor_i387"
14263 [(set (match_operand:XF 0 "register_operand" "=f")
14264 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14265 UNSPEC_FRNDINT_FLOOR))
14266 (use (match_operand:HI 2 "memory_operand" "m"))
14267 (use (match_operand:HI 3 "memory_operand" "m"))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && flag_unsafe_math_optimizations"
14270 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14271 [(set_attr "type" "frndint")
14272 (set_attr "i387_cw" "floor")
14273 (set_attr "mode" "XF")])
14274
14275 (define_expand "floorxf2"
14276 [(use (match_operand:XF 0 "register_operand" ""))
14277 (use (match_operand:XF 1 "register_operand" ""))]
14278 "TARGET_USE_FANCY_MATH_387
14279 && flag_unsafe_math_optimizations"
14280 {
14281 if (optimize_insn_for_size_p ())
14282 FAIL;
14283 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14284 DONE;
14285 })
14286
14287 (define_expand "floor<mode>2"
14288 [(use (match_operand:MODEF 0 "register_operand" ""))
14289 (use (match_operand:MODEF 1 "register_operand" ""))]
14290 "(TARGET_USE_FANCY_MATH_387
14291 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14292 || TARGET_MIX_SSE_I387)
14293 && flag_unsafe_math_optimizations)
14294 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14295 && !flag_trapping_math)"
14296 {
14297 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14298 && !flag_trapping_math
14299 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14300 {
14301 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14302 FAIL;
14303 if (TARGET_ROUND)
14304 emit_insn (gen_sse4_1_round<mode>2
14305 (operands[0], operands[1], GEN_INT (0x01)));
14306 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14307 ix86_expand_floorceil (operand0, operand1, true);
14308 else
14309 ix86_expand_floorceildf_32 (operand0, operand1, true);
14310 }
14311 else
14312 {
14313 rtx op0, op1;
14314
14315 if (optimize_insn_for_size_p ())
14316 FAIL;
14317
14318 op0 = gen_reg_rtx (XFmode);
14319 op1 = gen_reg_rtx (XFmode);
14320 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14321 emit_insn (gen_frndintxf2_floor (op0, op1));
14322
14323 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14324 }
14325 DONE;
14326 })
14327
14328 (define_insn_and_split "*fist<mode>2_floor_1"
14329 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14330 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14331 UNSPEC_FIST_FLOOR))
14332 (clobber (reg:CC FLAGS_REG))]
14333 "TARGET_USE_FANCY_MATH_387
14334 && flag_unsafe_math_optimizations
14335 && can_create_pseudo_p ()"
14336 "#"
14337 "&& 1"
14338 [(const_int 0)]
14339 {
14340 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14341
14342 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14343 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14344 if (memory_operand (operands[0], VOIDmode))
14345 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14346 operands[2], operands[3]));
14347 else
14348 {
14349 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14350 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14351 operands[2], operands[3],
14352 operands[4]));
14353 }
14354 DONE;
14355 }
14356 [(set_attr "type" "fistp")
14357 (set_attr "i387_cw" "floor")
14358 (set_attr "mode" "<MODE>")])
14359
14360 (define_insn "fistdi2_floor"
14361 [(set (match_operand:DI 0 "memory_operand" "=m")
14362 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14363 UNSPEC_FIST_FLOOR))
14364 (use (match_operand:HI 2 "memory_operand" "m"))
14365 (use (match_operand:HI 3 "memory_operand" "m"))
14366 (clobber (match_scratch:XF 4 "=&1f"))]
14367 "TARGET_USE_FANCY_MATH_387
14368 && flag_unsafe_math_optimizations"
14369 "* return output_fix_trunc (insn, operands, 0);"
14370 [(set_attr "type" "fistp")
14371 (set_attr "i387_cw" "floor")
14372 (set_attr "mode" "DI")])
14373
14374 (define_insn "fistdi2_floor_with_temp"
14375 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14376 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14377 UNSPEC_FIST_FLOOR))
14378 (use (match_operand:HI 2 "memory_operand" "m,m"))
14379 (use (match_operand:HI 3 "memory_operand" "m,m"))
14380 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14381 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14382 "TARGET_USE_FANCY_MATH_387
14383 && flag_unsafe_math_optimizations"
14384 "#"
14385 [(set_attr "type" "fistp")
14386 (set_attr "i387_cw" "floor")
14387 (set_attr "mode" "DI")])
14388
14389 (define_split
14390 [(set (match_operand:DI 0 "register_operand" "")
14391 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14392 UNSPEC_FIST_FLOOR))
14393 (use (match_operand:HI 2 "memory_operand" ""))
14394 (use (match_operand:HI 3 "memory_operand" ""))
14395 (clobber (match_operand:DI 4 "memory_operand" ""))
14396 (clobber (match_scratch 5 ""))]
14397 "reload_completed"
14398 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14399 (use (match_dup 2))
14400 (use (match_dup 3))
14401 (clobber (match_dup 5))])
14402 (set (match_dup 0) (match_dup 4))]
14403 "")
14404
14405 (define_split
14406 [(set (match_operand:DI 0 "memory_operand" "")
14407 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14408 UNSPEC_FIST_FLOOR))
14409 (use (match_operand:HI 2 "memory_operand" ""))
14410 (use (match_operand:HI 3 "memory_operand" ""))
14411 (clobber (match_operand:DI 4 "memory_operand" ""))
14412 (clobber (match_scratch 5 ""))]
14413 "reload_completed"
14414 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14415 (use (match_dup 2))
14416 (use (match_dup 3))
14417 (clobber (match_dup 5))])]
14418 "")
14419
14420 (define_insn "fist<mode>2_floor"
14421 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14422 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14423 UNSPEC_FIST_FLOOR))
14424 (use (match_operand:HI 2 "memory_operand" "m"))
14425 (use (match_operand:HI 3 "memory_operand" "m"))]
14426 "TARGET_USE_FANCY_MATH_387
14427 && flag_unsafe_math_optimizations"
14428 "* return output_fix_trunc (insn, operands, 0);"
14429 [(set_attr "type" "fistp")
14430 (set_attr "i387_cw" "floor")
14431 (set_attr "mode" "<MODE>")])
14432
14433 (define_insn "fist<mode>2_floor_with_temp"
14434 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14435 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14436 UNSPEC_FIST_FLOOR))
14437 (use (match_operand:HI 2 "memory_operand" "m,m"))
14438 (use (match_operand:HI 3 "memory_operand" "m,m"))
14439 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && flag_unsafe_math_optimizations"
14442 "#"
14443 [(set_attr "type" "fistp")
14444 (set_attr "i387_cw" "floor")
14445 (set_attr "mode" "<MODE>")])
14446
14447 (define_split
14448 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14449 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14450 UNSPEC_FIST_FLOOR))
14451 (use (match_operand:HI 2 "memory_operand" ""))
14452 (use (match_operand:HI 3 "memory_operand" ""))
14453 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14454 "reload_completed"
14455 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14456 UNSPEC_FIST_FLOOR))
14457 (use (match_dup 2))
14458 (use (match_dup 3))])
14459 (set (match_dup 0) (match_dup 4))]
14460 "")
14461
14462 (define_split
14463 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14464 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14465 UNSPEC_FIST_FLOOR))
14466 (use (match_operand:HI 2 "memory_operand" ""))
14467 (use (match_operand:HI 3 "memory_operand" ""))
14468 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14469 "reload_completed"
14470 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14471 UNSPEC_FIST_FLOOR))
14472 (use (match_dup 2))
14473 (use (match_dup 3))])]
14474 "")
14475
14476 (define_expand "lfloorxf<mode>2"
14477 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14478 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14479 UNSPEC_FIST_FLOOR))
14480 (clobber (reg:CC FLAGS_REG))])]
14481 "TARGET_USE_FANCY_MATH_387
14482 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14483 && flag_unsafe_math_optimizations"
14484 "")
14485
14486 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14487 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14488 (match_operand:MODEF 1 "register_operand" "")]
14489 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14490 && !flag_trapping_math"
14491 {
14492 if (TARGET_64BIT && optimize_insn_for_size_p ())
14493 FAIL;
14494 ix86_expand_lfloorceil (operand0, operand1, true);
14495 DONE;
14496 })
14497
14498 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14499 (define_insn_and_split "frndintxf2_ceil"
14500 [(set (match_operand:XF 0 "register_operand" "")
14501 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14502 UNSPEC_FRNDINT_CEIL))
14503 (clobber (reg:CC FLAGS_REG))]
14504 "TARGET_USE_FANCY_MATH_387
14505 && flag_unsafe_math_optimizations
14506 && can_create_pseudo_p ()"
14507 "#"
14508 "&& 1"
14509 [(const_int 0)]
14510 {
14511 ix86_optimize_mode_switching[I387_CEIL] = 1;
14512
14513 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14514 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14515
14516 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14517 operands[2], operands[3]));
14518 DONE;
14519 }
14520 [(set_attr "type" "frndint")
14521 (set_attr "i387_cw" "ceil")
14522 (set_attr "mode" "XF")])
14523
14524 (define_insn "frndintxf2_ceil_i387"
14525 [(set (match_operand:XF 0 "register_operand" "=f")
14526 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14527 UNSPEC_FRNDINT_CEIL))
14528 (use (match_operand:HI 2 "memory_operand" "m"))
14529 (use (match_operand:HI 3 "memory_operand" "m"))]
14530 "TARGET_USE_FANCY_MATH_387
14531 && flag_unsafe_math_optimizations"
14532 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14533 [(set_attr "type" "frndint")
14534 (set_attr "i387_cw" "ceil")
14535 (set_attr "mode" "XF")])
14536
14537 (define_expand "ceilxf2"
14538 [(use (match_operand:XF 0 "register_operand" ""))
14539 (use (match_operand:XF 1 "register_operand" ""))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_unsafe_math_optimizations"
14542 {
14543 if (optimize_insn_for_size_p ())
14544 FAIL;
14545 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14546 DONE;
14547 })
14548
14549 (define_expand "ceil<mode>2"
14550 [(use (match_operand:MODEF 0 "register_operand" ""))
14551 (use (match_operand:MODEF 1 "register_operand" ""))]
14552 "(TARGET_USE_FANCY_MATH_387
14553 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14554 || TARGET_MIX_SSE_I387)
14555 && flag_unsafe_math_optimizations)
14556 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14557 && !flag_trapping_math)"
14558 {
14559 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14560 && !flag_trapping_math
14561 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14562 {
14563 if (TARGET_ROUND)
14564 emit_insn (gen_sse4_1_round<mode>2
14565 (operands[0], operands[1], GEN_INT (0x02)));
14566 else if (optimize_insn_for_size_p ())
14567 FAIL;
14568 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14569 ix86_expand_floorceil (operand0, operand1, false);
14570 else
14571 ix86_expand_floorceildf_32 (operand0, operand1, false);
14572 }
14573 else
14574 {
14575 rtx op0, op1;
14576
14577 if (optimize_insn_for_size_p ())
14578 FAIL;
14579
14580 op0 = gen_reg_rtx (XFmode);
14581 op1 = gen_reg_rtx (XFmode);
14582 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14583 emit_insn (gen_frndintxf2_ceil (op0, op1));
14584
14585 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14586 }
14587 DONE;
14588 })
14589
14590 (define_insn_and_split "*fist<mode>2_ceil_1"
14591 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14592 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14593 UNSPEC_FIST_CEIL))
14594 (clobber (reg:CC FLAGS_REG))]
14595 "TARGET_USE_FANCY_MATH_387
14596 && flag_unsafe_math_optimizations
14597 && can_create_pseudo_p ()"
14598 "#"
14599 "&& 1"
14600 [(const_int 0)]
14601 {
14602 ix86_optimize_mode_switching[I387_CEIL] = 1;
14603
14604 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14605 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14606 if (memory_operand (operands[0], VOIDmode))
14607 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14608 operands[2], operands[3]));
14609 else
14610 {
14611 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14612 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14613 operands[2], operands[3],
14614 operands[4]));
14615 }
14616 DONE;
14617 }
14618 [(set_attr "type" "fistp")
14619 (set_attr "i387_cw" "ceil")
14620 (set_attr "mode" "<MODE>")])
14621
14622 (define_insn "fistdi2_ceil"
14623 [(set (match_operand:DI 0 "memory_operand" "=m")
14624 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14625 UNSPEC_FIST_CEIL))
14626 (use (match_operand:HI 2 "memory_operand" "m"))
14627 (use (match_operand:HI 3 "memory_operand" "m"))
14628 (clobber (match_scratch:XF 4 "=&1f"))]
14629 "TARGET_USE_FANCY_MATH_387
14630 && flag_unsafe_math_optimizations"
14631 "* return output_fix_trunc (insn, operands, 0);"
14632 [(set_attr "type" "fistp")
14633 (set_attr "i387_cw" "ceil")
14634 (set_attr "mode" "DI")])
14635
14636 (define_insn "fistdi2_ceil_with_temp"
14637 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14638 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14639 UNSPEC_FIST_CEIL))
14640 (use (match_operand:HI 2 "memory_operand" "m,m"))
14641 (use (match_operand:HI 3 "memory_operand" "m,m"))
14642 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14643 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14644 "TARGET_USE_FANCY_MATH_387
14645 && flag_unsafe_math_optimizations"
14646 "#"
14647 [(set_attr "type" "fistp")
14648 (set_attr "i387_cw" "ceil")
14649 (set_attr "mode" "DI")])
14650
14651 (define_split
14652 [(set (match_operand:DI 0 "register_operand" "")
14653 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14654 UNSPEC_FIST_CEIL))
14655 (use (match_operand:HI 2 "memory_operand" ""))
14656 (use (match_operand:HI 3 "memory_operand" ""))
14657 (clobber (match_operand:DI 4 "memory_operand" ""))
14658 (clobber (match_scratch 5 ""))]
14659 "reload_completed"
14660 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14661 (use (match_dup 2))
14662 (use (match_dup 3))
14663 (clobber (match_dup 5))])
14664 (set (match_dup 0) (match_dup 4))]
14665 "")
14666
14667 (define_split
14668 [(set (match_operand:DI 0 "memory_operand" "")
14669 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14670 UNSPEC_FIST_CEIL))
14671 (use (match_operand:HI 2 "memory_operand" ""))
14672 (use (match_operand:HI 3 "memory_operand" ""))
14673 (clobber (match_operand:DI 4 "memory_operand" ""))
14674 (clobber (match_scratch 5 ""))]
14675 "reload_completed"
14676 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14677 (use (match_dup 2))
14678 (use (match_dup 3))
14679 (clobber (match_dup 5))])]
14680 "")
14681
14682 (define_insn "fist<mode>2_ceil"
14683 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14684 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14685 UNSPEC_FIST_CEIL))
14686 (use (match_operand:HI 2 "memory_operand" "m"))
14687 (use (match_operand:HI 3 "memory_operand" "m"))]
14688 "TARGET_USE_FANCY_MATH_387
14689 && flag_unsafe_math_optimizations"
14690 "* return output_fix_trunc (insn, operands, 0);"
14691 [(set_attr "type" "fistp")
14692 (set_attr "i387_cw" "ceil")
14693 (set_attr "mode" "<MODE>")])
14694
14695 (define_insn "fist<mode>2_ceil_with_temp"
14696 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14697 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14698 UNSPEC_FIST_CEIL))
14699 (use (match_operand:HI 2 "memory_operand" "m,m"))
14700 (use (match_operand:HI 3 "memory_operand" "m,m"))
14701 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14702 "TARGET_USE_FANCY_MATH_387
14703 && flag_unsafe_math_optimizations"
14704 "#"
14705 [(set_attr "type" "fistp")
14706 (set_attr "i387_cw" "ceil")
14707 (set_attr "mode" "<MODE>")])
14708
14709 (define_split
14710 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14711 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14712 UNSPEC_FIST_CEIL))
14713 (use (match_operand:HI 2 "memory_operand" ""))
14714 (use (match_operand:HI 3 "memory_operand" ""))
14715 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14716 "reload_completed"
14717 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14718 UNSPEC_FIST_CEIL))
14719 (use (match_dup 2))
14720 (use (match_dup 3))])
14721 (set (match_dup 0) (match_dup 4))]
14722 "")
14723
14724 (define_split
14725 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14726 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14727 UNSPEC_FIST_CEIL))
14728 (use (match_operand:HI 2 "memory_operand" ""))
14729 (use (match_operand:HI 3 "memory_operand" ""))
14730 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14731 "reload_completed"
14732 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14733 UNSPEC_FIST_CEIL))
14734 (use (match_dup 2))
14735 (use (match_dup 3))])]
14736 "")
14737
14738 (define_expand "lceilxf<mode>2"
14739 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14740 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14741 UNSPEC_FIST_CEIL))
14742 (clobber (reg:CC FLAGS_REG))])]
14743 "TARGET_USE_FANCY_MATH_387
14744 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14745 && flag_unsafe_math_optimizations"
14746 "")
14747
14748 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14749 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14750 (match_operand:MODEF 1 "register_operand" "")]
14751 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14752 && !flag_trapping_math"
14753 {
14754 ix86_expand_lfloorceil (operand0, operand1, false);
14755 DONE;
14756 })
14757
14758 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14759 (define_insn_and_split "frndintxf2_trunc"
14760 [(set (match_operand:XF 0 "register_operand" "")
14761 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14762 UNSPEC_FRNDINT_TRUNC))
14763 (clobber (reg:CC FLAGS_REG))]
14764 "TARGET_USE_FANCY_MATH_387
14765 && flag_unsafe_math_optimizations
14766 && can_create_pseudo_p ()"
14767 "#"
14768 "&& 1"
14769 [(const_int 0)]
14770 {
14771 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14772
14773 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14774 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14775
14776 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14777 operands[2], operands[3]));
14778 DONE;
14779 }
14780 [(set_attr "type" "frndint")
14781 (set_attr "i387_cw" "trunc")
14782 (set_attr "mode" "XF")])
14783
14784 (define_insn "frndintxf2_trunc_i387"
14785 [(set (match_operand:XF 0 "register_operand" "=f")
14786 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14787 UNSPEC_FRNDINT_TRUNC))
14788 (use (match_operand:HI 2 "memory_operand" "m"))
14789 (use (match_operand:HI 3 "memory_operand" "m"))]
14790 "TARGET_USE_FANCY_MATH_387
14791 && flag_unsafe_math_optimizations"
14792 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14793 [(set_attr "type" "frndint")
14794 (set_attr "i387_cw" "trunc")
14795 (set_attr "mode" "XF")])
14796
14797 (define_expand "btruncxf2"
14798 [(use (match_operand:XF 0 "register_operand" ""))
14799 (use (match_operand:XF 1 "register_operand" ""))]
14800 "TARGET_USE_FANCY_MATH_387
14801 && flag_unsafe_math_optimizations"
14802 {
14803 if (optimize_insn_for_size_p ())
14804 FAIL;
14805 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14806 DONE;
14807 })
14808
14809 (define_expand "btrunc<mode>2"
14810 [(use (match_operand:MODEF 0 "register_operand" ""))
14811 (use (match_operand:MODEF 1 "register_operand" ""))]
14812 "(TARGET_USE_FANCY_MATH_387
14813 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14814 || TARGET_MIX_SSE_I387)
14815 && flag_unsafe_math_optimizations)
14816 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14817 && !flag_trapping_math)"
14818 {
14819 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14820 && !flag_trapping_math
14821 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14822 {
14823 if (TARGET_ROUND)
14824 emit_insn (gen_sse4_1_round<mode>2
14825 (operands[0], operands[1], GEN_INT (0x03)));
14826 else if (optimize_insn_for_size_p ())
14827 FAIL;
14828 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14829 ix86_expand_trunc (operand0, operand1);
14830 else
14831 ix86_expand_truncdf_32 (operand0, operand1);
14832 }
14833 else
14834 {
14835 rtx op0, op1;
14836
14837 if (optimize_insn_for_size_p ())
14838 FAIL;
14839
14840 op0 = gen_reg_rtx (XFmode);
14841 op1 = gen_reg_rtx (XFmode);
14842 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14843 emit_insn (gen_frndintxf2_trunc (op0, op1));
14844
14845 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14846 }
14847 DONE;
14848 })
14849
14850 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14851 (define_insn_and_split "frndintxf2_mask_pm"
14852 [(set (match_operand:XF 0 "register_operand" "")
14853 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14854 UNSPEC_FRNDINT_MASK_PM))
14855 (clobber (reg:CC FLAGS_REG))]
14856 "TARGET_USE_FANCY_MATH_387
14857 && flag_unsafe_math_optimizations
14858 && can_create_pseudo_p ()"
14859 "#"
14860 "&& 1"
14861 [(const_int 0)]
14862 {
14863 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14864
14865 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14866 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14867
14868 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14869 operands[2], operands[3]));
14870 DONE;
14871 }
14872 [(set_attr "type" "frndint")
14873 (set_attr "i387_cw" "mask_pm")
14874 (set_attr "mode" "XF")])
14875
14876 (define_insn "frndintxf2_mask_pm_i387"
14877 [(set (match_operand:XF 0 "register_operand" "=f")
14878 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14879 UNSPEC_FRNDINT_MASK_PM))
14880 (use (match_operand:HI 2 "memory_operand" "m"))
14881 (use (match_operand:HI 3 "memory_operand" "m"))]
14882 "TARGET_USE_FANCY_MATH_387
14883 && flag_unsafe_math_optimizations"
14884 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14885 [(set_attr "type" "frndint")
14886 (set_attr "i387_cw" "mask_pm")
14887 (set_attr "mode" "XF")])
14888
14889 (define_expand "nearbyintxf2"
14890 [(use (match_operand:XF 0 "register_operand" ""))
14891 (use (match_operand:XF 1 "register_operand" ""))]
14892 "TARGET_USE_FANCY_MATH_387
14893 && flag_unsafe_math_optimizations"
14894 {
14895 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14896
14897 DONE;
14898 })
14899
14900 (define_expand "nearbyint<mode>2"
14901 [(use (match_operand:MODEF 0 "register_operand" ""))
14902 (use (match_operand:MODEF 1 "register_operand" ""))]
14903 "TARGET_USE_FANCY_MATH_387
14904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14905 || TARGET_MIX_SSE_I387)
14906 && flag_unsafe_math_optimizations"
14907 {
14908 rtx op0 = gen_reg_rtx (XFmode);
14909 rtx op1 = gen_reg_rtx (XFmode);
14910
14911 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14912 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14913
14914 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14915 DONE;
14916 })
14917
14918 (define_insn "fxam<mode>2_i387"
14919 [(set (match_operand:HI 0 "register_operand" "=a")
14920 (unspec:HI
14921 [(match_operand:X87MODEF 1 "register_operand" "f")]
14922 UNSPEC_FXAM))]
14923 "TARGET_USE_FANCY_MATH_387"
14924 "fxam\n\tfnstsw\t%0"
14925 [(set_attr "type" "multi")
14926 (set_attr "length" "4")
14927 (set_attr "unit" "i387")
14928 (set_attr "mode" "<MODE>")])
14929
14930 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14931 [(set (match_operand:HI 0 "register_operand" "")
14932 (unspec:HI
14933 [(match_operand:MODEF 1 "memory_operand" "")]
14934 UNSPEC_FXAM_MEM))]
14935 "TARGET_USE_FANCY_MATH_387
14936 && can_create_pseudo_p ()"
14937 "#"
14938 "&& 1"
14939 [(set (match_dup 2)(match_dup 1))
14940 (set (match_dup 0)
14941 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14942 {
14943 operands[2] = gen_reg_rtx (<MODE>mode);
14944
14945 MEM_VOLATILE_P (operands[1]) = 1;
14946 }
14947 [(set_attr "type" "multi")
14948 (set_attr "unit" "i387")
14949 (set_attr "mode" "<MODE>")])
14950
14951 (define_expand "isinfxf2"
14952 [(use (match_operand:SI 0 "register_operand" ""))
14953 (use (match_operand:XF 1 "register_operand" ""))]
14954 "TARGET_USE_FANCY_MATH_387
14955 && TARGET_C99_FUNCTIONS"
14956 {
14957 rtx mask = GEN_INT (0x45);
14958 rtx val = GEN_INT (0x05);
14959
14960 rtx cond;
14961
14962 rtx scratch = gen_reg_rtx (HImode);
14963 rtx res = gen_reg_rtx (QImode);
14964
14965 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14966
14967 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14968 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14969 cond = gen_rtx_fmt_ee (EQ, QImode,
14970 gen_rtx_REG (CCmode, FLAGS_REG),
14971 const0_rtx);
14972 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14973 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14974 DONE;
14975 })
14976
14977 (define_expand "isinf<mode>2"
14978 [(use (match_operand:SI 0 "register_operand" ""))
14979 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && TARGET_C99_FUNCTIONS
14982 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14983 {
14984 rtx mask = GEN_INT (0x45);
14985 rtx val = GEN_INT (0x05);
14986
14987 rtx cond;
14988
14989 rtx scratch = gen_reg_rtx (HImode);
14990 rtx res = gen_reg_rtx (QImode);
14991
14992 /* Remove excess precision by forcing value through memory. */
14993 if (memory_operand (operands[1], VOIDmode))
14994 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14995 else
14996 {
14997 enum ix86_stack_slot slot = (virtuals_instantiated
14998 ? SLOT_TEMP
14999 : SLOT_VIRTUAL);
15000 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15001
15002 emit_move_insn (temp, operands[1]);
15003 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15004 }
15005
15006 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15007 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15008 cond = gen_rtx_fmt_ee (EQ, QImode,
15009 gen_rtx_REG (CCmode, FLAGS_REG),
15010 const0_rtx);
15011 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15012 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15013 DONE;
15014 })
15015
15016 (define_expand "signbit<mode>2"
15017 [(use (match_operand:SI 0 "register_operand" ""))
15018 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15019 "TARGET_USE_FANCY_MATH_387
15020 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15021 {
15022 rtx mask = GEN_INT (0x0200);
15023
15024 rtx scratch = gen_reg_rtx (HImode);
15025
15026 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15027 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15028 DONE;
15029 })
15030 \f
15031 ;; Block operation instructions
15032
15033 (define_insn "cld"
15034 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15035 ""
15036 "cld"
15037 [(set_attr "length" "1")
15038 (set_attr "length_immediate" "0")
15039 (set_attr "modrm" "0")])
15040
15041 (define_expand "movmemsi"
15042 [(use (match_operand:BLK 0 "memory_operand" ""))
15043 (use (match_operand:BLK 1 "memory_operand" ""))
15044 (use (match_operand:SI 2 "nonmemory_operand" ""))
15045 (use (match_operand:SI 3 "const_int_operand" ""))
15046 (use (match_operand:SI 4 "const_int_operand" ""))
15047 (use (match_operand:SI 5 "const_int_operand" ""))]
15048 ""
15049 {
15050 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15051 operands[4], operands[5]))
15052 DONE;
15053 else
15054 FAIL;
15055 })
15056
15057 (define_expand "movmemdi"
15058 [(use (match_operand:BLK 0 "memory_operand" ""))
15059 (use (match_operand:BLK 1 "memory_operand" ""))
15060 (use (match_operand:DI 2 "nonmemory_operand" ""))
15061 (use (match_operand:DI 3 "const_int_operand" ""))
15062 (use (match_operand:SI 4 "const_int_operand" ""))
15063 (use (match_operand:SI 5 "const_int_operand" ""))]
15064 "TARGET_64BIT"
15065 {
15066 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15067 operands[4], operands[5]))
15068 DONE;
15069 else
15070 FAIL;
15071 })
15072
15073 ;; Most CPUs don't like single string operations
15074 ;; Handle this case here to simplify previous expander.
15075
15076 (define_expand "strmov"
15077 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15078 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15079 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15080 (clobber (reg:CC FLAGS_REG))])
15081 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15082 (clobber (reg:CC FLAGS_REG))])]
15083 ""
15084 {
15085 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15086
15087 /* If .md ever supports :P for Pmode, these can be directly
15088 in the pattern above. */
15089 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15090 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15091
15092 /* Can't use this if the user has appropriated esi or edi. */
15093 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15094 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15095 {
15096 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15097 operands[2], operands[3],
15098 operands[5], operands[6]));
15099 DONE;
15100 }
15101
15102 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15103 })
15104
15105 (define_expand "strmov_singleop"
15106 [(parallel [(set (match_operand 1 "memory_operand" "")
15107 (match_operand 3 "memory_operand" ""))
15108 (set (match_operand 0 "register_operand" "")
15109 (match_operand 4 "" ""))
15110 (set (match_operand 2 "register_operand" "")
15111 (match_operand 5 "" ""))])]
15112 ""
15113 "ix86_current_function_needs_cld = 1;")
15114
15115 (define_insn "*strmovdi_rex_1"
15116 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15117 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15118 (set (match_operand:DI 0 "register_operand" "=D")
15119 (plus:DI (match_dup 2)
15120 (const_int 8)))
15121 (set (match_operand:DI 1 "register_operand" "=S")
15122 (plus:DI (match_dup 3)
15123 (const_int 8)))]
15124 "TARGET_64BIT"
15125 "movsq"
15126 [(set_attr "type" "str")
15127 (set_attr "mode" "DI")
15128 (set_attr "memory" "both")])
15129
15130 (define_insn "*strmovsi_1"
15131 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15132 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15133 (set (match_operand:SI 0 "register_operand" "=D")
15134 (plus:SI (match_dup 2)
15135 (const_int 4)))
15136 (set (match_operand:SI 1 "register_operand" "=S")
15137 (plus:SI (match_dup 3)
15138 (const_int 4)))]
15139 "!TARGET_64BIT"
15140 "movs{l|d}"
15141 [(set_attr "type" "str")
15142 (set_attr "mode" "SI")
15143 (set_attr "memory" "both")])
15144
15145 (define_insn "*strmovsi_rex_1"
15146 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15147 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15148 (set (match_operand:DI 0 "register_operand" "=D")
15149 (plus:DI (match_dup 2)
15150 (const_int 4)))
15151 (set (match_operand:DI 1 "register_operand" "=S")
15152 (plus:DI (match_dup 3)
15153 (const_int 4)))]
15154 "TARGET_64BIT"
15155 "movs{l|d}"
15156 [(set_attr "type" "str")
15157 (set_attr "mode" "SI")
15158 (set_attr "memory" "both")])
15159
15160 (define_insn "*strmovhi_1"
15161 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15162 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15163 (set (match_operand:SI 0 "register_operand" "=D")
15164 (plus:SI (match_dup 2)
15165 (const_int 2)))
15166 (set (match_operand:SI 1 "register_operand" "=S")
15167 (plus:SI (match_dup 3)
15168 (const_int 2)))]
15169 "!TARGET_64BIT"
15170 "movsw"
15171 [(set_attr "type" "str")
15172 (set_attr "memory" "both")
15173 (set_attr "mode" "HI")])
15174
15175 (define_insn "*strmovhi_rex_1"
15176 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15177 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15178 (set (match_operand:DI 0 "register_operand" "=D")
15179 (plus:DI (match_dup 2)
15180 (const_int 2)))
15181 (set (match_operand:DI 1 "register_operand" "=S")
15182 (plus:DI (match_dup 3)
15183 (const_int 2)))]
15184 "TARGET_64BIT"
15185 "movsw"
15186 [(set_attr "type" "str")
15187 (set_attr "memory" "both")
15188 (set_attr "mode" "HI")])
15189
15190 (define_insn "*strmovqi_1"
15191 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15192 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15193 (set (match_operand:SI 0 "register_operand" "=D")
15194 (plus:SI (match_dup 2)
15195 (const_int 1)))
15196 (set (match_operand:SI 1 "register_operand" "=S")
15197 (plus:SI (match_dup 3)
15198 (const_int 1)))]
15199 "!TARGET_64BIT"
15200 "movsb"
15201 [(set_attr "type" "str")
15202 (set_attr "memory" "both")
15203 (set_attr "mode" "QI")])
15204
15205 (define_insn "*strmovqi_rex_1"
15206 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15207 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15208 (set (match_operand:DI 0 "register_operand" "=D")
15209 (plus:DI (match_dup 2)
15210 (const_int 1)))
15211 (set (match_operand:DI 1 "register_operand" "=S")
15212 (plus:DI (match_dup 3)
15213 (const_int 1)))]
15214 "TARGET_64BIT"
15215 "movsb"
15216 [(set_attr "type" "str")
15217 (set_attr "memory" "both")
15218 (set_attr "prefix_rex" "0")
15219 (set_attr "mode" "QI")])
15220
15221 (define_expand "rep_mov"
15222 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15223 (set (match_operand 0 "register_operand" "")
15224 (match_operand 5 "" ""))
15225 (set (match_operand 2 "register_operand" "")
15226 (match_operand 6 "" ""))
15227 (set (match_operand 1 "memory_operand" "")
15228 (match_operand 3 "memory_operand" ""))
15229 (use (match_dup 4))])]
15230 ""
15231 "ix86_current_function_needs_cld = 1;")
15232
15233 (define_insn "*rep_movdi_rex64"
15234 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15235 (set (match_operand:DI 0 "register_operand" "=D")
15236 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15237 (const_int 3))
15238 (match_operand:DI 3 "register_operand" "0")))
15239 (set (match_operand:DI 1 "register_operand" "=S")
15240 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15241 (match_operand:DI 4 "register_operand" "1")))
15242 (set (mem:BLK (match_dup 3))
15243 (mem:BLK (match_dup 4)))
15244 (use (match_dup 5))]
15245 "TARGET_64BIT"
15246 "rep{%;} movsq"
15247 [(set_attr "type" "str")
15248 (set_attr "prefix_rep" "1")
15249 (set_attr "memory" "both")
15250 (set_attr "mode" "DI")])
15251
15252 (define_insn "*rep_movsi"
15253 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15254 (set (match_operand:SI 0 "register_operand" "=D")
15255 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15256 (const_int 2))
15257 (match_operand:SI 3 "register_operand" "0")))
15258 (set (match_operand:SI 1 "register_operand" "=S")
15259 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15260 (match_operand:SI 4 "register_operand" "1")))
15261 (set (mem:BLK (match_dup 3))
15262 (mem:BLK (match_dup 4)))
15263 (use (match_dup 5))]
15264 "!TARGET_64BIT"
15265 "rep{%;} movs{l|d}"
15266 [(set_attr "type" "str")
15267 (set_attr "prefix_rep" "1")
15268 (set_attr "memory" "both")
15269 (set_attr "mode" "SI")])
15270
15271 (define_insn "*rep_movsi_rex64"
15272 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15273 (set (match_operand:DI 0 "register_operand" "=D")
15274 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15275 (const_int 2))
15276 (match_operand:DI 3 "register_operand" "0")))
15277 (set (match_operand:DI 1 "register_operand" "=S")
15278 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15279 (match_operand:DI 4 "register_operand" "1")))
15280 (set (mem:BLK (match_dup 3))
15281 (mem:BLK (match_dup 4)))
15282 (use (match_dup 5))]
15283 "TARGET_64BIT"
15284 "rep{%;} movs{l|d}"
15285 [(set_attr "type" "str")
15286 (set_attr "prefix_rep" "1")
15287 (set_attr "memory" "both")
15288 (set_attr "mode" "SI")])
15289
15290 (define_insn "*rep_movqi"
15291 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15292 (set (match_operand:SI 0 "register_operand" "=D")
15293 (plus:SI (match_operand:SI 3 "register_operand" "0")
15294 (match_operand:SI 5 "register_operand" "2")))
15295 (set (match_operand:SI 1 "register_operand" "=S")
15296 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15297 (set (mem:BLK (match_dup 3))
15298 (mem:BLK (match_dup 4)))
15299 (use (match_dup 5))]
15300 "!TARGET_64BIT"
15301 "rep{%;} movsb"
15302 [(set_attr "type" "str")
15303 (set_attr "prefix_rep" "1")
15304 (set_attr "memory" "both")
15305 (set_attr "mode" "SI")])
15306
15307 (define_insn "*rep_movqi_rex64"
15308 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15309 (set (match_operand:DI 0 "register_operand" "=D")
15310 (plus:DI (match_operand:DI 3 "register_operand" "0")
15311 (match_operand:DI 5 "register_operand" "2")))
15312 (set (match_operand:DI 1 "register_operand" "=S")
15313 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15314 (set (mem:BLK (match_dup 3))
15315 (mem:BLK (match_dup 4)))
15316 (use (match_dup 5))]
15317 "TARGET_64BIT"
15318 "rep{%;} movsb"
15319 [(set_attr "type" "str")
15320 (set_attr "prefix_rep" "1")
15321 (set_attr "memory" "both")
15322 (set_attr "mode" "SI")])
15323
15324 (define_expand "setmemsi"
15325 [(use (match_operand:BLK 0 "memory_operand" ""))
15326 (use (match_operand:SI 1 "nonmemory_operand" ""))
15327 (use (match_operand 2 "const_int_operand" ""))
15328 (use (match_operand 3 "const_int_operand" ""))
15329 (use (match_operand:SI 4 "const_int_operand" ""))
15330 (use (match_operand:SI 5 "const_int_operand" ""))]
15331 ""
15332 {
15333 if (ix86_expand_setmem (operands[0], operands[1],
15334 operands[2], operands[3],
15335 operands[4], operands[5]))
15336 DONE;
15337 else
15338 FAIL;
15339 })
15340
15341 (define_expand "setmemdi"
15342 [(use (match_operand:BLK 0 "memory_operand" ""))
15343 (use (match_operand:DI 1 "nonmemory_operand" ""))
15344 (use (match_operand 2 "const_int_operand" ""))
15345 (use (match_operand 3 "const_int_operand" ""))
15346 (use (match_operand 4 "const_int_operand" ""))
15347 (use (match_operand 5 "const_int_operand" ""))]
15348 "TARGET_64BIT"
15349 {
15350 if (ix86_expand_setmem (operands[0], operands[1],
15351 operands[2], operands[3],
15352 operands[4], operands[5]))
15353 DONE;
15354 else
15355 FAIL;
15356 })
15357
15358 ;; Most CPUs don't like single string operations
15359 ;; Handle this case here to simplify previous expander.
15360
15361 (define_expand "strset"
15362 [(set (match_operand 1 "memory_operand" "")
15363 (match_operand 2 "register_operand" ""))
15364 (parallel [(set (match_operand 0 "register_operand" "")
15365 (match_dup 3))
15366 (clobber (reg:CC FLAGS_REG))])]
15367 ""
15368 {
15369 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15370 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15371
15372 /* If .md ever supports :P for Pmode, this can be directly
15373 in the pattern above. */
15374 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15375 GEN_INT (GET_MODE_SIZE (GET_MODE
15376 (operands[2]))));
15377 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15378 {
15379 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15380 operands[3]));
15381 DONE;
15382 }
15383 })
15384
15385 (define_expand "strset_singleop"
15386 [(parallel [(set (match_operand 1 "memory_operand" "")
15387 (match_operand 2 "register_operand" ""))
15388 (set (match_operand 0 "register_operand" "")
15389 (match_operand 3 "" ""))])]
15390 ""
15391 "ix86_current_function_needs_cld = 1;")
15392
15393 (define_insn "*strsetdi_rex_1"
15394 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15395 (match_operand:DI 2 "register_operand" "a"))
15396 (set (match_operand:DI 0 "register_operand" "=D")
15397 (plus:DI (match_dup 1)
15398 (const_int 8)))]
15399 "TARGET_64BIT"
15400 "stosq"
15401 [(set_attr "type" "str")
15402 (set_attr "memory" "store")
15403 (set_attr "mode" "DI")])
15404
15405 (define_insn "*strsetsi_1"
15406 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15407 (match_operand:SI 2 "register_operand" "a"))
15408 (set (match_operand:SI 0 "register_operand" "=D")
15409 (plus:SI (match_dup 1)
15410 (const_int 4)))]
15411 "!TARGET_64BIT"
15412 "stos{l|d}"
15413 [(set_attr "type" "str")
15414 (set_attr "memory" "store")
15415 (set_attr "mode" "SI")])
15416
15417 (define_insn "*strsetsi_rex_1"
15418 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15419 (match_operand:SI 2 "register_operand" "a"))
15420 (set (match_operand:DI 0 "register_operand" "=D")
15421 (plus:DI (match_dup 1)
15422 (const_int 4)))]
15423 "TARGET_64BIT"
15424 "stos{l|d}"
15425 [(set_attr "type" "str")
15426 (set_attr "memory" "store")
15427 (set_attr "mode" "SI")])
15428
15429 (define_insn "*strsethi_1"
15430 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15431 (match_operand:HI 2 "register_operand" "a"))
15432 (set (match_operand:SI 0 "register_operand" "=D")
15433 (plus:SI (match_dup 1)
15434 (const_int 2)))]
15435 "!TARGET_64BIT"
15436 "stosw"
15437 [(set_attr "type" "str")
15438 (set_attr "memory" "store")
15439 (set_attr "mode" "HI")])
15440
15441 (define_insn "*strsethi_rex_1"
15442 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15443 (match_operand:HI 2 "register_operand" "a"))
15444 (set (match_operand:DI 0 "register_operand" "=D")
15445 (plus:DI (match_dup 1)
15446 (const_int 2)))]
15447 "TARGET_64BIT"
15448 "stosw"
15449 [(set_attr "type" "str")
15450 (set_attr "memory" "store")
15451 (set_attr "mode" "HI")])
15452
15453 (define_insn "*strsetqi_1"
15454 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15455 (match_operand:QI 2 "register_operand" "a"))
15456 (set (match_operand:SI 0 "register_operand" "=D")
15457 (plus:SI (match_dup 1)
15458 (const_int 1)))]
15459 "!TARGET_64BIT"
15460 "stosb"
15461 [(set_attr "type" "str")
15462 (set_attr "memory" "store")
15463 (set_attr "mode" "QI")])
15464
15465 (define_insn "*strsetqi_rex_1"
15466 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15467 (match_operand:QI 2 "register_operand" "a"))
15468 (set (match_operand:DI 0 "register_operand" "=D")
15469 (plus:DI (match_dup 1)
15470 (const_int 1)))]
15471 "TARGET_64BIT"
15472 "stosb"
15473 [(set_attr "type" "str")
15474 (set_attr "memory" "store")
15475 (set_attr "prefix_rex" "0")
15476 (set_attr "mode" "QI")])
15477
15478 (define_expand "rep_stos"
15479 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15480 (set (match_operand 0 "register_operand" "")
15481 (match_operand 4 "" ""))
15482 (set (match_operand 2 "memory_operand" "") (const_int 0))
15483 (use (match_operand 3 "register_operand" ""))
15484 (use (match_dup 1))])]
15485 ""
15486 "ix86_current_function_needs_cld = 1;")
15487
15488 (define_insn "*rep_stosdi_rex64"
15489 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15490 (set (match_operand:DI 0 "register_operand" "=D")
15491 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15492 (const_int 3))
15493 (match_operand:DI 3 "register_operand" "0")))
15494 (set (mem:BLK (match_dup 3))
15495 (const_int 0))
15496 (use (match_operand:DI 2 "register_operand" "a"))
15497 (use (match_dup 4))]
15498 "TARGET_64BIT"
15499 "rep{%;} stosq"
15500 [(set_attr "type" "str")
15501 (set_attr "prefix_rep" "1")
15502 (set_attr "memory" "store")
15503 (set_attr "mode" "DI")])
15504
15505 (define_insn "*rep_stossi"
15506 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15507 (set (match_operand:SI 0 "register_operand" "=D")
15508 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15509 (const_int 2))
15510 (match_operand:SI 3 "register_operand" "0")))
15511 (set (mem:BLK (match_dup 3))
15512 (const_int 0))
15513 (use (match_operand:SI 2 "register_operand" "a"))
15514 (use (match_dup 4))]
15515 "!TARGET_64BIT"
15516 "rep{%;} stos{l|d}"
15517 [(set_attr "type" "str")
15518 (set_attr "prefix_rep" "1")
15519 (set_attr "memory" "store")
15520 (set_attr "mode" "SI")])
15521
15522 (define_insn "*rep_stossi_rex64"
15523 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15524 (set (match_operand:DI 0 "register_operand" "=D")
15525 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15526 (const_int 2))
15527 (match_operand:DI 3 "register_operand" "0")))
15528 (set (mem:BLK (match_dup 3))
15529 (const_int 0))
15530 (use (match_operand:SI 2 "register_operand" "a"))
15531 (use (match_dup 4))]
15532 "TARGET_64BIT"
15533 "rep{%;} stos{l|d}"
15534 [(set_attr "type" "str")
15535 (set_attr "prefix_rep" "1")
15536 (set_attr "memory" "store")
15537 (set_attr "mode" "SI")])
15538
15539 (define_insn "*rep_stosqi"
15540 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15541 (set (match_operand:SI 0 "register_operand" "=D")
15542 (plus:SI (match_operand:SI 3 "register_operand" "0")
15543 (match_operand:SI 4 "register_operand" "1")))
15544 (set (mem:BLK (match_dup 3))
15545 (const_int 0))
15546 (use (match_operand:QI 2 "register_operand" "a"))
15547 (use (match_dup 4))]
15548 "!TARGET_64BIT"
15549 "rep{%;} stosb"
15550 [(set_attr "type" "str")
15551 (set_attr "prefix_rep" "1")
15552 (set_attr "memory" "store")
15553 (set_attr "mode" "QI")])
15554
15555 (define_insn "*rep_stosqi_rex64"
15556 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15557 (set (match_operand:DI 0 "register_operand" "=D")
15558 (plus:DI (match_operand:DI 3 "register_operand" "0")
15559 (match_operand:DI 4 "register_operand" "1")))
15560 (set (mem:BLK (match_dup 3))
15561 (const_int 0))
15562 (use (match_operand:QI 2 "register_operand" "a"))
15563 (use (match_dup 4))]
15564 "TARGET_64BIT"
15565 "rep{%;} stosb"
15566 [(set_attr "type" "str")
15567 (set_attr "prefix_rep" "1")
15568 (set_attr "memory" "store")
15569 (set_attr "prefix_rex" "0")
15570 (set_attr "mode" "QI")])
15571
15572 (define_expand "cmpstrnsi"
15573 [(set (match_operand:SI 0 "register_operand" "")
15574 (compare:SI (match_operand:BLK 1 "general_operand" "")
15575 (match_operand:BLK 2 "general_operand" "")))
15576 (use (match_operand 3 "general_operand" ""))
15577 (use (match_operand 4 "immediate_operand" ""))]
15578 ""
15579 {
15580 rtx addr1, addr2, out, outlow, count, countreg, align;
15581
15582 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15583 FAIL;
15584
15585 /* Can't use this if the user has appropriated esi or edi. */
15586 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15587 FAIL;
15588
15589 out = operands[0];
15590 if (!REG_P (out))
15591 out = gen_reg_rtx (SImode);
15592
15593 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15594 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15595 if (addr1 != XEXP (operands[1], 0))
15596 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15597 if (addr2 != XEXP (operands[2], 0))
15598 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15599
15600 count = operands[3];
15601 countreg = ix86_zero_extend_to_Pmode (count);
15602
15603 /* %%% Iff we are testing strict equality, we can use known alignment
15604 to good advantage. This may be possible with combine, particularly
15605 once cc0 is dead. */
15606 align = operands[4];
15607
15608 if (CONST_INT_P (count))
15609 {
15610 if (INTVAL (count) == 0)
15611 {
15612 emit_move_insn (operands[0], const0_rtx);
15613 DONE;
15614 }
15615 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15616 operands[1], operands[2]));
15617 }
15618 else
15619 {
15620 rtx (*cmp_insn)(rtx, rtx);
15621
15622 if (TARGET_64BIT)
15623 cmp_insn = gen_cmpdi_1;
15624 else
15625 cmp_insn = gen_cmpsi_1;
15626 emit_insn (cmp_insn (countreg, countreg));
15627 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15628 operands[1], operands[2]));
15629 }
15630
15631 outlow = gen_lowpart (QImode, out);
15632 emit_insn (gen_cmpintqi (outlow));
15633 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15634
15635 if (operands[0] != out)
15636 emit_move_insn (operands[0], out);
15637
15638 DONE;
15639 })
15640
15641 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15642
15643 (define_expand "cmpintqi"
15644 [(set (match_dup 1)
15645 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15646 (set (match_dup 2)
15647 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15648 (parallel [(set (match_operand:QI 0 "register_operand" "")
15649 (minus:QI (match_dup 1)
15650 (match_dup 2)))
15651 (clobber (reg:CC FLAGS_REG))])]
15652 ""
15653 "operands[1] = gen_reg_rtx (QImode);
15654 operands[2] = gen_reg_rtx (QImode);")
15655
15656 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15657 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15658
15659 (define_expand "cmpstrnqi_nz_1"
15660 [(parallel [(set (reg:CC FLAGS_REG)
15661 (compare:CC (match_operand 4 "memory_operand" "")
15662 (match_operand 5 "memory_operand" "")))
15663 (use (match_operand 2 "register_operand" ""))
15664 (use (match_operand:SI 3 "immediate_operand" ""))
15665 (clobber (match_operand 0 "register_operand" ""))
15666 (clobber (match_operand 1 "register_operand" ""))
15667 (clobber (match_dup 2))])]
15668 ""
15669 "ix86_current_function_needs_cld = 1;")
15670
15671 (define_insn "*cmpstrnqi_nz_1"
15672 [(set (reg:CC FLAGS_REG)
15673 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15674 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15675 (use (match_operand:SI 6 "register_operand" "2"))
15676 (use (match_operand:SI 3 "immediate_operand" "i"))
15677 (clobber (match_operand:SI 0 "register_operand" "=S"))
15678 (clobber (match_operand:SI 1 "register_operand" "=D"))
15679 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15680 "!TARGET_64BIT"
15681 "repz{%;} cmpsb"
15682 [(set_attr "type" "str")
15683 (set_attr "mode" "QI")
15684 (set_attr "prefix_rep" "1")])
15685
15686 (define_insn "*cmpstrnqi_nz_rex_1"
15687 [(set (reg:CC FLAGS_REG)
15688 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15689 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15690 (use (match_operand:DI 6 "register_operand" "2"))
15691 (use (match_operand:SI 3 "immediate_operand" "i"))
15692 (clobber (match_operand:DI 0 "register_operand" "=S"))
15693 (clobber (match_operand:DI 1 "register_operand" "=D"))
15694 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15695 "TARGET_64BIT"
15696 "repz{%;} cmpsb"
15697 [(set_attr "type" "str")
15698 (set_attr "mode" "QI")
15699 (set_attr "prefix_rex" "0")
15700 (set_attr "prefix_rep" "1")])
15701
15702 ;; The same, but the count is not known to not be zero.
15703
15704 (define_expand "cmpstrnqi_1"
15705 [(parallel [(set (reg:CC FLAGS_REG)
15706 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15707 (const_int 0))
15708 (compare:CC (match_operand 4 "memory_operand" "")
15709 (match_operand 5 "memory_operand" ""))
15710 (const_int 0)))
15711 (use (match_operand:SI 3 "immediate_operand" ""))
15712 (use (reg:CC FLAGS_REG))
15713 (clobber (match_operand 0 "register_operand" ""))
15714 (clobber (match_operand 1 "register_operand" ""))
15715 (clobber (match_dup 2))])]
15716 ""
15717 "ix86_current_function_needs_cld = 1;")
15718
15719 (define_insn "*cmpstrnqi_1"
15720 [(set (reg:CC FLAGS_REG)
15721 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15722 (const_int 0))
15723 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15724 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15725 (const_int 0)))
15726 (use (match_operand:SI 3 "immediate_operand" "i"))
15727 (use (reg:CC FLAGS_REG))
15728 (clobber (match_operand:SI 0 "register_operand" "=S"))
15729 (clobber (match_operand:SI 1 "register_operand" "=D"))
15730 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15731 "!TARGET_64BIT"
15732 "repz{%;} cmpsb"
15733 [(set_attr "type" "str")
15734 (set_attr "mode" "QI")
15735 (set_attr "prefix_rep" "1")])
15736
15737 (define_insn "*cmpstrnqi_rex_1"
15738 [(set (reg:CC FLAGS_REG)
15739 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15740 (const_int 0))
15741 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15742 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15743 (const_int 0)))
15744 (use (match_operand:SI 3 "immediate_operand" "i"))
15745 (use (reg:CC FLAGS_REG))
15746 (clobber (match_operand:DI 0 "register_operand" "=S"))
15747 (clobber (match_operand:DI 1 "register_operand" "=D"))
15748 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15749 "TARGET_64BIT"
15750 "repz{%;} cmpsb"
15751 [(set_attr "type" "str")
15752 (set_attr "mode" "QI")
15753 (set_attr "prefix_rex" "0")
15754 (set_attr "prefix_rep" "1")])
15755
15756 (define_expand "strlensi"
15757 [(set (match_operand:SI 0 "register_operand" "")
15758 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15759 (match_operand:QI 2 "immediate_operand" "")
15760 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15761 ""
15762 {
15763 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15764 DONE;
15765 else
15766 FAIL;
15767 })
15768
15769 (define_expand "strlendi"
15770 [(set (match_operand:DI 0 "register_operand" "")
15771 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15772 (match_operand:QI 2 "immediate_operand" "")
15773 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15774 ""
15775 {
15776 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15777 DONE;
15778 else
15779 FAIL;
15780 })
15781
15782 (define_expand "strlenqi_1"
15783 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15784 (clobber (match_operand 1 "register_operand" ""))
15785 (clobber (reg:CC FLAGS_REG))])]
15786 ""
15787 "ix86_current_function_needs_cld = 1;")
15788
15789 (define_insn "*strlenqi_1"
15790 [(set (match_operand:SI 0 "register_operand" "=&c")
15791 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15792 (match_operand:QI 2 "register_operand" "a")
15793 (match_operand:SI 3 "immediate_operand" "i")
15794 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15795 (clobber (match_operand:SI 1 "register_operand" "=D"))
15796 (clobber (reg:CC FLAGS_REG))]
15797 "!TARGET_64BIT"
15798 "repnz{%;} scasb"
15799 [(set_attr "type" "str")
15800 (set_attr "mode" "QI")
15801 (set_attr "prefix_rep" "1")])
15802
15803 (define_insn "*strlenqi_rex_1"
15804 [(set (match_operand:DI 0 "register_operand" "=&c")
15805 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15806 (match_operand:QI 2 "register_operand" "a")
15807 (match_operand:DI 3 "immediate_operand" "i")
15808 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15809 (clobber (match_operand:DI 1 "register_operand" "=D"))
15810 (clobber (reg:CC FLAGS_REG))]
15811 "TARGET_64BIT"
15812 "repnz{%;} scasb"
15813 [(set_attr "type" "str")
15814 (set_attr "mode" "QI")
15815 (set_attr "prefix_rex" "0")
15816 (set_attr "prefix_rep" "1")])
15817
15818 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15819 ;; handled in combine, but it is not currently up to the task.
15820 ;; When used for their truth value, the cmpstrn* expanders generate
15821 ;; code like this:
15822 ;;
15823 ;; repz cmpsb
15824 ;; seta %al
15825 ;; setb %dl
15826 ;; cmpb %al, %dl
15827 ;; jcc label
15828 ;;
15829 ;; The intermediate three instructions are unnecessary.
15830
15831 ;; This one handles cmpstrn*_nz_1...
15832 (define_peephole2
15833 [(parallel[
15834 (set (reg:CC FLAGS_REG)
15835 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15836 (mem:BLK (match_operand 5 "register_operand" ""))))
15837 (use (match_operand 6 "register_operand" ""))
15838 (use (match_operand:SI 3 "immediate_operand" ""))
15839 (clobber (match_operand 0 "register_operand" ""))
15840 (clobber (match_operand 1 "register_operand" ""))
15841 (clobber (match_operand 2 "register_operand" ""))])
15842 (set (match_operand:QI 7 "register_operand" "")
15843 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15844 (set (match_operand:QI 8 "register_operand" "")
15845 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15846 (set (reg FLAGS_REG)
15847 (compare (match_dup 7) (match_dup 8)))
15848 ]
15849 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15850 [(parallel[
15851 (set (reg:CC FLAGS_REG)
15852 (compare:CC (mem:BLK (match_dup 4))
15853 (mem:BLK (match_dup 5))))
15854 (use (match_dup 6))
15855 (use (match_dup 3))
15856 (clobber (match_dup 0))
15857 (clobber (match_dup 1))
15858 (clobber (match_dup 2))])]
15859 "")
15860
15861 ;; ...and this one handles cmpstrn*_1.
15862 (define_peephole2
15863 [(parallel[
15864 (set (reg:CC FLAGS_REG)
15865 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15866 (const_int 0))
15867 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15868 (mem:BLK (match_operand 5 "register_operand" "")))
15869 (const_int 0)))
15870 (use (match_operand:SI 3 "immediate_operand" ""))
15871 (use (reg:CC FLAGS_REG))
15872 (clobber (match_operand 0 "register_operand" ""))
15873 (clobber (match_operand 1 "register_operand" ""))
15874 (clobber (match_operand 2 "register_operand" ""))])
15875 (set (match_operand:QI 7 "register_operand" "")
15876 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15877 (set (match_operand:QI 8 "register_operand" "")
15878 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15879 (set (reg FLAGS_REG)
15880 (compare (match_dup 7) (match_dup 8)))
15881 ]
15882 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15883 [(parallel[
15884 (set (reg:CC FLAGS_REG)
15885 (if_then_else:CC (ne (match_dup 6)
15886 (const_int 0))
15887 (compare:CC (mem:BLK (match_dup 4))
15888 (mem:BLK (match_dup 5)))
15889 (const_int 0)))
15890 (use (match_dup 3))
15891 (use (reg:CC FLAGS_REG))
15892 (clobber (match_dup 0))
15893 (clobber (match_dup 1))
15894 (clobber (match_dup 2))])]
15895 "")
15896
15897
15898 \f
15899 ;; Conditional move instructions.
15900
15901 (define_expand "mov<mode>cc"
15902 [(set (match_operand:SWIM 0 "register_operand" "")
15903 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
15904 (match_operand:SWIM 2 "general_operand" "")
15905 (match_operand:SWIM 3 "general_operand" "")))]
15906 ""
15907 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15908
15909 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15910 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15911 ;; So just document what we're doing explicitly.
15912
15913 (define_expand "x86_mov<mode>cc_0_m1"
15914 [(parallel
15915 [(set (match_operand:SWI48 0 "register_operand" "")
15916 (if_then_else:SWI48
15917 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15918 [(match_operand 1 "flags_reg_operand" "")
15919 (const_int 0)])
15920 (const_int -1)
15921 (const_int 0)))
15922 (clobber (reg:CC FLAGS_REG))])]
15923 ""
15924 "")
15925
15926 (define_insn "*x86_mov<mode>cc_0_m1"
15927 [(set (match_operand:SWI48 0 "register_operand" "=r")
15928 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15929 [(reg FLAGS_REG) (const_int 0)])
15930 (const_int -1)
15931 (const_int 0)))
15932 (clobber (reg:CC FLAGS_REG))]
15933 ""
15934 "sbb{<imodesuffix>}\t%0, %0"
15935 ; Since we don't have the proper number of operands for an alu insn,
15936 ; fill in all the blanks.
15937 [(set_attr "type" "alu")
15938 (set_attr "use_carry" "1")
15939 (set_attr "pent_pair" "pu")
15940 (set_attr "memory" "none")
15941 (set_attr "imm_disp" "false")
15942 (set_attr "mode" "<MODE>")
15943 (set_attr "length_immediate" "0")])
15944
15945 (define_insn "*x86_mov<mode>cc_0_m1_se"
15946 [(set (match_operand:SWI48 0 "register_operand" "=r")
15947 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15948 [(reg FLAGS_REG) (const_int 0)])
15949 (const_int 1)
15950 (const_int 0)))
15951 (clobber (reg:CC FLAGS_REG))]
15952 ""
15953 "sbb{<imodesuffix>}\t%0, %0"
15954 [(set_attr "type" "alu")
15955 (set_attr "use_carry" "1")
15956 (set_attr "pent_pair" "pu")
15957 (set_attr "memory" "none")
15958 (set_attr "imm_disp" "false")
15959 (set_attr "mode" "<MODE>")
15960 (set_attr "length_immediate" "0")])
15961
15962 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15963 [(set (match_operand:SWI48 0 "register_operand" "=r")
15964 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15965 [(reg FLAGS_REG) (const_int 0)])))]
15966 ""
15967 "sbb{<imodesuffix>}\t%0, %0"
15968 [(set_attr "type" "alu")
15969 (set_attr "use_carry" "1")
15970 (set_attr "pent_pair" "pu")
15971 (set_attr "memory" "none")
15972 (set_attr "imm_disp" "false")
15973 (set_attr "mode" "<MODE>")
15974 (set_attr "length_immediate" "0")])
15975
15976 (define_insn "*mov<mode>cc_noc"
15977 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15978 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15979 [(reg FLAGS_REG) (const_int 0)])
15980 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15981 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15982 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15983 "@
15984 cmov%O2%C1\t{%2, %0|%0, %2}
15985 cmov%O2%c1\t{%3, %0|%0, %3}"
15986 [(set_attr "type" "icmov")
15987 (set_attr "mode" "<MODE>")])
15988
15989 (define_insn_and_split "*movqicc_noc"
15990 [(set (match_operand:QI 0 "register_operand" "=r,r")
15991 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15992 [(match_operand 4 "flags_reg_operand" "")
15993 (const_int 0)])
15994 (match_operand:QI 2 "register_operand" "r,0")
15995 (match_operand:QI 3 "register_operand" "0,r")))]
15996 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15997 "#"
15998 "&& reload_completed"
15999 [(set (match_dup 0)
16000 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16001 (match_dup 2)
16002 (match_dup 3)))]
16003 "operands[0] = gen_lowpart (SImode, operands[0]);
16004 operands[2] = gen_lowpart (SImode, operands[2]);
16005 operands[3] = gen_lowpart (SImode, operands[3]);"
16006 [(set_attr "type" "icmov")
16007 (set_attr "mode" "SI")])
16008
16009 (define_expand "mov<mode>cc"
16010 [(set (match_operand:X87MODEF 0 "register_operand" "")
16011 (if_then_else:X87MODEF
16012 (match_operand 1 "ix86_fp_comparison_operator" "")
16013 (match_operand:X87MODEF 2 "register_operand" "")
16014 (match_operand:X87MODEF 3 "register_operand" "")))]
16015 "(TARGET_80387 && TARGET_CMOVE)
16016 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16017 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16018
16019 (define_insn "*movsfcc_1_387"
16020 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16021 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16022 [(reg FLAGS_REG) (const_int 0)])
16023 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16024 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16025 "TARGET_80387 && TARGET_CMOVE
16026 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16027 "@
16028 fcmov%F1\t{%2, %0|%0, %2}
16029 fcmov%f1\t{%3, %0|%0, %3}
16030 cmov%O2%C1\t{%2, %0|%0, %2}
16031 cmov%O2%c1\t{%3, %0|%0, %3}"
16032 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16033 (set_attr "mode" "SF,SF,SI,SI")])
16034
16035 (define_insn "*movdfcc_1"
16036 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16037 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16038 [(reg FLAGS_REG) (const_int 0)])
16039 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16040 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16041 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16042 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16043 "@
16044 fcmov%F1\t{%2, %0|%0, %2}
16045 fcmov%f1\t{%3, %0|%0, %3}
16046 #
16047 #"
16048 [(set_attr "type" "fcmov,fcmov,multi,multi")
16049 (set_attr "mode" "DF")])
16050
16051 (define_insn "*movdfcc_1_rex64"
16052 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16053 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16054 [(reg FLAGS_REG) (const_int 0)])
16055 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16056 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16057 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16058 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16059 "@
16060 fcmov%F1\t{%2, %0|%0, %2}
16061 fcmov%f1\t{%3, %0|%0, %3}
16062 cmov%O2%C1\t{%2, %0|%0, %2}
16063 cmov%O2%c1\t{%3, %0|%0, %3}"
16064 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16065 (set_attr "mode" "DF")])
16066
16067 (define_split
16068 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16069 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16070 [(match_operand 4 "flags_reg_operand" "")
16071 (const_int 0)])
16072 (match_operand:DF 2 "nonimmediate_operand" "")
16073 (match_operand:DF 3 "nonimmediate_operand" "")))]
16074 "!TARGET_64BIT && reload_completed"
16075 [(set (match_dup 2)
16076 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16077 (match_dup 5)
16078 (match_dup 6)))
16079 (set (match_dup 3)
16080 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16081 (match_dup 7)
16082 (match_dup 8)))]
16083 {
16084 split_di (&operands[2], 2, &operands[5], &operands[7]);
16085 split_di (&operands[0], 1, &operands[2], &operands[3]);
16086 })
16087
16088 (define_insn "*movxfcc_1"
16089 [(set (match_operand:XF 0 "register_operand" "=f,f")
16090 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16091 [(reg FLAGS_REG) (const_int 0)])
16092 (match_operand:XF 2 "register_operand" "f,0")
16093 (match_operand:XF 3 "register_operand" "0,f")))]
16094 "TARGET_80387 && TARGET_CMOVE"
16095 "@
16096 fcmov%F1\t{%2, %0|%0, %2}
16097 fcmov%f1\t{%3, %0|%0, %3}"
16098 [(set_attr "type" "fcmov")
16099 (set_attr "mode" "XF")])
16100
16101 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16102 ;; the scalar versions to have only XMM registers as operands.
16103
16104 ;; XOP conditional move
16105 (define_insn "*xop_pcmov_<mode>"
16106 [(set (match_operand:MODEF 0 "register_operand" "=x")
16107 (if_then_else:MODEF
16108 (match_operand:MODEF 1 "register_operand" "x")
16109 (match_operand:MODEF 2 "register_operand" "x")
16110 (match_operand:MODEF 3 "register_operand" "x")))]
16111 "TARGET_XOP"
16112 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16113 [(set_attr "type" "sse4arg")])
16114
16115 ;; These versions of the min/max patterns are intentionally ignorant of
16116 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16117 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16118 ;; are undefined in this condition, we're certain this is correct.
16119
16120 (define_insn "*avx_<code><mode>3"
16121 [(set (match_operand:MODEF 0 "register_operand" "=x")
16122 (smaxmin:MODEF
16123 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16124 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16125 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16126 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16127 [(set_attr "type" "sseadd")
16128 (set_attr "prefix" "vex")
16129 (set_attr "mode" "<MODE>")])
16130
16131 (define_insn "<code><mode>3"
16132 [(set (match_operand:MODEF 0 "register_operand" "=x")
16133 (smaxmin:MODEF
16134 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16135 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16136 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16137 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16138 [(set_attr "type" "sseadd")
16139 (set_attr "mode" "<MODE>")])
16140
16141 ;; These versions of the min/max patterns implement exactly the operations
16142 ;; min = (op1 < op2 ? op1 : op2)
16143 ;; max = (!(op1 < op2) ? op1 : op2)
16144 ;; Their operands are not commutative, and thus they may be used in the
16145 ;; presence of -0.0 and NaN.
16146
16147 (define_insn "*avx_ieee_smin<mode>3"
16148 [(set (match_operand:MODEF 0 "register_operand" "=x")
16149 (unspec:MODEF
16150 [(match_operand:MODEF 1 "register_operand" "x")
16151 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16152 UNSPEC_IEEE_MIN))]
16153 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16154 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16155 [(set_attr "type" "sseadd")
16156 (set_attr "prefix" "vex")
16157 (set_attr "mode" "<MODE>")])
16158
16159 (define_insn "*ieee_smin<mode>3"
16160 [(set (match_operand:MODEF 0 "register_operand" "=x")
16161 (unspec:MODEF
16162 [(match_operand:MODEF 1 "register_operand" "0")
16163 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16164 UNSPEC_IEEE_MIN))]
16165 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16166 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16167 [(set_attr "type" "sseadd")
16168 (set_attr "mode" "<MODE>")])
16169
16170 (define_insn "*avx_ieee_smax<mode>3"
16171 [(set (match_operand:MODEF 0 "register_operand" "=x")
16172 (unspec:MODEF
16173 [(match_operand:MODEF 1 "register_operand" "0")
16174 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16175 UNSPEC_IEEE_MAX))]
16176 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16177 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16178 [(set_attr "type" "sseadd")
16179 (set_attr "prefix" "vex")
16180 (set_attr "mode" "<MODE>")])
16181
16182 (define_insn "*ieee_smax<mode>3"
16183 [(set (match_operand:MODEF 0 "register_operand" "=x")
16184 (unspec:MODEF
16185 [(match_operand:MODEF 1 "register_operand" "0")
16186 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16187 UNSPEC_IEEE_MAX))]
16188 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16189 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16190 [(set_attr "type" "sseadd")
16191 (set_attr "mode" "<MODE>")])
16192
16193 ;; Make two stack loads independent:
16194 ;; fld aa fld aa
16195 ;; fld %st(0) -> fld bb
16196 ;; fmul bb fmul %st(1), %st
16197 ;;
16198 ;; Actually we only match the last two instructions for simplicity.
16199 (define_peephole2
16200 [(set (match_operand 0 "fp_register_operand" "")
16201 (match_operand 1 "fp_register_operand" ""))
16202 (set (match_dup 0)
16203 (match_operator 2 "binary_fp_operator"
16204 [(match_dup 0)
16205 (match_operand 3 "memory_operand" "")]))]
16206 "REGNO (operands[0]) != REGNO (operands[1])"
16207 [(set (match_dup 0) (match_dup 3))
16208 (set (match_dup 0) (match_dup 4))]
16209
16210 ;; The % modifier is not operational anymore in peephole2's, so we have to
16211 ;; swap the operands manually in the case of addition and multiplication.
16212 "if (COMMUTATIVE_ARITH_P (operands[2]))
16213 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16214 operands[0], operands[1]);
16215 else
16216 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16217 operands[1], operands[0]);")
16218
16219 ;; Conditional addition patterns
16220 (define_expand "add<mode>cc"
16221 [(match_operand:SWI 0 "register_operand" "")
16222 (match_operand 1 "comparison_operator" "")
16223 (match_operand:SWI 2 "register_operand" "")
16224 (match_operand:SWI 3 "const_int_operand" "")]
16225 ""
16226 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16227
16228 \f
16229 ;; Misc patterns (?)
16230
16231 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16232 ;; Otherwise there will be nothing to keep
16233 ;;
16234 ;; [(set (reg ebp) (reg esp))]
16235 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16236 ;; (clobber (eflags)]
16237 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16238 ;;
16239 ;; in proper program order.
16240 (define_insn "pro_epilogue_adjust_stack_1"
16241 [(set (match_operand:SI 0 "register_operand" "=r,r")
16242 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16243 (match_operand:SI 2 "immediate_operand" "i,i")))
16244 (clobber (reg:CC FLAGS_REG))
16245 (clobber (mem:BLK (scratch)))]
16246 "!TARGET_64BIT"
16247 {
16248 switch (get_attr_type (insn))
16249 {
16250 case TYPE_IMOV:
16251 return "mov{l}\t{%1, %0|%0, %1}";
16252
16253 case TYPE_ALU:
16254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16255 if (x86_maybe_negate_const_int (&operands[2], SImode))
16256 return "sub{l}\t{%2, %0|%0, %2}";
16257
16258 return "add{l}\t{%2, %0|%0, %2}";
16259
16260 default:
16261 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16262 return "lea{l}\t{%a2, %0|%0, %a2}";
16263 }
16264 }
16265 [(set (attr "type")
16266 (cond [(and (eq_attr "alternative" "0")
16267 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16268 (const_string "alu")
16269 (match_operand:SI 2 "const0_operand" "")
16270 (const_string "imov")
16271 ]
16272 (const_string "lea")))
16273 (set (attr "length_immediate")
16274 (cond [(eq_attr "type" "imov")
16275 (const_string "0")
16276 (and (eq_attr "type" "alu")
16277 (match_operand 2 "const128_operand" ""))
16278 (const_string "1")
16279 ]
16280 (const_string "*")))
16281 (set_attr "mode" "SI")])
16282
16283 (define_insn "pro_epilogue_adjust_stack_rex64"
16284 [(set (match_operand:DI 0 "register_operand" "=r,r")
16285 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16286 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16287 (clobber (reg:CC FLAGS_REG))
16288 (clobber (mem:BLK (scratch)))]
16289 "TARGET_64BIT"
16290 {
16291 switch (get_attr_type (insn))
16292 {
16293 case TYPE_IMOV:
16294 return "mov{q}\t{%1, %0|%0, %1}";
16295
16296 case TYPE_ALU:
16297 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16298 if (x86_maybe_negate_const_int (&operands[2], DImode))
16299 return "sub{q}\t{%2, %0|%0, %2}";
16300
16301 return "add{q}\t{%2, %0|%0, %2}";
16302
16303 default:
16304 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16305 return "lea{q}\t{%a2, %0|%0, %a2}";
16306 }
16307 }
16308 [(set (attr "type")
16309 (cond [(and (eq_attr "alternative" "0")
16310 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16311 (const_string "alu")
16312 (match_operand:DI 2 "const0_operand" "")
16313 (const_string "imov")
16314 ]
16315 (const_string "lea")))
16316 (set (attr "length_immediate")
16317 (cond [(eq_attr "type" "imov")
16318 (const_string "0")
16319 (and (eq_attr "type" "alu")
16320 (match_operand 2 "const128_operand" ""))
16321 (const_string "1")
16322 ]
16323 (const_string "*")))
16324 (set_attr "mode" "DI")])
16325
16326 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16327 [(set (match_operand:DI 0 "register_operand" "=r,r")
16328 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16329 (match_operand:DI 3 "immediate_operand" "i,i")))
16330 (use (match_operand:DI 2 "register_operand" "r,r"))
16331 (clobber (reg:CC FLAGS_REG))
16332 (clobber (mem:BLK (scratch)))]
16333 "TARGET_64BIT"
16334 {
16335 switch (get_attr_type (insn))
16336 {
16337 case TYPE_ALU:
16338 return "add{q}\t{%2, %0|%0, %2}";
16339
16340 case TYPE_LEA:
16341 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16342 return "lea{q}\t{%a2, %0|%0, %a2}";
16343
16344 default:
16345 gcc_unreachable ();
16346 }
16347 }
16348 [(set_attr "type" "alu,lea")
16349 (set_attr "mode" "DI")])
16350
16351 (define_insn "allocate_stack_worker_32"
16352 [(set (match_operand:SI 0 "register_operand" "=a")
16353 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16354 UNSPECV_STACK_PROBE))
16355 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16356 (clobber (reg:CC FLAGS_REG))]
16357 "!TARGET_64BIT && TARGET_STACK_PROBE"
16358 "call\t___chkstk"
16359 [(set_attr "type" "multi")
16360 (set_attr "length" "5")])
16361
16362 (define_insn "allocate_stack_worker_64"
16363 [(set (match_operand:DI 0 "register_operand" "=a")
16364 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16365 UNSPECV_STACK_PROBE))
16366 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16367 (clobber (reg:DI R10_REG))
16368 (clobber (reg:DI R11_REG))
16369 (clobber (reg:CC FLAGS_REG))]
16370 "TARGET_64BIT && TARGET_STACK_PROBE"
16371 "call\t___chkstk"
16372 [(set_attr "type" "multi")
16373 (set_attr "length" "5")])
16374
16375 (define_expand "allocate_stack"
16376 [(match_operand 0 "register_operand" "")
16377 (match_operand 1 "general_operand" "")]
16378 "TARGET_STACK_PROBE"
16379 {
16380 rtx x;
16381
16382 #ifndef CHECK_STACK_LIMIT
16383 #define CHECK_STACK_LIMIT 0
16384 #endif
16385
16386 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16387 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16388 {
16389 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16390 stack_pointer_rtx, 0, OPTAB_DIRECT);
16391 if (x != stack_pointer_rtx)
16392 emit_move_insn (stack_pointer_rtx, x);
16393 }
16394 else
16395 {
16396 x = copy_to_mode_reg (Pmode, operands[1]);
16397 if (TARGET_64BIT)
16398 x = gen_allocate_stack_worker_64 (x, x);
16399 else
16400 x = gen_allocate_stack_worker_32 (x, x);
16401 emit_insn (x);
16402 }
16403
16404 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16405 DONE;
16406 })
16407
16408 ;; Use IOR for stack probes, this is shorter.
16409 (define_expand "probe_stack"
16410 [(match_operand 0 "memory_operand" "")]
16411 ""
16412 {
16413 if (GET_MODE (operands[0]) == DImode)
16414 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
16415 else
16416 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
16417 DONE;
16418 })
16419
16420 (define_expand "builtin_setjmp_receiver"
16421 [(label_ref (match_operand 0 "" ""))]
16422 "!TARGET_64BIT && flag_pic"
16423 {
16424 #if TARGET_MACHO
16425 if (TARGET_MACHO)
16426 {
16427 rtx xops[3];
16428 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16429 rtx label_rtx = gen_label_rtx ();
16430 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16431 xops[0] = xops[1] = picreg;
16432 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16433 ix86_expand_binary_operator (MINUS, SImode, xops);
16434 }
16435 else
16436 #endif
16437 emit_insn (gen_set_got (pic_offset_table_rtx));
16438 DONE;
16439 })
16440 \f
16441 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16442
16443 (define_split
16444 [(set (match_operand 0 "register_operand" "")
16445 (match_operator 3 "promotable_binary_operator"
16446 [(match_operand 1 "register_operand" "")
16447 (match_operand 2 "aligned_operand" "")]))
16448 (clobber (reg:CC FLAGS_REG))]
16449 "! TARGET_PARTIAL_REG_STALL && reload_completed
16450 && ((GET_MODE (operands[0]) == HImode
16451 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16452 /* ??? next two lines just !satisfies_constraint_K (...) */
16453 || !CONST_INT_P (operands[2])
16454 || satisfies_constraint_K (operands[2])))
16455 || (GET_MODE (operands[0]) == QImode
16456 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16457 [(parallel [(set (match_dup 0)
16458 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16459 (clobber (reg:CC FLAGS_REG))])]
16460 "operands[0] = gen_lowpart (SImode, operands[0]);
16461 operands[1] = gen_lowpart (SImode, operands[1]);
16462 if (GET_CODE (operands[3]) != ASHIFT)
16463 operands[2] = gen_lowpart (SImode, operands[2]);
16464 PUT_MODE (operands[3], SImode);")
16465
16466 ; Promote the QImode tests, as i386 has encoding of the AND
16467 ; instruction with 32-bit sign-extended immediate and thus the
16468 ; instruction size is unchanged, except in the %eax case for
16469 ; which it is increased by one byte, hence the ! optimize_size.
16470 (define_split
16471 [(set (match_operand 0 "flags_reg_operand" "")
16472 (match_operator 2 "compare_operator"
16473 [(and (match_operand 3 "aligned_operand" "")
16474 (match_operand 4 "const_int_operand" ""))
16475 (const_int 0)]))
16476 (set (match_operand 1 "register_operand" "")
16477 (and (match_dup 3) (match_dup 4)))]
16478 "! TARGET_PARTIAL_REG_STALL && reload_completed
16479 && optimize_insn_for_speed_p ()
16480 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16481 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16482 /* Ensure that the operand will remain sign-extended immediate. */
16483 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16484 [(parallel [(set (match_dup 0)
16485 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16486 (const_int 0)]))
16487 (set (match_dup 1)
16488 (and:SI (match_dup 3) (match_dup 4)))])]
16489 {
16490 operands[4]
16491 = gen_int_mode (INTVAL (operands[4])
16492 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16493 operands[1] = gen_lowpart (SImode, operands[1]);
16494 operands[3] = gen_lowpart (SImode, operands[3]);
16495 })
16496
16497 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16498 ; the TEST instruction with 32-bit sign-extended immediate and thus
16499 ; the instruction size would at least double, which is not what we
16500 ; want even with ! optimize_size.
16501 (define_split
16502 [(set (match_operand 0 "flags_reg_operand" "")
16503 (match_operator 1 "compare_operator"
16504 [(and (match_operand:HI 2 "aligned_operand" "")
16505 (match_operand:HI 3 "const_int_operand" ""))
16506 (const_int 0)]))]
16507 "! TARGET_PARTIAL_REG_STALL && reload_completed
16508 && ! TARGET_FAST_PREFIX
16509 && optimize_insn_for_speed_p ()
16510 /* Ensure that the operand will remain sign-extended immediate. */
16511 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16512 [(set (match_dup 0)
16513 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16514 (const_int 0)]))]
16515 {
16516 operands[3]
16517 = gen_int_mode (INTVAL (operands[3])
16518 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16519 operands[2] = gen_lowpart (SImode, operands[2]);
16520 })
16521
16522 (define_split
16523 [(set (match_operand 0 "register_operand" "")
16524 (neg (match_operand 1 "register_operand" "")))
16525 (clobber (reg:CC FLAGS_REG))]
16526 "! TARGET_PARTIAL_REG_STALL && reload_completed
16527 && (GET_MODE (operands[0]) == HImode
16528 || (GET_MODE (operands[0]) == QImode
16529 && (TARGET_PROMOTE_QImode
16530 || optimize_insn_for_size_p ())))"
16531 [(parallel [(set (match_dup 0)
16532 (neg:SI (match_dup 1)))
16533 (clobber (reg:CC FLAGS_REG))])]
16534 "operands[0] = gen_lowpart (SImode, operands[0]);
16535 operands[1] = gen_lowpart (SImode, operands[1]);")
16536
16537 (define_split
16538 [(set (match_operand 0 "register_operand" "")
16539 (not (match_operand 1 "register_operand" "")))]
16540 "! TARGET_PARTIAL_REG_STALL && reload_completed
16541 && (GET_MODE (operands[0]) == HImode
16542 || (GET_MODE (operands[0]) == QImode
16543 && (TARGET_PROMOTE_QImode
16544 || optimize_insn_for_size_p ())))"
16545 [(set (match_dup 0)
16546 (not:SI (match_dup 1)))]
16547 "operands[0] = gen_lowpart (SImode, operands[0]);
16548 operands[1] = gen_lowpart (SImode, operands[1]);")
16549
16550 (define_split
16551 [(set (match_operand 0 "register_operand" "")
16552 (if_then_else (match_operator 1 "comparison_operator"
16553 [(reg FLAGS_REG) (const_int 0)])
16554 (match_operand 2 "register_operand" "")
16555 (match_operand 3 "register_operand" "")))]
16556 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16557 && (GET_MODE (operands[0]) == HImode
16558 || (GET_MODE (operands[0]) == QImode
16559 && (TARGET_PROMOTE_QImode
16560 || optimize_insn_for_size_p ())))"
16561 [(set (match_dup 0)
16562 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16563 "operands[0] = gen_lowpart (SImode, operands[0]);
16564 operands[2] = gen_lowpart (SImode, operands[2]);
16565 operands[3] = gen_lowpart (SImode, operands[3]);")
16566
16567 \f
16568 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16569 ;; transform a complex memory operation into two memory to register operations.
16570
16571 ;; Don't push memory operands
16572 (define_peephole2
16573 [(set (match_operand:SI 0 "push_operand" "")
16574 (match_operand:SI 1 "memory_operand" ""))
16575 (match_scratch:SI 2 "r")]
16576 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16577 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16578 [(set (match_dup 2) (match_dup 1))
16579 (set (match_dup 0) (match_dup 2))]
16580 "")
16581
16582 (define_peephole2
16583 [(set (match_operand:DI 0 "push_operand" "")
16584 (match_operand:DI 1 "memory_operand" ""))
16585 (match_scratch:DI 2 "r")]
16586 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16587 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16588 [(set (match_dup 2) (match_dup 1))
16589 (set (match_dup 0) (match_dup 2))]
16590 "")
16591
16592 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16593 ;; SImode pushes.
16594 (define_peephole2
16595 [(set (match_operand:SF 0 "push_operand" "")
16596 (match_operand:SF 1 "memory_operand" ""))
16597 (match_scratch:SF 2 "r")]
16598 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16599 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16600 [(set (match_dup 2) (match_dup 1))
16601 (set (match_dup 0) (match_dup 2))]
16602 "")
16603
16604 (define_peephole2
16605 [(set (match_operand:HI 0 "push_operand" "")
16606 (match_operand:HI 1 "memory_operand" ""))
16607 (match_scratch:HI 2 "r")]
16608 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16609 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16610 [(set (match_dup 2) (match_dup 1))
16611 (set (match_dup 0) (match_dup 2))]
16612 "")
16613
16614 (define_peephole2
16615 [(set (match_operand:QI 0 "push_operand" "")
16616 (match_operand:QI 1 "memory_operand" ""))
16617 (match_scratch:QI 2 "q")]
16618 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16619 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16620 [(set (match_dup 2) (match_dup 1))
16621 (set (match_dup 0) (match_dup 2))]
16622 "")
16623
16624 ;; Don't move an immediate directly to memory when the instruction
16625 ;; gets too big.
16626 (define_peephole2
16627 [(match_scratch:SI 1 "r")
16628 (set (match_operand:SI 0 "memory_operand" "")
16629 (const_int 0))]
16630 "optimize_insn_for_speed_p ()
16631 && ! TARGET_USE_MOV0
16632 && TARGET_SPLIT_LONG_MOVES
16633 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16634 && peep2_regno_dead_p (0, FLAGS_REG)"
16635 [(parallel [(set (match_dup 1) (const_int 0))
16636 (clobber (reg:CC FLAGS_REG))])
16637 (set (match_dup 0) (match_dup 1))]
16638 "")
16639
16640 (define_peephole2
16641 [(match_scratch:HI 1 "r")
16642 (set (match_operand:HI 0 "memory_operand" "")
16643 (const_int 0))]
16644 "optimize_insn_for_speed_p ()
16645 && ! TARGET_USE_MOV0
16646 && TARGET_SPLIT_LONG_MOVES
16647 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16648 && peep2_regno_dead_p (0, FLAGS_REG)"
16649 [(parallel [(set (match_dup 2) (const_int 0))
16650 (clobber (reg:CC FLAGS_REG))])
16651 (set (match_dup 0) (match_dup 1))]
16652 "operands[2] = gen_lowpart (SImode, operands[1]);")
16653
16654 (define_peephole2
16655 [(match_scratch:QI 1 "q")
16656 (set (match_operand:QI 0 "memory_operand" "")
16657 (const_int 0))]
16658 "optimize_insn_for_speed_p ()
16659 && ! TARGET_USE_MOV0
16660 && TARGET_SPLIT_LONG_MOVES
16661 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16662 && peep2_regno_dead_p (0, FLAGS_REG)"
16663 [(parallel [(set (match_dup 2) (const_int 0))
16664 (clobber (reg:CC FLAGS_REG))])
16665 (set (match_dup 0) (match_dup 1))]
16666 "operands[2] = gen_lowpart (SImode, operands[1]);")
16667
16668 (define_peephole2
16669 [(match_scratch:SI 2 "r")
16670 (set (match_operand:SI 0 "memory_operand" "")
16671 (match_operand:SI 1 "immediate_operand" ""))]
16672 "optimize_insn_for_speed_p ()
16673 && TARGET_SPLIT_LONG_MOVES
16674 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16675 [(set (match_dup 2) (match_dup 1))
16676 (set (match_dup 0) (match_dup 2))]
16677 "")
16678
16679 (define_peephole2
16680 [(match_scratch:HI 2 "r")
16681 (set (match_operand:HI 0 "memory_operand" "")
16682 (match_operand:HI 1 "immediate_operand" ""))]
16683 "optimize_insn_for_speed_p ()
16684 && TARGET_SPLIT_LONG_MOVES
16685 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16686 [(set (match_dup 2) (match_dup 1))
16687 (set (match_dup 0) (match_dup 2))]
16688 "")
16689
16690 (define_peephole2
16691 [(match_scratch:QI 2 "q")
16692 (set (match_operand:QI 0 "memory_operand" "")
16693 (match_operand:QI 1 "immediate_operand" ""))]
16694 "optimize_insn_for_speed_p ()
16695 && TARGET_SPLIT_LONG_MOVES
16696 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16697 [(set (match_dup 2) (match_dup 1))
16698 (set (match_dup 0) (match_dup 2))]
16699 "")
16700
16701 ;; Don't compare memory with zero, load and use a test instead.
16702 (define_peephole2
16703 [(set (match_operand 0 "flags_reg_operand" "")
16704 (match_operator 1 "compare_operator"
16705 [(match_operand:SI 2 "memory_operand" "")
16706 (const_int 0)]))
16707 (match_scratch:SI 3 "r")]
16708 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16709 [(set (match_dup 3) (match_dup 2))
16710 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16711 "")
16712
16713 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16714 ;; Don't split NOTs with a displacement operand, because resulting XOR
16715 ;; will not be pairable anyway.
16716 ;;
16717 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16718 ;; represented using a modRM byte. The XOR replacement is long decoded,
16719 ;; so this split helps here as well.
16720 ;;
16721 ;; Note: Can't do this as a regular split because we can't get proper
16722 ;; lifetime information then.
16723
16724 (define_peephole2
16725 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16726 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16727 "optimize_insn_for_speed_p ()
16728 && ((TARGET_NOT_UNPAIRABLE
16729 && (!MEM_P (operands[0])
16730 || !memory_displacement_operand (operands[0], SImode)))
16731 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
16732 && peep2_regno_dead_p (0, FLAGS_REG)"
16733 [(parallel [(set (match_dup 0)
16734 (xor:SI (match_dup 1) (const_int -1)))
16735 (clobber (reg:CC FLAGS_REG))])]
16736 "")
16737
16738 (define_peephole2
16739 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16740 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16741 "optimize_insn_for_speed_p ()
16742 && ((TARGET_NOT_UNPAIRABLE
16743 && (!MEM_P (operands[0])
16744 || !memory_displacement_operand (operands[0], HImode)))
16745 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
16746 && peep2_regno_dead_p (0, FLAGS_REG)"
16747 [(parallel [(set (match_dup 0)
16748 (xor:HI (match_dup 1) (const_int -1)))
16749 (clobber (reg:CC FLAGS_REG))])]
16750 "")
16751
16752 (define_peephole2
16753 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16754 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16755 "optimize_insn_for_speed_p ()
16756 && ((TARGET_NOT_UNPAIRABLE
16757 && (!MEM_P (operands[0])
16758 || !memory_displacement_operand (operands[0], QImode)))
16759 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
16760 && peep2_regno_dead_p (0, FLAGS_REG)"
16761 [(parallel [(set (match_dup 0)
16762 (xor:QI (match_dup 1) (const_int -1)))
16763 (clobber (reg:CC FLAGS_REG))])]
16764 "")
16765
16766 ;; Non pairable "test imm, reg" instructions can be translated to
16767 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16768 ;; byte opcode instead of two, have a short form for byte operands),
16769 ;; so do it for other CPUs as well. Given that the value was dead,
16770 ;; this should not create any new dependencies. Pass on the sub-word
16771 ;; versions if we're concerned about partial register stalls.
16772
16773 (define_peephole2
16774 [(set (match_operand 0 "flags_reg_operand" "")
16775 (match_operator 1 "compare_operator"
16776 [(and:SI (match_operand:SI 2 "register_operand" "")
16777 (match_operand:SI 3 "immediate_operand" ""))
16778 (const_int 0)]))]
16779 "ix86_match_ccmode (insn, CCNOmode)
16780 && (true_regnum (operands[2]) != AX_REG
16781 || satisfies_constraint_K (operands[3]))
16782 && peep2_reg_dead_p (1, operands[2])"
16783 [(parallel
16784 [(set (match_dup 0)
16785 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16786 (const_int 0)]))
16787 (set (match_dup 2)
16788 (and:SI (match_dup 2) (match_dup 3)))])]
16789 "")
16790
16791 ;; We don't need to handle HImode case, because it will be promoted to SImode
16792 ;; on ! TARGET_PARTIAL_REG_STALL
16793
16794 (define_peephole2
16795 [(set (match_operand 0 "flags_reg_operand" "")
16796 (match_operator 1 "compare_operator"
16797 [(and:QI (match_operand:QI 2 "register_operand" "")
16798 (match_operand:QI 3 "immediate_operand" ""))
16799 (const_int 0)]))]
16800 "! TARGET_PARTIAL_REG_STALL
16801 && ix86_match_ccmode (insn, CCNOmode)
16802 && true_regnum (operands[2]) != AX_REG
16803 && peep2_reg_dead_p (1, operands[2])"
16804 [(parallel
16805 [(set (match_dup 0)
16806 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16807 (const_int 0)]))
16808 (set (match_dup 2)
16809 (and:QI (match_dup 2) (match_dup 3)))])]
16810 "")
16811
16812 (define_peephole2
16813 [(set (match_operand 0 "flags_reg_operand" "")
16814 (match_operator 1 "compare_operator"
16815 [(and:SI
16816 (zero_extract:SI
16817 (match_operand 2 "ext_register_operand" "")
16818 (const_int 8)
16819 (const_int 8))
16820 (match_operand 3 "const_int_operand" ""))
16821 (const_int 0)]))]
16822 "! TARGET_PARTIAL_REG_STALL
16823 && ix86_match_ccmode (insn, CCNOmode)
16824 && true_regnum (operands[2]) != AX_REG
16825 && peep2_reg_dead_p (1, operands[2])"
16826 [(parallel [(set (match_dup 0)
16827 (match_op_dup 1
16828 [(and:SI
16829 (zero_extract:SI
16830 (match_dup 2)
16831 (const_int 8)
16832 (const_int 8))
16833 (match_dup 3))
16834 (const_int 0)]))
16835 (set (zero_extract:SI (match_dup 2)
16836 (const_int 8)
16837 (const_int 8))
16838 (and:SI
16839 (zero_extract:SI
16840 (match_dup 2)
16841 (const_int 8)
16842 (const_int 8))
16843 (match_dup 3)))])]
16844 "")
16845
16846 ;; Don't do logical operations with memory inputs.
16847 (define_peephole2
16848 [(match_scratch:SI 2 "r")
16849 (parallel [(set (match_operand:SI 0 "register_operand" "")
16850 (match_operator:SI 3 "arith_or_logical_operator"
16851 [(match_dup 0)
16852 (match_operand:SI 1 "memory_operand" "")]))
16853 (clobber (reg:CC FLAGS_REG))])]
16854 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16855 [(set (match_dup 2) (match_dup 1))
16856 (parallel [(set (match_dup 0)
16857 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16858 (clobber (reg:CC FLAGS_REG))])]
16859 "")
16860
16861 (define_peephole2
16862 [(match_scratch:SI 2 "r")
16863 (parallel [(set (match_operand:SI 0 "register_operand" "")
16864 (match_operator:SI 3 "arith_or_logical_operator"
16865 [(match_operand:SI 1 "memory_operand" "")
16866 (match_dup 0)]))
16867 (clobber (reg:CC FLAGS_REG))])]
16868 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16869 [(set (match_dup 2) (match_dup 1))
16870 (parallel [(set (match_dup 0)
16871 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16872 (clobber (reg:CC FLAGS_REG))])]
16873 "")
16874
16875 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16876 ;; refers to the destination of the load!
16877
16878 (define_peephole2
16879 [(set (match_operand:SI 0 "register_operand" "")
16880 (match_operand:SI 1 "register_operand" ""))
16881 (parallel [(set (match_dup 0)
16882 (match_operator:SI 3 "commutative_operator"
16883 [(match_dup 0)
16884 (match_operand:SI 2 "memory_operand" "")]))
16885 (clobber (reg:CC FLAGS_REG))])]
16886 "REGNO (operands[0]) != REGNO (operands[1])
16887 && GENERAL_REGNO_P (REGNO (operands[0]))
16888 && GENERAL_REGNO_P (REGNO (operands[1]))"
16889 [(set (match_dup 0) (match_dup 4))
16890 (parallel [(set (match_dup 0)
16891 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16892 (clobber (reg:CC FLAGS_REG))])]
16893 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16894
16895 (define_peephole2
16896 [(set (match_operand 0 "register_operand" "")
16897 (match_operand 1 "register_operand" ""))
16898 (set (match_dup 0)
16899 (match_operator 3 "commutative_operator"
16900 [(match_dup 0)
16901 (match_operand 2 "memory_operand" "")]))]
16902 "REGNO (operands[0]) != REGNO (operands[1])
16903 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16904 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16905 [(set (match_dup 0) (match_dup 2))
16906 (set (match_dup 0)
16907 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
16908 "")
16909
16910 ; Don't do logical operations with memory outputs
16911 ;
16912 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16913 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16914 ; the same decoder scheduling characteristics as the original.
16915
16916 (define_peephole2
16917 [(match_scratch:SI 2 "r")
16918 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16919 (match_operator:SI 3 "arith_or_logical_operator"
16920 [(match_dup 0)
16921 (match_operand:SI 1 "nonmemory_operand" "")]))
16922 (clobber (reg:CC FLAGS_REG))])]
16923 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16924 /* Do not split stack checking probes. */
16925 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16926 [(set (match_dup 2) (match_dup 0))
16927 (parallel [(set (match_dup 2)
16928 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16929 (clobber (reg:CC FLAGS_REG))])
16930 (set (match_dup 0) (match_dup 2))]
16931 "")
16932
16933 (define_peephole2
16934 [(match_scratch:SI 2 "r")
16935 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16936 (match_operator:SI 3 "arith_or_logical_operator"
16937 [(match_operand:SI 1 "nonmemory_operand" "")
16938 (match_dup 0)]))
16939 (clobber (reg:CC FLAGS_REG))])]
16940 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16941 /* Do not split stack checking probes. */
16942 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16943 [(set (match_dup 2) (match_dup 0))
16944 (parallel [(set (match_dup 2)
16945 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16946 (clobber (reg:CC FLAGS_REG))])
16947 (set (match_dup 0) (match_dup 2))]
16948 "")
16949
16950 ;; Attempt to always use XOR for zeroing registers.
16951 (define_peephole2
16952 [(set (match_operand 0 "register_operand" "")
16953 (match_operand 1 "const0_operand" ""))]
16954 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16955 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16956 && GENERAL_REG_P (operands[0])
16957 && peep2_regno_dead_p (0, FLAGS_REG)"
16958 [(parallel [(set (match_dup 0) (const_int 0))
16959 (clobber (reg:CC FLAGS_REG))])]
16960 {
16961 operands[0] = gen_lowpart (word_mode, operands[0]);
16962 })
16963
16964 (define_peephole2
16965 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16966 (const_int 0))]
16967 "(GET_MODE (operands[0]) == QImode
16968 || GET_MODE (operands[0]) == HImode)
16969 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16970 && peep2_regno_dead_p (0, FLAGS_REG)"
16971 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16972 (clobber (reg:CC FLAGS_REG))])])
16973
16974 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
16975 (define_peephole2
16976 [(set (match_operand 0 "register_operand" "")
16977 (const_int -1))]
16978 "(GET_MODE (operands[0]) == HImode
16979 || GET_MODE (operands[0]) == SImode
16980 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16981 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16982 && peep2_regno_dead_p (0, FLAGS_REG)"
16983 [(parallel [(set (match_dup 0) (const_int -1))
16984 (clobber (reg:CC FLAGS_REG))])]
16985 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16986 operands[0]);")
16987
16988 ;; Attempt to convert simple leas to adds. These can be created by
16989 ;; move expanders.
16990 (define_peephole2
16991 [(set (match_operand:SI 0 "register_operand" "")
16992 (plus:SI (match_dup 0)
16993 (match_operand:SI 1 "nonmemory_operand" "")))]
16994 "peep2_regno_dead_p (0, FLAGS_REG)"
16995 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
16996 (clobber (reg:CC FLAGS_REG))])]
16997 "")
16998
16999 (define_peephole2
17000 [(set (match_operand:SI 0 "register_operand" "")
17001 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17002 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17003 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17004 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17005 (clobber (reg:CC FLAGS_REG))])]
17006 "operands[2] = gen_lowpart (SImode, operands[2]);")
17007
17008 (define_peephole2
17009 [(set (match_operand:DI 0 "register_operand" "")
17010 (plus:DI (match_dup 0)
17011 (match_operand:DI 1 "x86_64_general_operand" "")))]
17012 "peep2_regno_dead_p (0, FLAGS_REG)"
17013 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17014 (clobber (reg:CC FLAGS_REG))])]
17015 "")
17016
17017 (define_peephole2
17018 [(set (match_operand:SI 0 "register_operand" "")
17019 (mult:SI (match_dup 0)
17020 (match_operand:SI 1 "const_int_operand" "")))]
17021 "exact_log2 (INTVAL (operands[1])) >= 0
17022 && peep2_regno_dead_p (0, FLAGS_REG)"
17023 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17024 (clobber (reg:CC FLAGS_REG))])]
17025 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17026
17027 (define_peephole2
17028 [(set (match_operand:DI 0 "register_operand" "")
17029 (mult:DI (match_dup 0)
17030 (match_operand:DI 1 "const_int_operand" "")))]
17031 "exact_log2 (INTVAL (operands[1])) >= 0
17032 && peep2_regno_dead_p (0, FLAGS_REG)"
17033 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17034 (clobber (reg:CC FLAGS_REG))])]
17035 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17036
17037 (define_peephole2
17038 [(set (match_operand:SI 0 "register_operand" "")
17039 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17040 (match_operand:DI 2 "const_int_operand" "")) 0))]
17041 "exact_log2 (INTVAL (operands[2])) >= 0
17042 && REGNO (operands[0]) == REGNO (operands[1])
17043 && peep2_regno_dead_p (0, FLAGS_REG)"
17044 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17045 (clobber (reg:CC FLAGS_REG))])]
17046 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17047
17048 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17049 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17050 ;; many CPUs it is also faster, since special hardware to avoid esp
17051 ;; dependencies is present.
17052
17053 ;; While some of these conversions may be done using splitters, we use peepholes
17054 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17055
17056 ;; Convert prologue esp subtractions to push.
17057 ;; We need register to push. In order to keep verify_flow_info happy we have
17058 ;; two choices
17059 ;; - use scratch and clobber it in order to avoid dependencies
17060 ;; - use already live register
17061 ;; We can't use the second way right now, since there is no reliable way how to
17062 ;; verify that given register is live. First choice will also most likely in
17063 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17064 ;; call clobbered registers are dead. We may want to use base pointer as an
17065 ;; alternative when no register is available later.
17066
17067 (define_peephole2
17068 [(match_scratch:SI 0 "r")
17069 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17070 (clobber (reg:CC FLAGS_REG))
17071 (clobber (mem:BLK (scratch)))])]
17072 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17073 [(clobber (match_dup 0))
17074 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17075 (clobber (mem:BLK (scratch)))])])
17076
17077 (define_peephole2
17078 [(match_scratch:SI 0 "r")
17079 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17080 (clobber (reg:CC FLAGS_REG))
17081 (clobber (mem:BLK (scratch)))])]
17082 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17083 [(clobber (match_dup 0))
17084 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17085 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17086 (clobber (mem:BLK (scratch)))])])
17087
17088 ;; Convert esp subtractions to push.
17089 (define_peephole2
17090 [(match_scratch:SI 0 "r")
17091 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17092 (clobber (reg:CC FLAGS_REG))])]
17093 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17094 [(clobber (match_dup 0))
17095 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17096
17097 (define_peephole2
17098 [(match_scratch:SI 0 "r")
17099 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17100 (clobber (reg:CC FLAGS_REG))])]
17101 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17102 [(clobber (match_dup 0))
17103 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17104 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17105
17106 ;; Convert epilogue deallocator to pop.
17107 (define_peephole2
17108 [(match_scratch:SI 0 "r")
17109 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17110 (clobber (reg:CC FLAGS_REG))
17111 (clobber (mem:BLK (scratch)))])]
17112 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17113 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17114 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17115 (clobber (mem:BLK (scratch)))])]
17116 "")
17117
17118 ;; Two pops case is tricky, since pop causes dependency on destination register.
17119 ;; We use two registers if available.
17120 (define_peephole2
17121 [(match_scratch:SI 0 "r")
17122 (match_scratch:SI 1 "r")
17123 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17124 (clobber (reg:CC FLAGS_REG))
17125 (clobber (mem:BLK (scratch)))])]
17126 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17127 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17128 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17129 (clobber (mem:BLK (scratch)))])
17130 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17131 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17132 "")
17133
17134 (define_peephole2
17135 [(match_scratch:SI 0 "r")
17136 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17137 (clobber (reg:CC FLAGS_REG))
17138 (clobber (mem:BLK (scratch)))])]
17139 "optimize_insn_for_size_p ()"
17140 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17141 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17142 (clobber (mem:BLK (scratch)))])
17143 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17144 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17145 "")
17146
17147 ;; Convert esp additions to pop.
17148 (define_peephole2
17149 [(match_scratch:SI 0 "r")
17150 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17151 (clobber (reg:CC FLAGS_REG))])]
17152 ""
17153 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17154 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17155 "")
17156
17157 ;; Two pops case is tricky, since pop causes dependency on destination register.
17158 ;; We use two registers if available.
17159 (define_peephole2
17160 [(match_scratch:SI 0 "r")
17161 (match_scratch:SI 1 "r")
17162 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17163 (clobber (reg:CC FLAGS_REG))])]
17164 ""
17165 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17166 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17167 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17168 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17169 "")
17170
17171 (define_peephole2
17172 [(match_scratch:SI 0 "r")
17173 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17174 (clobber (reg:CC FLAGS_REG))])]
17175 "optimize_insn_for_size_p ()"
17176 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17177 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17178 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17179 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17180 "")
17181 \f
17182 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17183 ;; required and register dies. Similarly for 128 to -128.
17184 (define_peephole2
17185 [(set (match_operand 0 "flags_reg_operand" "")
17186 (match_operator 1 "compare_operator"
17187 [(match_operand 2 "register_operand" "")
17188 (match_operand 3 "const_int_operand" "")]))]
17189 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17190 && incdec_operand (operands[3], GET_MODE (operands[3])))
17191 || (!TARGET_FUSE_CMP_AND_BRANCH
17192 && INTVAL (operands[3]) == 128))
17193 && ix86_match_ccmode (insn, CCGCmode)
17194 && peep2_reg_dead_p (1, operands[2])"
17195 [(parallel [(set (match_dup 0)
17196 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17197 (clobber (match_dup 2))])]
17198 "")
17199 \f
17200 (define_peephole2
17201 [(match_scratch:DI 0 "r")
17202 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17203 (clobber (reg:CC FLAGS_REG))
17204 (clobber (mem:BLK (scratch)))])]
17205 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17206 [(clobber (match_dup 0))
17207 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17208 (clobber (mem:BLK (scratch)))])])
17209
17210 (define_peephole2
17211 [(match_scratch:DI 0 "r")
17212 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17213 (clobber (reg:CC FLAGS_REG))
17214 (clobber (mem:BLK (scratch)))])]
17215 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17216 [(clobber (match_dup 0))
17217 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17218 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17219 (clobber (mem:BLK (scratch)))])])
17220
17221 ;; Convert esp subtractions to push.
17222 (define_peephole2
17223 [(match_scratch:DI 0 "r")
17224 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17225 (clobber (reg:CC FLAGS_REG))])]
17226 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17227 [(clobber (match_dup 0))
17228 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17229
17230 (define_peephole2
17231 [(match_scratch:DI 0 "r")
17232 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17233 (clobber (reg:CC FLAGS_REG))])]
17234 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17235 [(clobber (match_dup 0))
17236 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17237 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17238
17239 ;; Convert epilogue deallocator to pop.
17240 (define_peephole2
17241 [(match_scratch:DI 0 "r")
17242 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17243 (clobber (reg:CC FLAGS_REG))
17244 (clobber (mem:BLK (scratch)))])]
17245 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17246 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17247 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17248 (clobber (mem:BLK (scratch)))])]
17249 "")
17250
17251 ;; Two pops case is tricky, since pop causes dependency on destination register.
17252 ;; We use two registers if available.
17253 (define_peephole2
17254 [(match_scratch:DI 0 "r")
17255 (match_scratch:DI 1 "r")
17256 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17257 (clobber (reg:CC FLAGS_REG))
17258 (clobber (mem:BLK (scratch)))])]
17259 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17260 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17261 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17262 (clobber (mem:BLK (scratch)))])
17263 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17264 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17265 "")
17266
17267 (define_peephole2
17268 [(match_scratch:DI 0 "r")
17269 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17270 (clobber (reg:CC FLAGS_REG))
17271 (clobber (mem:BLK (scratch)))])]
17272 "optimize_insn_for_size_p ()"
17273 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17274 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17275 (clobber (mem:BLK (scratch)))])
17276 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17277 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17278 "")
17279
17280 ;; Convert esp additions to pop.
17281 (define_peephole2
17282 [(match_scratch:DI 0 "r")
17283 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17284 (clobber (reg:CC FLAGS_REG))])]
17285 ""
17286 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17287 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17288 "")
17289
17290 ;; Two pops case is tricky, since pop causes dependency on destination register.
17291 ;; We use two registers if available.
17292 (define_peephole2
17293 [(match_scratch:DI 0 "r")
17294 (match_scratch:DI 1 "r")
17295 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17296 (clobber (reg:CC FLAGS_REG))])]
17297 ""
17298 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17299 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17300 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17301 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17302 "")
17303
17304 (define_peephole2
17305 [(match_scratch:DI 0 "r")
17306 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17307 (clobber (reg:CC FLAGS_REG))])]
17308 "optimize_insn_for_size_p ()"
17309 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17310 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17311 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17312 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17313 "")
17314 \f
17315 ;; Convert imul by three, five and nine into lea
17316 (define_peephole2
17317 [(parallel
17318 [(set (match_operand:SI 0 "register_operand" "")
17319 (mult:SI (match_operand:SI 1 "register_operand" "")
17320 (match_operand:SI 2 "const_int_operand" "")))
17321 (clobber (reg:CC FLAGS_REG))])]
17322 "INTVAL (operands[2]) == 3
17323 || INTVAL (operands[2]) == 5
17324 || INTVAL (operands[2]) == 9"
17325 [(set (match_dup 0)
17326 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17327 (match_dup 1)))]
17328 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17329
17330 (define_peephole2
17331 [(parallel
17332 [(set (match_operand:SI 0 "register_operand" "")
17333 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17334 (match_operand:SI 2 "const_int_operand" "")))
17335 (clobber (reg:CC FLAGS_REG))])]
17336 "optimize_insn_for_speed_p ()
17337 && (INTVAL (operands[2]) == 3
17338 || INTVAL (operands[2]) == 5
17339 || INTVAL (operands[2]) == 9)"
17340 [(set (match_dup 0) (match_dup 1))
17341 (set (match_dup 0)
17342 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17343 (match_dup 0)))]
17344 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17345
17346 (define_peephole2
17347 [(parallel
17348 [(set (match_operand:DI 0 "register_operand" "")
17349 (mult:DI (match_operand:DI 1 "register_operand" "")
17350 (match_operand:DI 2 "const_int_operand" "")))
17351 (clobber (reg:CC FLAGS_REG))])]
17352 "TARGET_64BIT
17353 && (INTVAL (operands[2]) == 3
17354 || INTVAL (operands[2]) == 5
17355 || INTVAL (operands[2]) == 9)"
17356 [(set (match_dup 0)
17357 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17358 (match_dup 1)))]
17359 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17360
17361 (define_peephole2
17362 [(parallel
17363 [(set (match_operand:DI 0 "register_operand" "")
17364 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17365 (match_operand:DI 2 "const_int_operand" "")))
17366 (clobber (reg:CC FLAGS_REG))])]
17367 "TARGET_64BIT
17368 && optimize_insn_for_speed_p ()
17369 && (INTVAL (operands[2]) == 3
17370 || INTVAL (operands[2]) == 5
17371 || INTVAL (operands[2]) == 9)"
17372 [(set (match_dup 0) (match_dup 1))
17373 (set (match_dup 0)
17374 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17375 (match_dup 0)))]
17376 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17377
17378 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17379 ;; imul $32bit_imm, reg, reg is direct decoded.
17380 (define_peephole2
17381 [(match_scratch:DI 3 "r")
17382 (parallel [(set (match_operand:DI 0 "register_operand" "")
17383 (mult:DI (match_operand:DI 1 "memory_operand" "")
17384 (match_operand:DI 2 "immediate_operand" "")))
17385 (clobber (reg:CC FLAGS_REG))])]
17386 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17387 && !satisfies_constraint_K (operands[2])"
17388 [(set (match_dup 3) (match_dup 1))
17389 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17390 (clobber (reg:CC FLAGS_REG))])]
17391 "")
17392
17393 (define_peephole2
17394 [(match_scratch:SI 3 "r")
17395 (parallel [(set (match_operand:SI 0 "register_operand" "")
17396 (mult:SI (match_operand:SI 1 "memory_operand" "")
17397 (match_operand:SI 2 "immediate_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))])]
17399 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17400 && !satisfies_constraint_K (operands[2])"
17401 [(set (match_dup 3) (match_dup 1))
17402 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17403 (clobber (reg:CC FLAGS_REG))])]
17404 "")
17405
17406 (define_peephole2
17407 [(match_scratch:SI 3 "r")
17408 (parallel [(set (match_operand:DI 0 "register_operand" "")
17409 (zero_extend:DI
17410 (mult:SI (match_operand:SI 1 "memory_operand" "")
17411 (match_operand:SI 2 "immediate_operand" ""))))
17412 (clobber (reg:CC FLAGS_REG))])]
17413 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17414 && !satisfies_constraint_K (operands[2])"
17415 [(set (match_dup 3) (match_dup 1))
17416 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17417 (clobber (reg:CC FLAGS_REG))])]
17418 "")
17419
17420 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17421 ;; Convert it into imul reg, reg
17422 ;; It would be better to force assembler to encode instruction using long
17423 ;; immediate, but there is apparently no way to do so.
17424 (define_peephole2
17425 [(parallel [(set (match_operand:DI 0 "register_operand" "")
17426 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17427 (match_operand:DI 2 "const_int_operand" "")))
17428 (clobber (reg:CC FLAGS_REG))])
17429 (match_scratch:DI 3 "r")]
17430 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17431 && satisfies_constraint_K (operands[2])"
17432 [(set (match_dup 3) (match_dup 2))
17433 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17434 (clobber (reg:CC FLAGS_REG))])]
17435 {
17436 if (!rtx_equal_p (operands[0], operands[1]))
17437 emit_move_insn (operands[0], operands[1]);
17438 })
17439
17440 (define_peephole2
17441 [(parallel [(set (match_operand:SI 0 "register_operand" "")
17442 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17443 (match_operand:SI 2 "const_int_operand" "")))
17444 (clobber (reg:CC FLAGS_REG))])
17445 (match_scratch:SI 3 "r")]
17446 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17447 && satisfies_constraint_K (operands[2])"
17448 [(set (match_dup 3) (match_dup 2))
17449 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17450 (clobber (reg:CC FLAGS_REG))])]
17451 {
17452 if (!rtx_equal_p (operands[0], operands[1]))
17453 emit_move_insn (operands[0], operands[1]);
17454 })
17455
17456 (define_peephole2
17457 [(parallel [(set (match_operand:HI 0 "register_operand" "")
17458 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17459 (match_operand:HI 2 "immediate_operand" "")))
17460 (clobber (reg:CC FLAGS_REG))])
17461 (match_scratch:HI 3 "r")]
17462 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17463 [(set (match_dup 3) (match_dup 2))
17464 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17465 (clobber (reg:CC FLAGS_REG))])]
17466 {
17467 if (!rtx_equal_p (operands[0], operands[1]))
17468 emit_move_insn (operands[0], operands[1]);
17469 })
17470
17471 ;; After splitting up read-modify operations, array accesses with memory
17472 ;; operands might end up in form:
17473 ;; sall $2, %eax
17474 ;; movl 4(%esp), %edx
17475 ;; addl %edx, %eax
17476 ;; instead of pre-splitting:
17477 ;; sall $2, %eax
17478 ;; addl 4(%esp), %eax
17479 ;; Turn it into:
17480 ;; movl 4(%esp), %edx
17481 ;; leal (%edx,%eax,4), %eax
17482
17483 (define_peephole2
17484 [(parallel [(set (match_operand 0 "register_operand" "")
17485 (ashift (match_operand 1 "register_operand" "")
17486 (match_operand 2 "const_int_operand" "")))
17487 (clobber (reg:CC FLAGS_REG))])
17488 (set (match_operand 3 "register_operand")
17489 (match_operand 4 "x86_64_general_operand" ""))
17490 (parallel [(set (match_operand 5 "register_operand" "")
17491 (plus (match_operand 6 "register_operand" "")
17492 (match_operand 7 "register_operand" "")))
17493 (clobber (reg:CC FLAGS_REG))])]
17494 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17495 /* Validate MODE for lea. */
17496 && ((!TARGET_PARTIAL_REG_STALL
17497 && (GET_MODE (operands[0]) == QImode
17498 || GET_MODE (operands[0]) == HImode))
17499 || GET_MODE (operands[0]) == SImode
17500 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17501 /* We reorder load and the shift. */
17502 && !rtx_equal_p (operands[1], operands[3])
17503 && !reg_overlap_mentioned_p (operands[0], operands[4])
17504 /* Last PLUS must consist of operand 0 and 3. */
17505 && !rtx_equal_p (operands[0], operands[3])
17506 && (rtx_equal_p (operands[3], operands[6])
17507 || rtx_equal_p (operands[3], operands[7]))
17508 && (rtx_equal_p (operands[0], operands[6])
17509 || rtx_equal_p (operands[0], operands[7]))
17510 /* The intermediate operand 0 must die or be same as output. */
17511 && (rtx_equal_p (operands[0], operands[5])
17512 || peep2_reg_dead_p (3, operands[0]))"
17513 [(set (match_dup 3) (match_dup 4))
17514 (set (match_dup 0) (match_dup 1))]
17515 {
17516 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
17517 int scale = 1 << INTVAL (operands[2]);
17518 rtx index = gen_lowpart (Pmode, operands[1]);
17519 rtx base = gen_lowpart (Pmode, operands[3]);
17520 rtx dest = gen_lowpart (mode, operands[5]);
17521
17522 operands[1] = gen_rtx_PLUS (Pmode, base,
17523 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17524 if (mode != Pmode)
17525 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17526 operands[0] = dest;
17527 })
17528 \f
17529 ;; Call-value patterns last so that the wildcard operand does not
17530 ;; disrupt insn-recog's switch tables.
17531
17532 (define_insn "*call_value_pop_0"
17533 [(set (match_operand 0 "" "")
17534 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17535 (match_operand:SI 2 "" "")))
17536 (set (reg:SI SP_REG)
17537 (plus:SI (reg:SI SP_REG)
17538 (match_operand:SI 3 "immediate_operand" "")))]
17539 "!TARGET_64BIT"
17540 {
17541 if (SIBLING_CALL_P (insn))
17542 return "jmp\t%P1";
17543 else
17544 return "call\t%P1";
17545 }
17546 [(set_attr "type" "callv")])
17547
17548 (define_insn "*call_value_pop_1"
17549 [(set (match_operand 0 "" "")
17550 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17551 (match_operand:SI 2 "" "")))
17552 (set (reg:SI SP_REG)
17553 (plus:SI (reg:SI SP_REG)
17554 (match_operand:SI 3 "immediate_operand" "i")))]
17555 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17556 {
17557 if (constant_call_address_operand (operands[1], Pmode))
17558 return "call\t%P1";
17559 return "call\t%A1";
17560 }
17561 [(set_attr "type" "callv")])
17562
17563 (define_insn "*sibcall_value_pop_1"
17564 [(set (match_operand 0 "" "")
17565 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17566 (match_operand:SI 2 "" "")))
17567 (set (reg:SI SP_REG)
17568 (plus:SI (reg:SI SP_REG)
17569 (match_operand:SI 3 "immediate_operand" "i,i")))]
17570 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17571 "@
17572 jmp\t%P1
17573 jmp\t%A1"
17574 [(set_attr "type" "callv")])
17575
17576 (define_insn "*call_value_0"
17577 [(set (match_operand 0 "" "")
17578 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17579 (match_operand:SI 2 "" "")))]
17580 "!TARGET_64BIT"
17581 {
17582 if (SIBLING_CALL_P (insn))
17583 return "jmp\t%P1";
17584 else
17585 return "call\t%P1";
17586 }
17587 [(set_attr "type" "callv")])
17588
17589 (define_insn "*call_value_0_rex64"
17590 [(set (match_operand 0 "" "")
17591 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17592 (match_operand:DI 2 "const_int_operand" "")))]
17593 "TARGET_64BIT"
17594 {
17595 if (SIBLING_CALL_P (insn))
17596 return "jmp\t%P1";
17597 else
17598 return "call\t%P1";
17599 }
17600 [(set_attr "type" "callv")])
17601
17602 (define_insn "*call_value_0_rex64_ms_sysv"
17603 [(set (match_operand 0 "" "")
17604 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17605 (match_operand:DI 2 "const_int_operand" "")))
17606 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17607 (clobber (reg:TI XMM6_REG))
17608 (clobber (reg:TI XMM7_REG))
17609 (clobber (reg:TI XMM8_REG))
17610 (clobber (reg:TI XMM9_REG))
17611 (clobber (reg:TI XMM10_REG))
17612 (clobber (reg:TI XMM11_REG))
17613 (clobber (reg:TI XMM12_REG))
17614 (clobber (reg:TI XMM13_REG))
17615 (clobber (reg:TI XMM14_REG))
17616 (clobber (reg:TI XMM15_REG))
17617 (clobber (reg:DI SI_REG))
17618 (clobber (reg:DI DI_REG))]
17619 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17620 {
17621 if (SIBLING_CALL_P (insn))
17622 return "jmp\t%P1";
17623 else
17624 return "call\t%P1";
17625 }
17626 [(set_attr "type" "callv")])
17627
17628 (define_insn "*call_value_1"
17629 [(set (match_operand 0 "" "")
17630 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17631 (match_operand:SI 2 "" "")))]
17632 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17633 {
17634 if (constant_call_address_operand (operands[1], Pmode))
17635 return "call\t%P1";
17636 return "call\t%A1";
17637 }
17638 [(set_attr "type" "callv")])
17639
17640 (define_insn "*sibcall_value_1"
17641 [(set (match_operand 0 "" "")
17642 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17643 (match_operand:SI 2 "" "")))]
17644 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17645 "@
17646 jmp\t%P1
17647 jmp\t%A1"
17648 [(set_attr "type" "callv")])
17649
17650 (define_insn "*call_value_1_rex64"
17651 [(set (match_operand 0 "" "")
17652 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17653 (match_operand:DI 2 "" "")))]
17654 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17655 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17656 {
17657 if (constant_call_address_operand (operands[1], Pmode))
17658 return "call\t%P1";
17659 return "call\t%A1";
17660 }
17661 [(set_attr "type" "callv")])
17662
17663 (define_insn "*call_value_1_rex64_ms_sysv"
17664 [(set (match_operand 0 "" "")
17665 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17666 (match_operand:DI 2 "" "")))
17667 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17668 (clobber (reg:TI XMM6_REG))
17669 (clobber (reg:TI XMM7_REG))
17670 (clobber (reg:TI XMM8_REG))
17671 (clobber (reg:TI XMM9_REG))
17672 (clobber (reg:TI XMM10_REG))
17673 (clobber (reg:TI XMM11_REG))
17674 (clobber (reg:TI XMM12_REG))
17675 (clobber (reg:TI XMM13_REG))
17676 (clobber (reg:TI XMM14_REG))
17677 (clobber (reg:TI XMM15_REG))
17678 (clobber (reg:DI SI_REG))
17679 (clobber (reg:DI DI_REG))]
17680 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17681 {
17682 if (constant_call_address_operand (operands[1], Pmode))
17683 return "call\t%P1";
17684 return "call\t%A1";
17685 }
17686 [(set_attr "type" "callv")])
17687
17688 (define_insn "*call_value_1_rex64_large"
17689 [(set (match_operand 0 "" "")
17690 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17691 (match_operand:DI 2 "" "")))]
17692 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17693 "call\t%A1"
17694 [(set_attr "type" "callv")])
17695
17696 (define_insn "*sibcall_value_1_rex64"
17697 [(set (match_operand 0 "" "")
17698 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17699 (match_operand:DI 2 "" "")))]
17700 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17701 "@
17702 jmp\t%P1
17703 jmp\t%A1"
17704 [(set_attr "type" "callv")])
17705 \f
17706 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17707 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17708 ;; caught for use by garbage collectors and the like. Using an insn that
17709 ;; maps to SIGILL makes it more likely the program will rightfully die.
17710 ;; Keeping with tradition, "6" is in honor of #UD.
17711 (define_insn "trap"
17712 [(trap_if (const_int 1) (const_int 6))]
17713 ""
17714 { return ASM_SHORT "0x0b0f"; }
17715 [(set_attr "length" "2")])
17716
17717 (define_expand "sse_prologue_save"
17718 [(parallel [(set (match_operand:BLK 0 "" "")
17719 (unspec:BLK [(reg:DI XMM0_REG)
17720 (reg:DI XMM1_REG)
17721 (reg:DI XMM2_REG)
17722 (reg:DI XMM3_REG)
17723 (reg:DI XMM4_REG)
17724 (reg:DI XMM5_REG)
17725 (reg:DI XMM6_REG)
17726 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17727 (clobber (reg:CC FLAGS_REG))
17728 (clobber (match_operand:DI 1 "register_operand" ""))
17729 (use (match_operand:DI 2 "immediate_operand" ""))
17730 (use (label_ref:DI (match_operand 3 "" "")))
17731 (clobber (match_operand:DI 4 "register_operand" ""))
17732 (use (match_dup 1))])]
17733 "TARGET_64BIT"
17734 "")
17735
17736 ;; Pre-reload version of prologue save. Until after prologue generation we don't know
17737 ;; what the size of save instruction will be.
17738 ;; Operand 0+operand 6 is the memory save area
17739 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
17740 ;; Operand 2 is number of non-vaargs SSE arguments
17741 ;; Operand 3 is label starting the save block
17742 ;; Operand 4 is used for temporary computation of jump address
17743 (define_insn "*sse_prologue_save_insn1"
17744 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
17745 (match_operand:DI 6 "const_int_operand" "n")))
17746 (unspec:BLK [(reg:DI XMM0_REG)
17747 (reg:DI XMM1_REG)
17748 (reg:DI XMM2_REG)
17749 (reg:DI XMM3_REG)
17750 (reg:DI XMM4_REG)
17751 (reg:DI XMM5_REG)
17752 (reg:DI XMM6_REG)
17753 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17754 (clobber (reg:CC FLAGS_REG))
17755 (clobber (match_operand:DI 1 "register_operand" "=r"))
17756 (use (match_operand:DI 2 "const_int_operand" "i"))
17757 (use (label_ref:DI (match_operand 3 "" "X")))
17758 (clobber (match_operand:DI 4 "register_operand" "=&r"))
17759 (use (match_operand:DI 5 "register_operand" "1"))]
17760 "TARGET_64BIT
17761 && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
17762 && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
17763 "#"
17764 [(set_attr "type" "other")
17765 (set_attr "memory" "store")
17766 (set_attr "mode" "DI")])
17767
17768 ;; We know size of save instruction; expand the computation of jump address
17769 ;; in the jumptable.
17770 (define_split
17771 [(parallel [(set (match_operand:BLK 0 "" "")
17772 (unspec:BLK [(reg:DI XMM0_REG)
17773 (reg:DI XMM1_REG)
17774 (reg:DI XMM2_REG)
17775 (reg:DI XMM3_REG)
17776 (reg:DI XMM4_REG)
17777 (reg:DI XMM5_REG)
17778 (reg:DI XMM6_REG)
17779 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17780 (clobber (reg:CC FLAGS_REG))
17781 (clobber (match_operand:DI 1 "register_operand" ""))
17782 (use (match_operand:DI 2 "const_int_operand" ""))
17783 (use (match_operand 3 "" ""))
17784 (clobber (match_operand:DI 4 "register_operand" ""))
17785 (use (match_operand:DI 5 "register_operand" ""))])]
17786 "reload_completed"
17787 [(parallel [(set (match_dup 0)
17788 (unspec:BLK [(reg:DI XMM0_REG)
17789 (reg:DI XMM1_REG)
17790 (reg:DI XMM2_REG)
17791 (reg:DI XMM3_REG)
17792 (reg:DI XMM4_REG)
17793 (reg:DI XMM5_REG)
17794 (reg:DI XMM6_REG)
17795 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
17796 (use (match_dup 1))
17797 (use (match_dup 2))
17798 (use (match_dup 3))
17799 (use (match_dup 5))])]
17800 {
17801 /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
17802 int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
17803
17804 /* Compute address to jump to:
17805 label - eax*size + nnamed_sse_arguments*size. */
17806 if (size == 5)
17807 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
17808 gen_rtx_PLUS
17809 (Pmode,
17810 gen_rtx_MULT (Pmode, operands[1],
17811 GEN_INT (4)),
17812 operands[1])));
17813 else if (size == 4)
17814 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
17815 gen_rtx_MULT (Pmode, operands[1],
17816 GEN_INT (4))));
17817 else
17818 gcc_unreachable ();
17819 if (INTVAL (operands[2]))
17820 emit_move_insn
17821 (operands[1],
17822 gen_rtx_CONST (DImode,
17823 gen_rtx_PLUS (DImode,
17824 operands[3],
17825 GEN_INT (INTVAL (operands[2])
17826 * size))));
17827 else
17828 emit_move_insn (operands[1], operands[3]);
17829 emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
17830 operands[5] = GEN_INT (size);
17831 })
17832
17833 (define_insn "sse_prologue_save_insn"
17834 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
17835 (match_operand:DI 4 "const_int_operand" "n")))
17836 (unspec:BLK [(reg:DI XMM0_REG)
17837 (reg:DI XMM1_REG)
17838 (reg:DI XMM2_REG)
17839 (reg:DI XMM3_REG)
17840 (reg:DI XMM4_REG)
17841 (reg:DI XMM5_REG)
17842 (reg:DI XMM6_REG)
17843 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
17844 (use (match_operand:DI 1 "register_operand" "r"))
17845 (use (match_operand:DI 2 "const_int_operand" "i"))
17846 (use (label_ref:DI (match_operand 3 "" "X")))
17847 (use (match_operand:DI 5 "const_int_operand" "i"))]
17848 "TARGET_64BIT
17849 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
17850 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
17851 {
17852 int i;
17853 operands[0] = gen_rtx_MEM (Pmode,
17854 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
17855 /* VEX instruction with a REX prefix will #UD. */
17856 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
17857 gcc_unreachable ();
17858
17859 output_asm_insn ("jmp\t%A1", operands);
17860 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
17861 {
17862 operands[4] = adjust_address (operands[0], DImode, i*16);
17863 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
17864 PUT_MODE (operands[4], TImode);
17865 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
17866 output_asm_insn ("rex", operands);
17867 if (crtl->stack_alignment_needed < 128)
17868 output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
17869 else
17870 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
17871 }
17872 (*targetm.asm_out.internal_label) (asm_out_file, "L",
17873 CODE_LABEL_NUMBER (operands[3]));
17874 return "";
17875 }
17876 [(set_attr "type" "other")
17877 (set_attr "length_immediate" "0")
17878 (set_attr "length_address" "0")
17879 ;; 2 bytes for jump and opernds[4] bytes for each save.
17880 (set (attr "length")
17881 (plus (const_int 2)
17882 (mult (symbol_ref ("INTVAL (operands[5])"))
17883 (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
17884 (set_attr "memory" "store")
17885 (set_attr "modrm" "0")
17886 (set_attr "prefix" "maybe_vex")
17887 (set_attr "mode" "DI")])
17888
17889 (define_expand "prefetch"
17890 [(prefetch (match_operand 0 "address_operand" "")
17891 (match_operand:SI 1 "const_int_operand" "")
17892 (match_operand:SI 2 "const_int_operand" ""))]
17893 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17894 {
17895 int rw = INTVAL (operands[1]);
17896 int locality = INTVAL (operands[2]);
17897
17898 gcc_assert (rw == 0 || rw == 1);
17899 gcc_assert (locality >= 0 && locality <= 3);
17900 gcc_assert (GET_MODE (operands[0]) == Pmode
17901 || GET_MODE (operands[0]) == VOIDmode);
17902
17903 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17904 supported by SSE counterpart or the SSE prefetch is not available
17905 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17906 of locality. */
17907 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17908 operands[2] = GEN_INT (3);
17909 else
17910 operands[1] = const0_rtx;
17911 })
17912
17913 (define_insn "*prefetch_sse_<mode>"
17914 [(prefetch (match_operand:P 0 "address_operand" "p")
17915 (const_int 0)
17916 (match_operand:SI 1 "const_int_operand" ""))]
17917 "TARGET_PREFETCH_SSE"
17918 {
17919 static const char * const patterns[4] = {
17920 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17921 };
17922
17923 int locality = INTVAL (operands[1]);
17924 gcc_assert (locality >= 0 && locality <= 3);
17925
17926 return patterns[locality];
17927 }
17928 [(set_attr "type" "sse")
17929 (set_attr "atom_sse_attr" "prefetch")
17930 (set (attr "length_address")
17931 (symbol_ref "memory_address_length (operands[0])"))
17932 (set_attr "memory" "none")])
17933
17934 (define_insn "*prefetch_3dnow_<mode>"
17935 [(prefetch (match_operand:P 0 "address_operand" "p")
17936 (match_operand:SI 1 "const_int_operand" "n")
17937 (const_int 3))]
17938 "TARGET_3DNOW"
17939 {
17940 if (INTVAL (operands[1]) == 0)
17941 return "prefetch\t%a0";
17942 else
17943 return "prefetchw\t%a0";
17944 }
17945 [(set_attr "type" "mmx")
17946 (set (attr "length_address")
17947 (symbol_ref "memory_address_length (operands[0])"))
17948 (set_attr "memory" "none")])
17949
17950 (define_expand "stack_protect_set"
17951 [(match_operand 0 "memory_operand" "")
17952 (match_operand 1 "memory_operand" "")]
17953 ""
17954 {
17955 #ifdef TARGET_THREAD_SSP_OFFSET
17956 if (TARGET_64BIT)
17957 emit_insn (gen_stack_tls_protect_set_di (operands[0],
17958 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17959 else
17960 emit_insn (gen_stack_tls_protect_set_si (operands[0],
17961 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17962 #else
17963 if (TARGET_64BIT)
17964 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17965 else
17966 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17967 #endif
17968 DONE;
17969 })
17970
17971 (define_insn "stack_protect_set_si"
17972 [(set (match_operand:SI 0 "memory_operand" "=m")
17973 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17974 (set (match_scratch:SI 2 "=&r") (const_int 0))
17975 (clobber (reg:CC FLAGS_REG))]
17976 ""
17977 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17978 [(set_attr "type" "multi")])
17979
17980 (define_insn "stack_protect_set_di"
17981 [(set (match_operand:DI 0 "memory_operand" "=m")
17982 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17983 (set (match_scratch:DI 2 "=&r") (const_int 0))
17984 (clobber (reg:CC FLAGS_REG))]
17985 "TARGET_64BIT"
17986 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17987 [(set_attr "type" "multi")])
17988
17989 (define_insn "stack_tls_protect_set_si"
17990 [(set (match_operand:SI 0 "memory_operand" "=m")
17991 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17992 UNSPEC_SP_TLS_SET))
17993 (set (match_scratch:SI 2 "=&r") (const_int 0))
17994 (clobber (reg:CC FLAGS_REG))]
17995 ""
17996 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17997 [(set_attr "type" "multi")])
17998
17999 (define_insn "stack_tls_protect_set_di"
18000 [(set (match_operand:DI 0 "memory_operand" "=m")
18001 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
18002 UNSPEC_SP_TLS_SET))
18003 (set (match_scratch:DI 2 "=&r") (const_int 0))
18004 (clobber (reg:CC FLAGS_REG))]
18005 "TARGET_64BIT"
18006 {
18007 /* The kernel uses a different segment register for performance reasons; a
18008 system call would not have to trash the userspace segment register,
18009 which would be expensive */
18010 if (ix86_cmodel != CM_KERNEL)
18011 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18012 else
18013 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18014 }
18015 [(set_attr "type" "multi")])
18016
18017 (define_expand "stack_protect_test"
18018 [(match_operand 0 "memory_operand" "")
18019 (match_operand 1 "memory_operand" "")
18020 (match_operand 2 "" "")]
18021 ""
18022 {
18023 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18024
18025 #ifdef TARGET_THREAD_SSP_OFFSET
18026 if (TARGET_64BIT)
18027 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18028 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18029 else
18030 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18031 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18032 #else
18033 if (TARGET_64BIT)
18034 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18035 else
18036 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18037 #endif
18038
18039 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18040 flags, const0_rtx, operands[2]));
18041 DONE;
18042 })
18043
18044 (define_insn "stack_protect_test_si"
18045 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18046 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18047 (match_operand:SI 2 "memory_operand" "m")]
18048 UNSPEC_SP_TEST))
18049 (clobber (match_scratch:SI 3 "=&r"))]
18050 ""
18051 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18052 [(set_attr "type" "multi")])
18053
18054 (define_insn "stack_protect_test_di"
18055 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18056 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18057 (match_operand:DI 2 "memory_operand" "m")]
18058 UNSPEC_SP_TEST))
18059 (clobber (match_scratch:DI 3 "=&r"))]
18060 "TARGET_64BIT"
18061 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18062 [(set_attr "type" "multi")])
18063
18064 (define_insn "stack_tls_protect_test_si"
18065 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18066 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18067 (match_operand:SI 2 "const_int_operand" "i")]
18068 UNSPEC_SP_TLS_TEST))
18069 (clobber (match_scratch:SI 3 "=r"))]
18070 ""
18071 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18072 [(set_attr "type" "multi")])
18073
18074 (define_insn "stack_tls_protect_test_di"
18075 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18076 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18077 (match_operand:DI 2 "const_int_operand" "i")]
18078 UNSPEC_SP_TLS_TEST))
18079 (clobber (match_scratch:DI 3 "=r"))]
18080 "TARGET_64BIT"
18081 {
18082 /* The kernel uses a different segment register for performance reasons; a
18083 system call would not have to trash the userspace segment register,
18084 which would be expensive */
18085 if (ix86_cmodel != CM_KERNEL)
18086 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18087 else
18088 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18089 }
18090 [(set_attr "type" "multi")])
18091
18092 (define_insn "sse4_2_crc32<mode>"
18093 [(set (match_operand:SI 0 "register_operand" "=r")
18094 (unspec:SI
18095 [(match_operand:SI 1 "register_operand" "0")
18096 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18097 UNSPEC_CRC32))]
18098 "TARGET_SSE4_2 || TARGET_CRC32"
18099 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18100 [(set_attr "type" "sselog1")
18101 (set_attr "prefix_rep" "1")
18102 (set_attr "prefix_extra" "1")
18103 (set (attr "prefix_data16")
18104 (if_then_else (match_operand:HI 2 "" "")
18105 (const_string "1")
18106 (const_string "*")))
18107 (set (attr "prefix_rex")
18108 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18109 (const_string "1")
18110 (const_string "*")))
18111 (set_attr "mode" "SI")])
18112
18113 (define_insn "sse4_2_crc32di"
18114 [(set (match_operand:DI 0 "register_operand" "=r")
18115 (unspec:DI
18116 [(match_operand:DI 1 "register_operand" "0")
18117 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18118 UNSPEC_CRC32))]
18119 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18120 "crc32{q}\t{%2, %0|%0, %2}"
18121 [(set_attr "type" "sselog1")
18122 (set_attr "prefix_rep" "1")
18123 (set_attr "prefix_extra" "1")
18124 (set_attr "mode" "DI")])
18125
18126 (define_expand "rdpmc"
18127 [(match_operand:DI 0 "register_operand" "")
18128 (match_operand:SI 1 "register_operand" "")]
18129 ""
18130 {
18131 rtx reg = gen_reg_rtx (DImode);
18132 rtx si;
18133
18134 /* Force operand 1 into ECX. */
18135 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18136 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18137 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18138 UNSPECV_RDPMC);
18139
18140 if (TARGET_64BIT)
18141 {
18142 rtvec vec = rtvec_alloc (2);
18143 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18144 rtx upper = gen_reg_rtx (DImode);
18145 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18146 gen_rtvec (1, const0_rtx),
18147 UNSPECV_RDPMC);
18148 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18149 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18150 emit_insn (load);
18151 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18152 NULL, 1, OPTAB_DIRECT);
18153 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18154 OPTAB_DIRECT);
18155 }
18156 else
18157 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18158 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18159 DONE;
18160 })
18161
18162 (define_insn "*rdpmc"
18163 [(set (match_operand:DI 0 "register_operand" "=A")
18164 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18165 UNSPECV_RDPMC))]
18166 "!TARGET_64BIT"
18167 "rdpmc"
18168 [(set_attr "type" "other")
18169 (set_attr "length" "2")])
18170
18171 (define_insn "*rdpmc_rex64"
18172 [(set (match_operand:DI 0 "register_operand" "=a")
18173 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18174 UNSPECV_RDPMC))
18175 (set (match_operand:DI 1 "register_operand" "=d")
18176 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18177 "TARGET_64BIT"
18178 "rdpmc"
18179 [(set_attr "type" "other")
18180 (set_attr "length" "2")])
18181
18182 (define_expand "rdtsc"
18183 [(set (match_operand:DI 0 "register_operand" "")
18184 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18185 ""
18186 {
18187 if (TARGET_64BIT)
18188 {
18189 rtvec vec = rtvec_alloc (2);
18190 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18191 rtx upper = gen_reg_rtx (DImode);
18192 rtx lower = gen_reg_rtx (DImode);
18193 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18194 gen_rtvec (1, const0_rtx),
18195 UNSPECV_RDTSC);
18196 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18197 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18198 emit_insn (load);
18199 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18200 NULL, 1, OPTAB_DIRECT);
18201 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18202 OPTAB_DIRECT);
18203 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18204 DONE;
18205 }
18206 })
18207
18208 (define_insn "*rdtsc"
18209 [(set (match_operand:DI 0 "register_operand" "=A")
18210 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18211 "!TARGET_64BIT"
18212 "rdtsc"
18213 [(set_attr "type" "other")
18214 (set_attr "length" "2")])
18215
18216 (define_insn "*rdtsc_rex64"
18217 [(set (match_operand:DI 0 "register_operand" "=a")
18218 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18219 (set (match_operand:DI 1 "register_operand" "=d")
18220 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18221 "TARGET_64BIT"
18222 "rdtsc"
18223 [(set_attr "type" "other")
18224 (set_attr "length" "2")])
18225
18226 (define_expand "rdtscp"
18227 [(match_operand:DI 0 "register_operand" "")
18228 (match_operand:SI 1 "memory_operand" "")]
18229 ""
18230 {
18231 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18232 gen_rtvec (1, const0_rtx),
18233 UNSPECV_RDTSCP);
18234 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18235 gen_rtvec (1, const0_rtx),
18236 UNSPECV_RDTSCP);
18237 rtx reg = gen_reg_rtx (DImode);
18238 rtx tmp = gen_reg_rtx (SImode);
18239
18240 if (TARGET_64BIT)
18241 {
18242 rtvec vec = rtvec_alloc (3);
18243 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18244 rtx upper = gen_reg_rtx (DImode);
18245 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18246 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18247 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18248 emit_insn (load);
18249 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18250 NULL, 1, OPTAB_DIRECT);
18251 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18252 OPTAB_DIRECT);
18253 }
18254 else
18255 {
18256 rtvec vec = rtvec_alloc (2);
18257 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18258 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18259 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18260 emit_insn (load);
18261 }
18262 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18263 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18264 DONE;
18265 })
18266
18267 (define_insn "*rdtscp"
18268 [(set (match_operand:DI 0 "register_operand" "=A")
18269 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18270 (set (match_operand:SI 1 "register_operand" "=c")
18271 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18272 "!TARGET_64BIT"
18273 "rdtscp"
18274 [(set_attr "type" "other")
18275 (set_attr "length" "3")])
18276
18277 (define_insn "*rdtscp_rex64"
18278 [(set (match_operand:DI 0 "register_operand" "=a")
18279 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18280 (set (match_operand:DI 1 "register_operand" "=d")
18281 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18282 (set (match_operand:SI 2 "register_operand" "=c")
18283 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18284 "TARGET_64BIT"
18285 "rdtscp"
18286 [(set_attr "type" "other")
18287 (set_attr "length" "3")])
18288
18289 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18290 ;;
18291 ;; LWP instructions
18292 ;;
18293 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18294
18295 (define_expand "lwp_llwpcb"
18296 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18297 UNSPECV_LLWP_INTRINSIC)]
18298 "TARGET_LWP"
18299 "")
18300
18301 (define_insn "*lwp_llwpcb<mode>1"
18302 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18303 UNSPECV_LLWP_INTRINSIC)]
18304 "TARGET_LWP"
18305 "llwpcb\t%0"
18306 [(set_attr "type" "lwp")
18307 (set_attr "mode" "<MODE>")
18308 (set_attr "length" "5")])
18309
18310 (define_expand "lwp_slwpcb"
18311 [(set (match_operand 0 "register_operand" "=r")
18312 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18313 "TARGET_LWP"
18314 {
18315 if (TARGET_64BIT)
18316 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18317 else
18318 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18319 DONE;
18320 })
18321
18322 (define_insn "lwp_slwpcb<mode>"
18323 [(set (match_operand:P 0 "register_operand" "=r")
18324 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18325 "TARGET_LWP"
18326 "slwpcb\t%0"
18327 [(set_attr "type" "lwp")
18328 (set_attr "mode" "<MODE>")
18329 (set_attr "length" "5")])
18330
18331 (define_expand "lwp_lwpval<mode>3"
18332 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18333 (match_operand:SI 2 "nonimmediate_operand" "rm")
18334 (match_operand:SI 3 "const_int_operand" "i")]
18335 UNSPECV_LWPVAL_INTRINSIC)]
18336 "TARGET_LWP"
18337 "/* Avoid unused variable warning. */
18338 (void) operand0;")
18339
18340 (define_insn "*lwp_lwpval<mode>3_1"
18341 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18342 (match_operand:SI 1 "nonimmediate_operand" "rm")
18343 (match_operand:SI 2 "const_int_operand" "i")]
18344 UNSPECV_LWPVAL_INTRINSIC)]
18345 "TARGET_LWP"
18346 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18347 [(set_attr "type" "lwp")
18348 (set_attr "mode" "<MODE>")
18349 (set (attr "length")
18350 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18351
18352 (define_expand "lwp_lwpins<mode>3"
18353 [(set (reg:CCC FLAGS_REG)
18354 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18355 (match_operand:SI 2 "nonimmediate_operand" "rm")
18356 (match_operand:SI 3 "const_int_operand" "i")]
18357 UNSPECV_LWPINS_INTRINSIC))
18358 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18359 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18360 "TARGET_LWP"
18361 "")
18362
18363 (define_insn "*lwp_lwpins<mode>3_1"
18364 [(set (reg:CCC FLAGS_REG)
18365 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18366 (match_operand:SI 1 "nonimmediate_operand" "rm")
18367 (match_operand:SI 2 "const_int_operand" "i")]
18368 UNSPECV_LWPINS_INTRINSIC))]
18369 "TARGET_LWP"
18370 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18371 [(set_attr "type" "lwp")
18372 (set_attr "mode" "<MODE>")
18373 (set (attr "length")
18374 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18375
18376 (include "mmx.md")
18377 (include "sse.md")
18378 (include "sync.md")