* ChangeLog: Fix whitespace.
[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, 2011, 2012
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 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; K -- print HLE lock prefix
62 ;; Y -- print condition for XOP pcom* instruction.
63 ;; + -- print a branch hint as 'cs' or 'ds' prefix
64 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
66 ;; @ -- print a segment register of thread base pointer load
67 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
68
69 (define_c_enum "unspec" [
70 ;; Relocation specifiers
71 UNSPEC_GOT
72 UNSPEC_GOTOFF
73 UNSPEC_GOTPCREL
74 UNSPEC_GOTTPOFF
75 UNSPEC_TPOFF
76 UNSPEC_NTPOFF
77 UNSPEC_DTPOFF
78 UNSPEC_GOTNTPOFF
79 UNSPEC_INDNTPOFF
80 UNSPEC_PLTOFF
81 UNSPEC_MACHOPIC_OFFSET
82 UNSPEC_PCREL
83
84 ;; Prologue support
85 UNSPEC_STACK_ALLOC
86 UNSPEC_SET_GOT
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_MS_TO_SYSV_CALL
112 UNSPEC_CALL_NEEDS_VZEROUPPER
113 UNSPEC_PAUSE
114 UNSPEC_LEA_ADDR
115 UNSPEC_XBEGIN_ABORT
116
117 ;; For SSE/MMX support:
118 UNSPEC_FIX_NOTRUNC
119 UNSPEC_MASKMOV
120 UNSPEC_MOVMSK
121 UNSPEC_RCP
122 UNSPEC_RSQRT
123 UNSPEC_PSADBW
124
125 ;; Generic math support
126 UNSPEC_COPYSIGN
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
129
130 ;; x87 Floating point
131 UNSPEC_SIN
132 UNSPEC_COS
133 UNSPEC_FPATAN
134 UNSPEC_FYL2X
135 UNSPEC_FYL2XP1
136 UNSPEC_FRNDINT
137 UNSPEC_FIST
138 UNSPEC_F2XM1
139 UNSPEC_TAN
140 UNSPEC_FXAM
141
142 ;; x87 Rounding
143 UNSPEC_FRNDINT_FLOOR
144 UNSPEC_FRNDINT_CEIL
145 UNSPEC_FRNDINT_TRUNC
146 UNSPEC_FRNDINT_MASK_PM
147 UNSPEC_FIST_FLOOR
148 UNSPEC_FIST_CEIL
149
150 ;; x87 Double output FP
151 UNSPEC_SINCOS_COS
152 UNSPEC_SINCOS_SIN
153 UNSPEC_XTRACT_FRACT
154 UNSPEC_XTRACT_EXP
155 UNSPEC_FSCALE_FRACT
156 UNSPEC_FSCALE_EXP
157 UNSPEC_FPREM_F
158 UNSPEC_FPREM_U
159 UNSPEC_FPREM1_F
160 UNSPEC_FPREM1_U
161
162 UNSPEC_C2_FLAG
163 UNSPEC_FXAM_MEM
164
165 ;; SSP patterns
166 UNSPEC_SP_SET
167 UNSPEC_SP_TEST
168 UNSPEC_SP_TLS_SET
169 UNSPEC_SP_TLS_TEST
170
171 ;; For ROUND support
172 UNSPEC_ROUND
173
174 ;; For CRC32 support
175 UNSPEC_CRC32
176
177 ;; For BMI support
178 UNSPEC_BEXTR
179
180 ;; For BMI2 support
181 UNSPEC_PDEP
182 UNSPEC_PEXT
183 ])
184
185 (define_c_enum "unspecv" [
186 UNSPECV_BLOCKAGE
187 UNSPECV_STACK_PROBE
188 UNSPECV_PROBE_STACK_RANGE
189 UNSPECV_ALIGN
190 UNSPECV_PROLOGUE_USE
191 UNSPECV_SPLIT_STACK_RETURN
192 UNSPECV_CLD
193 UNSPECV_NOPS
194 UNSPECV_RDTSC
195 UNSPECV_RDTSCP
196 UNSPECV_RDPMC
197 UNSPECV_LLWP_INTRINSIC
198 UNSPECV_SLWP_INTRINSIC
199 UNSPECV_LWPVAL_INTRINSIC
200 UNSPECV_LWPINS_INTRINSIC
201 UNSPECV_RDFSBASE
202 UNSPECV_RDGSBASE
203 UNSPECV_WRFSBASE
204 UNSPECV_WRGSBASE
205
206 ;; For RDRAND support
207 UNSPECV_RDRAND
208
209 ;; For RDSEED support
210 UNSPECV_RDSEED
211
212 ;; For RTM support
213 UNSPECV_XBEGIN
214 UNSPECV_XEND
215 UNSPECV_XABORT
216 UNSPECV_XTEST
217 ])
218
219 ;; Constants to represent rounding modes in the ROUND instruction
220 (define_constants
221 [(ROUND_FLOOR 0x1)
222 (ROUND_CEIL 0x2)
223 (ROUND_TRUNC 0x3)
224 (ROUND_MXCSR 0x4)
225 (ROUND_NO_EXC 0x8)
226 ])
227
228 ;; Constants to represent pcomtrue/pcomfalse variants
229 (define_constants
230 [(PCOM_FALSE 0)
231 (PCOM_TRUE 1)
232 (COM_FALSE_S 2)
233 (COM_FALSE_P 3)
234 (COM_TRUE_S 4)
235 (COM_TRUE_P 5)
236 ])
237
238 ;; Constants used in the XOP pperm instruction
239 (define_constants
240 [(PPERM_SRC 0x00) /* copy source */
241 (PPERM_INVERT 0x20) /* invert source */
242 (PPERM_REVERSE 0x40) /* bit reverse source */
243 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
244 (PPERM_ZERO 0x80) /* all 0's */
245 (PPERM_ONES 0xa0) /* all 1's */
246 (PPERM_SIGN 0xc0) /* propagate sign bit */
247 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
248 (PPERM_SRC1 0x00) /* use first source byte */
249 (PPERM_SRC2 0x10) /* use second source byte */
250 ])
251
252 ;; Registers by name.
253 (define_constants
254 [(AX_REG 0)
255 (DX_REG 1)
256 (CX_REG 2)
257 (BX_REG 3)
258 (SI_REG 4)
259 (DI_REG 5)
260 (BP_REG 6)
261 (SP_REG 7)
262 (ST0_REG 8)
263 (ST1_REG 9)
264 (ST2_REG 10)
265 (ST3_REG 11)
266 (ST4_REG 12)
267 (ST5_REG 13)
268 (ST6_REG 14)
269 (ST7_REG 15)
270 (FLAGS_REG 17)
271 (FPSR_REG 18)
272 (FPCR_REG 19)
273 (XMM0_REG 21)
274 (XMM1_REG 22)
275 (XMM2_REG 23)
276 (XMM3_REG 24)
277 (XMM4_REG 25)
278 (XMM5_REG 26)
279 (XMM6_REG 27)
280 (XMM7_REG 28)
281 (MM0_REG 29)
282 (MM1_REG 30)
283 (MM2_REG 31)
284 (MM3_REG 32)
285 (MM4_REG 33)
286 (MM5_REG 34)
287 (MM6_REG 35)
288 (MM7_REG 36)
289 (R8_REG 37)
290 (R9_REG 38)
291 (R10_REG 39)
292 (R11_REG 40)
293 (R12_REG 41)
294 (R13_REG 42)
295 (XMM8_REG 45)
296 (XMM9_REG 46)
297 (XMM10_REG 47)
298 (XMM11_REG 48)
299 (XMM12_REG 49)
300 (XMM13_REG 50)
301 (XMM14_REG 51)
302 (XMM15_REG 52)
303 ])
304
305 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
306 ;; from i386.c.
307
308 ;; In C guard expressions, put expressions which may be compile-time
309 ;; constants first. This allows for better optimization. For
310 ;; example, write "TARGET_64BIT && reload_completed", not
311 ;; "reload_completed && TARGET_64BIT".
312
313 \f
314 ;; Processor type.
315 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
316 atom,generic64,amdfam10,bdver1,bdver2,btver1,btver2"
317 (const (symbol_ref "ix86_schedule")))
318
319 ;; A basic instruction type. Refinements due to arguments to be
320 ;; provided in other attributes.
321 (define_attr "type"
322 "other,multi,
323 alu,alu1,negnot,imov,imovx,lea,
324 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
325 icmp,test,ibr,setcc,icmov,
326 push,pop,call,callv,leave,
327 str,bitmanip,
328 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
329 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
330 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
331 ssemuladd,sse4arg,lwp,
332 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
333 (const_string "other"))
334
335 ;; Main data type used by the insn
336 (define_attr "mode"
337 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
338 (const_string "unknown"))
339
340 ;; The CPU unit operations uses.
341 (define_attr "unit" "integer,i387,sse,mmx,unknown"
342 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
343 (const_string "i387")
344 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
345 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
346 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
347 (const_string "sse")
348 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
349 (const_string "mmx")
350 (eq_attr "type" "other")
351 (const_string "unknown")]
352 (const_string "integer")))
353
354 ;; The (bounding maximum) length of an instruction immediate.
355 (define_attr "length_immediate" ""
356 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
357 bitmanip,imulx")
358 (const_int 0)
359 (eq_attr "unit" "i387,sse,mmx")
360 (const_int 0)
361 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
362 rotate,rotatex,rotate1,imul,icmp,push,pop")
363 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
364 (eq_attr "type" "imov,test")
365 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
366 (eq_attr "type" "call")
367 (if_then_else (match_operand 0 "constant_call_address_operand")
368 (const_int 4)
369 (const_int 0))
370 (eq_attr "type" "callv")
371 (if_then_else (match_operand 1 "constant_call_address_operand")
372 (const_int 4)
373 (const_int 0))
374 ;; We don't know the size before shorten_branches. Expect
375 ;; the instruction to fit for better scheduling.
376 (eq_attr "type" "ibr")
377 (const_int 1)
378 ]
379 (symbol_ref "/* Update immediate_length and other attributes! */
380 gcc_unreachable (),1")))
381
382 ;; The (bounding maximum) length of an instruction address.
383 (define_attr "length_address" ""
384 (cond [(eq_attr "type" "str,other,multi,fxch")
385 (const_int 0)
386 (and (eq_attr "type" "call")
387 (match_operand 0 "constant_call_address_operand"))
388 (const_int 0)
389 (and (eq_attr "type" "callv")
390 (match_operand 1 "constant_call_address_operand"))
391 (const_int 0)
392 ]
393 (symbol_ref "ix86_attr_length_address_default (insn)")))
394
395 ;; Set when length prefix is used.
396 (define_attr "prefix_data16" ""
397 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
398 (const_int 0)
399 (eq_attr "mode" "HI")
400 (const_int 1)
401 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
402 (const_int 1)
403 ]
404 (const_int 0)))
405
406 ;; Set when string REP prefix is used.
407 (define_attr "prefix_rep" ""
408 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
409 (const_int 0)
410 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
411 (const_int 1)
412 ]
413 (const_int 0)))
414
415 ;; Set when 0f opcode prefix is used.
416 (define_attr "prefix_0f" ""
417 (if_then_else
418 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
419 (eq_attr "unit" "sse,mmx"))
420 (const_int 1)
421 (const_int 0)))
422
423 ;; Set when REX opcode prefix is used.
424 (define_attr "prefix_rex" ""
425 (cond [(not (match_test "TARGET_64BIT"))
426 (const_int 0)
427 (and (eq_attr "mode" "DI")
428 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
429 (eq_attr "unit" "!mmx")))
430 (const_int 1)
431 (and (eq_attr "mode" "QI")
432 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
433 (const_int 1)
434 (match_test "x86_extended_reg_mentioned_p (insn)")
435 (const_int 1)
436 (and (eq_attr "type" "imovx")
437 (match_operand:QI 1 "ext_QIreg_operand"))
438 (const_int 1)
439 ]
440 (const_int 0)))
441
442 ;; There are also additional prefixes in 3DNOW, SSSE3.
443 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
444 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
445 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
446 (define_attr "prefix_extra" ""
447 (cond [(eq_attr "type" "ssemuladd,sse4arg")
448 (const_int 2)
449 (eq_attr "type" "sseiadd1,ssecvt1")
450 (const_int 1)
451 ]
452 (const_int 0)))
453
454 ;; Prefix used: original, VEX or maybe VEX.
455 (define_attr "prefix" "orig,vex,maybe_vex"
456 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
457 (const_string "vex")
458 (const_string "orig")))
459
460 ;; VEX W bit is used.
461 (define_attr "prefix_vex_w" "" (const_int 0))
462
463 ;; The length of VEX prefix
464 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
465 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
466 ;; still prefix_0f 1, with prefix_extra 1.
467 (define_attr "length_vex" ""
468 (if_then_else (and (eq_attr "prefix_0f" "1")
469 (eq_attr "prefix_extra" "0"))
470 (if_then_else (eq_attr "prefix_vex_w" "1")
471 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
472 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
473 (if_then_else (eq_attr "prefix_vex_w" "1")
474 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
475 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
476
477 ;; Set when modrm byte is used.
478 (define_attr "modrm" ""
479 (cond [(eq_attr "type" "str,leave")
480 (const_int 0)
481 (eq_attr "unit" "i387")
482 (const_int 0)
483 (and (eq_attr "type" "incdec")
484 (and (not (match_test "TARGET_64BIT"))
485 (ior (match_operand:SI 1 "register_operand")
486 (match_operand:HI 1 "register_operand"))))
487 (const_int 0)
488 (and (eq_attr "type" "push")
489 (not (match_operand 1 "memory_operand")))
490 (const_int 0)
491 (and (eq_attr "type" "pop")
492 (not (match_operand 0 "memory_operand")))
493 (const_int 0)
494 (and (eq_attr "type" "imov")
495 (and (not (eq_attr "mode" "DI"))
496 (ior (and (match_operand 0 "register_operand")
497 (match_operand 1 "immediate_operand"))
498 (ior (and (match_operand 0 "ax_reg_operand")
499 (match_operand 1 "memory_displacement_only_operand"))
500 (and (match_operand 0 "memory_displacement_only_operand")
501 (match_operand 1 "ax_reg_operand"))))))
502 (const_int 0)
503 (and (eq_attr "type" "call")
504 (match_operand 0 "constant_call_address_operand"))
505 (const_int 0)
506 (and (eq_attr "type" "callv")
507 (match_operand 1 "constant_call_address_operand"))
508 (const_int 0)
509 (and (eq_attr "type" "alu,alu1,icmp,test")
510 (match_operand 0 "ax_reg_operand"))
511 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
512 ]
513 (const_int 1)))
514
515 ;; The (bounding maximum) length of an instruction in bytes.
516 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
517 ;; Later we may want to split them and compute proper length as for
518 ;; other insns.
519 (define_attr "length" ""
520 (cond [(eq_attr "type" "other,multi,fistp,frndint")
521 (const_int 16)
522 (eq_attr "type" "fcmp")
523 (const_int 4)
524 (eq_attr "unit" "i387")
525 (plus (const_int 2)
526 (plus (attr "prefix_data16")
527 (attr "length_address")))
528 (ior (eq_attr "prefix" "vex")
529 (and (eq_attr "prefix" "maybe_vex")
530 (match_test "TARGET_AVX")))
531 (plus (attr "length_vex")
532 (plus (attr "length_immediate")
533 (plus (attr "modrm")
534 (attr "length_address"))))]
535 (plus (plus (attr "modrm")
536 (plus (attr "prefix_0f")
537 (plus (attr "prefix_rex")
538 (plus (attr "prefix_extra")
539 (const_int 1)))))
540 (plus (attr "prefix_rep")
541 (plus (attr "prefix_data16")
542 (plus (attr "length_immediate")
543 (attr "length_address")))))))
544
545 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
546 ;; `store' if there is a simple memory reference therein, or `unknown'
547 ;; if the instruction is complex.
548
549 (define_attr "memory" "none,load,store,both,unknown"
550 (cond [(eq_attr "type" "other,multi,str,lwp")
551 (const_string "unknown")
552 (eq_attr "type" "lea,fcmov,fpspc")
553 (const_string "none")
554 (eq_attr "type" "fistp,leave")
555 (const_string "both")
556 (eq_attr "type" "frndint")
557 (const_string "load")
558 (eq_attr "type" "push")
559 (if_then_else (match_operand 1 "memory_operand")
560 (const_string "both")
561 (const_string "store"))
562 (eq_attr "type" "pop")
563 (if_then_else (match_operand 0 "memory_operand")
564 (const_string "both")
565 (const_string "load"))
566 (eq_attr "type" "setcc")
567 (if_then_else (match_operand 0 "memory_operand")
568 (const_string "store")
569 (const_string "none"))
570 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
571 (if_then_else (ior (match_operand 0 "memory_operand")
572 (match_operand 1 "memory_operand"))
573 (const_string "load")
574 (const_string "none"))
575 (eq_attr "type" "ibr")
576 (if_then_else (match_operand 0 "memory_operand")
577 (const_string "load")
578 (const_string "none"))
579 (eq_attr "type" "call")
580 (if_then_else (match_operand 0 "constant_call_address_operand")
581 (const_string "none")
582 (const_string "load"))
583 (eq_attr "type" "callv")
584 (if_then_else (match_operand 1 "constant_call_address_operand")
585 (const_string "none")
586 (const_string "load"))
587 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
588 (match_operand 1 "memory_operand"))
589 (const_string "both")
590 (and (match_operand 0 "memory_operand")
591 (match_operand 1 "memory_operand"))
592 (const_string "both")
593 (match_operand 0 "memory_operand")
594 (const_string "store")
595 (match_operand 1 "memory_operand")
596 (const_string "load")
597 (and (eq_attr "type"
598 "!alu1,negnot,ishift1,
599 imov,imovx,icmp,test,bitmanip,
600 fmov,fcmp,fsgn,
601 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
602 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
603 (match_operand 2 "memory_operand"))
604 (const_string "load")
605 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
606 (match_operand 3 "memory_operand"))
607 (const_string "load")
608 ]
609 (const_string "none")))
610
611 ;; Indicates if an instruction has both an immediate and a displacement.
612
613 (define_attr "imm_disp" "false,true,unknown"
614 (cond [(eq_attr "type" "other,multi")
615 (const_string "unknown")
616 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
617 (and (match_operand 0 "memory_displacement_operand")
618 (match_operand 1 "immediate_operand")))
619 (const_string "true")
620 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
621 (and (match_operand 0 "memory_displacement_operand")
622 (match_operand 2 "immediate_operand")))
623 (const_string "true")
624 ]
625 (const_string "false")))
626
627 ;; Indicates if an FP operation has an integer source.
628
629 (define_attr "fp_int_src" "false,true"
630 (const_string "false"))
631
632 ;; Defines rounding mode of an FP operation.
633
634 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
635 (const_string "any"))
636
637 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
638 (define_attr "use_carry" "0,1" (const_string "0"))
639
640 ;; Define attribute to indicate unaligned ssemov insns
641 (define_attr "movu" "0,1" (const_string "0"))
642
643 ;; Used to control the "enabled" attribute on a per-instruction basis.
644 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
645 avx2,noavx2,bmi2,fma,fma4"
646 (const_string "base"))
647
648 (define_attr "enabled" ""
649 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
650 (eq_attr "isa" "sse2_noavx")
651 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
652 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
653 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
654 (eq_attr "isa" "sse4_noavx")
655 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
656 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
657 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
658 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
659 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
660 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
661 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
662 ;; Disable generation of FMA4 instructions for generic code
663 ;; since FMA3 is preferred for targets that implement both
664 ;; instruction sets.
665 (eq_attr "isa" "fma4")
666 (symbol_ref "TARGET_FMA4 && !TARGET_FMA")
667 ]
668 (const_int 1)))
669
670 ;; Describe a user's asm statement.
671 (define_asm_attributes
672 [(set_attr "length" "128")
673 (set_attr "type" "multi")])
674
675 (define_code_iterator plusminus [plus minus])
676
677 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
678
679 ;; Base name for define_insn
680 (define_code_attr plusminus_insn
681 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
682 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
683
684 ;; Base name for insn mnemonic.
685 (define_code_attr plusminus_mnemonic
686 [(plus "add") (ss_plus "adds") (us_plus "addus")
687 (minus "sub") (ss_minus "subs") (us_minus "subus")])
688 (define_code_attr plusminus_carry_mnemonic
689 [(plus "adc") (minus "sbb")])
690
691 ;; Mark commutative operators as such in constraints.
692 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
693 (minus "") (ss_minus "") (us_minus "")])
694
695 ;; Mapping of max and min
696 (define_code_iterator maxmin [smax smin umax umin])
697
698 ;; Mapping of signed max and min
699 (define_code_iterator smaxmin [smax smin])
700
701 ;; Mapping of unsigned max and min
702 (define_code_iterator umaxmin [umax umin])
703
704 ;; Base name for integer and FP insn mnemonic
705 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
706 (umax "maxu") (umin "minu")])
707 (define_code_attr maxmin_float [(smax "max") (smin "min")])
708
709 ;; Mapping of logic operators
710 (define_code_iterator any_logic [and ior xor])
711 (define_code_iterator any_or [ior xor])
712
713 ;; Base name for insn mnemonic.
714 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
715
716 ;; Mapping of logic-shift operators
717 (define_code_iterator any_lshift [ashift lshiftrt])
718
719 ;; Mapping of shift-right operators
720 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
721
722 ;; Mapping of all shift operators
723 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
724
725 ;; Base name for define_insn
726 (define_code_attr shift_insn
727 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
728
729 ;; Base name for insn mnemonic.
730 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
731 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
732
733 ;; Mapping of rotate operators
734 (define_code_iterator any_rotate [rotate rotatert])
735
736 ;; Base name for define_insn
737 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
738
739 ;; Base name for insn mnemonic.
740 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
741
742 ;; Mapping of abs neg operators
743 (define_code_iterator absneg [abs neg])
744
745 ;; Base name for x87 insn mnemonic.
746 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
747
748 ;; Used in signed and unsigned widening multiplications.
749 (define_code_iterator any_extend [sign_extend zero_extend])
750
751 ;; Prefix for insn menmonic.
752 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
753
754 ;; Prefix for define_insn
755 (define_code_attr u [(sign_extend "") (zero_extend "u")])
756 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
757 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
758
759 ;; All integer modes.
760 (define_mode_iterator SWI1248x [QI HI SI DI])
761
762 ;; All integer modes without QImode.
763 (define_mode_iterator SWI248x [HI SI DI])
764
765 ;; All integer modes without QImode and HImode.
766 (define_mode_iterator SWI48x [SI DI])
767
768 ;; All integer modes without SImode and DImode.
769 (define_mode_iterator SWI12 [QI HI])
770
771 ;; All integer modes without DImode.
772 (define_mode_iterator SWI124 [QI HI SI])
773
774 ;; All integer modes without QImode and DImode.
775 (define_mode_iterator SWI24 [HI SI])
776
777 ;; Single word integer modes.
778 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
779
780 ;; Single word integer modes without QImode.
781 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
782
783 ;; Single word integer modes without QImode and HImode.
784 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
785
786 ;; All math-dependant single and double word integer modes.
787 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
788 (HI "TARGET_HIMODE_MATH")
789 SI DI (TI "TARGET_64BIT")])
790
791 ;; Math-dependant single word integer modes.
792 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
793 (HI "TARGET_HIMODE_MATH")
794 SI (DI "TARGET_64BIT")])
795
796 ;; Math-dependant integer modes without DImode.
797 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
798 (HI "TARGET_HIMODE_MATH")
799 SI])
800
801 ;; Math-dependant single word integer modes without QImode.
802 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
803 SI (DI "TARGET_64BIT")])
804
805 ;; Double word integer modes.
806 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
807 (TI "TARGET_64BIT")])
808
809 ;; Double word integer modes as mode attribute.
810 (define_mode_attr DWI [(SI "DI") (DI "TI")])
811 (define_mode_attr dwi [(SI "di") (DI "ti")])
812
813 ;; Half mode for double word integer modes.
814 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
815 (DI "TARGET_64BIT")])
816
817 ;; Instruction suffix for integer modes.
818 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
819
820 ;; Pointer size prefix for integer modes (Intel asm dialect)
821 (define_mode_attr iptrsize [(QI "BYTE")
822 (HI "WORD")
823 (SI "DWORD")
824 (DI "QWORD")])
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 "e") (DI "e")])
831
832 ;; General operand constraint for word modes.
833 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
834
835 ;; Immediate operand constraint for double integer modes.
836 (define_mode_attr di [(SI "nF") (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 "x86_64_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 "x86_64_szext_general_operand")
854 (DI "x86_64_szext_general_operand")])
855
856 ;; Immediate operand predicate for integer modes.
857 (define_mode_attr immediate_operand
858 [(QI "immediate_operand")
859 (HI "immediate_operand")
860 (SI "x86_64_immediate_operand")
861 (DI "x86_64_immediate_operand")])
862
863 ;; Nonmemory operand predicate for integer modes.
864 (define_mode_attr nonmemory_operand
865 [(QI "nonmemory_operand")
866 (HI "nonmemory_operand")
867 (SI "x86_64_nonmemory_operand")
868 (DI "x86_64_nonmemory_operand")])
869
870 ;; Operand predicate for shifts.
871 (define_mode_attr shift_operand
872 [(QI "nonimmediate_operand")
873 (HI "nonimmediate_operand")
874 (SI "nonimmediate_operand")
875 (DI "shiftdi_operand")
876 (TI "register_operand")])
877
878 ;; Operand predicate for shift argument.
879 (define_mode_attr shift_immediate_operand
880 [(QI "const_1_to_31_operand")
881 (HI "const_1_to_31_operand")
882 (SI "const_1_to_31_operand")
883 (DI "const_1_to_63_operand")])
884
885 ;; Input operand predicate for arithmetic left shifts.
886 (define_mode_attr ashl_input_operand
887 [(QI "nonimmediate_operand")
888 (HI "nonimmediate_operand")
889 (SI "nonimmediate_operand")
890 (DI "ashldi_input_operand")
891 (TI "reg_or_pm1_operand")])
892
893 ;; SSE and x87 SFmode and DFmode floating point modes
894 (define_mode_iterator MODEF [SF DF])
895
896 ;; All x87 floating point modes
897 (define_mode_iterator X87MODEF [SF DF XF])
898
899 ;; SSE instruction suffix for various modes
900 (define_mode_attr ssemodesuffix
901 [(SF "ss") (DF "sd")
902 (V8SF "ps") (V4DF "pd")
903 (V4SF "ps") (V2DF "pd")
904 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
905 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
906
907 ;; SSE vector suffix for floating point modes
908 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
909
910 ;; SSE vector mode corresponding to a scalar mode
911 (define_mode_attr ssevecmode
912 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
913
914 ;; Instruction suffix for REX 64bit operators.
915 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
916
917 ;; This mode iterator allows :P to be used for patterns that operate on
918 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
919 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
920
921 ;; This mode iterator allows :W to be used for patterns that operate on
922 ;; word_mode sized quantities.
923 (define_mode_iterator W
924 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
925
926 ;; This mode iterator allows :PTR to be used for patterns that operate on
927 ;; ptr_mode sized quantities.
928 (define_mode_iterator PTR
929 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
930 \f
931 ;; Scheduling descriptions
932
933 (include "pentium.md")
934 (include "ppro.md")
935 (include "k6.md")
936 (include "athlon.md")
937 (include "bdver1.md")
938 (include "geode.md")
939 (include "atom.md")
940 (include "core2.md")
941
942 \f
943 ;; Operand and operator predicates and constraints
944
945 (include "predicates.md")
946 (include "constraints.md")
947
948 \f
949 ;; Compare and branch/compare and store instructions.
950
951 (define_expand "cbranch<mode>4"
952 [(set (reg:CC FLAGS_REG)
953 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
954 (match_operand:SDWIM 2 "<general_operand>")))
955 (set (pc) (if_then_else
956 (match_operator 0 "ordered_comparison_operator"
957 [(reg:CC FLAGS_REG) (const_int 0)])
958 (label_ref (match_operand 3))
959 (pc)))]
960 ""
961 {
962 if (MEM_P (operands[1]) && MEM_P (operands[2]))
963 operands[1] = force_reg (<MODE>mode, operands[1]);
964 ix86_expand_branch (GET_CODE (operands[0]),
965 operands[1], operands[2], operands[3]);
966 DONE;
967 })
968
969 (define_expand "cstore<mode>4"
970 [(set (reg:CC FLAGS_REG)
971 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
972 (match_operand:SWIM 3 "<general_operand>")))
973 (set (match_operand:QI 0 "register_operand")
974 (match_operator 1 "ordered_comparison_operator"
975 [(reg:CC FLAGS_REG) (const_int 0)]))]
976 ""
977 {
978 if (MEM_P (operands[2]) && MEM_P (operands[3]))
979 operands[2] = force_reg (<MODE>mode, operands[2]);
980 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
981 operands[2], operands[3]);
982 DONE;
983 })
984
985 (define_expand "cmp<mode>_1"
986 [(set (reg:CC FLAGS_REG)
987 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
988 (match_operand:SWI48 1 "<general_operand>")))])
989
990 (define_insn "*cmp<mode>_ccno_1"
991 [(set (reg FLAGS_REG)
992 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
993 (match_operand:SWI 1 "const0_operand")))]
994 "ix86_match_ccmode (insn, CCNOmode)"
995 "@
996 test{<imodesuffix>}\t%0, %0
997 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "test,icmp")
999 (set_attr "length_immediate" "0,1")
1000 (set_attr "mode" "<MODE>")])
1001
1002 (define_insn "*cmp<mode>_1"
1003 [(set (reg FLAGS_REG)
1004 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1005 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1006 "ix86_match_ccmode (insn, CCmode)"
1007 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008 [(set_attr "type" "icmp")
1009 (set_attr "mode" "<MODE>")])
1010
1011 (define_insn "*cmp<mode>_minus_1"
1012 [(set (reg FLAGS_REG)
1013 (compare
1014 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1015 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1016 (const_int 0)))]
1017 "ix86_match_ccmode (insn, CCGOCmode)"
1018 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1019 [(set_attr "type" "icmp")
1020 (set_attr "mode" "<MODE>")])
1021
1022 (define_insn "*cmpqi_ext_1"
1023 [(set (reg FLAGS_REG)
1024 (compare
1025 (match_operand:QI 0 "general_operand" "Qm")
1026 (subreg:QI
1027 (zero_extract:SI
1028 (match_operand 1 "ext_register_operand" "Q")
1029 (const_int 8)
1030 (const_int 8)) 0)))]
1031 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1032 "cmp{b}\t{%h1, %0|%0, %h1}"
1033 [(set_attr "type" "icmp")
1034 (set_attr "mode" "QI")])
1035
1036 (define_insn "*cmpqi_ext_1_rex64"
1037 [(set (reg FLAGS_REG)
1038 (compare
1039 (match_operand:QI 0 "register_operand" "Q")
1040 (subreg:QI
1041 (zero_extract:SI
1042 (match_operand 1 "ext_register_operand" "Q")
1043 (const_int 8)
1044 (const_int 8)) 0)))]
1045 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1046 "cmp{b}\t{%h1, %0|%0, %h1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "QI")])
1049
1050 (define_insn "*cmpqi_ext_2"
1051 [(set (reg FLAGS_REG)
1052 (compare
1053 (subreg:QI
1054 (zero_extract:SI
1055 (match_operand 0 "ext_register_operand" "Q")
1056 (const_int 8)
1057 (const_int 8)) 0)
1058 (match_operand:QI 1 "const0_operand")))]
1059 "ix86_match_ccmode (insn, CCNOmode)"
1060 "test{b}\t%h0, %h0"
1061 [(set_attr "type" "test")
1062 (set_attr "length_immediate" "0")
1063 (set_attr "mode" "QI")])
1064
1065 (define_expand "cmpqi_ext_3"
1066 [(set (reg:CC FLAGS_REG)
1067 (compare:CC
1068 (subreg:QI
1069 (zero_extract:SI
1070 (match_operand 0 "ext_register_operand")
1071 (const_int 8)
1072 (const_int 8)) 0)
1073 (match_operand:QI 1 "immediate_operand")))])
1074
1075 (define_insn "*cmpqi_ext_3_insn"
1076 [(set (reg FLAGS_REG)
1077 (compare
1078 (subreg:QI
1079 (zero_extract:SI
1080 (match_operand 0 "ext_register_operand" "Q")
1081 (const_int 8)
1082 (const_int 8)) 0)
1083 (match_operand:QI 1 "general_operand" "Qmn")))]
1084 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1085 "cmp{b}\t{%1, %h0|%h0, %1}"
1086 [(set_attr "type" "icmp")
1087 (set_attr "modrm" "1")
1088 (set_attr "mode" "QI")])
1089
1090 (define_insn "*cmpqi_ext_3_insn_rex64"
1091 [(set (reg FLAGS_REG)
1092 (compare
1093 (subreg:QI
1094 (zero_extract:SI
1095 (match_operand 0 "ext_register_operand" "Q")
1096 (const_int 8)
1097 (const_int 8)) 0)
1098 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1099 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1100 "cmp{b}\t{%1, %h0|%h0, %1}"
1101 [(set_attr "type" "icmp")
1102 (set_attr "modrm" "1")
1103 (set_attr "mode" "QI")])
1104
1105 (define_insn "*cmpqi_ext_4"
1106 [(set (reg FLAGS_REG)
1107 (compare
1108 (subreg:QI
1109 (zero_extract:SI
1110 (match_operand 0 "ext_register_operand" "Q")
1111 (const_int 8)
1112 (const_int 8)) 0)
1113 (subreg:QI
1114 (zero_extract:SI
1115 (match_operand 1 "ext_register_operand" "Q")
1116 (const_int 8)
1117 (const_int 8)) 0)))]
1118 "ix86_match_ccmode (insn, CCmode)"
1119 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1120 [(set_attr "type" "icmp")
1121 (set_attr "mode" "QI")])
1122
1123 ;; These implement float point compares.
1124 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1125 ;; which would allow mix and match FP modes on the compares. Which is what
1126 ;; the old patterns did, but with many more of them.
1127
1128 (define_expand "cbranchxf4"
1129 [(set (reg:CC FLAGS_REG)
1130 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1131 (match_operand:XF 2 "nonmemory_operand")))
1132 (set (pc) (if_then_else
1133 (match_operator 0 "ix86_fp_comparison_operator"
1134 [(reg:CC FLAGS_REG)
1135 (const_int 0)])
1136 (label_ref (match_operand 3))
1137 (pc)))]
1138 "TARGET_80387"
1139 {
1140 ix86_expand_branch (GET_CODE (operands[0]),
1141 operands[1], operands[2], operands[3]);
1142 DONE;
1143 })
1144
1145 (define_expand "cstorexf4"
1146 [(set (reg:CC FLAGS_REG)
1147 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1148 (match_operand:XF 3 "nonmemory_operand")))
1149 (set (match_operand:QI 0 "register_operand")
1150 (match_operator 1 "ix86_fp_comparison_operator"
1151 [(reg:CC FLAGS_REG)
1152 (const_int 0)]))]
1153 "TARGET_80387"
1154 {
1155 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1156 operands[2], operands[3]);
1157 DONE;
1158 })
1159
1160 (define_expand "cbranch<mode>4"
1161 [(set (reg:CC FLAGS_REG)
1162 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1163 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1164 (set (pc) (if_then_else
1165 (match_operator 0 "ix86_fp_comparison_operator"
1166 [(reg:CC FLAGS_REG)
1167 (const_int 0)])
1168 (label_ref (match_operand 3))
1169 (pc)))]
1170 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1171 {
1172 ix86_expand_branch (GET_CODE (operands[0]),
1173 operands[1], operands[2], operands[3]);
1174 DONE;
1175 })
1176
1177 (define_expand "cstore<mode>4"
1178 [(set (reg:CC FLAGS_REG)
1179 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1180 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1181 (set (match_operand:QI 0 "register_operand")
1182 (match_operator 1 "ix86_fp_comparison_operator"
1183 [(reg:CC FLAGS_REG)
1184 (const_int 0)]))]
1185 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1186 {
1187 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1188 operands[2], operands[3]);
1189 DONE;
1190 })
1191
1192 (define_expand "cbranchcc4"
1193 [(set (pc) (if_then_else
1194 (match_operator 0 "comparison_operator"
1195 [(match_operand 1 "flags_reg_operand")
1196 (match_operand 2 "const0_operand")])
1197 (label_ref (match_operand 3))
1198 (pc)))]
1199 ""
1200 {
1201 ix86_expand_branch (GET_CODE (operands[0]),
1202 operands[1], operands[2], operands[3]);
1203 DONE;
1204 })
1205
1206 (define_expand "cstorecc4"
1207 [(set (match_operand:QI 0 "register_operand")
1208 (match_operator 1 "comparison_operator"
1209 [(match_operand 2 "flags_reg_operand")
1210 (match_operand 3 "const0_operand")]))]
1211 ""
1212 {
1213 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1214 operands[2], operands[3]);
1215 DONE;
1216 })
1217
1218
1219 ;; FP compares, step 1:
1220 ;; Set the FP condition codes.
1221 ;;
1222 ;; CCFPmode compare with exceptions
1223 ;; CCFPUmode compare with no exceptions
1224
1225 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1226 ;; used to manage the reg stack popping would not be preserved.
1227
1228 (define_insn "*cmpfp_0"
1229 [(set (match_operand:HI 0 "register_operand" "=a")
1230 (unspec:HI
1231 [(compare:CCFP
1232 (match_operand 1 "register_operand" "f")
1233 (match_operand 2 "const0_operand"))]
1234 UNSPEC_FNSTSW))]
1235 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1236 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1237 "* return output_fp_compare (insn, operands, false, false);"
1238 [(set_attr "type" "multi")
1239 (set_attr "unit" "i387")
1240 (set (attr "mode")
1241 (cond [(match_operand:SF 1)
1242 (const_string "SF")
1243 (match_operand:DF 1)
1244 (const_string "DF")
1245 ]
1246 (const_string "XF")))])
1247
1248 (define_insn_and_split "*cmpfp_0_cc"
1249 [(set (reg:CCFP FLAGS_REG)
1250 (compare:CCFP
1251 (match_operand 1 "register_operand" "f")
1252 (match_operand 2 "const0_operand")))
1253 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1254 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1255 && TARGET_SAHF && !TARGET_CMOVE
1256 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1257 "#"
1258 "&& reload_completed"
1259 [(set (match_dup 0)
1260 (unspec:HI
1261 [(compare:CCFP (match_dup 1)(match_dup 2))]
1262 UNSPEC_FNSTSW))
1263 (set (reg:CC FLAGS_REG)
1264 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1265 ""
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1268 (set (attr "mode")
1269 (cond [(match_operand:SF 1)
1270 (const_string "SF")
1271 (match_operand:DF 1)
1272 (const_string "DF")
1273 ]
1274 (const_string "XF")))])
1275
1276 (define_insn "*cmpfp_xf"
1277 [(set (match_operand:HI 0 "register_operand" "=a")
1278 (unspec:HI
1279 [(compare:CCFP
1280 (match_operand:XF 1 "register_operand" "f")
1281 (match_operand:XF 2 "register_operand" "f"))]
1282 UNSPEC_FNSTSW))]
1283 "TARGET_80387"
1284 "* return output_fp_compare (insn, operands, false, false);"
1285 [(set_attr "type" "multi")
1286 (set_attr "unit" "i387")
1287 (set_attr "mode" "XF")])
1288
1289 (define_insn_and_split "*cmpfp_xf_cc"
1290 [(set (reg:CCFP FLAGS_REG)
1291 (compare:CCFP
1292 (match_operand:XF 1 "register_operand" "f")
1293 (match_operand:XF 2 "register_operand" "f")))
1294 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1295 "TARGET_80387
1296 && TARGET_SAHF && !TARGET_CMOVE"
1297 "#"
1298 "&& reload_completed"
1299 [(set (match_dup 0)
1300 (unspec:HI
1301 [(compare:CCFP (match_dup 1)(match_dup 2))]
1302 UNSPEC_FNSTSW))
1303 (set (reg:CC FLAGS_REG)
1304 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1305 ""
1306 [(set_attr "type" "multi")
1307 (set_attr "unit" "i387")
1308 (set_attr "mode" "XF")])
1309
1310 (define_insn "*cmpfp_<mode>"
1311 [(set (match_operand:HI 0 "register_operand" "=a")
1312 (unspec:HI
1313 [(compare:CCFP
1314 (match_operand:MODEF 1 "register_operand" "f")
1315 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1316 UNSPEC_FNSTSW))]
1317 "TARGET_80387"
1318 "* return output_fp_compare (insn, operands, false, false);"
1319 [(set_attr "type" "multi")
1320 (set_attr "unit" "i387")
1321 (set_attr "mode" "<MODE>")])
1322
1323 (define_insn_and_split "*cmpfp_<mode>_cc"
1324 [(set (reg:CCFP FLAGS_REG)
1325 (compare:CCFP
1326 (match_operand:MODEF 1 "register_operand" "f")
1327 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1328 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1329 "TARGET_80387
1330 && TARGET_SAHF && !TARGET_CMOVE"
1331 "#"
1332 "&& reload_completed"
1333 [(set (match_dup 0)
1334 (unspec:HI
1335 [(compare:CCFP (match_dup 1)(match_dup 2))]
1336 UNSPEC_FNSTSW))
1337 (set (reg:CC FLAGS_REG)
1338 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1339 ""
1340 [(set_attr "type" "multi")
1341 (set_attr "unit" "i387")
1342 (set_attr "mode" "<MODE>")])
1343
1344 (define_insn "*cmpfp_u"
1345 [(set (match_operand:HI 0 "register_operand" "=a")
1346 (unspec:HI
1347 [(compare:CCFPU
1348 (match_operand 1 "register_operand" "f")
1349 (match_operand 2 "register_operand" "f"))]
1350 UNSPEC_FNSTSW))]
1351 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1352 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1353 "* return output_fp_compare (insn, operands, false, true);"
1354 [(set_attr "type" "multi")
1355 (set_attr "unit" "i387")
1356 (set (attr "mode")
1357 (cond [(match_operand:SF 1)
1358 (const_string "SF")
1359 (match_operand:DF 1)
1360 (const_string "DF")
1361 ]
1362 (const_string "XF")))])
1363
1364 (define_insn_and_split "*cmpfp_u_cc"
1365 [(set (reg:CCFPU FLAGS_REG)
1366 (compare:CCFPU
1367 (match_operand 1 "register_operand" "f")
1368 (match_operand 2 "register_operand" "f")))
1369 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1370 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1371 && TARGET_SAHF && !TARGET_CMOVE
1372 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1373 "#"
1374 "&& reload_completed"
1375 [(set (match_dup 0)
1376 (unspec:HI
1377 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1378 UNSPEC_FNSTSW))
1379 (set (reg:CC FLAGS_REG)
1380 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1381 ""
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1384 (set (attr "mode")
1385 (cond [(match_operand:SF 1)
1386 (const_string "SF")
1387 (match_operand:DF 1)
1388 (const_string "DF")
1389 ]
1390 (const_string "XF")))])
1391
1392 (define_insn "*cmpfp_<mode>"
1393 [(set (match_operand:HI 0 "register_operand" "=a")
1394 (unspec:HI
1395 [(compare:CCFP
1396 (match_operand 1 "register_operand" "f")
1397 (match_operator 3 "float_operator"
1398 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1399 UNSPEC_FNSTSW))]
1400 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1401 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1402 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1403 "* return output_fp_compare (insn, operands, false, false);"
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "fp_int_src" "true")
1407 (set_attr "mode" "<MODE>")])
1408
1409 (define_insn_and_split "*cmpfp_<mode>_cc"
1410 [(set (reg:CCFP FLAGS_REG)
1411 (compare:CCFP
1412 (match_operand 1 "register_operand" "f")
1413 (match_operator 3 "float_operator"
1414 [(match_operand:SWI24 2 "memory_operand" "m")])))
1415 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1416 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1417 && TARGET_SAHF && !TARGET_CMOVE
1418 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1419 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1420 "#"
1421 "&& reload_completed"
1422 [(set (match_dup 0)
1423 (unspec:HI
1424 [(compare:CCFP
1425 (match_dup 1)
1426 (match_op_dup 3 [(match_dup 2)]))]
1427 UNSPEC_FNSTSW))
1428 (set (reg:CC FLAGS_REG)
1429 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1430 ""
1431 [(set_attr "type" "multi")
1432 (set_attr "unit" "i387")
1433 (set_attr "fp_int_src" "true")
1434 (set_attr "mode" "<MODE>")])
1435
1436 ;; FP compares, step 2
1437 ;; Move the fpsw to ax.
1438
1439 (define_insn "x86_fnstsw_1"
1440 [(set (match_operand:HI 0 "register_operand" "=a")
1441 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1442 "TARGET_80387"
1443 "fnstsw\t%0"
1444 [(set (attr "length")
1445 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1446 (set_attr "mode" "SI")
1447 (set_attr "unit" "i387")])
1448
1449 ;; FP compares, step 3
1450 ;; Get ax into flags, general case.
1451
1452 (define_insn "x86_sahf_1"
1453 [(set (reg:CC FLAGS_REG)
1454 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1455 UNSPEC_SAHF))]
1456 "TARGET_SAHF"
1457 {
1458 #ifndef HAVE_AS_IX86_SAHF
1459 if (TARGET_64BIT)
1460 return ASM_BYTE "0x9e";
1461 else
1462 #endif
1463 return "sahf";
1464 }
1465 [(set_attr "length" "1")
1466 (set_attr "athlon_decode" "vector")
1467 (set_attr "amdfam10_decode" "direct")
1468 (set_attr "bdver1_decode" "direct")
1469 (set_attr "mode" "SI")])
1470
1471 ;; Pentium Pro can do steps 1 through 3 in one go.
1472 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1473 ;; (these i387 instructions set flags directly)
1474 (define_insn "*cmpfp_i_mixed"
1475 [(set (reg:CCFP FLAGS_REG)
1476 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1477 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1478 "TARGET_MIX_SSE_I387
1479 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1480 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1481 "* return output_fp_compare (insn, operands, true, false);"
1482 [(set_attr "type" "fcmp,ssecomi")
1483 (set_attr "prefix" "orig,maybe_vex")
1484 (set (attr "mode")
1485 (if_then_else (match_operand:SF 1)
1486 (const_string "SF")
1487 (const_string "DF")))
1488 (set (attr "prefix_rep")
1489 (if_then_else (eq_attr "type" "ssecomi")
1490 (const_string "0")
1491 (const_string "*")))
1492 (set (attr "prefix_data16")
1493 (cond [(eq_attr "type" "fcmp")
1494 (const_string "*")
1495 (eq_attr "mode" "DF")
1496 (const_string "1")
1497 ]
1498 (const_string "0")))
1499 (set_attr "athlon_decode" "vector")
1500 (set_attr "amdfam10_decode" "direct")
1501 (set_attr "bdver1_decode" "double")])
1502
1503 (define_insn "*cmpfp_i_sse"
1504 [(set (reg:CCFP FLAGS_REG)
1505 (compare:CCFP (match_operand 0 "register_operand" "x")
1506 (match_operand 1 "nonimmediate_operand" "xm")))]
1507 "TARGET_SSE_MATH
1508 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1509 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510 "* return output_fp_compare (insn, operands, true, false);"
1511 [(set_attr "type" "ssecomi")
1512 (set_attr "prefix" "maybe_vex")
1513 (set (attr "mode")
1514 (if_then_else (match_operand:SF 1)
1515 (const_string "SF")
1516 (const_string "DF")))
1517 (set_attr "prefix_rep" "0")
1518 (set (attr "prefix_data16")
1519 (if_then_else (eq_attr "mode" "DF")
1520 (const_string "1")
1521 (const_string "0")))
1522 (set_attr "athlon_decode" "vector")
1523 (set_attr "amdfam10_decode" "direct")
1524 (set_attr "bdver1_decode" "double")])
1525
1526 (define_insn "*cmpfp_i_i387"
1527 [(set (reg:CCFP FLAGS_REG)
1528 (compare:CCFP (match_operand 0 "register_operand" "f")
1529 (match_operand 1 "register_operand" "f")))]
1530 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1531 && TARGET_CMOVE
1532 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1533 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1534 "* return output_fp_compare (insn, operands, true, false);"
1535 [(set_attr "type" "fcmp")
1536 (set (attr "mode")
1537 (cond [(match_operand:SF 1)
1538 (const_string "SF")
1539 (match_operand:DF 1)
1540 (const_string "DF")
1541 ]
1542 (const_string "XF")))
1543 (set_attr "athlon_decode" "vector")
1544 (set_attr "amdfam10_decode" "direct")
1545 (set_attr "bdver1_decode" "double")])
1546
1547 (define_insn "*cmpfp_iu_mixed"
1548 [(set (reg:CCFPU FLAGS_REG)
1549 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1550 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1551 "TARGET_MIX_SSE_I387
1552 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1554 "* return output_fp_compare (insn, operands, true, true);"
1555 [(set_attr "type" "fcmp,ssecomi")
1556 (set_attr "prefix" "orig,maybe_vex")
1557 (set (attr "mode")
1558 (if_then_else (match_operand:SF 1)
1559 (const_string "SF")
1560 (const_string "DF")))
1561 (set (attr "prefix_rep")
1562 (if_then_else (eq_attr "type" "ssecomi")
1563 (const_string "0")
1564 (const_string "*")))
1565 (set (attr "prefix_data16")
1566 (cond [(eq_attr "type" "fcmp")
1567 (const_string "*")
1568 (eq_attr "mode" "DF")
1569 (const_string "1")
1570 ]
1571 (const_string "0")))
1572 (set_attr "athlon_decode" "vector")
1573 (set_attr "amdfam10_decode" "direct")
1574 (set_attr "bdver1_decode" "double")])
1575
1576 (define_insn "*cmpfp_iu_sse"
1577 [(set (reg:CCFPU FLAGS_REG)
1578 (compare:CCFPU (match_operand 0 "register_operand" "x")
1579 (match_operand 1 "nonimmediate_operand" "xm")))]
1580 "TARGET_SSE_MATH
1581 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1582 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583 "* return output_fp_compare (insn, operands, true, true);"
1584 [(set_attr "type" "ssecomi")
1585 (set_attr "prefix" "maybe_vex")
1586 (set (attr "mode")
1587 (if_then_else (match_operand:SF 1)
1588 (const_string "SF")
1589 (const_string "DF")))
1590 (set_attr "prefix_rep" "0")
1591 (set (attr "prefix_data16")
1592 (if_then_else (eq_attr "mode" "DF")
1593 (const_string "1")
1594 (const_string "0")))
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "direct")
1597 (set_attr "bdver1_decode" "double")])
1598
1599 (define_insn "*cmpfp_iu_387"
1600 [(set (reg:CCFPU FLAGS_REG)
1601 (compare:CCFPU (match_operand 0 "register_operand" "f")
1602 (match_operand 1 "register_operand" "f")))]
1603 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1604 && TARGET_CMOVE
1605 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1606 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1607 "* return output_fp_compare (insn, operands, true, true);"
1608 [(set_attr "type" "fcmp")
1609 (set (attr "mode")
1610 (cond [(match_operand:SF 1)
1611 (const_string "SF")
1612 (match_operand:DF 1)
1613 (const_string "DF")
1614 ]
1615 (const_string "XF")))
1616 (set_attr "athlon_decode" "vector")
1617 (set_attr "amdfam10_decode" "direct")
1618 (set_attr "bdver1_decode" "direct")])
1619 \f
1620 ;; Push/pop instructions.
1621
1622 (define_insn "*push<mode>2"
1623 [(set (match_operand:DWI 0 "push_operand" "=<")
1624 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1625 ""
1626 "#"
1627 [(set_attr "type" "multi")
1628 (set_attr "mode" "<MODE>")])
1629
1630 (define_split
1631 [(set (match_operand:TI 0 "push_operand")
1632 (match_operand:TI 1 "general_operand"))]
1633 "TARGET_64BIT && reload_completed
1634 && !SSE_REG_P (operands[1])"
1635 [(const_int 0)]
1636 "ix86_split_long_move (operands); DONE;")
1637
1638 (define_insn "*pushdi2_rex64"
1639 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1640 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1641 "TARGET_64BIT"
1642 "@
1643 push{q}\t%1
1644 #"
1645 [(set_attr "type" "push,multi")
1646 (set_attr "mode" "DI")])
1647
1648 ;; Convert impossible pushes of immediate to existing instructions.
1649 ;; First try to get scratch register and go through it. In case this
1650 ;; fails, push sign extended lower part first and then overwrite
1651 ;; upper part by 32bit move.
1652 (define_peephole2
1653 [(match_scratch:DI 2 "r")
1654 (set (match_operand:DI 0 "push_operand")
1655 (match_operand:DI 1 "immediate_operand"))]
1656 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode)"
1658 [(set (match_dup 2) (match_dup 1))
1659 (set (match_dup 0) (match_dup 2))])
1660
1661 ;; We need to define this as both peepholer and splitter for case
1662 ;; peephole2 pass is not run.
1663 ;; "&& 1" is needed to keep it from matching the previous pattern.
1664 (define_peephole2
1665 [(set (match_operand:DI 0 "push_operand")
1666 (match_operand:DI 1 "immediate_operand"))]
1667 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1668 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1669 [(set (match_dup 0) (match_dup 1))
1670 (set (match_dup 2) (match_dup 3))]
1671 {
1672 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1673
1674 operands[1] = gen_lowpart (DImode, operands[2]);
1675 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1676 GEN_INT (4)));
1677 })
1678
1679 (define_split
1680 [(set (match_operand:DI 0 "push_operand")
1681 (match_operand:DI 1 "immediate_operand"))]
1682 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1683 ? epilogue_completed : reload_completed)
1684 && !symbolic_operand (operands[1], DImode)
1685 && !x86_64_immediate_operand (operands[1], DImode)"
1686 [(set (match_dup 0) (match_dup 1))
1687 (set (match_dup 2) (match_dup 3))]
1688 {
1689 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1690
1691 operands[1] = gen_lowpart (DImode, operands[2]);
1692 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1693 GEN_INT (4)));
1694 })
1695
1696 (define_split
1697 [(set (match_operand:DI 0 "push_operand")
1698 (match_operand:DI 1 "general_operand"))]
1699 "!TARGET_64BIT && reload_completed
1700 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1701 [(const_int 0)]
1702 "ix86_split_long_move (operands); DONE;")
1703
1704 (define_insn "*pushsi2"
1705 [(set (match_operand:SI 0 "push_operand" "=<")
1706 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1707 "!TARGET_64BIT"
1708 "push{l}\t%1"
1709 [(set_attr "type" "push")
1710 (set_attr "mode" "SI")])
1711
1712 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1713 ;; "push a byte/word". But actually we use pushl, which has the effect
1714 ;; of rounding the amount pushed up to a word.
1715
1716 ;; For TARGET_64BIT we always round up to 8 bytes.
1717 (define_insn "*push<mode>2_rex64"
1718 [(set (match_operand:SWI124 0 "push_operand" "=X")
1719 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1720 "TARGET_64BIT"
1721 "push{q}\t%q1"
1722 [(set_attr "type" "push")
1723 (set_attr "mode" "DI")])
1724
1725 (define_insn "*push<mode>2"
1726 [(set (match_operand:SWI12 0 "push_operand" "=X")
1727 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1728 "!TARGET_64BIT"
1729 "push{l}\t%k1"
1730 [(set_attr "type" "push")
1731 (set_attr "mode" "SI")])
1732
1733 (define_insn "*push<mode>2_prologue"
1734 [(set (match_operand:W 0 "push_operand" "=<")
1735 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1736 (clobber (mem:BLK (scratch)))]
1737 ""
1738 "push{<imodesuffix>}\t%1"
1739 [(set_attr "type" "push")
1740 (set_attr "mode" "<MODE>")])
1741
1742 (define_insn "*pop<mode>1"
1743 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1744 (match_operand:W 1 "pop_operand" ">"))]
1745 ""
1746 "pop{<imodesuffix>}\t%0"
1747 [(set_attr "type" "pop")
1748 (set_attr "mode" "<MODE>")])
1749
1750 (define_insn "*pop<mode>1_epilogue"
1751 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1752 (match_operand:W 1 "pop_operand" ">"))
1753 (clobber (mem:BLK (scratch)))]
1754 ""
1755 "pop{<imodesuffix>}\t%0"
1756 [(set_attr "type" "pop")
1757 (set_attr "mode" "<MODE>")])
1758 \f
1759 ;; Move instructions.
1760
1761 (define_expand "movoi"
1762 [(set (match_operand:OI 0 "nonimmediate_operand")
1763 (match_operand:OI 1 "general_operand"))]
1764 "TARGET_AVX"
1765 "ix86_expand_move (OImode, operands); DONE;")
1766
1767 (define_expand "movti"
1768 [(set (match_operand:TI 0 "nonimmediate_operand")
1769 (match_operand:TI 1 "nonimmediate_operand"))]
1770 "TARGET_64BIT || TARGET_SSE"
1771 {
1772 if (TARGET_64BIT)
1773 ix86_expand_move (TImode, operands);
1774 else if (push_operand (operands[0], TImode))
1775 ix86_expand_push (TImode, operands[1]);
1776 else
1777 ix86_expand_vector_move (TImode, operands);
1778 DONE;
1779 })
1780
1781 ;; This expands to what emit_move_complex would generate if we didn't
1782 ;; have a movti pattern. Having this avoids problems with reload on
1783 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1784 ;; to have around all the time.
1785 (define_expand "movcdi"
1786 [(set (match_operand:CDI 0 "nonimmediate_operand")
1787 (match_operand:CDI 1 "general_operand"))]
1788 ""
1789 {
1790 if (push_operand (operands[0], CDImode))
1791 emit_move_complex_push (CDImode, operands[0], operands[1]);
1792 else
1793 emit_move_complex_parts (operands[0], operands[1]);
1794 DONE;
1795 })
1796
1797 (define_expand "mov<mode>"
1798 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1799 (match_operand:SWI1248x 1 "general_operand"))]
1800 ""
1801 "ix86_expand_move (<MODE>mode, operands); DONE;")
1802
1803 (define_insn "*mov<mode>_xor"
1804 [(set (match_operand:SWI48 0 "register_operand" "=r")
1805 (match_operand:SWI48 1 "const0_operand"))
1806 (clobber (reg:CC FLAGS_REG))]
1807 "reload_completed"
1808 "xor{l}\t%k0, %k0"
1809 [(set_attr "type" "alu1")
1810 (set_attr "mode" "SI")
1811 (set_attr "length_immediate" "0")])
1812
1813 (define_insn "*mov<mode>_or"
1814 [(set (match_operand:SWI48 0 "register_operand" "=r")
1815 (match_operand:SWI48 1 "const_int_operand"))
1816 (clobber (reg:CC FLAGS_REG))]
1817 "reload_completed
1818 && operands[1] == constm1_rtx"
1819 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1820 [(set_attr "type" "alu1")
1821 (set_attr "mode" "<MODE>")
1822 (set_attr "length_immediate" "1")])
1823
1824 (define_insn "*movoi_internal_avx"
1825 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1826 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1827 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1828 {
1829 switch (which_alternative)
1830 {
1831 case 0:
1832 return standard_sse_constant_opcode (insn, operands[1]);
1833 case 1:
1834 case 2:
1835 if (misaligned_operand (operands[0], OImode)
1836 || misaligned_operand (operands[1], OImode))
1837 {
1838 if (get_attr_mode (insn) == MODE_V8SF)
1839 return "vmovups\t{%1, %0|%0, %1}";
1840 else
1841 return "vmovdqu\t{%1, %0|%0, %1}";
1842 }
1843 else
1844 {
1845 if (get_attr_mode (insn) == MODE_V8SF)
1846 return "vmovaps\t{%1, %0|%0, %1}";
1847 else
1848 return "vmovdqa\t{%1, %0|%0, %1}";
1849 }
1850 default:
1851 gcc_unreachable ();
1852 }
1853 }
1854 [(set_attr "type" "sselog1,ssemov,ssemov")
1855 (set_attr "prefix" "vex")
1856 (set (attr "mode")
1857 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1858 (const_string "V8SF")
1859 (and (eq_attr "alternative" "2")
1860 (match_test "TARGET_SSE_TYPELESS_STORES"))
1861 (const_string "V8SF")
1862 ]
1863 (const_string "OI")))])
1864
1865 (define_insn "*movti_internal_rex64"
1866 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1867 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1868 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1869 {
1870 switch (which_alternative)
1871 {
1872 case 0:
1873 case 1:
1874 return "#";
1875 case 2:
1876 return standard_sse_constant_opcode (insn, operands[1]);
1877 case 3:
1878 case 4:
1879 /* TDmode values are passed as TImode on the stack. Moving them
1880 to stack may result in unaligned memory access. */
1881 if (misaligned_operand (operands[0], TImode)
1882 || misaligned_operand (operands[1], TImode))
1883 {
1884 if (get_attr_mode (insn) == MODE_V4SF)
1885 return "%vmovups\t{%1, %0|%0, %1}";
1886 else
1887 return "%vmovdqu\t{%1, %0|%0, %1}";
1888 }
1889 else
1890 {
1891 if (get_attr_mode (insn) == MODE_V4SF)
1892 return "%vmovaps\t{%1, %0|%0, %1}";
1893 else
1894 return "%vmovdqa\t{%1, %0|%0, %1}";
1895 }
1896 default:
1897 gcc_unreachable ();
1898 }
1899 }
1900 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1901 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1902 (set (attr "mode")
1903 (cond [(eq_attr "alternative" "0,1")
1904 (const_string "DI")
1905 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1906 (const_string "V4SF")
1907 (and (eq_attr "alternative" "4")
1908 (match_test "TARGET_SSE_TYPELESS_STORES"))
1909 (const_string "V4SF")
1910 (match_test "TARGET_AVX")
1911 (const_string "TI")
1912 (match_test "optimize_function_for_size_p (cfun)")
1913 (const_string "V4SF")
1914 ]
1915 (const_string "TI")))])
1916
1917 (define_split
1918 [(set (match_operand:TI 0 "nonimmediate_operand")
1919 (match_operand:TI 1 "general_operand"))]
1920 "reload_completed
1921 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1922 [(const_int 0)]
1923 "ix86_split_long_move (operands); DONE;")
1924
1925 (define_insn "*movti_internal_sse"
1926 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1927 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1928 "TARGET_SSE && !TARGET_64BIT
1929 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1930 {
1931 switch (which_alternative)
1932 {
1933 case 0:
1934 return standard_sse_constant_opcode (insn, operands[1]);
1935 case 1:
1936 case 2:
1937 /* TDmode values are passed as TImode on the stack. Moving them
1938 to stack may result in unaligned memory access. */
1939 if (misaligned_operand (operands[0], TImode)
1940 || misaligned_operand (operands[1], TImode))
1941 {
1942 if (get_attr_mode (insn) == MODE_V4SF)
1943 return "%vmovups\t{%1, %0|%0, %1}";
1944 else
1945 return "%vmovdqu\t{%1, %0|%0, %1}";
1946 }
1947 else
1948 {
1949 if (get_attr_mode (insn) == MODE_V4SF)
1950 return "%vmovaps\t{%1, %0|%0, %1}";
1951 else
1952 return "%vmovdqa\t{%1, %0|%0, %1}";
1953 }
1954 default:
1955 gcc_unreachable ();
1956 }
1957 }
1958 [(set_attr "type" "sselog1,ssemov,ssemov")
1959 (set_attr "prefix" "maybe_vex")
1960 (set (attr "mode")
1961 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1962 (const_string "V4SF")
1963 (and (eq_attr "alternative" "2")
1964 (match_test "TARGET_SSE_TYPELESS_STORES"))
1965 (const_string "V4SF")
1966 (match_test "TARGET_AVX")
1967 (const_string "TI")
1968 (ior (not (match_test "TARGET_SSE2"))
1969 (match_test "optimize_function_for_size_p (cfun)"))
1970 (const_string "V4SF")
1971 ]
1972 (const_string "TI")))])
1973
1974 (define_insn "*movdi_internal_rex64"
1975 [(set (match_operand:DI 0 "nonimmediate_operand"
1976 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1977 (match_operand:DI 1 "general_operand"
1978 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1979 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1980 {
1981 switch (get_attr_type (insn))
1982 {
1983 case TYPE_SSECVT:
1984 if (SSE_REG_P (operands[0]))
1985 return "movq2dq\t{%1, %0|%0, %1}";
1986 else
1987 return "movdq2q\t{%1, %0|%0, %1}";
1988
1989 case TYPE_SSEMOV:
1990 if (get_attr_mode (insn) == MODE_V4SF)
1991 return "%vmovaps\t{%1, %0|%0, %1}";
1992 else if (get_attr_mode (insn) == MODE_TI)
1993 return "%vmovdqa\t{%1, %0|%0, %1}";
1994
1995 /* Handle broken assemblers that require movd instead of movq. */
1996 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1997 return "%vmovd\t{%1, %0|%0, %1}";
1998 else
1999 return "%vmovq\t{%1, %0|%0, %1}";
2000
2001 case TYPE_MMXMOV:
2002 /* Handle broken assemblers that require movd instead of movq. */
2003 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2004 return "movd\t{%1, %0|%0, %1}";
2005 else
2006 return "movq\t{%1, %0|%0, %1}";
2007
2008 case TYPE_SSELOG1:
2009 return standard_sse_constant_opcode (insn, operands[1]);
2010
2011 case TYPE_MMX:
2012 return "pxor\t%0, %0";
2013
2014 case TYPE_MULTI:
2015 return "#";
2016
2017 case TYPE_LEA:
2018 return "lea{q}\t{%E1, %0|%0, %E1}";
2019
2020 default:
2021 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2022 if (get_attr_mode (insn) == MODE_SI)
2023 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2024 else if (which_alternative == 2)
2025 return "movabs{q}\t{%1, %0|%0, %1}";
2026 else if (ix86_use_lea_for_mov (insn, operands))
2027 return "lea{q}\t{%E1, %0|%0, %E1}";
2028 else
2029 return "mov{q}\t{%1, %0|%0, %1}";
2030 }
2031 }
2032 [(set (attr "type")
2033 (cond [(eq_attr "alternative" "4")
2034 (const_string "multi")
2035 (eq_attr "alternative" "5")
2036 (const_string "mmx")
2037 (eq_attr "alternative" "6,7,8,9")
2038 (const_string "mmxmov")
2039 (eq_attr "alternative" "10")
2040 (const_string "sselog1")
2041 (eq_attr "alternative" "11,12,13,14,15")
2042 (const_string "ssemov")
2043 (eq_attr "alternative" "16,17")
2044 (const_string "ssecvt")
2045 (match_operand 1 "pic_32bit_operand")
2046 (const_string "lea")
2047 ]
2048 (const_string "imov")))
2049 (set (attr "modrm")
2050 (if_then_else
2051 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2052 (const_string "0")
2053 (const_string "*")))
2054 (set (attr "length_immediate")
2055 (if_then_else
2056 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2057 (const_string "8")
2058 (const_string "*")))
2059 (set (attr "prefix_rex")
2060 (if_then_else (eq_attr "alternative" "8,9")
2061 (const_string "1")
2062 (const_string "*")))
2063 (set (attr "prefix_data16")
2064 (if_then_else (eq_attr "alternative" "11")
2065 (const_string "1")
2066 (const_string "*")))
2067 (set (attr "prefix")
2068 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2069 (const_string "maybe_vex")
2070 (const_string "orig")))
2071 (set (attr "mode")
2072 (cond [(eq_attr "alternative" "0,4")
2073 (const_string "SI")
2074 (eq_attr "alternative" "10,12")
2075 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2076 (const_string "V4SF")
2077 (match_test "TARGET_AVX")
2078 (const_string "TI")
2079 (match_test "optimize_function_for_size_p (cfun)")
2080 (const_string "V4SF")
2081 ]
2082 (const_string "TI"))
2083 ]
2084 (const_string "DI")))])
2085
2086 ;; Reload patterns to support multi-word load/store
2087 ;; with non-offsetable address.
2088 (define_expand "reload_noff_store"
2089 [(parallel [(match_operand 0 "memory_operand" "=m")
2090 (match_operand 1 "register_operand" "r")
2091 (match_operand:DI 2 "register_operand" "=&r")])]
2092 "TARGET_64BIT"
2093 {
2094 rtx mem = operands[0];
2095 rtx addr = XEXP (mem, 0);
2096
2097 emit_move_insn (operands[2], addr);
2098 mem = replace_equiv_address_nv (mem, operands[2]);
2099
2100 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2101 DONE;
2102 })
2103
2104 (define_expand "reload_noff_load"
2105 [(parallel [(match_operand 0 "register_operand" "=r")
2106 (match_operand 1 "memory_operand" "m")
2107 (match_operand:DI 2 "register_operand" "=r")])]
2108 "TARGET_64BIT"
2109 {
2110 rtx mem = operands[1];
2111 rtx addr = XEXP (mem, 0);
2112
2113 emit_move_insn (operands[2], addr);
2114 mem = replace_equiv_address_nv (mem, operands[2]);
2115
2116 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2117 DONE;
2118 })
2119
2120 ;; Convert impossible stores of immediate to existing instructions.
2121 ;; First try to get scratch register and go through it. In case this
2122 ;; fails, move by 32bit parts.
2123 (define_peephole2
2124 [(match_scratch:DI 2 "r")
2125 (set (match_operand:DI 0 "memory_operand")
2126 (match_operand:DI 1 "immediate_operand"))]
2127 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2128 && !x86_64_immediate_operand (operands[1], DImode)"
2129 [(set (match_dup 2) (match_dup 1))
2130 (set (match_dup 0) (match_dup 2))])
2131
2132 ;; We need to define this as both peepholer and splitter for case
2133 ;; peephole2 pass is not run.
2134 ;; "&& 1" is needed to keep it from matching the previous pattern.
2135 (define_peephole2
2136 [(set (match_operand:DI 0 "memory_operand")
2137 (match_operand:DI 1 "immediate_operand"))]
2138 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2139 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2140 [(set (match_dup 2) (match_dup 3))
2141 (set (match_dup 4) (match_dup 5))]
2142 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2143
2144 (define_split
2145 [(set (match_operand:DI 0 "memory_operand")
2146 (match_operand:DI 1 "immediate_operand"))]
2147 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2148 ? epilogue_completed : reload_completed)
2149 && !symbolic_operand (operands[1], DImode)
2150 && !x86_64_immediate_operand (operands[1], DImode)"
2151 [(set (match_dup 2) (match_dup 3))
2152 (set (match_dup 4) (match_dup 5))]
2153 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2154
2155 (define_insn "*movdi_internal"
2156 [(set (match_operand:DI 0 "nonimmediate_operand"
2157 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2158 (match_operand:DI 1 "general_operand"
2159 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2160 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2161 {
2162 switch (get_attr_type (insn))
2163 {
2164 case TYPE_SSECVT:
2165 if (SSE_REG_P (operands[0]))
2166 return "movq2dq\t{%1, %0|%0, %1}";
2167 else
2168 return "movdq2q\t{%1, %0|%0, %1}";
2169
2170 case TYPE_SSEMOV:
2171 switch (get_attr_mode (insn))
2172 {
2173 case MODE_TI:
2174 return "%vmovdqa\t{%1, %0|%0, %1}";
2175 case MODE_DI:
2176 return "%vmovq\t{%1, %0|%0, %1}";
2177 case MODE_V4SF:
2178 return "%vmovaps\t{%1, %0|%0, %1}";
2179 case MODE_V2SF:
2180 return "movlps\t{%1, %0|%0, %1}";
2181 default:
2182 gcc_unreachable ();
2183 }
2184
2185 case TYPE_MMXMOV:
2186 return "movq\t{%1, %0|%0, %1}";
2187
2188 case TYPE_SSELOG1:
2189 return standard_sse_constant_opcode (insn, operands[1]);
2190
2191 case TYPE_MMX:
2192 return "pxor\t%0, %0";
2193
2194 case TYPE_MULTI:
2195 return "#";
2196
2197 default:
2198 gcc_unreachable ();
2199 }
2200 }
2201 [(set (attr "isa")
2202 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2203 (const_string "sse2")
2204 (eq_attr "alternative" "9,10,11,12")
2205 (const_string "noavx")
2206 ]
2207 (const_string "*")))
2208 (set (attr "type")
2209 (cond [(eq_attr "alternative" "0,1")
2210 (const_string "multi")
2211 (eq_attr "alternative" "2")
2212 (const_string "mmx")
2213 (eq_attr "alternative" "3,4")
2214 (const_string "mmxmov")
2215 (eq_attr "alternative" "5,9")
2216 (const_string "sselog1")
2217 (eq_attr "alternative" "13,14")
2218 (const_string "ssecvt")
2219 ]
2220 (const_string "ssemov")))
2221 (set (attr "prefix")
2222 (if_then_else (eq_attr "alternative" "5,6,7,8")
2223 (const_string "maybe_vex")
2224 (const_string "orig")))
2225 (set (attr "mode")
2226 (cond [(eq_attr "alternative" "9,11")
2227 (const_string "V4SF")
2228 (eq_attr "alternative" "10,12")
2229 (const_string "V2SF")
2230 (eq_attr "alternative" "5,7")
2231 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2232 (const_string "V4SF")
2233 (match_test "TARGET_AVX")
2234 (const_string "TI")
2235 (match_test "optimize_function_for_size_p (cfun)")
2236 (const_string "V4SF")
2237 ]
2238 (const_string "TI"))
2239 ]
2240 (const_string "DI")))])
2241
2242 (define_split
2243 [(set (match_operand:DI 0 "nonimmediate_operand")
2244 (match_operand:DI 1 "general_operand"))]
2245 "!TARGET_64BIT && reload_completed
2246 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2247 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2248 [(const_int 0)]
2249 "ix86_split_long_move (operands); DONE;")
2250
2251 (define_insn "*movsi_internal"
2252 [(set (match_operand:SI 0 "nonimmediate_operand"
2253 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2254 (match_operand:SI 1 "general_operand"
2255 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2256 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2257 {
2258 switch (get_attr_type (insn))
2259 {
2260 case TYPE_SSELOG1:
2261 return standard_sse_constant_opcode (insn, operands[1]);
2262
2263 case TYPE_SSEMOV:
2264 switch (get_attr_mode (insn))
2265 {
2266 case MODE_TI:
2267 return "%vmovdqa\t{%1, %0|%0, %1}";
2268 case MODE_V4SF:
2269 return "%vmovaps\t{%1, %0|%0, %1}";
2270 case MODE_SI:
2271 return "%vmovd\t{%1, %0|%0, %1}";
2272 case MODE_SF:
2273 return "%vmovss\t{%1, %0|%0, %1}";
2274 default:
2275 gcc_unreachable ();
2276 }
2277
2278 case TYPE_MMX:
2279 return "pxor\t%0, %0";
2280
2281 case TYPE_MMXMOV:
2282 if (get_attr_mode (insn) == MODE_DI)
2283 return "movq\t{%1, %0|%0, %1}";
2284 return "movd\t{%1, %0|%0, %1}";
2285
2286 case TYPE_LEA:
2287 return "lea{l}\t{%E1, %0|%0, %E1}";
2288
2289 default:
2290 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2291 if (ix86_use_lea_for_mov (insn, operands))
2292 return "lea{l}\t{%E1, %0|%0, %E1}";
2293 else
2294 return "mov{l}\t{%1, %0|%0, %1}";
2295 }
2296 }
2297 [(set (attr "type")
2298 (cond [(eq_attr "alternative" "2")
2299 (const_string "mmx")
2300 (eq_attr "alternative" "3,4,5")
2301 (const_string "mmxmov")
2302 (eq_attr "alternative" "6")
2303 (const_string "sselog1")
2304 (eq_attr "alternative" "7,8,9,10,11")
2305 (const_string "ssemov")
2306 (match_operand 1 "pic_32bit_operand")
2307 (const_string "lea")
2308 ]
2309 (const_string "imov")))
2310 (set (attr "prefix")
2311 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2312 (const_string "orig")
2313 (const_string "maybe_vex")))
2314 (set (attr "prefix_data16")
2315 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2316 (const_string "1")
2317 (const_string "*")))
2318 (set (attr "mode")
2319 (cond [(eq_attr "alternative" "2,3")
2320 (const_string "DI")
2321 (eq_attr "alternative" "6,7")
2322 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2323 (const_string "V4SF")
2324 (match_test "TARGET_AVX")
2325 (const_string "TI")
2326 (ior (not (match_test "TARGET_SSE2"))
2327 (match_test "optimize_function_for_size_p (cfun)"))
2328 (const_string "V4SF")
2329 ]
2330 (const_string "TI"))
2331 (and (eq_attr "alternative" "8,9,10,11")
2332 (not (match_test "TARGET_SSE2")))
2333 (const_string "SF")
2334 ]
2335 (const_string "SI")))])
2336
2337 (define_insn "*movhi_internal"
2338 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2339 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2340 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2341 {
2342 switch (get_attr_type (insn))
2343 {
2344 case TYPE_IMOVX:
2345 /* movzwl is faster than movw on p2 due to partial word stalls,
2346 though not as fast as an aligned movl. */
2347 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2348 default:
2349 if (get_attr_mode (insn) == MODE_SI)
2350 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2351 else
2352 return "mov{w}\t{%1, %0|%0, %1}";
2353 }
2354 }
2355 [(set (attr "type")
2356 (cond [(match_test "optimize_function_for_size_p (cfun)")
2357 (const_string "imov")
2358 (and (eq_attr "alternative" "0")
2359 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2360 (not (match_test "TARGET_HIMODE_MATH"))))
2361 (const_string "imov")
2362 (and (eq_attr "alternative" "1,2")
2363 (match_operand:HI 1 "aligned_operand"))
2364 (const_string "imov")
2365 (and (match_test "TARGET_MOVX")
2366 (eq_attr "alternative" "0,2"))
2367 (const_string "imovx")
2368 ]
2369 (const_string "imov")))
2370 (set (attr "mode")
2371 (cond [(eq_attr "type" "imovx")
2372 (const_string "SI")
2373 (and (eq_attr "alternative" "1,2")
2374 (match_operand:HI 1 "aligned_operand"))
2375 (const_string "SI")
2376 (and (eq_attr "alternative" "0")
2377 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2378 (not (match_test "TARGET_HIMODE_MATH"))))
2379 (const_string "SI")
2380 ]
2381 (const_string "HI")))])
2382
2383 ;; Situation is quite tricky about when to choose full sized (SImode) move
2384 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2385 ;; partial register dependency machines (such as AMD Athlon), where QImode
2386 ;; moves issue extra dependency and for partial register stalls machines
2387 ;; that don't use QImode patterns (and QImode move cause stall on the next
2388 ;; instruction).
2389 ;;
2390 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2391 ;; register stall machines with, where we use QImode instructions, since
2392 ;; partial register stall can be caused there. Then we use movzx.
2393 (define_insn "*movqi_internal"
2394 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2395 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2396 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2397 {
2398 switch (get_attr_type (insn))
2399 {
2400 case TYPE_IMOVX:
2401 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2402 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2403 default:
2404 if (get_attr_mode (insn) == MODE_SI)
2405 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2406 else
2407 return "mov{b}\t{%1, %0|%0, %1}";
2408 }
2409 }
2410 [(set (attr "type")
2411 (cond [(and (eq_attr "alternative" "5")
2412 (not (match_operand:QI 1 "aligned_operand")))
2413 (const_string "imovx")
2414 (match_test "optimize_function_for_size_p (cfun)")
2415 (const_string "imov")
2416 (and (eq_attr "alternative" "3")
2417 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2418 (not (match_test "TARGET_QIMODE_MATH"))))
2419 (const_string "imov")
2420 (eq_attr "alternative" "3,5")
2421 (const_string "imovx")
2422 (and (match_test "TARGET_MOVX")
2423 (eq_attr "alternative" "2"))
2424 (const_string "imovx")
2425 ]
2426 (const_string "imov")))
2427 (set (attr "mode")
2428 (cond [(eq_attr "alternative" "3,4,5")
2429 (const_string "SI")
2430 (eq_attr "alternative" "6")
2431 (const_string "QI")
2432 (eq_attr "type" "imovx")
2433 (const_string "SI")
2434 (and (eq_attr "type" "imov")
2435 (and (eq_attr "alternative" "0,1")
2436 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2437 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2438 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2439 (const_string "SI")
2440 ;; Avoid partial register stalls when not using QImode arithmetic
2441 (and (eq_attr "type" "imov")
2442 (and (eq_attr "alternative" "0,1")
2443 (and (match_test "TARGET_PARTIAL_REG_STALL")
2444 (not (match_test "TARGET_QIMODE_MATH")))))
2445 (const_string "SI")
2446 ]
2447 (const_string "QI")))])
2448
2449 ;; Stores and loads of ax to arbitrary constant address.
2450 ;; We fake an second form of instruction to force reload to load address
2451 ;; into register when rax is not available
2452 (define_insn "*movabs<mode>_1"
2453 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2454 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2455 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2456 "@
2457 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2458 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2459 [(set_attr "type" "imov")
2460 (set_attr "modrm" "0,*")
2461 (set_attr "length_address" "8,0")
2462 (set_attr "length_immediate" "0,*")
2463 (set_attr "memory" "store")
2464 (set_attr "mode" "<MODE>")])
2465
2466 (define_insn "*movabs<mode>_2"
2467 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2468 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2469 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2470 "@
2471 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2472 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2473 [(set_attr "type" "imov")
2474 (set_attr "modrm" "0,*")
2475 (set_attr "length_address" "8,0")
2476 (set_attr "length_immediate" "0")
2477 (set_attr "memory" "load")
2478 (set_attr "mode" "<MODE>")])
2479
2480 (define_insn "swap<mode>"
2481 [(set (match_operand:SWI48 0 "register_operand" "+r")
2482 (match_operand:SWI48 1 "register_operand" "+r"))
2483 (set (match_dup 1)
2484 (match_dup 0))]
2485 ""
2486 "xchg{<imodesuffix>}\t%1, %0"
2487 [(set_attr "type" "imov")
2488 (set_attr "mode" "<MODE>")
2489 (set_attr "pent_pair" "np")
2490 (set_attr "athlon_decode" "vector")
2491 (set_attr "amdfam10_decode" "double")
2492 (set_attr "bdver1_decode" "double")])
2493
2494 (define_insn "*swap<mode>_1"
2495 [(set (match_operand:SWI12 0 "register_operand" "+r")
2496 (match_operand:SWI12 1 "register_operand" "+r"))
2497 (set (match_dup 1)
2498 (match_dup 0))]
2499 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2500 "xchg{l}\t%k1, %k0"
2501 [(set_attr "type" "imov")
2502 (set_attr "mode" "SI")
2503 (set_attr "pent_pair" "np")
2504 (set_attr "athlon_decode" "vector")
2505 (set_attr "amdfam10_decode" "double")
2506 (set_attr "bdver1_decode" "double")])
2507
2508 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2509 ;; is disabled for AMDFAM10
2510 (define_insn "*swap<mode>_2"
2511 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2512 (match_operand:SWI12 1 "register_operand" "+<r>"))
2513 (set (match_dup 1)
2514 (match_dup 0))]
2515 "TARGET_PARTIAL_REG_STALL"
2516 "xchg{<imodesuffix>}\t%1, %0"
2517 [(set_attr "type" "imov")
2518 (set_attr "mode" "<MODE>")
2519 (set_attr "pent_pair" "np")
2520 (set_attr "athlon_decode" "vector")])
2521
2522 (define_expand "movstrict<mode>"
2523 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2524 (match_operand:SWI12 1 "general_operand"))]
2525 ""
2526 {
2527 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2528 FAIL;
2529 if (GET_CODE (operands[0]) == SUBREG
2530 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2531 FAIL;
2532 /* Don't generate memory->memory moves, go through a register */
2533 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2534 operands[1] = force_reg (<MODE>mode, operands[1]);
2535 })
2536
2537 (define_insn "*movstrict<mode>_1"
2538 [(set (strict_low_part
2539 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2540 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2541 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2542 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2543 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2544 [(set_attr "type" "imov")
2545 (set_attr "mode" "<MODE>")])
2546
2547 (define_insn "*movstrict<mode>_xor"
2548 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2549 (match_operand:SWI12 1 "const0_operand"))
2550 (clobber (reg:CC FLAGS_REG))]
2551 "reload_completed"
2552 "xor{<imodesuffix>}\t%0, %0"
2553 [(set_attr "type" "alu1")
2554 (set_attr "mode" "<MODE>")
2555 (set_attr "length_immediate" "0")])
2556
2557 (define_insn "*mov<mode>_extv_1"
2558 [(set (match_operand:SWI24 0 "register_operand" "=R")
2559 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2560 (const_int 8)
2561 (const_int 8)))]
2562 ""
2563 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2564 [(set_attr "type" "imovx")
2565 (set_attr "mode" "SI")])
2566
2567 (define_insn "*movqi_extv_1_rex64"
2568 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2569 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2570 (const_int 8)
2571 (const_int 8)))]
2572 "TARGET_64BIT"
2573 {
2574 switch (get_attr_type (insn))
2575 {
2576 case TYPE_IMOVX:
2577 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2578 default:
2579 return "mov{b}\t{%h1, %0|%0, %h1}";
2580 }
2581 }
2582 [(set (attr "type")
2583 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2584 (match_test "TARGET_MOVX"))
2585 (const_string "imovx")
2586 (const_string "imov")))
2587 (set (attr "mode")
2588 (if_then_else (eq_attr "type" "imovx")
2589 (const_string "SI")
2590 (const_string "QI")))])
2591
2592 (define_insn "*movqi_extv_1"
2593 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2594 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2595 (const_int 8)
2596 (const_int 8)))]
2597 "!TARGET_64BIT"
2598 {
2599 switch (get_attr_type (insn))
2600 {
2601 case TYPE_IMOVX:
2602 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2603 default:
2604 return "mov{b}\t{%h1, %0|%0, %h1}";
2605 }
2606 }
2607 [(set (attr "type")
2608 (if_then_else (and (match_operand:QI 0 "register_operand")
2609 (ior (not (match_operand:QI 0 "QIreg_operand"))
2610 (match_test "TARGET_MOVX")))
2611 (const_string "imovx")
2612 (const_string "imov")))
2613 (set (attr "mode")
2614 (if_then_else (eq_attr "type" "imovx")
2615 (const_string "SI")
2616 (const_string "QI")))])
2617
2618 (define_insn "*mov<mode>_extzv_1"
2619 [(set (match_operand:SWI48 0 "register_operand" "=R")
2620 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2621 (const_int 8)
2622 (const_int 8)))]
2623 ""
2624 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2625 [(set_attr "type" "imovx")
2626 (set_attr "mode" "SI")])
2627
2628 (define_insn "*movqi_extzv_2_rex64"
2629 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2630 (subreg:QI
2631 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2632 (const_int 8)
2633 (const_int 8)) 0))]
2634 "TARGET_64BIT"
2635 {
2636 switch (get_attr_type (insn))
2637 {
2638 case TYPE_IMOVX:
2639 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2640 default:
2641 return "mov{b}\t{%h1, %0|%0, %h1}";
2642 }
2643 }
2644 [(set (attr "type")
2645 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2646 (match_test "TARGET_MOVX"))
2647 (const_string "imovx")
2648 (const_string "imov")))
2649 (set (attr "mode")
2650 (if_then_else (eq_attr "type" "imovx")
2651 (const_string "SI")
2652 (const_string "QI")))])
2653
2654 (define_insn "*movqi_extzv_2"
2655 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2656 (subreg:QI
2657 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2658 (const_int 8)
2659 (const_int 8)) 0))]
2660 "!TARGET_64BIT"
2661 {
2662 switch (get_attr_type (insn))
2663 {
2664 case TYPE_IMOVX:
2665 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2666 default:
2667 return "mov{b}\t{%h1, %0|%0, %h1}";
2668 }
2669 }
2670 [(set (attr "type")
2671 (if_then_else (and (match_operand:QI 0 "register_operand")
2672 (ior (not (match_operand:QI 0 "QIreg_operand"))
2673 (match_test "TARGET_MOVX")))
2674 (const_string "imovx")
2675 (const_string "imov")))
2676 (set (attr "mode")
2677 (if_then_else (eq_attr "type" "imovx")
2678 (const_string "SI")
2679 (const_string "QI")))])
2680
2681 (define_expand "mov<mode>_insv_1"
2682 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2683 (const_int 8)
2684 (const_int 8))
2685 (match_operand:SWI48 1 "nonmemory_operand"))])
2686
2687 (define_insn "*mov<mode>_insv_1_rex64"
2688 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2689 (const_int 8)
2690 (const_int 8))
2691 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2692 "TARGET_64BIT"
2693 "mov{b}\t{%b1, %h0|%h0, %b1}"
2694 [(set_attr "type" "imov")
2695 (set_attr "mode" "QI")])
2696
2697 (define_insn "*movsi_insv_1"
2698 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2699 (const_int 8)
2700 (const_int 8))
2701 (match_operand:SI 1 "general_operand" "Qmn"))]
2702 "!TARGET_64BIT"
2703 "mov{b}\t{%b1, %h0|%h0, %b1}"
2704 [(set_attr "type" "imov")
2705 (set_attr "mode" "QI")])
2706
2707 (define_insn "*movqi_insv_2"
2708 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2709 (const_int 8)
2710 (const_int 8))
2711 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2712 (const_int 8)))]
2713 ""
2714 "mov{b}\t{%h1, %h0|%h0, %h1}"
2715 [(set_attr "type" "imov")
2716 (set_attr "mode" "QI")])
2717 \f
2718 ;; Floating point push instructions.
2719
2720 (define_insn "*pushtf"
2721 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2722 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2723 "TARGET_SSE"
2724 {
2725 /* This insn should be already split before reg-stack. */
2726 gcc_unreachable ();
2727 }
2728 [(set_attr "type" "multi")
2729 (set_attr "unit" "sse,*,*")
2730 (set_attr "mode" "TF,SI,SI")])
2731
2732 ;; %%% Kill this when call knows how to work this out.
2733 (define_split
2734 [(set (match_operand:TF 0 "push_operand")
2735 (match_operand:TF 1 "sse_reg_operand"))]
2736 "TARGET_SSE && reload_completed"
2737 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2738 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2739
2740 (define_insn "*pushxf"
2741 [(set (match_operand:XF 0 "push_operand" "=<,<")
2742 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2743 "optimize_function_for_speed_p (cfun)"
2744 {
2745 /* This insn should be already split before reg-stack. */
2746 gcc_unreachable ();
2747 }
2748 [(set_attr "type" "multi")
2749 (set_attr "unit" "i387,*")
2750 (set_attr "mode" "XF,SI")])
2751
2752 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2753 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2754 ;; Pushing using integer instructions is longer except for constants
2755 ;; and direct memory references (assuming that any given constant is pushed
2756 ;; only once, but this ought to be handled elsewhere).
2757
2758 (define_insn "*pushxf_nointeger"
2759 [(set (match_operand:XF 0 "push_operand" "=<,<")
2760 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2761 "optimize_function_for_size_p (cfun)"
2762 {
2763 /* This insn should be already split before reg-stack. */
2764 gcc_unreachable ();
2765 }
2766 [(set_attr "type" "multi")
2767 (set_attr "unit" "i387,*")
2768 (set_attr "mode" "XF,SI")])
2769
2770 ;; %%% Kill this when call knows how to work this out.
2771 (define_split
2772 [(set (match_operand:XF 0 "push_operand")
2773 (match_operand:XF 1 "fp_register_operand"))]
2774 "reload_completed"
2775 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2776 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2777 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2778
2779 (define_insn "*pushdf_rex64"
2780 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2781 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2782 "TARGET_64BIT"
2783 {
2784 /* This insn should be already split before reg-stack. */
2785 gcc_unreachable ();
2786 }
2787 [(set_attr "type" "multi")
2788 (set_attr "unit" "i387,*,*")
2789 (set_attr "mode" "DF,DI,DF")])
2790
2791 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2792 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2793 ;; On the average, pushdf using integers can be still shorter.
2794
2795 (define_insn "*pushdf"
2796 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2797 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2798 "!TARGET_64BIT"
2799 {
2800 /* This insn should be already split before reg-stack. */
2801 gcc_unreachable ();
2802 }
2803 [(set_attr "isa" "*,*,sse2")
2804 (set_attr "type" "multi")
2805 (set_attr "unit" "i387,*,*")
2806 (set_attr "mode" "DF,DI,DF")])
2807
2808 ;; %%% Kill this when call knows how to work this out.
2809 (define_split
2810 [(set (match_operand:DF 0 "push_operand")
2811 (match_operand:DF 1 "any_fp_register_operand"))]
2812 "reload_completed"
2813 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2814 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2815
2816 (define_insn "*pushsf_rex64"
2817 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2818 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2819 "TARGET_64BIT"
2820 {
2821 /* Anything else should be already split before reg-stack. */
2822 gcc_assert (which_alternative == 1);
2823 return "push{q}\t%q1";
2824 }
2825 [(set_attr "type" "multi,push,multi")
2826 (set_attr "unit" "i387,*,*")
2827 (set_attr "mode" "SF,DI,SF")])
2828
2829 (define_insn "*pushsf"
2830 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2831 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2832 "!TARGET_64BIT"
2833 {
2834 /* Anything else should be already split before reg-stack. */
2835 gcc_assert (which_alternative == 1);
2836 return "push{l}\t%1";
2837 }
2838 [(set_attr "type" "multi,push,multi")
2839 (set_attr "unit" "i387,*,*")
2840 (set_attr "mode" "SF,SI,SF")])
2841
2842 ;; %%% Kill this when call knows how to work this out.
2843 (define_split
2844 [(set (match_operand:SF 0 "push_operand")
2845 (match_operand:SF 1 "any_fp_register_operand"))]
2846 "reload_completed"
2847 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2848 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2849 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2850
2851 (define_split
2852 [(set (match_operand:SF 0 "push_operand")
2853 (match_operand:SF 1 "memory_operand"))]
2854 "reload_completed
2855 && (operands[2] = find_constant_src (insn))"
2856 [(set (match_dup 0) (match_dup 2))])
2857
2858 (define_split
2859 [(set (match_operand 0 "push_operand")
2860 (match_operand 1 "general_operand"))]
2861 "reload_completed
2862 && (GET_MODE (operands[0]) == TFmode
2863 || GET_MODE (operands[0]) == XFmode
2864 || GET_MODE (operands[0]) == DFmode)
2865 && !ANY_FP_REG_P (operands[1])"
2866 [(const_int 0)]
2867 "ix86_split_long_move (operands); DONE;")
2868 \f
2869 ;; Floating point move instructions.
2870
2871 (define_expand "movtf"
2872 [(set (match_operand:TF 0 "nonimmediate_operand")
2873 (match_operand:TF 1 "nonimmediate_operand"))]
2874 "TARGET_SSE"
2875 {
2876 ix86_expand_move (TFmode, operands);
2877 DONE;
2878 })
2879
2880 (define_expand "mov<mode>"
2881 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2882 (match_operand:X87MODEF 1 "general_operand"))]
2883 ""
2884 "ix86_expand_move (<MODE>mode, operands); DONE;")
2885
2886 (define_insn "*movtf_internal"
2887 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2888 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2889 "TARGET_SSE
2890 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2891 && (!can_create_pseudo_p ()
2892 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2893 || GET_CODE (operands[1]) != CONST_DOUBLE
2894 || (optimize_function_for_size_p (cfun)
2895 && standard_sse_constant_p (operands[1])
2896 && !memory_operand (operands[0], TFmode))
2897 || (!TARGET_MEMORY_MISMATCH_STALL
2898 && memory_operand (operands[0], TFmode)))"
2899 {
2900 switch (which_alternative)
2901 {
2902 case 0:
2903 return standard_sse_constant_opcode (insn, operands[1]);
2904 case 1:
2905 case 2:
2906 /* Handle misaligned load/store since we
2907 don't have movmisaligntf pattern. */
2908 if (misaligned_operand (operands[0], TFmode)
2909 || misaligned_operand (operands[1], TFmode))
2910 {
2911 if (get_attr_mode (insn) == MODE_V4SF)
2912 return "%vmovups\t{%1, %0|%0, %1}";
2913 else
2914 return "%vmovdqu\t{%1, %0|%0, %1}";
2915 }
2916 else
2917 {
2918 if (get_attr_mode (insn) == MODE_V4SF)
2919 return "%vmovaps\t{%1, %0|%0, %1}";
2920 else
2921 return "%vmovdqa\t{%1, %0|%0, %1}";
2922 }
2923
2924 case 3:
2925 case 4:
2926 return "#";
2927
2928 default:
2929 gcc_unreachable ();
2930 }
2931 }
2932 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2933 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2934 (set (attr "mode")
2935 (cond [(eq_attr "alternative" "3,4")
2936 (const_string "DI")
2937 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2938 (const_string "V4SF")
2939 (and (eq_attr "alternative" "2")
2940 (match_test "TARGET_SSE_TYPELESS_STORES"))
2941 (const_string "V4SF")
2942 (match_test "TARGET_AVX")
2943 (const_string "TI")
2944 (ior (not (match_test "TARGET_SSE2"))
2945 (match_test "optimize_function_for_size_p (cfun)"))
2946 (const_string "V4SF")
2947 ]
2948 (const_string "TI")))])
2949
2950 ;; Possible store forwarding (partial memory) stall in alternative 4.
2951 (define_insn "*movxf_internal"
2952 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2953 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2954 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2955 && (!can_create_pseudo_p ()
2956 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2957 || GET_CODE (operands[1]) != CONST_DOUBLE
2958 || (optimize_function_for_size_p (cfun)
2959 && standard_80387_constant_p (operands[1]) > 0
2960 && !memory_operand (operands[0], XFmode))
2961 || (!TARGET_MEMORY_MISMATCH_STALL
2962 && memory_operand (operands[0], XFmode)))"
2963 {
2964 switch (which_alternative)
2965 {
2966 case 0:
2967 case 1:
2968 return output_387_reg_move (insn, operands);
2969
2970 case 2:
2971 return standard_80387_constant_opcode (operands[1]);
2972
2973 case 3:
2974 case 4:
2975 return "#";
2976
2977 default:
2978 gcc_unreachable ();
2979 }
2980 }
2981 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2982 (set_attr "mode" "XF,XF,XF,SI,SI")])
2983
2984 (define_insn "*movdf_internal_rex64"
2985 [(set (match_operand:DF 0 "nonimmediate_operand"
2986 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2987 (match_operand:DF 1 "general_operand"
2988 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2989 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2990 && (!can_create_pseudo_p ()
2991 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2992 || GET_CODE (operands[1]) != CONST_DOUBLE
2993 || (optimize_function_for_size_p (cfun)
2994 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2995 && standard_80387_constant_p (operands[1]) > 0)
2996 || (TARGET_SSE2 && TARGET_SSE_MATH
2997 && standard_sse_constant_p (operands[1]))))
2998 || memory_operand (operands[0], DFmode))"
2999 {
3000 switch (which_alternative)
3001 {
3002 case 0:
3003 case 1:
3004 return output_387_reg_move (insn, operands);
3005
3006 case 2:
3007 return standard_80387_constant_opcode (operands[1]);
3008
3009 case 3:
3010 case 4:
3011 return "mov{q}\t{%1, %0|%0, %1}";
3012
3013 case 5:
3014 return "movabs{q}\t{%1, %0|%0, %1}";
3015
3016 case 6:
3017 return "#";
3018
3019 case 7:
3020 return standard_sse_constant_opcode (insn, operands[1]);
3021
3022 case 8:
3023 case 9:
3024 case 10:
3025 switch (get_attr_mode (insn))
3026 {
3027 case MODE_V2DF:
3028 return "%vmovapd\t{%1, %0|%0, %1}";
3029 case MODE_V4SF:
3030 return "%vmovaps\t{%1, %0|%0, %1}";
3031
3032 case MODE_DI:
3033 return "%vmovq\t{%1, %0|%0, %1}";
3034 case MODE_DF:
3035 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3036 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3037 return "%vmovsd\t{%1, %0|%0, %1}";
3038 case MODE_V1DF:
3039 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3040 case MODE_V2SF:
3041 return "%vmovlps\t{%1, %d0|%d0, %1}";
3042 default:
3043 gcc_unreachable ();
3044 }
3045
3046 case 11:
3047 case 12:
3048 /* Handle broken assemblers that require movd instead of movq. */
3049 return "%vmovd\t{%1, %0|%0, %1}";
3050
3051 default:
3052 gcc_unreachable();
3053 }
3054 }
3055 [(set (attr "type")
3056 (cond [(eq_attr "alternative" "0,1,2")
3057 (const_string "fmov")
3058 (eq_attr "alternative" "3,4,5")
3059 (const_string "imov")
3060 (eq_attr "alternative" "6")
3061 (const_string "multi")
3062 (eq_attr "alternative" "7")
3063 (const_string "sselog1")
3064 ]
3065 (const_string "ssemov")))
3066 (set (attr "modrm")
3067 (if_then_else
3068 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3069 (const_string "0")
3070 (const_string "*")))
3071 (set (attr "length_immediate")
3072 (if_then_else
3073 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3074 (const_string "8")
3075 (const_string "*")))
3076 (set (attr "prefix")
3077 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3078 (const_string "orig")
3079 (const_string "maybe_vex")))
3080 (set (attr "prefix_data16")
3081 (if_then_else (eq_attr "mode" "V1DF")
3082 (const_string "1")
3083 (const_string "*")))
3084 (set (attr "mode")
3085 (cond [(eq_attr "alternative" "0,1,2")
3086 (const_string "DF")
3087 (eq_attr "alternative" "3,4,5,6,11,12")
3088 (const_string "DI")
3089
3090 /* xorps is one byte shorter for !TARGET_AVX. */
3091 (eq_attr "alternative" "7")
3092 (cond [(match_test "TARGET_AVX")
3093 (const_string "V2DF")
3094 (match_test "optimize_function_for_size_p (cfun)")
3095 (const_string "V4SF")
3096 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3097 (const_string "TI")
3098 ]
3099 (const_string "V2DF"))
3100
3101 /* For architectures resolving dependencies on
3102 whole SSE registers use APD move to break dependency
3103 chains, otherwise use short move to avoid extra work.
3104
3105 movaps encodes one byte shorter for !TARGET_AVX. */
3106 (eq_attr "alternative" "8")
3107 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3108 (const_string "V4SF")
3109 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3110 (const_string "V2DF")
3111 (match_test "TARGET_AVX")
3112 (const_string "DF")
3113 (match_test "optimize_function_for_size_p (cfun)")
3114 (const_string "V4SF")
3115 ]
3116 (const_string "DF"))
3117 /* For architectures resolving dependencies on register
3118 parts we may avoid extra work to zero out upper part
3119 of register. */
3120 (eq_attr "alternative" "9")
3121 (if_then_else
3122 (match_test "TARGET_SSE_SPLIT_REGS")
3123 (const_string "V1DF")
3124 (const_string "DF"))
3125 ]
3126 (const_string "DF")))])
3127
3128 ;; Possible store forwarding (partial memory) stall in alternative 4.
3129 (define_insn "*movdf_internal"
3130 [(set (match_operand:DF 0 "nonimmediate_operand"
3131 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3132 (match_operand:DF 1 "general_operand"
3133 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3134 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3135 && (!can_create_pseudo_p ()
3136 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3137 || GET_CODE (operands[1]) != CONST_DOUBLE
3138 || (optimize_function_for_size_p (cfun)
3139 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3140 && standard_80387_constant_p (operands[1]) > 0)
3141 || (TARGET_SSE2 && TARGET_SSE_MATH
3142 && standard_sse_constant_p (operands[1])))
3143 && !memory_operand (operands[0], DFmode))
3144 || (!TARGET_MEMORY_MISMATCH_STALL
3145 && memory_operand (operands[0], DFmode)))"
3146 {
3147 switch (which_alternative)
3148 {
3149 case 0:
3150 case 1:
3151 return output_387_reg_move (insn, operands);
3152
3153 case 2:
3154 return standard_80387_constant_opcode (operands[1]);
3155
3156 case 3:
3157 case 4:
3158 return "#";
3159
3160 case 5:
3161 case 9:
3162 return standard_sse_constant_opcode (insn, operands[1]);
3163
3164 case 6:
3165 case 7:
3166 case 8:
3167 case 10:
3168 case 11:
3169 case 12:
3170 switch (get_attr_mode (insn))
3171 {
3172 case MODE_V2DF:
3173 return "%vmovapd\t{%1, %0|%0, %1}";
3174 case MODE_V4SF:
3175 return "%vmovaps\t{%1, %0|%0, %1}";
3176
3177 case MODE_DI:
3178 return "%vmovq\t{%1, %0|%0, %1}";
3179 case MODE_DF:
3180 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3181 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3182 return "%vmovsd\t{%1, %0|%0, %1}";
3183 case MODE_V1DF:
3184 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3185 case MODE_V2SF:
3186 return "%vmovlps\t{%1, %d0|%d0, %1}";
3187 default:
3188 gcc_unreachable ();
3189 }
3190
3191 default:
3192 gcc_unreachable ();
3193 }
3194 }
3195 [(set (attr "isa")
3196 (if_then_else (eq_attr "alternative" "5,6,7,8")
3197 (const_string "sse2")
3198 (const_string "*")))
3199 (set (attr "type")
3200 (cond [(eq_attr "alternative" "0,1,2")
3201 (const_string "fmov")
3202 (eq_attr "alternative" "3,4")
3203 (const_string "multi")
3204 (eq_attr "alternative" "5,9")
3205 (const_string "sselog1")
3206 ]
3207 (const_string "ssemov")))
3208 (set (attr "prefix")
3209 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3210 (const_string "orig")
3211 (const_string "maybe_vex")))
3212 (set (attr "prefix_data16")
3213 (if_then_else (eq_attr "mode" "V1DF")
3214 (const_string "1")
3215 (const_string "*")))
3216 (set (attr "mode")
3217 (cond [(eq_attr "alternative" "0,1,2")
3218 (const_string "DF")
3219 (eq_attr "alternative" "3,4")
3220 (const_string "SI")
3221
3222 /* For SSE1, we have many fewer alternatives. */
3223 (not (match_test "TARGET_SSE2"))
3224 (if_then_else
3225 (eq_attr "alternative" "5,6,9,10")
3226 (const_string "V4SF")
3227 (const_string "V2SF"))
3228
3229 /* xorps is one byte shorter for !TARGET_AVX. */
3230 (eq_attr "alternative" "5,9")
3231 (cond [(match_test "TARGET_AVX")
3232 (const_string "V2DF")
3233 (match_test "optimize_function_for_size_p (cfun)")
3234 (const_string "V4SF")
3235 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3236 (const_string "TI")
3237 ]
3238 (const_string "V2DF"))
3239
3240 /* For architectures resolving dependencies on
3241 whole SSE registers use APD move to break dependency
3242 chains, otherwise use short move to avoid extra work.
3243
3244 movaps encodes one byte shorter for !TARGET_AVX. */
3245 (eq_attr "alternative" "6,10")
3246 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3247 (const_string "V4SF")
3248 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3249 (const_string "V2DF")
3250 (match_test "TARGET_AVX")
3251 (const_string "DF")
3252 (match_test "optimize_function_for_size_p (cfun)")
3253 (const_string "V4SF")
3254 ]
3255 (const_string "DF"))
3256
3257 /* For architectures resolving dependencies on register
3258 parts we may avoid extra work to zero out upper part
3259 of register. */
3260 (eq_attr "alternative" "7,11")
3261 (if_then_else
3262 (match_test "TARGET_SSE_SPLIT_REGS")
3263 (const_string "V1DF")
3264 (const_string "DF"))
3265 ]
3266 (const_string "DF")))])
3267
3268 (define_insn "*movsf_internal"
3269 [(set (match_operand:SF 0 "nonimmediate_operand"
3270 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3271 (match_operand:SF 1 "general_operand"
3272 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3273 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3274 && (!can_create_pseudo_p ()
3275 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3276 || GET_CODE (operands[1]) != CONST_DOUBLE
3277 || (optimize_function_for_size_p (cfun)
3278 && ((!TARGET_SSE_MATH
3279 && standard_80387_constant_p (operands[1]) > 0)
3280 || (TARGET_SSE_MATH
3281 && standard_sse_constant_p (operands[1]))))
3282 || memory_operand (operands[0], SFmode))"
3283 {
3284 switch (which_alternative)
3285 {
3286 case 0:
3287 case 1:
3288 return output_387_reg_move (insn, operands);
3289
3290 case 2:
3291 return standard_80387_constant_opcode (operands[1]);
3292
3293 case 3:
3294 case 4:
3295 return "mov{l}\t{%1, %0|%0, %1}";
3296
3297 case 5:
3298 return standard_sse_constant_opcode (insn, operands[1]);
3299
3300 case 6:
3301 if (get_attr_mode (insn) == MODE_V4SF)
3302 return "%vmovaps\t{%1, %0|%0, %1}";
3303 if (TARGET_AVX)
3304 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3305
3306 case 7:
3307 case 8:
3308 return "%vmovss\t{%1, %0|%0, %1}";
3309
3310 case 9:
3311 case 10:
3312 case 14:
3313 case 15:
3314 return "movd\t{%1, %0|%0, %1}";
3315
3316 case 11:
3317 return "movq\t{%1, %0|%0, %1}";
3318
3319 case 12:
3320 case 13:
3321 return "%vmovd\t{%1, %0|%0, %1}";
3322
3323 default:
3324 gcc_unreachable ();
3325 }
3326 }
3327 [(set (attr "type")
3328 (cond [(eq_attr "alternative" "0,1,2")
3329 (const_string "fmov")
3330 (eq_attr "alternative" "3,4")
3331 (const_string "multi")
3332 (eq_attr "alternative" "5")
3333 (const_string "sselog1")
3334 (eq_attr "alternative" "9,10,11,14,15")
3335 (const_string "mmxmov")
3336 ]
3337 (const_string "ssemov")))
3338 (set (attr "prefix")
3339 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3340 (const_string "maybe_vex")
3341 (const_string "orig")))
3342 (set (attr "mode")
3343 (cond [(eq_attr "alternative" "3,4,9,10")
3344 (const_string "SI")
3345 (eq_attr "alternative" "5")
3346 (cond [(match_test "TARGET_AVX")
3347 (const_string "V4SF")
3348 (ior (not (match_test "TARGET_SSE2"))
3349 (match_test "optimize_function_for_size_p (cfun)"))
3350 (const_string "V4SF")
3351 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3352 (const_string "TI")
3353 ]
3354 (const_string "V4SF"))
3355
3356 /* For architectures resolving dependencies on
3357 whole SSE registers use APS move to break dependency
3358 chains, otherwise use short move to avoid extra work.
3359
3360 Do the same for architectures resolving dependencies on
3361 the parts. While in DF mode it is better to always handle
3362 just register parts, the SF mode is different due to lack
3363 of instructions to load just part of the register. It is
3364 better to maintain the whole registers in single format
3365 to avoid problems on using packed logical operations. */
3366 (eq_attr "alternative" "6")
3367 (if_then_else
3368 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3369 (match_test "TARGET_SSE_SPLIT_REGS"))
3370 (const_string "V4SF")
3371 (const_string "SF"))
3372 (eq_attr "alternative" "11")
3373 (const_string "DI")]
3374 (const_string "SF")))])
3375
3376 (define_split
3377 [(set (match_operand 0 "any_fp_register_operand")
3378 (match_operand 1 "memory_operand"))]
3379 "reload_completed
3380 && (GET_MODE (operands[0]) == TFmode
3381 || GET_MODE (operands[0]) == XFmode
3382 || GET_MODE (operands[0]) == DFmode
3383 || GET_MODE (operands[0]) == SFmode)
3384 && (operands[2] = find_constant_src (insn))"
3385 [(set (match_dup 0) (match_dup 2))]
3386 {
3387 rtx c = operands[2];
3388 int r = REGNO (operands[0]);
3389
3390 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3391 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3392 FAIL;
3393 })
3394
3395 (define_split
3396 [(set (match_operand 0 "any_fp_register_operand")
3397 (float_extend (match_operand 1 "memory_operand")))]
3398 "reload_completed
3399 && (GET_MODE (operands[0]) == TFmode
3400 || GET_MODE (operands[0]) == XFmode
3401 || GET_MODE (operands[0]) == DFmode)
3402 && (operands[2] = find_constant_src (insn))"
3403 [(set (match_dup 0) (match_dup 2))]
3404 {
3405 rtx c = operands[2];
3406 int r = REGNO (operands[0]);
3407
3408 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3409 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3410 FAIL;
3411 })
3412
3413 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3414 (define_split
3415 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3416 (match_operand:X87MODEF 1 "immediate_operand"))]
3417 "reload_completed
3418 && (standard_80387_constant_p (operands[1]) == 8
3419 || standard_80387_constant_p (operands[1]) == 9)"
3420 [(set (match_dup 0)(match_dup 1))
3421 (set (match_dup 0)
3422 (neg:X87MODEF (match_dup 0)))]
3423 {
3424 REAL_VALUE_TYPE r;
3425
3426 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3427 if (real_isnegzero (&r))
3428 operands[1] = CONST0_RTX (<MODE>mode);
3429 else
3430 operands[1] = CONST1_RTX (<MODE>mode);
3431 })
3432
3433 (define_split
3434 [(set (match_operand 0 "nonimmediate_operand")
3435 (match_operand 1 "general_operand"))]
3436 "reload_completed
3437 && (GET_MODE (operands[0]) == TFmode
3438 || GET_MODE (operands[0]) == XFmode
3439 || GET_MODE (operands[0]) == DFmode)
3440 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3441 [(const_int 0)]
3442 "ix86_split_long_move (operands); DONE;")
3443
3444 (define_insn "swapxf"
3445 [(set (match_operand:XF 0 "register_operand" "+f")
3446 (match_operand:XF 1 "register_operand" "+f"))
3447 (set (match_dup 1)
3448 (match_dup 0))]
3449 "TARGET_80387"
3450 {
3451 if (STACK_TOP_P (operands[0]))
3452 return "fxch\t%1";
3453 else
3454 return "fxch\t%0";
3455 }
3456 [(set_attr "type" "fxch")
3457 (set_attr "mode" "XF")])
3458
3459 (define_insn "*swap<mode>"
3460 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3461 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3462 (set (match_dup 1)
3463 (match_dup 0))]
3464 "TARGET_80387 || reload_completed"
3465 {
3466 if (STACK_TOP_P (operands[0]))
3467 return "fxch\t%1";
3468 else
3469 return "fxch\t%0";
3470 }
3471 [(set_attr "type" "fxch")
3472 (set_attr "mode" "<MODE>")])
3473 \f
3474 ;; Zero extension instructions
3475
3476 (define_expand "zero_extendsidi2"
3477 [(set (match_operand:DI 0 "nonimmediate_operand")
3478 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3479
3480 (define_insn "*zero_extendsidi2_rex64"
3481 [(set (match_operand:DI 0 "nonimmediate_operand"
3482 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3483 (zero_extend:DI
3484 (match_operand:SI 1 "x86_64_zext_general_operand"
3485 "rmWz,0,r ,m ,r ,m")))]
3486 "TARGET_64BIT"
3487 {
3488 switch (get_attr_type (insn))
3489 {
3490 case TYPE_IMOVX:
3491 if (ix86_use_lea_for_mov (insn, operands))
3492 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3493 else
3494 return "mov{l}\t{%1, %k0|%k0, %1}";
3495
3496 case TYPE_MULTI:
3497 return "#";
3498
3499 case TYPE_MMXMOV:
3500 return "movd\t{%1, %0|%0, %1}";
3501
3502 case TYPE_SSEMOV:
3503 return "%vmovd\t{%1, %0|%0, %1}";
3504
3505 default:
3506 gcc_unreachable ();
3507 }
3508 }
3509 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3510 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3511 (set_attr "prefix_0f" "0,*,*,*,*,*")
3512 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3513
3514 (define_insn "*zero_extendsidi2"
3515 [(set (match_operand:DI 0 "nonimmediate_operand"
3516 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3517 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3518 "0 ,rm,r ,r ,m ,r ,m")))]
3519 "!TARGET_64BIT"
3520 "@
3521 #
3522 #
3523 #
3524 movd\t{%1, %0|%0, %1}
3525 movd\t{%1, %0|%0, %1}
3526 %vmovd\t{%1, %0|%0, %1}
3527 %vmovd\t{%1, %0|%0, %1}"
3528 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3529 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3530 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3531 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3532
3533 (define_split
3534 [(set (match_operand:DI 0 "memory_operand")
3535 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3536 "reload_completed"
3537 [(set (match_dup 4) (const_int 0))]
3538 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3539
3540 (define_split
3541 [(set (match_operand:DI 0 "register_operand")
3542 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3543 "!TARGET_64BIT && reload_completed
3544 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3545 && true_regnum (operands[0]) == true_regnum (operands[1])"
3546 [(set (match_dup 4) (const_int 0))]
3547 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3548
3549 (define_split
3550 [(set (match_operand:DI 0 "nonimmediate_operand")
3551 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3552 "!TARGET_64BIT && reload_completed
3553 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3554 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3555 [(set (match_dup 3) (match_dup 1))
3556 (set (match_dup 4) (const_int 0))]
3557 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3558
3559 (define_insn "zero_extend<mode>di2"
3560 [(set (match_operand:DI 0 "register_operand" "=r")
3561 (zero_extend:DI
3562 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3563 "TARGET_64BIT"
3564 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3565 [(set_attr "type" "imovx")
3566 (set_attr "mode" "SI")])
3567
3568 (define_expand "zero_extend<mode>si2"
3569 [(set (match_operand:SI 0 "register_operand")
3570 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3571 ""
3572 {
3573 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3574 {
3575 operands[1] = force_reg (<MODE>mode, operands[1]);
3576 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3577 DONE;
3578 }
3579 })
3580
3581 (define_insn_and_split "zero_extend<mode>si2_and"
3582 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3583 (zero_extend:SI
3584 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3585 (clobber (reg:CC FLAGS_REG))]
3586 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3587 "#"
3588 "&& reload_completed"
3589 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3590 (clobber (reg:CC FLAGS_REG))])]
3591 {
3592 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3593 {
3594 ix86_expand_clear (operands[0]);
3595
3596 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3597 emit_insn (gen_movstrict<mode>
3598 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3599 DONE;
3600 }
3601
3602 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3603 }
3604 [(set_attr "type" "alu1")
3605 (set_attr "mode" "SI")])
3606
3607 (define_insn "*zero_extend<mode>si2"
3608 [(set (match_operand:SI 0 "register_operand" "=r")
3609 (zero_extend:SI
3610 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3611 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3612 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3613 [(set_attr "type" "imovx")
3614 (set_attr "mode" "SI")])
3615
3616 (define_expand "zero_extendqihi2"
3617 [(set (match_operand:HI 0 "register_operand")
3618 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3619 ""
3620 {
3621 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3622 {
3623 operands[1] = force_reg (QImode, operands[1]);
3624 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3625 DONE;
3626 }
3627 })
3628
3629 (define_insn_and_split "zero_extendqihi2_and"
3630 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3631 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3632 (clobber (reg:CC FLAGS_REG))]
3633 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3634 "#"
3635 "&& reload_completed"
3636 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3637 (clobber (reg:CC FLAGS_REG))])]
3638 {
3639 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3640 {
3641 ix86_expand_clear (operands[0]);
3642
3643 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3644 emit_insn (gen_movstrictqi
3645 (gen_lowpart (QImode, operands[0]), operands[1]));
3646 DONE;
3647 }
3648
3649 operands[0] = gen_lowpart (SImode, operands[0]);
3650 }
3651 [(set_attr "type" "alu1")
3652 (set_attr "mode" "SI")])
3653
3654 ; zero extend to SImode to avoid partial register stalls
3655 (define_insn "*zero_extendqihi2"
3656 [(set (match_operand:HI 0 "register_operand" "=r")
3657 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3658 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3659 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3660 [(set_attr "type" "imovx")
3661 (set_attr "mode" "SI")])
3662 \f
3663 ;; Sign extension instructions
3664
3665 (define_expand "extendsidi2"
3666 [(set (match_operand:DI 0 "register_operand")
3667 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3668 ""
3669 {
3670 if (!TARGET_64BIT)
3671 {
3672 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3673 DONE;
3674 }
3675 })
3676
3677 (define_insn "*extendsidi2_rex64"
3678 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3679 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3680 "TARGET_64BIT"
3681 "@
3682 {cltq|cdqe}
3683 movs{lq|x}\t{%1, %0|%0, %1}"
3684 [(set_attr "type" "imovx")
3685 (set_attr "mode" "DI")
3686 (set_attr "prefix_0f" "0")
3687 (set_attr "modrm" "0,1")])
3688
3689 (define_insn "extendsidi2_1"
3690 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3691 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3692 (clobber (reg:CC FLAGS_REG))
3693 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3694 "!TARGET_64BIT"
3695 "#")
3696
3697 ;; Extend to memory case when source register does die.
3698 (define_split
3699 [(set (match_operand:DI 0 "memory_operand")
3700 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3701 (clobber (reg:CC FLAGS_REG))
3702 (clobber (match_operand:SI 2 "register_operand"))]
3703 "(reload_completed
3704 && dead_or_set_p (insn, operands[1])
3705 && !reg_mentioned_p (operands[1], operands[0]))"
3706 [(set (match_dup 3) (match_dup 1))
3707 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3708 (clobber (reg:CC FLAGS_REG))])
3709 (set (match_dup 4) (match_dup 1))]
3710 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3711
3712 ;; Extend to memory case when source register does not die.
3713 (define_split
3714 [(set (match_operand:DI 0 "memory_operand")
3715 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3716 (clobber (reg:CC FLAGS_REG))
3717 (clobber (match_operand:SI 2 "register_operand"))]
3718 "reload_completed"
3719 [(const_int 0)]
3720 {
3721 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3722
3723 emit_move_insn (operands[3], operands[1]);
3724
3725 /* Generate a cltd if possible and doing so it profitable. */
3726 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3727 && true_regnum (operands[1]) == AX_REG
3728 && true_regnum (operands[2]) == DX_REG)
3729 {
3730 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3731 }
3732 else
3733 {
3734 emit_move_insn (operands[2], operands[1]);
3735 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3736 }
3737 emit_move_insn (operands[4], operands[2]);
3738 DONE;
3739 })
3740
3741 ;; Extend to register case. Optimize case where source and destination
3742 ;; registers match and cases where we can use cltd.
3743 (define_split
3744 [(set (match_operand:DI 0 "register_operand")
3745 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3746 (clobber (reg:CC FLAGS_REG))
3747 (clobber (match_scratch:SI 2))]
3748 "reload_completed"
3749 [(const_int 0)]
3750 {
3751 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3752
3753 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3754 emit_move_insn (operands[3], operands[1]);
3755
3756 /* Generate a cltd if possible and doing so it profitable. */
3757 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3758 && true_regnum (operands[3]) == AX_REG
3759 && true_regnum (operands[4]) == DX_REG)
3760 {
3761 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3762 DONE;
3763 }
3764
3765 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3766 emit_move_insn (operands[4], operands[1]);
3767
3768 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3769 DONE;
3770 })
3771
3772 (define_insn "extend<mode>di2"
3773 [(set (match_operand:DI 0 "register_operand" "=r")
3774 (sign_extend:DI
3775 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3776 "TARGET_64BIT"
3777 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3778 [(set_attr "type" "imovx")
3779 (set_attr "mode" "DI")])
3780
3781 (define_insn "extendhisi2"
3782 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3783 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3784 ""
3785 {
3786 switch (get_attr_prefix_0f (insn))
3787 {
3788 case 0:
3789 return "{cwtl|cwde}";
3790 default:
3791 return "movs{wl|x}\t{%1, %0|%0, %1}";
3792 }
3793 }
3794 [(set_attr "type" "imovx")
3795 (set_attr "mode" "SI")
3796 (set (attr "prefix_0f")
3797 ;; movsx is short decodable while cwtl is vector decoded.
3798 (if_then_else (and (eq_attr "cpu" "!k6")
3799 (eq_attr "alternative" "0"))
3800 (const_string "0")
3801 (const_string "1")))
3802 (set (attr "modrm")
3803 (if_then_else (eq_attr "prefix_0f" "0")
3804 (const_string "0")
3805 (const_string "1")))])
3806
3807 (define_insn "*extendhisi2_zext"
3808 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3809 (zero_extend:DI
3810 (sign_extend:SI
3811 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3812 "TARGET_64BIT"
3813 {
3814 switch (get_attr_prefix_0f (insn))
3815 {
3816 case 0:
3817 return "{cwtl|cwde}";
3818 default:
3819 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3820 }
3821 }
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")
3824 (set (attr "prefix_0f")
3825 ;; movsx is short decodable while cwtl is vector decoded.
3826 (if_then_else (and (eq_attr "cpu" "!k6")
3827 (eq_attr "alternative" "0"))
3828 (const_string "0")
3829 (const_string "1")))
3830 (set (attr "modrm")
3831 (if_then_else (eq_attr "prefix_0f" "0")
3832 (const_string "0")
3833 (const_string "1")))])
3834
3835 (define_insn "extendqisi2"
3836 [(set (match_operand:SI 0 "register_operand" "=r")
3837 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3838 ""
3839 "movs{bl|x}\t{%1, %0|%0, %1}"
3840 [(set_attr "type" "imovx")
3841 (set_attr "mode" "SI")])
3842
3843 (define_insn "*extendqisi2_zext"
3844 [(set (match_operand:DI 0 "register_operand" "=r")
3845 (zero_extend:DI
3846 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3847 "TARGET_64BIT"
3848 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3849 [(set_attr "type" "imovx")
3850 (set_attr "mode" "SI")])
3851
3852 (define_insn "extendqihi2"
3853 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3854 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3855 ""
3856 {
3857 switch (get_attr_prefix_0f (insn))
3858 {
3859 case 0:
3860 return "{cbtw|cbw}";
3861 default:
3862 return "movs{bw|x}\t{%1, %0|%0, %1}";
3863 }
3864 }
3865 [(set_attr "type" "imovx")
3866 (set_attr "mode" "HI")
3867 (set (attr "prefix_0f")
3868 ;; movsx is short decodable while cwtl is vector decoded.
3869 (if_then_else (and (eq_attr "cpu" "!k6")
3870 (eq_attr "alternative" "0"))
3871 (const_string "0")
3872 (const_string "1")))
3873 (set (attr "modrm")
3874 (if_then_else (eq_attr "prefix_0f" "0")
3875 (const_string "0")
3876 (const_string "1")))])
3877 \f
3878 ;; Conversions between float and double.
3879
3880 ;; These are all no-ops in the model used for the 80387.
3881 ;; So just emit moves.
3882
3883 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3884 (define_split
3885 [(set (match_operand:DF 0 "push_operand")
3886 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3887 "reload_completed"
3888 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3889 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3890
3891 (define_split
3892 [(set (match_operand:XF 0 "push_operand")
3893 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3894 "reload_completed"
3895 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3896 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3897 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3898
3899 (define_expand "extendsfdf2"
3900 [(set (match_operand:DF 0 "nonimmediate_operand")
3901 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3902 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3903 {
3904 /* ??? Needed for compress_float_constant since all fp constants
3905 are TARGET_LEGITIMATE_CONSTANT_P. */
3906 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3907 {
3908 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3909 && standard_80387_constant_p (operands[1]) > 0)
3910 {
3911 operands[1] = simplify_const_unary_operation
3912 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3913 emit_move_insn_1 (operands[0], operands[1]);
3914 DONE;
3915 }
3916 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3917 }
3918 })
3919
3920 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3921 cvtss2sd:
3922 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3923 cvtps2pd xmm2,xmm1
3924 We do the conversion post reload to avoid producing of 128bit spills
3925 that might lead to ICE on 32bit target. The sequence unlikely combine
3926 anyway. */
3927 (define_split
3928 [(set (match_operand:DF 0 "register_operand")
3929 (float_extend:DF
3930 (match_operand:SF 1 "nonimmediate_operand")))]
3931 "TARGET_USE_VECTOR_FP_CONVERTS
3932 && optimize_insn_for_speed_p ()
3933 && reload_completed && SSE_REG_P (operands[0])"
3934 [(set (match_dup 2)
3935 (float_extend:V2DF
3936 (vec_select:V2SF
3937 (match_dup 3)
3938 (parallel [(const_int 0) (const_int 1)]))))]
3939 {
3940 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3941 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3942 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3943 Try to avoid move when unpacking can be done in source. */
3944 if (REG_P (operands[1]))
3945 {
3946 /* If it is unsafe to overwrite upper half of source, we need
3947 to move to destination and unpack there. */
3948 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3949 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3950 && true_regnum (operands[0]) != true_regnum (operands[1]))
3951 {
3952 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3953 emit_move_insn (tmp, operands[1]);
3954 }
3955 else
3956 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3957 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3958 operands[3]));
3959 }
3960 else
3961 emit_insn (gen_vec_setv4sf_0 (operands[3],
3962 CONST0_RTX (V4SFmode), operands[1]));
3963 })
3964
3965 (define_insn "*extendsfdf2_mixed"
3966 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3967 (float_extend:DF
3968 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3969 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3970 {
3971 switch (which_alternative)
3972 {
3973 case 0:
3974 case 1:
3975 return output_387_reg_move (insn, operands);
3976
3977 case 2:
3978 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3979
3980 default:
3981 gcc_unreachable ();
3982 }
3983 }
3984 [(set_attr "type" "fmov,fmov,ssecvt")
3985 (set_attr "prefix" "orig,orig,maybe_vex")
3986 (set_attr "mode" "SF,XF,DF")])
3987
3988 (define_insn "*extendsfdf2_sse"
3989 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3990 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3991 "TARGET_SSE2 && TARGET_SSE_MATH"
3992 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3993 [(set_attr "type" "ssecvt")
3994 (set_attr "prefix" "maybe_vex")
3995 (set_attr "mode" "DF")])
3996
3997 (define_insn "*extendsfdf2_i387"
3998 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3999 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4000 "TARGET_80387"
4001 "* return output_387_reg_move (insn, operands);"
4002 [(set_attr "type" "fmov")
4003 (set_attr "mode" "SF,XF")])
4004
4005 (define_expand "extend<mode>xf2"
4006 [(set (match_operand:XF 0 "nonimmediate_operand")
4007 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4008 "TARGET_80387"
4009 {
4010 /* ??? Needed for compress_float_constant since all fp constants
4011 are TARGET_LEGITIMATE_CONSTANT_P. */
4012 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4013 {
4014 if (standard_80387_constant_p (operands[1]) > 0)
4015 {
4016 operands[1] = simplify_const_unary_operation
4017 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4018 emit_move_insn_1 (operands[0], operands[1]);
4019 DONE;
4020 }
4021 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4022 }
4023 })
4024
4025 (define_insn "*extend<mode>xf2_i387"
4026 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4027 (float_extend:XF
4028 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4029 "TARGET_80387"
4030 "* return output_387_reg_move (insn, operands);"
4031 [(set_attr "type" "fmov")
4032 (set_attr "mode" "<MODE>,XF")])
4033
4034 ;; %%% This seems bad bad news.
4035 ;; This cannot output into an f-reg because there is no way to be sure
4036 ;; of truncating in that case. Otherwise this is just like a simple move
4037 ;; insn. So we pretend we can output to a reg in order to get better
4038 ;; register preferencing, but we really use a stack slot.
4039
4040 ;; Conversion from DFmode to SFmode.
4041
4042 (define_expand "truncdfsf2"
4043 [(set (match_operand:SF 0 "nonimmediate_operand")
4044 (float_truncate:SF
4045 (match_operand:DF 1 "nonimmediate_operand")))]
4046 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4047 {
4048 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4049 ;
4050 else if (flag_unsafe_math_optimizations)
4051 ;
4052 else
4053 {
4054 enum ix86_stack_slot slot = (virtuals_instantiated
4055 ? SLOT_TEMP
4056 : SLOT_VIRTUAL);
4057 rtx temp = assign_386_stack_local (SFmode, slot);
4058 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4059 DONE;
4060 }
4061 })
4062
4063 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4064 cvtsd2ss:
4065 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4066 cvtpd2ps xmm2,xmm1
4067 We do the conversion post reload to avoid producing of 128bit spills
4068 that might lead to ICE on 32bit target. The sequence unlikely combine
4069 anyway. */
4070 (define_split
4071 [(set (match_operand:SF 0 "register_operand")
4072 (float_truncate:SF
4073 (match_operand:DF 1 "nonimmediate_operand")))]
4074 "TARGET_USE_VECTOR_FP_CONVERTS
4075 && optimize_insn_for_speed_p ()
4076 && reload_completed && SSE_REG_P (operands[0])"
4077 [(set (match_dup 2)
4078 (vec_concat:V4SF
4079 (float_truncate:V2SF
4080 (match_dup 4))
4081 (match_dup 3)))]
4082 {
4083 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4084 operands[3] = CONST0_RTX (V2SFmode);
4085 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4086 /* Use movsd for loading from memory, unpcklpd for registers.
4087 Try to avoid move when unpacking can be done in source, or SSE3
4088 movddup is available. */
4089 if (REG_P (operands[1]))
4090 {
4091 if (!TARGET_SSE3
4092 && true_regnum (operands[0]) != true_regnum (operands[1])
4093 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4094 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4095 {
4096 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4097 emit_move_insn (tmp, operands[1]);
4098 operands[1] = tmp;
4099 }
4100 else if (!TARGET_SSE3)
4101 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4102 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4103 }
4104 else
4105 emit_insn (gen_sse2_loadlpd (operands[4],
4106 CONST0_RTX (V2DFmode), operands[1]));
4107 })
4108
4109 (define_expand "truncdfsf2_with_temp"
4110 [(parallel [(set (match_operand:SF 0)
4111 (float_truncate:SF (match_operand:DF 1)))
4112 (clobber (match_operand:SF 2))])])
4113
4114 (define_insn "*truncdfsf_fast_mixed"
4115 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4116 (float_truncate:SF
4117 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4118 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4119 {
4120 switch (which_alternative)
4121 {
4122 case 0:
4123 return output_387_reg_move (insn, operands);
4124 case 1:
4125 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4126 default:
4127 gcc_unreachable ();
4128 }
4129 }
4130 [(set_attr "type" "fmov,ssecvt")
4131 (set_attr "prefix" "orig,maybe_vex")
4132 (set_attr "mode" "SF")])
4133
4134 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4135 ;; because nothing we do here is unsafe.
4136 (define_insn "*truncdfsf_fast_sse"
4137 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4138 (float_truncate:SF
4139 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4140 "TARGET_SSE2 && TARGET_SSE_MATH"
4141 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4142 [(set_attr "type" "ssecvt")
4143 (set_attr "prefix" "maybe_vex")
4144 (set_attr "mode" "SF")])
4145
4146 (define_insn "*truncdfsf_fast_i387"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4148 (float_truncate:SF
4149 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4150 "TARGET_80387 && flag_unsafe_math_optimizations"
4151 "* return output_387_reg_move (insn, operands);"
4152 [(set_attr "type" "fmov")
4153 (set_attr "mode" "SF")])
4154
4155 (define_insn "*truncdfsf_mixed"
4156 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4157 (float_truncate:SF
4158 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4159 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4160 "TARGET_MIX_SSE_I387"
4161 {
4162 switch (which_alternative)
4163 {
4164 case 0:
4165 return output_387_reg_move (insn, operands);
4166 case 1:
4167 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4168
4169 default:
4170 return "#";
4171 }
4172 }
4173 [(set_attr "isa" "*,sse2,*,*,*")
4174 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4175 (set_attr "unit" "*,*,i387,i387,i387")
4176 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4177 (set_attr "mode" "SF")])
4178
4179 (define_insn "*truncdfsf_i387"
4180 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4181 (float_truncate:SF
4182 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4183 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4184 "TARGET_80387"
4185 {
4186 switch (which_alternative)
4187 {
4188 case 0:
4189 return output_387_reg_move (insn, operands);
4190
4191 default:
4192 return "#";
4193 }
4194 }
4195 [(set_attr "type" "fmov,multi,multi,multi")
4196 (set_attr "unit" "*,i387,i387,i387")
4197 (set_attr "mode" "SF")])
4198
4199 (define_insn "*truncdfsf2_i387_1"
4200 [(set (match_operand:SF 0 "memory_operand" "=m")
4201 (float_truncate:SF
4202 (match_operand:DF 1 "register_operand" "f")))]
4203 "TARGET_80387
4204 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4205 && !TARGET_MIX_SSE_I387"
4206 "* return output_387_reg_move (insn, operands);"
4207 [(set_attr "type" "fmov")
4208 (set_attr "mode" "SF")])
4209
4210 (define_split
4211 [(set (match_operand:SF 0 "register_operand")
4212 (float_truncate:SF
4213 (match_operand:DF 1 "fp_register_operand")))
4214 (clobber (match_operand 2))]
4215 "reload_completed"
4216 [(set (match_dup 2) (match_dup 1))
4217 (set (match_dup 0) (match_dup 2))]
4218 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4219
4220 ;; Conversion from XFmode to {SF,DF}mode
4221
4222 (define_expand "truncxf<mode>2"
4223 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4224 (float_truncate:MODEF
4225 (match_operand:XF 1 "register_operand")))
4226 (clobber (match_dup 2))])]
4227 "TARGET_80387"
4228 {
4229 if (flag_unsafe_math_optimizations)
4230 {
4231 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4232 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4233 if (reg != operands[0])
4234 emit_move_insn (operands[0], reg);
4235 DONE;
4236 }
4237 else
4238 {
4239 enum ix86_stack_slot slot = (virtuals_instantiated
4240 ? SLOT_TEMP
4241 : SLOT_VIRTUAL);
4242 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4243 }
4244 })
4245
4246 (define_insn "*truncxfsf2_mixed"
4247 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4248 (float_truncate:SF
4249 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4250 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4251 "TARGET_80387"
4252 {
4253 gcc_assert (!which_alternative);
4254 return output_387_reg_move (insn, operands);
4255 }
4256 [(set_attr "type" "fmov,multi,multi,multi")
4257 (set_attr "unit" "*,i387,i387,i387")
4258 (set_attr "mode" "SF")])
4259
4260 (define_insn "*truncxfdf2_mixed"
4261 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4262 (float_truncate:DF
4263 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4264 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4265 "TARGET_80387"
4266 {
4267 gcc_assert (!which_alternative);
4268 return output_387_reg_move (insn, operands);
4269 }
4270 [(set_attr "isa" "*,*,sse2,*")
4271 (set_attr "type" "fmov,multi,multi,multi")
4272 (set_attr "unit" "*,i387,i387,i387")
4273 (set_attr "mode" "DF")])
4274
4275 (define_insn "truncxf<mode>2_i387_noop"
4276 [(set (match_operand:MODEF 0 "register_operand" "=f")
4277 (float_truncate:MODEF
4278 (match_operand:XF 1 "register_operand" "f")))]
4279 "TARGET_80387 && flag_unsafe_math_optimizations"
4280 "* return output_387_reg_move (insn, operands);"
4281 [(set_attr "type" "fmov")
4282 (set_attr "mode" "<MODE>")])
4283
4284 (define_insn "*truncxf<mode>2_i387"
4285 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4286 (float_truncate:MODEF
4287 (match_operand:XF 1 "register_operand" "f")))]
4288 "TARGET_80387"
4289 "* return output_387_reg_move (insn, operands);"
4290 [(set_attr "type" "fmov")
4291 (set_attr "mode" "<MODE>")])
4292
4293 (define_split
4294 [(set (match_operand:MODEF 0 "register_operand")
4295 (float_truncate:MODEF
4296 (match_operand:XF 1 "register_operand")))
4297 (clobber (match_operand:MODEF 2 "memory_operand"))]
4298 "TARGET_80387 && reload_completed"
4299 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4300 (set (match_dup 0) (match_dup 2))])
4301
4302 (define_split
4303 [(set (match_operand:MODEF 0 "memory_operand")
4304 (float_truncate:MODEF
4305 (match_operand:XF 1 "register_operand")))
4306 (clobber (match_operand:MODEF 2 "memory_operand"))]
4307 "TARGET_80387"
4308 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4309 \f
4310 ;; Signed conversion to DImode.
4311
4312 (define_expand "fix_truncxfdi2"
4313 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4314 (fix:DI (match_operand:XF 1 "register_operand")))
4315 (clobber (reg:CC FLAGS_REG))])]
4316 "TARGET_80387"
4317 {
4318 if (TARGET_FISTTP)
4319 {
4320 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4321 DONE;
4322 }
4323 })
4324
4325 (define_expand "fix_trunc<mode>di2"
4326 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4327 (fix:DI (match_operand:MODEF 1 "register_operand")))
4328 (clobber (reg:CC FLAGS_REG))])]
4329 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4330 {
4331 if (TARGET_FISTTP
4332 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4333 {
4334 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4335 DONE;
4336 }
4337 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4338 {
4339 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4340 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4341 if (out != operands[0])
4342 emit_move_insn (operands[0], out);
4343 DONE;
4344 }
4345 })
4346
4347 ;; Signed conversion to SImode.
4348
4349 (define_expand "fix_truncxfsi2"
4350 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4351 (fix:SI (match_operand:XF 1 "register_operand")))
4352 (clobber (reg:CC FLAGS_REG))])]
4353 "TARGET_80387"
4354 {
4355 if (TARGET_FISTTP)
4356 {
4357 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4358 DONE;
4359 }
4360 })
4361
4362 (define_expand "fix_trunc<mode>si2"
4363 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4364 (fix:SI (match_operand:MODEF 1 "register_operand")))
4365 (clobber (reg:CC FLAGS_REG))])]
4366 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4367 {
4368 if (TARGET_FISTTP
4369 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4370 {
4371 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4372 DONE;
4373 }
4374 if (SSE_FLOAT_MODE_P (<MODE>mode))
4375 {
4376 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4377 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4378 if (out != operands[0])
4379 emit_move_insn (operands[0], out);
4380 DONE;
4381 }
4382 })
4383
4384 ;; Signed conversion to HImode.
4385
4386 (define_expand "fix_trunc<mode>hi2"
4387 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4388 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4389 (clobber (reg:CC FLAGS_REG))])]
4390 "TARGET_80387
4391 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4392 {
4393 if (TARGET_FISTTP)
4394 {
4395 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4396 DONE;
4397 }
4398 })
4399
4400 ;; Unsigned conversion to SImode.
4401
4402 (define_expand "fixuns_trunc<mode>si2"
4403 [(parallel
4404 [(set (match_operand:SI 0 "register_operand")
4405 (unsigned_fix:SI
4406 (match_operand:MODEF 1 "nonimmediate_operand")))
4407 (use (match_dup 2))
4408 (clobber (match_scratch:<ssevecmode> 3))
4409 (clobber (match_scratch:<ssevecmode> 4))])]
4410 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4411 {
4412 enum machine_mode mode = <MODE>mode;
4413 enum machine_mode vecmode = <ssevecmode>mode;
4414 REAL_VALUE_TYPE TWO31r;
4415 rtx two31;
4416
4417 if (optimize_insn_for_size_p ())
4418 FAIL;
4419
4420 real_ldexp (&TWO31r, &dconst1, 31);
4421 two31 = const_double_from_real_value (TWO31r, mode);
4422 two31 = ix86_build_const_vector (vecmode, true, two31);
4423 operands[2] = force_reg (vecmode, two31);
4424 })
4425
4426 (define_insn_and_split "*fixuns_trunc<mode>_1"
4427 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4428 (unsigned_fix:SI
4429 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4430 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4431 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4432 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4433 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4434 && optimize_function_for_speed_p (cfun)"
4435 "#"
4436 "&& reload_completed"
4437 [(const_int 0)]
4438 {
4439 ix86_split_convert_uns_si_sse (operands);
4440 DONE;
4441 })
4442
4443 ;; Unsigned conversion to HImode.
4444 ;; Without these patterns, we'll try the unsigned SI conversion which
4445 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4446
4447 (define_expand "fixuns_trunc<mode>hi2"
4448 [(set (match_dup 2)
4449 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4450 (set (match_operand:HI 0 "nonimmediate_operand")
4451 (subreg:HI (match_dup 2) 0))]
4452 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4453 "operands[2] = gen_reg_rtx (SImode);")
4454
4455 ;; When SSE is available, it is always faster to use it!
4456 (define_insn "fix_trunc<mode>di_sse"
4457 [(set (match_operand:DI 0 "register_operand" "=r,r")
4458 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4459 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4460 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4461 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4462 [(set_attr "type" "sseicvt")
4463 (set_attr "prefix" "maybe_vex")
4464 (set_attr "prefix_rex" "1")
4465 (set_attr "mode" "<MODE>")
4466 (set_attr "athlon_decode" "double,vector")
4467 (set_attr "amdfam10_decode" "double,double")
4468 (set_attr "bdver1_decode" "double,double")])
4469
4470 (define_insn "fix_trunc<mode>si_sse"
4471 [(set (match_operand:SI 0 "register_operand" "=r,r")
4472 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4473 "SSE_FLOAT_MODE_P (<MODE>mode)
4474 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4475 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4476 [(set_attr "type" "sseicvt")
4477 (set_attr "prefix" "maybe_vex")
4478 (set_attr "mode" "<MODE>")
4479 (set_attr "athlon_decode" "double,vector")
4480 (set_attr "amdfam10_decode" "double,double")
4481 (set_attr "bdver1_decode" "double,double")])
4482
4483 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4484 (define_peephole2
4485 [(set (match_operand:MODEF 0 "register_operand")
4486 (match_operand:MODEF 1 "memory_operand"))
4487 (set (match_operand:SWI48x 2 "register_operand")
4488 (fix:SWI48x (match_dup 0)))]
4489 "TARGET_SHORTEN_X87_SSE
4490 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4491 && peep2_reg_dead_p (2, operands[0])"
4492 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4493
4494 ;; Avoid vector decoded forms of the instruction.
4495 (define_peephole2
4496 [(match_scratch:DF 2 "x")
4497 (set (match_operand:SWI48x 0 "register_operand")
4498 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4499 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4500 [(set (match_dup 2) (match_dup 1))
4501 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4502
4503 (define_peephole2
4504 [(match_scratch:SF 2 "x")
4505 (set (match_operand:SWI48x 0 "register_operand")
4506 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4507 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4508 [(set (match_dup 2) (match_dup 1))
4509 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4510
4511 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4512 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4513 (fix:SWI248x (match_operand 1 "register_operand")))]
4514 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && TARGET_FISTTP
4516 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4517 && (TARGET_64BIT || <MODE>mode != DImode))
4518 && TARGET_SSE_MATH)
4519 && can_create_pseudo_p ()"
4520 "#"
4521 "&& 1"
4522 [(const_int 0)]
4523 {
4524 if (memory_operand (operands[0], VOIDmode))
4525 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4526 else
4527 {
4528 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4529 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4530 operands[1],
4531 operands[2]));
4532 }
4533 DONE;
4534 }
4535 [(set_attr "type" "fisttp")
4536 (set_attr "mode" "<MODE>")])
4537
4538 (define_insn "fix_trunc<mode>_i387_fisttp"
4539 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4540 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4541 (clobber (match_scratch:XF 2 "=&1f"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543 && TARGET_FISTTP
4544 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4545 && (TARGET_64BIT || <MODE>mode != DImode))
4546 && TARGET_SSE_MATH)"
4547 "* return output_fix_trunc (insn, operands, true);"
4548 [(set_attr "type" "fisttp")
4549 (set_attr "mode" "<MODE>")])
4550
4551 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4552 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4553 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4554 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4555 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4556 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4557 && TARGET_FISTTP
4558 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4559 && (TARGET_64BIT || <MODE>mode != DImode))
4560 && TARGET_SSE_MATH)"
4561 "#"
4562 [(set_attr "type" "fisttp")
4563 (set_attr "mode" "<MODE>")])
4564
4565 (define_split
4566 [(set (match_operand:SWI248x 0 "register_operand")
4567 (fix:SWI248x (match_operand 1 "register_operand")))
4568 (clobber (match_operand:SWI248x 2 "memory_operand"))
4569 (clobber (match_scratch 3))]
4570 "reload_completed"
4571 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4572 (clobber (match_dup 3))])
4573 (set (match_dup 0) (match_dup 2))])
4574
4575 (define_split
4576 [(set (match_operand:SWI248x 0 "memory_operand")
4577 (fix:SWI248x (match_operand 1 "register_operand")))
4578 (clobber (match_operand:SWI248x 2 "memory_operand"))
4579 (clobber (match_scratch 3))]
4580 "reload_completed"
4581 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4582 (clobber (match_dup 3))])])
4583
4584 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4585 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4586 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4587 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4588 ;; function in i386.c.
4589 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4590 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4591 (fix:SWI248x (match_operand 1 "register_operand")))
4592 (clobber (reg:CC FLAGS_REG))]
4593 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4594 && !TARGET_FISTTP
4595 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4596 && (TARGET_64BIT || <MODE>mode != DImode))
4597 && can_create_pseudo_p ()"
4598 "#"
4599 "&& 1"
4600 [(const_int 0)]
4601 {
4602 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4603
4604 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4605 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4606 if (memory_operand (operands[0], VOIDmode))
4607 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4608 operands[2], operands[3]));
4609 else
4610 {
4611 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4612 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4613 operands[2], operands[3],
4614 operands[4]));
4615 }
4616 DONE;
4617 }
4618 [(set_attr "type" "fistp")
4619 (set_attr "i387_cw" "trunc")
4620 (set_attr "mode" "<MODE>")])
4621
4622 (define_insn "fix_truncdi_i387"
4623 [(set (match_operand:DI 0 "memory_operand" "=m")
4624 (fix:DI (match_operand 1 "register_operand" "f")))
4625 (use (match_operand:HI 2 "memory_operand" "m"))
4626 (use (match_operand:HI 3 "memory_operand" "m"))
4627 (clobber (match_scratch:XF 4 "=&1f"))]
4628 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4629 && !TARGET_FISTTP
4630 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4631 "* return output_fix_trunc (insn, operands, false);"
4632 [(set_attr "type" "fistp")
4633 (set_attr "i387_cw" "trunc")
4634 (set_attr "mode" "DI")])
4635
4636 (define_insn "fix_truncdi_i387_with_temp"
4637 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4638 (fix:DI (match_operand 1 "register_operand" "f,f")))
4639 (use (match_operand:HI 2 "memory_operand" "m,m"))
4640 (use (match_operand:HI 3 "memory_operand" "m,m"))
4641 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4642 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4643 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4644 && !TARGET_FISTTP
4645 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4646 "#"
4647 [(set_attr "type" "fistp")
4648 (set_attr "i387_cw" "trunc")
4649 (set_attr "mode" "DI")])
4650
4651 (define_split
4652 [(set (match_operand:DI 0 "register_operand")
4653 (fix:DI (match_operand 1 "register_operand")))
4654 (use (match_operand:HI 2 "memory_operand"))
4655 (use (match_operand:HI 3 "memory_operand"))
4656 (clobber (match_operand:DI 4 "memory_operand"))
4657 (clobber (match_scratch 5))]
4658 "reload_completed"
4659 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4660 (use (match_dup 2))
4661 (use (match_dup 3))
4662 (clobber (match_dup 5))])
4663 (set (match_dup 0) (match_dup 4))])
4664
4665 (define_split
4666 [(set (match_operand:DI 0 "memory_operand")
4667 (fix:DI (match_operand 1 "register_operand")))
4668 (use (match_operand:HI 2 "memory_operand"))
4669 (use (match_operand:HI 3 "memory_operand"))
4670 (clobber (match_operand:DI 4 "memory_operand"))
4671 (clobber (match_scratch 5))]
4672 "reload_completed"
4673 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4674 (use (match_dup 2))
4675 (use (match_dup 3))
4676 (clobber (match_dup 5))])])
4677
4678 (define_insn "fix_trunc<mode>_i387"
4679 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4680 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4681 (use (match_operand:HI 2 "memory_operand" "m"))
4682 (use (match_operand:HI 3 "memory_operand" "m"))]
4683 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4684 && !TARGET_FISTTP
4685 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4686 "* return output_fix_trunc (insn, operands, false);"
4687 [(set_attr "type" "fistp")
4688 (set_attr "i387_cw" "trunc")
4689 (set_attr "mode" "<MODE>")])
4690
4691 (define_insn "fix_trunc<mode>_i387_with_temp"
4692 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4693 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4694 (use (match_operand:HI 2 "memory_operand" "m,m"))
4695 (use (match_operand:HI 3 "memory_operand" "m,m"))
4696 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4697 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4698 && !TARGET_FISTTP
4699 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4700 "#"
4701 [(set_attr "type" "fistp")
4702 (set_attr "i387_cw" "trunc")
4703 (set_attr "mode" "<MODE>")])
4704
4705 (define_split
4706 [(set (match_operand:SWI24 0 "register_operand")
4707 (fix:SWI24 (match_operand 1 "register_operand")))
4708 (use (match_operand:HI 2 "memory_operand"))
4709 (use (match_operand:HI 3 "memory_operand"))
4710 (clobber (match_operand:SWI24 4 "memory_operand"))]
4711 "reload_completed"
4712 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4713 (use (match_dup 2))
4714 (use (match_dup 3))])
4715 (set (match_dup 0) (match_dup 4))])
4716
4717 (define_split
4718 [(set (match_operand:SWI24 0 "memory_operand")
4719 (fix:SWI24 (match_operand 1 "register_operand")))
4720 (use (match_operand:HI 2 "memory_operand"))
4721 (use (match_operand:HI 3 "memory_operand"))
4722 (clobber (match_operand:SWI24 4 "memory_operand"))]
4723 "reload_completed"
4724 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4725 (use (match_dup 2))
4726 (use (match_dup 3))])])
4727
4728 (define_insn "x86_fnstcw_1"
4729 [(set (match_operand:HI 0 "memory_operand" "=m")
4730 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4731 "TARGET_80387"
4732 "fnstcw\t%0"
4733 [(set (attr "length")
4734 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4735 (set_attr "mode" "HI")
4736 (set_attr "unit" "i387")
4737 (set_attr "bdver1_decode" "vector")])
4738
4739 (define_insn "x86_fldcw_1"
4740 [(set (reg:HI FPCR_REG)
4741 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4742 "TARGET_80387"
4743 "fldcw\t%0"
4744 [(set (attr "length")
4745 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4746 (set_attr "mode" "HI")
4747 (set_attr "unit" "i387")
4748 (set_attr "athlon_decode" "vector")
4749 (set_attr "amdfam10_decode" "vector")
4750 (set_attr "bdver1_decode" "vector")])
4751 \f
4752 ;; Conversion between fixed point and floating point.
4753
4754 ;; Even though we only accept memory inputs, the backend _really_
4755 ;; wants to be able to do this between registers.
4756
4757 (define_expand "floathi<mode>2"
4758 [(set (match_operand:X87MODEF 0 "register_operand")
4759 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4760 "TARGET_80387
4761 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4762 || TARGET_MIX_SSE_I387)")
4763
4764 ;; Pre-reload splitter to add memory clobber to the pattern.
4765 (define_insn_and_split "*floathi<mode>2_1"
4766 [(set (match_operand:X87MODEF 0 "register_operand")
4767 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4768 "TARGET_80387
4769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4770 || TARGET_MIX_SSE_I387)
4771 && can_create_pseudo_p ()"
4772 "#"
4773 "&& 1"
4774 [(parallel [(set (match_dup 0)
4775 (float:X87MODEF (match_dup 1)))
4776 (clobber (match_dup 2))])]
4777 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4778
4779 (define_insn "*floathi<mode>2_i387_with_temp"
4780 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4781 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4782 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4783 "TARGET_80387
4784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4785 || TARGET_MIX_SSE_I387)"
4786 "#"
4787 [(set_attr "type" "fmov,multi")
4788 (set_attr "mode" "<MODE>")
4789 (set_attr "unit" "*,i387")
4790 (set_attr "fp_int_src" "true")])
4791
4792 (define_insn "*floathi<mode>2_i387"
4793 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4794 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4795 "TARGET_80387
4796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4797 || TARGET_MIX_SSE_I387)"
4798 "fild%Z1\t%1"
4799 [(set_attr "type" "fmov")
4800 (set_attr "mode" "<MODE>")
4801 (set_attr "fp_int_src" "true")])
4802
4803 (define_split
4804 [(set (match_operand:X87MODEF 0 "register_operand")
4805 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4806 (clobber (match_operand:HI 2 "memory_operand"))]
4807 "TARGET_80387
4808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4809 || TARGET_MIX_SSE_I387)
4810 && reload_completed"
4811 [(set (match_dup 2) (match_dup 1))
4812 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4813
4814 (define_split
4815 [(set (match_operand:X87MODEF 0 "register_operand")
4816 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4817 (clobber (match_operand:HI 2 "memory_operand"))]
4818 "TARGET_80387
4819 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4820 || TARGET_MIX_SSE_I387)
4821 && reload_completed"
4822 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4823
4824 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4825 [(set (match_operand:X87MODEF 0 "register_operand")
4826 (float:X87MODEF
4827 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4828 "TARGET_80387
4829 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4830 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4831 {
4832 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4833 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4834 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4835 {
4836 rtx reg = gen_reg_rtx (XFmode);
4837 rtx (*insn)(rtx, rtx);
4838
4839 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4840
4841 if (<X87MODEF:MODE>mode == SFmode)
4842 insn = gen_truncxfsf2;
4843 else if (<X87MODEF:MODE>mode == DFmode)
4844 insn = gen_truncxfdf2;
4845 else
4846 gcc_unreachable ();
4847
4848 emit_insn (insn (operands[0], reg));
4849 DONE;
4850 }
4851 })
4852
4853 ;; Pre-reload splitter to add memory clobber to the pattern.
4854 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4855 [(set (match_operand:X87MODEF 0 "register_operand")
4856 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4857 "((TARGET_80387
4858 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4859 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4860 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4861 || TARGET_MIX_SSE_I387))
4862 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4863 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4864 && ((<SWI48x:MODE>mode == SImode
4865 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4866 && optimize_function_for_speed_p (cfun)
4867 && flag_trapping_math)
4868 || !(TARGET_INTER_UNIT_CONVERSIONS
4869 || optimize_function_for_size_p (cfun)))))
4870 && can_create_pseudo_p ()"
4871 "#"
4872 "&& 1"
4873 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4874 (clobber (match_dup 2))])]
4875 {
4876 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4877
4878 /* Avoid store forwarding (partial memory) stall penalty
4879 by passing DImode value through XMM registers. */
4880 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4881 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4882 && optimize_function_for_speed_p (cfun))
4883 {
4884 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4885 operands[1],
4886 operands[2]));
4887 DONE;
4888 }
4889 })
4890
4891 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4893 (float:MODEF
4894 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4895 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4896 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4897 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4898 "#"
4899 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4900 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4901 (set_attr "unit" "*,i387,*,*,*")
4902 (set_attr "athlon_decode" "*,*,double,direct,double")
4903 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4904 (set_attr "bdver1_decode" "*,*,double,direct,double")
4905 (set_attr "fp_int_src" "true")])
4906
4907 (define_insn "*floatsi<mode>2_vector_mixed"
4908 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4909 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4910 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4911 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4912 "@
4913 fild%Z1\t%1
4914 #"
4915 [(set_attr "type" "fmov,sseicvt")
4916 (set_attr "mode" "<MODE>,<ssevecmode>")
4917 (set_attr "unit" "i387,*")
4918 (set_attr "athlon_decode" "*,direct")
4919 (set_attr "amdfam10_decode" "*,double")
4920 (set_attr "bdver1_decode" "*,direct")
4921 (set_attr "fp_int_src" "true")])
4922
4923 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4924 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4925 (float:MODEF
4926 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4927 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4928 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4929 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4930 "#"
4931 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4932 (set_attr "mode" "<MODEF:MODE>")
4933 (set_attr "unit" "*,i387,*,*")
4934 (set_attr "athlon_decode" "*,*,double,direct")
4935 (set_attr "amdfam10_decode" "*,*,vector,double")
4936 (set_attr "bdver1_decode" "*,*,double,direct")
4937 (set_attr "fp_int_src" "true")])
4938
4939 (define_split
4940 [(set (match_operand:MODEF 0 "register_operand")
4941 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4942 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4943 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4944 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4945 && TARGET_INTER_UNIT_CONVERSIONS
4946 && reload_completed
4947 && (SSE_REG_P (operands[0])
4948 || (GET_CODE (operands[0]) == SUBREG
4949 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4950 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4951
4952 (define_split
4953 [(set (match_operand:MODEF 0 "register_operand")
4954 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4955 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4956 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4957 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4958 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4959 && reload_completed
4960 && (SSE_REG_P (operands[0])
4961 || (GET_CODE (operands[0]) == SUBREG
4962 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4963 [(set (match_dup 2) (match_dup 1))
4964 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4965
4966 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4967 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4968 (float:MODEF
4969 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4970 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4971 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4972 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4973 "@
4974 fild%Z1\t%1
4975 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4976 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4977 [(set_attr "type" "fmov,sseicvt,sseicvt")
4978 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4979 (set_attr "mode" "<MODEF:MODE>")
4980 (set (attr "prefix_rex")
4981 (if_then_else
4982 (and (eq_attr "prefix" "maybe_vex")
4983 (match_test "<SWI48x:MODE>mode == DImode"))
4984 (const_string "1")
4985 (const_string "*")))
4986 (set_attr "unit" "i387,*,*")
4987 (set_attr "athlon_decode" "*,double,direct")
4988 (set_attr "amdfam10_decode" "*,vector,double")
4989 (set_attr "bdver1_decode" "*,double,direct")
4990 (set_attr "fp_int_src" "true")])
4991
4992 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4993 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4994 (float:MODEF
4995 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4996 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4997 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4998 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4999 "@
5000 fild%Z1\t%1
5001 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5002 [(set_attr "type" "fmov,sseicvt")
5003 (set_attr "prefix" "orig,maybe_vex")
5004 (set_attr "mode" "<MODEF:MODE>")
5005 (set (attr "prefix_rex")
5006 (if_then_else
5007 (and (eq_attr "prefix" "maybe_vex")
5008 (match_test "<SWI48x:MODE>mode == DImode"))
5009 (const_string "1")
5010 (const_string "*")))
5011 (set_attr "athlon_decode" "*,direct")
5012 (set_attr "amdfam10_decode" "*,double")
5013 (set_attr "bdver1_decode" "*,direct")
5014 (set_attr "fp_int_src" "true")])
5015
5016 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5017 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5018 (float:MODEF
5019 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5020 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5021 "TARGET_SSE2 && TARGET_SSE_MATH
5022 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5023 "#"
5024 [(set_attr "type" "sseicvt")
5025 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5026 (set_attr "athlon_decode" "double,direct,double")
5027 (set_attr "amdfam10_decode" "vector,double,double")
5028 (set_attr "bdver1_decode" "double,direct,double")
5029 (set_attr "fp_int_src" "true")])
5030
5031 (define_insn "*floatsi<mode>2_vector_sse"
5032 [(set (match_operand:MODEF 0 "register_operand" "=x")
5033 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5034 "TARGET_SSE2 && TARGET_SSE_MATH
5035 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5036 "#"
5037 [(set_attr "type" "sseicvt")
5038 (set_attr "mode" "<MODE>")
5039 (set_attr "athlon_decode" "direct")
5040 (set_attr "amdfam10_decode" "double")
5041 (set_attr "bdver1_decode" "direct")
5042 (set_attr "fp_int_src" "true")])
5043
5044 (define_split
5045 [(set (match_operand:MODEF 0 "register_operand")
5046 (float:MODEF (match_operand:SI 1 "register_operand")))
5047 (clobber (match_operand:SI 2 "memory_operand"))]
5048 "TARGET_SSE2 && TARGET_SSE_MATH
5049 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5050 && reload_completed
5051 && (SSE_REG_P (operands[0])
5052 || (GET_CODE (operands[0]) == SUBREG
5053 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5054 [(const_int 0)]
5055 {
5056 rtx op1 = operands[1];
5057
5058 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5059 <MODE>mode, 0);
5060 if (GET_CODE (op1) == SUBREG)
5061 op1 = SUBREG_REG (op1);
5062
5063 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5064 {
5065 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066 emit_insn (gen_sse2_loadld (operands[4],
5067 CONST0_RTX (V4SImode), operands[1]));
5068 }
5069 /* We can ignore possible trapping value in the
5070 high part of SSE register for non-trapping math. */
5071 else if (SSE_REG_P (op1) && !flag_trapping_math)
5072 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5073 else
5074 {
5075 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5076 emit_move_insn (operands[2], operands[1]);
5077 emit_insn (gen_sse2_loadld (operands[4],
5078 CONST0_RTX (V4SImode), operands[2]));
5079 }
5080 if (<ssevecmode>mode == V4SFmode)
5081 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5082 else
5083 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5084 DONE;
5085 })
5086
5087 (define_split
5088 [(set (match_operand:MODEF 0 "register_operand")
5089 (float:MODEF (match_operand:SI 1 "memory_operand")))
5090 (clobber (match_operand:SI 2 "memory_operand"))]
5091 "TARGET_SSE2 && TARGET_SSE_MATH
5092 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5093 && reload_completed
5094 && (SSE_REG_P (operands[0])
5095 || (GET_CODE (operands[0]) == SUBREG
5096 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5097 [(const_int 0)]
5098 {
5099 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5100 <MODE>mode, 0);
5101 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5102
5103 emit_insn (gen_sse2_loadld (operands[4],
5104 CONST0_RTX (V4SImode), operands[1]));
5105 if (<ssevecmode>mode == V4SFmode)
5106 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5107 else
5108 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5109 DONE;
5110 })
5111
5112 (define_split
5113 [(set (match_operand:MODEF 0 "register_operand")
5114 (float:MODEF (match_operand:SI 1 "register_operand")))]
5115 "TARGET_SSE2 && TARGET_SSE_MATH
5116 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5117 && reload_completed
5118 && (SSE_REG_P (operands[0])
5119 || (GET_CODE (operands[0]) == SUBREG
5120 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5121 [(const_int 0)]
5122 {
5123 rtx op1 = operands[1];
5124
5125 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5126 <MODE>mode, 0);
5127 if (GET_CODE (op1) == SUBREG)
5128 op1 = SUBREG_REG (op1);
5129
5130 if (GENERAL_REG_P (op1))
5131 {
5132 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5133 if (TARGET_INTER_UNIT_MOVES)
5134 emit_insn (gen_sse2_loadld (operands[4],
5135 CONST0_RTX (V4SImode), operands[1]));
5136 else
5137 {
5138 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5139 operands[1]);
5140 emit_insn (gen_sse2_loadld (operands[4],
5141 CONST0_RTX (V4SImode), operands[5]));
5142 ix86_free_from_memory (GET_MODE (operands[1]));
5143 }
5144 }
5145 /* We can ignore possible trapping value in the
5146 high part of SSE register for non-trapping math. */
5147 else if (SSE_REG_P (op1) && !flag_trapping_math)
5148 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5149 else
5150 gcc_unreachable ();
5151 if (<ssevecmode>mode == V4SFmode)
5152 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5153 else
5154 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5155 DONE;
5156 })
5157
5158 (define_split
5159 [(set (match_operand:MODEF 0 "register_operand")
5160 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5161 "TARGET_SSE2 && TARGET_SSE_MATH
5162 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5163 && reload_completed
5164 && (SSE_REG_P (operands[0])
5165 || (GET_CODE (operands[0]) == SUBREG
5166 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5167 [(const_int 0)]
5168 {
5169 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5170 <MODE>mode, 0);
5171 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5172
5173 emit_insn (gen_sse2_loadld (operands[4],
5174 CONST0_RTX (V4SImode), operands[1]));
5175 if (<ssevecmode>mode == V4SFmode)
5176 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5177 else
5178 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5179 DONE;
5180 })
5181
5182 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5183 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5184 (float:MODEF
5185 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5186 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5187 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5188 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5189 "#"
5190 [(set_attr "type" "sseicvt")
5191 (set_attr "mode" "<MODEF:MODE>")
5192 (set_attr "athlon_decode" "double,direct")
5193 (set_attr "amdfam10_decode" "vector,double")
5194 (set_attr "bdver1_decode" "double,direct")
5195 (set_attr "fp_int_src" "true")])
5196
5197 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5198 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5199 (float:MODEF
5200 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5201 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5202 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5203 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5204 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5205 [(set_attr "type" "sseicvt")
5206 (set_attr "prefix" "maybe_vex")
5207 (set_attr "mode" "<MODEF:MODE>")
5208 (set (attr "prefix_rex")
5209 (if_then_else
5210 (and (eq_attr "prefix" "maybe_vex")
5211 (match_test "<SWI48x:MODE>mode == DImode"))
5212 (const_string "1")
5213 (const_string "*")))
5214 (set_attr "athlon_decode" "double,direct")
5215 (set_attr "amdfam10_decode" "vector,double")
5216 (set_attr "bdver1_decode" "double,direct")
5217 (set_attr "fp_int_src" "true")])
5218
5219 (define_split
5220 [(set (match_operand:MODEF 0 "register_operand")
5221 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5222 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5223 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5224 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5225 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5226 && reload_completed
5227 && (SSE_REG_P (operands[0])
5228 || (GET_CODE (operands[0]) == SUBREG
5229 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5230 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5231
5232 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5233 [(set (match_operand:MODEF 0 "register_operand" "=x")
5234 (float:MODEF
5235 (match_operand:SWI48x 1 "memory_operand" "m")))]
5236 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5237 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5238 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5239 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5240 [(set_attr "type" "sseicvt")
5241 (set_attr "prefix" "maybe_vex")
5242 (set_attr "mode" "<MODEF:MODE>")
5243 (set (attr "prefix_rex")
5244 (if_then_else
5245 (and (eq_attr "prefix" "maybe_vex")
5246 (match_test "<SWI48x:MODE>mode == DImode"))
5247 (const_string "1")
5248 (const_string "*")))
5249 (set_attr "athlon_decode" "direct")
5250 (set_attr "amdfam10_decode" "double")
5251 (set_attr "bdver1_decode" "direct")
5252 (set_attr "fp_int_src" "true")])
5253
5254 (define_split
5255 [(set (match_operand:MODEF 0 "register_operand")
5256 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5257 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5258 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5259 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5260 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5261 && reload_completed
5262 && (SSE_REG_P (operands[0])
5263 || (GET_CODE (operands[0]) == SUBREG
5264 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5265 [(set (match_dup 2) (match_dup 1))
5266 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5267
5268 (define_split
5269 [(set (match_operand:MODEF 0 "register_operand")
5270 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5271 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5272 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5273 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5274 && reload_completed
5275 && (SSE_REG_P (operands[0])
5276 || (GET_CODE (operands[0]) == SUBREG
5277 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5278 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5279
5280 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5281 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5282 (float:X87MODEF
5283 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5284 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5285 "TARGET_80387
5286 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5287 "@
5288 fild%Z1\t%1
5289 #"
5290 [(set_attr "type" "fmov,multi")
5291 (set_attr "mode" "<X87MODEF:MODE>")
5292 (set_attr "unit" "*,i387")
5293 (set_attr "fp_int_src" "true")])
5294
5295 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5296 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5297 (float:X87MODEF
5298 (match_operand:SWI48x 1 "memory_operand" "m")))]
5299 "TARGET_80387
5300 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5301 "fild%Z1\t%1"
5302 [(set_attr "type" "fmov")
5303 (set_attr "mode" "<X87MODEF:MODE>")
5304 (set_attr "fp_int_src" "true")])
5305
5306 (define_split
5307 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5308 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5309 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5310 "TARGET_80387
5311 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5312 && reload_completed"
5313 [(set (match_dup 2) (match_dup 1))
5314 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5315
5316 (define_split
5317 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5318 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5319 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5320 "TARGET_80387
5321 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5322 && reload_completed"
5323 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5324
5325 ;; Avoid store forwarding (partial memory) stall penalty
5326 ;; by passing DImode value through XMM registers. */
5327
5328 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5329 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5330 (float:X87MODEF
5331 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5332 (clobber (match_scratch:V4SI 3 "=X,x"))
5333 (clobber (match_scratch:V4SI 4 "=X,x"))
5334 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5335 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5336 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5337 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5338 "#"
5339 [(set_attr "type" "multi")
5340 (set_attr "mode" "<X87MODEF:MODE>")
5341 (set_attr "unit" "i387")
5342 (set_attr "fp_int_src" "true")])
5343
5344 (define_split
5345 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5346 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5347 (clobber (match_scratch:V4SI 3))
5348 (clobber (match_scratch:V4SI 4))
5349 (clobber (match_operand:DI 2 "memory_operand"))]
5350 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5352 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5353 && reload_completed"
5354 [(set (match_dup 2) (match_dup 3))
5355 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5356 {
5357 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5358 Assemble the 64-bit DImode value in an xmm register. */
5359 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5360 gen_rtx_SUBREG (SImode, operands[1], 0)));
5361 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5362 gen_rtx_SUBREG (SImode, operands[1], 4)));
5363 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5364 operands[4]));
5365
5366 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5367 })
5368
5369 (define_split
5370 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5371 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5372 (clobber (match_scratch:V4SI 3))
5373 (clobber (match_scratch:V4SI 4))
5374 (clobber (match_operand:DI 2 "memory_operand"))]
5375 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5376 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5377 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5378 && reload_completed"
5379 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5380
5381 ;; Avoid store forwarding (partial memory) stall penalty by extending
5382 ;; SImode value to DImode through XMM register instead of pushing two
5383 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5384 ;; targets benefit from this optimization. Also note that fild
5385 ;; loads from memory only.
5386
5387 (define_insn "*floatunssi<mode>2_1"
5388 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5389 (unsigned_float:X87MODEF
5390 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5391 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5392 (clobber (match_scratch:SI 3 "=X,x"))]
5393 "!TARGET_64BIT
5394 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5395 && TARGET_SSE"
5396 "#"
5397 [(set_attr "type" "multi")
5398 (set_attr "mode" "<MODE>")])
5399
5400 (define_split
5401 [(set (match_operand:X87MODEF 0 "register_operand")
5402 (unsigned_float:X87MODEF
5403 (match_operand:SI 1 "register_operand")))
5404 (clobber (match_operand:DI 2 "memory_operand"))
5405 (clobber (match_scratch:SI 3))]
5406 "!TARGET_64BIT
5407 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5408 && TARGET_SSE
5409 && reload_completed"
5410 [(set (match_dup 2) (match_dup 1))
5411 (set (match_dup 0)
5412 (float:X87MODEF (match_dup 2)))]
5413 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5414
5415 (define_split
5416 [(set (match_operand:X87MODEF 0 "register_operand")
5417 (unsigned_float:X87MODEF
5418 (match_operand:SI 1 "memory_operand")))
5419 (clobber (match_operand:DI 2 "memory_operand"))
5420 (clobber (match_scratch:SI 3))]
5421 "!TARGET_64BIT
5422 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5423 && TARGET_SSE
5424 && reload_completed"
5425 [(set (match_dup 2) (match_dup 3))
5426 (set (match_dup 0)
5427 (float:X87MODEF (match_dup 2)))]
5428 {
5429 emit_move_insn (operands[3], operands[1]);
5430 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5431 })
5432
5433 (define_expand "floatunssi<mode>2"
5434 [(parallel
5435 [(set (match_operand:X87MODEF 0 "register_operand")
5436 (unsigned_float:X87MODEF
5437 (match_operand:SI 1 "nonimmediate_operand")))
5438 (clobber (match_dup 2))
5439 (clobber (match_scratch:SI 3))])]
5440 "!TARGET_64BIT
5441 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5442 && TARGET_SSE)
5443 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5444 {
5445 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5446 {
5447 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5448 DONE;
5449 }
5450 else
5451 {
5452 enum ix86_stack_slot slot = (virtuals_instantiated
5453 ? SLOT_TEMP
5454 : SLOT_VIRTUAL);
5455 operands[2] = assign_386_stack_local (DImode, slot);
5456 }
5457 })
5458
5459 (define_expand "floatunsdisf2"
5460 [(use (match_operand:SF 0 "register_operand"))
5461 (use (match_operand:DI 1 "nonimmediate_operand"))]
5462 "TARGET_64BIT && TARGET_SSE_MATH"
5463 "x86_emit_floatuns (operands); DONE;")
5464
5465 (define_expand "floatunsdidf2"
5466 [(use (match_operand:DF 0 "register_operand"))
5467 (use (match_operand:DI 1 "nonimmediate_operand"))]
5468 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5469 && TARGET_SSE2 && TARGET_SSE_MATH"
5470 {
5471 if (TARGET_64BIT)
5472 x86_emit_floatuns (operands);
5473 else
5474 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5475 DONE;
5476 })
5477 \f
5478 ;; Load effective address instructions
5479
5480 (define_insn_and_split "*lea<mode>"
5481 [(set (match_operand:SWI48 0 "register_operand" "=r")
5482 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5483 ""
5484 {
5485 rtx addr = operands[1];
5486
5487 if (GET_CODE (addr) == SUBREG)
5488 {
5489 gcc_assert (TARGET_64BIT);
5490 gcc_assert (<MODE>mode == SImode);
5491 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5492 return "lea{l}\t{%E1, %0|%0, %E1}";
5493 }
5494 else if (GET_CODE (addr) == ZERO_EXTEND
5495 || GET_CODE (addr) == AND)
5496 {
5497 gcc_assert (TARGET_64BIT);
5498 gcc_assert (<MODE>mode == DImode);
5499 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5500 }
5501 else
5502 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5503 }
5504 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5505 [(const_int 0)]
5506 {
5507 enum machine_mode mode = <MODE>mode;
5508 rtx pat;
5509
5510 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5511 change operands[] array behind our back. */
5512 pat = PATTERN (curr_insn);
5513
5514 operands[0] = SET_DEST (pat);
5515 operands[1] = SET_SRC (pat);
5516
5517 /* Emit all operations in SImode for zero-extended addresses. Recall
5518 that x86_64 inheretly zero-extends SImode operations to DImode. */
5519 if (GET_CODE (operands[1]) == ZERO_EXTEND
5520 || GET_CODE (operands[1]) == AND)
5521 mode = SImode;
5522
5523 ix86_split_lea_for_addr (curr_insn, operands, mode);
5524 DONE;
5525 }
5526 [(set_attr "type" "lea")
5527 (set_attr "mode" "<MODE>")])
5528 \f
5529 ;; Add instructions
5530
5531 (define_expand "add<mode>3"
5532 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5533 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5534 (match_operand:SDWIM 2 "<general_operand>")))]
5535 ""
5536 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5537
5538 (define_insn_and_split "*add<dwi>3_doubleword"
5539 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5540 (plus:<DWI>
5541 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5542 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5543 (clobber (reg:CC FLAGS_REG))]
5544 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5545 "#"
5546 "reload_completed"
5547 [(parallel [(set (reg:CC FLAGS_REG)
5548 (unspec:CC [(match_dup 1) (match_dup 2)]
5549 UNSPEC_ADD_CARRY))
5550 (set (match_dup 0)
5551 (plus:DWIH (match_dup 1) (match_dup 2)))])
5552 (parallel [(set (match_dup 3)
5553 (plus:DWIH
5554 (match_dup 4)
5555 (plus:DWIH
5556 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5557 (match_dup 5))))
5558 (clobber (reg:CC FLAGS_REG))])]
5559 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5560
5561 (define_insn "*add<mode>3_cc"
5562 [(set (reg:CC FLAGS_REG)
5563 (unspec:CC
5564 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5565 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5566 UNSPEC_ADD_CARRY))
5567 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5568 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5569 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5570 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5571 [(set_attr "type" "alu")
5572 (set_attr "mode" "<MODE>")])
5573
5574 (define_insn "addqi3_cc"
5575 [(set (reg:CC FLAGS_REG)
5576 (unspec:CC
5577 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5578 (match_operand:QI 2 "general_operand" "qn,qm")]
5579 UNSPEC_ADD_CARRY))
5580 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5581 (plus:QI (match_dup 1) (match_dup 2)))]
5582 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5583 "add{b}\t{%2, %0|%0, %2}"
5584 [(set_attr "type" "alu")
5585 (set_attr "mode" "QI")])
5586
5587 (define_insn "*add<mode>_1"
5588 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5589 (plus:SWI48
5590 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5591 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5592 (clobber (reg:CC FLAGS_REG))]
5593 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5594 {
5595 switch (get_attr_type (insn))
5596 {
5597 case TYPE_LEA:
5598 return "#";
5599
5600 case TYPE_INCDEC:
5601 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5602 if (operands[2] == const1_rtx)
5603 return "inc{<imodesuffix>}\t%0";
5604 else
5605 {
5606 gcc_assert (operands[2] == constm1_rtx);
5607 return "dec{<imodesuffix>}\t%0";
5608 }
5609
5610 default:
5611 /* For most processors, ADD is faster than LEA. This alternative
5612 was added to use ADD as much as possible. */
5613 if (which_alternative == 2)
5614 {
5615 rtx tmp;
5616 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5617 }
5618
5619 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5620 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5621 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5622
5623 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5624 }
5625 }
5626 [(set (attr "type")
5627 (cond [(eq_attr "alternative" "3")
5628 (const_string "lea")
5629 (match_operand:SWI48 2 "incdec_operand")
5630 (const_string "incdec")
5631 ]
5632 (const_string "alu")))
5633 (set (attr "length_immediate")
5634 (if_then_else
5635 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5636 (const_string "1")
5637 (const_string "*")))
5638 (set_attr "mode" "<MODE>")])
5639
5640 ;; It may seem that nonimmediate operand is proper one for operand 1.
5641 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5642 ;; we take care in ix86_binary_operator_ok to not allow two memory
5643 ;; operands so proper swapping will be done in reload. This allow
5644 ;; patterns constructed from addsi_1 to match.
5645
5646 (define_insn "addsi_1_zext"
5647 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5648 (zero_extend:DI
5649 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5650 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5651 (clobber (reg:CC FLAGS_REG))]
5652 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5653 {
5654 switch (get_attr_type (insn))
5655 {
5656 case TYPE_LEA:
5657 return "#";
5658
5659 case TYPE_INCDEC:
5660 if (operands[2] == const1_rtx)
5661 return "inc{l}\t%k0";
5662 else
5663 {
5664 gcc_assert (operands[2] == constm1_rtx);
5665 return "dec{l}\t%k0";
5666 }
5667
5668 default:
5669 /* For most processors, ADD is faster than LEA. This alternative
5670 was added to use ADD as much as possible. */
5671 if (which_alternative == 1)
5672 {
5673 rtx tmp;
5674 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5675 }
5676
5677 if (x86_maybe_negate_const_int (&operands[2], SImode))
5678 return "sub{l}\t{%2, %k0|%k0, %2}";
5679
5680 return "add{l}\t{%2, %k0|%k0, %2}";
5681 }
5682 }
5683 [(set (attr "type")
5684 (cond [(eq_attr "alternative" "2")
5685 (const_string "lea")
5686 (match_operand:SI 2 "incdec_operand")
5687 (const_string "incdec")
5688 ]
5689 (const_string "alu")))
5690 (set (attr "length_immediate")
5691 (if_then_else
5692 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5693 (const_string "1")
5694 (const_string "*")))
5695 (set_attr "mode" "SI")])
5696
5697 (define_insn "*addhi_1"
5698 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5699 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5700 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5701 (clobber (reg:CC FLAGS_REG))]
5702 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5703 {
5704 switch (get_attr_type (insn))
5705 {
5706 case TYPE_LEA:
5707 return "#";
5708
5709 case TYPE_INCDEC:
5710 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5711 if (operands[2] == const1_rtx)
5712 return "inc{w}\t%0";
5713 else
5714 {
5715 gcc_assert (operands[2] == constm1_rtx);
5716 return "dec{w}\t%0";
5717 }
5718
5719 default:
5720 /* For most processors, ADD is faster than LEA. This alternative
5721 was added to use ADD as much as possible. */
5722 if (which_alternative == 2)
5723 {
5724 rtx tmp;
5725 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5726 }
5727
5728 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5729 if (x86_maybe_negate_const_int (&operands[2], HImode))
5730 return "sub{w}\t{%2, %0|%0, %2}";
5731
5732 return "add{w}\t{%2, %0|%0, %2}";
5733 }
5734 }
5735 [(set (attr "type")
5736 (cond [(eq_attr "alternative" "3")
5737 (const_string "lea")
5738 (match_operand:HI 2 "incdec_operand")
5739 (const_string "incdec")
5740 ]
5741 (const_string "alu")))
5742 (set (attr "length_immediate")
5743 (if_then_else
5744 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5745 (const_string "1")
5746 (const_string "*")))
5747 (set_attr "mode" "HI,HI,HI,SI")])
5748
5749 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5750 (define_insn "*addqi_1"
5751 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5752 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5753 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5754 (clobber (reg:CC FLAGS_REG))]
5755 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5756 {
5757 bool widen = (which_alternative == 3 || which_alternative == 4);
5758
5759 switch (get_attr_type (insn))
5760 {
5761 case TYPE_LEA:
5762 return "#";
5763
5764 case TYPE_INCDEC:
5765 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5766 if (operands[2] == const1_rtx)
5767 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5768 else
5769 {
5770 gcc_assert (operands[2] == constm1_rtx);
5771 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5772 }
5773
5774 default:
5775 /* For most processors, ADD is faster than LEA. These alternatives
5776 were added to use ADD as much as possible. */
5777 if (which_alternative == 2 || which_alternative == 4)
5778 {
5779 rtx tmp;
5780 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5781 }
5782
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (x86_maybe_negate_const_int (&operands[2], QImode))
5785 {
5786 if (widen)
5787 return "sub{l}\t{%2, %k0|%k0, %2}";
5788 else
5789 return "sub{b}\t{%2, %0|%0, %2}";
5790 }
5791 if (widen)
5792 return "add{l}\t{%k2, %k0|%k0, %k2}";
5793 else
5794 return "add{b}\t{%2, %0|%0, %2}";
5795 }
5796 }
5797 [(set (attr "type")
5798 (cond [(eq_attr "alternative" "5")
5799 (const_string "lea")
5800 (match_operand:QI 2 "incdec_operand")
5801 (const_string "incdec")
5802 ]
5803 (const_string "alu")))
5804 (set (attr "length_immediate")
5805 (if_then_else
5806 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5807 (const_string "1")
5808 (const_string "*")))
5809 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5810
5811 (define_insn "*addqi_1_slp"
5812 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5813 (plus:QI (match_dup 0)
5814 (match_operand:QI 1 "general_operand" "qn,qm")))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5817 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5818 {
5819 switch (get_attr_type (insn))
5820 {
5821 case TYPE_INCDEC:
5822 if (operands[1] == const1_rtx)
5823 return "inc{b}\t%0";
5824 else
5825 {
5826 gcc_assert (operands[1] == constm1_rtx);
5827 return "dec{b}\t%0";
5828 }
5829
5830 default:
5831 if (x86_maybe_negate_const_int (&operands[1], QImode))
5832 return "sub{b}\t{%1, %0|%0, %1}";
5833
5834 return "add{b}\t{%1, %0|%0, %1}";
5835 }
5836 }
5837 [(set (attr "type")
5838 (if_then_else (match_operand:QI 1 "incdec_operand")
5839 (const_string "incdec")
5840 (const_string "alu1")))
5841 (set (attr "memory")
5842 (if_then_else (match_operand 1 "memory_operand")
5843 (const_string "load")
5844 (const_string "none")))
5845 (set_attr "mode" "QI")])
5846
5847 ;; Split non destructive adds if we cannot use lea.
5848 (define_split
5849 [(set (match_operand:SWI48 0 "register_operand")
5850 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5851 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5852 (clobber (reg:CC FLAGS_REG))]
5853 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5854 [(set (match_dup 0) (match_dup 1))
5855 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5856 (clobber (reg:CC FLAGS_REG))])])
5857
5858 ;; Convert add to the lea pattern to avoid flags dependency.
5859 (define_split
5860 [(set (match_operand:SWI 0 "register_operand")
5861 (plus:SWI (match_operand:SWI 1 "register_operand")
5862 (match_operand:SWI 2 "<nonmemory_operand>")))
5863 (clobber (reg:CC FLAGS_REG))]
5864 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5865 [(const_int 0)]
5866 {
5867 enum machine_mode mode = <MODE>mode;
5868 rtx pat;
5869
5870 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5871 {
5872 mode = SImode;
5873 operands[0] = gen_lowpart (mode, operands[0]);
5874 operands[1] = gen_lowpart (mode, operands[1]);
5875 operands[2] = gen_lowpart (mode, operands[2]);
5876 }
5877
5878 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5879
5880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5881 DONE;
5882 })
5883
5884 ;; Split non destructive adds if we cannot use lea.
5885 (define_split
5886 [(set (match_operand:DI 0 "register_operand")
5887 (zero_extend:DI
5888 (plus:SI (match_operand:SI 1 "register_operand")
5889 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5890 (clobber (reg:CC FLAGS_REG))]
5891 "TARGET_64BIT
5892 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5893 [(set (match_dup 3) (match_dup 1))
5894 (parallel [(set (match_dup 0)
5895 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5896 (clobber (reg:CC FLAGS_REG))])]
5897 "operands[3] = gen_lowpart (SImode, operands[0]);")
5898
5899 ;; Convert add to the lea pattern to avoid flags dependency.
5900 (define_split
5901 [(set (match_operand:DI 0 "register_operand")
5902 (zero_extend:DI
5903 (plus:SI (match_operand:SI 1 "register_operand")
5904 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5905 (clobber (reg:CC FLAGS_REG))]
5906 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5907 [(set (match_dup 0)
5908 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5909
5910 (define_insn "*add<mode>_2"
5911 [(set (reg FLAGS_REG)
5912 (compare
5913 (plus:SWI
5914 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5915 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5916 (const_int 0)))
5917 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5918 (plus:SWI (match_dup 1) (match_dup 2)))]
5919 "ix86_match_ccmode (insn, CCGOCmode)
5920 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5921 {
5922 switch (get_attr_type (insn))
5923 {
5924 case TYPE_INCDEC:
5925 if (operands[2] == const1_rtx)
5926 return "inc{<imodesuffix>}\t%0";
5927 else
5928 {
5929 gcc_assert (operands[2] == constm1_rtx);
5930 return "dec{<imodesuffix>}\t%0";
5931 }
5932
5933 default:
5934 if (which_alternative == 2)
5935 {
5936 rtx tmp;
5937 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5938 }
5939
5940 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5941 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5942 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5943
5944 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5945 }
5946 }
5947 [(set (attr "type")
5948 (if_then_else (match_operand:SWI 2 "incdec_operand")
5949 (const_string "incdec")
5950 (const_string "alu")))
5951 (set (attr "length_immediate")
5952 (if_then_else
5953 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5954 (const_string "1")
5955 (const_string "*")))
5956 (set_attr "mode" "<MODE>")])
5957
5958 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5959 (define_insn "*addsi_2_zext"
5960 [(set (reg FLAGS_REG)
5961 (compare
5962 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5963 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5964 (const_int 0)))
5965 (set (match_operand:DI 0 "register_operand" "=r,r")
5966 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5967 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5968 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5969 {
5970 switch (get_attr_type (insn))
5971 {
5972 case TYPE_INCDEC:
5973 if (operands[2] == const1_rtx)
5974 return "inc{l}\t%k0";
5975 else
5976 {
5977 gcc_assert (operands[2] == constm1_rtx);
5978 return "dec{l}\t%k0";
5979 }
5980
5981 default:
5982 if (which_alternative == 1)
5983 {
5984 rtx tmp;
5985 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5986 }
5987
5988 if (x86_maybe_negate_const_int (&operands[2], SImode))
5989 return "sub{l}\t{%2, %k0|%k0, %2}";
5990
5991 return "add{l}\t{%2, %k0|%k0, %2}";
5992 }
5993 }
5994 [(set (attr "type")
5995 (if_then_else (match_operand:SI 2 "incdec_operand")
5996 (const_string "incdec")
5997 (const_string "alu")))
5998 (set (attr "length_immediate")
5999 (if_then_else
6000 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6001 (const_string "1")
6002 (const_string "*")))
6003 (set_attr "mode" "SI")])
6004
6005 (define_insn "*add<mode>_3"
6006 [(set (reg FLAGS_REG)
6007 (compare
6008 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6009 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6010 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6011 "ix86_match_ccmode (insn, CCZmode)
6012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6013 {
6014 switch (get_attr_type (insn))
6015 {
6016 case TYPE_INCDEC:
6017 if (operands[2] == const1_rtx)
6018 return "inc{<imodesuffix>}\t%0";
6019 else
6020 {
6021 gcc_assert (operands[2] == constm1_rtx);
6022 return "dec{<imodesuffix>}\t%0";
6023 }
6024
6025 default:
6026 if (which_alternative == 1)
6027 {
6028 rtx tmp;
6029 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6030 }
6031
6032 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6033 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6034 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6035
6036 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6037 }
6038 }
6039 [(set (attr "type")
6040 (if_then_else (match_operand:SWI 2 "incdec_operand")
6041 (const_string "incdec")
6042 (const_string "alu")))
6043 (set (attr "length_immediate")
6044 (if_then_else
6045 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6046 (const_string "1")
6047 (const_string "*")))
6048 (set_attr "mode" "<MODE>")])
6049
6050 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6051 (define_insn "*addsi_3_zext"
6052 [(set (reg FLAGS_REG)
6053 (compare
6054 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6055 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6056 (set (match_operand:DI 0 "register_operand" "=r,r")
6057 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6058 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6059 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6060 {
6061 switch (get_attr_type (insn))
6062 {
6063 case TYPE_INCDEC:
6064 if (operands[2] == const1_rtx)
6065 return "inc{l}\t%k0";
6066 else
6067 {
6068 gcc_assert (operands[2] == constm1_rtx);
6069 return "dec{l}\t%k0";
6070 }
6071
6072 default:
6073 if (which_alternative == 1)
6074 {
6075 rtx tmp;
6076 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6077 }
6078
6079 if (x86_maybe_negate_const_int (&operands[2], SImode))
6080 return "sub{l}\t{%2, %k0|%k0, %2}";
6081
6082 return "add{l}\t{%2, %k0|%k0, %2}";
6083 }
6084 }
6085 [(set (attr "type")
6086 (if_then_else (match_operand:SI 2 "incdec_operand")
6087 (const_string "incdec")
6088 (const_string "alu")))
6089 (set (attr "length_immediate")
6090 (if_then_else
6091 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6092 (const_string "1")
6093 (const_string "*")))
6094 (set_attr "mode" "SI")])
6095
6096 ; For comparisons against 1, -1 and 128, we may generate better code
6097 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6098 ; is matched then. We can't accept general immediate, because for
6099 ; case of overflows, the result is messed up.
6100 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6101 ; only for comparisons not depending on it.
6102
6103 (define_insn "*adddi_4"
6104 [(set (reg FLAGS_REG)
6105 (compare
6106 (match_operand:DI 1 "nonimmediate_operand" "0")
6107 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6108 (clobber (match_scratch:DI 0 "=rm"))]
6109 "TARGET_64BIT
6110 && ix86_match_ccmode (insn, CCGCmode)"
6111 {
6112 switch (get_attr_type (insn))
6113 {
6114 case TYPE_INCDEC:
6115 if (operands[2] == constm1_rtx)
6116 return "inc{q}\t%0";
6117 else
6118 {
6119 gcc_assert (operands[2] == const1_rtx);
6120 return "dec{q}\t%0";
6121 }
6122
6123 default:
6124 if (x86_maybe_negate_const_int (&operands[2], DImode))
6125 return "add{q}\t{%2, %0|%0, %2}";
6126
6127 return "sub{q}\t{%2, %0|%0, %2}";
6128 }
6129 }
6130 [(set (attr "type")
6131 (if_then_else (match_operand:DI 2 "incdec_operand")
6132 (const_string "incdec")
6133 (const_string "alu")))
6134 (set (attr "length_immediate")
6135 (if_then_else
6136 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6137 (const_string "1")
6138 (const_string "*")))
6139 (set_attr "mode" "DI")])
6140
6141 ; For comparisons against 1, -1 and 128, we may generate better code
6142 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6143 ; is matched then. We can't accept general immediate, because for
6144 ; case of overflows, the result is messed up.
6145 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6146 ; only for comparisons not depending on it.
6147
6148 (define_insn "*add<mode>_4"
6149 [(set (reg FLAGS_REG)
6150 (compare
6151 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6152 (match_operand:SWI124 2 "const_int_operand" "n")))
6153 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6154 "ix86_match_ccmode (insn, CCGCmode)"
6155 {
6156 switch (get_attr_type (insn))
6157 {
6158 case TYPE_INCDEC:
6159 if (operands[2] == constm1_rtx)
6160 return "inc{<imodesuffix>}\t%0";
6161 else
6162 {
6163 gcc_assert (operands[2] == const1_rtx);
6164 return "dec{<imodesuffix>}\t%0";
6165 }
6166
6167 default:
6168 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6169 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6170
6171 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6172 }
6173 }
6174 [(set (attr "type")
6175 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6176 (const_string "incdec")
6177 (const_string "alu")))
6178 (set (attr "length_immediate")
6179 (if_then_else
6180 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6181 (const_string "1")
6182 (const_string "*")))
6183 (set_attr "mode" "<MODE>")])
6184
6185 (define_insn "*add<mode>_5"
6186 [(set (reg FLAGS_REG)
6187 (compare
6188 (plus:SWI
6189 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6190 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6191 (const_int 0)))
6192 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6193 "ix86_match_ccmode (insn, CCGOCmode)
6194 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6195 {
6196 switch (get_attr_type (insn))
6197 {
6198 case TYPE_INCDEC:
6199 if (operands[2] == const1_rtx)
6200 return "inc{<imodesuffix>}\t%0";
6201 else
6202 {
6203 gcc_assert (operands[2] == constm1_rtx);
6204 return "dec{<imodesuffix>}\t%0";
6205 }
6206
6207 default:
6208 if (which_alternative == 1)
6209 {
6210 rtx tmp;
6211 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6212 }
6213
6214 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6215 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6216 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6217
6218 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6219 }
6220 }
6221 [(set (attr "type")
6222 (if_then_else (match_operand:SWI 2 "incdec_operand")
6223 (const_string "incdec")
6224 (const_string "alu")))
6225 (set (attr "length_immediate")
6226 (if_then_else
6227 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6228 (const_string "1")
6229 (const_string "*")))
6230 (set_attr "mode" "<MODE>")])
6231
6232 (define_insn "*addqi_ext_1_rex64"
6233 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6234 (const_int 8)
6235 (const_int 8))
6236 (plus:SI
6237 (zero_extract:SI
6238 (match_operand 1 "ext_register_operand" "0")
6239 (const_int 8)
6240 (const_int 8))
6241 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6242 (clobber (reg:CC FLAGS_REG))]
6243 "TARGET_64BIT"
6244 {
6245 switch (get_attr_type (insn))
6246 {
6247 case TYPE_INCDEC:
6248 if (operands[2] == const1_rtx)
6249 return "inc{b}\t%h0";
6250 else
6251 {
6252 gcc_assert (operands[2] == constm1_rtx);
6253 return "dec{b}\t%h0";
6254 }
6255
6256 default:
6257 return "add{b}\t{%2, %h0|%h0, %2}";
6258 }
6259 }
6260 [(set (attr "type")
6261 (if_then_else (match_operand:QI 2 "incdec_operand")
6262 (const_string "incdec")
6263 (const_string "alu")))
6264 (set_attr "modrm" "1")
6265 (set_attr "mode" "QI")])
6266
6267 (define_insn "addqi_ext_1"
6268 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6269 (const_int 8)
6270 (const_int 8))
6271 (plus:SI
6272 (zero_extract:SI
6273 (match_operand 1 "ext_register_operand" "0")
6274 (const_int 8)
6275 (const_int 8))
6276 (match_operand:QI 2 "general_operand" "Qmn")))
6277 (clobber (reg:CC FLAGS_REG))]
6278 "!TARGET_64BIT"
6279 {
6280 switch (get_attr_type (insn))
6281 {
6282 case TYPE_INCDEC:
6283 if (operands[2] == const1_rtx)
6284 return "inc{b}\t%h0";
6285 else
6286 {
6287 gcc_assert (operands[2] == constm1_rtx);
6288 return "dec{b}\t%h0";
6289 }
6290
6291 default:
6292 return "add{b}\t{%2, %h0|%h0, %2}";
6293 }
6294 }
6295 [(set (attr "type")
6296 (if_then_else (match_operand:QI 2 "incdec_operand")
6297 (const_string "incdec")
6298 (const_string "alu")))
6299 (set_attr "modrm" "1")
6300 (set_attr "mode" "QI")])
6301
6302 (define_insn "*addqi_ext_2"
6303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6304 (const_int 8)
6305 (const_int 8))
6306 (plus:SI
6307 (zero_extract:SI
6308 (match_operand 1 "ext_register_operand" "%0")
6309 (const_int 8)
6310 (const_int 8))
6311 (zero_extract:SI
6312 (match_operand 2 "ext_register_operand" "Q")
6313 (const_int 8)
6314 (const_int 8))))
6315 (clobber (reg:CC FLAGS_REG))]
6316 ""
6317 "add{b}\t{%h2, %h0|%h0, %h2}"
6318 [(set_attr "type" "alu")
6319 (set_attr "mode" "QI")])
6320
6321 ;; The lea patterns for modes less than 32 bits need to be matched by
6322 ;; several insns converted to real lea by splitters.
6323
6324 (define_insn_and_split "*lea_general_1"
6325 [(set (match_operand 0 "register_operand" "=r")
6326 (plus (plus (match_operand 1 "index_register_operand" "l")
6327 (match_operand 2 "register_operand" "r"))
6328 (match_operand 3 "immediate_operand" "i")))]
6329 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6330 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6331 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6332 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6333 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6334 || GET_MODE (operands[3]) == VOIDmode)"
6335 "#"
6336 "&& reload_completed"
6337 [(const_int 0)]
6338 {
6339 enum machine_mode mode = SImode;
6340 rtx pat;
6341
6342 operands[0] = gen_lowpart (mode, operands[0]);
6343 operands[1] = gen_lowpart (mode, operands[1]);
6344 operands[2] = gen_lowpart (mode, operands[2]);
6345 operands[3] = gen_lowpart (mode, operands[3]);
6346
6347 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6348 operands[3]);
6349
6350 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6351 DONE;
6352 }
6353 [(set_attr "type" "lea")
6354 (set_attr "mode" "SI")])
6355
6356 (define_insn_and_split "*lea_general_2"
6357 [(set (match_operand 0 "register_operand" "=r")
6358 (plus (mult (match_operand 1 "index_register_operand" "l")
6359 (match_operand 2 "const248_operand" "n"))
6360 (match_operand 3 "nonmemory_operand" "ri")))]
6361 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6362 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6363 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6364 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6365 || GET_MODE (operands[3]) == VOIDmode)"
6366 "#"
6367 "&& reload_completed"
6368 [(const_int 0)]
6369 {
6370 enum machine_mode mode = SImode;
6371 rtx pat;
6372
6373 operands[0] = gen_lowpart (mode, operands[0]);
6374 operands[1] = gen_lowpart (mode, operands[1]);
6375 operands[3] = gen_lowpart (mode, operands[3]);
6376
6377 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6378 operands[3]);
6379
6380 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6381 DONE;
6382 }
6383 [(set_attr "type" "lea")
6384 (set_attr "mode" "SI")])
6385
6386 (define_insn_and_split "*lea_general_3"
6387 [(set (match_operand 0 "register_operand" "=r")
6388 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6389 (match_operand 2 "const248_operand" "n"))
6390 (match_operand 3 "register_operand" "r"))
6391 (match_operand 4 "immediate_operand" "i")))]
6392 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6393 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6394 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6395 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6396 "#"
6397 "&& reload_completed"
6398 [(const_int 0)]
6399 {
6400 enum machine_mode mode = SImode;
6401 rtx pat;
6402
6403 operands[0] = gen_lowpart (mode, operands[0]);
6404 operands[1] = gen_lowpart (mode, operands[1]);
6405 operands[3] = gen_lowpart (mode, operands[3]);
6406 operands[4] = gen_lowpart (mode, operands[4]);
6407
6408 pat = gen_rtx_PLUS (mode,
6409 gen_rtx_PLUS (mode,
6410 gen_rtx_MULT (mode, operands[1],
6411 operands[2]),
6412 operands[3]),
6413 operands[4]);
6414
6415 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6416 DONE;
6417 }
6418 [(set_attr "type" "lea")
6419 (set_attr "mode" "SI")])
6420
6421 (define_insn_and_split "*lea_general_4"
6422 [(set (match_operand 0 "register_operand" "=r")
6423 (any_or (ashift
6424 (match_operand 1 "index_register_operand" "l")
6425 (match_operand 2 "const_int_operand" "n"))
6426 (match_operand 3 "const_int_operand" "n")))]
6427 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6428 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6429 || GET_MODE (operands[0]) == SImode
6430 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6431 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6432 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6433 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6434 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6435 "#"
6436 "&& reload_completed"
6437 [(const_int 0)]
6438 {
6439 enum machine_mode mode = GET_MODE (operands[0]);
6440 rtx pat;
6441
6442 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6443 {
6444 mode = SImode;
6445 operands[0] = gen_lowpart (mode, operands[0]);
6446 operands[1] = gen_lowpart (mode, operands[1]);
6447 }
6448
6449 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6450
6451 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6452 INTVAL (operands[3]));
6453
6454 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6455 DONE;
6456 }
6457 [(set_attr "type" "lea")
6458 (set (attr "mode")
6459 (if_then_else (match_operand:DI 0)
6460 (const_string "DI")
6461 (const_string "SI")))])
6462 \f
6463 ;; Subtract instructions
6464
6465 (define_expand "sub<mode>3"
6466 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6467 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6468 (match_operand:SDWIM 2 "<general_operand>")))]
6469 ""
6470 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6471
6472 (define_insn_and_split "*sub<dwi>3_doubleword"
6473 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6474 (minus:<DWI>
6475 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6476 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6477 (clobber (reg:CC FLAGS_REG))]
6478 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6479 "#"
6480 "reload_completed"
6481 [(parallel [(set (reg:CC FLAGS_REG)
6482 (compare:CC (match_dup 1) (match_dup 2)))
6483 (set (match_dup 0)
6484 (minus:DWIH (match_dup 1) (match_dup 2)))])
6485 (parallel [(set (match_dup 3)
6486 (minus:DWIH
6487 (match_dup 4)
6488 (plus:DWIH
6489 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6490 (match_dup 5))))
6491 (clobber (reg:CC FLAGS_REG))])]
6492 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6493
6494 (define_insn "*sub<mode>_1"
6495 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6496 (minus:SWI
6497 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6498 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6499 (clobber (reg:CC FLAGS_REG))]
6500 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6501 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6502 [(set_attr "type" "alu")
6503 (set_attr "mode" "<MODE>")])
6504
6505 (define_insn "*subsi_1_zext"
6506 [(set (match_operand:DI 0 "register_operand" "=r")
6507 (zero_extend:DI
6508 (minus:SI (match_operand:SI 1 "register_operand" "0")
6509 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6510 (clobber (reg:CC FLAGS_REG))]
6511 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6512 "sub{l}\t{%2, %k0|%k0, %2}"
6513 [(set_attr "type" "alu")
6514 (set_attr "mode" "SI")])
6515
6516 (define_insn "*subqi_1_slp"
6517 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6518 (minus:QI (match_dup 0)
6519 (match_operand:QI 1 "general_operand" "qn,qm")))
6520 (clobber (reg:CC FLAGS_REG))]
6521 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6522 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6523 "sub{b}\t{%1, %0|%0, %1}"
6524 [(set_attr "type" "alu1")
6525 (set_attr "mode" "QI")])
6526
6527 (define_insn "*sub<mode>_2"
6528 [(set (reg FLAGS_REG)
6529 (compare
6530 (minus:SWI
6531 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6532 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6533 (const_int 0)))
6534 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6535 (minus:SWI (match_dup 1) (match_dup 2)))]
6536 "ix86_match_ccmode (insn, CCGOCmode)
6537 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6538 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6539 [(set_attr "type" "alu")
6540 (set_attr "mode" "<MODE>")])
6541
6542 (define_insn "*subsi_2_zext"
6543 [(set (reg FLAGS_REG)
6544 (compare
6545 (minus:SI (match_operand:SI 1 "register_operand" "0")
6546 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6547 (const_int 0)))
6548 (set (match_operand:DI 0 "register_operand" "=r")
6549 (zero_extend:DI
6550 (minus:SI (match_dup 1)
6551 (match_dup 2))))]
6552 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6553 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554 "sub{l}\t{%2, %k0|%k0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "SI")])
6557
6558 (define_insn "*sub<mode>_3"
6559 [(set (reg FLAGS_REG)
6560 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6561 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6562 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6563 (minus:SWI (match_dup 1) (match_dup 2)))]
6564 "ix86_match_ccmode (insn, CCmode)
6565 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6566 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "<MODE>")])
6569
6570 (define_insn "*subsi_3_zext"
6571 [(set (reg FLAGS_REG)
6572 (compare (match_operand:SI 1 "register_operand" "0")
6573 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6574 (set (match_operand:DI 0 "register_operand" "=r")
6575 (zero_extend:DI
6576 (minus:SI (match_dup 1)
6577 (match_dup 2))))]
6578 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6579 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6580 "sub{l}\t{%2, %1|%1, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "SI")])
6583 \f
6584 ;; Add with carry and subtract with borrow
6585
6586 (define_expand "<plusminus_insn><mode>3_carry"
6587 [(parallel
6588 [(set (match_operand:SWI 0 "nonimmediate_operand")
6589 (plusminus:SWI
6590 (match_operand:SWI 1 "nonimmediate_operand")
6591 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6592 [(match_operand 3 "flags_reg_operand")
6593 (const_int 0)])
6594 (match_operand:SWI 2 "<general_operand>"))))
6595 (clobber (reg:CC FLAGS_REG))])]
6596 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6597
6598 (define_insn "*<plusminus_insn><mode>3_carry"
6599 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6600 (plusminus:SWI
6601 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6602 (plus:SWI
6603 (match_operator 3 "ix86_carry_flag_operator"
6604 [(reg FLAGS_REG) (const_int 0)])
6605 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6606 (clobber (reg:CC FLAGS_REG))]
6607 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6608 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "use_carry" "1")
6611 (set_attr "pent_pair" "pu")
6612 (set_attr "mode" "<MODE>")])
6613
6614 (define_insn "*addsi3_carry_zext"
6615 [(set (match_operand:DI 0 "register_operand" "=r")
6616 (zero_extend:DI
6617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6618 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6619 [(reg FLAGS_REG) (const_int 0)])
6620 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6621 (clobber (reg:CC FLAGS_REG))]
6622 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6623 "adc{l}\t{%2, %k0|%k0, %2}"
6624 [(set_attr "type" "alu")
6625 (set_attr "use_carry" "1")
6626 (set_attr "pent_pair" "pu")
6627 (set_attr "mode" "SI")])
6628
6629 (define_insn "*subsi3_carry_zext"
6630 [(set (match_operand:DI 0 "register_operand" "=r")
6631 (zero_extend:DI
6632 (minus:SI (match_operand:SI 1 "register_operand" "0")
6633 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6634 [(reg FLAGS_REG) (const_int 0)])
6635 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6638 "sbb{l}\t{%2, %k0|%k0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "pent_pair" "pu")
6641 (set_attr "mode" "SI")])
6642 \f
6643 ;; ADCX instruction
6644
6645 (define_insn "adcx<mode>3"
6646 [(set (reg:CCC FLAGS_REG)
6647 (compare:CCC
6648 (plus:SWI48
6649 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6650 (plus:SWI48
6651 (match_operator 4 "ix86_carry_flag_operator"
6652 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6653 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6654 (const_int 0)))
6655 (set (match_operand:SWI48 0 "register_operand" "=r")
6656 (plus:SWI48 (match_dup 1)
6657 (plus:SWI48 (match_op_dup 4
6658 [(match_dup 3) (const_int 0)])
6659 (match_dup 2))))]
6660 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6661 "adcx\t{%2, %0|%0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "use_carry" "1")
6664 (set_attr "mode" "<MODE>")])
6665 \f
6666 ;; Overflow setting add and subtract instructions
6667
6668 (define_insn "*add<mode>3_cconly_overflow"
6669 [(set (reg:CCC FLAGS_REG)
6670 (compare:CCC
6671 (plus:SWI
6672 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6673 (match_operand:SWI 2 "<general_operand>" "<g>"))
6674 (match_dup 1)))
6675 (clobber (match_scratch:SWI 0 "=<r>"))]
6676 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6677 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "alu")
6679 (set_attr "mode" "<MODE>")])
6680
6681 (define_insn "*sub<mode>3_cconly_overflow"
6682 [(set (reg:CCC FLAGS_REG)
6683 (compare:CCC
6684 (minus:SWI
6685 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6686 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6687 (match_dup 0)))]
6688 ""
6689 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6690 [(set_attr "type" "icmp")
6691 (set_attr "mode" "<MODE>")])
6692
6693 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6694 [(set (reg:CCC FLAGS_REG)
6695 (compare:CCC
6696 (plusminus:SWI
6697 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6698 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6699 (match_dup 1)))
6700 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6701 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6702 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6703 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6704 [(set_attr "type" "alu")
6705 (set_attr "mode" "<MODE>")])
6706
6707 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6708 [(set (reg:CCC FLAGS_REG)
6709 (compare:CCC
6710 (plusminus:SI
6711 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6712 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6713 (match_dup 1)))
6714 (set (match_operand:DI 0 "register_operand" "=r")
6715 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6716 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6717 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6718 [(set_attr "type" "alu")
6719 (set_attr "mode" "SI")])
6720
6721 ;; The patterns that match these are at the end of this file.
6722
6723 (define_expand "<plusminus_insn>xf3"
6724 [(set (match_operand:XF 0 "register_operand")
6725 (plusminus:XF
6726 (match_operand:XF 1 "register_operand")
6727 (match_operand:XF 2 "register_operand")))]
6728 "TARGET_80387")
6729
6730 (define_expand "<plusminus_insn><mode>3"
6731 [(set (match_operand:MODEF 0 "register_operand")
6732 (plusminus:MODEF
6733 (match_operand:MODEF 1 "register_operand")
6734 (match_operand:MODEF 2 "nonimmediate_operand")))]
6735 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6736 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6737 \f
6738 ;; Multiply instructions
6739
6740 (define_expand "mul<mode>3"
6741 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6742 (mult:SWIM248
6743 (match_operand:SWIM248 1 "register_operand")
6744 (match_operand:SWIM248 2 "<general_operand>")))
6745 (clobber (reg:CC FLAGS_REG))])])
6746
6747 (define_expand "mulqi3"
6748 [(parallel [(set (match_operand:QI 0 "register_operand")
6749 (mult:QI
6750 (match_operand:QI 1 "register_operand")
6751 (match_operand:QI 2 "nonimmediate_operand")))
6752 (clobber (reg:CC FLAGS_REG))])]
6753 "TARGET_QIMODE_MATH")
6754
6755 ;; On AMDFAM10
6756 ;; IMUL reg32/64, reg32/64, imm8 Direct
6757 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6758 ;; IMUL reg32/64, reg32/64, imm32 Direct
6759 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6760 ;; IMUL reg32/64, reg32/64 Direct
6761 ;; IMUL reg32/64, mem32/64 Direct
6762 ;;
6763 ;; On BDVER1, all above IMULs use DirectPath
6764
6765 (define_insn "*mul<mode>3_1"
6766 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6767 (mult:SWI48
6768 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6769 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6772 "@
6773 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6774 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6775 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6776 [(set_attr "type" "imul")
6777 (set_attr "prefix_0f" "0,0,1")
6778 (set (attr "athlon_decode")
6779 (cond [(eq_attr "cpu" "athlon")
6780 (const_string "vector")
6781 (eq_attr "alternative" "1")
6782 (const_string "vector")
6783 (and (eq_attr "alternative" "2")
6784 (match_operand 1 "memory_operand"))
6785 (const_string "vector")]
6786 (const_string "direct")))
6787 (set (attr "amdfam10_decode")
6788 (cond [(and (eq_attr "alternative" "0,1")
6789 (match_operand 1 "memory_operand"))
6790 (const_string "vector")]
6791 (const_string "direct")))
6792 (set_attr "bdver1_decode" "direct")
6793 (set_attr "mode" "<MODE>")])
6794
6795 (define_insn "*mulsi3_1_zext"
6796 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6797 (zero_extend:DI
6798 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6799 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6800 (clobber (reg:CC FLAGS_REG))]
6801 "TARGET_64BIT
6802 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6803 "@
6804 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6805 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6806 imul{l}\t{%2, %k0|%k0, %2}"
6807 [(set_attr "type" "imul")
6808 (set_attr "prefix_0f" "0,0,1")
6809 (set (attr "athlon_decode")
6810 (cond [(eq_attr "cpu" "athlon")
6811 (const_string "vector")
6812 (eq_attr "alternative" "1")
6813 (const_string "vector")
6814 (and (eq_attr "alternative" "2")
6815 (match_operand 1 "memory_operand"))
6816 (const_string "vector")]
6817 (const_string "direct")))
6818 (set (attr "amdfam10_decode")
6819 (cond [(and (eq_attr "alternative" "0,1")
6820 (match_operand 1 "memory_operand"))
6821 (const_string "vector")]
6822 (const_string "direct")))
6823 (set_attr "bdver1_decode" "direct")
6824 (set_attr "mode" "SI")])
6825
6826 ;; On AMDFAM10
6827 ;; IMUL reg16, reg16, imm8 VectorPath
6828 ;; IMUL reg16, mem16, imm8 VectorPath
6829 ;; IMUL reg16, reg16, imm16 VectorPath
6830 ;; IMUL reg16, mem16, imm16 VectorPath
6831 ;; IMUL reg16, reg16 Direct
6832 ;; IMUL reg16, mem16 Direct
6833 ;;
6834 ;; On BDVER1, all HI MULs use DoublePath
6835
6836 (define_insn "*mulhi3_1"
6837 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6838 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6839 (match_operand:HI 2 "general_operand" "K,n,mr")))
6840 (clobber (reg:CC FLAGS_REG))]
6841 "TARGET_HIMODE_MATH
6842 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6843 "@
6844 imul{w}\t{%2, %1, %0|%0, %1, %2}
6845 imul{w}\t{%2, %1, %0|%0, %1, %2}
6846 imul{w}\t{%2, %0|%0, %2}"
6847 [(set_attr "type" "imul")
6848 (set_attr "prefix_0f" "0,0,1")
6849 (set (attr "athlon_decode")
6850 (cond [(eq_attr "cpu" "athlon")
6851 (const_string "vector")
6852 (eq_attr "alternative" "1,2")
6853 (const_string "vector")]
6854 (const_string "direct")))
6855 (set (attr "amdfam10_decode")
6856 (cond [(eq_attr "alternative" "0,1")
6857 (const_string "vector")]
6858 (const_string "direct")))
6859 (set_attr "bdver1_decode" "double")
6860 (set_attr "mode" "HI")])
6861
6862 ;;On AMDFAM10 and BDVER1
6863 ;; MUL reg8 Direct
6864 ;; MUL mem8 Direct
6865
6866 (define_insn "*mulqi3_1"
6867 [(set (match_operand:QI 0 "register_operand" "=a")
6868 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6869 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6870 (clobber (reg:CC FLAGS_REG))]
6871 "TARGET_QIMODE_MATH
6872 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6873 "mul{b}\t%2"
6874 [(set_attr "type" "imul")
6875 (set_attr "length_immediate" "0")
6876 (set (attr "athlon_decode")
6877 (if_then_else (eq_attr "cpu" "athlon")
6878 (const_string "vector")
6879 (const_string "direct")))
6880 (set_attr "amdfam10_decode" "direct")
6881 (set_attr "bdver1_decode" "direct")
6882 (set_attr "mode" "QI")])
6883
6884 (define_expand "<u>mul<mode><dwi>3"
6885 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6886 (mult:<DWI>
6887 (any_extend:<DWI>
6888 (match_operand:DWIH 1 "nonimmediate_operand"))
6889 (any_extend:<DWI>
6890 (match_operand:DWIH 2 "register_operand"))))
6891 (clobber (reg:CC FLAGS_REG))])])
6892
6893 (define_expand "<u>mulqihi3"
6894 [(parallel [(set (match_operand:HI 0 "register_operand")
6895 (mult:HI
6896 (any_extend:HI
6897 (match_operand:QI 1 "nonimmediate_operand"))
6898 (any_extend:HI
6899 (match_operand:QI 2 "register_operand"))))
6900 (clobber (reg:CC FLAGS_REG))])]
6901 "TARGET_QIMODE_MATH")
6902
6903 (define_insn "*bmi2_umulditi3_1"
6904 [(set (match_operand:DI 0 "register_operand" "=r")
6905 (mult:DI
6906 (match_operand:DI 2 "nonimmediate_operand" "%d")
6907 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6908 (set (match_operand:DI 1 "register_operand" "=r")
6909 (truncate:DI
6910 (lshiftrt:TI
6911 (mult:TI (zero_extend:TI (match_dup 2))
6912 (zero_extend:TI (match_dup 3)))
6913 (const_int 64))))]
6914 "TARGET_64BIT && TARGET_BMI2
6915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6916 "mulx\t{%3, %0, %1|%1, %0, %3}"
6917 [(set_attr "type" "imulx")
6918 (set_attr "prefix" "vex")
6919 (set_attr "mode" "DI")])
6920
6921 (define_insn "*bmi2_umulsidi3_1"
6922 [(set (match_operand:SI 0 "register_operand" "=r")
6923 (mult:SI
6924 (match_operand:SI 2 "nonimmediate_operand" "%d")
6925 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6926 (set (match_operand:SI 1 "register_operand" "=r")
6927 (truncate:SI
6928 (lshiftrt:DI
6929 (mult:DI (zero_extend:DI (match_dup 2))
6930 (zero_extend:DI (match_dup 3)))
6931 (const_int 32))))]
6932 "!TARGET_64BIT && TARGET_BMI2
6933 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6934 "mulx\t{%3, %0, %1|%1, %0, %3}"
6935 [(set_attr "type" "imulx")
6936 (set_attr "prefix" "vex")
6937 (set_attr "mode" "SI")])
6938
6939 (define_insn "*umul<mode><dwi>3_1"
6940 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6941 (mult:<DWI>
6942 (zero_extend:<DWI>
6943 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6944 (zero_extend:<DWI>
6945 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6946 (clobber (reg:CC FLAGS_REG))]
6947 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6948 "@
6949 #
6950 mul{<imodesuffix>}\t%2"
6951 [(set_attr "isa" "bmi2,*")
6952 (set_attr "type" "imulx,imul")
6953 (set_attr "length_immediate" "*,0")
6954 (set (attr "athlon_decode")
6955 (cond [(eq_attr "alternative" "1")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "double"))]
6959 (const_string "*")))
6960 (set_attr "amdfam10_decode" "*,double")
6961 (set_attr "bdver1_decode" "*,direct")
6962 (set_attr "prefix" "vex,orig")
6963 (set_attr "mode" "<MODE>")])
6964
6965 ;; Convert mul to the mulx pattern to avoid flags dependency.
6966 (define_split
6967 [(set (match_operand:<DWI> 0 "register_operand")
6968 (mult:<DWI>
6969 (zero_extend:<DWI>
6970 (match_operand:DWIH 1 "register_operand"))
6971 (zero_extend:<DWI>
6972 (match_operand:DWIH 2 "nonimmediate_operand"))))
6973 (clobber (reg:CC FLAGS_REG))]
6974 "TARGET_BMI2 && reload_completed
6975 && true_regnum (operands[1]) == DX_REG"
6976 [(parallel [(set (match_dup 3)
6977 (mult:DWIH (match_dup 1) (match_dup 2)))
6978 (set (match_dup 4)
6979 (truncate:DWIH
6980 (lshiftrt:<DWI>
6981 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6982 (zero_extend:<DWI> (match_dup 2)))
6983 (match_dup 5))))])]
6984 {
6985 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6986
6987 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6988 })
6989
6990 (define_insn "*mul<mode><dwi>3_1"
6991 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6992 (mult:<DWI>
6993 (sign_extend:<DWI>
6994 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6995 (sign_extend:<DWI>
6996 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6997 (clobber (reg:CC FLAGS_REG))]
6998 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999 "imul{<imodesuffix>}\t%2"
7000 [(set_attr "type" "imul")
7001 (set_attr "length_immediate" "0")
7002 (set (attr "athlon_decode")
7003 (if_then_else (eq_attr "cpu" "athlon")
7004 (const_string "vector")
7005 (const_string "double")))
7006 (set_attr "amdfam10_decode" "double")
7007 (set_attr "bdver1_decode" "direct")
7008 (set_attr "mode" "<MODE>")])
7009
7010 (define_insn "*<u>mulqihi3_1"
7011 [(set (match_operand:HI 0 "register_operand" "=a")
7012 (mult:HI
7013 (any_extend:HI
7014 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7015 (any_extend:HI
7016 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7017 (clobber (reg:CC FLAGS_REG))]
7018 "TARGET_QIMODE_MATH
7019 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7020 "<sgnprefix>mul{b}\t%2"
7021 [(set_attr "type" "imul")
7022 (set_attr "length_immediate" "0")
7023 (set (attr "athlon_decode")
7024 (if_then_else (eq_attr "cpu" "athlon")
7025 (const_string "vector")
7026 (const_string "direct")))
7027 (set_attr "amdfam10_decode" "direct")
7028 (set_attr "bdver1_decode" "direct")
7029 (set_attr "mode" "QI")])
7030
7031 (define_expand "<s>mul<mode>3_highpart"
7032 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7033 (truncate:SWI48
7034 (lshiftrt:<DWI>
7035 (mult:<DWI>
7036 (any_extend:<DWI>
7037 (match_operand:SWI48 1 "nonimmediate_operand"))
7038 (any_extend:<DWI>
7039 (match_operand:SWI48 2 "register_operand")))
7040 (match_dup 4))))
7041 (clobber (match_scratch:SWI48 3))
7042 (clobber (reg:CC FLAGS_REG))])]
7043 ""
7044 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7045
7046 (define_insn "*<s>muldi3_highpart_1"
7047 [(set (match_operand:DI 0 "register_operand" "=d")
7048 (truncate:DI
7049 (lshiftrt:TI
7050 (mult:TI
7051 (any_extend:TI
7052 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7053 (any_extend:TI
7054 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7055 (const_int 64))))
7056 (clobber (match_scratch:DI 3 "=1"))
7057 (clobber (reg:CC FLAGS_REG))]
7058 "TARGET_64BIT
7059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7060 "<sgnprefix>mul{q}\t%2"
7061 [(set_attr "type" "imul")
7062 (set_attr "length_immediate" "0")
7063 (set (attr "athlon_decode")
7064 (if_then_else (eq_attr "cpu" "athlon")
7065 (const_string "vector")
7066 (const_string "double")))
7067 (set_attr "amdfam10_decode" "double")
7068 (set_attr "bdver1_decode" "direct")
7069 (set_attr "mode" "DI")])
7070
7071 (define_insn "*<s>mulsi3_highpart_1"
7072 [(set (match_operand:SI 0 "register_operand" "=d")
7073 (truncate:SI
7074 (lshiftrt:DI
7075 (mult:DI
7076 (any_extend:DI
7077 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7078 (any_extend:DI
7079 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7080 (const_int 32))))
7081 (clobber (match_scratch:SI 3 "=1"))
7082 (clobber (reg:CC FLAGS_REG))]
7083 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7084 "<sgnprefix>mul{l}\t%2"
7085 [(set_attr "type" "imul")
7086 (set_attr "length_immediate" "0")
7087 (set (attr "athlon_decode")
7088 (if_then_else (eq_attr "cpu" "athlon")
7089 (const_string "vector")
7090 (const_string "double")))
7091 (set_attr "amdfam10_decode" "double")
7092 (set_attr "bdver1_decode" "direct")
7093 (set_attr "mode" "SI")])
7094
7095 (define_insn "*<s>mulsi3_highpart_zext"
7096 [(set (match_operand:DI 0 "register_operand" "=d")
7097 (zero_extend:DI (truncate:SI
7098 (lshiftrt:DI
7099 (mult:DI (any_extend:DI
7100 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7101 (any_extend:DI
7102 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7103 (const_int 32)))))
7104 (clobber (match_scratch:SI 3 "=1"))
7105 (clobber (reg:CC FLAGS_REG))]
7106 "TARGET_64BIT
7107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7108 "<sgnprefix>mul{l}\t%2"
7109 [(set_attr "type" "imul")
7110 (set_attr "length_immediate" "0")
7111 (set (attr "athlon_decode")
7112 (if_then_else (eq_attr "cpu" "athlon")
7113 (const_string "vector")
7114 (const_string "double")))
7115 (set_attr "amdfam10_decode" "double")
7116 (set_attr "bdver1_decode" "direct")
7117 (set_attr "mode" "SI")])
7118
7119 ;; The patterns that match these are at the end of this file.
7120
7121 (define_expand "mulxf3"
7122 [(set (match_operand:XF 0 "register_operand")
7123 (mult:XF (match_operand:XF 1 "register_operand")
7124 (match_operand:XF 2 "register_operand")))]
7125 "TARGET_80387")
7126
7127 (define_expand "mul<mode>3"
7128 [(set (match_operand:MODEF 0 "register_operand")
7129 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7130 (match_operand:MODEF 2 "nonimmediate_operand")))]
7131 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7132 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7133 \f
7134 ;; Divide instructions
7135
7136 ;; The patterns that match these are at the end of this file.
7137
7138 (define_expand "divxf3"
7139 [(set (match_operand:XF 0 "register_operand")
7140 (div:XF (match_operand:XF 1 "register_operand")
7141 (match_operand:XF 2 "register_operand")))]
7142 "TARGET_80387")
7143
7144 (define_expand "divdf3"
7145 [(set (match_operand:DF 0 "register_operand")
7146 (div:DF (match_operand:DF 1 "register_operand")
7147 (match_operand:DF 2 "nonimmediate_operand")))]
7148 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7149 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7150
7151 (define_expand "divsf3"
7152 [(set (match_operand:SF 0 "register_operand")
7153 (div:SF (match_operand:SF 1 "register_operand")
7154 (match_operand:SF 2 "nonimmediate_operand")))]
7155 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7156 || TARGET_SSE_MATH"
7157 {
7158 if (TARGET_SSE_MATH
7159 && TARGET_RECIP_DIV
7160 && optimize_insn_for_speed_p ()
7161 && flag_finite_math_only && !flag_trapping_math
7162 && flag_unsafe_math_optimizations)
7163 {
7164 ix86_emit_swdivsf (operands[0], operands[1],
7165 operands[2], SFmode);
7166 DONE;
7167 }
7168 })
7169 \f
7170 ;; Divmod instructions.
7171
7172 (define_expand "divmod<mode>4"
7173 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7174 (div:SWIM248
7175 (match_operand:SWIM248 1 "register_operand")
7176 (match_operand:SWIM248 2 "nonimmediate_operand")))
7177 (set (match_operand:SWIM248 3 "register_operand")
7178 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7179 (clobber (reg:CC FLAGS_REG))])])
7180
7181 ;; Split with 8bit unsigned divide:
7182 ;; if (dividend an divisor are in [0-255])
7183 ;; use 8bit unsigned integer divide
7184 ;; else
7185 ;; use original integer divide
7186 (define_split
7187 [(set (match_operand:SWI48 0 "register_operand")
7188 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7189 (match_operand:SWI48 3 "nonimmediate_operand")))
7190 (set (match_operand:SWI48 1 "register_operand")
7191 (mod:SWI48 (match_dup 2) (match_dup 3)))
7192 (clobber (reg:CC FLAGS_REG))]
7193 "TARGET_USE_8BIT_IDIV
7194 && TARGET_QIMODE_MATH
7195 && can_create_pseudo_p ()
7196 && !optimize_insn_for_size_p ()"
7197 [(const_int 0)]
7198 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7199
7200 (define_insn_and_split "divmod<mode>4_1"
7201 [(set (match_operand:SWI48 0 "register_operand" "=a")
7202 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7203 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7204 (set (match_operand:SWI48 1 "register_operand" "=&d")
7205 (mod:SWI48 (match_dup 2) (match_dup 3)))
7206 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7207 (clobber (reg:CC FLAGS_REG))]
7208 ""
7209 "#"
7210 "reload_completed"
7211 [(parallel [(set (match_dup 1)
7212 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7213 (clobber (reg:CC FLAGS_REG))])
7214 (parallel [(set (match_dup 0)
7215 (div:SWI48 (match_dup 2) (match_dup 3)))
7216 (set (match_dup 1)
7217 (mod:SWI48 (match_dup 2) (match_dup 3)))
7218 (use (match_dup 1))
7219 (clobber (reg:CC FLAGS_REG))])]
7220 {
7221 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7222
7223 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7224 operands[4] = operands[2];
7225 else
7226 {
7227 /* Avoid use of cltd in favor of a mov+shift. */
7228 emit_move_insn (operands[1], operands[2]);
7229 operands[4] = operands[1];
7230 }
7231 }
7232 [(set_attr "type" "multi")
7233 (set_attr "mode" "<MODE>")])
7234
7235 (define_insn_and_split "*divmod<mode>4"
7236 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7237 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7238 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7239 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7240 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7241 (clobber (reg:CC FLAGS_REG))]
7242 ""
7243 "#"
7244 "reload_completed"
7245 [(parallel [(set (match_dup 1)
7246 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7247 (clobber (reg:CC FLAGS_REG))])
7248 (parallel [(set (match_dup 0)
7249 (div:SWIM248 (match_dup 2) (match_dup 3)))
7250 (set (match_dup 1)
7251 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7252 (use (match_dup 1))
7253 (clobber (reg:CC FLAGS_REG))])]
7254 {
7255 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7256
7257 if (<MODE>mode != HImode
7258 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7259 operands[4] = operands[2];
7260 else
7261 {
7262 /* Avoid use of cltd in favor of a mov+shift. */
7263 emit_move_insn (operands[1], operands[2]);
7264 operands[4] = operands[1];
7265 }
7266 }
7267 [(set_attr "type" "multi")
7268 (set_attr "mode" "<MODE>")])
7269
7270 (define_insn "*divmod<mode>4_noext"
7271 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7272 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7273 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7274 (set (match_operand:SWIM248 1 "register_operand" "=d")
7275 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7276 (use (match_operand:SWIM248 4 "register_operand" "1"))
7277 (clobber (reg:CC FLAGS_REG))]
7278 ""
7279 "idiv{<imodesuffix>}\t%3"
7280 [(set_attr "type" "idiv")
7281 (set_attr "mode" "<MODE>")])
7282
7283 (define_expand "divmodqi4"
7284 [(parallel [(set (match_operand:QI 0 "register_operand")
7285 (div:QI
7286 (match_operand:QI 1 "register_operand")
7287 (match_operand:QI 2 "nonimmediate_operand")))
7288 (set (match_operand:QI 3 "register_operand")
7289 (mod:QI (match_dup 1) (match_dup 2)))
7290 (clobber (reg:CC FLAGS_REG))])]
7291 "TARGET_QIMODE_MATH"
7292 {
7293 rtx div, mod, insn;
7294 rtx tmp0, tmp1;
7295
7296 tmp0 = gen_reg_rtx (HImode);
7297 tmp1 = gen_reg_rtx (HImode);
7298
7299 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7300 in AX. */
7301 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7302 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7303
7304 /* Extract remainder from AH. */
7305 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7306 insn = emit_move_insn (operands[3], tmp1);
7307
7308 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7309 set_unique_reg_note (insn, REG_EQUAL, mod);
7310
7311 /* Extract quotient from AL. */
7312 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7313
7314 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7315 set_unique_reg_note (insn, REG_EQUAL, div);
7316
7317 DONE;
7318 })
7319
7320 ;; Divide AX by r/m8, with result stored in
7321 ;; AL <- Quotient
7322 ;; AH <- Remainder
7323 ;; Change div/mod to HImode and extend the second argument to HImode
7324 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7325 ;; combine may fail.
7326 (define_insn "divmodhiqi3"
7327 [(set (match_operand:HI 0 "register_operand" "=a")
7328 (ior:HI
7329 (ashift:HI
7330 (zero_extend:HI
7331 (truncate:QI
7332 (mod:HI (match_operand:HI 1 "register_operand" "0")
7333 (sign_extend:HI
7334 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7335 (const_int 8))
7336 (zero_extend:HI
7337 (truncate:QI
7338 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7339 (clobber (reg:CC FLAGS_REG))]
7340 "TARGET_QIMODE_MATH"
7341 "idiv{b}\t%2"
7342 [(set_attr "type" "idiv")
7343 (set_attr "mode" "QI")])
7344
7345 (define_expand "udivmod<mode>4"
7346 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7347 (udiv:SWIM248
7348 (match_operand:SWIM248 1 "register_operand")
7349 (match_operand:SWIM248 2 "nonimmediate_operand")))
7350 (set (match_operand:SWIM248 3 "register_operand")
7351 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7352 (clobber (reg:CC FLAGS_REG))])])
7353
7354 ;; Split with 8bit unsigned divide:
7355 ;; if (dividend an divisor are in [0-255])
7356 ;; use 8bit unsigned integer divide
7357 ;; else
7358 ;; use original integer divide
7359 (define_split
7360 [(set (match_operand:SWI48 0 "register_operand")
7361 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7362 (match_operand:SWI48 3 "nonimmediate_operand")))
7363 (set (match_operand:SWI48 1 "register_operand")
7364 (umod:SWI48 (match_dup 2) (match_dup 3)))
7365 (clobber (reg:CC FLAGS_REG))]
7366 "TARGET_USE_8BIT_IDIV
7367 && TARGET_QIMODE_MATH
7368 && can_create_pseudo_p ()
7369 && !optimize_insn_for_size_p ()"
7370 [(const_int 0)]
7371 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7372
7373 (define_insn_and_split "udivmod<mode>4_1"
7374 [(set (match_operand:SWI48 0 "register_operand" "=a")
7375 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7376 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7377 (set (match_operand:SWI48 1 "register_operand" "=&d")
7378 (umod:SWI48 (match_dup 2) (match_dup 3)))
7379 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7380 (clobber (reg:CC FLAGS_REG))]
7381 ""
7382 "#"
7383 "reload_completed"
7384 [(set (match_dup 1) (const_int 0))
7385 (parallel [(set (match_dup 0)
7386 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7387 (set (match_dup 1)
7388 (umod:SWI48 (match_dup 2) (match_dup 3)))
7389 (use (match_dup 1))
7390 (clobber (reg:CC FLAGS_REG))])]
7391 ""
7392 [(set_attr "type" "multi")
7393 (set_attr "mode" "<MODE>")])
7394
7395 (define_insn_and_split "*udivmod<mode>4"
7396 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7397 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7398 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7399 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7400 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7401 (clobber (reg:CC FLAGS_REG))]
7402 ""
7403 "#"
7404 "reload_completed"
7405 [(set (match_dup 1) (const_int 0))
7406 (parallel [(set (match_dup 0)
7407 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7408 (set (match_dup 1)
7409 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7410 (use (match_dup 1))
7411 (clobber (reg:CC FLAGS_REG))])]
7412 ""
7413 [(set_attr "type" "multi")
7414 (set_attr "mode" "<MODE>")])
7415
7416 (define_insn "*udivmod<mode>4_noext"
7417 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7418 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7419 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7420 (set (match_operand:SWIM248 1 "register_operand" "=d")
7421 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7422 (use (match_operand:SWIM248 4 "register_operand" "1"))
7423 (clobber (reg:CC FLAGS_REG))]
7424 ""
7425 "div{<imodesuffix>}\t%3"
7426 [(set_attr "type" "idiv")
7427 (set_attr "mode" "<MODE>")])
7428
7429 (define_expand "udivmodqi4"
7430 [(parallel [(set (match_operand:QI 0 "register_operand")
7431 (udiv:QI
7432 (match_operand:QI 1 "register_operand")
7433 (match_operand:QI 2 "nonimmediate_operand")))
7434 (set (match_operand:QI 3 "register_operand")
7435 (umod:QI (match_dup 1) (match_dup 2)))
7436 (clobber (reg:CC FLAGS_REG))])]
7437 "TARGET_QIMODE_MATH"
7438 {
7439 rtx div, mod, insn;
7440 rtx tmp0, tmp1;
7441
7442 tmp0 = gen_reg_rtx (HImode);
7443 tmp1 = gen_reg_rtx (HImode);
7444
7445 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7446 in AX. */
7447 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7448 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7449
7450 /* Extract remainder from AH. */
7451 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7452 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7453 insn = emit_move_insn (operands[3], tmp1);
7454
7455 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7456 set_unique_reg_note (insn, REG_EQUAL, mod);
7457
7458 /* Extract quotient from AL. */
7459 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7460
7461 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7462 set_unique_reg_note (insn, REG_EQUAL, div);
7463
7464 DONE;
7465 })
7466
7467 (define_insn "udivmodhiqi3"
7468 [(set (match_operand:HI 0 "register_operand" "=a")
7469 (ior:HI
7470 (ashift:HI
7471 (zero_extend:HI
7472 (truncate:QI
7473 (mod:HI (match_operand:HI 1 "register_operand" "0")
7474 (zero_extend:HI
7475 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7476 (const_int 8))
7477 (zero_extend:HI
7478 (truncate:QI
7479 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7480 (clobber (reg:CC FLAGS_REG))]
7481 "TARGET_QIMODE_MATH"
7482 "div{b}\t%2"
7483 [(set_attr "type" "idiv")
7484 (set_attr "mode" "QI")])
7485
7486 ;; We cannot use div/idiv for double division, because it causes
7487 ;; "division by zero" on the overflow and that's not what we expect
7488 ;; from truncate. Because true (non truncating) double division is
7489 ;; never generated, we can't create this insn anyway.
7490 ;
7491 ;(define_insn ""
7492 ; [(set (match_operand:SI 0 "register_operand" "=a")
7493 ; (truncate:SI
7494 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7495 ; (zero_extend:DI
7496 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7497 ; (set (match_operand:SI 3 "register_operand" "=d")
7498 ; (truncate:SI
7499 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7500 ; (clobber (reg:CC FLAGS_REG))]
7501 ; ""
7502 ; "div{l}\t{%2, %0|%0, %2}"
7503 ; [(set_attr "type" "idiv")])
7504 \f
7505 ;;- Logical AND instructions
7506
7507 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7508 ;; Note that this excludes ah.
7509
7510 (define_expand "testsi_ccno_1"
7511 [(set (reg:CCNO FLAGS_REG)
7512 (compare:CCNO
7513 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7514 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7515 (const_int 0)))])
7516
7517 (define_expand "testqi_ccz_1"
7518 [(set (reg:CCZ FLAGS_REG)
7519 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7520 (match_operand:QI 1 "nonmemory_operand"))
7521 (const_int 0)))])
7522
7523 (define_expand "testdi_ccno_1"
7524 [(set (reg:CCNO FLAGS_REG)
7525 (compare:CCNO
7526 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7527 (match_operand:DI 1 "x86_64_szext_general_operand"))
7528 (const_int 0)))]
7529 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7530
7531 (define_insn "*testdi_1"
7532 [(set (reg FLAGS_REG)
7533 (compare
7534 (and:DI
7535 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7536 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7537 (const_int 0)))]
7538 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7539 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7540 "@
7541 test{l}\t{%k1, %k0|%k0, %k1}
7542 test{l}\t{%k1, %k0|%k0, %k1}
7543 test{q}\t{%1, %0|%0, %1}
7544 test{q}\t{%1, %0|%0, %1}
7545 test{q}\t{%1, %0|%0, %1}"
7546 [(set_attr "type" "test")
7547 (set_attr "modrm" "0,1,0,1,1")
7548 (set_attr "mode" "SI,SI,DI,DI,DI")])
7549
7550 (define_insn "*testqi_1_maybe_si"
7551 [(set (reg FLAGS_REG)
7552 (compare
7553 (and:QI
7554 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7555 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7556 (const_int 0)))]
7557 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7558 && ix86_match_ccmode (insn,
7559 CONST_INT_P (operands[1])
7560 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7561 {
7562 if (which_alternative == 3)
7563 {
7564 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7565 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7566 return "test{l}\t{%1, %k0|%k0, %1}";
7567 }
7568 return "test{b}\t{%1, %0|%0, %1}";
7569 }
7570 [(set_attr "type" "test")
7571 (set_attr "modrm" "0,1,1,1")
7572 (set_attr "mode" "QI,QI,QI,SI")
7573 (set_attr "pent_pair" "uv,np,uv,np")])
7574
7575 (define_insn "*test<mode>_1"
7576 [(set (reg FLAGS_REG)
7577 (compare
7578 (and:SWI124
7579 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7580 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7581 (const_int 0)))]
7582 "ix86_match_ccmode (insn, CCNOmode)
7583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7584 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7585 [(set_attr "type" "test")
7586 (set_attr "modrm" "0,1,1")
7587 (set_attr "mode" "<MODE>")
7588 (set_attr "pent_pair" "uv,np,uv")])
7589
7590 (define_expand "testqi_ext_ccno_0"
7591 [(set (reg:CCNO FLAGS_REG)
7592 (compare:CCNO
7593 (and:SI
7594 (zero_extract:SI
7595 (match_operand 0 "ext_register_operand")
7596 (const_int 8)
7597 (const_int 8))
7598 (match_operand 1 "const_int_operand"))
7599 (const_int 0)))])
7600
7601 (define_insn "*testqi_ext_0"
7602 [(set (reg FLAGS_REG)
7603 (compare
7604 (and:SI
7605 (zero_extract:SI
7606 (match_operand 0 "ext_register_operand" "Q")
7607 (const_int 8)
7608 (const_int 8))
7609 (match_operand 1 "const_int_operand" "n"))
7610 (const_int 0)))]
7611 "ix86_match_ccmode (insn, CCNOmode)"
7612 "test{b}\t{%1, %h0|%h0, %1}"
7613 [(set_attr "type" "test")
7614 (set_attr "mode" "QI")
7615 (set_attr "length_immediate" "1")
7616 (set_attr "modrm" "1")
7617 (set_attr "pent_pair" "np")])
7618
7619 (define_insn "*testqi_ext_1_rex64"
7620 [(set (reg FLAGS_REG)
7621 (compare
7622 (and:SI
7623 (zero_extract:SI
7624 (match_operand 0 "ext_register_operand" "Q")
7625 (const_int 8)
7626 (const_int 8))
7627 (zero_extend:SI
7628 (match_operand:QI 1 "register_operand" "Q")))
7629 (const_int 0)))]
7630 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7631 "test{b}\t{%1, %h0|%h0, %1}"
7632 [(set_attr "type" "test")
7633 (set_attr "mode" "QI")])
7634
7635 (define_insn "*testqi_ext_1"
7636 [(set (reg FLAGS_REG)
7637 (compare
7638 (and:SI
7639 (zero_extract:SI
7640 (match_operand 0 "ext_register_operand" "Q")
7641 (const_int 8)
7642 (const_int 8))
7643 (zero_extend:SI
7644 (match_operand:QI 1 "general_operand" "Qm")))
7645 (const_int 0)))]
7646 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7647 "test{b}\t{%1, %h0|%h0, %1}"
7648 [(set_attr "type" "test")
7649 (set_attr "mode" "QI")])
7650
7651 (define_insn "*testqi_ext_2"
7652 [(set (reg FLAGS_REG)
7653 (compare
7654 (and:SI
7655 (zero_extract:SI
7656 (match_operand 0 "ext_register_operand" "Q")
7657 (const_int 8)
7658 (const_int 8))
7659 (zero_extract:SI
7660 (match_operand 1 "ext_register_operand" "Q")
7661 (const_int 8)
7662 (const_int 8)))
7663 (const_int 0)))]
7664 "ix86_match_ccmode (insn, CCNOmode)"
7665 "test{b}\t{%h1, %h0|%h0, %h1}"
7666 [(set_attr "type" "test")
7667 (set_attr "mode" "QI")])
7668
7669 (define_insn "*testqi_ext_3_rex64"
7670 [(set (reg FLAGS_REG)
7671 (compare (zero_extract:DI
7672 (match_operand 0 "nonimmediate_operand" "rm")
7673 (match_operand:DI 1 "const_int_operand")
7674 (match_operand:DI 2 "const_int_operand"))
7675 (const_int 0)))]
7676 "TARGET_64BIT
7677 && ix86_match_ccmode (insn, CCNOmode)
7678 && INTVAL (operands[1]) > 0
7679 && INTVAL (operands[2]) >= 0
7680 /* Ensure that resulting mask is zero or sign extended operand. */
7681 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7682 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7683 && INTVAL (operands[1]) > 32))
7684 && (GET_MODE (operands[0]) == SImode
7685 || GET_MODE (operands[0]) == DImode
7686 || GET_MODE (operands[0]) == HImode
7687 || GET_MODE (operands[0]) == QImode)"
7688 "#")
7689
7690 ;; Combine likes to form bit extractions for some tests. Humor it.
7691 (define_insn "*testqi_ext_3"
7692 [(set (reg FLAGS_REG)
7693 (compare (zero_extract:SI
7694 (match_operand 0 "nonimmediate_operand" "rm")
7695 (match_operand:SI 1 "const_int_operand")
7696 (match_operand:SI 2 "const_int_operand"))
7697 (const_int 0)))]
7698 "ix86_match_ccmode (insn, CCNOmode)
7699 && INTVAL (operands[1]) > 0
7700 && INTVAL (operands[2]) >= 0
7701 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7702 && (GET_MODE (operands[0]) == SImode
7703 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7704 || GET_MODE (operands[0]) == HImode
7705 || GET_MODE (operands[0]) == QImode)"
7706 "#")
7707
7708 (define_split
7709 [(set (match_operand 0 "flags_reg_operand")
7710 (match_operator 1 "compare_operator"
7711 [(zero_extract
7712 (match_operand 2 "nonimmediate_operand")
7713 (match_operand 3 "const_int_operand")
7714 (match_operand 4 "const_int_operand"))
7715 (const_int 0)]))]
7716 "ix86_match_ccmode (insn, CCNOmode)"
7717 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7718 {
7719 rtx val = operands[2];
7720 HOST_WIDE_INT len = INTVAL (operands[3]);
7721 HOST_WIDE_INT pos = INTVAL (operands[4]);
7722 HOST_WIDE_INT mask;
7723 enum machine_mode mode, submode;
7724
7725 mode = GET_MODE (val);
7726 if (MEM_P (val))
7727 {
7728 /* ??? Combine likes to put non-volatile mem extractions in QImode
7729 no matter the size of the test. So find a mode that works. */
7730 if (! MEM_VOLATILE_P (val))
7731 {
7732 mode = smallest_mode_for_size (pos + len, MODE_INT);
7733 val = adjust_address (val, mode, 0);
7734 }
7735 }
7736 else if (GET_CODE (val) == SUBREG
7737 && (submode = GET_MODE (SUBREG_REG (val)),
7738 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7739 && pos + len <= GET_MODE_BITSIZE (submode)
7740 && GET_MODE_CLASS (submode) == MODE_INT)
7741 {
7742 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7743 mode = submode;
7744 val = SUBREG_REG (val);
7745 }
7746 else if (mode == HImode && pos + len <= 8)
7747 {
7748 /* Small HImode tests can be converted to QImode. */
7749 mode = QImode;
7750 val = gen_lowpart (QImode, val);
7751 }
7752
7753 if (len == HOST_BITS_PER_WIDE_INT)
7754 mask = -1;
7755 else
7756 mask = ((HOST_WIDE_INT)1 << len) - 1;
7757 mask <<= pos;
7758
7759 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7760 })
7761
7762 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7763 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7764 ;; this is relatively important trick.
7765 ;; Do the conversion only post-reload to avoid limiting of the register class
7766 ;; to QI regs.
7767 (define_split
7768 [(set (match_operand 0 "flags_reg_operand")
7769 (match_operator 1 "compare_operator"
7770 [(and (match_operand 2 "register_operand")
7771 (match_operand 3 "const_int_operand"))
7772 (const_int 0)]))]
7773 "reload_completed
7774 && QI_REG_P (operands[2])
7775 && GET_MODE (operands[2]) != QImode
7776 && ((ix86_match_ccmode (insn, CCZmode)
7777 && !(INTVAL (operands[3]) & ~(255 << 8)))
7778 || (ix86_match_ccmode (insn, CCNOmode)
7779 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7780 [(set (match_dup 0)
7781 (match_op_dup 1
7782 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7783 (match_dup 3))
7784 (const_int 0)]))]
7785 {
7786 operands[2] = gen_lowpart (SImode, operands[2]);
7787 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7788 })
7789
7790 (define_split
7791 [(set (match_operand 0 "flags_reg_operand")
7792 (match_operator 1 "compare_operator"
7793 [(and (match_operand 2 "nonimmediate_operand")
7794 (match_operand 3 "const_int_operand"))
7795 (const_int 0)]))]
7796 "reload_completed
7797 && GET_MODE (operands[2]) != QImode
7798 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7799 && ((ix86_match_ccmode (insn, CCZmode)
7800 && !(INTVAL (operands[3]) & ~255))
7801 || (ix86_match_ccmode (insn, CCNOmode)
7802 && !(INTVAL (operands[3]) & ~127)))"
7803 [(set (match_dup 0)
7804 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7805 (const_int 0)]))]
7806 {
7807 operands[2] = gen_lowpart (QImode, operands[2]);
7808 operands[3] = gen_lowpart (QImode, operands[3]);
7809 })
7810
7811 ;; %%% This used to optimize known byte-wide and operations to memory,
7812 ;; and sometimes to QImode registers. If this is considered useful,
7813 ;; it should be done with splitters.
7814
7815 (define_expand "and<mode>3"
7816 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7817 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7818 (match_operand:SWIM 2 "<general_szext_operand>")))]
7819 ""
7820 {
7821 enum machine_mode mode = <MODE>mode;
7822 rtx (*insn) (rtx, rtx);
7823
7824 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7825 {
7826 HOST_WIDE_INT ival = INTVAL (operands[2]);
7827
7828 if (ival == (HOST_WIDE_INT) 0xffffffff)
7829 mode = SImode;
7830 else if (ival == 0xffff)
7831 mode = HImode;
7832 else if (ival == 0xff)
7833 mode = QImode;
7834 }
7835
7836 if (mode == <MODE>mode)
7837 {
7838 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7839 DONE;
7840 }
7841
7842 if (<MODE>mode == DImode)
7843 insn = (mode == SImode)
7844 ? gen_zero_extendsidi2
7845 : (mode == HImode)
7846 ? gen_zero_extendhidi2
7847 : gen_zero_extendqidi2;
7848 else if (<MODE>mode == SImode)
7849 insn = (mode == HImode)
7850 ? gen_zero_extendhisi2
7851 : gen_zero_extendqisi2;
7852 else if (<MODE>mode == HImode)
7853 insn = gen_zero_extendqihi2;
7854 else
7855 gcc_unreachable ();
7856
7857 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7858 DONE;
7859 })
7860
7861 (define_insn "*anddi_1"
7862 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7863 (and:DI
7864 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7865 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7868 {
7869 switch (get_attr_type (insn))
7870 {
7871 case TYPE_IMOVX:
7872 return "#";
7873
7874 default:
7875 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7876 if (get_attr_mode (insn) == MODE_SI)
7877 return "and{l}\t{%k2, %k0|%k0, %k2}";
7878 else
7879 return "and{q}\t{%2, %0|%0, %2}";
7880 }
7881 }
7882 [(set_attr "type" "alu,alu,alu,imovx")
7883 (set_attr "length_immediate" "*,*,*,0")
7884 (set (attr "prefix_rex")
7885 (if_then_else
7886 (and (eq_attr "type" "imovx")
7887 (and (match_test "INTVAL (operands[2]) == 0xff")
7888 (match_operand 1 "ext_QIreg_operand")))
7889 (const_string "1")
7890 (const_string "*")))
7891 (set_attr "mode" "SI,DI,DI,SI")])
7892
7893 (define_insn "*andsi_1"
7894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7895 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7896 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7897 (clobber (reg:CC FLAGS_REG))]
7898 "ix86_binary_operator_ok (AND, SImode, operands)"
7899 {
7900 switch (get_attr_type (insn))
7901 {
7902 case TYPE_IMOVX:
7903 return "#";
7904
7905 default:
7906 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7907 return "and{l}\t{%2, %0|%0, %2}";
7908 }
7909 }
7910 [(set_attr "type" "alu,alu,imovx")
7911 (set (attr "prefix_rex")
7912 (if_then_else
7913 (and (eq_attr "type" "imovx")
7914 (and (match_test "INTVAL (operands[2]) == 0xff")
7915 (match_operand 1 "ext_QIreg_operand")))
7916 (const_string "1")
7917 (const_string "*")))
7918 (set_attr "length_immediate" "*,*,0")
7919 (set_attr "mode" "SI")])
7920
7921 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7922 (define_insn "*andsi_1_zext"
7923 [(set (match_operand:DI 0 "register_operand" "=r")
7924 (zero_extend:DI
7925 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7926 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7927 (clobber (reg:CC FLAGS_REG))]
7928 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7929 "and{l}\t{%2, %k0|%k0, %2}"
7930 [(set_attr "type" "alu")
7931 (set_attr "mode" "SI")])
7932
7933 (define_insn "*andhi_1"
7934 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7935 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7936 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7937 (clobber (reg:CC FLAGS_REG))]
7938 "ix86_binary_operator_ok (AND, HImode, operands)"
7939 {
7940 switch (get_attr_type (insn))
7941 {
7942 case TYPE_IMOVX:
7943 return "#";
7944
7945 default:
7946 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7947 return "and{w}\t{%2, %0|%0, %2}";
7948 }
7949 }
7950 [(set_attr "type" "alu,alu,imovx")
7951 (set_attr "length_immediate" "*,*,0")
7952 (set (attr "prefix_rex")
7953 (if_then_else
7954 (and (eq_attr "type" "imovx")
7955 (match_operand 1 "ext_QIreg_operand"))
7956 (const_string "1")
7957 (const_string "*")))
7958 (set_attr "mode" "HI,HI,SI")])
7959
7960 ;; %%% Potential partial reg stall on alternative 2. What to do?
7961 (define_insn "*andqi_1"
7962 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7963 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7964 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7965 (clobber (reg:CC FLAGS_REG))]
7966 "ix86_binary_operator_ok (AND, QImode, operands)"
7967 "@
7968 and{b}\t{%2, %0|%0, %2}
7969 and{b}\t{%2, %0|%0, %2}
7970 and{l}\t{%k2, %k0|%k0, %k2}"
7971 [(set_attr "type" "alu")
7972 (set_attr "mode" "QI,QI,SI")])
7973
7974 (define_insn "*andqi_1_slp"
7975 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7976 (and:QI (match_dup 0)
7977 (match_operand:QI 1 "general_operand" "qn,qmn")))
7978 (clobber (reg:CC FLAGS_REG))]
7979 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7980 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7981 "and{b}\t{%1, %0|%0, %1}"
7982 [(set_attr "type" "alu1")
7983 (set_attr "mode" "QI")])
7984
7985 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7986 (define_split
7987 [(set (match_operand:DI 0 "register_operand")
7988 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7989 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "TARGET_64BIT"
7992 [(parallel [(set (match_dup 0)
7993 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7994 (clobber (reg:CC FLAGS_REG))])]
7995 "operands[2] = gen_lowpart (SImode, operands[2]);")
7996
7997 (define_split
7998 [(set (match_operand:SWI248 0 "register_operand")
7999 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8000 (match_operand:SWI248 2 "const_int_operand")))
8001 (clobber (reg:CC FLAGS_REG))]
8002 "reload_completed
8003 && true_regnum (operands[0]) != true_regnum (operands[1])"
8004 [(const_int 0)]
8005 {
8006 HOST_WIDE_INT ival = INTVAL (operands[2]);
8007 enum machine_mode mode;
8008 rtx (*insn) (rtx, rtx);
8009
8010 if (ival == (HOST_WIDE_INT) 0xffffffff)
8011 mode = SImode;
8012 else if (ival == 0xffff)
8013 mode = HImode;
8014 else
8015 {
8016 gcc_assert (ival == 0xff);
8017 mode = QImode;
8018 }
8019
8020 if (<MODE>mode == DImode)
8021 insn = (mode == SImode)
8022 ? gen_zero_extendsidi2
8023 : (mode == HImode)
8024 ? gen_zero_extendhidi2
8025 : gen_zero_extendqidi2;
8026 else
8027 {
8028 if (<MODE>mode != SImode)
8029 /* Zero extend to SImode to avoid partial register stalls. */
8030 operands[0] = gen_lowpart (SImode, operands[0]);
8031
8032 insn = (mode == HImode)
8033 ? gen_zero_extendhisi2
8034 : gen_zero_extendqisi2;
8035 }
8036 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8037 DONE;
8038 })
8039
8040 (define_split
8041 [(set (match_operand 0 "register_operand")
8042 (and (match_dup 0)
8043 (const_int -65536)))
8044 (clobber (reg:CC FLAGS_REG))]
8045 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8046 || optimize_function_for_size_p (cfun)"
8047 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8048 "operands[1] = gen_lowpart (HImode, operands[0]);")
8049
8050 (define_split
8051 [(set (match_operand 0 "ext_register_operand")
8052 (and (match_dup 0)
8053 (const_int -256)))
8054 (clobber (reg:CC FLAGS_REG))]
8055 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8056 && reload_completed"
8057 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8058 "operands[1] = gen_lowpart (QImode, operands[0]);")
8059
8060 (define_split
8061 [(set (match_operand 0 "ext_register_operand")
8062 (and (match_dup 0)
8063 (const_int -65281)))
8064 (clobber (reg:CC FLAGS_REG))]
8065 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8066 && reload_completed"
8067 [(parallel [(set (zero_extract:SI (match_dup 0)
8068 (const_int 8)
8069 (const_int 8))
8070 (xor:SI
8071 (zero_extract:SI (match_dup 0)
8072 (const_int 8)
8073 (const_int 8))
8074 (zero_extract:SI (match_dup 0)
8075 (const_int 8)
8076 (const_int 8))))
8077 (clobber (reg:CC FLAGS_REG))])]
8078 "operands[0] = gen_lowpart (SImode, operands[0]);")
8079
8080 (define_insn "*anddi_2"
8081 [(set (reg FLAGS_REG)
8082 (compare
8083 (and:DI
8084 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8085 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8086 (const_int 0)))
8087 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8088 (and:DI (match_dup 1) (match_dup 2)))]
8089 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8090 && ix86_binary_operator_ok (AND, DImode, operands)"
8091 "@
8092 and{l}\t{%k2, %k0|%k0, %k2}
8093 and{q}\t{%2, %0|%0, %2}
8094 and{q}\t{%2, %0|%0, %2}"
8095 [(set_attr "type" "alu")
8096 (set_attr "mode" "SI,DI,DI")])
8097
8098 (define_insn "*andqi_2_maybe_si"
8099 [(set (reg FLAGS_REG)
8100 (compare (and:QI
8101 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8102 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8103 (const_int 0)))
8104 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8105 (and:QI (match_dup 1) (match_dup 2)))]
8106 "ix86_binary_operator_ok (AND, QImode, operands)
8107 && ix86_match_ccmode (insn,
8108 CONST_INT_P (operands[2])
8109 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8110 {
8111 if (which_alternative == 2)
8112 {
8113 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8114 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8115 return "and{l}\t{%2, %k0|%k0, %2}";
8116 }
8117 return "and{b}\t{%2, %0|%0, %2}";
8118 }
8119 [(set_attr "type" "alu")
8120 (set_attr "mode" "QI,QI,SI")])
8121
8122 (define_insn "*and<mode>_2"
8123 [(set (reg FLAGS_REG)
8124 (compare (and:SWI124
8125 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8126 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8127 (const_int 0)))
8128 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8129 (and:SWI124 (match_dup 1) (match_dup 2)))]
8130 "ix86_match_ccmode (insn, CCNOmode)
8131 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8132 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "mode" "<MODE>")])
8135
8136 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8137 (define_insn "*andsi_2_zext"
8138 [(set (reg FLAGS_REG)
8139 (compare (and:SI
8140 (match_operand:SI 1 "nonimmediate_operand" "%0")
8141 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8142 (const_int 0)))
8143 (set (match_operand:DI 0 "register_operand" "=r")
8144 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8145 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8146 && ix86_binary_operator_ok (AND, SImode, operands)"
8147 "and{l}\t{%2, %k0|%k0, %2}"
8148 [(set_attr "type" "alu")
8149 (set_attr "mode" "SI")])
8150
8151 (define_insn "*andqi_2_slp"
8152 [(set (reg FLAGS_REG)
8153 (compare (and:QI
8154 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8155 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8156 (const_int 0)))
8157 (set (strict_low_part (match_dup 0))
8158 (and:QI (match_dup 0) (match_dup 1)))]
8159 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8160 && ix86_match_ccmode (insn, CCNOmode)
8161 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8162 "and{b}\t{%1, %0|%0, %1}"
8163 [(set_attr "type" "alu1")
8164 (set_attr "mode" "QI")])
8165
8166 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8167 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8168 ;; for a QImode operand, which of course failed.
8169 (define_insn "andqi_ext_0"
8170 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8171 (const_int 8)
8172 (const_int 8))
8173 (and:SI
8174 (zero_extract:SI
8175 (match_operand 1 "ext_register_operand" "0")
8176 (const_int 8)
8177 (const_int 8))
8178 (match_operand 2 "const_int_operand" "n")))
8179 (clobber (reg:CC FLAGS_REG))]
8180 ""
8181 "and{b}\t{%2, %h0|%h0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "length_immediate" "1")
8184 (set_attr "modrm" "1")
8185 (set_attr "mode" "QI")])
8186
8187 ;; Generated by peephole translating test to and. This shows up
8188 ;; often in fp comparisons.
8189 (define_insn "*andqi_ext_0_cc"
8190 [(set (reg FLAGS_REG)
8191 (compare
8192 (and:SI
8193 (zero_extract:SI
8194 (match_operand 1 "ext_register_operand" "0")
8195 (const_int 8)
8196 (const_int 8))
8197 (match_operand 2 "const_int_operand" "n"))
8198 (const_int 0)))
8199 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8200 (const_int 8)
8201 (const_int 8))
8202 (and:SI
8203 (zero_extract:SI
8204 (match_dup 1)
8205 (const_int 8)
8206 (const_int 8))
8207 (match_dup 2)))]
8208 "ix86_match_ccmode (insn, CCNOmode)"
8209 "and{b}\t{%2, %h0|%h0, %2}"
8210 [(set_attr "type" "alu")
8211 (set_attr "length_immediate" "1")
8212 (set_attr "modrm" "1")
8213 (set_attr "mode" "QI")])
8214
8215 (define_insn "*andqi_ext_1_rex64"
8216 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8217 (const_int 8)
8218 (const_int 8))
8219 (and:SI
8220 (zero_extract:SI
8221 (match_operand 1 "ext_register_operand" "0")
8222 (const_int 8)
8223 (const_int 8))
8224 (zero_extend:SI
8225 (match_operand 2 "ext_register_operand" "Q"))))
8226 (clobber (reg:CC FLAGS_REG))]
8227 "TARGET_64BIT"
8228 "and{b}\t{%2, %h0|%h0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "length_immediate" "0")
8231 (set_attr "mode" "QI")])
8232
8233 (define_insn "*andqi_ext_1"
8234 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8235 (const_int 8)
8236 (const_int 8))
8237 (and:SI
8238 (zero_extract:SI
8239 (match_operand 1 "ext_register_operand" "0")
8240 (const_int 8)
8241 (const_int 8))
8242 (zero_extend:SI
8243 (match_operand:QI 2 "general_operand" "Qm"))))
8244 (clobber (reg:CC FLAGS_REG))]
8245 "!TARGET_64BIT"
8246 "and{b}\t{%2, %h0|%h0, %2}"
8247 [(set_attr "type" "alu")
8248 (set_attr "length_immediate" "0")
8249 (set_attr "mode" "QI")])
8250
8251 (define_insn "*andqi_ext_2"
8252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253 (const_int 8)
8254 (const_int 8))
8255 (and:SI
8256 (zero_extract:SI
8257 (match_operand 1 "ext_register_operand" "%0")
8258 (const_int 8)
8259 (const_int 8))
8260 (zero_extract:SI
8261 (match_operand 2 "ext_register_operand" "Q")
8262 (const_int 8)
8263 (const_int 8))))
8264 (clobber (reg:CC FLAGS_REG))]
8265 ""
8266 "and{b}\t{%h2, %h0|%h0, %h2}"
8267 [(set_attr "type" "alu")
8268 (set_attr "length_immediate" "0")
8269 (set_attr "mode" "QI")])
8270
8271 ;; Convert wide AND instructions with immediate operand to shorter QImode
8272 ;; equivalents when possible.
8273 ;; Don't do the splitting with memory operands, since it introduces risk
8274 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8275 ;; for size, but that can (should?) be handled by generic code instead.
8276 (define_split
8277 [(set (match_operand 0 "register_operand")
8278 (and (match_operand 1 "register_operand")
8279 (match_operand 2 "const_int_operand")))
8280 (clobber (reg:CC FLAGS_REG))]
8281 "reload_completed
8282 && QI_REG_P (operands[0])
8283 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8284 && !(~INTVAL (operands[2]) & ~(255 << 8))
8285 && GET_MODE (operands[0]) != QImode"
8286 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8287 (and:SI (zero_extract:SI (match_dup 1)
8288 (const_int 8) (const_int 8))
8289 (match_dup 2)))
8290 (clobber (reg:CC FLAGS_REG))])]
8291 {
8292 operands[0] = gen_lowpart (SImode, operands[0]);
8293 operands[1] = gen_lowpart (SImode, operands[1]);
8294 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8295 })
8296
8297 ;; Since AND can be encoded with sign extended immediate, this is only
8298 ;; profitable when 7th bit is not set.
8299 (define_split
8300 [(set (match_operand 0 "register_operand")
8301 (and (match_operand 1 "general_operand")
8302 (match_operand 2 "const_int_operand")))
8303 (clobber (reg:CC FLAGS_REG))]
8304 "reload_completed
8305 && ANY_QI_REG_P (operands[0])
8306 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8307 && !(~INTVAL (operands[2]) & ~255)
8308 && !(INTVAL (operands[2]) & 128)
8309 && GET_MODE (operands[0]) != QImode"
8310 [(parallel [(set (strict_low_part (match_dup 0))
8311 (and:QI (match_dup 1)
8312 (match_dup 2)))
8313 (clobber (reg:CC FLAGS_REG))])]
8314 {
8315 operands[0] = gen_lowpart (QImode, operands[0]);
8316 operands[1] = gen_lowpart (QImode, operands[1]);
8317 operands[2] = gen_lowpart (QImode, operands[2]);
8318 })
8319 \f
8320 ;; Logical inclusive and exclusive OR instructions
8321
8322 ;; %%% This used to optimize known byte-wide and operations to memory.
8323 ;; If this is considered useful, it should be done with splitters.
8324
8325 (define_expand "<code><mode>3"
8326 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8327 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8328 (match_operand:SWIM 2 "<general_operand>")))]
8329 ""
8330 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8331
8332 (define_insn "*<code><mode>_1"
8333 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8334 (any_or:SWI248
8335 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8336 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8339 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "mode" "<MODE>")])
8342
8343 ;; %%% Potential partial reg stall on alternative 2. What to do?
8344 (define_insn "*<code>qi_1"
8345 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8346 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8347 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8348 (clobber (reg:CC FLAGS_REG))]
8349 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8350 "@
8351 <logic>{b}\t{%2, %0|%0, %2}
8352 <logic>{b}\t{%2, %0|%0, %2}
8353 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8354 [(set_attr "type" "alu")
8355 (set_attr "mode" "QI,QI,SI")])
8356
8357 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8358 (define_insn "*<code>si_1_zext"
8359 [(set (match_operand:DI 0 "register_operand" "=r")
8360 (zero_extend:DI
8361 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8362 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8363 (clobber (reg:CC FLAGS_REG))]
8364 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8365 "<logic>{l}\t{%2, %k0|%k0, %2}"
8366 [(set_attr "type" "alu")
8367 (set_attr "mode" "SI")])
8368
8369 (define_insn "*<code>si_1_zext_imm"
8370 [(set (match_operand:DI 0 "register_operand" "=r")
8371 (any_or:DI
8372 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8373 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8374 (clobber (reg:CC FLAGS_REG))]
8375 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8376 "<logic>{l}\t{%2, %k0|%k0, %2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "SI")])
8379
8380 (define_insn "*<code>qi_1_slp"
8381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8382 (any_or:QI (match_dup 0)
8383 (match_operand:QI 1 "general_operand" "qmn,qn")))
8384 (clobber (reg:CC FLAGS_REG))]
8385 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8386 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8387 "<logic>{b}\t{%1, %0|%0, %1}"
8388 [(set_attr "type" "alu1")
8389 (set_attr "mode" "QI")])
8390
8391 (define_insn "*<code><mode>_2"
8392 [(set (reg FLAGS_REG)
8393 (compare (any_or:SWI
8394 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8395 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8396 (const_int 0)))
8397 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8398 (any_or:SWI (match_dup 1) (match_dup 2)))]
8399 "ix86_match_ccmode (insn, CCNOmode)
8400 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8401 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "mode" "<MODE>")])
8404
8405 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8406 ;; ??? Special case for immediate operand is missing - it is tricky.
8407 (define_insn "*<code>si_2_zext"
8408 [(set (reg FLAGS_REG)
8409 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8410 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8411 (const_int 0)))
8412 (set (match_operand:DI 0 "register_operand" "=r")
8413 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8414 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8415 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8416 "<logic>{l}\t{%2, %k0|%k0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "mode" "SI")])
8419
8420 (define_insn "*<code>si_2_zext_imm"
8421 [(set (reg FLAGS_REG)
8422 (compare (any_or:SI
8423 (match_operand:SI 1 "nonimmediate_operand" "%0")
8424 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8425 (const_int 0)))
8426 (set (match_operand:DI 0 "register_operand" "=r")
8427 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8428 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8429 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8430 "<logic>{l}\t{%2, %k0|%k0, %2}"
8431 [(set_attr "type" "alu")
8432 (set_attr "mode" "SI")])
8433
8434 (define_insn "*<code>qi_2_slp"
8435 [(set (reg FLAGS_REG)
8436 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8437 (match_operand:QI 1 "general_operand" "qmn,qn"))
8438 (const_int 0)))
8439 (set (strict_low_part (match_dup 0))
8440 (any_or:QI (match_dup 0) (match_dup 1)))]
8441 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8442 && ix86_match_ccmode (insn, CCNOmode)
8443 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8444 "<logic>{b}\t{%1, %0|%0, %1}"
8445 [(set_attr "type" "alu1")
8446 (set_attr "mode" "QI")])
8447
8448 (define_insn "*<code><mode>_3"
8449 [(set (reg FLAGS_REG)
8450 (compare (any_or:SWI
8451 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8452 (match_operand:SWI 2 "<general_operand>" "<g>"))
8453 (const_int 0)))
8454 (clobber (match_scratch:SWI 0 "=<r>"))]
8455 "ix86_match_ccmode (insn, CCNOmode)
8456 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8457 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8458 [(set_attr "type" "alu")
8459 (set_attr "mode" "<MODE>")])
8460
8461 (define_insn "*<code>qi_ext_0"
8462 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8463 (const_int 8)
8464 (const_int 8))
8465 (any_or:SI
8466 (zero_extract:SI
8467 (match_operand 1 "ext_register_operand" "0")
8468 (const_int 8)
8469 (const_int 8))
8470 (match_operand 2 "const_int_operand" "n")))
8471 (clobber (reg:CC FLAGS_REG))]
8472 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8473 "<logic>{b}\t{%2, %h0|%h0, %2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "length_immediate" "1")
8476 (set_attr "modrm" "1")
8477 (set_attr "mode" "QI")])
8478
8479 (define_insn "*<code>qi_ext_1_rex64"
8480 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8481 (const_int 8)
8482 (const_int 8))
8483 (any_or:SI
8484 (zero_extract:SI
8485 (match_operand 1 "ext_register_operand" "0")
8486 (const_int 8)
8487 (const_int 8))
8488 (zero_extend:SI
8489 (match_operand 2 "ext_register_operand" "Q"))))
8490 (clobber (reg:CC FLAGS_REG))]
8491 "TARGET_64BIT
8492 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8493 "<logic>{b}\t{%2, %h0|%h0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "length_immediate" "0")
8496 (set_attr "mode" "QI")])
8497
8498 (define_insn "*<code>qi_ext_1"
8499 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8500 (const_int 8)
8501 (const_int 8))
8502 (any_or:SI
8503 (zero_extract:SI
8504 (match_operand 1 "ext_register_operand" "0")
8505 (const_int 8)
8506 (const_int 8))
8507 (zero_extend:SI
8508 (match_operand:QI 2 "general_operand" "Qm"))))
8509 (clobber (reg:CC FLAGS_REG))]
8510 "!TARGET_64BIT
8511 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8512 "<logic>{b}\t{%2, %h0|%h0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "length_immediate" "0")
8515 (set_attr "mode" "QI")])
8516
8517 (define_insn "*<code>qi_ext_2"
8518 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8519 (const_int 8)
8520 (const_int 8))
8521 (any_or:SI
8522 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8523 (const_int 8)
8524 (const_int 8))
8525 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8526 (const_int 8)
8527 (const_int 8))))
8528 (clobber (reg:CC FLAGS_REG))]
8529 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8530 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8531 [(set_attr "type" "alu")
8532 (set_attr "length_immediate" "0")
8533 (set_attr "mode" "QI")])
8534
8535 (define_split
8536 [(set (match_operand 0 "register_operand")
8537 (any_or (match_operand 1 "register_operand")
8538 (match_operand 2 "const_int_operand")))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "reload_completed
8541 && QI_REG_P (operands[0])
8542 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8543 && !(INTVAL (operands[2]) & ~(255 << 8))
8544 && GET_MODE (operands[0]) != QImode"
8545 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8546 (any_or:SI (zero_extract:SI (match_dup 1)
8547 (const_int 8) (const_int 8))
8548 (match_dup 2)))
8549 (clobber (reg:CC FLAGS_REG))])]
8550 {
8551 operands[0] = gen_lowpart (SImode, operands[0]);
8552 operands[1] = gen_lowpart (SImode, operands[1]);
8553 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8554 })
8555
8556 ;; Since OR can be encoded with sign extended immediate, this is only
8557 ;; profitable when 7th bit is set.
8558 (define_split
8559 [(set (match_operand 0 "register_operand")
8560 (any_or (match_operand 1 "general_operand")
8561 (match_operand 2 "const_int_operand")))
8562 (clobber (reg:CC FLAGS_REG))]
8563 "reload_completed
8564 && ANY_QI_REG_P (operands[0])
8565 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8566 && !(INTVAL (operands[2]) & ~255)
8567 && (INTVAL (operands[2]) & 128)
8568 && GET_MODE (operands[0]) != QImode"
8569 [(parallel [(set (strict_low_part (match_dup 0))
8570 (any_or:QI (match_dup 1)
8571 (match_dup 2)))
8572 (clobber (reg:CC FLAGS_REG))])]
8573 {
8574 operands[0] = gen_lowpart (QImode, operands[0]);
8575 operands[1] = gen_lowpart (QImode, operands[1]);
8576 operands[2] = gen_lowpart (QImode, operands[2]);
8577 })
8578
8579 (define_expand "xorqi_cc_ext_1"
8580 [(parallel [
8581 (set (reg:CCNO FLAGS_REG)
8582 (compare:CCNO
8583 (xor:SI
8584 (zero_extract:SI
8585 (match_operand 1 "ext_register_operand")
8586 (const_int 8)
8587 (const_int 8))
8588 (match_operand:QI 2 "general_operand"))
8589 (const_int 0)))
8590 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8591 (const_int 8)
8592 (const_int 8))
8593 (xor:SI
8594 (zero_extract:SI
8595 (match_dup 1)
8596 (const_int 8)
8597 (const_int 8))
8598 (match_dup 2)))])])
8599
8600 (define_insn "*xorqi_cc_ext_1_rex64"
8601 [(set (reg FLAGS_REG)
8602 (compare
8603 (xor:SI
8604 (zero_extract:SI
8605 (match_operand 1 "ext_register_operand" "0")
8606 (const_int 8)
8607 (const_int 8))
8608 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8609 (const_int 0)))
8610 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8611 (const_int 8)
8612 (const_int 8))
8613 (xor:SI
8614 (zero_extract:SI
8615 (match_dup 1)
8616 (const_int 8)
8617 (const_int 8))
8618 (match_dup 2)))]
8619 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8620 "xor{b}\t{%2, %h0|%h0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "modrm" "1")
8623 (set_attr "mode" "QI")])
8624
8625 (define_insn "*xorqi_cc_ext_1"
8626 [(set (reg FLAGS_REG)
8627 (compare
8628 (xor:SI
8629 (zero_extract:SI
8630 (match_operand 1 "ext_register_operand" "0")
8631 (const_int 8)
8632 (const_int 8))
8633 (match_operand:QI 2 "general_operand" "qmn"))
8634 (const_int 0)))
8635 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8636 (const_int 8)
8637 (const_int 8))
8638 (xor:SI
8639 (zero_extract:SI
8640 (match_dup 1)
8641 (const_int 8)
8642 (const_int 8))
8643 (match_dup 2)))]
8644 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8645 "xor{b}\t{%2, %h0|%h0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "modrm" "1")
8648 (set_attr "mode" "QI")])
8649 \f
8650 ;; Negation instructions
8651
8652 (define_expand "neg<mode>2"
8653 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8654 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8655 ""
8656 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8657
8658 (define_insn_and_split "*neg<dwi>2_doubleword"
8659 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8660 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8663 "#"
8664 "reload_completed"
8665 [(parallel
8666 [(set (reg:CCZ FLAGS_REG)
8667 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8668 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8669 (parallel
8670 [(set (match_dup 2)
8671 (plus:DWIH (match_dup 3)
8672 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8673 (const_int 0))))
8674 (clobber (reg:CC FLAGS_REG))])
8675 (parallel
8676 [(set (match_dup 2)
8677 (neg:DWIH (match_dup 2)))
8678 (clobber (reg:CC FLAGS_REG))])]
8679 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8680
8681 (define_insn "*neg<mode>2_1"
8682 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8683 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8684 (clobber (reg:CC FLAGS_REG))]
8685 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8686 "neg{<imodesuffix>}\t%0"
8687 [(set_attr "type" "negnot")
8688 (set_attr "mode" "<MODE>")])
8689
8690 ;; Combine is quite creative about this pattern.
8691 (define_insn "*negsi2_1_zext"
8692 [(set (match_operand:DI 0 "register_operand" "=r")
8693 (lshiftrt:DI
8694 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8695 (const_int 32)))
8696 (const_int 32)))
8697 (clobber (reg:CC FLAGS_REG))]
8698 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8699 "neg{l}\t%k0"
8700 [(set_attr "type" "negnot")
8701 (set_attr "mode" "SI")])
8702
8703 ;; The problem with neg is that it does not perform (compare x 0),
8704 ;; it really performs (compare 0 x), which leaves us with the zero
8705 ;; flag being the only useful item.
8706
8707 (define_insn "*neg<mode>2_cmpz"
8708 [(set (reg:CCZ FLAGS_REG)
8709 (compare:CCZ
8710 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8711 (const_int 0)))
8712 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8713 (neg:SWI (match_dup 1)))]
8714 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8715 "neg{<imodesuffix>}\t%0"
8716 [(set_attr "type" "negnot")
8717 (set_attr "mode" "<MODE>")])
8718
8719 (define_insn "*negsi2_cmpz_zext"
8720 [(set (reg:CCZ FLAGS_REG)
8721 (compare:CCZ
8722 (lshiftrt:DI
8723 (neg:DI (ashift:DI
8724 (match_operand:DI 1 "register_operand" "0")
8725 (const_int 32)))
8726 (const_int 32))
8727 (const_int 0)))
8728 (set (match_operand:DI 0 "register_operand" "=r")
8729 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8730 (const_int 32)))
8731 (const_int 32)))]
8732 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8733 "neg{l}\t%k0"
8734 [(set_attr "type" "negnot")
8735 (set_attr "mode" "SI")])
8736
8737 ;; Changing of sign for FP values is doable using integer unit too.
8738
8739 (define_expand "<code><mode>2"
8740 [(set (match_operand:X87MODEF 0 "register_operand")
8741 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8742 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8743 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8744
8745 (define_insn "*absneg<mode>2_mixed"
8746 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8747 (match_operator:MODEF 3 "absneg_operator"
8748 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8749 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8750 (clobber (reg:CC FLAGS_REG))]
8751 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8752 "#")
8753
8754 (define_insn "*absneg<mode>2_sse"
8755 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8756 (match_operator:MODEF 3 "absneg_operator"
8757 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8758 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8759 (clobber (reg:CC FLAGS_REG))]
8760 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8761 "#")
8762
8763 (define_insn "*absneg<mode>2_i387"
8764 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8765 (match_operator:X87MODEF 3 "absneg_operator"
8766 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8767 (use (match_operand 2))
8768 (clobber (reg:CC FLAGS_REG))]
8769 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8770 "#")
8771
8772 (define_expand "<code>tf2"
8773 [(set (match_operand:TF 0 "register_operand")
8774 (absneg:TF (match_operand:TF 1 "register_operand")))]
8775 "TARGET_SSE"
8776 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8777
8778 (define_insn "*absnegtf2_sse"
8779 [(set (match_operand:TF 0 "register_operand" "=x,x")
8780 (match_operator:TF 3 "absneg_operator"
8781 [(match_operand:TF 1 "register_operand" "0,x")]))
8782 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8783 (clobber (reg:CC FLAGS_REG))]
8784 "TARGET_SSE"
8785 "#")
8786
8787 ;; Splitters for fp abs and neg.
8788
8789 (define_split
8790 [(set (match_operand 0 "fp_register_operand")
8791 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8792 (use (match_operand 2))
8793 (clobber (reg:CC FLAGS_REG))]
8794 "reload_completed"
8795 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8796
8797 (define_split
8798 [(set (match_operand 0 "register_operand")
8799 (match_operator 3 "absneg_operator"
8800 [(match_operand 1 "register_operand")]))
8801 (use (match_operand 2 "nonimmediate_operand"))
8802 (clobber (reg:CC FLAGS_REG))]
8803 "reload_completed && SSE_REG_P (operands[0])"
8804 [(set (match_dup 0) (match_dup 3))]
8805 {
8806 enum machine_mode mode = GET_MODE (operands[0]);
8807 enum machine_mode vmode = GET_MODE (operands[2]);
8808 rtx tmp;
8809
8810 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8811 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8812 if (operands_match_p (operands[0], operands[2]))
8813 {
8814 tmp = operands[1];
8815 operands[1] = operands[2];
8816 operands[2] = tmp;
8817 }
8818 if (GET_CODE (operands[3]) == ABS)
8819 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8820 else
8821 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8822 operands[3] = tmp;
8823 })
8824
8825 (define_split
8826 [(set (match_operand:SF 0 "register_operand")
8827 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8828 (use (match_operand:V4SF 2))
8829 (clobber (reg:CC FLAGS_REG))]
8830 "reload_completed"
8831 [(parallel [(set (match_dup 0) (match_dup 1))
8832 (clobber (reg:CC FLAGS_REG))])]
8833 {
8834 rtx tmp;
8835 operands[0] = gen_lowpart (SImode, operands[0]);
8836 if (GET_CODE (operands[1]) == ABS)
8837 {
8838 tmp = gen_int_mode (0x7fffffff, SImode);
8839 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8840 }
8841 else
8842 {
8843 tmp = gen_int_mode (0x80000000, SImode);
8844 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8845 }
8846 operands[1] = tmp;
8847 })
8848
8849 (define_split
8850 [(set (match_operand:DF 0 "register_operand")
8851 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8852 (use (match_operand 2))
8853 (clobber (reg:CC FLAGS_REG))]
8854 "reload_completed"
8855 [(parallel [(set (match_dup 0) (match_dup 1))
8856 (clobber (reg:CC FLAGS_REG))])]
8857 {
8858 rtx tmp;
8859 if (TARGET_64BIT)
8860 {
8861 tmp = gen_lowpart (DImode, operands[0]);
8862 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8863 operands[0] = tmp;
8864
8865 if (GET_CODE (operands[1]) == ABS)
8866 tmp = const0_rtx;
8867 else
8868 tmp = gen_rtx_NOT (DImode, tmp);
8869 }
8870 else
8871 {
8872 operands[0] = gen_highpart (SImode, operands[0]);
8873 if (GET_CODE (operands[1]) == ABS)
8874 {
8875 tmp = gen_int_mode (0x7fffffff, SImode);
8876 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8877 }
8878 else
8879 {
8880 tmp = gen_int_mode (0x80000000, SImode);
8881 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8882 }
8883 }
8884 operands[1] = tmp;
8885 })
8886
8887 (define_split
8888 [(set (match_operand:XF 0 "register_operand")
8889 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8890 (use (match_operand 2))
8891 (clobber (reg:CC FLAGS_REG))]
8892 "reload_completed"
8893 [(parallel [(set (match_dup 0) (match_dup 1))
8894 (clobber (reg:CC FLAGS_REG))])]
8895 {
8896 rtx tmp;
8897 operands[0] = gen_rtx_REG (SImode,
8898 true_regnum (operands[0])
8899 + (TARGET_64BIT ? 1 : 2));
8900 if (GET_CODE (operands[1]) == ABS)
8901 {
8902 tmp = GEN_INT (0x7fff);
8903 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8904 }
8905 else
8906 {
8907 tmp = GEN_INT (0x8000);
8908 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8909 }
8910 operands[1] = tmp;
8911 })
8912
8913 ;; Conditionalize these after reload. If they match before reload, we
8914 ;; lose the clobber and ability to use integer instructions.
8915
8916 (define_insn "*<code><mode>2_1"
8917 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8918 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8919 "TARGET_80387
8920 && (reload_completed
8921 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8922 "f<absneg_mnemonic>"
8923 [(set_attr "type" "fsgn")
8924 (set_attr "mode" "<MODE>")])
8925
8926 (define_insn "*<code>extendsfdf2"
8927 [(set (match_operand:DF 0 "register_operand" "=f")
8928 (absneg:DF (float_extend:DF
8929 (match_operand:SF 1 "register_operand" "0"))))]
8930 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8931 "f<absneg_mnemonic>"
8932 [(set_attr "type" "fsgn")
8933 (set_attr "mode" "DF")])
8934
8935 (define_insn "*<code>extendsfxf2"
8936 [(set (match_operand:XF 0 "register_operand" "=f")
8937 (absneg:XF (float_extend:XF
8938 (match_operand:SF 1 "register_operand" "0"))))]
8939 "TARGET_80387"
8940 "f<absneg_mnemonic>"
8941 [(set_attr "type" "fsgn")
8942 (set_attr "mode" "XF")])
8943
8944 (define_insn "*<code>extenddfxf2"
8945 [(set (match_operand:XF 0 "register_operand" "=f")
8946 (absneg:XF (float_extend:XF
8947 (match_operand:DF 1 "register_operand" "0"))))]
8948 "TARGET_80387"
8949 "f<absneg_mnemonic>"
8950 [(set_attr "type" "fsgn")
8951 (set_attr "mode" "XF")])
8952
8953 ;; Copysign instructions
8954
8955 (define_mode_iterator CSGNMODE [SF DF TF])
8956 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8957
8958 (define_expand "copysign<mode>3"
8959 [(match_operand:CSGNMODE 0 "register_operand")
8960 (match_operand:CSGNMODE 1 "nonmemory_operand")
8961 (match_operand:CSGNMODE 2 "register_operand")]
8962 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8963 || (TARGET_SSE && (<MODE>mode == TFmode))"
8964 "ix86_expand_copysign (operands); DONE;")
8965
8966 (define_insn_and_split "copysign<mode>3_const"
8967 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8968 (unspec:CSGNMODE
8969 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8970 (match_operand:CSGNMODE 2 "register_operand" "0")
8971 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8972 UNSPEC_COPYSIGN))]
8973 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8974 || (TARGET_SSE && (<MODE>mode == TFmode))"
8975 "#"
8976 "&& reload_completed"
8977 [(const_int 0)]
8978 "ix86_split_copysign_const (operands); DONE;")
8979
8980 (define_insn "copysign<mode>3_var"
8981 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8982 (unspec:CSGNMODE
8983 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8984 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8985 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8986 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8987 UNSPEC_COPYSIGN))
8988 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8989 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8990 || (TARGET_SSE && (<MODE>mode == TFmode))"
8991 "#")
8992
8993 (define_split
8994 [(set (match_operand:CSGNMODE 0 "register_operand")
8995 (unspec:CSGNMODE
8996 [(match_operand:CSGNMODE 2 "register_operand")
8997 (match_operand:CSGNMODE 3 "register_operand")
8998 (match_operand:<CSGNVMODE> 4)
8999 (match_operand:<CSGNVMODE> 5)]
9000 UNSPEC_COPYSIGN))
9001 (clobber (match_scratch:<CSGNVMODE> 1))]
9002 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9003 || (TARGET_SSE && (<MODE>mode == TFmode)))
9004 && reload_completed"
9005 [(const_int 0)]
9006 "ix86_split_copysign_var (operands); DONE;")
9007 \f
9008 ;; One complement instructions
9009
9010 (define_expand "one_cmpl<mode>2"
9011 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9012 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9013 ""
9014 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9015
9016 (define_insn "*one_cmpl<mode>2_1"
9017 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9018 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9019 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9020 "not{<imodesuffix>}\t%0"
9021 [(set_attr "type" "negnot")
9022 (set_attr "mode" "<MODE>")])
9023
9024 ;; %%% Potential partial reg stall on alternative 1. What to do?
9025 (define_insn "*one_cmplqi2_1"
9026 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9027 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9028 "ix86_unary_operator_ok (NOT, QImode, operands)"
9029 "@
9030 not{b}\t%0
9031 not{l}\t%k0"
9032 [(set_attr "type" "negnot")
9033 (set_attr "mode" "QI,SI")])
9034
9035 ;; ??? Currently never generated - xor is used instead.
9036 (define_insn "*one_cmplsi2_1_zext"
9037 [(set (match_operand:DI 0 "register_operand" "=r")
9038 (zero_extend:DI
9039 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9040 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9041 "not{l}\t%k0"
9042 [(set_attr "type" "negnot")
9043 (set_attr "mode" "SI")])
9044
9045 (define_insn "*one_cmpl<mode>2_2"
9046 [(set (reg FLAGS_REG)
9047 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9048 (const_int 0)))
9049 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9050 (not:SWI (match_dup 1)))]
9051 "ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9053 "#"
9054 [(set_attr "type" "alu1")
9055 (set_attr "mode" "<MODE>")])
9056
9057 (define_split
9058 [(set (match_operand 0 "flags_reg_operand")
9059 (match_operator 2 "compare_operator"
9060 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9061 (const_int 0)]))
9062 (set (match_operand:SWI 1 "nonimmediate_operand")
9063 (not:SWI (match_dup 3)))]
9064 "ix86_match_ccmode (insn, CCNOmode)"
9065 [(parallel [(set (match_dup 0)
9066 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9067 (const_int 0)]))
9068 (set (match_dup 1)
9069 (xor:SWI (match_dup 3) (const_int -1)))])])
9070
9071 ;; ??? Currently never generated - xor is used instead.
9072 (define_insn "*one_cmplsi2_2_zext"
9073 [(set (reg FLAGS_REG)
9074 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9075 (const_int 0)))
9076 (set (match_operand:DI 0 "register_operand" "=r")
9077 (zero_extend:DI (not:SI (match_dup 1))))]
9078 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9079 && ix86_unary_operator_ok (NOT, SImode, operands)"
9080 "#"
9081 [(set_attr "type" "alu1")
9082 (set_attr "mode" "SI")])
9083
9084 (define_split
9085 [(set (match_operand 0 "flags_reg_operand")
9086 (match_operator 2 "compare_operator"
9087 [(not:SI (match_operand:SI 3 "register_operand"))
9088 (const_int 0)]))
9089 (set (match_operand:DI 1 "register_operand")
9090 (zero_extend:DI (not:SI (match_dup 3))))]
9091 "ix86_match_ccmode (insn, CCNOmode)"
9092 [(parallel [(set (match_dup 0)
9093 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9094 (const_int 0)]))
9095 (set (match_dup 1)
9096 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9097 \f
9098 ;; Shift instructions
9099
9100 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9101 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9102 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9103 ;; from the assembler input.
9104 ;;
9105 ;; This instruction shifts the target reg/mem as usual, but instead of
9106 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9107 ;; is a left shift double, bits are taken from the high order bits of
9108 ;; reg, else if the insn is a shift right double, bits are taken from the
9109 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9110 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9111 ;;
9112 ;; Since sh[lr]d does not change the `reg' operand, that is done
9113 ;; separately, making all shifts emit pairs of shift double and normal
9114 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9115 ;; support a 63 bit shift, each shift where the count is in a reg expands
9116 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9117 ;;
9118 ;; If the shift count is a constant, we need never emit more than one
9119 ;; shift pair, instead using moves and sign extension for counts greater
9120 ;; than 31.
9121
9122 (define_expand "ashl<mode>3"
9123 [(set (match_operand:SDWIM 0 "<shift_operand>")
9124 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9125 (match_operand:QI 2 "nonmemory_operand")))]
9126 ""
9127 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9128
9129 (define_insn "*ashl<mode>3_doubleword"
9130 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9131 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9132 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9133 (clobber (reg:CC FLAGS_REG))]
9134 ""
9135 "#"
9136 [(set_attr "type" "multi")])
9137
9138 (define_split
9139 [(set (match_operand:DWI 0 "register_operand")
9140 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9141 (match_operand:QI 2 "nonmemory_operand")))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9144 [(const_int 0)]
9145 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9146
9147 ;; By default we don't ask for a scratch register, because when DWImode
9148 ;; values are manipulated, registers are already at a premium. But if
9149 ;; we have one handy, we won't turn it away.
9150
9151 (define_peephole2
9152 [(match_scratch:DWIH 3 "r")
9153 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9154 (ashift:<DWI>
9155 (match_operand:<DWI> 1 "nonmemory_operand")
9156 (match_operand:QI 2 "nonmemory_operand")))
9157 (clobber (reg:CC FLAGS_REG))])
9158 (match_dup 3)]
9159 "TARGET_CMOVE"
9160 [(const_int 0)]
9161 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9162
9163 (define_insn "x86_64_shld"
9164 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9165 (ior:DI (ashift:DI (match_dup 0)
9166 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9167 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9168 (minus:QI (const_int 64) (match_dup 2)))))
9169 (clobber (reg:CC FLAGS_REG))]
9170 "TARGET_64BIT"
9171 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9172 [(set_attr "type" "ishift")
9173 (set_attr "prefix_0f" "1")
9174 (set_attr "mode" "DI")
9175 (set_attr "athlon_decode" "vector")
9176 (set_attr "amdfam10_decode" "vector")
9177 (set_attr "bdver1_decode" "vector")])
9178
9179 (define_insn "x86_shld"
9180 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9181 (ior:SI (ashift:SI (match_dup 0)
9182 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9183 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9184 (minus:QI (const_int 32) (match_dup 2)))))
9185 (clobber (reg:CC FLAGS_REG))]
9186 ""
9187 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9188 [(set_attr "type" "ishift")
9189 (set_attr "prefix_0f" "1")
9190 (set_attr "mode" "SI")
9191 (set_attr "pent_pair" "np")
9192 (set_attr "athlon_decode" "vector")
9193 (set_attr "amdfam10_decode" "vector")
9194 (set_attr "bdver1_decode" "vector")])
9195
9196 (define_expand "x86_shift<mode>_adj_1"
9197 [(set (reg:CCZ FLAGS_REG)
9198 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9199 (match_dup 4))
9200 (const_int 0)))
9201 (set (match_operand:SWI48 0 "register_operand")
9202 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9203 (match_operand:SWI48 1 "register_operand")
9204 (match_dup 0)))
9205 (set (match_dup 1)
9206 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9207 (match_operand:SWI48 3 "register_operand")
9208 (match_dup 1)))]
9209 "TARGET_CMOVE"
9210 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9211
9212 (define_expand "x86_shift<mode>_adj_2"
9213 [(use (match_operand:SWI48 0 "register_operand"))
9214 (use (match_operand:SWI48 1 "register_operand"))
9215 (use (match_operand:QI 2 "register_operand"))]
9216 ""
9217 {
9218 rtx label = gen_label_rtx ();
9219 rtx tmp;
9220
9221 emit_insn (gen_testqi_ccz_1 (operands[2],
9222 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9223
9224 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9225 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9226 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9227 gen_rtx_LABEL_REF (VOIDmode, label),
9228 pc_rtx);
9229 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9230 JUMP_LABEL (tmp) = label;
9231
9232 emit_move_insn (operands[0], operands[1]);
9233 ix86_expand_clear (operands[1]);
9234
9235 emit_label (label);
9236 LABEL_NUSES (label) = 1;
9237
9238 DONE;
9239 })
9240
9241 ;; Avoid useless masking of count operand.
9242 (define_insn_and_split "*ashl<mode>3_mask"
9243 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9244 (ashift:SWI48
9245 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9246 (subreg:QI
9247 (and:SI
9248 (match_operand:SI 2 "nonimmediate_operand" "c")
9249 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9250 (clobber (reg:CC FLAGS_REG))]
9251 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9252 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9253 == GET_MODE_BITSIZE (<MODE>mode)-1"
9254 "#"
9255 "&& 1"
9256 [(parallel [(set (match_dup 0)
9257 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9258 (clobber (reg:CC FLAGS_REG))])]
9259 {
9260 if (can_create_pseudo_p ())
9261 operands [2] = force_reg (SImode, operands[2]);
9262
9263 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9264 }
9265 [(set_attr "type" "ishift")
9266 (set_attr "mode" "<MODE>")])
9267
9268 (define_insn "*bmi2_ashl<mode>3_1"
9269 [(set (match_operand:SWI48 0 "register_operand" "=r")
9270 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9271 (match_operand:SWI48 2 "register_operand" "r")))]
9272 "TARGET_BMI2"
9273 "shlx\t{%2, %1, %0|%0, %1, %2}"
9274 [(set_attr "type" "ishiftx")
9275 (set_attr "mode" "<MODE>")])
9276
9277 (define_insn "*ashl<mode>3_1"
9278 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9279 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9280 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9281 (clobber (reg:CC FLAGS_REG))]
9282 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9283 {
9284 switch (get_attr_type (insn))
9285 {
9286 case TYPE_LEA:
9287 case TYPE_ISHIFTX:
9288 return "#";
9289
9290 case TYPE_ALU:
9291 gcc_assert (operands[2] == const1_rtx);
9292 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9293 return "add{<imodesuffix>}\t%0, %0";
9294
9295 default:
9296 if (operands[2] == const1_rtx
9297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9298 return "sal{<imodesuffix>}\t%0";
9299 else
9300 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9301 }
9302 }
9303 [(set_attr "isa" "*,*,bmi2")
9304 (set (attr "type")
9305 (cond [(eq_attr "alternative" "1")
9306 (const_string "lea")
9307 (eq_attr "alternative" "2")
9308 (const_string "ishiftx")
9309 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9310 (match_operand 0 "register_operand"))
9311 (match_operand 2 "const1_operand"))
9312 (const_string "alu")
9313 ]
9314 (const_string "ishift")))
9315 (set (attr "length_immediate")
9316 (if_then_else
9317 (ior (eq_attr "type" "alu")
9318 (and (eq_attr "type" "ishift")
9319 (and (match_operand 2 "const1_operand")
9320 (ior (match_test "TARGET_SHIFT1")
9321 (match_test "optimize_function_for_size_p (cfun)")))))
9322 (const_string "0")
9323 (const_string "*")))
9324 (set_attr "mode" "<MODE>")])
9325
9326 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9327 (define_split
9328 [(set (match_operand:SWI48 0 "register_operand")
9329 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9330 (match_operand:QI 2 "register_operand")))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "TARGET_BMI2 && reload_completed"
9333 [(set (match_dup 0)
9334 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9335 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9336
9337 (define_insn "*bmi2_ashlsi3_1_zext"
9338 [(set (match_operand:DI 0 "register_operand" "=r")
9339 (zero_extend:DI
9340 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9341 (match_operand:SI 2 "register_operand" "r"))))]
9342 "TARGET_64BIT && TARGET_BMI2"
9343 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9344 [(set_attr "type" "ishiftx")
9345 (set_attr "mode" "SI")])
9346
9347 (define_insn "*ashlsi3_1_zext"
9348 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9349 (zero_extend:DI
9350 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9351 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9354 {
9355 switch (get_attr_type (insn))
9356 {
9357 case TYPE_LEA:
9358 case TYPE_ISHIFTX:
9359 return "#";
9360
9361 case TYPE_ALU:
9362 gcc_assert (operands[2] == const1_rtx);
9363 return "add{l}\t%k0, %k0";
9364
9365 default:
9366 if (operands[2] == const1_rtx
9367 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9368 return "sal{l}\t%k0";
9369 else
9370 return "sal{l}\t{%2, %k0|%k0, %2}";
9371 }
9372 }
9373 [(set_attr "isa" "*,*,bmi2")
9374 (set (attr "type")
9375 (cond [(eq_attr "alternative" "1")
9376 (const_string "lea")
9377 (eq_attr "alternative" "2")
9378 (const_string "ishiftx")
9379 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9380 (match_operand 2 "const1_operand"))
9381 (const_string "alu")
9382 ]
9383 (const_string "ishift")))
9384 (set (attr "length_immediate")
9385 (if_then_else
9386 (ior (eq_attr "type" "alu")
9387 (and (eq_attr "type" "ishift")
9388 (and (match_operand 2 "const1_operand")
9389 (ior (match_test "TARGET_SHIFT1")
9390 (match_test "optimize_function_for_size_p (cfun)")))))
9391 (const_string "0")
9392 (const_string "*")))
9393 (set_attr "mode" "SI")])
9394
9395 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9396 (define_split
9397 [(set (match_operand:DI 0 "register_operand")
9398 (zero_extend:DI
9399 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9400 (match_operand:QI 2 "register_operand"))))
9401 (clobber (reg:CC FLAGS_REG))]
9402 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9403 [(set (match_dup 0)
9404 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9405 "operands[2] = gen_lowpart (SImode, operands[2]);")
9406
9407 (define_insn "*ashlhi3_1"
9408 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9409 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9410 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9411 (clobber (reg:CC FLAGS_REG))]
9412 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9413 {
9414 switch (get_attr_type (insn))
9415 {
9416 case TYPE_LEA:
9417 return "#";
9418
9419 case TYPE_ALU:
9420 gcc_assert (operands[2] == const1_rtx);
9421 return "add{w}\t%0, %0";
9422
9423 default:
9424 if (operands[2] == const1_rtx
9425 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9426 return "sal{w}\t%0";
9427 else
9428 return "sal{w}\t{%2, %0|%0, %2}";
9429 }
9430 }
9431 [(set (attr "type")
9432 (cond [(eq_attr "alternative" "1")
9433 (const_string "lea")
9434 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9435 (match_operand 0 "register_operand"))
9436 (match_operand 2 "const1_operand"))
9437 (const_string "alu")
9438 ]
9439 (const_string "ishift")))
9440 (set (attr "length_immediate")
9441 (if_then_else
9442 (ior (eq_attr "type" "alu")
9443 (and (eq_attr "type" "ishift")
9444 (and (match_operand 2 "const1_operand")
9445 (ior (match_test "TARGET_SHIFT1")
9446 (match_test "optimize_function_for_size_p (cfun)")))))
9447 (const_string "0")
9448 (const_string "*")))
9449 (set_attr "mode" "HI,SI")])
9450
9451 ;; %%% Potential partial reg stall on alternative 1. What to do?
9452 (define_insn "*ashlqi3_1"
9453 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9454 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9455 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9458 {
9459 switch (get_attr_type (insn))
9460 {
9461 case TYPE_LEA:
9462 return "#";
9463
9464 case TYPE_ALU:
9465 gcc_assert (operands[2] == const1_rtx);
9466 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9467 return "add{l}\t%k0, %k0";
9468 else
9469 return "add{b}\t%0, %0";
9470
9471 default:
9472 if (operands[2] == const1_rtx
9473 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9474 {
9475 if (get_attr_mode (insn) == MODE_SI)
9476 return "sal{l}\t%k0";
9477 else
9478 return "sal{b}\t%0";
9479 }
9480 else
9481 {
9482 if (get_attr_mode (insn) == MODE_SI)
9483 return "sal{l}\t{%2, %k0|%k0, %2}";
9484 else
9485 return "sal{b}\t{%2, %0|%0, %2}";
9486 }
9487 }
9488 }
9489 [(set (attr "type")
9490 (cond [(eq_attr "alternative" "2")
9491 (const_string "lea")
9492 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9493 (match_operand 0 "register_operand"))
9494 (match_operand 2 "const1_operand"))
9495 (const_string "alu")
9496 ]
9497 (const_string "ishift")))
9498 (set (attr "length_immediate")
9499 (if_then_else
9500 (ior (eq_attr "type" "alu")
9501 (and (eq_attr "type" "ishift")
9502 (and (match_operand 2 "const1_operand")
9503 (ior (match_test "TARGET_SHIFT1")
9504 (match_test "optimize_function_for_size_p (cfun)")))))
9505 (const_string "0")
9506 (const_string "*")))
9507 (set_attr "mode" "QI,SI,SI")])
9508
9509 (define_insn "*ashlqi3_1_slp"
9510 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9511 (ashift:QI (match_dup 0)
9512 (match_operand:QI 1 "nonmemory_operand" "cI")))
9513 (clobber (reg:CC FLAGS_REG))]
9514 "(optimize_function_for_size_p (cfun)
9515 || !TARGET_PARTIAL_FLAG_REG_STALL
9516 || (operands[1] == const1_rtx
9517 && (TARGET_SHIFT1
9518 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9519 {
9520 switch (get_attr_type (insn))
9521 {
9522 case TYPE_ALU:
9523 gcc_assert (operands[1] == const1_rtx);
9524 return "add{b}\t%0, %0";
9525
9526 default:
9527 if (operands[1] == const1_rtx
9528 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9529 return "sal{b}\t%0";
9530 else
9531 return "sal{b}\t{%1, %0|%0, %1}";
9532 }
9533 }
9534 [(set (attr "type")
9535 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9536 (match_operand 0 "register_operand"))
9537 (match_operand 1 "const1_operand"))
9538 (const_string "alu")
9539 ]
9540 (const_string "ishift1")))
9541 (set (attr "length_immediate")
9542 (if_then_else
9543 (ior (eq_attr "type" "alu")
9544 (and (eq_attr "type" "ishift1")
9545 (and (match_operand 1 "const1_operand")
9546 (ior (match_test "TARGET_SHIFT1")
9547 (match_test "optimize_function_for_size_p (cfun)")))))
9548 (const_string "0")
9549 (const_string "*")))
9550 (set_attr "mode" "QI")])
9551
9552 ;; Convert ashift to the lea pattern to avoid flags dependency.
9553 (define_split
9554 [(set (match_operand 0 "register_operand")
9555 (ashift (match_operand 1 "index_register_operand")
9556 (match_operand:QI 2 "const_int_operand")))
9557 (clobber (reg:CC FLAGS_REG))]
9558 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9559 && reload_completed
9560 && true_regnum (operands[0]) != true_regnum (operands[1])"
9561 [(const_int 0)]
9562 {
9563 enum machine_mode mode = GET_MODE (operands[0]);
9564 rtx pat;
9565
9566 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9567 {
9568 mode = SImode;
9569 operands[0] = gen_lowpart (mode, operands[0]);
9570 operands[1] = gen_lowpart (mode, operands[1]);
9571 }
9572
9573 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9574
9575 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9576
9577 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9578 DONE;
9579 })
9580
9581 ;; Convert ashift to the lea pattern to avoid flags dependency.
9582 (define_split
9583 [(set (match_operand:DI 0 "register_operand")
9584 (zero_extend:DI
9585 (ashift:SI (match_operand:SI 1 "index_register_operand")
9586 (match_operand:QI 2 "const_int_operand"))))
9587 (clobber (reg:CC FLAGS_REG))]
9588 "TARGET_64BIT && reload_completed
9589 && true_regnum (operands[0]) != true_regnum (operands[1])"
9590 [(set (match_dup 0)
9591 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9592 {
9593 operands[1] = gen_lowpart (DImode, operands[1]);
9594 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9595 })
9596
9597 ;; This pattern can't accept a variable shift count, since shifts by
9598 ;; zero don't affect the flags. We assume that shifts by constant
9599 ;; zero are optimized away.
9600 (define_insn "*ashl<mode>3_cmp"
9601 [(set (reg FLAGS_REG)
9602 (compare
9603 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9604 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9605 (const_int 0)))
9606 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9607 (ashift:SWI (match_dup 1) (match_dup 2)))]
9608 "(optimize_function_for_size_p (cfun)
9609 || !TARGET_PARTIAL_FLAG_REG_STALL
9610 || (operands[2] == const1_rtx
9611 && (TARGET_SHIFT1
9612 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9613 && ix86_match_ccmode (insn, CCGOCmode)
9614 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9615 {
9616 switch (get_attr_type (insn))
9617 {
9618 case TYPE_ALU:
9619 gcc_assert (operands[2] == const1_rtx);
9620 return "add{<imodesuffix>}\t%0, %0";
9621
9622 default:
9623 if (operands[2] == const1_rtx
9624 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9625 return "sal{<imodesuffix>}\t%0";
9626 else
9627 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9628 }
9629 }
9630 [(set (attr "type")
9631 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9632 (match_operand 0 "register_operand"))
9633 (match_operand 2 "const1_operand"))
9634 (const_string "alu")
9635 ]
9636 (const_string "ishift")))
9637 (set (attr "length_immediate")
9638 (if_then_else
9639 (ior (eq_attr "type" "alu")
9640 (and (eq_attr "type" "ishift")
9641 (and (match_operand 2 "const1_operand")
9642 (ior (match_test "TARGET_SHIFT1")
9643 (match_test "optimize_function_for_size_p (cfun)")))))
9644 (const_string "0")
9645 (const_string "*")))
9646 (set_attr "mode" "<MODE>")])
9647
9648 (define_insn "*ashlsi3_cmp_zext"
9649 [(set (reg FLAGS_REG)
9650 (compare
9651 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9652 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9653 (const_int 0)))
9654 (set (match_operand:DI 0 "register_operand" "=r")
9655 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9656 "TARGET_64BIT
9657 && (optimize_function_for_size_p (cfun)
9658 || !TARGET_PARTIAL_FLAG_REG_STALL
9659 || (operands[2] == const1_rtx
9660 && (TARGET_SHIFT1
9661 || TARGET_DOUBLE_WITH_ADD)))
9662 && ix86_match_ccmode (insn, CCGOCmode)
9663 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9664 {
9665 switch (get_attr_type (insn))
9666 {
9667 case TYPE_ALU:
9668 gcc_assert (operands[2] == const1_rtx);
9669 return "add{l}\t%k0, %k0";
9670
9671 default:
9672 if (operands[2] == const1_rtx
9673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9674 return "sal{l}\t%k0";
9675 else
9676 return "sal{l}\t{%2, %k0|%k0, %2}";
9677 }
9678 }
9679 [(set (attr "type")
9680 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9681 (match_operand 2 "const1_operand"))
9682 (const_string "alu")
9683 ]
9684 (const_string "ishift")))
9685 (set (attr "length_immediate")
9686 (if_then_else
9687 (ior (eq_attr "type" "alu")
9688 (and (eq_attr "type" "ishift")
9689 (and (match_operand 2 "const1_operand")
9690 (ior (match_test "TARGET_SHIFT1")
9691 (match_test "optimize_function_for_size_p (cfun)")))))
9692 (const_string "0")
9693 (const_string "*")))
9694 (set_attr "mode" "SI")])
9695
9696 (define_insn "*ashl<mode>3_cconly"
9697 [(set (reg FLAGS_REG)
9698 (compare
9699 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9700 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9701 (const_int 0)))
9702 (clobber (match_scratch:SWI 0 "=<r>"))]
9703 "(optimize_function_for_size_p (cfun)
9704 || !TARGET_PARTIAL_FLAG_REG_STALL
9705 || (operands[2] == const1_rtx
9706 && (TARGET_SHIFT1
9707 || TARGET_DOUBLE_WITH_ADD)))
9708 && ix86_match_ccmode (insn, CCGOCmode)"
9709 {
9710 switch (get_attr_type (insn))
9711 {
9712 case TYPE_ALU:
9713 gcc_assert (operands[2] == const1_rtx);
9714 return "add{<imodesuffix>}\t%0, %0";
9715
9716 default:
9717 if (operands[2] == const1_rtx
9718 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9719 return "sal{<imodesuffix>}\t%0";
9720 else
9721 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9722 }
9723 }
9724 [(set (attr "type")
9725 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9726 (match_operand 0 "register_operand"))
9727 (match_operand 2 "const1_operand"))
9728 (const_string "alu")
9729 ]
9730 (const_string "ishift")))
9731 (set (attr "length_immediate")
9732 (if_then_else
9733 (ior (eq_attr "type" "alu")
9734 (and (eq_attr "type" "ishift")
9735 (and (match_operand 2 "const1_operand")
9736 (ior (match_test "TARGET_SHIFT1")
9737 (match_test "optimize_function_for_size_p (cfun)")))))
9738 (const_string "0")
9739 (const_string "*")))
9740 (set_attr "mode" "<MODE>")])
9741
9742 ;; See comment above `ashl<mode>3' about how this works.
9743
9744 (define_expand "<shift_insn><mode>3"
9745 [(set (match_operand:SDWIM 0 "<shift_operand>")
9746 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9747 (match_operand:QI 2 "nonmemory_operand")))]
9748 ""
9749 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9750
9751 ;; Avoid useless masking of count operand.
9752 (define_insn_and_split "*<shift_insn><mode>3_mask"
9753 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9754 (any_shiftrt:SWI48
9755 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9756 (subreg:QI
9757 (and:SI
9758 (match_operand:SI 2 "nonimmediate_operand" "c")
9759 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9760 (clobber (reg:CC FLAGS_REG))]
9761 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9762 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9763 == GET_MODE_BITSIZE (<MODE>mode)-1"
9764 "#"
9765 "&& 1"
9766 [(parallel [(set (match_dup 0)
9767 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9768 (clobber (reg:CC FLAGS_REG))])]
9769 {
9770 if (can_create_pseudo_p ())
9771 operands [2] = force_reg (SImode, operands[2]);
9772
9773 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9774 }
9775 [(set_attr "type" "ishift")
9776 (set_attr "mode" "<MODE>")])
9777
9778 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9779 [(set (match_operand:DWI 0 "register_operand" "=r")
9780 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9781 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9782 (clobber (reg:CC FLAGS_REG))]
9783 ""
9784 "#"
9785 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9786 [(const_int 0)]
9787 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9788 [(set_attr "type" "multi")])
9789
9790 ;; By default we don't ask for a scratch register, because when DWImode
9791 ;; values are manipulated, registers are already at a premium. But if
9792 ;; we have one handy, we won't turn it away.
9793
9794 (define_peephole2
9795 [(match_scratch:DWIH 3 "r")
9796 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9797 (any_shiftrt:<DWI>
9798 (match_operand:<DWI> 1 "register_operand")
9799 (match_operand:QI 2 "nonmemory_operand")))
9800 (clobber (reg:CC FLAGS_REG))])
9801 (match_dup 3)]
9802 "TARGET_CMOVE"
9803 [(const_int 0)]
9804 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9805
9806 (define_insn "x86_64_shrd"
9807 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9808 (ior:DI (ashiftrt:DI (match_dup 0)
9809 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9810 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9811 (minus:QI (const_int 64) (match_dup 2)))))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "TARGET_64BIT"
9814 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9815 [(set_attr "type" "ishift")
9816 (set_attr "prefix_0f" "1")
9817 (set_attr "mode" "DI")
9818 (set_attr "athlon_decode" "vector")
9819 (set_attr "amdfam10_decode" "vector")
9820 (set_attr "bdver1_decode" "vector")])
9821
9822 (define_insn "x86_shrd"
9823 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9824 (ior:SI (ashiftrt:SI (match_dup 0)
9825 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9826 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9827 (minus:QI (const_int 32) (match_dup 2)))))
9828 (clobber (reg:CC FLAGS_REG))]
9829 ""
9830 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9831 [(set_attr "type" "ishift")
9832 (set_attr "prefix_0f" "1")
9833 (set_attr "mode" "SI")
9834 (set_attr "pent_pair" "np")
9835 (set_attr "athlon_decode" "vector")
9836 (set_attr "amdfam10_decode" "vector")
9837 (set_attr "bdver1_decode" "vector")])
9838
9839 (define_insn "ashrdi3_cvt"
9840 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9841 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9842 (match_operand:QI 2 "const_int_operand")))
9843 (clobber (reg:CC FLAGS_REG))]
9844 "TARGET_64BIT && INTVAL (operands[2]) == 63
9845 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9846 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9847 "@
9848 {cqto|cqo}
9849 sar{q}\t{%2, %0|%0, %2}"
9850 [(set_attr "type" "imovx,ishift")
9851 (set_attr "prefix_0f" "0,*")
9852 (set_attr "length_immediate" "0,*")
9853 (set_attr "modrm" "0,1")
9854 (set_attr "mode" "DI")])
9855
9856 (define_insn "ashrsi3_cvt"
9857 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9858 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9859 (match_operand:QI 2 "const_int_operand")))
9860 (clobber (reg:CC FLAGS_REG))]
9861 "INTVAL (operands[2]) == 31
9862 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9863 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9864 "@
9865 {cltd|cdq}
9866 sar{l}\t{%2, %0|%0, %2}"
9867 [(set_attr "type" "imovx,ishift")
9868 (set_attr "prefix_0f" "0,*")
9869 (set_attr "length_immediate" "0,*")
9870 (set_attr "modrm" "0,1")
9871 (set_attr "mode" "SI")])
9872
9873 (define_insn "*ashrsi3_cvt_zext"
9874 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9875 (zero_extend:DI
9876 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9877 (match_operand:QI 2 "const_int_operand"))))
9878 (clobber (reg:CC FLAGS_REG))]
9879 "TARGET_64BIT && INTVAL (operands[2]) == 31
9880 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9881 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9882 "@
9883 {cltd|cdq}
9884 sar{l}\t{%2, %k0|%k0, %2}"
9885 [(set_attr "type" "imovx,ishift")
9886 (set_attr "prefix_0f" "0,*")
9887 (set_attr "length_immediate" "0,*")
9888 (set_attr "modrm" "0,1")
9889 (set_attr "mode" "SI")])
9890
9891 (define_expand "x86_shift<mode>_adj_3"
9892 [(use (match_operand:SWI48 0 "register_operand"))
9893 (use (match_operand:SWI48 1 "register_operand"))
9894 (use (match_operand:QI 2 "register_operand"))]
9895 ""
9896 {
9897 rtx label = gen_label_rtx ();
9898 rtx tmp;
9899
9900 emit_insn (gen_testqi_ccz_1 (operands[2],
9901 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9902
9903 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9904 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9905 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9906 gen_rtx_LABEL_REF (VOIDmode, label),
9907 pc_rtx);
9908 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9909 JUMP_LABEL (tmp) = label;
9910
9911 emit_move_insn (operands[0], operands[1]);
9912 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9913 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9914 emit_label (label);
9915 LABEL_NUSES (label) = 1;
9916
9917 DONE;
9918 })
9919
9920 (define_insn "*bmi2_<shift_insn><mode>3_1"
9921 [(set (match_operand:SWI48 0 "register_operand" "=r")
9922 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9923 (match_operand:SWI48 2 "register_operand" "r")))]
9924 "TARGET_BMI2"
9925 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9926 [(set_attr "type" "ishiftx")
9927 (set_attr "mode" "<MODE>")])
9928
9929 (define_insn "*<shift_insn><mode>3_1"
9930 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9931 (any_shiftrt:SWI48
9932 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9933 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9936 {
9937 switch (get_attr_type (insn))
9938 {
9939 case TYPE_ISHIFTX:
9940 return "#";
9941
9942 default:
9943 if (operands[2] == const1_rtx
9944 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9945 return "<shift>{<imodesuffix>}\t%0";
9946 else
9947 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9948 }
9949 }
9950 [(set_attr "isa" "*,bmi2")
9951 (set_attr "type" "ishift,ishiftx")
9952 (set (attr "length_immediate")
9953 (if_then_else
9954 (and (match_operand 2 "const1_operand")
9955 (ior (match_test "TARGET_SHIFT1")
9956 (match_test "optimize_function_for_size_p (cfun)")))
9957 (const_string "0")
9958 (const_string "*")))
9959 (set_attr "mode" "<MODE>")])
9960
9961 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9962 (define_split
9963 [(set (match_operand:SWI48 0 "register_operand")
9964 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9965 (match_operand:QI 2 "register_operand")))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "TARGET_BMI2 && reload_completed"
9968 [(set (match_dup 0)
9969 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9970 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9971
9972 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9973 [(set (match_operand:DI 0 "register_operand" "=r")
9974 (zero_extend:DI
9975 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9976 (match_operand:SI 2 "register_operand" "r"))))]
9977 "TARGET_64BIT && TARGET_BMI2"
9978 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9979 [(set_attr "type" "ishiftx")
9980 (set_attr "mode" "SI")])
9981
9982 (define_insn "*<shift_insn>si3_1_zext"
9983 [(set (match_operand:DI 0 "register_operand" "=r,r")
9984 (zero_extend:DI
9985 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9986 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9987 (clobber (reg:CC FLAGS_REG))]
9988 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9989 {
9990 switch (get_attr_type (insn))
9991 {
9992 case TYPE_ISHIFTX:
9993 return "#";
9994
9995 default:
9996 if (operands[2] == const1_rtx
9997 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9998 return "<shift>{l}\t%k0";
9999 else
10000 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10001 }
10002 }
10003 [(set_attr "isa" "*,bmi2")
10004 (set_attr "type" "ishift,ishiftx")
10005 (set (attr "length_immediate")
10006 (if_then_else
10007 (and (match_operand 2 "const1_operand")
10008 (ior (match_test "TARGET_SHIFT1")
10009 (match_test "optimize_function_for_size_p (cfun)")))
10010 (const_string "0")
10011 (const_string "*")))
10012 (set_attr "mode" "SI")])
10013
10014 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10015 (define_split
10016 [(set (match_operand:DI 0 "register_operand")
10017 (zero_extend:DI
10018 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10019 (match_operand:QI 2 "register_operand"))))
10020 (clobber (reg:CC FLAGS_REG))]
10021 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10022 [(set (match_dup 0)
10023 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10024 "operands[2] = gen_lowpart (SImode, operands[2]);")
10025
10026 (define_insn "*<shift_insn><mode>3_1"
10027 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10028 (any_shiftrt:SWI12
10029 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10030 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10031 (clobber (reg:CC FLAGS_REG))]
10032 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10033 {
10034 if (operands[2] == const1_rtx
10035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036 return "<shift>{<imodesuffix>}\t%0";
10037 else
10038 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10039 }
10040 [(set_attr "type" "ishift")
10041 (set (attr "length_immediate")
10042 (if_then_else
10043 (and (match_operand 2 "const1_operand")
10044 (ior (match_test "TARGET_SHIFT1")
10045 (match_test "optimize_function_for_size_p (cfun)")))
10046 (const_string "0")
10047 (const_string "*")))
10048 (set_attr "mode" "<MODE>")])
10049
10050 (define_insn "*<shift_insn>qi3_1_slp"
10051 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10052 (any_shiftrt:QI (match_dup 0)
10053 (match_operand:QI 1 "nonmemory_operand" "cI")))
10054 (clobber (reg:CC FLAGS_REG))]
10055 "(optimize_function_for_size_p (cfun)
10056 || !TARGET_PARTIAL_REG_STALL
10057 || (operands[1] == const1_rtx
10058 && TARGET_SHIFT1))"
10059 {
10060 if (operands[1] == const1_rtx
10061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062 return "<shift>{b}\t%0";
10063 else
10064 return "<shift>{b}\t{%1, %0|%0, %1}";
10065 }
10066 [(set_attr "type" "ishift1")
10067 (set (attr "length_immediate")
10068 (if_then_else
10069 (and (match_operand 1 "const1_operand")
10070 (ior (match_test "TARGET_SHIFT1")
10071 (match_test "optimize_function_for_size_p (cfun)")))
10072 (const_string "0")
10073 (const_string "*")))
10074 (set_attr "mode" "QI")])
10075
10076 ;; This pattern can't accept a variable shift count, since shifts by
10077 ;; zero don't affect the flags. We assume that shifts by constant
10078 ;; zero are optimized away.
10079 (define_insn "*<shift_insn><mode>3_cmp"
10080 [(set (reg FLAGS_REG)
10081 (compare
10082 (any_shiftrt:SWI
10083 (match_operand:SWI 1 "nonimmediate_operand" "0")
10084 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10085 (const_int 0)))
10086 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10087 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10088 "(optimize_function_for_size_p (cfun)
10089 || !TARGET_PARTIAL_FLAG_REG_STALL
10090 || (operands[2] == const1_rtx
10091 && TARGET_SHIFT1))
10092 && ix86_match_ccmode (insn, CCGOCmode)
10093 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10094 {
10095 if (operands[2] == const1_rtx
10096 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10097 return "<shift>{<imodesuffix>}\t%0";
10098 else
10099 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10100 }
10101 [(set_attr "type" "ishift")
10102 (set (attr "length_immediate")
10103 (if_then_else
10104 (and (match_operand 2 "const1_operand")
10105 (ior (match_test "TARGET_SHIFT1")
10106 (match_test "optimize_function_for_size_p (cfun)")))
10107 (const_string "0")
10108 (const_string "*")))
10109 (set_attr "mode" "<MODE>")])
10110
10111 (define_insn "*<shift_insn>si3_cmp_zext"
10112 [(set (reg FLAGS_REG)
10113 (compare
10114 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10115 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10116 (const_int 0)))
10117 (set (match_operand:DI 0 "register_operand" "=r")
10118 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10119 "TARGET_64BIT
10120 && (optimize_function_for_size_p (cfun)
10121 || !TARGET_PARTIAL_FLAG_REG_STALL
10122 || (operands[2] == const1_rtx
10123 && TARGET_SHIFT1))
10124 && ix86_match_ccmode (insn, CCGOCmode)
10125 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10126 {
10127 if (operands[2] == const1_rtx
10128 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10129 return "<shift>{l}\t%k0";
10130 else
10131 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10132 }
10133 [(set_attr "type" "ishift")
10134 (set (attr "length_immediate")
10135 (if_then_else
10136 (and (match_operand 2 "const1_operand")
10137 (ior (match_test "TARGET_SHIFT1")
10138 (match_test "optimize_function_for_size_p (cfun)")))
10139 (const_string "0")
10140 (const_string "*")))
10141 (set_attr "mode" "SI")])
10142
10143 (define_insn "*<shift_insn><mode>3_cconly"
10144 [(set (reg FLAGS_REG)
10145 (compare
10146 (any_shiftrt:SWI
10147 (match_operand:SWI 1 "register_operand" "0")
10148 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10149 (const_int 0)))
10150 (clobber (match_scratch:SWI 0 "=<r>"))]
10151 "(optimize_function_for_size_p (cfun)
10152 || !TARGET_PARTIAL_FLAG_REG_STALL
10153 || (operands[2] == const1_rtx
10154 && TARGET_SHIFT1))
10155 && ix86_match_ccmode (insn, CCGOCmode)"
10156 {
10157 if (operands[2] == const1_rtx
10158 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10159 return "<shift>{<imodesuffix>}\t%0";
10160 else
10161 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10162 }
10163 [(set_attr "type" "ishift")
10164 (set (attr "length_immediate")
10165 (if_then_else
10166 (and (match_operand 2 "const1_operand")
10167 (ior (match_test "TARGET_SHIFT1")
10168 (match_test "optimize_function_for_size_p (cfun)")))
10169 (const_string "0")
10170 (const_string "*")))
10171 (set_attr "mode" "<MODE>")])
10172 \f
10173 ;; Rotate instructions
10174
10175 (define_expand "<rotate_insn>ti3"
10176 [(set (match_operand:TI 0 "register_operand")
10177 (any_rotate:TI (match_operand:TI 1 "register_operand")
10178 (match_operand:QI 2 "nonmemory_operand")))]
10179 "TARGET_64BIT"
10180 {
10181 if (const_1_to_63_operand (operands[2], VOIDmode))
10182 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10183 (operands[0], operands[1], operands[2]));
10184 else
10185 FAIL;
10186
10187 DONE;
10188 })
10189
10190 (define_expand "<rotate_insn>di3"
10191 [(set (match_operand:DI 0 "shiftdi_operand")
10192 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10193 (match_operand:QI 2 "nonmemory_operand")))]
10194 ""
10195 {
10196 if (TARGET_64BIT)
10197 ix86_expand_binary_operator (<CODE>, DImode, operands);
10198 else if (const_1_to_31_operand (operands[2], VOIDmode))
10199 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10200 (operands[0], operands[1], operands[2]));
10201 else
10202 FAIL;
10203
10204 DONE;
10205 })
10206
10207 (define_expand "<rotate_insn><mode>3"
10208 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10209 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10210 (match_operand:QI 2 "nonmemory_operand")))]
10211 ""
10212 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10213
10214 ;; Avoid useless masking of count operand.
10215 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10216 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10217 (any_rotate:SWI48
10218 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10219 (subreg:QI
10220 (and:SI
10221 (match_operand:SI 2 "nonimmediate_operand" "c")
10222 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10225 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10226 == GET_MODE_BITSIZE (<MODE>mode)-1"
10227 "#"
10228 "&& 1"
10229 [(parallel [(set (match_dup 0)
10230 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10231 (clobber (reg:CC FLAGS_REG))])]
10232 {
10233 if (can_create_pseudo_p ())
10234 operands [2] = force_reg (SImode, operands[2]);
10235
10236 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10237 }
10238 [(set_attr "type" "rotate")
10239 (set_attr "mode" "<MODE>")])
10240
10241 ;; Implement rotation using two double-precision
10242 ;; shift instructions and a scratch register.
10243
10244 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10245 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10246 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10247 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10248 (clobber (reg:CC FLAGS_REG))
10249 (clobber (match_scratch:DWIH 3 "=&r"))]
10250 ""
10251 "#"
10252 "reload_completed"
10253 [(set (match_dup 3) (match_dup 4))
10254 (parallel
10255 [(set (match_dup 4)
10256 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10257 (lshiftrt:DWIH (match_dup 5)
10258 (minus:QI (match_dup 6) (match_dup 2)))))
10259 (clobber (reg:CC FLAGS_REG))])
10260 (parallel
10261 [(set (match_dup 5)
10262 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10263 (lshiftrt:DWIH (match_dup 3)
10264 (minus:QI (match_dup 6) (match_dup 2)))))
10265 (clobber (reg:CC FLAGS_REG))])]
10266 {
10267 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10268
10269 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10270 })
10271
10272 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10273 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10274 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10275 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10276 (clobber (reg:CC FLAGS_REG))
10277 (clobber (match_scratch:DWIH 3 "=&r"))]
10278 ""
10279 "#"
10280 "reload_completed"
10281 [(set (match_dup 3) (match_dup 4))
10282 (parallel
10283 [(set (match_dup 4)
10284 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10285 (ashift:DWIH (match_dup 5)
10286 (minus:QI (match_dup 6) (match_dup 2)))))
10287 (clobber (reg:CC FLAGS_REG))])
10288 (parallel
10289 [(set (match_dup 5)
10290 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10291 (ashift:DWIH (match_dup 3)
10292 (minus:QI (match_dup 6) (match_dup 2)))))
10293 (clobber (reg:CC FLAGS_REG))])]
10294 {
10295 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10296
10297 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10298 })
10299
10300 (define_insn "*bmi2_rorx<mode>3_1"
10301 [(set (match_operand:SWI48 0 "register_operand" "=r")
10302 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10303 (match_operand:QI 2 "immediate_operand" "<S>")))]
10304 "TARGET_BMI2"
10305 "rorx\t{%2, %1, %0|%0, %1, %2}"
10306 [(set_attr "type" "rotatex")
10307 (set_attr "mode" "<MODE>")])
10308
10309 (define_insn "*<rotate_insn><mode>3_1"
10310 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10311 (any_rotate:SWI48
10312 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10313 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10314 (clobber (reg:CC FLAGS_REG))]
10315 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10316 {
10317 switch (get_attr_type (insn))
10318 {
10319 case TYPE_ROTATEX:
10320 return "#";
10321
10322 default:
10323 if (operands[2] == const1_rtx
10324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10325 return "<rotate>{<imodesuffix>}\t%0";
10326 else
10327 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10328 }
10329 }
10330 [(set_attr "isa" "*,bmi2")
10331 (set_attr "type" "rotate,rotatex")
10332 (set (attr "length_immediate")
10333 (if_then_else
10334 (and (eq_attr "type" "rotate")
10335 (and (match_operand 2 "const1_operand")
10336 (ior (match_test "TARGET_SHIFT1")
10337 (match_test "optimize_function_for_size_p (cfun)"))))
10338 (const_string "0")
10339 (const_string "*")))
10340 (set_attr "mode" "<MODE>")])
10341
10342 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10343 (define_split
10344 [(set (match_operand:SWI48 0 "register_operand")
10345 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10346 (match_operand:QI 2 "immediate_operand")))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "TARGET_BMI2 && reload_completed"
10349 [(set (match_dup 0)
10350 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10351 {
10352 operands[2]
10353 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10354 })
10355
10356 (define_split
10357 [(set (match_operand:SWI48 0 "register_operand")
10358 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10359 (match_operand:QI 2 "immediate_operand")))
10360 (clobber (reg:CC FLAGS_REG))]
10361 "TARGET_BMI2 && reload_completed"
10362 [(set (match_dup 0)
10363 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10364
10365 (define_insn "*bmi2_rorxsi3_1_zext"
10366 [(set (match_operand:DI 0 "register_operand" "=r")
10367 (zero_extend:DI
10368 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10369 (match_operand:QI 2 "immediate_operand" "I"))))]
10370 "TARGET_64BIT && TARGET_BMI2"
10371 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10372 [(set_attr "type" "rotatex")
10373 (set_attr "mode" "SI")])
10374
10375 (define_insn "*<rotate_insn>si3_1_zext"
10376 [(set (match_operand:DI 0 "register_operand" "=r,r")
10377 (zero_extend:DI
10378 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10379 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10382 {
10383 switch (get_attr_type (insn))
10384 {
10385 case TYPE_ROTATEX:
10386 return "#";
10387
10388 default:
10389 if (operands[2] == const1_rtx
10390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10391 return "<rotate>{l}\t%k0";
10392 else
10393 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10394 }
10395 }
10396 [(set_attr "isa" "*,bmi2")
10397 (set_attr "type" "rotate,rotatex")
10398 (set (attr "length_immediate")
10399 (if_then_else
10400 (and (eq_attr "type" "rotate")
10401 (and (match_operand 2 "const1_operand")
10402 (ior (match_test "TARGET_SHIFT1")
10403 (match_test "optimize_function_for_size_p (cfun)"))))
10404 (const_string "0")
10405 (const_string "*")))
10406 (set_attr "mode" "SI")])
10407
10408 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10409 (define_split
10410 [(set (match_operand:DI 0 "register_operand")
10411 (zero_extend:DI
10412 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10413 (match_operand:QI 2 "immediate_operand"))))
10414 (clobber (reg:CC FLAGS_REG))]
10415 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10416 [(set (match_dup 0)
10417 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10418 {
10419 operands[2]
10420 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10421 })
10422
10423 (define_split
10424 [(set (match_operand:DI 0 "register_operand")
10425 (zero_extend:DI
10426 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10427 (match_operand:QI 2 "immediate_operand"))))
10428 (clobber (reg:CC FLAGS_REG))]
10429 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10430 [(set (match_dup 0)
10431 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10432
10433 (define_insn "*<rotate_insn><mode>3_1"
10434 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10435 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10436 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10437 (clobber (reg:CC FLAGS_REG))]
10438 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10439 {
10440 if (operands[2] == const1_rtx
10441 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10442 return "<rotate>{<imodesuffix>}\t%0";
10443 else
10444 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10445 }
10446 [(set_attr "type" "rotate")
10447 (set (attr "length_immediate")
10448 (if_then_else
10449 (and (match_operand 2 "const1_operand")
10450 (ior (match_test "TARGET_SHIFT1")
10451 (match_test "optimize_function_for_size_p (cfun)")))
10452 (const_string "0")
10453 (const_string "*")))
10454 (set_attr "mode" "<MODE>")])
10455
10456 (define_insn "*<rotate_insn>qi3_1_slp"
10457 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10458 (any_rotate:QI (match_dup 0)
10459 (match_operand:QI 1 "nonmemory_operand" "cI")))
10460 (clobber (reg:CC FLAGS_REG))]
10461 "(optimize_function_for_size_p (cfun)
10462 || !TARGET_PARTIAL_REG_STALL
10463 || (operands[1] == const1_rtx
10464 && TARGET_SHIFT1))"
10465 {
10466 if (operands[1] == const1_rtx
10467 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10468 return "<rotate>{b}\t%0";
10469 else
10470 return "<rotate>{b}\t{%1, %0|%0, %1}";
10471 }
10472 [(set_attr "type" "rotate1")
10473 (set (attr "length_immediate")
10474 (if_then_else
10475 (and (match_operand 1 "const1_operand")
10476 (ior (match_test "TARGET_SHIFT1")
10477 (match_test "optimize_function_for_size_p (cfun)")))
10478 (const_string "0")
10479 (const_string "*")))
10480 (set_attr "mode" "QI")])
10481
10482 (define_split
10483 [(set (match_operand:HI 0 "register_operand")
10484 (any_rotate:HI (match_dup 0) (const_int 8)))
10485 (clobber (reg:CC FLAGS_REG))]
10486 "reload_completed
10487 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10488 [(parallel [(set (strict_low_part (match_dup 0))
10489 (bswap:HI (match_dup 0)))
10490 (clobber (reg:CC FLAGS_REG))])])
10491 \f
10492 ;; Bit set / bit test instructions
10493
10494 (define_expand "extv"
10495 [(set (match_operand:SI 0 "register_operand")
10496 (sign_extract:SI (match_operand:SI 1 "register_operand")
10497 (match_operand:SI 2 "const8_operand")
10498 (match_operand:SI 3 "const8_operand")))]
10499 ""
10500 {
10501 /* Handle extractions from %ah et al. */
10502 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10503 FAIL;
10504
10505 /* From mips.md: extract_bit_field doesn't verify that our source
10506 matches the predicate, so check it again here. */
10507 if (! ext_register_operand (operands[1], VOIDmode))
10508 FAIL;
10509 })
10510
10511 (define_expand "extzv"
10512 [(set (match_operand:SI 0 "register_operand")
10513 (zero_extract:SI (match_operand 1 "ext_register_operand")
10514 (match_operand:SI 2 "const8_operand")
10515 (match_operand:SI 3 "const8_operand")))]
10516 ""
10517 {
10518 /* Handle extractions from %ah et al. */
10519 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10520 FAIL;
10521
10522 /* From mips.md: extract_bit_field doesn't verify that our source
10523 matches the predicate, so check it again here. */
10524 if (! ext_register_operand (operands[1], VOIDmode))
10525 FAIL;
10526 })
10527
10528 (define_expand "insv"
10529 [(set (zero_extract (match_operand 0 "register_operand")
10530 (match_operand 1 "const_int_operand")
10531 (match_operand 2 "const_int_operand"))
10532 (match_operand 3 "register_operand"))]
10533 ""
10534 {
10535 rtx (*gen_mov_insv_1) (rtx, rtx);
10536
10537 if (ix86_expand_pinsr (operands))
10538 DONE;
10539
10540 /* Handle insertions to %ah et al. */
10541 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10542 FAIL;
10543
10544 /* From mips.md: insert_bit_field doesn't verify that our source
10545 matches the predicate, so check it again here. */
10546 if (! ext_register_operand (operands[0], VOIDmode))
10547 FAIL;
10548
10549 gen_mov_insv_1 = (TARGET_64BIT
10550 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10551
10552 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10553 DONE;
10554 })
10555
10556 ;; %%% bts, btr, btc, bt.
10557 ;; In general these instructions are *slow* when applied to memory,
10558 ;; since they enforce atomic operation. When applied to registers,
10559 ;; it depends on the cpu implementation. They're never faster than
10560 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10561 ;; no point. But in 64-bit, we can't hold the relevant immediates
10562 ;; within the instruction itself, so operating on bits in the high
10563 ;; 32-bits of a register becomes easier.
10564 ;;
10565 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10566 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10567 ;; negdf respectively, so they can never be disabled entirely.
10568
10569 (define_insn "*btsq"
10570 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10571 (const_int 1)
10572 (match_operand:DI 1 "const_0_to_63_operand"))
10573 (const_int 1))
10574 (clobber (reg:CC FLAGS_REG))]
10575 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10576 "bts{q}\t{%1, %0|%0, %1}"
10577 [(set_attr "type" "alu1")
10578 (set_attr "prefix_0f" "1")
10579 (set_attr "mode" "DI")])
10580
10581 (define_insn "*btrq"
10582 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10583 (const_int 1)
10584 (match_operand:DI 1 "const_0_to_63_operand"))
10585 (const_int 0))
10586 (clobber (reg:CC FLAGS_REG))]
10587 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10588 "btr{q}\t{%1, %0|%0, %1}"
10589 [(set_attr "type" "alu1")
10590 (set_attr "prefix_0f" "1")
10591 (set_attr "mode" "DI")])
10592
10593 (define_insn "*btcq"
10594 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10595 (const_int 1)
10596 (match_operand:DI 1 "const_0_to_63_operand"))
10597 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10598 (clobber (reg:CC FLAGS_REG))]
10599 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10600 "btc{q}\t{%1, %0|%0, %1}"
10601 [(set_attr "type" "alu1")
10602 (set_attr "prefix_0f" "1")
10603 (set_attr "mode" "DI")])
10604
10605 ;; Allow Nocona to avoid these instructions if a register is available.
10606
10607 (define_peephole2
10608 [(match_scratch:DI 2 "r")
10609 (parallel [(set (zero_extract:DI
10610 (match_operand:DI 0 "register_operand")
10611 (const_int 1)
10612 (match_operand:DI 1 "const_0_to_63_operand"))
10613 (const_int 1))
10614 (clobber (reg:CC FLAGS_REG))])]
10615 "TARGET_64BIT && !TARGET_USE_BT"
10616 [(const_int 0)]
10617 {
10618 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10619 rtx op1;
10620
10621 if (HOST_BITS_PER_WIDE_INT >= 64)
10622 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10623 else if (i < HOST_BITS_PER_WIDE_INT)
10624 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10625 else
10626 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10627
10628 op1 = immed_double_const (lo, hi, DImode);
10629 if (i >= 31)
10630 {
10631 emit_move_insn (operands[2], op1);
10632 op1 = operands[2];
10633 }
10634
10635 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10636 DONE;
10637 })
10638
10639 (define_peephole2
10640 [(match_scratch:DI 2 "r")
10641 (parallel [(set (zero_extract:DI
10642 (match_operand:DI 0 "register_operand")
10643 (const_int 1)
10644 (match_operand:DI 1 "const_0_to_63_operand"))
10645 (const_int 0))
10646 (clobber (reg:CC FLAGS_REG))])]
10647 "TARGET_64BIT && !TARGET_USE_BT"
10648 [(const_int 0)]
10649 {
10650 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10651 rtx op1;
10652
10653 if (HOST_BITS_PER_WIDE_INT >= 64)
10654 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10655 else if (i < HOST_BITS_PER_WIDE_INT)
10656 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10657 else
10658 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10659
10660 op1 = immed_double_const (~lo, ~hi, DImode);
10661 if (i >= 32)
10662 {
10663 emit_move_insn (operands[2], op1);
10664 op1 = operands[2];
10665 }
10666
10667 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10668 DONE;
10669 })
10670
10671 (define_peephole2
10672 [(match_scratch:DI 2 "r")
10673 (parallel [(set (zero_extract:DI
10674 (match_operand:DI 0 "register_operand")
10675 (const_int 1)
10676 (match_operand:DI 1 "const_0_to_63_operand"))
10677 (not:DI (zero_extract:DI
10678 (match_dup 0) (const_int 1) (match_dup 1))))
10679 (clobber (reg:CC FLAGS_REG))])]
10680 "TARGET_64BIT && !TARGET_USE_BT"
10681 [(const_int 0)]
10682 {
10683 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10684 rtx op1;
10685
10686 if (HOST_BITS_PER_WIDE_INT >= 64)
10687 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10688 else if (i < HOST_BITS_PER_WIDE_INT)
10689 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10690 else
10691 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10692
10693 op1 = immed_double_const (lo, hi, DImode);
10694 if (i >= 31)
10695 {
10696 emit_move_insn (operands[2], op1);
10697 op1 = operands[2];
10698 }
10699
10700 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10701 DONE;
10702 })
10703
10704 (define_insn "*bt<mode>"
10705 [(set (reg:CCC FLAGS_REG)
10706 (compare:CCC
10707 (zero_extract:SWI48
10708 (match_operand:SWI48 0 "register_operand" "r")
10709 (const_int 1)
10710 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10711 (const_int 0)))]
10712 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10713 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10714 [(set_attr "type" "alu1")
10715 (set_attr "prefix_0f" "1")
10716 (set_attr "mode" "<MODE>")])
10717 \f
10718 ;; Store-flag instructions.
10719
10720 ;; For all sCOND expanders, also expand the compare or test insn that
10721 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10722
10723 (define_insn_and_split "*setcc_di_1"
10724 [(set (match_operand:DI 0 "register_operand" "=q")
10725 (match_operator:DI 1 "ix86_comparison_operator"
10726 [(reg FLAGS_REG) (const_int 0)]))]
10727 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10728 "#"
10729 "&& reload_completed"
10730 [(set (match_dup 2) (match_dup 1))
10731 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10732 {
10733 PUT_MODE (operands[1], QImode);
10734 operands[2] = gen_lowpart (QImode, operands[0]);
10735 })
10736
10737 (define_insn_and_split "*setcc_si_1_and"
10738 [(set (match_operand:SI 0 "register_operand" "=q")
10739 (match_operator:SI 1 "ix86_comparison_operator"
10740 [(reg FLAGS_REG) (const_int 0)]))
10741 (clobber (reg:CC FLAGS_REG))]
10742 "!TARGET_PARTIAL_REG_STALL
10743 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10744 "#"
10745 "&& reload_completed"
10746 [(set (match_dup 2) (match_dup 1))
10747 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10748 (clobber (reg:CC FLAGS_REG))])]
10749 {
10750 PUT_MODE (operands[1], QImode);
10751 operands[2] = gen_lowpart (QImode, operands[0]);
10752 })
10753
10754 (define_insn_and_split "*setcc_si_1_movzbl"
10755 [(set (match_operand:SI 0 "register_operand" "=q")
10756 (match_operator:SI 1 "ix86_comparison_operator"
10757 [(reg FLAGS_REG) (const_int 0)]))]
10758 "!TARGET_PARTIAL_REG_STALL
10759 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10760 "#"
10761 "&& reload_completed"
10762 [(set (match_dup 2) (match_dup 1))
10763 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10764 {
10765 PUT_MODE (operands[1], QImode);
10766 operands[2] = gen_lowpart (QImode, operands[0]);
10767 })
10768
10769 (define_insn "*setcc_qi"
10770 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10771 (match_operator:QI 1 "ix86_comparison_operator"
10772 [(reg FLAGS_REG) (const_int 0)]))]
10773 ""
10774 "set%C1\t%0"
10775 [(set_attr "type" "setcc")
10776 (set_attr "mode" "QI")])
10777
10778 (define_insn "*setcc_qi_slp"
10779 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10780 (match_operator:QI 1 "ix86_comparison_operator"
10781 [(reg FLAGS_REG) (const_int 0)]))]
10782 ""
10783 "set%C1\t%0"
10784 [(set_attr "type" "setcc")
10785 (set_attr "mode" "QI")])
10786
10787 ;; In general it is not safe to assume too much about CCmode registers,
10788 ;; so simplify-rtx stops when it sees a second one. Under certain
10789 ;; conditions this is safe on x86, so help combine not create
10790 ;;
10791 ;; seta %al
10792 ;; testb %al, %al
10793 ;; sete %al
10794
10795 (define_split
10796 [(set (match_operand:QI 0 "nonimmediate_operand")
10797 (ne:QI (match_operator 1 "ix86_comparison_operator"
10798 [(reg FLAGS_REG) (const_int 0)])
10799 (const_int 0)))]
10800 ""
10801 [(set (match_dup 0) (match_dup 1))]
10802 "PUT_MODE (operands[1], QImode);")
10803
10804 (define_split
10805 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10806 (ne:QI (match_operator 1 "ix86_comparison_operator"
10807 [(reg FLAGS_REG) (const_int 0)])
10808 (const_int 0)))]
10809 ""
10810 [(set (match_dup 0) (match_dup 1))]
10811 "PUT_MODE (operands[1], QImode);")
10812
10813 (define_split
10814 [(set (match_operand:QI 0 "nonimmediate_operand")
10815 (eq:QI (match_operator 1 "ix86_comparison_operator"
10816 [(reg FLAGS_REG) (const_int 0)])
10817 (const_int 0)))]
10818 ""
10819 [(set (match_dup 0) (match_dup 1))]
10820 {
10821 rtx new_op1 = copy_rtx (operands[1]);
10822 operands[1] = new_op1;
10823 PUT_MODE (new_op1, QImode);
10824 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10825 GET_MODE (XEXP (new_op1, 0))));
10826
10827 /* Make sure that (a) the CCmode we have for the flags is strong
10828 enough for the reversed compare or (b) we have a valid FP compare. */
10829 if (! ix86_comparison_operator (new_op1, VOIDmode))
10830 FAIL;
10831 })
10832
10833 (define_split
10834 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10835 (eq:QI (match_operator 1 "ix86_comparison_operator"
10836 [(reg FLAGS_REG) (const_int 0)])
10837 (const_int 0)))]
10838 ""
10839 [(set (match_dup 0) (match_dup 1))]
10840 {
10841 rtx new_op1 = copy_rtx (operands[1]);
10842 operands[1] = new_op1;
10843 PUT_MODE (new_op1, QImode);
10844 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10845 GET_MODE (XEXP (new_op1, 0))));
10846
10847 /* Make sure that (a) the CCmode we have for the flags is strong
10848 enough for the reversed compare or (b) we have a valid FP compare. */
10849 if (! ix86_comparison_operator (new_op1, VOIDmode))
10850 FAIL;
10851 })
10852
10853 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10854 ;; subsequent logical operations are used to imitate conditional moves.
10855 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10856 ;; it directly.
10857
10858 (define_insn "setcc_<mode>_sse"
10859 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10860 (match_operator:MODEF 3 "sse_comparison_operator"
10861 [(match_operand:MODEF 1 "register_operand" "0,x")
10862 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10863 "SSE_FLOAT_MODE_P (<MODE>mode)"
10864 "@
10865 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10866 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10867 [(set_attr "isa" "noavx,avx")
10868 (set_attr "type" "ssecmp")
10869 (set_attr "length_immediate" "1")
10870 (set_attr "prefix" "orig,vex")
10871 (set_attr "mode" "<MODE>")])
10872 \f
10873 ;; Basic conditional jump instructions.
10874 ;; We ignore the overflow flag for signed branch instructions.
10875
10876 (define_insn "*jcc_1"
10877 [(set (pc)
10878 (if_then_else (match_operator 1 "ix86_comparison_operator"
10879 [(reg FLAGS_REG) (const_int 0)])
10880 (label_ref (match_operand 0))
10881 (pc)))]
10882 ""
10883 "%+j%C1\t%l0"
10884 [(set_attr "type" "ibr")
10885 (set_attr "modrm" "0")
10886 (set (attr "length")
10887 (if_then_else (and (ge (minus (match_dup 0) (pc))
10888 (const_int -126))
10889 (lt (minus (match_dup 0) (pc))
10890 (const_int 128)))
10891 (const_int 2)
10892 (const_int 6)))])
10893
10894 (define_insn "*jcc_2"
10895 [(set (pc)
10896 (if_then_else (match_operator 1 "ix86_comparison_operator"
10897 [(reg FLAGS_REG) (const_int 0)])
10898 (pc)
10899 (label_ref (match_operand 0))))]
10900 ""
10901 "%+j%c1\t%l0"
10902 [(set_attr "type" "ibr")
10903 (set_attr "modrm" "0")
10904 (set (attr "length")
10905 (if_then_else (and (ge (minus (match_dup 0) (pc))
10906 (const_int -126))
10907 (lt (minus (match_dup 0) (pc))
10908 (const_int 128)))
10909 (const_int 2)
10910 (const_int 6)))])
10911
10912 ;; In general it is not safe to assume too much about CCmode registers,
10913 ;; so simplify-rtx stops when it sees a second one. Under certain
10914 ;; conditions this is safe on x86, so help combine not create
10915 ;;
10916 ;; seta %al
10917 ;; testb %al, %al
10918 ;; je Lfoo
10919
10920 (define_split
10921 [(set (pc)
10922 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10923 [(reg FLAGS_REG) (const_int 0)])
10924 (const_int 0))
10925 (label_ref (match_operand 1))
10926 (pc)))]
10927 ""
10928 [(set (pc)
10929 (if_then_else (match_dup 0)
10930 (label_ref (match_dup 1))
10931 (pc)))]
10932 "PUT_MODE (operands[0], VOIDmode);")
10933
10934 (define_split
10935 [(set (pc)
10936 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10937 [(reg FLAGS_REG) (const_int 0)])
10938 (const_int 0))
10939 (label_ref (match_operand 1))
10940 (pc)))]
10941 ""
10942 [(set (pc)
10943 (if_then_else (match_dup 0)
10944 (label_ref (match_dup 1))
10945 (pc)))]
10946 {
10947 rtx new_op0 = copy_rtx (operands[0]);
10948 operands[0] = new_op0;
10949 PUT_MODE (new_op0, VOIDmode);
10950 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10951 GET_MODE (XEXP (new_op0, 0))));
10952
10953 /* Make sure that (a) the CCmode we have for the flags is strong
10954 enough for the reversed compare or (b) we have a valid FP compare. */
10955 if (! ix86_comparison_operator (new_op0, VOIDmode))
10956 FAIL;
10957 })
10958
10959 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10960 ;; pass generates from shift insn with QImode operand. Actually, the mode
10961 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10962 ;; appropriate modulo of the bit offset value.
10963
10964 (define_insn_and_split "*jcc_bt<mode>"
10965 [(set (pc)
10966 (if_then_else (match_operator 0 "bt_comparison_operator"
10967 [(zero_extract:SWI48
10968 (match_operand:SWI48 1 "register_operand" "r")
10969 (const_int 1)
10970 (zero_extend:SI
10971 (match_operand:QI 2 "register_operand" "r")))
10972 (const_int 0)])
10973 (label_ref (match_operand 3))
10974 (pc)))
10975 (clobber (reg:CC FLAGS_REG))]
10976 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10977 "#"
10978 "&& 1"
10979 [(set (reg:CCC FLAGS_REG)
10980 (compare:CCC
10981 (zero_extract:SWI48
10982 (match_dup 1)
10983 (const_int 1)
10984 (match_dup 2))
10985 (const_int 0)))
10986 (set (pc)
10987 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10988 (label_ref (match_dup 3))
10989 (pc)))]
10990 {
10991 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10992
10993 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10994 })
10995
10996 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10997 ;; also for DImode, this is what combine produces.
10998 (define_insn_and_split "*jcc_bt<mode>_mask"
10999 [(set (pc)
11000 (if_then_else (match_operator 0 "bt_comparison_operator"
11001 [(zero_extract:SWI48
11002 (match_operand:SWI48 1 "register_operand" "r")
11003 (const_int 1)
11004 (and:SI
11005 (match_operand:SI 2 "register_operand" "r")
11006 (match_operand:SI 3 "const_int_operand" "n")))])
11007 (label_ref (match_operand 4))
11008 (pc)))
11009 (clobber (reg:CC FLAGS_REG))]
11010 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11011 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11012 == GET_MODE_BITSIZE (<MODE>mode)-1"
11013 "#"
11014 "&& 1"
11015 [(set (reg:CCC FLAGS_REG)
11016 (compare:CCC
11017 (zero_extract:SWI48
11018 (match_dup 1)
11019 (const_int 1)
11020 (match_dup 2))
11021 (const_int 0)))
11022 (set (pc)
11023 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11024 (label_ref (match_dup 4))
11025 (pc)))]
11026 {
11027 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11028
11029 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11030 })
11031
11032 (define_insn_and_split "*jcc_btsi_1"
11033 [(set (pc)
11034 (if_then_else (match_operator 0 "bt_comparison_operator"
11035 [(and:SI
11036 (lshiftrt:SI
11037 (match_operand:SI 1 "register_operand" "r")
11038 (match_operand:QI 2 "register_operand" "r"))
11039 (const_int 1))
11040 (const_int 0)])
11041 (label_ref (match_operand 3))
11042 (pc)))
11043 (clobber (reg:CC FLAGS_REG))]
11044 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11045 "#"
11046 "&& 1"
11047 [(set (reg:CCC FLAGS_REG)
11048 (compare:CCC
11049 (zero_extract:SI
11050 (match_dup 1)
11051 (const_int 1)
11052 (match_dup 2))
11053 (const_int 0)))
11054 (set (pc)
11055 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11056 (label_ref (match_dup 3))
11057 (pc)))]
11058 {
11059 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11060
11061 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11062 })
11063
11064 ;; avoid useless masking of bit offset operand
11065 (define_insn_and_split "*jcc_btsi_mask_1"
11066 [(set (pc)
11067 (if_then_else
11068 (match_operator 0 "bt_comparison_operator"
11069 [(and:SI
11070 (lshiftrt:SI
11071 (match_operand:SI 1 "register_operand" "r")
11072 (subreg:QI
11073 (and:SI
11074 (match_operand:SI 2 "register_operand" "r")
11075 (match_operand:SI 3 "const_int_operand" "n")) 0))
11076 (const_int 1))
11077 (const_int 0)])
11078 (label_ref (match_operand 4))
11079 (pc)))
11080 (clobber (reg:CC FLAGS_REG))]
11081 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11082 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11083 "#"
11084 "&& 1"
11085 [(set (reg:CCC FLAGS_REG)
11086 (compare:CCC
11087 (zero_extract:SI
11088 (match_dup 1)
11089 (const_int 1)
11090 (match_dup 2))
11091 (const_int 0)))
11092 (set (pc)
11093 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11094 (label_ref (match_dup 4))
11095 (pc)))]
11096 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11097
11098 ;; Define combination compare-and-branch fp compare instructions to help
11099 ;; combine.
11100
11101 (define_insn "*fp_jcc_1_387"
11102 [(set (pc)
11103 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11104 [(match_operand 1 "register_operand" "f")
11105 (match_operand 2 "nonimmediate_operand" "fm")])
11106 (label_ref (match_operand 3))
11107 (pc)))
11108 (clobber (reg:CCFP FPSR_REG))
11109 (clobber (reg:CCFP FLAGS_REG))
11110 (clobber (match_scratch:HI 4 "=a"))]
11111 "TARGET_80387
11112 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11113 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11114 && SELECT_CC_MODE (GET_CODE (operands[0]),
11115 operands[1], operands[2]) == CCFPmode
11116 && !TARGET_CMOVE"
11117 "#")
11118
11119 (define_insn "*fp_jcc_1r_387"
11120 [(set (pc)
11121 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11122 [(match_operand 1 "register_operand" "f")
11123 (match_operand 2 "nonimmediate_operand" "fm")])
11124 (pc)
11125 (label_ref (match_operand 3))))
11126 (clobber (reg:CCFP FPSR_REG))
11127 (clobber (reg:CCFP FLAGS_REG))
11128 (clobber (match_scratch:HI 4 "=a"))]
11129 "TARGET_80387
11130 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11131 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11132 && SELECT_CC_MODE (GET_CODE (operands[0]),
11133 operands[1], operands[2]) == CCFPmode
11134 && !TARGET_CMOVE"
11135 "#")
11136
11137 (define_insn "*fp_jcc_2_387"
11138 [(set (pc)
11139 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11140 [(match_operand 1 "register_operand" "f")
11141 (match_operand 2 "register_operand" "f")])
11142 (label_ref (match_operand 3))
11143 (pc)))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))
11146 (clobber (match_scratch:HI 4 "=a"))]
11147 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11148 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11149 && !TARGET_CMOVE"
11150 "#")
11151
11152 (define_insn "*fp_jcc_2r_387"
11153 [(set (pc)
11154 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11155 [(match_operand 1 "register_operand" "f")
11156 (match_operand 2 "register_operand" "f")])
11157 (pc)
11158 (label_ref (match_operand 3))))
11159 (clobber (reg:CCFP FPSR_REG))
11160 (clobber (reg:CCFP FLAGS_REG))
11161 (clobber (match_scratch:HI 4 "=a"))]
11162 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11163 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11164 && !TARGET_CMOVE"
11165 "#")
11166
11167 (define_insn "*fp_jcc_3_387"
11168 [(set (pc)
11169 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11170 [(match_operand 1 "register_operand" "f")
11171 (match_operand 2 "const0_operand")])
11172 (label_ref (match_operand 3))
11173 (pc)))
11174 (clobber (reg:CCFP FPSR_REG))
11175 (clobber (reg:CCFP FLAGS_REG))
11176 (clobber (match_scratch:HI 4 "=a"))]
11177 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11178 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11179 && SELECT_CC_MODE (GET_CODE (operands[0]),
11180 operands[1], operands[2]) == CCFPmode
11181 && !TARGET_CMOVE"
11182 "#")
11183
11184 (define_split
11185 [(set (pc)
11186 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11187 [(match_operand 1 "register_operand")
11188 (match_operand 2 "nonimmediate_operand")])
11189 (match_operand 3)
11190 (match_operand 4)))
11191 (clobber (reg:CCFP FPSR_REG))
11192 (clobber (reg:CCFP FLAGS_REG))]
11193 "reload_completed"
11194 [(const_int 0)]
11195 {
11196 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11197 operands[3], operands[4], NULL_RTX, NULL_RTX);
11198 DONE;
11199 })
11200
11201 (define_split
11202 [(set (pc)
11203 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11204 [(match_operand 1 "register_operand")
11205 (match_operand 2 "general_operand")])
11206 (match_operand 3)
11207 (match_operand 4)))
11208 (clobber (reg:CCFP FPSR_REG))
11209 (clobber (reg:CCFP FLAGS_REG))
11210 (clobber (match_scratch:HI 5 "=a"))]
11211 "reload_completed"
11212 [(const_int 0)]
11213 {
11214 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11215 operands[3], operands[4], operands[5], NULL_RTX);
11216 DONE;
11217 })
11218
11219 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11220 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11221 ;; with a precedence over other operators and is always put in the first
11222 ;; place. Swap condition and operands to match ficom instruction.
11223
11224 (define_insn "*fp_jcc_4_<mode>_387"
11225 [(set (pc)
11226 (if_then_else
11227 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11228 [(match_operator 1 "float_operator"
11229 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11230 (match_operand 3 "register_operand" "f,f")])
11231 (label_ref (match_operand 4))
11232 (pc)))
11233 (clobber (reg:CCFP FPSR_REG))
11234 (clobber (reg:CCFP FLAGS_REG))
11235 (clobber (match_scratch:HI 5 "=a,a"))]
11236 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11237 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11238 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11239 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11240 && !TARGET_CMOVE"
11241 "#")
11242
11243 (define_split
11244 [(set (pc)
11245 (if_then_else
11246 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11247 [(match_operator 1 "float_operator"
11248 [(match_operand:SWI24 2 "memory_operand")])
11249 (match_operand 3 "register_operand")])
11250 (match_operand 4)
11251 (match_operand 5)))
11252 (clobber (reg:CCFP FPSR_REG))
11253 (clobber (reg:CCFP FLAGS_REG))
11254 (clobber (match_scratch:HI 6 "=a"))]
11255 "reload_completed"
11256 [(const_int 0)]
11257 {
11258 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11259
11260 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11261 operands[3], operands[7],
11262 operands[4], operands[5], operands[6], NULL_RTX);
11263 DONE;
11264 })
11265
11266 ;; %%% Kill this when reload knows how to do it.
11267 (define_split
11268 [(set (pc)
11269 (if_then_else
11270 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11271 [(match_operator 1 "float_operator"
11272 [(match_operand:SWI24 2 "register_operand")])
11273 (match_operand 3 "register_operand")])
11274 (match_operand 4)
11275 (match_operand 5)))
11276 (clobber (reg:CCFP FPSR_REG))
11277 (clobber (reg:CCFP FLAGS_REG))
11278 (clobber (match_scratch:HI 6 "=a"))]
11279 "reload_completed"
11280 [(const_int 0)]
11281 {
11282 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11283 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11284
11285 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11286 operands[3], operands[7],
11287 operands[4], operands[5], operands[6], operands[2]);
11288 DONE;
11289 })
11290 \f
11291 ;; Unconditional and other jump instructions
11292
11293 (define_insn "jump"
11294 [(set (pc)
11295 (label_ref (match_operand 0)))]
11296 ""
11297 "jmp\t%l0"
11298 [(set_attr "type" "ibr")
11299 (set (attr "length")
11300 (if_then_else (and (ge (minus (match_dup 0) (pc))
11301 (const_int -126))
11302 (lt (minus (match_dup 0) (pc))
11303 (const_int 128)))
11304 (const_int 2)
11305 (const_int 5)))
11306 (set_attr "modrm" "0")])
11307
11308 (define_expand "indirect_jump"
11309 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11310 ""
11311 {
11312 if (TARGET_X32)
11313 operands[0] = convert_memory_address (word_mode, operands[0]);
11314 })
11315
11316 (define_insn "*indirect_jump"
11317 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11318 ""
11319 "jmp\t%A0"
11320 [(set_attr "type" "ibr")
11321 (set_attr "length_immediate" "0")])
11322
11323 (define_expand "tablejump"
11324 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11325 (use (label_ref (match_operand 1)))])]
11326 ""
11327 {
11328 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11329 relative. Convert the relative address to an absolute address. */
11330 if (flag_pic)
11331 {
11332 rtx op0, op1;
11333 enum rtx_code code;
11334
11335 /* We can't use @GOTOFF for text labels on VxWorks;
11336 see gotoff_operand. */
11337 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11338 {
11339 code = PLUS;
11340 op0 = operands[0];
11341 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11342 }
11343 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11344 {
11345 code = PLUS;
11346 op0 = operands[0];
11347 op1 = pic_offset_table_rtx;
11348 }
11349 else
11350 {
11351 code = MINUS;
11352 op0 = pic_offset_table_rtx;
11353 op1 = operands[0];
11354 }
11355
11356 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11357 OPTAB_DIRECT);
11358 }
11359
11360 if (TARGET_X32)
11361 operands[0] = convert_memory_address (word_mode, operands[0]);
11362 })
11363
11364 (define_insn "*tablejump_1"
11365 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11366 (use (label_ref (match_operand 1)))]
11367 ""
11368 "jmp\t%A0"
11369 [(set_attr "type" "ibr")
11370 (set_attr "length_immediate" "0")])
11371 \f
11372 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11373
11374 (define_peephole2
11375 [(set (reg FLAGS_REG) (match_operand 0))
11376 (set (match_operand:QI 1 "register_operand")
11377 (match_operator:QI 2 "ix86_comparison_operator"
11378 [(reg FLAGS_REG) (const_int 0)]))
11379 (set (match_operand 3 "q_regs_operand")
11380 (zero_extend (match_dup 1)))]
11381 "(peep2_reg_dead_p (3, operands[1])
11382 || operands_match_p (operands[1], operands[3]))
11383 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11384 [(set (match_dup 4) (match_dup 0))
11385 (set (strict_low_part (match_dup 5))
11386 (match_dup 2))]
11387 {
11388 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11389 operands[5] = gen_lowpart (QImode, operands[3]);
11390 ix86_expand_clear (operands[3]);
11391 })
11392
11393 (define_peephole2
11394 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11395 (match_operand 4)])
11396 (set (match_operand:QI 1 "register_operand")
11397 (match_operator:QI 2 "ix86_comparison_operator"
11398 [(reg FLAGS_REG) (const_int 0)]))
11399 (set (match_operand 3 "q_regs_operand")
11400 (zero_extend (match_dup 1)))]
11401 "(peep2_reg_dead_p (3, operands[1])
11402 || operands_match_p (operands[1], operands[3]))
11403 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11404 [(parallel [(set (match_dup 5) (match_dup 0))
11405 (match_dup 4)])
11406 (set (strict_low_part (match_dup 6))
11407 (match_dup 2))]
11408 {
11409 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11410 operands[6] = gen_lowpart (QImode, operands[3]);
11411 ix86_expand_clear (operands[3]);
11412 })
11413
11414 ;; Similar, but match zero extend with andsi3.
11415
11416 (define_peephole2
11417 [(set (reg FLAGS_REG) (match_operand 0))
11418 (set (match_operand:QI 1 "register_operand")
11419 (match_operator:QI 2 "ix86_comparison_operator"
11420 [(reg FLAGS_REG) (const_int 0)]))
11421 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11422 (and:SI (match_dup 3) (const_int 255)))
11423 (clobber (reg:CC FLAGS_REG))])]
11424 "REGNO (operands[1]) == REGNO (operands[3])
11425 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11426 [(set (match_dup 4) (match_dup 0))
11427 (set (strict_low_part (match_dup 5))
11428 (match_dup 2))]
11429 {
11430 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11431 operands[5] = gen_lowpart (QImode, operands[3]);
11432 ix86_expand_clear (operands[3]);
11433 })
11434
11435 (define_peephole2
11436 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11437 (match_operand 4)])
11438 (set (match_operand:QI 1 "register_operand")
11439 (match_operator:QI 2 "ix86_comparison_operator"
11440 [(reg FLAGS_REG) (const_int 0)]))
11441 (parallel [(set (match_operand 3 "q_regs_operand")
11442 (zero_extend (match_dup 1)))
11443 (clobber (reg:CC FLAGS_REG))])]
11444 "(peep2_reg_dead_p (3, operands[1])
11445 || operands_match_p (operands[1], operands[3]))
11446 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11447 [(parallel [(set (match_dup 5) (match_dup 0))
11448 (match_dup 4)])
11449 (set (strict_low_part (match_dup 6))
11450 (match_dup 2))]
11451 {
11452 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11453 operands[6] = gen_lowpart (QImode, operands[3]);
11454 ix86_expand_clear (operands[3]);
11455 })
11456 \f
11457 ;; Call instructions.
11458
11459 ;; The predicates normally associated with named expanders are not properly
11460 ;; checked for calls. This is a bug in the generic code, but it isn't that
11461 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11462
11463 ;; P6 processors will jump to the address after the decrement when %esp
11464 ;; is used as a call operand, so they will execute return address as a code.
11465 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11466
11467 ;; Register constraint for call instruction.
11468 (define_mode_attr c [(SI "l") (DI "r")])
11469
11470 ;; Call subroutine returning no value.
11471
11472 (define_expand "call"
11473 [(call (match_operand:QI 0)
11474 (match_operand 1))
11475 (use (match_operand 2))]
11476 ""
11477 {
11478 ix86_expand_call (NULL, operands[0], operands[1],
11479 operands[2], NULL, false);
11480 DONE;
11481 })
11482
11483 (define_expand "sibcall"
11484 [(call (match_operand:QI 0)
11485 (match_operand 1))
11486 (use (match_operand 2))]
11487 ""
11488 {
11489 ix86_expand_call (NULL, operands[0], operands[1],
11490 operands[2], NULL, true);
11491 DONE;
11492 })
11493
11494 (define_insn_and_split "*call_vzeroupper"
11495 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11496 (match_operand 1))
11497 (unspec [(match_operand 2 "const_int_operand")]
11498 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11499 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11500 "#"
11501 "&& reload_completed"
11502 [(const_int 0)]
11503 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11504 [(set_attr "type" "call")])
11505
11506 (define_insn "*call"
11507 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11508 (match_operand 1))]
11509 "!SIBLING_CALL_P (insn)"
11510 "* return ix86_output_call_insn (insn, operands[0]);"
11511 [(set_attr "type" "call")])
11512
11513 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11514 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11515 (match_operand 1))
11516 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11517 (clobber (reg:TI XMM6_REG))
11518 (clobber (reg:TI XMM7_REG))
11519 (clobber (reg:TI XMM8_REG))
11520 (clobber (reg:TI XMM9_REG))
11521 (clobber (reg:TI XMM10_REG))
11522 (clobber (reg:TI XMM11_REG))
11523 (clobber (reg:TI XMM12_REG))
11524 (clobber (reg:TI XMM13_REG))
11525 (clobber (reg:TI XMM14_REG))
11526 (clobber (reg:TI XMM15_REG))
11527 (clobber (reg:DI SI_REG))
11528 (clobber (reg:DI DI_REG))
11529 (unspec [(match_operand 2 "const_int_operand")]
11530 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11531 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11532 "#"
11533 "&& reload_completed"
11534 [(const_int 0)]
11535 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11536 [(set_attr "type" "call")])
11537
11538 (define_insn "*call_rex64_ms_sysv"
11539 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11540 (match_operand 1))
11541 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11542 (clobber (reg:TI XMM6_REG))
11543 (clobber (reg:TI XMM7_REG))
11544 (clobber (reg:TI XMM8_REG))
11545 (clobber (reg:TI XMM9_REG))
11546 (clobber (reg:TI XMM10_REG))
11547 (clobber (reg:TI XMM11_REG))
11548 (clobber (reg:TI XMM12_REG))
11549 (clobber (reg:TI XMM13_REG))
11550 (clobber (reg:TI XMM14_REG))
11551 (clobber (reg:TI XMM15_REG))
11552 (clobber (reg:DI SI_REG))
11553 (clobber (reg:DI DI_REG))]
11554 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11555 "* return ix86_output_call_insn (insn, operands[0]);"
11556 [(set_attr "type" "call")])
11557
11558 (define_insn_and_split "*sibcall_vzeroupper"
11559 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11560 (match_operand 1))
11561 (unspec [(match_operand 2 "const_int_operand")]
11562 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11563 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11564 "#"
11565 "&& reload_completed"
11566 [(const_int 0)]
11567 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11568 [(set_attr "type" "call")])
11569
11570 (define_insn "*sibcall"
11571 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11572 (match_operand 1))]
11573 "SIBLING_CALL_P (insn)"
11574 "* return ix86_output_call_insn (insn, operands[0]);"
11575 [(set_attr "type" "call")])
11576
11577 (define_expand "call_pop"
11578 [(parallel [(call (match_operand:QI 0)
11579 (match_operand:SI 1))
11580 (set (reg:SI SP_REG)
11581 (plus:SI (reg:SI SP_REG)
11582 (match_operand:SI 3)))])]
11583 "!TARGET_64BIT"
11584 {
11585 ix86_expand_call (NULL, operands[0], operands[1],
11586 operands[2], operands[3], false);
11587 DONE;
11588 })
11589
11590 (define_insn_and_split "*call_pop_vzeroupper"
11591 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11592 (match_operand 1))
11593 (set (reg:SI SP_REG)
11594 (plus:SI (reg:SI SP_REG)
11595 (match_operand:SI 2 "immediate_operand" "i")))
11596 (unspec [(match_operand 3 "const_int_operand")]
11597 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11598 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11599 "#"
11600 "&& reload_completed"
11601 [(const_int 0)]
11602 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11603 [(set_attr "type" "call")])
11604
11605 (define_insn "*call_pop"
11606 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11607 (match_operand 1))
11608 (set (reg:SI SP_REG)
11609 (plus:SI (reg:SI SP_REG)
11610 (match_operand:SI 2 "immediate_operand" "i")))]
11611 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11612 "* return ix86_output_call_insn (insn, operands[0]);"
11613 [(set_attr "type" "call")])
11614
11615 (define_insn_and_split "*sibcall_pop_vzeroupper"
11616 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11617 (match_operand 1))
11618 (set (reg:SI SP_REG)
11619 (plus:SI (reg:SI SP_REG)
11620 (match_operand:SI 2 "immediate_operand" "i")))
11621 (unspec [(match_operand 3 "const_int_operand")]
11622 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11623 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11624 "#"
11625 "&& reload_completed"
11626 [(const_int 0)]
11627 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11628 [(set_attr "type" "call")])
11629
11630 (define_insn "*sibcall_pop"
11631 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11632 (match_operand 1))
11633 (set (reg:SI SP_REG)
11634 (plus:SI (reg:SI SP_REG)
11635 (match_operand:SI 2 "immediate_operand" "i")))]
11636 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11637 "* return ix86_output_call_insn (insn, operands[0]);"
11638 [(set_attr "type" "call")])
11639
11640 ;; Call subroutine, returning value in operand 0
11641
11642 (define_expand "call_value"
11643 [(set (match_operand 0)
11644 (call (match_operand:QI 1)
11645 (match_operand 2)))
11646 (use (match_operand 3))]
11647 ""
11648 {
11649 ix86_expand_call (operands[0], operands[1], operands[2],
11650 operands[3], NULL, false);
11651 DONE;
11652 })
11653
11654 (define_expand "sibcall_value"
11655 [(set (match_operand 0)
11656 (call (match_operand:QI 1)
11657 (match_operand 2)))
11658 (use (match_operand 3))]
11659 ""
11660 {
11661 ix86_expand_call (operands[0], operands[1], operands[2],
11662 operands[3], NULL, true);
11663 DONE;
11664 })
11665
11666 (define_insn_and_split "*call_value_vzeroupper"
11667 [(set (match_operand 0)
11668 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11669 (match_operand 2)))
11670 (unspec [(match_operand 3 "const_int_operand")]
11671 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11672 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11673 "#"
11674 "&& reload_completed"
11675 [(const_int 0)]
11676 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11677 [(set_attr "type" "callv")])
11678
11679 (define_insn "*call_value"
11680 [(set (match_operand 0)
11681 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11682 (match_operand 2)))]
11683 "!SIBLING_CALL_P (insn)"
11684 "* return ix86_output_call_insn (insn, operands[1]);"
11685 [(set_attr "type" "callv")])
11686
11687 (define_insn_and_split "*sibcall_value_vzeroupper"
11688 [(set (match_operand 0)
11689 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11690 (match_operand 2)))
11691 (unspec [(match_operand 3 "const_int_operand")]
11692 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11693 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11694 "#"
11695 "&& reload_completed"
11696 [(const_int 0)]
11697 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11698 [(set_attr "type" "callv")])
11699
11700 (define_insn "*sibcall_value"
11701 [(set (match_operand 0)
11702 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11703 (match_operand 2)))]
11704 "SIBLING_CALL_P (insn)"
11705 "* return ix86_output_call_insn (insn, operands[1]);"
11706 [(set_attr "type" "callv")])
11707
11708 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11709 [(set (match_operand 0)
11710 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11711 (match_operand 2)))
11712 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11713 (clobber (reg:TI XMM6_REG))
11714 (clobber (reg:TI XMM7_REG))
11715 (clobber (reg:TI XMM8_REG))
11716 (clobber (reg:TI XMM9_REG))
11717 (clobber (reg:TI XMM10_REG))
11718 (clobber (reg:TI XMM11_REG))
11719 (clobber (reg:TI XMM12_REG))
11720 (clobber (reg:TI XMM13_REG))
11721 (clobber (reg:TI XMM14_REG))
11722 (clobber (reg:TI XMM15_REG))
11723 (clobber (reg:DI SI_REG))
11724 (clobber (reg:DI DI_REG))
11725 (unspec [(match_operand 3 "const_int_operand")]
11726 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11727 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11728 "#"
11729 "&& reload_completed"
11730 [(const_int 0)]
11731 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11732 [(set_attr "type" "callv")])
11733
11734 (define_insn "*call_value_rex64_ms_sysv"
11735 [(set (match_operand 0)
11736 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11737 (match_operand 2)))
11738 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11739 (clobber (reg:TI XMM6_REG))
11740 (clobber (reg:TI XMM7_REG))
11741 (clobber (reg:TI XMM8_REG))
11742 (clobber (reg:TI XMM9_REG))
11743 (clobber (reg:TI XMM10_REG))
11744 (clobber (reg:TI XMM11_REG))
11745 (clobber (reg:TI XMM12_REG))
11746 (clobber (reg:TI XMM13_REG))
11747 (clobber (reg:TI XMM14_REG))
11748 (clobber (reg:TI XMM15_REG))
11749 (clobber (reg:DI SI_REG))
11750 (clobber (reg:DI DI_REG))]
11751 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11752 "* return ix86_output_call_insn (insn, operands[1]);"
11753 [(set_attr "type" "callv")])
11754
11755 (define_expand "call_value_pop"
11756 [(parallel [(set (match_operand 0)
11757 (call (match_operand:QI 1)
11758 (match_operand:SI 2)))
11759 (set (reg:SI SP_REG)
11760 (plus:SI (reg:SI SP_REG)
11761 (match_operand:SI 4)))])]
11762 "!TARGET_64BIT"
11763 {
11764 ix86_expand_call (operands[0], operands[1], operands[2],
11765 operands[3], operands[4], false);
11766 DONE;
11767 })
11768
11769 (define_insn_and_split "*call_value_pop_vzeroupper"
11770 [(set (match_operand 0)
11771 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11772 (match_operand 2)))
11773 (set (reg:SI SP_REG)
11774 (plus:SI (reg:SI SP_REG)
11775 (match_operand:SI 3 "immediate_operand" "i")))
11776 (unspec [(match_operand 4 "const_int_operand")]
11777 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11778 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11779 "#"
11780 "&& reload_completed"
11781 [(const_int 0)]
11782 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11783 [(set_attr "type" "callv")])
11784
11785 (define_insn "*call_value_pop"
11786 [(set (match_operand 0)
11787 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11788 (match_operand 2)))
11789 (set (reg:SI SP_REG)
11790 (plus:SI (reg:SI SP_REG)
11791 (match_operand:SI 3 "immediate_operand" "i")))]
11792 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11793 "* return ix86_output_call_insn (insn, operands[1]);"
11794 [(set_attr "type" "callv")])
11795
11796 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11797 [(set (match_operand 0)
11798 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11799 (match_operand 2)))
11800 (set (reg:SI SP_REG)
11801 (plus:SI (reg:SI SP_REG)
11802 (match_operand:SI 3 "immediate_operand" "i")))
11803 (unspec [(match_operand 4 "const_int_operand")]
11804 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11805 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11806 "#"
11807 "&& reload_completed"
11808 [(const_int 0)]
11809 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11810 [(set_attr "type" "callv")])
11811
11812 (define_insn "*sibcall_value_pop"
11813 [(set (match_operand 0)
11814 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11815 (match_operand 2)))
11816 (set (reg:SI SP_REG)
11817 (plus:SI (reg:SI SP_REG)
11818 (match_operand:SI 3 "immediate_operand" "i")))]
11819 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11820 "* return ix86_output_call_insn (insn, operands[1]);"
11821 [(set_attr "type" "callv")])
11822
11823 ;; Call subroutine returning any type.
11824
11825 (define_expand "untyped_call"
11826 [(parallel [(call (match_operand 0)
11827 (const_int 0))
11828 (match_operand 1)
11829 (match_operand 2)])]
11830 ""
11831 {
11832 int i;
11833
11834 /* In order to give reg-stack an easier job in validating two
11835 coprocessor registers as containing a possible return value,
11836 simply pretend the untyped call returns a complex long double
11837 value.
11838
11839 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11840 and should have the default ABI. */
11841
11842 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11843 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11844 operands[0], const0_rtx,
11845 GEN_INT ((TARGET_64BIT
11846 ? (ix86_abi == SYSV_ABI
11847 ? X86_64_SSE_REGPARM_MAX
11848 : X86_64_MS_SSE_REGPARM_MAX)
11849 : X86_32_SSE_REGPARM_MAX)
11850 - 1),
11851 NULL, false);
11852
11853 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11854 {
11855 rtx set = XVECEXP (operands[2], 0, i);
11856 emit_move_insn (SET_DEST (set), SET_SRC (set));
11857 }
11858
11859 /* The optimizer does not know that the call sets the function value
11860 registers we stored in the result block. We avoid problems by
11861 claiming that all hard registers are used and clobbered at this
11862 point. */
11863 emit_insn (gen_blockage ());
11864
11865 DONE;
11866 })
11867 \f
11868 ;; Prologue and epilogue instructions
11869
11870 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11871 ;; all of memory. This blocks insns from being moved across this point.
11872
11873 (define_insn "blockage"
11874 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11875 ""
11876 ""
11877 [(set_attr "length" "0")])
11878
11879 ;; Do not schedule instructions accessing memory across this point.
11880
11881 (define_expand "memory_blockage"
11882 [(set (match_dup 0)
11883 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11884 ""
11885 {
11886 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11887 MEM_VOLATILE_P (operands[0]) = 1;
11888 })
11889
11890 (define_insn "*memory_blockage"
11891 [(set (match_operand:BLK 0)
11892 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11893 ""
11894 ""
11895 [(set_attr "length" "0")])
11896
11897 ;; As USE insns aren't meaningful after reload, this is used instead
11898 ;; to prevent deleting instructions setting registers for PIC code
11899 (define_insn "prologue_use"
11900 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11901 ""
11902 ""
11903 [(set_attr "length" "0")])
11904
11905 ;; Insn emitted into the body of a function to return from a function.
11906 ;; This is only done if the function's epilogue is known to be simple.
11907 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11908
11909 (define_expand "return"
11910 [(simple_return)]
11911 "ix86_can_use_return_insn_p ()"
11912 {
11913 ix86_maybe_emit_epilogue_vzeroupper ();
11914 if (crtl->args.pops_args)
11915 {
11916 rtx popc = GEN_INT (crtl->args.pops_args);
11917 emit_jump_insn (gen_simple_return_pop_internal (popc));
11918 DONE;
11919 }
11920 })
11921
11922 ;; We need to disable this for TARGET_SEH, as otherwise
11923 ;; shrink-wrapped prologue gets enabled too. This might exceed
11924 ;; the maximum size of prologue in unwind information.
11925
11926 (define_expand "simple_return"
11927 [(simple_return)]
11928 "!TARGET_SEH"
11929 {
11930 ix86_maybe_emit_epilogue_vzeroupper ();
11931 if (crtl->args.pops_args)
11932 {
11933 rtx popc = GEN_INT (crtl->args.pops_args);
11934 emit_jump_insn (gen_simple_return_pop_internal (popc));
11935 DONE;
11936 }
11937 })
11938
11939 (define_insn "simple_return_internal"
11940 [(simple_return)]
11941 "reload_completed"
11942 "ret"
11943 [(set_attr "length" "1")
11944 (set_attr "atom_unit" "jeu")
11945 (set_attr "length_immediate" "0")
11946 (set_attr "modrm" "0")])
11947
11948 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11949 ;; instruction Athlon and K8 have.
11950
11951 (define_insn "simple_return_internal_long"
11952 [(simple_return)
11953 (unspec [(const_int 0)] UNSPEC_REP)]
11954 "reload_completed"
11955 "rep%; ret"
11956 [(set_attr "length" "2")
11957 (set_attr "atom_unit" "jeu")
11958 (set_attr "length_immediate" "0")
11959 (set_attr "prefix_rep" "1")
11960 (set_attr "modrm" "0")])
11961
11962 (define_insn "simple_return_pop_internal"
11963 [(simple_return)
11964 (use (match_operand:SI 0 "const_int_operand"))]
11965 "reload_completed"
11966 "ret\t%0"
11967 [(set_attr "length" "3")
11968 (set_attr "atom_unit" "jeu")
11969 (set_attr "length_immediate" "2")
11970 (set_attr "modrm" "0")])
11971
11972 (define_insn "simple_return_indirect_internal"
11973 [(simple_return)
11974 (use (match_operand:SI 0 "register_operand" "r"))]
11975 "reload_completed"
11976 "jmp\t%A0"
11977 [(set_attr "type" "ibr")
11978 (set_attr "length_immediate" "0")])
11979
11980 (define_insn "nop"
11981 [(const_int 0)]
11982 ""
11983 "nop"
11984 [(set_attr "length" "1")
11985 (set_attr "length_immediate" "0")
11986 (set_attr "modrm" "0")])
11987
11988 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11989 (define_insn "nops"
11990 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11991 UNSPECV_NOPS)]
11992 "reload_completed"
11993 {
11994 int num = INTVAL (operands[0]);
11995
11996 gcc_assert (IN_RANGE (num, 1, 8));
11997
11998 while (num--)
11999 fputs ("\tnop\n", asm_out_file);
12000
12001 return "";
12002 }
12003 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12004 (set_attr "length_immediate" "0")
12005 (set_attr "modrm" "0")])
12006
12007 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12008 ;; branch prediction penalty for the third jump in a 16-byte
12009 ;; block on K8.
12010
12011 (define_insn "pad"
12012 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12013 ""
12014 {
12015 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12016 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12017 #else
12018 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12019 The align insn is used to avoid 3 jump instructions in the row to improve
12020 branch prediction and the benefits hardly outweigh the cost of extra 8
12021 nops on the average inserted by full alignment pseudo operation. */
12022 #endif
12023 return "";
12024 }
12025 [(set_attr "length" "16")])
12026
12027 (define_expand "prologue"
12028 [(const_int 0)]
12029 ""
12030 "ix86_expand_prologue (); DONE;")
12031
12032 (define_insn "set_got"
12033 [(set (match_operand:SI 0 "register_operand" "=r")
12034 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12035 (clobber (reg:CC FLAGS_REG))]
12036 "!TARGET_64BIT"
12037 "* return output_set_got (operands[0], NULL_RTX);"
12038 [(set_attr "type" "multi")
12039 (set_attr "length" "12")])
12040
12041 (define_insn "set_got_labelled"
12042 [(set (match_operand:SI 0 "register_operand" "=r")
12043 (unspec:SI [(label_ref (match_operand 1))]
12044 UNSPEC_SET_GOT))
12045 (clobber (reg:CC FLAGS_REG))]
12046 "!TARGET_64BIT"
12047 "* return output_set_got (operands[0], operands[1]);"
12048 [(set_attr "type" "multi")
12049 (set_attr "length" "12")])
12050
12051 (define_insn "set_got_rex64"
12052 [(set (match_operand:DI 0 "register_operand" "=r")
12053 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12054 "TARGET_64BIT"
12055 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12056 [(set_attr "type" "lea")
12057 (set_attr "length_address" "4")
12058 (set_attr "mode" "DI")])
12059
12060 (define_insn "set_rip_rex64"
12061 [(set (match_operand:DI 0 "register_operand" "=r")
12062 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12063 "TARGET_64BIT"
12064 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12065 [(set_attr "type" "lea")
12066 (set_attr "length_address" "4")
12067 (set_attr "mode" "DI")])
12068
12069 (define_insn "set_got_offset_rex64"
12070 [(set (match_operand:DI 0 "register_operand" "=r")
12071 (unspec:DI
12072 [(label_ref (match_operand 1))]
12073 UNSPEC_SET_GOT_OFFSET))]
12074 "TARGET_LP64"
12075 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12076 [(set_attr "type" "imov")
12077 (set_attr "length_immediate" "0")
12078 (set_attr "length_address" "8")
12079 (set_attr "mode" "DI")])
12080
12081 (define_expand "epilogue"
12082 [(const_int 0)]
12083 ""
12084 "ix86_expand_epilogue (1); DONE;")
12085
12086 (define_expand "sibcall_epilogue"
12087 [(const_int 0)]
12088 ""
12089 "ix86_expand_epilogue (0); DONE;")
12090
12091 (define_expand "eh_return"
12092 [(use (match_operand 0 "register_operand"))]
12093 ""
12094 {
12095 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12096
12097 /* Tricky bit: we write the address of the handler to which we will
12098 be returning into someone else's stack frame, one word below the
12099 stack address we wish to restore. */
12100 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12101 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12102 tmp = gen_rtx_MEM (Pmode, tmp);
12103 emit_move_insn (tmp, ra);
12104
12105 emit_jump_insn (gen_eh_return_internal ());
12106 emit_barrier ();
12107 DONE;
12108 })
12109
12110 (define_insn_and_split "eh_return_internal"
12111 [(eh_return)]
12112 ""
12113 "#"
12114 "epilogue_completed"
12115 [(const_int 0)]
12116 "ix86_expand_epilogue (2); DONE;")
12117
12118 (define_insn "leave"
12119 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12120 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12121 (clobber (mem:BLK (scratch)))]
12122 "!TARGET_64BIT"
12123 "leave"
12124 [(set_attr "type" "leave")])
12125
12126 (define_insn "leave_rex64"
12127 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12128 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12129 (clobber (mem:BLK (scratch)))]
12130 "TARGET_64BIT"
12131 "leave"
12132 [(set_attr "type" "leave")])
12133 \f
12134 ;; Handle -fsplit-stack.
12135
12136 (define_expand "split_stack_prologue"
12137 [(const_int 0)]
12138 ""
12139 {
12140 ix86_expand_split_stack_prologue ();
12141 DONE;
12142 })
12143
12144 ;; In order to support the call/return predictor, we use a return
12145 ;; instruction which the middle-end doesn't see.
12146 (define_insn "split_stack_return"
12147 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12148 UNSPECV_SPLIT_STACK_RETURN)]
12149 ""
12150 {
12151 if (operands[0] == const0_rtx)
12152 return "ret";
12153 else
12154 return "ret\t%0";
12155 }
12156 [(set_attr "atom_unit" "jeu")
12157 (set_attr "modrm" "0")
12158 (set (attr "length")
12159 (if_then_else (match_operand:SI 0 "const0_operand")
12160 (const_int 1)
12161 (const_int 3)))
12162 (set (attr "length_immediate")
12163 (if_then_else (match_operand:SI 0 "const0_operand")
12164 (const_int 0)
12165 (const_int 2)))])
12166
12167 ;; If there are operand 0 bytes available on the stack, jump to
12168 ;; operand 1.
12169
12170 (define_expand "split_stack_space_check"
12171 [(set (pc) (if_then_else
12172 (ltu (minus (reg SP_REG)
12173 (match_operand 0 "register_operand"))
12174 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12175 (label_ref (match_operand 1))
12176 (pc)))]
12177 ""
12178 {
12179 rtx reg, size, limit;
12180
12181 reg = gen_reg_rtx (Pmode);
12182 size = force_reg (Pmode, operands[0]);
12183 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12184 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12185 UNSPEC_STACK_CHECK);
12186 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12187 ix86_expand_branch (GEU, reg, limit, operands[1]);
12188
12189 DONE;
12190 })
12191 \f
12192 ;; Bit manipulation instructions.
12193
12194 (define_expand "ffs<mode>2"
12195 [(set (match_dup 2) (const_int -1))
12196 (parallel [(set (match_dup 3) (match_dup 4))
12197 (set (match_operand:SWI48 0 "register_operand")
12198 (ctz:SWI48
12199 (match_operand:SWI48 1 "nonimmediate_operand")))])
12200 (set (match_dup 0) (if_then_else:SWI48
12201 (eq (match_dup 3) (const_int 0))
12202 (match_dup 2)
12203 (match_dup 0)))
12204 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12205 (clobber (reg:CC FLAGS_REG))])]
12206 ""
12207 {
12208 enum machine_mode flags_mode;
12209
12210 if (<MODE>mode == SImode && !TARGET_CMOVE)
12211 {
12212 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12213 DONE;
12214 }
12215
12216 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12217
12218 operands[2] = gen_reg_rtx (<MODE>mode);
12219 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12220 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12221 })
12222
12223 (define_insn_and_split "ffssi2_no_cmove"
12224 [(set (match_operand:SI 0 "register_operand" "=r")
12225 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12226 (clobber (match_scratch:SI 2 "=&q"))
12227 (clobber (reg:CC FLAGS_REG))]
12228 "!TARGET_CMOVE"
12229 "#"
12230 "&& reload_completed"
12231 [(parallel [(set (match_dup 4) (match_dup 5))
12232 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12233 (set (strict_low_part (match_dup 3))
12234 (eq:QI (match_dup 4) (const_int 0)))
12235 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12236 (clobber (reg:CC FLAGS_REG))])
12237 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12238 (clobber (reg:CC FLAGS_REG))])
12239 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12240 (clobber (reg:CC FLAGS_REG))])]
12241 {
12242 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12243
12244 operands[3] = gen_lowpart (QImode, operands[2]);
12245 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12246 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12247
12248 ix86_expand_clear (operands[2]);
12249 })
12250
12251 (define_insn "*tzcnt<mode>_1"
12252 [(set (reg:CCC FLAGS_REG)
12253 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12254 (const_int 0)))
12255 (set (match_operand:SWI48 0 "register_operand" "=r")
12256 (ctz:SWI48 (match_dup 1)))]
12257 "TARGET_BMI"
12258 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12259 [(set_attr "type" "alu1")
12260 (set_attr "prefix_0f" "1")
12261 (set_attr "prefix_rep" "1")
12262 (set_attr "mode" "<MODE>")])
12263
12264 (define_insn "*bsf<mode>_1"
12265 [(set (reg:CCZ FLAGS_REG)
12266 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12267 (const_int 0)))
12268 (set (match_operand:SWI48 0 "register_operand" "=r")
12269 (ctz:SWI48 (match_dup 1)))]
12270 ""
12271 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12272 [(set_attr "type" "alu1")
12273 (set_attr "prefix_0f" "1")
12274 (set_attr "mode" "<MODE>")])
12275
12276 (define_insn "ctz<mode>2"
12277 [(set (match_operand:SWI248 0 "register_operand" "=r")
12278 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12279 (clobber (reg:CC FLAGS_REG))]
12280 ""
12281 {
12282 if (TARGET_BMI)
12283 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12284 else if (optimize_function_for_size_p (cfun))
12285 ;
12286 else if (TARGET_GENERIC)
12287 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12288 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12289
12290 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12291 }
12292 [(set_attr "type" "alu1")
12293 (set_attr "prefix_0f" "1")
12294 (set (attr "prefix_rep")
12295 (if_then_else
12296 (ior (match_test "TARGET_BMI")
12297 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12298 (match_test "TARGET_GENERIC")))
12299 (const_string "1")
12300 (const_string "0")))
12301 (set_attr "mode" "<MODE>")])
12302
12303 (define_expand "clz<mode>2"
12304 [(parallel
12305 [(set (match_operand:SWI248 0 "register_operand")
12306 (minus:SWI248
12307 (match_dup 2)
12308 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12309 (clobber (reg:CC FLAGS_REG))])
12310 (parallel
12311 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12312 (clobber (reg:CC FLAGS_REG))])]
12313 ""
12314 {
12315 if (TARGET_LZCNT)
12316 {
12317 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12318 DONE;
12319 }
12320 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12321 })
12322
12323 (define_insn "clz<mode>2_lzcnt"
12324 [(set (match_operand:SWI248 0 "register_operand" "=r")
12325 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12326 (clobber (reg:CC FLAGS_REG))]
12327 "TARGET_LZCNT"
12328 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12329 [(set_attr "prefix_rep" "1")
12330 (set_attr "type" "bitmanip")
12331 (set_attr "mode" "<MODE>")])
12332
12333 ;; BMI instructions.
12334 (define_insn "*bmi_andn_<mode>"
12335 [(set (match_operand:SWI48 0 "register_operand" "=r")
12336 (and:SWI48
12337 (not:SWI48
12338 (match_operand:SWI48 1 "register_operand" "r"))
12339 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12340 (clobber (reg:CC FLAGS_REG))]
12341 "TARGET_BMI"
12342 "andn\t{%2, %1, %0|%0, %1, %2}"
12343 [(set_attr "type" "bitmanip")
12344 (set_attr "mode" "<MODE>")])
12345
12346 (define_insn "bmi_bextr_<mode>"
12347 [(set (match_operand:SWI48 0 "register_operand" "=r")
12348 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12349 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12350 UNSPEC_BEXTR))
12351 (clobber (reg:CC FLAGS_REG))]
12352 "TARGET_BMI"
12353 "bextr\t{%2, %1, %0|%0, %1, %2}"
12354 [(set_attr "type" "bitmanip")
12355 (set_attr "mode" "<MODE>")])
12356
12357 (define_insn "*bmi_blsi_<mode>"
12358 [(set (match_operand:SWI48 0 "register_operand" "=r")
12359 (and:SWI48
12360 (neg:SWI48
12361 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12362 (match_dup 1)))
12363 (clobber (reg:CC FLAGS_REG))]
12364 "TARGET_BMI"
12365 "blsi\t{%1, %0|%0, %1}"
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "mode" "<MODE>")])
12368
12369 (define_insn "*bmi_blsmsk_<mode>"
12370 [(set (match_operand:SWI48 0 "register_operand" "=r")
12371 (xor:SWI48
12372 (plus:SWI48
12373 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12374 (const_int -1))
12375 (match_dup 1)))
12376 (clobber (reg:CC FLAGS_REG))]
12377 "TARGET_BMI"
12378 "blsmsk\t{%1, %0|%0, %1}"
12379 [(set_attr "type" "bitmanip")
12380 (set_attr "mode" "<MODE>")])
12381
12382 (define_insn "*bmi_blsr_<mode>"
12383 [(set (match_operand:SWI48 0 "register_operand" "=r")
12384 (and:SWI48
12385 (plus:SWI48
12386 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12387 (const_int -1))
12388 (match_dup 1)))
12389 (clobber (reg:CC FLAGS_REG))]
12390 "TARGET_BMI"
12391 "blsr\t{%1, %0|%0, %1}"
12392 [(set_attr "type" "bitmanip")
12393 (set_attr "mode" "<MODE>")])
12394
12395 ;; BMI2 instructions.
12396 (define_insn "bmi2_bzhi_<mode>3"
12397 [(set (match_operand:SWI48 0 "register_operand" "=r")
12398 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12399 (lshiftrt:SWI48 (const_int -1)
12400 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "TARGET_BMI2"
12403 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12404 [(set_attr "type" "bitmanip")
12405 (set_attr "prefix" "vex")
12406 (set_attr "mode" "<MODE>")])
12407
12408 (define_insn "bmi2_pdep_<mode>3"
12409 [(set (match_operand:SWI48 0 "register_operand" "=r")
12410 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12411 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12412 UNSPEC_PDEP))]
12413 "TARGET_BMI2"
12414 "pdep\t{%2, %1, %0|%0, %1, %2}"
12415 [(set_attr "type" "bitmanip")
12416 (set_attr "prefix" "vex")
12417 (set_attr "mode" "<MODE>")])
12418
12419 (define_insn "bmi2_pext_<mode>3"
12420 [(set (match_operand:SWI48 0 "register_operand" "=r")
12421 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12422 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12423 UNSPEC_PEXT))]
12424 "TARGET_BMI2"
12425 "pext\t{%2, %1, %0|%0, %1, %2}"
12426 [(set_attr "type" "bitmanip")
12427 (set_attr "prefix" "vex")
12428 (set_attr "mode" "<MODE>")])
12429
12430 ;; TBM instructions.
12431 (define_insn "tbm_bextri_<mode>"
12432 [(set (match_operand:SWI48 0 "register_operand" "=r")
12433 (zero_extract:SWI48
12434 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12435 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12436 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12437 (clobber (reg:CC FLAGS_REG))]
12438 "TARGET_TBM"
12439 {
12440 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12441 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12442 }
12443 [(set_attr "type" "bitmanip")
12444 (set_attr "mode" "<MODE>")])
12445
12446 (define_insn "*tbm_blcfill_<mode>"
12447 [(set (match_operand:SWI48 0 "register_operand" "=r")
12448 (and:SWI48
12449 (plus:SWI48
12450 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12451 (const_int 1))
12452 (match_dup 1)))
12453 (clobber (reg:CC FLAGS_REG))]
12454 "TARGET_TBM"
12455 "blcfill\t{%1, %0|%0, %1}"
12456 [(set_attr "type" "bitmanip")
12457 (set_attr "mode" "<MODE>")])
12458
12459 (define_insn "*tbm_blci_<mode>"
12460 [(set (match_operand:SWI48 0 "register_operand" "=r")
12461 (ior:SWI48
12462 (not:SWI48
12463 (plus:SWI48
12464 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12465 (const_int 1)))
12466 (match_dup 1)))
12467 (clobber (reg:CC FLAGS_REG))]
12468 "TARGET_TBM"
12469 "blci\t{%1, %0|%0, %1}"
12470 [(set_attr "type" "bitmanip")
12471 (set_attr "mode" "<MODE>")])
12472
12473 (define_insn "*tbm_blcic_<mode>"
12474 [(set (match_operand:SWI48 0 "register_operand" "=r")
12475 (and:SWI48
12476 (plus:SWI48
12477 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12478 (const_int 1))
12479 (not:SWI48
12480 (match_dup 1))))
12481 (clobber (reg:CC FLAGS_REG))]
12482 "TARGET_TBM"
12483 "blcic\t{%1, %0|%0, %1}"
12484 [(set_attr "type" "bitmanip")
12485 (set_attr "mode" "<MODE>")])
12486
12487 (define_insn "*tbm_blcmsk_<mode>"
12488 [(set (match_operand:SWI48 0 "register_operand" "=r")
12489 (xor:SWI48
12490 (plus:SWI48
12491 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12492 (const_int 1))
12493 (match_dup 1)))
12494 (clobber (reg:CC FLAGS_REG))]
12495 "TARGET_TBM"
12496 "blcmsk\t{%1, %0|%0, %1}"
12497 [(set_attr "type" "bitmanip")
12498 (set_attr "mode" "<MODE>")])
12499
12500 (define_insn "*tbm_blcs_<mode>"
12501 [(set (match_operand:SWI48 0 "register_operand" "=r")
12502 (ior:SWI48
12503 (plus:SWI48
12504 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12505 (const_int 1))
12506 (match_dup 1)))
12507 (clobber (reg:CC FLAGS_REG))]
12508 "TARGET_TBM"
12509 "blcs\t{%1, %0|%0, %1}"
12510 [(set_attr "type" "bitmanip")
12511 (set_attr "mode" "<MODE>")])
12512
12513 (define_insn "*tbm_blsfill_<mode>"
12514 [(set (match_operand:SWI48 0 "register_operand" "=r")
12515 (ior:SWI48
12516 (plus:SWI48
12517 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12518 (const_int -1))
12519 (match_dup 1)))
12520 (clobber (reg:CC FLAGS_REG))]
12521 "TARGET_TBM"
12522 "blsfill\t{%1, %0|%0, %1}"
12523 [(set_attr "type" "bitmanip")
12524 (set_attr "mode" "<MODE>")])
12525
12526 (define_insn "*tbm_blsic_<mode>"
12527 [(set (match_operand:SWI48 0 "register_operand" "=r")
12528 (ior:SWI48
12529 (plus:SWI48
12530 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12531 (const_int -1))
12532 (not:SWI48
12533 (match_dup 1))))
12534 (clobber (reg:CC FLAGS_REG))]
12535 "TARGET_TBM"
12536 "blsic\t{%1, %0|%0, %1}"
12537 [(set_attr "type" "bitmanip")
12538 (set_attr "mode" "<MODE>")])
12539
12540 (define_insn "*tbm_t1mskc_<mode>"
12541 [(set (match_operand:SWI48 0 "register_operand" "=r")
12542 (ior:SWI48
12543 (plus:SWI48
12544 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12545 (const_int 1))
12546 (not:SWI48
12547 (match_dup 1))))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "TARGET_TBM"
12550 "t1mskc\t{%1, %0|%0, %1}"
12551 [(set_attr "type" "bitmanip")
12552 (set_attr "mode" "<MODE>")])
12553
12554 (define_insn "*tbm_tzmsk_<mode>"
12555 [(set (match_operand:SWI48 0 "register_operand" "=r")
12556 (and:SWI48
12557 (plus:SWI48
12558 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12559 (const_int -1))
12560 (not:SWI48
12561 (match_dup 1))))
12562 (clobber (reg:CC FLAGS_REG))]
12563 "TARGET_TBM"
12564 "tzmsk\t{%1, %0|%0, %1}"
12565 [(set_attr "type" "bitmanip")
12566 (set_attr "mode" "<MODE>")])
12567
12568 (define_insn "bsr_rex64"
12569 [(set (match_operand:DI 0 "register_operand" "=r")
12570 (minus:DI (const_int 63)
12571 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12572 (clobber (reg:CC FLAGS_REG))]
12573 "TARGET_64BIT"
12574 "bsr{q}\t{%1, %0|%0, %1}"
12575 [(set_attr "type" "alu1")
12576 (set_attr "prefix_0f" "1")
12577 (set_attr "mode" "DI")])
12578
12579 (define_insn "bsr"
12580 [(set (match_operand:SI 0 "register_operand" "=r")
12581 (minus:SI (const_int 31)
12582 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12583 (clobber (reg:CC FLAGS_REG))]
12584 ""
12585 "bsr{l}\t{%1, %0|%0, %1}"
12586 [(set_attr "type" "alu1")
12587 (set_attr "prefix_0f" "1")
12588 (set_attr "mode" "SI")])
12589
12590 (define_insn "*bsrhi"
12591 [(set (match_operand:HI 0 "register_operand" "=r")
12592 (minus:HI (const_int 15)
12593 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12594 (clobber (reg:CC FLAGS_REG))]
12595 ""
12596 "bsr{w}\t{%1, %0|%0, %1}"
12597 [(set_attr "type" "alu1")
12598 (set_attr "prefix_0f" "1")
12599 (set_attr "mode" "HI")])
12600
12601 (define_insn "popcount<mode>2"
12602 [(set (match_operand:SWI248 0 "register_operand" "=r")
12603 (popcount:SWI248
12604 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12605 (clobber (reg:CC FLAGS_REG))]
12606 "TARGET_POPCNT"
12607 {
12608 #if TARGET_MACHO
12609 return "popcnt\t{%1, %0|%0, %1}";
12610 #else
12611 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12612 #endif
12613 }
12614 [(set_attr "prefix_rep" "1")
12615 (set_attr "type" "bitmanip")
12616 (set_attr "mode" "<MODE>")])
12617
12618 (define_insn "*popcount<mode>2_cmp"
12619 [(set (reg FLAGS_REG)
12620 (compare
12621 (popcount:SWI248
12622 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12623 (const_int 0)))
12624 (set (match_operand:SWI248 0 "register_operand" "=r")
12625 (popcount:SWI248 (match_dup 1)))]
12626 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12627 {
12628 #if TARGET_MACHO
12629 return "popcnt\t{%1, %0|%0, %1}";
12630 #else
12631 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12632 #endif
12633 }
12634 [(set_attr "prefix_rep" "1")
12635 (set_attr "type" "bitmanip")
12636 (set_attr "mode" "<MODE>")])
12637
12638 (define_insn "*popcountsi2_cmp_zext"
12639 [(set (reg FLAGS_REG)
12640 (compare
12641 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12642 (const_int 0)))
12643 (set (match_operand:DI 0 "register_operand" "=r")
12644 (zero_extend:DI(popcount:SI (match_dup 1))))]
12645 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12646 {
12647 #if TARGET_MACHO
12648 return "popcnt\t{%1, %0|%0, %1}";
12649 #else
12650 return "popcnt{l}\t{%1, %0|%0, %1}";
12651 #endif
12652 }
12653 [(set_attr "prefix_rep" "1")
12654 (set_attr "type" "bitmanip")
12655 (set_attr "mode" "SI")])
12656
12657 (define_expand "bswapdi2"
12658 [(set (match_operand:DI 0 "register_operand")
12659 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12660 ""
12661 {
12662 if (TARGET_64BIT && !TARGET_MOVBE)
12663 operands[1] = force_reg (DImode, operands[1]);
12664 })
12665
12666 (define_insn_and_split "*bswapdi2_doubleword"
12667 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12668 (bswap:DI
12669 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12670 "!TARGET_64BIT
12671 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12672 "#"
12673 "&& reload_completed"
12674 [(set (match_dup 2)
12675 (bswap:SI (match_dup 1)))
12676 (set (match_dup 0)
12677 (bswap:SI (match_dup 3)))]
12678 {
12679 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12680
12681 if (REG_P (operands[0]) && REG_P (operands[1]))
12682 {
12683 emit_insn (gen_swapsi (operands[0], operands[2]));
12684 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12685 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12686 DONE;
12687 }
12688
12689 if (!TARGET_MOVBE)
12690 {
12691 if (MEM_P (operands[0]))
12692 {
12693 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12694 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12695
12696 emit_move_insn (operands[0], operands[3]);
12697 emit_move_insn (operands[2], operands[1]);
12698 }
12699 if (MEM_P (operands[1]))
12700 {
12701 emit_move_insn (operands[2], operands[1]);
12702 emit_move_insn (operands[0], operands[3]);
12703
12704 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12705 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12706 }
12707 DONE;
12708 }
12709 })
12710
12711 (define_expand "bswapsi2"
12712 [(set (match_operand:SI 0 "register_operand")
12713 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12714 ""
12715 {
12716 if (TARGET_MOVBE)
12717 ;
12718 else if (TARGET_BSWAP)
12719 operands[1] = force_reg (SImode, operands[1]);
12720 else
12721 {
12722 rtx x = operands[0];
12723
12724 emit_move_insn (x, operands[1]);
12725 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12726 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12727 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12728 DONE;
12729 }
12730 })
12731
12732 (define_insn "*bswap<mode>2_movbe"
12733 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12734 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12735 "TARGET_MOVBE
12736 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12737 "@
12738 bswap\t%0
12739 movbe\t{%1, %0|%0, %1}
12740 movbe\t{%1, %0|%0, %1}"
12741 [(set_attr "type" "bitmanip,imov,imov")
12742 (set_attr "modrm" "0,1,1")
12743 (set_attr "prefix_0f" "*,1,1")
12744 (set_attr "prefix_extra" "*,1,1")
12745 (set_attr "mode" "<MODE>")])
12746
12747 (define_insn "*bswap<mode>2"
12748 [(set (match_operand:SWI48 0 "register_operand" "=r")
12749 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12750 "TARGET_BSWAP"
12751 "bswap\t%0"
12752 [(set_attr "type" "bitmanip")
12753 (set_attr "modrm" "0")
12754 (set_attr "mode" "<MODE>")])
12755
12756 (define_insn "*bswaphi_lowpart_1"
12757 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12758 (bswap:HI (match_dup 0)))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12761 "@
12762 xchg{b}\t{%h0, %b0|%b0, %h0}
12763 rol{w}\t{$8, %0|%0, 8}"
12764 [(set_attr "length" "2,4")
12765 (set_attr "mode" "QI,HI")])
12766
12767 (define_insn "bswaphi_lowpart"
12768 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12769 (bswap:HI (match_dup 0)))
12770 (clobber (reg:CC FLAGS_REG))]
12771 ""
12772 "rol{w}\t{$8, %0|%0, 8}"
12773 [(set_attr "length" "4")
12774 (set_attr "mode" "HI")])
12775
12776 (define_expand "paritydi2"
12777 [(set (match_operand:DI 0 "register_operand")
12778 (parity:DI (match_operand:DI 1 "register_operand")))]
12779 "! TARGET_POPCNT"
12780 {
12781 rtx scratch = gen_reg_rtx (QImode);
12782 rtx cond;
12783
12784 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12785 NULL_RTX, operands[1]));
12786
12787 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12788 gen_rtx_REG (CCmode, FLAGS_REG),
12789 const0_rtx);
12790 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12791
12792 if (TARGET_64BIT)
12793 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12794 else
12795 {
12796 rtx tmp = gen_reg_rtx (SImode);
12797
12798 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12799 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12800 }
12801 DONE;
12802 })
12803
12804 (define_expand "paritysi2"
12805 [(set (match_operand:SI 0 "register_operand")
12806 (parity:SI (match_operand:SI 1 "register_operand")))]
12807 "! TARGET_POPCNT"
12808 {
12809 rtx scratch = gen_reg_rtx (QImode);
12810 rtx cond;
12811
12812 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12813
12814 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12815 gen_rtx_REG (CCmode, FLAGS_REG),
12816 const0_rtx);
12817 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12818
12819 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12820 DONE;
12821 })
12822
12823 (define_insn_and_split "paritydi2_cmp"
12824 [(set (reg:CC FLAGS_REG)
12825 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12826 UNSPEC_PARITY))
12827 (clobber (match_scratch:DI 0 "=r"))
12828 (clobber (match_scratch:SI 1 "=&r"))
12829 (clobber (match_scratch:HI 2 "=Q"))]
12830 "! TARGET_POPCNT"
12831 "#"
12832 "&& reload_completed"
12833 [(parallel
12834 [(set (match_dup 1)
12835 (xor:SI (match_dup 1) (match_dup 4)))
12836 (clobber (reg:CC FLAGS_REG))])
12837 (parallel
12838 [(set (reg:CC FLAGS_REG)
12839 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12840 (clobber (match_dup 1))
12841 (clobber (match_dup 2))])]
12842 {
12843 operands[4] = gen_lowpart (SImode, operands[3]);
12844
12845 if (TARGET_64BIT)
12846 {
12847 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12848 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12849 }
12850 else
12851 operands[1] = gen_highpart (SImode, operands[3]);
12852 })
12853
12854 (define_insn_and_split "paritysi2_cmp"
12855 [(set (reg:CC FLAGS_REG)
12856 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12857 UNSPEC_PARITY))
12858 (clobber (match_scratch:SI 0 "=r"))
12859 (clobber (match_scratch:HI 1 "=&Q"))]
12860 "! TARGET_POPCNT"
12861 "#"
12862 "&& reload_completed"
12863 [(parallel
12864 [(set (match_dup 1)
12865 (xor:HI (match_dup 1) (match_dup 3)))
12866 (clobber (reg:CC FLAGS_REG))])
12867 (parallel
12868 [(set (reg:CC FLAGS_REG)
12869 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12870 (clobber (match_dup 1))])]
12871 {
12872 operands[3] = gen_lowpart (HImode, operands[2]);
12873
12874 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12875 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12876 })
12877
12878 (define_insn "*parityhi2_cmp"
12879 [(set (reg:CC FLAGS_REG)
12880 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12881 UNSPEC_PARITY))
12882 (clobber (match_scratch:HI 0 "=Q"))]
12883 "! TARGET_POPCNT"
12884 "xor{b}\t{%h0, %b0|%b0, %h0}"
12885 [(set_attr "length" "2")
12886 (set_attr "mode" "HI")])
12887
12888 \f
12889 ;; Thread-local storage patterns for ELF.
12890 ;;
12891 ;; Note that these code sequences must appear exactly as shown
12892 ;; in order to allow linker relaxation.
12893
12894 (define_insn "*tls_global_dynamic_32_gnu"
12895 [(set (match_operand:SI 0 "register_operand" "=a")
12896 (unspec:SI
12897 [(match_operand:SI 1 "register_operand" "b")
12898 (match_operand 2 "tls_symbolic_operand")
12899 (match_operand 3 "constant_call_address_operand" "z")]
12900 UNSPEC_TLS_GD))
12901 (clobber (match_scratch:SI 4 "=d"))
12902 (clobber (match_scratch:SI 5 "=c"))
12903 (clobber (reg:CC FLAGS_REG))]
12904 "!TARGET_64BIT && TARGET_GNU_TLS"
12905 {
12906 output_asm_insn
12907 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12908 if (TARGET_SUN_TLS)
12909 #ifdef HAVE_AS_IX86_TLSGDPLT
12910 return "call\t%a2@tlsgdplt";
12911 #else
12912 return "call\t%p3@plt";
12913 #endif
12914 return "call\t%P3";
12915 }
12916 [(set_attr "type" "multi")
12917 (set_attr "length" "12")])
12918
12919 (define_expand "tls_global_dynamic_32"
12920 [(parallel
12921 [(set (match_operand:SI 0 "register_operand")
12922 (unspec:SI [(match_operand:SI 2 "register_operand")
12923 (match_operand 1 "tls_symbolic_operand")
12924 (match_operand 3 "constant_call_address_operand")]
12925 UNSPEC_TLS_GD))
12926 (clobber (match_scratch:SI 4))
12927 (clobber (match_scratch:SI 5))
12928 (clobber (reg:CC FLAGS_REG))])])
12929
12930 (define_insn "*tls_global_dynamic_64_<mode>"
12931 [(set (match_operand:P 0 "register_operand" "=a")
12932 (call:P
12933 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12934 (match_operand 3)))
12935 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12936 UNSPEC_TLS_GD)]
12937 "TARGET_64BIT"
12938 {
12939 if (!TARGET_X32)
12940 fputs (ASM_BYTE "0x66\n", asm_out_file);
12941 output_asm_insn
12942 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12943 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12944 fputs ("\trex64\n", asm_out_file);
12945 if (TARGET_SUN_TLS)
12946 return "call\t%p2@plt";
12947 return "call\t%P2";
12948 }
12949 [(set_attr "type" "multi")
12950 (set (attr "length")
12951 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12952
12953 (define_expand "tls_global_dynamic_64_<mode>"
12954 [(parallel
12955 [(set (match_operand:P 0 "register_operand")
12956 (call:P
12957 (mem:QI (match_operand 2 "constant_call_address_operand"))
12958 (const_int 0)))
12959 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12960 UNSPEC_TLS_GD)])]
12961 "TARGET_64BIT")
12962
12963 (define_insn "*tls_local_dynamic_base_32_gnu"
12964 [(set (match_operand:SI 0 "register_operand" "=a")
12965 (unspec:SI
12966 [(match_operand:SI 1 "register_operand" "b")
12967 (match_operand 2 "constant_call_address_operand" "z")]
12968 UNSPEC_TLS_LD_BASE))
12969 (clobber (match_scratch:SI 3 "=d"))
12970 (clobber (match_scratch:SI 4 "=c"))
12971 (clobber (reg:CC FLAGS_REG))]
12972 "!TARGET_64BIT && TARGET_GNU_TLS"
12973 {
12974 output_asm_insn
12975 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12976 if (TARGET_SUN_TLS)
12977 #ifdef HAVE_AS_IX86_TLSLDMPLT
12978 return "call\t%&@tlsldmplt";
12979 #else
12980 return "call\t%p2@plt";
12981 #endif
12982 return "call\t%P2";
12983 }
12984 [(set_attr "type" "multi")
12985 (set_attr "length" "11")])
12986
12987 (define_expand "tls_local_dynamic_base_32"
12988 [(parallel
12989 [(set (match_operand:SI 0 "register_operand")
12990 (unspec:SI
12991 [(match_operand:SI 1 "register_operand")
12992 (match_operand 2 "constant_call_address_operand")]
12993 UNSPEC_TLS_LD_BASE))
12994 (clobber (match_scratch:SI 3))
12995 (clobber (match_scratch:SI 4))
12996 (clobber (reg:CC FLAGS_REG))])])
12997
12998 (define_insn "*tls_local_dynamic_base_64_<mode>"
12999 [(set (match_operand:P 0 "register_operand" "=a")
13000 (call:P
13001 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
13002 (match_operand 2)))
13003 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13004 "TARGET_64BIT"
13005 {
13006 output_asm_insn
13007 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13008 if (TARGET_SUN_TLS)
13009 return "call\t%p1@plt";
13010 return "call\t%P1";
13011 }
13012 [(set_attr "type" "multi")
13013 (set_attr "length" "12")])
13014
13015 (define_expand "tls_local_dynamic_base_64_<mode>"
13016 [(parallel
13017 [(set (match_operand:P 0 "register_operand")
13018 (call:P
13019 (mem:QI (match_operand 1 "constant_call_address_operand"))
13020 (const_int 0)))
13021 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13022 "TARGET_64BIT")
13023
13024 ;; Local dynamic of a single variable is a lose. Show combine how
13025 ;; to convert that back to global dynamic.
13026
13027 (define_insn_and_split "*tls_local_dynamic_32_once"
13028 [(set (match_operand:SI 0 "register_operand" "=a")
13029 (plus:SI
13030 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13031 (match_operand 2 "constant_call_address_operand" "z")]
13032 UNSPEC_TLS_LD_BASE)
13033 (const:SI (unspec:SI
13034 [(match_operand 3 "tls_symbolic_operand")]
13035 UNSPEC_DTPOFF))))
13036 (clobber (match_scratch:SI 4 "=d"))
13037 (clobber (match_scratch:SI 5 "=c"))
13038 (clobber (reg:CC FLAGS_REG))]
13039 ""
13040 "#"
13041 ""
13042 [(parallel
13043 [(set (match_dup 0)
13044 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13045 UNSPEC_TLS_GD))
13046 (clobber (match_dup 4))
13047 (clobber (match_dup 5))
13048 (clobber (reg:CC FLAGS_REG))])])
13049
13050 ;; Segment register for the thread base ptr load
13051 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13052
13053 ;; Load and add the thread base pointer from %<tp_seg>:0.
13054 (define_insn "*load_tp_x32"
13055 [(set (match_operand:SI 0 "register_operand" "=r")
13056 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13057 "TARGET_X32"
13058 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13059 [(set_attr "type" "imov")
13060 (set_attr "modrm" "0")
13061 (set_attr "length" "7")
13062 (set_attr "memory" "load")
13063 (set_attr "imm_disp" "false")])
13064
13065 (define_insn "*load_tp_x32_zext"
13066 [(set (match_operand:DI 0 "register_operand" "=r")
13067 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13068 "TARGET_X32"
13069 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13070 [(set_attr "type" "imov")
13071 (set_attr "modrm" "0")
13072 (set_attr "length" "7")
13073 (set_attr "memory" "load")
13074 (set_attr "imm_disp" "false")])
13075
13076 (define_insn "*load_tp_<mode>"
13077 [(set (match_operand:P 0 "register_operand" "=r")
13078 (unspec:P [(const_int 0)] UNSPEC_TP))]
13079 "!TARGET_X32"
13080 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13081 [(set_attr "type" "imov")
13082 (set_attr "modrm" "0")
13083 (set_attr "length" "7")
13084 (set_attr "memory" "load")
13085 (set_attr "imm_disp" "false")])
13086
13087 (define_insn "*add_tp_x32"
13088 [(set (match_operand:SI 0 "register_operand" "=r")
13089 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13090 (match_operand:SI 1 "register_operand" "0")))
13091 (clobber (reg:CC FLAGS_REG))]
13092 "TARGET_X32"
13093 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13094 [(set_attr "type" "alu")
13095 (set_attr "modrm" "0")
13096 (set_attr "length" "7")
13097 (set_attr "memory" "load")
13098 (set_attr "imm_disp" "false")])
13099
13100 (define_insn "*add_tp_x32_zext"
13101 [(set (match_operand:DI 0 "register_operand" "=r")
13102 (zero_extend:DI
13103 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13104 (match_operand:SI 1 "register_operand" "0"))))
13105 (clobber (reg:CC FLAGS_REG))]
13106 "TARGET_X32"
13107 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13108 [(set_attr "type" "alu")
13109 (set_attr "modrm" "0")
13110 (set_attr "length" "7")
13111 (set_attr "memory" "load")
13112 (set_attr "imm_disp" "false")])
13113
13114 (define_insn "*add_tp_<mode>"
13115 [(set (match_operand:P 0 "register_operand" "=r")
13116 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13117 (match_operand:P 1 "register_operand" "0")))
13118 (clobber (reg:CC FLAGS_REG))]
13119 "!TARGET_X32"
13120 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13121 [(set_attr "type" "alu")
13122 (set_attr "modrm" "0")
13123 (set_attr "length" "7")
13124 (set_attr "memory" "load")
13125 (set_attr "imm_disp" "false")])
13126
13127 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13128 ;; %rax as destination of the initial executable code sequence.
13129 (define_insn "tls_initial_exec_64_sun"
13130 [(set (match_operand:DI 0 "register_operand" "=a")
13131 (unspec:DI
13132 [(match_operand 1 "tls_symbolic_operand")]
13133 UNSPEC_TLS_IE_SUN))
13134 (clobber (reg:CC FLAGS_REG))]
13135 "TARGET_64BIT && TARGET_SUN_TLS"
13136 {
13137 output_asm_insn
13138 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13139 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13140 }
13141 [(set_attr "type" "multi")])
13142
13143 ;; GNU2 TLS patterns can be split.
13144
13145 (define_expand "tls_dynamic_gnu2_32"
13146 [(set (match_dup 3)
13147 (plus:SI (match_operand:SI 2 "register_operand")
13148 (const:SI
13149 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13150 UNSPEC_TLSDESC))))
13151 (parallel
13152 [(set (match_operand:SI 0 "register_operand")
13153 (unspec:SI [(match_dup 1) (match_dup 3)
13154 (match_dup 2) (reg:SI SP_REG)]
13155 UNSPEC_TLSDESC))
13156 (clobber (reg:CC FLAGS_REG))])]
13157 "!TARGET_64BIT && TARGET_GNU2_TLS"
13158 {
13159 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13160 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13161 })
13162
13163 (define_insn "*tls_dynamic_gnu2_lea_32"
13164 [(set (match_operand:SI 0 "register_operand" "=r")
13165 (plus:SI (match_operand:SI 1 "register_operand" "b")
13166 (const:SI
13167 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13168 UNSPEC_TLSDESC))))]
13169 "!TARGET_64BIT && TARGET_GNU2_TLS"
13170 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13171 [(set_attr "type" "lea")
13172 (set_attr "mode" "SI")
13173 (set_attr "length" "6")
13174 (set_attr "length_address" "4")])
13175
13176 (define_insn "*tls_dynamic_gnu2_call_32"
13177 [(set (match_operand:SI 0 "register_operand" "=a")
13178 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13179 (match_operand:SI 2 "register_operand" "0")
13180 ;; we have to make sure %ebx still points to the GOT
13181 (match_operand:SI 3 "register_operand" "b")
13182 (reg:SI SP_REG)]
13183 UNSPEC_TLSDESC))
13184 (clobber (reg:CC FLAGS_REG))]
13185 "!TARGET_64BIT && TARGET_GNU2_TLS"
13186 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13187 [(set_attr "type" "call")
13188 (set_attr "length" "2")
13189 (set_attr "length_address" "0")])
13190
13191 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13192 [(set (match_operand:SI 0 "register_operand" "=&a")
13193 (plus:SI
13194 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13195 (match_operand:SI 4)
13196 (match_operand:SI 2 "register_operand" "b")
13197 (reg:SI SP_REG)]
13198 UNSPEC_TLSDESC)
13199 (const:SI (unspec:SI
13200 [(match_operand 1 "tls_symbolic_operand")]
13201 UNSPEC_DTPOFF))))
13202 (clobber (reg:CC FLAGS_REG))]
13203 "!TARGET_64BIT && TARGET_GNU2_TLS"
13204 "#"
13205 ""
13206 [(set (match_dup 0) (match_dup 5))]
13207 {
13208 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13209 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13210 })
13211
13212 (define_expand "tls_dynamic_gnu2_64"
13213 [(set (match_dup 2)
13214 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13215 UNSPEC_TLSDESC))
13216 (parallel
13217 [(set (match_operand:DI 0 "register_operand")
13218 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13219 UNSPEC_TLSDESC))
13220 (clobber (reg:CC FLAGS_REG))])]
13221 "TARGET_64BIT && TARGET_GNU2_TLS"
13222 {
13223 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13224 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13225 })
13226
13227 (define_insn "*tls_dynamic_gnu2_lea_64"
13228 [(set (match_operand:DI 0 "register_operand" "=r")
13229 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13230 UNSPEC_TLSDESC))]
13231 "TARGET_64BIT && TARGET_GNU2_TLS"
13232 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13233 [(set_attr "type" "lea")
13234 (set_attr "mode" "DI")
13235 (set_attr "length" "7")
13236 (set_attr "length_address" "4")])
13237
13238 (define_insn "*tls_dynamic_gnu2_call_64"
13239 [(set (match_operand:DI 0 "register_operand" "=a")
13240 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13241 (match_operand:DI 2 "register_operand" "0")
13242 (reg:DI SP_REG)]
13243 UNSPEC_TLSDESC))
13244 (clobber (reg:CC FLAGS_REG))]
13245 "TARGET_64BIT && TARGET_GNU2_TLS"
13246 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13247 [(set_attr "type" "call")
13248 (set_attr "length" "2")
13249 (set_attr "length_address" "0")])
13250
13251 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13252 [(set (match_operand:DI 0 "register_operand" "=&a")
13253 (plus:DI
13254 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13255 (match_operand:DI 3)
13256 (reg:DI SP_REG)]
13257 UNSPEC_TLSDESC)
13258 (const:DI (unspec:DI
13259 [(match_operand 1 "tls_symbolic_operand")]
13260 UNSPEC_DTPOFF))))
13261 (clobber (reg:CC FLAGS_REG))]
13262 "TARGET_64BIT && TARGET_GNU2_TLS"
13263 "#"
13264 ""
13265 [(set (match_dup 0) (match_dup 4))]
13266 {
13267 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13268 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13269 })
13270 \f
13271 ;; These patterns match the binary 387 instructions for addM3, subM3,
13272 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13273 ;; SFmode. The first is the normal insn, the second the same insn but
13274 ;; with one operand a conversion, and the third the same insn but with
13275 ;; the other operand a conversion. The conversion may be SFmode or
13276 ;; SImode if the target mode DFmode, but only SImode if the target mode
13277 ;; is SFmode.
13278
13279 ;; Gcc is slightly more smart about handling normal two address instructions
13280 ;; so use special patterns for add and mull.
13281
13282 (define_insn "*fop_<mode>_comm_mixed"
13283 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13284 (match_operator:MODEF 3 "binary_fp_operator"
13285 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13286 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13287 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13288 && COMMUTATIVE_ARITH_P (operands[3])
13289 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13290 "* return output_387_binary_op (insn, operands);"
13291 [(set (attr "type")
13292 (if_then_else (eq_attr "alternative" "1,2")
13293 (if_then_else (match_operand:MODEF 3 "mult_operator")
13294 (const_string "ssemul")
13295 (const_string "sseadd"))
13296 (if_then_else (match_operand:MODEF 3 "mult_operator")
13297 (const_string "fmul")
13298 (const_string "fop"))))
13299 (set_attr "isa" "*,noavx,avx")
13300 (set_attr "prefix" "orig,orig,vex")
13301 (set_attr "mode" "<MODE>")])
13302
13303 (define_insn "*fop_<mode>_comm_sse"
13304 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13305 (match_operator:MODEF 3 "binary_fp_operator"
13306 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13307 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13308 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13309 && COMMUTATIVE_ARITH_P (operands[3])
13310 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13311 "* return output_387_binary_op (insn, operands);"
13312 [(set (attr "type")
13313 (if_then_else (match_operand:MODEF 3 "mult_operator")
13314 (const_string "ssemul")
13315 (const_string "sseadd")))
13316 (set_attr "isa" "noavx,avx")
13317 (set_attr "prefix" "orig,vex")
13318 (set_attr "mode" "<MODE>")])
13319
13320 (define_insn "*fop_<mode>_comm_i387"
13321 [(set (match_operand:MODEF 0 "register_operand" "=f")
13322 (match_operator:MODEF 3 "binary_fp_operator"
13323 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13324 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13325 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13326 && COMMUTATIVE_ARITH_P (operands[3])
13327 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13328 "* return output_387_binary_op (insn, operands);"
13329 [(set (attr "type")
13330 (if_then_else (match_operand:MODEF 3 "mult_operator")
13331 (const_string "fmul")
13332 (const_string "fop")))
13333 (set_attr "mode" "<MODE>")])
13334
13335 (define_insn "*fop_<mode>_1_mixed"
13336 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13337 (match_operator:MODEF 3 "binary_fp_operator"
13338 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13339 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13340 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13341 && !COMMUTATIVE_ARITH_P (operands[3])
13342 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13343 "* return output_387_binary_op (insn, operands);"
13344 [(set (attr "type")
13345 (cond [(and (eq_attr "alternative" "2,3")
13346 (match_operand:MODEF 3 "mult_operator"))
13347 (const_string "ssemul")
13348 (and (eq_attr "alternative" "2,3")
13349 (match_operand:MODEF 3 "div_operator"))
13350 (const_string "ssediv")
13351 (eq_attr "alternative" "2,3")
13352 (const_string "sseadd")
13353 (match_operand:MODEF 3 "mult_operator")
13354 (const_string "fmul")
13355 (match_operand:MODEF 3 "div_operator")
13356 (const_string "fdiv")
13357 ]
13358 (const_string "fop")))
13359 (set_attr "isa" "*,*,noavx,avx")
13360 (set_attr "prefix" "orig,orig,orig,vex")
13361 (set_attr "mode" "<MODE>")])
13362
13363 (define_insn "*rcpsf2_sse"
13364 [(set (match_operand:SF 0 "register_operand" "=x")
13365 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13366 UNSPEC_RCP))]
13367 "TARGET_SSE_MATH"
13368 "%vrcpss\t{%1, %d0|%d0, %1}"
13369 [(set_attr "type" "sse")
13370 (set_attr "atom_sse_attr" "rcp")
13371 (set_attr "prefix" "maybe_vex")
13372 (set_attr "mode" "SF")])
13373
13374 (define_insn "*fop_<mode>_1_sse"
13375 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13376 (match_operator:MODEF 3 "binary_fp_operator"
13377 [(match_operand:MODEF 1 "register_operand" "0,x")
13378 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13379 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13380 && !COMMUTATIVE_ARITH_P (operands[3])"
13381 "* return output_387_binary_op (insn, operands);"
13382 [(set (attr "type")
13383 (cond [(match_operand:MODEF 3 "mult_operator")
13384 (const_string "ssemul")
13385 (match_operand:MODEF 3 "div_operator")
13386 (const_string "ssediv")
13387 ]
13388 (const_string "sseadd")))
13389 (set_attr "isa" "noavx,avx")
13390 (set_attr "prefix" "orig,vex")
13391 (set_attr "mode" "<MODE>")])
13392
13393 ;; This pattern is not fully shadowed by the pattern above.
13394 (define_insn "*fop_<mode>_1_i387"
13395 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13396 (match_operator:MODEF 3 "binary_fp_operator"
13397 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13398 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13399 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13400 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13401 && !COMMUTATIVE_ARITH_P (operands[3])
13402 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13403 "* return output_387_binary_op (insn, operands);"
13404 [(set (attr "type")
13405 (cond [(match_operand:MODEF 3 "mult_operator")
13406 (const_string "fmul")
13407 (match_operand:MODEF 3 "div_operator")
13408 (const_string "fdiv")
13409 ]
13410 (const_string "fop")))
13411 (set_attr "mode" "<MODE>")])
13412
13413 ;; ??? Add SSE splitters for these!
13414 (define_insn "*fop_<MODEF:mode>_2_i387"
13415 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13416 (match_operator:MODEF 3 "binary_fp_operator"
13417 [(float:MODEF
13418 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13419 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13420 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13421 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13422 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13423 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13424 [(set (attr "type")
13425 (cond [(match_operand:MODEF 3 "mult_operator")
13426 (const_string "fmul")
13427 (match_operand:MODEF 3 "div_operator")
13428 (const_string "fdiv")
13429 ]
13430 (const_string "fop")))
13431 (set_attr "fp_int_src" "true")
13432 (set_attr "mode" "<SWI24:MODE>")])
13433
13434 (define_insn "*fop_<MODEF:mode>_3_i387"
13435 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13436 (match_operator:MODEF 3 "binary_fp_operator"
13437 [(match_operand:MODEF 1 "register_operand" "0,0")
13438 (float:MODEF
13439 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13440 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13441 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13442 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13443 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13444 [(set (attr "type")
13445 (cond [(match_operand:MODEF 3 "mult_operator")
13446 (const_string "fmul")
13447 (match_operand:MODEF 3 "div_operator")
13448 (const_string "fdiv")
13449 ]
13450 (const_string "fop")))
13451 (set_attr "fp_int_src" "true")
13452 (set_attr "mode" "<MODE>")])
13453
13454 (define_insn "*fop_df_4_i387"
13455 [(set (match_operand:DF 0 "register_operand" "=f,f")
13456 (match_operator:DF 3 "binary_fp_operator"
13457 [(float_extend:DF
13458 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13459 (match_operand:DF 2 "register_operand" "0,f")]))]
13460 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13461 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13462 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13463 "* return output_387_binary_op (insn, operands);"
13464 [(set (attr "type")
13465 (cond [(match_operand:DF 3 "mult_operator")
13466 (const_string "fmul")
13467 (match_operand:DF 3 "div_operator")
13468 (const_string "fdiv")
13469 ]
13470 (const_string "fop")))
13471 (set_attr "mode" "SF")])
13472
13473 (define_insn "*fop_df_5_i387"
13474 [(set (match_operand:DF 0 "register_operand" "=f,f")
13475 (match_operator:DF 3 "binary_fp_operator"
13476 [(match_operand:DF 1 "register_operand" "0,f")
13477 (float_extend:DF
13478 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13479 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13480 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13481 "* return output_387_binary_op (insn, operands);"
13482 [(set (attr "type")
13483 (cond [(match_operand:DF 3 "mult_operator")
13484 (const_string "fmul")
13485 (match_operand:DF 3 "div_operator")
13486 (const_string "fdiv")
13487 ]
13488 (const_string "fop")))
13489 (set_attr "mode" "SF")])
13490
13491 (define_insn "*fop_df_6_i387"
13492 [(set (match_operand:DF 0 "register_operand" "=f,f")
13493 (match_operator:DF 3 "binary_fp_operator"
13494 [(float_extend:DF
13495 (match_operand:SF 1 "register_operand" "0,f"))
13496 (float_extend:DF
13497 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13498 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13499 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13500 "* return output_387_binary_op (insn, operands);"
13501 [(set (attr "type")
13502 (cond [(match_operand:DF 3 "mult_operator")
13503 (const_string "fmul")
13504 (match_operand:DF 3 "div_operator")
13505 (const_string "fdiv")
13506 ]
13507 (const_string "fop")))
13508 (set_attr "mode" "SF")])
13509
13510 (define_insn "*fop_xf_comm_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f")
13512 (match_operator:XF 3 "binary_fp_operator"
13513 [(match_operand:XF 1 "register_operand" "%0")
13514 (match_operand:XF 2 "register_operand" "f")]))]
13515 "TARGET_80387
13516 && COMMUTATIVE_ARITH_P (operands[3])"
13517 "* return output_387_binary_op (insn, operands);"
13518 [(set (attr "type")
13519 (if_then_else (match_operand:XF 3 "mult_operator")
13520 (const_string "fmul")
13521 (const_string "fop")))
13522 (set_attr "mode" "XF")])
13523
13524 (define_insn "*fop_xf_1_i387"
13525 [(set (match_operand:XF 0 "register_operand" "=f,f")
13526 (match_operator:XF 3 "binary_fp_operator"
13527 [(match_operand:XF 1 "register_operand" "0,f")
13528 (match_operand:XF 2 "register_operand" "f,0")]))]
13529 "TARGET_80387
13530 && !COMMUTATIVE_ARITH_P (operands[3])"
13531 "* return output_387_binary_op (insn, operands);"
13532 [(set (attr "type")
13533 (cond [(match_operand:XF 3 "mult_operator")
13534 (const_string "fmul")
13535 (match_operand:XF 3 "div_operator")
13536 (const_string "fdiv")
13537 ]
13538 (const_string "fop")))
13539 (set_attr "mode" "XF")])
13540
13541 (define_insn "*fop_xf_2_i387"
13542 [(set (match_operand:XF 0 "register_operand" "=f,f")
13543 (match_operator:XF 3 "binary_fp_operator"
13544 [(float:XF
13545 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13546 (match_operand:XF 2 "register_operand" "0,0")]))]
13547 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13548 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13549 [(set (attr "type")
13550 (cond [(match_operand:XF 3 "mult_operator")
13551 (const_string "fmul")
13552 (match_operand:XF 3 "div_operator")
13553 (const_string "fdiv")
13554 ]
13555 (const_string "fop")))
13556 (set_attr "fp_int_src" "true")
13557 (set_attr "mode" "<MODE>")])
13558
13559 (define_insn "*fop_xf_3_i387"
13560 [(set (match_operand:XF 0 "register_operand" "=f,f")
13561 (match_operator:XF 3 "binary_fp_operator"
13562 [(match_operand:XF 1 "register_operand" "0,0")
13563 (float:XF
13564 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13565 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13566 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13567 [(set (attr "type")
13568 (cond [(match_operand:XF 3 "mult_operator")
13569 (const_string "fmul")
13570 (match_operand:XF 3 "div_operator")
13571 (const_string "fdiv")
13572 ]
13573 (const_string "fop")))
13574 (set_attr "fp_int_src" "true")
13575 (set_attr "mode" "<MODE>")])
13576
13577 (define_insn "*fop_xf_4_i387"
13578 [(set (match_operand:XF 0 "register_operand" "=f,f")
13579 (match_operator:XF 3 "binary_fp_operator"
13580 [(float_extend:XF
13581 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13582 (match_operand:XF 2 "register_operand" "0,f")]))]
13583 "TARGET_80387"
13584 "* return output_387_binary_op (insn, operands);"
13585 [(set (attr "type")
13586 (cond [(match_operand:XF 3 "mult_operator")
13587 (const_string "fmul")
13588 (match_operand:XF 3 "div_operator")
13589 (const_string "fdiv")
13590 ]
13591 (const_string "fop")))
13592 (set_attr "mode" "<MODE>")])
13593
13594 (define_insn "*fop_xf_5_i387"
13595 [(set (match_operand:XF 0 "register_operand" "=f,f")
13596 (match_operator:XF 3 "binary_fp_operator"
13597 [(match_operand:XF 1 "register_operand" "0,f")
13598 (float_extend:XF
13599 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13600 "TARGET_80387"
13601 "* return output_387_binary_op (insn, operands);"
13602 [(set (attr "type")
13603 (cond [(match_operand:XF 3 "mult_operator")
13604 (const_string "fmul")
13605 (match_operand:XF 3 "div_operator")
13606 (const_string "fdiv")
13607 ]
13608 (const_string "fop")))
13609 (set_attr "mode" "<MODE>")])
13610
13611 (define_insn "*fop_xf_6_i387"
13612 [(set (match_operand:XF 0 "register_operand" "=f,f")
13613 (match_operator:XF 3 "binary_fp_operator"
13614 [(float_extend:XF
13615 (match_operand:MODEF 1 "register_operand" "0,f"))
13616 (float_extend:XF
13617 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13618 "TARGET_80387"
13619 "* return output_387_binary_op (insn, operands);"
13620 [(set (attr "type")
13621 (cond [(match_operand:XF 3 "mult_operator")
13622 (const_string "fmul")
13623 (match_operand:XF 3 "div_operator")
13624 (const_string "fdiv")
13625 ]
13626 (const_string "fop")))
13627 (set_attr "mode" "<MODE>")])
13628
13629 (define_split
13630 [(set (match_operand 0 "register_operand")
13631 (match_operator 3 "binary_fp_operator"
13632 [(float (match_operand:SWI24 1 "register_operand"))
13633 (match_operand 2 "register_operand")]))]
13634 "reload_completed
13635 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13636 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13637 [(const_int 0)]
13638 {
13639 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13640 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13641 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13642 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13643 GET_MODE (operands[3]),
13644 operands[4],
13645 operands[2])));
13646 ix86_free_from_memory (GET_MODE (operands[1]));
13647 DONE;
13648 })
13649
13650 (define_split
13651 [(set (match_operand 0 "register_operand")
13652 (match_operator 3 "binary_fp_operator"
13653 [(match_operand 1 "register_operand")
13654 (float (match_operand:SWI24 2 "register_operand"))]))]
13655 "reload_completed
13656 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13657 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13658 [(const_int 0)]
13659 {
13660 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13661 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13662 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13663 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13664 GET_MODE (operands[3]),
13665 operands[1],
13666 operands[4])));
13667 ix86_free_from_memory (GET_MODE (operands[2]));
13668 DONE;
13669 })
13670 \f
13671 ;; FPU special functions.
13672
13673 ;; This pattern implements a no-op XFmode truncation for
13674 ;; all fancy i386 XFmode math functions.
13675
13676 (define_insn "truncxf<mode>2_i387_noop_unspec"
13677 [(set (match_operand:MODEF 0 "register_operand" "=f")
13678 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13679 UNSPEC_TRUNC_NOOP))]
13680 "TARGET_USE_FANCY_MATH_387"
13681 "* return output_387_reg_move (insn, operands);"
13682 [(set_attr "type" "fmov")
13683 (set_attr "mode" "<MODE>")])
13684
13685 (define_insn "sqrtxf2"
13686 [(set (match_operand:XF 0 "register_operand" "=f")
13687 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13688 "TARGET_USE_FANCY_MATH_387"
13689 "fsqrt"
13690 [(set_attr "type" "fpspc")
13691 (set_attr "mode" "XF")
13692 (set_attr "athlon_decode" "direct")
13693 (set_attr "amdfam10_decode" "direct")
13694 (set_attr "bdver1_decode" "direct")])
13695
13696 (define_insn "sqrt_extend<mode>xf2_i387"
13697 [(set (match_operand:XF 0 "register_operand" "=f")
13698 (sqrt:XF
13699 (float_extend:XF
13700 (match_operand:MODEF 1 "register_operand" "0"))))]
13701 "TARGET_USE_FANCY_MATH_387"
13702 "fsqrt"
13703 [(set_attr "type" "fpspc")
13704 (set_attr "mode" "XF")
13705 (set_attr "athlon_decode" "direct")
13706 (set_attr "amdfam10_decode" "direct")
13707 (set_attr "bdver1_decode" "direct")])
13708
13709 (define_insn "*rsqrtsf2_sse"
13710 [(set (match_operand:SF 0 "register_operand" "=x")
13711 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13712 UNSPEC_RSQRT))]
13713 "TARGET_SSE_MATH"
13714 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13715 [(set_attr "type" "sse")
13716 (set_attr "atom_sse_attr" "rcp")
13717 (set_attr "prefix" "maybe_vex")
13718 (set_attr "mode" "SF")])
13719
13720 (define_expand "rsqrtsf2"
13721 [(set (match_operand:SF 0 "register_operand")
13722 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13723 UNSPEC_RSQRT))]
13724 "TARGET_SSE_MATH"
13725 {
13726 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13727 DONE;
13728 })
13729
13730 (define_insn "*sqrt<mode>2_sse"
13731 [(set (match_operand:MODEF 0 "register_operand" "=x")
13732 (sqrt:MODEF
13733 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13734 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13735 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13736 [(set_attr "type" "sse")
13737 (set_attr "atom_sse_attr" "sqrt")
13738 (set_attr "prefix" "maybe_vex")
13739 (set_attr "mode" "<MODE>")
13740 (set_attr "athlon_decode" "*")
13741 (set_attr "amdfam10_decode" "*")
13742 (set_attr "bdver1_decode" "*")])
13743
13744 (define_expand "sqrt<mode>2"
13745 [(set (match_operand:MODEF 0 "register_operand")
13746 (sqrt:MODEF
13747 (match_operand:MODEF 1 "nonimmediate_operand")))]
13748 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13749 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13750 {
13751 if (<MODE>mode == SFmode
13752 && TARGET_SSE_MATH
13753 && TARGET_RECIP_SQRT
13754 && !optimize_function_for_size_p (cfun)
13755 && flag_finite_math_only && !flag_trapping_math
13756 && flag_unsafe_math_optimizations)
13757 {
13758 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13759 DONE;
13760 }
13761
13762 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13763 {
13764 rtx op0 = gen_reg_rtx (XFmode);
13765 rtx op1 = force_reg (<MODE>mode, operands[1]);
13766
13767 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13768 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13769 DONE;
13770 }
13771 })
13772
13773 (define_insn "fpremxf4_i387"
13774 [(set (match_operand:XF 0 "register_operand" "=f")
13775 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13776 (match_operand:XF 3 "register_operand" "1")]
13777 UNSPEC_FPREM_F))
13778 (set (match_operand:XF 1 "register_operand" "=u")
13779 (unspec:XF [(match_dup 2) (match_dup 3)]
13780 UNSPEC_FPREM_U))
13781 (set (reg:CCFP FPSR_REG)
13782 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13783 UNSPEC_C2_FLAG))]
13784 "TARGET_USE_FANCY_MATH_387"
13785 "fprem"
13786 [(set_attr "type" "fpspc")
13787 (set_attr "mode" "XF")])
13788
13789 (define_expand "fmodxf3"
13790 [(use (match_operand:XF 0 "register_operand"))
13791 (use (match_operand:XF 1 "general_operand"))
13792 (use (match_operand:XF 2 "general_operand"))]
13793 "TARGET_USE_FANCY_MATH_387"
13794 {
13795 rtx label = gen_label_rtx ();
13796
13797 rtx op1 = gen_reg_rtx (XFmode);
13798 rtx op2 = gen_reg_rtx (XFmode);
13799
13800 emit_move_insn (op2, operands[2]);
13801 emit_move_insn (op1, operands[1]);
13802
13803 emit_label (label);
13804 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13805 ix86_emit_fp_unordered_jump (label);
13806 LABEL_NUSES (label) = 1;
13807
13808 emit_move_insn (operands[0], op1);
13809 DONE;
13810 })
13811
13812 (define_expand "fmod<mode>3"
13813 [(use (match_operand:MODEF 0 "register_operand"))
13814 (use (match_operand:MODEF 1 "general_operand"))
13815 (use (match_operand:MODEF 2 "general_operand"))]
13816 "TARGET_USE_FANCY_MATH_387"
13817 {
13818 rtx (*gen_truncxf) (rtx, rtx);
13819
13820 rtx label = gen_label_rtx ();
13821
13822 rtx op1 = gen_reg_rtx (XFmode);
13823 rtx op2 = gen_reg_rtx (XFmode);
13824
13825 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13826 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13827
13828 emit_label (label);
13829 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13830 ix86_emit_fp_unordered_jump (label);
13831 LABEL_NUSES (label) = 1;
13832
13833 /* Truncate the result properly for strict SSE math. */
13834 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13835 && !TARGET_MIX_SSE_I387)
13836 gen_truncxf = gen_truncxf<mode>2;
13837 else
13838 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13839
13840 emit_insn (gen_truncxf (operands[0], op1));
13841 DONE;
13842 })
13843
13844 (define_insn "fprem1xf4_i387"
13845 [(set (match_operand:XF 0 "register_operand" "=f")
13846 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13847 (match_operand:XF 3 "register_operand" "1")]
13848 UNSPEC_FPREM1_F))
13849 (set (match_operand:XF 1 "register_operand" "=u")
13850 (unspec:XF [(match_dup 2) (match_dup 3)]
13851 UNSPEC_FPREM1_U))
13852 (set (reg:CCFP FPSR_REG)
13853 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13854 UNSPEC_C2_FLAG))]
13855 "TARGET_USE_FANCY_MATH_387"
13856 "fprem1"
13857 [(set_attr "type" "fpspc")
13858 (set_attr "mode" "XF")])
13859
13860 (define_expand "remainderxf3"
13861 [(use (match_operand:XF 0 "register_operand"))
13862 (use (match_operand:XF 1 "general_operand"))
13863 (use (match_operand:XF 2 "general_operand"))]
13864 "TARGET_USE_FANCY_MATH_387"
13865 {
13866 rtx label = gen_label_rtx ();
13867
13868 rtx op1 = gen_reg_rtx (XFmode);
13869 rtx op2 = gen_reg_rtx (XFmode);
13870
13871 emit_move_insn (op2, operands[2]);
13872 emit_move_insn (op1, operands[1]);
13873
13874 emit_label (label);
13875 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13876 ix86_emit_fp_unordered_jump (label);
13877 LABEL_NUSES (label) = 1;
13878
13879 emit_move_insn (operands[0], op1);
13880 DONE;
13881 })
13882
13883 (define_expand "remainder<mode>3"
13884 [(use (match_operand:MODEF 0 "register_operand"))
13885 (use (match_operand:MODEF 1 "general_operand"))
13886 (use (match_operand:MODEF 2 "general_operand"))]
13887 "TARGET_USE_FANCY_MATH_387"
13888 {
13889 rtx (*gen_truncxf) (rtx, rtx);
13890
13891 rtx label = gen_label_rtx ();
13892
13893 rtx op1 = gen_reg_rtx (XFmode);
13894 rtx op2 = gen_reg_rtx (XFmode);
13895
13896 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13897 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13898
13899 emit_label (label);
13900
13901 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13902 ix86_emit_fp_unordered_jump (label);
13903 LABEL_NUSES (label) = 1;
13904
13905 /* Truncate the result properly for strict SSE math. */
13906 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13907 && !TARGET_MIX_SSE_I387)
13908 gen_truncxf = gen_truncxf<mode>2;
13909 else
13910 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13911
13912 emit_insn (gen_truncxf (operands[0], op1));
13913 DONE;
13914 })
13915
13916 (define_int_iterator SINCOS
13917 [UNSPEC_SIN
13918 UNSPEC_COS])
13919
13920 (define_int_attr sincos
13921 [(UNSPEC_SIN "sin")
13922 (UNSPEC_COS "cos")])
13923
13924 (define_insn "*<sincos>xf2_i387"
13925 [(set (match_operand:XF 0 "register_operand" "=f")
13926 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13927 SINCOS))]
13928 "TARGET_USE_FANCY_MATH_387
13929 && flag_unsafe_math_optimizations"
13930 "f<sincos>"
13931 [(set_attr "type" "fpspc")
13932 (set_attr "mode" "XF")])
13933
13934 (define_insn "*<sincos>_extend<mode>xf2_i387"
13935 [(set (match_operand:XF 0 "register_operand" "=f")
13936 (unspec:XF [(float_extend:XF
13937 (match_operand:MODEF 1 "register_operand" "0"))]
13938 SINCOS))]
13939 "TARGET_USE_FANCY_MATH_387
13940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13941 || TARGET_MIX_SSE_I387)
13942 && flag_unsafe_math_optimizations"
13943 "f<sincos>"
13944 [(set_attr "type" "fpspc")
13945 (set_attr "mode" "XF")])
13946
13947 ;; When sincos pattern is defined, sin and cos builtin functions will be
13948 ;; expanded to sincos pattern with one of its outputs left unused.
13949 ;; CSE pass will figure out if two sincos patterns can be combined,
13950 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13951 ;; depending on the unused output.
13952
13953 (define_insn "sincosxf3"
13954 [(set (match_operand:XF 0 "register_operand" "=f")
13955 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13956 UNSPEC_SINCOS_COS))
13957 (set (match_operand:XF 1 "register_operand" "=u")
13958 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13959 "TARGET_USE_FANCY_MATH_387
13960 && flag_unsafe_math_optimizations"
13961 "fsincos"
13962 [(set_attr "type" "fpspc")
13963 (set_attr "mode" "XF")])
13964
13965 (define_split
13966 [(set (match_operand:XF 0 "register_operand")
13967 (unspec:XF [(match_operand:XF 2 "register_operand")]
13968 UNSPEC_SINCOS_COS))
13969 (set (match_operand:XF 1 "register_operand")
13970 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13971 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13972 && can_create_pseudo_p ()"
13973 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13974
13975 (define_split
13976 [(set (match_operand:XF 0 "register_operand")
13977 (unspec:XF [(match_operand:XF 2 "register_operand")]
13978 UNSPEC_SINCOS_COS))
13979 (set (match_operand:XF 1 "register_operand")
13980 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13981 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13982 && can_create_pseudo_p ()"
13983 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13984
13985 (define_insn "sincos_extend<mode>xf3_i387"
13986 [(set (match_operand:XF 0 "register_operand" "=f")
13987 (unspec:XF [(float_extend:XF
13988 (match_operand:MODEF 2 "register_operand" "0"))]
13989 UNSPEC_SINCOS_COS))
13990 (set (match_operand:XF 1 "register_operand" "=u")
13991 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13992 "TARGET_USE_FANCY_MATH_387
13993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13994 || TARGET_MIX_SSE_I387)
13995 && flag_unsafe_math_optimizations"
13996 "fsincos"
13997 [(set_attr "type" "fpspc")
13998 (set_attr "mode" "XF")])
13999
14000 (define_split
14001 [(set (match_operand:XF 0 "register_operand")
14002 (unspec:XF [(float_extend:XF
14003 (match_operand:MODEF 2 "register_operand"))]
14004 UNSPEC_SINCOS_COS))
14005 (set (match_operand:XF 1 "register_operand")
14006 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14007 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14008 && can_create_pseudo_p ()"
14009 [(set (match_dup 1)
14010 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14011
14012 (define_split
14013 [(set (match_operand:XF 0 "register_operand")
14014 (unspec:XF [(float_extend:XF
14015 (match_operand:MODEF 2 "register_operand"))]
14016 UNSPEC_SINCOS_COS))
14017 (set (match_operand:XF 1 "register_operand")
14018 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14019 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14020 && can_create_pseudo_p ()"
14021 [(set (match_dup 0)
14022 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14023
14024 (define_expand "sincos<mode>3"
14025 [(use (match_operand:MODEF 0 "register_operand"))
14026 (use (match_operand:MODEF 1 "register_operand"))
14027 (use (match_operand:MODEF 2 "register_operand"))]
14028 "TARGET_USE_FANCY_MATH_387
14029 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14030 || TARGET_MIX_SSE_I387)
14031 && flag_unsafe_math_optimizations"
14032 {
14033 rtx op0 = gen_reg_rtx (XFmode);
14034 rtx op1 = gen_reg_rtx (XFmode);
14035
14036 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14037 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14038 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14039 DONE;
14040 })
14041
14042 (define_insn "fptanxf4_i387"
14043 [(set (match_operand:XF 0 "register_operand" "=f")
14044 (match_operand:XF 3 "const_double_operand" "F"))
14045 (set (match_operand:XF 1 "register_operand" "=u")
14046 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14047 UNSPEC_TAN))]
14048 "TARGET_USE_FANCY_MATH_387
14049 && flag_unsafe_math_optimizations
14050 && standard_80387_constant_p (operands[3]) == 2"
14051 "fptan"
14052 [(set_attr "type" "fpspc")
14053 (set_attr "mode" "XF")])
14054
14055 (define_insn "fptan_extend<mode>xf4_i387"
14056 [(set (match_operand:MODEF 0 "register_operand" "=f")
14057 (match_operand:MODEF 3 "const_double_operand" "F"))
14058 (set (match_operand:XF 1 "register_operand" "=u")
14059 (unspec:XF [(float_extend:XF
14060 (match_operand:MODEF 2 "register_operand" "0"))]
14061 UNSPEC_TAN))]
14062 "TARGET_USE_FANCY_MATH_387
14063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14064 || TARGET_MIX_SSE_I387)
14065 && flag_unsafe_math_optimizations
14066 && standard_80387_constant_p (operands[3]) == 2"
14067 "fptan"
14068 [(set_attr "type" "fpspc")
14069 (set_attr "mode" "XF")])
14070
14071 (define_expand "tanxf2"
14072 [(use (match_operand:XF 0 "register_operand"))
14073 (use (match_operand:XF 1 "register_operand"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && flag_unsafe_math_optimizations"
14076 {
14077 rtx one = gen_reg_rtx (XFmode);
14078 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14079
14080 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14081 DONE;
14082 })
14083
14084 (define_expand "tan<mode>2"
14085 [(use (match_operand:MODEF 0 "register_operand"))
14086 (use (match_operand:MODEF 1 "register_operand"))]
14087 "TARGET_USE_FANCY_MATH_387
14088 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14089 || TARGET_MIX_SSE_I387)
14090 && flag_unsafe_math_optimizations"
14091 {
14092 rtx op0 = gen_reg_rtx (XFmode);
14093
14094 rtx one = gen_reg_rtx (<MODE>mode);
14095 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14096
14097 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14098 operands[1], op2));
14099 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14100 DONE;
14101 })
14102
14103 (define_insn "*fpatanxf3_i387"
14104 [(set (match_operand:XF 0 "register_operand" "=f")
14105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14106 (match_operand:XF 2 "register_operand" "u")]
14107 UNSPEC_FPATAN))
14108 (clobber (match_scratch:XF 3 "=2"))]
14109 "TARGET_USE_FANCY_MATH_387
14110 && flag_unsafe_math_optimizations"
14111 "fpatan"
14112 [(set_attr "type" "fpspc")
14113 (set_attr "mode" "XF")])
14114
14115 (define_insn "fpatan_extend<mode>xf3_i387"
14116 [(set (match_operand:XF 0 "register_operand" "=f")
14117 (unspec:XF [(float_extend:XF
14118 (match_operand:MODEF 1 "register_operand" "0"))
14119 (float_extend:XF
14120 (match_operand:MODEF 2 "register_operand" "u"))]
14121 UNSPEC_FPATAN))
14122 (clobber (match_scratch:XF 3 "=2"))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125 || TARGET_MIX_SSE_I387)
14126 && flag_unsafe_math_optimizations"
14127 "fpatan"
14128 [(set_attr "type" "fpspc")
14129 (set_attr "mode" "XF")])
14130
14131 (define_expand "atan2xf3"
14132 [(parallel [(set (match_operand:XF 0 "register_operand")
14133 (unspec:XF [(match_operand:XF 2 "register_operand")
14134 (match_operand:XF 1 "register_operand")]
14135 UNSPEC_FPATAN))
14136 (clobber (match_scratch:XF 3))])]
14137 "TARGET_USE_FANCY_MATH_387
14138 && flag_unsafe_math_optimizations")
14139
14140 (define_expand "atan2<mode>3"
14141 [(use (match_operand:MODEF 0 "register_operand"))
14142 (use (match_operand:MODEF 1 "register_operand"))
14143 (use (match_operand:MODEF 2 "register_operand"))]
14144 "TARGET_USE_FANCY_MATH_387
14145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14146 || TARGET_MIX_SSE_I387)
14147 && flag_unsafe_math_optimizations"
14148 {
14149 rtx op0 = gen_reg_rtx (XFmode);
14150
14151 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14152 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14153 DONE;
14154 })
14155
14156 (define_expand "atanxf2"
14157 [(parallel [(set (match_operand:XF 0 "register_operand")
14158 (unspec:XF [(match_dup 2)
14159 (match_operand:XF 1 "register_operand")]
14160 UNSPEC_FPATAN))
14161 (clobber (match_scratch:XF 3))])]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14164 {
14165 operands[2] = gen_reg_rtx (XFmode);
14166 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14167 })
14168
14169 (define_expand "atan<mode>2"
14170 [(use (match_operand:MODEF 0 "register_operand"))
14171 (use (match_operand:MODEF 1 "register_operand"))]
14172 "TARGET_USE_FANCY_MATH_387
14173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14174 || TARGET_MIX_SSE_I387)
14175 && flag_unsafe_math_optimizations"
14176 {
14177 rtx op0 = gen_reg_rtx (XFmode);
14178
14179 rtx op2 = gen_reg_rtx (<MODE>mode);
14180 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14181
14182 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14183 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14184 DONE;
14185 })
14186
14187 (define_expand "asinxf2"
14188 [(set (match_dup 2)
14189 (mult:XF (match_operand:XF 1 "register_operand")
14190 (match_dup 1)))
14191 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14192 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14193 (parallel [(set (match_operand:XF 0 "register_operand")
14194 (unspec:XF [(match_dup 5) (match_dup 1)]
14195 UNSPEC_FPATAN))
14196 (clobber (match_scratch:XF 6))])]
14197 "TARGET_USE_FANCY_MATH_387
14198 && flag_unsafe_math_optimizations"
14199 {
14200 int i;
14201
14202 if (optimize_insn_for_size_p ())
14203 FAIL;
14204
14205 for (i = 2; i < 6; i++)
14206 operands[i] = gen_reg_rtx (XFmode);
14207
14208 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14209 })
14210
14211 (define_expand "asin<mode>2"
14212 [(use (match_operand:MODEF 0 "register_operand"))
14213 (use (match_operand:MODEF 1 "general_operand"))]
14214 "TARGET_USE_FANCY_MATH_387
14215 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14216 || TARGET_MIX_SSE_I387)
14217 && flag_unsafe_math_optimizations"
14218 {
14219 rtx op0 = gen_reg_rtx (XFmode);
14220 rtx op1 = gen_reg_rtx (XFmode);
14221
14222 if (optimize_insn_for_size_p ())
14223 FAIL;
14224
14225 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14226 emit_insn (gen_asinxf2 (op0, op1));
14227 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14228 DONE;
14229 })
14230
14231 (define_expand "acosxf2"
14232 [(set (match_dup 2)
14233 (mult:XF (match_operand:XF 1 "register_operand")
14234 (match_dup 1)))
14235 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14236 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14237 (parallel [(set (match_operand:XF 0 "register_operand")
14238 (unspec:XF [(match_dup 1) (match_dup 5)]
14239 UNSPEC_FPATAN))
14240 (clobber (match_scratch:XF 6))])]
14241 "TARGET_USE_FANCY_MATH_387
14242 && flag_unsafe_math_optimizations"
14243 {
14244 int i;
14245
14246 if (optimize_insn_for_size_p ())
14247 FAIL;
14248
14249 for (i = 2; i < 6; i++)
14250 operands[i] = gen_reg_rtx (XFmode);
14251
14252 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14253 })
14254
14255 (define_expand "acos<mode>2"
14256 [(use (match_operand:MODEF 0 "register_operand"))
14257 (use (match_operand:MODEF 1 "general_operand"))]
14258 "TARGET_USE_FANCY_MATH_387
14259 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14260 || TARGET_MIX_SSE_I387)
14261 && flag_unsafe_math_optimizations"
14262 {
14263 rtx op0 = gen_reg_rtx (XFmode);
14264 rtx op1 = gen_reg_rtx (XFmode);
14265
14266 if (optimize_insn_for_size_p ())
14267 FAIL;
14268
14269 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14270 emit_insn (gen_acosxf2 (op0, op1));
14271 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14272 DONE;
14273 })
14274
14275 (define_insn "fyl2xxf3_i387"
14276 [(set (match_operand:XF 0 "register_operand" "=f")
14277 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14278 (match_operand:XF 2 "register_operand" "u")]
14279 UNSPEC_FYL2X))
14280 (clobber (match_scratch:XF 3 "=2"))]
14281 "TARGET_USE_FANCY_MATH_387
14282 && flag_unsafe_math_optimizations"
14283 "fyl2x"
14284 [(set_attr "type" "fpspc")
14285 (set_attr "mode" "XF")])
14286
14287 (define_insn "fyl2x_extend<mode>xf3_i387"
14288 [(set (match_operand:XF 0 "register_operand" "=f")
14289 (unspec:XF [(float_extend:XF
14290 (match_operand:MODEF 1 "register_operand" "0"))
14291 (match_operand:XF 2 "register_operand" "u")]
14292 UNSPEC_FYL2X))
14293 (clobber (match_scratch:XF 3 "=2"))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14298 "fyl2x"
14299 [(set_attr "type" "fpspc")
14300 (set_attr "mode" "XF")])
14301
14302 (define_expand "logxf2"
14303 [(parallel [(set (match_operand:XF 0 "register_operand")
14304 (unspec:XF [(match_operand:XF 1 "register_operand")
14305 (match_dup 2)] UNSPEC_FYL2X))
14306 (clobber (match_scratch:XF 3))])]
14307 "TARGET_USE_FANCY_MATH_387
14308 && flag_unsafe_math_optimizations"
14309 {
14310 operands[2] = gen_reg_rtx (XFmode);
14311 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14312 })
14313
14314 (define_expand "log<mode>2"
14315 [(use (match_operand:MODEF 0 "register_operand"))
14316 (use (match_operand:MODEF 1 "register_operand"))]
14317 "TARGET_USE_FANCY_MATH_387
14318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14319 || TARGET_MIX_SSE_I387)
14320 && flag_unsafe_math_optimizations"
14321 {
14322 rtx op0 = gen_reg_rtx (XFmode);
14323
14324 rtx op2 = gen_reg_rtx (XFmode);
14325 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14326
14327 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14328 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14329 DONE;
14330 })
14331
14332 (define_expand "log10xf2"
14333 [(parallel [(set (match_operand:XF 0 "register_operand")
14334 (unspec:XF [(match_operand:XF 1 "register_operand")
14335 (match_dup 2)] UNSPEC_FYL2X))
14336 (clobber (match_scratch:XF 3))])]
14337 "TARGET_USE_FANCY_MATH_387
14338 && flag_unsafe_math_optimizations"
14339 {
14340 operands[2] = gen_reg_rtx (XFmode);
14341 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14342 })
14343
14344 (define_expand "log10<mode>2"
14345 [(use (match_operand:MODEF 0 "register_operand"))
14346 (use (match_operand:MODEF 1 "register_operand"))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349 || TARGET_MIX_SSE_I387)
14350 && flag_unsafe_math_optimizations"
14351 {
14352 rtx op0 = gen_reg_rtx (XFmode);
14353
14354 rtx op2 = gen_reg_rtx (XFmode);
14355 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14356
14357 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14358 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14359 DONE;
14360 })
14361
14362 (define_expand "log2xf2"
14363 [(parallel [(set (match_operand:XF 0 "register_operand")
14364 (unspec:XF [(match_operand:XF 1 "register_operand")
14365 (match_dup 2)] UNSPEC_FYL2X))
14366 (clobber (match_scratch:XF 3))])]
14367 "TARGET_USE_FANCY_MATH_387
14368 && flag_unsafe_math_optimizations"
14369 {
14370 operands[2] = gen_reg_rtx (XFmode);
14371 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14372 })
14373
14374 (define_expand "log2<mode>2"
14375 [(use (match_operand:MODEF 0 "register_operand"))
14376 (use (match_operand:MODEF 1 "register_operand"))]
14377 "TARGET_USE_FANCY_MATH_387
14378 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14379 || TARGET_MIX_SSE_I387)
14380 && flag_unsafe_math_optimizations"
14381 {
14382 rtx op0 = gen_reg_rtx (XFmode);
14383
14384 rtx op2 = gen_reg_rtx (XFmode);
14385 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14386
14387 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14388 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14389 DONE;
14390 })
14391
14392 (define_insn "fyl2xp1xf3_i387"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14395 (match_operand:XF 2 "register_operand" "u")]
14396 UNSPEC_FYL2XP1))
14397 (clobber (match_scratch:XF 3 "=2"))]
14398 "TARGET_USE_FANCY_MATH_387
14399 && flag_unsafe_math_optimizations"
14400 "fyl2xp1"
14401 [(set_attr "type" "fpspc")
14402 (set_attr "mode" "XF")])
14403
14404 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14405 [(set (match_operand:XF 0 "register_operand" "=f")
14406 (unspec:XF [(float_extend:XF
14407 (match_operand:MODEF 1 "register_operand" "0"))
14408 (match_operand:XF 2 "register_operand" "u")]
14409 UNSPEC_FYL2XP1))
14410 (clobber (match_scratch:XF 3 "=2"))]
14411 "TARGET_USE_FANCY_MATH_387
14412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14413 || TARGET_MIX_SSE_I387)
14414 && flag_unsafe_math_optimizations"
14415 "fyl2xp1"
14416 [(set_attr "type" "fpspc")
14417 (set_attr "mode" "XF")])
14418
14419 (define_expand "log1pxf2"
14420 [(use (match_operand:XF 0 "register_operand"))
14421 (use (match_operand:XF 1 "register_operand"))]
14422 "TARGET_USE_FANCY_MATH_387
14423 && flag_unsafe_math_optimizations"
14424 {
14425 if (optimize_insn_for_size_p ())
14426 FAIL;
14427
14428 ix86_emit_i387_log1p (operands[0], operands[1]);
14429 DONE;
14430 })
14431
14432 (define_expand "log1p<mode>2"
14433 [(use (match_operand:MODEF 0 "register_operand"))
14434 (use (match_operand:MODEF 1 "register_operand"))]
14435 "TARGET_USE_FANCY_MATH_387
14436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14437 || TARGET_MIX_SSE_I387)
14438 && flag_unsafe_math_optimizations"
14439 {
14440 rtx op0;
14441
14442 if (optimize_insn_for_size_p ())
14443 FAIL;
14444
14445 op0 = gen_reg_rtx (XFmode);
14446
14447 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14448
14449 ix86_emit_i387_log1p (op0, operands[1]);
14450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14451 DONE;
14452 })
14453
14454 (define_insn "fxtractxf3_i387"
14455 [(set (match_operand:XF 0 "register_operand" "=f")
14456 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14457 UNSPEC_XTRACT_FRACT))
14458 (set (match_operand:XF 1 "register_operand" "=u")
14459 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14460 "TARGET_USE_FANCY_MATH_387
14461 && flag_unsafe_math_optimizations"
14462 "fxtract"
14463 [(set_attr "type" "fpspc")
14464 (set_attr "mode" "XF")])
14465
14466 (define_insn "fxtract_extend<mode>xf3_i387"
14467 [(set (match_operand:XF 0 "register_operand" "=f")
14468 (unspec:XF [(float_extend:XF
14469 (match_operand:MODEF 2 "register_operand" "0"))]
14470 UNSPEC_XTRACT_FRACT))
14471 (set (match_operand:XF 1 "register_operand" "=u")
14472 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14473 "TARGET_USE_FANCY_MATH_387
14474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14475 || TARGET_MIX_SSE_I387)
14476 && flag_unsafe_math_optimizations"
14477 "fxtract"
14478 [(set_attr "type" "fpspc")
14479 (set_attr "mode" "XF")])
14480
14481 (define_expand "logbxf2"
14482 [(parallel [(set (match_dup 2)
14483 (unspec:XF [(match_operand:XF 1 "register_operand")]
14484 UNSPEC_XTRACT_FRACT))
14485 (set (match_operand:XF 0 "register_operand")
14486 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14487 "TARGET_USE_FANCY_MATH_387
14488 && flag_unsafe_math_optimizations"
14489 "operands[2] = gen_reg_rtx (XFmode);")
14490
14491 (define_expand "logb<mode>2"
14492 [(use (match_operand:MODEF 0 "register_operand"))
14493 (use (match_operand:MODEF 1 "register_operand"))]
14494 "TARGET_USE_FANCY_MATH_387
14495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14496 || TARGET_MIX_SSE_I387)
14497 && flag_unsafe_math_optimizations"
14498 {
14499 rtx op0 = gen_reg_rtx (XFmode);
14500 rtx op1 = gen_reg_rtx (XFmode);
14501
14502 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14504 DONE;
14505 })
14506
14507 (define_expand "ilogbxf2"
14508 [(use (match_operand:SI 0 "register_operand"))
14509 (use (match_operand:XF 1 "register_operand"))]
14510 "TARGET_USE_FANCY_MATH_387
14511 && flag_unsafe_math_optimizations"
14512 {
14513 rtx op0, op1;
14514
14515 if (optimize_insn_for_size_p ())
14516 FAIL;
14517
14518 op0 = gen_reg_rtx (XFmode);
14519 op1 = gen_reg_rtx (XFmode);
14520
14521 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14522 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14523 DONE;
14524 })
14525
14526 (define_expand "ilogb<mode>2"
14527 [(use (match_operand:SI 0 "register_operand"))
14528 (use (match_operand:MODEF 1 "register_operand"))]
14529 "TARGET_USE_FANCY_MATH_387
14530 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14531 || TARGET_MIX_SSE_I387)
14532 && flag_unsafe_math_optimizations"
14533 {
14534 rtx op0, op1;
14535
14536 if (optimize_insn_for_size_p ())
14537 FAIL;
14538
14539 op0 = gen_reg_rtx (XFmode);
14540 op1 = gen_reg_rtx (XFmode);
14541
14542 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14543 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14544 DONE;
14545 })
14546
14547 (define_insn "*f2xm1xf2_i387"
14548 [(set (match_operand:XF 0 "register_operand" "=f")
14549 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14550 UNSPEC_F2XM1))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14553 "f2xm1"
14554 [(set_attr "type" "fpspc")
14555 (set_attr "mode" "XF")])
14556
14557 (define_insn "*fscalexf4_i387"
14558 [(set (match_operand:XF 0 "register_operand" "=f")
14559 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14560 (match_operand:XF 3 "register_operand" "1")]
14561 UNSPEC_FSCALE_FRACT))
14562 (set (match_operand:XF 1 "register_operand" "=u")
14563 (unspec:XF [(match_dup 2) (match_dup 3)]
14564 UNSPEC_FSCALE_EXP))]
14565 "TARGET_USE_FANCY_MATH_387
14566 && flag_unsafe_math_optimizations"
14567 "fscale"
14568 [(set_attr "type" "fpspc")
14569 (set_attr "mode" "XF")])
14570
14571 (define_expand "expNcorexf3"
14572 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14573 (match_operand:XF 2 "register_operand")))
14574 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14575 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14576 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14577 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14578 (parallel [(set (match_operand:XF 0 "register_operand")
14579 (unspec:XF [(match_dup 8) (match_dup 4)]
14580 UNSPEC_FSCALE_FRACT))
14581 (set (match_dup 9)
14582 (unspec:XF [(match_dup 8) (match_dup 4)]
14583 UNSPEC_FSCALE_EXP))])]
14584 "TARGET_USE_FANCY_MATH_387
14585 && flag_unsafe_math_optimizations"
14586 {
14587 int i;
14588
14589 if (optimize_insn_for_size_p ())
14590 FAIL;
14591
14592 for (i = 3; i < 10; i++)
14593 operands[i] = gen_reg_rtx (XFmode);
14594
14595 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14596 })
14597
14598 (define_expand "expxf2"
14599 [(use (match_operand:XF 0 "register_operand"))
14600 (use (match_operand:XF 1 "register_operand"))]
14601 "TARGET_USE_FANCY_MATH_387
14602 && flag_unsafe_math_optimizations"
14603 {
14604 rtx op2;
14605
14606 if (optimize_insn_for_size_p ())
14607 FAIL;
14608
14609 op2 = gen_reg_rtx (XFmode);
14610 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14611
14612 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14613 DONE;
14614 })
14615
14616 (define_expand "exp<mode>2"
14617 [(use (match_operand:MODEF 0 "register_operand"))
14618 (use (match_operand:MODEF 1 "general_operand"))]
14619 "TARGET_USE_FANCY_MATH_387
14620 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14621 || TARGET_MIX_SSE_I387)
14622 && flag_unsafe_math_optimizations"
14623 {
14624 rtx op0, op1;
14625
14626 if (optimize_insn_for_size_p ())
14627 FAIL;
14628
14629 op0 = gen_reg_rtx (XFmode);
14630 op1 = gen_reg_rtx (XFmode);
14631
14632 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14633 emit_insn (gen_expxf2 (op0, op1));
14634 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14635 DONE;
14636 })
14637
14638 (define_expand "exp10xf2"
14639 [(use (match_operand:XF 0 "register_operand"))
14640 (use (match_operand:XF 1 "register_operand"))]
14641 "TARGET_USE_FANCY_MATH_387
14642 && flag_unsafe_math_optimizations"
14643 {
14644 rtx op2;
14645
14646 if (optimize_insn_for_size_p ())
14647 FAIL;
14648
14649 op2 = gen_reg_rtx (XFmode);
14650 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14651
14652 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14653 DONE;
14654 })
14655
14656 (define_expand "exp10<mode>2"
14657 [(use (match_operand:MODEF 0 "register_operand"))
14658 (use (match_operand:MODEF 1 "general_operand"))]
14659 "TARGET_USE_FANCY_MATH_387
14660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14661 || TARGET_MIX_SSE_I387)
14662 && flag_unsafe_math_optimizations"
14663 {
14664 rtx op0, op1;
14665
14666 if (optimize_insn_for_size_p ())
14667 FAIL;
14668
14669 op0 = gen_reg_rtx (XFmode);
14670 op1 = gen_reg_rtx (XFmode);
14671
14672 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14673 emit_insn (gen_exp10xf2 (op0, op1));
14674 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14675 DONE;
14676 })
14677
14678 (define_expand "exp2xf2"
14679 [(use (match_operand:XF 0 "register_operand"))
14680 (use (match_operand:XF 1 "register_operand"))]
14681 "TARGET_USE_FANCY_MATH_387
14682 && flag_unsafe_math_optimizations"
14683 {
14684 rtx op2;
14685
14686 if (optimize_insn_for_size_p ())
14687 FAIL;
14688
14689 op2 = gen_reg_rtx (XFmode);
14690 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14691
14692 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14693 DONE;
14694 })
14695
14696 (define_expand "exp2<mode>2"
14697 [(use (match_operand:MODEF 0 "register_operand"))
14698 (use (match_operand:MODEF 1 "general_operand"))]
14699 "TARGET_USE_FANCY_MATH_387
14700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14701 || TARGET_MIX_SSE_I387)
14702 && flag_unsafe_math_optimizations"
14703 {
14704 rtx op0, op1;
14705
14706 if (optimize_insn_for_size_p ())
14707 FAIL;
14708
14709 op0 = gen_reg_rtx (XFmode);
14710 op1 = gen_reg_rtx (XFmode);
14711
14712 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14713 emit_insn (gen_exp2xf2 (op0, op1));
14714 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14715 DONE;
14716 })
14717
14718 (define_expand "expm1xf2"
14719 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14720 (match_dup 2)))
14721 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14722 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14723 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14724 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14725 (parallel [(set (match_dup 7)
14726 (unspec:XF [(match_dup 6) (match_dup 4)]
14727 UNSPEC_FSCALE_FRACT))
14728 (set (match_dup 8)
14729 (unspec:XF [(match_dup 6) (match_dup 4)]
14730 UNSPEC_FSCALE_EXP))])
14731 (parallel [(set (match_dup 10)
14732 (unspec:XF [(match_dup 9) (match_dup 8)]
14733 UNSPEC_FSCALE_FRACT))
14734 (set (match_dup 11)
14735 (unspec:XF [(match_dup 9) (match_dup 8)]
14736 UNSPEC_FSCALE_EXP))])
14737 (set (match_dup 12) (minus:XF (match_dup 10)
14738 (float_extend:XF (match_dup 13))))
14739 (set (match_operand:XF 0 "register_operand")
14740 (plus:XF (match_dup 12) (match_dup 7)))]
14741 "TARGET_USE_FANCY_MATH_387
14742 && flag_unsafe_math_optimizations"
14743 {
14744 int i;
14745
14746 if (optimize_insn_for_size_p ())
14747 FAIL;
14748
14749 for (i = 2; i < 13; i++)
14750 operands[i] = gen_reg_rtx (XFmode);
14751
14752 operands[13]
14753 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14754
14755 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14756 })
14757
14758 (define_expand "expm1<mode>2"
14759 [(use (match_operand:MODEF 0 "register_operand"))
14760 (use (match_operand:MODEF 1 "general_operand"))]
14761 "TARGET_USE_FANCY_MATH_387
14762 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14763 || TARGET_MIX_SSE_I387)
14764 && flag_unsafe_math_optimizations"
14765 {
14766 rtx op0, op1;
14767
14768 if (optimize_insn_for_size_p ())
14769 FAIL;
14770
14771 op0 = gen_reg_rtx (XFmode);
14772 op1 = gen_reg_rtx (XFmode);
14773
14774 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14775 emit_insn (gen_expm1xf2 (op0, op1));
14776 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14777 DONE;
14778 })
14779
14780 (define_expand "ldexpxf3"
14781 [(set (match_dup 3)
14782 (float:XF (match_operand:SI 2 "register_operand")))
14783 (parallel [(set (match_operand:XF 0 " register_operand")
14784 (unspec:XF [(match_operand:XF 1 "register_operand")
14785 (match_dup 3)]
14786 UNSPEC_FSCALE_FRACT))
14787 (set (match_dup 4)
14788 (unspec:XF [(match_dup 1) (match_dup 3)]
14789 UNSPEC_FSCALE_EXP))])]
14790 "TARGET_USE_FANCY_MATH_387
14791 && flag_unsafe_math_optimizations"
14792 {
14793 if (optimize_insn_for_size_p ())
14794 FAIL;
14795
14796 operands[3] = gen_reg_rtx (XFmode);
14797 operands[4] = gen_reg_rtx (XFmode);
14798 })
14799
14800 (define_expand "ldexp<mode>3"
14801 [(use (match_operand:MODEF 0 "register_operand"))
14802 (use (match_operand:MODEF 1 "general_operand"))
14803 (use (match_operand:SI 2 "register_operand"))]
14804 "TARGET_USE_FANCY_MATH_387
14805 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14806 || TARGET_MIX_SSE_I387)
14807 && flag_unsafe_math_optimizations"
14808 {
14809 rtx op0, op1;
14810
14811 if (optimize_insn_for_size_p ())
14812 FAIL;
14813
14814 op0 = gen_reg_rtx (XFmode);
14815 op1 = gen_reg_rtx (XFmode);
14816
14817 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14818 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14819 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14820 DONE;
14821 })
14822
14823 (define_expand "scalbxf3"
14824 [(parallel [(set (match_operand:XF 0 " register_operand")
14825 (unspec:XF [(match_operand:XF 1 "register_operand")
14826 (match_operand:XF 2 "register_operand")]
14827 UNSPEC_FSCALE_FRACT))
14828 (set (match_dup 3)
14829 (unspec:XF [(match_dup 1) (match_dup 2)]
14830 UNSPEC_FSCALE_EXP))])]
14831 "TARGET_USE_FANCY_MATH_387
14832 && flag_unsafe_math_optimizations"
14833 {
14834 if (optimize_insn_for_size_p ())
14835 FAIL;
14836
14837 operands[3] = gen_reg_rtx (XFmode);
14838 })
14839
14840 (define_expand "scalb<mode>3"
14841 [(use (match_operand:MODEF 0 "register_operand"))
14842 (use (match_operand:MODEF 1 "general_operand"))
14843 (use (match_operand:MODEF 2 "general_operand"))]
14844 "TARGET_USE_FANCY_MATH_387
14845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14846 || TARGET_MIX_SSE_I387)
14847 && flag_unsafe_math_optimizations"
14848 {
14849 rtx op0, op1, op2;
14850
14851 if (optimize_insn_for_size_p ())
14852 FAIL;
14853
14854 op0 = gen_reg_rtx (XFmode);
14855 op1 = gen_reg_rtx (XFmode);
14856 op2 = gen_reg_rtx (XFmode);
14857
14858 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14859 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14860 emit_insn (gen_scalbxf3 (op0, op1, op2));
14861 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14862 DONE;
14863 })
14864
14865 (define_expand "significandxf2"
14866 [(parallel [(set (match_operand:XF 0 "register_operand")
14867 (unspec:XF [(match_operand:XF 1 "register_operand")]
14868 UNSPEC_XTRACT_FRACT))
14869 (set (match_dup 2)
14870 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14871 "TARGET_USE_FANCY_MATH_387
14872 && flag_unsafe_math_optimizations"
14873 "operands[2] = gen_reg_rtx (XFmode);")
14874
14875 (define_expand "significand<mode>2"
14876 [(use (match_operand:MODEF 0 "register_operand"))
14877 (use (match_operand:MODEF 1 "register_operand"))]
14878 "TARGET_USE_FANCY_MATH_387
14879 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14880 || TARGET_MIX_SSE_I387)
14881 && flag_unsafe_math_optimizations"
14882 {
14883 rtx op0 = gen_reg_rtx (XFmode);
14884 rtx op1 = gen_reg_rtx (XFmode);
14885
14886 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14887 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14888 DONE;
14889 })
14890 \f
14891
14892 (define_insn "sse4_1_round<mode>2"
14893 [(set (match_operand:MODEF 0 "register_operand" "=x")
14894 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14895 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14896 UNSPEC_ROUND))]
14897 "TARGET_ROUND"
14898 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14899 [(set_attr "type" "ssecvt")
14900 (set_attr "prefix_extra" "1")
14901 (set_attr "prefix" "maybe_vex")
14902 (set_attr "mode" "<MODE>")])
14903
14904 (define_insn "rintxf2"
14905 [(set (match_operand:XF 0 "register_operand" "=f")
14906 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14907 UNSPEC_FRNDINT))]
14908 "TARGET_USE_FANCY_MATH_387
14909 && flag_unsafe_math_optimizations"
14910 "frndint"
14911 [(set_attr "type" "fpspc")
14912 (set_attr "mode" "XF")])
14913
14914 (define_expand "rint<mode>2"
14915 [(use (match_operand:MODEF 0 "register_operand"))
14916 (use (match_operand:MODEF 1 "register_operand"))]
14917 "(TARGET_USE_FANCY_MATH_387
14918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14919 || TARGET_MIX_SSE_I387)
14920 && flag_unsafe_math_optimizations)
14921 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14922 && !flag_trapping_math)"
14923 {
14924 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14925 && !flag_trapping_math)
14926 {
14927 if (TARGET_ROUND)
14928 emit_insn (gen_sse4_1_round<mode>2
14929 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14930 else if (optimize_insn_for_size_p ())
14931 FAIL;
14932 else
14933 ix86_expand_rint (operands[0], operands[1]);
14934 }
14935 else
14936 {
14937 rtx op0 = gen_reg_rtx (XFmode);
14938 rtx op1 = gen_reg_rtx (XFmode);
14939
14940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14941 emit_insn (gen_rintxf2 (op0, op1));
14942
14943 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14944 }
14945 DONE;
14946 })
14947
14948 (define_expand "round<mode>2"
14949 [(match_operand:X87MODEF 0 "register_operand")
14950 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14951 "(TARGET_USE_FANCY_MATH_387
14952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14953 || TARGET_MIX_SSE_I387)
14954 && flag_unsafe_math_optimizations)
14955 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14956 && !flag_trapping_math && !flag_rounding_math)"
14957 {
14958 if (optimize_insn_for_size_p ())
14959 FAIL;
14960
14961 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14962 && !flag_trapping_math && !flag_rounding_math)
14963 {
14964 if (TARGET_ROUND)
14965 {
14966 operands[1] = force_reg (<MODE>mode, operands[1]);
14967 ix86_expand_round_sse4 (operands[0], operands[1]);
14968 }
14969 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14970 ix86_expand_round (operands[0], operands[1]);
14971 else
14972 ix86_expand_rounddf_32 (operands[0], operands[1]);
14973 }
14974 else
14975 {
14976 operands[1] = force_reg (<MODE>mode, operands[1]);
14977 ix86_emit_i387_round (operands[0], operands[1]);
14978 }
14979 DONE;
14980 })
14981
14982 (define_insn_and_split "*fistdi2_1"
14983 [(set (match_operand:DI 0 "nonimmediate_operand")
14984 (unspec:DI [(match_operand:XF 1 "register_operand")]
14985 UNSPEC_FIST))]
14986 "TARGET_USE_FANCY_MATH_387
14987 && can_create_pseudo_p ()"
14988 "#"
14989 "&& 1"
14990 [(const_int 0)]
14991 {
14992 if (memory_operand (operands[0], VOIDmode))
14993 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14994 else
14995 {
14996 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14997 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14998 operands[2]));
14999 }
15000 DONE;
15001 }
15002 [(set_attr "type" "fpspc")
15003 (set_attr "mode" "DI")])
15004
15005 (define_insn "fistdi2"
15006 [(set (match_operand:DI 0 "memory_operand" "=m")
15007 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15008 UNSPEC_FIST))
15009 (clobber (match_scratch:XF 2 "=&1f"))]
15010 "TARGET_USE_FANCY_MATH_387"
15011 "* return output_fix_trunc (insn, operands, false);"
15012 [(set_attr "type" "fpspc")
15013 (set_attr "mode" "DI")])
15014
15015 (define_insn "fistdi2_with_temp"
15016 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15017 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15018 UNSPEC_FIST))
15019 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15020 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15021 "TARGET_USE_FANCY_MATH_387"
15022 "#"
15023 [(set_attr "type" "fpspc")
15024 (set_attr "mode" "DI")])
15025
15026 (define_split
15027 [(set (match_operand:DI 0 "register_operand")
15028 (unspec:DI [(match_operand:XF 1 "register_operand")]
15029 UNSPEC_FIST))
15030 (clobber (match_operand:DI 2 "memory_operand"))
15031 (clobber (match_scratch 3))]
15032 "reload_completed"
15033 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15034 (clobber (match_dup 3))])
15035 (set (match_dup 0) (match_dup 2))])
15036
15037 (define_split
15038 [(set (match_operand:DI 0 "memory_operand")
15039 (unspec:DI [(match_operand:XF 1 "register_operand")]
15040 UNSPEC_FIST))
15041 (clobber (match_operand:DI 2 "memory_operand"))
15042 (clobber (match_scratch 3))]
15043 "reload_completed"
15044 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15045 (clobber (match_dup 3))])])
15046
15047 (define_insn_and_split "*fist<mode>2_1"
15048 [(set (match_operand:SWI24 0 "register_operand")
15049 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15050 UNSPEC_FIST))]
15051 "TARGET_USE_FANCY_MATH_387
15052 && can_create_pseudo_p ()"
15053 "#"
15054 "&& 1"
15055 [(const_int 0)]
15056 {
15057 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15058 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15059 operands[2]));
15060 DONE;
15061 }
15062 [(set_attr "type" "fpspc")
15063 (set_attr "mode" "<MODE>")])
15064
15065 (define_insn "fist<mode>2"
15066 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15067 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15068 UNSPEC_FIST))]
15069 "TARGET_USE_FANCY_MATH_387"
15070 "* return output_fix_trunc (insn, operands, false);"
15071 [(set_attr "type" "fpspc")
15072 (set_attr "mode" "<MODE>")])
15073
15074 (define_insn "fist<mode>2_with_temp"
15075 [(set (match_operand:SWI24 0 "register_operand" "=r")
15076 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15077 UNSPEC_FIST))
15078 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15079 "TARGET_USE_FANCY_MATH_387"
15080 "#"
15081 [(set_attr "type" "fpspc")
15082 (set_attr "mode" "<MODE>")])
15083
15084 (define_split
15085 [(set (match_operand:SWI24 0 "register_operand")
15086 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15087 UNSPEC_FIST))
15088 (clobber (match_operand:SWI24 2 "memory_operand"))]
15089 "reload_completed"
15090 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15091 (set (match_dup 0) (match_dup 2))])
15092
15093 (define_split
15094 [(set (match_operand:SWI24 0 "memory_operand")
15095 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15096 UNSPEC_FIST))
15097 (clobber (match_operand:SWI24 2 "memory_operand"))]
15098 "reload_completed"
15099 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15100
15101 (define_expand "lrintxf<mode>2"
15102 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15103 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15104 UNSPEC_FIST))]
15105 "TARGET_USE_FANCY_MATH_387")
15106
15107 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15108 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15109 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15110 UNSPEC_FIX_NOTRUNC))]
15111 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15112 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15113
15114 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15115 [(match_operand:SWI248x 0 "nonimmediate_operand")
15116 (match_operand:X87MODEF 1 "register_operand")]
15117 "(TARGET_USE_FANCY_MATH_387
15118 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15119 || TARGET_MIX_SSE_I387)
15120 && flag_unsafe_math_optimizations)
15121 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15122 && <SWI248x:MODE>mode != HImode
15123 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15124 && !flag_trapping_math && !flag_rounding_math)"
15125 {
15126 if (optimize_insn_for_size_p ())
15127 FAIL;
15128
15129 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15130 && <SWI248x:MODE>mode != HImode
15131 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15132 && !flag_trapping_math && !flag_rounding_math)
15133 ix86_expand_lround (operands[0], operands[1]);
15134 else
15135 ix86_emit_i387_round (operands[0], operands[1]);
15136 DONE;
15137 })
15138
15139 (define_int_iterator FRNDINT_ROUNDING
15140 [UNSPEC_FRNDINT_FLOOR
15141 UNSPEC_FRNDINT_CEIL
15142 UNSPEC_FRNDINT_TRUNC])
15143
15144 (define_int_iterator FIST_ROUNDING
15145 [UNSPEC_FIST_FLOOR
15146 UNSPEC_FIST_CEIL])
15147
15148 ;; Base name for define_insn
15149 (define_int_attr rounding_insn
15150 [(UNSPEC_FRNDINT_FLOOR "floor")
15151 (UNSPEC_FRNDINT_CEIL "ceil")
15152 (UNSPEC_FRNDINT_TRUNC "btrunc")
15153 (UNSPEC_FIST_FLOOR "floor")
15154 (UNSPEC_FIST_CEIL "ceil")])
15155
15156 (define_int_attr rounding
15157 [(UNSPEC_FRNDINT_FLOOR "floor")
15158 (UNSPEC_FRNDINT_CEIL "ceil")
15159 (UNSPEC_FRNDINT_TRUNC "trunc")
15160 (UNSPEC_FIST_FLOOR "floor")
15161 (UNSPEC_FIST_CEIL "ceil")])
15162
15163 (define_int_attr ROUNDING
15164 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15165 (UNSPEC_FRNDINT_CEIL "CEIL")
15166 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15167 (UNSPEC_FIST_FLOOR "FLOOR")
15168 (UNSPEC_FIST_CEIL "CEIL")])
15169
15170 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15171 (define_insn_and_split "frndintxf2_<rounding>"
15172 [(set (match_operand:XF 0 "register_operand")
15173 (unspec:XF [(match_operand:XF 1 "register_operand")]
15174 FRNDINT_ROUNDING))
15175 (clobber (reg:CC FLAGS_REG))]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations
15178 && can_create_pseudo_p ()"
15179 "#"
15180 "&& 1"
15181 [(const_int 0)]
15182 {
15183 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15184
15185 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15186 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15187
15188 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15189 operands[2], operands[3]));
15190 DONE;
15191 }
15192 [(set_attr "type" "frndint")
15193 (set_attr "i387_cw" "<rounding>")
15194 (set_attr "mode" "XF")])
15195
15196 (define_insn "frndintxf2_<rounding>_i387"
15197 [(set (match_operand:XF 0 "register_operand" "=f")
15198 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15199 FRNDINT_ROUNDING))
15200 (use (match_operand:HI 2 "memory_operand" "m"))
15201 (use (match_operand:HI 3 "memory_operand" "m"))]
15202 "TARGET_USE_FANCY_MATH_387
15203 && flag_unsafe_math_optimizations"
15204 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15205 [(set_attr "type" "frndint")
15206 (set_attr "i387_cw" "<rounding>")
15207 (set_attr "mode" "XF")])
15208
15209 (define_expand "<rounding_insn>xf2"
15210 [(parallel [(set (match_operand:XF 0 "register_operand")
15211 (unspec:XF [(match_operand:XF 1 "register_operand")]
15212 FRNDINT_ROUNDING))
15213 (clobber (reg:CC FLAGS_REG))])]
15214 "TARGET_USE_FANCY_MATH_387
15215 && flag_unsafe_math_optimizations
15216 && !optimize_insn_for_size_p ()")
15217
15218 (define_expand "<rounding_insn><mode>2"
15219 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15220 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15221 FRNDINT_ROUNDING))
15222 (clobber (reg:CC FLAGS_REG))])]
15223 "(TARGET_USE_FANCY_MATH_387
15224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15225 || TARGET_MIX_SSE_I387)
15226 && flag_unsafe_math_optimizations)
15227 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15228 && !flag_trapping_math)"
15229 {
15230 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15231 && !flag_trapping_math)
15232 {
15233 if (TARGET_ROUND)
15234 emit_insn (gen_sse4_1_round<mode>2
15235 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15236 else if (optimize_insn_for_size_p ())
15237 FAIL;
15238 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15239 {
15240 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15241 ix86_expand_floorceil (operands[0], operands[1], true);
15242 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15243 ix86_expand_floorceil (operands[0], operands[1], false);
15244 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15245 ix86_expand_trunc (operands[0], operands[1]);
15246 else
15247 gcc_unreachable ();
15248 }
15249 else
15250 {
15251 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15252 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15253 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15254 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15255 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15256 ix86_expand_truncdf_32 (operands[0], operands[1]);
15257 else
15258 gcc_unreachable ();
15259 }
15260 }
15261 else
15262 {
15263 rtx op0, op1;
15264
15265 if (optimize_insn_for_size_p ())
15266 FAIL;
15267
15268 op0 = gen_reg_rtx (XFmode);
15269 op1 = gen_reg_rtx (XFmode);
15270 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15271 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15272
15273 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15274 }
15275 DONE;
15276 })
15277
15278 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15279 (define_insn_and_split "frndintxf2_mask_pm"
15280 [(set (match_operand:XF 0 "register_operand")
15281 (unspec:XF [(match_operand:XF 1 "register_operand")]
15282 UNSPEC_FRNDINT_MASK_PM))
15283 (clobber (reg:CC FLAGS_REG))]
15284 "TARGET_USE_FANCY_MATH_387
15285 && flag_unsafe_math_optimizations
15286 && can_create_pseudo_p ()"
15287 "#"
15288 "&& 1"
15289 [(const_int 0)]
15290 {
15291 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15292
15293 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15294 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15295
15296 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15297 operands[2], operands[3]));
15298 DONE;
15299 }
15300 [(set_attr "type" "frndint")
15301 (set_attr "i387_cw" "mask_pm")
15302 (set_attr "mode" "XF")])
15303
15304 (define_insn "frndintxf2_mask_pm_i387"
15305 [(set (match_operand:XF 0 "register_operand" "=f")
15306 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15307 UNSPEC_FRNDINT_MASK_PM))
15308 (use (match_operand:HI 2 "memory_operand" "m"))
15309 (use (match_operand:HI 3 "memory_operand" "m"))]
15310 "TARGET_USE_FANCY_MATH_387
15311 && flag_unsafe_math_optimizations"
15312 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15313 [(set_attr "type" "frndint")
15314 (set_attr "i387_cw" "mask_pm")
15315 (set_attr "mode" "XF")])
15316
15317 (define_expand "nearbyintxf2"
15318 [(parallel [(set (match_operand:XF 0 "register_operand")
15319 (unspec:XF [(match_operand:XF 1 "register_operand")]
15320 UNSPEC_FRNDINT_MASK_PM))
15321 (clobber (reg:CC FLAGS_REG))])]
15322 "TARGET_USE_FANCY_MATH_387
15323 && flag_unsafe_math_optimizations")
15324
15325 (define_expand "nearbyint<mode>2"
15326 [(use (match_operand:MODEF 0 "register_operand"))
15327 (use (match_operand:MODEF 1 "register_operand"))]
15328 "TARGET_USE_FANCY_MATH_387
15329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15330 || TARGET_MIX_SSE_I387)
15331 && flag_unsafe_math_optimizations"
15332 {
15333 rtx op0 = gen_reg_rtx (XFmode);
15334 rtx op1 = gen_reg_rtx (XFmode);
15335
15336 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15337 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15338
15339 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15340 DONE;
15341 })
15342
15343 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15344 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15345 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15346 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15347 FIST_ROUNDING))
15348 (clobber (reg:CC FLAGS_REG))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && flag_unsafe_math_optimizations
15351 && can_create_pseudo_p ()"
15352 "#"
15353 "&& 1"
15354 [(const_int 0)]
15355 {
15356 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15357
15358 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15359 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15360 if (memory_operand (operands[0], VOIDmode))
15361 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15362 operands[2], operands[3]));
15363 else
15364 {
15365 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15366 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15367 (operands[0], operands[1], operands[2],
15368 operands[3], operands[4]));
15369 }
15370 DONE;
15371 }
15372 [(set_attr "type" "fistp")
15373 (set_attr "i387_cw" "<rounding>")
15374 (set_attr "mode" "<MODE>")])
15375
15376 (define_insn "fistdi2_<rounding>"
15377 [(set (match_operand:DI 0 "memory_operand" "=m")
15378 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15379 FIST_ROUNDING))
15380 (use (match_operand:HI 2 "memory_operand" "m"))
15381 (use (match_operand:HI 3 "memory_operand" "m"))
15382 (clobber (match_scratch:XF 4 "=&1f"))]
15383 "TARGET_USE_FANCY_MATH_387
15384 && flag_unsafe_math_optimizations"
15385 "* return output_fix_trunc (insn, operands, false);"
15386 [(set_attr "type" "fistp")
15387 (set_attr "i387_cw" "<rounding>")
15388 (set_attr "mode" "DI")])
15389
15390 (define_insn "fistdi2_<rounding>_with_temp"
15391 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15392 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15393 FIST_ROUNDING))
15394 (use (match_operand:HI 2 "memory_operand" "m,m"))
15395 (use (match_operand:HI 3 "memory_operand" "m,m"))
15396 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15397 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && flag_unsafe_math_optimizations"
15400 "#"
15401 [(set_attr "type" "fistp")
15402 (set_attr "i387_cw" "<rounding>")
15403 (set_attr "mode" "DI")])
15404
15405 (define_split
15406 [(set (match_operand:DI 0 "register_operand")
15407 (unspec:DI [(match_operand:XF 1 "register_operand")]
15408 FIST_ROUNDING))
15409 (use (match_operand:HI 2 "memory_operand"))
15410 (use (match_operand:HI 3 "memory_operand"))
15411 (clobber (match_operand:DI 4 "memory_operand"))
15412 (clobber (match_scratch 5))]
15413 "reload_completed"
15414 [(parallel [(set (match_dup 4)
15415 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15416 (use (match_dup 2))
15417 (use (match_dup 3))
15418 (clobber (match_dup 5))])
15419 (set (match_dup 0) (match_dup 4))])
15420
15421 (define_split
15422 [(set (match_operand:DI 0 "memory_operand")
15423 (unspec:DI [(match_operand:XF 1 "register_operand")]
15424 FIST_ROUNDING))
15425 (use (match_operand:HI 2 "memory_operand"))
15426 (use (match_operand:HI 3 "memory_operand"))
15427 (clobber (match_operand:DI 4 "memory_operand"))
15428 (clobber (match_scratch 5))]
15429 "reload_completed"
15430 [(parallel [(set (match_dup 0)
15431 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15432 (use (match_dup 2))
15433 (use (match_dup 3))
15434 (clobber (match_dup 5))])])
15435
15436 (define_insn "fist<mode>2_<rounding>"
15437 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15438 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15439 FIST_ROUNDING))
15440 (use (match_operand:HI 2 "memory_operand" "m"))
15441 (use (match_operand:HI 3 "memory_operand" "m"))]
15442 "TARGET_USE_FANCY_MATH_387
15443 && flag_unsafe_math_optimizations"
15444 "* return output_fix_trunc (insn, operands, false);"
15445 [(set_attr "type" "fistp")
15446 (set_attr "i387_cw" "<rounding>")
15447 (set_attr "mode" "<MODE>")])
15448
15449 (define_insn "fist<mode>2_<rounding>_with_temp"
15450 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15451 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15452 FIST_ROUNDING))
15453 (use (match_operand:HI 2 "memory_operand" "m,m"))
15454 (use (match_operand:HI 3 "memory_operand" "m,m"))
15455 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15456 "TARGET_USE_FANCY_MATH_387
15457 && flag_unsafe_math_optimizations"
15458 "#"
15459 [(set_attr "type" "fistp")
15460 (set_attr "i387_cw" "<rounding>")
15461 (set_attr "mode" "<MODE>")])
15462
15463 (define_split
15464 [(set (match_operand:SWI24 0 "register_operand")
15465 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15466 FIST_ROUNDING))
15467 (use (match_operand:HI 2 "memory_operand"))
15468 (use (match_operand:HI 3 "memory_operand"))
15469 (clobber (match_operand:SWI24 4 "memory_operand"))]
15470 "reload_completed"
15471 [(parallel [(set (match_dup 4)
15472 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15473 (use (match_dup 2))
15474 (use (match_dup 3))])
15475 (set (match_dup 0) (match_dup 4))])
15476
15477 (define_split
15478 [(set (match_operand:SWI24 0 "memory_operand")
15479 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15480 FIST_ROUNDING))
15481 (use (match_operand:HI 2 "memory_operand"))
15482 (use (match_operand:HI 3 "memory_operand"))
15483 (clobber (match_operand:SWI24 4 "memory_operand"))]
15484 "reload_completed"
15485 [(parallel [(set (match_dup 0)
15486 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15487 (use (match_dup 2))
15488 (use (match_dup 3))])])
15489
15490 (define_expand "l<rounding_insn>xf<mode>2"
15491 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15492 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15493 FIST_ROUNDING))
15494 (clobber (reg:CC FLAGS_REG))])]
15495 "TARGET_USE_FANCY_MATH_387
15496 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15497 && flag_unsafe_math_optimizations")
15498
15499 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15500 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15501 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15502 FIST_ROUNDING))
15503 (clobber (reg:CC FLAGS_REG))])]
15504 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15505 && !flag_trapping_math"
15506 {
15507 if (TARGET_64BIT && optimize_insn_for_size_p ())
15508 FAIL;
15509
15510 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15511 ix86_expand_lfloorceil (operands[0], operands[1], true);
15512 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15513 ix86_expand_lfloorceil (operands[0], operands[1], false);
15514 else
15515 gcc_unreachable ();
15516
15517 DONE;
15518 })
15519
15520 (define_insn "fxam<mode>2_i387"
15521 [(set (match_operand:HI 0 "register_operand" "=a")
15522 (unspec:HI
15523 [(match_operand:X87MODEF 1 "register_operand" "f")]
15524 UNSPEC_FXAM))]
15525 "TARGET_USE_FANCY_MATH_387"
15526 "fxam\n\tfnstsw\t%0"
15527 [(set_attr "type" "multi")
15528 (set_attr "length" "4")
15529 (set_attr "unit" "i387")
15530 (set_attr "mode" "<MODE>")])
15531
15532 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15533 [(set (match_operand:HI 0 "register_operand")
15534 (unspec:HI
15535 [(match_operand:MODEF 1 "memory_operand")]
15536 UNSPEC_FXAM_MEM))]
15537 "TARGET_USE_FANCY_MATH_387
15538 && can_create_pseudo_p ()"
15539 "#"
15540 "&& 1"
15541 [(set (match_dup 2)(match_dup 1))
15542 (set (match_dup 0)
15543 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15544 {
15545 operands[2] = gen_reg_rtx (<MODE>mode);
15546
15547 MEM_VOLATILE_P (operands[1]) = 1;
15548 }
15549 [(set_attr "type" "multi")
15550 (set_attr "unit" "i387")
15551 (set_attr "mode" "<MODE>")])
15552
15553 (define_expand "isinfxf2"
15554 [(use (match_operand:SI 0 "register_operand"))
15555 (use (match_operand:XF 1 "register_operand"))]
15556 "TARGET_USE_FANCY_MATH_387
15557 && TARGET_C99_FUNCTIONS"
15558 {
15559 rtx mask = GEN_INT (0x45);
15560 rtx val = GEN_INT (0x05);
15561
15562 rtx cond;
15563
15564 rtx scratch = gen_reg_rtx (HImode);
15565 rtx res = gen_reg_rtx (QImode);
15566
15567 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15568
15569 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15570 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15571 cond = gen_rtx_fmt_ee (EQ, QImode,
15572 gen_rtx_REG (CCmode, FLAGS_REG),
15573 const0_rtx);
15574 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15575 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15576 DONE;
15577 })
15578
15579 (define_expand "isinf<mode>2"
15580 [(use (match_operand:SI 0 "register_operand"))
15581 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && TARGET_C99_FUNCTIONS
15584 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15585 {
15586 rtx mask = GEN_INT (0x45);
15587 rtx val = GEN_INT (0x05);
15588
15589 rtx cond;
15590
15591 rtx scratch = gen_reg_rtx (HImode);
15592 rtx res = gen_reg_rtx (QImode);
15593
15594 /* Remove excess precision by forcing value through memory. */
15595 if (memory_operand (operands[1], VOIDmode))
15596 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15597 else
15598 {
15599 enum ix86_stack_slot slot = (virtuals_instantiated
15600 ? SLOT_TEMP
15601 : SLOT_VIRTUAL);
15602 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15603
15604 emit_move_insn (temp, operands[1]);
15605 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15606 }
15607
15608 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15609 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15610 cond = gen_rtx_fmt_ee (EQ, QImode,
15611 gen_rtx_REG (CCmode, FLAGS_REG),
15612 const0_rtx);
15613 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15614 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15615 DONE;
15616 })
15617
15618 (define_expand "signbitxf2"
15619 [(use (match_operand:SI 0 "register_operand"))
15620 (use (match_operand:XF 1 "register_operand"))]
15621 "TARGET_USE_FANCY_MATH_387"
15622 {
15623 rtx scratch = gen_reg_rtx (HImode);
15624
15625 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15626 emit_insn (gen_andsi3 (operands[0],
15627 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15628 DONE;
15629 })
15630
15631 (define_insn "movmsk_df"
15632 [(set (match_operand:SI 0 "register_operand" "=r")
15633 (unspec:SI
15634 [(match_operand:DF 1 "register_operand" "x")]
15635 UNSPEC_MOVMSK))]
15636 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15637 "%vmovmskpd\t{%1, %0|%0, %1}"
15638 [(set_attr "type" "ssemov")
15639 (set_attr "prefix" "maybe_vex")
15640 (set_attr "mode" "DF")])
15641
15642 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15643 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15644 (define_expand "signbitdf2"
15645 [(use (match_operand:SI 0 "register_operand"))
15646 (use (match_operand:DF 1 "register_operand"))]
15647 "TARGET_USE_FANCY_MATH_387
15648 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15649 {
15650 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15651 {
15652 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15653 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15654 }
15655 else
15656 {
15657 rtx scratch = gen_reg_rtx (HImode);
15658
15659 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15660 emit_insn (gen_andsi3 (operands[0],
15661 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15662 }
15663 DONE;
15664 })
15665
15666 (define_expand "signbitsf2"
15667 [(use (match_operand:SI 0 "register_operand"))
15668 (use (match_operand:SF 1 "register_operand"))]
15669 "TARGET_USE_FANCY_MATH_387
15670 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15671 {
15672 rtx scratch = gen_reg_rtx (HImode);
15673
15674 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15675 emit_insn (gen_andsi3 (operands[0],
15676 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15677 DONE;
15678 })
15679 \f
15680 ;; Block operation instructions
15681
15682 (define_insn "cld"
15683 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15684 ""
15685 "cld"
15686 [(set_attr "length" "1")
15687 (set_attr "length_immediate" "0")
15688 (set_attr "modrm" "0")])
15689
15690 (define_expand "movmem<mode>"
15691 [(use (match_operand:BLK 0 "memory_operand"))
15692 (use (match_operand:BLK 1 "memory_operand"))
15693 (use (match_operand:SWI48 2 "nonmemory_operand"))
15694 (use (match_operand:SWI48 3 "const_int_operand"))
15695 (use (match_operand:SI 4 "const_int_operand"))
15696 (use (match_operand:SI 5 "const_int_operand"))]
15697 ""
15698 {
15699 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15700 operands[4], operands[5]))
15701 DONE;
15702 else
15703 FAIL;
15704 })
15705
15706 ;; Most CPUs don't like single string operations
15707 ;; Handle this case here to simplify previous expander.
15708
15709 (define_expand "strmov"
15710 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15711 (set (match_operand 1 "memory_operand") (match_dup 4))
15712 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15713 (clobber (reg:CC FLAGS_REG))])
15714 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15715 (clobber (reg:CC FLAGS_REG))])]
15716 ""
15717 {
15718 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15719
15720 /* If .md ever supports :P for Pmode, these can be directly
15721 in the pattern above. */
15722 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15723 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15724
15725 /* Can't use this if the user has appropriated esi or edi. */
15726 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15727 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15728 {
15729 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15730 operands[2], operands[3],
15731 operands[5], operands[6]));
15732 DONE;
15733 }
15734
15735 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15736 })
15737
15738 (define_expand "strmov_singleop"
15739 [(parallel [(set (match_operand 1 "memory_operand")
15740 (match_operand 3 "memory_operand"))
15741 (set (match_operand 0 "register_operand")
15742 (match_operand 4))
15743 (set (match_operand 2 "register_operand")
15744 (match_operand 5))])]
15745 ""
15746 "ix86_current_function_needs_cld = 1;")
15747
15748 (define_insn "*strmovdi_rex_1"
15749 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15750 (mem:DI (match_operand:P 3 "register_operand" "1")))
15751 (set (match_operand:P 0 "register_operand" "=D")
15752 (plus:P (match_dup 2)
15753 (const_int 8)))
15754 (set (match_operand:P 1 "register_operand" "=S")
15755 (plus:P (match_dup 3)
15756 (const_int 8)))]
15757 "TARGET_64BIT
15758 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15759 "%^movsq"
15760 [(set_attr "type" "str")
15761 (set_attr "memory" "both")
15762 (set_attr "mode" "DI")])
15763
15764 (define_insn "*strmovsi_1"
15765 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15766 (mem:SI (match_operand:P 3 "register_operand" "1")))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (match_dup 2)
15769 (const_int 4)))
15770 (set (match_operand:P 1 "register_operand" "=S")
15771 (plus:P (match_dup 3)
15772 (const_int 4)))]
15773 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774 "%^movs{l|d}"
15775 [(set_attr "type" "str")
15776 (set_attr "memory" "both")
15777 (set_attr "mode" "SI")])
15778
15779 (define_insn "*strmovhi_1"
15780 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15781 (mem:HI (match_operand:P 3 "register_operand" "1")))
15782 (set (match_operand:P 0 "register_operand" "=D")
15783 (plus:P (match_dup 2)
15784 (const_int 2)))
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (match_dup 3)
15787 (const_int 2)))]
15788 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15789 "%^movsw"
15790 [(set_attr "type" "str")
15791 (set_attr "memory" "both")
15792 (set_attr "mode" "HI")])
15793
15794 (define_insn "*strmovqi_1"
15795 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15796 (mem:QI (match_operand:P 3 "register_operand" "1")))
15797 (set (match_operand:P 0 "register_operand" "=D")
15798 (plus:P (match_dup 2)
15799 (const_int 1)))
15800 (set (match_operand:P 1 "register_operand" "=S")
15801 (plus:P (match_dup 3)
15802 (const_int 1)))]
15803 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15804 "%^movsb"
15805 [(set_attr "type" "str")
15806 (set_attr "memory" "both")
15807 (set (attr "prefix_rex")
15808 (if_then_else
15809 (match_test "<P:MODE>mode == DImode")
15810 (const_string "0")
15811 (const_string "*")))
15812 (set_attr "mode" "QI")])
15813
15814 (define_expand "rep_mov"
15815 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15816 (set (match_operand 0 "register_operand")
15817 (match_operand 5))
15818 (set (match_operand 2 "register_operand")
15819 (match_operand 6))
15820 (set (match_operand 1 "memory_operand")
15821 (match_operand 3 "memory_operand"))
15822 (use (match_dup 4))])]
15823 ""
15824 "ix86_current_function_needs_cld = 1;")
15825
15826 (define_insn "*rep_movdi_rex64"
15827 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15828 (set (match_operand:P 0 "register_operand" "=D")
15829 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15830 (const_int 3))
15831 (match_operand:P 3 "register_operand" "0")))
15832 (set (match_operand:P 1 "register_operand" "=S")
15833 (plus:P (ashift:P (match_dup 5) (const_int 3))
15834 (match_operand:P 4 "register_operand" "1")))
15835 (set (mem:BLK (match_dup 3))
15836 (mem:BLK (match_dup 4)))
15837 (use (match_dup 5))]
15838 "TARGET_64BIT
15839 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15840 "%^rep{%;} movsq"
15841 [(set_attr "type" "str")
15842 (set_attr "prefix_rep" "1")
15843 (set_attr "memory" "both")
15844 (set_attr "mode" "DI")])
15845
15846 (define_insn "*rep_movsi"
15847 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15848 (set (match_operand:P 0 "register_operand" "=D")
15849 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15850 (const_int 2))
15851 (match_operand:P 3 "register_operand" "0")))
15852 (set (match_operand:P 1 "register_operand" "=S")
15853 (plus:P (ashift:P (match_dup 5) (const_int 2))
15854 (match_operand:P 4 "register_operand" "1")))
15855 (set (mem:BLK (match_dup 3))
15856 (mem:BLK (match_dup 4)))
15857 (use (match_dup 5))]
15858 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15859 "%^rep{%;} movs{l|d}"
15860 [(set_attr "type" "str")
15861 (set_attr "prefix_rep" "1")
15862 (set_attr "memory" "both")
15863 (set_attr "mode" "SI")])
15864
15865 (define_insn "*rep_movqi"
15866 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15867 (set (match_operand:P 0 "register_operand" "=D")
15868 (plus:P (match_operand:P 3 "register_operand" "0")
15869 (match_operand:P 5 "register_operand" "2")))
15870 (set (match_operand:P 1 "register_operand" "=S")
15871 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15872 (set (mem:BLK (match_dup 3))
15873 (mem:BLK (match_dup 4)))
15874 (use (match_dup 5))]
15875 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15876 "%^rep{%;} movsb"
15877 [(set_attr "type" "str")
15878 (set_attr "prefix_rep" "1")
15879 (set_attr "memory" "both")
15880 (set_attr "mode" "QI")])
15881
15882 (define_expand "setmem<mode>"
15883 [(use (match_operand:BLK 0 "memory_operand"))
15884 (use (match_operand:SWI48 1 "nonmemory_operand"))
15885 (use (match_operand:QI 2 "nonmemory_operand"))
15886 (use (match_operand 3 "const_int_operand"))
15887 (use (match_operand:SI 4 "const_int_operand"))
15888 (use (match_operand:SI 5 "const_int_operand"))]
15889 ""
15890 {
15891 if (ix86_expand_setmem (operands[0], operands[1],
15892 operands[2], operands[3],
15893 operands[4], operands[5]))
15894 DONE;
15895 else
15896 FAIL;
15897 })
15898
15899 ;; Most CPUs don't like single string operations
15900 ;; Handle this case here to simplify previous expander.
15901
15902 (define_expand "strset"
15903 [(set (match_operand 1 "memory_operand")
15904 (match_operand 2 "register_operand"))
15905 (parallel [(set (match_operand 0 "register_operand")
15906 (match_dup 3))
15907 (clobber (reg:CC FLAGS_REG))])]
15908 ""
15909 {
15910 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15911 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15912
15913 /* If .md ever supports :P for Pmode, this can be directly
15914 in the pattern above. */
15915 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15916 GEN_INT (GET_MODE_SIZE (GET_MODE
15917 (operands[2]))));
15918 /* Can't use this if the user has appropriated eax or edi. */
15919 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15920 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15921 {
15922 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15923 operands[3]));
15924 DONE;
15925 }
15926 })
15927
15928 (define_expand "strset_singleop"
15929 [(parallel [(set (match_operand 1 "memory_operand")
15930 (match_operand 2 "register_operand"))
15931 (set (match_operand 0 "register_operand")
15932 (match_operand 3))])]
15933 ""
15934 "ix86_current_function_needs_cld = 1;")
15935
15936 (define_insn "*strsetdi_rex_1"
15937 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15938 (match_operand:DI 2 "register_operand" "a"))
15939 (set (match_operand:P 0 "register_operand" "=D")
15940 (plus:P (match_dup 1)
15941 (const_int 8)))]
15942 "TARGET_64BIT
15943 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15944 "%^stosq"
15945 [(set_attr "type" "str")
15946 (set_attr "memory" "store")
15947 (set_attr "mode" "DI")])
15948
15949 (define_insn "*strsetsi_1"
15950 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15951 (match_operand:SI 2 "register_operand" "a"))
15952 (set (match_operand:P 0 "register_operand" "=D")
15953 (plus:P (match_dup 1)
15954 (const_int 4)))]
15955 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15956 "%^stos{l|d}"
15957 [(set_attr "type" "str")
15958 (set_attr "memory" "store")
15959 (set_attr "mode" "SI")])
15960
15961 (define_insn "*strsethi_1"
15962 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:HI 2 "register_operand" "a"))
15964 (set (match_operand:P 0 "register_operand" "=D")
15965 (plus:P (match_dup 1)
15966 (const_int 2)))]
15967 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15968 "%^stosw"
15969 [(set_attr "type" "str")
15970 (set_attr "memory" "store")
15971 (set_attr "mode" "HI")])
15972
15973 (define_insn "*strsetqi_1"
15974 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15975 (match_operand:QI 2 "register_operand" "a"))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (match_dup 1)
15978 (const_int 1)))]
15979 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15980 "%^stosb"
15981 [(set_attr "type" "str")
15982 (set_attr "memory" "store")
15983 (set (attr "prefix_rex")
15984 (if_then_else
15985 (match_test "<P:MODE>mode == DImode")
15986 (const_string "0")
15987 (const_string "*")))
15988 (set_attr "mode" "QI")])
15989
15990 (define_expand "rep_stos"
15991 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15992 (set (match_operand 0 "register_operand")
15993 (match_operand 4))
15994 (set (match_operand 2 "memory_operand") (const_int 0))
15995 (use (match_operand 3 "register_operand"))
15996 (use (match_dup 1))])]
15997 ""
15998 "ix86_current_function_needs_cld = 1;")
15999
16000 (define_insn "*rep_stosdi_rex64"
16001 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16002 (set (match_operand:P 0 "register_operand" "=D")
16003 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16004 (const_int 3))
16005 (match_operand:P 3 "register_operand" "0")))
16006 (set (mem:BLK (match_dup 3))
16007 (const_int 0))
16008 (use (match_operand:DI 2 "register_operand" "a"))
16009 (use (match_dup 4))]
16010 "TARGET_64BIT
16011 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012 "%^rep{%;} stosq"
16013 [(set_attr "type" "str")
16014 (set_attr "prefix_rep" "1")
16015 (set_attr "memory" "store")
16016 (set_attr "mode" "DI")])
16017
16018 (define_insn "*rep_stossi"
16019 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16020 (set (match_operand:P 0 "register_operand" "=D")
16021 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16022 (const_int 2))
16023 (match_operand:P 3 "register_operand" "0")))
16024 (set (mem:BLK (match_dup 3))
16025 (const_int 0))
16026 (use (match_operand:SI 2 "register_operand" "a"))
16027 (use (match_dup 4))]
16028 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16029 "%^rep{%;} stos{l|d}"
16030 [(set_attr "type" "str")
16031 (set_attr "prefix_rep" "1")
16032 (set_attr "memory" "store")
16033 (set_attr "mode" "SI")])
16034
16035 (define_insn "*rep_stosqi"
16036 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16037 (set (match_operand:P 0 "register_operand" "=D")
16038 (plus:P (match_operand:P 3 "register_operand" "0")
16039 (match_operand:P 4 "register_operand" "1")))
16040 (set (mem:BLK (match_dup 3))
16041 (const_int 0))
16042 (use (match_operand:QI 2 "register_operand" "a"))
16043 (use (match_dup 4))]
16044 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16045 "%^rep{%;} stosb"
16046 [(set_attr "type" "str")
16047 (set_attr "prefix_rep" "1")
16048 (set_attr "memory" "store")
16049 (set (attr "prefix_rex")
16050 (if_then_else
16051 (match_test "<P:MODE>mode == DImode")
16052 (const_string "0")
16053 (const_string "*")))
16054 (set_attr "mode" "QI")])
16055
16056 (define_expand "cmpstrnsi"
16057 [(set (match_operand:SI 0 "register_operand")
16058 (compare:SI (match_operand:BLK 1 "general_operand")
16059 (match_operand:BLK 2 "general_operand")))
16060 (use (match_operand 3 "general_operand"))
16061 (use (match_operand 4 "immediate_operand"))]
16062 ""
16063 {
16064 rtx addr1, addr2, out, outlow, count, countreg, align;
16065
16066 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16067 FAIL;
16068
16069 /* Can't use this if the user has appropriated ecx, esi or edi. */
16070 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16071 FAIL;
16072
16073 out = operands[0];
16074 if (!REG_P (out))
16075 out = gen_reg_rtx (SImode);
16076
16077 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16078 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16079 if (addr1 != XEXP (operands[1], 0))
16080 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16081 if (addr2 != XEXP (operands[2], 0))
16082 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16083
16084 count = operands[3];
16085 countreg = ix86_zero_extend_to_Pmode (count);
16086
16087 /* %%% Iff we are testing strict equality, we can use known alignment
16088 to good advantage. This may be possible with combine, particularly
16089 once cc0 is dead. */
16090 align = operands[4];
16091
16092 if (CONST_INT_P (count))
16093 {
16094 if (INTVAL (count) == 0)
16095 {
16096 emit_move_insn (operands[0], const0_rtx);
16097 DONE;
16098 }
16099 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16100 operands[1], operands[2]));
16101 }
16102 else
16103 {
16104 rtx (*gen_cmp) (rtx, rtx);
16105
16106 gen_cmp = (TARGET_64BIT
16107 ? gen_cmpdi_1 : gen_cmpsi_1);
16108
16109 emit_insn (gen_cmp (countreg, countreg));
16110 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16111 operands[1], operands[2]));
16112 }
16113
16114 outlow = gen_lowpart (QImode, out);
16115 emit_insn (gen_cmpintqi (outlow));
16116 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16117
16118 if (operands[0] != out)
16119 emit_move_insn (operands[0], out);
16120
16121 DONE;
16122 })
16123
16124 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16125
16126 (define_expand "cmpintqi"
16127 [(set (match_dup 1)
16128 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16129 (set (match_dup 2)
16130 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16131 (parallel [(set (match_operand:QI 0 "register_operand")
16132 (minus:QI (match_dup 1)
16133 (match_dup 2)))
16134 (clobber (reg:CC FLAGS_REG))])]
16135 ""
16136 {
16137 operands[1] = gen_reg_rtx (QImode);
16138 operands[2] = gen_reg_rtx (QImode);
16139 })
16140
16141 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16142 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16143
16144 (define_expand "cmpstrnqi_nz_1"
16145 [(parallel [(set (reg:CC FLAGS_REG)
16146 (compare:CC (match_operand 4 "memory_operand")
16147 (match_operand 5 "memory_operand")))
16148 (use (match_operand 2 "register_operand"))
16149 (use (match_operand:SI 3 "immediate_operand"))
16150 (clobber (match_operand 0 "register_operand"))
16151 (clobber (match_operand 1 "register_operand"))
16152 (clobber (match_dup 2))])]
16153 ""
16154 "ix86_current_function_needs_cld = 1;")
16155
16156 (define_insn "*cmpstrnqi_nz_1"
16157 [(set (reg:CC FLAGS_REG)
16158 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16159 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16160 (use (match_operand:P 6 "register_operand" "2"))
16161 (use (match_operand:SI 3 "immediate_operand" "i"))
16162 (clobber (match_operand:P 0 "register_operand" "=S"))
16163 (clobber (match_operand:P 1 "register_operand" "=D"))
16164 (clobber (match_operand:P 2 "register_operand" "=c"))]
16165 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16166 "%^repz{%;} cmpsb"
16167 [(set_attr "type" "str")
16168 (set_attr "mode" "QI")
16169 (set (attr "prefix_rex")
16170 (if_then_else
16171 (match_test "<P:MODE>mode == DImode")
16172 (const_string "0")
16173 (const_string "*")))
16174 (set_attr "prefix_rep" "1")])
16175
16176 ;; The same, but the count is not known to not be zero.
16177
16178 (define_expand "cmpstrnqi_1"
16179 [(parallel [(set (reg:CC FLAGS_REG)
16180 (if_then_else:CC (ne (match_operand 2 "register_operand")
16181 (const_int 0))
16182 (compare:CC (match_operand 4 "memory_operand")
16183 (match_operand 5 "memory_operand"))
16184 (const_int 0)))
16185 (use (match_operand:SI 3 "immediate_operand"))
16186 (use (reg:CC FLAGS_REG))
16187 (clobber (match_operand 0 "register_operand"))
16188 (clobber (match_operand 1 "register_operand"))
16189 (clobber (match_dup 2))])]
16190 ""
16191 "ix86_current_function_needs_cld = 1;")
16192
16193 (define_insn "*cmpstrnqi_1"
16194 [(set (reg:CC FLAGS_REG)
16195 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16196 (const_int 0))
16197 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16198 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16199 (const_int 0)))
16200 (use (match_operand:SI 3 "immediate_operand" "i"))
16201 (use (reg:CC FLAGS_REG))
16202 (clobber (match_operand:P 0 "register_operand" "=S"))
16203 (clobber (match_operand:P 1 "register_operand" "=D"))
16204 (clobber (match_operand:P 2 "register_operand" "=c"))]
16205 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16206 "%^repz{%;} cmpsb"
16207 [(set_attr "type" "str")
16208 (set_attr "mode" "QI")
16209 (set (attr "prefix_rex")
16210 (if_then_else
16211 (match_test "<P:MODE>mode == DImode")
16212 (const_string "0")
16213 (const_string "*")))
16214 (set_attr "prefix_rep" "1")])
16215
16216 (define_expand "strlen<mode>"
16217 [(set (match_operand:P 0 "register_operand")
16218 (unspec:P [(match_operand:BLK 1 "general_operand")
16219 (match_operand:QI 2 "immediate_operand")
16220 (match_operand 3 "immediate_operand")]
16221 UNSPEC_SCAS))]
16222 ""
16223 {
16224 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16225 DONE;
16226 else
16227 FAIL;
16228 })
16229
16230 (define_expand "strlenqi_1"
16231 [(parallel [(set (match_operand 0 "register_operand")
16232 (match_operand 2))
16233 (clobber (match_operand 1 "register_operand"))
16234 (clobber (reg:CC FLAGS_REG))])]
16235 ""
16236 "ix86_current_function_needs_cld = 1;")
16237
16238 (define_insn "*strlenqi_1"
16239 [(set (match_operand:P 0 "register_operand" "=&c")
16240 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16241 (match_operand:QI 2 "register_operand" "a")
16242 (match_operand:P 3 "immediate_operand" "i")
16243 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16244 (clobber (match_operand:P 1 "register_operand" "=D"))
16245 (clobber (reg:CC FLAGS_REG))]
16246 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16247 "%^repnz{%;} scasb"
16248 [(set_attr "type" "str")
16249 (set_attr "mode" "QI")
16250 (set (attr "prefix_rex")
16251 (if_then_else
16252 (match_test "<P:MODE>mode == DImode")
16253 (const_string "0")
16254 (const_string "*")))
16255 (set_attr "prefix_rep" "1")])
16256
16257 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16258 ;; handled in combine, but it is not currently up to the task.
16259 ;; When used for their truth value, the cmpstrn* expanders generate
16260 ;; code like this:
16261 ;;
16262 ;; repz cmpsb
16263 ;; seta %al
16264 ;; setb %dl
16265 ;; cmpb %al, %dl
16266 ;; jcc label
16267 ;;
16268 ;; The intermediate three instructions are unnecessary.
16269
16270 ;; This one handles cmpstrn*_nz_1...
16271 (define_peephole2
16272 [(parallel[
16273 (set (reg:CC FLAGS_REG)
16274 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16275 (mem:BLK (match_operand 5 "register_operand"))))
16276 (use (match_operand 6 "register_operand"))
16277 (use (match_operand:SI 3 "immediate_operand"))
16278 (clobber (match_operand 0 "register_operand"))
16279 (clobber (match_operand 1 "register_operand"))
16280 (clobber (match_operand 2 "register_operand"))])
16281 (set (match_operand:QI 7 "register_operand")
16282 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16283 (set (match_operand:QI 8 "register_operand")
16284 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16285 (set (reg FLAGS_REG)
16286 (compare (match_dup 7) (match_dup 8)))
16287 ]
16288 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16289 [(parallel[
16290 (set (reg:CC FLAGS_REG)
16291 (compare:CC (mem:BLK (match_dup 4))
16292 (mem:BLK (match_dup 5))))
16293 (use (match_dup 6))
16294 (use (match_dup 3))
16295 (clobber (match_dup 0))
16296 (clobber (match_dup 1))
16297 (clobber (match_dup 2))])])
16298
16299 ;; ...and this one handles cmpstrn*_1.
16300 (define_peephole2
16301 [(parallel[
16302 (set (reg:CC FLAGS_REG)
16303 (if_then_else:CC (ne (match_operand 6 "register_operand")
16304 (const_int 0))
16305 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16306 (mem:BLK (match_operand 5 "register_operand")))
16307 (const_int 0)))
16308 (use (match_operand:SI 3 "immediate_operand"))
16309 (use (reg:CC FLAGS_REG))
16310 (clobber (match_operand 0 "register_operand"))
16311 (clobber (match_operand 1 "register_operand"))
16312 (clobber (match_operand 2 "register_operand"))])
16313 (set (match_operand:QI 7 "register_operand")
16314 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16315 (set (match_operand:QI 8 "register_operand")
16316 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16317 (set (reg FLAGS_REG)
16318 (compare (match_dup 7) (match_dup 8)))
16319 ]
16320 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16321 [(parallel[
16322 (set (reg:CC FLAGS_REG)
16323 (if_then_else:CC (ne (match_dup 6)
16324 (const_int 0))
16325 (compare:CC (mem:BLK (match_dup 4))
16326 (mem:BLK (match_dup 5)))
16327 (const_int 0)))
16328 (use (match_dup 3))
16329 (use (reg:CC FLAGS_REG))
16330 (clobber (match_dup 0))
16331 (clobber (match_dup 1))
16332 (clobber (match_dup 2))])])
16333 \f
16334 ;; Conditional move instructions.
16335
16336 (define_expand "mov<mode>cc"
16337 [(set (match_operand:SWIM 0 "register_operand")
16338 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16339 (match_operand:SWIM 2 "<general_operand>")
16340 (match_operand:SWIM 3 "<general_operand>")))]
16341 ""
16342 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16343
16344 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16345 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16346 ;; So just document what we're doing explicitly.
16347
16348 (define_expand "x86_mov<mode>cc_0_m1"
16349 [(parallel
16350 [(set (match_operand:SWI48 0 "register_operand")
16351 (if_then_else:SWI48
16352 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16353 [(match_operand 1 "flags_reg_operand")
16354 (const_int 0)])
16355 (const_int -1)
16356 (const_int 0)))
16357 (clobber (reg:CC FLAGS_REG))])])
16358
16359 (define_insn "*x86_mov<mode>cc_0_m1"
16360 [(set (match_operand:SWI48 0 "register_operand" "=r")
16361 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16362 [(reg FLAGS_REG) (const_int 0)])
16363 (const_int -1)
16364 (const_int 0)))
16365 (clobber (reg:CC FLAGS_REG))]
16366 ""
16367 "sbb{<imodesuffix>}\t%0, %0"
16368 ; Since we don't have the proper number of operands for an alu insn,
16369 ; fill in all the blanks.
16370 [(set_attr "type" "alu")
16371 (set_attr "use_carry" "1")
16372 (set_attr "pent_pair" "pu")
16373 (set_attr "memory" "none")
16374 (set_attr "imm_disp" "false")
16375 (set_attr "mode" "<MODE>")
16376 (set_attr "length_immediate" "0")])
16377
16378 (define_insn "*x86_mov<mode>cc_0_m1_se"
16379 [(set (match_operand:SWI48 0 "register_operand" "=r")
16380 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16381 [(reg FLAGS_REG) (const_int 0)])
16382 (const_int 1)
16383 (const_int 0)))
16384 (clobber (reg:CC FLAGS_REG))]
16385 ""
16386 "sbb{<imodesuffix>}\t%0, %0"
16387 [(set_attr "type" "alu")
16388 (set_attr "use_carry" "1")
16389 (set_attr "pent_pair" "pu")
16390 (set_attr "memory" "none")
16391 (set_attr "imm_disp" "false")
16392 (set_attr "mode" "<MODE>")
16393 (set_attr "length_immediate" "0")])
16394
16395 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16396 [(set (match_operand:SWI48 0 "register_operand" "=r")
16397 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16398 [(reg FLAGS_REG) (const_int 0)])))
16399 (clobber (reg:CC FLAGS_REG))]
16400 ""
16401 "sbb{<imodesuffix>}\t%0, %0"
16402 [(set_attr "type" "alu")
16403 (set_attr "use_carry" "1")
16404 (set_attr "pent_pair" "pu")
16405 (set_attr "memory" "none")
16406 (set_attr "imm_disp" "false")
16407 (set_attr "mode" "<MODE>")
16408 (set_attr "length_immediate" "0")])
16409
16410 (define_insn "*mov<mode>cc_noc"
16411 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16412 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16413 [(reg FLAGS_REG) (const_int 0)])
16414 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16415 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16416 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16417 "@
16418 cmov%O2%C1\t{%2, %0|%0, %2}
16419 cmov%O2%c1\t{%3, %0|%0, %3}"
16420 [(set_attr "type" "icmov")
16421 (set_attr "mode" "<MODE>")])
16422
16423 (define_insn "*movqicc_noc"
16424 [(set (match_operand:QI 0 "register_operand" "=r,r")
16425 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16426 [(reg FLAGS_REG) (const_int 0)])
16427 (match_operand:QI 2 "register_operand" "r,0")
16428 (match_operand:QI 3 "register_operand" "0,r")))]
16429 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16430 "#"
16431 [(set_attr "type" "icmov")
16432 (set_attr "mode" "QI")])
16433
16434 (define_split
16435 [(set (match_operand 0 "register_operand")
16436 (if_then_else (match_operator 1 "ix86_comparison_operator"
16437 [(reg FLAGS_REG) (const_int 0)])
16438 (match_operand 2 "register_operand")
16439 (match_operand 3 "register_operand")))]
16440 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16441 && (GET_MODE (operands[0]) == QImode
16442 || GET_MODE (operands[0]) == HImode)
16443 && reload_completed"
16444 [(set (match_dup 0)
16445 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16446 {
16447 operands[0] = gen_lowpart (SImode, operands[0]);
16448 operands[2] = gen_lowpart (SImode, operands[2]);
16449 operands[3] = gen_lowpart (SImode, operands[3]);
16450 })
16451
16452 (define_expand "mov<mode>cc"
16453 [(set (match_operand:X87MODEF 0 "register_operand")
16454 (if_then_else:X87MODEF
16455 (match_operand 1 "ix86_fp_comparison_operator")
16456 (match_operand:X87MODEF 2 "register_operand")
16457 (match_operand:X87MODEF 3 "register_operand")))]
16458 "(TARGET_80387 && TARGET_CMOVE)
16459 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16460 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16461
16462 (define_insn "*movxfcc_1"
16463 [(set (match_operand:XF 0 "register_operand" "=f,f")
16464 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16465 [(reg FLAGS_REG) (const_int 0)])
16466 (match_operand:XF 2 "register_operand" "f,0")
16467 (match_operand:XF 3 "register_operand" "0,f")))]
16468 "TARGET_80387 && TARGET_CMOVE"
16469 "@
16470 fcmov%F1\t{%2, %0|%0, %2}
16471 fcmov%f1\t{%3, %0|%0, %3}"
16472 [(set_attr "type" "fcmov")
16473 (set_attr "mode" "XF")])
16474
16475 (define_insn "*movdfcc_1_rex64"
16476 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16477 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16478 [(reg FLAGS_REG) (const_int 0)])
16479 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16480 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16481 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16483 "@
16484 fcmov%F1\t{%2, %0|%0, %2}
16485 fcmov%f1\t{%3, %0|%0, %3}
16486 cmov%O2%C1\t{%2, %0|%0, %2}
16487 cmov%O2%c1\t{%3, %0|%0, %3}"
16488 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16489 (set_attr "mode" "DF,DF,DI,DI")])
16490
16491 (define_insn "*movdfcc_1"
16492 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16493 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16494 [(reg FLAGS_REG) (const_int 0)])
16495 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16496 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16497 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16498 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16499 "@
16500 fcmov%F1\t{%2, %0|%0, %2}
16501 fcmov%f1\t{%3, %0|%0, %3}
16502 #
16503 #"
16504 [(set_attr "type" "fcmov,fcmov,multi,multi")
16505 (set_attr "mode" "DF,DF,DI,DI")])
16506
16507 (define_split
16508 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16509 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16510 [(reg FLAGS_REG) (const_int 0)])
16511 (match_operand:DF 2 "nonimmediate_operand")
16512 (match_operand:DF 3 "nonimmediate_operand")))]
16513 "!TARGET_64BIT && reload_completed"
16514 [(set (match_dup 2)
16515 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16516 (set (match_dup 3)
16517 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16518 {
16519 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16520 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16521 })
16522
16523 (define_insn "*movsfcc_1_387"
16524 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16525 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16526 [(reg FLAGS_REG) (const_int 0)])
16527 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16528 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16529 "TARGET_80387 && TARGET_CMOVE
16530 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16531 "@
16532 fcmov%F1\t{%2, %0|%0, %2}
16533 fcmov%f1\t{%3, %0|%0, %3}
16534 cmov%O2%C1\t{%2, %0|%0, %2}
16535 cmov%O2%c1\t{%3, %0|%0, %3}"
16536 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16537 (set_attr "mode" "SF,SF,SI,SI")])
16538
16539 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16540 ;; the scalar versions to have only XMM registers as operands.
16541
16542 ;; XOP conditional move
16543 (define_insn "*xop_pcmov_<mode>"
16544 [(set (match_operand:MODEF 0 "register_operand" "=x")
16545 (if_then_else:MODEF
16546 (match_operand:MODEF 1 "register_operand" "x")
16547 (match_operand:MODEF 2 "register_operand" "x")
16548 (match_operand:MODEF 3 "register_operand" "x")))]
16549 "TARGET_XOP"
16550 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16551 [(set_attr "type" "sse4arg")])
16552
16553 ;; These versions of the min/max patterns are intentionally ignorant of
16554 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16555 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16556 ;; are undefined in this condition, we're certain this is correct.
16557
16558 (define_insn "<code><mode>3"
16559 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16560 (smaxmin:MODEF
16561 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16562 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16563 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16564 "@
16565 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16566 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16567 [(set_attr "isa" "noavx,avx")
16568 (set_attr "prefix" "orig,vex")
16569 (set_attr "type" "sseadd")
16570 (set_attr "mode" "<MODE>")])
16571
16572 ;; These versions of the min/max patterns implement exactly the operations
16573 ;; min = (op1 < op2 ? op1 : op2)
16574 ;; max = (!(op1 < op2) ? op1 : op2)
16575 ;; Their operands are not commutative, and thus they may be used in the
16576 ;; presence of -0.0 and NaN.
16577
16578 (define_int_iterator IEEE_MAXMIN
16579 [UNSPEC_IEEE_MAX
16580 UNSPEC_IEEE_MIN])
16581
16582 (define_int_attr ieee_maxmin
16583 [(UNSPEC_IEEE_MAX "max")
16584 (UNSPEC_IEEE_MIN "min")])
16585
16586 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16587 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16588 (unspec:MODEF
16589 [(match_operand:MODEF 1 "register_operand" "0,x")
16590 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16591 IEEE_MAXMIN))]
16592 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16593 "@
16594 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16595 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16596 [(set_attr "isa" "noavx,avx")
16597 (set_attr "prefix" "orig,vex")
16598 (set_attr "type" "sseadd")
16599 (set_attr "mode" "<MODE>")])
16600
16601 ;; Make two stack loads independent:
16602 ;; fld aa fld aa
16603 ;; fld %st(0) -> fld bb
16604 ;; fmul bb fmul %st(1), %st
16605 ;;
16606 ;; Actually we only match the last two instructions for simplicity.
16607 (define_peephole2
16608 [(set (match_operand 0 "fp_register_operand")
16609 (match_operand 1 "fp_register_operand"))
16610 (set (match_dup 0)
16611 (match_operator 2 "binary_fp_operator"
16612 [(match_dup 0)
16613 (match_operand 3 "memory_operand")]))]
16614 "REGNO (operands[0]) != REGNO (operands[1])"
16615 [(set (match_dup 0) (match_dup 3))
16616 (set (match_dup 0) (match_dup 4))]
16617
16618 ;; The % modifier is not operational anymore in peephole2's, so we have to
16619 ;; swap the operands manually in the case of addition and multiplication.
16620 {
16621 rtx op0, op1;
16622
16623 if (COMMUTATIVE_ARITH_P (operands[2]))
16624 op0 = operands[0], op1 = operands[1];
16625 else
16626 op0 = operands[1], op1 = operands[0];
16627
16628 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16629 GET_MODE (operands[2]),
16630 op0, op1);
16631 })
16632
16633 ;; Conditional addition patterns
16634 (define_expand "add<mode>cc"
16635 [(match_operand:SWI 0 "register_operand")
16636 (match_operand 1 "ordered_comparison_operator")
16637 (match_operand:SWI 2 "register_operand")
16638 (match_operand:SWI 3 "const_int_operand")]
16639 ""
16640 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16641 \f
16642 ;; Misc patterns (?)
16643
16644 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16645 ;; Otherwise there will be nothing to keep
16646 ;;
16647 ;; [(set (reg ebp) (reg esp))]
16648 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16649 ;; (clobber (eflags)]
16650 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16651 ;;
16652 ;; in proper program order.
16653
16654 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16655 [(set (match_operand:P 0 "register_operand" "=r,r")
16656 (plus:P (match_operand:P 1 "register_operand" "0,r")
16657 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16658 (clobber (reg:CC FLAGS_REG))
16659 (clobber (mem:BLK (scratch)))]
16660 ""
16661 {
16662 switch (get_attr_type (insn))
16663 {
16664 case TYPE_IMOV:
16665 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16666
16667 case TYPE_ALU:
16668 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16669 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16670 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16671
16672 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16673
16674 default:
16675 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16676 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16677 }
16678 }
16679 [(set (attr "type")
16680 (cond [(and (eq_attr "alternative" "0")
16681 (not (match_test "TARGET_OPT_AGU")))
16682 (const_string "alu")
16683 (match_operand:<MODE> 2 "const0_operand")
16684 (const_string "imov")
16685 ]
16686 (const_string "lea")))
16687 (set (attr "length_immediate")
16688 (cond [(eq_attr "type" "imov")
16689 (const_string "0")
16690 (and (eq_attr "type" "alu")
16691 (match_operand 2 "const128_operand"))
16692 (const_string "1")
16693 ]
16694 (const_string "*")))
16695 (set_attr "mode" "<MODE>")])
16696
16697 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16698 [(set (match_operand:P 0 "register_operand" "=r")
16699 (minus:P (match_operand:P 1 "register_operand" "0")
16700 (match_operand:P 2 "register_operand" "r")))
16701 (clobber (reg:CC FLAGS_REG))
16702 (clobber (mem:BLK (scratch)))]
16703 ""
16704 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16705 [(set_attr "type" "alu")
16706 (set_attr "mode" "<MODE>")])
16707
16708 (define_insn "allocate_stack_worker_probe_<mode>"
16709 [(set (match_operand:P 0 "register_operand" "=a")
16710 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16711 UNSPECV_STACK_PROBE))
16712 (clobber (reg:CC FLAGS_REG))]
16713 "ix86_target_stack_probe ()"
16714 "call\t___chkstk_ms"
16715 [(set_attr "type" "multi")
16716 (set_attr "length" "5")])
16717
16718 (define_expand "allocate_stack"
16719 [(match_operand 0 "register_operand")
16720 (match_operand 1 "general_operand")]
16721 "ix86_target_stack_probe ()"
16722 {
16723 rtx x;
16724
16725 #ifndef CHECK_STACK_LIMIT
16726 #define CHECK_STACK_LIMIT 0
16727 #endif
16728
16729 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16730 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16731 x = operands[1];
16732 else
16733 {
16734 rtx (*insn) (rtx, rtx);
16735
16736 x = copy_to_mode_reg (Pmode, operands[1]);
16737
16738 insn = (TARGET_64BIT
16739 ? gen_allocate_stack_worker_probe_di
16740 : gen_allocate_stack_worker_probe_si);
16741
16742 emit_insn (insn (x, x));
16743 }
16744
16745 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16746 stack_pointer_rtx, 0, OPTAB_DIRECT);
16747
16748 if (x != stack_pointer_rtx)
16749 emit_move_insn (stack_pointer_rtx, x);
16750
16751 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16752 DONE;
16753 })
16754
16755 ;; Use IOR for stack probes, this is shorter.
16756 (define_expand "probe_stack"
16757 [(match_operand 0 "memory_operand")]
16758 ""
16759 {
16760 rtx (*gen_ior3) (rtx, rtx, rtx);
16761
16762 gen_ior3 = (GET_MODE (operands[0]) == DImode
16763 ? gen_iordi3 : gen_iorsi3);
16764
16765 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16766 DONE;
16767 })
16768
16769 (define_insn "adjust_stack_and_probe<mode>"
16770 [(set (match_operand:P 0 "register_operand" "=r")
16771 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16772 UNSPECV_PROBE_STACK_RANGE))
16773 (set (reg:P SP_REG)
16774 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16775 (clobber (reg:CC FLAGS_REG))
16776 (clobber (mem:BLK (scratch)))]
16777 ""
16778 "* return output_adjust_stack_and_probe (operands[0]);"
16779 [(set_attr "type" "multi")])
16780
16781 (define_insn "probe_stack_range<mode>"
16782 [(set (match_operand:P 0 "register_operand" "=r")
16783 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16784 (match_operand:P 2 "const_int_operand" "n")]
16785 UNSPECV_PROBE_STACK_RANGE))
16786 (clobber (reg:CC FLAGS_REG))]
16787 ""
16788 "* return output_probe_stack_range (operands[0], operands[2]);"
16789 [(set_attr "type" "multi")])
16790
16791 (define_expand "builtin_setjmp_receiver"
16792 [(label_ref (match_operand 0))]
16793 "!TARGET_64BIT && flag_pic"
16794 {
16795 #if TARGET_MACHO
16796 if (TARGET_MACHO)
16797 {
16798 rtx xops[3];
16799 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16800 rtx label_rtx = gen_label_rtx ();
16801 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16802 xops[0] = xops[1] = picreg;
16803 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16804 ix86_expand_binary_operator (MINUS, SImode, xops);
16805 }
16806 else
16807 #endif
16808 emit_insn (gen_set_got (pic_offset_table_rtx));
16809 DONE;
16810 })
16811 \f
16812 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16813
16814 (define_split
16815 [(set (match_operand 0 "register_operand")
16816 (match_operator 3 "promotable_binary_operator"
16817 [(match_operand 1 "register_operand")
16818 (match_operand 2 "aligned_operand")]))
16819 (clobber (reg:CC FLAGS_REG))]
16820 "! TARGET_PARTIAL_REG_STALL && reload_completed
16821 && ((GET_MODE (operands[0]) == HImode
16822 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16823 /* ??? next two lines just !satisfies_constraint_K (...) */
16824 || !CONST_INT_P (operands[2])
16825 || satisfies_constraint_K (operands[2])))
16826 || (GET_MODE (operands[0]) == QImode
16827 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16828 [(parallel [(set (match_dup 0)
16829 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16830 (clobber (reg:CC FLAGS_REG))])]
16831 {
16832 operands[0] = gen_lowpart (SImode, operands[0]);
16833 operands[1] = gen_lowpart (SImode, operands[1]);
16834 if (GET_CODE (operands[3]) != ASHIFT)
16835 operands[2] = gen_lowpart (SImode, operands[2]);
16836 PUT_MODE (operands[3], SImode);
16837 })
16838
16839 ; Promote the QImode tests, as i386 has encoding of the AND
16840 ; instruction with 32-bit sign-extended immediate and thus the
16841 ; instruction size is unchanged, except in the %eax case for
16842 ; which it is increased by one byte, hence the ! optimize_size.
16843 (define_split
16844 [(set (match_operand 0 "flags_reg_operand")
16845 (match_operator 2 "compare_operator"
16846 [(and (match_operand 3 "aligned_operand")
16847 (match_operand 4 "const_int_operand"))
16848 (const_int 0)]))
16849 (set (match_operand 1 "register_operand")
16850 (and (match_dup 3) (match_dup 4)))]
16851 "! TARGET_PARTIAL_REG_STALL && reload_completed
16852 && optimize_insn_for_speed_p ()
16853 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16854 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16855 /* Ensure that the operand will remain sign-extended immediate. */
16856 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16857 [(parallel [(set (match_dup 0)
16858 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16859 (const_int 0)]))
16860 (set (match_dup 1)
16861 (and:SI (match_dup 3) (match_dup 4)))])]
16862 {
16863 operands[4]
16864 = gen_int_mode (INTVAL (operands[4])
16865 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16866 operands[1] = gen_lowpart (SImode, operands[1]);
16867 operands[3] = gen_lowpart (SImode, operands[3]);
16868 })
16869
16870 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16871 ; the TEST instruction with 32-bit sign-extended immediate and thus
16872 ; the instruction size would at least double, which is not what we
16873 ; want even with ! optimize_size.
16874 (define_split
16875 [(set (match_operand 0 "flags_reg_operand")
16876 (match_operator 1 "compare_operator"
16877 [(and (match_operand:HI 2 "aligned_operand")
16878 (match_operand:HI 3 "const_int_operand"))
16879 (const_int 0)]))]
16880 "! TARGET_PARTIAL_REG_STALL && reload_completed
16881 && ! TARGET_FAST_PREFIX
16882 && optimize_insn_for_speed_p ()
16883 /* Ensure that the operand will remain sign-extended immediate. */
16884 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16885 [(set (match_dup 0)
16886 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16887 (const_int 0)]))]
16888 {
16889 operands[3]
16890 = gen_int_mode (INTVAL (operands[3])
16891 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16892 operands[2] = gen_lowpart (SImode, operands[2]);
16893 })
16894
16895 (define_split
16896 [(set (match_operand 0 "register_operand")
16897 (neg (match_operand 1 "register_operand")))
16898 (clobber (reg:CC FLAGS_REG))]
16899 "! TARGET_PARTIAL_REG_STALL && reload_completed
16900 && (GET_MODE (operands[0]) == HImode
16901 || (GET_MODE (operands[0]) == QImode
16902 && (TARGET_PROMOTE_QImode
16903 || optimize_insn_for_size_p ())))"
16904 [(parallel [(set (match_dup 0)
16905 (neg:SI (match_dup 1)))
16906 (clobber (reg:CC FLAGS_REG))])]
16907 {
16908 operands[0] = gen_lowpart (SImode, operands[0]);
16909 operands[1] = gen_lowpart (SImode, operands[1]);
16910 })
16911
16912 (define_split
16913 [(set (match_operand 0 "register_operand")
16914 (not (match_operand 1 "register_operand")))]
16915 "! TARGET_PARTIAL_REG_STALL && reload_completed
16916 && (GET_MODE (operands[0]) == HImode
16917 || (GET_MODE (operands[0]) == QImode
16918 && (TARGET_PROMOTE_QImode
16919 || optimize_insn_for_size_p ())))"
16920 [(set (match_dup 0)
16921 (not:SI (match_dup 1)))]
16922 {
16923 operands[0] = gen_lowpart (SImode, operands[0]);
16924 operands[1] = gen_lowpart (SImode, operands[1]);
16925 })
16926 \f
16927 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16928 ;; transform a complex memory operation into two memory to register operations.
16929
16930 ;; Don't push memory operands
16931 (define_peephole2
16932 [(set (match_operand:SWI 0 "push_operand")
16933 (match_operand:SWI 1 "memory_operand"))
16934 (match_scratch:SWI 2 "<r>")]
16935 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16936 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16937 [(set (match_dup 2) (match_dup 1))
16938 (set (match_dup 0) (match_dup 2))])
16939
16940 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16941 ;; SImode pushes.
16942 (define_peephole2
16943 [(set (match_operand:SF 0 "push_operand")
16944 (match_operand:SF 1 "memory_operand"))
16945 (match_scratch:SF 2 "r")]
16946 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16947 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16948 [(set (match_dup 2) (match_dup 1))
16949 (set (match_dup 0) (match_dup 2))])
16950
16951 ;; Don't move an immediate directly to memory when the instruction
16952 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16953 (define_peephole2
16954 [(match_scratch:SWI124 1 "<r>")
16955 (set (match_operand:SWI124 0 "memory_operand")
16956 (const_int 0))]
16957 "optimize_insn_for_speed_p ()
16958 && ((<MODE>mode == HImode
16959 && TARGET_LCP_STALL)
16960 || (!TARGET_USE_MOV0
16961 && TARGET_SPLIT_LONG_MOVES
16962 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16963 && peep2_regno_dead_p (0, FLAGS_REG)"
16964 [(parallel [(set (match_dup 2) (const_int 0))
16965 (clobber (reg:CC FLAGS_REG))])
16966 (set (match_dup 0) (match_dup 1))]
16967 "operands[2] = gen_lowpart (SImode, operands[1]);")
16968
16969 (define_peephole2
16970 [(match_scratch:SWI124 2 "<r>")
16971 (set (match_operand:SWI124 0 "memory_operand")
16972 (match_operand:SWI124 1 "immediate_operand"))]
16973 "optimize_insn_for_speed_p ()
16974 && ((<MODE>mode == HImode
16975 && TARGET_LCP_STALL)
16976 || (TARGET_SPLIT_LONG_MOVES
16977 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16978 [(set (match_dup 2) (match_dup 1))
16979 (set (match_dup 0) (match_dup 2))])
16980
16981 ;; Don't compare memory with zero, load and use a test instead.
16982 (define_peephole2
16983 [(set (match_operand 0 "flags_reg_operand")
16984 (match_operator 1 "compare_operator"
16985 [(match_operand:SI 2 "memory_operand")
16986 (const_int 0)]))
16987 (match_scratch:SI 3 "r")]
16988 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16989 [(set (match_dup 3) (match_dup 2))
16990 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16991
16992 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16993 ;; Don't split NOTs with a displacement operand, because resulting XOR
16994 ;; will not be pairable anyway.
16995 ;;
16996 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16997 ;; represented using a modRM byte. The XOR replacement is long decoded,
16998 ;; so this split helps here as well.
16999 ;;
17000 ;; Note: Can't do this as a regular split because we can't get proper
17001 ;; lifetime information then.
17002
17003 (define_peephole2
17004 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17005 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17006 "optimize_insn_for_speed_p ()
17007 && ((TARGET_NOT_UNPAIRABLE
17008 && (!MEM_P (operands[0])
17009 || !memory_displacement_operand (operands[0], <MODE>mode)))
17010 || (TARGET_NOT_VECTORMODE
17011 && long_memory_operand (operands[0], <MODE>mode)))
17012 && peep2_regno_dead_p (0, FLAGS_REG)"
17013 [(parallel [(set (match_dup 0)
17014 (xor:SWI124 (match_dup 1) (const_int -1)))
17015 (clobber (reg:CC FLAGS_REG))])])
17016
17017 ;; Non pairable "test imm, reg" instructions can be translated to
17018 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17019 ;; byte opcode instead of two, have a short form for byte operands),
17020 ;; so do it for other CPUs as well. Given that the value was dead,
17021 ;; this should not create any new dependencies. Pass on the sub-word
17022 ;; versions if we're concerned about partial register stalls.
17023
17024 (define_peephole2
17025 [(set (match_operand 0 "flags_reg_operand")
17026 (match_operator 1 "compare_operator"
17027 [(and:SI (match_operand:SI 2 "register_operand")
17028 (match_operand:SI 3 "immediate_operand"))
17029 (const_int 0)]))]
17030 "ix86_match_ccmode (insn, CCNOmode)
17031 && (true_regnum (operands[2]) != AX_REG
17032 || satisfies_constraint_K (operands[3]))
17033 && peep2_reg_dead_p (1, operands[2])"
17034 [(parallel
17035 [(set (match_dup 0)
17036 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17037 (const_int 0)]))
17038 (set (match_dup 2)
17039 (and:SI (match_dup 2) (match_dup 3)))])])
17040
17041 ;; We don't need to handle HImode case, because it will be promoted to SImode
17042 ;; on ! TARGET_PARTIAL_REG_STALL
17043
17044 (define_peephole2
17045 [(set (match_operand 0 "flags_reg_operand")
17046 (match_operator 1 "compare_operator"
17047 [(and:QI (match_operand:QI 2 "register_operand")
17048 (match_operand:QI 3 "immediate_operand"))
17049 (const_int 0)]))]
17050 "! TARGET_PARTIAL_REG_STALL
17051 && ix86_match_ccmode (insn, CCNOmode)
17052 && true_regnum (operands[2]) != AX_REG
17053 && peep2_reg_dead_p (1, operands[2])"
17054 [(parallel
17055 [(set (match_dup 0)
17056 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17057 (const_int 0)]))
17058 (set (match_dup 2)
17059 (and:QI (match_dup 2) (match_dup 3)))])])
17060
17061 (define_peephole2
17062 [(set (match_operand 0 "flags_reg_operand")
17063 (match_operator 1 "compare_operator"
17064 [(and:SI
17065 (zero_extract:SI
17066 (match_operand 2 "ext_register_operand")
17067 (const_int 8)
17068 (const_int 8))
17069 (match_operand 3 "const_int_operand"))
17070 (const_int 0)]))]
17071 "! TARGET_PARTIAL_REG_STALL
17072 && ix86_match_ccmode (insn, CCNOmode)
17073 && true_regnum (operands[2]) != AX_REG
17074 && peep2_reg_dead_p (1, operands[2])"
17075 [(parallel [(set (match_dup 0)
17076 (match_op_dup 1
17077 [(and:SI
17078 (zero_extract:SI
17079 (match_dup 2)
17080 (const_int 8)
17081 (const_int 8))
17082 (match_dup 3))
17083 (const_int 0)]))
17084 (set (zero_extract:SI (match_dup 2)
17085 (const_int 8)
17086 (const_int 8))
17087 (and:SI
17088 (zero_extract:SI
17089 (match_dup 2)
17090 (const_int 8)
17091 (const_int 8))
17092 (match_dup 3)))])])
17093
17094 ;; Don't do logical operations with memory inputs.
17095 (define_peephole2
17096 [(match_scratch:SI 2 "r")
17097 (parallel [(set (match_operand:SI 0 "register_operand")
17098 (match_operator:SI 3 "arith_or_logical_operator"
17099 [(match_dup 0)
17100 (match_operand:SI 1 "memory_operand")]))
17101 (clobber (reg:CC FLAGS_REG))])]
17102 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17103 [(set (match_dup 2) (match_dup 1))
17104 (parallel [(set (match_dup 0)
17105 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17106 (clobber (reg:CC FLAGS_REG))])])
17107
17108 (define_peephole2
17109 [(match_scratch:SI 2 "r")
17110 (parallel [(set (match_operand:SI 0 "register_operand")
17111 (match_operator:SI 3 "arith_or_logical_operator"
17112 [(match_operand:SI 1 "memory_operand")
17113 (match_dup 0)]))
17114 (clobber (reg:CC FLAGS_REG))])]
17115 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17116 [(set (match_dup 2) (match_dup 1))
17117 (parallel [(set (match_dup 0)
17118 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17119 (clobber (reg:CC FLAGS_REG))])])
17120
17121 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17122 ;; refers to the destination of the load!
17123
17124 (define_peephole2
17125 [(set (match_operand:SI 0 "register_operand")
17126 (match_operand:SI 1 "register_operand"))
17127 (parallel [(set (match_dup 0)
17128 (match_operator:SI 3 "commutative_operator"
17129 [(match_dup 0)
17130 (match_operand:SI 2 "memory_operand")]))
17131 (clobber (reg:CC FLAGS_REG))])]
17132 "REGNO (operands[0]) != REGNO (operands[1])
17133 && GENERAL_REGNO_P (REGNO (operands[0]))
17134 && GENERAL_REGNO_P (REGNO (operands[1]))"
17135 [(set (match_dup 0) (match_dup 4))
17136 (parallel [(set (match_dup 0)
17137 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17138 (clobber (reg:CC FLAGS_REG))])]
17139 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17140
17141 (define_peephole2
17142 [(set (match_operand 0 "register_operand")
17143 (match_operand 1 "register_operand"))
17144 (set (match_dup 0)
17145 (match_operator 3 "commutative_operator"
17146 [(match_dup 0)
17147 (match_operand 2 "memory_operand")]))]
17148 "REGNO (operands[0]) != REGNO (operands[1])
17149 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17150 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17151 [(set (match_dup 0) (match_dup 2))
17152 (set (match_dup 0)
17153 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17154
17155 ; Don't do logical operations with memory outputs
17156 ;
17157 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17158 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17159 ; the same decoder scheduling characteristics as the original.
17160
17161 (define_peephole2
17162 [(match_scratch:SI 2 "r")
17163 (parallel [(set (match_operand:SI 0 "memory_operand")
17164 (match_operator:SI 3 "arith_or_logical_operator"
17165 [(match_dup 0)
17166 (match_operand:SI 1 "nonmemory_operand")]))
17167 (clobber (reg:CC FLAGS_REG))])]
17168 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17169 /* Do not split stack checking probes. */
17170 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17171 [(set (match_dup 2) (match_dup 0))
17172 (parallel [(set (match_dup 2)
17173 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17174 (clobber (reg:CC FLAGS_REG))])
17175 (set (match_dup 0) (match_dup 2))])
17176
17177 (define_peephole2
17178 [(match_scratch:SI 2 "r")
17179 (parallel [(set (match_operand:SI 0 "memory_operand")
17180 (match_operator:SI 3 "arith_or_logical_operator"
17181 [(match_operand:SI 1 "nonmemory_operand")
17182 (match_dup 0)]))
17183 (clobber (reg:CC FLAGS_REG))])]
17184 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17185 /* Do not split stack checking probes. */
17186 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17187 [(set (match_dup 2) (match_dup 0))
17188 (parallel [(set (match_dup 2)
17189 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17190 (clobber (reg:CC FLAGS_REG))])
17191 (set (match_dup 0) (match_dup 2))])
17192
17193 ;; Attempt to use arith or logical operations with memory outputs with
17194 ;; setting of flags.
17195 (define_peephole2
17196 [(set (match_operand:SWI 0 "register_operand")
17197 (match_operand:SWI 1 "memory_operand"))
17198 (parallel [(set (match_dup 0)
17199 (match_operator:SWI 3 "plusminuslogic_operator"
17200 [(match_dup 0)
17201 (match_operand:SWI 2 "<nonmemory_operand>")]))
17202 (clobber (reg:CC FLAGS_REG))])
17203 (set (match_dup 1) (match_dup 0))
17204 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17205 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17206 && peep2_reg_dead_p (4, operands[0])
17207 && !reg_overlap_mentioned_p (operands[0], operands[1])
17208 && (<MODE>mode != QImode
17209 || immediate_operand (operands[2], QImode)
17210 || q_regs_operand (operands[2], QImode))
17211 && ix86_match_ccmode (peep2_next_insn (3),
17212 (GET_CODE (operands[3]) == PLUS
17213 || GET_CODE (operands[3]) == MINUS)
17214 ? CCGOCmode : CCNOmode)"
17215 [(parallel [(set (match_dup 4) (match_dup 5))
17216 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17217 (match_dup 2)]))])]
17218 {
17219 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17220 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17221 copy_rtx (operands[1]),
17222 copy_rtx (operands[2]));
17223 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17224 operands[5], const0_rtx);
17225 })
17226
17227 (define_peephole2
17228 [(parallel [(set (match_operand:SWI 0 "register_operand")
17229 (match_operator:SWI 2 "plusminuslogic_operator"
17230 [(match_dup 0)
17231 (match_operand:SWI 1 "memory_operand")]))
17232 (clobber (reg:CC FLAGS_REG))])
17233 (set (match_dup 1) (match_dup 0))
17234 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17235 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17236 && GET_CODE (operands[2]) != MINUS
17237 && peep2_reg_dead_p (3, operands[0])
17238 && !reg_overlap_mentioned_p (operands[0], operands[1])
17239 && ix86_match_ccmode (peep2_next_insn (2),
17240 GET_CODE (operands[2]) == PLUS
17241 ? CCGOCmode : CCNOmode)"
17242 [(parallel [(set (match_dup 3) (match_dup 4))
17243 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17244 (match_dup 0)]))])]
17245 {
17246 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17247 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17248 copy_rtx (operands[1]),
17249 copy_rtx (operands[0]));
17250 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17251 operands[4], const0_rtx);
17252 })
17253
17254 (define_peephole2
17255 [(set (match_operand:SWI12 0 "register_operand")
17256 (match_operand:SWI12 1 "memory_operand"))
17257 (parallel [(set (match_operand:SI 4 "register_operand")
17258 (match_operator:SI 3 "plusminuslogic_operator"
17259 [(match_dup 4)
17260 (match_operand:SI 2 "nonmemory_operand")]))
17261 (clobber (reg:CC FLAGS_REG))])
17262 (set (match_dup 1) (match_dup 0))
17263 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17264 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17265 && REG_P (operands[0]) && REG_P (operands[4])
17266 && REGNO (operands[0]) == REGNO (operands[4])
17267 && peep2_reg_dead_p (4, operands[0])
17268 && (<MODE>mode != QImode
17269 || immediate_operand (operands[2], SImode)
17270 || q_regs_operand (operands[2], SImode))
17271 && !reg_overlap_mentioned_p (operands[0], operands[1])
17272 && ix86_match_ccmode (peep2_next_insn (3),
17273 (GET_CODE (operands[3]) == PLUS
17274 || GET_CODE (operands[3]) == MINUS)
17275 ? CCGOCmode : CCNOmode)"
17276 [(parallel [(set (match_dup 4) (match_dup 5))
17277 (set (match_dup 1) (match_dup 6))])]
17278 {
17279 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17280 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17281 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17282 copy_rtx (operands[1]), operands[2]);
17283 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17284 operands[5], const0_rtx);
17285 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17286 copy_rtx (operands[1]),
17287 copy_rtx (operands[2]));
17288 })
17289
17290 ;; Attempt to always use XOR for zeroing registers.
17291 (define_peephole2
17292 [(set (match_operand 0 "register_operand")
17293 (match_operand 1 "const0_operand"))]
17294 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17295 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17296 && GENERAL_REG_P (operands[0])
17297 && peep2_regno_dead_p (0, FLAGS_REG)"
17298 [(parallel [(set (match_dup 0) (const_int 0))
17299 (clobber (reg:CC FLAGS_REG))])]
17300 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17301
17302 (define_peephole2
17303 [(set (strict_low_part (match_operand 0 "register_operand"))
17304 (const_int 0))]
17305 "(GET_MODE (operands[0]) == QImode
17306 || GET_MODE (operands[0]) == HImode)
17307 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17308 && peep2_regno_dead_p (0, FLAGS_REG)"
17309 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17310 (clobber (reg:CC FLAGS_REG))])])
17311
17312 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17313 (define_peephole2
17314 [(set (match_operand:SWI248 0 "register_operand")
17315 (const_int -1))]
17316 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17317 && peep2_regno_dead_p (0, FLAGS_REG)"
17318 [(parallel [(set (match_dup 0) (const_int -1))
17319 (clobber (reg:CC FLAGS_REG))])]
17320 {
17321 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17322 operands[0] = gen_lowpart (SImode, operands[0]);
17323 })
17324
17325 ;; Attempt to convert simple lea to add/shift.
17326 ;; These can be created by move expanders.
17327 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17328 ;; relevant lea instructions were already split.
17329
17330 (define_peephole2
17331 [(set (match_operand:SWI48 0 "register_operand")
17332 (plus:SWI48 (match_dup 0)
17333 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17334 "!TARGET_OPT_AGU
17335 && peep2_regno_dead_p (0, FLAGS_REG)"
17336 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17337 (clobber (reg:CC FLAGS_REG))])])
17338
17339 (define_peephole2
17340 [(set (match_operand:SWI48 0 "register_operand")
17341 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17342 (match_dup 0)))]
17343 "!TARGET_OPT_AGU
17344 && peep2_regno_dead_p (0, FLAGS_REG)"
17345 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17346 (clobber (reg:CC FLAGS_REG))])])
17347
17348 (define_peephole2
17349 [(set (match_operand:SI 0 "register_operand")
17350 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17351 (match_operand:DI 2 "nonmemory_operand")) 0))]
17352 "TARGET_64BIT && !TARGET_OPT_AGU
17353 && REGNO (operands[0]) == REGNO (operands[1])
17354 && peep2_regno_dead_p (0, FLAGS_REG)"
17355 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17356 (clobber (reg:CC FLAGS_REG))])]
17357 "operands[2] = gen_lowpart (SImode, operands[2]);")
17358
17359 (define_peephole2
17360 [(set (match_operand:SI 0 "register_operand")
17361 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17362 (match_operand:DI 2 "register_operand")) 0))]
17363 "TARGET_64BIT && !TARGET_OPT_AGU
17364 && REGNO (operands[0]) == REGNO (operands[2])
17365 && peep2_regno_dead_p (0, FLAGS_REG)"
17366 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17367 (clobber (reg:CC FLAGS_REG))])]
17368 "operands[1] = gen_lowpart (SImode, operands[1]);")
17369
17370 (define_peephole2
17371 [(set (match_operand:DI 0 "register_operand")
17372 (zero_extend:DI
17373 (plus:SI (match_operand:SI 1 "register_operand")
17374 (match_operand:SI 2 "nonmemory_operand"))))]
17375 "TARGET_64BIT && !TARGET_OPT_AGU
17376 && REGNO (operands[0]) == REGNO (operands[1])
17377 && peep2_regno_dead_p (0, FLAGS_REG)"
17378 [(parallel [(set (match_dup 0)
17379 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17380 (clobber (reg:CC FLAGS_REG))])])
17381
17382 (define_peephole2
17383 [(set (match_operand:DI 0 "register_operand")
17384 (zero_extend:DI
17385 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17386 (match_operand:SI 2 "register_operand"))))]
17387 "TARGET_64BIT && !TARGET_OPT_AGU
17388 && REGNO (operands[0]) == REGNO (operands[2])
17389 && peep2_regno_dead_p (0, FLAGS_REG)"
17390 [(parallel [(set (match_dup 0)
17391 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17392 (clobber (reg:CC FLAGS_REG))])])
17393
17394 (define_peephole2
17395 [(set (match_operand:DI 0 "register_operand")
17396 (zero_extend:DI
17397 (subreg:SI (plus:DI (match_dup 0)
17398 (match_operand:DI 1 "nonmemory_operand")) 0)))]
17399 "TARGET_64BIT && !TARGET_OPT_AGU
17400 && peep2_regno_dead_p (0, FLAGS_REG)"
17401 [(parallel [(set (match_dup 0)
17402 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17403 (clobber (reg:CC FLAGS_REG))])]
17404 {
17405 operands[1] = gen_lowpart (SImode, operands[1]);
17406 operands[2] = gen_lowpart (SImode, operands[0]);
17407 })
17408
17409 (define_peephole2
17410 [(set (match_operand:DI 0 "register_operand")
17411 (zero_extend:DI
17412 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17413 (match_dup 0)) 0)))]
17414 "TARGET_64BIT && !TARGET_OPT_AGU
17415 && peep2_regno_dead_p (0, FLAGS_REG)"
17416 [(parallel [(set (match_dup 0)
17417 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17418 (clobber (reg:CC FLAGS_REG))])]
17419 {
17420 operands[1] = gen_lowpart (SImode, operands[1]);
17421 operands[2] = gen_lowpart (SImode, operands[0]);
17422 })
17423
17424 (define_peephole2
17425 [(set (match_operand:SWI48 0 "register_operand")
17426 (mult:SWI48 (match_dup 0)
17427 (match_operand:SWI48 1 "const_int_operand")))]
17428 "exact_log2 (INTVAL (operands[1])) >= 0
17429 && peep2_regno_dead_p (0, FLAGS_REG)"
17430 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17431 (clobber (reg:CC FLAGS_REG))])]
17432 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17433
17434 (define_peephole2
17435 [(set (match_operand:SI 0 "register_operand")
17436 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17437 (match_operand:DI 2 "const_int_operand")) 0))]
17438 "TARGET_64BIT
17439 && exact_log2 (INTVAL (operands[2])) >= 0
17440 && REGNO (operands[0]) == REGNO (operands[1])
17441 && peep2_regno_dead_p (0, FLAGS_REG)"
17442 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17443 (clobber (reg:CC FLAGS_REG))])]
17444 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17445
17446 (define_peephole2
17447 [(set (match_operand:DI 0 "register_operand")
17448 (zero_extend:DI
17449 (mult:SI (match_operand:SI 1 "register_operand")
17450 (match_operand:SI 2 "const_int_operand"))))]
17451 "TARGET_64BIT
17452 && exact_log2 (INTVAL (operands[2])) >= 0
17453 && REGNO (operands[0]) == REGNO (operands[1])
17454 && peep2_regno_dead_p (0, FLAGS_REG)"
17455 [(parallel [(set (match_dup 0)
17456 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17457 (clobber (reg:CC FLAGS_REG))])]
17458 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17459
17460 (define_peephole2
17461 [(set (match_operand:DI 0 "register_operand")
17462 (zero_extend:DI
17463 (subreg:SI (mult:DI (match_dup 0)
17464 (match_operand:DI 1 "const_int_operand")) 0)))]
17465 "TARGET_64BIT
17466 && exact_log2 (INTVAL (operands[2])) >= 0
17467 && peep2_regno_dead_p (0, FLAGS_REG)"
17468 [(parallel [(set (match_dup 0)
17469 (zero_extend:DI (ashift:SI (match_dup 2) (match_dup 1))))
17470 (clobber (reg:CC FLAGS_REG))])]
17471 {
17472 operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
17473 operands[2] = gen_lowpart (SImode, operands[0]);
17474 })
17475
17476 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17477 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17478 ;; On many CPUs it is also faster, since special hardware to avoid esp
17479 ;; dependencies is present.
17480
17481 ;; While some of these conversions may be done using splitters, we use
17482 ;; peepholes in order to allow combine_stack_adjustments pass to see
17483 ;; nonobfuscated RTL.
17484
17485 ;; Convert prologue esp subtractions to push.
17486 ;; We need register to push. In order to keep verify_flow_info happy we have
17487 ;; two choices
17488 ;; - use scratch and clobber it in order to avoid dependencies
17489 ;; - use already live register
17490 ;; We can't use the second way right now, since there is no reliable way how to
17491 ;; verify that given register is live. First choice will also most likely in
17492 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17493 ;; call clobbered registers are dead. We may want to use base pointer as an
17494 ;; alternative when no register is available later.
17495
17496 (define_peephole2
17497 [(match_scratch:W 1 "r")
17498 (parallel [(set (reg:P SP_REG)
17499 (plus:P (reg:P SP_REG)
17500 (match_operand:P 0 "const_int_operand")))
17501 (clobber (reg:CC FLAGS_REG))
17502 (clobber (mem:BLK (scratch)))])]
17503 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17504 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17505 [(clobber (match_dup 1))
17506 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17507 (clobber (mem:BLK (scratch)))])])
17508
17509 (define_peephole2
17510 [(match_scratch:W 1 "r")
17511 (parallel [(set (reg:P SP_REG)
17512 (plus:P (reg:P SP_REG)
17513 (match_operand:P 0 "const_int_operand")))
17514 (clobber (reg:CC FLAGS_REG))
17515 (clobber (mem:BLK (scratch)))])]
17516 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17517 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17518 [(clobber (match_dup 1))
17519 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17520 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17521 (clobber (mem:BLK (scratch)))])])
17522
17523 ;; Convert esp subtractions to push.
17524 (define_peephole2
17525 [(match_scratch:W 1 "r")
17526 (parallel [(set (reg:P SP_REG)
17527 (plus:P (reg:P SP_REG)
17528 (match_operand:P 0 "const_int_operand")))
17529 (clobber (reg:CC FLAGS_REG))])]
17530 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17531 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17532 [(clobber (match_dup 1))
17533 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17534
17535 (define_peephole2
17536 [(match_scratch:W 1 "r")
17537 (parallel [(set (reg:P SP_REG)
17538 (plus:P (reg:P SP_REG)
17539 (match_operand:P 0 "const_int_operand")))
17540 (clobber (reg:CC FLAGS_REG))])]
17541 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17542 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17543 [(clobber (match_dup 1))
17544 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17545 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17546
17547 ;; Convert epilogue deallocator to pop.
17548 (define_peephole2
17549 [(match_scratch:W 1 "r")
17550 (parallel [(set (reg:P SP_REG)
17551 (plus:P (reg:P SP_REG)
17552 (match_operand:P 0 "const_int_operand")))
17553 (clobber (reg:CC FLAGS_REG))
17554 (clobber (mem:BLK (scratch)))])]
17555 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17556 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17557 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17558 (clobber (mem:BLK (scratch)))])])
17559
17560 ;; Two pops case is tricky, since pop causes dependency
17561 ;; on destination register. We use two registers if available.
17562 (define_peephole2
17563 [(match_scratch:W 1 "r")
17564 (match_scratch:W 2 "r")
17565 (parallel [(set (reg:P SP_REG)
17566 (plus:P (reg:P SP_REG)
17567 (match_operand:P 0 "const_int_operand")))
17568 (clobber (reg:CC FLAGS_REG))
17569 (clobber (mem:BLK (scratch)))])]
17570 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17571 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17572 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17573 (clobber (mem:BLK (scratch)))])
17574 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17575
17576 (define_peephole2
17577 [(match_scratch:W 1 "r")
17578 (parallel [(set (reg:P SP_REG)
17579 (plus:P (reg:P SP_REG)
17580 (match_operand:P 0 "const_int_operand")))
17581 (clobber (reg:CC FLAGS_REG))
17582 (clobber (mem:BLK (scratch)))])]
17583 "optimize_insn_for_size_p ()
17584 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17585 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17586 (clobber (mem:BLK (scratch)))])
17587 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17588
17589 ;; Convert esp additions to pop.
17590 (define_peephole2
17591 [(match_scratch:W 1 "r")
17592 (parallel [(set (reg:P SP_REG)
17593 (plus:P (reg:P SP_REG)
17594 (match_operand:P 0 "const_int_operand")))
17595 (clobber (reg:CC FLAGS_REG))])]
17596 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17597 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17598
17599 ;; Two pops case is tricky, since pop causes dependency
17600 ;; on destination register. We use two registers if available.
17601 (define_peephole2
17602 [(match_scratch:W 1 "r")
17603 (match_scratch:W 2 "r")
17604 (parallel [(set (reg:P SP_REG)
17605 (plus:P (reg:P SP_REG)
17606 (match_operand:P 0 "const_int_operand")))
17607 (clobber (reg:CC FLAGS_REG))])]
17608 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17609 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17610 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17611
17612 (define_peephole2
17613 [(match_scratch:W 1 "r")
17614 (parallel [(set (reg:P SP_REG)
17615 (plus:P (reg:P SP_REG)
17616 (match_operand:P 0 "const_int_operand")))
17617 (clobber (reg:CC FLAGS_REG))])]
17618 "optimize_insn_for_size_p ()
17619 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17620 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17621 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17622 \f
17623 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17624 ;; required and register dies. Similarly for 128 to -128.
17625 (define_peephole2
17626 [(set (match_operand 0 "flags_reg_operand")
17627 (match_operator 1 "compare_operator"
17628 [(match_operand 2 "register_operand")
17629 (match_operand 3 "const_int_operand")]))]
17630 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17631 && incdec_operand (operands[3], GET_MODE (operands[3])))
17632 || (!TARGET_FUSE_CMP_AND_BRANCH
17633 && INTVAL (operands[3]) == 128))
17634 && ix86_match_ccmode (insn, CCGCmode)
17635 && peep2_reg_dead_p (1, operands[2])"
17636 [(parallel [(set (match_dup 0)
17637 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17638 (clobber (match_dup 2))])])
17639 \f
17640 ;; Convert imul by three, five and nine into lea
17641 (define_peephole2
17642 [(parallel
17643 [(set (match_operand:SWI48 0 "register_operand")
17644 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17645 (match_operand:SWI48 2 "const359_operand")))
17646 (clobber (reg:CC FLAGS_REG))])]
17647 "!TARGET_PARTIAL_REG_STALL
17648 || <MODE>mode == SImode
17649 || optimize_function_for_size_p (cfun)"
17650 [(set (match_dup 0)
17651 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17652 (match_dup 1)))]
17653 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17654
17655 (define_peephole2
17656 [(parallel
17657 [(set (match_operand:SWI48 0 "register_operand")
17658 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17659 (match_operand:SWI48 2 "const359_operand")))
17660 (clobber (reg:CC FLAGS_REG))])]
17661 "optimize_insn_for_speed_p ()
17662 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17663 [(set (match_dup 0) (match_dup 1))
17664 (set (match_dup 0)
17665 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17666 (match_dup 0)))]
17667 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17668
17669 ;; imul $32bit_imm, mem, reg is vector decoded, while
17670 ;; imul $32bit_imm, reg, reg is direct decoded.
17671 (define_peephole2
17672 [(match_scratch:SWI48 3 "r")
17673 (parallel [(set (match_operand:SWI48 0 "register_operand")
17674 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17675 (match_operand:SWI48 2 "immediate_operand")))
17676 (clobber (reg:CC FLAGS_REG))])]
17677 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17678 && !satisfies_constraint_K (operands[2])"
17679 [(set (match_dup 3) (match_dup 1))
17680 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17681 (clobber (reg:CC FLAGS_REG))])])
17682
17683 (define_peephole2
17684 [(match_scratch:SI 3 "r")
17685 (parallel [(set (match_operand:DI 0 "register_operand")
17686 (zero_extend:DI
17687 (mult:SI (match_operand:SI 1 "memory_operand")
17688 (match_operand:SI 2 "immediate_operand"))))
17689 (clobber (reg:CC FLAGS_REG))])]
17690 "TARGET_64BIT
17691 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17692 && !satisfies_constraint_K (operands[2])"
17693 [(set (match_dup 3) (match_dup 1))
17694 (parallel [(set (match_dup 0)
17695 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17696 (clobber (reg:CC FLAGS_REG))])])
17697
17698 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17699 ;; Convert it into imul reg, reg
17700 ;; It would be better to force assembler to encode instruction using long
17701 ;; immediate, but there is apparently no way to do so.
17702 (define_peephole2
17703 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17704 (mult:SWI248
17705 (match_operand:SWI248 1 "nonimmediate_operand")
17706 (match_operand:SWI248 2 "const_int_operand")))
17707 (clobber (reg:CC FLAGS_REG))])
17708 (match_scratch:SWI248 3 "r")]
17709 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17710 && satisfies_constraint_K (operands[2])"
17711 [(set (match_dup 3) (match_dup 2))
17712 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17713 (clobber (reg:CC FLAGS_REG))])]
17714 {
17715 if (!rtx_equal_p (operands[0], operands[1]))
17716 emit_move_insn (operands[0], operands[1]);
17717 })
17718
17719 ;; After splitting up read-modify operations, array accesses with memory
17720 ;; operands might end up in form:
17721 ;; sall $2, %eax
17722 ;; movl 4(%esp), %edx
17723 ;; addl %edx, %eax
17724 ;; instead of pre-splitting:
17725 ;; sall $2, %eax
17726 ;; addl 4(%esp), %eax
17727 ;; Turn it into:
17728 ;; movl 4(%esp), %edx
17729 ;; leal (%edx,%eax,4), %eax
17730
17731 (define_peephole2
17732 [(match_scratch:W 5 "r")
17733 (parallel [(set (match_operand 0 "register_operand")
17734 (ashift (match_operand 1 "register_operand")
17735 (match_operand 2 "const_int_operand")))
17736 (clobber (reg:CC FLAGS_REG))])
17737 (parallel [(set (match_operand 3 "register_operand")
17738 (plus (match_dup 0)
17739 (match_operand 4 "x86_64_general_operand")))
17740 (clobber (reg:CC FLAGS_REG))])]
17741 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17742 /* Validate MODE for lea. */
17743 && ((!TARGET_PARTIAL_REG_STALL
17744 && (GET_MODE (operands[0]) == QImode
17745 || GET_MODE (operands[0]) == HImode))
17746 || GET_MODE (operands[0]) == SImode
17747 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17748 && (rtx_equal_p (operands[0], operands[3])
17749 || peep2_reg_dead_p (2, operands[0]))
17750 /* We reorder load and the shift. */
17751 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17752 [(set (match_dup 5) (match_dup 4))
17753 (set (match_dup 0) (match_dup 1))]
17754 {
17755 enum machine_mode op1mode = GET_MODE (operands[1]);
17756 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17757 int scale = 1 << INTVAL (operands[2]);
17758 rtx index = gen_lowpart (word_mode, operands[1]);
17759 rtx base = gen_lowpart (word_mode, operands[5]);
17760 rtx dest = gen_lowpart (mode, operands[3]);
17761
17762 operands[1] = gen_rtx_PLUS (word_mode, base,
17763 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17764 operands[5] = base;
17765 if (mode != word_mode)
17766 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17767 if (op1mode != word_mode)
17768 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17769 operands[0] = dest;
17770 })
17771 \f
17772 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17773 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17774 ;; caught for use by garbage collectors and the like. Using an insn that
17775 ;; maps to SIGILL makes it more likely the program will rightfully die.
17776 ;; Keeping with tradition, "6" is in honor of #UD.
17777 (define_insn "trap"
17778 [(trap_if (const_int 1) (const_int 6))]
17779 ""
17780 { return ASM_SHORT "0x0b0f"; }
17781 [(set_attr "length" "2")])
17782
17783 (define_expand "prefetch"
17784 [(prefetch (match_operand 0 "address_operand")
17785 (match_operand:SI 1 "const_int_operand")
17786 (match_operand:SI 2 "const_int_operand"))]
17787 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17788 {
17789 int rw = INTVAL (operands[1]);
17790 int locality = INTVAL (operands[2]);
17791
17792 gcc_assert (rw == 0 || rw == 1);
17793 gcc_assert (locality >= 0 && locality <= 3);
17794 gcc_assert (GET_MODE (operands[0]) == Pmode
17795 || GET_MODE (operands[0]) == VOIDmode);
17796 if (TARGET_PRFCHW && rw)
17797 operands[2] = GEN_INT (3);
17798
17799 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17800 supported by SSE counterpart or the SSE prefetch is not available
17801 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17802 of locality. */
17803 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17804 operands[2] = GEN_INT (3);
17805 else
17806 operands[1] = const0_rtx;
17807 })
17808
17809 (define_insn "*prefetch_sse_<mode>"
17810 [(prefetch (match_operand:P 0 "address_operand" "p")
17811 (const_int 0)
17812 (match_operand:SI 1 "const_int_operand"))]
17813 "TARGET_PREFETCH_SSE"
17814 {
17815 static const char * const patterns[4] = {
17816 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17817 };
17818
17819 int locality = INTVAL (operands[1]);
17820 gcc_assert (locality >= 0 && locality <= 3);
17821
17822 return patterns[locality];
17823 }
17824 [(set_attr "type" "sse")
17825 (set_attr "atom_sse_attr" "prefetch")
17826 (set (attr "length_address")
17827 (symbol_ref "memory_address_length (operands[0])"))
17828 (set_attr "memory" "none")])
17829
17830 (define_insn "*prefetch_3dnow_<mode>"
17831 [(prefetch (match_operand:P 0 "address_operand" "p")
17832 (match_operand:SI 1 "const_int_operand" "n")
17833 (const_int 3))]
17834 "TARGET_3DNOW || TARGET_PRFCHW"
17835 {
17836 if (INTVAL (operands[1]) == 0)
17837 return "prefetch\t%a0";
17838 else
17839 return "prefetchw\t%a0";
17840 }
17841 [(set_attr "type" "mmx")
17842 (set (attr "length_address")
17843 (symbol_ref "memory_address_length (operands[0])"))
17844 (set_attr "memory" "none")])
17845
17846 (define_expand "stack_protect_set"
17847 [(match_operand 0 "memory_operand")
17848 (match_operand 1 "memory_operand")]
17849 "!TARGET_HAS_BIONIC"
17850 {
17851 rtx (*insn)(rtx, rtx);
17852
17853 #ifdef TARGET_THREAD_SSP_OFFSET
17854 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17855 insn = (TARGET_LP64
17856 ? gen_stack_tls_protect_set_di
17857 : gen_stack_tls_protect_set_si);
17858 #else
17859 insn = (TARGET_LP64
17860 ? gen_stack_protect_set_di
17861 : gen_stack_protect_set_si);
17862 #endif
17863
17864 emit_insn (insn (operands[0], operands[1]));
17865 DONE;
17866 })
17867
17868 (define_insn "stack_protect_set_<mode>"
17869 [(set (match_operand:PTR 0 "memory_operand" "=m")
17870 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17871 UNSPEC_SP_SET))
17872 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17873 (clobber (reg:CC FLAGS_REG))]
17874 "!TARGET_HAS_BIONIC"
17875 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17876 [(set_attr "type" "multi")])
17877
17878 (define_insn "stack_tls_protect_set_<mode>"
17879 [(set (match_operand:PTR 0 "memory_operand" "=m")
17880 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17881 UNSPEC_SP_TLS_SET))
17882 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17883 (clobber (reg:CC FLAGS_REG))]
17884 ""
17885 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17886 [(set_attr "type" "multi")])
17887
17888 (define_expand "stack_protect_test"
17889 [(match_operand 0 "memory_operand")
17890 (match_operand 1 "memory_operand")
17891 (match_operand 2)]
17892 "!TARGET_HAS_BIONIC"
17893 {
17894 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17895
17896 rtx (*insn)(rtx, rtx, rtx);
17897
17898 #ifdef TARGET_THREAD_SSP_OFFSET
17899 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17900 insn = (TARGET_LP64
17901 ? gen_stack_tls_protect_test_di
17902 : gen_stack_tls_protect_test_si);
17903 #else
17904 insn = (TARGET_LP64
17905 ? gen_stack_protect_test_di
17906 : gen_stack_protect_test_si);
17907 #endif
17908
17909 emit_insn (insn (flags, operands[0], operands[1]));
17910
17911 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17912 flags, const0_rtx, operands[2]));
17913 DONE;
17914 })
17915
17916 (define_insn "stack_protect_test_<mode>"
17917 [(set (match_operand:CCZ 0 "flags_reg_operand")
17918 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17919 (match_operand:PTR 2 "memory_operand" "m")]
17920 UNSPEC_SP_TEST))
17921 (clobber (match_scratch:PTR 3 "=&r"))]
17922 "!TARGET_HAS_BIONIC"
17923 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17924 [(set_attr "type" "multi")])
17925
17926 (define_insn "stack_tls_protect_test_<mode>"
17927 [(set (match_operand:CCZ 0 "flags_reg_operand")
17928 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17929 (match_operand:PTR 2 "const_int_operand" "i")]
17930 UNSPEC_SP_TLS_TEST))
17931 (clobber (match_scratch:PTR 3 "=r"))]
17932 ""
17933 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17934 [(set_attr "type" "multi")])
17935
17936 (define_insn "sse4_2_crc32<mode>"
17937 [(set (match_operand:SI 0 "register_operand" "=r")
17938 (unspec:SI
17939 [(match_operand:SI 1 "register_operand" "0")
17940 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17941 UNSPEC_CRC32))]
17942 "TARGET_SSE4_2 || TARGET_CRC32"
17943 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17944 [(set_attr "type" "sselog1")
17945 (set_attr "prefix_rep" "1")
17946 (set_attr "prefix_extra" "1")
17947 (set (attr "prefix_data16")
17948 (if_then_else (match_operand:HI 2)
17949 (const_string "1")
17950 (const_string "*")))
17951 (set (attr "prefix_rex")
17952 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17953 (const_string "1")
17954 (const_string "*")))
17955 (set_attr "mode" "SI")])
17956
17957 (define_insn "sse4_2_crc32di"
17958 [(set (match_operand:DI 0 "register_operand" "=r")
17959 (unspec:DI
17960 [(match_operand:DI 1 "register_operand" "0")
17961 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17962 UNSPEC_CRC32))]
17963 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17964 "crc32{q}\t{%2, %0|%0, %2}"
17965 [(set_attr "type" "sselog1")
17966 (set_attr "prefix_rep" "1")
17967 (set_attr "prefix_extra" "1")
17968 (set_attr "mode" "DI")])
17969
17970 (define_expand "rdpmc"
17971 [(match_operand:DI 0 "register_operand")
17972 (match_operand:SI 1 "register_operand")]
17973 ""
17974 {
17975 rtx reg = gen_reg_rtx (DImode);
17976 rtx si;
17977
17978 /* Force operand 1 into ECX. */
17979 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17980 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17981 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17982 UNSPECV_RDPMC);
17983
17984 if (TARGET_64BIT)
17985 {
17986 rtvec vec = rtvec_alloc (2);
17987 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17988 rtx upper = gen_reg_rtx (DImode);
17989 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17990 gen_rtvec (1, const0_rtx),
17991 UNSPECV_RDPMC);
17992 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17993 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17994 emit_insn (load);
17995 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17996 NULL, 1, OPTAB_DIRECT);
17997 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17998 OPTAB_DIRECT);
17999 }
18000 else
18001 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18002 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18003 DONE;
18004 })
18005
18006 (define_insn "*rdpmc"
18007 [(set (match_operand:DI 0 "register_operand" "=A")
18008 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18009 UNSPECV_RDPMC))]
18010 "!TARGET_64BIT"
18011 "rdpmc"
18012 [(set_attr "type" "other")
18013 (set_attr "length" "2")])
18014
18015 (define_insn "*rdpmc_rex64"
18016 [(set (match_operand:DI 0 "register_operand" "=a")
18017 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18018 UNSPECV_RDPMC))
18019 (set (match_operand:DI 1 "register_operand" "=d")
18020 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18021 "TARGET_64BIT"
18022 "rdpmc"
18023 [(set_attr "type" "other")
18024 (set_attr "length" "2")])
18025
18026 (define_expand "rdtsc"
18027 [(set (match_operand:DI 0 "register_operand")
18028 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18029 ""
18030 {
18031 if (TARGET_64BIT)
18032 {
18033 rtvec vec = rtvec_alloc (2);
18034 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18035 rtx upper = gen_reg_rtx (DImode);
18036 rtx lower = gen_reg_rtx (DImode);
18037 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18038 gen_rtvec (1, const0_rtx),
18039 UNSPECV_RDTSC);
18040 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18041 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18042 emit_insn (load);
18043 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18044 NULL, 1, OPTAB_DIRECT);
18045 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18046 OPTAB_DIRECT);
18047 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18048 DONE;
18049 }
18050 })
18051
18052 (define_insn "*rdtsc"
18053 [(set (match_operand:DI 0 "register_operand" "=A")
18054 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18055 "!TARGET_64BIT"
18056 "rdtsc"
18057 [(set_attr "type" "other")
18058 (set_attr "length" "2")])
18059
18060 (define_insn "*rdtsc_rex64"
18061 [(set (match_operand:DI 0 "register_operand" "=a")
18062 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18063 (set (match_operand:DI 1 "register_operand" "=d")
18064 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18065 "TARGET_64BIT"
18066 "rdtsc"
18067 [(set_attr "type" "other")
18068 (set_attr "length" "2")])
18069
18070 (define_expand "rdtscp"
18071 [(match_operand:DI 0 "register_operand")
18072 (match_operand:SI 1 "memory_operand")]
18073 ""
18074 {
18075 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18076 gen_rtvec (1, const0_rtx),
18077 UNSPECV_RDTSCP);
18078 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18079 gen_rtvec (1, const0_rtx),
18080 UNSPECV_RDTSCP);
18081 rtx reg = gen_reg_rtx (DImode);
18082 rtx tmp = gen_reg_rtx (SImode);
18083
18084 if (TARGET_64BIT)
18085 {
18086 rtvec vec = rtvec_alloc (3);
18087 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18088 rtx upper = gen_reg_rtx (DImode);
18089 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18090 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18091 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18092 emit_insn (load);
18093 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18094 NULL, 1, OPTAB_DIRECT);
18095 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18096 OPTAB_DIRECT);
18097 }
18098 else
18099 {
18100 rtvec vec = rtvec_alloc (2);
18101 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18102 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18103 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18104 emit_insn (load);
18105 }
18106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18107 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18108 DONE;
18109 })
18110
18111 (define_insn "*rdtscp"
18112 [(set (match_operand:DI 0 "register_operand" "=A")
18113 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18114 (set (match_operand:SI 1 "register_operand" "=c")
18115 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18116 "!TARGET_64BIT"
18117 "rdtscp"
18118 [(set_attr "type" "other")
18119 (set_attr "length" "3")])
18120
18121 (define_insn "*rdtscp_rex64"
18122 [(set (match_operand:DI 0 "register_operand" "=a")
18123 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18124 (set (match_operand:DI 1 "register_operand" "=d")
18125 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18126 (set (match_operand:SI 2 "register_operand" "=c")
18127 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18128 "TARGET_64BIT"
18129 "rdtscp"
18130 [(set_attr "type" "other")
18131 (set_attr "length" "3")])
18132
18133 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18134 ;;
18135 ;; LWP instructions
18136 ;;
18137 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18138
18139 (define_expand "lwp_llwpcb"
18140 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18141 UNSPECV_LLWP_INTRINSIC)]
18142 "TARGET_LWP")
18143
18144 (define_insn "*lwp_llwpcb<mode>1"
18145 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18146 UNSPECV_LLWP_INTRINSIC)]
18147 "TARGET_LWP"
18148 "llwpcb\t%0"
18149 [(set_attr "type" "lwp")
18150 (set_attr "mode" "<MODE>")
18151 (set_attr "length" "5")])
18152
18153 (define_expand "lwp_slwpcb"
18154 [(set (match_operand 0 "register_operand" "=r")
18155 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18156 "TARGET_LWP"
18157 {
18158 rtx (*insn)(rtx);
18159
18160 insn = (Pmode == DImode
18161 ? gen_lwp_slwpcbdi
18162 : gen_lwp_slwpcbsi);
18163
18164 emit_insn (insn (operands[0]));
18165 DONE;
18166 })
18167
18168 (define_insn "lwp_slwpcb<mode>"
18169 [(set (match_operand:P 0 "register_operand" "=r")
18170 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18171 "TARGET_LWP"
18172 "slwpcb\t%0"
18173 [(set_attr "type" "lwp")
18174 (set_attr "mode" "<MODE>")
18175 (set_attr "length" "5")])
18176
18177 (define_expand "lwp_lwpval<mode>3"
18178 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18179 (match_operand:SI 2 "nonimmediate_operand" "rm")
18180 (match_operand:SI 3 "const_int_operand" "i")]
18181 UNSPECV_LWPVAL_INTRINSIC)]
18182 "TARGET_LWP"
18183 ;; Avoid unused variable warning.
18184 "(void) operands[0];")
18185
18186 (define_insn "*lwp_lwpval<mode>3_1"
18187 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18188 (match_operand:SI 1 "nonimmediate_operand" "rm")
18189 (match_operand:SI 2 "const_int_operand" "i")]
18190 UNSPECV_LWPVAL_INTRINSIC)]
18191 "TARGET_LWP"
18192 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18193 [(set_attr "type" "lwp")
18194 (set_attr "mode" "<MODE>")
18195 (set (attr "length")
18196 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18197
18198 (define_expand "lwp_lwpins<mode>3"
18199 [(set (reg:CCC FLAGS_REG)
18200 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18201 (match_operand:SI 2 "nonimmediate_operand" "rm")
18202 (match_operand:SI 3 "const_int_operand" "i")]
18203 UNSPECV_LWPINS_INTRINSIC))
18204 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18205 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18206 "TARGET_LWP")
18207
18208 (define_insn "*lwp_lwpins<mode>3_1"
18209 [(set (reg:CCC FLAGS_REG)
18210 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18211 (match_operand:SI 1 "nonimmediate_operand" "rm")
18212 (match_operand:SI 2 "const_int_operand" "i")]
18213 UNSPECV_LWPINS_INTRINSIC))]
18214 "TARGET_LWP"
18215 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18216 [(set_attr "type" "lwp")
18217 (set_attr "mode" "<MODE>")
18218 (set (attr "length")
18219 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18220
18221 (define_int_iterator RDFSGSBASE
18222 [UNSPECV_RDFSBASE
18223 UNSPECV_RDGSBASE])
18224
18225 (define_int_iterator WRFSGSBASE
18226 [UNSPECV_WRFSBASE
18227 UNSPECV_WRGSBASE])
18228
18229 (define_int_attr fsgs
18230 [(UNSPECV_RDFSBASE "fs")
18231 (UNSPECV_RDGSBASE "gs")
18232 (UNSPECV_WRFSBASE "fs")
18233 (UNSPECV_WRGSBASE "gs")])
18234
18235 (define_insn "rd<fsgs>base<mode>"
18236 [(set (match_operand:SWI48 0 "register_operand" "=r")
18237 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18238 "TARGET_64BIT && TARGET_FSGSBASE"
18239 "rd<fsgs>base\t%0"
18240 [(set_attr "type" "other")
18241 (set_attr "prefix_extra" "2")])
18242
18243 (define_insn "wr<fsgs>base<mode>"
18244 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18245 WRFSGSBASE)]
18246 "TARGET_64BIT && TARGET_FSGSBASE"
18247 "wr<fsgs>base\t%0"
18248 [(set_attr "type" "other")
18249 (set_attr "prefix_extra" "2")])
18250
18251 (define_insn "rdrand<mode>_1"
18252 [(set (match_operand:SWI248 0 "register_operand" "=r")
18253 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18254 (set (reg:CCC FLAGS_REG)
18255 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18256 "TARGET_RDRND"
18257 "rdrand\t%0"
18258 [(set_attr "type" "other")
18259 (set_attr "prefix_extra" "1")])
18260
18261 (define_insn "rdseed<mode>_1"
18262 [(set (match_operand:SWI248 0 "register_operand" "=r")
18263 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18264 (set (reg:CCC FLAGS_REG)
18265 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18266 "TARGET_RDSEED"
18267 "rdseed\t%0"
18268 [(set_attr "type" "other")
18269 (set_attr "prefix_extra" "1")])
18270
18271 (define_expand "pause"
18272 [(set (match_dup 0)
18273 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18274 ""
18275 {
18276 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18277 MEM_VOLATILE_P (operands[0]) = 1;
18278 })
18279
18280 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18281 ;; They have the same encoding.
18282 (define_insn "*pause"
18283 [(set (match_operand:BLK 0)
18284 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18285 ""
18286 "rep%; nop"
18287 [(set_attr "length" "2")
18288 (set_attr "memory" "unknown")])
18289
18290 (define_expand "xbegin"
18291 [(set (match_operand:SI 0 "register_operand")
18292 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18293 "TARGET_RTM"
18294 {
18295 rtx label = gen_label_rtx ();
18296
18297 operands[1] = force_reg (SImode, constm1_rtx);
18298
18299 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18300
18301 emit_label (label);
18302 LABEL_NUSES (label) = 1;
18303
18304 emit_move_insn (operands[0], operands[1]);
18305
18306 DONE;
18307 })
18308
18309 (define_insn "xbegin_1"
18310 [(set (pc)
18311 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18312 (const_int 0))
18313 (label_ref (match_operand 1))
18314 (pc)))
18315 (set (match_operand:SI 0 "register_operand" "+a")
18316 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18317 "TARGET_RTM"
18318 "xbegin\t%l1"
18319 [(set_attr "type" "other")
18320 (set_attr "length" "6")])
18321
18322 (define_insn "xend"
18323 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18324 "TARGET_RTM"
18325 "xend"
18326 [(set_attr "type" "other")
18327 (set_attr "length" "3")])
18328
18329 (define_insn "xabort"
18330 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18331 UNSPECV_XABORT)]
18332 "TARGET_RTM"
18333 "xabort\t%0"
18334 [(set_attr "type" "other")
18335 (set_attr "length" "3")])
18336
18337 (define_expand "xtest"
18338 [(set (match_operand:QI 0 "register_operand")
18339 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18340 "TARGET_RTM"
18341 {
18342 emit_insn (gen_xtest_1 ());
18343
18344 ix86_expand_setcc (operands[0], NE,
18345 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18346 DONE;
18347 })
18348
18349 (define_insn "xtest_1"
18350 [(set (reg:CCZ FLAGS_REG)
18351 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18352 "TARGET_RTM"
18353 "xtest"
18354 [(set_attr "type" "other")
18355 (set_attr "length" "3")])
18356
18357 (include "mmx.md")
18358 (include "sse.md")
18359 (include "sync.md")