]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
21 ;;
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24 ;;
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;; otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;; delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81
82 ;; Prologue support
83 UNSPEC_STACK_ALLOC
84 UNSPEC_SET_GOT
85 UNSPEC_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_STACK_CHECK
89
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
95 UNSPEC_TLS_IE_SUN
96
97 ;; Other random patterns
98 UNSPEC_SCAS
99 UNSPEC_FNSTSW
100 UNSPEC_SAHF
101 UNSPEC_PARITY
102 UNSPEC_FSTCW
103 UNSPEC_ADD_CARRY
104 UNSPEC_FLDCW
105 UNSPEC_REP
106 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_TRUNC_NOOP
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
110 UNSPEC_PAUSE
111 UNSPEC_LEA_ADDR
112 UNSPEC_XBEGIN_ABORT
113 UNSPEC_STOS
114
115 ;; For SSE/MMX support:
116 UNSPEC_FIX_NOTRUNC
117 UNSPEC_MASKMOV
118 UNSPEC_MOVMSK
119 UNSPEC_RCP
120 UNSPEC_RSQRT
121 UNSPEC_PSADBW
122
123 ;; Generic math support
124 UNSPEC_COPYSIGN
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
127
128 ;; x87 Floating point
129 UNSPEC_SIN
130 UNSPEC_COS
131 UNSPEC_FPATAN
132 UNSPEC_FYL2X
133 UNSPEC_FYL2XP1
134 UNSPEC_FRNDINT
135 UNSPEC_FIST
136 UNSPEC_F2XM1
137 UNSPEC_TAN
138 UNSPEC_FXAM
139
140 ;; x87 Rounding
141 UNSPEC_FRNDINT_FLOOR
142 UNSPEC_FRNDINT_CEIL
143 UNSPEC_FRNDINT_TRUNC
144 UNSPEC_FRNDINT_MASK_PM
145 UNSPEC_FIST_FLOOR
146 UNSPEC_FIST_CEIL
147
148 ;; x87 Double output FP
149 UNSPEC_SINCOS_COS
150 UNSPEC_SINCOS_SIN
151 UNSPEC_XTRACT_FRACT
152 UNSPEC_XTRACT_EXP
153 UNSPEC_FSCALE_FRACT
154 UNSPEC_FSCALE_EXP
155 UNSPEC_FPREM_F
156 UNSPEC_FPREM_U
157 UNSPEC_FPREM1_F
158 UNSPEC_FPREM1_U
159
160 UNSPEC_C2_FLAG
161 UNSPEC_FXAM_MEM
162
163 ;; SSP patterns
164 UNSPEC_SP_SET
165 UNSPEC_SP_TEST
166 UNSPEC_SP_TLS_SET
167 UNSPEC_SP_TLS_TEST
168
169 ;; For ROUND support
170 UNSPEC_ROUND
171
172 ;; For CRC32 support
173 UNSPEC_CRC32
174
175 ;; For BMI support
176 UNSPEC_BEXTR
177
178 ;; For BMI2 support
179 UNSPEC_PDEP
180 UNSPEC_PEXT
181 ])
182
183 (define_c_enum "unspecv" [
184 UNSPECV_BLOCKAGE
185 UNSPECV_STACK_PROBE
186 UNSPECV_PROBE_STACK_RANGE
187 UNSPECV_ALIGN
188 UNSPECV_PROLOGUE_USE
189 UNSPECV_SPLIT_STACK_RETURN
190 UNSPECV_CLD
191 UNSPECV_NOPS
192 UNSPECV_RDTSC
193 UNSPECV_RDTSCP
194 UNSPECV_RDPMC
195 UNSPECV_LLWP_INTRINSIC
196 UNSPECV_SLWP_INTRINSIC
197 UNSPECV_LWPVAL_INTRINSIC
198 UNSPECV_LWPINS_INTRINSIC
199 UNSPECV_RDFSBASE
200 UNSPECV_RDGSBASE
201 UNSPECV_WRFSBASE
202 UNSPECV_WRGSBASE
203 UNSPECV_FXSAVE
204 UNSPECV_FXRSTOR
205 UNSPECV_FXSAVE64
206 UNSPECV_FXRSTOR64
207 UNSPECV_XSAVE
208 UNSPECV_XRSTOR
209 UNSPECV_XSAVE64
210 UNSPECV_XRSTOR64
211 UNSPECV_XSAVEOPT
212 UNSPECV_XSAVEOPT64
213
214 ;; For atomic compound assignments.
215 UNSPECV_FNSTENV
216 UNSPECV_FLDENV
217 UNSPECV_FNSTSW
218 UNSPECV_FNCLEX
219
220 ;; For RDRAND support
221 UNSPECV_RDRAND
222
223 ;; For RDSEED support
224 UNSPECV_RDSEED
225
226 ;; For RTM support
227 UNSPECV_XBEGIN
228 UNSPECV_XEND
229 UNSPECV_XABORT
230 UNSPECV_XTEST
231
232 UNSPECV_NLGR
233 ])
234
235 ;; Constants to represent rounding modes in the ROUND instruction
236 (define_constants
237 [(ROUND_FLOOR 0x1)
238 (ROUND_CEIL 0x2)
239 (ROUND_TRUNC 0x3)
240 (ROUND_MXCSR 0x4)
241 (ROUND_NO_EXC 0x8)
242 ])
243
244 ;; Constants to represent AVX512F embeded rounding
245 (define_constants
246 [(ROUND_NEAREST_INT 0)
247 (ROUND_NEG_INF 1)
248 (ROUND_POS_INF 2)
249 (ROUND_ZERO 3)
250 (NO_ROUND 4)
251 (ROUND_SAE 5)
252 ])
253
254 ;; Constants to represent pcomtrue/pcomfalse variants
255 (define_constants
256 [(PCOM_FALSE 0)
257 (PCOM_TRUE 1)
258 (COM_FALSE_S 2)
259 (COM_FALSE_P 3)
260 (COM_TRUE_S 4)
261 (COM_TRUE_P 5)
262 ])
263
264 ;; Constants used in the XOP pperm instruction
265 (define_constants
266 [(PPERM_SRC 0x00) /* copy source */
267 (PPERM_INVERT 0x20) /* invert source */
268 (PPERM_REVERSE 0x40) /* bit reverse source */
269 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
270 (PPERM_ZERO 0x80) /* all 0's */
271 (PPERM_ONES 0xa0) /* all 1's */
272 (PPERM_SIGN 0xc0) /* propagate sign bit */
273 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
274 (PPERM_SRC1 0x00) /* use first source byte */
275 (PPERM_SRC2 0x10) /* use second source byte */
276 ])
277
278 ;; Registers by name.
279 (define_constants
280 [(AX_REG 0)
281 (DX_REG 1)
282 (CX_REG 2)
283 (BX_REG 3)
284 (SI_REG 4)
285 (DI_REG 5)
286 (BP_REG 6)
287 (SP_REG 7)
288 (ST0_REG 8)
289 (ST1_REG 9)
290 (ST2_REG 10)
291 (ST3_REG 11)
292 (ST4_REG 12)
293 (ST5_REG 13)
294 (ST6_REG 14)
295 (ST7_REG 15)
296 (FLAGS_REG 17)
297 (FPSR_REG 18)
298 (FPCR_REG 19)
299 (XMM0_REG 21)
300 (XMM1_REG 22)
301 (XMM2_REG 23)
302 (XMM3_REG 24)
303 (XMM4_REG 25)
304 (XMM5_REG 26)
305 (XMM6_REG 27)
306 (XMM7_REG 28)
307 (MM0_REG 29)
308 (MM1_REG 30)
309 (MM2_REG 31)
310 (MM3_REG 32)
311 (MM4_REG 33)
312 (MM5_REG 34)
313 (MM6_REG 35)
314 (MM7_REG 36)
315 (R8_REG 37)
316 (R9_REG 38)
317 (R10_REG 39)
318 (R11_REG 40)
319 (R12_REG 41)
320 (R13_REG 42)
321 (R14_REG 43)
322 (R15_REG 44)
323 (XMM8_REG 45)
324 (XMM9_REG 46)
325 (XMM10_REG 47)
326 (XMM11_REG 48)
327 (XMM12_REG 49)
328 (XMM13_REG 50)
329 (XMM14_REG 51)
330 (XMM15_REG 52)
331 (XMM16_REG 53)
332 (XMM17_REG 54)
333 (XMM18_REG 55)
334 (XMM19_REG 56)
335 (XMM20_REG 57)
336 (XMM21_REG 58)
337 (XMM22_REG 59)
338 (XMM23_REG 60)
339 (XMM24_REG 61)
340 (XMM25_REG 62)
341 (XMM26_REG 63)
342 (XMM27_REG 64)
343 (XMM28_REG 65)
344 (XMM29_REG 66)
345 (XMM30_REG 67)
346 (XMM31_REG 68)
347 (MASK0_REG 69)
348 (MASK1_REG 70)
349 (MASK2_REG 71)
350 (MASK3_REG 72)
351 (MASK4_REG 73)
352 (MASK5_REG 74)
353 (MASK6_REG 75)
354 (MASK7_REG 76)
355 ])
356
357 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
358 ;; from i386.c.
359
360 ;; In C guard expressions, put expressions which may be compile-time
361 ;; constants first. This allows for better optimization. For
362 ;; example, write "TARGET_64BIT && reload_completed", not
363 ;; "reload_completed && TARGET_64BIT".
364
365 \f
366 ;; Processor type.
367 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
368 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
369 btver1,btver2"
370 (const (symbol_ref "ix86_schedule")))
371
372 ;; A basic instruction type. Refinements due to arguments to be
373 ;; provided in other attributes.
374 (define_attr "type"
375 "other,multi,
376 alu,alu1,negnot,imov,imovx,lea,
377 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
378 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
379 push,pop,call,callv,leave,
380 str,bitmanip,
381 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
382 fxch,fistp,fisttp,frndint,
383 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
384 ssemul,sseimul,ssediv,sselog,sselog1,
385 sseishft,sseishft1,ssecmp,ssecomi,
386 ssecvt,ssecvt1,sseicvt,sseins,
387 sseshuf,sseshuf1,ssemuladd,sse4arg,
388 lwp,mskmov,msklog,
389 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
390 (const_string "other"))
391
392 ;; Main data type used by the insn
393 (define_attr "mode"
394 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
395 V2DF,V2SF,V1DF,V8DF"
396 (const_string "unknown"))
397
398 ;; The CPU unit operations uses.
399 (define_attr "unit" "integer,i387,sse,mmx,unknown"
400 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
401 fxch,fistp,fisttp,frndint")
402 (const_string "i387")
403 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
404 ssemul,sseimul,ssediv,sselog,sselog1,
405 sseishft,sseishft1,ssecmp,ssecomi,
406 ssecvt,ssecvt1,sseicvt,sseins,
407 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
408 (const_string "sse")
409 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
410 (const_string "mmx")
411 (eq_attr "type" "other")
412 (const_string "unknown")]
413 (const_string "integer")))
414
415 ;; The minimum required alignment of vector mode memory operands of the SSE
416 ;; (non-VEX/EVEX) instruction in bits, if it is different from
417 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
418 ;; multiple alternatives, this should be conservative maximum of those minimum
419 ;; required alignments.
420 (define_attr "ssememalign" "" (const_int 0))
421
422 ;; The (bounding maximum) length of an instruction immediate.
423 (define_attr "length_immediate" ""
424 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
425 bitmanip,imulx,msklog,mskmov")
426 (const_int 0)
427 (eq_attr "unit" "i387,sse,mmx")
428 (const_int 0)
429 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
430 rotate,rotatex,rotate1,imul,icmp,push,pop")
431 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
432 (eq_attr "type" "imov,test")
433 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
434 (eq_attr "type" "call")
435 (if_then_else (match_operand 0 "constant_call_address_operand")
436 (const_int 4)
437 (const_int 0))
438 (eq_attr "type" "callv")
439 (if_then_else (match_operand 1 "constant_call_address_operand")
440 (const_int 4)
441 (const_int 0))
442 ;; We don't know the size before shorten_branches. Expect
443 ;; the instruction to fit for better scheduling.
444 (eq_attr "type" "ibr")
445 (const_int 1)
446 ]
447 (symbol_ref "/* Update immediate_length and other attributes! */
448 gcc_unreachable (),1")))
449
450 ;; The (bounding maximum) length of an instruction address.
451 (define_attr "length_address" ""
452 (cond [(eq_attr "type" "str,other,multi,fxch")
453 (const_int 0)
454 (and (eq_attr "type" "call")
455 (match_operand 0 "constant_call_address_operand"))
456 (const_int 0)
457 (and (eq_attr "type" "callv")
458 (match_operand 1 "constant_call_address_operand"))
459 (const_int 0)
460 ]
461 (symbol_ref "ix86_attr_length_address_default (insn)")))
462
463 ;; Set when length prefix is used.
464 (define_attr "prefix_data16" ""
465 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
466 (const_int 0)
467 (eq_attr "mode" "HI")
468 (const_int 1)
469 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
470 (const_int 1)
471 ]
472 (const_int 0)))
473
474 ;; Set when string REP prefix is used.
475 (define_attr "prefix_rep" ""
476 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
477 (const_int 0)
478 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
479 (const_int 1)
480 ]
481 (const_int 0)))
482
483 ;; Set when 0f opcode prefix is used.
484 (define_attr "prefix_0f" ""
485 (if_then_else
486 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
487 (eq_attr "unit" "sse,mmx"))
488 (const_int 1)
489 (const_int 0)))
490
491 ;; Set when REX opcode prefix is used.
492 (define_attr "prefix_rex" ""
493 (cond [(not (match_test "TARGET_64BIT"))
494 (const_int 0)
495 (and (eq_attr "mode" "DI")
496 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
497 (eq_attr "unit" "!mmx")))
498 (const_int 1)
499 (and (eq_attr "mode" "QI")
500 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
501 (const_int 1)
502 (match_test "x86_extended_reg_mentioned_p (insn)")
503 (const_int 1)
504 (and (eq_attr "type" "imovx")
505 (match_operand:QI 1 "ext_QIreg_operand"))
506 (const_int 1)
507 ]
508 (const_int 0)))
509
510 ;; There are also additional prefixes in 3DNOW, SSSE3.
511 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
512 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
513 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
514 (define_attr "prefix_extra" ""
515 (cond [(eq_attr "type" "ssemuladd,sse4arg")
516 (const_int 2)
517 (eq_attr "type" "sseiadd1,ssecvt1")
518 (const_int 1)
519 ]
520 (const_int 0)))
521
522 ;; Prefix used: original, VEX or maybe VEX.
523 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
524 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
525 (const_string "vex")
526 (eq_attr "mode" "XI,V16SF,V8DF")
527 (const_string "evex")
528 ]
529 (const_string "orig")))
530
531 ;; VEX W bit is used.
532 (define_attr "prefix_vex_w" "" (const_int 0))
533
534 ;; The length of VEX prefix
535 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
536 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
537 ;; still prefix_0f 1, with prefix_extra 1.
538 (define_attr "length_vex" ""
539 (if_then_else (and (eq_attr "prefix_0f" "1")
540 (eq_attr "prefix_extra" "0"))
541 (if_then_else (eq_attr "prefix_vex_w" "1")
542 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
543 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
544 (if_then_else (eq_attr "prefix_vex_w" "1")
545 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
546 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
547
548 ;; 4-bytes evex prefix and 1 byte opcode.
549 (define_attr "length_evex" "" (const_int 5))
550
551 ;; Set when modrm byte is used.
552 (define_attr "modrm" ""
553 (cond [(eq_attr "type" "str,leave")
554 (const_int 0)
555 (eq_attr "unit" "i387")
556 (const_int 0)
557 (and (eq_attr "type" "incdec")
558 (and (not (match_test "TARGET_64BIT"))
559 (ior (match_operand:SI 1 "register_operand")
560 (match_operand:HI 1 "register_operand"))))
561 (const_int 0)
562 (and (eq_attr "type" "push")
563 (not (match_operand 1 "memory_operand")))
564 (const_int 0)
565 (and (eq_attr "type" "pop")
566 (not (match_operand 0 "memory_operand")))
567 (const_int 0)
568 (and (eq_attr "type" "imov")
569 (and (not (eq_attr "mode" "DI"))
570 (ior (and (match_operand 0 "register_operand")
571 (match_operand 1 "immediate_operand"))
572 (ior (and (match_operand 0 "ax_reg_operand")
573 (match_operand 1 "memory_displacement_only_operand"))
574 (and (match_operand 0 "memory_displacement_only_operand")
575 (match_operand 1 "ax_reg_operand"))))))
576 (const_int 0)
577 (and (eq_attr "type" "call")
578 (match_operand 0 "constant_call_address_operand"))
579 (const_int 0)
580 (and (eq_attr "type" "callv")
581 (match_operand 1 "constant_call_address_operand"))
582 (const_int 0)
583 (and (eq_attr "type" "alu,alu1,icmp,test")
584 (match_operand 0 "ax_reg_operand"))
585 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
586 ]
587 (const_int 1)))
588
589 ;; The (bounding maximum) length of an instruction in bytes.
590 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
591 ;; Later we may want to split them and compute proper length as for
592 ;; other insns.
593 (define_attr "length" ""
594 (cond [(eq_attr "type" "other,multi,fistp,frndint")
595 (const_int 16)
596 (eq_attr "type" "fcmp")
597 (const_int 4)
598 (eq_attr "unit" "i387")
599 (plus (const_int 2)
600 (plus (attr "prefix_data16")
601 (attr "length_address")))
602 (ior (eq_attr "prefix" "evex")
603 (and (ior (eq_attr "prefix" "maybe_evex")
604 (eq_attr "prefix" "maybe_vex"))
605 (match_test "TARGET_AVX512F")))
606 (plus (attr "length_evex")
607 (plus (attr "length_immediate")
608 (plus (attr "modrm")
609 (attr "length_address"))))
610 (ior (eq_attr "prefix" "vex")
611 (and (ior (eq_attr "prefix" "maybe_vex")
612 (eq_attr "prefix" "maybe_evex"))
613 (match_test "TARGET_AVX")))
614 (plus (attr "length_vex")
615 (plus (attr "length_immediate")
616 (plus (attr "modrm")
617 (attr "length_address"))))]
618 (plus (plus (attr "modrm")
619 (plus (attr "prefix_0f")
620 (plus (attr "prefix_rex")
621 (plus (attr "prefix_extra")
622 (const_int 1)))))
623 (plus (attr "prefix_rep")
624 (plus (attr "prefix_data16")
625 (plus (attr "length_immediate")
626 (attr "length_address")))))))
627
628 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
629 ;; `store' if there is a simple memory reference therein, or `unknown'
630 ;; if the instruction is complex.
631
632 (define_attr "memory" "none,load,store,both,unknown"
633 (cond [(eq_attr "type" "other,multi,str,lwp")
634 (const_string "unknown")
635 (eq_attr "type" "lea,fcmov,fpspc")
636 (const_string "none")
637 (eq_attr "type" "fistp,leave")
638 (const_string "both")
639 (eq_attr "type" "frndint")
640 (const_string "load")
641 (eq_attr "type" "push")
642 (if_then_else (match_operand 1 "memory_operand")
643 (const_string "both")
644 (const_string "store"))
645 (eq_attr "type" "pop")
646 (if_then_else (match_operand 0 "memory_operand")
647 (const_string "both")
648 (const_string "load"))
649 (eq_attr "type" "setcc")
650 (if_then_else (match_operand 0 "memory_operand")
651 (const_string "store")
652 (const_string "none"))
653 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
654 (if_then_else (ior (match_operand 0 "memory_operand")
655 (match_operand 1 "memory_operand"))
656 (const_string "load")
657 (const_string "none"))
658 (eq_attr "type" "ibr")
659 (if_then_else (match_operand 0 "memory_operand")
660 (const_string "load")
661 (const_string "none"))
662 (eq_attr "type" "call")
663 (if_then_else (match_operand 0 "constant_call_address_operand")
664 (const_string "none")
665 (const_string "load"))
666 (eq_attr "type" "callv")
667 (if_then_else (match_operand 1 "constant_call_address_operand")
668 (const_string "none")
669 (const_string "load"))
670 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
671 (match_operand 1 "memory_operand"))
672 (const_string "both")
673 (and (match_operand 0 "memory_operand")
674 (match_operand 1 "memory_operand"))
675 (const_string "both")
676 (match_operand 0 "memory_operand")
677 (const_string "store")
678 (match_operand 1 "memory_operand")
679 (const_string "load")
680 (and (eq_attr "type"
681 "!alu1,negnot,ishift1,
682 imov,imovx,icmp,test,bitmanip,
683 fmov,fcmp,fsgn,
684 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
685 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
686 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
687 (match_operand 2 "memory_operand"))
688 (const_string "load")
689 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
690 (match_operand 3 "memory_operand"))
691 (const_string "load")
692 ]
693 (const_string "none")))
694
695 ;; Indicates if an instruction has both an immediate and a displacement.
696
697 (define_attr "imm_disp" "false,true,unknown"
698 (cond [(eq_attr "type" "other,multi")
699 (const_string "unknown")
700 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
701 (and (match_operand 0 "memory_displacement_operand")
702 (match_operand 1 "immediate_operand")))
703 (const_string "true")
704 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
705 (and (match_operand 0 "memory_displacement_operand")
706 (match_operand 2 "immediate_operand")))
707 (const_string "true")
708 ]
709 (const_string "false")))
710
711 ;; Indicates if an FP operation has an integer source.
712
713 (define_attr "fp_int_src" "false,true"
714 (const_string "false"))
715
716 ;; Defines rounding mode of an FP operation.
717
718 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
719 (const_string "any"))
720
721 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
722 (define_attr "use_carry" "0,1" (const_string "0"))
723
724 ;; Define attribute to indicate unaligned ssemov insns
725 (define_attr "movu" "0,1" (const_string "0"))
726
727 ;; Used to control the "enabled" attribute on a per-instruction basis.
728 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
729 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
730 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
731 (const_string "base"))
732
733 (define_attr "enabled" ""
734 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
735 (eq_attr "isa" "x64_sse4")
736 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
737 (eq_attr "isa" "x64_sse4_noavx")
738 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
739 (eq_attr "isa" "x64_avx")
740 (symbol_ref "TARGET_64BIT && TARGET_AVX")
741 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
742 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
743 (eq_attr "isa" "sse2_noavx")
744 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
745 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
746 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
747 (eq_attr "isa" "sse4_noavx")
748 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
749 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
750 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
751 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
752 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
753 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
754 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
755 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
756 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
757 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
758 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
759 (eq_attr "isa" "fma_avx512f")
760 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
761 ]
762 (const_int 1)))
763
764 ;; Describe a user's asm statement.
765 (define_asm_attributes
766 [(set_attr "length" "128")
767 (set_attr "type" "multi")])
768
769 (define_code_iterator plusminus [plus minus])
770
771 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
772
773 (define_code_iterator multdiv [mult div])
774
775 ;; Base name for define_insn
776 (define_code_attr plusminus_insn
777 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
778 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
779
780 ;; Base name for insn mnemonic.
781 (define_code_attr plusminus_mnemonic
782 [(plus "add") (ss_plus "adds") (us_plus "addus")
783 (minus "sub") (ss_minus "subs") (us_minus "subus")])
784 (define_code_attr plusminus_carry_mnemonic
785 [(plus "adc") (minus "sbb")])
786 (define_code_attr multdiv_mnemonic
787 [(mult "mul") (div "div")])
788
789 ;; Mark commutative operators as such in constraints.
790 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
791 (minus "") (ss_minus "") (us_minus "")])
792
793 ;; Mapping of max and min
794 (define_code_iterator maxmin [smax smin umax umin])
795
796 ;; Mapping of signed max and min
797 (define_code_iterator smaxmin [smax smin])
798
799 ;; Mapping of unsigned max and min
800 (define_code_iterator umaxmin [umax umin])
801
802 ;; Base name for integer and FP insn mnemonic
803 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
804 (umax "maxu") (umin "minu")])
805 (define_code_attr maxmin_float [(smax "max") (smin "min")])
806
807 ;; Mapping of logic operators
808 (define_code_iterator any_logic [and ior xor])
809 (define_code_iterator any_or [ior xor])
810 (define_code_iterator fpint_logic [and xor])
811
812 ;; Base name for insn mnemonic.
813 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
814
815 ;; Mapping of logic-shift operators
816 (define_code_iterator any_lshift [ashift lshiftrt])
817
818 ;; Mapping of shift-right operators
819 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
820
821 ;; Mapping of all shift operators
822 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
823
824 ;; Base name for define_insn
825 (define_code_attr shift_insn
826 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
827
828 ;; Base name for insn mnemonic.
829 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
830 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
831
832 ;; Mapping of rotate operators
833 (define_code_iterator any_rotate [rotate rotatert])
834
835 ;; Base name for define_insn
836 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
837
838 ;; Base name for insn mnemonic.
839 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
840
841 ;; Mapping of abs neg operators
842 (define_code_iterator absneg [abs neg])
843
844 ;; Base name for x87 insn mnemonic.
845 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
846
847 ;; Used in signed and unsigned widening multiplications.
848 (define_code_iterator any_extend [sign_extend zero_extend])
849
850 ;; Prefix for insn menmonic.
851 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
852
853 ;; Prefix for define_insn
854 (define_code_attr u [(sign_extend "") (zero_extend "u")])
855 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
856 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
857
858 ;; Used in signed and unsigned truncations.
859 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
860 ;; Instruction suffix for truncations.
861 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
862
863 ;; Used in signed and unsigned fix.
864 (define_code_iterator any_fix [fix unsigned_fix])
865 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
866
867 ;; All integer modes.
868 (define_mode_iterator SWI1248x [QI HI SI DI])
869
870 ;; All integer modes without QImode.
871 (define_mode_iterator SWI248x [HI SI DI])
872
873 ;; All integer modes without QImode and HImode.
874 (define_mode_iterator SWI48x [SI DI])
875
876 ;; All integer modes without SImode and DImode.
877 (define_mode_iterator SWI12 [QI HI])
878
879 ;; All integer modes without DImode.
880 (define_mode_iterator SWI124 [QI HI SI])
881
882 ;; All integer modes without QImode and DImode.
883 (define_mode_iterator SWI24 [HI SI])
884
885 ;; Single word integer modes.
886 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
887
888 ;; Single word integer modes without QImode.
889 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
890
891 ;; Single word integer modes without QImode and HImode.
892 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
893
894 ;; All math-dependant single and double word integer modes.
895 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
896 (HI "TARGET_HIMODE_MATH")
897 SI DI (TI "TARGET_64BIT")])
898
899 ;; Math-dependant single word integer modes.
900 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
901 (HI "TARGET_HIMODE_MATH")
902 SI (DI "TARGET_64BIT")])
903
904 ;; Math-dependant integer modes without DImode.
905 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
906 (HI "TARGET_HIMODE_MATH")
907 SI])
908
909 ;; Math-dependant single word integer modes without QImode.
910 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
911 SI (DI "TARGET_64BIT")])
912
913 ;; Double word integer modes.
914 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
915 (TI "TARGET_64BIT")])
916
917 ;; Double word integer modes as mode attribute.
918 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
919 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
920
921 ;; Half mode for double word integer modes.
922 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
923 (DI "TARGET_64BIT")])
924
925 ;; Instruction suffix for integer modes.
926 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
927
928 ;; Pointer size prefix for integer modes (Intel asm dialect)
929 (define_mode_attr iptrsize [(QI "BYTE")
930 (HI "WORD")
931 (SI "DWORD")
932 (DI "QWORD")])
933
934 ;; Register class for integer modes.
935 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
936
937 ;; Immediate operand constraint for integer modes.
938 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
939
940 ;; General operand constraint for word modes.
941 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
942
943 ;; Immediate operand constraint for double integer modes.
944 (define_mode_attr di [(SI "nF") (DI "e")])
945
946 ;; Immediate operand constraint for shifts.
947 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
948
949 ;; General operand predicate for integer modes.
950 (define_mode_attr general_operand
951 [(QI "general_operand")
952 (HI "general_operand")
953 (SI "x86_64_general_operand")
954 (DI "x86_64_general_operand")
955 (TI "x86_64_general_operand")])
956
957 ;; General sign/zero extend operand predicate for integer modes.
958 (define_mode_attr general_szext_operand
959 [(QI "general_operand")
960 (HI "general_operand")
961 (SI "x86_64_szext_general_operand")
962 (DI "x86_64_szext_general_operand")])
963
964 ;; Immediate operand predicate for integer modes.
965 (define_mode_attr immediate_operand
966 [(QI "immediate_operand")
967 (HI "immediate_operand")
968 (SI "x86_64_immediate_operand")
969 (DI "x86_64_immediate_operand")])
970
971 ;; Nonmemory operand predicate for integer modes.
972 (define_mode_attr nonmemory_operand
973 [(QI "nonmemory_operand")
974 (HI "nonmemory_operand")
975 (SI "x86_64_nonmemory_operand")
976 (DI "x86_64_nonmemory_operand")])
977
978 ;; Operand predicate for shifts.
979 (define_mode_attr shift_operand
980 [(QI "nonimmediate_operand")
981 (HI "nonimmediate_operand")
982 (SI "nonimmediate_operand")
983 (DI "shiftdi_operand")
984 (TI "register_operand")])
985
986 ;; Operand predicate for shift argument.
987 (define_mode_attr shift_immediate_operand
988 [(QI "const_1_to_31_operand")
989 (HI "const_1_to_31_operand")
990 (SI "const_1_to_31_operand")
991 (DI "const_1_to_63_operand")])
992
993 ;; Input operand predicate for arithmetic left shifts.
994 (define_mode_attr ashl_input_operand
995 [(QI "nonimmediate_operand")
996 (HI "nonimmediate_operand")
997 (SI "nonimmediate_operand")
998 (DI "ashldi_input_operand")
999 (TI "reg_or_pm1_operand")])
1000
1001 ;; SSE and x87 SFmode and DFmode floating point modes
1002 (define_mode_iterator MODEF [SF DF])
1003
1004 ;; All x87 floating point modes
1005 (define_mode_iterator X87MODEF [SF DF XF])
1006
1007 ;; SSE instruction suffix for various modes
1008 (define_mode_attr ssemodesuffix
1009 [(SF "ss") (DF "sd")
1010 (V16SF "ps") (V8DF "pd")
1011 (V8SF "ps") (V4DF "pd")
1012 (V4SF "ps") (V2DF "pd")
1013 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1014 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1015 (V64QI "b") (V16SI "d") (V8DI "q")])
1016
1017 ;; SSE vector suffix for floating point modes
1018 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1019
1020 ;; SSE vector mode corresponding to a scalar mode
1021 (define_mode_attr ssevecmode
1022 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1023 (define_mode_attr ssevecmodelower
1024 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1025
1026 ;; Instruction suffix for REX 64bit operators.
1027 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1028
1029 ;; This mode iterator allows :P to be used for patterns that operate on
1030 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1031 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1032
1033 ;; This mode iterator allows :W to be used for patterns that operate on
1034 ;; word_mode sized quantities.
1035 (define_mode_iterator W
1036 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1037
1038 ;; This mode iterator allows :PTR to be used for patterns that operate on
1039 ;; ptr_mode sized quantities.
1040 (define_mode_iterator PTR
1041 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1042 \f
1043 ;; Scheduling descriptions
1044
1045 (include "pentium.md")
1046 (include "ppro.md")
1047 (include "k6.md")
1048 (include "athlon.md")
1049 (include "bdver1.md")
1050 (include "bdver3.md")
1051 (include "btver2.md")
1052 (include "geode.md")
1053 (include "atom.md")
1054 (include "slm.md")
1055 (include "core2.md")
1056
1057 \f
1058 ;; Operand and operator predicates and constraints
1059
1060 (include "predicates.md")
1061 (include "constraints.md")
1062
1063 \f
1064 ;; Compare and branch/compare and store instructions.
1065
1066 (define_expand "cbranch<mode>4"
1067 [(set (reg:CC FLAGS_REG)
1068 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1069 (match_operand:SDWIM 2 "<general_operand>")))
1070 (set (pc) (if_then_else
1071 (match_operator 0 "ordered_comparison_operator"
1072 [(reg:CC FLAGS_REG) (const_int 0)])
1073 (label_ref (match_operand 3))
1074 (pc)))]
1075 ""
1076 {
1077 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1078 operands[1] = force_reg (<MODE>mode, operands[1]);
1079 ix86_expand_branch (GET_CODE (operands[0]),
1080 operands[1], operands[2], operands[3]);
1081 DONE;
1082 })
1083
1084 (define_expand "cstore<mode>4"
1085 [(set (reg:CC FLAGS_REG)
1086 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1087 (match_operand:SWIM 3 "<general_operand>")))
1088 (set (match_operand:QI 0 "register_operand")
1089 (match_operator 1 "ordered_comparison_operator"
1090 [(reg:CC FLAGS_REG) (const_int 0)]))]
1091 ""
1092 {
1093 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1094 operands[2] = force_reg (<MODE>mode, operands[2]);
1095 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1096 operands[2], operands[3]);
1097 DONE;
1098 })
1099
1100 (define_expand "cmp<mode>_1"
1101 [(set (reg:CC FLAGS_REG)
1102 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1103 (match_operand:SWI48 1 "<general_operand>")))])
1104
1105 (define_insn "*cmp<mode>_ccno_1"
1106 [(set (reg FLAGS_REG)
1107 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1108 (match_operand:SWI 1 "const0_operand")))]
1109 "ix86_match_ccmode (insn, CCNOmode)"
1110 "@
1111 test{<imodesuffix>}\t%0, %0
1112 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1113 [(set_attr "type" "test,icmp")
1114 (set_attr "length_immediate" "0,1")
1115 (set_attr "mode" "<MODE>")])
1116
1117 (define_insn "*cmp<mode>_1"
1118 [(set (reg FLAGS_REG)
1119 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1120 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1121 "ix86_match_ccmode (insn, CCmode)"
1122 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1123 [(set_attr "type" "icmp")
1124 (set_attr "mode" "<MODE>")])
1125
1126 (define_insn "*cmp<mode>_minus_1"
1127 [(set (reg FLAGS_REG)
1128 (compare
1129 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1130 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1131 (const_int 0)))]
1132 "ix86_match_ccmode (insn, CCGOCmode)"
1133 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1134 [(set_attr "type" "icmp")
1135 (set_attr "mode" "<MODE>")])
1136
1137 (define_insn "*cmpqi_ext_1"
1138 [(set (reg FLAGS_REG)
1139 (compare
1140 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1141 (subreg:QI
1142 (zero_extract:SI
1143 (match_operand 1 "ext_register_operand" "Q,Q")
1144 (const_int 8)
1145 (const_int 8)) 0)))]
1146 "ix86_match_ccmode (insn, CCmode)"
1147 "cmp{b}\t{%h1, %0|%0, %h1}"
1148 [(set_attr "isa" "*,nox64")
1149 (set_attr "type" "icmp")
1150 (set_attr "mode" "QI")])
1151
1152 (define_insn "*cmpqi_ext_2"
1153 [(set (reg FLAGS_REG)
1154 (compare
1155 (subreg:QI
1156 (zero_extract:SI
1157 (match_operand 0 "ext_register_operand" "Q")
1158 (const_int 8)
1159 (const_int 8)) 0)
1160 (match_operand:QI 1 "const0_operand")))]
1161 "ix86_match_ccmode (insn, CCNOmode)"
1162 "test{b}\t%h0, %h0"
1163 [(set_attr "type" "test")
1164 (set_attr "length_immediate" "0")
1165 (set_attr "mode" "QI")])
1166
1167 (define_expand "cmpqi_ext_3"
1168 [(set (reg:CC FLAGS_REG)
1169 (compare:CC
1170 (subreg:QI
1171 (zero_extract:SI
1172 (match_operand 0 "ext_register_operand")
1173 (const_int 8)
1174 (const_int 8)) 0)
1175 (match_operand:QI 1 "const_int_operand")))])
1176
1177 (define_insn "*cmpqi_ext_3"
1178 [(set (reg FLAGS_REG)
1179 (compare
1180 (subreg:QI
1181 (zero_extract:SI
1182 (match_operand 0 "ext_register_operand" "Q,Q")
1183 (const_int 8)
1184 (const_int 8)) 0)
1185 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1186 "ix86_match_ccmode (insn, CCmode)"
1187 "cmp{b}\t{%1, %h0|%h0, %1}"
1188 [(set_attr "isa" "*,nox64")
1189 (set_attr "type" "icmp")
1190 (set_attr "modrm" "1")
1191 (set_attr "mode" "QI")])
1192
1193 (define_insn "*cmpqi_ext_4"
1194 [(set (reg FLAGS_REG)
1195 (compare
1196 (subreg:QI
1197 (zero_extract:SI
1198 (match_operand 0 "ext_register_operand" "Q")
1199 (const_int 8)
1200 (const_int 8)) 0)
1201 (subreg:QI
1202 (zero_extract:SI
1203 (match_operand 1 "ext_register_operand" "Q")
1204 (const_int 8)
1205 (const_int 8)) 0)))]
1206 "ix86_match_ccmode (insn, CCmode)"
1207 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1208 [(set_attr "type" "icmp")
1209 (set_attr "mode" "QI")])
1210
1211 ;; These implement float point compares.
1212 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1213 ;; which would allow mix and match FP modes on the compares. Which is what
1214 ;; the old patterns did, but with many more of them.
1215
1216 (define_expand "cbranchxf4"
1217 [(set (reg:CC FLAGS_REG)
1218 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1219 (match_operand:XF 2 "nonmemory_operand")))
1220 (set (pc) (if_then_else
1221 (match_operator 0 "ix86_fp_comparison_operator"
1222 [(reg:CC FLAGS_REG)
1223 (const_int 0)])
1224 (label_ref (match_operand 3))
1225 (pc)))]
1226 "TARGET_80387"
1227 {
1228 ix86_expand_branch (GET_CODE (operands[0]),
1229 operands[1], operands[2], operands[3]);
1230 DONE;
1231 })
1232
1233 (define_expand "cstorexf4"
1234 [(set (reg:CC FLAGS_REG)
1235 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1236 (match_operand:XF 3 "nonmemory_operand")))
1237 (set (match_operand:QI 0 "register_operand")
1238 (match_operator 1 "ix86_fp_comparison_operator"
1239 [(reg:CC FLAGS_REG)
1240 (const_int 0)]))]
1241 "TARGET_80387"
1242 {
1243 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1244 operands[2], operands[3]);
1245 DONE;
1246 })
1247
1248 (define_expand "cbranch<mode>4"
1249 [(set (reg:CC FLAGS_REG)
1250 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1251 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1252 (set (pc) (if_then_else
1253 (match_operator 0 "ix86_fp_comparison_operator"
1254 [(reg:CC FLAGS_REG)
1255 (const_int 0)])
1256 (label_ref (match_operand 3))
1257 (pc)))]
1258 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1259 {
1260 ix86_expand_branch (GET_CODE (operands[0]),
1261 operands[1], operands[2], operands[3]);
1262 DONE;
1263 })
1264
1265 (define_expand "cstore<mode>4"
1266 [(set (reg:CC FLAGS_REG)
1267 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1268 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1269 (set (match_operand:QI 0 "register_operand")
1270 (match_operator 1 "ix86_fp_comparison_operator"
1271 [(reg:CC FLAGS_REG)
1272 (const_int 0)]))]
1273 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1274 {
1275 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1276 operands[2], operands[3]);
1277 DONE;
1278 })
1279
1280 (define_expand "cbranchcc4"
1281 [(set (pc) (if_then_else
1282 (match_operator 0 "comparison_operator"
1283 [(match_operand 1 "flags_reg_operand")
1284 (match_operand 2 "const0_operand")])
1285 (label_ref (match_operand 3))
1286 (pc)))]
1287 ""
1288 {
1289 ix86_expand_branch (GET_CODE (operands[0]),
1290 operands[1], operands[2], operands[3]);
1291 DONE;
1292 })
1293
1294 (define_expand "cstorecc4"
1295 [(set (match_operand:QI 0 "register_operand")
1296 (match_operator 1 "comparison_operator"
1297 [(match_operand 2 "flags_reg_operand")
1298 (match_operand 3 "const0_operand")]))]
1299 ""
1300 {
1301 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1302 operands[2], operands[3]);
1303 DONE;
1304 })
1305
1306
1307 ;; FP compares, step 1:
1308 ;; Set the FP condition codes.
1309 ;;
1310 ;; CCFPmode compare with exceptions
1311 ;; CCFPUmode compare with no exceptions
1312
1313 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1314 ;; used to manage the reg stack popping would not be preserved.
1315
1316 (define_insn "*cmp<mode>_0_i387"
1317 [(set (match_operand:HI 0 "register_operand" "=a")
1318 (unspec:HI
1319 [(compare:CCFP
1320 (match_operand:X87MODEF 1 "register_operand" "f")
1321 (match_operand:X87MODEF 2 "const0_operand"))]
1322 UNSPEC_FNSTSW))]
1323 "TARGET_80387"
1324 "* return output_fp_compare (insn, operands, false, false);"
1325 [(set_attr "type" "multi")
1326 (set_attr "unit" "i387")
1327 (set_attr "mode" "<MODE>")])
1328
1329 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1330 [(set (reg:CCFP FLAGS_REG)
1331 (compare:CCFP
1332 (match_operand:X87MODEF 1 "register_operand" "f")
1333 (match_operand:X87MODEF 2 "const0_operand")))
1334 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1335 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1336 "#"
1337 "&& reload_completed"
1338 [(set (match_dup 0)
1339 (unspec:HI
1340 [(compare:CCFP (match_dup 1)(match_dup 2))]
1341 UNSPEC_FNSTSW))
1342 (set (reg:CC FLAGS_REG)
1343 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1344 ""
1345 [(set_attr "type" "multi")
1346 (set_attr "unit" "i387")
1347 (set_attr "mode" "<MODE>")])
1348
1349 (define_insn "*cmpxf_i387"
1350 [(set (match_operand:HI 0 "register_operand" "=a")
1351 (unspec:HI
1352 [(compare:CCFP
1353 (match_operand:XF 1 "register_operand" "f")
1354 (match_operand:XF 2 "register_operand" "f"))]
1355 UNSPEC_FNSTSW))]
1356 "TARGET_80387"
1357 "* return output_fp_compare (insn, operands, false, false);"
1358 [(set_attr "type" "multi")
1359 (set_attr "unit" "i387")
1360 (set_attr "mode" "XF")])
1361
1362 (define_insn_and_split "*cmpxf_cc_i387"
1363 [(set (reg:CCFP FLAGS_REG)
1364 (compare:CCFP
1365 (match_operand:XF 1 "register_operand" "f")
1366 (match_operand:XF 2 "register_operand" "f")))
1367 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1368 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1369 "#"
1370 "&& reload_completed"
1371 [(set (match_dup 0)
1372 (unspec:HI
1373 [(compare:CCFP (match_dup 1)(match_dup 2))]
1374 UNSPEC_FNSTSW))
1375 (set (reg:CC FLAGS_REG)
1376 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1377 ""
1378 [(set_attr "type" "multi")
1379 (set_attr "unit" "i387")
1380 (set_attr "mode" "XF")])
1381
1382 (define_insn "*cmp<mode>_i387"
1383 [(set (match_operand:HI 0 "register_operand" "=a")
1384 (unspec:HI
1385 [(compare:CCFP
1386 (match_operand:MODEF 1 "register_operand" "f")
1387 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1388 UNSPEC_FNSTSW))]
1389 "TARGET_80387"
1390 "* return output_fp_compare (insn, operands, false, false);"
1391 [(set_attr "type" "multi")
1392 (set_attr "unit" "i387")
1393 (set_attr "mode" "<MODE>")])
1394
1395 (define_insn_and_split "*cmp<mode>_cc_i387"
1396 [(set (reg:CCFP FLAGS_REG)
1397 (compare:CCFP
1398 (match_operand:MODEF 1 "register_operand" "f")
1399 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1400 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1401 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1402 "#"
1403 "&& reload_completed"
1404 [(set (match_dup 0)
1405 (unspec:HI
1406 [(compare:CCFP (match_dup 1)(match_dup 2))]
1407 UNSPEC_FNSTSW))
1408 (set (reg:CC FLAGS_REG)
1409 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1410 ""
1411 [(set_attr "type" "multi")
1412 (set_attr "unit" "i387")
1413 (set_attr "mode" "<MODE>")])
1414
1415 (define_insn "*cmpu<mode>_i387"
1416 [(set (match_operand:HI 0 "register_operand" "=a")
1417 (unspec:HI
1418 [(compare:CCFPU
1419 (match_operand:X87MODEF 1 "register_operand" "f")
1420 (match_operand:X87MODEF 2 "register_operand" "f"))]
1421 UNSPEC_FNSTSW))]
1422 "TARGET_80387"
1423 "* return output_fp_compare (insn, operands, false, true);"
1424 [(set_attr "type" "multi")
1425 (set_attr "unit" "i387")
1426 (set_attr "mode" "<MODE>")])
1427
1428 (define_insn_and_split "*cmpu<mode>_cc_i387"
1429 [(set (reg:CCFPU FLAGS_REG)
1430 (compare:CCFPU
1431 (match_operand:X87MODEF 1 "register_operand" "f")
1432 (match_operand:X87MODEF 2 "register_operand" "f")))
1433 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1434 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1435 "#"
1436 "&& reload_completed"
1437 [(set (match_dup 0)
1438 (unspec:HI
1439 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1440 UNSPEC_FNSTSW))
1441 (set (reg:CC FLAGS_REG)
1442 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1443 ""
1444 [(set_attr "type" "multi")
1445 (set_attr "unit" "i387")
1446 (set_attr "mode" "<MODE>")])
1447
1448 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1449 [(set (match_operand:HI 0 "register_operand" "=a")
1450 (unspec:HI
1451 [(compare:CCFP
1452 (match_operand:X87MODEF 1 "register_operand" "f")
1453 (match_operator:X87MODEF 3 "float_operator"
1454 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1455 UNSPEC_FNSTSW))]
1456 "TARGET_80387
1457 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1458 || optimize_function_for_size_p (cfun))"
1459 "* return output_fp_compare (insn, operands, false, false);"
1460 [(set_attr "type" "multi")
1461 (set_attr "unit" "i387")
1462 (set_attr "fp_int_src" "true")
1463 (set_attr "mode" "<SWI24:MODE>")])
1464
1465 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1466 [(set (reg:CCFP FLAGS_REG)
1467 (compare:CCFP
1468 (match_operand:X87MODEF 1 "register_operand" "f")
1469 (match_operator:X87MODEF 3 "float_operator"
1470 [(match_operand:SWI24 2 "memory_operand" "m")])))
1471 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1472 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1473 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1474 || optimize_function_for_size_p (cfun))"
1475 "#"
1476 "&& reload_completed"
1477 [(set (match_dup 0)
1478 (unspec:HI
1479 [(compare:CCFP
1480 (match_dup 1)
1481 (match_op_dup 3 [(match_dup 2)]))]
1482 UNSPEC_FNSTSW))
1483 (set (reg:CC FLAGS_REG)
1484 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1485 ""
1486 [(set_attr "type" "multi")
1487 (set_attr "unit" "i387")
1488 (set_attr "fp_int_src" "true")
1489 (set_attr "mode" "<SWI24:MODE>")])
1490
1491 ;; FP compares, step 2
1492 ;; Move the fpsw to ax.
1493
1494 (define_insn "x86_fnstsw_1"
1495 [(set (match_operand:HI 0 "register_operand" "=a")
1496 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1497 "TARGET_80387"
1498 "fnstsw\t%0"
1499 [(set (attr "length")
1500 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1501 (set_attr "mode" "SI")
1502 (set_attr "unit" "i387")])
1503
1504 ;; FP compares, step 3
1505 ;; Get ax into flags, general case.
1506
1507 (define_insn "x86_sahf_1"
1508 [(set (reg:CC FLAGS_REG)
1509 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1510 UNSPEC_SAHF))]
1511 "TARGET_SAHF"
1512 {
1513 #ifndef HAVE_AS_IX86_SAHF
1514 if (TARGET_64BIT)
1515 return ASM_BYTE "0x9e";
1516 else
1517 #endif
1518 return "sahf";
1519 }
1520 [(set_attr "length" "1")
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "direct")
1524 (set_attr "mode" "SI")])
1525
1526 ;; Pentium Pro can do steps 1 through 3 in one go.
1527 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1528 ;; (these i387 instructions set flags directly)
1529
1530 (define_mode_iterator FPCMP [CCFP CCFPU])
1531 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1532
1533 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1534 [(set (reg:FPCMP FLAGS_REG)
1535 (compare:FPCMP
1536 (match_operand:MODEF 0 "register_operand" "f,x")
1537 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1538 "TARGET_MIX_SSE_I387
1539 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1540 "* return output_fp_compare (insn, operands, true,
1541 <FPCMP:MODE>mode == CCFPUmode);"
1542 [(set_attr "type" "fcmp,ssecomi")
1543 (set_attr "prefix" "orig,maybe_vex")
1544 (set_attr "mode" "<MODEF:MODE>")
1545 (set (attr "prefix_rep")
1546 (if_then_else (eq_attr "type" "ssecomi")
1547 (const_string "0")
1548 (const_string "*")))
1549 (set (attr "prefix_data16")
1550 (cond [(eq_attr "type" "fcmp")
1551 (const_string "*")
1552 (eq_attr "mode" "DF")
1553 (const_string "1")
1554 ]
1555 (const_string "0")))
1556 (set_attr "athlon_decode" "vector")
1557 (set_attr "amdfam10_decode" "direct")
1558 (set_attr "bdver1_decode" "double")])
1559
1560 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1561 [(set (reg:FPCMP FLAGS_REG)
1562 (compare:FPCMP
1563 (match_operand:MODEF 0 "register_operand" "x")
1564 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1565 "TARGET_SSE_MATH
1566 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1567 "* return output_fp_compare (insn, operands, true,
1568 <FPCMP:MODE>mode == CCFPUmode);"
1569 [(set_attr "type" "ssecomi")
1570 (set_attr "prefix" "maybe_vex")
1571 (set_attr "mode" "<MODEF:MODE>")
1572 (set_attr "prefix_rep" "0")
1573 (set (attr "prefix_data16")
1574 (if_then_else (eq_attr "mode" "DF")
1575 (const_string "1")
1576 (const_string "0")))
1577 (set_attr "athlon_decode" "vector")
1578 (set_attr "amdfam10_decode" "direct")
1579 (set_attr "bdver1_decode" "double")])
1580
1581 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1582 [(set (reg:FPCMP FLAGS_REG)
1583 (compare:FPCMP
1584 (match_operand:X87MODEF 0 "register_operand" "f")
1585 (match_operand:X87MODEF 1 "register_operand" "f")))]
1586 "TARGET_80387 && TARGET_CMOVE
1587 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1588 "* return output_fp_compare (insn, operands, true,
1589 <FPCMP:MODE>mode == CCFPUmode);"
1590 [(set_attr "type" "fcmp")
1591 (set_attr "mode" "<X87MODEF:MODE>")
1592 (set_attr "athlon_decode" "vector")
1593 (set_attr "amdfam10_decode" "direct")
1594 (set_attr "bdver1_decode" "double")])
1595 \f
1596 ;; Push/pop instructions.
1597
1598 (define_insn "*push<mode>2"
1599 [(set (match_operand:DWI 0 "push_operand" "=<")
1600 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1601 ""
1602 "#"
1603 [(set_attr "type" "multi")
1604 (set_attr "mode" "<MODE>")])
1605
1606 (define_split
1607 [(set (match_operand:TI 0 "push_operand")
1608 (match_operand:TI 1 "general_operand"))]
1609 "TARGET_64BIT && reload_completed
1610 && !SSE_REG_P (operands[1])"
1611 [(const_int 0)]
1612 "ix86_split_long_move (operands); DONE;")
1613
1614 (define_insn "*pushdi2_rex64"
1615 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1616 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1617 "TARGET_64BIT"
1618 "@
1619 push{q}\t%1
1620 #"
1621 [(set_attr "type" "push,multi")
1622 (set_attr "mode" "DI")])
1623
1624 ;; Convert impossible pushes of immediate to existing instructions.
1625 ;; First try to get scratch register and go through it. In case this
1626 ;; fails, push sign extended lower part first and then overwrite
1627 ;; upper part by 32bit move.
1628 (define_peephole2
1629 [(match_scratch:DI 2 "r")
1630 (set (match_operand:DI 0 "push_operand")
1631 (match_operand:DI 1 "immediate_operand"))]
1632 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1633 && !x86_64_immediate_operand (operands[1], DImode)"
1634 [(set (match_dup 2) (match_dup 1))
1635 (set (match_dup 0) (match_dup 2))])
1636
1637 ;; We need to define this as both peepholer and splitter for case
1638 ;; peephole2 pass is not run.
1639 ;; "&& 1" is needed to keep it from matching the previous pattern.
1640 (define_peephole2
1641 [(set (match_operand:DI 0 "push_operand")
1642 (match_operand:DI 1 "immediate_operand"))]
1643 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1644 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1645 [(set (match_dup 0) (match_dup 1))
1646 (set (match_dup 2) (match_dup 3))]
1647 {
1648 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1649
1650 operands[1] = gen_lowpart (DImode, operands[2]);
1651 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1652 GEN_INT (4)));
1653 })
1654
1655 (define_split
1656 [(set (match_operand:DI 0 "push_operand")
1657 (match_operand:DI 1 "immediate_operand"))]
1658 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1659 ? epilogue_completed : reload_completed)
1660 && !symbolic_operand (operands[1], DImode)
1661 && !x86_64_immediate_operand (operands[1], DImode)"
1662 [(set (match_dup 0) (match_dup 1))
1663 (set (match_dup 2) (match_dup 3))]
1664 {
1665 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1666
1667 operands[1] = gen_lowpart (DImode, operands[2]);
1668 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1669 GEN_INT (4)));
1670 })
1671
1672 (define_split
1673 [(set (match_operand:DI 0 "push_operand")
1674 (match_operand:DI 1 "general_operand"))]
1675 "!TARGET_64BIT && reload_completed
1676 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1677 [(const_int 0)]
1678 "ix86_split_long_move (operands); DONE;")
1679
1680 (define_insn "*pushsi2"
1681 [(set (match_operand:SI 0 "push_operand" "=<")
1682 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1683 "!TARGET_64BIT"
1684 "push{l}\t%1"
1685 [(set_attr "type" "push")
1686 (set_attr "mode" "SI")])
1687
1688 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1689 ;; "push a byte/word". But actually we use pushl, which has the effect
1690 ;; of rounding the amount pushed up to a word.
1691
1692 ;; For TARGET_64BIT we always round up to 8 bytes.
1693 (define_insn "*push<mode>2_rex64"
1694 [(set (match_operand:SWI124 0 "push_operand" "=X")
1695 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1696 "TARGET_64BIT"
1697 "push{q}\t%q1"
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "DI")])
1700
1701 (define_insn "*push<mode>2"
1702 [(set (match_operand:SWI12 0 "push_operand" "=X")
1703 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1704 "!TARGET_64BIT"
1705 "push{l}\t%k1"
1706 [(set_attr "type" "push")
1707 (set_attr "mode" "SI")])
1708
1709 (define_insn "*push<mode>2_prologue"
1710 [(set (match_operand:W 0 "push_operand" "=<")
1711 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1712 (clobber (mem:BLK (scratch)))]
1713 ""
1714 "push{<imodesuffix>}\t%1"
1715 [(set_attr "type" "push")
1716 (set_attr "mode" "<MODE>")])
1717
1718 (define_insn "*pop<mode>1"
1719 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1720 (match_operand:W 1 "pop_operand" ">"))]
1721 ""
1722 "pop{<imodesuffix>}\t%0"
1723 [(set_attr "type" "pop")
1724 (set_attr "mode" "<MODE>")])
1725
1726 (define_insn "*pop<mode>1_epilogue"
1727 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1728 (match_operand:W 1 "pop_operand" ">"))
1729 (clobber (mem:BLK (scratch)))]
1730 ""
1731 "pop{<imodesuffix>}\t%0"
1732 [(set_attr "type" "pop")
1733 (set_attr "mode" "<MODE>")])
1734
1735 (define_insn "*pushfl<mode>2"
1736 [(set (match_operand:W 0 "push_operand" "=<")
1737 (match_operand:W 1 "flags_reg_operand"))]
1738 ""
1739 "pushf{<imodesuffix>}"
1740 [(set_attr "type" "push")
1741 (set_attr "mode" "<MODE>")])
1742
1743 (define_insn "*popfl<mode>1"
1744 [(set (match_operand:W 0 "flags_reg_operand")
1745 (match_operand:W 1 "pop_operand" ">"))]
1746 ""
1747 "popf{<imodesuffix>}"
1748 [(set_attr "type" "pop")
1749 (set_attr "mode" "<MODE>")])
1750
1751 \f
1752 ;; Move instructions.
1753
1754 (define_expand "movxi"
1755 [(set (match_operand:XI 0 "nonimmediate_operand")
1756 (match_operand:XI 1 "general_operand"))]
1757 "TARGET_AVX512F"
1758 "ix86_expand_move (XImode, operands); DONE;")
1759
1760 ;; Reload patterns to support multi-word load/store
1761 ;; with non-offsetable address.
1762 (define_expand "reload_noff_store"
1763 [(parallel [(match_operand 0 "memory_operand" "=m")
1764 (match_operand 1 "register_operand" "r")
1765 (match_operand:DI 2 "register_operand" "=&r")])]
1766 "TARGET_64BIT"
1767 {
1768 rtx mem = operands[0];
1769 rtx addr = XEXP (mem, 0);
1770
1771 emit_move_insn (operands[2], addr);
1772 mem = replace_equiv_address_nv (mem, operands[2]);
1773
1774 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1775 DONE;
1776 })
1777
1778 (define_expand "reload_noff_load"
1779 [(parallel [(match_operand 0 "register_operand" "=r")
1780 (match_operand 1 "memory_operand" "m")
1781 (match_operand:DI 2 "register_operand" "=r")])]
1782 "TARGET_64BIT"
1783 {
1784 rtx mem = operands[1];
1785 rtx addr = XEXP (mem, 0);
1786
1787 emit_move_insn (operands[2], addr);
1788 mem = replace_equiv_address_nv (mem, operands[2]);
1789
1790 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1791 DONE;
1792 })
1793
1794 (define_expand "movoi"
1795 [(set (match_operand:OI 0 "nonimmediate_operand")
1796 (match_operand:OI 1 "general_operand"))]
1797 "TARGET_AVX"
1798 "ix86_expand_move (OImode, operands); DONE;")
1799
1800 (define_expand "movti"
1801 [(set (match_operand:TI 0 "nonimmediate_operand")
1802 (match_operand:TI 1 "nonimmediate_operand"))]
1803 "TARGET_64BIT || TARGET_SSE"
1804 {
1805 if (TARGET_64BIT)
1806 ix86_expand_move (TImode, operands);
1807 else if (push_operand (operands[0], TImode))
1808 ix86_expand_push (TImode, operands[1]);
1809 else
1810 ix86_expand_vector_move (TImode, operands);
1811 DONE;
1812 })
1813
1814 ;; This expands to what emit_move_complex would generate if we didn't
1815 ;; have a movti pattern. Having this avoids problems with reload on
1816 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1817 ;; to have around all the time.
1818 (define_expand "movcdi"
1819 [(set (match_operand:CDI 0 "nonimmediate_operand")
1820 (match_operand:CDI 1 "general_operand"))]
1821 ""
1822 {
1823 if (push_operand (operands[0], CDImode))
1824 emit_move_complex_push (CDImode, operands[0], operands[1]);
1825 else
1826 emit_move_complex_parts (operands[0], operands[1]);
1827 DONE;
1828 })
1829
1830 (define_expand "mov<mode>"
1831 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1832 (match_operand:SWI1248x 1 "general_operand"))]
1833 ""
1834 "ix86_expand_move (<MODE>mode, operands); DONE;")
1835
1836 (define_insn "*mov<mode>_xor"
1837 [(set (match_operand:SWI48 0 "register_operand" "=r")
1838 (match_operand:SWI48 1 "const0_operand"))
1839 (clobber (reg:CC FLAGS_REG))]
1840 "reload_completed"
1841 "xor{l}\t%k0, %k0"
1842 [(set_attr "type" "alu1")
1843 (set_attr "mode" "SI")
1844 (set_attr "length_immediate" "0")])
1845
1846 (define_insn "*mov<mode>_or"
1847 [(set (match_operand:SWI48 0 "register_operand" "=r")
1848 (match_operand:SWI48 1 "const_int_operand"))
1849 (clobber (reg:CC FLAGS_REG))]
1850 "reload_completed
1851 && operands[1] == constm1_rtx"
1852 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1853 [(set_attr "type" "alu1")
1854 (set_attr "mode" "<MODE>")
1855 (set_attr "length_immediate" "1")])
1856
1857 (define_insn "*movxi_internal_avx512f"
1858 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1859 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1860 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1861 {
1862 switch (which_alternative)
1863 {
1864 case 0:
1865 return standard_sse_constant_opcode (insn, operands[1]);
1866 case 1:
1867 case 2:
1868 if (misaligned_operand (operands[0], XImode)
1869 || misaligned_operand (operands[1], XImode))
1870 return "vmovdqu32\t{%1, %0|%0, %1}";
1871 else
1872 return "vmovdqa32\t{%1, %0|%0, %1}";
1873 default:
1874 gcc_unreachable ();
1875 }
1876 }
1877 [(set_attr "type" "sselog1,ssemov,ssemov")
1878 (set_attr "prefix" "evex")
1879 (set_attr "mode" "XI")])
1880
1881 (define_insn "*movoi_internal_avx"
1882 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1883 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1884 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1885 {
1886 switch (get_attr_type (insn))
1887 {
1888 case TYPE_SSELOG1:
1889 return standard_sse_constant_opcode (insn, operands[1]);
1890
1891 case TYPE_SSEMOV:
1892 if (misaligned_operand (operands[0], OImode)
1893 || misaligned_operand (operands[1], OImode))
1894 {
1895 if (get_attr_mode (insn) == MODE_V8SF)
1896 return "vmovups\t{%1, %0|%0, %1}";
1897 else
1898 return "vmovdqu\t{%1, %0|%0, %1}";
1899 }
1900 else
1901 {
1902 if (get_attr_mode (insn) == MODE_V8SF)
1903 return "vmovaps\t{%1, %0|%0, %1}";
1904 else
1905 return "vmovdqa\t{%1, %0|%0, %1}";
1906 }
1907
1908 default:
1909 gcc_unreachable ();
1910 }
1911 }
1912 [(set_attr "type" "sselog1,ssemov,ssemov")
1913 (set_attr "prefix" "vex")
1914 (set (attr "mode")
1915 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1916 (const_string "V8SF")
1917 (and (eq_attr "alternative" "2")
1918 (match_test "TARGET_SSE_TYPELESS_STORES"))
1919 (const_string "V8SF")
1920 ]
1921 (const_string "OI")))])
1922
1923 (define_insn "*movti_internal"
1924 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1925 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1926 "(TARGET_64BIT || TARGET_SSE)
1927 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1928 {
1929 switch (get_attr_type (insn))
1930 {
1931 case TYPE_MULTI:
1932 return "#";
1933
1934 case TYPE_SSELOG1:
1935 return standard_sse_constant_opcode (insn, operands[1]);
1936
1937 case TYPE_SSEMOV:
1938 /* TDmode values are passed as TImode on the stack. Moving them
1939 to stack may result in unaligned memory access. */
1940 if (misaligned_operand (operands[0], TImode)
1941 || misaligned_operand (operands[1], TImode))
1942 {
1943 if (get_attr_mode (insn) == MODE_V4SF)
1944 return "%vmovups\t{%1, %0|%0, %1}";
1945 else
1946 return "%vmovdqu\t{%1, %0|%0, %1}";
1947 }
1948 else
1949 {
1950 if (get_attr_mode (insn) == MODE_V4SF)
1951 return "%vmovaps\t{%1, %0|%0, %1}";
1952 else
1953 return "%vmovdqa\t{%1, %0|%0, %1}";
1954 }
1955
1956 default:
1957 gcc_unreachable ();
1958 }
1959 }
1960 [(set_attr "isa" "x64,x64,*,*,*")
1961 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1962 (set (attr "prefix")
1963 (if_then_else (eq_attr "type" "sselog1,ssemov")
1964 (const_string "maybe_vex")
1965 (const_string "orig")))
1966 (set (attr "mode")
1967 (cond [(eq_attr "alternative" "0,1")
1968 (const_string "DI")
1969 (ior (not (match_test "TARGET_SSE2"))
1970 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1971 (const_string "V4SF")
1972 (and (eq_attr "alternative" "4")
1973 (match_test "TARGET_SSE_TYPELESS_STORES"))
1974 (const_string "V4SF")
1975 (match_test "TARGET_AVX")
1976 (const_string "TI")
1977 (match_test "optimize_function_for_size_p (cfun)")
1978 (const_string "V4SF")
1979 ]
1980 (const_string "TI")))])
1981
1982 (define_split
1983 [(set (match_operand:TI 0 "nonimmediate_operand")
1984 (match_operand:TI 1 "general_operand"))]
1985 "reload_completed
1986 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1987 [(const_int 0)]
1988 "ix86_split_long_move (operands); DONE;")
1989
1990 (define_insn "*movdi_internal"
1991 [(set (match_operand:DI 0 "nonimmediate_operand"
1992 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1993 (match_operand:DI 1 "general_operand"
1994 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
1995 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1996 {
1997 switch (get_attr_type (insn))
1998 {
1999 case TYPE_MULTI:
2000 return "#";
2001
2002 case TYPE_MMX:
2003 return "pxor\t%0, %0";
2004
2005 case TYPE_MMXMOV:
2006 /* Handle broken assemblers that require movd instead of movq. */
2007 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2008 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2009 return "movd\t{%1, %0|%0, %1}";
2010 return "movq\t{%1, %0|%0, %1}";
2011
2012 case TYPE_SSELOG1:
2013 if (GENERAL_REG_P (operands[0]))
2014 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2015
2016 return standard_sse_constant_opcode (insn, operands[1]);
2017
2018 case TYPE_SSEMOV:
2019 switch (get_attr_mode (insn))
2020 {
2021 case MODE_DI:
2022 /* Handle broken assemblers that require movd instead of movq. */
2023 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2024 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2025 return "%vmovd\t{%1, %0|%0, %1}";
2026 return "%vmovq\t{%1, %0|%0, %1}";
2027 case MODE_TI:
2028 return "%vmovdqa\t{%1, %0|%0, %1}";
2029 case MODE_XI:
2030 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2031
2032 case MODE_V2SF:
2033 gcc_assert (!TARGET_AVX);
2034 return "movlps\t{%1, %0|%0, %1}";
2035 case MODE_V4SF:
2036 return "%vmovaps\t{%1, %0|%0, %1}";
2037
2038 default:
2039 gcc_unreachable ();
2040 }
2041
2042 case TYPE_SSECVT:
2043 if (SSE_REG_P (operands[0]))
2044 return "movq2dq\t{%1, %0|%0, %1}";
2045 else
2046 return "movdq2q\t{%1, %0|%0, %1}";
2047
2048 case TYPE_LEA:
2049 return "lea{q}\t{%E1, %0|%0, %E1}";
2050
2051 case TYPE_IMOV:
2052 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2053 if (get_attr_mode (insn) == MODE_SI)
2054 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2055 else if (which_alternative == 4)
2056 return "movabs{q}\t{%1, %0|%0, %1}";
2057 else if (ix86_use_lea_for_mov (insn, operands))
2058 return "lea{q}\t{%E1, %0|%0, %E1}";
2059 else
2060 return "mov{q}\t{%1, %0|%0, %1}";
2061
2062 default:
2063 gcc_unreachable ();
2064 }
2065 }
2066 [(set (attr "isa")
2067 (cond [(eq_attr "alternative" "0,1")
2068 (const_string "nox64")
2069 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
2070 (const_string "x64")
2071 (eq_attr "alternative" "17")
2072 (const_string "x64_sse4")
2073 ]
2074 (const_string "*")))
2075 (set (attr "type")
2076 (cond [(eq_attr "alternative" "0,1")
2077 (const_string "multi")
2078 (eq_attr "alternative" "6")
2079 (const_string "mmx")
2080 (eq_attr "alternative" "7,8,9,10,11")
2081 (const_string "mmxmov")
2082 (eq_attr "alternative" "12,17")
2083 (const_string "sselog1")
2084 (eq_attr "alternative" "13,14,15,16,18")
2085 (const_string "ssemov")
2086 (eq_attr "alternative" "19,20")
2087 (const_string "ssecvt")
2088 (match_operand 1 "pic_32bit_operand")
2089 (const_string "lea")
2090 ]
2091 (const_string "imov")))
2092 (set (attr "modrm")
2093 (if_then_else
2094 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2095 (const_string "0")
2096 (const_string "*")))
2097 (set (attr "length_immediate")
2098 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2099 (const_string "8")
2100 (eq_attr "alternative" "17")
2101 (const_string "1")
2102 ]
2103 (const_string "*")))
2104 (set (attr "prefix_rex")
2105 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2106 (const_string "1")
2107 (const_string "*")))
2108 (set (attr "prefix_extra")
2109 (if_then_else (eq_attr "alternative" "17")
2110 (const_string "1")
2111 (const_string "*")))
2112 (set (attr "prefix")
2113 (if_then_else (eq_attr "type" "sselog1,ssemov")
2114 (const_string "maybe_vex")
2115 (const_string "orig")))
2116 (set (attr "prefix_data16")
2117 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2118 (const_string "1")
2119 (const_string "*")))
2120 (set (attr "mode")
2121 (cond [(eq_attr "alternative" "2")
2122 (const_string "SI")
2123 (eq_attr "alternative" "12,13")
2124 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2125 (match_operand 1 "ext_sse_reg_operand"))
2126 (const_string "XI")
2127 (ior (not (match_test "TARGET_SSE2"))
2128 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2129 (const_string "V4SF")
2130 (match_test "TARGET_AVX")
2131 (const_string "TI")
2132 (match_test "optimize_function_for_size_p (cfun)")
2133 (const_string "V4SF")
2134 ]
2135 (const_string "TI"))
2136
2137 (and (eq_attr "alternative" "14,15")
2138 (not (match_test "TARGET_SSE2")))
2139 (const_string "V2SF")
2140 (eq_attr "alternative" "17")
2141 (const_string "TI")
2142 ]
2143 (const_string "DI")))])
2144
2145 (define_split
2146 [(set (match_operand:DI 0 "nonimmediate_operand")
2147 (match_operand:DI 1 "general_operand"))]
2148 "!TARGET_64BIT && reload_completed
2149 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2150 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2151 [(const_int 0)]
2152 "ix86_split_long_move (operands); DONE;")
2153
2154 (define_insn "*movsi_internal"
2155 [(set (match_operand:SI 0 "nonimmediate_operand"
2156 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
2157 (match_operand:SI 1 "general_operand"
2158 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
2159 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2160 {
2161 switch (get_attr_type (insn))
2162 {
2163 case TYPE_SSELOG1:
2164 if (GENERAL_REG_P (operands[0]))
2165 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2166
2167 return standard_sse_constant_opcode (insn, operands[1]);
2168
2169 case TYPE_SSEMOV:
2170 switch (get_attr_mode (insn))
2171 {
2172 case MODE_SI:
2173 return "%vmovd\t{%1, %0|%0, %1}";
2174 case MODE_TI:
2175 return "%vmovdqa\t{%1, %0|%0, %1}";
2176 case MODE_XI:
2177 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2178
2179 case MODE_V4SF:
2180 return "%vmovaps\t{%1, %0|%0, %1}";
2181
2182 case MODE_SF:
2183 gcc_assert (!TARGET_AVX);
2184 return "movss\t{%1, %0|%0, %1}";
2185
2186 default:
2187 gcc_unreachable ();
2188 }
2189
2190 case TYPE_MMX:
2191 return "pxor\t%0, %0";
2192
2193 case TYPE_MMXMOV:
2194 switch (get_attr_mode (insn))
2195 {
2196 case MODE_DI:
2197 return "movq\t{%1, %0|%0, %1}";
2198 case MODE_SI:
2199 return "movd\t{%1, %0|%0, %1}";
2200
2201 default:
2202 gcc_unreachable ();
2203 }
2204
2205 case TYPE_LEA:
2206 return "lea{l}\t{%E1, %0|%0, %E1}";
2207
2208 case TYPE_IMOV:
2209 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2210 if (ix86_use_lea_for_mov (insn, operands))
2211 return "lea{l}\t{%E1, %0|%0, %E1}";
2212 else
2213 return "mov{l}\t{%1, %0|%0, %1}";
2214
2215 default:
2216 gcc_unreachable ();
2217 }
2218 }
2219 [(set (attr "isa")
2220 (if_then_else (eq_attr "alternative" "11")
2221 (const_string "sse4")
2222 (const_string "*")))
2223 (set (attr "type")
2224 (cond [(eq_attr "alternative" "2")
2225 (const_string "mmx")
2226 (eq_attr "alternative" "3,4,5")
2227 (const_string "mmxmov")
2228 (eq_attr "alternative" "6,11")
2229 (const_string "sselog1")
2230 (eq_attr "alternative" "7,8,9,10,12")
2231 (const_string "ssemov")
2232 (match_operand 1 "pic_32bit_operand")
2233 (const_string "lea")
2234 ]
2235 (const_string "imov")))
2236 (set (attr "length_immediate")
2237 (if_then_else (eq_attr "alternative" "11")
2238 (const_string "1")
2239 (const_string "*")))
2240 (set (attr "prefix_extra")
2241 (if_then_else (eq_attr "alternative" "11")
2242 (const_string "1")
2243 (const_string "*")))
2244 (set (attr "prefix")
2245 (if_then_else (eq_attr "type" "sselog1,ssemov")
2246 (const_string "maybe_vex")
2247 (const_string "orig")))
2248 (set (attr "prefix_data16")
2249 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2250 (const_string "1")
2251 (const_string "*")))
2252 (set (attr "mode")
2253 (cond [(eq_attr "alternative" "2,3")
2254 (const_string "DI")
2255 (eq_attr "alternative" "6,7")
2256 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2257 (match_operand 1 "ext_sse_reg_operand"))
2258 (const_string "XI")
2259 (ior (not (match_test "TARGET_SSE2"))
2260 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2261 (const_string "V4SF")
2262 (match_test "TARGET_AVX")
2263 (const_string "TI")
2264 (match_test "optimize_function_for_size_p (cfun)")
2265 (const_string "V4SF")
2266 ]
2267 (const_string "TI"))
2268
2269 (and (eq_attr "alternative" "8,9")
2270 (not (match_test "TARGET_SSE2")))
2271 (const_string "SF")
2272 (eq_attr "alternative" "11")
2273 (const_string "TI")
2274 ]
2275 (const_string "SI")))])
2276
2277 (define_insn "*movhi_internal"
2278 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,Yk,Yk,rm")
2279 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,Yk,Yk"))]
2280 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2281 {
2282 switch (get_attr_type (insn))
2283 {
2284 case TYPE_IMOVX:
2285 /* movzwl is faster than movw on p2 due to partial word stalls,
2286 though not as fast as an aligned movl. */
2287 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2288
2289 case TYPE_MSKMOV:
2290 switch (which_alternative)
2291 {
2292 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2293 case 5: return "kmovw\t{%1, %0|%0, %1}";
2294 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2295 default: gcc_unreachable ();
2296 }
2297
2298 default:
2299 if (get_attr_mode (insn) == MODE_SI)
2300 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2301 else
2302 return "mov{w}\t{%1, %0|%0, %1}";
2303 }
2304 }
2305 [(set (attr "type")
2306 (cond [(match_test "optimize_function_for_size_p (cfun)")
2307 (const_string "imov")
2308 (and (eq_attr "alternative" "0")
2309 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2310 (not (match_test "TARGET_HIMODE_MATH"))))
2311 (const_string "imov")
2312 (and (eq_attr "alternative" "1,2")
2313 (match_operand:HI 1 "aligned_operand"))
2314 (const_string "imov")
2315 (eq_attr "alternative" "4,5,6")
2316 (const_string "mskmov")
2317 (and (match_test "TARGET_MOVX")
2318 (eq_attr "alternative" "0,2"))
2319 (const_string "imovx")
2320 ]
2321 (const_string "imov")))
2322 (set (attr "prefix")
2323 (if_then_else (eq_attr "alternative" "4,5,6")
2324 (const_string "vex")
2325 (const_string "orig")))
2326 (set (attr "mode")
2327 (cond [(eq_attr "type" "imovx")
2328 (const_string "SI")
2329 (and (eq_attr "alternative" "1,2")
2330 (match_operand:HI 1 "aligned_operand"))
2331 (const_string "SI")
2332 (and (eq_attr "alternative" "0")
2333 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2334 (not (match_test "TARGET_HIMODE_MATH"))))
2335 (const_string "SI")
2336 ]
2337 (const_string "HI")))])
2338
2339 ;; Situation is quite tricky about when to choose full sized (SImode) move
2340 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2341 ;; partial register dependency machines (such as AMD Athlon), where QImode
2342 ;; moves issue extra dependency and for partial register stalls machines
2343 ;; that don't use QImode patterns (and QImode move cause stall on the next
2344 ;; instruction).
2345 ;;
2346 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2347 ;; register stall machines with, where we use QImode instructions, since
2348 ;; partial register stall can be caused there. Then we use movzx.
2349
2350 (define_insn "*movqi_internal"
2351 [(set (match_operand:QI 0 "nonimmediate_operand"
2352 "=q,q ,q ,r,r ,?r,m ,Yk,Yk,r")
2353 (match_operand:QI 1 "general_operand"
2354 "q ,qn,qm,q,rn,qm,qn,r ,Yk,Yk"))]
2355 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2356 {
2357 switch (get_attr_type (insn))
2358 {
2359 case TYPE_IMOVX:
2360 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2361 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2362
2363 case TYPE_MSKMOV:
2364 switch (which_alternative)
2365 {
2366 case 7: return "kmovw\t{%k1, %0|%0, %k1}";
2367 case 8: return "kmovw\t{%1, %0|%0, %1}";
2368 case 9: return "kmovw\t{%1, %k0|%k0, %1}";
2369 default: gcc_unreachable ();
2370 }
2371
2372 default:
2373 if (get_attr_mode (insn) == MODE_SI)
2374 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2375 else
2376 return "mov{b}\t{%1, %0|%0, %1}";
2377 }
2378 }
2379 [(set (attr "type")
2380 (cond [(and (eq_attr "alternative" "5")
2381 (not (match_operand:QI 1 "aligned_operand")))
2382 (const_string "imovx")
2383 (match_test "optimize_function_for_size_p (cfun)")
2384 (const_string "imov")
2385 (and (eq_attr "alternative" "3")
2386 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2387 (not (match_test "TARGET_QIMODE_MATH"))))
2388 (const_string "imov")
2389 (eq_attr "alternative" "3,5")
2390 (const_string "imovx")
2391 (eq_attr "alternative" "7,8,9")
2392 (const_string "mskmov")
2393 (and (match_test "TARGET_MOVX")
2394 (eq_attr "alternative" "2"))
2395 (const_string "imovx")
2396 ]
2397 (const_string "imov")))
2398 (set (attr "prefix")
2399 (if_then_else (eq_attr "alternative" "7,8,9")
2400 (const_string "vex")
2401 (const_string "orig")))
2402 (set (attr "mode")
2403 (cond [(eq_attr "alternative" "3,4,5")
2404 (const_string "SI")
2405 (eq_attr "alternative" "6")
2406 (const_string "QI")
2407 (eq_attr "type" "imovx")
2408 (const_string "SI")
2409 (and (eq_attr "type" "imov")
2410 (and (eq_attr "alternative" "0,1")
2411 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2412 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2413 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2414 (const_string "SI")
2415 ;; Avoid partial register stalls when not using QImode arithmetic
2416 (and (eq_attr "type" "imov")
2417 (and (eq_attr "alternative" "0,1")
2418 (and (match_test "TARGET_PARTIAL_REG_STALL")
2419 (not (match_test "TARGET_QIMODE_MATH")))))
2420 (const_string "SI")
2421 ]
2422 (const_string "QI")))])
2423
2424 ;; Stores and loads of ax to arbitrary constant address.
2425 ;; We fake an second form of instruction to force reload to load address
2426 ;; into register when rax is not available
2427 (define_insn "*movabs<mode>_1"
2428 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2429 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2430 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2431 "@
2432 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2433 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2434 [(set_attr "type" "imov")
2435 (set_attr "modrm" "0,*")
2436 (set_attr "length_address" "8,0")
2437 (set_attr "length_immediate" "0,*")
2438 (set_attr "memory" "store")
2439 (set_attr "mode" "<MODE>")])
2440
2441 (define_insn "*movabs<mode>_2"
2442 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2443 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2444 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2445 "@
2446 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2447 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2448 [(set_attr "type" "imov")
2449 (set_attr "modrm" "0,*")
2450 (set_attr "length_address" "8,0")
2451 (set_attr "length_immediate" "0")
2452 (set_attr "memory" "load")
2453 (set_attr "mode" "<MODE>")])
2454
2455 (define_insn "swap<mode>"
2456 [(set (match_operand:SWI48 0 "register_operand" "+r")
2457 (match_operand:SWI48 1 "register_operand" "+r"))
2458 (set (match_dup 1)
2459 (match_dup 0))]
2460 ""
2461 "xchg{<imodesuffix>}\t%1, %0"
2462 [(set_attr "type" "imov")
2463 (set_attr "mode" "<MODE>")
2464 (set_attr "pent_pair" "np")
2465 (set_attr "athlon_decode" "vector")
2466 (set_attr "amdfam10_decode" "double")
2467 (set_attr "bdver1_decode" "double")])
2468
2469 (define_insn "*swap<mode>_1"
2470 [(set (match_operand:SWI12 0 "register_operand" "+r")
2471 (match_operand:SWI12 1 "register_operand" "+r"))
2472 (set (match_dup 1)
2473 (match_dup 0))]
2474 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2475 "xchg{l}\t%k1, %k0"
2476 [(set_attr "type" "imov")
2477 (set_attr "mode" "SI")
2478 (set_attr "pent_pair" "np")
2479 (set_attr "athlon_decode" "vector")
2480 (set_attr "amdfam10_decode" "double")
2481 (set_attr "bdver1_decode" "double")])
2482
2483 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2484 ;; is disabled for AMDFAM10
2485 (define_insn "*swap<mode>_2"
2486 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2487 (match_operand:SWI12 1 "register_operand" "+<r>"))
2488 (set (match_dup 1)
2489 (match_dup 0))]
2490 "TARGET_PARTIAL_REG_STALL"
2491 "xchg{<imodesuffix>}\t%1, %0"
2492 [(set_attr "type" "imov")
2493 (set_attr "mode" "<MODE>")
2494 (set_attr "pent_pair" "np")
2495 (set_attr "athlon_decode" "vector")])
2496
2497 (define_expand "movstrict<mode>"
2498 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2499 (match_operand:SWI12 1 "general_operand"))]
2500 ""
2501 {
2502 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2503 FAIL;
2504 if (GET_CODE (operands[0]) == SUBREG
2505 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2506 FAIL;
2507 /* Don't generate memory->memory moves, go through a register */
2508 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2509 operands[1] = force_reg (<MODE>mode, operands[1]);
2510 })
2511
2512 (define_insn "*movstrict<mode>_1"
2513 [(set (strict_low_part
2514 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2515 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2516 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2517 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2518 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2519 [(set_attr "type" "imov")
2520 (set_attr "mode" "<MODE>")])
2521
2522 (define_insn "*movstrict<mode>_xor"
2523 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2524 (match_operand:SWI12 1 "const0_operand"))
2525 (clobber (reg:CC FLAGS_REG))]
2526 "reload_completed"
2527 "xor{<imodesuffix>}\t%0, %0"
2528 [(set_attr "type" "alu1")
2529 (set_attr "mode" "<MODE>")
2530 (set_attr "length_immediate" "0")])
2531
2532 (define_insn "*mov<mode>_extv_1"
2533 [(set (match_operand:SWI24 0 "register_operand" "=R")
2534 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2535 (const_int 8)
2536 (const_int 8)))]
2537 ""
2538 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2539 [(set_attr "type" "imovx")
2540 (set_attr "mode" "SI")])
2541
2542 (define_insn "*movqi_extv_1"
2543 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2544 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2545 (const_int 8)
2546 (const_int 8)))]
2547 ""
2548 {
2549 switch (get_attr_type (insn))
2550 {
2551 case TYPE_IMOVX:
2552 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2553 default:
2554 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 }
2556 }
2557 [(set_attr "isa" "*,*,nox64")
2558 (set (attr "type")
2559 (if_then_else (and (match_operand:QI 0 "register_operand")
2560 (ior (not (match_operand:QI 0 "QIreg_operand"))
2561 (match_test "TARGET_MOVX")))
2562 (const_string "imovx")
2563 (const_string "imov")))
2564 (set (attr "mode")
2565 (if_then_else (eq_attr "type" "imovx")
2566 (const_string "SI")
2567 (const_string "QI")))])
2568
2569 (define_insn "*mov<mode>_extzv_1"
2570 [(set (match_operand:SWI48 0 "register_operand" "=R")
2571 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2572 (const_int 8)
2573 (const_int 8)))]
2574 ""
2575 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2576 [(set_attr "type" "imovx")
2577 (set_attr "mode" "SI")])
2578
2579 (define_insn "*movqi_extzv_2"
2580 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2581 (subreg:QI
2582 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2583 (const_int 8)
2584 (const_int 8)) 0))]
2585 ""
2586 {
2587 switch (get_attr_type (insn))
2588 {
2589 case TYPE_IMOVX:
2590 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2591 default:
2592 return "mov{b}\t{%h1, %0|%0, %h1}";
2593 }
2594 }
2595 [(set_attr "isa" "*,*,nox64")
2596 (set (attr "type")
2597 (if_then_else (and (match_operand:QI 0 "register_operand")
2598 (ior (not (match_operand:QI 0 "QIreg_operand"))
2599 (match_test "TARGET_MOVX")))
2600 (const_string "imovx")
2601 (const_string "imov")))
2602 (set (attr "mode")
2603 (if_then_else (eq_attr "type" "imovx")
2604 (const_string "SI")
2605 (const_string "QI")))])
2606
2607 (define_insn "mov<mode>_insv_1"
2608 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2609 (const_int 8)
2610 (const_int 8))
2611 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2612 ""
2613 {
2614 if (CONST_INT_P (operands[1]))
2615 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2616 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2617 }
2618 [(set_attr "isa" "*,nox64")
2619 (set_attr "type" "imov")
2620 (set_attr "mode" "QI")])
2621
2622 (define_insn "*movqi_insv_2"
2623 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2624 (const_int 8)
2625 (const_int 8))
2626 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2627 (const_int 8)))]
2628 ""
2629 "mov{b}\t{%h1, %h0|%h0, %h1}"
2630 [(set_attr "type" "imov")
2631 (set_attr "mode" "QI")])
2632 \f
2633 ;; Floating point push instructions.
2634
2635 (define_insn "*pushtf"
2636 [(set (match_operand:TF 0 "push_operand" "=<,<")
2637 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2638 "TARGET_64BIT || TARGET_SSE"
2639 {
2640 /* This insn should be already split before reg-stack. */
2641 gcc_unreachable ();
2642 }
2643 [(set_attr "isa" "*,x64")
2644 (set_attr "type" "multi")
2645 (set_attr "unit" "sse,*")
2646 (set_attr "mode" "TF,DI")])
2647
2648 ;; %%% Kill this when call knows how to work this out.
2649 (define_split
2650 [(set (match_operand:TF 0 "push_operand")
2651 (match_operand:TF 1 "sse_reg_operand"))]
2652 "TARGET_SSE && reload_completed"
2653 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2654 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2655
2656 (define_insn "*pushxf"
2657 [(set (match_operand:XF 0 "push_operand" "=<,<")
2658 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2659 ""
2660 {
2661 /* This insn should be already split before reg-stack. */
2662 gcc_unreachable ();
2663 }
2664 [(set_attr "type" "multi")
2665 (set_attr "unit" "i387,*")
2666 (set (attr "mode")
2667 (cond [(eq_attr "alternative" "1")
2668 (if_then_else (match_test "TARGET_64BIT")
2669 (const_string "DI")
2670 (const_string "SI"))
2671 ]
2672 (const_string "XF")))])
2673
2674 ;; %%% Kill this when call knows how to work this out.
2675 (define_split
2676 [(set (match_operand:XF 0 "push_operand")
2677 (match_operand:XF 1 "fp_register_operand"))]
2678 "reload_completed"
2679 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2680 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2681 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2682
2683 (define_insn "*pushdf"
2684 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2685 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2686 ""
2687 {
2688 /* This insn should be already split before reg-stack. */
2689 gcc_unreachable ();
2690 }
2691 [(set_attr "isa" "*,nox64,x64,sse2")
2692 (set_attr "type" "multi")
2693 (set_attr "unit" "i387,*,*,sse")
2694 (set_attr "mode" "DF,SI,DI,DF")])
2695
2696 ;; %%% Kill this when call knows how to work this out.
2697 (define_split
2698 [(set (match_operand:DF 0 "push_operand")
2699 (match_operand:DF 1 "any_fp_register_operand"))]
2700 "reload_completed"
2701 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2702 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2703
2704 (define_insn "*pushsf_rex64"
2705 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2706 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2707 "TARGET_64BIT"
2708 {
2709 /* Anything else should be already split before reg-stack. */
2710 gcc_assert (which_alternative == 1);
2711 return "push{q}\t%q1";
2712 }
2713 [(set_attr "type" "multi,push,multi")
2714 (set_attr "unit" "i387,*,*")
2715 (set_attr "mode" "SF,DI,SF")])
2716
2717 (define_insn "*pushsf"
2718 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2719 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2720 "!TARGET_64BIT"
2721 {
2722 /* Anything else should be already split before reg-stack. */
2723 gcc_assert (which_alternative == 1);
2724 return "push{l}\t%1";
2725 }
2726 [(set_attr "type" "multi,push,multi")
2727 (set_attr "unit" "i387,*,*")
2728 (set_attr "mode" "SF,SI,SF")])
2729
2730 ;; %%% Kill this when call knows how to work this out.
2731 (define_split
2732 [(set (match_operand:SF 0 "push_operand")
2733 (match_operand:SF 1 "any_fp_register_operand"))]
2734 "reload_completed"
2735 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2736 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2737 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2738
2739 (define_split
2740 [(set (match_operand:SF 0 "push_operand")
2741 (match_operand:SF 1 "memory_operand"))]
2742 "reload_completed
2743 && (operands[2] = find_constant_src (insn))"
2744 [(set (match_dup 0) (match_dup 2))])
2745
2746 (define_split
2747 [(set (match_operand 0 "push_operand")
2748 (match_operand 1 "general_operand"))]
2749 "reload_completed
2750 && (GET_MODE (operands[0]) == TFmode
2751 || GET_MODE (operands[0]) == XFmode
2752 || GET_MODE (operands[0]) == DFmode)
2753 && !ANY_FP_REG_P (operands[1])"
2754 [(const_int 0)]
2755 "ix86_split_long_move (operands); DONE;")
2756 \f
2757 ;; Floating point move instructions.
2758
2759 (define_expand "movtf"
2760 [(set (match_operand:TF 0 "nonimmediate_operand")
2761 (match_operand:TF 1 "nonimmediate_operand"))]
2762 "TARGET_64BIT || TARGET_SSE"
2763 "ix86_expand_move (TFmode, operands); DONE;")
2764
2765 (define_expand "mov<mode>"
2766 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2767 (match_operand:X87MODEF 1 "general_operand"))]
2768 ""
2769 "ix86_expand_move (<MODE>mode, operands); DONE;")
2770
2771 (define_insn "*movtf_internal"
2772 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2773 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2774 "(TARGET_64BIT || TARGET_SSE)
2775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2776 && (!can_create_pseudo_p ()
2777 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2778 || GET_CODE (operands[1]) != CONST_DOUBLE
2779 || (optimize_function_for_size_p (cfun)
2780 && standard_sse_constant_p (operands[1])
2781 && !memory_operand (operands[0], TFmode))
2782 || (!TARGET_MEMORY_MISMATCH_STALL
2783 && memory_operand (operands[0], TFmode)))"
2784 {
2785 switch (get_attr_type (insn))
2786 {
2787 case TYPE_SSELOG1:
2788 return standard_sse_constant_opcode (insn, operands[1]);
2789
2790 case TYPE_SSEMOV:
2791 /* Handle misaligned load/store since we
2792 don't have movmisaligntf pattern. */
2793 if (misaligned_operand (operands[0], TFmode)
2794 || misaligned_operand (operands[1], TFmode))
2795 {
2796 if (get_attr_mode (insn) == MODE_V4SF)
2797 return "%vmovups\t{%1, %0|%0, %1}";
2798 else
2799 return "%vmovdqu\t{%1, %0|%0, %1}";
2800 }
2801 else
2802 {
2803 if (get_attr_mode (insn) == MODE_V4SF)
2804 return "%vmovaps\t{%1, %0|%0, %1}";
2805 else
2806 return "%vmovdqa\t{%1, %0|%0, %1}";
2807 }
2808
2809 case TYPE_MULTI:
2810 return "#";
2811
2812 default:
2813 gcc_unreachable ();
2814 }
2815 }
2816 [(set_attr "isa" "*,*,*,x64,x64")
2817 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2818 (set (attr "prefix")
2819 (if_then_else (eq_attr "type" "sselog1,ssemov")
2820 (const_string "maybe_vex")
2821 (const_string "orig")))
2822 (set (attr "mode")
2823 (cond [(eq_attr "alternative" "3,4")
2824 (const_string "DI")
2825 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2826 (const_string "V4SF")
2827 (and (eq_attr "alternative" "2")
2828 (match_test "TARGET_SSE_TYPELESS_STORES"))
2829 (const_string "V4SF")
2830 (match_test "TARGET_AVX")
2831 (const_string "TI")
2832 (ior (not (match_test "TARGET_SSE2"))
2833 (match_test "optimize_function_for_size_p (cfun)"))
2834 (const_string "V4SF")
2835 ]
2836 (const_string "TI")))])
2837
2838 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2839 (define_insn "*movxf_internal"
2840 [(set (match_operand:XF 0 "nonimmediate_operand"
2841 "=f,m,f,?Yx*r ,!o ,!o")
2842 (match_operand:XF 1 "general_operand"
2843 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2844 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2845 && (!can_create_pseudo_p ()
2846 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2847 || GET_CODE (operands[1]) != CONST_DOUBLE
2848 || (optimize_function_for_size_p (cfun)
2849 && standard_80387_constant_p (operands[1]) > 0
2850 && !memory_operand (operands[0], XFmode))
2851 || (!TARGET_MEMORY_MISMATCH_STALL
2852 && memory_operand (operands[0], XFmode)))"
2853 {
2854 switch (get_attr_type (insn))
2855 {
2856 case TYPE_FMOV:
2857 if (which_alternative == 2)
2858 return standard_80387_constant_opcode (operands[1]);
2859 return output_387_reg_move (insn, operands);
2860
2861 case TYPE_MULTI:
2862 return "#";
2863
2864 default:
2865 gcc_unreachable ();
2866 }
2867 }
2868 [(set_attr "isa" "*,*,*,*,nox64,x64")
2869 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2870 (set (attr "mode")
2871 (cond [(eq_attr "alternative" "3,4,5")
2872 (if_then_else (match_test "TARGET_64BIT")
2873 (const_string "DI")
2874 (const_string "SI"))
2875 ]
2876 (const_string "XF")))])
2877
2878 ;; Possible store forwarding (partial memory) stall in alternative 4.
2879 (define_insn "*movdf_internal"
2880 [(set (match_operand:DF 0 "nonimmediate_operand"
2881 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
2882 (match_operand:DF 1 "general_operand"
2883 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
2884 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2885 && (!can_create_pseudo_p ()
2886 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2887 || GET_CODE (operands[1]) != CONST_DOUBLE
2888 || (optimize_function_for_size_p (cfun)
2889 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2890 && standard_80387_constant_p (operands[1]) > 0)
2891 || (TARGET_SSE2 && TARGET_SSE_MATH
2892 && standard_sse_constant_p (operands[1])))
2893 && !memory_operand (operands[0], DFmode))
2894 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2895 && memory_operand (operands[0], DFmode)))"
2896 {
2897 switch (get_attr_type (insn))
2898 {
2899 case TYPE_FMOV:
2900 if (which_alternative == 2)
2901 return standard_80387_constant_opcode (operands[1]);
2902 return output_387_reg_move (insn, operands);
2903
2904 case TYPE_MULTI:
2905 return "#";
2906
2907 case TYPE_IMOV:
2908 if (get_attr_mode (insn) == MODE_SI)
2909 return "mov{l}\t{%1, %k0|%k0, %1}";
2910 else if (which_alternative == 8)
2911 return "movabs{q}\t{%1, %0|%0, %1}";
2912 else
2913 return "mov{q}\t{%1, %0|%0, %1}";
2914
2915 case TYPE_SSELOG1:
2916 return standard_sse_constant_opcode (insn, operands[1]);
2917
2918 case TYPE_SSEMOV:
2919 switch (get_attr_mode (insn))
2920 {
2921 case MODE_DF:
2922 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2923 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2924 return "%vmovsd\t{%1, %0|%0, %1}";
2925
2926 case MODE_V4SF:
2927 return "%vmovaps\t{%1, %0|%0, %1}";
2928 case MODE_V8DF:
2929 return "vmovapd\t{%g1, %g0|%g0, %g1}";
2930 case MODE_V2DF:
2931 return "%vmovapd\t{%1, %0|%0, %1}";
2932
2933 case MODE_V2SF:
2934 gcc_assert (!TARGET_AVX);
2935 return "movlps\t{%1, %0|%0, %1}";
2936 case MODE_V1DF:
2937 gcc_assert (!TARGET_AVX);
2938 return "movlpd\t{%1, %0|%0, %1}";
2939
2940 case MODE_DI:
2941 /* Handle broken assemblers that require movd instead of movq. */
2942 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2943 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2944 return "%vmovd\t{%1, %0|%0, %1}";
2945 return "%vmovq\t{%1, %0|%0, %1}";
2946
2947 default:
2948 gcc_unreachable ();
2949 }
2950
2951 default:
2952 gcc_unreachable ();
2953 }
2954 }
2955 [(set (attr "isa")
2956 (cond [(eq_attr "alternative" "3,4")
2957 (const_string "nox64")
2958 (eq_attr "alternative" "5,6,7,8,17,18")
2959 (const_string "x64")
2960 (eq_attr "alternative" "9,10,11,12")
2961 (const_string "sse2")
2962 ]
2963 (const_string "*")))
2964 (set (attr "type")
2965 (cond [(eq_attr "alternative" "0,1,2")
2966 (const_string "fmov")
2967 (eq_attr "alternative" "3,4")
2968 (const_string "multi")
2969 (eq_attr "alternative" "5,6,7,8")
2970 (const_string "imov")
2971 (eq_attr "alternative" "9,13")
2972 (const_string "sselog1")
2973 ]
2974 (const_string "ssemov")))
2975 (set (attr "modrm")
2976 (if_then_else (eq_attr "alternative" "8")
2977 (const_string "0")
2978 (const_string "*")))
2979 (set (attr "length_immediate")
2980 (if_then_else (eq_attr "alternative" "8")
2981 (const_string "8")
2982 (const_string "*")))
2983 (set (attr "prefix")
2984 (if_then_else (eq_attr "type" "sselog1,ssemov")
2985 (const_string "maybe_vex")
2986 (const_string "orig")))
2987 (set (attr "prefix_data16")
2988 (if_then_else
2989 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2990 (eq_attr "mode" "V1DF"))
2991 (const_string "1")
2992 (const_string "*")))
2993 (set (attr "mode")
2994 (cond [(eq_attr "alternative" "3,4,7")
2995 (const_string "SI")
2996 (eq_attr "alternative" "5,6,8,17,18")
2997 (const_string "DI")
2998
2999 /* xorps is one byte shorter for non-AVX targets. */
3000 (eq_attr "alternative" "9,13")
3001 (cond [(not (match_test "TARGET_SSE2"))
3002 (const_string "V4SF")
3003 (match_test "TARGET_AVX512F")
3004 (const_string "XI")
3005 (match_test "TARGET_AVX")
3006 (const_string "V2DF")
3007 (match_test "optimize_function_for_size_p (cfun)")
3008 (const_string "V4SF")
3009 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3010 (const_string "TI")
3011 ]
3012 (const_string "V2DF"))
3013
3014 /* For architectures resolving dependencies on
3015 whole SSE registers use movapd to break dependency
3016 chains, otherwise use short move to avoid extra work. */
3017
3018 /* movaps is one byte shorter for non-AVX targets. */
3019 (eq_attr "alternative" "10,14")
3020 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3021 (match_operand 1 "ext_sse_reg_operand"))
3022 (const_string "V8DF")
3023 (ior (not (match_test "TARGET_SSE2"))
3024 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3025 (const_string "V4SF")
3026 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3027 (const_string "V2DF")
3028 (match_test "TARGET_AVX")
3029 (const_string "DF")
3030 (match_test "optimize_function_for_size_p (cfun)")
3031 (const_string "V4SF")
3032 ]
3033 (const_string "DF"))
3034
3035 /* For architectures resolving dependencies on register
3036 parts we may avoid extra work to zero out upper part
3037 of register. */
3038 (eq_attr "alternative" "11,15")
3039 (cond [(not (match_test "TARGET_SSE2"))
3040 (const_string "V2SF")
3041 (match_test "TARGET_AVX")
3042 (const_string "DF")
3043 (match_test "TARGET_SSE_SPLIT_REGS")
3044 (const_string "V1DF")
3045 ]
3046 (const_string "DF"))
3047
3048 (and (eq_attr "alternative" "12,16")
3049 (not (match_test "TARGET_SSE2")))
3050 (const_string "V2SF")
3051 ]
3052 (const_string "DF")))])
3053
3054 (define_insn "*movsf_internal"
3055 [(set (match_operand:SF 0 "nonimmediate_operand"
3056 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3057 (match_operand:SF 1 "general_operand"
3058 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3059 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3060 && (!can_create_pseudo_p ()
3061 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3062 || GET_CODE (operands[1]) != CONST_DOUBLE
3063 || (optimize_function_for_size_p (cfun)
3064 && ((!TARGET_SSE_MATH
3065 && standard_80387_constant_p (operands[1]) > 0)
3066 || (TARGET_SSE_MATH
3067 && standard_sse_constant_p (operands[1]))))
3068 || memory_operand (operands[0], SFmode))"
3069 {
3070 switch (get_attr_type (insn))
3071 {
3072 case TYPE_FMOV:
3073 if (which_alternative == 2)
3074 return standard_80387_constant_opcode (operands[1]);
3075 return output_387_reg_move (insn, operands);
3076
3077 case TYPE_IMOV:
3078 return "mov{l}\t{%1, %0|%0, %1}";
3079
3080 case TYPE_SSELOG1:
3081 return standard_sse_constant_opcode (insn, operands[1]);
3082
3083 case TYPE_SSEMOV:
3084 switch (get_attr_mode (insn))
3085 {
3086 case MODE_SF:
3087 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3088 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3089 return "%vmovss\t{%1, %0|%0, %1}";
3090
3091 case MODE_V16SF:
3092 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3093 case MODE_V4SF:
3094 return "%vmovaps\t{%1, %0|%0, %1}";
3095
3096 case MODE_SI:
3097 return "%vmovd\t{%1, %0|%0, %1}";
3098
3099 default:
3100 gcc_unreachable ();
3101 }
3102
3103 case TYPE_MMXMOV:
3104 switch (get_attr_mode (insn))
3105 {
3106 case MODE_DI:
3107 return "movq\t{%1, %0|%0, %1}";
3108 case MODE_SI:
3109 return "movd\t{%1, %0|%0, %1}";
3110
3111 default:
3112 gcc_unreachable ();
3113 }
3114
3115 default:
3116 gcc_unreachable ();
3117 }
3118 }
3119 [(set (attr "type")
3120 (cond [(eq_attr "alternative" "0,1,2")
3121 (const_string "fmov")
3122 (eq_attr "alternative" "3,4")
3123 (const_string "imov")
3124 (eq_attr "alternative" "5")
3125 (const_string "sselog1")
3126 (eq_attr "alternative" "11,12,13,14,15")
3127 (const_string "mmxmov")
3128 ]
3129 (const_string "ssemov")))
3130 (set (attr "prefix")
3131 (if_then_else (eq_attr "type" "sselog1,ssemov")
3132 (const_string "maybe_vex")
3133 (const_string "orig")))
3134 (set (attr "prefix_data16")
3135 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3136 (const_string "1")
3137 (const_string "*")))
3138 (set (attr "mode")
3139 (cond [(eq_attr "alternative" "3,4,9,10,13,14,15")
3140 (const_string "SI")
3141 (eq_attr "alternative" "11")
3142 (const_string "DI")
3143 (eq_attr "alternative" "5")
3144 (cond [(not (match_test "TARGET_SSE2"))
3145 (const_string "V4SF")
3146 (match_test "TARGET_AVX512F")
3147 (const_string "V16SF")
3148 (match_test "TARGET_AVX")
3149 (const_string "V4SF")
3150 (match_test "optimize_function_for_size_p (cfun)")
3151 (const_string "V4SF")
3152 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3153 (const_string "TI")
3154 ]
3155 (const_string "V4SF"))
3156
3157 /* For architectures resolving dependencies on
3158 whole SSE registers use APS move to break dependency
3159 chains, otherwise use short move to avoid extra work.
3160
3161 Do the same for architectures resolving dependencies on
3162 the parts. While in DF mode it is better to always handle
3163 just register parts, the SF mode is different due to lack
3164 of instructions to load just part of the register. It is
3165 better to maintain the whole registers in single format
3166 to avoid problems on using packed logical operations. */
3167 (eq_attr "alternative" "6")
3168 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3169 (match_operand 1 "ext_sse_reg_operand"))
3170 (const_string "V16SF")
3171 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3172 (match_test "TARGET_SSE_SPLIT_REGS"))
3173 (const_string "V4SF")
3174 ]
3175 (const_string "SF"))
3176 ]
3177 (const_string "SF")))])
3178
3179 (define_split
3180 [(set (match_operand 0 "any_fp_register_operand")
3181 (match_operand 1 "memory_operand"))]
3182 "reload_completed
3183 && (GET_MODE (operands[0]) == TFmode
3184 || GET_MODE (operands[0]) == XFmode
3185 || GET_MODE (operands[0]) == DFmode
3186 || GET_MODE (operands[0]) == SFmode)
3187 && (operands[2] = find_constant_src (insn))"
3188 [(set (match_dup 0) (match_dup 2))]
3189 {
3190 rtx c = operands[2];
3191 int r = REGNO (operands[0]);
3192
3193 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3194 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3195 FAIL;
3196 })
3197
3198 (define_split
3199 [(set (match_operand 0 "any_fp_register_operand")
3200 (float_extend (match_operand 1 "memory_operand")))]
3201 "reload_completed
3202 && (GET_MODE (operands[0]) == TFmode
3203 || GET_MODE (operands[0]) == XFmode
3204 || GET_MODE (operands[0]) == DFmode)
3205 && (operands[2] = find_constant_src (insn))"
3206 [(set (match_dup 0) (match_dup 2))]
3207 {
3208 rtx c = operands[2];
3209 int r = REGNO (operands[0]);
3210
3211 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3212 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3213 FAIL;
3214 })
3215
3216 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3217 (define_split
3218 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3219 (match_operand:X87MODEF 1 "immediate_operand"))]
3220 "reload_completed
3221 && (standard_80387_constant_p (operands[1]) == 8
3222 || standard_80387_constant_p (operands[1]) == 9)"
3223 [(set (match_dup 0)(match_dup 1))
3224 (set (match_dup 0)
3225 (neg:X87MODEF (match_dup 0)))]
3226 {
3227 REAL_VALUE_TYPE r;
3228
3229 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3230 if (real_isnegzero (&r))
3231 operands[1] = CONST0_RTX (<MODE>mode);
3232 else
3233 operands[1] = CONST1_RTX (<MODE>mode);
3234 })
3235
3236 (define_split
3237 [(set (match_operand 0 "nonimmediate_operand")
3238 (match_operand 1 "general_operand"))]
3239 "reload_completed
3240 && (GET_MODE (operands[0]) == TFmode
3241 || GET_MODE (operands[0]) == XFmode
3242 || GET_MODE (operands[0]) == DFmode)
3243 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3244 [(const_int 0)]
3245 "ix86_split_long_move (operands); DONE;")
3246
3247 (define_insn "swapxf"
3248 [(set (match_operand:XF 0 "register_operand" "+f")
3249 (match_operand:XF 1 "register_operand" "+f"))
3250 (set (match_dup 1)
3251 (match_dup 0))]
3252 "TARGET_80387"
3253 {
3254 if (STACK_TOP_P (operands[0]))
3255 return "fxch\t%1";
3256 else
3257 return "fxch\t%0";
3258 }
3259 [(set_attr "type" "fxch")
3260 (set_attr "mode" "XF")])
3261
3262 (define_insn "*swap<mode>"
3263 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3264 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3265 (set (match_dup 1)
3266 (match_dup 0))]
3267 "TARGET_80387 || reload_completed"
3268 {
3269 if (STACK_TOP_P (operands[0]))
3270 return "fxch\t%1";
3271 else
3272 return "fxch\t%0";
3273 }
3274 [(set_attr "type" "fxch")
3275 (set_attr "mode" "<MODE>")])
3276 \f
3277 ;; Zero extension instructions
3278
3279 (define_expand "zero_extendsidi2"
3280 [(set (match_operand:DI 0 "nonimmediate_operand")
3281 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3282
3283 (define_insn "*zero_extendsidi2"
3284 [(set (match_operand:DI 0 "nonimmediate_operand"
3285 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3286 (zero_extend:DI
3287 (match_operand:SI 1 "x86_64_zext_operand"
3288 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3289 ""
3290 {
3291 switch (get_attr_type (insn))
3292 {
3293 case TYPE_IMOVX:
3294 if (ix86_use_lea_for_mov (insn, operands))
3295 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3296 else
3297 return "mov{l}\t{%1, %k0|%k0, %1}";
3298
3299 case TYPE_MULTI:
3300 return "#";
3301
3302 case TYPE_MMXMOV:
3303 return "movd\t{%1, %0|%0, %1}";
3304
3305 case TYPE_SSELOG1:
3306 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3307
3308 case TYPE_SSEMOV:
3309 if (GENERAL_REG_P (operands[0]))
3310 return "%vmovd\t{%1, %k0|%k0, %1}";
3311
3312 return "%vmovd\t{%1, %0|%0, %1}";
3313
3314 default:
3315 gcc_unreachable ();
3316 }
3317 }
3318 [(set (attr "isa")
3319 (cond [(eq_attr "alternative" "0,1,2")
3320 (const_string "nox64")
3321 (eq_attr "alternative" "3,7")
3322 (const_string "x64")
3323 (eq_attr "alternative" "8")
3324 (const_string "x64_sse4")
3325 (eq_attr "alternative" "10")
3326 (const_string "sse2")
3327 ]
3328 (const_string "*")))
3329 (set (attr "type")
3330 (cond [(eq_attr "alternative" "0,1,2,4")
3331 (const_string "multi")
3332 (eq_attr "alternative" "5,6")
3333 (const_string "mmxmov")
3334 (eq_attr "alternative" "7,9,10")
3335 (const_string "ssemov")
3336 (eq_attr "alternative" "8")
3337 (const_string "sselog1")
3338 ]
3339 (const_string "imovx")))
3340 (set (attr "prefix_extra")
3341 (if_then_else (eq_attr "alternative" "8")
3342 (const_string "1")
3343 (const_string "*")))
3344 (set (attr "length_immediate")
3345 (if_then_else (eq_attr "alternative" "8")
3346 (const_string "1")
3347 (const_string "*")))
3348 (set (attr "prefix")
3349 (if_then_else (eq_attr "type" "ssemov,sselog1")
3350 (const_string "maybe_vex")
3351 (const_string "orig")))
3352 (set (attr "prefix_0f")
3353 (if_then_else (eq_attr "type" "imovx")
3354 (const_string "0")
3355 (const_string "*")))
3356 (set (attr "mode")
3357 (cond [(eq_attr "alternative" "5,6")
3358 (const_string "DI")
3359 (eq_attr "alternative" "7,8,9")
3360 (const_string "TI")
3361 ]
3362 (const_string "SI")))])
3363
3364 (define_split
3365 [(set (match_operand:DI 0 "memory_operand")
3366 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3367 "reload_completed"
3368 [(set (match_dup 4) (const_int 0))]
3369 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3370
3371 (define_split
3372 [(set (match_operand:DI 0 "register_operand")
3373 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3374 "!TARGET_64BIT && reload_completed
3375 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3376 && true_regnum (operands[0]) == true_regnum (operands[1])"
3377 [(set (match_dup 4) (const_int 0))]
3378 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3379
3380 (define_split
3381 [(set (match_operand:DI 0 "nonimmediate_operand")
3382 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3383 "!TARGET_64BIT && reload_completed
3384 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3385 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3386 [(set (match_dup 3) (match_dup 1))
3387 (set (match_dup 4) (const_int 0))]
3388 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3389
3390 (define_insn "zero_extend<mode>di2"
3391 [(set (match_operand:DI 0 "register_operand" "=r")
3392 (zero_extend:DI
3393 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3394 "TARGET_64BIT"
3395 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3396 [(set_attr "type" "imovx")
3397 (set_attr "mode" "SI")])
3398
3399 (define_expand "zero_extend<mode>si2"
3400 [(set (match_operand:SI 0 "register_operand")
3401 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3402 ""
3403 {
3404 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3405 {
3406 operands[1] = force_reg (<MODE>mode, operands[1]);
3407 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3408 DONE;
3409 }
3410 })
3411
3412 (define_insn_and_split "zero_extend<mode>si2_and"
3413 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3414 (zero_extend:SI
3415 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3416 (clobber (reg:CC FLAGS_REG))]
3417 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3418 "#"
3419 "&& reload_completed"
3420 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3421 (clobber (reg:CC FLAGS_REG))])]
3422 {
3423 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3424 {
3425 ix86_expand_clear (operands[0]);
3426
3427 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3428 emit_insn (gen_movstrict<mode>
3429 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3430 DONE;
3431 }
3432
3433 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3434 }
3435 [(set_attr "type" "alu1")
3436 (set_attr "mode" "SI")])
3437
3438 (define_insn "*zero_extend<mode>si2"
3439 [(set (match_operand:SI 0 "register_operand" "=r")
3440 (zero_extend:SI
3441 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3442 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3443 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3444 [(set_attr "type" "imovx")
3445 (set_attr "mode" "SI")])
3446
3447 (define_expand "zero_extendqihi2"
3448 [(set (match_operand:HI 0 "register_operand")
3449 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3450 ""
3451 {
3452 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3453 {
3454 operands[1] = force_reg (QImode, operands[1]);
3455 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3456 DONE;
3457 }
3458 })
3459
3460 (define_insn_and_split "zero_extendqihi2_and"
3461 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3462 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3463 (clobber (reg:CC FLAGS_REG))]
3464 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3465 "#"
3466 "&& reload_completed"
3467 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3468 (clobber (reg:CC FLAGS_REG))])]
3469 {
3470 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3471 {
3472 ix86_expand_clear (operands[0]);
3473
3474 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3475 emit_insn (gen_movstrictqi
3476 (gen_lowpart (QImode, operands[0]), operands[1]));
3477 DONE;
3478 }
3479
3480 operands[0] = gen_lowpart (SImode, operands[0]);
3481 }
3482 [(set_attr "type" "alu1")
3483 (set_attr "mode" "SI")])
3484
3485 ; zero extend to SImode to avoid partial register stalls
3486 (define_insn "*zero_extendqihi2"
3487 [(set (match_operand:HI 0 "register_operand" "=r")
3488 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3489 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3490 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3491 [(set_attr "type" "imovx")
3492 (set_attr "mode" "SI")])
3493 \f
3494 ;; Sign extension instructions
3495
3496 (define_expand "extendsidi2"
3497 [(set (match_operand:DI 0 "register_operand")
3498 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3499 ""
3500 {
3501 if (!TARGET_64BIT)
3502 {
3503 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3504 DONE;
3505 }
3506 })
3507
3508 (define_insn "*extendsidi2_rex64"
3509 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3510 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3511 "TARGET_64BIT"
3512 "@
3513 {cltq|cdqe}
3514 movs{lq|x}\t{%1, %0|%0, %1}"
3515 [(set_attr "type" "imovx")
3516 (set_attr "mode" "DI")
3517 (set_attr "prefix_0f" "0")
3518 (set_attr "modrm" "0,1")])
3519
3520 (define_insn "extendsidi2_1"
3521 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3522 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3523 (clobber (reg:CC FLAGS_REG))
3524 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3525 "!TARGET_64BIT"
3526 "#")
3527
3528 ;; Split the memory case. If the source register doesn't die, it will stay
3529 ;; this way, if it does die, following peephole2s take care of it.
3530 (define_split
3531 [(set (match_operand:DI 0 "memory_operand")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand"))]
3535 "reload_completed"
3536 [(const_int 0)]
3537 {
3538 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3539
3540 emit_move_insn (operands[3], operands[1]);
3541
3542 /* Generate a cltd if possible and doing so it profitable. */
3543 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3544 && true_regnum (operands[1]) == AX_REG
3545 && true_regnum (operands[2]) == DX_REG)
3546 {
3547 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3548 }
3549 else
3550 {
3551 emit_move_insn (operands[2], operands[1]);
3552 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3553 }
3554 emit_move_insn (operands[4], operands[2]);
3555 DONE;
3556 })
3557
3558 ;; Peepholes for the case where the source register does die, after
3559 ;; being split with the above splitter.
3560 (define_peephole2
3561 [(set (match_operand:SI 0 "memory_operand")
3562 (match_operand:SI 1 "register_operand"))
3563 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3564 (parallel [(set (match_dup 2)
3565 (ashiftrt:SI (match_dup 2) (const_int 31)))
3566 (clobber (reg:CC FLAGS_REG))])
3567 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3568 "REGNO (operands[1]) != REGNO (operands[2])
3569 && peep2_reg_dead_p (2, operands[1])
3570 && peep2_reg_dead_p (4, operands[2])
3571 && !reg_mentioned_p (operands[2], operands[3])"
3572 [(set (match_dup 0) (match_dup 1))
3573 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3574 (clobber (reg:CC FLAGS_REG))])
3575 (set (match_dup 3) (match_dup 1))])
3576
3577 (define_peephole2
3578 [(set (match_operand:SI 0 "memory_operand")
3579 (match_operand:SI 1 "register_operand"))
3580 (parallel [(set (match_operand:SI 2 "register_operand")
3581 (ashiftrt:SI (match_dup 1) (const_int 31)))
3582 (clobber (reg:CC FLAGS_REG))])
3583 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3584 "/* cltd is shorter than sarl $31, %eax */
3585 !optimize_function_for_size_p (cfun)
3586 && true_regnum (operands[1]) == AX_REG
3587 && true_regnum (operands[2]) == DX_REG
3588 && peep2_reg_dead_p (2, operands[1])
3589 && peep2_reg_dead_p (3, operands[2])
3590 && !reg_mentioned_p (operands[2], operands[3])"
3591 [(set (match_dup 0) (match_dup 1))
3592 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3593 (clobber (reg:CC FLAGS_REG))])
3594 (set (match_dup 3) (match_dup 1))])
3595
3596 ;; Extend to register case. Optimize case where source and destination
3597 ;; registers match and cases where we can use cltd.
3598 (define_split
3599 [(set (match_operand:DI 0 "register_operand")
3600 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3601 (clobber (reg:CC FLAGS_REG))
3602 (clobber (match_scratch:SI 2))]
3603 "reload_completed"
3604 [(const_int 0)]
3605 {
3606 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3607
3608 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3609 emit_move_insn (operands[3], operands[1]);
3610
3611 /* Generate a cltd if possible and doing so it profitable. */
3612 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3613 && true_regnum (operands[3]) == AX_REG
3614 && true_regnum (operands[4]) == DX_REG)
3615 {
3616 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3617 DONE;
3618 }
3619
3620 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3621 emit_move_insn (operands[4], operands[1]);
3622
3623 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3624 DONE;
3625 })
3626
3627 (define_insn "extend<mode>di2"
3628 [(set (match_operand:DI 0 "register_operand" "=r")
3629 (sign_extend:DI
3630 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3631 "TARGET_64BIT"
3632 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "DI")])
3635
3636 (define_insn "extendhisi2"
3637 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3638 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3639 ""
3640 {
3641 switch (get_attr_prefix_0f (insn))
3642 {
3643 case 0:
3644 return "{cwtl|cwde}";
3645 default:
3646 return "movs{wl|x}\t{%1, %0|%0, %1}";
3647 }
3648 }
3649 [(set_attr "type" "imovx")
3650 (set_attr "mode" "SI")
3651 (set (attr "prefix_0f")
3652 ;; movsx is short decodable while cwtl is vector decoded.
3653 (if_then_else (and (eq_attr "cpu" "!k6")
3654 (eq_attr "alternative" "0"))
3655 (const_string "0")
3656 (const_string "1")))
3657 (set (attr "modrm")
3658 (if_then_else (eq_attr "prefix_0f" "0")
3659 (const_string "0")
3660 (const_string "1")))])
3661
3662 (define_insn "*extendhisi2_zext"
3663 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3664 (zero_extend:DI
3665 (sign_extend:SI
3666 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3667 "TARGET_64BIT"
3668 {
3669 switch (get_attr_prefix_0f (insn))
3670 {
3671 case 0:
3672 return "{cwtl|cwde}";
3673 default:
3674 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3675 }
3676 }
3677 [(set_attr "type" "imovx")
3678 (set_attr "mode" "SI")
3679 (set (attr "prefix_0f")
3680 ;; movsx is short decodable while cwtl is vector decoded.
3681 (if_then_else (and (eq_attr "cpu" "!k6")
3682 (eq_attr "alternative" "0"))
3683 (const_string "0")
3684 (const_string "1")))
3685 (set (attr "modrm")
3686 (if_then_else (eq_attr "prefix_0f" "0")
3687 (const_string "0")
3688 (const_string "1")))])
3689
3690 (define_insn "extendqisi2"
3691 [(set (match_operand:SI 0 "register_operand" "=r")
3692 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3693 ""
3694 "movs{bl|x}\t{%1, %0|%0, %1}"
3695 [(set_attr "type" "imovx")
3696 (set_attr "mode" "SI")])
3697
3698 (define_insn "*extendqisi2_zext"
3699 [(set (match_operand:DI 0 "register_operand" "=r")
3700 (zero_extend:DI
3701 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3702 "TARGET_64BIT"
3703 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3704 [(set_attr "type" "imovx")
3705 (set_attr "mode" "SI")])
3706
3707 (define_insn "extendqihi2"
3708 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3709 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3710 ""
3711 {
3712 switch (get_attr_prefix_0f (insn))
3713 {
3714 case 0:
3715 return "{cbtw|cbw}";
3716 default:
3717 return "movs{bw|x}\t{%1, %0|%0, %1}";
3718 }
3719 }
3720 [(set_attr "type" "imovx")
3721 (set_attr "mode" "HI")
3722 (set (attr "prefix_0f")
3723 ;; movsx is short decodable while cwtl is vector decoded.
3724 (if_then_else (and (eq_attr "cpu" "!k6")
3725 (eq_attr "alternative" "0"))
3726 (const_string "0")
3727 (const_string "1")))
3728 (set (attr "modrm")
3729 (if_then_else (eq_attr "prefix_0f" "0")
3730 (const_string "0")
3731 (const_string "1")))])
3732 \f
3733 ;; Conversions between float and double.
3734
3735 ;; These are all no-ops in the model used for the 80387.
3736 ;; So just emit moves.
3737
3738 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3739 (define_split
3740 [(set (match_operand:DF 0 "push_operand")
3741 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3742 "reload_completed"
3743 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3744 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3745
3746 (define_split
3747 [(set (match_operand:XF 0 "push_operand")
3748 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3749 "reload_completed"
3750 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3751 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3752 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3753
3754 (define_expand "extendsfdf2"
3755 [(set (match_operand:DF 0 "nonimmediate_operand")
3756 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3757 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3758 {
3759 /* ??? Needed for compress_float_constant since all fp constants
3760 are TARGET_LEGITIMATE_CONSTANT_P. */
3761 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3762 {
3763 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3764 && standard_80387_constant_p (operands[1]) > 0)
3765 {
3766 operands[1] = simplify_const_unary_operation
3767 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3768 emit_move_insn_1 (operands[0], operands[1]);
3769 DONE;
3770 }
3771 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3772 }
3773 })
3774
3775 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3776 cvtss2sd:
3777 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3778 cvtps2pd xmm2,xmm1
3779 We do the conversion post reload to avoid producing of 128bit spills
3780 that might lead to ICE on 32bit target. The sequence unlikely combine
3781 anyway. */
3782 (define_split
3783 [(set (match_operand:DF 0 "register_operand")
3784 (float_extend:DF
3785 (match_operand:SF 1 "nonimmediate_operand")))]
3786 "TARGET_USE_VECTOR_FP_CONVERTS
3787 && optimize_insn_for_speed_p ()
3788 && reload_completed && SSE_REG_P (operands[0])"
3789 [(set (match_dup 2)
3790 (float_extend:V2DF
3791 (vec_select:V2SF
3792 (match_dup 3)
3793 (parallel [(const_int 0) (const_int 1)]))))]
3794 {
3795 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3796 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3797 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3798 Try to avoid move when unpacking can be done in source. */
3799 if (REG_P (operands[1]))
3800 {
3801 /* If it is unsafe to overwrite upper half of source, we need
3802 to move to destination and unpack there. */
3803 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3804 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3805 && true_regnum (operands[0]) != true_regnum (operands[1]))
3806 {
3807 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3808 emit_move_insn (tmp, operands[1]);
3809 }
3810 else
3811 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3812 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3813 operands[3]));
3814 }
3815 else
3816 emit_insn (gen_vec_setv4sf_0 (operands[3],
3817 CONST0_RTX (V4SFmode), operands[1]));
3818 })
3819
3820 ;; It's more profitable to split and then extend in the same register.
3821 (define_peephole2
3822 [(set (match_operand:DF 0 "register_operand")
3823 (float_extend:DF
3824 (match_operand:SF 1 "memory_operand")))]
3825 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3826 && optimize_insn_for_speed_p ()
3827 && SSE_REG_P (operands[0])"
3828 [(set (match_dup 2) (match_dup 1))
3829 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3830 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3831
3832 (define_insn "*extendsfdf2_mixed"
3833 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3834 (float_extend:DF
3835 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3836 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3837 {
3838 switch (which_alternative)
3839 {
3840 case 0:
3841 case 1:
3842 return output_387_reg_move (insn, operands);
3843
3844 case 2:
3845 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3846
3847 default:
3848 gcc_unreachable ();
3849 }
3850 }
3851 [(set_attr "type" "fmov,fmov,ssecvt")
3852 (set_attr "prefix" "orig,orig,maybe_vex")
3853 (set_attr "mode" "SF,XF,DF")])
3854
3855 (define_insn "*extendsfdf2_sse"
3856 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3857 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3858 "TARGET_SSE2 && TARGET_SSE_MATH"
3859 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3860 [(set_attr "type" "ssecvt")
3861 (set_attr "prefix" "maybe_vex")
3862 (set_attr "mode" "DF")])
3863
3864 (define_insn "*extendsfdf2_i387"
3865 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3866 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3867 "TARGET_80387"
3868 "* return output_387_reg_move (insn, operands);"
3869 [(set_attr "type" "fmov")
3870 (set_attr "mode" "SF,XF")])
3871
3872 (define_expand "extend<mode>xf2"
3873 [(set (match_operand:XF 0 "nonimmediate_operand")
3874 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3875 "TARGET_80387"
3876 {
3877 /* ??? Needed for compress_float_constant since all fp constants
3878 are TARGET_LEGITIMATE_CONSTANT_P. */
3879 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3880 {
3881 if (standard_80387_constant_p (operands[1]) > 0)
3882 {
3883 operands[1] = simplify_const_unary_operation
3884 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3885 emit_move_insn_1 (operands[0], operands[1]);
3886 DONE;
3887 }
3888 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3889 }
3890 })
3891
3892 (define_insn "*extend<mode>xf2_i387"
3893 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3894 (float_extend:XF
3895 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3896 "TARGET_80387"
3897 "* return output_387_reg_move (insn, operands);"
3898 [(set_attr "type" "fmov")
3899 (set_attr "mode" "<MODE>,XF")])
3900
3901 ;; %%% This seems bad bad news.
3902 ;; This cannot output into an f-reg because there is no way to be sure
3903 ;; of truncating in that case. Otherwise this is just like a simple move
3904 ;; insn. So we pretend we can output to a reg in order to get better
3905 ;; register preferencing, but we really use a stack slot.
3906
3907 ;; Conversion from DFmode to SFmode.
3908
3909 (define_expand "truncdfsf2"
3910 [(set (match_operand:SF 0 "nonimmediate_operand")
3911 (float_truncate:SF
3912 (match_operand:DF 1 "nonimmediate_operand")))]
3913 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3914 {
3915 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3916 ;
3917 else if (flag_unsafe_math_optimizations)
3918 ;
3919 else
3920 {
3921 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3922 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3923 DONE;
3924 }
3925 })
3926
3927 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3928 cvtsd2ss:
3929 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3930 cvtpd2ps xmm2,xmm1
3931 We do the conversion post reload to avoid producing of 128bit spills
3932 that might lead to ICE on 32bit target. The sequence unlikely combine
3933 anyway. */
3934 (define_split
3935 [(set (match_operand:SF 0 "register_operand")
3936 (float_truncate:SF
3937 (match_operand:DF 1 "nonimmediate_operand")))]
3938 "TARGET_USE_VECTOR_FP_CONVERTS
3939 && optimize_insn_for_speed_p ()
3940 && reload_completed && SSE_REG_P (operands[0])"
3941 [(set (match_dup 2)
3942 (vec_concat:V4SF
3943 (float_truncate:V2SF
3944 (match_dup 4))
3945 (match_dup 3)))]
3946 {
3947 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3948 operands[3] = CONST0_RTX (V2SFmode);
3949 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3950 /* Use movsd for loading from memory, unpcklpd for registers.
3951 Try to avoid move when unpacking can be done in source, or SSE3
3952 movddup is available. */
3953 if (REG_P (operands[1]))
3954 {
3955 if (!TARGET_SSE3
3956 && true_regnum (operands[0]) != true_regnum (operands[1])
3957 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3958 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3959 {
3960 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3961 emit_move_insn (tmp, operands[1]);
3962 operands[1] = tmp;
3963 }
3964 else if (!TARGET_SSE3)
3965 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3966 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3967 }
3968 else
3969 emit_insn (gen_sse2_loadlpd (operands[4],
3970 CONST0_RTX (V2DFmode), operands[1]));
3971 })
3972
3973 ;; It's more profitable to split and then extend in the same register.
3974 (define_peephole2
3975 [(set (match_operand:SF 0 "register_operand")
3976 (float_truncate:SF
3977 (match_operand:DF 1 "memory_operand")))]
3978 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3979 && optimize_insn_for_speed_p ()
3980 && SSE_REG_P (operands[0])"
3981 [(set (match_dup 2) (match_dup 1))
3982 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3983 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3984
3985 (define_expand "truncdfsf2_with_temp"
3986 [(parallel [(set (match_operand:SF 0)
3987 (float_truncate:SF (match_operand:DF 1)))
3988 (clobber (match_operand:SF 2))])])
3989
3990 (define_insn "*truncdfsf_fast_mixed"
3991 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3992 (float_truncate:SF
3993 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3994 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3995 {
3996 switch (which_alternative)
3997 {
3998 case 0:
3999 return output_387_reg_move (insn, operands);
4000 case 1:
4001 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4002 default:
4003 gcc_unreachable ();
4004 }
4005 }
4006 [(set_attr "type" "fmov,ssecvt")
4007 (set_attr "prefix" "orig,maybe_vex")
4008 (set_attr "mode" "SF")])
4009
4010 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4011 ;; because nothing we do here is unsafe.
4012 (define_insn "*truncdfsf_fast_sse"
4013 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4014 (float_truncate:SF
4015 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4016 "TARGET_SSE2 && TARGET_SSE_MATH"
4017 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4018 [(set_attr "type" "ssecvt")
4019 (set_attr "prefix" "maybe_vex")
4020 (set_attr "mode" "SF")])
4021
4022 (define_insn "*truncdfsf_fast_i387"
4023 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4024 (float_truncate:SF
4025 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4026 "TARGET_80387 && flag_unsafe_math_optimizations"
4027 "* return output_387_reg_move (insn, operands);"
4028 [(set_attr "type" "fmov")
4029 (set_attr "mode" "SF")])
4030
4031 (define_insn "*truncdfsf_mixed"
4032 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4033 (float_truncate:SF
4034 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4035 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4036 "TARGET_MIX_SSE_I387"
4037 {
4038 switch (which_alternative)
4039 {
4040 case 0:
4041 return output_387_reg_move (insn, operands);
4042 case 1:
4043 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4044
4045 default:
4046 return "#";
4047 }
4048 }
4049 [(set_attr "isa" "*,sse2,*,*,*")
4050 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4051 (set_attr "unit" "*,*,i387,i387,i387")
4052 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4053 (set_attr "mode" "SF")])
4054
4055 (define_insn "*truncdfsf_i387"
4056 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4057 (float_truncate:SF
4058 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4059 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4060 "TARGET_80387"
4061 {
4062 switch (which_alternative)
4063 {
4064 case 0:
4065 return output_387_reg_move (insn, operands);
4066
4067 default:
4068 return "#";
4069 }
4070 }
4071 [(set_attr "type" "fmov,multi,multi,multi")
4072 (set_attr "unit" "*,i387,i387,i387")
4073 (set_attr "mode" "SF")])
4074
4075 (define_insn "*truncdfsf2_i387_1"
4076 [(set (match_operand:SF 0 "memory_operand" "=m")
4077 (float_truncate:SF
4078 (match_operand:DF 1 "register_operand" "f")))]
4079 "TARGET_80387
4080 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4081 && !TARGET_MIX_SSE_I387"
4082 "* return output_387_reg_move (insn, operands);"
4083 [(set_attr "type" "fmov")
4084 (set_attr "mode" "SF")])
4085
4086 (define_split
4087 [(set (match_operand:SF 0 "register_operand")
4088 (float_truncate:SF
4089 (match_operand:DF 1 "fp_register_operand")))
4090 (clobber (match_operand 2))]
4091 "reload_completed"
4092 [(set (match_dup 2) (match_dup 1))
4093 (set (match_dup 0) (match_dup 2))]
4094 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4095
4096 ;; Conversion from XFmode to {SF,DF}mode
4097
4098 (define_expand "truncxf<mode>2"
4099 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4100 (float_truncate:MODEF
4101 (match_operand:XF 1 "register_operand")))
4102 (clobber (match_dup 2))])]
4103 "TARGET_80387"
4104 {
4105 if (flag_unsafe_math_optimizations)
4106 {
4107 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4108 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4109 if (reg != operands[0])
4110 emit_move_insn (operands[0], reg);
4111 DONE;
4112 }
4113 else
4114 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4115 })
4116
4117 (define_insn "*truncxfsf2_mixed"
4118 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4119 (float_truncate:SF
4120 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4121 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4122 "TARGET_80387"
4123 {
4124 gcc_assert (!which_alternative);
4125 return output_387_reg_move (insn, operands);
4126 }
4127 [(set_attr "type" "fmov,multi,multi,multi")
4128 (set_attr "unit" "*,i387,i387,i387")
4129 (set_attr "mode" "SF")])
4130
4131 (define_insn "*truncxfdf2_mixed"
4132 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4133 (float_truncate:DF
4134 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4135 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4136 "TARGET_80387"
4137 {
4138 gcc_assert (!which_alternative);
4139 return output_387_reg_move (insn, operands);
4140 }
4141 [(set_attr "isa" "*,*,sse2,*")
4142 (set_attr "type" "fmov,multi,multi,multi")
4143 (set_attr "unit" "*,i387,i387,i387")
4144 (set_attr "mode" "DF")])
4145
4146 (define_insn "truncxf<mode>2_i387_noop"
4147 [(set (match_operand:MODEF 0 "register_operand" "=f")
4148 (float_truncate:MODEF
4149 (match_operand:XF 1 "register_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" "<MODE>")])
4154
4155 (define_insn "*truncxf<mode>2_i387"
4156 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4157 (float_truncate:MODEF
4158 (match_operand:XF 1 "register_operand" "f")))]
4159 "TARGET_80387"
4160 "* return output_387_reg_move (insn, operands);"
4161 [(set_attr "type" "fmov")
4162 (set_attr "mode" "<MODE>")])
4163
4164 (define_split
4165 [(set (match_operand:MODEF 0 "register_operand")
4166 (float_truncate:MODEF
4167 (match_operand:XF 1 "register_operand")))
4168 (clobber (match_operand:MODEF 2 "memory_operand"))]
4169 "TARGET_80387 && reload_completed"
4170 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4171 (set (match_dup 0) (match_dup 2))])
4172
4173 (define_split
4174 [(set (match_operand:MODEF 0 "memory_operand")
4175 (float_truncate:MODEF
4176 (match_operand:XF 1 "register_operand")))
4177 (clobber (match_operand:MODEF 2 "memory_operand"))]
4178 "TARGET_80387"
4179 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4180 \f
4181 ;; Signed conversion to DImode.
4182
4183 (define_expand "fix_truncxfdi2"
4184 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4185 (fix:DI (match_operand:XF 1 "register_operand")))
4186 (clobber (reg:CC FLAGS_REG))])]
4187 "TARGET_80387"
4188 {
4189 if (TARGET_FISTTP)
4190 {
4191 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4192 DONE;
4193 }
4194 })
4195
4196 (define_expand "fix_trunc<mode>di2"
4197 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4198 (fix:DI (match_operand:MODEF 1 "register_operand")))
4199 (clobber (reg:CC FLAGS_REG))])]
4200 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4201 {
4202 if (TARGET_FISTTP
4203 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4204 {
4205 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4206 DONE;
4207 }
4208 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4209 {
4210 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4211 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4212 if (out != operands[0])
4213 emit_move_insn (operands[0], out);
4214 DONE;
4215 }
4216 })
4217
4218 ;; Signed conversion to SImode.
4219
4220 (define_expand "fix_truncxfsi2"
4221 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4222 (fix:SI (match_operand:XF 1 "register_operand")))
4223 (clobber (reg:CC FLAGS_REG))])]
4224 "TARGET_80387"
4225 {
4226 if (TARGET_FISTTP)
4227 {
4228 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4229 DONE;
4230 }
4231 })
4232
4233 (define_expand "fix_trunc<mode>si2"
4234 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4235 (fix:SI (match_operand:MODEF 1 "register_operand")))
4236 (clobber (reg:CC FLAGS_REG))])]
4237 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4238 {
4239 if (TARGET_FISTTP
4240 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4241 {
4242 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4243 DONE;
4244 }
4245 if (SSE_FLOAT_MODE_P (<MODE>mode))
4246 {
4247 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4248 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4249 if (out != operands[0])
4250 emit_move_insn (operands[0], out);
4251 DONE;
4252 }
4253 })
4254
4255 ;; Signed conversion to HImode.
4256
4257 (define_expand "fix_trunc<mode>hi2"
4258 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4259 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4260 (clobber (reg:CC FLAGS_REG))])]
4261 "TARGET_80387
4262 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4263 {
4264 if (TARGET_FISTTP)
4265 {
4266 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4267 DONE;
4268 }
4269 })
4270
4271 ;; Unsigned conversion to SImode.
4272
4273 (define_expand "fixuns_trunc<mode>si2"
4274 [(parallel
4275 [(set (match_operand:SI 0 "register_operand")
4276 (unsigned_fix:SI
4277 (match_operand:MODEF 1 "nonimmediate_operand")))
4278 (use (match_dup 2))
4279 (clobber (match_scratch:<ssevecmode> 3))
4280 (clobber (match_scratch:<ssevecmode> 4))])]
4281 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4282 {
4283 enum machine_mode mode = <MODE>mode;
4284 enum machine_mode vecmode = <ssevecmode>mode;
4285 REAL_VALUE_TYPE TWO31r;
4286 rtx two31;
4287
4288 if (optimize_insn_for_size_p ())
4289 FAIL;
4290
4291 real_ldexp (&TWO31r, &dconst1, 31);
4292 two31 = const_double_from_real_value (TWO31r, mode);
4293 two31 = ix86_build_const_vector (vecmode, true, two31);
4294 operands[2] = force_reg (vecmode, two31);
4295 })
4296
4297 (define_insn_and_split "*fixuns_trunc<mode>_1"
4298 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4299 (unsigned_fix:SI
4300 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4301 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4302 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4303 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4304 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4305 && optimize_function_for_speed_p (cfun)"
4306 "#"
4307 "&& reload_completed"
4308 [(const_int 0)]
4309 {
4310 ix86_split_convert_uns_si_sse (operands);
4311 DONE;
4312 })
4313
4314 ;; Unsigned conversion to HImode.
4315 ;; Without these patterns, we'll try the unsigned SI conversion which
4316 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4317
4318 (define_expand "fixuns_trunc<mode>hi2"
4319 [(set (match_dup 2)
4320 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4321 (set (match_operand:HI 0 "nonimmediate_operand")
4322 (subreg:HI (match_dup 2) 0))]
4323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4324 "operands[2] = gen_reg_rtx (SImode);")
4325
4326 ;; When SSE is available, it is always faster to use it!
4327 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4328 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4329 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4330 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4331 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4332 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4333 [(set_attr "type" "sseicvt")
4334 (set_attr "prefix" "maybe_vex")
4335 (set (attr "prefix_rex")
4336 (if_then_else
4337 (match_test "<SWI48:MODE>mode == DImode")
4338 (const_string "1")
4339 (const_string "*")))
4340 (set_attr "mode" "<MODEF:MODE>")
4341 (set_attr "athlon_decode" "double,vector")
4342 (set_attr "amdfam10_decode" "double,double")
4343 (set_attr "bdver1_decode" "double,double")])
4344
4345 ;; Avoid vector decoded forms of the instruction.
4346 (define_peephole2
4347 [(match_scratch:MODEF 2 "x")
4348 (set (match_operand:SWI48 0 "register_operand")
4349 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4350 "TARGET_AVOID_VECTOR_DECODE
4351 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4352 && optimize_insn_for_speed_p ()"
4353 [(set (match_dup 2) (match_dup 1))
4354 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4355
4356 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4357 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4358 (fix:SWI248x (match_operand 1 "register_operand")))]
4359 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4360 && TARGET_FISTTP
4361 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4362 && (TARGET_64BIT || <MODE>mode != DImode))
4363 && TARGET_SSE_MATH)
4364 && can_create_pseudo_p ()"
4365 "#"
4366 "&& 1"
4367 [(const_int 0)]
4368 {
4369 if (memory_operand (operands[0], VOIDmode))
4370 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4371 else
4372 {
4373 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4374 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4375 operands[1],
4376 operands[2]));
4377 }
4378 DONE;
4379 }
4380 [(set_attr "type" "fisttp")
4381 (set_attr "mode" "<MODE>")])
4382
4383 (define_insn "fix_trunc<mode>_i387_fisttp"
4384 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4385 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4386 (clobber (match_scratch:XF 2 "=&1f"))]
4387 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4388 && TARGET_FISTTP
4389 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4390 && (TARGET_64BIT || <MODE>mode != DImode))
4391 && TARGET_SSE_MATH)"
4392 "* return output_fix_trunc (insn, operands, true);"
4393 [(set_attr "type" "fisttp")
4394 (set_attr "mode" "<MODE>")])
4395
4396 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4397 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4398 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4399 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4400 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4401 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4402 && TARGET_FISTTP
4403 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4404 && (TARGET_64BIT || <MODE>mode != DImode))
4405 && TARGET_SSE_MATH)"
4406 "#"
4407 [(set_attr "type" "fisttp")
4408 (set_attr "mode" "<MODE>")])
4409
4410 (define_split
4411 [(set (match_operand:SWI248x 0 "register_operand")
4412 (fix:SWI248x (match_operand 1 "register_operand")))
4413 (clobber (match_operand:SWI248x 2 "memory_operand"))
4414 (clobber (match_scratch 3))]
4415 "reload_completed"
4416 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4417 (clobber (match_dup 3))])
4418 (set (match_dup 0) (match_dup 2))])
4419
4420 (define_split
4421 [(set (match_operand:SWI248x 0 "memory_operand")
4422 (fix:SWI248x (match_operand 1 "register_operand")))
4423 (clobber (match_operand:SWI248x 2 "memory_operand"))
4424 (clobber (match_scratch 3))]
4425 "reload_completed"
4426 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4427 (clobber (match_dup 3))])])
4428
4429 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4430 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4431 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4432 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4433 ;; function in i386.c.
4434 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4435 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4436 (fix:SWI248x (match_operand 1 "register_operand")))
4437 (clobber (reg:CC FLAGS_REG))]
4438 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4439 && !TARGET_FISTTP
4440 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4441 && (TARGET_64BIT || <MODE>mode != DImode))
4442 && can_create_pseudo_p ()"
4443 "#"
4444 "&& 1"
4445 [(const_int 0)]
4446 {
4447 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4448
4449 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4450 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4451 if (memory_operand (operands[0], VOIDmode))
4452 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4453 operands[2], operands[3]));
4454 else
4455 {
4456 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4457 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4458 operands[2], operands[3],
4459 operands[4]));
4460 }
4461 DONE;
4462 }
4463 [(set_attr "type" "fistp")
4464 (set_attr "i387_cw" "trunc")
4465 (set_attr "mode" "<MODE>")])
4466
4467 (define_insn "fix_truncdi_i387"
4468 [(set (match_operand:DI 0 "memory_operand" "=m")
4469 (fix:DI (match_operand 1 "register_operand" "f")))
4470 (use (match_operand:HI 2 "memory_operand" "m"))
4471 (use (match_operand:HI 3 "memory_operand" "m"))
4472 (clobber (match_scratch:XF 4 "=&1f"))]
4473 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4474 && !TARGET_FISTTP
4475 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4476 "* return output_fix_trunc (insn, operands, false);"
4477 [(set_attr "type" "fistp")
4478 (set_attr "i387_cw" "trunc")
4479 (set_attr "mode" "DI")])
4480
4481 (define_insn "fix_truncdi_i387_with_temp"
4482 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4483 (fix:DI (match_operand 1 "register_operand" "f,f")))
4484 (use (match_operand:HI 2 "memory_operand" "m,m"))
4485 (use (match_operand:HI 3 "memory_operand" "m,m"))
4486 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4487 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4488 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4489 && !TARGET_FISTTP
4490 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4491 "#"
4492 [(set_attr "type" "fistp")
4493 (set_attr "i387_cw" "trunc")
4494 (set_attr "mode" "DI")])
4495
4496 (define_split
4497 [(set (match_operand:DI 0 "register_operand")
4498 (fix:DI (match_operand 1 "register_operand")))
4499 (use (match_operand:HI 2 "memory_operand"))
4500 (use (match_operand:HI 3 "memory_operand"))
4501 (clobber (match_operand:DI 4 "memory_operand"))
4502 (clobber (match_scratch 5))]
4503 "reload_completed"
4504 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4505 (use (match_dup 2))
4506 (use (match_dup 3))
4507 (clobber (match_dup 5))])
4508 (set (match_dup 0) (match_dup 4))])
4509
4510 (define_split
4511 [(set (match_operand:DI 0 "memory_operand")
4512 (fix:DI (match_operand 1 "register_operand")))
4513 (use (match_operand:HI 2 "memory_operand"))
4514 (use (match_operand:HI 3 "memory_operand"))
4515 (clobber (match_operand:DI 4 "memory_operand"))
4516 (clobber (match_scratch 5))]
4517 "reload_completed"
4518 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4519 (use (match_dup 2))
4520 (use (match_dup 3))
4521 (clobber (match_dup 5))])])
4522
4523 (define_insn "fix_trunc<mode>_i387"
4524 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4525 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4526 (use (match_operand:HI 2 "memory_operand" "m"))
4527 (use (match_operand:HI 3 "memory_operand" "m"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !TARGET_FISTTP
4530 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4531 "* return output_fix_trunc (insn, operands, false);"
4532 [(set_attr "type" "fistp")
4533 (set_attr "i387_cw" "trunc")
4534 (set_attr "mode" "<MODE>")])
4535
4536 (define_insn "fix_trunc<mode>_i387_with_temp"
4537 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4538 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4539 (use (match_operand:HI 2 "memory_operand" "m,m"))
4540 (use (match_operand:HI 3 "memory_operand" "m,m"))
4541 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4542 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543 && !TARGET_FISTTP
4544 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4545 "#"
4546 [(set_attr "type" "fistp")
4547 (set_attr "i387_cw" "trunc")
4548 (set_attr "mode" "<MODE>")])
4549
4550 (define_split
4551 [(set (match_operand:SWI24 0 "register_operand")
4552 (fix:SWI24 (match_operand 1 "register_operand")))
4553 (use (match_operand:HI 2 "memory_operand"))
4554 (use (match_operand:HI 3 "memory_operand"))
4555 (clobber (match_operand:SWI24 4 "memory_operand"))]
4556 "reload_completed"
4557 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4558 (use (match_dup 2))
4559 (use (match_dup 3))])
4560 (set (match_dup 0) (match_dup 4))])
4561
4562 (define_split
4563 [(set (match_operand:SWI24 0 "memory_operand")
4564 (fix:SWI24 (match_operand 1 "register_operand")))
4565 (use (match_operand:HI 2 "memory_operand"))
4566 (use (match_operand:HI 3 "memory_operand"))
4567 (clobber (match_operand:SWI24 4 "memory_operand"))]
4568 "reload_completed"
4569 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4570 (use (match_dup 2))
4571 (use (match_dup 3))])])
4572
4573 (define_insn "x86_fnstcw_1"
4574 [(set (match_operand:HI 0 "memory_operand" "=m")
4575 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4576 "TARGET_80387"
4577 "fnstcw\t%0"
4578 [(set (attr "length")
4579 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4580 (set_attr "mode" "HI")
4581 (set_attr "unit" "i387")
4582 (set_attr "bdver1_decode" "vector")])
4583
4584 (define_insn "x86_fldcw_1"
4585 [(set (reg:HI FPCR_REG)
4586 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4587 "TARGET_80387"
4588 "fldcw\t%0"
4589 [(set (attr "length")
4590 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4591 (set_attr "mode" "HI")
4592 (set_attr "unit" "i387")
4593 (set_attr "athlon_decode" "vector")
4594 (set_attr "amdfam10_decode" "vector")
4595 (set_attr "bdver1_decode" "vector")])
4596 \f
4597 ;; Conversion between fixed point and floating point.
4598
4599 ;; Even though we only accept memory inputs, the backend _really_
4600 ;; wants to be able to do this between registers.
4601
4602 (define_expand "floathi<mode>2"
4603 [(set (match_operand:X87MODEF 0 "register_operand")
4604 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4605 "TARGET_80387
4606 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4607 || TARGET_MIX_SSE_I387)")
4608
4609 ;; Pre-reload splitter to add memory clobber to the pattern.
4610 (define_insn_and_split "*floathi<mode>2_1"
4611 [(set (match_operand:X87MODEF 0 "register_operand")
4612 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4613 "TARGET_80387
4614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4615 || TARGET_MIX_SSE_I387)
4616 && can_create_pseudo_p ()"
4617 "#"
4618 "&& 1"
4619 [(parallel [(set (match_dup 0)
4620 (float:X87MODEF (match_dup 1)))
4621 (clobber (match_dup 2))])]
4622 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4623
4624 (define_insn "*floathi<mode>2_i387_with_temp"
4625 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4626 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4627 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4628 "TARGET_80387
4629 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4630 || TARGET_MIX_SSE_I387)"
4631 "#"
4632 [(set_attr "type" "fmov,multi")
4633 (set_attr "mode" "<MODE>")
4634 (set_attr "unit" "*,i387")
4635 (set_attr "fp_int_src" "true")])
4636
4637 (define_insn "*floathi<mode>2_i387"
4638 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4639 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4640 "TARGET_80387
4641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4642 || TARGET_MIX_SSE_I387)"
4643 "fild%Z1\t%1"
4644 [(set_attr "type" "fmov")
4645 (set_attr "mode" "<MODE>")
4646 (set_attr "fp_int_src" "true")])
4647
4648 (define_split
4649 [(set (match_operand:X87MODEF 0 "register_operand")
4650 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4651 (clobber (match_operand:HI 2 "memory_operand"))]
4652 "TARGET_80387
4653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4654 || TARGET_MIX_SSE_I387)
4655 && reload_completed"
4656 [(set (match_dup 2) (match_dup 1))
4657 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4658
4659 (define_split
4660 [(set (match_operand:X87MODEF 0 "register_operand")
4661 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4662 (clobber (match_operand:HI 2 "memory_operand"))]
4663 "TARGET_80387
4664 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4665 || TARGET_MIX_SSE_I387)
4666 && reload_completed"
4667 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4668
4669 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4670 [(set (match_operand:X87MODEF 0 "register_operand")
4671 (float:X87MODEF
4672 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4673 "TARGET_80387
4674 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4675 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4676 {
4677 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4678 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4679 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4680 {
4681 rtx reg = gen_reg_rtx (XFmode);
4682 rtx (*insn)(rtx, rtx);
4683
4684 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4685
4686 if (<X87MODEF:MODE>mode == SFmode)
4687 insn = gen_truncxfsf2;
4688 else if (<X87MODEF:MODE>mode == DFmode)
4689 insn = gen_truncxfdf2;
4690 else
4691 gcc_unreachable ();
4692
4693 emit_insn (insn (operands[0], reg));
4694 DONE;
4695 }
4696 })
4697
4698 ;; Pre-reload splitter to add memory clobber to the pattern.
4699 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4700 [(set (match_operand:X87MODEF 0 "register_operand")
4701 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4702 "((TARGET_80387
4703 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4704 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4705 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4706 || TARGET_MIX_SSE_I387))
4707 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4708 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4709 && ((<SWI48x:MODE>mode == SImode
4710 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4711 && optimize_function_for_speed_p (cfun)
4712 && flag_trapping_math)
4713 || !(TARGET_INTER_UNIT_CONVERSIONS
4714 || optimize_function_for_size_p (cfun)))))
4715 && can_create_pseudo_p ()"
4716 "#"
4717 "&& 1"
4718 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4719 (clobber (match_dup 2))])]
4720 {
4721 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4722
4723 /* Avoid store forwarding (partial memory) stall penalty
4724 by passing DImode value through XMM registers. */
4725 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4726 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4727 && optimize_function_for_speed_p (cfun))
4728 {
4729 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4730 operands[1],
4731 operands[2]));
4732 DONE;
4733 }
4734 })
4735
4736 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4737 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4738 (float:MODEF
4739 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4740 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4741 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4742 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4743 "#"
4744 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4745 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4746 (set_attr "unit" "*,i387,*,*,*")
4747 (set_attr "athlon_decode" "*,*,double,direct,double")
4748 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4749 (set_attr "bdver1_decode" "*,*,double,direct,double")
4750 (set_attr "fp_int_src" "true")])
4751
4752 (define_insn "*floatsi<mode>2_vector_mixed"
4753 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4754 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4755 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4756 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4757 "@
4758 fild%Z1\t%1
4759 #"
4760 [(set_attr "type" "fmov,sseicvt")
4761 (set_attr "mode" "<MODE>,<ssevecmode>")
4762 (set_attr "unit" "i387,*")
4763 (set_attr "athlon_decode" "*,direct")
4764 (set_attr "amdfam10_decode" "*,double")
4765 (set_attr "bdver1_decode" "*,direct")
4766 (set_attr "fp_int_src" "true")])
4767
4768 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4769 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4770 (float:MODEF
4771 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4772 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4773 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4774 "#"
4775 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4776 (set_attr "mode" "<MODEF:MODE>")
4777 (set_attr "unit" "*,i387,*,*")
4778 (set_attr "athlon_decode" "*,*,double,direct")
4779 (set_attr "amdfam10_decode" "*,*,vector,double")
4780 (set_attr "bdver1_decode" "*,*,double,direct")
4781 (set_attr "fp_int_src" "true")])
4782
4783 (define_split
4784 [(set (match_operand:MODEF 0 "register_operand")
4785 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4786 (clobber (match_operand:SWI48 2 "memory_operand"))]
4787 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4788 && TARGET_INTER_UNIT_CONVERSIONS
4789 && reload_completed && SSE_REG_P (operands[0])"
4790 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4791
4792 (define_split
4793 [(set (match_operand:MODEF 0 "register_operand")
4794 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4795 (clobber (match_operand:SWI48 2 "memory_operand"))]
4796 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4797 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4798 && reload_completed && SSE_REG_P (operands[0])"
4799 [(set (match_dup 2) (match_dup 1))
4800 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4801
4802 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4803 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4804 (float:MODEF
4805 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4806 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4807 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4808 "@
4809 fild%Z1\t%1
4810 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4811 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4812 [(set_attr "type" "fmov,sseicvt,sseicvt")
4813 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4814 (set_attr "mode" "<MODEF:MODE>")
4815 (set (attr "prefix_rex")
4816 (if_then_else
4817 (and (eq_attr "prefix" "maybe_vex")
4818 (match_test "<SWI48:MODE>mode == DImode"))
4819 (const_string "1")
4820 (const_string "*")))
4821 (set_attr "unit" "i387,*,*")
4822 (set_attr "athlon_decode" "*,double,direct")
4823 (set_attr "amdfam10_decode" "*,vector,double")
4824 (set_attr "bdver1_decode" "*,double,direct")
4825 (set_attr "fp_int_src" "true")])
4826
4827 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4828 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4829 (float:MODEF
4830 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4831 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4832 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4833 "@
4834 fild%Z1\t%1
4835 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4836 [(set_attr "type" "fmov,sseicvt")
4837 (set_attr "prefix" "orig,maybe_vex")
4838 (set_attr "mode" "<MODEF:MODE>")
4839 (set (attr "prefix_rex")
4840 (if_then_else
4841 (and (eq_attr "prefix" "maybe_vex")
4842 (match_test "<SWI48:MODE>mode == DImode"))
4843 (const_string "1")
4844 (const_string "*")))
4845 (set_attr "athlon_decode" "*,direct")
4846 (set_attr "amdfam10_decode" "*,double")
4847 (set_attr "bdver1_decode" "*,direct")
4848 (set_attr "fp_int_src" "true")])
4849
4850 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4851 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4852 (float:MODEF
4853 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4854 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4855 "TARGET_SSE2 && TARGET_SSE_MATH
4856 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4857 "#"
4858 [(set_attr "type" "sseicvt")
4859 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4860 (set_attr "athlon_decode" "double,direct,double")
4861 (set_attr "amdfam10_decode" "vector,double,double")
4862 (set_attr "bdver1_decode" "double,direct,double")
4863 (set_attr "fp_int_src" "true")])
4864
4865 (define_insn "*floatsi<mode>2_vector_sse"
4866 [(set (match_operand:MODEF 0 "register_operand" "=x")
4867 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4868 "TARGET_SSE2 && TARGET_SSE_MATH
4869 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4870 "#"
4871 [(set_attr "type" "sseicvt")
4872 (set_attr "mode" "<MODE>")
4873 (set_attr "athlon_decode" "direct")
4874 (set_attr "amdfam10_decode" "double")
4875 (set_attr "bdver1_decode" "direct")
4876 (set_attr "fp_int_src" "true")])
4877
4878 (define_split
4879 [(set (match_operand:MODEF 0 "register_operand")
4880 (float:MODEF (match_operand:SI 1 "register_operand")))
4881 (clobber (match_operand:SI 2 "memory_operand"))]
4882 "TARGET_SSE2 && TARGET_SSE_MATH
4883 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4884 && reload_completed && SSE_REG_P (operands[0])"
4885 [(const_int 0)]
4886 {
4887 rtx op1 = operands[1];
4888
4889 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4890 <MODE>mode, 0);
4891 if (GET_CODE (op1) == SUBREG)
4892 op1 = SUBREG_REG (op1);
4893
4894 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4895 {
4896 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4897 emit_insn (gen_sse2_loadld (operands[4],
4898 CONST0_RTX (V4SImode), operands[1]));
4899 }
4900 /* We can ignore possible trapping value in the
4901 high part of SSE register for non-trapping math. */
4902 else if (SSE_REG_P (op1) && !flag_trapping_math)
4903 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4904 else
4905 {
4906 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4907 emit_move_insn (operands[2], operands[1]);
4908 emit_insn (gen_sse2_loadld (operands[4],
4909 CONST0_RTX (V4SImode), operands[2]));
4910 }
4911 if (<ssevecmode>mode == V4SFmode)
4912 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4913 else
4914 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4915 DONE;
4916 })
4917
4918 (define_split
4919 [(set (match_operand:MODEF 0 "register_operand")
4920 (float:MODEF (match_operand:SI 1 "memory_operand")))
4921 (clobber (match_operand:SI 2 "memory_operand"))]
4922 "TARGET_SSE2 && TARGET_SSE_MATH
4923 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4924 && reload_completed && SSE_REG_P (operands[0])"
4925 [(const_int 0)]
4926 {
4927 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4928 <MODE>mode, 0);
4929 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4930
4931 emit_insn (gen_sse2_loadld (operands[4],
4932 CONST0_RTX (V4SImode), operands[1]));
4933 if (<ssevecmode>mode == V4SFmode)
4934 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4935 else
4936 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4937 DONE;
4938 })
4939
4940 (define_split
4941 [(set (match_operand:MODEF 0 "register_operand")
4942 (float:MODEF (match_operand:SI 1 "register_operand")))]
4943 "TARGET_SSE2 && TARGET_SSE_MATH
4944 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4945 && reload_completed && SSE_REG_P (operands[0])"
4946 [(const_int 0)]
4947 {
4948 rtx op1 = operands[1];
4949
4950 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4951 <MODE>mode, 0);
4952 if (GET_CODE (op1) == SUBREG)
4953 op1 = SUBREG_REG (op1);
4954
4955 if (GENERAL_REG_P (op1))
4956 {
4957 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4958 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4959 emit_insn (gen_sse2_loadld (operands[4],
4960 CONST0_RTX (V4SImode), operands[1]));
4961 else
4962 {
4963 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4964 operands[1]);
4965 emit_insn (gen_sse2_loadld (operands[4],
4966 CONST0_RTX (V4SImode), operands[5]));
4967 ix86_free_from_memory (GET_MODE (operands[1]));
4968 }
4969 }
4970 /* We can ignore possible trapping value in the
4971 high part of SSE register for non-trapping math. */
4972 else if (SSE_REG_P (op1) && !flag_trapping_math)
4973 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4974 else
4975 gcc_unreachable ();
4976 if (<ssevecmode>mode == V4SFmode)
4977 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4978 else
4979 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4980 DONE;
4981 })
4982
4983 (define_split
4984 [(set (match_operand:MODEF 0 "register_operand")
4985 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4986 "TARGET_SSE2 && TARGET_SSE_MATH
4987 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4988 && reload_completed && SSE_REG_P (operands[0])"
4989 [(const_int 0)]
4990 {
4991 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4992 <MODE>mode, 0);
4993 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4994
4995 emit_insn (gen_sse2_loadld (operands[4],
4996 CONST0_RTX (V4SImode), operands[1]));
4997 if (<ssevecmode>mode == V4SFmode)
4998 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4999 else
5000 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5001 DONE;
5002 })
5003
5004 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5005 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5006 (float:MODEF
5007 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5008 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5009 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5010 "#"
5011 [(set_attr "type" "sseicvt")
5012 (set_attr "mode" "<MODEF:MODE>")
5013 (set_attr "athlon_decode" "double,direct")
5014 (set_attr "amdfam10_decode" "vector,double")
5015 (set_attr "bdver1_decode" "double,direct")
5016 (set_attr "btver2_decode" "double,double")
5017 (set_attr "fp_int_src" "true")])
5018
5019 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5020 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5021 (float:MODEF
5022 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5023 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5024 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5025 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5026 [(set_attr "type" "sseicvt")
5027 (set_attr "prefix" "maybe_vex")
5028 (set_attr "mode" "<MODEF:MODE>")
5029 (set (attr "prefix_rex")
5030 (if_then_else
5031 (and (eq_attr "prefix" "maybe_vex")
5032 (match_test "<SWI48:MODE>mode == DImode"))
5033 (const_string "1")
5034 (const_string "*")))
5035 (set_attr "athlon_decode" "double,direct")
5036 (set_attr "amdfam10_decode" "vector,double")
5037 (set_attr "bdver1_decode" "double,direct")
5038 (set_attr "btver2_decode" "double,double")
5039 (set_attr "fp_int_src" "true")])
5040
5041 (define_split
5042 [(set (match_operand:MODEF 0 "register_operand")
5043 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5044 (clobber (match_operand:SWI48 2 "memory_operand"))]
5045 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5046 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5047 && reload_completed && SSE_REG_P (operands[0])"
5048 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5049
5050 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5051 [(set (match_operand:MODEF 0 "register_operand" "=x")
5052 (float:MODEF
5053 (match_operand:SWI48 1 "memory_operand" "m")))]
5054 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5055 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5056 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5057 [(set_attr "type" "sseicvt")
5058 (set_attr "prefix" "maybe_vex")
5059 (set_attr "mode" "<MODEF:MODE>")
5060 (set (attr "prefix_rex")
5061 (if_then_else
5062 (and (eq_attr "prefix" "maybe_vex")
5063 (match_test "<SWI48:MODE>mode == DImode"))
5064 (const_string "1")
5065 (const_string "*")))
5066 (set_attr "athlon_decode" "direct")
5067 (set_attr "amdfam10_decode" "double")
5068 (set_attr "bdver1_decode" "direct")
5069 (set_attr "fp_int_src" "true")])
5070
5071 (define_split
5072 [(set (match_operand:MODEF 0 "register_operand")
5073 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5074 (clobber (match_operand:SWI48 2 "memory_operand"))]
5075 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5076 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5077 && reload_completed && SSE_REG_P (operands[0])"
5078 [(set (match_dup 2) (match_dup 1))
5079 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5080
5081 (define_split
5082 [(set (match_operand:MODEF 0 "register_operand")
5083 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5084 (clobber (match_operand:SWI48 2 "memory_operand"))]
5085 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5086 && reload_completed && SSE_REG_P (operands[0])"
5087 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5088
5089 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5090 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5091 (float:X87MODEF
5092 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5093 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5094 "TARGET_80387
5095 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5096 "@
5097 fild%Z1\t%1
5098 #"
5099 [(set_attr "type" "fmov,multi")
5100 (set_attr "mode" "<X87MODEF:MODE>")
5101 (set_attr "unit" "*,i387")
5102 (set_attr "fp_int_src" "true")])
5103
5104 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5105 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5106 (float:X87MODEF
5107 (match_operand:SWI48x 1 "memory_operand" "m")))]
5108 "TARGET_80387
5109 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5110 "fild%Z1\t%1"
5111 [(set_attr "type" "fmov")
5112 (set_attr "mode" "<X87MODEF:MODE>")
5113 (set_attr "fp_int_src" "true")])
5114
5115 (define_split
5116 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5117 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5118 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5119 "TARGET_80387
5120 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5121 && reload_completed"
5122 [(set (match_dup 2) (match_dup 1))
5123 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5124
5125 (define_split
5126 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5127 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5128 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5129 "TARGET_80387
5130 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5131 && reload_completed"
5132 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5133
5134 ;; Avoid partial SSE register dependency stalls
5135
5136 (define_split
5137 [(set (match_operand:MODEF 0 "register_operand")
5138 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5139 "TARGET_SSE2 && TARGET_SSE_MATH
5140 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5141 && optimize_function_for_speed_p (cfun)
5142 && reload_completed && SSE_REG_P (operands[0])"
5143 [(set (match_dup 0)
5144 (vec_merge:<ssevecmode>
5145 (vec_duplicate:<ssevecmode>
5146 (float:MODEF (match_dup 1)))
5147 (match_dup 0)
5148 (const_int 1)))]
5149 {
5150 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5151 <MODE>mode, 0);
5152 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5153 })
5154
5155 (define_split
5156 [(set (match_operand:MODEF 0 "register_operand")
5157 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
5158 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5159 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5160 && optimize_function_for_speed_p (cfun)
5161 && reload_completed && SSE_REG_P (operands[0])"
5162 [(set (match_dup 0)
5163 (vec_merge:<ssevecmode>
5164 (vec_duplicate:<ssevecmode>
5165 (float:MODEF (match_dup 1)))
5166 (match_dup 0)
5167 (const_int 1)))]
5168 {
5169 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5170 <MODE>mode, 0);
5171 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
5172 })
5173
5174 ;; Break partial reg stall for cvtsd2ss.
5175
5176 (define_peephole2
5177 [(set (match_operand:SF 0 "register_operand")
5178 (float_truncate:SF
5179 (match_operand:DF 1 "nonimmediate_operand")))]
5180 "TARGET_SSE2 && TARGET_SSE_MATH
5181 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5182 && optimize_function_for_speed_p (cfun)
5183 && SSE_REG_P (operands[0])
5184 && (!SSE_REG_P (operands[1])
5185 || REGNO (operands[0]) != REGNO (operands[1]))"
5186 [(set (match_dup 0)
5187 (vec_merge:V4SF
5188 (vec_duplicate:V4SF
5189 (float_truncate:V2SF
5190 (match_dup 1)))
5191 (match_dup 0)
5192 (const_int 1)))]
5193 {
5194 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5195 SFmode, 0);
5196 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5197 DFmode, 0);
5198 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5199 })
5200
5201 ;; Break partial reg stall for cvtss2sd.
5202
5203 (define_peephole2
5204 [(set (match_operand:DF 0 "register_operand")
5205 (float_extend:DF
5206 (match_operand:SF 1 "nonimmediate_operand")))]
5207 "TARGET_SSE2 && TARGET_SSE_MATH
5208 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5209 && optimize_function_for_speed_p (cfun)
5210 && SSE_REG_P (operands[0])
5211 && (!SSE_REG_P (operands[1])
5212 || REGNO (operands[0]) != REGNO (operands[1]))"
5213 [(set (match_dup 0)
5214 (vec_merge:V2DF
5215 (float_extend:V2DF
5216 (vec_select:V2SF
5217 (match_dup 1)
5218 (parallel [(const_int 0) (const_int 1)])))
5219 (match_dup 0)
5220 (const_int 1)))]
5221 {
5222 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5223 DFmode, 0);
5224 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5225 SFmode, 0);
5226 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5227 })
5228
5229 ;; Avoid store forwarding (partial memory) stall penalty
5230 ;; by passing DImode value through XMM registers. */
5231
5232 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5233 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5234 (float:X87MODEF
5235 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5236 (clobber (match_scratch:V4SI 3 "=X,x"))
5237 (clobber (match_scratch:V4SI 4 "=X,x"))
5238 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5239 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5240 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5241 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5242 "#"
5243 [(set_attr "type" "multi")
5244 (set_attr "mode" "<X87MODEF:MODE>")
5245 (set_attr "unit" "i387")
5246 (set_attr "fp_int_src" "true")])
5247
5248 (define_split
5249 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5250 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5251 (clobber (match_scratch:V4SI 3))
5252 (clobber (match_scratch:V4SI 4))
5253 (clobber (match_operand:DI 2 "memory_operand"))]
5254 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5255 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5256 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5257 && reload_completed"
5258 [(set (match_dup 2) (match_dup 3))
5259 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5260 {
5261 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5262 Assemble the 64-bit DImode value in an xmm register. */
5263 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5264 gen_rtx_SUBREG (SImode, operands[1], 0)));
5265 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5266 gen_rtx_SUBREG (SImode, operands[1], 4)));
5267 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5268 operands[4]));
5269
5270 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5271 })
5272
5273 (define_split
5274 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5275 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5276 (clobber (match_scratch:V4SI 3))
5277 (clobber (match_scratch:V4SI 4))
5278 (clobber (match_operand:DI 2 "memory_operand"))]
5279 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5280 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5281 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5282 && reload_completed"
5283 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5284
5285 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5286 [(set (match_operand:MODEF 0 "register_operand")
5287 (unsigned_float:MODEF
5288 (match_operand:SWI12 1 "nonimmediate_operand")))]
5289 "!TARGET_64BIT
5290 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5291 {
5292 operands[1] = convert_to_mode (SImode, operands[1], 1);
5293 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5294 DONE;
5295 })
5296
5297 ;; Avoid store forwarding (partial memory) stall penalty by extending
5298 ;; SImode value to DImode through XMM register instead of pushing two
5299 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5300 ;; targets benefit from this optimization. Also note that fild
5301 ;; loads from memory only.
5302
5303 (define_insn "*floatunssi<mode>2_1"
5304 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5305 (unsigned_float:X87MODEF
5306 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5307 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5308 (clobber (match_scratch:SI 3 "=X,x"))]
5309 "!TARGET_64BIT
5310 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5311 && TARGET_SSE"
5312 "#"
5313 [(set_attr "type" "multi")
5314 (set_attr "mode" "<MODE>")])
5315
5316 (define_split
5317 [(set (match_operand:X87MODEF 0 "register_operand")
5318 (unsigned_float:X87MODEF
5319 (match_operand:SI 1 "register_operand")))
5320 (clobber (match_operand:DI 2 "memory_operand"))
5321 (clobber (match_scratch:SI 3))]
5322 "!TARGET_64BIT
5323 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5324 && TARGET_SSE
5325 && reload_completed"
5326 [(set (match_dup 2) (match_dup 1))
5327 (set (match_dup 0)
5328 (float:X87MODEF (match_dup 2)))]
5329 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5330
5331 (define_split
5332 [(set (match_operand:X87MODEF 0 "register_operand")
5333 (unsigned_float:X87MODEF
5334 (match_operand:SI 1 "memory_operand")))
5335 (clobber (match_operand:DI 2 "memory_operand"))
5336 (clobber (match_scratch:SI 3))]
5337 "!TARGET_64BIT
5338 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5339 && TARGET_SSE
5340 && reload_completed"
5341 [(set (match_dup 2) (match_dup 3))
5342 (set (match_dup 0)
5343 (float:X87MODEF (match_dup 2)))]
5344 {
5345 emit_move_insn (operands[3], operands[1]);
5346 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5347 })
5348
5349 (define_expand "floatunssi<mode>2"
5350 [(parallel
5351 [(set (match_operand:X87MODEF 0 "register_operand")
5352 (unsigned_float:X87MODEF
5353 (match_operand:SI 1 "nonimmediate_operand")))
5354 (clobber (match_dup 2))
5355 (clobber (match_scratch:SI 3))])]
5356 "!TARGET_64BIT
5357 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5358 && TARGET_SSE)
5359 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5360 {
5361 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5362 {
5363 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5364 DONE;
5365 }
5366 else
5367 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5368 })
5369
5370 (define_expand "floatunsdisf2"
5371 [(use (match_operand:SF 0 "register_operand"))
5372 (use (match_operand:DI 1 "nonimmediate_operand"))]
5373 "TARGET_64BIT && TARGET_SSE_MATH"
5374 "x86_emit_floatuns (operands); DONE;")
5375
5376 (define_expand "floatunsdidf2"
5377 [(use (match_operand:DF 0 "register_operand"))
5378 (use (match_operand:DI 1 "nonimmediate_operand"))]
5379 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5380 && TARGET_SSE2 && TARGET_SSE_MATH"
5381 {
5382 if (TARGET_64BIT)
5383 x86_emit_floatuns (operands);
5384 else
5385 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5386 DONE;
5387 })
5388 \f
5389 ;; Load effective address instructions
5390
5391 (define_insn_and_split "*lea<mode>"
5392 [(set (match_operand:SWI48 0 "register_operand" "=r")
5393 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5394 ""
5395 {
5396 if (SImode_address_operand (operands[1], VOIDmode))
5397 {
5398 gcc_assert (TARGET_64BIT);
5399 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5400 }
5401 else
5402 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5403 }
5404 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5405 [(const_int 0)]
5406 {
5407 enum machine_mode mode = <MODE>mode;
5408 rtx pat;
5409
5410 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5411 change operands[] array behind our back. */
5412 pat = PATTERN (curr_insn);
5413
5414 operands[0] = SET_DEST (pat);
5415 operands[1] = SET_SRC (pat);
5416
5417 /* Emit all operations in SImode for zero-extended addresses. Recall
5418 that x86_64 inheretly zero-extends SImode operations to DImode. */
5419 if (SImode_address_operand (operands[1], VOIDmode))
5420 mode = SImode;
5421
5422 ix86_split_lea_for_addr (curr_insn, operands, mode);
5423 DONE;
5424 }
5425 [(set_attr "type" "lea")
5426 (set (attr "mode")
5427 (if_then_else
5428 (match_operand 1 "SImode_address_operand")
5429 (const_string "SI")
5430 (const_string "<MODE>")))])
5431 \f
5432 ;; Add instructions
5433
5434 (define_expand "add<mode>3"
5435 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5436 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5437 (match_operand:SDWIM 2 "<general_operand>")))]
5438 ""
5439 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5440
5441 (define_insn_and_split "*add<dwi>3_doubleword"
5442 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5443 (plus:<DWI>
5444 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5445 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5446 (clobber (reg:CC FLAGS_REG))]
5447 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5448 "#"
5449 "reload_completed"
5450 [(parallel [(set (reg:CC FLAGS_REG)
5451 (unspec:CC [(match_dup 1) (match_dup 2)]
5452 UNSPEC_ADD_CARRY))
5453 (set (match_dup 0)
5454 (plus:DWIH (match_dup 1) (match_dup 2)))])
5455 (parallel [(set (match_dup 3)
5456 (plus:DWIH
5457 (match_dup 4)
5458 (plus:DWIH
5459 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5460 (match_dup 5))))
5461 (clobber (reg:CC FLAGS_REG))])]
5462 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5463
5464 (define_insn "*add<mode>3_cc"
5465 [(set (reg:CC FLAGS_REG)
5466 (unspec:CC
5467 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5468 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5469 UNSPEC_ADD_CARRY))
5470 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5471 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5472 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5473 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5474 [(set_attr "type" "alu")
5475 (set_attr "mode" "<MODE>")])
5476
5477 (define_insn "addqi3_cc"
5478 [(set (reg:CC FLAGS_REG)
5479 (unspec:CC
5480 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5481 (match_operand:QI 2 "general_operand" "qn,qm")]
5482 UNSPEC_ADD_CARRY))
5483 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5484 (plus:QI (match_dup 1) (match_dup 2)))]
5485 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5486 "add{b}\t{%2, %0|%0, %2}"
5487 [(set_attr "type" "alu")
5488 (set_attr "mode" "QI")])
5489
5490 (define_insn "*add<mode>_1"
5491 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5492 (plus:SWI48
5493 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5494 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5495 (clobber (reg:CC FLAGS_REG))]
5496 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5497 {
5498 switch (get_attr_type (insn))
5499 {
5500 case TYPE_LEA:
5501 return "#";
5502
5503 case TYPE_INCDEC:
5504 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5505 if (operands[2] == const1_rtx)
5506 return "inc{<imodesuffix>}\t%0";
5507 else
5508 {
5509 gcc_assert (operands[2] == constm1_rtx);
5510 return "dec{<imodesuffix>}\t%0";
5511 }
5512
5513 default:
5514 /* For most processors, ADD is faster than LEA. This alternative
5515 was added to use ADD as much as possible. */
5516 if (which_alternative == 2)
5517 {
5518 rtx tmp;
5519 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5520 }
5521
5522 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5523 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5524 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5525
5526 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5527 }
5528 }
5529 [(set (attr "type")
5530 (cond [(eq_attr "alternative" "3")
5531 (const_string "lea")
5532 (match_operand:SWI48 2 "incdec_operand")
5533 (const_string "incdec")
5534 ]
5535 (const_string "alu")))
5536 (set (attr "length_immediate")
5537 (if_then_else
5538 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5539 (const_string "1")
5540 (const_string "*")))
5541 (set_attr "mode" "<MODE>")])
5542
5543 ;; It may seem that nonimmediate operand is proper one for operand 1.
5544 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5545 ;; we take care in ix86_binary_operator_ok to not allow two memory
5546 ;; operands so proper swapping will be done in reload. This allow
5547 ;; patterns constructed from addsi_1 to match.
5548
5549 (define_insn "addsi_1_zext"
5550 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5551 (zero_extend:DI
5552 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5553 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5554 (clobber (reg:CC FLAGS_REG))]
5555 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5556 {
5557 switch (get_attr_type (insn))
5558 {
5559 case TYPE_LEA:
5560 return "#";
5561
5562 case TYPE_INCDEC:
5563 if (operands[2] == const1_rtx)
5564 return "inc{l}\t%k0";
5565 else
5566 {
5567 gcc_assert (operands[2] == constm1_rtx);
5568 return "dec{l}\t%k0";
5569 }
5570
5571 default:
5572 /* For most processors, ADD is faster than LEA. This alternative
5573 was added to use ADD as much as possible. */
5574 if (which_alternative == 1)
5575 {
5576 rtx tmp;
5577 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5578 }
5579
5580 if (x86_maybe_negate_const_int (&operands[2], SImode))
5581 return "sub{l}\t{%2, %k0|%k0, %2}";
5582
5583 return "add{l}\t{%2, %k0|%k0, %2}";
5584 }
5585 }
5586 [(set (attr "type")
5587 (cond [(eq_attr "alternative" "2")
5588 (const_string "lea")
5589 (match_operand:SI 2 "incdec_operand")
5590 (const_string "incdec")
5591 ]
5592 (const_string "alu")))
5593 (set (attr "length_immediate")
5594 (if_then_else
5595 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5596 (const_string "1")
5597 (const_string "*")))
5598 (set_attr "mode" "SI")])
5599
5600 (define_insn "*addhi_1"
5601 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5602 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5603 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5604 (clobber (reg:CC FLAGS_REG))]
5605 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5606 {
5607 switch (get_attr_type (insn))
5608 {
5609 case TYPE_LEA:
5610 return "#";
5611
5612 case TYPE_INCDEC:
5613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614 if (operands[2] == const1_rtx)
5615 return "inc{w}\t%0";
5616 else
5617 {
5618 gcc_assert (operands[2] == constm1_rtx);
5619 return "dec{w}\t%0";
5620 }
5621
5622 default:
5623 /* For most processors, ADD is faster than LEA. This alternative
5624 was added to use ADD as much as possible. */
5625 if (which_alternative == 2)
5626 {
5627 rtx tmp;
5628 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5629 }
5630
5631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632 if (x86_maybe_negate_const_int (&operands[2], HImode))
5633 return "sub{w}\t{%2, %0|%0, %2}";
5634
5635 return "add{w}\t{%2, %0|%0, %2}";
5636 }
5637 }
5638 [(set (attr "type")
5639 (cond [(eq_attr "alternative" "3")
5640 (const_string "lea")
5641 (match_operand:HI 2 "incdec_operand")
5642 (const_string "incdec")
5643 ]
5644 (const_string "alu")))
5645 (set (attr "length_immediate")
5646 (if_then_else
5647 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5648 (const_string "1")
5649 (const_string "*")))
5650 (set_attr "mode" "HI,HI,HI,SI")])
5651
5652 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5653 (define_insn "*addqi_1"
5654 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5655 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5656 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5657 (clobber (reg:CC FLAGS_REG))]
5658 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5659 {
5660 bool widen = (which_alternative == 3 || which_alternative == 4);
5661
5662 switch (get_attr_type (insn))
5663 {
5664 case TYPE_LEA:
5665 return "#";
5666
5667 case TYPE_INCDEC:
5668 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5669 if (operands[2] == const1_rtx)
5670 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5671 else
5672 {
5673 gcc_assert (operands[2] == constm1_rtx);
5674 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5675 }
5676
5677 default:
5678 /* For most processors, ADD is faster than LEA. These alternatives
5679 were added to use ADD as much as possible. */
5680 if (which_alternative == 2 || which_alternative == 4)
5681 {
5682 rtx tmp;
5683 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5684 }
5685
5686 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5687 if (x86_maybe_negate_const_int (&operands[2], QImode))
5688 {
5689 if (widen)
5690 return "sub{l}\t{%2, %k0|%k0, %2}";
5691 else
5692 return "sub{b}\t{%2, %0|%0, %2}";
5693 }
5694 if (widen)
5695 return "add{l}\t{%k2, %k0|%k0, %k2}";
5696 else
5697 return "add{b}\t{%2, %0|%0, %2}";
5698 }
5699 }
5700 [(set (attr "type")
5701 (cond [(eq_attr "alternative" "5")
5702 (const_string "lea")
5703 (match_operand:QI 2 "incdec_operand")
5704 (const_string "incdec")
5705 ]
5706 (const_string "alu")))
5707 (set (attr "length_immediate")
5708 (if_then_else
5709 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5710 (const_string "1")
5711 (const_string "*")))
5712 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5713
5714 (define_insn "*addqi_1_slp"
5715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5716 (plus:QI (match_dup 0)
5717 (match_operand:QI 1 "general_operand" "qn,qm")))
5718 (clobber (reg:CC FLAGS_REG))]
5719 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5720 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5721 {
5722 switch (get_attr_type (insn))
5723 {
5724 case TYPE_INCDEC:
5725 if (operands[1] == const1_rtx)
5726 return "inc{b}\t%0";
5727 else
5728 {
5729 gcc_assert (operands[1] == constm1_rtx);
5730 return "dec{b}\t%0";
5731 }
5732
5733 default:
5734 if (x86_maybe_negate_const_int (&operands[1], QImode))
5735 return "sub{b}\t{%1, %0|%0, %1}";
5736
5737 return "add{b}\t{%1, %0|%0, %1}";
5738 }
5739 }
5740 [(set (attr "type")
5741 (if_then_else (match_operand:QI 1 "incdec_operand")
5742 (const_string "incdec")
5743 (const_string "alu1")))
5744 (set (attr "memory")
5745 (if_then_else (match_operand 1 "memory_operand")
5746 (const_string "load")
5747 (const_string "none")))
5748 (set_attr "mode" "QI")])
5749
5750 ;; Split non destructive adds if we cannot use lea.
5751 (define_split
5752 [(set (match_operand:SWI48 0 "register_operand")
5753 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5754 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5755 (clobber (reg:CC FLAGS_REG))]
5756 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5757 [(set (match_dup 0) (match_dup 1))
5758 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5759 (clobber (reg:CC FLAGS_REG))])])
5760
5761 ;; Convert add to the lea pattern to avoid flags dependency.
5762 (define_split
5763 [(set (match_operand:SWI 0 "register_operand")
5764 (plus:SWI (match_operand:SWI 1 "register_operand")
5765 (match_operand:SWI 2 "<nonmemory_operand>")))
5766 (clobber (reg:CC FLAGS_REG))]
5767 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5768 [(const_int 0)]
5769 {
5770 enum machine_mode mode = <MODE>mode;
5771 rtx pat;
5772
5773 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5774 {
5775 mode = SImode;
5776 operands[0] = gen_lowpart (mode, operands[0]);
5777 operands[1] = gen_lowpart (mode, operands[1]);
5778 operands[2] = gen_lowpart (mode, operands[2]);
5779 }
5780
5781 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5782
5783 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5784 DONE;
5785 })
5786
5787 ;; Split non destructive adds if we cannot use lea.
5788 (define_split
5789 [(set (match_operand:DI 0 "register_operand")
5790 (zero_extend:DI
5791 (plus:SI (match_operand:SI 1 "register_operand")
5792 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5793 (clobber (reg:CC FLAGS_REG))]
5794 "TARGET_64BIT
5795 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5796 [(set (match_dup 3) (match_dup 1))
5797 (parallel [(set (match_dup 0)
5798 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5799 (clobber (reg:CC FLAGS_REG))])]
5800 "operands[3] = gen_lowpart (SImode, operands[0]);")
5801
5802 ;; Convert add to the lea pattern to avoid flags dependency.
5803 (define_split
5804 [(set (match_operand:DI 0 "register_operand")
5805 (zero_extend:DI
5806 (plus:SI (match_operand:SI 1 "register_operand")
5807 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5808 (clobber (reg:CC FLAGS_REG))]
5809 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5810 [(set (match_dup 0)
5811 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5812
5813 (define_insn "*add<mode>_2"
5814 [(set (reg FLAGS_REG)
5815 (compare
5816 (plus:SWI
5817 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5818 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5819 (const_int 0)))
5820 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5821 (plus:SWI (match_dup 1) (match_dup 2)))]
5822 "ix86_match_ccmode (insn, CCGOCmode)
5823 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5824 {
5825 switch (get_attr_type (insn))
5826 {
5827 case TYPE_INCDEC:
5828 if (operands[2] == const1_rtx)
5829 return "inc{<imodesuffix>}\t%0";
5830 else
5831 {
5832 gcc_assert (operands[2] == constm1_rtx);
5833 return "dec{<imodesuffix>}\t%0";
5834 }
5835
5836 default:
5837 if (which_alternative == 2)
5838 {
5839 rtx tmp;
5840 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5841 }
5842
5843 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5844 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5845 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5846
5847 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5848 }
5849 }
5850 [(set (attr "type")
5851 (if_then_else (match_operand:SWI 2 "incdec_operand")
5852 (const_string "incdec")
5853 (const_string "alu")))
5854 (set (attr "length_immediate")
5855 (if_then_else
5856 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5857 (const_string "1")
5858 (const_string "*")))
5859 (set_attr "mode" "<MODE>")])
5860
5861 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5862 (define_insn "*addsi_2_zext"
5863 [(set (reg FLAGS_REG)
5864 (compare
5865 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5866 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5867 (const_int 0)))
5868 (set (match_operand:DI 0 "register_operand" "=r,r")
5869 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5870 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5871 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5872 {
5873 switch (get_attr_type (insn))
5874 {
5875 case TYPE_INCDEC:
5876 if (operands[2] == const1_rtx)
5877 return "inc{l}\t%k0";
5878 else
5879 {
5880 gcc_assert (operands[2] == constm1_rtx);
5881 return "dec{l}\t%k0";
5882 }
5883
5884 default:
5885 if (which_alternative == 1)
5886 {
5887 rtx tmp;
5888 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5889 }
5890
5891 if (x86_maybe_negate_const_int (&operands[2], SImode))
5892 return "sub{l}\t{%2, %k0|%k0, %2}";
5893
5894 return "add{l}\t{%2, %k0|%k0, %2}";
5895 }
5896 }
5897 [(set (attr "type")
5898 (if_then_else (match_operand:SI 2 "incdec_operand")
5899 (const_string "incdec")
5900 (const_string "alu")))
5901 (set (attr "length_immediate")
5902 (if_then_else
5903 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5904 (const_string "1")
5905 (const_string "*")))
5906 (set_attr "mode" "SI")])
5907
5908 (define_insn "*add<mode>_3"
5909 [(set (reg FLAGS_REG)
5910 (compare
5911 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5912 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5913 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5914 "ix86_match_ccmode (insn, CCZmode)
5915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5916 {
5917 switch (get_attr_type (insn))
5918 {
5919 case TYPE_INCDEC:
5920 if (operands[2] == const1_rtx)
5921 return "inc{<imodesuffix>}\t%0";
5922 else
5923 {
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{<imodesuffix>}\t%0";
5926 }
5927
5928 default:
5929 if (which_alternative == 1)
5930 {
5931 rtx tmp;
5932 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5933 }
5934
5935 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5936 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5937 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5938
5939 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5940 }
5941 }
5942 [(set (attr "type")
5943 (if_then_else (match_operand:SWI 2 "incdec_operand")
5944 (const_string "incdec")
5945 (const_string "alu")))
5946 (set (attr "length_immediate")
5947 (if_then_else
5948 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5949 (const_string "1")
5950 (const_string "*")))
5951 (set_attr "mode" "<MODE>")])
5952
5953 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5954 (define_insn "*addsi_3_zext"
5955 [(set (reg FLAGS_REG)
5956 (compare
5957 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5958 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5959 (set (match_operand:DI 0 "register_operand" "=r,r")
5960 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5961 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5962 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5963 {
5964 switch (get_attr_type (insn))
5965 {
5966 case TYPE_INCDEC:
5967 if (operands[2] == const1_rtx)
5968 return "inc{l}\t%k0";
5969 else
5970 {
5971 gcc_assert (operands[2] == constm1_rtx);
5972 return "dec{l}\t%k0";
5973 }
5974
5975 default:
5976 if (which_alternative == 1)
5977 {
5978 rtx tmp;
5979 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5980 }
5981
5982 if (x86_maybe_negate_const_int (&operands[2], SImode))
5983 return "sub{l}\t{%2, %k0|%k0, %2}";
5984
5985 return "add{l}\t{%2, %k0|%k0, %2}";
5986 }
5987 }
5988 [(set (attr "type")
5989 (if_then_else (match_operand:SI 2 "incdec_operand")
5990 (const_string "incdec")
5991 (const_string "alu")))
5992 (set (attr "length_immediate")
5993 (if_then_else
5994 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5995 (const_string "1")
5996 (const_string "*")))
5997 (set_attr "mode" "SI")])
5998
5999 ; For comparisons against 1, -1 and 128, we may generate better code
6000 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6001 ; is matched then. We can't accept general immediate, because for
6002 ; case of overflows, the result is messed up.
6003 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6004 ; only for comparisons not depending on it.
6005
6006 (define_insn "*adddi_4"
6007 [(set (reg FLAGS_REG)
6008 (compare
6009 (match_operand:DI 1 "nonimmediate_operand" "0")
6010 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6011 (clobber (match_scratch:DI 0 "=rm"))]
6012 "TARGET_64BIT
6013 && ix86_match_ccmode (insn, CCGCmode)"
6014 {
6015 switch (get_attr_type (insn))
6016 {
6017 case TYPE_INCDEC:
6018 if (operands[2] == constm1_rtx)
6019 return "inc{q}\t%0";
6020 else
6021 {
6022 gcc_assert (operands[2] == const1_rtx);
6023 return "dec{q}\t%0";
6024 }
6025
6026 default:
6027 if (x86_maybe_negate_const_int (&operands[2], DImode))
6028 return "add{q}\t{%2, %0|%0, %2}";
6029
6030 return "sub{q}\t{%2, %0|%0, %2}";
6031 }
6032 }
6033 [(set (attr "type")
6034 (if_then_else (match_operand:DI 2 "incdec_operand")
6035 (const_string "incdec")
6036 (const_string "alu")))
6037 (set (attr "length_immediate")
6038 (if_then_else
6039 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6040 (const_string "1")
6041 (const_string "*")))
6042 (set_attr "mode" "DI")])
6043
6044 ; For comparisons against 1, -1 and 128, we may generate better code
6045 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6046 ; is matched then. We can't accept general immediate, because for
6047 ; case of overflows, the result is messed up.
6048 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6049 ; only for comparisons not depending on it.
6050
6051 (define_insn "*add<mode>_4"
6052 [(set (reg FLAGS_REG)
6053 (compare
6054 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6055 (match_operand:SWI124 2 "const_int_operand" "n")))
6056 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6057 "ix86_match_ccmode (insn, CCGCmode)"
6058 {
6059 switch (get_attr_type (insn))
6060 {
6061 case TYPE_INCDEC:
6062 if (operands[2] == constm1_rtx)
6063 return "inc{<imodesuffix>}\t%0";
6064 else
6065 {
6066 gcc_assert (operands[2] == const1_rtx);
6067 return "dec{<imodesuffix>}\t%0";
6068 }
6069
6070 default:
6071 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6072 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6073
6074 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6075 }
6076 }
6077 [(set (attr "type")
6078 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set (attr "length_immediate")
6082 (if_then_else
6083 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6084 (const_string "1")
6085 (const_string "*")))
6086 (set_attr "mode" "<MODE>")])
6087
6088 (define_insn "*add<mode>_5"
6089 [(set (reg FLAGS_REG)
6090 (compare
6091 (plus:SWI
6092 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6093 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6094 (const_int 0)))
6095 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6096 "ix86_match_ccmode (insn, CCGOCmode)
6097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6098 {
6099 switch (get_attr_type (insn))
6100 {
6101 case TYPE_INCDEC:
6102 if (operands[2] == const1_rtx)
6103 return "inc{<imodesuffix>}\t%0";
6104 else
6105 {
6106 gcc_assert (operands[2] == constm1_rtx);
6107 return "dec{<imodesuffix>}\t%0";
6108 }
6109
6110 default:
6111 if (which_alternative == 1)
6112 {
6113 rtx tmp;
6114 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6115 }
6116
6117 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6118 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6119 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6120
6121 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6122 }
6123 }
6124 [(set (attr "type")
6125 (if_then_else (match_operand:SWI 2 "incdec_operand")
6126 (const_string "incdec")
6127 (const_string "alu")))
6128 (set (attr "length_immediate")
6129 (if_then_else
6130 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6131 (const_string "1")
6132 (const_string "*")))
6133 (set_attr "mode" "<MODE>")])
6134
6135 (define_insn "addqi_ext_1"
6136 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6137 (const_int 8)
6138 (const_int 8))
6139 (plus:SI
6140 (zero_extract:SI
6141 (match_operand 1 "ext_register_operand" "0,0")
6142 (const_int 8)
6143 (const_int 8))
6144 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6145 (clobber (reg:CC FLAGS_REG))]
6146 ""
6147 {
6148 switch (get_attr_type (insn))
6149 {
6150 case TYPE_INCDEC:
6151 if (operands[2] == const1_rtx)
6152 return "inc{b}\t%h0";
6153 else
6154 {
6155 gcc_assert (operands[2] == constm1_rtx);
6156 return "dec{b}\t%h0";
6157 }
6158
6159 default:
6160 return "add{b}\t{%2, %h0|%h0, %2}";
6161 }
6162 }
6163 [(set_attr "isa" "*,nox64")
6164 (set (attr "type")
6165 (if_then_else (match_operand:QI 2 "incdec_operand")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set_attr "modrm" "1")
6169 (set_attr "mode" "QI")])
6170
6171 (define_insn "*addqi_ext_2"
6172 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6173 (const_int 8)
6174 (const_int 8))
6175 (plus:SI
6176 (zero_extract:SI
6177 (match_operand 1 "ext_register_operand" "%0")
6178 (const_int 8)
6179 (const_int 8))
6180 (zero_extract:SI
6181 (match_operand 2 "ext_register_operand" "Q")
6182 (const_int 8)
6183 (const_int 8))))
6184 (clobber (reg:CC FLAGS_REG))]
6185 ""
6186 "add{b}\t{%h2, %h0|%h0, %h2}"
6187 [(set_attr "type" "alu")
6188 (set_attr "mode" "QI")])
6189
6190 ;; Add with jump on overflow.
6191 (define_expand "addv<mode>4"
6192 [(parallel [(set (reg:CCO FLAGS_REG)
6193 (eq:CCO (plus:<DWI>
6194 (sign_extend:<DWI>
6195 (match_operand:SWI 1 "nonimmediate_operand"))
6196 (sign_extend:<DWI>
6197 (match_operand:SWI 2 "<general_operand>")))
6198 (sign_extend:<DWI>
6199 (plus:SWI (match_dup 1) (match_dup 2)))))
6200 (set (match_operand:SWI 0 "register_operand")
6201 (plus:SWI (match_dup 1) (match_dup 2)))])
6202 (set (pc) (if_then_else
6203 (eq (reg:CCO FLAGS_REG) (const_int 0))
6204 (label_ref (match_operand 3))
6205 (pc)))]
6206 ""
6207 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6208
6209 (define_insn "*addv<mode>4"
6210 [(set (reg:CCO FLAGS_REG)
6211 (eq:CCO (plus:<DWI>
6212 (sign_extend:<DWI>
6213 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6214 (sign_extend:<DWI>
6215 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")))
6216 (sign_extend:<DWI>
6217 (plus:SWI (match_dup 1) (match_dup 2)))))
6218 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6219 (plus:SWI (match_dup 1) (match_dup 2)))]
6220 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6221 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6222 [(set_attr "type" "alu")
6223 (set_attr "mode" "<MODE>")])
6224
6225 ;; The lea patterns for modes less than 32 bits need to be matched by
6226 ;; several insns converted to real lea by splitters.
6227
6228 (define_insn_and_split "*lea_general_1"
6229 [(set (match_operand 0 "register_operand" "=r")
6230 (plus (plus (match_operand 1 "index_register_operand" "l")
6231 (match_operand 2 "register_operand" "r"))
6232 (match_operand 3 "immediate_operand" "i")))]
6233 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6235 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6236 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6237 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6238 || GET_MODE (operands[3]) == VOIDmode)"
6239 "#"
6240 "&& reload_completed"
6241 [(const_int 0)]
6242 {
6243 enum machine_mode mode = SImode;
6244 rtx pat;
6245
6246 operands[0] = gen_lowpart (mode, operands[0]);
6247 operands[1] = gen_lowpart (mode, operands[1]);
6248 operands[2] = gen_lowpart (mode, operands[2]);
6249 operands[3] = gen_lowpart (mode, operands[3]);
6250
6251 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6252 operands[3]);
6253
6254 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6255 DONE;
6256 }
6257 [(set_attr "type" "lea")
6258 (set_attr "mode" "SI")])
6259
6260 (define_insn_and_split "*lea_general_2"
6261 [(set (match_operand 0 "register_operand" "=r")
6262 (plus (mult (match_operand 1 "index_register_operand" "l")
6263 (match_operand 2 "const248_operand" "n"))
6264 (match_operand 3 "nonmemory_operand" "ri")))]
6265 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6266 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6267 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6268 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6269 || GET_MODE (operands[3]) == VOIDmode)"
6270 "#"
6271 "&& reload_completed"
6272 [(const_int 0)]
6273 {
6274 enum machine_mode mode = SImode;
6275 rtx pat;
6276
6277 operands[0] = gen_lowpart (mode, operands[0]);
6278 operands[1] = gen_lowpart (mode, operands[1]);
6279 operands[3] = gen_lowpart (mode, operands[3]);
6280
6281 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6282 operands[3]);
6283
6284 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6285 DONE;
6286 }
6287 [(set_attr "type" "lea")
6288 (set_attr "mode" "SI")])
6289
6290 (define_insn_and_split "*lea_general_3"
6291 [(set (match_operand 0 "register_operand" "=r")
6292 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6293 (match_operand 2 "const248_operand" "n"))
6294 (match_operand 3 "register_operand" "r"))
6295 (match_operand 4 "immediate_operand" "i")))]
6296 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6297 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6298 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6299 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6300 "#"
6301 "&& reload_completed"
6302 [(const_int 0)]
6303 {
6304 enum machine_mode mode = SImode;
6305 rtx pat;
6306
6307 operands[0] = gen_lowpart (mode, operands[0]);
6308 operands[1] = gen_lowpart (mode, operands[1]);
6309 operands[3] = gen_lowpart (mode, operands[3]);
6310 operands[4] = gen_lowpart (mode, operands[4]);
6311
6312 pat = gen_rtx_PLUS (mode,
6313 gen_rtx_PLUS (mode,
6314 gen_rtx_MULT (mode, operands[1],
6315 operands[2]),
6316 operands[3]),
6317 operands[4]);
6318
6319 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6320 DONE;
6321 }
6322 [(set_attr "type" "lea")
6323 (set_attr "mode" "SI")])
6324
6325 (define_insn_and_split "*lea_general_4"
6326 [(set (match_operand 0 "register_operand" "=r")
6327 (any_or (ashift
6328 (match_operand 1 "index_register_operand" "l")
6329 (match_operand 2 "const_int_operand" "n"))
6330 (match_operand 3 "const_int_operand" "n")))]
6331 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6332 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6333 || GET_MODE (operands[0]) == SImode
6334 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6335 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6336 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6337 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6338 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6339 "#"
6340 "&& reload_completed"
6341 [(const_int 0)]
6342 {
6343 enum machine_mode mode = GET_MODE (operands[0]);
6344 rtx pat;
6345
6346 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6347 {
6348 mode = SImode;
6349 operands[0] = gen_lowpart (mode, operands[0]);
6350 operands[1] = gen_lowpart (mode, operands[1]);
6351 }
6352
6353 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6354
6355 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6356 INTVAL (operands[3]));
6357
6358 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6359 DONE;
6360 }
6361 [(set_attr "type" "lea")
6362 (set (attr "mode")
6363 (if_then_else (match_operand:DI 0)
6364 (const_string "DI")
6365 (const_string "SI")))])
6366 \f
6367 ;; Subtract instructions
6368
6369 (define_expand "sub<mode>3"
6370 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6371 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6372 (match_operand:SDWIM 2 "<general_operand>")))]
6373 ""
6374 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6375
6376 (define_insn_and_split "*sub<dwi>3_doubleword"
6377 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6378 (minus:<DWI>
6379 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6380 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6381 (clobber (reg:CC FLAGS_REG))]
6382 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6383 "#"
6384 "reload_completed"
6385 [(parallel [(set (reg:CC FLAGS_REG)
6386 (compare:CC (match_dup 1) (match_dup 2)))
6387 (set (match_dup 0)
6388 (minus:DWIH (match_dup 1) (match_dup 2)))])
6389 (parallel [(set (match_dup 3)
6390 (minus:DWIH
6391 (match_dup 4)
6392 (plus:DWIH
6393 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6394 (match_dup 5))))
6395 (clobber (reg:CC FLAGS_REG))])]
6396 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6397
6398 (define_insn "*sub<mode>_1"
6399 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6400 (minus:SWI
6401 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6402 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6403 (clobber (reg:CC FLAGS_REG))]
6404 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6405 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "mode" "<MODE>")])
6408
6409 (define_insn "*subsi_1_zext"
6410 [(set (match_operand:DI 0 "register_operand" "=r")
6411 (zero_extend:DI
6412 (minus:SI (match_operand:SI 1 "register_operand" "0")
6413 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6414 (clobber (reg:CC FLAGS_REG))]
6415 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6416 "sub{l}\t{%2, %k0|%k0, %2}"
6417 [(set_attr "type" "alu")
6418 (set_attr "mode" "SI")])
6419
6420 (define_insn "*subqi_1_slp"
6421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6422 (minus:QI (match_dup 0)
6423 (match_operand:QI 1 "general_operand" "qn,qm")))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6426 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6427 "sub{b}\t{%1, %0|%0, %1}"
6428 [(set_attr "type" "alu1")
6429 (set_attr "mode" "QI")])
6430
6431 (define_insn "*sub<mode>_2"
6432 [(set (reg FLAGS_REG)
6433 (compare
6434 (minus:SWI
6435 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6436 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6437 (const_int 0)))
6438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6439 (minus:SWI (match_dup 1) (match_dup 2)))]
6440 "ix86_match_ccmode (insn, CCGOCmode)
6441 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6442 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6443 [(set_attr "type" "alu")
6444 (set_attr "mode" "<MODE>")])
6445
6446 (define_insn "*subsi_2_zext"
6447 [(set (reg FLAGS_REG)
6448 (compare
6449 (minus:SI (match_operand:SI 1 "register_operand" "0")
6450 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6451 (const_int 0)))
6452 (set (match_operand:DI 0 "register_operand" "=r")
6453 (zero_extend:DI
6454 (minus:SI (match_dup 1)
6455 (match_dup 2))))]
6456 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6457 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6458 "sub{l}\t{%2, %k0|%k0, %2}"
6459 [(set_attr "type" "alu")
6460 (set_attr "mode" "SI")])
6461
6462 ;; Subtract with jump on overflow.
6463 (define_expand "subv<mode>4"
6464 [(parallel [(set (reg:CCO FLAGS_REG)
6465 (eq:CCO (minus:<DWI>
6466 (sign_extend:<DWI>
6467 (match_operand:SWI 1 "nonimmediate_operand"))
6468 (sign_extend:<DWI>
6469 (match_operand:SWI 2 "<general_operand>")))
6470 (sign_extend:<DWI>
6471 (minus:SWI (match_dup 1) (match_dup 2)))))
6472 (set (match_operand:SWI 0 "register_operand")
6473 (minus:SWI (match_dup 1) (match_dup 2)))])
6474 (set (pc) (if_then_else
6475 (eq (reg:CCO FLAGS_REG) (const_int 0))
6476 (label_ref (match_operand 3))
6477 (pc)))]
6478 ""
6479 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6480
6481 (define_insn "*subv<mode>4"
6482 [(set (reg:CCO FLAGS_REG)
6483 (eq:CCO (minus:<DWI>
6484 (sign_extend:<DWI>
6485 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6486 (sign_extend:<DWI>
6487 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6488 (sign_extend:<DWI>
6489 (minus:SWI (match_dup 1) (match_dup 2)))))
6490 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6491 (minus:SWI (match_dup 1) (match_dup 2)))]
6492 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6493 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6494 [(set_attr "type" "alu")
6495 (set_attr "mode" "<MODE>")])
6496
6497 (define_insn "*sub<mode>_3"
6498 [(set (reg FLAGS_REG)
6499 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6500 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6501 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6502 (minus:SWI (match_dup 1) (match_dup 2)))]
6503 "ix86_match_ccmode (insn, CCmode)
6504 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6505 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6508
6509 (define_insn "*subsi_3_zext"
6510 [(set (reg FLAGS_REG)
6511 (compare (match_operand:SI 1 "register_operand" "0")
6512 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6513 (set (match_operand:DI 0 "register_operand" "=r")
6514 (zero_extend:DI
6515 (minus:SI (match_dup 1)
6516 (match_dup 2))))]
6517 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6518 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6519 "sub{l}\t{%2, %1|%1, %2}"
6520 [(set_attr "type" "alu")
6521 (set_attr "mode" "SI")])
6522 \f
6523 ;; Add with carry and subtract with borrow
6524
6525 (define_expand "<plusminus_insn><mode>3_carry"
6526 [(parallel
6527 [(set (match_operand:SWI 0 "nonimmediate_operand")
6528 (plusminus:SWI
6529 (match_operand:SWI 1 "nonimmediate_operand")
6530 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6531 [(match_operand 3 "flags_reg_operand")
6532 (const_int 0)])
6533 (match_operand:SWI 2 "<general_operand>"))))
6534 (clobber (reg:CC FLAGS_REG))])]
6535 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6536
6537 (define_insn "*<plusminus_insn><mode>3_carry"
6538 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6539 (plusminus:SWI
6540 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6541 (plus:SWI
6542 (match_operator 3 "ix86_carry_flag_operator"
6543 [(reg FLAGS_REG) (const_int 0)])
6544 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6545 (clobber (reg:CC FLAGS_REG))]
6546 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6547 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6548 [(set_attr "type" "alu")
6549 (set_attr "use_carry" "1")
6550 (set_attr "pent_pair" "pu")
6551 (set_attr "mode" "<MODE>")])
6552
6553 (define_insn "*addsi3_carry_zext"
6554 [(set (match_operand:DI 0 "register_operand" "=r")
6555 (zero_extend:DI
6556 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6557 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6558 [(reg FLAGS_REG) (const_int 0)])
6559 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6562 "adc{l}\t{%2, %k0|%k0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "use_carry" "1")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "SI")])
6567
6568 (define_insn "*subsi3_carry_zext"
6569 [(set (match_operand:DI 0 "register_operand" "=r")
6570 (zero_extend:DI
6571 (minus:SI (match_operand:SI 1 "register_operand" "0")
6572 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6573 [(reg FLAGS_REG) (const_int 0)])
6574 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6575 (clobber (reg:CC FLAGS_REG))]
6576 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6577 "sbb{l}\t{%2, %k0|%k0, %2}"
6578 [(set_attr "type" "alu")
6579 (set_attr "pent_pair" "pu")
6580 (set_attr "mode" "SI")])
6581 \f
6582 ;; ADCX instruction
6583
6584 (define_insn "adcx<mode>3"
6585 [(set (reg:CCC FLAGS_REG)
6586 (compare:CCC
6587 (plus:SWI48
6588 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6589 (plus:SWI48
6590 (match_operator 4 "ix86_carry_flag_operator"
6591 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6592 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6593 (const_int 0)))
6594 (set (match_operand:SWI48 0 "register_operand" "=r")
6595 (plus:SWI48 (match_dup 1)
6596 (plus:SWI48 (match_op_dup 4
6597 [(match_dup 3) (const_int 0)])
6598 (match_dup 2))))]
6599 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6600 "adcx\t{%2, %0|%0, %2}"
6601 [(set_attr "type" "alu")
6602 (set_attr "use_carry" "1")
6603 (set_attr "mode" "<MODE>")])
6604 \f
6605 ;; Overflow setting add instructions
6606
6607 (define_insn "*add<mode>3_cconly_overflow"
6608 [(set (reg:CCC FLAGS_REG)
6609 (compare:CCC
6610 (plus:SWI
6611 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6612 (match_operand:SWI 2 "<general_operand>" "<g>"))
6613 (match_dup 1)))
6614 (clobber (match_scratch:SWI 0 "=<r>"))]
6615 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "mode" "<MODE>")])
6619
6620 (define_insn "*add<mode>3_cc_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6622 (compare:CCC
6623 (plus:SWI
6624 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6625 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6626 (match_dup 1)))
6627 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6628 (plus:SWI (match_dup 1) (match_dup 2)))]
6629 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6630 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "<MODE>")])
6633
6634 (define_insn "*addsi3_zext_cc_overflow"
6635 [(set (reg:CCC FLAGS_REG)
6636 (compare:CCC
6637 (plus:SI
6638 (match_operand:SI 1 "nonimmediate_operand" "%0")
6639 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6640 (match_dup 1)))
6641 (set (match_operand:DI 0 "register_operand" "=r")
6642 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6643 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6644 "add{l}\t{%2, %k0|%k0, %2}"
6645 [(set_attr "type" "alu")
6646 (set_attr "mode" "SI")])
6647
6648 ;; The patterns that match these are at the end of this file.
6649
6650 (define_expand "<plusminus_insn>xf3"
6651 [(set (match_operand:XF 0 "register_operand")
6652 (plusminus:XF
6653 (match_operand:XF 1 "register_operand")
6654 (match_operand:XF 2 "register_operand")))]
6655 "TARGET_80387")
6656
6657 (define_expand "<plusminus_insn><mode>3"
6658 [(set (match_operand:MODEF 0 "register_operand")
6659 (plusminus:MODEF
6660 (match_operand:MODEF 1 "register_operand")
6661 (match_operand:MODEF 2 "nonimmediate_operand")))]
6662 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6663 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6664 \f
6665 ;; Multiply instructions
6666
6667 (define_expand "mul<mode>3"
6668 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6669 (mult:SWIM248
6670 (match_operand:SWIM248 1 "register_operand")
6671 (match_operand:SWIM248 2 "<general_operand>")))
6672 (clobber (reg:CC FLAGS_REG))])])
6673
6674 (define_expand "mulqi3"
6675 [(parallel [(set (match_operand:QI 0 "register_operand")
6676 (mult:QI
6677 (match_operand:QI 1 "register_operand")
6678 (match_operand:QI 2 "nonimmediate_operand")))
6679 (clobber (reg:CC FLAGS_REG))])]
6680 "TARGET_QIMODE_MATH")
6681
6682 ;; On AMDFAM10
6683 ;; IMUL reg32/64, reg32/64, imm8 Direct
6684 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6685 ;; IMUL reg32/64, reg32/64, imm32 Direct
6686 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6687 ;; IMUL reg32/64, reg32/64 Direct
6688 ;; IMUL reg32/64, mem32/64 Direct
6689 ;;
6690 ;; On BDVER1, all above IMULs use DirectPath
6691
6692 (define_insn "*mul<mode>3_1"
6693 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6694 (mult:SWI48
6695 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6696 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6697 (clobber (reg:CC FLAGS_REG))]
6698 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6699 "@
6700 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6701 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6702 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6703 [(set_attr "type" "imul")
6704 (set_attr "prefix_0f" "0,0,1")
6705 (set (attr "athlon_decode")
6706 (cond [(eq_attr "cpu" "athlon")
6707 (const_string "vector")
6708 (eq_attr "alternative" "1")
6709 (const_string "vector")
6710 (and (eq_attr "alternative" "2")
6711 (match_operand 1 "memory_operand"))
6712 (const_string "vector")]
6713 (const_string "direct")))
6714 (set (attr "amdfam10_decode")
6715 (cond [(and (eq_attr "alternative" "0,1")
6716 (match_operand 1 "memory_operand"))
6717 (const_string "vector")]
6718 (const_string "direct")))
6719 (set_attr "bdver1_decode" "direct")
6720 (set_attr "mode" "<MODE>")])
6721
6722 (define_insn "*mulsi3_1_zext"
6723 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6724 (zero_extend:DI
6725 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6726 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6727 (clobber (reg:CC FLAGS_REG))]
6728 "TARGET_64BIT
6729 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6730 "@
6731 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6732 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6733 imul{l}\t{%2, %k0|%k0, %2}"
6734 [(set_attr "type" "imul")
6735 (set_attr "prefix_0f" "0,0,1")
6736 (set (attr "athlon_decode")
6737 (cond [(eq_attr "cpu" "athlon")
6738 (const_string "vector")
6739 (eq_attr "alternative" "1")
6740 (const_string "vector")
6741 (and (eq_attr "alternative" "2")
6742 (match_operand 1 "memory_operand"))
6743 (const_string "vector")]
6744 (const_string "direct")))
6745 (set (attr "amdfam10_decode")
6746 (cond [(and (eq_attr "alternative" "0,1")
6747 (match_operand 1 "memory_operand"))
6748 (const_string "vector")]
6749 (const_string "direct")))
6750 (set_attr "bdver1_decode" "direct")
6751 (set_attr "mode" "SI")])
6752
6753 ;; On AMDFAM10
6754 ;; IMUL reg16, reg16, imm8 VectorPath
6755 ;; IMUL reg16, mem16, imm8 VectorPath
6756 ;; IMUL reg16, reg16, imm16 VectorPath
6757 ;; IMUL reg16, mem16, imm16 VectorPath
6758 ;; IMUL reg16, reg16 Direct
6759 ;; IMUL reg16, mem16 Direct
6760 ;;
6761 ;; On BDVER1, all HI MULs use DoublePath
6762
6763 (define_insn "*mulhi3_1"
6764 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6765 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6766 (match_operand:HI 2 "general_operand" "K,n,mr")))
6767 (clobber (reg:CC FLAGS_REG))]
6768 "TARGET_HIMODE_MATH
6769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6770 "@
6771 imul{w}\t{%2, %1, %0|%0, %1, %2}
6772 imul{w}\t{%2, %1, %0|%0, %1, %2}
6773 imul{w}\t{%2, %0|%0, %2}"
6774 [(set_attr "type" "imul")
6775 (set_attr "prefix_0f" "0,0,1")
6776 (set (attr "athlon_decode")
6777 (cond [(eq_attr "cpu" "athlon")
6778 (const_string "vector")
6779 (eq_attr "alternative" "1,2")
6780 (const_string "vector")]
6781 (const_string "direct")))
6782 (set (attr "amdfam10_decode")
6783 (cond [(eq_attr "alternative" "0,1")
6784 (const_string "vector")]
6785 (const_string "direct")))
6786 (set_attr "bdver1_decode" "double")
6787 (set_attr "mode" "HI")])
6788
6789 ;;On AMDFAM10 and BDVER1
6790 ;; MUL reg8 Direct
6791 ;; MUL mem8 Direct
6792
6793 (define_insn "*mulqi3_1"
6794 [(set (match_operand:QI 0 "register_operand" "=a")
6795 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6796 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6797 (clobber (reg:CC FLAGS_REG))]
6798 "TARGET_QIMODE_MATH
6799 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6800 "mul{b}\t%2"
6801 [(set_attr "type" "imul")
6802 (set_attr "length_immediate" "0")
6803 (set (attr "athlon_decode")
6804 (if_then_else (eq_attr "cpu" "athlon")
6805 (const_string "vector")
6806 (const_string "direct")))
6807 (set_attr "amdfam10_decode" "direct")
6808 (set_attr "bdver1_decode" "direct")
6809 (set_attr "mode" "QI")])
6810
6811 ;; Multiply with jump on overflow.
6812 (define_expand "mulv<mode>4"
6813 [(parallel [(set (reg:CCO FLAGS_REG)
6814 (eq:CCO (mult:<DWI>
6815 (sign_extend:<DWI>
6816 (match_operand:SWI48 1 "register_operand"))
6817 (sign_extend:<DWI>
6818 (match_operand:SWI48 2 "<general_operand>")))
6819 (sign_extend:<DWI>
6820 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6821 (set (match_operand:SWI48 0 "register_operand")
6822 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6823 (set (pc) (if_then_else
6824 (eq (reg:CCO FLAGS_REG) (const_int 0))
6825 (label_ref (match_operand 3))
6826 (pc)))])
6827
6828 (define_insn "*mulv<mode>4"
6829 [(set (reg:CCO FLAGS_REG)
6830 (eq:CCO (mult:<DWI>
6831 (sign_extend:<DWI>
6832 (match_operand:SWI 1 "nonimmediate_operand" "%rm,rm,0"))
6833 (sign_extend:<DWI>
6834 (match_operand:SWI 2 "<general_operand>" "K,<i>,mr")))
6835 (sign_extend:<DWI>
6836 (mult:SWI (match_dup 1) (match_dup 2)))))
6837 (set (match_operand:SWI 0 "register_operand" "=r,r,r")
6838 (mult:SWI (match_dup 1) (match_dup 2)))]
6839 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6840 "@
6841 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6842 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6843 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6844 [(set_attr "type" "imul")
6845 (set_attr "prefix_0f" "0,0,1")
6846 (set (attr "athlon_decode")
6847 (cond [(eq_attr "cpu" "athlon")
6848 (const_string "vector")
6849 (eq_attr "alternative" "1")
6850 (const_string "vector")
6851 (and (eq_attr "alternative" "2")
6852 (match_operand 1 "memory_operand"))
6853 (const_string "vector")]
6854 (const_string "direct")))
6855 (set (attr "amdfam10_decode")
6856 (cond [(and (eq_attr "alternative" "0,1")
6857 (match_operand 1 "memory_operand"))
6858 (const_string "vector")]
6859 (const_string "direct")))
6860 (set_attr "bdver1_decode" "direct")
6861 (set_attr "mode" "<MODE>")])
6862
6863 (define_expand "<u>mul<mode><dwi>3"
6864 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6865 (mult:<DWI>
6866 (any_extend:<DWI>
6867 (match_operand:DWIH 1 "nonimmediate_operand"))
6868 (any_extend:<DWI>
6869 (match_operand:DWIH 2 "register_operand"))))
6870 (clobber (reg:CC FLAGS_REG))])])
6871
6872 (define_expand "<u>mulqihi3"
6873 [(parallel [(set (match_operand:HI 0 "register_operand")
6874 (mult:HI
6875 (any_extend:HI
6876 (match_operand:QI 1 "nonimmediate_operand"))
6877 (any_extend:HI
6878 (match_operand:QI 2 "register_operand"))))
6879 (clobber (reg:CC FLAGS_REG))])]
6880 "TARGET_QIMODE_MATH")
6881
6882 (define_insn "*bmi2_umulditi3_1"
6883 [(set (match_operand:DI 0 "register_operand" "=r")
6884 (mult:DI
6885 (match_operand:DI 2 "nonimmediate_operand" "%d")
6886 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6887 (set (match_operand:DI 1 "register_operand" "=r")
6888 (truncate:DI
6889 (lshiftrt:TI
6890 (mult:TI (zero_extend:TI (match_dup 2))
6891 (zero_extend:TI (match_dup 3)))
6892 (const_int 64))))]
6893 "TARGET_64BIT && TARGET_BMI2
6894 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6895 "mulx\t{%3, %0, %1|%1, %0, %3}"
6896 [(set_attr "type" "imulx")
6897 (set_attr "prefix" "vex")
6898 (set_attr "mode" "DI")])
6899
6900 (define_insn "*bmi2_umulsidi3_1"
6901 [(set (match_operand:SI 0 "register_operand" "=r")
6902 (mult:SI
6903 (match_operand:SI 2 "nonimmediate_operand" "%d")
6904 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6905 (set (match_operand:SI 1 "register_operand" "=r")
6906 (truncate:SI
6907 (lshiftrt:DI
6908 (mult:DI (zero_extend:DI (match_dup 2))
6909 (zero_extend:DI (match_dup 3)))
6910 (const_int 32))))]
6911 "!TARGET_64BIT && TARGET_BMI2
6912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6913 "mulx\t{%3, %0, %1|%1, %0, %3}"
6914 [(set_attr "type" "imulx")
6915 (set_attr "prefix" "vex")
6916 (set_attr "mode" "SI")])
6917
6918 (define_insn "*umul<mode><dwi>3_1"
6919 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6920 (mult:<DWI>
6921 (zero_extend:<DWI>
6922 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6923 (zero_extend:<DWI>
6924 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6925 (clobber (reg:CC FLAGS_REG))]
6926 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6927 "@
6928 #
6929 mul{<imodesuffix>}\t%2"
6930 [(set_attr "isa" "bmi2,*")
6931 (set_attr "type" "imulx,imul")
6932 (set_attr "length_immediate" "*,0")
6933 (set (attr "athlon_decode")
6934 (cond [(eq_attr "alternative" "1")
6935 (if_then_else (eq_attr "cpu" "athlon")
6936 (const_string "vector")
6937 (const_string "double"))]
6938 (const_string "*")))
6939 (set_attr "amdfam10_decode" "*,double")
6940 (set_attr "bdver1_decode" "*,direct")
6941 (set_attr "prefix" "vex,orig")
6942 (set_attr "mode" "<MODE>")])
6943
6944 ;; Convert mul to the mulx pattern to avoid flags dependency.
6945 (define_split
6946 [(set (match_operand:<DWI> 0 "register_operand")
6947 (mult:<DWI>
6948 (zero_extend:<DWI>
6949 (match_operand:DWIH 1 "register_operand"))
6950 (zero_extend:<DWI>
6951 (match_operand:DWIH 2 "nonimmediate_operand"))))
6952 (clobber (reg:CC FLAGS_REG))]
6953 "TARGET_BMI2 && reload_completed
6954 && true_regnum (operands[1]) == DX_REG"
6955 [(parallel [(set (match_dup 3)
6956 (mult:DWIH (match_dup 1) (match_dup 2)))
6957 (set (match_dup 4)
6958 (truncate:DWIH
6959 (lshiftrt:<DWI>
6960 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6961 (zero_extend:<DWI> (match_dup 2)))
6962 (match_dup 5))))])]
6963 {
6964 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6965
6966 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6967 })
6968
6969 (define_insn "*mul<mode><dwi>3_1"
6970 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6971 (mult:<DWI>
6972 (sign_extend:<DWI>
6973 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6974 (sign_extend:<DWI>
6975 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6976 (clobber (reg:CC FLAGS_REG))]
6977 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6978 "imul{<imodesuffix>}\t%2"
6979 [(set_attr "type" "imul")
6980 (set_attr "length_immediate" "0")
6981 (set (attr "athlon_decode")
6982 (if_then_else (eq_attr "cpu" "athlon")
6983 (const_string "vector")
6984 (const_string "double")))
6985 (set_attr "amdfam10_decode" "double")
6986 (set_attr "bdver1_decode" "direct")
6987 (set_attr "mode" "<MODE>")])
6988
6989 (define_insn "*<u>mulqihi3_1"
6990 [(set (match_operand:HI 0 "register_operand" "=a")
6991 (mult:HI
6992 (any_extend:HI
6993 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6994 (any_extend:HI
6995 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6996 (clobber (reg:CC FLAGS_REG))]
6997 "TARGET_QIMODE_MATH
6998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999 "<sgnprefix>mul{b}\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 "direct")))
7006 (set_attr "amdfam10_decode" "direct")
7007 (set_attr "bdver1_decode" "direct")
7008 (set_attr "mode" "QI")])
7009
7010 (define_expand "<s>mul<mode>3_highpart"
7011 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7012 (truncate:SWI48
7013 (lshiftrt:<DWI>
7014 (mult:<DWI>
7015 (any_extend:<DWI>
7016 (match_operand:SWI48 1 "nonimmediate_operand"))
7017 (any_extend:<DWI>
7018 (match_operand:SWI48 2 "register_operand")))
7019 (match_dup 4))))
7020 (clobber (match_scratch:SWI48 3))
7021 (clobber (reg:CC FLAGS_REG))])]
7022 ""
7023 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7024
7025 (define_insn "*<s>muldi3_highpart_1"
7026 [(set (match_operand:DI 0 "register_operand" "=d")
7027 (truncate:DI
7028 (lshiftrt:TI
7029 (mult:TI
7030 (any_extend:TI
7031 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7032 (any_extend:TI
7033 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7034 (const_int 64))))
7035 (clobber (match_scratch:DI 3 "=1"))
7036 (clobber (reg:CC FLAGS_REG))]
7037 "TARGET_64BIT
7038 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7039 "<sgnprefix>mul{q}\t%2"
7040 [(set_attr "type" "imul")
7041 (set_attr "length_immediate" "0")
7042 (set (attr "athlon_decode")
7043 (if_then_else (eq_attr "cpu" "athlon")
7044 (const_string "vector")
7045 (const_string "double")))
7046 (set_attr "amdfam10_decode" "double")
7047 (set_attr "bdver1_decode" "direct")
7048 (set_attr "mode" "DI")])
7049
7050 (define_insn "*<s>mulsi3_highpart_1"
7051 [(set (match_operand:SI 0 "register_operand" "=d")
7052 (truncate:SI
7053 (lshiftrt:DI
7054 (mult:DI
7055 (any_extend:DI
7056 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7057 (any_extend:DI
7058 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7059 (const_int 32))))
7060 (clobber (match_scratch:SI 3 "=1"))
7061 (clobber (reg:CC FLAGS_REG))]
7062 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7063 "<sgnprefix>mul{l}\t%2"
7064 [(set_attr "type" "imul")
7065 (set_attr "length_immediate" "0")
7066 (set (attr "athlon_decode")
7067 (if_then_else (eq_attr "cpu" "athlon")
7068 (const_string "vector")
7069 (const_string "double")))
7070 (set_attr "amdfam10_decode" "double")
7071 (set_attr "bdver1_decode" "direct")
7072 (set_attr "mode" "SI")])
7073
7074 (define_insn "*<s>mulsi3_highpart_zext"
7075 [(set (match_operand:DI 0 "register_operand" "=d")
7076 (zero_extend:DI (truncate:SI
7077 (lshiftrt:DI
7078 (mult:DI (any_extend:DI
7079 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7080 (any_extend:DI
7081 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7082 (const_int 32)))))
7083 (clobber (match_scratch:SI 3 "=1"))
7084 (clobber (reg:CC FLAGS_REG))]
7085 "TARGET_64BIT
7086 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7087 "<sgnprefix>mul{l}\t%2"
7088 [(set_attr "type" "imul")
7089 (set_attr "length_immediate" "0")
7090 (set (attr "athlon_decode")
7091 (if_then_else (eq_attr "cpu" "athlon")
7092 (const_string "vector")
7093 (const_string "double")))
7094 (set_attr "amdfam10_decode" "double")
7095 (set_attr "bdver1_decode" "direct")
7096 (set_attr "mode" "SI")])
7097
7098 ;; The patterns that match these are at the end of this file.
7099
7100 (define_expand "mulxf3"
7101 [(set (match_operand:XF 0 "register_operand")
7102 (mult:XF (match_operand:XF 1 "register_operand")
7103 (match_operand:XF 2 "register_operand")))]
7104 "TARGET_80387")
7105
7106 (define_expand "mul<mode>3"
7107 [(set (match_operand:MODEF 0 "register_operand")
7108 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7109 (match_operand:MODEF 2 "nonimmediate_operand")))]
7110 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7111 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7112 \f
7113 ;; Divide instructions
7114
7115 ;; The patterns that match these are at the end of this file.
7116
7117 (define_expand "divxf3"
7118 [(set (match_operand:XF 0 "register_operand")
7119 (div:XF (match_operand:XF 1 "register_operand")
7120 (match_operand:XF 2 "register_operand")))]
7121 "TARGET_80387")
7122
7123 (define_expand "divdf3"
7124 [(set (match_operand:DF 0 "register_operand")
7125 (div:DF (match_operand:DF 1 "register_operand")
7126 (match_operand:DF 2 "nonimmediate_operand")))]
7127 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7128 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7129
7130 (define_expand "divsf3"
7131 [(set (match_operand:SF 0 "register_operand")
7132 (div:SF (match_operand:SF 1 "register_operand")
7133 (match_operand:SF 2 "nonimmediate_operand")))]
7134 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7135 || TARGET_SSE_MATH"
7136 {
7137 if (TARGET_SSE_MATH
7138 && TARGET_RECIP_DIV
7139 && optimize_insn_for_speed_p ()
7140 && flag_finite_math_only && !flag_trapping_math
7141 && flag_unsafe_math_optimizations)
7142 {
7143 ix86_emit_swdivsf (operands[0], operands[1],
7144 operands[2], SFmode);
7145 DONE;
7146 }
7147 })
7148 \f
7149 ;; Divmod instructions.
7150
7151 (define_expand "divmod<mode>4"
7152 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7153 (div:SWIM248
7154 (match_operand:SWIM248 1 "register_operand")
7155 (match_operand:SWIM248 2 "nonimmediate_operand")))
7156 (set (match_operand:SWIM248 3 "register_operand")
7157 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7158 (clobber (reg:CC FLAGS_REG))])])
7159
7160 ;; Split with 8bit unsigned divide:
7161 ;; if (dividend an divisor are in [0-255])
7162 ;; use 8bit unsigned integer divide
7163 ;; else
7164 ;; use original integer divide
7165 (define_split
7166 [(set (match_operand:SWI48 0 "register_operand")
7167 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7168 (match_operand:SWI48 3 "nonimmediate_operand")))
7169 (set (match_operand:SWI48 1 "register_operand")
7170 (mod:SWI48 (match_dup 2) (match_dup 3)))
7171 (clobber (reg:CC FLAGS_REG))]
7172 "TARGET_USE_8BIT_IDIV
7173 && TARGET_QIMODE_MATH
7174 && can_create_pseudo_p ()
7175 && !optimize_insn_for_size_p ()"
7176 [(const_int 0)]
7177 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7178
7179 (define_insn_and_split "divmod<mode>4_1"
7180 [(set (match_operand:SWI48 0 "register_operand" "=a")
7181 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7182 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7183 (set (match_operand:SWI48 1 "register_operand" "=&d")
7184 (mod:SWI48 (match_dup 2) (match_dup 3)))
7185 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7186 (clobber (reg:CC FLAGS_REG))]
7187 ""
7188 "#"
7189 "reload_completed"
7190 [(parallel [(set (match_dup 1)
7191 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7192 (clobber (reg:CC FLAGS_REG))])
7193 (parallel [(set (match_dup 0)
7194 (div:SWI48 (match_dup 2) (match_dup 3)))
7195 (set (match_dup 1)
7196 (mod:SWI48 (match_dup 2) (match_dup 3)))
7197 (use (match_dup 1))
7198 (clobber (reg:CC FLAGS_REG))])]
7199 {
7200 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7201
7202 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7203 operands[4] = operands[2];
7204 else
7205 {
7206 /* Avoid use of cltd in favor of a mov+shift. */
7207 emit_move_insn (operands[1], operands[2]);
7208 operands[4] = operands[1];
7209 }
7210 }
7211 [(set_attr "type" "multi")
7212 (set_attr "mode" "<MODE>")])
7213
7214 (define_insn_and_split "*divmod<mode>4"
7215 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7216 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7217 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7218 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7219 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7220 (clobber (reg:CC FLAGS_REG))]
7221 ""
7222 "#"
7223 "reload_completed"
7224 [(parallel [(set (match_dup 1)
7225 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7226 (clobber (reg:CC FLAGS_REG))])
7227 (parallel [(set (match_dup 0)
7228 (div:SWIM248 (match_dup 2) (match_dup 3)))
7229 (set (match_dup 1)
7230 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7231 (use (match_dup 1))
7232 (clobber (reg:CC FLAGS_REG))])]
7233 {
7234 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7235
7236 if (<MODE>mode != HImode
7237 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7238 operands[4] = operands[2];
7239 else
7240 {
7241 /* Avoid use of cltd in favor of a mov+shift. */
7242 emit_move_insn (operands[1], operands[2]);
7243 operands[4] = operands[1];
7244 }
7245 }
7246 [(set_attr "type" "multi")
7247 (set_attr "mode" "<MODE>")])
7248
7249 (define_insn "*divmod<mode>4_noext"
7250 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7251 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7252 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7253 (set (match_operand:SWIM248 1 "register_operand" "=d")
7254 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7255 (use (match_operand:SWIM248 4 "register_operand" "1"))
7256 (clobber (reg:CC FLAGS_REG))]
7257 ""
7258 "idiv{<imodesuffix>}\t%3"
7259 [(set_attr "type" "idiv")
7260 (set_attr "mode" "<MODE>")])
7261
7262 (define_expand "divmodqi4"
7263 [(parallel [(set (match_operand:QI 0 "register_operand")
7264 (div:QI
7265 (match_operand:QI 1 "register_operand")
7266 (match_operand:QI 2 "nonimmediate_operand")))
7267 (set (match_operand:QI 3 "register_operand")
7268 (mod:QI (match_dup 1) (match_dup 2)))
7269 (clobber (reg:CC FLAGS_REG))])]
7270 "TARGET_QIMODE_MATH"
7271 {
7272 rtx div, mod, insn;
7273 rtx tmp0, tmp1;
7274
7275 tmp0 = gen_reg_rtx (HImode);
7276 tmp1 = gen_reg_rtx (HImode);
7277
7278 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7279 in AX. */
7280 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7281 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7282
7283 /* Extract remainder from AH. */
7284 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7285 insn = emit_move_insn (operands[3], tmp1);
7286
7287 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7288 set_unique_reg_note (insn, REG_EQUAL, mod);
7289
7290 /* Extract quotient from AL. */
7291 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7292
7293 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7294 set_unique_reg_note (insn, REG_EQUAL, div);
7295
7296 DONE;
7297 })
7298
7299 ;; Divide AX by r/m8, with result stored in
7300 ;; AL <- Quotient
7301 ;; AH <- Remainder
7302 ;; Change div/mod to HImode and extend the second argument to HImode
7303 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7304 ;; combine may fail.
7305 (define_insn "divmodhiqi3"
7306 [(set (match_operand:HI 0 "register_operand" "=a")
7307 (ior:HI
7308 (ashift:HI
7309 (zero_extend:HI
7310 (truncate:QI
7311 (mod:HI (match_operand:HI 1 "register_operand" "0")
7312 (sign_extend:HI
7313 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7314 (const_int 8))
7315 (zero_extend:HI
7316 (truncate:QI
7317 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7318 (clobber (reg:CC FLAGS_REG))]
7319 "TARGET_QIMODE_MATH"
7320 "idiv{b}\t%2"
7321 [(set_attr "type" "idiv")
7322 (set_attr "mode" "QI")])
7323
7324 (define_expand "udivmod<mode>4"
7325 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7326 (udiv:SWIM248
7327 (match_operand:SWIM248 1 "register_operand")
7328 (match_operand:SWIM248 2 "nonimmediate_operand")))
7329 (set (match_operand:SWIM248 3 "register_operand")
7330 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7331 (clobber (reg:CC FLAGS_REG))])])
7332
7333 ;; Split with 8bit unsigned divide:
7334 ;; if (dividend an divisor are in [0-255])
7335 ;; use 8bit unsigned integer divide
7336 ;; else
7337 ;; use original integer divide
7338 (define_split
7339 [(set (match_operand:SWI48 0 "register_operand")
7340 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7341 (match_operand:SWI48 3 "nonimmediate_operand")))
7342 (set (match_operand:SWI48 1 "register_operand")
7343 (umod:SWI48 (match_dup 2) (match_dup 3)))
7344 (clobber (reg:CC FLAGS_REG))]
7345 "TARGET_USE_8BIT_IDIV
7346 && TARGET_QIMODE_MATH
7347 && can_create_pseudo_p ()
7348 && !optimize_insn_for_size_p ()"
7349 [(const_int 0)]
7350 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7351
7352 (define_insn_and_split "udivmod<mode>4_1"
7353 [(set (match_operand:SWI48 0 "register_operand" "=a")
7354 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7355 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7356 (set (match_operand:SWI48 1 "register_operand" "=&d")
7357 (umod:SWI48 (match_dup 2) (match_dup 3)))
7358 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7359 (clobber (reg:CC FLAGS_REG))]
7360 ""
7361 "#"
7362 "reload_completed"
7363 [(set (match_dup 1) (const_int 0))
7364 (parallel [(set (match_dup 0)
7365 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7366 (set (match_dup 1)
7367 (umod:SWI48 (match_dup 2) (match_dup 3)))
7368 (use (match_dup 1))
7369 (clobber (reg:CC FLAGS_REG))])]
7370 ""
7371 [(set_attr "type" "multi")
7372 (set_attr "mode" "<MODE>")])
7373
7374 (define_insn_and_split "*udivmod<mode>4"
7375 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7376 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7377 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7378 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7379 (umod:SWIM248 (match_dup 2) (match_dup 3)))
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:SWIM248 (match_dup 2) (match_dup 3)))
7387 (set (match_dup 1)
7388 (umod:SWIM248 (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 "*udivmod<mode>4_noext"
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 (use (match_operand:SWIM248 4 "register_operand" "1"))
7402 (clobber (reg:CC FLAGS_REG))]
7403 ""
7404 "div{<imodesuffix>}\t%3"
7405 [(set_attr "type" "idiv")
7406 (set_attr "mode" "<MODE>")])
7407
7408 (define_expand "udivmodqi4"
7409 [(parallel [(set (match_operand:QI 0 "register_operand")
7410 (udiv:QI
7411 (match_operand:QI 1 "register_operand")
7412 (match_operand:QI 2 "nonimmediate_operand")))
7413 (set (match_operand:QI 3 "register_operand")
7414 (umod:QI (match_dup 1) (match_dup 2)))
7415 (clobber (reg:CC FLAGS_REG))])]
7416 "TARGET_QIMODE_MATH"
7417 {
7418 rtx div, mod, insn;
7419 rtx tmp0, tmp1;
7420
7421 tmp0 = gen_reg_rtx (HImode);
7422 tmp1 = gen_reg_rtx (HImode);
7423
7424 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7425 in AX. */
7426 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7427 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7428
7429 /* Extract remainder from AH. */
7430 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7431 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7432 insn = emit_move_insn (operands[3], tmp1);
7433
7434 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7435 set_unique_reg_note (insn, REG_EQUAL, mod);
7436
7437 /* Extract quotient from AL. */
7438 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7439
7440 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7441 set_unique_reg_note (insn, REG_EQUAL, div);
7442
7443 DONE;
7444 })
7445
7446 (define_insn "udivmodhiqi3"
7447 [(set (match_operand:HI 0 "register_operand" "=a")
7448 (ior:HI
7449 (ashift:HI
7450 (zero_extend:HI
7451 (truncate:QI
7452 (mod:HI (match_operand:HI 1 "register_operand" "0")
7453 (zero_extend:HI
7454 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7455 (const_int 8))
7456 (zero_extend:HI
7457 (truncate:QI
7458 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7459 (clobber (reg:CC FLAGS_REG))]
7460 "TARGET_QIMODE_MATH"
7461 "div{b}\t%2"
7462 [(set_attr "type" "idiv")
7463 (set_attr "mode" "QI")])
7464
7465 ;; We cannot use div/idiv for double division, because it causes
7466 ;; "division by zero" on the overflow and that's not what we expect
7467 ;; from truncate. Because true (non truncating) double division is
7468 ;; never generated, we can't create this insn anyway.
7469 ;
7470 ;(define_insn ""
7471 ; [(set (match_operand:SI 0 "register_operand" "=a")
7472 ; (truncate:SI
7473 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7474 ; (zero_extend:DI
7475 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7476 ; (set (match_operand:SI 3 "register_operand" "=d")
7477 ; (truncate:SI
7478 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7479 ; (clobber (reg:CC FLAGS_REG))]
7480 ; ""
7481 ; "div{l}\t{%2, %0|%0, %2}"
7482 ; [(set_attr "type" "idiv")])
7483 \f
7484 ;;- Logical AND instructions
7485
7486 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7487 ;; Note that this excludes ah.
7488
7489 (define_expand "testsi_ccno_1"
7490 [(set (reg:CCNO FLAGS_REG)
7491 (compare:CCNO
7492 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7493 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7494 (const_int 0)))])
7495
7496 (define_expand "testqi_ccz_1"
7497 [(set (reg:CCZ FLAGS_REG)
7498 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7499 (match_operand:QI 1 "nonmemory_operand"))
7500 (const_int 0)))])
7501
7502 (define_expand "testdi_ccno_1"
7503 [(set (reg:CCNO FLAGS_REG)
7504 (compare:CCNO
7505 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7506 (match_operand:DI 1 "x86_64_szext_general_operand"))
7507 (const_int 0)))]
7508 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7509
7510 (define_insn "*testdi_1"
7511 [(set (reg FLAGS_REG)
7512 (compare
7513 (and:DI
7514 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7515 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7516 (const_int 0)))]
7517 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7518 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7519 "@
7520 test{l}\t{%k1, %k0|%k0, %k1}
7521 test{l}\t{%k1, %k0|%k0, %k1}
7522 test{q}\t{%1, %0|%0, %1}
7523 test{q}\t{%1, %0|%0, %1}
7524 test{q}\t{%1, %0|%0, %1}"
7525 [(set_attr "type" "test")
7526 (set_attr "modrm" "0,1,0,1,1")
7527 (set_attr "mode" "SI,SI,DI,DI,DI")])
7528
7529 (define_insn "*testqi_1_maybe_si"
7530 [(set (reg FLAGS_REG)
7531 (compare
7532 (and:QI
7533 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7534 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7535 (const_int 0)))]
7536 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7537 && ix86_match_ccmode (insn,
7538 CONST_INT_P (operands[1])
7539 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7540 {
7541 if (which_alternative == 3)
7542 {
7543 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7544 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7545 return "test{l}\t{%1, %k0|%k0, %1}";
7546 }
7547 return "test{b}\t{%1, %0|%0, %1}";
7548 }
7549 [(set_attr "type" "test")
7550 (set_attr "modrm" "0,1,1,1")
7551 (set_attr "mode" "QI,QI,QI,SI")
7552 (set_attr "pent_pair" "uv,np,uv,np")])
7553
7554 (define_insn "*test<mode>_1"
7555 [(set (reg FLAGS_REG)
7556 (compare
7557 (and:SWI124
7558 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7559 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7560 (const_int 0)))]
7561 "ix86_match_ccmode (insn, CCNOmode)
7562 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7563 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7564 [(set_attr "type" "test")
7565 (set_attr "modrm" "0,1,1")
7566 (set_attr "mode" "<MODE>")
7567 (set_attr "pent_pair" "uv,np,uv")])
7568
7569 (define_expand "testqi_ext_ccno_0"
7570 [(set (reg:CCNO FLAGS_REG)
7571 (compare:CCNO
7572 (and:SI
7573 (zero_extract:SI
7574 (match_operand 0 "ext_register_operand")
7575 (const_int 8)
7576 (const_int 8))
7577 (match_operand 1 "const_int_operand"))
7578 (const_int 0)))])
7579
7580 (define_insn "*testqi_ext_0"
7581 [(set (reg FLAGS_REG)
7582 (compare
7583 (and:SI
7584 (zero_extract:SI
7585 (match_operand 0 "ext_register_operand" "Q")
7586 (const_int 8)
7587 (const_int 8))
7588 (match_operand 1 "const_int_operand" "n"))
7589 (const_int 0)))]
7590 "ix86_match_ccmode (insn, CCNOmode)"
7591 "test{b}\t{%1, %h0|%h0, %1}"
7592 [(set_attr "type" "test")
7593 (set_attr "mode" "QI")
7594 (set_attr "length_immediate" "1")
7595 (set_attr "modrm" "1")
7596 (set_attr "pent_pair" "np")])
7597
7598 (define_insn "*testqi_ext_1"
7599 [(set (reg FLAGS_REG)
7600 (compare
7601 (and:SI
7602 (zero_extract:SI
7603 (match_operand 0 "ext_register_operand" "Q,Q")
7604 (const_int 8)
7605 (const_int 8))
7606 (zero_extend:SI
7607 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7608 (const_int 0)))]
7609 "ix86_match_ccmode (insn, CCNOmode)"
7610 "test{b}\t{%1, %h0|%h0, %1}"
7611 [(set_attr "isa" "*,nox64")
7612 (set_attr "type" "test")
7613 (set_attr "mode" "QI")])
7614
7615 (define_insn "*testqi_ext_2"
7616 [(set (reg FLAGS_REG)
7617 (compare
7618 (and:SI
7619 (zero_extract:SI
7620 (match_operand 0 "ext_register_operand" "Q")
7621 (const_int 8)
7622 (const_int 8))
7623 (zero_extract:SI
7624 (match_operand 1 "ext_register_operand" "Q")
7625 (const_int 8)
7626 (const_int 8)))
7627 (const_int 0)))]
7628 "ix86_match_ccmode (insn, CCNOmode)"
7629 "test{b}\t{%h1, %h0|%h0, %h1}"
7630 [(set_attr "type" "test")
7631 (set_attr "mode" "QI")])
7632
7633 ;; Combine likes to form bit extractions for some tests. Humor it.
7634 (define_insn "*testqi_ext_3"
7635 [(set (reg FLAGS_REG)
7636 (compare (zero_extract:SWI48
7637 (match_operand 0 "nonimmediate_operand" "rm")
7638 (match_operand:SWI48 1 "const_int_operand")
7639 (match_operand:SWI48 2 "const_int_operand"))
7640 (const_int 0)))]
7641 "ix86_match_ccmode (insn, CCNOmode)
7642 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7643 || GET_MODE (operands[0]) == SImode
7644 || GET_MODE (operands[0]) == HImode
7645 || GET_MODE (operands[0]) == QImode)
7646 /* Ensure that resulting mask is zero or sign extended operand. */
7647 && INTVAL (operands[2]) >= 0
7648 && ((INTVAL (operands[1]) > 0
7649 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7650 || (<MODE>mode == DImode
7651 && INTVAL (operands[1]) > 32
7652 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7653 "#")
7654
7655 (define_split
7656 [(set (match_operand 0 "flags_reg_operand")
7657 (match_operator 1 "compare_operator"
7658 [(zero_extract
7659 (match_operand 2 "nonimmediate_operand")
7660 (match_operand 3 "const_int_operand")
7661 (match_operand 4 "const_int_operand"))
7662 (const_int 0)]))]
7663 "ix86_match_ccmode (insn, CCNOmode)"
7664 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7665 {
7666 rtx val = operands[2];
7667 HOST_WIDE_INT len = INTVAL (operands[3]);
7668 HOST_WIDE_INT pos = INTVAL (operands[4]);
7669 HOST_WIDE_INT mask;
7670 enum machine_mode mode, submode;
7671
7672 mode = GET_MODE (val);
7673 if (MEM_P (val))
7674 {
7675 /* ??? Combine likes to put non-volatile mem extractions in QImode
7676 no matter the size of the test. So find a mode that works. */
7677 if (! MEM_VOLATILE_P (val))
7678 {
7679 mode = smallest_mode_for_size (pos + len, MODE_INT);
7680 val = adjust_address (val, mode, 0);
7681 }
7682 }
7683 else if (GET_CODE (val) == SUBREG
7684 && (submode = GET_MODE (SUBREG_REG (val)),
7685 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7686 && pos + len <= GET_MODE_BITSIZE (submode)
7687 && GET_MODE_CLASS (submode) == MODE_INT)
7688 {
7689 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7690 mode = submode;
7691 val = SUBREG_REG (val);
7692 }
7693 else if (mode == HImode && pos + len <= 8)
7694 {
7695 /* Small HImode tests can be converted to QImode. */
7696 mode = QImode;
7697 val = gen_lowpart (QImode, val);
7698 }
7699
7700 if (len == HOST_BITS_PER_WIDE_INT)
7701 mask = -1;
7702 else
7703 mask = ((HOST_WIDE_INT)1 << len) - 1;
7704 mask <<= pos;
7705
7706 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7707 })
7708
7709 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7710 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7711 ;; this is relatively important trick.
7712 ;; Do the conversion only post-reload to avoid limiting of the register class
7713 ;; to QI regs.
7714 (define_split
7715 [(set (match_operand 0 "flags_reg_operand")
7716 (match_operator 1 "compare_operator"
7717 [(and (match_operand 2 "register_operand")
7718 (match_operand 3 "const_int_operand"))
7719 (const_int 0)]))]
7720 "reload_completed
7721 && QI_REG_P (operands[2])
7722 && GET_MODE (operands[2]) != QImode
7723 && ((ix86_match_ccmode (insn, CCZmode)
7724 && !(INTVAL (operands[3]) & ~(255 << 8)))
7725 || (ix86_match_ccmode (insn, CCNOmode)
7726 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7727 [(set (match_dup 0)
7728 (match_op_dup 1
7729 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7730 (match_dup 3))
7731 (const_int 0)]))]
7732 {
7733 operands[2] = gen_lowpart (SImode, operands[2]);
7734 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7735 })
7736
7737 (define_split
7738 [(set (match_operand 0 "flags_reg_operand")
7739 (match_operator 1 "compare_operator"
7740 [(and (match_operand 2 "nonimmediate_operand")
7741 (match_operand 3 "const_int_operand"))
7742 (const_int 0)]))]
7743 "reload_completed
7744 && GET_MODE (operands[2]) != QImode
7745 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7746 && ((ix86_match_ccmode (insn, CCZmode)
7747 && !(INTVAL (operands[3]) & ~255))
7748 || (ix86_match_ccmode (insn, CCNOmode)
7749 && !(INTVAL (operands[3]) & ~127)))"
7750 [(set (match_dup 0)
7751 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7752 (const_int 0)]))]
7753 {
7754 operands[2] = gen_lowpart (QImode, operands[2]);
7755 operands[3] = gen_lowpart (QImode, operands[3]);
7756 })
7757
7758 (define_split
7759 [(set (match_operand:SWI12 0 "mask_reg_operand")
7760 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand")
7761 (match_operand:SWI12 2 "mask_reg_operand")))
7762 (clobber (reg:CC FLAGS_REG))]
7763 "TARGET_AVX512F && reload_completed"
7764 [(set (match_dup 0)
7765 (any_logic:SWI12 (match_dup 1)
7766 (match_dup 2)))])
7767
7768 (define_insn "*k<logic><mode>"
7769 [(set (match_operand:SWI12 0 "mask_reg_operand" "=Yk")
7770 (any_logic:SWI12 (match_operand:SWI12 1 "mask_reg_operand" "Yk")
7771 (match_operand:SWI12 2 "mask_reg_operand" "Yk")))]
7772 "TARGET_AVX512F"
7773 "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7774 [(set_attr "mode" "<MODE>")
7775 (set_attr "type" "msklog")
7776 (set_attr "prefix" "vex")])
7777
7778 ;; %%% This used to optimize known byte-wide and operations to memory,
7779 ;; and sometimes to QImode registers. If this is considered useful,
7780 ;; it should be done with splitters.
7781
7782 (define_expand "and<mode>3"
7783 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7784 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7785 (match_operand:SWIM 2 "<general_szext_operand>")))]
7786 ""
7787 {
7788 enum machine_mode mode = <MODE>mode;
7789 rtx (*insn) (rtx, rtx);
7790
7791 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7792 {
7793 HOST_WIDE_INT ival = INTVAL (operands[2]);
7794
7795 if (ival == (HOST_WIDE_INT) 0xffffffff)
7796 mode = SImode;
7797 else if (ival == 0xffff)
7798 mode = HImode;
7799 else if (ival == 0xff)
7800 mode = QImode;
7801 }
7802
7803 if (mode == <MODE>mode)
7804 {
7805 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7806 DONE;
7807 }
7808
7809 if (<MODE>mode == DImode)
7810 insn = (mode == SImode)
7811 ? gen_zero_extendsidi2
7812 : (mode == HImode)
7813 ? gen_zero_extendhidi2
7814 : gen_zero_extendqidi2;
7815 else if (<MODE>mode == SImode)
7816 insn = (mode == HImode)
7817 ? gen_zero_extendhisi2
7818 : gen_zero_extendqisi2;
7819 else if (<MODE>mode == HImode)
7820 insn = gen_zero_extendqihi2;
7821 else
7822 gcc_unreachable ();
7823
7824 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7825 DONE;
7826 })
7827
7828 (define_insn "*anddi_1"
7829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7830 (and:DI
7831 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7832 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7833 (clobber (reg:CC FLAGS_REG))]
7834 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7835 {
7836 switch (get_attr_type (insn))
7837 {
7838 case TYPE_IMOVX:
7839 return "#";
7840
7841 default:
7842 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7843 if (get_attr_mode (insn) == MODE_SI)
7844 return "and{l}\t{%k2, %k0|%k0, %k2}";
7845 else
7846 return "and{q}\t{%2, %0|%0, %2}";
7847 }
7848 }
7849 [(set_attr "type" "alu,alu,alu,imovx")
7850 (set_attr "length_immediate" "*,*,*,0")
7851 (set (attr "prefix_rex")
7852 (if_then_else
7853 (and (eq_attr "type" "imovx")
7854 (and (match_test "INTVAL (operands[2]) == 0xff")
7855 (match_operand 1 "ext_QIreg_operand")))
7856 (const_string "1")
7857 (const_string "*")))
7858 (set_attr "mode" "SI,DI,DI,SI")])
7859
7860 (define_insn "*andsi_1"
7861 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7862 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7863 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7864 (clobber (reg:CC FLAGS_REG))]
7865 "ix86_binary_operator_ok (AND, SImode, operands)"
7866 {
7867 switch (get_attr_type (insn))
7868 {
7869 case TYPE_IMOVX:
7870 return "#";
7871
7872 default:
7873 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7874 return "and{l}\t{%2, %0|%0, %2}";
7875 }
7876 }
7877 [(set_attr "type" "alu,alu,imovx")
7878 (set (attr "prefix_rex")
7879 (if_then_else
7880 (and (eq_attr "type" "imovx")
7881 (and (match_test "INTVAL (operands[2]) == 0xff")
7882 (match_operand 1 "ext_QIreg_operand")))
7883 (const_string "1")
7884 (const_string "*")))
7885 (set_attr "length_immediate" "*,*,0")
7886 (set_attr "mode" "SI")])
7887
7888 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7889 (define_insn "*andsi_1_zext"
7890 [(set (match_operand:DI 0 "register_operand" "=r")
7891 (zero_extend:DI
7892 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7893 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7896 "and{l}\t{%2, %k0|%k0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "SI")])
7899
7900 (define_insn "*andhi_1"
7901 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!Yk")
7902 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,Yk")
7903 (match_operand:HI 2 "general_operand" "rn,rm,L,Yk")))
7904 (clobber (reg:CC FLAGS_REG))]
7905 "ix86_binary_operator_ok (AND, HImode, operands)"
7906 {
7907 switch (get_attr_type (insn))
7908 {
7909 case TYPE_IMOVX:
7910 return "#";
7911
7912 case TYPE_MSKLOG:
7913 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7914
7915 default:
7916 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7917 return "and{w}\t{%2, %0|%0, %2}";
7918 }
7919 }
7920 [(set_attr "type" "alu,alu,imovx,msklog")
7921 (set_attr "length_immediate" "*,*,0,*")
7922 (set (attr "prefix_rex")
7923 (if_then_else
7924 (and (eq_attr "type" "imovx")
7925 (match_operand 1 "ext_QIreg_operand"))
7926 (const_string "1")
7927 (const_string "*")))
7928 (set_attr "mode" "HI,HI,SI,HI")])
7929
7930 ;; %%% Potential partial reg stall on alternative 2. What to do?
7931 (define_insn "*andqi_1"
7932 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!Yk")
7933 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
7934 (match_operand:QI 2 "general_operand" "qn,qmn,rn,Yk")))
7935 (clobber (reg:CC FLAGS_REG))]
7936 "ix86_binary_operator_ok (AND, QImode, operands)"
7937 "@
7938 and{b}\t{%2, %0|%0, %2}
7939 and{b}\t{%2, %0|%0, %2}
7940 and{l}\t{%k2, %k0|%k0, %k2}
7941 kandw\t{%2, %1, %0|%0, %1, %2}"
7942 [(set_attr "type" "alu,alu,alu,msklog")
7943 (set_attr "mode" "QI,QI,SI,HI")])
7944
7945 (define_insn "*andqi_1_slp"
7946 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7947 (and:QI (match_dup 0)
7948 (match_operand:QI 1 "general_operand" "qn,qmn")))
7949 (clobber (reg:CC FLAGS_REG))]
7950 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7951 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7952 "and{b}\t{%1, %0|%0, %1}"
7953 [(set_attr "type" "alu1")
7954 (set_attr "mode" "QI")])
7955
7956 (define_insn "kandn<mode>"
7957 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!Yk")
7958 (and:SWI12
7959 (not:SWI12
7960 (match_operand:SWI12 1 "register_operand" "r,0,Yk"))
7961 (match_operand:SWI12 2 "register_operand" "r,r,Yk")))
7962 (clobber (reg:CC FLAGS_REG))]
7963 "TARGET_AVX512F"
7964 "@
7965 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
7966 #
7967 kandnw\t{%2, %1, %0|%0, %1, %2}"
7968 [(set_attr "isa" "bmi,*,avx512f")
7969 (set_attr "type" "bitmanip,*,msklog")
7970 (set_attr "prefix" "*,*,vex")
7971 (set_attr "btver2_decode" "direct,*,*")
7972 (set_attr "mode" "<MODE>")])
7973
7974 (define_split
7975 [(set (match_operand:SWI12 0 "general_reg_operand")
7976 (and:SWI12
7977 (not:SWI12
7978 (match_dup 0))
7979 (match_operand:SWI12 1 "general_reg_operand")))
7980 (clobber (reg:CC FLAGS_REG))]
7981 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7982 [(set (match_dup 0)
7983 (not:HI (match_dup 0)))
7984 (parallel [(set (match_dup 0)
7985 (and:HI (match_dup 0)
7986 (match_dup 1)))
7987 (clobber (reg:CC FLAGS_REG))])])
7988
7989 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7990 (define_split
7991 [(set (match_operand:DI 0 "register_operand")
7992 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7993 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7994 (clobber (reg:CC FLAGS_REG))]
7995 "TARGET_64BIT"
7996 [(parallel [(set (match_dup 0)
7997 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7998 (clobber (reg:CC FLAGS_REG))])]
7999 "operands[2] = gen_lowpart (SImode, operands[2]);")
8000
8001 (define_split
8002 [(set (match_operand:SWI248 0 "register_operand")
8003 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8004 (match_operand:SWI248 2 "const_int_operand")))
8005 (clobber (reg:CC FLAGS_REG))]
8006 "reload_completed
8007 && true_regnum (operands[0]) != true_regnum (operands[1])"
8008 [(const_int 0)]
8009 {
8010 HOST_WIDE_INT ival = INTVAL (operands[2]);
8011 enum machine_mode mode;
8012 rtx (*insn) (rtx, rtx);
8013
8014 if (ival == (HOST_WIDE_INT) 0xffffffff)
8015 mode = SImode;
8016 else if (ival == 0xffff)
8017 mode = HImode;
8018 else
8019 {
8020 gcc_assert (ival == 0xff);
8021 mode = QImode;
8022 }
8023
8024 if (<MODE>mode == DImode)
8025 insn = (mode == SImode)
8026 ? gen_zero_extendsidi2
8027 : (mode == HImode)
8028 ? gen_zero_extendhidi2
8029 : gen_zero_extendqidi2;
8030 else
8031 {
8032 if (<MODE>mode != SImode)
8033 /* Zero extend to SImode to avoid partial register stalls. */
8034 operands[0] = gen_lowpart (SImode, operands[0]);
8035
8036 insn = (mode == HImode)
8037 ? gen_zero_extendhisi2
8038 : gen_zero_extendqisi2;
8039 }
8040 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8041 DONE;
8042 })
8043
8044 (define_split
8045 [(set (match_operand 0 "register_operand")
8046 (and (match_dup 0)
8047 (const_int -65536)))
8048 (clobber (reg:CC FLAGS_REG))]
8049 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8050 || optimize_function_for_size_p (cfun)"
8051 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8052 "operands[1] = gen_lowpart (HImode, operands[0]);")
8053
8054 (define_split
8055 [(set (match_operand 0 "ext_register_operand")
8056 (and (match_dup 0)
8057 (const_int -256)))
8058 (clobber (reg:CC FLAGS_REG))]
8059 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8060 && reload_completed"
8061 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8062 "operands[1] = gen_lowpart (QImode, operands[0]);")
8063
8064 (define_split
8065 [(set (match_operand 0 "ext_register_operand")
8066 (and (match_dup 0)
8067 (const_int -65281)))
8068 (clobber (reg:CC FLAGS_REG))]
8069 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8070 && reload_completed"
8071 [(parallel [(set (zero_extract:SI (match_dup 0)
8072 (const_int 8)
8073 (const_int 8))
8074 (xor:SI
8075 (zero_extract:SI (match_dup 0)
8076 (const_int 8)
8077 (const_int 8))
8078 (zero_extract:SI (match_dup 0)
8079 (const_int 8)
8080 (const_int 8))))
8081 (clobber (reg:CC FLAGS_REG))])]
8082 "operands[0] = gen_lowpart (SImode, operands[0]);")
8083
8084 (define_insn "*anddi_2"
8085 [(set (reg FLAGS_REG)
8086 (compare
8087 (and:DI
8088 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8089 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8090 (const_int 0)))
8091 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8092 (and:DI (match_dup 1) (match_dup 2)))]
8093 "TARGET_64BIT
8094 && ix86_match_ccmode
8095 (insn,
8096 /* If we are going to emit andl instead of andq, and the operands[2]
8097 constant might have the SImode sign bit set, make sure the sign
8098 flag isn't tested, because the instruction will set the sign flag
8099 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8100 conservatively assume it might have bit 31 set. */
8101 (satisfies_constraint_Z (operands[2])
8102 && (!CONST_INT_P (operands[2])
8103 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8104 ? CCZmode : CCNOmode)
8105 && ix86_binary_operator_ok (AND, DImode, operands)"
8106 "@
8107 and{l}\t{%k2, %k0|%k0, %k2}
8108 and{q}\t{%2, %0|%0, %2}
8109 and{q}\t{%2, %0|%0, %2}"
8110 [(set_attr "type" "alu")
8111 (set_attr "mode" "SI,DI,DI")])
8112
8113 (define_insn "*andqi_2_maybe_si"
8114 [(set (reg FLAGS_REG)
8115 (compare (and:QI
8116 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8117 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8118 (const_int 0)))
8119 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8120 (and:QI (match_dup 1) (match_dup 2)))]
8121 "ix86_binary_operator_ok (AND, QImode, operands)
8122 && ix86_match_ccmode (insn,
8123 CONST_INT_P (operands[2])
8124 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8125 {
8126 if (which_alternative == 2)
8127 {
8128 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8129 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8130 return "and{l}\t{%2, %k0|%k0, %2}";
8131 }
8132 return "and{b}\t{%2, %0|%0, %2}";
8133 }
8134 [(set_attr "type" "alu")
8135 (set_attr "mode" "QI,QI,SI")])
8136
8137 (define_insn "*and<mode>_2"
8138 [(set (reg FLAGS_REG)
8139 (compare (and:SWI124
8140 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8141 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8142 (const_int 0)))
8143 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8144 (and:SWI124 (match_dup 1) (match_dup 2)))]
8145 "ix86_match_ccmode (insn, CCNOmode)
8146 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8147 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8148 [(set_attr "type" "alu")
8149 (set_attr "mode" "<MODE>")])
8150
8151 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8152 (define_insn "*andsi_2_zext"
8153 [(set (reg FLAGS_REG)
8154 (compare (and:SI
8155 (match_operand:SI 1 "nonimmediate_operand" "%0")
8156 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8157 (const_int 0)))
8158 (set (match_operand:DI 0 "register_operand" "=r")
8159 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8160 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8161 && ix86_binary_operator_ok (AND, SImode, operands)"
8162 "and{l}\t{%2, %k0|%k0, %2}"
8163 [(set_attr "type" "alu")
8164 (set_attr "mode" "SI")])
8165
8166 (define_insn "*andqi_2_slp"
8167 [(set (reg FLAGS_REG)
8168 (compare (and:QI
8169 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8170 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8171 (const_int 0)))
8172 (set (strict_low_part (match_dup 0))
8173 (and:QI (match_dup 0) (match_dup 1)))]
8174 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8175 && ix86_match_ccmode (insn, CCNOmode)
8176 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8177 "and{b}\t{%1, %0|%0, %1}"
8178 [(set_attr "type" "alu1")
8179 (set_attr "mode" "QI")])
8180
8181 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8182 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8183 ;; for a QImode operand, which of course failed.
8184 (define_insn "andqi_ext_0"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8186 (const_int 8)
8187 (const_int 8))
8188 (and:SI
8189 (zero_extract:SI
8190 (match_operand 1 "ext_register_operand" "0")
8191 (const_int 8)
8192 (const_int 8))
8193 (match_operand 2 "const_int_operand" "n")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 ""
8196 "and{b}\t{%2, %h0|%h0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "length_immediate" "1")
8199 (set_attr "modrm" "1")
8200 (set_attr "mode" "QI")])
8201
8202 ;; Generated by peephole translating test to and. This shows up
8203 ;; often in fp comparisons.
8204 (define_insn "*andqi_ext_0_cc"
8205 [(set (reg FLAGS_REG)
8206 (compare
8207 (and:SI
8208 (zero_extract:SI
8209 (match_operand 1 "ext_register_operand" "0")
8210 (const_int 8)
8211 (const_int 8))
8212 (match_operand 2 "const_int_operand" "n"))
8213 (const_int 0)))
8214 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8215 (const_int 8)
8216 (const_int 8))
8217 (and:SI
8218 (zero_extract:SI
8219 (match_dup 1)
8220 (const_int 8)
8221 (const_int 8))
8222 (match_dup 2)))]
8223 "ix86_match_ccmode (insn, CCNOmode)"
8224 "and{b}\t{%2, %h0|%h0, %2}"
8225 [(set_attr "type" "alu")
8226 (set_attr "length_immediate" "1")
8227 (set_attr "modrm" "1")
8228 (set_attr "mode" "QI")])
8229
8230 (define_insn "*andqi_ext_1"
8231 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8232 (const_int 8)
8233 (const_int 8))
8234 (and:SI
8235 (zero_extract:SI
8236 (match_operand 1 "ext_register_operand" "0,0")
8237 (const_int 8)
8238 (const_int 8))
8239 (zero_extend:SI
8240 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8241 (clobber (reg:CC FLAGS_REG))]
8242 ""
8243 "and{b}\t{%2, %h0|%h0, %2}"
8244 [(set_attr "isa" "*,nox64")
8245 (set_attr "type" "alu")
8246 (set_attr "length_immediate" "0")
8247 (set_attr "mode" "QI")])
8248
8249 (define_insn "*andqi_ext_2"
8250 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8251 (const_int 8)
8252 (const_int 8))
8253 (and:SI
8254 (zero_extract:SI
8255 (match_operand 1 "ext_register_operand" "%0")
8256 (const_int 8)
8257 (const_int 8))
8258 (zero_extract:SI
8259 (match_operand 2 "ext_register_operand" "Q")
8260 (const_int 8)
8261 (const_int 8))))
8262 (clobber (reg:CC FLAGS_REG))]
8263 ""
8264 "and{b}\t{%h2, %h0|%h0, %h2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "length_immediate" "0")
8267 (set_attr "mode" "QI")])
8268
8269 ;; Convert wide AND instructions with immediate operand to shorter QImode
8270 ;; equivalents when possible.
8271 ;; Don't do the splitting with memory operands, since it introduces risk
8272 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8273 ;; for size, but that can (should?) be handled by generic code instead.
8274 (define_split
8275 [(set (match_operand 0 "register_operand")
8276 (and (match_operand 1 "register_operand")
8277 (match_operand 2 "const_int_operand")))
8278 (clobber (reg:CC FLAGS_REG))]
8279 "reload_completed
8280 && QI_REG_P (operands[0])
8281 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8282 && !(~INTVAL (operands[2]) & ~(255 << 8))
8283 && GET_MODE (operands[0]) != QImode"
8284 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8285 (and:SI (zero_extract:SI (match_dup 1)
8286 (const_int 8) (const_int 8))
8287 (match_dup 2)))
8288 (clobber (reg:CC FLAGS_REG))])]
8289 {
8290 operands[0] = gen_lowpart (SImode, operands[0]);
8291 operands[1] = gen_lowpart (SImode, operands[1]);
8292 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8293 })
8294
8295 ;; Since AND can be encoded with sign extended immediate, this is only
8296 ;; profitable when 7th bit is not set.
8297 (define_split
8298 [(set (match_operand 0 "register_operand")
8299 (and (match_operand 1 "general_operand")
8300 (match_operand 2 "const_int_operand")))
8301 (clobber (reg:CC FLAGS_REG))]
8302 "reload_completed
8303 && ANY_QI_REG_P (operands[0])
8304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8305 && !(~INTVAL (operands[2]) & ~255)
8306 && !(INTVAL (operands[2]) & 128)
8307 && GET_MODE (operands[0]) != QImode"
8308 [(parallel [(set (strict_low_part (match_dup 0))
8309 (and:QI (match_dup 1)
8310 (match_dup 2)))
8311 (clobber (reg:CC FLAGS_REG))])]
8312 {
8313 operands[0] = gen_lowpart (QImode, operands[0]);
8314 operands[1] = gen_lowpart (QImode, operands[1]);
8315 operands[2] = gen_lowpart (QImode, operands[2]);
8316 })
8317 \f
8318 ;; Logical inclusive and exclusive OR instructions
8319
8320 ;; %%% This used to optimize known byte-wide and operations to memory.
8321 ;; If this is considered useful, it should be done with splitters.
8322
8323 (define_expand "<code><mode>3"
8324 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8325 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8326 (match_operand:SWIM 2 "<general_operand>")))]
8327 ""
8328 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8329
8330 (define_insn "*<code><mode>_1"
8331 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
8332 (any_or:SWI48
8333 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
8334 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>")))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8337 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8338 [(set_attr "type" "alu")
8339 (set_attr "mode" "<MODE>")])
8340
8341 (define_insn "*<code>hi_1"
8342 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!Yk")
8343 (any_or:HI
8344 (match_operand:HI 1 "nonimmediate_operand" "%0,0,Yk")
8345 (match_operand:HI 2 "general_operand" "<g>,r<i>,Yk")))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8348 "@
8349 <logic>{w}\t{%2, %0|%0, %2}
8350 <logic>{w}\t{%2, %0|%0, %2}
8351 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8352 [(set_attr "type" "alu,alu,msklog")
8353 (set_attr "mode" "HI")])
8354
8355 ;; %%% Potential partial reg stall on alternative 2. What to do?
8356 (define_insn "*<code>qi_1"
8357 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!Yk")
8358 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,Yk")
8359 (match_operand:QI 2 "general_operand" "qmn,qn,rn,Yk")))
8360 (clobber (reg:CC FLAGS_REG))]
8361 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8362 "@
8363 <logic>{b}\t{%2, %0|%0, %2}
8364 <logic>{b}\t{%2, %0|%0, %2}
8365 <logic>{l}\t{%k2, %k0|%k0, %k2}
8366 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8367 [(set_attr "type" "alu,alu,alu,msklog")
8368 (set_attr "mode" "QI,QI,SI,HI")])
8369
8370 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8371 (define_insn "*<code>si_1_zext"
8372 [(set (match_operand:DI 0 "register_operand" "=r")
8373 (zero_extend:DI
8374 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8375 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8376 (clobber (reg:CC FLAGS_REG))]
8377 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8378 "<logic>{l}\t{%2, %k0|%k0, %2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "mode" "SI")])
8381
8382 (define_insn "*<code>si_1_zext_imm"
8383 [(set (match_operand:DI 0 "register_operand" "=r")
8384 (any_or:DI
8385 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8386 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8387 (clobber (reg:CC FLAGS_REG))]
8388 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8389 "<logic>{l}\t{%2, %k0|%k0, %2}"
8390 [(set_attr "type" "alu")
8391 (set_attr "mode" "SI")])
8392
8393 (define_insn "*<code>qi_1_slp"
8394 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8395 (any_or:QI (match_dup 0)
8396 (match_operand:QI 1 "general_operand" "qmn,qn")))
8397 (clobber (reg:CC FLAGS_REG))]
8398 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8400 "<logic>{b}\t{%1, %0|%0, %1}"
8401 [(set_attr "type" "alu1")
8402 (set_attr "mode" "QI")])
8403
8404 (define_insn "*<code><mode>_2"
8405 [(set (reg FLAGS_REG)
8406 (compare (any_or:SWI
8407 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8408 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8409 (const_int 0)))
8410 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8411 (any_or:SWI (match_dup 1) (match_dup 2)))]
8412 "ix86_match_ccmode (insn, CCNOmode)
8413 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8414 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "mode" "<MODE>")])
8417
8418 (define_insn "kxnor<mode>"
8419 [(set (match_operand:SWI12 0 "register_operand" "=r,!Yk")
8420 (not:SWI12
8421 (xor:SWI12
8422 (match_operand:SWI12 1 "register_operand" "0,Yk")
8423 (match_operand:SWI12 2 "register_operand" "r,Yk"))))
8424 (clobber (reg:CC FLAGS_REG))]
8425 "TARGET_AVX512F"
8426 "@
8427 #
8428 kxnorw\t{%2, %1, %0|%0, %1, %2}"
8429 [(set_attr "type" "*,msklog")
8430 (set_attr "prefix" "*,vex")
8431 (set_attr "mode" "<MODE>")])
8432
8433 (define_split
8434 [(set (match_operand:SWI12 0 "general_reg_operand")
8435 (not:SWI12
8436 (xor:SWI12
8437 (match_dup 0)
8438 (match_operand:SWI12 1 "general_reg_operand"))))
8439 (clobber (reg:CC FLAGS_REG))]
8440 "TARGET_AVX512F && reload_completed"
8441 [(parallel [(set (match_dup 0)
8442 (xor:HI (match_dup 0)
8443 (match_dup 1)))
8444 (clobber (reg:CC FLAGS_REG))])
8445 (set (match_dup 0)
8446 (not:HI (match_dup 0)))])
8447
8448 (define_insn "kortestzhi"
8449 [(set (reg:CCZ FLAGS_REG)
8450 (compare:CCZ
8451 (ior:HI
8452 (match_operand:HI 0 "register_operand" "Yk")
8453 (match_operand:HI 1 "register_operand" "Yk"))
8454 (const_int 0)))]
8455 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8456 "kortestw\t{%1, %0|%0, %1}"
8457 [(set_attr "mode" "HI")
8458 (set_attr "type" "msklog")
8459 (set_attr "prefix" "vex")])
8460
8461 (define_insn "kortestchi"
8462 [(set (reg:CCC FLAGS_REG)
8463 (compare:CCC
8464 (ior:HI
8465 (match_operand:HI 0 "register_operand" "Yk")
8466 (match_operand:HI 1 "register_operand" "Yk"))
8467 (const_int -1)))]
8468 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8469 "kortestw\t{%1, %0|%0, %1}"
8470 [(set_attr "mode" "HI")
8471 (set_attr "type" "msklog")
8472 (set_attr "prefix" "vex")])
8473
8474 (define_insn "kunpckhi"
8475 [(set (match_operand:HI 0 "register_operand" "=Yk")
8476 (ior:HI
8477 (ashift:HI
8478 (match_operand:HI 1 "register_operand" "Yk")
8479 (const_int 8))
8480 (zero_extend:HI (match_operand:QI 2 "register_operand" "Yk"))))]
8481 "TARGET_AVX512F"
8482 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8483 [(set_attr "mode" "HI")
8484 (set_attr "type" "msklog")
8485 (set_attr "prefix" "vex")])
8486
8487 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8488 ;; ??? Special case for immediate operand is missing - it is tricky.
8489 (define_insn "*<code>si_2_zext"
8490 [(set (reg FLAGS_REG)
8491 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8492 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8493 (const_int 0)))
8494 (set (match_operand:DI 0 "register_operand" "=r")
8495 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8496 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8497 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8498 "<logic>{l}\t{%2, %k0|%k0, %2}"
8499 [(set_attr "type" "alu")
8500 (set_attr "mode" "SI")])
8501
8502 (define_insn "*<code>si_2_zext_imm"
8503 [(set (reg FLAGS_REG)
8504 (compare (any_or:SI
8505 (match_operand:SI 1 "nonimmediate_operand" "%0")
8506 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8507 (const_int 0)))
8508 (set (match_operand:DI 0 "register_operand" "=r")
8509 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8510 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8511 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8512 "<logic>{l}\t{%2, %k0|%k0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "mode" "SI")])
8515
8516 (define_insn "*<code>qi_2_slp"
8517 [(set (reg FLAGS_REG)
8518 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8519 (match_operand:QI 1 "general_operand" "qmn,qn"))
8520 (const_int 0)))
8521 (set (strict_low_part (match_dup 0))
8522 (any_or:QI (match_dup 0) (match_dup 1)))]
8523 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8524 && ix86_match_ccmode (insn, CCNOmode)
8525 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8526 "<logic>{b}\t{%1, %0|%0, %1}"
8527 [(set_attr "type" "alu1")
8528 (set_attr "mode" "QI")])
8529
8530 (define_insn "*<code><mode>_3"
8531 [(set (reg FLAGS_REG)
8532 (compare (any_or:SWI
8533 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8534 (match_operand:SWI 2 "<general_operand>" "<g>"))
8535 (const_int 0)))
8536 (clobber (match_scratch:SWI 0 "=<r>"))]
8537 "ix86_match_ccmode (insn, CCNOmode)
8538 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8539 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8540 [(set_attr "type" "alu")
8541 (set_attr "mode" "<MODE>")])
8542
8543 (define_insn "*<code>qi_ext_0"
8544 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8545 (const_int 8)
8546 (const_int 8))
8547 (any_or:SI
8548 (zero_extract:SI
8549 (match_operand 1 "ext_register_operand" "0")
8550 (const_int 8)
8551 (const_int 8))
8552 (match_operand 2 "const_int_operand" "n")))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8555 "<logic>{b}\t{%2, %h0|%h0, %2}"
8556 [(set_attr "type" "alu")
8557 (set_attr "length_immediate" "1")
8558 (set_attr "modrm" "1")
8559 (set_attr "mode" "QI")])
8560
8561 (define_insn "*<code>qi_ext_1"
8562 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8563 (const_int 8)
8564 (const_int 8))
8565 (any_or:SI
8566 (zero_extract:SI
8567 (match_operand 1 "ext_register_operand" "0,0")
8568 (const_int 8)
8569 (const_int 8))
8570 (zero_extend:SI
8571 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8574 "<logic>{b}\t{%2, %h0|%h0, %2}"
8575 [(set_attr "isa" "*,nox64")
8576 (set_attr "type" "alu")
8577 (set_attr "length_immediate" "0")
8578 (set_attr "mode" "QI")])
8579
8580 (define_insn "*<code>qi_ext_2"
8581 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8582 (const_int 8)
8583 (const_int 8))
8584 (any_or:SI
8585 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8586 (const_int 8)
8587 (const_int 8))
8588 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8589 (const_int 8)
8590 (const_int 8))))
8591 (clobber (reg:CC FLAGS_REG))]
8592 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8593 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8594 [(set_attr "type" "alu")
8595 (set_attr "length_immediate" "0")
8596 (set_attr "mode" "QI")])
8597
8598 (define_split
8599 [(set (match_operand 0 "register_operand")
8600 (any_or (match_operand 1 "register_operand")
8601 (match_operand 2 "const_int_operand")))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "reload_completed
8604 && QI_REG_P (operands[0])
8605 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8606 && !(INTVAL (operands[2]) & ~(255 << 8))
8607 && GET_MODE (operands[0]) != QImode"
8608 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8609 (any_or:SI (zero_extract:SI (match_dup 1)
8610 (const_int 8) (const_int 8))
8611 (match_dup 2)))
8612 (clobber (reg:CC FLAGS_REG))])]
8613 {
8614 operands[0] = gen_lowpart (SImode, operands[0]);
8615 operands[1] = gen_lowpart (SImode, operands[1]);
8616 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8617 })
8618
8619 ;; Since OR can be encoded with sign extended immediate, this is only
8620 ;; profitable when 7th bit is set.
8621 (define_split
8622 [(set (match_operand 0 "register_operand")
8623 (any_or (match_operand 1 "general_operand")
8624 (match_operand 2 "const_int_operand")))
8625 (clobber (reg:CC FLAGS_REG))]
8626 "reload_completed
8627 && ANY_QI_REG_P (operands[0])
8628 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8629 && !(INTVAL (operands[2]) & ~255)
8630 && (INTVAL (operands[2]) & 128)
8631 && GET_MODE (operands[0]) != QImode"
8632 [(parallel [(set (strict_low_part (match_dup 0))
8633 (any_or:QI (match_dup 1)
8634 (match_dup 2)))
8635 (clobber (reg:CC FLAGS_REG))])]
8636 {
8637 operands[0] = gen_lowpart (QImode, operands[0]);
8638 operands[1] = gen_lowpart (QImode, operands[1]);
8639 operands[2] = gen_lowpart (QImode, operands[2]);
8640 })
8641
8642 (define_expand "xorqi_cc_ext_1"
8643 [(parallel [
8644 (set (reg:CCNO FLAGS_REG)
8645 (compare:CCNO
8646 (xor:SI
8647 (zero_extract:SI
8648 (match_operand 1 "ext_register_operand")
8649 (const_int 8)
8650 (const_int 8))
8651 (match_operand:QI 2 "const_int_operand"))
8652 (const_int 0)))
8653 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8654 (const_int 8)
8655 (const_int 8))
8656 (xor:SI
8657 (zero_extract:SI
8658 (match_dup 1)
8659 (const_int 8)
8660 (const_int 8))
8661 (match_dup 2)))])])
8662
8663 (define_insn "*xorqi_cc_ext_1"
8664 [(set (reg FLAGS_REG)
8665 (compare
8666 (xor:SI
8667 (zero_extract:SI
8668 (match_operand 1 "ext_register_operand" "0,0")
8669 (const_int 8)
8670 (const_int 8))
8671 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8672 (const_int 0)))
8673 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8674 (const_int 8)
8675 (const_int 8))
8676 (xor:SI
8677 (zero_extract:SI
8678 (match_dup 1)
8679 (const_int 8)
8680 (const_int 8))
8681 (match_dup 2)))]
8682 "ix86_match_ccmode (insn, CCNOmode)"
8683 "xor{b}\t{%2, %h0|%h0, %2}"
8684 [(set_attr "isa" "*,nox64")
8685 (set_attr "type" "alu")
8686 (set_attr "modrm" "1")
8687 (set_attr "mode" "QI")])
8688 \f
8689 ;; Negation instructions
8690
8691 (define_expand "neg<mode>2"
8692 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8693 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8694 ""
8695 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8696
8697 (define_insn_and_split "*neg<dwi>2_doubleword"
8698 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8699 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8700 (clobber (reg:CC FLAGS_REG))]
8701 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8702 "#"
8703 "reload_completed"
8704 [(parallel
8705 [(set (reg:CCZ FLAGS_REG)
8706 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8707 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8708 (parallel
8709 [(set (match_dup 2)
8710 (plus:DWIH (match_dup 3)
8711 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8712 (const_int 0))))
8713 (clobber (reg:CC FLAGS_REG))])
8714 (parallel
8715 [(set (match_dup 2)
8716 (neg:DWIH (match_dup 2)))
8717 (clobber (reg:CC FLAGS_REG))])]
8718 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8719
8720 (define_insn "*neg<mode>2_1"
8721 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8723 (clobber (reg:CC FLAGS_REG))]
8724 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8725 "neg{<imodesuffix>}\t%0"
8726 [(set_attr "type" "negnot")
8727 (set_attr "mode" "<MODE>")])
8728
8729 ;; Combine is quite creative about this pattern.
8730 (define_insn "*negsi2_1_zext"
8731 [(set (match_operand:DI 0 "register_operand" "=r")
8732 (lshiftrt:DI
8733 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8734 (const_int 32)))
8735 (const_int 32)))
8736 (clobber (reg:CC FLAGS_REG))]
8737 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8738 "neg{l}\t%k0"
8739 [(set_attr "type" "negnot")
8740 (set_attr "mode" "SI")])
8741
8742 ;; The problem with neg is that it does not perform (compare x 0),
8743 ;; it really performs (compare 0 x), which leaves us with the zero
8744 ;; flag being the only useful item.
8745
8746 (define_insn "*neg<mode>2_cmpz"
8747 [(set (reg:CCZ FLAGS_REG)
8748 (compare:CCZ
8749 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8750 (const_int 0)))
8751 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8752 (neg:SWI (match_dup 1)))]
8753 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8754 "neg{<imodesuffix>}\t%0"
8755 [(set_attr "type" "negnot")
8756 (set_attr "mode" "<MODE>")])
8757
8758 (define_insn "*negsi2_cmpz_zext"
8759 [(set (reg:CCZ FLAGS_REG)
8760 (compare:CCZ
8761 (lshiftrt:DI
8762 (neg:DI (ashift:DI
8763 (match_operand:DI 1 "register_operand" "0")
8764 (const_int 32)))
8765 (const_int 32))
8766 (const_int 0)))
8767 (set (match_operand:DI 0 "register_operand" "=r")
8768 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8769 (const_int 32)))
8770 (const_int 32)))]
8771 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8772 "neg{l}\t%k0"
8773 [(set_attr "type" "negnot")
8774 (set_attr "mode" "SI")])
8775
8776 ;; Negate with jump on overflow.
8777 (define_expand "negv<mode>3"
8778 [(parallel [(set (reg:CCO FLAGS_REG)
8779 (ne:CCO (match_operand:SWI 1 "register_operand")
8780 (match_dup 3)))
8781 (set (match_operand:SWI 0 "register_operand")
8782 (neg:SWI (match_dup 1)))])
8783 (set (pc) (if_then_else
8784 (eq (reg:CCO FLAGS_REG) (const_int 0))
8785 (label_ref (match_operand 2))
8786 (pc)))]
8787 ""
8788 {
8789 operands[3]
8790 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8791 <MODE>mode);
8792 })
8793
8794 (define_insn "*negv<mode>3"
8795 [(set (reg:CCO FLAGS_REG)
8796 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8797 (match_operand:SWI 2 "const_int_operand")))
8798 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8799 (neg:SWI (match_dup 1)))]
8800 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8801 && mode_signbit_p (<MODE>mode, operands[2])"
8802 "neg{<imodesuffix>}\t%0"
8803 [(set_attr "type" "negnot")
8804 (set_attr "mode" "<MODE>")])
8805
8806 ;; Changing of sign for FP values is doable using integer unit too.
8807
8808 (define_expand "<code><mode>2"
8809 [(set (match_operand:X87MODEF 0 "register_operand")
8810 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8811 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8812 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8813
8814 (define_insn "*absneg<mode>2_mixed"
8815 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8816 (match_operator:MODEF 3 "absneg_operator"
8817 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8818 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8819 (clobber (reg:CC FLAGS_REG))]
8820 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8821 "#")
8822
8823 (define_insn "*absneg<mode>2_sse"
8824 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8825 (match_operator:MODEF 3 "absneg_operator"
8826 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8827 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8828 (clobber (reg:CC FLAGS_REG))]
8829 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8830 "#")
8831
8832 (define_insn "*absneg<mode>2_i387"
8833 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8834 (match_operator:X87MODEF 3 "absneg_operator"
8835 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8836 (use (match_operand 2))
8837 (clobber (reg:CC FLAGS_REG))]
8838 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8839 "#")
8840
8841 (define_expand "<code>tf2"
8842 [(set (match_operand:TF 0 "register_operand")
8843 (absneg:TF (match_operand:TF 1 "register_operand")))]
8844 "TARGET_SSE"
8845 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8846
8847 (define_insn "*absnegtf2_sse"
8848 [(set (match_operand:TF 0 "register_operand" "=x,x")
8849 (match_operator:TF 3 "absneg_operator"
8850 [(match_operand:TF 1 "register_operand" "0,x")]))
8851 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8852 (clobber (reg:CC FLAGS_REG))]
8853 "TARGET_SSE"
8854 "#")
8855
8856 ;; Splitters for fp abs and neg.
8857
8858 (define_split
8859 [(set (match_operand 0 "fp_register_operand")
8860 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8861 (use (match_operand 2))
8862 (clobber (reg:CC FLAGS_REG))]
8863 "reload_completed"
8864 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8865
8866 (define_split
8867 [(set (match_operand 0 "register_operand")
8868 (match_operator 3 "absneg_operator"
8869 [(match_operand 1 "register_operand")]))
8870 (use (match_operand 2 "nonimmediate_operand"))
8871 (clobber (reg:CC FLAGS_REG))]
8872 "reload_completed && SSE_REG_P (operands[0])"
8873 [(set (match_dup 0) (match_dup 3))]
8874 {
8875 enum machine_mode mode = GET_MODE (operands[0]);
8876 enum machine_mode vmode = GET_MODE (operands[2]);
8877 rtx tmp;
8878
8879 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8880 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8881 if (operands_match_p (operands[0], operands[2]))
8882 {
8883 tmp = operands[1];
8884 operands[1] = operands[2];
8885 operands[2] = tmp;
8886 }
8887 if (GET_CODE (operands[3]) == ABS)
8888 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8889 else
8890 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8891 operands[3] = tmp;
8892 })
8893
8894 (define_split
8895 [(set (match_operand:SF 0 "register_operand")
8896 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8897 (use (match_operand:V4SF 2))
8898 (clobber (reg:CC FLAGS_REG))]
8899 "reload_completed"
8900 [(parallel [(set (match_dup 0) (match_dup 1))
8901 (clobber (reg:CC FLAGS_REG))])]
8902 {
8903 rtx tmp;
8904 operands[0] = gen_lowpart (SImode, operands[0]);
8905 if (GET_CODE (operands[1]) == ABS)
8906 {
8907 tmp = gen_int_mode (0x7fffffff, SImode);
8908 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8909 }
8910 else
8911 {
8912 tmp = gen_int_mode (0x80000000, SImode);
8913 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8914 }
8915 operands[1] = tmp;
8916 })
8917
8918 (define_split
8919 [(set (match_operand:DF 0 "register_operand")
8920 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8921 (use (match_operand 2))
8922 (clobber (reg:CC FLAGS_REG))]
8923 "reload_completed"
8924 [(parallel [(set (match_dup 0) (match_dup 1))
8925 (clobber (reg:CC FLAGS_REG))])]
8926 {
8927 rtx tmp;
8928 if (TARGET_64BIT)
8929 {
8930 tmp = gen_lowpart (DImode, operands[0]);
8931 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8932 operands[0] = tmp;
8933
8934 if (GET_CODE (operands[1]) == ABS)
8935 tmp = const0_rtx;
8936 else
8937 tmp = gen_rtx_NOT (DImode, tmp);
8938 }
8939 else
8940 {
8941 operands[0] = gen_highpart (SImode, operands[0]);
8942 if (GET_CODE (operands[1]) == ABS)
8943 {
8944 tmp = gen_int_mode (0x7fffffff, SImode);
8945 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8946 }
8947 else
8948 {
8949 tmp = gen_int_mode (0x80000000, SImode);
8950 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8951 }
8952 }
8953 operands[1] = tmp;
8954 })
8955
8956 (define_split
8957 [(set (match_operand:XF 0 "register_operand")
8958 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8959 (use (match_operand 2))
8960 (clobber (reg:CC FLAGS_REG))]
8961 "reload_completed"
8962 [(parallel [(set (match_dup 0) (match_dup 1))
8963 (clobber (reg:CC FLAGS_REG))])]
8964 {
8965 rtx tmp;
8966 operands[0] = gen_rtx_REG (SImode,
8967 true_regnum (operands[0])
8968 + (TARGET_64BIT ? 1 : 2));
8969 if (GET_CODE (operands[1]) == ABS)
8970 {
8971 tmp = GEN_INT (0x7fff);
8972 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8973 }
8974 else
8975 {
8976 tmp = GEN_INT (0x8000);
8977 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8978 }
8979 operands[1] = tmp;
8980 })
8981
8982 ;; Conditionalize these after reload. If they match before reload, we
8983 ;; lose the clobber and ability to use integer instructions.
8984
8985 (define_insn "*<code><mode>2_1"
8986 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8987 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8988 "TARGET_80387
8989 && (reload_completed
8990 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8991 "f<absneg_mnemonic>"
8992 [(set_attr "type" "fsgn")
8993 (set_attr "mode" "<MODE>")])
8994
8995 (define_insn "*<code>extendsfdf2"
8996 [(set (match_operand:DF 0 "register_operand" "=f")
8997 (absneg:DF (float_extend:DF
8998 (match_operand:SF 1 "register_operand" "0"))))]
8999 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9000 "f<absneg_mnemonic>"
9001 [(set_attr "type" "fsgn")
9002 (set_attr "mode" "DF")])
9003
9004 (define_insn "*<code>extendsfxf2"
9005 [(set (match_operand:XF 0 "register_operand" "=f")
9006 (absneg:XF (float_extend:XF
9007 (match_operand:SF 1 "register_operand" "0"))))]
9008 "TARGET_80387"
9009 "f<absneg_mnemonic>"
9010 [(set_attr "type" "fsgn")
9011 (set_attr "mode" "XF")])
9012
9013 (define_insn "*<code>extenddfxf2"
9014 [(set (match_operand:XF 0 "register_operand" "=f")
9015 (absneg:XF (float_extend:XF
9016 (match_operand:DF 1 "register_operand" "0"))))]
9017 "TARGET_80387"
9018 "f<absneg_mnemonic>"
9019 [(set_attr "type" "fsgn")
9020 (set_attr "mode" "XF")])
9021
9022 ;; Copysign instructions
9023
9024 (define_mode_iterator CSGNMODE [SF DF TF])
9025 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9026
9027 (define_expand "copysign<mode>3"
9028 [(match_operand:CSGNMODE 0 "register_operand")
9029 (match_operand:CSGNMODE 1 "nonmemory_operand")
9030 (match_operand:CSGNMODE 2 "register_operand")]
9031 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9032 || (TARGET_SSE && (<MODE>mode == TFmode))"
9033 "ix86_expand_copysign (operands); DONE;")
9034
9035 (define_insn_and_split "copysign<mode>3_const"
9036 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9037 (unspec:CSGNMODE
9038 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9039 (match_operand:CSGNMODE 2 "register_operand" "0")
9040 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9041 UNSPEC_COPYSIGN))]
9042 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9043 || (TARGET_SSE && (<MODE>mode == TFmode))"
9044 "#"
9045 "&& reload_completed"
9046 [(const_int 0)]
9047 "ix86_split_copysign_const (operands); DONE;")
9048
9049 (define_insn "copysign<mode>3_var"
9050 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9051 (unspec:CSGNMODE
9052 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9053 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9054 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9055 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9056 UNSPEC_COPYSIGN))
9057 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9058 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9059 || (TARGET_SSE && (<MODE>mode == TFmode))"
9060 "#")
9061
9062 (define_split
9063 [(set (match_operand:CSGNMODE 0 "register_operand")
9064 (unspec:CSGNMODE
9065 [(match_operand:CSGNMODE 2 "register_operand")
9066 (match_operand:CSGNMODE 3 "register_operand")
9067 (match_operand:<CSGNVMODE> 4)
9068 (match_operand:<CSGNVMODE> 5)]
9069 UNSPEC_COPYSIGN))
9070 (clobber (match_scratch:<CSGNVMODE> 1))]
9071 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9072 || (TARGET_SSE && (<MODE>mode == TFmode)))
9073 && reload_completed"
9074 [(const_int 0)]
9075 "ix86_split_copysign_var (operands); DONE;")
9076 \f
9077 ;; One complement instructions
9078
9079 (define_expand "one_cmpl<mode>2"
9080 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9081 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9082 ""
9083 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9084
9085 (define_insn "*one_cmpl<mode>2_1"
9086 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9087 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0")))]
9088 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9089 "not{<imodesuffix>}\t%0"
9090 [(set_attr "type" "negnot")
9091 (set_attr "mode" "<MODE>")])
9092
9093 (define_insn "*one_cmplhi2_1"
9094 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!Yk")
9095 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,Yk")))]
9096 "ix86_unary_operator_ok (NOT, HImode, operands)"
9097 "@
9098 not{w}\t%0
9099 knotw\t{%1, %0|%0, %1}"
9100 [(set_attr "isa" "*,avx512f")
9101 (set_attr "type" "negnot,msklog")
9102 (set_attr "prefix" "*,vex")
9103 (set_attr "mode" "HI")])
9104
9105 ;; %%% Potential partial reg stall on alternative 1. What to do?
9106 (define_insn "*one_cmplqi2_1"
9107 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!Yk")
9108 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,Yk")))]
9109 "ix86_unary_operator_ok (NOT, QImode, operands)"
9110 "@
9111 not{b}\t%0
9112 not{l}\t%k0
9113 knotw\t{%1, %0|%0, %1}"
9114 [(set_attr "isa" "*,*,avx512f")
9115 (set_attr "type" "negnot,negnot,msklog")
9116 (set_attr "prefix" "*,*,vex")
9117 (set_attr "mode" "QI,SI,QI")])
9118
9119 ;; ??? Currently never generated - xor is used instead.
9120 (define_insn "*one_cmplsi2_1_zext"
9121 [(set (match_operand:DI 0 "register_operand" "=r")
9122 (zero_extend:DI
9123 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9124 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9125 "not{l}\t%k0"
9126 [(set_attr "type" "negnot")
9127 (set_attr "mode" "SI")])
9128
9129 (define_insn "*one_cmpl<mode>2_2"
9130 [(set (reg FLAGS_REG)
9131 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9132 (const_int 0)))
9133 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9134 (not:SWI (match_dup 1)))]
9135 "ix86_match_ccmode (insn, CCNOmode)
9136 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9137 "#"
9138 [(set_attr "type" "alu1")
9139 (set_attr "mode" "<MODE>")])
9140
9141 (define_split
9142 [(set (match_operand 0 "flags_reg_operand")
9143 (match_operator 2 "compare_operator"
9144 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9145 (const_int 0)]))
9146 (set (match_operand:SWI 1 "nonimmediate_operand")
9147 (not:SWI (match_dup 3)))]
9148 "ix86_match_ccmode (insn, CCNOmode)"
9149 [(parallel [(set (match_dup 0)
9150 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9151 (const_int 0)]))
9152 (set (match_dup 1)
9153 (xor:SWI (match_dup 3) (const_int -1)))])])
9154
9155 ;; ??? Currently never generated - xor is used instead.
9156 (define_insn "*one_cmplsi2_2_zext"
9157 [(set (reg FLAGS_REG)
9158 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9159 (const_int 0)))
9160 (set (match_operand:DI 0 "register_operand" "=r")
9161 (zero_extend:DI (not:SI (match_dup 1))))]
9162 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9163 && ix86_unary_operator_ok (NOT, SImode, operands)"
9164 "#"
9165 [(set_attr "type" "alu1")
9166 (set_attr "mode" "SI")])
9167
9168 (define_split
9169 [(set (match_operand 0 "flags_reg_operand")
9170 (match_operator 2 "compare_operator"
9171 [(not:SI (match_operand:SI 3 "register_operand"))
9172 (const_int 0)]))
9173 (set (match_operand:DI 1 "register_operand")
9174 (zero_extend:DI (not:SI (match_dup 3))))]
9175 "ix86_match_ccmode (insn, CCNOmode)"
9176 [(parallel [(set (match_dup 0)
9177 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9178 (const_int 0)]))
9179 (set (match_dup 1)
9180 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9181 \f
9182 ;; Shift instructions
9183
9184 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9185 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9186 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9187 ;; from the assembler input.
9188 ;;
9189 ;; This instruction shifts the target reg/mem as usual, but instead of
9190 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9191 ;; is a left shift double, bits are taken from the high order bits of
9192 ;; reg, else if the insn is a shift right double, bits are taken from the
9193 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9194 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9195 ;;
9196 ;; Since sh[lr]d does not change the `reg' operand, that is done
9197 ;; separately, making all shifts emit pairs of shift double and normal
9198 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9199 ;; support a 63 bit shift, each shift where the count is in a reg expands
9200 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9201 ;;
9202 ;; If the shift count is a constant, we need never emit more than one
9203 ;; shift pair, instead using moves and sign extension for counts greater
9204 ;; than 31.
9205
9206 (define_expand "ashl<mode>3"
9207 [(set (match_operand:SDWIM 0 "<shift_operand>")
9208 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9209 (match_operand:QI 2 "nonmemory_operand")))]
9210 ""
9211 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9212
9213 (define_insn "*ashl<mode>3_doubleword"
9214 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9215 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9216 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9217 (clobber (reg:CC FLAGS_REG))]
9218 ""
9219 "#"
9220 [(set_attr "type" "multi")])
9221
9222 (define_split
9223 [(set (match_operand:DWI 0 "register_operand")
9224 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9225 (match_operand:QI 2 "nonmemory_operand")))
9226 (clobber (reg:CC FLAGS_REG))]
9227 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9228 [(const_int 0)]
9229 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9230
9231 ;; By default we don't ask for a scratch register, because when DWImode
9232 ;; values are manipulated, registers are already at a premium. But if
9233 ;; we have one handy, we won't turn it away.
9234
9235 (define_peephole2
9236 [(match_scratch:DWIH 3 "r")
9237 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9238 (ashift:<DWI>
9239 (match_operand:<DWI> 1 "nonmemory_operand")
9240 (match_operand:QI 2 "nonmemory_operand")))
9241 (clobber (reg:CC FLAGS_REG))])
9242 (match_dup 3)]
9243 "TARGET_CMOVE"
9244 [(const_int 0)]
9245 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9246
9247 (define_insn "x86_64_shld"
9248 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9249 (ior:DI (ashift:DI (match_dup 0)
9250 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9251 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9252 (minus:QI (const_int 64) (match_dup 2)))))
9253 (clobber (reg:CC FLAGS_REG))]
9254 "TARGET_64BIT"
9255 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9256 [(set_attr "type" "ishift")
9257 (set_attr "prefix_0f" "1")
9258 (set_attr "mode" "DI")
9259 (set_attr "athlon_decode" "vector")
9260 (set_attr "amdfam10_decode" "vector")
9261 (set_attr "bdver1_decode" "vector")])
9262
9263 (define_insn "x86_shld"
9264 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9265 (ior:SI (ashift:SI (match_dup 0)
9266 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9267 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9268 (minus:QI (const_int 32) (match_dup 2)))))
9269 (clobber (reg:CC FLAGS_REG))]
9270 ""
9271 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9272 [(set_attr "type" "ishift")
9273 (set_attr "prefix_0f" "1")
9274 (set_attr "mode" "SI")
9275 (set_attr "pent_pair" "np")
9276 (set_attr "athlon_decode" "vector")
9277 (set_attr "amdfam10_decode" "vector")
9278 (set_attr "bdver1_decode" "vector")])
9279
9280 (define_expand "x86_shift<mode>_adj_1"
9281 [(set (reg:CCZ FLAGS_REG)
9282 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9283 (match_dup 4))
9284 (const_int 0)))
9285 (set (match_operand:SWI48 0 "register_operand")
9286 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9287 (match_operand:SWI48 1 "register_operand")
9288 (match_dup 0)))
9289 (set (match_dup 1)
9290 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9291 (match_operand:SWI48 3 "register_operand")
9292 (match_dup 1)))]
9293 "TARGET_CMOVE"
9294 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9295
9296 (define_expand "x86_shift<mode>_adj_2"
9297 [(use (match_operand:SWI48 0 "register_operand"))
9298 (use (match_operand:SWI48 1 "register_operand"))
9299 (use (match_operand:QI 2 "register_operand"))]
9300 ""
9301 {
9302 rtx label = gen_label_rtx ();
9303 rtx tmp;
9304
9305 emit_insn (gen_testqi_ccz_1 (operands[2],
9306 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9307
9308 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9309 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9310 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9311 gen_rtx_LABEL_REF (VOIDmode, label),
9312 pc_rtx);
9313 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9314 JUMP_LABEL (tmp) = label;
9315
9316 emit_move_insn (operands[0], operands[1]);
9317 ix86_expand_clear (operands[1]);
9318
9319 emit_label (label);
9320 LABEL_NUSES (label) = 1;
9321
9322 DONE;
9323 })
9324
9325 ;; Avoid useless masking of count operand.
9326 (define_insn "*ashl<mode>3_mask"
9327 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9328 (ashift:SWI48
9329 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9330 (subreg:QI
9331 (and:SI
9332 (match_operand:SI 2 "register_operand" "c")
9333 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9334 (clobber (reg:CC FLAGS_REG))]
9335 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9336 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9337 == GET_MODE_BITSIZE (<MODE>mode)-1"
9338 {
9339 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9340 }
9341 [(set_attr "type" "ishift")
9342 (set_attr "mode" "<MODE>")])
9343
9344 (define_insn "*bmi2_ashl<mode>3_1"
9345 [(set (match_operand:SWI48 0 "register_operand" "=r")
9346 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9347 (match_operand:SWI48 2 "register_operand" "r")))]
9348 "TARGET_BMI2"
9349 "shlx\t{%2, %1, %0|%0, %1, %2}"
9350 [(set_attr "type" "ishiftx")
9351 (set_attr "mode" "<MODE>")])
9352
9353 (define_insn "*ashl<mode>3_1"
9354 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9355 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9356 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9357 (clobber (reg:CC FLAGS_REG))]
9358 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9359 {
9360 switch (get_attr_type (insn))
9361 {
9362 case TYPE_LEA:
9363 case TYPE_ISHIFTX:
9364 return "#";
9365
9366 case TYPE_ALU:
9367 gcc_assert (operands[2] == const1_rtx);
9368 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9369 return "add{<imodesuffix>}\t%0, %0";
9370
9371 default:
9372 if (operands[2] == const1_rtx
9373 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9374 return "sal{<imodesuffix>}\t%0";
9375 else
9376 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9377 }
9378 }
9379 [(set_attr "isa" "*,*,bmi2")
9380 (set (attr "type")
9381 (cond [(eq_attr "alternative" "1")
9382 (const_string "lea")
9383 (eq_attr "alternative" "2")
9384 (const_string "ishiftx")
9385 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9386 (match_operand 0 "register_operand"))
9387 (match_operand 2 "const1_operand"))
9388 (const_string "alu")
9389 ]
9390 (const_string "ishift")))
9391 (set (attr "length_immediate")
9392 (if_then_else
9393 (ior (eq_attr "type" "alu")
9394 (and (eq_attr "type" "ishift")
9395 (and (match_operand 2 "const1_operand")
9396 (ior (match_test "TARGET_SHIFT1")
9397 (match_test "optimize_function_for_size_p (cfun)")))))
9398 (const_string "0")
9399 (const_string "*")))
9400 (set_attr "mode" "<MODE>")])
9401
9402 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9403 (define_split
9404 [(set (match_operand:SWI48 0 "register_operand")
9405 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9406 (match_operand:QI 2 "register_operand")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "TARGET_BMI2 && reload_completed"
9409 [(set (match_dup 0)
9410 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9411 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9412
9413 (define_insn "*bmi2_ashlsi3_1_zext"
9414 [(set (match_operand:DI 0 "register_operand" "=r")
9415 (zero_extend:DI
9416 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9417 (match_operand:SI 2 "register_operand" "r"))))]
9418 "TARGET_64BIT && TARGET_BMI2"
9419 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9420 [(set_attr "type" "ishiftx")
9421 (set_attr "mode" "SI")])
9422
9423 (define_insn "*ashlsi3_1_zext"
9424 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9425 (zero_extend:DI
9426 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9427 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9428 (clobber (reg:CC FLAGS_REG))]
9429 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9430 {
9431 switch (get_attr_type (insn))
9432 {
9433 case TYPE_LEA:
9434 case TYPE_ISHIFTX:
9435 return "#";
9436
9437 case TYPE_ALU:
9438 gcc_assert (operands[2] == const1_rtx);
9439 return "add{l}\t%k0, %k0";
9440
9441 default:
9442 if (operands[2] == const1_rtx
9443 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9444 return "sal{l}\t%k0";
9445 else
9446 return "sal{l}\t{%2, %k0|%k0, %2}";
9447 }
9448 }
9449 [(set_attr "isa" "*,*,bmi2")
9450 (set (attr "type")
9451 (cond [(eq_attr "alternative" "1")
9452 (const_string "lea")
9453 (eq_attr "alternative" "2")
9454 (const_string "ishiftx")
9455 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9456 (match_operand 2 "const1_operand"))
9457 (const_string "alu")
9458 ]
9459 (const_string "ishift")))
9460 (set (attr "length_immediate")
9461 (if_then_else
9462 (ior (eq_attr "type" "alu")
9463 (and (eq_attr "type" "ishift")
9464 (and (match_operand 2 "const1_operand")
9465 (ior (match_test "TARGET_SHIFT1")
9466 (match_test "optimize_function_for_size_p (cfun)")))))
9467 (const_string "0")
9468 (const_string "*")))
9469 (set_attr "mode" "SI")])
9470
9471 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9472 (define_split
9473 [(set (match_operand:DI 0 "register_operand")
9474 (zero_extend:DI
9475 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9476 (match_operand:QI 2 "register_operand"))))
9477 (clobber (reg:CC FLAGS_REG))]
9478 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9479 [(set (match_dup 0)
9480 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9481 "operands[2] = gen_lowpart (SImode, operands[2]);")
9482
9483 (define_insn "*ashlhi3_1"
9484 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9485 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9486 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9487 (clobber (reg:CC FLAGS_REG))]
9488 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9489 {
9490 switch (get_attr_type (insn))
9491 {
9492 case TYPE_LEA:
9493 return "#";
9494
9495 case TYPE_ALU:
9496 gcc_assert (operands[2] == const1_rtx);
9497 return "add{w}\t%0, %0";
9498
9499 default:
9500 if (operands[2] == const1_rtx
9501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9502 return "sal{w}\t%0";
9503 else
9504 return "sal{w}\t{%2, %0|%0, %2}";
9505 }
9506 }
9507 [(set (attr "type")
9508 (cond [(eq_attr "alternative" "1")
9509 (const_string "lea")
9510 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9511 (match_operand 0 "register_operand"))
9512 (match_operand 2 "const1_operand"))
9513 (const_string "alu")
9514 ]
9515 (const_string "ishift")))
9516 (set (attr "length_immediate")
9517 (if_then_else
9518 (ior (eq_attr "type" "alu")
9519 (and (eq_attr "type" "ishift")
9520 (and (match_operand 2 "const1_operand")
9521 (ior (match_test "TARGET_SHIFT1")
9522 (match_test "optimize_function_for_size_p (cfun)")))))
9523 (const_string "0")
9524 (const_string "*")))
9525 (set_attr "mode" "HI,SI")])
9526
9527 ;; %%% Potential partial reg stall on alternative 1. What to do?
9528 (define_insn "*ashlqi3_1"
9529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9530 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9531 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9532 (clobber (reg:CC FLAGS_REG))]
9533 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9534 {
9535 switch (get_attr_type (insn))
9536 {
9537 case TYPE_LEA:
9538 return "#";
9539
9540 case TYPE_ALU:
9541 gcc_assert (operands[2] == const1_rtx);
9542 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9543 return "add{l}\t%k0, %k0";
9544 else
9545 return "add{b}\t%0, %0";
9546
9547 default:
9548 if (operands[2] == const1_rtx
9549 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9550 {
9551 if (get_attr_mode (insn) == MODE_SI)
9552 return "sal{l}\t%k0";
9553 else
9554 return "sal{b}\t%0";
9555 }
9556 else
9557 {
9558 if (get_attr_mode (insn) == MODE_SI)
9559 return "sal{l}\t{%2, %k0|%k0, %2}";
9560 else
9561 return "sal{b}\t{%2, %0|%0, %2}";
9562 }
9563 }
9564 }
9565 [(set (attr "type")
9566 (cond [(eq_attr "alternative" "2")
9567 (const_string "lea")
9568 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9569 (match_operand 0 "register_operand"))
9570 (match_operand 2 "const1_operand"))
9571 (const_string "alu")
9572 ]
9573 (const_string "ishift")))
9574 (set (attr "length_immediate")
9575 (if_then_else
9576 (ior (eq_attr "type" "alu")
9577 (and (eq_attr "type" "ishift")
9578 (and (match_operand 2 "const1_operand")
9579 (ior (match_test "TARGET_SHIFT1")
9580 (match_test "optimize_function_for_size_p (cfun)")))))
9581 (const_string "0")
9582 (const_string "*")))
9583 (set_attr "mode" "QI,SI,SI")])
9584
9585 (define_insn "*ashlqi3_1_slp"
9586 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9587 (ashift:QI (match_dup 0)
9588 (match_operand:QI 1 "nonmemory_operand" "cI")))
9589 (clobber (reg:CC FLAGS_REG))]
9590 "(optimize_function_for_size_p (cfun)
9591 || !TARGET_PARTIAL_FLAG_REG_STALL
9592 || (operands[1] == const1_rtx
9593 && (TARGET_SHIFT1
9594 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9595 {
9596 switch (get_attr_type (insn))
9597 {
9598 case TYPE_ALU:
9599 gcc_assert (operands[1] == const1_rtx);
9600 return "add{b}\t%0, %0";
9601
9602 default:
9603 if (operands[1] == const1_rtx
9604 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9605 return "sal{b}\t%0";
9606 else
9607 return "sal{b}\t{%1, %0|%0, %1}";
9608 }
9609 }
9610 [(set (attr "type")
9611 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9612 (match_operand 0 "register_operand"))
9613 (match_operand 1 "const1_operand"))
9614 (const_string "alu")
9615 ]
9616 (const_string "ishift1")))
9617 (set (attr "length_immediate")
9618 (if_then_else
9619 (ior (eq_attr "type" "alu")
9620 (and (eq_attr "type" "ishift1")
9621 (and (match_operand 1 "const1_operand")
9622 (ior (match_test "TARGET_SHIFT1")
9623 (match_test "optimize_function_for_size_p (cfun)")))))
9624 (const_string "0")
9625 (const_string "*")))
9626 (set_attr "mode" "QI")])
9627
9628 ;; Convert ashift to the lea pattern to avoid flags dependency.
9629 (define_split
9630 [(set (match_operand 0 "register_operand")
9631 (ashift (match_operand 1 "index_register_operand")
9632 (match_operand:QI 2 "const_int_operand")))
9633 (clobber (reg:CC FLAGS_REG))]
9634 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9635 && reload_completed
9636 && true_regnum (operands[0]) != true_regnum (operands[1])"
9637 [(const_int 0)]
9638 {
9639 enum machine_mode mode = GET_MODE (operands[0]);
9640 rtx pat;
9641
9642 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9643 {
9644 mode = SImode;
9645 operands[0] = gen_lowpart (mode, operands[0]);
9646 operands[1] = gen_lowpart (mode, operands[1]);
9647 }
9648
9649 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9650
9651 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9652
9653 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9654 DONE;
9655 })
9656
9657 ;; Convert ashift to the lea pattern to avoid flags dependency.
9658 (define_split
9659 [(set (match_operand:DI 0 "register_operand")
9660 (zero_extend:DI
9661 (ashift:SI (match_operand:SI 1 "index_register_operand")
9662 (match_operand:QI 2 "const_int_operand"))))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_64BIT && reload_completed
9665 && true_regnum (operands[0]) != true_regnum (operands[1])"
9666 [(set (match_dup 0)
9667 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9668 {
9669 operands[1] = gen_lowpart (SImode, operands[1]);
9670 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9671 })
9672
9673 ;; This pattern can't accept a variable shift count, since shifts by
9674 ;; zero don't affect the flags. We assume that shifts by constant
9675 ;; zero are optimized away.
9676 (define_insn "*ashl<mode>3_cmp"
9677 [(set (reg FLAGS_REG)
9678 (compare
9679 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9680 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9681 (const_int 0)))
9682 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9683 (ashift:SWI (match_dup 1) (match_dup 2)))]
9684 "(optimize_function_for_size_p (cfun)
9685 || !TARGET_PARTIAL_FLAG_REG_STALL
9686 || (operands[2] == const1_rtx
9687 && (TARGET_SHIFT1
9688 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9689 && ix86_match_ccmode (insn, CCGOCmode)
9690 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9691 {
9692 switch (get_attr_type (insn))
9693 {
9694 case TYPE_ALU:
9695 gcc_assert (operands[2] == const1_rtx);
9696 return "add{<imodesuffix>}\t%0, %0";
9697
9698 default:
9699 if (operands[2] == const1_rtx
9700 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9701 return "sal{<imodesuffix>}\t%0";
9702 else
9703 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9704 }
9705 }
9706 [(set (attr "type")
9707 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9708 (match_operand 0 "register_operand"))
9709 (match_operand 2 "const1_operand"))
9710 (const_string "alu")
9711 ]
9712 (const_string "ishift")))
9713 (set (attr "length_immediate")
9714 (if_then_else
9715 (ior (eq_attr "type" "alu")
9716 (and (eq_attr "type" "ishift")
9717 (and (match_operand 2 "const1_operand")
9718 (ior (match_test "TARGET_SHIFT1")
9719 (match_test "optimize_function_for_size_p (cfun)")))))
9720 (const_string "0")
9721 (const_string "*")))
9722 (set_attr "mode" "<MODE>")])
9723
9724 (define_insn "*ashlsi3_cmp_zext"
9725 [(set (reg FLAGS_REG)
9726 (compare
9727 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9728 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9729 (const_int 0)))
9730 (set (match_operand:DI 0 "register_operand" "=r")
9731 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9732 "TARGET_64BIT
9733 && (optimize_function_for_size_p (cfun)
9734 || !TARGET_PARTIAL_FLAG_REG_STALL
9735 || (operands[2] == const1_rtx
9736 && (TARGET_SHIFT1
9737 || TARGET_DOUBLE_WITH_ADD)))
9738 && ix86_match_ccmode (insn, CCGOCmode)
9739 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9740 {
9741 switch (get_attr_type (insn))
9742 {
9743 case TYPE_ALU:
9744 gcc_assert (operands[2] == const1_rtx);
9745 return "add{l}\t%k0, %k0";
9746
9747 default:
9748 if (operands[2] == const1_rtx
9749 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9750 return "sal{l}\t%k0";
9751 else
9752 return "sal{l}\t{%2, %k0|%k0, %2}";
9753 }
9754 }
9755 [(set (attr "type")
9756 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9757 (match_operand 2 "const1_operand"))
9758 (const_string "alu")
9759 ]
9760 (const_string "ishift")))
9761 (set (attr "length_immediate")
9762 (if_then_else
9763 (ior (eq_attr "type" "alu")
9764 (and (eq_attr "type" "ishift")
9765 (and (match_operand 2 "const1_operand")
9766 (ior (match_test "TARGET_SHIFT1")
9767 (match_test "optimize_function_for_size_p (cfun)")))))
9768 (const_string "0")
9769 (const_string "*")))
9770 (set_attr "mode" "SI")])
9771
9772 (define_insn "*ashl<mode>3_cconly"
9773 [(set (reg FLAGS_REG)
9774 (compare
9775 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9776 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9777 (const_int 0)))
9778 (clobber (match_scratch:SWI 0 "=<r>"))]
9779 "(optimize_function_for_size_p (cfun)
9780 || !TARGET_PARTIAL_FLAG_REG_STALL
9781 || (operands[2] == const1_rtx
9782 && (TARGET_SHIFT1
9783 || TARGET_DOUBLE_WITH_ADD)))
9784 && ix86_match_ccmode (insn, CCGOCmode)"
9785 {
9786 switch (get_attr_type (insn))
9787 {
9788 case TYPE_ALU:
9789 gcc_assert (operands[2] == const1_rtx);
9790 return "add{<imodesuffix>}\t%0, %0";
9791
9792 default:
9793 if (operands[2] == const1_rtx
9794 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9795 return "sal{<imodesuffix>}\t%0";
9796 else
9797 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9798 }
9799 }
9800 [(set (attr "type")
9801 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9802 (match_operand 0 "register_operand"))
9803 (match_operand 2 "const1_operand"))
9804 (const_string "alu")
9805 ]
9806 (const_string "ishift")))
9807 (set (attr "length_immediate")
9808 (if_then_else
9809 (ior (eq_attr "type" "alu")
9810 (and (eq_attr "type" "ishift")
9811 (and (match_operand 2 "const1_operand")
9812 (ior (match_test "TARGET_SHIFT1")
9813 (match_test "optimize_function_for_size_p (cfun)")))))
9814 (const_string "0")
9815 (const_string "*")))
9816 (set_attr "mode" "<MODE>")])
9817
9818 ;; See comment above `ashl<mode>3' about how this works.
9819
9820 (define_expand "<shift_insn><mode>3"
9821 [(set (match_operand:SDWIM 0 "<shift_operand>")
9822 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9823 (match_operand:QI 2 "nonmemory_operand")))]
9824 ""
9825 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9826
9827 ;; Avoid useless masking of count operand.
9828 (define_insn "*<shift_insn><mode>3_mask"
9829 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9830 (any_shiftrt:SWI48
9831 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9832 (subreg:QI
9833 (and:SI
9834 (match_operand:SI 2 "register_operand" "c")
9835 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9836 (clobber (reg:CC FLAGS_REG))]
9837 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9838 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9839 == GET_MODE_BITSIZE (<MODE>mode)-1"
9840 {
9841 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9842 }
9843 [(set_attr "type" "ishift")
9844 (set_attr "mode" "<MODE>")])
9845
9846 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9847 [(set (match_operand:DWI 0 "register_operand" "=r")
9848 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9849 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9850 (clobber (reg:CC FLAGS_REG))]
9851 ""
9852 "#"
9853 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9854 [(const_int 0)]
9855 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9856 [(set_attr "type" "multi")])
9857
9858 ;; By default we don't ask for a scratch register, because when DWImode
9859 ;; values are manipulated, registers are already at a premium. But if
9860 ;; we have one handy, we won't turn it away.
9861
9862 (define_peephole2
9863 [(match_scratch:DWIH 3 "r")
9864 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9865 (any_shiftrt:<DWI>
9866 (match_operand:<DWI> 1 "register_operand")
9867 (match_operand:QI 2 "nonmemory_operand")))
9868 (clobber (reg:CC FLAGS_REG))])
9869 (match_dup 3)]
9870 "TARGET_CMOVE"
9871 [(const_int 0)]
9872 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9873
9874 (define_insn "x86_64_shrd"
9875 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9876 (ior:DI (ashiftrt:DI (match_dup 0)
9877 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9878 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9879 (minus:QI (const_int 64) (match_dup 2)))))
9880 (clobber (reg:CC FLAGS_REG))]
9881 "TARGET_64BIT"
9882 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9883 [(set_attr "type" "ishift")
9884 (set_attr "prefix_0f" "1")
9885 (set_attr "mode" "DI")
9886 (set_attr "athlon_decode" "vector")
9887 (set_attr "amdfam10_decode" "vector")
9888 (set_attr "bdver1_decode" "vector")])
9889
9890 (define_insn "x86_shrd"
9891 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9892 (ior:SI (ashiftrt:SI (match_dup 0)
9893 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9894 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9895 (minus:QI (const_int 32) (match_dup 2)))))
9896 (clobber (reg:CC FLAGS_REG))]
9897 ""
9898 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9899 [(set_attr "type" "ishift")
9900 (set_attr "prefix_0f" "1")
9901 (set_attr "mode" "SI")
9902 (set_attr "pent_pair" "np")
9903 (set_attr "athlon_decode" "vector")
9904 (set_attr "amdfam10_decode" "vector")
9905 (set_attr "bdver1_decode" "vector")])
9906
9907 (define_insn "ashrdi3_cvt"
9908 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9909 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9910 (match_operand:QI 2 "const_int_operand")))
9911 (clobber (reg:CC FLAGS_REG))]
9912 "TARGET_64BIT && INTVAL (operands[2]) == 63
9913 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9914 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9915 "@
9916 {cqto|cqo}
9917 sar{q}\t{%2, %0|%0, %2}"
9918 [(set_attr "type" "imovx,ishift")
9919 (set_attr "prefix_0f" "0,*")
9920 (set_attr "length_immediate" "0,*")
9921 (set_attr "modrm" "0,1")
9922 (set_attr "mode" "DI")])
9923
9924 (define_insn "ashrsi3_cvt"
9925 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9926 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9927 (match_operand:QI 2 "const_int_operand")))
9928 (clobber (reg:CC FLAGS_REG))]
9929 "INTVAL (operands[2]) == 31
9930 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9931 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9932 "@
9933 {cltd|cdq}
9934 sar{l}\t{%2, %0|%0, %2}"
9935 [(set_attr "type" "imovx,ishift")
9936 (set_attr "prefix_0f" "0,*")
9937 (set_attr "length_immediate" "0,*")
9938 (set_attr "modrm" "0,1")
9939 (set_attr "mode" "SI")])
9940
9941 (define_insn "*ashrsi3_cvt_zext"
9942 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9943 (zero_extend:DI
9944 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9945 (match_operand:QI 2 "const_int_operand"))))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "TARGET_64BIT && INTVAL (operands[2]) == 31
9948 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9949 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9950 "@
9951 {cltd|cdq}
9952 sar{l}\t{%2, %k0|%k0, %2}"
9953 [(set_attr "type" "imovx,ishift")
9954 (set_attr "prefix_0f" "0,*")
9955 (set_attr "length_immediate" "0,*")
9956 (set_attr "modrm" "0,1")
9957 (set_attr "mode" "SI")])
9958
9959 (define_expand "x86_shift<mode>_adj_3"
9960 [(use (match_operand:SWI48 0 "register_operand"))
9961 (use (match_operand:SWI48 1 "register_operand"))
9962 (use (match_operand:QI 2 "register_operand"))]
9963 ""
9964 {
9965 rtx label = gen_label_rtx ();
9966 rtx tmp;
9967
9968 emit_insn (gen_testqi_ccz_1 (operands[2],
9969 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9970
9971 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9972 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9973 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9974 gen_rtx_LABEL_REF (VOIDmode, label),
9975 pc_rtx);
9976 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9977 JUMP_LABEL (tmp) = label;
9978
9979 emit_move_insn (operands[0], operands[1]);
9980 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9981 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9982 emit_label (label);
9983 LABEL_NUSES (label) = 1;
9984
9985 DONE;
9986 })
9987
9988 (define_insn "*bmi2_<shift_insn><mode>3_1"
9989 [(set (match_operand:SWI48 0 "register_operand" "=r")
9990 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9991 (match_operand:SWI48 2 "register_operand" "r")))]
9992 "TARGET_BMI2"
9993 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9994 [(set_attr "type" "ishiftx")
9995 (set_attr "mode" "<MODE>")])
9996
9997 (define_insn "*<shift_insn><mode>3_1"
9998 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9999 (any_shiftrt:SWI48
10000 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10001 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10002 (clobber (reg:CC FLAGS_REG))]
10003 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10004 {
10005 switch (get_attr_type (insn))
10006 {
10007 case TYPE_ISHIFTX:
10008 return "#";
10009
10010 default:
10011 if (operands[2] == const1_rtx
10012 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10013 return "<shift>{<imodesuffix>}\t%0";
10014 else
10015 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10016 }
10017 }
10018 [(set_attr "isa" "*,bmi2")
10019 (set_attr "type" "ishift,ishiftx")
10020 (set (attr "length_immediate")
10021 (if_then_else
10022 (and (match_operand 2 "const1_operand")
10023 (ior (match_test "TARGET_SHIFT1")
10024 (match_test "optimize_function_for_size_p (cfun)")))
10025 (const_string "0")
10026 (const_string "*")))
10027 (set_attr "mode" "<MODE>")])
10028
10029 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10030 (define_split
10031 [(set (match_operand:SWI48 0 "register_operand")
10032 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10033 (match_operand:QI 2 "register_operand")))
10034 (clobber (reg:CC FLAGS_REG))]
10035 "TARGET_BMI2 && reload_completed"
10036 [(set (match_dup 0)
10037 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10038 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10039
10040 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10041 [(set (match_operand:DI 0 "register_operand" "=r")
10042 (zero_extend:DI
10043 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10044 (match_operand:SI 2 "register_operand" "r"))))]
10045 "TARGET_64BIT && TARGET_BMI2"
10046 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10047 [(set_attr "type" "ishiftx")
10048 (set_attr "mode" "SI")])
10049
10050 (define_insn "*<shift_insn>si3_1_zext"
10051 [(set (match_operand:DI 0 "register_operand" "=r,r")
10052 (zero_extend:DI
10053 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10054 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10057 {
10058 switch (get_attr_type (insn))
10059 {
10060 case TYPE_ISHIFTX:
10061 return "#";
10062
10063 default:
10064 if (operands[2] == const1_rtx
10065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10066 return "<shift>{l}\t%k0";
10067 else
10068 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10069 }
10070 }
10071 [(set_attr "isa" "*,bmi2")
10072 (set_attr "type" "ishift,ishiftx")
10073 (set (attr "length_immediate")
10074 (if_then_else
10075 (and (match_operand 2 "const1_operand")
10076 (ior (match_test "TARGET_SHIFT1")
10077 (match_test "optimize_function_for_size_p (cfun)")))
10078 (const_string "0")
10079 (const_string "*")))
10080 (set_attr "mode" "SI")])
10081
10082 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10083 (define_split
10084 [(set (match_operand:DI 0 "register_operand")
10085 (zero_extend:DI
10086 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10087 (match_operand:QI 2 "register_operand"))))
10088 (clobber (reg:CC FLAGS_REG))]
10089 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10090 [(set (match_dup 0)
10091 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10092 "operands[2] = gen_lowpart (SImode, operands[2]);")
10093
10094 (define_insn "*<shift_insn><mode>3_1"
10095 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10096 (any_shiftrt:SWI12
10097 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10098 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10099 (clobber (reg:CC FLAGS_REG))]
10100 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10101 {
10102 if (operands[2] == const1_rtx
10103 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10104 return "<shift>{<imodesuffix>}\t%0";
10105 else
10106 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10107 }
10108 [(set_attr "type" "ishift")
10109 (set (attr "length_immediate")
10110 (if_then_else
10111 (and (match_operand 2 "const1_operand")
10112 (ior (match_test "TARGET_SHIFT1")
10113 (match_test "optimize_function_for_size_p (cfun)")))
10114 (const_string "0")
10115 (const_string "*")))
10116 (set_attr "mode" "<MODE>")])
10117
10118 (define_insn "*<shift_insn>qi3_1_slp"
10119 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10120 (any_shiftrt:QI (match_dup 0)
10121 (match_operand:QI 1 "nonmemory_operand" "cI")))
10122 (clobber (reg:CC FLAGS_REG))]
10123 "(optimize_function_for_size_p (cfun)
10124 || !TARGET_PARTIAL_REG_STALL
10125 || (operands[1] == const1_rtx
10126 && TARGET_SHIFT1))"
10127 {
10128 if (operands[1] == const1_rtx
10129 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10130 return "<shift>{b}\t%0";
10131 else
10132 return "<shift>{b}\t{%1, %0|%0, %1}";
10133 }
10134 [(set_attr "type" "ishift1")
10135 (set (attr "length_immediate")
10136 (if_then_else
10137 (and (match_operand 1 "const1_operand")
10138 (ior (match_test "TARGET_SHIFT1")
10139 (match_test "optimize_function_for_size_p (cfun)")))
10140 (const_string "0")
10141 (const_string "*")))
10142 (set_attr "mode" "QI")])
10143
10144 ;; This pattern can't accept a variable shift count, since shifts by
10145 ;; zero don't affect the flags. We assume that shifts by constant
10146 ;; zero are optimized away.
10147 (define_insn "*<shift_insn><mode>3_cmp"
10148 [(set (reg FLAGS_REG)
10149 (compare
10150 (any_shiftrt:SWI
10151 (match_operand:SWI 1 "nonimmediate_operand" "0")
10152 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10153 (const_int 0)))
10154 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10155 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10156 "(optimize_function_for_size_p (cfun)
10157 || !TARGET_PARTIAL_FLAG_REG_STALL
10158 || (operands[2] == const1_rtx
10159 && TARGET_SHIFT1))
10160 && ix86_match_ccmode (insn, CCGOCmode)
10161 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10162 {
10163 if (operands[2] == const1_rtx
10164 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165 return "<shift>{<imodesuffix>}\t%0";
10166 else
10167 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10168 }
10169 [(set_attr "type" "ishift")
10170 (set (attr "length_immediate")
10171 (if_then_else
10172 (and (match_operand 2 "const1_operand")
10173 (ior (match_test "TARGET_SHIFT1")
10174 (match_test "optimize_function_for_size_p (cfun)")))
10175 (const_string "0")
10176 (const_string "*")))
10177 (set_attr "mode" "<MODE>")])
10178
10179 (define_insn "*<shift_insn>si3_cmp_zext"
10180 [(set (reg FLAGS_REG)
10181 (compare
10182 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10183 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10184 (const_int 0)))
10185 (set (match_operand:DI 0 "register_operand" "=r")
10186 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10187 "TARGET_64BIT
10188 && (optimize_function_for_size_p (cfun)
10189 || !TARGET_PARTIAL_FLAG_REG_STALL
10190 || (operands[2] == const1_rtx
10191 && TARGET_SHIFT1))
10192 && ix86_match_ccmode (insn, CCGOCmode)
10193 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10194 {
10195 if (operands[2] == const1_rtx
10196 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10197 return "<shift>{l}\t%k0";
10198 else
10199 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10200 }
10201 [(set_attr "type" "ishift")
10202 (set (attr "length_immediate")
10203 (if_then_else
10204 (and (match_operand 2 "const1_operand")
10205 (ior (match_test "TARGET_SHIFT1")
10206 (match_test "optimize_function_for_size_p (cfun)")))
10207 (const_string "0")
10208 (const_string "*")))
10209 (set_attr "mode" "SI")])
10210
10211 (define_insn "*<shift_insn><mode>3_cconly"
10212 [(set (reg FLAGS_REG)
10213 (compare
10214 (any_shiftrt:SWI
10215 (match_operand:SWI 1 "register_operand" "0")
10216 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10217 (const_int 0)))
10218 (clobber (match_scratch:SWI 0 "=<r>"))]
10219 "(optimize_function_for_size_p (cfun)
10220 || !TARGET_PARTIAL_FLAG_REG_STALL
10221 || (operands[2] == const1_rtx
10222 && TARGET_SHIFT1))
10223 && ix86_match_ccmode (insn, CCGOCmode)"
10224 {
10225 if (operands[2] == const1_rtx
10226 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10227 return "<shift>{<imodesuffix>}\t%0";
10228 else
10229 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10230 }
10231 [(set_attr "type" "ishift")
10232 (set (attr "length_immediate")
10233 (if_then_else
10234 (and (match_operand 2 "const1_operand")
10235 (ior (match_test "TARGET_SHIFT1")
10236 (match_test "optimize_function_for_size_p (cfun)")))
10237 (const_string "0")
10238 (const_string "*")))
10239 (set_attr "mode" "<MODE>")])
10240 \f
10241 ;; Rotate instructions
10242
10243 (define_expand "<rotate_insn>ti3"
10244 [(set (match_operand:TI 0 "register_operand")
10245 (any_rotate:TI (match_operand:TI 1 "register_operand")
10246 (match_operand:QI 2 "nonmemory_operand")))]
10247 "TARGET_64BIT"
10248 {
10249 if (const_1_to_63_operand (operands[2], VOIDmode))
10250 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10251 (operands[0], operands[1], operands[2]));
10252 else
10253 FAIL;
10254
10255 DONE;
10256 })
10257
10258 (define_expand "<rotate_insn>di3"
10259 [(set (match_operand:DI 0 "shiftdi_operand")
10260 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10261 (match_operand:QI 2 "nonmemory_operand")))]
10262 ""
10263 {
10264 if (TARGET_64BIT)
10265 ix86_expand_binary_operator (<CODE>, DImode, operands);
10266 else if (const_1_to_31_operand (operands[2], VOIDmode))
10267 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10268 (operands[0], operands[1], operands[2]));
10269 else
10270 FAIL;
10271
10272 DONE;
10273 })
10274
10275 (define_expand "<rotate_insn><mode>3"
10276 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10277 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10278 (match_operand:QI 2 "nonmemory_operand")))]
10279 ""
10280 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10281
10282 ;; Avoid useless masking of count operand.
10283 (define_insn "*<rotate_insn><mode>3_mask"
10284 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10285 (any_rotate:SWI48
10286 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10287 (subreg:QI
10288 (and:SI
10289 (match_operand:SI 2 "register_operand" "c")
10290 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10291 (clobber (reg:CC FLAGS_REG))]
10292 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10293 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10294 == GET_MODE_BITSIZE (<MODE>mode)-1"
10295 {
10296 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10297 }
10298 [(set_attr "type" "rotate")
10299 (set_attr "mode" "<MODE>")])
10300
10301 ;; Implement rotation using two double-precision
10302 ;; shift instructions and a scratch register.
10303
10304 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10305 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10306 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10307 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10308 (clobber (reg:CC FLAGS_REG))
10309 (clobber (match_scratch:DWIH 3 "=&r"))]
10310 ""
10311 "#"
10312 "reload_completed"
10313 [(set (match_dup 3) (match_dup 4))
10314 (parallel
10315 [(set (match_dup 4)
10316 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10317 (lshiftrt:DWIH (match_dup 5)
10318 (minus:QI (match_dup 6) (match_dup 2)))))
10319 (clobber (reg:CC FLAGS_REG))])
10320 (parallel
10321 [(set (match_dup 5)
10322 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10323 (lshiftrt:DWIH (match_dup 3)
10324 (minus:QI (match_dup 6) (match_dup 2)))))
10325 (clobber (reg:CC FLAGS_REG))])]
10326 {
10327 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10328
10329 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10330 })
10331
10332 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10333 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10334 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10335 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10336 (clobber (reg:CC FLAGS_REG))
10337 (clobber (match_scratch:DWIH 3 "=&r"))]
10338 ""
10339 "#"
10340 "reload_completed"
10341 [(set (match_dup 3) (match_dup 4))
10342 (parallel
10343 [(set (match_dup 4)
10344 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10345 (ashift:DWIH (match_dup 5)
10346 (minus:QI (match_dup 6) (match_dup 2)))))
10347 (clobber (reg:CC FLAGS_REG))])
10348 (parallel
10349 [(set (match_dup 5)
10350 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10351 (ashift:DWIH (match_dup 3)
10352 (minus:QI (match_dup 6) (match_dup 2)))))
10353 (clobber (reg:CC FLAGS_REG))])]
10354 {
10355 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10356
10357 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10358 })
10359
10360 (define_insn "*bmi2_rorx<mode>3_1"
10361 [(set (match_operand:SWI48 0 "register_operand" "=r")
10362 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10363 (match_operand:QI 2 "immediate_operand" "<S>")))]
10364 "TARGET_BMI2"
10365 "rorx\t{%2, %1, %0|%0, %1, %2}"
10366 [(set_attr "type" "rotatex")
10367 (set_attr "mode" "<MODE>")])
10368
10369 (define_insn "*<rotate_insn><mode>3_1"
10370 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10371 (any_rotate:SWI48
10372 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10373 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10374 (clobber (reg:CC FLAGS_REG))]
10375 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10376 {
10377 switch (get_attr_type (insn))
10378 {
10379 case TYPE_ROTATEX:
10380 return "#";
10381
10382 default:
10383 if (operands[2] == const1_rtx
10384 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10385 return "<rotate>{<imodesuffix>}\t%0";
10386 else
10387 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10388 }
10389 }
10390 [(set_attr "isa" "*,bmi2")
10391 (set_attr "type" "rotate,rotatex")
10392 (set (attr "length_immediate")
10393 (if_then_else
10394 (and (eq_attr "type" "rotate")
10395 (and (match_operand 2 "const1_operand")
10396 (ior (match_test "TARGET_SHIFT1")
10397 (match_test "optimize_function_for_size_p (cfun)"))))
10398 (const_string "0")
10399 (const_string "*")))
10400 (set_attr "mode" "<MODE>")])
10401
10402 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10403 (define_split
10404 [(set (match_operand:SWI48 0 "register_operand")
10405 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10406 (match_operand:QI 2 "immediate_operand")))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_BMI2 && reload_completed"
10409 [(set (match_dup 0)
10410 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10411 {
10412 operands[2]
10413 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10414 })
10415
10416 (define_split
10417 [(set (match_operand:SWI48 0 "register_operand")
10418 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10419 (match_operand:QI 2 "immediate_operand")))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_BMI2 && reload_completed"
10422 [(set (match_dup 0)
10423 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10424
10425 (define_insn "*bmi2_rorxsi3_1_zext"
10426 [(set (match_operand:DI 0 "register_operand" "=r")
10427 (zero_extend:DI
10428 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10429 (match_operand:QI 2 "immediate_operand" "I"))))]
10430 "TARGET_64BIT && TARGET_BMI2"
10431 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10432 [(set_attr "type" "rotatex")
10433 (set_attr "mode" "SI")])
10434
10435 (define_insn "*<rotate_insn>si3_1_zext"
10436 [(set (match_operand:DI 0 "register_operand" "=r,r")
10437 (zero_extend:DI
10438 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10439 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10440 (clobber (reg:CC FLAGS_REG))]
10441 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10442 {
10443 switch (get_attr_type (insn))
10444 {
10445 case TYPE_ROTATEX:
10446 return "#";
10447
10448 default:
10449 if (operands[2] == const1_rtx
10450 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10451 return "<rotate>{l}\t%k0";
10452 else
10453 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10454 }
10455 }
10456 [(set_attr "isa" "*,bmi2")
10457 (set_attr "type" "rotate,rotatex")
10458 (set (attr "length_immediate")
10459 (if_then_else
10460 (and (eq_attr "type" "rotate")
10461 (and (match_operand 2 "const1_operand")
10462 (ior (match_test "TARGET_SHIFT1")
10463 (match_test "optimize_function_for_size_p (cfun)"))))
10464 (const_string "0")
10465 (const_string "*")))
10466 (set_attr "mode" "SI")])
10467
10468 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10469 (define_split
10470 [(set (match_operand:DI 0 "register_operand")
10471 (zero_extend:DI
10472 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10473 (match_operand:QI 2 "immediate_operand"))))
10474 (clobber (reg:CC FLAGS_REG))]
10475 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10476 [(set (match_dup 0)
10477 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10478 {
10479 operands[2]
10480 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10481 })
10482
10483 (define_split
10484 [(set (match_operand:DI 0 "register_operand")
10485 (zero_extend:DI
10486 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10487 (match_operand:QI 2 "immediate_operand"))))
10488 (clobber (reg:CC FLAGS_REG))]
10489 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10490 [(set (match_dup 0)
10491 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10492
10493 (define_insn "*<rotate_insn><mode>3_1"
10494 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10495 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10496 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10499 {
10500 if (operands[2] == const1_rtx
10501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10502 return "<rotate>{<imodesuffix>}\t%0";
10503 else
10504 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10505 }
10506 [(set_attr "type" "rotate")
10507 (set (attr "length_immediate")
10508 (if_then_else
10509 (and (match_operand 2 "const1_operand")
10510 (ior (match_test "TARGET_SHIFT1")
10511 (match_test "optimize_function_for_size_p (cfun)")))
10512 (const_string "0")
10513 (const_string "*")))
10514 (set_attr "mode" "<MODE>")])
10515
10516 (define_insn "*<rotate_insn>qi3_1_slp"
10517 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10518 (any_rotate:QI (match_dup 0)
10519 (match_operand:QI 1 "nonmemory_operand" "cI")))
10520 (clobber (reg:CC FLAGS_REG))]
10521 "(optimize_function_for_size_p (cfun)
10522 || !TARGET_PARTIAL_REG_STALL
10523 || (operands[1] == const1_rtx
10524 && TARGET_SHIFT1))"
10525 {
10526 if (operands[1] == const1_rtx
10527 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10528 return "<rotate>{b}\t%0";
10529 else
10530 return "<rotate>{b}\t{%1, %0|%0, %1}";
10531 }
10532 [(set_attr "type" "rotate1")
10533 (set (attr "length_immediate")
10534 (if_then_else
10535 (and (match_operand 1 "const1_operand")
10536 (ior (match_test "TARGET_SHIFT1")
10537 (match_test "optimize_function_for_size_p (cfun)")))
10538 (const_string "0")
10539 (const_string "*")))
10540 (set_attr "mode" "QI")])
10541
10542 (define_split
10543 [(set (match_operand:HI 0 "register_operand")
10544 (any_rotate:HI (match_dup 0) (const_int 8)))
10545 (clobber (reg:CC FLAGS_REG))]
10546 "reload_completed
10547 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10548 [(parallel [(set (strict_low_part (match_dup 0))
10549 (bswap:HI (match_dup 0)))
10550 (clobber (reg:CC FLAGS_REG))])])
10551 \f
10552 ;; Bit set / bit test instructions
10553
10554 (define_expand "extv"
10555 [(set (match_operand:SI 0 "register_operand")
10556 (sign_extract:SI (match_operand:SI 1 "register_operand")
10557 (match_operand:SI 2 "const8_operand")
10558 (match_operand:SI 3 "const8_operand")))]
10559 ""
10560 {
10561 /* Handle extractions from %ah et al. */
10562 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10563 FAIL;
10564
10565 /* From mips.md: extract_bit_field doesn't verify that our source
10566 matches the predicate, so check it again here. */
10567 if (! ext_register_operand (operands[1], VOIDmode))
10568 FAIL;
10569 })
10570
10571 (define_expand "extzv"
10572 [(set (match_operand:SI 0 "register_operand")
10573 (zero_extract:SI (match_operand 1 "ext_register_operand")
10574 (match_operand:SI 2 "const8_operand")
10575 (match_operand:SI 3 "const8_operand")))]
10576 ""
10577 {
10578 /* Handle extractions from %ah et al. */
10579 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10580 FAIL;
10581
10582 /* From mips.md: extract_bit_field doesn't verify that our source
10583 matches the predicate, so check it again here. */
10584 if (! ext_register_operand (operands[1], VOIDmode))
10585 FAIL;
10586 })
10587
10588 (define_expand "insv"
10589 [(set (zero_extract (match_operand 0 "register_operand")
10590 (match_operand 1 "const_int_operand")
10591 (match_operand 2 "const_int_operand"))
10592 (match_operand 3 "register_operand"))]
10593 ""
10594 {
10595 rtx (*gen_mov_insv_1) (rtx, rtx);
10596
10597 if (ix86_expand_pinsr (operands))
10598 DONE;
10599
10600 /* Handle insertions to %ah et al. */
10601 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10602 FAIL;
10603
10604 /* From mips.md: insert_bit_field doesn't verify that our source
10605 matches the predicate, so check it again here. */
10606 if (! ext_register_operand (operands[0], VOIDmode))
10607 FAIL;
10608
10609 gen_mov_insv_1 = (TARGET_64BIT
10610 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10611
10612 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10613 DONE;
10614 })
10615
10616 ;; %%% bts, btr, btc, bt.
10617 ;; In general these instructions are *slow* when applied to memory,
10618 ;; since they enforce atomic operation. When applied to registers,
10619 ;; it depends on the cpu implementation. They're never faster than
10620 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10621 ;; no point. But in 64-bit, we can't hold the relevant immediates
10622 ;; within the instruction itself, so operating on bits in the high
10623 ;; 32-bits of a register becomes easier.
10624 ;;
10625 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10626 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10627 ;; negdf respectively, so they can never be disabled entirely.
10628
10629 (define_insn "*btsq"
10630 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10631 (const_int 1)
10632 (match_operand:DI 1 "const_0_to_63_operand"))
10633 (const_int 1))
10634 (clobber (reg:CC FLAGS_REG))]
10635 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10636 "bts{q}\t{%1, %0|%0, %1}"
10637 [(set_attr "type" "alu1")
10638 (set_attr "prefix_0f" "1")
10639 (set_attr "mode" "DI")])
10640
10641 (define_insn "*btrq"
10642 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
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 || reload_completed)"
10648 "btr{q}\t{%1, %0|%0, %1}"
10649 [(set_attr "type" "alu1")
10650 (set_attr "prefix_0f" "1")
10651 (set_attr "mode" "DI")])
10652
10653 (define_insn "*btcq"
10654 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10655 (const_int 1)
10656 (match_operand:DI 1 "const_0_to_63_operand"))
10657 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10658 (clobber (reg:CC FLAGS_REG))]
10659 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10660 "btc{q}\t{%1, %0|%0, %1}"
10661 [(set_attr "type" "alu1")
10662 (set_attr "prefix_0f" "1")
10663 (set_attr "mode" "DI")])
10664
10665 ;; Allow Nocona to avoid these instructions if a register is available.
10666
10667 (define_peephole2
10668 [(match_scratch:DI 2 "r")
10669 (parallel [(set (zero_extract:DI
10670 (match_operand:DI 0 "register_operand")
10671 (const_int 1)
10672 (match_operand:DI 1 "const_0_to_63_operand"))
10673 (const_int 1))
10674 (clobber (reg:CC FLAGS_REG))])]
10675 "TARGET_64BIT && !TARGET_USE_BT"
10676 [(const_int 0)]
10677 {
10678 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10679 rtx op1;
10680
10681 if (HOST_BITS_PER_WIDE_INT >= 64)
10682 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10683 else if (i < HOST_BITS_PER_WIDE_INT)
10684 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10685 else
10686 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10687
10688 op1 = immed_double_const (lo, hi, DImode);
10689 if (i >= 31)
10690 {
10691 emit_move_insn (operands[2], op1);
10692 op1 = operands[2];
10693 }
10694
10695 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10696 DONE;
10697 })
10698
10699 (define_peephole2
10700 [(match_scratch:DI 2 "r")
10701 (parallel [(set (zero_extract:DI
10702 (match_operand:DI 0 "register_operand")
10703 (const_int 1)
10704 (match_operand:DI 1 "const_0_to_63_operand"))
10705 (const_int 0))
10706 (clobber (reg:CC FLAGS_REG))])]
10707 "TARGET_64BIT && !TARGET_USE_BT"
10708 [(const_int 0)]
10709 {
10710 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10711 rtx op1;
10712
10713 if (HOST_BITS_PER_WIDE_INT >= 64)
10714 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10715 else if (i < HOST_BITS_PER_WIDE_INT)
10716 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10717 else
10718 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10719
10720 op1 = immed_double_const (~lo, ~hi, DImode);
10721 if (i >= 32)
10722 {
10723 emit_move_insn (operands[2], op1);
10724 op1 = operands[2];
10725 }
10726
10727 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10728 DONE;
10729 })
10730
10731 (define_peephole2
10732 [(match_scratch:DI 2 "r")
10733 (parallel [(set (zero_extract:DI
10734 (match_operand:DI 0 "register_operand")
10735 (const_int 1)
10736 (match_operand:DI 1 "const_0_to_63_operand"))
10737 (not:DI (zero_extract:DI
10738 (match_dup 0) (const_int 1) (match_dup 1))))
10739 (clobber (reg:CC FLAGS_REG))])]
10740 "TARGET_64BIT && !TARGET_USE_BT"
10741 [(const_int 0)]
10742 {
10743 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10744 rtx op1;
10745
10746 if (HOST_BITS_PER_WIDE_INT >= 64)
10747 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10748 else if (i < HOST_BITS_PER_WIDE_INT)
10749 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10750 else
10751 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10752
10753 op1 = immed_double_const (lo, hi, DImode);
10754 if (i >= 31)
10755 {
10756 emit_move_insn (operands[2], op1);
10757 op1 = operands[2];
10758 }
10759
10760 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10761 DONE;
10762 })
10763
10764 (define_insn "*bt<mode>"
10765 [(set (reg:CCC FLAGS_REG)
10766 (compare:CCC
10767 (zero_extract:SWI48
10768 (match_operand:SWI48 0 "register_operand" "r")
10769 (const_int 1)
10770 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10771 (const_int 0)))]
10772 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10773 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10774 [(set_attr "type" "alu1")
10775 (set_attr "prefix_0f" "1")
10776 (set_attr "mode" "<MODE>")])
10777 \f
10778 ;; Store-flag instructions.
10779
10780 ;; For all sCOND expanders, also expand the compare or test insn that
10781 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10782
10783 (define_insn_and_split "*setcc_di_1"
10784 [(set (match_operand:DI 0 "register_operand" "=q")
10785 (match_operator:DI 1 "ix86_comparison_operator"
10786 [(reg FLAGS_REG) (const_int 0)]))]
10787 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10788 "#"
10789 "&& reload_completed"
10790 [(set (match_dup 2) (match_dup 1))
10791 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10792 {
10793 PUT_MODE (operands[1], QImode);
10794 operands[2] = gen_lowpart (QImode, operands[0]);
10795 })
10796
10797 (define_insn_and_split "*setcc_si_1_and"
10798 [(set (match_operand:SI 0 "register_operand" "=q")
10799 (match_operator:SI 1 "ix86_comparison_operator"
10800 [(reg FLAGS_REG) (const_int 0)]))
10801 (clobber (reg:CC FLAGS_REG))]
10802 "!TARGET_PARTIAL_REG_STALL
10803 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10804 "#"
10805 "&& reload_completed"
10806 [(set (match_dup 2) (match_dup 1))
10807 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10808 (clobber (reg:CC FLAGS_REG))])]
10809 {
10810 PUT_MODE (operands[1], QImode);
10811 operands[2] = gen_lowpart (QImode, operands[0]);
10812 })
10813
10814 (define_insn_and_split "*setcc_si_1_movzbl"
10815 [(set (match_operand:SI 0 "register_operand" "=q")
10816 (match_operator:SI 1 "ix86_comparison_operator"
10817 [(reg FLAGS_REG) (const_int 0)]))]
10818 "!TARGET_PARTIAL_REG_STALL
10819 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10820 "#"
10821 "&& reload_completed"
10822 [(set (match_dup 2) (match_dup 1))
10823 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10824 {
10825 PUT_MODE (operands[1], QImode);
10826 operands[2] = gen_lowpart (QImode, operands[0]);
10827 })
10828
10829 (define_insn "*setcc_qi"
10830 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10831 (match_operator:QI 1 "ix86_comparison_operator"
10832 [(reg FLAGS_REG) (const_int 0)]))]
10833 ""
10834 "set%C1\t%0"
10835 [(set_attr "type" "setcc")
10836 (set_attr "mode" "QI")])
10837
10838 (define_insn "*setcc_qi_slp"
10839 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10840 (match_operator:QI 1 "ix86_comparison_operator"
10841 [(reg FLAGS_REG) (const_int 0)]))]
10842 ""
10843 "set%C1\t%0"
10844 [(set_attr "type" "setcc")
10845 (set_attr "mode" "QI")])
10846
10847 ;; In general it is not safe to assume too much about CCmode registers,
10848 ;; so simplify-rtx stops when it sees a second one. Under certain
10849 ;; conditions this is safe on x86, so help combine not create
10850 ;;
10851 ;; seta %al
10852 ;; testb %al, %al
10853 ;; sete %al
10854
10855 (define_split
10856 [(set (match_operand:QI 0 "nonimmediate_operand")
10857 (ne:QI (match_operator 1 "ix86_comparison_operator"
10858 [(reg FLAGS_REG) (const_int 0)])
10859 (const_int 0)))]
10860 ""
10861 [(set (match_dup 0) (match_dup 1))]
10862 "PUT_MODE (operands[1], QImode);")
10863
10864 (define_split
10865 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10866 (ne:QI (match_operator 1 "ix86_comparison_operator"
10867 [(reg FLAGS_REG) (const_int 0)])
10868 (const_int 0)))]
10869 ""
10870 [(set (match_dup 0) (match_dup 1))]
10871 "PUT_MODE (operands[1], QImode);")
10872
10873 (define_split
10874 [(set (match_operand:QI 0 "nonimmediate_operand")
10875 (eq:QI (match_operator 1 "ix86_comparison_operator"
10876 [(reg FLAGS_REG) (const_int 0)])
10877 (const_int 0)))]
10878 ""
10879 [(set (match_dup 0) (match_dup 1))]
10880 {
10881 rtx new_op1 = copy_rtx (operands[1]);
10882 operands[1] = new_op1;
10883 PUT_MODE (new_op1, QImode);
10884 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10885 GET_MODE (XEXP (new_op1, 0))));
10886
10887 /* Make sure that (a) the CCmode we have for the flags is strong
10888 enough for the reversed compare or (b) we have a valid FP compare. */
10889 if (! ix86_comparison_operator (new_op1, VOIDmode))
10890 FAIL;
10891 })
10892
10893 (define_split
10894 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10895 (eq:QI (match_operator 1 "ix86_comparison_operator"
10896 [(reg FLAGS_REG) (const_int 0)])
10897 (const_int 0)))]
10898 ""
10899 [(set (match_dup 0) (match_dup 1))]
10900 {
10901 rtx new_op1 = copy_rtx (operands[1]);
10902 operands[1] = new_op1;
10903 PUT_MODE (new_op1, QImode);
10904 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10905 GET_MODE (XEXP (new_op1, 0))));
10906
10907 /* Make sure that (a) the CCmode we have for the flags is strong
10908 enough for the reversed compare or (b) we have a valid FP compare. */
10909 if (! ix86_comparison_operator (new_op1, VOIDmode))
10910 FAIL;
10911 })
10912
10913 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10914 ;; subsequent logical operations are used to imitate conditional moves.
10915 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10916 ;; it directly.
10917
10918 (define_insn "setcc_<mode>_sse"
10919 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10920 (match_operator:MODEF 3 "sse_comparison_operator"
10921 [(match_operand:MODEF 1 "register_operand" "0,x")
10922 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10923 "SSE_FLOAT_MODE_P (<MODE>mode)"
10924 "@
10925 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10926 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10927 [(set_attr "isa" "noavx,avx")
10928 (set_attr "type" "ssecmp")
10929 (set_attr "length_immediate" "1")
10930 (set_attr "prefix" "orig,vex")
10931 (set_attr "mode" "<MODE>")])
10932 \f
10933 ;; Basic conditional jump instructions.
10934 ;; We ignore the overflow flag for signed branch instructions.
10935
10936 (define_insn "*jcc_1"
10937 [(set (pc)
10938 (if_then_else (match_operator 1 "ix86_comparison_operator"
10939 [(reg FLAGS_REG) (const_int 0)])
10940 (label_ref (match_operand 0))
10941 (pc)))]
10942 ""
10943 "%+j%C1\t%l0"
10944 [(set_attr "type" "ibr")
10945 (set_attr "modrm" "0")
10946 (set (attr "length")
10947 (if_then_else (and (ge (minus (match_dup 0) (pc))
10948 (const_int -126))
10949 (lt (minus (match_dup 0) (pc))
10950 (const_int 128)))
10951 (const_int 2)
10952 (const_int 6)))])
10953
10954 (define_insn "*jcc_2"
10955 [(set (pc)
10956 (if_then_else (match_operator 1 "ix86_comparison_operator"
10957 [(reg FLAGS_REG) (const_int 0)])
10958 (pc)
10959 (label_ref (match_operand 0))))]
10960 ""
10961 "%+j%c1\t%l0"
10962 [(set_attr "type" "ibr")
10963 (set_attr "modrm" "0")
10964 (set (attr "length")
10965 (if_then_else (and (ge (minus (match_dup 0) (pc))
10966 (const_int -126))
10967 (lt (minus (match_dup 0) (pc))
10968 (const_int 128)))
10969 (const_int 2)
10970 (const_int 6)))])
10971
10972 ;; In general it is not safe to assume too much about CCmode registers,
10973 ;; so simplify-rtx stops when it sees a second one. Under certain
10974 ;; conditions this is safe on x86, so help combine not create
10975 ;;
10976 ;; seta %al
10977 ;; testb %al, %al
10978 ;; je Lfoo
10979
10980 (define_split
10981 [(set (pc)
10982 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10983 [(reg FLAGS_REG) (const_int 0)])
10984 (const_int 0))
10985 (label_ref (match_operand 1))
10986 (pc)))]
10987 ""
10988 [(set (pc)
10989 (if_then_else (match_dup 0)
10990 (label_ref (match_dup 1))
10991 (pc)))]
10992 "PUT_MODE (operands[0], VOIDmode);")
10993
10994 (define_split
10995 [(set (pc)
10996 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10997 [(reg FLAGS_REG) (const_int 0)])
10998 (const_int 0))
10999 (label_ref (match_operand 1))
11000 (pc)))]
11001 ""
11002 [(set (pc)
11003 (if_then_else (match_dup 0)
11004 (label_ref (match_dup 1))
11005 (pc)))]
11006 {
11007 rtx new_op0 = copy_rtx (operands[0]);
11008 operands[0] = new_op0;
11009 PUT_MODE (new_op0, VOIDmode);
11010 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11011 GET_MODE (XEXP (new_op0, 0))));
11012
11013 /* Make sure that (a) the CCmode we have for the flags is strong
11014 enough for the reversed compare or (b) we have a valid FP compare. */
11015 if (! ix86_comparison_operator (new_op0, VOIDmode))
11016 FAIL;
11017 })
11018
11019 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11020 ;; pass generates from shift insn with QImode operand. Actually, the mode
11021 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11022 ;; appropriate modulo of the bit offset value.
11023
11024 (define_insn_and_split "*jcc_bt<mode>"
11025 [(set (pc)
11026 (if_then_else (match_operator 0 "bt_comparison_operator"
11027 [(zero_extract:SWI48
11028 (match_operand:SWI48 1 "register_operand" "r")
11029 (const_int 1)
11030 (zero_extend:SI
11031 (match_operand:QI 2 "register_operand" "r")))
11032 (const_int 0)])
11033 (label_ref (match_operand 3))
11034 (pc)))
11035 (clobber (reg:CC FLAGS_REG))]
11036 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11037 "#"
11038 "&& 1"
11039 [(set (reg:CCC FLAGS_REG)
11040 (compare:CCC
11041 (zero_extract:SWI48
11042 (match_dup 1)
11043 (const_int 1)
11044 (match_dup 2))
11045 (const_int 0)))
11046 (set (pc)
11047 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11048 (label_ref (match_dup 3))
11049 (pc)))]
11050 {
11051 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11052
11053 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11054 })
11055
11056 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11057 ;; zero extended to SImode.
11058 (define_insn_and_split "*jcc_bt<mode>_1"
11059 [(set (pc)
11060 (if_then_else (match_operator 0 "bt_comparison_operator"
11061 [(zero_extract:SWI48
11062 (match_operand:SWI48 1 "register_operand" "r")
11063 (const_int 1)
11064 (match_operand:SI 2 "register_operand" "r"))
11065 (const_int 0)])
11066 (label_ref (match_operand 3))
11067 (pc)))
11068 (clobber (reg:CC FLAGS_REG))]
11069 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11070 "#"
11071 "&& 1"
11072 [(set (reg:CCC FLAGS_REG)
11073 (compare:CCC
11074 (zero_extract:SWI48
11075 (match_dup 1)
11076 (const_int 1)
11077 (match_dup 2))
11078 (const_int 0)))
11079 (set (pc)
11080 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11081 (label_ref (match_dup 3))
11082 (pc)))]
11083 {
11084 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11085
11086 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11087 })
11088
11089 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11090 ;; also for DImode, this is what combine produces.
11091 (define_insn_and_split "*jcc_bt<mode>_mask"
11092 [(set (pc)
11093 (if_then_else (match_operator 0 "bt_comparison_operator"
11094 [(zero_extract:SWI48
11095 (match_operand:SWI48 1 "register_operand" "r")
11096 (const_int 1)
11097 (and:SI
11098 (match_operand:SI 2 "register_operand" "r")
11099 (match_operand:SI 3 "const_int_operand" "n")))])
11100 (label_ref (match_operand 4))
11101 (pc)))
11102 (clobber (reg:CC FLAGS_REG))]
11103 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11104 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11105 == GET_MODE_BITSIZE (<MODE>mode)-1"
11106 "#"
11107 "&& 1"
11108 [(set (reg:CCC FLAGS_REG)
11109 (compare:CCC
11110 (zero_extract:SWI48
11111 (match_dup 1)
11112 (const_int 1)
11113 (match_dup 2))
11114 (const_int 0)))
11115 (set (pc)
11116 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11117 (label_ref (match_dup 4))
11118 (pc)))]
11119 {
11120 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11121
11122 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11123 })
11124
11125 (define_insn_and_split "*jcc_btsi_1"
11126 [(set (pc)
11127 (if_then_else (match_operator 0 "bt_comparison_operator"
11128 [(and:SI
11129 (lshiftrt:SI
11130 (match_operand:SI 1 "register_operand" "r")
11131 (match_operand:QI 2 "register_operand" "r"))
11132 (const_int 1))
11133 (const_int 0)])
11134 (label_ref (match_operand 3))
11135 (pc)))
11136 (clobber (reg:CC FLAGS_REG))]
11137 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11138 "#"
11139 "&& 1"
11140 [(set (reg:CCC FLAGS_REG)
11141 (compare:CCC
11142 (zero_extract:SI
11143 (match_dup 1)
11144 (const_int 1)
11145 (match_dup 2))
11146 (const_int 0)))
11147 (set (pc)
11148 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11149 (label_ref (match_dup 3))
11150 (pc)))]
11151 {
11152 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11153
11154 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11155 })
11156
11157 ;; avoid useless masking of bit offset operand
11158 (define_insn_and_split "*jcc_btsi_mask_1"
11159 [(set (pc)
11160 (if_then_else
11161 (match_operator 0 "bt_comparison_operator"
11162 [(and:SI
11163 (lshiftrt:SI
11164 (match_operand:SI 1 "register_operand" "r")
11165 (subreg:QI
11166 (and:SI
11167 (match_operand:SI 2 "register_operand" "r")
11168 (match_operand:SI 3 "const_int_operand" "n")) 0))
11169 (const_int 1))
11170 (const_int 0)])
11171 (label_ref (match_operand 4))
11172 (pc)))
11173 (clobber (reg:CC FLAGS_REG))]
11174 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11175 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11176 "#"
11177 "&& 1"
11178 [(set (reg:CCC FLAGS_REG)
11179 (compare:CCC
11180 (zero_extract:SI
11181 (match_dup 1)
11182 (const_int 1)
11183 (match_dup 2))
11184 (const_int 0)))
11185 (set (pc)
11186 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11187 (label_ref (match_dup 4))
11188 (pc)))]
11189 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11190
11191 ;; Define combination compare-and-branch fp compare instructions to help
11192 ;; combine.
11193
11194 (define_insn "*jcc<mode>_0_i387"
11195 [(set (pc)
11196 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11197 [(match_operand:X87MODEF 1 "register_operand" "f")
11198 (match_operand:X87MODEF 2 "const0_operand")])
11199 (label_ref (match_operand 3))
11200 (pc)))
11201 (clobber (reg:CCFP FPSR_REG))
11202 (clobber (reg:CCFP FLAGS_REG))
11203 (clobber (match_scratch:HI 4 "=a"))]
11204 "TARGET_80387 && !TARGET_CMOVE"
11205 "#")
11206
11207 (define_insn "*jcc<mode>_0_r_i387"
11208 [(set (pc)
11209 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11210 [(match_operand:X87MODEF 1 "register_operand" "f")
11211 (match_operand:X87MODEF 2 "const0_operand")])
11212 (pc)
11213 (label_ref (match_operand 3))))
11214 (clobber (reg:CCFP FPSR_REG))
11215 (clobber (reg:CCFP FLAGS_REG))
11216 (clobber (match_scratch:HI 4 "=a"))]
11217 "TARGET_80387 && !TARGET_CMOVE"
11218 "#")
11219
11220 (define_insn "*jccxf_i387"
11221 [(set (pc)
11222 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11223 [(match_operand:XF 1 "register_operand" "f")
11224 (match_operand:XF 2 "register_operand" "f")])
11225 (label_ref (match_operand 3))
11226 (pc)))
11227 (clobber (reg:CCFP FPSR_REG))
11228 (clobber (reg:CCFP FLAGS_REG))
11229 (clobber (match_scratch:HI 4 "=a"))]
11230 "TARGET_80387 && !TARGET_CMOVE"
11231 "#")
11232
11233 (define_insn "*jccxf_r_i387"
11234 [(set (pc)
11235 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11236 [(match_operand:XF 1 "register_operand" "f")
11237 (match_operand:XF 2 "register_operand" "f")])
11238 (pc)
11239 (label_ref (match_operand 3))))
11240 (clobber (reg:CCFP FPSR_REG))
11241 (clobber (reg:CCFP FLAGS_REG))
11242 (clobber (match_scratch:HI 4 "=a"))]
11243 "TARGET_80387 && !TARGET_CMOVE"
11244 "#")
11245
11246 (define_insn "*jcc<mode>_i387"
11247 [(set (pc)
11248 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11249 [(match_operand:MODEF 1 "register_operand" "f")
11250 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11251 (label_ref (match_operand 3))
11252 (pc)))
11253 (clobber (reg:CCFP FPSR_REG))
11254 (clobber (reg:CCFP FLAGS_REG))
11255 (clobber (match_scratch:HI 4 "=a"))]
11256 "TARGET_80387 && !TARGET_CMOVE"
11257 "#")
11258
11259 (define_insn "*jcc<mode>_r_i387"
11260 [(set (pc)
11261 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11262 [(match_operand:MODEF 1 "register_operand" "f")
11263 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11264 (pc)
11265 (label_ref (match_operand 3))))
11266 (clobber (reg:CCFP FPSR_REG))
11267 (clobber (reg:CCFP FLAGS_REG))
11268 (clobber (match_scratch:HI 4 "=a"))]
11269 "TARGET_80387 && !TARGET_CMOVE"
11270 "#")
11271
11272 (define_insn "*jccu<mode>_i387"
11273 [(set (pc)
11274 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11275 [(match_operand:X87MODEF 1 "register_operand" "f")
11276 (match_operand:X87MODEF 2 "register_operand" "f")])
11277 (label_ref (match_operand 3))
11278 (pc)))
11279 (clobber (reg:CCFP FPSR_REG))
11280 (clobber (reg:CCFP FLAGS_REG))
11281 (clobber (match_scratch:HI 4 "=a"))]
11282 "TARGET_80387 && !TARGET_CMOVE"
11283 "#")
11284
11285 (define_insn "*jccu<mode>_r_i387"
11286 [(set (pc)
11287 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11288 [(match_operand:X87MODEF 1 "register_operand" "f")
11289 (match_operand:X87MODEF 2 "register_operand" "f")])
11290 (pc)
11291 (label_ref (match_operand 3))))
11292 (clobber (reg:CCFP FPSR_REG))
11293 (clobber (reg:CCFP FLAGS_REG))
11294 (clobber (match_scratch:HI 4 "=a"))]
11295 "TARGET_80387 && !TARGET_CMOVE"
11296 "#")
11297
11298 (define_split
11299 [(set (pc)
11300 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11301 [(match_operand:X87MODEF 1 "register_operand")
11302 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11303 (match_operand 3)
11304 (match_operand 4)))
11305 (clobber (reg:CCFP FPSR_REG))
11306 (clobber (reg:CCFP FLAGS_REG))]
11307 "TARGET_80387 && !TARGET_CMOVE
11308 && reload_completed"
11309 [(const_int 0)]
11310 {
11311 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11312 operands[3], operands[4], NULL_RTX, NULL_RTX);
11313 DONE;
11314 })
11315
11316 (define_split
11317 [(set (pc)
11318 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11319 [(match_operand:X87MODEF 1 "register_operand")
11320 (match_operand:X87MODEF 2 "general_operand")])
11321 (match_operand 3)
11322 (match_operand 4)))
11323 (clobber (reg:CCFP FPSR_REG))
11324 (clobber (reg:CCFP FLAGS_REG))
11325 (clobber (match_scratch:HI 5))]
11326 "TARGET_80387 && !TARGET_CMOVE
11327 && reload_completed"
11328 [(const_int 0)]
11329 {
11330 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11331 operands[3], operands[4], operands[5], NULL_RTX);
11332 DONE;
11333 })
11334
11335 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11336 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11337 ;; with a precedence over other operators and is always put in the first
11338 ;; place. Swap condition and operands to match ficom instruction.
11339
11340 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11341 [(set (pc)
11342 (if_then_else
11343 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11344 [(match_operator:X87MODEF 1 "float_operator"
11345 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11346 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11347 (label_ref (match_operand 4))
11348 (pc)))
11349 (clobber (reg:CCFP FPSR_REG))
11350 (clobber (reg:CCFP FLAGS_REG))
11351 (clobber (match_scratch:HI 5 "=a,a"))]
11352 "TARGET_80387 && !TARGET_CMOVE
11353 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11354 || optimize_function_for_size_p (cfun))"
11355 "#")
11356
11357 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11358 [(set (pc)
11359 (if_then_else
11360 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11361 [(match_operator:X87MODEF 1 "float_operator"
11362 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11363 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11364 (pc)
11365 (label_ref (match_operand 4))))
11366 (clobber (reg:CCFP FPSR_REG))
11367 (clobber (reg:CCFP FLAGS_REG))
11368 (clobber (match_scratch:HI 5 "=a,a"))]
11369 "TARGET_80387 && !TARGET_CMOVE
11370 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11371 || optimize_function_for_size_p (cfun))"
11372 "#")
11373
11374 (define_split
11375 [(set (pc)
11376 (if_then_else
11377 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11378 [(match_operator:X87MODEF 1 "float_operator"
11379 [(match_operand:SWI24 2 "memory_operand")])
11380 (match_operand:X87MODEF 3 "register_operand")])
11381 (match_operand 4)
11382 (match_operand 5)))
11383 (clobber (reg:CCFP FPSR_REG))
11384 (clobber (reg:CCFP FLAGS_REG))
11385 (clobber (match_scratch:HI 6))]
11386 "TARGET_80387 && !TARGET_CMOVE
11387 && reload_completed"
11388 [(const_int 0)]
11389 {
11390 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11391 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11392 operands[4], operands[5], operands[6], NULL_RTX);
11393 DONE;
11394 })
11395
11396 ;; %%% Kill this when reload knows how to do it.
11397 (define_split
11398 [(set (pc)
11399 (if_then_else
11400 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11401 [(match_operator:X87MODEF 1 "float_operator"
11402 [(match_operand:SWI24 2 "register_operand")])
11403 (match_operand:X87MODEF 3 "register_operand")])
11404 (match_operand 4)
11405 (match_operand 5)))
11406 (clobber (reg:CCFP FPSR_REG))
11407 (clobber (reg:CCFP FLAGS_REG))
11408 (clobber (match_scratch:HI 6))]
11409 "TARGET_80387 && !TARGET_CMOVE
11410 && reload_completed"
11411 [(const_int 0)]
11412 {
11413 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11414
11415 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11416 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11417 operands[4], operands[5], operands[6], operands[2]);
11418 DONE;
11419 })
11420 \f
11421 ;; Unconditional and other jump instructions
11422
11423 (define_insn "jump"
11424 [(set (pc)
11425 (label_ref (match_operand 0)))]
11426 ""
11427 "jmp\t%l0"
11428 [(set_attr "type" "ibr")
11429 (set (attr "length")
11430 (if_then_else (and (ge (minus (match_dup 0) (pc))
11431 (const_int -126))
11432 (lt (minus (match_dup 0) (pc))
11433 (const_int 128)))
11434 (const_int 2)
11435 (const_int 5)))
11436 (set_attr "modrm" "0")])
11437
11438 (define_expand "indirect_jump"
11439 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11440 ""
11441 {
11442 if (TARGET_X32)
11443 operands[0] = convert_memory_address (word_mode, operands[0]);
11444 })
11445
11446 (define_insn "*indirect_jump"
11447 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11448 ""
11449 "jmp\t%A0"
11450 [(set_attr "type" "ibr")
11451 (set_attr "length_immediate" "0")])
11452
11453 (define_expand "tablejump"
11454 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11455 (use (label_ref (match_operand 1)))])]
11456 ""
11457 {
11458 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11459 relative. Convert the relative address to an absolute address. */
11460 if (flag_pic)
11461 {
11462 rtx op0, op1;
11463 enum rtx_code code;
11464
11465 /* We can't use @GOTOFF for text labels on VxWorks;
11466 see gotoff_operand. */
11467 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11468 {
11469 code = PLUS;
11470 op0 = operands[0];
11471 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11472 }
11473 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11474 {
11475 code = PLUS;
11476 op0 = operands[0];
11477 op1 = pic_offset_table_rtx;
11478 }
11479 else
11480 {
11481 code = MINUS;
11482 op0 = pic_offset_table_rtx;
11483 op1 = operands[0];
11484 }
11485
11486 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11487 OPTAB_DIRECT);
11488 }
11489
11490 if (TARGET_X32)
11491 operands[0] = convert_memory_address (word_mode, operands[0]);
11492 })
11493
11494 (define_insn "*tablejump_1"
11495 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11496 (use (label_ref (match_operand 1)))]
11497 ""
11498 "jmp\t%A0"
11499 [(set_attr "type" "ibr")
11500 (set_attr "length_immediate" "0")])
11501 \f
11502 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11503
11504 (define_peephole2
11505 [(set (reg FLAGS_REG) (match_operand 0))
11506 (set (match_operand:QI 1 "register_operand")
11507 (match_operator:QI 2 "ix86_comparison_operator"
11508 [(reg FLAGS_REG) (const_int 0)]))
11509 (set (match_operand 3 "q_regs_operand")
11510 (zero_extend (match_dup 1)))]
11511 "(peep2_reg_dead_p (3, operands[1])
11512 || operands_match_p (operands[1], operands[3]))
11513 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11514 [(set (match_dup 4) (match_dup 0))
11515 (set (strict_low_part (match_dup 5))
11516 (match_dup 2))]
11517 {
11518 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11519 operands[5] = gen_lowpart (QImode, operands[3]);
11520 ix86_expand_clear (operands[3]);
11521 })
11522
11523 (define_peephole2
11524 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11525 (match_operand 4)])
11526 (set (match_operand:QI 1 "register_operand")
11527 (match_operator:QI 2 "ix86_comparison_operator"
11528 [(reg FLAGS_REG) (const_int 0)]))
11529 (set (match_operand 3 "q_regs_operand")
11530 (zero_extend (match_dup 1)))]
11531 "(peep2_reg_dead_p (3, operands[1])
11532 || operands_match_p (operands[1], operands[3]))
11533 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11534 [(parallel [(set (match_dup 5) (match_dup 0))
11535 (match_dup 4)])
11536 (set (strict_low_part (match_dup 6))
11537 (match_dup 2))]
11538 {
11539 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11540 operands[6] = gen_lowpart (QImode, operands[3]);
11541 ix86_expand_clear (operands[3]);
11542 })
11543
11544 ;; Similar, but match zero extend with andsi3.
11545
11546 (define_peephole2
11547 [(set (reg FLAGS_REG) (match_operand 0))
11548 (set (match_operand:QI 1 "register_operand")
11549 (match_operator:QI 2 "ix86_comparison_operator"
11550 [(reg FLAGS_REG) (const_int 0)]))
11551 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11552 (and:SI (match_dup 3) (const_int 255)))
11553 (clobber (reg:CC FLAGS_REG))])]
11554 "REGNO (operands[1]) == REGNO (operands[3])
11555 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11556 [(set (match_dup 4) (match_dup 0))
11557 (set (strict_low_part (match_dup 5))
11558 (match_dup 2))]
11559 {
11560 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11561 operands[5] = gen_lowpart (QImode, operands[3]);
11562 ix86_expand_clear (operands[3]);
11563 })
11564
11565 (define_peephole2
11566 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11567 (match_operand 4)])
11568 (set (match_operand:QI 1 "register_operand")
11569 (match_operator:QI 2 "ix86_comparison_operator"
11570 [(reg FLAGS_REG) (const_int 0)]))
11571 (parallel [(set (match_operand 3 "q_regs_operand")
11572 (zero_extend (match_dup 1)))
11573 (clobber (reg:CC FLAGS_REG))])]
11574 "(peep2_reg_dead_p (3, operands[1])
11575 || operands_match_p (operands[1], operands[3]))
11576 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11577 [(parallel [(set (match_dup 5) (match_dup 0))
11578 (match_dup 4)])
11579 (set (strict_low_part (match_dup 6))
11580 (match_dup 2))]
11581 {
11582 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11583 operands[6] = gen_lowpart (QImode, operands[3]);
11584 ix86_expand_clear (operands[3]);
11585 })
11586 \f
11587 ;; Call instructions.
11588
11589 ;; The predicates normally associated with named expanders are not properly
11590 ;; checked for calls. This is a bug in the generic code, but it isn't that
11591 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11592
11593 ;; P6 processors will jump to the address after the decrement when %esp
11594 ;; is used as a call operand, so they will execute return address as a code.
11595 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11596
11597 ;; Register constraint for call instruction.
11598 (define_mode_attr c [(SI "l") (DI "r")])
11599
11600 ;; Call subroutine returning no value.
11601
11602 (define_expand "call"
11603 [(call (match_operand:QI 0)
11604 (match_operand 1))
11605 (use (match_operand 2))]
11606 ""
11607 {
11608 ix86_expand_call (NULL, operands[0], operands[1],
11609 operands[2], NULL, false);
11610 DONE;
11611 })
11612
11613 (define_expand "sibcall"
11614 [(call (match_operand:QI 0)
11615 (match_operand 1))
11616 (use (match_operand 2))]
11617 ""
11618 {
11619 ix86_expand_call (NULL, operands[0], operands[1],
11620 operands[2], NULL, true);
11621 DONE;
11622 })
11623
11624 (define_insn "*call"
11625 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11626 (match_operand 1))]
11627 "!SIBLING_CALL_P (insn)"
11628 "* return ix86_output_call_insn (insn, operands[0]);"
11629 [(set_attr "type" "call")])
11630
11631 (define_insn "*call_rex64_ms_sysv"
11632 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11633 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11634 (match_operand 1))
11635 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11636 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11637 "* return ix86_output_call_insn (insn, operands[0]);"
11638 [(set_attr "type" "call")])
11639
11640 (define_insn "*sibcall"
11641 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11642 (match_operand 1))]
11643 "SIBLING_CALL_P (insn)"
11644 "* return ix86_output_call_insn (insn, operands[0]);"
11645 [(set_attr "type" "call")])
11646
11647 (define_expand "call_pop"
11648 [(parallel [(call (match_operand:QI 0)
11649 (match_operand:SI 1))
11650 (set (reg:SI SP_REG)
11651 (plus:SI (reg:SI SP_REG)
11652 (match_operand:SI 3)))])]
11653 "!TARGET_64BIT"
11654 {
11655 ix86_expand_call (NULL, operands[0], operands[1],
11656 operands[2], operands[3], false);
11657 DONE;
11658 })
11659
11660 (define_insn "*call_pop"
11661 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11662 (match_operand 1))
11663 (set (reg:SI SP_REG)
11664 (plus:SI (reg:SI SP_REG)
11665 (match_operand:SI 2 "immediate_operand" "i")))]
11666 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11667 "* return ix86_output_call_insn (insn, operands[0]);"
11668 [(set_attr "type" "call")])
11669
11670 (define_insn "*sibcall_pop"
11671 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11672 (match_operand 1))
11673 (set (reg:SI SP_REG)
11674 (plus:SI (reg:SI SP_REG)
11675 (match_operand:SI 2 "immediate_operand" "i")))]
11676 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11677 "* return ix86_output_call_insn (insn, operands[0]);"
11678 [(set_attr "type" "call")])
11679
11680 ;; Call subroutine, returning value in operand 0
11681
11682 (define_expand "call_value"
11683 [(set (match_operand 0)
11684 (call (match_operand:QI 1)
11685 (match_operand 2)))
11686 (use (match_operand 3))]
11687 ""
11688 {
11689 ix86_expand_call (operands[0], operands[1], operands[2],
11690 operands[3], NULL, false);
11691 DONE;
11692 })
11693
11694 (define_expand "sibcall_value"
11695 [(set (match_operand 0)
11696 (call (match_operand:QI 1)
11697 (match_operand 2)))
11698 (use (match_operand 3))]
11699 ""
11700 {
11701 ix86_expand_call (operands[0], operands[1], operands[2],
11702 operands[3], NULL, true);
11703 DONE;
11704 })
11705
11706 (define_insn "*call_value"
11707 [(set (match_operand 0)
11708 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11709 (match_operand 2)))]
11710 "!SIBLING_CALL_P (insn)"
11711 "* return ix86_output_call_insn (insn, operands[1]);"
11712 [(set_attr "type" "callv")])
11713
11714 (define_insn "*sibcall_value"
11715 [(set (match_operand 0)
11716 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11717 (match_operand 2)))]
11718 "SIBLING_CALL_P (insn)"
11719 "* return ix86_output_call_insn (insn, operands[1]);"
11720 [(set_attr "type" "callv")])
11721
11722 (define_insn "*call_value_rex64_ms_sysv"
11723 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11724 [(set (match_operand 0)
11725 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11726 (match_operand 2)))
11727 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11728 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11729 "* return ix86_output_call_insn (insn, operands[1]);"
11730 [(set_attr "type" "callv")])
11731
11732 (define_expand "call_value_pop"
11733 [(parallel [(set (match_operand 0)
11734 (call (match_operand:QI 1)
11735 (match_operand:SI 2)))
11736 (set (reg:SI SP_REG)
11737 (plus:SI (reg:SI SP_REG)
11738 (match_operand:SI 4)))])]
11739 "!TARGET_64BIT"
11740 {
11741 ix86_expand_call (operands[0], operands[1], operands[2],
11742 operands[3], operands[4], false);
11743 DONE;
11744 })
11745
11746 (define_insn "*call_value_pop"
11747 [(set (match_operand 0)
11748 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11749 (match_operand 2)))
11750 (set (reg:SI SP_REG)
11751 (plus:SI (reg:SI SP_REG)
11752 (match_operand:SI 3 "immediate_operand" "i")))]
11753 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11754 "* return ix86_output_call_insn (insn, operands[1]);"
11755 [(set_attr "type" "callv")])
11756
11757 (define_insn "*sibcall_value_pop"
11758 [(set (match_operand 0)
11759 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11760 (match_operand 2)))
11761 (set (reg:SI SP_REG)
11762 (plus:SI (reg:SI SP_REG)
11763 (match_operand:SI 3 "immediate_operand" "i")))]
11764 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11765 "* return ix86_output_call_insn (insn, operands[1]);"
11766 [(set_attr "type" "callv")])
11767
11768 ;; Call subroutine returning any type.
11769
11770 (define_expand "untyped_call"
11771 [(parallel [(call (match_operand 0)
11772 (const_int 0))
11773 (match_operand 1)
11774 (match_operand 2)])]
11775 ""
11776 {
11777 int i;
11778
11779 /* In order to give reg-stack an easier job in validating two
11780 coprocessor registers as containing a possible return value,
11781 simply pretend the untyped call returns a complex long double
11782 value.
11783
11784 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11785 and should have the default ABI. */
11786
11787 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11788 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11789 operands[0], const0_rtx,
11790 GEN_INT ((TARGET_64BIT
11791 ? (ix86_abi == SYSV_ABI
11792 ? X86_64_SSE_REGPARM_MAX
11793 : X86_64_MS_SSE_REGPARM_MAX)
11794 : X86_32_SSE_REGPARM_MAX)
11795 - 1),
11796 NULL, false);
11797
11798 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11799 {
11800 rtx set = XVECEXP (operands[2], 0, i);
11801 emit_move_insn (SET_DEST (set), SET_SRC (set));
11802 }
11803
11804 /* The optimizer does not know that the call sets the function value
11805 registers we stored in the result block. We avoid problems by
11806 claiming that all hard registers are used and clobbered at this
11807 point. */
11808 emit_insn (gen_blockage ());
11809
11810 DONE;
11811 })
11812 \f
11813 ;; Prologue and epilogue instructions
11814
11815 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11816 ;; all of memory. This blocks insns from being moved across this point.
11817
11818 (define_insn "blockage"
11819 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11820 ""
11821 ""
11822 [(set_attr "length" "0")])
11823
11824 ;; Do not schedule instructions accessing memory across this point.
11825
11826 (define_expand "memory_blockage"
11827 [(set (match_dup 0)
11828 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11829 ""
11830 {
11831 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11832 MEM_VOLATILE_P (operands[0]) = 1;
11833 })
11834
11835 (define_insn "*memory_blockage"
11836 [(set (match_operand:BLK 0)
11837 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11838 ""
11839 ""
11840 [(set_attr "length" "0")])
11841
11842 ;; As USE insns aren't meaningful after reload, this is used instead
11843 ;; to prevent deleting instructions setting registers for PIC code
11844 (define_insn "prologue_use"
11845 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11846 ""
11847 ""
11848 [(set_attr "length" "0")])
11849
11850 ;; Insn emitted into the body of a function to return from a function.
11851 ;; This is only done if the function's epilogue is known to be simple.
11852 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11853
11854 (define_expand "return"
11855 [(simple_return)]
11856 "ix86_can_use_return_insn_p ()"
11857 {
11858 if (crtl->args.pops_args)
11859 {
11860 rtx popc = GEN_INT (crtl->args.pops_args);
11861 emit_jump_insn (gen_simple_return_pop_internal (popc));
11862 DONE;
11863 }
11864 })
11865
11866 ;; We need to disable this for TARGET_SEH, as otherwise
11867 ;; shrink-wrapped prologue gets enabled too. This might exceed
11868 ;; the maximum size of prologue in unwind information.
11869
11870 (define_expand "simple_return"
11871 [(simple_return)]
11872 "!TARGET_SEH"
11873 {
11874 if (crtl->args.pops_args)
11875 {
11876 rtx popc = GEN_INT (crtl->args.pops_args);
11877 emit_jump_insn (gen_simple_return_pop_internal (popc));
11878 DONE;
11879 }
11880 })
11881
11882 (define_insn "simple_return_internal"
11883 [(simple_return)]
11884 "reload_completed"
11885 "ret"
11886 [(set_attr "length" "1")
11887 (set_attr "atom_unit" "jeu")
11888 (set_attr "length_immediate" "0")
11889 (set_attr "modrm" "0")])
11890
11891 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11892 ;; instruction Athlon and K8 have.
11893
11894 (define_insn "simple_return_internal_long"
11895 [(simple_return)
11896 (unspec [(const_int 0)] UNSPEC_REP)]
11897 "reload_completed"
11898 "rep%; ret"
11899 [(set_attr "length" "2")
11900 (set_attr "atom_unit" "jeu")
11901 (set_attr "length_immediate" "0")
11902 (set_attr "prefix_rep" "1")
11903 (set_attr "modrm" "0")])
11904
11905 (define_insn "simple_return_pop_internal"
11906 [(simple_return)
11907 (use (match_operand:SI 0 "const_int_operand"))]
11908 "reload_completed"
11909 "ret\t%0"
11910 [(set_attr "length" "3")
11911 (set_attr "atom_unit" "jeu")
11912 (set_attr "length_immediate" "2")
11913 (set_attr "modrm" "0")])
11914
11915 (define_insn "simple_return_indirect_internal"
11916 [(simple_return)
11917 (use (match_operand:SI 0 "register_operand" "r"))]
11918 "reload_completed"
11919 "jmp\t%A0"
11920 [(set_attr "type" "ibr")
11921 (set_attr "length_immediate" "0")])
11922
11923 (define_insn "nop"
11924 [(const_int 0)]
11925 ""
11926 "nop"
11927 [(set_attr "length" "1")
11928 (set_attr "length_immediate" "0")
11929 (set_attr "modrm" "0")])
11930
11931 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11932 (define_insn "nops"
11933 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11934 UNSPECV_NOPS)]
11935 "reload_completed"
11936 {
11937 int num = INTVAL (operands[0]);
11938
11939 gcc_assert (IN_RANGE (num, 1, 8));
11940
11941 while (num--)
11942 fputs ("\tnop\n", asm_out_file);
11943
11944 return "";
11945 }
11946 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11947 (set_attr "length_immediate" "0")
11948 (set_attr "modrm" "0")])
11949
11950 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11951 ;; branch prediction penalty for the third jump in a 16-byte
11952 ;; block on K8.
11953
11954 (define_insn "pad"
11955 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11956 ""
11957 {
11958 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11959 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11960 #else
11961 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11962 The align insn is used to avoid 3 jump instructions in the row to improve
11963 branch prediction and the benefits hardly outweigh the cost of extra 8
11964 nops on the average inserted by full alignment pseudo operation. */
11965 #endif
11966 return "";
11967 }
11968 [(set_attr "length" "16")])
11969
11970 (define_expand "prologue"
11971 [(const_int 0)]
11972 ""
11973 "ix86_expand_prologue (); DONE;")
11974
11975 (define_insn "set_got"
11976 [(set (match_operand:SI 0 "register_operand" "=r")
11977 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11978 (clobber (reg:CC FLAGS_REG))]
11979 "!TARGET_64BIT"
11980 "* return output_set_got (operands[0], NULL_RTX);"
11981 [(set_attr "type" "multi")
11982 (set_attr "length" "12")])
11983
11984 (define_insn "set_got_labelled"
11985 [(set (match_operand:SI 0 "register_operand" "=r")
11986 (unspec:SI [(label_ref (match_operand 1))]
11987 UNSPEC_SET_GOT))
11988 (clobber (reg:CC FLAGS_REG))]
11989 "!TARGET_64BIT"
11990 "* return output_set_got (operands[0], operands[1]);"
11991 [(set_attr "type" "multi")
11992 (set_attr "length" "12")])
11993
11994 (define_insn "set_got_rex64"
11995 [(set (match_operand:DI 0 "register_operand" "=r")
11996 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11997 "TARGET_64BIT"
11998 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11999 [(set_attr "type" "lea")
12000 (set_attr "length_address" "4")
12001 (set_attr "mode" "DI")])
12002
12003 (define_insn "set_rip_rex64"
12004 [(set (match_operand:DI 0 "register_operand" "=r")
12005 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12006 "TARGET_64BIT"
12007 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12008 [(set_attr "type" "lea")
12009 (set_attr "length_address" "4")
12010 (set_attr "mode" "DI")])
12011
12012 (define_insn "set_got_offset_rex64"
12013 [(set (match_operand:DI 0 "register_operand" "=r")
12014 (unspec:DI
12015 [(label_ref (match_operand 1))]
12016 UNSPEC_SET_GOT_OFFSET))]
12017 "TARGET_LP64"
12018 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12019 [(set_attr "type" "imov")
12020 (set_attr "length_immediate" "0")
12021 (set_attr "length_address" "8")
12022 (set_attr "mode" "DI")])
12023
12024 (define_expand "epilogue"
12025 [(const_int 0)]
12026 ""
12027 "ix86_expand_epilogue (1); DONE;")
12028
12029 (define_expand "sibcall_epilogue"
12030 [(const_int 0)]
12031 ""
12032 "ix86_expand_epilogue (0); DONE;")
12033
12034 (define_expand "eh_return"
12035 [(use (match_operand 0 "register_operand"))]
12036 ""
12037 {
12038 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12039
12040 /* Tricky bit: we write the address of the handler to which we will
12041 be returning into someone else's stack frame, one word below the
12042 stack address we wish to restore. */
12043 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12044 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12045 tmp = gen_rtx_MEM (Pmode, tmp);
12046 emit_move_insn (tmp, ra);
12047
12048 emit_jump_insn (gen_eh_return_internal ());
12049 emit_barrier ();
12050 DONE;
12051 })
12052
12053 (define_insn_and_split "eh_return_internal"
12054 [(eh_return)]
12055 ""
12056 "#"
12057 "epilogue_completed"
12058 [(const_int 0)]
12059 "ix86_expand_epilogue (2); DONE;")
12060
12061 (define_insn "leave"
12062 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12063 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12064 (clobber (mem:BLK (scratch)))]
12065 "!TARGET_64BIT"
12066 "leave"
12067 [(set_attr "type" "leave")])
12068
12069 (define_insn "leave_rex64"
12070 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12071 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12072 (clobber (mem:BLK (scratch)))]
12073 "TARGET_64BIT"
12074 "leave"
12075 [(set_attr "type" "leave")])
12076 \f
12077 ;; Handle -fsplit-stack.
12078
12079 (define_expand "split_stack_prologue"
12080 [(const_int 0)]
12081 ""
12082 {
12083 ix86_expand_split_stack_prologue ();
12084 DONE;
12085 })
12086
12087 ;; In order to support the call/return predictor, we use a return
12088 ;; instruction which the middle-end doesn't see.
12089 (define_insn "split_stack_return"
12090 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12091 UNSPECV_SPLIT_STACK_RETURN)]
12092 ""
12093 {
12094 if (operands[0] == const0_rtx)
12095 return "ret";
12096 else
12097 return "ret\t%0";
12098 }
12099 [(set_attr "atom_unit" "jeu")
12100 (set_attr "modrm" "0")
12101 (set (attr "length")
12102 (if_then_else (match_operand:SI 0 "const0_operand")
12103 (const_int 1)
12104 (const_int 3)))
12105 (set (attr "length_immediate")
12106 (if_then_else (match_operand:SI 0 "const0_operand")
12107 (const_int 0)
12108 (const_int 2)))])
12109
12110 ;; If there are operand 0 bytes available on the stack, jump to
12111 ;; operand 1.
12112
12113 (define_expand "split_stack_space_check"
12114 [(set (pc) (if_then_else
12115 (ltu (minus (reg SP_REG)
12116 (match_operand 0 "register_operand"))
12117 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12118 (label_ref (match_operand 1))
12119 (pc)))]
12120 ""
12121 {
12122 rtx reg, size, limit;
12123
12124 reg = gen_reg_rtx (Pmode);
12125 size = force_reg (Pmode, operands[0]);
12126 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12127 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12128 UNSPEC_STACK_CHECK);
12129 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12130 ix86_expand_branch (GEU, reg, limit, operands[1]);
12131
12132 DONE;
12133 })
12134 \f
12135 ;; Bit manipulation instructions.
12136
12137 (define_expand "ffs<mode>2"
12138 [(set (match_dup 2) (const_int -1))
12139 (parallel [(set (match_dup 3) (match_dup 4))
12140 (set (match_operand:SWI48 0 "register_operand")
12141 (ctz:SWI48
12142 (match_operand:SWI48 1 "nonimmediate_operand")))])
12143 (set (match_dup 0) (if_then_else:SWI48
12144 (eq (match_dup 3) (const_int 0))
12145 (match_dup 2)
12146 (match_dup 0)))
12147 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12148 (clobber (reg:CC FLAGS_REG))])]
12149 ""
12150 {
12151 enum machine_mode flags_mode;
12152
12153 if (<MODE>mode == SImode && !TARGET_CMOVE)
12154 {
12155 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12156 DONE;
12157 }
12158
12159 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12160
12161 operands[2] = gen_reg_rtx (<MODE>mode);
12162 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12163 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12164 })
12165
12166 (define_insn_and_split "ffssi2_no_cmove"
12167 [(set (match_operand:SI 0 "register_operand" "=r")
12168 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12169 (clobber (match_scratch:SI 2 "=&q"))
12170 (clobber (reg:CC FLAGS_REG))]
12171 "!TARGET_CMOVE"
12172 "#"
12173 "&& reload_completed"
12174 [(parallel [(set (match_dup 4) (match_dup 5))
12175 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12176 (set (strict_low_part (match_dup 3))
12177 (eq:QI (match_dup 4) (const_int 0)))
12178 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12179 (clobber (reg:CC FLAGS_REG))])
12180 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12181 (clobber (reg:CC FLAGS_REG))])
12182 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12183 (clobber (reg:CC FLAGS_REG))])]
12184 {
12185 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12186
12187 operands[3] = gen_lowpart (QImode, operands[2]);
12188 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12189 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12190
12191 ix86_expand_clear (operands[2]);
12192 })
12193
12194 (define_insn "*tzcnt<mode>_1"
12195 [(set (reg:CCC FLAGS_REG)
12196 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12197 (const_int 0)))
12198 (set (match_operand:SWI48 0 "register_operand" "=r")
12199 (ctz:SWI48 (match_dup 1)))]
12200 "TARGET_BMI"
12201 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12202 [(set_attr "type" "alu1")
12203 (set_attr "prefix_0f" "1")
12204 (set_attr "prefix_rep" "1")
12205 (set_attr "btver2_decode" "double")
12206 (set_attr "mode" "<MODE>")])
12207
12208 (define_insn "*bsf<mode>_1"
12209 [(set (reg:CCZ FLAGS_REG)
12210 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12211 (const_int 0)))
12212 (set (match_operand:SWI48 0 "register_operand" "=r")
12213 (ctz:SWI48 (match_dup 1)))]
12214 ""
12215 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12216 [(set_attr "type" "alu1")
12217 (set_attr "prefix_0f" "1")
12218 (set_attr "btver2_decode" "double")
12219 (set_attr "mode" "<MODE>")])
12220
12221 (define_insn "ctz<mode>2"
12222 [(set (match_operand:SWI248 0 "register_operand" "=r")
12223 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12224 (clobber (reg:CC FLAGS_REG))]
12225 ""
12226 {
12227 if (TARGET_BMI)
12228 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12229 else if (optimize_function_for_size_p (cfun))
12230 ;
12231 else if (TARGET_GENERIC)
12232 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12233 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12234
12235 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12236 }
12237 [(set_attr "type" "alu1")
12238 (set_attr "prefix_0f" "1")
12239 (set (attr "prefix_rep")
12240 (if_then_else
12241 (ior (match_test "TARGET_BMI")
12242 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12243 (match_test "TARGET_GENERIC")))
12244 (const_string "1")
12245 (const_string "0")))
12246 (set_attr "mode" "<MODE>")])
12247
12248 (define_expand "clz<mode>2"
12249 [(parallel
12250 [(set (match_operand:SWI248 0 "register_operand")
12251 (minus:SWI248
12252 (match_dup 2)
12253 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12254 (clobber (reg:CC FLAGS_REG))])
12255 (parallel
12256 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12257 (clobber (reg:CC FLAGS_REG))])]
12258 ""
12259 {
12260 if (TARGET_LZCNT)
12261 {
12262 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12263 DONE;
12264 }
12265 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12266 })
12267
12268 (define_insn "clz<mode>2_lzcnt"
12269 [(set (match_operand:SWI248 0 "register_operand" "=r")
12270 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12271 (clobber (reg:CC FLAGS_REG))]
12272 "TARGET_LZCNT"
12273 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12274 [(set_attr "prefix_rep" "1")
12275 (set_attr "type" "bitmanip")
12276 (set_attr "mode" "<MODE>")])
12277
12278 ;; BMI instructions.
12279 (define_insn "*bmi_andn_<mode>"
12280 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12281 (and:SWI48
12282 (not:SWI48
12283 (match_operand:SWI48 1 "register_operand" "r,r"))
12284 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12285 (clobber (reg:CC FLAGS_REG))]
12286 "TARGET_BMI"
12287 "andn\t{%2, %1, %0|%0, %1, %2}"
12288 [(set_attr "type" "bitmanip")
12289 (set_attr "btver2_decode" "direct, double")
12290 (set_attr "mode" "<MODE>")])
12291
12292 (define_insn "bmi_bextr_<mode>"
12293 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12294 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12295 (match_operand:SWI48 2 "register_operand" "r,r")]
12296 UNSPEC_BEXTR))
12297 (clobber (reg:CC FLAGS_REG))]
12298 "TARGET_BMI"
12299 "bextr\t{%2, %1, %0|%0, %1, %2}"
12300 [(set_attr "type" "bitmanip")
12301 (set_attr "btver2_decode" "direct, double")
12302 (set_attr "mode" "<MODE>")])
12303
12304 (define_insn "*bmi_blsi_<mode>"
12305 [(set (match_operand:SWI48 0 "register_operand" "=r")
12306 (and:SWI48
12307 (neg:SWI48
12308 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12309 (match_dup 1)))
12310 (clobber (reg:CC FLAGS_REG))]
12311 "TARGET_BMI"
12312 "blsi\t{%1, %0|%0, %1}"
12313 [(set_attr "type" "bitmanip")
12314 (set_attr "btver2_decode" "double")
12315 (set_attr "mode" "<MODE>")])
12316
12317 (define_insn "*bmi_blsmsk_<mode>"
12318 [(set (match_operand:SWI48 0 "register_operand" "=r")
12319 (xor:SWI48
12320 (plus:SWI48
12321 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12322 (const_int -1))
12323 (match_dup 1)))
12324 (clobber (reg:CC FLAGS_REG))]
12325 "TARGET_BMI"
12326 "blsmsk\t{%1, %0|%0, %1}"
12327 [(set_attr "type" "bitmanip")
12328 (set_attr "btver2_decode" "double")
12329 (set_attr "mode" "<MODE>")])
12330
12331 (define_insn "*bmi_blsr_<mode>"
12332 [(set (match_operand:SWI48 0 "register_operand" "=r")
12333 (and:SWI48
12334 (plus:SWI48
12335 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12336 (const_int -1))
12337 (match_dup 1)))
12338 (clobber (reg:CC FLAGS_REG))]
12339 "TARGET_BMI"
12340 "blsr\t{%1, %0|%0, %1}"
12341 [(set_attr "type" "bitmanip")
12342 (set_attr "btver2_decode" "double")
12343 (set_attr "mode" "<MODE>")])
12344
12345 ;; BMI2 instructions.
12346 (define_insn "bmi2_bzhi_<mode>3"
12347 [(set (match_operand:SWI48 0 "register_operand" "=r")
12348 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12349 (match_operand:SWI48 2 "register_operand" "r"))
12350 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12351 (clobber (reg:CC FLAGS_REG))]
12352 "TARGET_BMI2"
12353 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12354 [(set_attr "type" "bitmanip")
12355 (set_attr "prefix" "vex")
12356 (set_attr "mode" "<MODE>")])
12357
12358 (define_insn "bmi2_pdep_<mode>3"
12359 [(set (match_operand:SWI48 0 "register_operand" "=r")
12360 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12361 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12362 UNSPEC_PDEP))]
12363 "TARGET_BMI2"
12364 "pdep\t{%2, %1, %0|%0, %1, %2}"
12365 [(set_attr "type" "bitmanip")
12366 (set_attr "prefix" "vex")
12367 (set_attr "mode" "<MODE>")])
12368
12369 (define_insn "bmi2_pext_<mode>3"
12370 [(set (match_operand:SWI48 0 "register_operand" "=r")
12371 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12372 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12373 UNSPEC_PEXT))]
12374 "TARGET_BMI2"
12375 "pext\t{%2, %1, %0|%0, %1, %2}"
12376 [(set_attr "type" "bitmanip")
12377 (set_attr "prefix" "vex")
12378 (set_attr "mode" "<MODE>")])
12379
12380 ;; TBM instructions.
12381 (define_insn "tbm_bextri_<mode>"
12382 [(set (match_operand:SWI48 0 "register_operand" "=r")
12383 (zero_extract:SWI48
12384 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12385 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12386 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12387 (clobber (reg:CC FLAGS_REG))]
12388 "TARGET_TBM"
12389 {
12390 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12391 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12392 }
12393 [(set_attr "type" "bitmanip")
12394 (set_attr "mode" "<MODE>")])
12395
12396 (define_insn "*tbm_blcfill_<mode>"
12397 [(set (match_operand:SWI48 0 "register_operand" "=r")
12398 (and:SWI48
12399 (plus:SWI48
12400 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12401 (const_int 1))
12402 (match_dup 1)))
12403 (clobber (reg:CC FLAGS_REG))]
12404 "TARGET_TBM"
12405 "blcfill\t{%1, %0|%0, %1}"
12406 [(set_attr "type" "bitmanip")
12407 (set_attr "mode" "<MODE>")])
12408
12409 (define_insn "*tbm_blci_<mode>"
12410 [(set (match_operand:SWI48 0 "register_operand" "=r")
12411 (ior:SWI48
12412 (not:SWI48
12413 (plus:SWI48
12414 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12415 (const_int 1)))
12416 (match_dup 1)))
12417 (clobber (reg:CC FLAGS_REG))]
12418 "TARGET_TBM"
12419 "blci\t{%1, %0|%0, %1}"
12420 [(set_attr "type" "bitmanip")
12421 (set_attr "mode" "<MODE>")])
12422
12423 (define_insn "*tbm_blcic_<mode>"
12424 [(set (match_operand:SWI48 0 "register_operand" "=r")
12425 (and:SWI48
12426 (plus:SWI48
12427 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12428 (const_int 1))
12429 (not:SWI48
12430 (match_dup 1))))
12431 (clobber (reg:CC FLAGS_REG))]
12432 "TARGET_TBM"
12433 "blcic\t{%1, %0|%0, %1}"
12434 [(set_attr "type" "bitmanip")
12435 (set_attr "mode" "<MODE>")])
12436
12437 (define_insn "*tbm_blcmsk_<mode>"
12438 [(set (match_operand:SWI48 0 "register_operand" "=r")
12439 (xor:SWI48
12440 (plus:SWI48
12441 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12442 (const_int 1))
12443 (match_dup 1)))
12444 (clobber (reg:CC FLAGS_REG))]
12445 "TARGET_TBM"
12446 "blcmsk\t{%1, %0|%0, %1}"
12447 [(set_attr "type" "bitmanip")
12448 (set_attr "mode" "<MODE>")])
12449
12450 (define_insn "*tbm_blcs_<mode>"
12451 [(set (match_operand:SWI48 0 "register_operand" "=r")
12452 (ior:SWI48
12453 (plus:SWI48
12454 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12455 (const_int 1))
12456 (match_dup 1)))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "TARGET_TBM"
12459 "blcs\t{%1, %0|%0, %1}"
12460 [(set_attr "type" "bitmanip")
12461 (set_attr "mode" "<MODE>")])
12462
12463 (define_insn "*tbm_blsfill_<mode>"
12464 [(set (match_operand:SWI48 0 "register_operand" "=r")
12465 (ior:SWI48
12466 (plus:SWI48
12467 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12468 (const_int -1))
12469 (match_dup 1)))
12470 (clobber (reg:CC FLAGS_REG))]
12471 "TARGET_TBM"
12472 "blsfill\t{%1, %0|%0, %1}"
12473 [(set_attr "type" "bitmanip")
12474 (set_attr "mode" "<MODE>")])
12475
12476 (define_insn "*tbm_blsic_<mode>"
12477 [(set (match_operand:SWI48 0 "register_operand" "=r")
12478 (ior:SWI48
12479 (plus:SWI48
12480 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12481 (const_int -1))
12482 (not:SWI48
12483 (match_dup 1))))
12484 (clobber (reg:CC FLAGS_REG))]
12485 "TARGET_TBM"
12486 "blsic\t{%1, %0|%0, %1}"
12487 [(set_attr "type" "bitmanip")
12488 (set_attr "mode" "<MODE>")])
12489
12490 (define_insn "*tbm_t1mskc_<mode>"
12491 [(set (match_operand:SWI48 0 "register_operand" "=r")
12492 (ior:SWI48
12493 (plus:SWI48
12494 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12495 (const_int 1))
12496 (not:SWI48
12497 (match_dup 1))))
12498 (clobber (reg:CC FLAGS_REG))]
12499 "TARGET_TBM"
12500 "t1mskc\t{%1, %0|%0, %1}"
12501 [(set_attr "type" "bitmanip")
12502 (set_attr "mode" "<MODE>")])
12503
12504 (define_insn "*tbm_tzmsk_<mode>"
12505 [(set (match_operand:SWI48 0 "register_operand" "=r")
12506 (and:SWI48
12507 (plus:SWI48
12508 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12509 (const_int -1))
12510 (not:SWI48
12511 (match_dup 1))))
12512 (clobber (reg:CC FLAGS_REG))]
12513 "TARGET_TBM"
12514 "tzmsk\t{%1, %0|%0, %1}"
12515 [(set_attr "type" "bitmanip")
12516 (set_attr "mode" "<MODE>")])
12517
12518 (define_insn "bsr_rex64"
12519 [(set (match_operand:DI 0 "register_operand" "=r")
12520 (minus:DI (const_int 63)
12521 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12522 (clobber (reg:CC FLAGS_REG))]
12523 "TARGET_64BIT"
12524 "bsr{q}\t{%1, %0|%0, %1}"
12525 [(set_attr "type" "alu1")
12526 (set_attr "prefix_0f" "1")
12527 (set_attr "mode" "DI")])
12528
12529 (define_insn "bsr"
12530 [(set (match_operand:SI 0 "register_operand" "=r")
12531 (minus:SI (const_int 31)
12532 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12533 (clobber (reg:CC FLAGS_REG))]
12534 ""
12535 "bsr{l}\t{%1, %0|%0, %1}"
12536 [(set_attr "type" "alu1")
12537 (set_attr "prefix_0f" "1")
12538 (set_attr "mode" "SI")])
12539
12540 (define_insn "*bsrhi"
12541 [(set (match_operand:HI 0 "register_operand" "=r")
12542 (minus:HI (const_int 15)
12543 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12544 (clobber (reg:CC FLAGS_REG))]
12545 ""
12546 "bsr{w}\t{%1, %0|%0, %1}"
12547 [(set_attr "type" "alu1")
12548 (set_attr "prefix_0f" "1")
12549 (set_attr "mode" "HI")])
12550
12551 (define_insn "popcount<mode>2"
12552 [(set (match_operand:SWI248 0 "register_operand" "=r")
12553 (popcount:SWI248
12554 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12555 (clobber (reg:CC FLAGS_REG))]
12556 "TARGET_POPCNT"
12557 {
12558 #if TARGET_MACHO
12559 return "popcnt\t{%1, %0|%0, %1}";
12560 #else
12561 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12562 #endif
12563 }
12564 [(set_attr "prefix_rep" "1")
12565 (set_attr "type" "bitmanip")
12566 (set_attr "mode" "<MODE>")])
12567
12568 (define_insn "*popcount<mode>2_cmp"
12569 [(set (reg FLAGS_REG)
12570 (compare
12571 (popcount:SWI248
12572 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12573 (const_int 0)))
12574 (set (match_operand:SWI248 0 "register_operand" "=r")
12575 (popcount:SWI248 (match_dup 1)))]
12576 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12577 {
12578 #if TARGET_MACHO
12579 return "popcnt\t{%1, %0|%0, %1}";
12580 #else
12581 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12582 #endif
12583 }
12584 [(set_attr "prefix_rep" "1")
12585 (set_attr "type" "bitmanip")
12586 (set_attr "mode" "<MODE>")])
12587
12588 (define_insn "*popcountsi2_cmp_zext"
12589 [(set (reg FLAGS_REG)
12590 (compare
12591 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12592 (const_int 0)))
12593 (set (match_operand:DI 0 "register_operand" "=r")
12594 (zero_extend:DI(popcount:SI (match_dup 1))))]
12595 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12596 {
12597 #if TARGET_MACHO
12598 return "popcnt\t{%1, %0|%0, %1}";
12599 #else
12600 return "popcnt{l}\t{%1, %0|%0, %1}";
12601 #endif
12602 }
12603 [(set_attr "prefix_rep" "1")
12604 (set_attr "type" "bitmanip")
12605 (set_attr "mode" "SI")])
12606
12607 (define_expand "bswapdi2"
12608 [(set (match_operand:DI 0 "register_operand")
12609 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12610 "TARGET_64BIT"
12611 {
12612 if (!TARGET_MOVBE)
12613 operands[1] = force_reg (DImode, operands[1]);
12614 })
12615
12616 (define_expand "bswapsi2"
12617 [(set (match_operand:SI 0 "register_operand")
12618 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12619 ""
12620 {
12621 if (TARGET_MOVBE)
12622 ;
12623 else if (TARGET_BSWAP)
12624 operands[1] = force_reg (SImode, operands[1]);
12625 else
12626 {
12627 rtx x = operands[0];
12628
12629 emit_move_insn (x, operands[1]);
12630 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12631 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12632 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12633 DONE;
12634 }
12635 })
12636
12637 (define_insn "*bswap<mode>2_movbe"
12638 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12639 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12640 "TARGET_MOVBE
12641 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12642 "@
12643 bswap\t%0
12644 movbe\t{%1, %0|%0, %1}
12645 movbe\t{%1, %0|%0, %1}"
12646 [(set_attr "type" "bitmanip,imov,imov")
12647 (set_attr "modrm" "0,1,1")
12648 (set_attr "prefix_0f" "*,1,1")
12649 (set_attr "prefix_extra" "*,1,1")
12650 (set_attr "mode" "<MODE>")])
12651
12652 (define_insn "*bswap<mode>2"
12653 [(set (match_operand:SWI48 0 "register_operand" "=r")
12654 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12655 "TARGET_BSWAP"
12656 "bswap\t%0"
12657 [(set_attr "type" "bitmanip")
12658 (set_attr "modrm" "0")
12659 (set_attr "mode" "<MODE>")])
12660
12661 (define_insn "*bswaphi_lowpart_1"
12662 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12663 (bswap:HI (match_dup 0)))
12664 (clobber (reg:CC FLAGS_REG))]
12665 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12666 "@
12667 xchg{b}\t{%h0, %b0|%b0, %h0}
12668 rol{w}\t{$8, %0|%0, 8}"
12669 [(set_attr "length" "2,4")
12670 (set_attr "mode" "QI,HI")])
12671
12672 (define_insn "bswaphi_lowpart"
12673 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12674 (bswap:HI (match_dup 0)))
12675 (clobber (reg:CC FLAGS_REG))]
12676 ""
12677 "rol{w}\t{$8, %0|%0, 8}"
12678 [(set_attr "length" "4")
12679 (set_attr "mode" "HI")])
12680
12681 (define_expand "paritydi2"
12682 [(set (match_operand:DI 0 "register_operand")
12683 (parity:DI (match_operand:DI 1 "register_operand")))]
12684 "! TARGET_POPCNT"
12685 {
12686 rtx scratch = gen_reg_rtx (QImode);
12687 rtx cond;
12688
12689 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12690 NULL_RTX, operands[1]));
12691
12692 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12693 gen_rtx_REG (CCmode, FLAGS_REG),
12694 const0_rtx);
12695 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12696
12697 if (TARGET_64BIT)
12698 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12699 else
12700 {
12701 rtx tmp = gen_reg_rtx (SImode);
12702
12703 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12704 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12705 }
12706 DONE;
12707 })
12708
12709 (define_expand "paritysi2"
12710 [(set (match_operand:SI 0 "register_operand")
12711 (parity:SI (match_operand:SI 1 "register_operand")))]
12712 "! TARGET_POPCNT"
12713 {
12714 rtx scratch = gen_reg_rtx (QImode);
12715 rtx cond;
12716
12717 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12718
12719 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12720 gen_rtx_REG (CCmode, FLAGS_REG),
12721 const0_rtx);
12722 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12723
12724 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12725 DONE;
12726 })
12727
12728 (define_insn_and_split "paritydi2_cmp"
12729 [(set (reg:CC FLAGS_REG)
12730 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12731 UNSPEC_PARITY))
12732 (clobber (match_scratch:DI 0 "=r"))
12733 (clobber (match_scratch:SI 1 "=&r"))
12734 (clobber (match_scratch:HI 2 "=Q"))]
12735 "! TARGET_POPCNT"
12736 "#"
12737 "&& reload_completed"
12738 [(parallel
12739 [(set (match_dup 1)
12740 (xor:SI (match_dup 1) (match_dup 4)))
12741 (clobber (reg:CC FLAGS_REG))])
12742 (parallel
12743 [(set (reg:CC FLAGS_REG)
12744 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12745 (clobber (match_dup 1))
12746 (clobber (match_dup 2))])]
12747 {
12748 operands[4] = gen_lowpart (SImode, operands[3]);
12749
12750 if (TARGET_64BIT)
12751 {
12752 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12753 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12754 }
12755 else
12756 operands[1] = gen_highpart (SImode, operands[3]);
12757 })
12758
12759 (define_insn_and_split "paritysi2_cmp"
12760 [(set (reg:CC FLAGS_REG)
12761 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12762 UNSPEC_PARITY))
12763 (clobber (match_scratch:SI 0 "=r"))
12764 (clobber (match_scratch:HI 1 "=&Q"))]
12765 "! TARGET_POPCNT"
12766 "#"
12767 "&& reload_completed"
12768 [(parallel
12769 [(set (match_dup 1)
12770 (xor:HI (match_dup 1) (match_dup 3)))
12771 (clobber (reg:CC FLAGS_REG))])
12772 (parallel
12773 [(set (reg:CC FLAGS_REG)
12774 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12775 (clobber (match_dup 1))])]
12776 {
12777 operands[3] = gen_lowpart (HImode, operands[2]);
12778
12779 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12780 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12781 })
12782
12783 (define_insn "*parityhi2_cmp"
12784 [(set (reg:CC FLAGS_REG)
12785 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12786 UNSPEC_PARITY))
12787 (clobber (match_scratch:HI 0 "=Q"))]
12788 "! TARGET_POPCNT"
12789 "xor{b}\t{%h0, %b0|%b0, %h0}"
12790 [(set_attr "length" "2")
12791 (set_attr "mode" "HI")])
12792
12793 \f
12794 ;; Thread-local storage patterns for ELF.
12795 ;;
12796 ;; Note that these code sequences must appear exactly as shown
12797 ;; in order to allow linker relaxation.
12798
12799 (define_insn "*tls_global_dynamic_32_gnu"
12800 [(set (match_operand:SI 0 "register_operand" "=a")
12801 (unspec:SI
12802 [(match_operand:SI 1 "register_operand" "b")
12803 (match_operand 2 "tls_symbolic_operand")
12804 (match_operand 3 "constant_call_address_operand" "z")]
12805 UNSPEC_TLS_GD))
12806 (clobber (match_scratch:SI 4 "=d"))
12807 (clobber (match_scratch:SI 5 "=c"))
12808 (clobber (reg:CC FLAGS_REG))]
12809 "!TARGET_64BIT && TARGET_GNU_TLS"
12810 {
12811 output_asm_insn
12812 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12813 if (TARGET_SUN_TLS)
12814 #ifdef HAVE_AS_IX86_TLSGDPLT
12815 return "call\t%a2@tlsgdplt";
12816 #else
12817 return "call\t%p3@plt";
12818 #endif
12819 return "call\t%P3";
12820 }
12821 [(set_attr "type" "multi")
12822 (set_attr "length" "12")])
12823
12824 (define_expand "tls_global_dynamic_32"
12825 [(parallel
12826 [(set (match_operand:SI 0 "register_operand")
12827 (unspec:SI [(match_operand:SI 2 "register_operand")
12828 (match_operand 1 "tls_symbolic_operand")
12829 (match_operand 3 "constant_call_address_operand")]
12830 UNSPEC_TLS_GD))
12831 (clobber (match_scratch:SI 4))
12832 (clobber (match_scratch:SI 5))
12833 (clobber (reg:CC FLAGS_REG))])])
12834
12835 (define_insn "*tls_global_dynamic_64_<mode>"
12836 [(set (match_operand:P 0 "register_operand" "=a")
12837 (call:P
12838 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12839 (match_operand 3)))
12840 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12841 UNSPEC_TLS_GD)]
12842 "TARGET_64BIT"
12843 {
12844 if (!TARGET_X32)
12845 fputs (ASM_BYTE "0x66\n", asm_out_file);
12846 output_asm_insn
12847 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12848 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12849 fputs ("\trex64\n", asm_out_file);
12850 if (TARGET_SUN_TLS)
12851 return "call\t%p2@plt";
12852 return "call\t%P2";
12853 }
12854 [(set_attr "type" "multi")
12855 (set (attr "length")
12856 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12857
12858 (define_insn "*tls_global_dynamic_64_largepic"
12859 [(set (match_operand:DI 0 "register_operand" "=a")
12860 (call:DI
12861 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12862 (match_operand:DI 3 "immediate_operand" "i")))
12863 (match_operand 4)))
12864 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12865 UNSPEC_TLS_GD)]
12866 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12867 && GET_CODE (operands[3]) == CONST
12868 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
12869 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
12870 {
12871 output_asm_insn
12872 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12873 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
12874 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
12875 return "call\t{*%%rax|rax}";
12876 }
12877 [(set_attr "type" "multi")
12878 (set_attr "length" "22")])
12879
12880 (define_expand "tls_global_dynamic_64_<mode>"
12881 [(parallel
12882 [(set (match_operand:P 0 "register_operand")
12883 (call:P
12884 (mem:QI (match_operand 2))
12885 (const_int 0)))
12886 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12887 UNSPEC_TLS_GD)])]
12888 "TARGET_64BIT")
12889
12890 (define_insn "*tls_local_dynamic_base_32_gnu"
12891 [(set (match_operand:SI 0 "register_operand" "=a")
12892 (unspec:SI
12893 [(match_operand:SI 1 "register_operand" "b")
12894 (match_operand 2 "constant_call_address_operand" "z")]
12895 UNSPEC_TLS_LD_BASE))
12896 (clobber (match_scratch:SI 3 "=d"))
12897 (clobber (match_scratch:SI 4 "=c"))
12898 (clobber (reg:CC FLAGS_REG))]
12899 "!TARGET_64BIT && TARGET_GNU_TLS"
12900 {
12901 output_asm_insn
12902 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12903 if (TARGET_SUN_TLS)
12904 #ifdef HAVE_AS_IX86_TLSLDMPLT
12905 return "call\t%&@tlsldmplt";
12906 #else
12907 return "call\t%p2@plt";
12908 #endif
12909 return "call\t%P2";
12910 }
12911 [(set_attr "type" "multi")
12912 (set_attr "length" "11")])
12913
12914 (define_expand "tls_local_dynamic_base_32"
12915 [(parallel
12916 [(set (match_operand:SI 0 "register_operand")
12917 (unspec:SI
12918 [(match_operand:SI 1 "register_operand")
12919 (match_operand 2 "constant_call_address_operand")]
12920 UNSPEC_TLS_LD_BASE))
12921 (clobber (match_scratch:SI 3))
12922 (clobber (match_scratch:SI 4))
12923 (clobber (reg:CC FLAGS_REG))])])
12924
12925 (define_insn "*tls_local_dynamic_base_64_<mode>"
12926 [(set (match_operand:P 0 "register_operand" "=a")
12927 (call:P
12928 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12929 (match_operand 2)))
12930 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12931 "TARGET_64BIT"
12932 {
12933 output_asm_insn
12934 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12935 if (TARGET_SUN_TLS)
12936 return "call\t%p1@plt";
12937 return "call\t%P1";
12938 }
12939 [(set_attr "type" "multi")
12940 (set_attr "length" "12")])
12941
12942 (define_insn "*tls_local_dynamic_base_64_largepic"
12943 [(set (match_operand:DI 0 "register_operand" "=a")
12944 (call:DI
12945 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
12946 (match_operand:DI 2 "immediate_operand" "i")))
12947 (match_operand 3)))
12948 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12949 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
12950 && GET_CODE (operands[2]) == CONST
12951 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
12952 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
12953 {
12954 output_asm_insn
12955 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12956 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
12957 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
12958 return "call\t{*%%rax|rax}";
12959 }
12960 [(set_attr "type" "multi")
12961 (set_attr "length" "22")])
12962
12963 (define_expand "tls_local_dynamic_base_64_<mode>"
12964 [(parallel
12965 [(set (match_operand:P 0 "register_operand")
12966 (call:P
12967 (mem:QI (match_operand 1))
12968 (const_int 0)))
12969 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12970 "TARGET_64BIT")
12971
12972 ;; Local dynamic of a single variable is a lose. Show combine how
12973 ;; to convert that back to global dynamic.
12974
12975 (define_insn_and_split "*tls_local_dynamic_32_once"
12976 [(set (match_operand:SI 0 "register_operand" "=a")
12977 (plus:SI
12978 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12979 (match_operand 2 "constant_call_address_operand" "z")]
12980 UNSPEC_TLS_LD_BASE)
12981 (const:SI (unspec:SI
12982 [(match_operand 3 "tls_symbolic_operand")]
12983 UNSPEC_DTPOFF))))
12984 (clobber (match_scratch:SI 4 "=d"))
12985 (clobber (match_scratch:SI 5 "=c"))
12986 (clobber (reg:CC FLAGS_REG))]
12987 ""
12988 "#"
12989 ""
12990 [(parallel
12991 [(set (match_dup 0)
12992 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12993 UNSPEC_TLS_GD))
12994 (clobber (match_dup 4))
12995 (clobber (match_dup 5))
12996 (clobber (reg:CC FLAGS_REG))])])
12997
12998 ;; Segment register for the thread base ptr load
12999 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13000
13001 ;; Load and add the thread base pointer from %<tp_seg>:0.
13002 (define_insn "*load_tp_x32"
13003 [(set (match_operand:SI 0 "register_operand" "=r")
13004 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13005 "TARGET_X32"
13006 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13007 [(set_attr "type" "imov")
13008 (set_attr "modrm" "0")
13009 (set_attr "length" "7")
13010 (set_attr "memory" "load")
13011 (set_attr "imm_disp" "false")])
13012
13013 (define_insn "*load_tp_x32_zext"
13014 [(set (match_operand:DI 0 "register_operand" "=r")
13015 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13016 "TARGET_X32"
13017 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13018 [(set_attr "type" "imov")
13019 (set_attr "modrm" "0")
13020 (set_attr "length" "7")
13021 (set_attr "memory" "load")
13022 (set_attr "imm_disp" "false")])
13023
13024 (define_insn "*load_tp_<mode>"
13025 [(set (match_operand:P 0 "register_operand" "=r")
13026 (unspec:P [(const_int 0)] UNSPEC_TP))]
13027 "!TARGET_X32"
13028 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13029 [(set_attr "type" "imov")
13030 (set_attr "modrm" "0")
13031 (set_attr "length" "7")
13032 (set_attr "memory" "load")
13033 (set_attr "imm_disp" "false")])
13034
13035 (define_insn "*add_tp_x32"
13036 [(set (match_operand:SI 0 "register_operand" "=r")
13037 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13038 (match_operand:SI 1 "register_operand" "0")))
13039 (clobber (reg:CC FLAGS_REG))]
13040 "TARGET_X32"
13041 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13042 [(set_attr "type" "alu")
13043 (set_attr "modrm" "0")
13044 (set_attr "length" "7")
13045 (set_attr "memory" "load")
13046 (set_attr "imm_disp" "false")])
13047
13048 (define_insn "*add_tp_x32_zext"
13049 [(set (match_operand:DI 0 "register_operand" "=r")
13050 (zero_extend:DI
13051 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13052 (match_operand:SI 1 "register_operand" "0"))))
13053 (clobber (reg:CC FLAGS_REG))]
13054 "TARGET_X32"
13055 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13056 [(set_attr "type" "alu")
13057 (set_attr "modrm" "0")
13058 (set_attr "length" "7")
13059 (set_attr "memory" "load")
13060 (set_attr "imm_disp" "false")])
13061
13062 (define_insn "*add_tp_<mode>"
13063 [(set (match_operand:P 0 "register_operand" "=r")
13064 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13065 (match_operand:P 1 "register_operand" "0")))
13066 (clobber (reg:CC FLAGS_REG))]
13067 "!TARGET_X32"
13068 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13069 [(set_attr "type" "alu")
13070 (set_attr "modrm" "0")
13071 (set_attr "length" "7")
13072 (set_attr "memory" "load")
13073 (set_attr "imm_disp" "false")])
13074
13075 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13076 ;; %rax as destination of the initial executable code sequence.
13077 (define_insn "tls_initial_exec_64_sun"
13078 [(set (match_operand:DI 0 "register_operand" "=a")
13079 (unspec:DI
13080 [(match_operand 1 "tls_symbolic_operand")]
13081 UNSPEC_TLS_IE_SUN))
13082 (clobber (reg:CC FLAGS_REG))]
13083 "TARGET_64BIT && TARGET_SUN_TLS"
13084 {
13085 output_asm_insn
13086 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13087 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13088 }
13089 [(set_attr "type" "multi")])
13090
13091 ;; GNU2 TLS patterns can be split.
13092
13093 (define_expand "tls_dynamic_gnu2_32"
13094 [(set (match_dup 3)
13095 (plus:SI (match_operand:SI 2 "register_operand")
13096 (const:SI
13097 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13098 UNSPEC_TLSDESC))))
13099 (parallel
13100 [(set (match_operand:SI 0 "register_operand")
13101 (unspec:SI [(match_dup 1) (match_dup 3)
13102 (match_dup 2) (reg:SI SP_REG)]
13103 UNSPEC_TLSDESC))
13104 (clobber (reg:CC FLAGS_REG))])]
13105 "!TARGET_64BIT && TARGET_GNU2_TLS"
13106 {
13107 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13108 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13109 })
13110
13111 (define_insn "*tls_dynamic_gnu2_lea_32"
13112 [(set (match_operand:SI 0 "register_operand" "=r")
13113 (plus:SI (match_operand:SI 1 "register_operand" "b")
13114 (const:SI
13115 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13116 UNSPEC_TLSDESC))))]
13117 "!TARGET_64BIT && TARGET_GNU2_TLS"
13118 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13119 [(set_attr "type" "lea")
13120 (set_attr "mode" "SI")
13121 (set_attr "length" "6")
13122 (set_attr "length_address" "4")])
13123
13124 (define_insn "*tls_dynamic_gnu2_call_32"
13125 [(set (match_operand:SI 0 "register_operand" "=a")
13126 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13127 (match_operand:SI 2 "register_operand" "0")
13128 ;; we have to make sure %ebx still points to the GOT
13129 (match_operand:SI 3 "register_operand" "b")
13130 (reg:SI SP_REG)]
13131 UNSPEC_TLSDESC))
13132 (clobber (reg:CC FLAGS_REG))]
13133 "!TARGET_64BIT && TARGET_GNU2_TLS"
13134 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13135 [(set_attr "type" "call")
13136 (set_attr "length" "2")
13137 (set_attr "length_address" "0")])
13138
13139 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13140 [(set (match_operand:SI 0 "register_operand" "=&a")
13141 (plus:SI
13142 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13143 (match_operand:SI 4)
13144 (match_operand:SI 2 "register_operand" "b")
13145 (reg:SI SP_REG)]
13146 UNSPEC_TLSDESC)
13147 (const:SI (unspec:SI
13148 [(match_operand 1 "tls_symbolic_operand")]
13149 UNSPEC_DTPOFF))))
13150 (clobber (reg:CC FLAGS_REG))]
13151 "!TARGET_64BIT && TARGET_GNU2_TLS"
13152 "#"
13153 ""
13154 [(set (match_dup 0) (match_dup 5))]
13155 {
13156 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13157 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13158 })
13159
13160 (define_expand "tls_dynamic_gnu2_64"
13161 [(set (match_dup 2)
13162 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13163 UNSPEC_TLSDESC))
13164 (parallel
13165 [(set (match_operand:DI 0 "register_operand")
13166 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13167 UNSPEC_TLSDESC))
13168 (clobber (reg:CC FLAGS_REG))])]
13169 "TARGET_64BIT && TARGET_GNU2_TLS"
13170 {
13171 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13172 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13173 })
13174
13175 (define_insn "*tls_dynamic_gnu2_lea_64"
13176 [(set (match_operand:DI 0 "register_operand" "=r")
13177 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13178 UNSPEC_TLSDESC))]
13179 "TARGET_64BIT && TARGET_GNU2_TLS"
13180 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13181 [(set_attr "type" "lea")
13182 (set_attr "mode" "DI")
13183 (set_attr "length" "7")
13184 (set_attr "length_address" "4")])
13185
13186 (define_insn "*tls_dynamic_gnu2_call_64"
13187 [(set (match_operand:DI 0 "register_operand" "=a")
13188 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13189 (match_operand:DI 2 "register_operand" "0")
13190 (reg:DI SP_REG)]
13191 UNSPEC_TLSDESC))
13192 (clobber (reg:CC FLAGS_REG))]
13193 "TARGET_64BIT && TARGET_GNU2_TLS"
13194 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13195 [(set_attr "type" "call")
13196 (set_attr "length" "2")
13197 (set_attr "length_address" "0")])
13198
13199 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13200 [(set (match_operand:DI 0 "register_operand" "=&a")
13201 (plus:DI
13202 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13203 (match_operand:DI 3)
13204 (reg:DI SP_REG)]
13205 UNSPEC_TLSDESC)
13206 (const:DI (unspec:DI
13207 [(match_operand 1 "tls_symbolic_operand")]
13208 UNSPEC_DTPOFF))))
13209 (clobber (reg:CC FLAGS_REG))]
13210 "TARGET_64BIT && TARGET_GNU2_TLS"
13211 "#"
13212 ""
13213 [(set (match_dup 0) (match_dup 4))]
13214 {
13215 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13216 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13217 })
13218 \f
13219 ;; These patterns match the binary 387 instructions for addM3, subM3,
13220 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13221 ;; SFmode. The first is the normal insn, the second the same insn but
13222 ;; with one operand a conversion, and the third the same insn but with
13223 ;; the other operand a conversion. The conversion may be SFmode or
13224 ;; SImode if the target mode DFmode, but only SImode if the target mode
13225 ;; is SFmode.
13226
13227 ;; Gcc is slightly more smart about handling normal two address instructions
13228 ;; so use special patterns for add and mull.
13229
13230 (define_insn "*fop_<mode>_comm_mixed"
13231 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13232 (match_operator:MODEF 3 "binary_fp_operator"
13233 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13234 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13235 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13236 && COMMUTATIVE_ARITH_P (operands[3])
13237 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13238 "* return output_387_binary_op (insn, operands);"
13239 [(set (attr "type")
13240 (if_then_else (eq_attr "alternative" "1,2")
13241 (if_then_else (match_operand:MODEF 3 "mult_operator")
13242 (const_string "ssemul")
13243 (const_string "sseadd"))
13244 (if_then_else (match_operand:MODEF 3 "mult_operator")
13245 (const_string "fmul")
13246 (const_string "fop"))))
13247 (set_attr "isa" "*,noavx,avx")
13248 (set_attr "prefix" "orig,orig,vex")
13249 (set_attr "mode" "<MODE>")])
13250
13251 (define_insn "*fop_<mode>_comm_sse"
13252 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13253 (match_operator:MODEF 3 "binary_fp_operator"
13254 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13255 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13256 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13257 && COMMUTATIVE_ARITH_P (operands[3])
13258 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13259 "* return output_387_binary_op (insn, operands);"
13260 [(set (attr "type")
13261 (if_then_else (match_operand:MODEF 3 "mult_operator")
13262 (const_string "ssemul")
13263 (const_string "sseadd")))
13264 (set_attr "isa" "noavx,avx")
13265 (set_attr "prefix" "orig,vex")
13266 (set_attr "mode" "<MODE>")])
13267
13268 (define_insn "*fop_<mode>_comm_i387"
13269 [(set (match_operand:MODEF 0 "register_operand" "=f")
13270 (match_operator:MODEF 3 "binary_fp_operator"
13271 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13272 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13273 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13274 && COMMUTATIVE_ARITH_P (operands[3])
13275 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13276 "* return output_387_binary_op (insn, operands);"
13277 [(set (attr "type")
13278 (if_then_else (match_operand:MODEF 3 "mult_operator")
13279 (const_string "fmul")
13280 (const_string "fop")))
13281 (set_attr "mode" "<MODE>")])
13282
13283 (define_insn "*fop_<mode>_1_mixed"
13284 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13285 (match_operator:MODEF 3 "binary_fp_operator"
13286 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13287 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13288 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13289 && !COMMUTATIVE_ARITH_P (operands[3])
13290 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13291 "* return output_387_binary_op (insn, operands);"
13292 [(set (attr "type")
13293 (cond [(and (eq_attr "alternative" "2,3")
13294 (match_operand:MODEF 3 "mult_operator"))
13295 (const_string "ssemul")
13296 (and (eq_attr "alternative" "2,3")
13297 (match_operand:MODEF 3 "div_operator"))
13298 (const_string "ssediv")
13299 (eq_attr "alternative" "2,3")
13300 (const_string "sseadd")
13301 (match_operand:MODEF 3 "mult_operator")
13302 (const_string "fmul")
13303 (match_operand:MODEF 3 "div_operator")
13304 (const_string "fdiv")
13305 ]
13306 (const_string "fop")))
13307 (set_attr "isa" "*,*,noavx,avx")
13308 (set_attr "prefix" "orig,orig,orig,vex")
13309 (set_attr "mode" "<MODE>")])
13310
13311 (define_insn "*rcpsf2_sse"
13312 [(set (match_operand:SF 0 "register_operand" "=x")
13313 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13314 UNSPEC_RCP))]
13315 "TARGET_SSE_MATH"
13316 "%vrcpss\t{%1, %d0|%d0, %1}"
13317 [(set_attr "type" "sse")
13318 (set_attr "atom_sse_attr" "rcp")
13319 (set_attr "btver2_sse_attr" "rcp")
13320 (set_attr "prefix" "maybe_vex")
13321 (set_attr "mode" "SF")])
13322
13323 (define_insn "*fop_<mode>_1_sse"
13324 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13325 (match_operator:MODEF 3 "binary_fp_operator"
13326 [(match_operand:MODEF 1 "register_operand" "0,x")
13327 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13328 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13329 && !COMMUTATIVE_ARITH_P (operands[3])"
13330 "* return output_387_binary_op (insn, operands);"
13331 [(set (attr "type")
13332 (cond [(match_operand:MODEF 3 "mult_operator")
13333 (const_string "ssemul")
13334 (match_operand:MODEF 3 "div_operator")
13335 (const_string "ssediv")
13336 ]
13337 (const_string "sseadd")))
13338 (set_attr "isa" "noavx,avx")
13339 (set_attr "prefix" "orig,vex")
13340 (set_attr "mode" "<MODE>")])
13341
13342 ;; This pattern is not fully shadowed by the pattern above.
13343 (define_insn "*fop_<mode>_1_i387"
13344 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13345 (match_operator:MODEF 3 "binary_fp_operator"
13346 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13347 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13348 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13349 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13350 && !COMMUTATIVE_ARITH_P (operands[3])
13351 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13352 "* return output_387_binary_op (insn, operands);"
13353 [(set (attr "type")
13354 (cond [(match_operand:MODEF 3 "mult_operator")
13355 (const_string "fmul")
13356 (match_operand:MODEF 3 "div_operator")
13357 (const_string "fdiv")
13358 ]
13359 (const_string "fop")))
13360 (set_attr "mode" "<MODE>")])
13361
13362 ;; ??? Add SSE splitters for these!
13363 (define_insn "*fop_<MODEF:mode>_2_i387"
13364 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13365 (match_operator:MODEF 3 "binary_fp_operator"
13366 [(float:MODEF
13367 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13368 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13369 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13370 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13371 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13372 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13373 [(set (attr "type")
13374 (cond [(match_operand:MODEF 3 "mult_operator")
13375 (const_string "fmul")
13376 (match_operand:MODEF 3 "div_operator")
13377 (const_string "fdiv")
13378 ]
13379 (const_string "fop")))
13380 (set_attr "fp_int_src" "true")
13381 (set_attr "mode" "<SWI24:MODE>")])
13382
13383 (define_insn "*fop_<MODEF:mode>_3_i387"
13384 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13385 (match_operator:MODEF 3 "binary_fp_operator"
13386 [(match_operand:MODEF 1 "register_operand" "0,0")
13387 (float:MODEF
13388 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13389 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13390 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13391 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13392 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13393 [(set (attr "type")
13394 (cond [(match_operand:MODEF 3 "mult_operator")
13395 (const_string "fmul")
13396 (match_operand:MODEF 3 "div_operator")
13397 (const_string "fdiv")
13398 ]
13399 (const_string "fop")))
13400 (set_attr "fp_int_src" "true")
13401 (set_attr "mode" "<MODE>")])
13402
13403 (define_insn "*fop_df_4_i387"
13404 [(set (match_operand:DF 0 "register_operand" "=f,f")
13405 (match_operator:DF 3 "binary_fp_operator"
13406 [(float_extend:DF
13407 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13408 (match_operand:DF 2 "register_operand" "0,f")]))]
13409 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13410 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13411 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13412 "* return output_387_binary_op (insn, operands);"
13413 [(set (attr "type")
13414 (cond [(match_operand:DF 3 "mult_operator")
13415 (const_string "fmul")
13416 (match_operand:DF 3 "div_operator")
13417 (const_string "fdiv")
13418 ]
13419 (const_string "fop")))
13420 (set_attr "mode" "SF")])
13421
13422 (define_insn "*fop_df_5_i387"
13423 [(set (match_operand:DF 0 "register_operand" "=f,f")
13424 (match_operator:DF 3 "binary_fp_operator"
13425 [(match_operand:DF 1 "register_operand" "0,f")
13426 (float_extend:DF
13427 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13428 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13429 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13430 "* return output_387_binary_op (insn, operands);"
13431 [(set (attr "type")
13432 (cond [(match_operand:DF 3 "mult_operator")
13433 (const_string "fmul")
13434 (match_operand:DF 3 "div_operator")
13435 (const_string "fdiv")
13436 ]
13437 (const_string "fop")))
13438 (set_attr "mode" "SF")])
13439
13440 (define_insn "*fop_df_6_i387"
13441 [(set (match_operand:DF 0 "register_operand" "=f,f")
13442 (match_operator:DF 3 "binary_fp_operator"
13443 [(float_extend:DF
13444 (match_operand:SF 1 "register_operand" "0,f"))
13445 (float_extend:DF
13446 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13447 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13448 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13449 "* return output_387_binary_op (insn, operands);"
13450 [(set (attr "type")
13451 (cond [(match_operand:DF 3 "mult_operator")
13452 (const_string "fmul")
13453 (match_operand:DF 3 "div_operator")
13454 (const_string "fdiv")
13455 ]
13456 (const_string "fop")))
13457 (set_attr "mode" "SF")])
13458
13459 (define_insn "*fop_xf_comm_i387"
13460 [(set (match_operand:XF 0 "register_operand" "=f")
13461 (match_operator:XF 3 "binary_fp_operator"
13462 [(match_operand:XF 1 "register_operand" "%0")
13463 (match_operand:XF 2 "register_operand" "f")]))]
13464 "TARGET_80387
13465 && COMMUTATIVE_ARITH_P (operands[3])"
13466 "* return output_387_binary_op (insn, operands);"
13467 [(set (attr "type")
13468 (if_then_else (match_operand:XF 3 "mult_operator")
13469 (const_string "fmul")
13470 (const_string "fop")))
13471 (set_attr "mode" "XF")])
13472
13473 (define_insn "*fop_xf_1_i387"
13474 [(set (match_operand:XF 0 "register_operand" "=f,f")
13475 (match_operator:XF 3 "binary_fp_operator"
13476 [(match_operand:XF 1 "register_operand" "0,f")
13477 (match_operand:XF 2 "register_operand" "f,0")]))]
13478 "TARGET_80387
13479 && !COMMUTATIVE_ARITH_P (operands[3])"
13480 "* return output_387_binary_op (insn, operands);"
13481 [(set (attr "type")
13482 (cond [(match_operand:XF 3 "mult_operator")
13483 (const_string "fmul")
13484 (match_operand:XF 3 "div_operator")
13485 (const_string "fdiv")
13486 ]
13487 (const_string "fop")))
13488 (set_attr "mode" "XF")])
13489
13490 (define_insn "*fop_xf_2_i387"
13491 [(set (match_operand:XF 0 "register_operand" "=f,f")
13492 (match_operator:XF 3 "binary_fp_operator"
13493 [(float:XF
13494 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13495 (match_operand:XF 2 "register_operand" "0,0")]))]
13496 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13497 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13498 [(set (attr "type")
13499 (cond [(match_operand:XF 3 "mult_operator")
13500 (const_string "fmul")
13501 (match_operand:XF 3 "div_operator")
13502 (const_string "fdiv")
13503 ]
13504 (const_string "fop")))
13505 (set_attr "fp_int_src" "true")
13506 (set_attr "mode" "<MODE>")])
13507
13508 (define_insn "*fop_xf_3_i387"
13509 [(set (match_operand:XF 0 "register_operand" "=f,f")
13510 (match_operator:XF 3 "binary_fp_operator"
13511 [(match_operand:XF 1 "register_operand" "0,0")
13512 (float:XF
13513 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13514 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13515 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13516 [(set (attr "type")
13517 (cond [(match_operand:XF 3 "mult_operator")
13518 (const_string "fmul")
13519 (match_operand:XF 3 "div_operator")
13520 (const_string "fdiv")
13521 ]
13522 (const_string "fop")))
13523 (set_attr "fp_int_src" "true")
13524 (set_attr "mode" "<MODE>")])
13525
13526 (define_insn "*fop_xf_4_i387"
13527 [(set (match_operand:XF 0 "register_operand" "=f,f")
13528 (match_operator:XF 3 "binary_fp_operator"
13529 [(float_extend:XF
13530 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13531 (match_operand:XF 2 "register_operand" "0,f")]))]
13532 "TARGET_80387"
13533 "* return output_387_binary_op (insn, operands);"
13534 [(set (attr "type")
13535 (cond [(match_operand:XF 3 "mult_operator")
13536 (const_string "fmul")
13537 (match_operand:XF 3 "div_operator")
13538 (const_string "fdiv")
13539 ]
13540 (const_string "fop")))
13541 (set_attr "mode" "<MODE>")])
13542
13543 (define_insn "*fop_xf_5_i387"
13544 [(set (match_operand:XF 0 "register_operand" "=f,f")
13545 (match_operator:XF 3 "binary_fp_operator"
13546 [(match_operand:XF 1 "register_operand" "0,f")
13547 (float_extend:XF
13548 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13549 "TARGET_80387"
13550 "* return output_387_binary_op (insn, operands);"
13551 [(set (attr "type")
13552 (cond [(match_operand:XF 3 "mult_operator")
13553 (const_string "fmul")
13554 (match_operand:XF 3 "div_operator")
13555 (const_string "fdiv")
13556 ]
13557 (const_string "fop")))
13558 (set_attr "mode" "<MODE>")])
13559
13560 (define_insn "*fop_xf_6_i387"
13561 [(set (match_operand:XF 0 "register_operand" "=f,f")
13562 (match_operator:XF 3 "binary_fp_operator"
13563 [(float_extend:XF
13564 (match_operand:MODEF 1 "register_operand" "0,f"))
13565 (float_extend:XF
13566 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13567 "TARGET_80387"
13568 "* return output_387_binary_op (insn, operands);"
13569 [(set (attr "type")
13570 (cond [(match_operand:XF 3 "mult_operator")
13571 (const_string "fmul")
13572 (match_operand:XF 3 "div_operator")
13573 (const_string "fdiv")
13574 ]
13575 (const_string "fop")))
13576 (set_attr "mode" "<MODE>")])
13577
13578 (define_split
13579 [(set (match_operand 0 "register_operand")
13580 (match_operator 3 "binary_fp_operator"
13581 [(float (match_operand:SWI24 1 "register_operand"))
13582 (match_operand 2 "register_operand")]))]
13583 "reload_completed
13584 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13585 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13586 [(const_int 0)]
13587 {
13588 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13589 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13590 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13591 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13592 GET_MODE (operands[3]),
13593 operands[4],
13594 operands[2])));
13595 ix86_free_from_memory (GET_MODE (operands[1]));
13596 DONE;
13597 })
13598
13599 (define_split
13600 [(set (match_operand 0 "register_operand")
13601 (match_operator 3 "binary_fp_operator"
13602 [(match_operand 1 "register_operand")
13603 (float (match_operand:SWI24 2 "register_operand"))]))]
13604 "reload_completed
13605 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13606 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13607 [(const_int 0)]
13608 {
13609 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13610 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13611 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13612 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13613 GET_MODE (operands[3]),
13614 operands[1],
13615 operands[4])));
13616 ix86_free_from_memory (GET_MODE (operands[2]));
13617 DONE;
13618 })
13619 \f
13620 ;; FPU special functions.
13621
13622 ;; This pattern implements a no-op XFmode truncation for
13623 ;; all fancy i386 XFmode math functions.
13624
13625 (define_insn "truncxf<mode>2_i387_noop_unspec"
13626 [(set (match_operand:MODEF 0 "register_operand" "=f")
13627 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13628 UNSPEC_TRUNC_NOOP))]
13629 "TARGET_USE_FANCY_MATH_387"
13630 "* return output_387_reg_move (insn, operands);"
13631 [(set_attr "type" "fmov")
13632 (set_attr "mode" "<MODE>")])
13633
13634 (define_insn "sqrtxf2"
13635 [(set (match_operand:XF 0 "register_operand" "=f")
13636 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13637 "TARGET_USE_FANCY_MATH_387"
13638 "fsqrt"
13639 [(set_attr "type" "fpspc")
13640 (set_attr "mode" "XF")
13641 (set_attr "athlon_decode" "direct")
13642 (set_attr "amdfam10_decode" "direct")
13643 (set_attr "bdver1_decode" "direct")])
13644
13645 (define_insn "sqrt_extend<mode>xf2_i387"
13646 [(set (match_operand:XF 0 "register_operand" "=f")
13647 (sqrt:XF
13648 (float_extend:XF
13649 (match_operand:MODEF 1 "register_operand" "0"))))]
13650 "TARGET_USE_FANCY_MATH_387"
13651 "fsqrt"
13652 [(set_attr "type" "fpspc")
13653 (set_attr "mode" "XF")
13654 (set_attr "athlon_decode" "direct")
13655 (set_attr "amdfam10_decode" "direct")
13656 (set_attr "bdver1_decode" "direct")])
13657
13658 (define_insn "*rsqrtsf2_sse"
13659 [(set (match_operand:SF 0 "register_operand" "=x")
13660 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13661 UNSPEC_RSQRT))]
13662 "TARGET_SSE_MATH"
13663 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13664 [(set_attr "type" "sse")
13665 (set_attr "atom_sse_attr" "rcp")
13666 (set_attr "btver2_sse_attr" "rcp")
13667 (set_attr "prefix" "maybe_vex")
13668 (set_attr "mode" "SF")])
13669
13670 (define_expand "rsqrtsf2"
13671 [(set (match_operand:SF 0 "register_operand")
13672 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13673 UNSPEC_RSQRT))]
13674 "TARGET_SSE_MATH"
13675 {
13676 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13677 DONE;
13678 })
13679
13680 (define_insn "*sqrt<mode>2_sse"
13681 [(set (match_operand:MODEF 0 "register_operand" "=x")
13682 (sqrt:MODEF
13683 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13684 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13685 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13686 [(set_attr "type" "sse")
13687 (set_attr "atom_sse_attr" "sqrt")
13688 (set_attr "btver2_sse_attr" "sqrt")
13689 (set_attr "prefix" "maybe_vex")
13690 (set_attr "mode" "<MODE>")
13691 (set_attr "athlon_decode" "*")
13692 (set_attr "amdfam10_decode" "*")
13693 (set_attr "bdver1_decode" "*")])
13694
13695 (define_expand "sqrt<mode>2"
13696 [(set (match_operand:MODEF 0 "register_operand")
13697 (sqrt:MODEF
13698 (match_operand:MODEF 1 "nonimmediate_operand")))]
13699 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13700 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13701 {
13702 if (<MODE>mode == SFmode
13703 && TARGET_SSE_MATH
13704 && TARGET_RECIP_SQRT
13705 && !optimize_function_for_size_p (cfun)
13706 && flag_finite_math_only && !flag_trapping_math
13707 && flag_unsafe_math_optimizations)
13708 {
13709 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13710 DONE;
13711 }
13712
13713 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13714 {
13715 rtx op0 = gen_reg_rtx (XFmode);
13716 rtx op1 = force_reg (<MODE>mode, operands[1]);
13717
13718 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13719 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13720 DONE;
13721 }
13722 })
13723
13724 (define_insn "fpremxf4_i387"
13725 [(set (match_operand:XF 0 "register_operand" "=f")
13726 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13727 (match_operand:XF 3 "register_operand" "1")]
13728 UNSPEC_FPREM_F))
13729 (set (match_operand:XF 1 "register_operand" "=u")
13730 (unspec:XF [(match_dup 2) (match_dup 3)]
13731 UNSPEC_FPREM_U))
13732 (set (reg:CCFP FPSR_REG)
13733 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13734 UNSPEC_C2_FLAG))]
13735 "TARGET_USE_FANCY_MATH_387"
13736 "fprem"
13737 [(set_attr "type" "fpspc")
13738 (set_attr "mode" "XF")])
13739
13740 (define_expand "fmodxf3"
13741 [(use (match_operand:XF 0 "register_operand"))
13742 (use (match_operand:XF 1 "general_operand"))
13743 (use (match_operand:XF 2 "general_operand"))]
13744 "TARGET_USE_FANCY_MATH_387"
13745 {
13746 rtx label = gen_label_rtx ();
13747
13748 rtx op1 = gen_reg_rtx (XFmode);
13749 rtx op2 = gen_reg_rtx (XFmode);
13750
13751 emit_move_insn (op2, operands[2]);
13752 emit_move_insn (op1, operands[1]);
13753
13754 emit_label (label);
13755 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13756 ix86_emit_fp_unordered_jump (label);
13757 LABEL_NUSES (label) = 1;
13758
13759 emit_move_insn (operands[0], op1);
13760 DONE;
13761 })
13762
13763 (define_expand "fmod<mode>3"
13764 [(use (match_operand:MODEF 0 "register_operand"))
13765 (use (match_operand:MODEF 1 "general_operand"))
13766 (use (match_operand:MODEF 2 "general_operand"))]
13767 "TARGET_USE_FANCY_MATH_387"
13768 {
13769 rtx (*gen_truncxf) (rtx, rtx);
13770
13771 rtx label = gen_label_rtx ();
13772
13773 rtx op1 = gen_reg_rtx (XFmode);
13774 rtx op2 = gen_reg_rtx (XFmode);
13775
13776 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13778
13779 emit_label (label);
13780 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13781 ix86_emit_fp_unordered_jump (label);
13782 LABEL_NUSES (label) = 1;
13783
13784 /* Truncate the result properly for strict SSE math. */
13785 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13786 && !TARGET_MIX_SSE_I387)
13787 gen_truncxf = gen_truncxf<mode>2;
13788 else
13789 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13790
13791 emit_insn (gen_truncxf (operands[0], op1));
13792 DONE;
13793 })
13794
13795 (define_insn "fprem1xf4_i387"
13796 [(set (match_operand:XF 0 "register_operand" "=f")
13797 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13798 (match_operand:XF 3 "register_operand" "1")]
13799 UNSPEC_FPREM1_F))
13800 (set (match_operand:XF 1 "register_operand" "=u")
13801 (unspec:XF [(match_dup 2) (match_dup 3)]
13802 UNSPEC_FPREM1_U))
13803 (set (reg:CCFP FPSR_REG)
13804 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13805 UNSPEC_C2_FLAG))]
13806 "TARGET_USE_FANCY_MATH_387"
13807 "fprem1"
13808 [(set_attr "type" "fpspc")
13809 (set_attr "mode" "XF")])
13810
13811 (define_expand "remainderxf3"
13812 [(use (match_operand:XF 0 "register_operand"))
13813 (use (match_operand:XF 1 "general_operand"))
13814 (use (match_operand:XF 2 "general_operand"))]
13815 "TARGET_USE_FANCY_MATH_387"
13816 {
13817 rtx label = gen_label_rtx ();
13818
13819 rtx op1 = gen_reg_rtx (XFmode);
13820 rtx op2 = gen_reg_rtx (XFmode);
13821
13822 emit_move_insn (op2, operands[2]);
13823 emit_move_insn (op1, operands[1]);
13824
13825 emit_label (label);
13826 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13827 ix86_emit_fp_unordered_jump (label);
13828 LABEL_NUSES (label) = 1;
13829
13830 emit_move_insn (operands[0], op1);
13831 DONE;
13832 })
13833
13834 (define_expand "remainder<mode>3"
13835 [(use (match_operand:MODEF 0 "register_operand"))
13836 (use (match_operand:MODEF 1 "general_operand"))
13837 (use (match_operand:MODEF 2 "general_operand"))]
13838 "TARGET_USE_FANCY_MATH_387"
13839 {
13840 rtx (*gen_truncxf) (rtx, rtx);
13841
13842 rtx label = gen_label_rtx ();
13843
13844 rtx op1 = gen_reg_rtx (XFmode);
13845 rtx op2 = gen_reg_rtx (XFmode);
13846
13847 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13848 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13849
13850 emit_label (label);
13851
13852 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13853 ix86_emit_fp_unordered_jump (label);
13854 LABEL_NUSES (label) = 1;
13855
13856 /* Truncate the result properly for strict SSE math. */
13857 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13858 && !TARGET_MIX_SSE_I387)
13859 gen_truncxf = gen_truncxf<mode>2;
13860 else
13861 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13862
13863 emit_insn (gen_truncxf (operands[0], op1));
13864 DONE;
13865 })
13866
13867 (define_int_iterator SINCOS
13868 [UNSPEC_SIN
13869 UNSPEC_COS])
13870
13871 (define_int_attr sincos
13872 [(UNSPEC_SIN "sin")
13873 (UNSPEC_COS "cos")])
13874
13875 (define_insn "*<sincos>xf2_i387"
13876 [(set (match_operand:XF 0 "register_operand" "=f")
13877 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13878 SINCOS))]
13879 "TARGET_USE_FANCY_MATH_387
13880 && flag_unsafe_math_optimizations"
13881 "f<sincos>"
13882 [(set_attr "type" "fpspc")
13883 (set_attr "mode" "XF")])
13884
13885 (define_insn "*<sincos>_extend<mode>xf2_i387"
13886 [(set (match_operand:XF 0 "register_operand" "=f")
13887 (unspec:XF [(float_extend:XF
13888 (match_operand:MODEF 1 "register_operand" "0"))]
13889 SINCOS))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892 || TARGET_MIX_SSE_I387)
13893 && flag_unsafe_math_optimizations"
13894 "f<sincos>"
13895 [(set_attr "type" "fpspc")
13896 (set_attr "mode" "XF")])
13897
13898 ;; When sincos pattern is defined, sin and cos builtin functions will be
13899 ;; expanded to sincos pattern with one of its outputs left unused.
13900 ;; CSE pass will figure out if two sincos patterns can be combined,
13901 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13902 ;; depending on the unused output.
13903
13904 (define_insn "sincosxf3"
13905 [(set (match_operand:XF 0 "register_operand" "=f")
13906 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13907 UNSPEC_SINCOS_COS))
13908 (set (match_operand:XF 1 "register_operand" "=u")
13909 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13910 "TARGET_USE_FANCY_MATH_387
13911 && flag_unsafe_math_optimizations"
13912 "fsincos"
13913 [(set_attr "type" "fpspc")
13914 (set_attr "mode" "XF")])
13915
13916 (define_split
13917 [(set (match_operand:XF 0 "register_operand")
13918 (unspec:XF [(match_operand:XF 2 "register_operand")]
13919 UNSPEC_SINCOS_COS))
13920 (set (match_operand:XF 1 "register_operand")
13921 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13922 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13923 && can_create_pseudo_p ()"
13924 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13925
13926 (define_split
13927 [(set (match_operand:XF 0 "register_operand")
13928 (unspec:XF [(match_operand:XF 2 "register_operand")]
13929 UNSPEC_SINCOS_COS))
13930 (set (match_operand:XF 1 "register_operand")
13931 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13932 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13933 && can_create_pseudo_p ()"
13934 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13935
13936 (define_insn "sincos_extend<mode>xf3_i387"
13937 [(set (match_operand:XF 0 "register_operand" "=f")
13938 (unspec:XF [(float_extend:XF
13939 (match_operand:MODEF 2 "register_operand" "0"))]
13940 UNSPEC_SINCOS_COS))
13941 (set (match_operand:XF 1 "register_operand" "=u")
13942 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13943 "TARGET_USE_FANCY_MATH_387
13944 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13945 || TARGET_MIX_SSE_I387)
13946 && flag_unsafe_math_optimizations"
13947 "fsincos"
13948 [(set_attr "type" "fpspc")
13949 (set_attr "mode" "XF")])
13950
13951 (define_split
13952 [(set (match_operand:XF 0 "register_operand")
13953 (unspec:XF [(float_extend:XF
13954 (match_operand:MODEF 2 "register_operand"))]
13955 UNSPEC_SINCOS_COS))
13956 (set (match_operand:XF 1 "register_operand")
13957 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13958 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13959 && can_create_pseudo_p ()"
13960 [(set (match_dup 1)
13961 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13962
13963 (define_split
13964 [(set (match_operand:XF 0 "register_operand")
13965 (unspec:XF [(float_extend:XF
13966 (match_operand:MODEF 2 "register_operand"))]
13967 UNSPEC_SINCOS_COS))
13968 (set (match_operand:XF 1 "register_operand")
13969 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13970 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13971 && can_create_pseudo_p ()"
13972 [(set (match_dup 0)
13973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13974
13975 (define_expand "sincos<mode>3"
13976 [(use (match_operand:MODEF 0 "register_operand"))
13977 (use (match_operand:MODEF 1 "register_operand"))
13978 (use (match_operand:MODEF 2 "register_operand"))]
13979 "TARGET_USE_FANCY_MATH_387
13980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13981 || TARGET_MIX_SSE_I387)
13982 && flag_unsafe_math_optimizations"
13983 {
13984 rtx op0 = gen_reg_rtx (XFmode);
13985 rtx op1 = gen_reg_rtx (XFmode);
13986
13987 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13988 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13990 DONE;
13991 })
13992
13993 (define_insn "fptanxf4_i387"
13994 [(set (match_operand:XF 0 "register_operand" "=f")
13995 (match_operand:XF 3 "const_double_operand" "F"))
13996 (set (match_operand:XF 1 "register_operand" "=u")
13997 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13998 UNSPEC_TAN))]
13999 "TARGET_USE_FANCY_MATH_387
14000 && flag_unsafe_math_optimizations
14001 && standard_80387_constant_p (operands[3]) == 2"
14002 "fptan"
14003 [(set_attr "type" "fpspc")
14004 (set_attr "mode" "XF")])
14005
14006 (define_insn "fptan_extend<mode>xf4_i387"
14007 [(set (match_operand:MODEF 0 "register_operand" "=f")
14008 (match_operand:MODEF 3 "const_double_operand" "F"))
14009 (set (match_operand:XF 1 "register_operand" "=u")
14010 (unspec:XF [(float_extend:XF
14011 (match_operand:MODEF 2 "register_operand" "0"))]
14012 UNSPEC_TAN))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015 || TARGET_MIX_SSE_I387)
14016 && flag_unsafe_math_optimizations
14017 && standard_80387_constant_p (operands[3]) == 2"
14018 "fptan"
14019 [(set_attr "type" "fpspc")
14020 (set_attr "mode" "XF")])
14021
14022 (define_expand "tanxf2"
14023 [(use (match_operand:XF 0 "register_operand"))
14024 (use (match_operand:XF 1 "register_operand"))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && flag_unsafe_math_optimizations"
14027 {
14028 rtx one = gen_reg_rtx (XFmode);
14029 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14030
14031 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14032 DONE;
14033 })
14034
14035 (define_expand "tan<mode>2"
14036 [(use (match_operand:MODEF 0 "register_operand"))
14037 (use (match_operand:MODEF 1 "register_operand"))]
14038 "TARGET_USE_FANCY_MATH_387
14039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14040 || TARGET_MIX_SSE_I387)
14041 && flag_unsafe_math_optimizations"
14042 {
14043 rtx op0 = gen_reg_rtx (XFmode);
14044
14045 rtx one = gen_reg_rtx (<MODE>mode);
14046 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14047
14048 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14049 operands[1], op2));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14051 DONE;
14052 })
14053
14054 (define_insn "*fpatanxf3_i387"
14055 [(set (match_operand:XF 0 "register_operand" "=f")
14056 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14057 (match_operand:XF 2 "register_operand" "u")]
14058 UNSPEC_FPATAN))
14059 (clobber (match_scratch:XF 3 "=2"))]
14060 "TARGET_USE_FANCY_MATH_387
14061 && flag_unsafe_math_optimizations"
14062 "fpatan"
14063 [(set_attr "type" "fpspc")
14064 (set_attr "mode" "XF")])
14065
14066 (define_insn "fpatan_extend<mode>xf3_i387"
14067 [(set (match_operand:XF 0 "register_operand" "=f")
14068 (unspec:XF [(float_extend:XF
14069 (match_operand:MODEF 1 "register_operand" "0"))
14070 (float_extend:XF
14071 (match_operand:MODEF 2 "register_operand" "u"))]
14072 UNSPEC_FPATAN))
14073 (clobber (match_scratch:XF 3 "=2"))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations"
14078 "fpatan"
14079 [(set_attr "type" "fpspc")
14080 (set_attr "mode" "XF")])
14081
14082 (define_expand "atan2xf3"
14083 [(parallel [(set (match_operand:XF 0 "register_operand")
14084 (unspec:XF [(match_operand:XF 2 "register_operand")
14085 (match_operand:XF 1 "register_operand")]
14086 UNSPEC_FPATAN))
14087 (clobber (match_scratch:XF 3))])]
14088 "TARGET_USE_FANCY_MATH_387
14089 && flag_unsafe_math_optimizations")
14090
14091 (define_expand "atan2<mode>3"
14092 [(use (match_operand:MODEF 0 "register_operand"))
14093 (use (match_operand:MODEF 1 "register_operand"))
14094 (use (match_operand:MODEF 2 "register_operand"))]
14095 "TARGET_USE_FANCY_MATH_387
14096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14097 || TARGET_MIX_SSE_I387)
14098 && flag_unsafe_math_optimizations"
14099 {
14100 rtx op0 = gen_reg_rtx (XFmode);
14101
14102 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14103 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14104 DONE;
14105 })
14106
14107 (define_expand "atanxf2"
14108 [(parallel [(set (match_operand:XF 0 "register_operand")
14109 (unspec:XF [(match_dup 2)
14110 (match_operand:XF 1 "register_operand")]
14111 UNSPEC_FPATAN))
14112 (clobber (match_scratch:XF 3))])]
14113 "TARGET_USE_FANCY_MATH_387
14114 && flag_unsafe_math_optimizations"
14115 {
14116 operands[2] = gen_reg_rtx (XFmode);
14117 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14118 })
14119
14120 (define_expand "atan<mode>2"
14121 [(use (match_operand:MODEF 0 "register_operand"))
14122 (use (match_operand:MODEF 1 "register_operand"))]
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 {
14128 rtx op0 = gen_reg_rtx (XFmode);
14129
14130 rtx op2 = gen_reg_rtx (<MODE>mode);
14131 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14132
14133 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14134 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14135 DONE;
14136 })
14137
14138 (define_expand "asinxf2"
14139 [(set (match_dup 2)
14140 (mult:XF (match_operand:XF 1 "register_operand")
14141 (match_dup 1)))
14142 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14143 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14144 (parallel [(set (match_operand:XF 0 "register_operand")
14145 (unspec:XF [(match_dup 5) (match_dup 1)]
14146 UNSPEC_FPATAN))
14147 (clobber (match_scratch:XF 6))])]
14148 "TARGET_USE_FANCY_MATH_387
14149 && flag_unsafe_math_optimizations"
14150 {
14151 int i;
14152
14153 if (optimize_insn_for_size_p ())
14154 FAIL;
14155
14156 for (i = 2; i < 6; i++)
14157 operands[i] = gen_reg_rtx (XFmode);
14158
14159 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14160 })
14161
14162 (define_expand "asin<mode>2"
14163 [(use (match_operand:MODEF 0 "register_operand"))
14164 (use (match_operand:MODEF 1 "general_operand"))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14167 || TARGET_MIX_SSE_I387)
14168 && flag_unsafe_math_optimizations"
14169 {
14170 rtx op0 = gen_reg_rtx (XFmode);
14171 rtx op1 = gen_reg_rtx (XFmode);
14172
14173 if (optimize_insn_for_size_p ())
14174 FAIL;
14175
14176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14177 emit_insn (gen_asinxf2 (op0, op1));
14178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14179 DONE;
14180 })
14181
14182 (define_expand "acosxf2"
14183 [(set (match_dup 2)
14184 (mult:XF (match_operand:XF 1 "register_operand")
14185 (match_dup 1)))
14186 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14187 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14188 (parallel [(set (match_operand:XF 0 "register_operand")
14189 (unspec:XF [(match_dup 1) (match_dup 5)]
14190 UNSPEC_FPATAN))
14191 (clobber (match_scratch:XF 6))])]
14192 "TARGET_USE_FANCY_MATH_387
14193 && flag_unsafe_math_optimizations"
14194 {
14195 int i;
14196
14197 if (optimize_insn_for_size_p ())
14198 FAIL;
14199
14200 for (i = 2; i < 6; i++)
14201 operands[i] = gen_reg_rtx (XFmode);
14202
14203 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14204 })
14205
14206 (define_expand "acos<mode>2"
14207 [(use (match_operand:MODEF 0 "register_operand"))
14208 (use (match_operand:MODEF 1 "general_operand"))]
14209 "TARGET_USE_FANCY_MATH_387
14210 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14211 || TARGET_MIX_SSE_I387)
14212 && flag_unsafe_math_optimizations"
14213 {
14214 rtx op0 = gen_reg_rtx (XFmode);
14215 rtx op1 = gen_reg_rtx (XFmode);
14216
14217 if (optimize_insn_for_size_p ())
14218 FAIL;
14219
14220 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14221 emit_insn (gen_acosxf2 (op0, op1));
14222 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14223 DONE;
14224 })
14225
14226 (define_insn "fyl2xxf3_i387"
14227 [(set (match_operand:XF 0 "register_operand" "=f")
14228 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14229 (match_operand:XF 2 "register_operand" "u")]
14230 UNSPEC_FYL2X))
14231 (clobber (match_scratch:XF 3 "=2"))]
14232 "TARGET_USE_FANCY_MATH_387
14233 && flag_unsafe_math_optimizations"
14234 "fyl2x"
14235 [(set_attr "type" "fpspc")
14236 (set_attr "mode" "XF")])
14237
14238 (define_insn "fyl2x_extend<mode>xf3_i387"
14239 [(set (match_operand:XF 0 "register_operand" "=f")
14240 (unspec:XF [(float_extend:XF
14241 (match_operand:MODEF 1 "register_operand" "0"))
14242 (match_operand:XF 2 "register_operand" "u")]
14243 UNSPEC_FYL2X))
14244 (clobber (match_scratch:XF 3 "=2"))]
14245 "TARGET_USE_FANCY_MATH_387
14246 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14247 || TARGET_MIX_SSE_I387)
14248 && flag_unsafe_math_optimizations"
14249 "fyl2x"
14250 [(set_attr "type" "fpspc")
14251 (set_attr "mode" "XF")])
14252
14253 (define_expand "logxf2"
14254 [(parallel [(set (match_operand:XF 0 "register_operand")
14255 (unspec:XF [(match_operand:XF 1 "register_operand")
14256 (match_dup 2)] UNSPEC_FYL2X))
14257 (clobber (match_scratch:XF 3))])]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14260 {
14261 operands[2] = gen_reg_rtx (XFmode);
14262 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14263 })
14264
14265 (define_expand "log<mode>2"
14266 [(use (match_operand:MODEF 0 "register_operand"))
14267 (use (match_operand:MODEF 1 "register_operand"))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270 || TARGET_MIX_SSE_I387)
14271 && flag_unsafe_math_optimizations"
14272 {
14273 rtx op0 = gen_reg_rtx (XFmode);
14274
14275 rtx op2 = gen_reg_rtx (XFmode);
14276 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14277
14278 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14280 DONE;
14281 })
14282
14283 (define_expand "log10xf2"
14284 [(parallel [(set (match_operand:XF 0 "register_operand")
14285 (unspec:XF [(match_operand:XF 1 "register_operand")
14286 (match_dup 2)] UNSPEC_FYL2X))
14287 (clobber (match_scratch:XF 3))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14290 {
14291 operands[2] = gen_reg_rtx (XFmode);
14292 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14293 })
14294
14295 (define_expand "log10<mode>2"
14296 [(use (match_operand:MODEF 0 "register_operand"))
14297 (use (match_operand:MODEF 1 "register_operand"))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14302 {
14303 rtx op0 = gen_reg_rtx (XFmode);
14304
14305 rtx op2 = gen_reg_rtx (XFmode);
14306 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14307
14308 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14310 DONE;
14311 })
14312
14313 (define_expand "log2xf2"
14314 [(parallel [(set (match_operand:XF 0 "register_operand")
14315 (unspec:XF [(match_operand:XF 1 "register_operand")
14316 (match_dup 2)] UNSPEC_FYL2X))
14317 (clobber (match_scratch:XF 3))])]
14318 "TARGET_USE_FANCY_MATH_387
14319 && flag_unsafe_math_optimizations"
14320 {
14321 operands[2] = gen_reg_rtx (XFmode);
14322 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14323 })
14324
14325 (define_expand "log2<mode>2"
14326 [(use (match_operand:MODEF 0 "register_operand"))
14327 (use (match_operand:MODEF 1 "register_operand"))]
14328 "TARGET_USE_FANCY_MATH_387
14329 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14330 || TARGET_MIX_SSE_I387)
14331 && flag_unsafe_math_optimizations"
14332 {
14333 rtx op0 = gen_reg_rtx (XFmode);
14334
14335 rtx op2 = gen_reg_rtx (XFmode);
14336 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14337
14338 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14339 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14340 DONE;
14341 })
14342
14343 (define_insn "fyl2xp1xf3_i387"
14344 [(set (match_operand:XF 0 "register_operand" "=f")
14345 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14346 (match_operand:XF 2 "register_operand" "u")]
14347 UNSPEC_FYL2XP1))
14348 (clobber (match_scratch:XF 3 "=2"))]
14349 "TARGET_USE_FANCY_MATH_387
14350 && flag_unsafe_math_optimizations"
14351 "fyl2xp1"
14352 [(set_attr "type" "fpspc")
14353 (set_attr "mode" "XF")])
14354
14355 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14356 [(set (match_operand:XF 0 "register_operand" "=f")
14357 (unspec:XF [(float_extend:XF
14358 (match_operand:MODEF 1 "register_operand" "0"))
14359 (match_operand:XF 2 "register_operand" "u")]
14360 UNSPEC_FYL2XP1))
14361 (clobber (match_scratch:XF 3 "=2"))]
14362 "TARGET_USE_FANCY_MATH_387
14363 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14364 || TARGET_MIX_SSE_I387)
14365 && flag_unsafe_math_optimizations"
14366 "fyl2xp1"
14367 [(set_attr "type" "fpspc")
14368 (set_attr "mode" "XF")])
14369
14370 (define_expand "log1pxf2"
14371 [(use (match_operand:XF 0 "register_operand"))
14372 (use (match_operand:XF 1 "register_operand"))]
14373 "TARGET_USE_FANCY_MATH_387
14374 && flag_unsafe_math_optimizations"
14375 {
14376 if (optimize_insn_for_size_p ())
14377 FAIL;
14378
14379 ix86_emit_i387_log1p (operands[0], operands[1]);
14380 DONE;
14381 })
14382
14383 (define_expand "log1p<mode>2"
14384 [(use (match_operand:MODEF 0 "register_operand"))
14385 (use (match_operand:MODEF 1 "register_operand"))]
14386 "TARGET_USE_FANCY_MATH_387
14387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14388 || TARGET_MIX_SSE_I387)
14389 && flag_unsafe_math_optimizations"
14390 {
14391 rtx op0;
14392
14393 if (optimize_insn_for_size_p ())
14394 FAIL;
14395
14396 op0 = gen_reg_rtx (XFmode);
14397
14398 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14399
14400 ix86_emit_i387_log1p (op0, operands[1]);
14401 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14402 DONE;
14403 })
14404
14405 (define_insn "fxtractxf3_i387"
14406 [(set (match_operand:XF 0 "register_operand" "=f")
14407 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14408 UNSPEC_XTRACT_FRACT))
14409 (set (match_operand:XF 1 "register_operand" "=u")
14410 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14411 "TARGET_USE_FANCY_MATH_387
14412 && flag_unsafe_math_optimizations"
14413 "fxtract"
14414 [(set_attr "type" "fpspc")
14415 (set_attr "mode" "XF")])
14416
14417 (define_insn "fxtract_extend<mode>xf3_i387"
14418 [(set (match_operand:XF 0 "register_operand" "=f")
14419 (unspec:XF [(float_extend:XF
14420 (match_operand:MODEF 2 "register_operand" "0"))]
14421 UNSPEC_XTRACT_FRACT))
14422 (set (match_operand:XF 1 "register_operand" "=u")
14423 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14426 || TARGET_MIX_SSE_I387)
14427 && flag_unsafe_math_optimizations"
14428 "fxtract"
14429 [(set_attr "type" "fpspc")
14430 (set_attr "mode" "XF")])
14431
14432 (define_expand "logbxf2"
14433 [(parallel [(set (match_dup 2)
14434 (unspec:XF [(match_operand:XF 1 "register_operand")]
14435 UNSPEC_XTRACT_FRACT))
14436 (set (match_operand:XF 0 "register_operand")
14437 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14438 "TARGET_USE_FANCY_MATH_387
14439 && flag_unsafe_math_optimizations"
14440 "operands[2] = gen_reg_rtx (XFmode);")
14441
14442 (define_expand "logb<mode>2"
14443 [(use (match_operand:MODEF 0 "register_operand"))
14444 (use (match_operand:MODEF 1 "register_operand"))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447 || TARGET_MIX_SSE_I387)
14448 && flag_unsafe_math_optimizations"
14449 {
14450 rtx op0 = gen_reg_rtx (XFmode);
14451 rtx op1 = gen_reg_rtx (XFmode);
14452
14453 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14455 DONE;
14456 })
14457
14458 (define_expand "ilogbxf2"
14459 [(use (match_operand:SI 0 "register_operand"))
14460 (use (match_operand:XF 1 "register_operand"))]
14461 "TARGET_USE_FANCY_MATH_387
14462 && flag_unsafe_math_optimizations"
14463 {
14464 rtx op0, op1;
14465
14466 if (optimize_insn_for_size_p ())
14467 FAIL;
14468
14469 op0 = gen_reg_rtx (XFmode);
14470 op1 = gen_reg_rtx (XFmode);
14471
14472 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14473 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14474 DONE;
14475 })
14476
14477 (define_expand "ilogb<mode>2"
14478 [(use (match_operand:SI 0 "register_operand"))
14479 (use (match_operand:MODEF 1 "register_operand"))]
14480 "TARGET_USE_FANCY_MATH_387
14481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14482 || TARGET_MIX_SSE_I387)
14483 && flag_unsafe_math_optimizations"
14484 {
14485 rtx op0, op1;
14486
14487 if (optimize_insn_for_size_p ())
14488 FAIL;
14489
14490 op0 = gen_reg_rtx (XFmode);
14491 op1 = gen_reg_rtx (XFmode);
14492
14493 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14494 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14495 DONE;
14496 })
14497
14498 (define_insn "*f2xm1xf2_i387"
14499 [(set (match_operand:XF 0 "register_operand" "=f")
14500 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14501 UNSPEC_F2XM1))]
14502 "TARGET_USE_FANCY_MATH_387
14503 && flag_unsafe_math_optimizations"
14504 "f2xm1"
14505 [(set_attr "type" "fpspc")
14506 (set_attr "mode" "XF")])
14507
14508 (define_insn "*fscalexf4_i387"
14509 [(set (match_operand:XF 0 "register_operand" "=f")
14510 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14511 (match_operand:XF 3 "register_operand" "1")]
14512 UNSPEC_FSCALE_FRACT))
14513 (set (match_operand:XF 1 "register_operand" "=u")
14514 (unspec:XF [(match_dup 2) (match_dup 3)]
14515 UNSPEC_FSCALE_EXP))]
14516 "TARGET_USE_FANCY_MATH_387
14517 && flag_unsafe_math_optimizations"
14518 "fscale"
14519 [(set_attr "type" "fpspc")
14520 (set_attr "mode" "XF")])
14521
14522 (define_expand "expNcorexf3"
14523 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14524 (match_operand:XF 2 "register_operand")))
14525 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14526 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14527 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14528 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14529 (parallel [(set (match_operand:XF 0 "register_operand")
14530 (unspec:XF [(match_dup 8) (match_dup 4)]
14531 UNSPEC_FSCALE_FRACT))
14532 (set (match_dup 9)
14533 (unspec:XF [(match_dup 8) (match_dup 4)]
14534 UNSPEC_FSCALE_EXP))])]
14535 "TARGET_USE_FANCY_MATH_387
14536 && flag_unsafe_math_optimizations"
14537 {
14538 int i;
14539
14540 if (optimize_insn_for_size_p ())
14541 FAIL;
14542
14543 for (i = 3; i < 10; i++)
14544 operands[i] = gen_reg_rtx (XFmode);
14545
14546 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14547 })
14548
14549 (define_expand "expxf2"
14550 [(use (match_operand:XF 0 "register_operand"))
14551 (use (match_operand:XF 1 "register_operand"))]
14552 "TARGET_USE_FANCY_MATH_387
14553 && flag_unsafe_math_optimizations"
14554 {
14555 rtx op2;
14556
14557 if (optimize_insn_for_size_p ())
14558 FAIL;
14559
14560 op2 = gen_reg_rtx (XFmode);
14561 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14562
14563 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14564 DONE;
14565 })
14566
14567 (define_expand "exp<mode>2"
14568 [(use (match_operand:MODEF 0 "register_operand"))
14569 (use (match_operand:MODEF 1 "general_operand"))]
14570 "TARGET_USE_FANCY_MATH_387
14571 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14572 || TARGET_MIX_SSE_I387)
14573 && flag_unsafe_math_optimizations"
14574 {
14575 rtx op0, op1;
14576
14577 if (optimize_insn_for_size_p ())
14578 FAIL;
14579
14580 op0 = gen_reg_rtx (XFmode);
14581 op1 = gen_reg_rtx (XFmode);
14582
14583 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14584 emit_insn (gen_expxf2 (op0, op1));
14585 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14586 DONE;
14587 })
14588
14589 (define_expand "exp10xf2"
14590 [(use (match_operand:XF 0 "register_operand"))
14591 (use (match_operand:XF 1 "register_operand"))]
14592 "TARGET_USE_FANCY_MATH_387
14593 && flag_unsafe_math_optimizations"
14594 {
14595 rtx op2;
14596
14597 if (optimize_insn_for_size_p ())
14598 FAIL;
14599
14600 op2 = gen_reg_rtx (XFmode);
14601 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14602
14603 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14604 DONE;
14605 })
14606
14607 (define_expand "exp10<mode>2"
14608 [(use (match_operand:MODEF 0 "register_operand"))
14609 (use (match_operand:MODEF 1 "general_operand"))]
14610 "TARGET_USE_FANCY_MATH_387
14611 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14612 || TARGET_MIX_SSE_I387)
14613 && flag_unsafe_math_optimizations"
14614 {
14615 rtx op0, op1;
14616
14617 if (optimize_insn_for_size_p ())
14618 FAIL;
14619
14620 op0 = gen_reg_rtx (XFmode);
14621 op1 = gen_reg_rtx (XFmode);
14622
14623 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14624 emit_insn (gen_exp10xf2 (op0, op1));
14625 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14626 DONE;
14627 })
14628
14629 (define_expand "exp2xf2"
14630 [(use (match_operand:XF 0 "register_operand"))
14631 (use (match_operand:XF 1 "register_operand"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_unsafe_math_optimizations"
14634 {
14635 rtx op2;
14636
14637 if (optimize_insn_for_size_p ())
14638 FAIL;
14639
14640 op2 = gen_reg_rtx (XFmode);
14641 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14642
14643 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14644 DONE;
14645 })
14646
14647 (define_expand "exp2<mode>2"
14648 [(use (match_operand:MODEF 0 "register_operand"))
14649 (use (match_operand:MODEF 1 "general_operand"))]
14650 "TARGET_USE_FANCY_MATH_387
14651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14652 || TARGET_MIX_SSE_I387)
14653 && flag_unsafe_math_optimizations"
14654 {
14655 rtx op0, op1;
14656
14657 if (optimize_insn_for_size_p ())
14658 FAIL;
14659
14660 op0 = gen_reg_rtx (XFmode);
14661 op1 = gen_reg_rtx (XFmode);
14662
14663 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14664 emit_insn (gen_exp2xf2 (op0, op1));
14665 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14666 DONE;
14667 })
14668
14669 (define_expand "expm1xf2"
14670 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14671 (match_dup 2)))
14672 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14673 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14674 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14675 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14676 (parallel [(set (match_dup 7)
14677 (unspec:XF [(match_dup 6) (match_dup 4)]
14678 UNSPEC_FSCALE_FRACT))
14679 (set (match_dup 8)
14680 (unspec:XF [(match_dup 6) (match_dup 4)]
14681 UNSPEC_FSCALE_EXP))])
14682 (parallel [(set (match_dup 10)
14683 (unspec:XF [(match_dup 9) (match_dup 8)]
14684 UNSPEC_FSCALE_FRACT))
14685 (set (match_dup 11)
14686 (unspec:XF [(match_dup 9) (match_dup 8)]
14687 UNSPEC_FSCALE_EXP))])
14688 (set (match_dup 12) (minus:XF (match_dup 10)
14689 (float_extend:XF (match_dup 13))))
14690 (set (match_operand:XF 0 "register_operand")
14691 (plus:XF (match_dup 12) (match_dup 7)))]
14692 "TARGET_USE_FANCY_MATH_387
14693 && flag_unsafe_math_optimizations"
14694 {
14695 int i;
14696
14697 if (optimize_insn_for_size_p ())
14698 FAIL;
14699
14700 for (i = 2; i < 13; i++)
14701 operands[i] = gen_reg_rtx (XFmode);
14702
14703 operands[13]
14704 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14705
14706 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14707 })
14708
14709 (define_expand "expm1<mode>2"
14710 [(use (match_operand:MODEF 0 "register_operand"))
14711 (use (match_operand:MODEF 1 "general_operand"))]
14712 "TARGET_USE_FANCY_MATH_387
14713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714 || TARGET_MIX_SSE_I387)
14715 && flag_unsafe_math_optimizations"
14716 {
14717 rtx op0, op1;
14718
14719 if (optimize_insn_for_size_p ())
14720 FAIL;
14721
14722 op0 = gen_reg_rtx (XFmode);
14723 op1 = gen_reg_rtx (XFmode);
14724
14725 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14726 emit_insn (gen_expm1xf2 (op0, op1));
14727 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14728 DONE;
14729 })
14730
14731 (define_expand "ldexpxf3"
14732 [(set (match_dup 3)
14733 (float:XF (match_operand:SI 2 "register_operand")))
14734 (parallel [(set (match_operand:XF 0 " register_operand")
14735 (unspec:XF [(match_operand:XF 1 "register_operand")
14736 (match_dup 3)]
14737 UNSPEC_FSCALE_FRACT))
14738 (set (match_dup 4)
14739 (unspec:XF [(match_dup 1) (match_dup 3)]
14740 UNSPEC_FSCALE_EXP))])]
14741 "TARGET_USE_FANCY_MATH_387
14742 && flag_unsafe_math_optimizations"
14743 {
14744 if (optimize_insn_for_size_p ())
14745 FAIL;
14746
14747 operands[3] = gen_reg_rtx (XFmode);
14748 operands[4] = gen_reg_rtx (XFmode);
14749 })
14750
14751 (define_expand "ldexp<mode>3"
14752 [(use (match_operand:MODEF 0 "register_operand"))
14753 (use (match_operand:MODEF 1 "general_operand"))
14754 (use (match_operand:SI 2 "register_operand"))]
14755 "TARGET_USE_FANCY_MATH_387
14756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14757 || TARGET_MIX_SSE_I387)
14758 && flag_unsafe_math_optimizations"
14759 {
14760 rtx op0, op1;
14761
14762 if (optimize_insn_for_size_p ())
14763 FAIL;
14764
14765 op0 = gen_reg_rtx (XFmode);
14766 op1 = gen_reg_rtx (XFmode);
14767
14768 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14769 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14770 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14771 DONE;
14772 })
14773
14774 (define_expand "scalbxf3"
14775 [(parallel [(set (match_operand:XF 0 " register_operand")
14776 (unspec:XF [(match_operand:XF 1 "register_operand")
14777 (match_operand:XF 2 "register_operand")]
14778 UNSPEC_FSCALE_FRACT))
14779 (set (match_dup 3)
14780 (unspec:XF [(match_dup 1) (match_dup 2)]
14781 UNSPEC_FSCALE_EXP))])]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations"
14784 {
14785 if (optimize_insn_for_size_p ())
14786 FAIL;
14787
14788 operands[3] = gen_reg_rtx (XFmode);
14789 })
14790
14791 (define_expand "scalb<mode>3"
14792 [(use (match_operand:MODEF 0 "register_operand"))
14793 (use (match_operand:MODEF 1 "general_operand"))
14794 (use (match_operand:MODEF 2 "general_operand"))]
14795 "TARGET_USE_FANCY_MATH_387
14796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14797 || TARGET_MIX_SSE_I387)
14798 && flag_unsafe_math_optimizations"
14799 {
14800 rtx op0, op1, op2;
14801
14802 if (optimize_insn_for_size_p ())
14803 FAIL;
14804
14805 op0 = gen_reg_rtx (XFmode);
14806 op1 = gen_reg_rtx (XFmode);
14807 op2 = gen_reg_rtx (XFmode);
14808
14809 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14810 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14811 emit_insn (gen_scalbxf3 (op0, op1, op2));
14812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14813 DONE;
14814 })
14815
14816 (define_expand "significandxf2"
14817 [(parallel [(set (match_operand:XF 0 "register_operand")
14818 (unspec:XF [(match_operand:XF 1 "register_operand")]
14819 UNSPEC_XTRACT_FRACT))
14820 (set (match_dup 2)
14821 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14822 "TARGET_USE_FANCY_MATH_387
14823 && flag_unsafe_math_optimizations"
14824 "operands[2] = gen_reg_rtx (XFmode);")
14825
14826 (define_expand "significand<mode>2"
14827 [(use (match_operand:MODEF 0 "register_operand"))
14828 (use (match_operand:MODEF 1 "register_operand"))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14831 || TARGET_MIX_SSE_I387)
14832 && flag_unsafe_math_optimizations"
14833 {
14834 rtx op0 = gen_reg_rtx (XFmode);
14835 rtx op1 = gen_reg_rtx (XFmode);
14836
14837 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14839 DONE;
14840 })
14841 \f
14842
14843 (define_insn "sse4_1_round<mode>2"
14844 [(set (match_operand:MODEF 0 "register_operand" "=x")
14845 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14846 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14847 UNSPEC_ROUND))]
14848 "TARGET_ROUND"
14849 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14850 [(set_attr "type" "ssecvt")
14851 (set_attr "prefix_extra" "1")
14852 (set_attr "prefix" "maybe_vex")
14853 (set_attr "mode" "<MODE>")])
14854
14855 (define_insn "rintxf2"
14856 [(set (match_operand:XF 0 "register_operand" "=f")
14857 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14858 UNSPEC_FRNDINT))]
14859 "TARGET_USE_FANCY_MATH_387
14860 && flag_unsafe_math_optimizations"
14861 "frndint"
14862 [(set_attr "type" "fpspc")
14863 (set_attr "mode" "XF")])
14864
14865 (define_expand "rint<mode>2"
14866 [(use (match_operand:MODEF 0 "register_operand"))
14867 (use (match_operand:MODEF 1 "register_operand"))]
14868 "(TARGET_USE_FANCY_MATH_387
14869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14870 || TARGET_MIX_SSE_I387)
14871 && flag_unsafe_math_optimizations)
14872 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14873 && !flag_trapping_math)"
14874 {
14875 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14876 && !flag_trapping_math)
14877 {
14878 if (TARGET_ROUND)
14879 emit_insn (gen_sse4_1_round<mode>2
14880 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14881 else if (optimize_insn_for_size_p ())
14882 FAIL;
14883 else
14884 ix86_expand_rint (operands[0], operands[1]);
14885 }
14886 else
14887 {
14888 rtx op0 = gen_reg_rtx (XFmode);
14889 rtx op1 = gen_reg_rtx (XFmode);
14890
14891 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14892 emit_insn (gen_rintxf2 (op0, op1));
14893
14894 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14895 }
14896 DONE;
14897 })
14898
14899 (define_expand "round<mode>2"
14900 [(match_operand:X87MODEF 0 "register_operand")
14901 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14902 "(TARGET_USE_FANCY_MATH_387
14903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14904 || TARGET_MIX_SSE_I387)
14905 && flag_unsafe_math_optimizations)
14906 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14907 && !flag_trapping_math && !flag_rounding_math)"
14908 {
14909 if (optimize_insn_for_size_p ())
14910 FAIL;
14911
14912 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14913 && !flag_trapping_math && !flag_rounding_math)
14914 {
14915 if (TARGET_ROUND)
14916 {
14917 operands[1] = force_reg (<MODE>mode, operands[1]);
14918 ix86_expand_round_sse4 (operands[0], operands[1]);
14919 }
14920 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14921 ix86_expand_round (operands[0], operands[1]);
14922 else
14923 ix86_expand_rounddf_32 (operands[0], operands[1]);
14924 }
14925 else
14926 {
14927 operands[1] = force_reg (<MODE>mode, operands[1]);
14928 ix86_emit_i387_round (operands[0], operands[1]);
14929 }
14930 DONE;
14931 })
14932
14933 (define_insn_and_split "*fistdi2_1"
14934 [(set (match_operand:DI 0 "nonimmediate_operand")
14935 (unspec:DI [(match_operand:XF 1 "register_operand")]
14936 UNSPEC_FIST))]
14937 "TARGET_USE_FANCY_MATH_387
14938 && can_create_pseudo_p ()"
14939 "#"
14940 "&& 1"
14941 [(const_int 0)]
14942 {
14943 if (memory_operand (operands[0], VOIDmode))
14944 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14945 else
14946 {
14947 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14948 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14949 operands[2]));
14950 }
14951 DONE;
14952 }
14953 [(set_attr "type" "fpspc")
14954 (set_attr "mode" "DI")])
14955
14956 (define_insn "fistdi2"
14957 [(set (match_operand:DI 0 "memory_operand" "=m")
14958 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14959 UNSPEC_FIST))
14960 (clobber (match_scratch:XF 2 "=&1f"))]
14961 "TARGET_USE_FANCY_MATH_387"
14962 "* return output_fix_trunc (insn, operands, false);"
14963 [(set_attr "type" "fpspc")
14964 (set_attr "mode" "DI")])
14965
14966 (define_insn "fistdi2_with_temp"
14967 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14968 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14969 UNSPEC_FIST))
14970 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14971 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14972 "TARGET_USE_FANCY_MATH_387"
14973 "#"
14974 [(set_attr "type" "fpspc")
14975 (set_attr "mode" "DI")])
14976
14977 (define_split
14978 [(set (match_operand:DI 0 "register_operand")
14979 (unspec:DI [(match_operand:XF 1 "register_operand")]
14980 UNSPEC_FIST))
14981 (clobber (match_operand:DI 2 "memory_operand"))
14982 (clobber (match_scratch 3))]
14983 "reload_completed"
14984 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14985 (clobber (match_dup 3))])
14986 (set (match_dup 0) (match_dup 2))])
14987
14988 (define_split
14989 [(set (match_operand:DI 0 "memory_operand")
14990 (unspec:DI [(match_operand:XF 1 "register_operand")]
14991 UNSPEC_FIST))
14992 (clobber (match_operand:DI 2 "memory_operand"))
14993 (clobber (match_scratch 3))]
14994 "reload_completed"
14995 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14996 (clobber (match_dup 3))])])
14997
14998 (define_insn_and_split "*fist<mode>2_1"
14999 [(set (match_operand:SWI24 0 "register_operand")
15000 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15001 UNSPEC_FIST))]
15002 "TARGET_USE_FANCY_MATH_387
15003 && can_create_pseudo_p ()"
15004 "#"
15005 "&& 1"
15006 [(const_int 0)]
15007 {
15008 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15009 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15010 operands[2]));
15011 DONE;
15012 }
15013 [(set_attr "type" "fpspc")
15014 (set_attr "mode" "<MODE>")])
15015
15016 (define_insn "fist<mode>2"
15017 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15018 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15019 UNSPEC_FIST))]
15020 "TARGET_USE_FANCY_MATH_387"
15021 "* return output_fix_trunc (insn, operands, false);"
15022 [(set_attr "type" "fpspc")
15023 (set_attr "mode" "<MODE>")])
15024
15025 (define_insn "fist<mode>2_with_temp"
15026 [(set (match_operand:SWI24 0 "register_operand" "=r")
15027 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15028 UNSPEC_FIST))
15029 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15030 "TARGET_USE_FANCY_MATH_387"
15031 "#"
15032 [(set_attr "type" "fpspc")
15033 (set_attr "mode" "<MODE>")])
15034
15035 (define_split
15036 [(set (match_operand:SWI24 0 "register_operand")
15037 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15038 UNSPEC_FIST))
15039 (clobber (match_operand:SWI24 2 "memory_operand"))]
15040 "reload_completed"
15041 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15042 (set (match_dup 0) (match_dup 2))])
15043
15044 (define_split
15045 [(set (match_operand:SWI24 0 "memory_operand")
15046 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15047 UNSPEC_FIST))
15048 (clobber (match_operand:SWI24 2 "memory_operand"))]
15049 "reload_completed"
15050 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15051
15052 (define_expand "lrintxf<mode>2"
15053 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15054 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15055 UNSPEC_FIST))]
15056 "TARGET_USE_FANCY_MATH_387")
15057
15058 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15059 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15060 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15061 UNSPEC_FIX_NOTRUNC))]
15062 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15063
15064 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15065 [(match_operand:SWI248x 0 "nonimmediate_operand")
15066 (match_operand:X87MODEF 1 "register_operand")]
15067 "(TARGET_USE_FANCY_MATH_387
15068 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15069 || TARGET_MIX_SSE_I387)
15070 && flag_unsafe_math_optimizations)
15071 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15072 && <SWI248x:MODE>mode != HImode
15073 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15074 && !flag_trapping_math && !flag_rounding_math)"
15075 {
15076 if (optimize_insn_for_size_p ())
15077 FAIL;
15078
15079 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15080 && <SWI248x:MODE>mode != HImode
15081 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15082 && !flag_trapping_math && !flag_rounding_math)
15083 ix86_expand_lround (operands[0], operands[1]);
15084 else
15085 ix86_emit_i387_round (operands[0], operands[1]);
15086 DONE;
15087 })
15088
15089 (define_int_iterator FRNDINT_ROUNDING
15090 [UNSPEC_FRNDINT_FLOOR
15091 UNSPEC_FRNDINT_CEIL
15092 UNSPEC_FRNDINT_TRUNC])
15093
15094 (define_int_iterator FIST_ROUNDING
15095 [UNSPEC_FIST_FLOOR
15096 UNSPEC_FIST_CEIL])
15097
15098 ;; Base name for define_insn
15099 (define_int_attr rounding_insn
15100 [(UNSPEC_FRNDINT_FLOOR "floor")
15101 (UNSPEC_FRNDINT_CEIL "ceil")
15102 (UNSPEC_FRNDINT_TRUNC "btrunc")
15103 (UNSPEC_FIST_FLOOR "floor")
15104 (UNSPEC_FIST_CEIL "ceil")])
15105
15106 (define_int_attr rounding
15107 [(UNSPEC_FRNDINT_FLOOR "floor")
15108 (UNSPEC_FRNDINT_CEIL "ceil")
15109 (UNSPEC_FRNDINT_TRUNC "trunc")
15110 (UNSPEC_FIST_FLOOR "floor")
15111 (UNSPEC_FIST_CEIL "ceil")])
15112
15113 (define_int_attr ROUNDING
15114 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15115 (UNSPEC_FRNDINT_CEIL "CEIL")
15116 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15117 (UNSPEC_FIST_FLOOR "FLOOR")
15118 (UNSPEC_FIST_CEIL "CEIL")])
15119
15120 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15121 (define_insn_and_split "frndintxf2_<rounding>"
15122 [(set (match_operand:XF 0 "register_operand")
15123 (unspec:XF [(match_operand:XF 1 "register_operand")]
15124 FRNDINT_ROUNDING))
15125 (clobber (reg:CC FLAGS_REG))]
15126 "TARGET_USE_FANCY_MATH_387
15127 && flag_unsafe_math_optimizations
15128 && can_create_pseudo_p ()"
15129 "#"
15130 "&& 1"
15131 [(const_int 0)]
15132 {
15133 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15134
15135 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15136 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15137
15138 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15139 operands[2], operands[3]));
15140 DONE;
15141 }
15142 [(set_attr "type" "frndint")
15143 (set_attr "i387_cw" "<rounding>")
15144 (set_attr "mode" "XF")])
15145
15146 (define_insn "frndintxf2_<rounding>_i387"
15147 [(set (match_operand:XF 0 "register_operand" "=f")
15148 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15149 FRNDINT_ROUNDING))
15150 (use (match_operand:HI 2 "memory_operand" "m"))
15151 (use (match_operand:HI 3 "memory_operand" "m"))]
15152 "TARGET_USE_FANCY_MATH_387
15153 && flag_unsafe_math_optimizations"
15154 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15155 [(set_attr "type" "frndint")
15156 (set_attr "i387_cw" "<rounding>")
15157 (set_attr "mode" "XF")])
15158
15159 (define_expand "<rounding_insn>xf2"
15160 [(parallel [(set (match_operand:XF 0 "register_operand")
15161 (unspec:XF [(match_operand:XF 1 "register_operand")]
15162 FRNDINT_ROUNDING))
15163 (clobber (reg:CC FLAGS_REG))])]
15164 "TARGET_USE_FANCY_MATH_387
15165 && flag_unsafe_math_optimizations
15166 && !optimize_insn_for_size_p ()")
15167
15168 (define_expand "<rounding_insn><mode>2"
15169 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15170 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15171 FRNDINT_ROUNDING))
15172 (clobber (reg:CC FLAGS_REG))])]
15173 "(TARGET_USE_FANCY_MATH_387
15174 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15175 || TARGET_MIX_SSE_I387)
15176 && flag_unsafe_math_optimizations)
15177 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15178 && !flag_trapping_math)"
15179 {
15180 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15181 && !flag_trapping_math)
15182 {
15183 if (TARGET_ROUND)
15184 emit_insn (gen_sse4_1_round<mode>2
15185 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15186 else if (optimize_insn_for_size_p ())
15187 FAIL;
15188 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15189 {
15190 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15191 ix86_expand_floorceil (operands[0], operands[1], true);
15192 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15193 ix86_expand_floorceil (operands[0], operands[1], false);
15194 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15195 ix86_expand_trunc (operands[0], operands[1]);
15196 else
15197 gcc_unreachable ();
15198 }
15199 else
15200 {
15201 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15202 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15203 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15204 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15205 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15206 ix86_expand_truncdf_32 (operands[0], operands[1]);
15207 else
15208 gcc_unreachable ();
15209 }
15210 }
15211 else
15212 {
15213 rtx op0, op1;
15214
15215 if (optimize_insn_for_size_p ())
15216 FAIL;
15217
15218 op0 = gen_reg_rtx (XFmode);
15219 op1 = gen_reg_rtx (XFmode);
15220 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15221 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15222
15223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15224 }
15225 DONE;
15226 })
15227
15228 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15229 (define_insn_and_split "frndintxf2_mask_pm"
15230 [(set (match_operand:XF 0 "register_operand")
15231 (unspec:XF [(match_operand:XF 1 "register_operand")]
15232 UNSPEC_FRNDINT_MASK_PM))
15233 (clobber (reg:CC FLAGS_REG))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations
15236 && can_create_pseudo_p ()"
15237 "#"
15238 "&& 1"
15239 [(const_int 0)]
15240 {
15241 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15242
15243 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15244 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15245
15246 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15247 operands[2], operands[3]));
15248 DONE;
15249 }
15250 [(set_attr "type" "frndint")
15251 (set_attr "i387_cw" "mask_pm")
15252 (set_attr "mode" "XF")])
15253
15254 (define_insn "frndintxf2_mask_pm_i387"
15255 [(set (match_operand:XF 0 "register_operand" "=f")
15256 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15257 UNSPEC_FRNDINT_MASK_PM))
15258 (use (match_operand:HI 2 "memory_operand" "m"))
15259 (use (match_operand:HI 3 "memory_operand" "m"))]
15260 "TARGET_USE_FANCY_MATH_387
15261 && flag_unsafe_math_optimizations"
15262 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15263 [(set_attr "type" "frndint")
15264 (set_attr "i387_cw" "mask_pm")
15265 (set_attr "mode" "XF")])
15266
15267 (define_expand "nearbyintxf2"
15268 [(parallel [(set (match_operand:XF 0 "register_operand")
15269 (unspec:XF [(match_operand:XF 1 "register_operand")]
15270 UNSPEC_FRNDINT_MASK_PM))
15271 (clobber (reg:CC FLAGS_REG))])]
15272 "TARGET_USE_FANCY_MATH_387
15273 && flag_unsafe_math_optimizations")
15274
15275 (define_expand "nearbyint<mode>2"
15276 [(use (match_operand:MODEF 0 "register_operand"))
15277 (use (match_operand:MODEF 1 "register_operand"))]
15278 "TARGET_USE_FANCY_MATH_387
15279 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15280 || TARGET_MIX_SSE_I387)
15281 && flag_unsafe_math_optimizations"
15282 {
15283 rtx op0 = gen_reg_rtx (XFmode);
15284 rtx op1 = gen_reg_rtx (XFmode);
15285
15286 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15287 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15288
15289 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15290 DONE;
15291 })
15292
15293 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15294 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15295 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15296 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15297 FIST_ROUNDING))
15298 (clobber (reg:CC FLAGS_REG))]
15299 "TARGET_USE_FANCY_MATH_387
15300 && flag_unsafe_math_optimizations
15301 && can_create_pseudo_p ()"
15302 "#"
15303 "&& 1"
15304 [(const_int 0)]
15305 {
15306 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15307
15308 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15309 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15310 if (memory_operand (operands[0], VOIDmode))
15311 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15312 operands[2], operands[3]));
15313 else
15314 {
15315 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15316 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15317 (operands[0], operands[1], operands[2],
15318 operands[3], operands[4]));
15319 }
15320 DONE;
15321 }
15322 [(set_attr "type" "fistp")
15323 (set_attr "i387_cw" "<rounding>")
15324 (set_attr "mode" "<MODE>")])
15325
15326 (define_insn "fistdi2_<rounding>"
15327 [(set (match_operand:DI 0 "memory_operand" "=m")
15328 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15329 FIST_ROUNDING))
15330 (use (match_operand:HI 2 "memory_operand" "m"))
15331 (use (match_operand:HI 3 "memory_operand" "m"))
15332 (clobber (match_scratch:XF 4 "=&1f"))]
15333 "TARGET_USE_FANCY_MATH_387
15334 && flag_unsafe_math_optimizations"
15335 "* return output_fix_trunc (insn, operands, false);"
15336 [(set_attr "type" "fistp")
15337 (set_attr "i387_cw" "<rounding>")
15338 (set_attr "mode" "DI")])
15339
15340 (define_insn "fistdi2_<rounding>_with_temp"
15341 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15342 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15343 FIST_ROUNDING))
15344 (use (match_operand:HI 2 "memory_operand" "m,m"))
15345 (use (match_operand:HI 3 "memory_operand" "m,m"))
15346 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15347 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15348 "TARGET_USE_FANCY_MATH_387
15349 && flag_unsafe_math_optimizations"
15350 "#"
15351 [(set_attr "type" "fistp")
15352 (set_attr "i387_cw" "<rounding>")
15353 (set_attr "mode" "DI")])
15354
15355 (define_split
15356 [(set (match_operand:DI 0 "register_operand")
15357 (unspec:DI [(match_operand:XF 1 "register_operand")]
15358 FIST_ROUNDING))
15359 (use (match_operand:HI 2 "memory_operand"))
15360 (use (match_operand:HI 3 "memory_operand"))
15361 (clobber (match_operand:DI 4 "memory_operand"))
15362 (clobber (match_scratch 5))]
15363 "reload_completed"
15364 [(parallel [(set (match_dup 4)
15365 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15366 (use (match_dup 2))
15367 (use (match_dup 3))
15368 (clobber (match_dup 5))])
15369 (set (match_dup 0) (match_dup 4))])
15370
15371 (define_split
15372 [(set (match_operand:DI 0 "memory_operand")
15373 (unspec:DI [(match_operand:XF 1 "register_operand")]
15374 FIST_ROUNDING))
15375 (use (match_operand:HI 2 "memory_operand"))
15376 (use (match_operand:HI 3 "memory_operand"))
15377 (clobber (match_operand:DI 4 "memory_operand"))
15378 (clobber (match_scratch 5))]
15379 "reload_completed"
15380 [(parallel [(set (match_dup 0)
15381 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15382 (use (match_dup 2))
15383 (use (match_dup 3))
15384 (clobber (match_dup 5))])])
15385
15386 (define_insn "fist<mode>2_<rounding>"
15387 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15388 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15389 FIST_ROUNDING))
15390 (use (match_operand:HI 2 "memory_operand" "m"))
15391 (use (match_operand:HI 3 "memory_operand" "m"))]
15392 "TARGET_USE_FANCY_MATH_387
15393 && flag_unsafe_math_optimizations"
15394 "* return output_fix_trunc (insn, operands, false);"
15395 [(set_attr "type" "fistp")
15396 (set_attr "i387_cw" "<rounding>")
15397 (set_attr "mode" "<MODE>")])
15398
15399 (define_insn "fist<mode>2_<rounding>_with_temp"
15400 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15401 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15402 FIST_ROUNDING))
15403 (use (match_operand:HI 2 "memory_operand" "m,m"))
15404 (use (match_operand:HI 3 "memory_operand" "m,m"))
15405 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15406 "TARGET_USE_FANCY_MATH_387
15407 && flag_unsafe_math_optimizations"
15408 "#"
15409 [(set_attr "type" "fistp")
15410 (set_attr "i387_cw" "<rounding>")
15411 (set_attr "mode" "<MODE>")])
15412
15413 (define_split
15414 [(set (match_operand:SWI24 0 "register_operand")
15415 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15416 FIST_ROUNDING))
15417 (use (match_operand:HI 2 "memory_operand"))
15418 (use (match_operand:HI 3 "memory_operand"))
15419 (clobber (match_operand:SWI24 4 "memory_operand"))]
15420 "reload_completed"
15421 [(parallel [(set (match_dup 4)
15422 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15423 (use (match_dup 2))
15424 (use (match_dup 3))])
15425 (set (match_dup 0) (match_dup 4))])
15426
15427 (define_split
15428 [(set (match_operand:SWI24 0 "memory_operand")
15429 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15430 FIST_ROUNDING))
15431 (use (match_operand:HI 2 "memory_operand"))
15432 (use (match_operand:HI 3 "memory_operand"))
15433 (clobber (match_operand:SWI24 4 "memory_operand"))]
15434 "reload_completed"
15435 [(parallel [(set (match_dup 0)
15436 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15437 (use (match_dup 2))
15438 (use (match_dup 3))])])
15439
15440 (define_expand "l<rounding_insn>xf<mode>2"
15441 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15442 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15443 FIST_ROUNDING))
15444 (clobber (reg:CC FLAGS_REG))])]
15445 "TARGET_USE_FANCY_MATH_387
15446 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15447 && flag_unsafe_math_optimizations")
15448
15449 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15450 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15451 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15452 FIST_ROUNDING))
15453 (clobber (reg:CC FLAGS_REG))])]
15454 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15455 && !flag_trapping_math"
15456 {
15457 if (TARGET_64BIT && optimize_insn_for_size_p ())
15458 FAIL;
15459
15460 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15461 ix86_expand_lfloorceil (operands[0], operands[1], true);
15462 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15463 ix86_expand_lfloorceil (operands[0], operands[1], false);
15464 else
15465 gcc_unreachable ();
15466
15467 DONE;
15468 })
15469
15470 (define_insn "fxam<mode>2_i387"
15471 [(set (match_operand:HI 0 "register_operand" "=a")
15472 (unspec:HI
15473 [(match_operand:X87MODEF 1 "register_operand" "f")]
15474 UNSPEC_FXAM))]
15475 "TARGET_USE_FANCY_MATH_387"
15476 "fxam\n\tfnstsw\t%0"
15477 [(set_attr "type" "multi")
15478 (set_attr "length" "4")
15479 (set_attr "unit" "i387")
15480 (set_attr "mode" "<MODE>")])
15481
15482 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15483 [(set (match_operand:HI 0 "register_operand")
15484 (unspec:HI
15485 [(match_operand:MODEF 1 "memory_operand")]
15486 UNSPEC_FXAM_MEM))]
15487 "TARGET_USE_FANCY_MATH_387
15488 && can_create_pseudo_p ()"
15489 "#"
15490 "&& 1"
15491 [(set (match_dup 2)(match_dup 1))
15492 (set (match_dup 0)
15493 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15494 {
15495 operands[2] = gen_reg_rtx (<MODE>mode);
15496
15497 MEM_VOLATILE_P (operands[1]) = 1;
15498 }
15499 [(set_attr "type" "multi")
15500 (set_attr "unit" "i387")
15501 (set_attr "mode" "<MODE>")])
15502
15503 (define_expand "isinfxf2"
15504 [(use (match_operand:SI 0 "register_operand"))
15505 (use (match_operand:XF 1 "register_operand"))]
15506 "TARGET_USE_FANCY_MATH_387
15507 && ix86_libc_has_function (function_c99_misc)"
15508 {
15509 rtx mask = GEN_INT (0x45);
15510 rtx val = GEN_INT (0x05);
15511
15512 rtx cond;
15513
15514 rtx scratch = gen_reg_rtx (HImode);
15515 rtx res = gen_reg_rtx (QImode);
15516
15517 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15518
15519 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15520 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15521 cond = gen_rtx_fmt_ee (EQ, QImode,
15522 gen_rtx_REG (CCmode, FLAGS_REG),
15523 const0_rtx);
15524 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15525 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15526 DONE;
15527 })
15528
15529 (define_expand "isinf<mode>2"
15530 [(use (match_operand:SI 0 "register_operand"))
15531 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15532 "TARGET_USE_FANCY_MATH_387
15533 && ix86_libc_has_function (function_c99_misc)
15534 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15535 {
15536 rtx mask = GEN_INT (0x45);
15537 rtx val = GEN_INT (0x05);
15538
15539 rtx cond;
15540
15541 rtx scratch = gen_reg_rtx (HImode);
15542 rtx res = gen_reg_rtx (QImode);
15543
15544 /* Remove excess precision by forcing value through memory. */
15545 if (memory_operand (operands[1], VOIDmode))
15546 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15547 else
15548 {
15549 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15550
15551 emit_move_insn (temp, operands[1]);
15552 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15553 }
15554
15555 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15556 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15557 cond = gen_rtx_fmt_ee (EQ, QImode,
15558 gen_rtx_REG (CCmode, FLAGS_REG),
15559 const0_rtx);
15560 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15561 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15562 DONE;
15563 })
15564
15565 (define_expand "signbitxf2"
15566 [(use (match_operand:SI 0 "register_operand"))
15567 (use (match_operand:XF 1 "register_operand"))]
15568 "TARGET_USE_FANCY_MATH_387"
15569 {
15570 rtx scratch = gen_reg_rtx (HImode);
15571
15572 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15573 emit_insn (gen_andsi3 (operands[0],
15574 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15575 DONE;
15576 })
15577
15578 (define_insn "movmsk_df"
15579 [(set (match_operand:SI 0 "register_operand" "=r")
15580 (unspec:SI
15581 [(match_operand:DF 1 "register_operand" "x")]
15582 UNSPEC_MOVMSK))]
15583 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15584 "%vmovmskpd\t{%1, %0|%0, %1}"
15585 [(set_attr "type" "ssemov")
15586 (set_attr "prefix" "maybe_vex")
15587 (set_attr "mode" "DF")])
15588
15589 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15590 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15591 (define_expand "signbitdf2"
15592 [(use (match_operand:SI 0 "register_operand"))
15593 (use (match_operand:DF 1 "register_operand"))]
15594 "TARGET_USE_FANCY_MATH_387
15595 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15596 {
15597 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15598 {
15599 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15600 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15601 }
15602 else
15603 {
15604 rtx scratch = gen_reg_rtx (HImode);
15605
15606 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15607 emit_insn (gen_andsi3 (operands[0],
15608 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15609 }
15610 DONE;
15611 })
15612
15613 (define_expand "signbitsf2"
15614 [(use (match_operand:SI 0 "register_operand"))
15615 (use (match_operand:SF 1 "register_operand"))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15618 {
15619 rtx scratch = gen_reg_rtx (HImode);
15620
15621 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15622 emit_insn (gen_andsi3 (operands[0],
15623 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15624 DONE;
15625 })
15626 \f
15627 ;; Block operation instructions
15628
15629 (define_insn "cld"
15630 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15631 ""
15632 "cld"
15633 [(set_attr "length" "1")
15634 (set_attr "length_immediate" "0")
15635 (set_attr "modrm" "0")])
15636
15637 (define_expand "movmem<mode>"
15638 [(use (match_operand:BLK 0 "memory_operand"))
15639 (use (match_operand:BLK 1 "memory_operand"))
15640 (use (match_operand:SWI48 2 "nonmemory_operand"))
15641 (use (match_operand:SWI48 3 "const_int_operand"))
15642 (use (match_operand:SI 4 "const_int_operand"))
15643 (use (match_operand:SI 5 "const_int_operand"))
15644 (use (match_operand:SI 6 ""))
15645 (use (match_operand:SI 7 ""))
15646 (use (match_operand:SI 8 ""))]
15647 ""
15648 {
15649 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15650 operands[2], NULL, operands[3],
15651 operands[4], operands[5],
15652 operands[6], operands[7],
15653 operands[8], false))
15654 DONE;
15655 else
15656 FAIL;
15657 })
15658
15659 ;; Most CPUs don't like single string operations
15660 ;; Handle this case here to simplify previous expander.
15661
15662 (define_expand "strmov"
15663 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15664 (set (match_operand 1 "memory_operand") (match_dup 4))
15665 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15666 (clobber (reg:CC FLAGS_REG))])
15667 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15668 (clobber (reg:CC FLAGS_REG))])]
15669 ""
15670 {
15671 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15672
15673 /* If .md ever supports :P for Pmode, these can be directly
15674 in the pattern above. */
15675 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15676 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15677
15678 /* Can't use this if the user has appropriated esi or edi. */
15679 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15680 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15681 {
15682 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15683 operands[2], operands[3],
15684 operands[5], operands[6]));
15685 DONE;
15686 }
15687
15688 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15689 })
15690
15691 (define_expand "strmov_singleop"
15692 [(parallel [(set (match_operand 1 "memory_operand")
15693 (match_operand 3 "memory_operand"))
15694 (set (match_operand 0 "register_operand")
15695 (match_operand 4))
15696 (set (match_operand 2 "register_operand")
15697 (match_operand 5))])]
15698 ""
15699 "ix86_current_function_needs_cld = 1;")
15700
15701 (define_insn "*strmovdi_rex_1"
15702 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15703 (mem:DI (match_operand:P 3 "register_operand" "1")))
15704 (set (match_operand:P 0 "register_operand" "=D")
15705 (plus:P (match_dup 2)
15706 (const_int 8)))
15707 (set (match_operand:P 1 "register_operand" "=S")
15708 (plus:P (match_dup 3)
15709 (const_int 8)))]
15710 "TARGET_64BIT
15711 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15712 "%^movsq"
15713 [(set_attr "type" "str")
15714 (set_attr "memory" "both")
15715 (set_attr "mode" "DI")])
15716
15717 (define_insn "*strmovsi_1"
15718 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15719 (mem:SI (match_operand:P 3 "register_operand" "1")))
15720 (set (match_operand:P 0 "register_operand" "=D")
15721 (plus:P (match_dup 2)
15722 (const_int 4)))
15723 (set (match_operand:P 1 "register_operand" "=S")
15724 (plus:P (match_dup 3)
15725 (const_int 4)))]
15726 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15727 "%^movs{l|d}"
15728 [(set_attr "type" "str")
15729 (set_attr "memory" "both")
15730 (set_attr "mode" "SI")])
15731
15732 (define_insn "*strmovhi_1"
15733 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15734 (mem:HI (match_operand:P 3 "register_operand" "1")))
15735 (set (match_operand:P 0 "register_operand" "=D")
15736 (plus:P (match_dup 2)
15737 (const_int 2)))
15738 (set (match_operand:P 1 "register_operand" "=S")
15739 (plus:P (match_dup 3)
15740 (const_int 2)))]
15741 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15742 "%^movsw"
15743 [(set_attr "type" "str")
15744 (set_attr "memory" "both")
15745 (set_attr "mode" "HI")])
15746
15747 (define_insn "*strmovqi_1"
15748 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15749 (mem:QI (match_operand:P 3 "register_operand" "1")))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (match_dup 2)
15752 (const_int 1)))
15753 (set (match_operand:P 1 "register_operand" "=S")
15754 (plus:P (match_dup 3)
15755 (const_int 1)))]
15756 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757 "%^movsb"
15758 [(set_attr "type" "str")
15759 (set_attr "memory" "both")
15760 (set (attr "prefix_rex")
15761 (if_then_else
15762 (match_test "<P:MODE>mode == DImode")
15763 (const_string "0")
15764 (const_string "*")))
15765 (set_attr "mode" "QI")])
15766
15767 (define_expand "rep_mov"
15768 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15769 (set (match_operand 0 "register_operand")
15770 (match_operand 5))
15771 (set (match_operand 2 "register_operand")
15772 (match_operand 6))
15773 (set (match_operand 1 "memory_operand")
15774 (match_operand 3 "memory_operand"))
15775 (use (match_dup 4))])]
15776 ""
15777 "ix86_current_function_needs_cld = 1;")
15778
15779 (define_insn "*rep_movdi_rex64"
15780 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15781 (set (match_operand:P 0 "register_operand" "=D")
15782 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15783 (const_int 3))
15784 (match_operand:P 3 "register_operand" "0")))
15785 (set (match_operand:P 1 "register_operand" "=S")
15786 (plus:P (ashift:P (match_dup 5) (const_int 3))
15787 (match_operand:P 4 "register_operand" "1")))
15788 (set (mem:BLK (match_dup 3))
15789 (mem:BLK (match_dup 4)))
15790 (use (match_dup 5))]
15791 "TARGET_64BIT
15792 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15793 "%^rep{%;} movsq"
15794 [(set_attr "type" "str")
15795 (set_attr "prefix_rep" "1")
15796 (set_attr "memory" "both")
15797 (set_attr "mode" "DI")])
15798
15799 (define_insn "*rep_movsi"
15800 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15801 (set (match_operand:P 0 "register_operand" "=D")
15802 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15803 (const_int 2))
15804 (match_operand:P 3 "register_operand" "0")))
15805 (set (match_operand:P 1 "register_operand" "=S")
15806 (plus:P (ashift:P (match_dup 5) (const_int 2))
15807 (match_operand:P 4 "register_operand" "1")))
15808 (set (mem:BLK (match_dup 3))
15809 (mem:BLK (match_dup 4)))
15810 (use (match_dup 5))]
15811 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15812 "%^rep{%;} movs{l|d}"
15813 [(set_attr "type" "str")
15814 (set_attr "prefix_rep" "1")
15815 (set_attr "memory" "both")
15816 (set_attr "mode" "SI")])
15817
15818 (define_insn "*rep_movqi"
15819 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15820 (set (match_operand:P 0 "register_operand" "=D")
15821 (plus:P (match_operand:P 3 "register_operand" "0")
15822 (match_operand:P 5 "register_operand" "2")))
15823 (set (match_operand:P 1 "register_operand" "=S")
15824 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15825 (set (mem:BLK (match_dup 3))
15826 (mem:BLK (match_dup 4)))
15827 (use (match_dup 5))]
15828 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15829 "%^rep{%;} movsb"
15830 [(set_attr "type" "str")
15831 (set_attr "prefix_rep" "1")
15832 (set_attr "memory" "both")
15833 (set_attr "mode" "QI")])
15834
15835 (define_expand "setmem<mode>"
15836 [(use (match_operand:BLK 0 "memory_operand"))
15837 (use (match_operand:SWI48 1 "nonmemory_operand"))
15838 (use (match_operand:QI 2 "nonmemory_operand"))
15839 (use (match_operand 3 "const_int_operand"))
15840 (use (match_operand:SI 4 "const_int_operand"))
15841 (use (match_operand:SI 5 "const_int_operand"))
15842 (use (match_operand:SI 6 ""))
15843 (use (match_operand:SI 7 ""))
15844 (use (match_operand:SI 8 ""))]
15845 ""
15846 {
15847 if (ix86_expand_set_or_movmem (operands[0], NULL,
15848 operands[1], operands[2],
15849 operands[3], operands[4],
15850 operands[5], operands[6],
15851 operands[7], operands[8], true))
15852 DONE;
15853 else
15854 FAIL;
15855 })
15856
15857 ;; Most CPUs don't like single string operations
15858 ;; Handle this case here to simplify previous expander.
15859
15860 (define_expand "strset"
15861 [(set (match_operand 1 "memory_operand")
15862 (match_operand 2 "register_operand"))
15863 (parallel [(set (match_operand 0 "register_operand")
15864 (match_dup 3))
15865 (clobber (reg:CC FLAGS_REG))])]
15866 ""
15867 {
15868 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15869 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15870
15871 /* If .md ever supports :P for Pmode, this can be directly
15872 in the pattern above. */
15873 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15874 GEN_INT (GET_MODE_SIZE (GET_MODE
15875 (operands[2]))));
15876 /* Can't use this if the user has appropriated eax or edi. */
15877 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15878 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15879 {
15880 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15881 operands[3]));
15882 DONE;
15883 }
15884 })
15885
15886 (define_expand "strset_singleop"
15887 [(parallel [(set (match_operand 1 "memory_operand")
15888 (match_operand 2 "register_operand"))
15889 (set (match_operand 0 "register_operand")
15890 (match_operand 3))
15891 (unspec [(const_int 0)] UNSPEC_STOS)])]
15892 ""
15893 "ix86_current_function_needs_cld = 1;")
15894
15895 (define_insn "*strsetdi_rex_1"
15896 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15897 (match_operand:DI 2 "register_operand" "a"))
15898 (set (match_operand:P 0 "register_operand" "=D")
15899 (plus:P (match_dup 1)
15900 (const_int 8)))
15901 (unspec [(const_int 0)] UNSPEC_STOS)]
15902 "TARGET_64BIT
15903 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15904 "%^stosq"
15905 [(set_attr "type" "str")
15906 (set_attr "memory" "store")
15907 (set_attr "mode" "DI")])
15908
15909 (define_insn "*strsetsi_1"
15910 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15911 (match_operand:SI 2 "register_operand" "a"))
15912 (set (match_operand:P 0 "register_operand" "=D")
15913 (plus:P (match_dup 1)
15914 (const_int 4)))
15915 (unspec [(const_int 0)] UNSPEC_STOS)]
15916 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15917 "%^stos{l|d}"
15918 [(set_attr "type" "str")
15919 (set_attr "memory" "store")
15920 (set_attr "mode" "SI")])
15921
15922 (define_insn "*strsethi_1"
15923 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15924 (match_operand:HI 2 "register_operand" "a"))
15925 (set (match_operand:P 0 "register_operand" "=D")
15926 (plus:P (match_dup 1)
15927 (const_int 2)))
15928 (unspec [(const_int 0)] UNSPEC_STOS)]
15929 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15930 "%^stosw"
15931 [(set_attr "type" "str")
15932 (set_attr "memory" "store")
15933 (set_attr "mode" "HI")])
15934
15935 (define_insn "*strsetqi_1"
15936 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15937 (match_operand:QI 2 "register_operand" "a"))
15938 (set (match_operand:P 0 "register_operand" "=D")
15939 (plus:P (match_dup 1)
15940 (const_int 1)))
15941 (unspec [(const_int 0)] UNSPEC_STOS)]
15942 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15943 "%^stosb"
15944 [(set_attr "type" "str")
15945 (set_attr "memory" "store")
15946 (set (attr "prefix_rex")
15947 (if_then_else
15948 (match_test "<P:MODE>mode == DImode")
15949 (const_string "0")
15950 (const_string "*")))
15951 (set_attr "mode" "QI")])
15952
15953 (define_expand "rep_stos"
15954 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15955 (set (match_operand 0 "register_operand")
15956 (match_operand 4))
15957 (set (match_operand 2 "memory_operand") (const_int 0))
15958 (use (match_operand 3 "register_operand"))
15959 (use (match_dup 1))])]
15960 ""
15961 "ix86_current_function_needs_cld = 1;")
15962
15963 (define_insn "*rep_stosdi_rex64"
15964 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15965 (set (match_operand:P 0 "register_operand" "=D")
15966 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15967 (const_int 3))
15968 (match_operand:P 3 "register_operand" "0")))
15969 (set (mem:BLK (match_dup 3))
15970 (const_int 0))
15971 (use (match_operand:DI 2 "register_operand" "a"))
15972 (use (match_dup 4))]
15973 "TARGET_64BIT
15974 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15975 "%^rep{%;} stosq"
15976 [(set_attr "type" "str")
15977 (set_attr "prefix_rep" "1")
15978 (set_attr "memory" "store")
15979 (set_attr "mode" "DI")])
15980
15981 (define_insn "*rep_stossi"
15982 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15983 (set (match_operand:P 0 "register_operand" "=D")
15984 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15985 (const_int 2))
15986 (match_operand:P 3 "register_operand" "0")))
15987 (set (mem:BLK (match_dup 3))
15988 (const_int 0))
15989 (use (match_operand:SI 2 "register_operand" "a"))
15990 (use (match_dup 4))]
15991 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15992 "%^rep{%;} stos{l|d}"
15993 [(set_attr "type" "str")
15994 (set_attr "prefix_rep" "1")
15995 (set_attr "memory" "store")
15996 (set_attr "mode" "SI")])
15997
15998 (define_insn "*rep_stosqi"
15999 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16000 (set (match_operand:P 0 "register_operand" "=D")
16001 (plus:P (match_operand:P 3 "register_operand" "0")
16002 (match_operand:P 4 "register_operand" "1")))
16003 (set (mem:BLK (match_dup 3))
16004 (const_int 0))
16005 (use (match_operand:QI 2 "register_operand" "a"))
16006 (use (match_dup 4))]
16007 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16008 "%^rep{%;} stosb"
16009 [(set_attr "type" "str")
16010 (set_attr "prefix_rep" "1")
16011 (set_attr "memory" "store")
16012 (set (attr "prefix_rex")
16013 (if_then_else
16014 (match_test "<P:MODE>mode == DImode")
16015 (const_string "0")
16016 (const_string "*")))
16017 (set_attr "mode" "QI")])
16018
16019 (define_expand "cmpstrnsi"
16020 [(set (match_operand:SI 0 "register_operand")
16021 (compare:SI (match_operand:BLK 1 "general_operand")
16022 (match_operand:BLK 2 "general_operand")))
16023 (use (match_operand 3 "general_operand"))
16024 (use (match_operand 4 "immediate_operand"))]
16025 ""
16026 {
16027 rtx addr1, addr2, out, outlow, count, countreg, align;
16028
16029 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16030 FAIL;
16031
16032 /* Can't use this if the user has appropriated ecx, esi or edi. */
16033 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16034 FAIL;
16035
16036 out = operands[0];
16037 if (!REG_P (out))
16038 out = gen_reg_rtx (SImode);
16039
16040 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16041 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16042 if (addr1 != XEXP (operands[1], 0))
16043 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16044 if (addr2 != XEXP (operands[2], 0))
16045 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16046
16047 count = operands[3];
16048 countreg = ix86_zero_extend_to_Pmode (count);
16049
16050 /* %%% Iff we are testing strict equality, we can use known alignment
16051 to good advantage. This may be possible with combine, particularly
16052 once cc0 is dead. */
16053 align = operands[4];
16054
16055 if (CONST_INT_P (count))
16056 {
16057 if (INTVAL (count) == 0)
16058 {
16059 emit_move_insn (operands[0], const0_rtx);
16060 DONE;
16061 }
16062 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16063 operands[1], operands[2]));
16064 }
16065 else
16066 {
16067 rtx (*gen_cmp) (rtx, rtx);
16068
16069 gen_cmp = (TARGET_64BIT
16070 ? gen_cmpdi_1 : gen_cmpsi_1);
16071
16072 emit_insn (gen_cmp (countreg, countreg));
16073 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16074 operands[1], operands[2]));
16075 }
16076
16077 outlow = gen_lowpart (QImode, out);
16078 emit_insn (gen_cmpintqi (outlow));
16079 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16080
16081 if (operands[0] != out)
16082 emit_move_insn (operands[0], out);
16083
16084 DONE;
16085 })
16086
16087 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16088
16089 (define_expand "cmpintqi"
16090 [(set (match_dup 1)
16091 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16092 (set (match_dup 2)
16093 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16094 (parallel [(set (match_operand:QI 0 "register_operand")
16095 (minus:QI (match_dup 1)
16096 (match_dup 2)))
16097 (clobber (reg:CC FLAGS_REG))])]
16098 ""
16099 {
16100 operands[1] = gen_reg_rtx (QImode);
16101 operands[2] = gen_reg_rtx (QImode);
16102 })
16103
16104 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16105 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16106
16107 (define_expand "cmpstrnqi_nz_1"
16108 [(parallel [(set (reg:CC FLAGS_REG)
16109 (compare:CC (match_operand 4 "memory_operand")
16110 (match_operand 5 "memory_operand")))
16111 (use (match_operand 2 "register_operand"))
16112 (use (match_operand:SI 3 "immediate_operand"))
16113 (clobber (match_operand 0 "register_operand"))
16114 (clobber (match_operand 1 "register_operand"))
16115 (clobber (match_dup 2))])]
16116 ""
16117 "ix86_current_function_needs_cld = 1;")
16118
16119 (define_insn "*cmpstrnqi_nz_1"
16120 [(set (reg:CC FLAGS_REG)
16121 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16122 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16123 (use (match_operand:P 6 "register_operand" "2"))
16124 (use (match_operand:SI 3 "immediate_operand" "i"))
16125 (clobber (match_operand:P 0 "register_operand" "=S"))
16126 (clobber (match_operand:P 1 "register_operand" "=D"))
16127 (clobber (match_operand:P 2 "register_operand" "=c"))]
16128 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16129 "%^repz{%;} cmpsb"
16130 [(set_attr "type" "str")
16131 (set_attr "mode" "QI")
16132 (set (attr "prefix_rex")
16133 (if_then_else
16134 (match_test "<P:MODE>mode == DImode")
16135 (const_string "0")
16136 (const_string "*")))
16137 (set_attr "prefix_rep" "1")])
16138
16139 ;; The same, but the count is not known to not be zero.
16140
16141 (define_expand "cmpstrnqi_1"
16142 [(parallel [(set (reg:CC FLAGS_REG)
16143 (if_then_else:CC (ne (match_operand 2 "register_operand")
16144 (const_int 0))
16145 (compare:CC (match_operand 4 "memory_operand")
16146 (match_operand 5 "memory_operand"))
16147 (const_int 0)))
16148 (use (match_operand:SI 3 "immediate_operand"))
16149 (use (reg:CC FLAGS_REG))
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_1"
16157 [(set (reg:CC FLAGS_REG)
16158 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16159 (const_int 0))
16160 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16161 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16162 (const_int 0)))
16163 (use (match_operand:SI 3 "immediate_operand" "i"))
16164 (use (reg:CC FLAGS_REG))
16165 (clobber (match_operand:P 0 "register_operand" "=S"))
16166 (clobber (match_operand:P 1 "register_operand" "=D"))
16167 (clobber (match_operand:P 2 "register_operand" "=c"))]
16168 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16169 "%^repz{%;} cmpsb"
16170 [(set_attr "type" "str")
16171 (set_attr "mode" "QI")
16172 (set (attr "prefix_rex")
16173 (if_then_else
16174 (match_test "<P:MODE>mode == DImode")
16175 (const_string "0")
16176 (const_string "*")))
16177 (set_attr "prefix_rep" "1")])
16178
16179 (define_expand "strlen<mode>"
16180 [(set (match_operand:P 0 "register_operand")
16181 (unspec:P [(match_operand:BLK 1 "general_operand")
16182 (match_operand:QI 2 "immediate_operand")
16183 (match_operand 3 "immediate_operand")]
16184 UNSPEC_SCAS))]
16185 ""
16186 {
16187 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16188 DONE;
16189 else
16190 FAIL;
16191 })
16192
16193 (define_expand "strlenqi_1"
16194 [(parallel [(set (match_operand 0 "register_operand")
16195 (match_operand 2))
16196 (clobber (match_operand 1 "register_operand"))
16197 (clobber (reg:CC FLAGS_REG))])]
16198 ""
16199 "ix86_current_function_needs_cld = 1;")
16200
16201 (define_insn "*strlenqi_1"
16202 [(set (match_operand:P 0 "register_operand" "=&c")
16203 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16204 (match_operand:QI 2 "register_operand" "a")
16205 (match_operand:P 3 "immediate_operand" "i")
16206 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16207 (clobber (match_operand:P 1 "register_operand" "=D"))
16208 (clobber (reg:CC FLAGS_REG))]
16209 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16210 "%^repnz{%;} scasb"
16211 [(set_attr "type" "str")
16212 (set_attr "mode" "QI")
16213 (set (attr "prefix_rex")
16214 (if_then_else
16215 (match_test "<P:MODE>mode == DImode")
16216 (const_string "0")
16217 (const_string "*")))
16218 (set_attr "prefix_rep" "1")])
16219
16220 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16221 ;; handled in combine, but it is not currently up to the task.
16222 ;; When used for their truth value, the cmpstrn* expanders generate
16223 ;; code like this:
16224 ;;
16225 ;; repz cmpsb
16226 ;; seta %al
16227 ;; setb %dl
16228 ;; cmpb %al, %dl
16229 ;; jcc label
16230 ;;
16231 ;; The intermediate three instructions are unnecessary.
16232
16233 ;; This one handles cmpstrn*_nz_1...
16234 (define_peephole2
16235 [(parallel[
16236 (set (reg:CC FLAGS_REG)
16237 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16238 (mem:BLK (match_operand 5 "register_operand"))))
16239 (use (match_operand 6 "register_operand"))
16240 (use (match_operand:SI 3 "immediate_operand"))
16241 (clobber (match_operand 0 "register_operand"))
16242 (clobber (match_operand 1 "register_operand"))
16243 (clobber (match_operand 2 "register_operand"))])
16244 (set (match_operand:QI 7 "register_operand")
16245 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16246 (set (match_operand:QI 8 "register_operand")
16247 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16248 (set (reg FLAGS_REG)
16249 (compare (match_dup 7) (match_dup 8)))
16250 ]
16251 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16252 [(parallel[
16253 (set (reg:CC FLAGS_REG)
16254 (compare:CC (mem:BLK (match_dup 4))
16255 (mem:BLK (match_dup 5))))
16256 (use (match_dup 6))
16257 (use (match_dup 3))
16258 (clobber (match_dup 0))
16259 (clobber (match_dup 1))
16260 (clobber (match_dup 2))])])
16261
16262 ;; ...and this one handles cmpstrn*_1.
16263 (define_peephole2
16264 [(parallel[
16265 (set (reg:CC FLAGS_REG)
16266 (if_then_else:CC (ne (match_operand 6 "register_operand")
16267 (const_int 0))
16268 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16269 (mem:BLK (match_operand 5 "register_operand")))
16270 (const_int 0)))
16271 (use (match_operand:SI 3 "immediate_operand"))
16272 (use (reg:CC FLAGS_REG))
16273 (clobber (match_operand 0 "register_operand"))
16274 (clobber (match_operand 1 "register_operand"))
16275 (clobber (match_operand 2 "register_operand"))])
16276 (set (match_operand:QI 7 "register_operand")
16277 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16278 (set (match_operand:QI 8 "register_operand")
16279 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16280 (set (reg FLAGS_REG)
16281 (compare (match_dup 7) (match_dup 8)))
16282 ]
16283 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16284 [(parallel[
16285 (set (reg:CC FLAGS_REG)
16286 (if_then_else:CC (ne (match_dup 6)
16287 (const_int 0))
16288 (compare:CC (mem:BLK (match_dup 4))
16289 (mem:BLK (match_dup 5)))
16290 (const_int 0)))
16291 (use (match_dup 3))
16292 (use (reg:CC FLAGS_REG))
16293 (clobber (match_dup 0))
16294 (clobber (match_dup 1))
16295 (clobber (match_dup 2))])])
16296 \f
16297 ;; Conditional move instructions.
16298
16299 (define_expand "mov<mode>cc"
16300 [(set (match_operand:SWIM 0 "register_operand")
16301 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16302 (match_operand:SWIM 2 "<general_operand>")
16303 (match_operand:SWIM 3 "<general_operand>")))]
16304 ""
16305 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16306
16307 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16308 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16309 ;; So just document what we're doing explicitly.
16310
16311 (define_expand "x86_mov<mode>cc_0_m1"
16312 [(parallel
16313 [(set (match_operand:SWI48 0 "register_operand")
16314 (if_then_else:SWI48
16315 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16316 [(match_operand 1 "flags_reg_operand")
16317 (const_int 0)])
16318 (const_int -1)
16319 (const_int 0)))
16320 (clobber (reg:CC FLAGS_REG))])])
16321
16322 (define_insn "*x86_mov<mode>cc_0_m1"
16323 [(set (match_operand:SWI48 0 "register_operand" "=r")
16324 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16325 [(reg FLAGS_REG) (const_int 0)])
16326 (const_int -1)
16327 (const_int 0)))
16328 (clobber (reg:CC FLAGS_REG))]
16329 ""
16330 "sbb{<imodesuffix>}\t%0, %0"
16331 ; Since we don't have the proper number of operands for an alu insn,
16332 ; fill in all the blanks.
16333 [(set_attr "type" "alu")
16334 (set_attr "use_carry" "1")
16335 (set_attr "pent_pair" "pu")
16336 (set_attr "memory" "none")
16337 (set_attr "imm_disp" "false")
16338 (set_attr "mode" "<MODE>")
16339 (set_attr "length_immediate" "0")])
16340
16341 (define_insn "*x86_mov<mode>cc_0_m1_se"
16342 [(set (match_operand:SWI48 0 "register_operand" "=r")
16343 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16344 [(reg FLAGS_REG) (const_int 0)])
16345 (const_int 1)
16346 (const_int 0)))
16347 (clobber (reg:CC FLAGS_REG))]
16348 ""
16349 "sbb{<imodesuffix>}\t%0, %0"
16350 [(set_attr "type" "alu")
16351 (set_attr "use_carry" "1")
16352 (set_attr "pent_pair" "pu")
16353 (set_attr "memory" "none")
16354 (set_attr "imm_disp" "false")
16355 (set_attr "mode" "<MODE>")
16356 (set_attr "length_immediate" "0")])
16357
16358 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16359 [(set (match_operand:SWI48 0 "register_operand" "=r")
16360 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16361 [(reg FLAGS_REG) (const_int 0)])))
16362 (clobber (reg:CC FLAGS_REG))]
16363 ""
16364 "sbb{<imodesuffix>}\t%0, %0"
16365 [(set_attr "type" "alu")
16366 (set_attr "use_carry" "1")
16367 (set_attr "pent_pair" "pu")
16368 (set_attr "memory" "none")
16369 (set_attr "imm_disp" "false")
16370 (set_attr "mode" "<MODE>")
16371 (set_attr "length_immediate" "0")])
16372
16373 (define_insn "*mov<mode>cc_noc"
16374 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16375 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16376 [(reg FLAGS_REG) (const_int 0)])
16377 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16378 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16379 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16380 "@
16381 cmov%O2%C1\t{%2, %0|%0, %2}
16382 cmov%O2%c1\t{%3, %0|%0, %3}"
16383 [(set_attr "type" "icmov")
16384 (set_attr "mode" "<MODE>")])
16385
16386 ;; Don't do conditional moves with memory inputs. This splitter helps
16387 ;; register starved x86_32 by forcing inputs into registers before reload.
16388 (define_split
16389 [(set (match_operand:SWI248 0 "register_operand")
16390 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16391 [(reg FLAGS_REG) (const_int 0)])
16392 (match_operand:SWI248 2 "nonimmediate_operand")
16393 (match_operand:SWI248 3 "nonimmediate_operand")))]
16394 "!TARGET_64BIT && TARGET_CMOVE
16395 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16396 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16397 && can_create_pseudo_p ()
16398 && optimize_insn_for_speed_p ()"
16399 [(set (match_dup 0)
16400 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16401 {
16402 if (MEM_P (operands[2]))
16403 operands[2] = force_reg (<MODE>mode, operands[2]);
16404 if (MEM_P (operands[3]))
16405 operands[3] = force_reg (<MODE>mode, operands[3]);
16406 })
16407
16408 (define_insn "*movqicc_noc"
16409 [(set (match_operand:QI 0 "register_operand" "=r,r")
16410 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16411 [(reg FLAGS_REG) (const_int 0)])
16412 (match_operand:QI 2 "register_operand" "r,0")
16413 (match_operand:QI 3 "register_operand" "0,r")))]
16414 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16415 "#"
16416 [(set_attr "type" "icmov")
16417 (set_attr "mode" "QI")])
16418
16419 (define_split
16420 [(set (match_operand:SWI12 0 "register_operand")
16421 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16422 [(reg FLAGS_REG) (const_int 0)])
16423 (match_operand:SWI12 2 "register_operand")
16424 (match_operand:SWI12 3 "register_operand")))]
16425 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16426 && reload_completed"
16427 [(set (match_dup 0)
16428 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16429 {
16430 operands[0] = gen_lowpart (SImode, operands[0]);
16431 operands[2] = gen_lowpart (SImode, operands[2]);
16432 operands[3] = gen_lowpart (SImode, operands[3]);
16433 })
16434
16435 ;; Don't do conditional moves with memory inputs
16436 (define_peephole2
16437 [(match_scratch:SWI248 2 "r")
16438 (set (match_operand:SWI248 0 "register_operand")
16439 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16440 [(reg FLAGS_REG) (const_int 0)])
16441 (match_dup 0)
16442 (match_operand:SWI248 3 "memory_operand")))]
16443 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16444 && optimize_insn_for_speed_p ()"
16445 [(set (match_dup 2) (match_dup 3))
16446 (set (match_dup 0)
16447 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16448
16449 (define_peephole2
16450 [(match_scratch:SWI248 2 "r")
16451 (set (match_operand:SWI248 0 "register_operand")
16452 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16453 [(reg FLAGS_REG) (const_int 0)])
16454 (match_operand:SWI248 3 "memory_operand")
16455 (match_dup 0)))]
16456 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16457 && optimize_insn_for_speed_p ()"
16458 [(set (match_dup 2) (match_dup 3))
16459 (set (match_dup 0)
16460 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16461
16462 (define_expand "mov<mode>cc"
16463 [(set (match_operand:X87MODEF 0 "register_operand")
16464 (if_then_else:X87MODEF
16465 (match_operand 1 "comparison_operator")
16466 (match_operand:X87MODEF 2 "register_operand")
16467 (match_operand:X87MODEF 3 "register_operand")))]
16468 "(TARGET_80387 && TARGET_CMOVE)
16469 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16470 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16471
16472 (define_insn "*movxfcc_1"
16473 [(set (match_operand:XF 0 "register_operand" "=f,f")
16474 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16475 [(reg FLAGS_REG) (const_int 0)])
16476 (match_operand:XF 2 "register_operand" "f,0")
16477 (match_operand:XF 3 "register_operand" "0,f")))]
16478 "TARGET_80387 && TARGET_CMOVE"
16479 "@
16480 fcmov%F1\t{%2, %0|%0, %2}
16481 fcmov%f1\t{%3, %0|%0, %3}"
16482 [(set_attr "type" "fcmov")
16483 (set_attr "mode" "XF")])
16484
16485 (define_insn "*movdfcc_1"
16486 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16487 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16488 [(reg FLAGS_REG) (const_int 0)])
16489 (match_operand:DF 2 "nonimmediate_operand"
16490 "f ,0,rm,0 ,rm,0")
16491 (match_operand:DF 3 "nonimmediate_operand"
16492 "0 ,f,0 ,rm,0, rm")))]
16493 "TARGET_80387 && TARGET_CMOVE
16494 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16495 "@
16496 fcmov%F1\t{%2, %0|%0, %2}
16497 fcmov%f1\t{%3, %0|%0, %3}
16498 #
16499 #
16500 cmov%O2%C1\t{%2, %0|%0, %2}
16501 cmov%O2%c1\t{%3, %0|%0, %3}"
16502 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16503 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16504 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16505
16506 (define_split
16507 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16508 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16509 [(reg FLAGS_REG) (const_int 0)])
16510 (match_operand:DF 2 "nonimmediate_operand")
16511 (match_operand:DF 3 "nonimmediate_operand")))]
16512 "!TARGET_64BIT && reload_completed"
16513 [(set (match_dup 2)
16514 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16515 (set (match_dup 3)
16516 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16517 {
16518 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16519 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16520 })
16521
16522 (define_insn "*movsfcc_1_387"
16523 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16524 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16525 [(reg FLAGS_REG) (const_int 0)])
16526 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16527 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16528 "TARGET_80387 && TARGET_CMOVE
16529 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16530 "@
16531 fcmov%F1\t{%2, %0|%0, %2}
16532 fcmov%f1\t{%3, %0|%0, %3}
16533 cmov%O2%C1\t{%2, %0|%0, %2}
16534 cmov%O2%c1\t{%3, %0|%0, %3}"
16535 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16536 (set_attr "mode" "SF,SF,SI,SI")])
16537
16538 ;; Don't do conditional moves with memory inputs. This splitter helps
16539 ;; register starved x86_32 by forcing inputs into registers before reload.
16540 (define_split
16541 [(set (match_operand:MODEF 0 "register_operand")
16542 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16543 [(reg FLAGS_REG) (const_int 0)])
16544 (match_operand:MODEF 2 "nonimmediate_operand")
16545 (match_operand:MODEF 3 "nonimmediate_operand")))]
16546 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16547 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16548 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16549 && can_create_pseudo_p ()
16550 && optimize_insn_for_speed_p ()"
16551 [(set (match_dup 0)
16552 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16553 {
16554 if (MEM_P (operands[2]))
16555 operands[2] = force_reg (<MODE>mode, operands[2]);
16556 if (MEM_P (operands[3]))
16557 operands[3] = force_reg (<MODE>mode, operands[3]);
16558 })
16559
16560 ;; Don't do conditional moves with memory inputs
16561 (define_peephole2
16562 [(match_scratch:MODEF 2 "r")
16563 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16564 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16565 [(reg FLAGS_REG) (const_int 0)])
16566 (match_dup 0)
16567 (match_operand:MODEF 3 "memory_operand")))]
16568 "(<MODE>mode != DFmode || TARGET_64BIT)
16569 && TARGET_80387 && TARGET_CMOVE
16570 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16571 && optimize_insn_for_speed_p ()"
16572 [(set (match_dup 2) (match_dup 3))
16573 (set (match_dup 0)
16574 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16575
16576 (define_peephole2
16577 [(match_scratch:MODEF 2 "r")
16578 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16579 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16580 [(reg FLAGS_REG) (const_int 0)])
16581 (match_operand:MODEF 3 "memory_operand")
16582 (match_dup 0)))]
16583 "(<MODE>mode != DFmode || TARGET_64BIT)
16584 && TARGET_80387 && TARGET_CMOVE
16585 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16586 && optimize_insn_for_speed_p ()"
16587 [(set (match_dup 2) (match_dup 3))
16588 (set (match_dup 0)
16589 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16590
16591 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16592 ;; the scalar versions to have only XMM registers as operands.
16593
16594 ;; XOP conditional move
16595 (define_insn "*xop_pcmov_<mode>"
16596 [(set (match_operand:MODEF 0 "register_operand" "=x")
16597 (if_then_else:MODEF
16598 (match_operand:MODEF 1 "register_operand" "x")
16599 (match_operand:MODEF 2 "register_operand" "x")
16600 (match_operand:MODEF 3 "register_operand" "x")))]
16601 "TARGET_XOP"
16602 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16603 [(set_attr "type" "sse4arg")])
16604
16605 ;; These versions of the min/max patterns are intentionally ignorant of
16606 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16607 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16608 ;; are undefined in this condition, we're certain this is correct.
16609
16610 (define_insn "<code><mode>3"
16611 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16612 (smaxmin:MODEF
16613 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16614 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16615 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16616 "@
16617 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16618 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16619 [(set_attr "isa" "noavx,avx")
16620 (set_attr "prefix" "orig,vex")
16621 (set_attr "type" "sseadd")
16622 (set_attr "mode" "<MODE>")])
16623
16624 ;; These versions of the min/max patterns implement exactly the operations
16625 ;; min = (op1 < op2 ? op1 : op2)
16626 ;; max = (!(op1 < op2) ? op1 : op2)
16627 ;; Their operands are not commutative, and thus they may be used in the
16628 ;; presence of -0.0 and NaN.
16629
16630 (define_int_iterator IEEE_MAXMIN
16631 [UNSPEC_IEEE_MAX
16632 UNSPEC_IEEE_MIN])
16633
16634 (define_int_attr ieee_maxmin
16635 [(UNSPEC_IEEE_MAX "max")
16636 (UNSPEC_IEEE_MIN "min")])
16637
16638 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16639 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16640 (unspec:MODEF
16641 [(match_operand:MODEF 1 "register_operand" "0,x")
16642 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16643 IEEE_MAXMIN))]
16644 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16645 "@
16646 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16647 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16648 [(set_attr "isa" "noavx,avx")
16649 (set_attr "prefix" "orig,vex")
16650 (set_attr "type" "sseadd")
16651 (set_attr "mode" "<MODE>")])
16652
16653 ;; Make two stack loads independent:
16654 ;; fld aa fld aa
16655 ;; fld %st(0) -> fld bb
16656 ;; fmul bb fmul %st(1), %st
16657 ;;
16658 ;; Actually we only match the last two instructions for simplicity.
16659 (define_peephole2
16660 [(set (match_operand 0 "fp_register_operand")
16661 (match_operand 1 "fp_register_operand"))
16662 (set (match_dup 0)
16663 (match_operator 2 "binary_fp_operator"
16664 [(match_dup 0)
16665 (match_operand 3 "memory_operand")]))]
16666 "REGNO (operands[0]) != REGNO (operands[1])"
16667 [(set (match_dup 0) (match_dup 3))
16668 (set (match_dup 0) (match_dup 4))]
16669
16670 ;; The % modifier is not operational anymore in peephole2's, so we have to
16671 ;; swap the operands manually in the case of addition and multiplication.
16672 {
16673 rtx op0, op1;
16674
16675 if (COMMUTATIVE_ARITH_P (operands[2]))
16676 op0 = operands[0], op1 = operands[1];
16677 else
16678 op0 = operands[1], op1 = operands[0];
16679
16680 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16681 GET_MODE (operands[2]),
16682 op0, op1);
16683 })
16684
16685 ;; Conditional addition patterns
16686 (define_expand "add<mode>cc"
16687 [(match_operand:SWI 0 "register_operand")
16688 (match_operand 1 "ordered_comparison_operator")
16689 (match_operand:SWI 2 "register_operand")
16690 (match_operand:SWI 3 "const_int_operand")]
16691 ""
16692 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16693 \f
16694 ;; Misc patterns (?)
16695
16696 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16697 ;; Otherwise there will be nothing to keep
16698 ;;
16699 ;; [(set (reg ebp) (reg esp))]
16700 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16701 ;; (clobber (eflags)]
16702 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16703 ;;
16704 ;; in proper program order.
16705
16706 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16707 [(set (match_operand:P 0 "register_operand" "=r,r")
16708 (plus:P (match_operand:P 1 "register_operand" "0,r")
16709 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16710 (clobber (reg:CC FLAGS_REG))
16711 (clobber (mem:BLK (scratch)))]
16712 ""
16713 {
16714 switch (get_attr_type (insn))
16715 {
16716 case TYPE_IMOV:
16717 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16718
16719 case TYPE_ALU:
16720 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16721 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16722 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16723
16724 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16725
16726 default:
16727 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16728 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16729 }
16730 }
16731 [(set (attr "type")
16732 (cond [(and (eq_attr "alternative" "0")
16733 (not (match_test "TARGET_OPT_AGU")))
16734 (const_string "alu")
16735 (match_operand:<MODE> 2 "const0_operand")
16736 (const_string "imov")
16737 ]
16738 (const_string "lea")))
16739 (set (attr "length_immediate")
16740 (cond [(eq_attr "type" "imov")
16741 (const_string "0")
16742 (and (eq_attr "type" "alu")
16743 (match_operand 2 "const128_operand"))
16744 (const_string "1")
16745 ]
16746 (const_string "*")))
16747 (set_attr "mode" "<MODE>")])
16748
16749 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16750 [(set (match_operand:P 0 "register_operand" "=r")
16751 (minus:P (match_operand:P 1 "register_operand" "0")
16752 (match_operand:P 2 "register_operand" "r")))
16753 (clobber (reg:CC FLAGS_REG))
16754 (clobber (mem:BLK (scratch)))]
16755 ""
16756 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16757 [(set_attr "type" "alu")
16758 (set_attr "mode" "<MODE>")])
16759
16760 (define_insn "allocate_stack_worker_probe_<mode>"
16761 [(set (match_operand:P 0 "register_operand" "=a")
16762 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16763 UNSPECV_STACK_PROBE))
16764 (clobber (reg:CC FLAGS_REG))]
16765 "ix86_target_stack_probe ()"
16766 "call\t___chkstk_ms"
16767 [(set_attr "type" "multi")
16768 (set_attr "length" "5")])
16769
16770 (define_expand "allocate_stack"
16771 [(match_operand 0 "register_operand")
16772 (match_operand 1 "general_operand")]
16773 "ix86_target_stack_probe ()"
16774 {
16775 rtx x;
16776
16777 #ifndef CHECK_STACK_LIMIT
16778 #define CHECK_STACK_LIMIT 0
16779 #endif
16780
16781 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16782 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16783 x = operands[1];
16784 else
16785 {
16786 rtx (*insn) (rtx, rtx);
16787
16788 x = copy_to_mode_reg (Pmode, operands[1]);
16789
16790 insn = (TARGET_64BIT
16791 ? gen_allocate_stack_worker_probe_di
16792 : gen_allocate_stack_worker_probe_si);
16793
16794 emit_insn (insn (x, x));
16795 }
16796
16797 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16798 stack_pointer_rtx, 0, OPTAB_DIRECT);
16799
16800 if (x != stack_pointer_rtx)
16801 emit_move_insn (stack_pointer_rtx, x);
16802
16803 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16804 DONE;
16805 })
16806
16807 ;; Use IOR for stack probes, this is shorter.
16808 (define_expand "probe_stack"
16809 [(match_operand 0 "memory_operand")]
16810 ""
16811 {
16812 rtx (*gen_ior3) (rtx, rtx, rtx);
16813
16814 gen_ior3 = (GET_MODE (operands[0]) == DImode
16815 ? gen_iordi3 : gen_iorsi3);
16816
16817 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16818 DONE;
16819 })
16820
16821 (define_insn "adjust_stack_and_probe<mode>"
16822 [(set (match_operand:P 0 "register_operand" "=r")
16823 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16824 UNSPECV_PROBE_STACK_RANGE))
16825 (set (reg:P SP_REG)
16826 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16827 (clobber (reg:CC FLAGS_REG))
16828 (clobber (mem:BLK (scratch)))]
16829 ""
16830 "* return output_adjust_stack_and_probe (operands[0]);"
16831 [(set_attr "type" "multi")])
16832
16833 (define_insn "probe_stack_range<mode>"
16834 [(set (match_operand:P 0 "register_operand" "=r")
16835 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16836 (match_operand:P 2 "const_int_operand" "n")]
16837 UNSPECV_PROBE_STACK_RANGE))
16838 (clobber (reg:CC FLAGS_REG))]
16839 ""
16840 "* return output_probe_stack_range (operands[0], operands[2]);"
16841 [(set_attr "type" "multi")])
16842
16843 (define_expand "builtin_setjmp_receiver"
16844 [(label_ref (match_operand 0))]
16845 "!TARGET_64BIT && flag_pic"
16846 {
16847 #if TARGET_MACHO
16848 if (TARGET_MACHO)
16849 {
16850 rtx xops[3];
16851 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16852 rtx label_rtx = gen_label_rtx ();
16853 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16854 xops[0] = xops[1] = picreg;
16855 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16856 ix86_expand_binary_operator (MINUS, SImode, xops);
16857 }
16858 else
16859 #endif
16860 emit_insn (gen_set_got (pic_offset_table_rtx));
16861 DONE;
16862 })
16863
16864 (define_insn_and_split "nonlocal_goto_receiver"
16865 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16866 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16867 "#"
16868 "&& reload_completed"
16869 [(const_int 0)]
16870 {
16871 if (crtl->uses_pic_offset_table)
16872 {
16873 rtx xops[3];
16874 rtx label_rtx = gen_label_rtx ();
16875 rtx tmp;
16876
16877 /* Get a new pic base. */
16878 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16879 /* Correct this with the offset from the new to the old. */
16880 xops[0] = xops[1] = pic_offset_table_rtx;
16881 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16882 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16883 UNSPEC_MACHOPIC_OFFSET);
16884 xops[2] = gen_rtx_CONST (Pmode, tmp);
16885 ix86_expand_binary_operator (MINUS, SImode, xops);
16886 }
16887 else
16888 /* No pic reg restore needed. */
16889 emit_note (NOTE_INSN_DELETED);
16890
16891 DONE;
16892 })
16893
16894 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16895 ;; Do not split instructions with mask registers.
16896 (define_split
16897 [(set (match_operand 0 "general_reg_operand")
16898 (match_operator 3 "promotable_binary_operator"
16899 [(match_operand 1 "general_reg_operand")
16900 (match_operand 2 "aligned_operand")]))
16901 (clobber (reg:CC FLAGS_REG))]
16902 "! TARGET_PARTIAL_REG_STALL && reload_completed
16903 && ((GET_MODE (operands[0]) == HImode
16904 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16905 /* ??? next two lines just !satisfies_constraint_K (...) */
16906 || !CONST_INT_P (operands[2])
16907 || satisfies_constraint_K (operands[2])))
16908 || (GET_MODE (operands[0]) == QImode
16909 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16910 [(parallel [(set (match_dup 0)
16911 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16912 (clobber (reg:CC FLAGS_REG))])]
16913 {
16914 operands[0] = gen_lowpart (SImode, operands[0]);
16915 operands[1] = gen_lowpart (SImode, operands[1]);
16916 if (GET_CODE (operands[3]) != ASHIFT)
16917 operands[2] = gen_lowpart (SImode, operands[2]);
16918 PUT_MODE (operands[3], SImode);
16919 })
16920
16921 ; Promote the QImode tests, as i386 has encoding of the AND
16922 ; instruction with 32-bit sign-extended immediate and thus the
16923 ; instruction size is unchanged, except in the %eax case for
16924 ; which it is increased by one byte, hence the ! optimize_size.
16925 (define_split
16926 [(set (match_operand 0 "flags_reg_operand")
16927 (match_operator 2 "compare_operator"
16928 [(and (match_operand 3 "aligned_operand")
16929 (match_operand 4 "const_int_operand"))
16930 (const_int 0)]))
16931 (set (match_operand 1 "register_operand")
16932 (and (match_dup 3) (match_dup 4)))]
16933 "! TARGET_PARTIAL_REG_STALL && reload_completed
16934 && optimize_insn_for_speed_p ()
16935 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16936 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16937 /* Ensure that the operand will remain sign-extended immediate. */
16938 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16939 [(parallel [(set (match_dup 0)
16940 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16941 (const_int 0)]))
16942 (set (match_dup 1)
16943 (and:SI (match_dup 3) (match_dup 4)))])]
16944 {
16945 operands[4]
16946 = gen_int_mode (INTVAL (operands[4])
16947 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16948 operands[1] = gen_lowpart (SImode, operands[1]);
16949 operands[3] = gen_lowpart (SImode, operands[3]);
16950 })
16951
16952 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16953 ; the TEST instruction with 32-bit sign-extended immediate and thus
16954 ; the instruction size would at least double, which is not what we
16955 ; want even with ! optimize_size.
16956 (define_split
16957 [(set (match_operand 0 "flags_reg_operand")
16958 (match_operator 1 "compare_operator"
16959 [(and (match_operand:HI 2 "aligned_operand")
16960 (match_operand:HI 3 "const_int_operand"))
16961 (const_int 0)]))]
16962 "! TARGET_PARTIAL_REG_STALL && reload_completed
16963 && ! TARGET_FAST_PREFIX
16964 && optimize_insn_for_speed_p ()
16965 /* Ensure that the operand will remain sign-extended immediate. */
16966 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16967 [(set (match_dup 0)
16968 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16969 (const_int 0)]))]
16970 {
16971 operands[3]
16972 = gen_int_mode (INTVAL (operands[3])
16973 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16974 operands[2] = gen_lowpart (SImode, operands[2]);
16975 })
16976
16977 (define_split
16978 [(set (match_operand 0 "register_operand")
16979 (neg (match_operand 1 "register_operand")))
16980 (clobber (reg:CC FLAGS_REG))]
16981 "! TARGET_PARTIAL_REG_STALL && reload_completed
16982 && (GET_MODE (operands[0]) == HImode
16983 || (GET_MODE (operands[0]) == QImode
16984 && (TARGET_PROMOTE_QImode
16985 || optimize_insn_for_size_p ())))"
16986 [(parallel [(set (match_dup 0)
16987 (neg:SI (match_dup 1)))
16988 (clobber (reg:CC FLAGS_REG))])]
16989 {
16990 operands[0] = gen_lowpart (SImode, operands[0]);
16991 operands[1] = gen_lowpart (SImode, operands[1]);
16992 })
16993
16994 ;; Do not split instructions with mask regs.
16995 (define_split
16996 [(set (match_operand 0 "general_reg_operand")
16997 (not (match_operand 1 "general_reg_operand")))]
16998 "! TARGET_PARTIAL_REG_STALL && reload_completed
16999 && (GET_MODE (operands[0]) == HImode
17000 || (GET_MODE (operands[0]) == QImode
17001 && (TARGET_PROMOTE_QImode
17002 || optimize_insn_for_size_p ())))"
17003 [(set (match_dup 0)
17004 (not:SI (match_dup 1)))]
17005 {
17006 operands[0] = gen_lowpart (SImode, operands[0]);
17007 operands[1] = gen_lowpart (SImode, operands[1]);
17008 })
17009 \f
17010 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17011 ;; transform a complex memory operation into two memory to register operations.
17012
17013 ;; Don't push memory operands
17014 (define_peephole2
17015 [(set (match_operand:SWI 0 "push_operand")
17016 (match_operand:SWI 1 "memory_operand"))
17017 (match_scratch:SWI 2 "<r>")]
17018 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17019 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17020 [(set (match_dup 2) (match_dup 1))
17021 (set (match_dup 0) (match_dup 2))])
17022
17023 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17024 ;; SImode pushes.
17025 (define_peephole2
17026 [(set (match_operand:SF 0 "push_operand")
17027 (match_operand:SF 1 "memory_operand"))
17028 (match_scratch:SF 2 "r")]
17029 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17030 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17031 [(set (match_dup 2) (match_dup 1))
17032 (set (match_dup 0) (match_dup 2))])
17033
17034 ;; Don't move an immediate directly to memory when the instruction
17035 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17036 (define_peephole2
17037 [(match_scratch:SWI124 1 "<r>")
17038 (set (match_operand:SWI124 0 "memory_operand")
17039 (const_int 0))]
17040 "optimize_insn_for_speed_p ()
17041 && ((<MODE>mode == HImode
17042 && TARGET_LCP_STALL)
17043 || (!TARGET_USE_MOV0
17044 && TARGET_SPLIT_LONG_MOVES
17045 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17046 && peep2_regno_dead_p (0, FLAGS_REG)"
17047 [(parallel [(set (match_dup 2) (const_int 0))
17048 (clobber (reg:CC FLAGS_REG))])
17049 (set (match_dup 0) (match_dup 1))]
17050 "operands[2] = gen_lowpart (SImode, operands[1]);")
17051
17052 (define_peephole2
17053 [(match_scratch:SWI124 2 "<r>")
17054 (set (match_operand:SWI124 0 "memory_operand")
17055 (match_operand:SWI124 1 "immediate_operand"))]
17056 "optimize_insn_for_speed_p ()
17057 && ((<MODE>mode == HImode
17058 && TARGET_LCP_STALL)
17059 || (TARGET_SPLIT_LONG_MOVES
17060 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17061 [(set (match_dup 2) (match_dup 1))
17062 (set (match_dup 0) (match_dup 2))])
17063
17064 ;; Don't compare memory with zero, load and use a test instead.
17065 (define_peephole2
17066 [(set (match_operand 0 "flags_reg_operand")
17067 (match_operator 1 "compare_operator"
17068 [(match_operand:SI 2 "memory_operand")
17069 (const_int 0)]))
17070 (match_scratch:SI 3 "r")]
17071 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17072 [(set (match_dup 3) (match_dup 2))
17073 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17074
17075 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17076 ;; Don't split NOTs with a displacement operand, because resulting XOR
17077 ;; will not be pairable anyway.
17078 ;;
17079 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17080 ;; represented using a modRM byte. The XOR replacement is long decoded,
17081 ;; so this split helps here as well.
17082 ;;
17083 ;; Note: Can't do this as a regular split because we can't get proper
17084 ;; lifetime information then.
17085
17086 (define_peephole2
17087 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17088 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17089 "optimize_insn_for_speed_p ()
17090 && ((TARGET_NOT_UNPAIRABLE
17091 && (!MEM_P (operands[0])
17092 || !memory_displacement_operand (operands[0], <MODE>mode)))
17093 || (TARGET_NOT_VECTORMODE
17094 && long_memory_operand (operands[0], <MODE>mode)))
17095 && peep2_regno_dead_p (0, FLAGS_REG)"
17096 [(parallel [(set (match_dup 0)
17097 (xor:SWI124 (match_dup 1) (const_int -1)))
17098 (clobber (reg:CC FLAGS_REG))])])
17099
17100 ;; Non pairable "test imm, reg" instructions can be translated to
17101 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17102 ;; byte opcode instead of two, have a short form for byte operands),
17103 ;; so do it for other CPUs as well. Given that the value was dead,
17104 ;; this should not create any new dependencies. Pass on the sub-word
17105 ;; versions if we're concerned about partial register stalls.
17106
17107 (define_peephole2
17108 [(set (match_operand 0 "flags_reg_operand")
17109 (match_operator 1 "compare_operator"
17110 [(and:SI (match_operand:SI 2 "register_operand")
17111 (match_operand:SI 3 "immediate_operand"))
17112 (const_int 0)]))]
17113 "ix86_match_ccmode (insn, CCNOmode)
17114 && (true_regnum (operands[2]) != AX_REG
17115 || satisfies_constraint_K (operands[3]))
17116 && peep2_reg_dead_p (1, operands[2])"
17117 [(parallel
17118 [(set (match_dup 0)
17119 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17120 (const_int 0)]))
17121 (set (match_dup 2)
17122 (and:SI (match_dup 2) (match_dup 3)))])])
17123
17124 ;; We don't need to handle HImode case, because it will be promoted to SImode
17125 ;; on ! TARGET_PARTIAL_REG_STALL
17126
17127 (define_peephole2
17128 [(set (match_operand 0 "flags_reg_operand")
17129 (match_operator 1 "compare_operator"
17130 [(and:QI (match_operand:QI 2 "register_operand")
17131 (match_operand:QI 3 "immediate_operand"))
17132 (const_int 0)]))]
17133 "! TARGET_PARTIAL_REG_STALL
17134 && ix86_match_ccmode (insn, CCNOmode)
17135 && true_regnum (operands[2]) != AX_REG
17136 && peep2_reg_dead_p (1, operands[2])"
17137 [(parallel
17138 [(set (match_dup 0)
17139 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17140 (const_int 0)]))
17141 (set (match_dup 2)
17142 (and:QI (match_dup 2) (match_dup 3)))])])
17143
17144 (define_peephole2
17145 [(set (match_operand 0 "flags_reg_operand")
17146 (match_operator 1 "compare_operator"
17147 [(and:SI
17148 (zero_extract:SI
17149 (match_operand 2 "ext_register_operand")
17150 (const_int 8)
17151 (const_int 8))
17152 (match_operand 3 "const_int_operand"))
17153 (const_int 0)]))]
17154 "! TARGET_PARTIAL_REG_STALL
17155 && ix86_match_ccmode (insn, CCNOmode)
17156 && true_regnum (operands[2]) != AX_REG
17157 && peep2_reg_dead_p (1, operands[2])"
17158 [(parallel [(set (match_dup 0)
17159 (match_op_dup 1
17160 [(and:SI
17161 (zero_extract:SI
17162 (match_dup 2)
17163 (const_int 8)
17164 (const_int 8))
17165 (match_dup 3))
17166 (const_int 0)]))
17167 (set (zero_extract:SI (match_dup 2)
17168 (const_int 8)
17169 (const_int 8))
17170 (and:SI
17171 (zero_extract:SI
17172 (match_dup 2)
17173 (const_int 8)
17174 (const_int 8))
17175 (match_dup 3)))])])
17176
17177 ;; Don't do logical operations with memory inputs.
17178 (define_peephole2
17179 [(match_scratch:SI 2 "r")
17180 (parallel [(set (match_operand:SI 0 "register_operand")
17181 (match_operator:SI 3 "arith_or_logical_operator"
17182 [(match_dup 0)
17183 (match_operand:SI 1 "memory_operand")]))
17184 (clobber (reg:CC FLAGS_REG))])]
17185 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17186 [(set (match_dup 2) (match_dup 1))
17187 (parallel [(set (match_dup 0)
17188 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17189 (clobber (reg:CC FLAGS_REG))])])
17190
17191 (define_peephole2
17192 [(match_scratch:SI 2 "r")
17193 (parallel [(set (match_operand:SI 0 "register_operand")
17194 (match_operator:SI 3 "arith_or_logical_operator"
17195 [(match_operand:SI 1 "memory_operand")
17196 (match_dup 0)]))
17197 (clobber (reg:CC FLAGS_REG))])]
17198 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17199 [(set (match_dup 2) (match_dup 1))
17200 (parallel [(set (match_dup 0)
17201 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17202 (clobber (reg:CC FLAGS_REG))])])
17203
17204 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17205 ;; refers to the destination of the load!
17206
17207 (define_peephole2
17208 [(set (match_operand:SI 0 "register_operand")
17209 (match_operand:SI 1 "register_operand"))
17210 (parallel [(set (match_dup 0)
17211 (match_operator:SI 3 "commutative_operator"
17212 [(match_dup 0)
17213 (match_operand:SI 2 "memory_operand")]))
17214 (clobber (reg:CC FLAGS_REG))])]
17215 "REGNO (operands[0]) != REGNO (operands[1])
17216 && GENERAL_REGNO_P (REGNO (operands[0]))
17217 && GENERAL_REGNO_P (REGNO (operands[1]))"
17218 [(set (match_dup 0) (match_dup 4))
17219 (parallel [(set (match_dup 0)
17220 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17221 (clobber (reg:CC FLAGS_REG))])]
17222 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17223
17224 (define_peephole2
17225 [(set (match_operand 0 "register_operand")
17226 (match_operand 1 "register_operand"))
17227 (set (match_dup 0)
17228 (match_operator 3 "commutative_operator"
17229 [(match_dup 0)
17230 (match_operand 2 "memory_operand")]))]
17231 "REGNO (operands[0]) != REGNO (operands[1])
17232 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17233 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17234 [(set (match_dup 0) (match_dup 2))
17235 (set (match_dup 0)
17236 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17237
17238 ; Don't do logical operations with memory outputs
17239 ;
17240 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17241 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17242 ; the same decoder scheduling characteristics as the original.
17243
17244 (define_peephole2
17245 [(match_scratch:SI 2 "r")
17246 (parallel [(set (match_operand:SI 0 "memory_operand")
17247 (match_operator:SI 3 "arith_or_logical_operator"
17248 [(match_dup 0)
17249 (match_operand:SI 1 "nonmemory_operand")]))
17250 (clobber (reg:CC FLAGS_REG))])]
17251 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17252 /* Do not split stack checking probes. */
17253 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17254 [(set (match_dup 2) (match_dup 0))
17255 (parallel [(set (match_dup 2)
17256 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17257 (clobber (reg:CC FLAGS_REG))])
17258 (set (match_dup 0) (match_dup 2))])
17259
17260 (define_peephole2
17261 [(match_scratch:SI 2 "r")
17262 (parallel [(set (match_operand:SI 0 "memory_operand")
17263 (match_operator:SI 3 "arith_or_logical_operator"
17264 [(match_operand:SI 1 "nonmemory_operand")
17265 (match_dup 0)]))
17266 (clobber (reg:CC FLAGS_REG))])]
17267 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17268 /* Do not split stack checking probes. */
17269 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17270 [(set (match_dup 2) (match_dup 0))
17271 (parallel [(set (match_dup 2)
17272 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17273 (clobber (reg:CC FLAGS_REG))])
17274 (set (match_dup 0) (match_dup 2))])
17275
17276 ;; Attempt to use arith or logical operations with memory outputs with
17277 ;; setting of flags.
17278 (define_peephole2
17279 [(set (match_operand:SWI 0 "register_operand")
17280 (match_operand:SWI 1 "memory_operand"))
17281 (parallel [(set (match_dup 0)
17282 (match_operator:SWI 3 "plusminuslogic_operator"
17283 [(match_dup 0)
17284 (match_operand:SWI 2 "<nonmemory_operand>")]))
17285 (clobber (reg:CC FLAGS_REG))])
17286 (set (match_dup 1) (match_dup 0))
17287 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17288 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17289 && peep2_reg_dead_p (4, operands[0])
17290 && !reg_overlap_mentioned_p (operands[0], operands[1])
17291 && !reg_overlap_mentioned_p (operands[0], operands[2])
17292 && (<MODE>mode != QImode
17293 || immediate_operand (operands[2], QImode)
17294 || q_regs_operand (operands[2], QImode))
17295 && ix86_match_ccmode (peep2_next_insn (3),
17296 (GET_CODE (operands[3]) == PLUS
17297 || GET_CODE (operands[3]) == MINUS)
17298 ? CCGOCmode : CCNOmode)"
17299 [(parallel [(set (match_dup 4) (match_dup 5))
17300 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17301 (match_dup 2)]))])]
17302 {
17303 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17304 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17305 copy_rtx (operands[1]),
17306 copy_rtx (operands[2]));
17307 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17308 operands[5], const0_rtx);
17309 })
17310
17311 (define_peephole2
17312 [(parallel [(set (match_operand:SWI 0 "register_operand")
17313 (match_operator:SWI 2 "plusminuslogic_operator"
17314 [(match_dup 0)
17315 (match_operand:SWI 1 "memory_operand")]))
17316 (clobber (reg:CC FLAGS_REG))])
17317 (set (match_dup 1) (match_dup 0))
17318 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17319 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17320 && GET_CODE (operands[2]) != MINUS
17321 && peep2_reg_dead_p (3, operands[0])
17322 && !reg_overlap_mentioned_p (operands[0], operands[1])
17323 && ix86_match_ccmode (peep2_next_insn (2),
17324 GET_CODE (operands[2]) == PLUS
17325 ? CCGOCmode : CCNOmode)"
17326 [(parallel [(set (match_dup 3) (match_dup 4))
17327 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17328 (match_dup 0)]))])]
17329 {
17330 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17331 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17332 copy_rtx (operands[1]),
17333 copy_rtx (operands[0]));
17334 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17335 operands[4], const0_rtx);
17336 })
17337
17338 (define_peephole2
17339 [(set (match_operand:SWI12 0 "register_operand")
17340 (match_operand:SWI12 1 "memory_operand"))
17341 (parallel [(set (match_operand:SI 4 "register_operand")
17342 (match_operator:SI 3 "plusminuslogic_operator"
17343 [(match_dup 4)
17344 (match_operand:SI 2 "nonmemory_operand")]))
17345 (clobber (reg:CC FLAGS_REG))])
17346 (set (match_dup 1) (match_dup 0))
17347 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17348 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17349 && REG_P (operands[0]) && REG_P (operands[4])
17350 && REGNO (operands[0]) == REGNO (operands[4])
17351 && peep2_reg_dead_p (4, operands[0])
17352 && (<MODE>mode != QImode
17353 || immediate_operand (operands[2], SImode)
17354 || q_regs_operand (operands[2], SImode))
17355 && !reg_overlap_mentioned_p (operands[0], operands[1])
17356 && !reg_overlap_mentioned_p (operands[0], operands[2])
17357 && ix86_match_ccmode (peep2_next_insn (3),
17358 (GET_CODE (operands[3]) == PLUS
17359 || GET_CODE (operands[3]) == MINUS)
17360 ? CCGOCmode : CCNOmode)"
17361 [(parallel [(set (match_dup 4) (match_dup 5))
17362 (set (match_dup 1) (match_dup 6))])]
17363 {
17364 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17365 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17366 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17367 copy_rtx (operands[1]), operands[2]);
17368 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17369 operands[5], const0_rtx);
17370 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17371 copy_rtx (operands[1]),
17372 copy_rtx (operands[2]));
17373 })
17374
17375 ;; Attempt to always use XOR for zeroing registers.
17376 (define_peephole2
17377 [(set (match_operand 0 "register_operand")
17378 (match_operand 1 "const0_operand"))]
17379 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17380 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17381 && GENERAL_REG_P (operands[0])
17382 && peep2_regno_dead_p (0, FLAGS_REG)"
17383 [(parallel [(set (match_dup 0) (const_int 0))
17384 (clobber (reg:CC FLAGS_REG))])]
17385 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17386
17387 (define_peephole2
17388 [(set (strict_low_part (match_operand 0 "register_operand"))
17389 (const_int 0))]
17390 "(GET_MODE (operands[0]) == QImode
17391 || GET_MODE (operands[0]) == HImode)
17392 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17393 && peep2_regno_dead_p (0, FLAGS_REG)"
17394 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17395 (clobber (reg:CC FLAGS_REG))])])
17396
17397 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17398 (define_peephole2
17399 [(set (match_operand:SWI248 0 "register_operand")
17400 (const_int -1))]
17401 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17402 && peep2_regno_dead_p (0, FLAGS_REG)"
17403 [(parallel [(set (match_dup 0) (const_int -1))
17404 (clobber (reg:CC FLAGS_REG))])]
17405 {
17406 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17407 operands[0] = gen_lowpart (SImode, operands[0]);
17408 })
17409
17410 ;; Attempt to convert simple lea to add/shift.
17411 ;; These can be created by move expanders.
17412 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17413 ;; relevant lea instructions were already split.
17414
17415 (define_peephole2
17416 [(set (match_operand:SWI48 0 "register_operand")
17417 (plus:SWI48 (match_dup 0)
17418 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17419 "!TARGET_OPT_AGU
17420 && peep2_regno_dead_p (0, FLAGS_REG)"
17421 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17422 (clobber (reg:CC FLAGS_REG))])])
17423
17424 (define_peephole2
17425 [(set (match_operand:SWI48 0 "register_operand")
17426 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17427 (match_dup 0)))]
17428 "!TARGET_OPT_AGU
17429 && peep2_regno_dead_p (0, FLAGS_REG)"
17430 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17431 (clobber (reg:CC FLAGS_REG))])])
17432
17433 (define_peephole2
17434 [(set (match_operand:DI 0 "register_operand")
17435 (zero_extend:DI
17436 (plus:SI (match_operand:SI 1 "register_operand")
17437 (match_operand:SI 2 "nonmemory_operand"))))]
17438 "TARGET_64BIT && !TARGET_OPT_AGU
17439 && REGNO (operands[0]) == REGNO (operands[1])
17440 && peep2_regno_dead_p (0, FLAGS_REG)"
17441 [(parallel [(set (match_dup 0)
17442 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17443 (clobber (reg:CC FLAGS_REG))])])
17444
17445 (define_peephole2
17446 [(set (match_operand:DI 0 "register_operand")
17447 (zero_extend:DI
17448 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17449 (match_operand:SI 2 "register_operand"))))]
17450 "TARGET_64BIT && !TARGET_OPT_AGU
17451 && REGNO (operands[0]) == REGNO (operands[2])
17452 && peep2_regno_dead_p (0, FLAGS_REG)"
17453 [(parallel [(set (match_dup 0)
17454 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17455 (clobber (reg:CC FLAGS_REG))])])
17456
17457 (define_peephole2
17458 [(set (match_operand:SWI48 0 "register_operand")
17459 (mult:SWI48 (match_dup 0)
17460 (match_operand:SWI48 1 "const_int_operand")))]
17461 "exact_log2 (INTVAL (operands[1])) >= 0
17462 && peep2_regno_dead_p (0, FLAGS_REG)"
17463 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17464 (clobber (reg:CC FLAGS_REG))])]
17465 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17466
17467 (define_peephole2
17468 [(set (match_operand:DI 0 "register_operand")
17469 (zero_extend:DI
17470 (mult:SI (match_operand:SI 1 "register_operand")
17471 (match_operand:SI 2 "const_int_operand"))))]
17472 "TARGET_64BIT
17473 && exact_log2 (INTVAL (operands[2])) >= 0
17474 && REGNO (operands[0]) == REGNO (operands[1])
17475 && peep2_regno_dead_p (0, FLAGS_REG)"
17476 [(parallel [(set (match_dup 0)
17477 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17478 (clobber (reg:CC FLAGS_REG))])]
17479 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17480
17481 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17482 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17483 ;; On many CPUs it is also faster, since special hardware to avoid esp
17484 ;; dependencies is present.
17485
17486 ;; While some of these conversions may be done using splitters, we use
17487 ;; peepholes in order to allow combine_stack_adjustments pass to see
17488 ;; nonobfuscated RTL.
17489
17490 ;; Convert prologue esp subtractions to push.
17491 ;; We need register to push. In order to keep verify_flow_info happy we have
17492 ;; two choices
17493 ;; - use scratch and clobber it in order to avoid dependencies
17494 ;; - use already live register
17495 ;; We can't use the second way right now, since there is no reliable way how to
17496 ;; verify that given register is live. First choice will also most likely in
17497 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17498 ;; call clobbered registers are dead. We may want to use base pointer as an
17499 ;; alternative when no register is available later.
17500
17501 (define_peephole2
17502 [(match_scratch:W 1 "r")
17503 (parallel [(set (reg:P SP_REG)
17504 (plus:P (reg:P SP_REG)
17505 (match_operand:P 0 "const_int_operand")))
17506 (clobber (reg:CC FLAGS_REG))
17507 (clobber (mem:BLK (scratch)))])]
17508 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17509 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17510 [(clobber (match_dup 1))
17511 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17512 (clobber (mem:BLK (scratch)))])])
17513
17514 (define_peephole2
17515 [(match_scratch:W 1 "r")
17516 (parallel [(set (reg:P SP_REG)
17517 (plus:P (reg:P SP_REG)
17518 (match_operand:P 0 "const_int_operand")))
17519 (clobber (reg:CC FLAGS_REG))
17520 (clobber (mem:BLK (scratch)))])]
17521 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17522 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17523 [(clobber (match_dup 1))
17524 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17525 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17526 (clobber (mem:BLK (scratch)))])])
17527
17528 ;; Convert esp subtractions to push.
17529 (define_peephole2
17530 [(match_scratch:W 1 "r")
17531 (parallel [(set (reg:P SP_REG)
17532 (plus:P (reg:P SP_REG)
17533 (match_operand:P 0 "const_int_operand")))
17534 (clobber (reg:CC FLAGS_REG))])]
17535 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17536 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17537 [(clobber (match_dup 1))
17538 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17539
17540 (define_peephole2
17541 [(match_scratch:W 1 "r")
17542 (parallel [(set (reg:P SP_REG)
17543 (plus:P (reg:P SP_REG)
17544 (match_operand:P 0 "const_int_operand")))
17545 (clobber (reg:CC FLAGS_REG))])]
17546 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17547 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17548 [(clobber (match_dup 1))
17549 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17550 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17551
17552 ;; Convert epilogue deallocator to pop.
17553 (define_peephole2
17554 [(match_scratch:W 1 "r")
17555 (parallel [(set (reg:P SP_REG)
17556 (plus:P (reg:P SP_REG)
17557 (match_operand:P 0 "const_int_operand")))
17558 (clobber (reg:CC FLAGS_REG))
17559 (clobber (mem:BLK (scratch)))])]
17560 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17561 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17562 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17563 (clobber (mem:BLK (scratch)))])])
17564
17565 ;; Two pops case is tricky, since pop causes dependency
17566 ;; on destination register. We use two registers if available.
17567 (define_peephole2
17568 [(match_scratch:W 1 "r")
17569 (match_scratch:W 2 "r")
17570 (parallel [(set (reg:P SP_REG)
17571 (plus:P (reg:P SP_REG)
17572 (match_operand:P 0 "const_int_operand")))
17573 (clobber (reg:CC FLAGS_REG))
17574 (clobber (mem:BLK (scratch)))])]
17575 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17576 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17577 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17578 (clobber (mem:BLK (scratch)))])
17579 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17580
17581 (define_peephole2
17582 [(match_scratch:W 1 "r")
17583 (parallel [(set (reg:P SP_REG)
17584 (plus:P (reg:P SP_REG)
17585 (match_operand:P 0 "const_int_operand")))
17586 (clobber (reg:CC FLAGS_REG))
17587 (clobber (mem:BLK (scratch)))])]
17588 "optimize_insn_for_size_p ()
17589 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17590 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17591 (clobber (mem:BLK (scratch)))])
17592 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17593
17594 ;; Convert esp additions to pop.
17595 (define_peephole2
17596 [(match_scratch:W 1 "r")
17597 (parallel [(set (reg:P SP_REG)
17598 (plus:P (reg:P SP_REG)
17599 (match_operand:P 0 "const_int_operand")))
17600 (clobber (reg:CC FLAGS_REG))])]
17601 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17602 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17603
17604 ;; Two pops case is tricky, since pop causes dependency
17605 ;; on destination register. We use two registers if available.
17606 (define_peephole2
17607 [(match_scratch:W 1 "r")
17608 (match_scratch:W 2 "r")
17609 (parallel [(set (reg:P SP_REG)
17610 (plus:P (reg:P SP_REG)
17611 (match_operand:P 0 "const_int_operand")))
17612 (clobber (reg:CC FLAGS_REG))])]
17613 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17614 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17615 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17616
17617 (define_peephole2
17618 [(match_scratch:W 1 "r")
17619 (parallel [(set (reg:P SP_REG)
17620 (plus:P (reg:P SP_REG)
17621 (match_operand:P 0 "const_int_operand")))
17622 (clobber (reg:CC FLAGS_REG))])]
17623 "optimize_insn_for_size_p ()
17624 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17625 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17626 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17627 \f
17628 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17629 ;; required and register dies. Similarly for 128 to -128.
17630 (define_peephole2
17631 [(set (match_operand 0 "flags_reg_operand")
17632 (match_operator 1 "compare_operator"
17633 [(match_operand 2 "register_operand")
17634 (match_operand 3 "const_int_operand")]))]
17635 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17636 && incdec_operand (operands[3], GET_MODE (operands[3])))
17637 || (!TARGET_FUSE_CMP_AND_BRANCH
17638 && INTVAL (operands[3]) == 128))
17639 && ix86_match_ccmode (insn, CCGCmode)
17640 && peep2_reg_dead_p (1, operands[2])"
17641 [(parallel [(set (match_dup 0)
17642 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17643 (clobber (match_dup 2))])])
17644 \f
17645 ;; Convert imul by three, five and nine into lea
17646 (define_peephole2
17647 [(parallel
17648 [(set (match_operand:SWI48 0 "register_operand")
17649 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17650 (match_operand:SWI48 2 "const359_operand")))
17651 (clobber (reg:CC FLAGS_REG))])]
17652 "!TARGET_PARTIAL_REG_STALL
17653 || <MODE>mode == SImode
17654 || optimize_function_for_size_p (cfun)"
17655 [(set (match_dup 0)
17656 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17657 (match_dup 1)))]
17658 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17659
17660 (define_peephole2
17661 [(parallel
17662 [(set (match_operand:SWI48 0 "register_operand")
17663 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17664 (match_operand:SWI48 2 "const359_operand")))
17665 (clobber (reg:CC FLAGS_REG))])]
17666 "optimize_insn_for_speed_p ()
17667 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17668 [(set (match_dup 0) (match_dup 1))
17669 (set (match_dup 0)
17670 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17671 (match_dup 0)))]
17672 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17673
17674 ;; imul $32bit_imm, mem, reg is vector decoded, while
17675 ;; imul $32bit_imm, reg, reg is direct decoded.
17676 (define_peephole2
17677 [(match_scratch:SWI48 3 "r")
17678 (parallel [(set (match_operand:SWI48 0 "register_operand")
17679 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17680 (match_operand:SWI48 2 "immediate_operand")))
17681 (clobber (reg:CC FLAGS_REG))])]
17682 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17683 && !satisfies_constraint_K (operands[2])"
17684 [(set (match_dup 3) (match_dup 1))
17685 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17686 (clobber (reg:CC FLAGS_REG))])])
17687
17688 (define_peephole2
17689 [(match_scratch:SI 3 "r")
17690 (parallel [(set (match_operand:DI 0 "register_operand")
17691 (zero_extend:DI
17692 (mult:SI (match_operand:SI 1 "memory_operand")
17693 (match_operand:SI 2 "immediate_operand"))))
17694 (clobber (reg:CC FLAGS_REG))])]
17695 "TARGET_64BIT
17696 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17697 && !satisfies_constraint_K (operands[2])"
17698 [(set (match_dup 3) (match_dup 1))
17699 (parallel [(set (match_dup 0)
17700 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17701 (clobber (reg:CC FLAGS_REG))])])
17702
17703 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17704 ;; Convert it into imul reg, reg
17705 ;; It would be better to force assembler to encode instruction using long
17706 ;; immediate, but there is apparently no way to do so.
17707 (define_peephole2
17708 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17709 (mult:SWI248
17710 (match_operand:SWI248 1 "nonimmediate_operand")
17711 (match_operand:SWI248 2 "const_int_operand")))
17712 (clobber (reg:CC FLAGS_REG))])
17713 (match_scratch:SWI248 3 "r")]
17714 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17715 && satisfies_constraint_K (operands[2])"
17716 [(set (match_dup 3) (match_dup 2))
17717 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17718 (clobber (reg:CC FLAGS_REG))])]
17719 {
17720 if (!rtx_equal_p (operands[0], operands[1]))
17721 emit_move_insn (operands[0], operands[1]);
17722 })
17723
17724 ;; After splitting up read-modify operations, array accesses with memory
17725 ;; operands might end up in form:
17726 ;; sall $2, %eax
17727 ;; movl 4(%esp), %edx
17728 ;; addl %edx, %eax
17729 ;; instead of pre-splitting:
17730 ;; sall $2, %eax
17731 ;; addl 4(%esp), %eax
17732 ;; Turn it into:
17733 ;; movl 4(%esp), %edx
17734 ;; leal (%edx,%eax,4), %eax
17735
17736 (define_peephole2
17737 [(match_scratch:W 5 "r")
17738 (parallel [(set (match_operand 0 "register_operand")
17739 (ashift (match_operand 1 "register_operand")
17740 (match_operand 2 "const_int_operand")))
17741 (clobber (reg:CC FLAGS_REG))])
17742 (parallel [(set (match_operand 3 "register_operand")
17743 (plus (match_dup 0)
17744 (match_operand 4 "x86_64_general_operand")))
17745 (clobber (reg:CC FLAGS_REG))])]
17746 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17747 /* Validate MODE for lea. */
17748 && ((!TARGET_PARTIAL_REG_STALL
17749 && (GET_MODE (operands[0]) == QImode
17750 || GET_MODE (operands[0]) == HImode))
17751 || GET_MODE (operands[0]) == SImode
17752 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17753 && (rtx_equal_p (operands[0], operands[3])
17754 || peep2_reg_dead_p (2, operands[0]))
17755 /* We reorder load and the shift. */
17756 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17757 [(set (match_dup 5) (match_dup 4))
17758 (set (match_dup 0) (match_dup 1))]
17759 {
17760 enum machine_mode op1mode = GET_MODE (operands[1]);
17761 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17762 int scale = 1 << INTVAL (operands[2]);
17763 rtx index = gen_lowpart (word_mode, operands[1]);
17764 rtx base = gen_lowpart (word_mode, operands[5]);
17765 rtx dest = gen_lowpart (mode, operands[3]);
17766
17767 operands[1] = gen_rtx_PLUS (word_mode, base,
17768 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17769 operands[5] = base;
17770 if (mode != word_mode)
17771 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17772 if (op1mode != word_mode)
17773 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17774 operands[0] = dest;
17775 })
17776 \f
17777 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17778 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17779 ;; caught for use by garbage collectors and the like. Using an insn that
17780 ;; maps to SIGILL makes it more likely the program will rightfully die.
17781 ;; Keeping with tradition, "6" is in honor of #UD.
17782 (define_insn "trap"
17783 [(trap_if (const_int 1) (const_int 6))]
17784 ""
17785 { return ASM_SHORT "0x0b0f"; }
17786 [(set_attr "length" "2")])
17787
17788 (define_expand "prefetch"
17789 [(prefetch (match_operand 0 "address_operand")
17790 (match_operand:SI 1 "const_int_operand")
17791 (match_operand:SI 2 "const_int_operand"))]
17792 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_AVX512PF"
17793 {
17794 bool write = INTVAL (operands[1]) != 0;
17795 int locality = INTVAL (operands[2]);
17796
17797 gcc_assert (IN_RANGE (locality, 0, 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 if (TARGET_AVX512PF && write)
17804 operands[2] = const1_rtx;
17805 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17806 operands[2] = GEN_INT (3);
17807 else
17808 operands[1] = const0_rtx;
17809 })
17810
17811 (define_insn "*prefetch_sse"
17812 [(prefetch (match_operand 0 "address_operand" "p")
17813 (const_int 0)
17814 (match_operand:SI 1 "const_int_operand"))]
17815 "TARGET_PREFETCH_SSE"
17816 {
17817 static const char * const patterns[4] = {
17818 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17819 };
17820
17821 int locality = INTVAL (operands[1]);
17822 gcc_assert (IN_RANGE (locality, 0, 3));
17823
17824 return patterns[locality];
17825 }
17826 [(set_attr "type" "sse")
17827 (set_attr "atom_sse_attr" "prefetch")
17828 (set (attr "length_address")
17829 (symbol_ref "memory_address_length (operands[0], false)"))
17830 (set_attr "memory" "none")])
17831
17832 (define_insn "*prefetch_3dnow"
17833 [(prefetch (match_operand 0 "address_operand" "p")
17834 (match_operand:SI 1 "const_int_operand" "n")
17835 (const_int 3))]
17836 "TARGET_PRFCHW"
17837 {
17838 if (INTVAL (operands[1]) == 0)
17839 return "prefetch\t%a0";
17840 else
17841 return "prefetchw\t%a0";
17842 }
17843 [(set_attr "type" "mmx")
17844 (set (attr "length_address")
17845 (symbol_ref "memory_address_length (operands[0], false)"))
17846 (set_attr "memory" "none")])
17847
17848 (define_insn "*prefetch_avx512pf_<mode>"
17849 [(prefetch (match_operand:P 0 "address_operand" "p")
17850 (const_int 1)
17851 (const_int 1))]
17852 "TARGET_AVX512PF"
17853 "prefetchwt1\t%a0";
17854 [(set_attr "type" "sse")
17855 (set_attr "prefix" "evex")
17856 (set (attr "length_address")
17857 (symbol_ref "memory_address_length (operands[0], false)"))
17858 (set_attr "memory" "none")])
17859
17860 (define_expand "stack_protect_set"
17861 [(match_operand 0 "memory_operand")
17862 (match_operand 1 "memory_operand")]
17863 "TARGET_SSP_TLS_GUARD"
17864 {
17865 rtx (*insn)(rtx, rtx);
17866
17867 #ifdef TARGET_THREAD_SSP_OFFSET
17868 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17869 insn = (TARGET_LP64
17870 ? gen_stack_tls_protect_set_di
17871 : gen_stack_tls_protect_set_si);
17872 #else
17873 insn = (TARGET_LP64
17874 ? gen_stack_protect_set_di
17875 : gen_stack_protect_set_si);
17876 #endif
17877
17878 emit_insn (insn (operands[0], operands[1]));
17879 DONE;
17880 })
17881
17882 (define_insn "stack_protect_set_<mode>"
17883 [(set (match_operand:PTR 0 "memory_operand" "=m")
17884 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17885 UNSPEC_SP_SET))
17886 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17887 (clobber (reg:CC FLAGS_REG))]
17888 "TARGET_SSP_TLS_GUARD"
17889 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17890 [(set_attr "type" "multi")])
17891
17892 (define_insn "stack_tls_protect_set_<mode>"
17893 [(set (match_operand:PTR 0 "memory_operand" "=m")
17894 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17895 UNSPEC_SP_TLS_SET))
17896 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17897 (clobber (reg:CC FLAGS_REG))]
17898 ""
17899 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17900 [(set_attr "type" "multi")])
17901
17902 (define_expand "stack_protect_test"
17903 [(match_operand 0 "memory_operand")
17904 (match_operand 1 "memory_operand")
17905 (match_operand 2)]
17906 "TARGET_SSP_TLS_GUARD"
17907 {
17908 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17909
17910 rtx (*insn)(rtx, rtx, rtx);
17911
17912 #ifdef TARGET_THREAD_SSP_OFFSET
17913 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17914 insn = (TARGET_LP64
17915 ? gen_stack_tls_protect_test_di
17916 : gen_stack_tls_protect_test_si);
17917 #else
17918 insn = (TARGET_LP64
17919 ? gen_stack_protect_test_di
17920 : gen_stack_protect_test_si);
17921 #endif
17922
17923 emit_insn (insn (flags, operands[0], operands[1]));
17924
17925 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17926 flags, const0_rtx, operands[2]));
17927 DONE;
17928 })
17929
17930 (define_insn "stack_protect_test_<mode>"
17931 [(set (match_operand:CCZ 0 "flags_reg_operand")
17932 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17933 (match_operand:PTR 2 "memory_operand" "m")]
17934 UNSPEC_SP_TEST))
17935 (clobber (match_scratch:PTR 3 "=&r"))]
17936 "TARGET_SSP_TLS_GUARD"
17937 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17938 [(set_attr "type" "multi")])
17939
17940 (define_insn "stack_tls_protect_test_<mode>"
17941 [(set (match_operand:CCZ 0 "flags_reg_operand")
17942 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17943 (match_operand:PTR 2 "const_int_operand" "i")]
17944 UNSPEC_SP_TLS_TEST))
17945 (clobber (match_scratch:PTR 3 "=r"))]
17946 ""
17947 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17948 [(set_attr "type" "multi")])
17949
17950 (define_insn "sse4_2_crc32<mode>"
17951 [(set (match_operand:SI 0 "register_operand" "=r")
17952 (unspec:SI
17953 [(match_operand:SI 1 "register_operand" "0")
17954 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17955 UNSPEC_CRC32))]
17956 "TARGET_SSE4_2 || TARGET_CRC32"
17957 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17958 [(set_attr "type" "sselog1")
17959 (set_attr "prefix_rep" "1")
17960 (set_attr "prefix_extra" "1")
17961 (set (attr "prefix_data16")
17962 (if_then_else (match_operand:HI 2)
17963 (const_string "1")
17964 (const_string "*")))
17965 (set (attr "prefix_rex")
17966 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17967 (const_string "1")
17968 (const_string "*")))
17969 (set_attr "mode" "SI")])
17970
17971 (define_insn "sse4_2_crc32di"
17972 [(set (match_operand:DI 0 "register_operand" "=r")
17973 (unspec:DI
17974 [(match_operand:DI 1 "register_operand" "0")
17975 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17976 UNSPEC_CRC32))]
17977 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17978 "crc32{q}\t{%2, %0|%0, %2}"
17979 [(set_attr "type" "sselog1")
17980 (set_attr "prefix_rep" "1")
17981 (set_attr "prefix_extra" "1")
17982 (set_attr "mode" "DI")])
17983
17984 (define_insn "rdpmc"
17985 [(set (match_operand:DI 0 "register_operand" "=A")
17986 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17987 UNSPECV_RDPMC))]
17988 "!TARGET_64BIT"
17989 "rdpmc"
17990 [(set_attr "type" "other")
17991 (set_attr "length" "2")])
17992
17993 (define_insn "rdpmc_rex64"
17994 [(set (match_operand:DI 0 "register_operand" "=a")
17995 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17996 UNSPECV_RDPMC))
17997 (set (match_operand:DI 1 "register_operand" "=d")
17998 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17999 "TARGET_64BIT"
18000 "rdpmc"
18001 [(set_attr "type" "other")
18002 (set_attr "length" "2")])
18003
18004 (define_insn "rdtsc"
18005 [(set (match_operand:DI 0 "register_operand" "=A")
18006 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18007 "!TARGET_64BIT"
18008 "rdtsc"
18009 [(set_attr "type" "other")
18010 (set_attr "length" "2")])
18011
18012 (define_insn "rdtsc_rex64"
18013 [(set (match_operand:DI 0 "register_operand" "=a")
18014 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18015 (set (match_operand:DI 1 "register_operand" "=d")
18016 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18017 "TARGET_64BIT"
18018 "rdtsc"
18019 [(set_attr "type" "other")
18020 (set_attr "length" "2")])
18021
18022 (define_insn "rdtscp"
18023 [(set (match_operand:DI 0 "register_operand" "=A")
18024 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18025 (set (match_operand:SI 1 "register_operand" "=c")
18026 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18027 "!TARGET_64BIT"
18028 "rdtscp"
18029 [(set_attr "type" "other")
18030 (set_attr "length" "3")])
18031
18032 (define_insn "rdtscp_rex64"
18033 [(set (match_operand:DI 0 "register_operand" "=a")
18034 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18035 (set (match_operand:DI 1 "register_operand" "=d")
18036 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18037 (set (match_operand:SI 2 "register_operand" "=c")
18038 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18039 "TARGET_64BIT"
18040 "rdtscp"
18041 [(set_attr "type" "other")
18042 (set_attr "length" "3")])
18043
18044 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18045 ;;
18046 ;; FXSR, XSAVE and XSAVEOPT instructions
18047 ;;
18048 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18049
18050 (define_insn "fxsave"
18051 [(set (match_operand:BLK 0 "memory_operand" "=m")
18052 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18053 "TARGET_FXSR"
18054 "fxsave\t%0"
18055 [(set_attr "type" "other")
18056 (set_attr "memory" "store")
18057 (set (attr "length")
18058 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18059
18060 (define_insn "fxsave64"
18061 [(set (match_operand:BLK 0 "memory_operand" "=m")
18062 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18063 "TARGET_64BIT && TARGET_FXSR"
18064 "fxsave64\t%0"
18065 [(set_attr "type" "other")
18066 (set_attr "memory" "store")
18067 (set (attr "length")
18068 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18069
18070 (define_insn "fxrstor"
18071 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18072 UNSPECV_FXRSTOR)]
18073 "TARGET_FXSR"
18074 "fxrstor\t%0"
18075 [(set_attr "type" "other")
18076 (set_attr "memory" "load")
18077 (set (attr "length")
18078 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18079
18080 (define_insn "fxrstor64"
18081 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18082 UNSPECV_FXRSTOR64)]
18083 "TARGET_64BIT && TARGET_FXSR"
18084 "fxrstor64\t%0"
18085 [(set_attr "type" "other")
18086 (set_attr "memory" "load")
18087 (set (attr "length")
18088 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18089
18090 (define_int_iterator ANY_XSAVE
18091 [UNSPECV_XSAVE
18092 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
18093
18094 (define_int_iterator ANY_XSAVE64
18095 [UNSPECV_XSAVE64
18096 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
18097
18098 (define_int_attr xsave
18099 [(UNSPECV_XSAVE "xsave")
18100 (UNSPECV_XSAVE64 "xsave64")
18101 (UNSPECV_XSAVEOPT "xsaveopt")
18102 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
18103
18104 (define_insn "<xsave>"
18105 [(set (match_operand:BLK 0 "memory_operand" "=m")
18106 (unspec_volatile:BLK
18107 [(match_operand:DI 1 "register_operand" "A")]
18108 ANY_XSAVE))]
18109 "!TARGET_64BIT && TARGET_XSAVE"
18110 "<xsave>\t%0"
18111 [(set_attr "type" "other")
18112 (set_attr "memory" "store")
18113 (set (attr "length")
18114 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18115
18116 (define_insn "<xsave>_rex64"
18117 [(set (match_operand:BLK 0 "memory_operand" "=m")
18118 (unspec_volatile:BLK
18119 [(match_operand:SI 1 "register_operand" "a")
18120 (match_operand:SI 2 "register_operand" "d")]
18121 ANY_XSAVE))]
18122 "TARGET_64BIT && TARGET_XSAVE"
18123 "<xsave>\t%0"
18124 [(set_attr "type" "other")
18125 (set_attr "memory" "store")
18126 (set (attr "length")
18127 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18128
18129 (define_insn "<xsave>"
18130 [(set (match_operand:BLK 0 "memory_operand" "=m")
18131 (unspec_volatile:BLK
18132 [(match_operand:SI 1 "register_operand" "a")
18133 (match_operand:SI 2 "register_operand" "d")]
18134 ANY_XSAVE64))]
18135 "TARGET_64BIT && TARGET_XSAVE"
18136 "<xsave>\t%0"
18137 [(set_attr "type" "other")
18138 (set_attr "memory" "store")
18139 (set (attr "length")
18140 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18141
18142 (define_insn "xrstor"
18143 [(unspec_volatile:BLK
18144 [(match_operand:BLK 0 "memory_operand" "m")
18145 (match_operand:DI 1 "register_operand" "A")]
18146 UNSPECV_XRSTOR)]
18147 "!TARGET_64BIT && TARGET_XSAVE"
18148 "xrstor\t%0"
18149 [(set_attr "type" "other")
18150 (set_attr "memory" "load")
18151 (set (attr "length")
18152 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18153
18154 (define_insn "xrstor_rex64"
18155 [(unspec_volatile:BLK
18156 [(match_operand:BLK 0 "memory_operand" "m")
18157 (match_operand:SI 1 "register_operand" "a")
18158 (match_operand:SI 2 "register_operand" "d")]
18159 UNSPECV_XRSTOR)]
18160 "TARGET_64BIT && TARGET_XSAVE"
18161 "xrstor\t%0"
18162 [(set_attr "type" "other")
18163 (set_attr "memory" "load")
18164 (set (attr "length")
18165 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18166
18167 (define_insn "xrstor64"
18168 [(unspec_volatile:BLK
18169 [(match_operand:BLK 0 "memory_operand" "m")
18170 (match_operand:SI 1 "register_operand" "a")
18171 (match_operand:SI 2 "register_operand" "d")]
18172 UNSPECV_XRSTOR64)]
18173 "TARGET_64BIT && TARGET_XSAVE"
18174 "xrstor64\t%0"
18175 [(set_attr "type" "other")
18176 (set_attr "memory" "load")
18177 (set (attr "length")
18178 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18179
18180 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18181 ;;
18182 ;; Floating-point instructions for atomic compound assignments
18183 ;;
18184 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18185
18186 ; Clobber all floating-point registers on environment save and restore
18187 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18188 (define_insn "fnstenv"
18189 [(set (match_operand:BLK 0 "memory_operand" "=m")
18190 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18191 (clobber (reg:HI FPCR_REG))
18192 (clobber (reg:XF ST0_REG))
18193 (clobber (reg:XF ST1_REG))
18194 (clobber (reg:XF ST2_REG))
18195 (clobber (reg:XF ST3_REG))
18196 (clobber (reg:XF ST4_REG))
18197 (clobber (reg:XF ST5_REG))
18198 (clobber (reg:XF ST6_REG))
18199 (clobber (reg:XF ST7_REG))]
18200 "TARGET_80387"
18201 "fnstenv\t%0"
18202 [(set_attr "type" "other")
18203 (set_attr "memory" "store")
18204 (set (attr "length")
18205 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18206
18207 (define_insn "fldenv"
18208 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18209 UNSPECV_FLDENV)
18210 (clobber (reg:CCFP FPSR_REG))
18211 (clobber (reg:HI FPCR_REG))
18212 (clobber (reg:XF ST0_REG))
18213 (clobber (reg:XF ST1_REG))
18214 (clobber (reg:XF ST2_REG))
18215 (clobber (reg:XF ST3_REG))
18216 (clobber (reg:XF ST4_REG))
18217 (clobber (reg:XF ST5_REG))
18218 (clobber (reg:XF ST6_REG))
18219 (clobber (reg:XF ST7_REG))]
18220 "TARGET_80387"
18221 "fldenv\t%0"
18222 [(set_attr "type" "other")
18223 (set_attr "memory" "load")
18224 (set (attr "length")
18225 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18226
18227 (define_insn "fnstsw"
18228 [(set (match_operand:HI 0 "memory_operand" "=m")
18229 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18230 "TARGET_80387"
18231 "fnstsw\t%0"
18232 [(set_attr "type" "other")
18233 (set_attr "memory" "store")
18234 (set (attr "length")
18235 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18236
18237 (define_insn "fnclex"
18238 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18239 "TARGET_80387"
18240 "fnclex"
18241 [(set_attr "type" "other")
18242 (set_attr "memory" "none")
18243 (set_attr "length" "2")])
18244
18245 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18246 ;;
18247 ;; LWP instructions
18248 ;;
18249 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18250
18251 (define_expand "lwp_llwpcb"
18252 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18253 UNSPECV_LLWP_INTRINSIC)]
18254 "TARGET_LWP")
18255
18256 (define_insn "*lwp_llwpcb<mode>1"
18257 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18258 UNSPECV_LLWP_INTRINSIC)]
18259 "TARGET_LWP"
18260 "llwpcb\t%0"
18261 [(set_attr "type" "lwp")
18262 (set_attr "mode" "<MODE>")
18263 (set_attr "length" "5")])
18264
18265 (define_expand "lwp_slwpcb"
18266 [(set (match_operand 0 "register_operand" "=r")
18267 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18268 "TARGET_LWP"
18269 {
18270 rtx (*insn)(rtx);
18271
18272 insn = (Pmode == DImode
18273 ? gen_lwp_slwpcbdi
18274 : gen_lwp_slwpcbsi);
18275
18276 emit_insn (insn (operands[0]));
18277 DONE;
18278 })
18279
18280 (define_insn "lwp_slwpcb<mode>"
18281 [(set (match_operand:P 0 "register_operand" "=r")
18282 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18283 "TARGET_LWP"
18284 "slwpcb\t%0"
18285 [(set_attr "type" "lwp")
18286 (set_attr "mode" "<MODE>")
18287 (set_attr "length" "5")])
18288
18289 (define_expand "lwp_lwpval<mode>3"
18290 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18291 (match_operand:SI 2 "nonimmediate_operand" "rm")
18292 (match_operand:SI 3 "const_int_operand" "i")]
18293 UNSPECV_LWPVAL_INTRINSIC)]
18294 "TARGET_LWP"
18295 ;; Avoid unused variable warning.
18296 "(void) operands[0];")
18297
18298 (define_insn "*lwp_lwpval<mode>3_1"
18299 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18300 (match_operand:SI 1 "nonimmediate_operand" "rm")
18301 (match_operand:SI 2 "const_int_operand" "i")]
18302 UNSPECV_LWPVAL_INTRINSIC)]
18303 "TARGET_LWP"
18304 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18305 [(set_attr "type" "lwp")
18306 (set_attr "mode" "<MODE>")
18307 (set (attr "length")
18308 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18309
18310 (define_expand "lwp_lwpins<mode>3"
18311 [(set (reg:CCC FLAGS_REG)
18312 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18313 (match_operand:SI 2 "nonimmediate_operand" "rm")
18314 (match_operand:SI 3 "const_int_operand" "i")]
18315 UNSPECV_LWPINS_INTRINSIC))
18316 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18317 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18318 "TARGET_LWP")
18319
18320 (define_insn "*lwp_lwpins<mode>3_1"
18321 [(set (reg:CCC FLAGS_REG)
18322 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18323 (match_operand:SI 1 "nonimmediate_operand" "rm")
18324 (match_operand:SI 2 "const_int_operand" "i")]
18325 UNSPECV_LWPINS_INTRINSIC))]
18326 "TARGET_LWP"
18327 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18328 [(set_attr "type" "lwp")
18329 (set_attr "mode" "<MODE>")
18330 (set (attr "length")
18331 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18332
18333 (define_int_iterator RDFSGSBASE
18334 [UNSPECV_RDFSBASE
18335 UNSPECV_RDGSBASE])
18336
18337 (define_int_iterator WRFSGSBASE
18338 [UNSPECV_WRFSBASE
18339 UNSPECV_WRGSBASE])
18340
18341 (define_int_attr fsgs
18342 [(UNSPECV_RDFSBASE "fs")
18343 (UNSPECV_RDGSBASE "gs")
18344 (UNSPECV_WRFSBASE "fs")
18345 (UNSPECV_WRGSBASE "gs")])
18346
18347 (define_insn "rd<fsgs>base<mode>"
18348 [(set (match_operand:SWI48 0 "register_operand" "=r")
18349 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18350 "TARGET_64BIT && TARGET_FSGSBASE"
18351 "rd<fsgs>base\t%0"
18352 [(set_attr "type" "other")
18353 (set_attr "prefix_extra" "2")])
18354
18355 (define_insn "wr<fsgs>base<mode>"
18356 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18357 WRFSGSBASE)]
18358 "TARGET_64BIT && TARGET_FSGSBASE"
18359 "wr<fsgs>base\t%0"
18360 [(set_attr "type" "other")
18361 (set_attr "prefix_extra" "2")])
18362
18363 (define_insn "rdrand<mode>_1"
18364 [(set (match_operand:SWI248 0 "register_operand" "=r")
18365 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18366 (set (reg:CCC FLAGS_REG)
18367 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18368 "TARGET_RDRND"
18369 "rdrand\t%0"
18370 [(set_attr "type" "other")
18371 (set_attr "prefix_extra" "1")])
18372
18373 (define_insn "rdseed<mode>_1"
18374 [(set (match_operand:SWI248 0 "register_operand" "=r")
18375 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18376 (set (reg:CCC FLAGS_REG)
18377 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18378 "TARGET_RDSEED"
18379 "rdseed\t%0"
18380 [(set_attr "type" "other")
18381 (set_attr "prefix_extra" "1")])
18382
18383 (define_expand "pause"
18384 [(set (match_dup 0)
18385 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18386 ""
18387 {
18388 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18389 MEM_VOLATILE_P (operands[0]) = 1;
18390 })
18391
18392 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18393 ;; They have the same encoding.
18394 (define_insn "*pause"
18395 [(set (match_operand:BLK 0)
18396 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18397 ""
18398 "rep%; nop"
18399 [(set_attr "length" "2")
18400 (set_attr "memory" "unknown")])
18401
18402 (define_expand "xbegin"
18403 [(set (match_operand:SI 0 "register_operand")
18404 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18405 "TARGET_RTM"
18406 {
18407 rtx label = gen_label_rtx ();
18408
18409 /* xbegin is emitted as jump_insn, so reload won't be able
18410 to reload its operand. Force the value into AX hard register. */
18411 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18412 emit_move_insn (ax_reg, constm1_rtx);
18413
18414 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18415
18416 emit_label (label);
18417 LABEL_NUSES (label) = 1;
18418
18419 emit_move_insn (operands[0], ax_reg);
18420
18421 DONE;
18422 })
18423
18424 (define_insn "xbegin_1"
18425 [(set (pc)
18426 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18427 (const_int 0))
18428 (label_ref (match_operand 1))
18429 (pc)))
18430 (set (match_operand:SI 0 "register_operand" "+a")
18431 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18432 "TARGET_RTM"
18433 "xbegin\t%l1"
18434 [(set_attr "type" "other")
18435 (set_attr "length" "6")])
18436
18437 (define_insn "xend"
18438 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18439 "TARGET_RTM"
18440 "xend"
18441 [(set_attr "type" "other")
18442 (set_attr "length" "3")])
18443
18444 (define_insn "xabort"
18445 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18446 UNSPECV_XABORT)]
18447 "TARGET_RTM"
18448 "xabort\t%0"
18449 [(set_attr "type" "other")
18450 (set_attr "length" "3")])
18451
18452 (define_expand "xtest"
18453 [(set (match_operand:QI 0 "register_operand")
18454 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18455 "TARGET_RTM"
18456 {
18457 emit_insn (gen_xtest_1 ());
18458
18459 ix86_expand_setcc (operands[0], NE,
18460 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18461 DONE;
18462 })
18463
18464 (define_insn "xtest_1"
18465 [(set (reg:CCZ FLAGS_REG)
18466 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18467 "TARGET_RTM"
18468 "xtest"
18469 [(set_attr "type" "other")
18470 (set_attr "length" "3")])
18471
18472 (include "mmx.md")
18473 (include "sse.md")
18474 (include "sync.md")