]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2020 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 addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
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 UNSPEC_SIZEOF
82
83 ;; Prologue support
84 UNSPEC_STACK_ALLOC
85 UNSPEC_SET_GOT
86 UNSPEC_SET_RIP
87 UNSPEC_SET_GOT_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
89 UNSPEC_PROBE_STACK
90
91 ;; TLS support
92 UNSPEC_TP
93 UNSPEC_TLS_GD
94 UNSPEC_TLS_LD_BASE
95 UNSPEC_TLSDESC
96 UNSPEC_TLS_IE_SUN
97
98 ;; Other random patterns
99 UNSPEC_SCAS
100 UNSPEC_FNSTSW
101 UNSPEC_SAHF
102 UNSPEC_NOTRAP
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_REP
106 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_TRUNC_NOOP
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_PAUSE
110 UNSPEC_LEA_ADDR
111 UNSPEC_XBEGIN_ABORT
112 UNSPEC_STOS
113 UNSPEC_PEEPSIB
114 UNSPEC_INSN_FALSE_DEP
115 UNSPEC_SBB
116
117 ;; For SSE/MMX support:
118 UNSPEC_FIX_NOTRUNC
119 UNSPEC_MASKMOV
120 UNSPEC_MOVMSK
121 UNSPEC_RCP
122 UNSPEC_RSQRT
123 UNSPEC_PSADBW
124
125 ;; Generic math support
126 UNSPEC_COPYSIGN
127 UNSPEC_XORSIGN
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
130
131 ;; x87 Floating point
132 UNSPEC_SIN
133 UNSPEC_COS
134 UNSPEC_FPATAN
135 UNSPEC_FYL2X
136 UNSPEC_FYL2XP1
137 UNSPEC_FRNDINT
138 UNSPEC_FIST
139 UNSPEC_F2XM1
140 UNSPEC_TAN
141 UNSPEC_FXAM
142
143 ;; x87 Rounding
144 UNSPEC_FRNDINT_ROUNDEVEN
145 UNSPEC_FRNDINT_FLOOR
146 UNSPEC_FRNDINT_CEIL
147 UNSPEC_FRNDINT_TRUNC
148 UNSPEC_FIST_FLOOR
149 UNSPEC_FIST_CEIL
150
151 ;; x87 Double output FP
152 UNSPEC_SINCOS_COS
153 UNSPEC_SINCOS_SIN
154 UNSPEC_XTRACT_FRACT
155 UNSPEC_XTRACT_EXP
156 UNSPEC_FSCALE_FRACT
157 UNSPEC_FSCALE_EXP
158 UNSPEC_FPREM_F
159 UNSPEC_FPREM_U
160 UNSPEC_FPREM1_F
161 UNSPEC_FPREM1_U
162
163 UNSPEC_C2_FLAG
164 UNSPEC_FXAM_MEM
165
166 ;; SSP patterns
167 UNSPEC_SP_SET
168 UNSPEC_SP_TEST
169
170 ;; For ROUND support
171 UNSPEC_ROUND
172
173 ;; For CRC32 support
174 UNSPEC_CRC32
175
176 ;; For LZCNT suppoprt
177 UNSPEC_LZCNT
178
179 ;; For BMI support
180 UNSPEC_TZCNT
181 UNSPEC_BEXTR
182
183 ;; For BMI2 support
184 UNSPEC_PDEP
185 UNSPEC_PEXT
186
187 ;; IRET support
188 UNSPEC_INTERRUPT_RETURN
189 ])
190
191 (define_c_enum "unspecv" [
192 UNSPECV_UD2
193 UNSPECV_BLOCKAGE
194 UNSPECV_STACK_PROBE
195 UNSPECV_PROBE_STACK_RANGE
196 UNSPECV_ALIGN
197 UNSPECV_PROLOGUE_USE
198 UNSPECV_SPLIT_STACK_RETURN
199 UNSPECV_CLD
200 UNSPECV_NOPS
201 UNSPECV_RDTSC
202 UNSPECV_RDTSCP
203 UNSPECV_RDPMC
204 UNSPECV_LLWP_INTRINSIC
205 UNSPECV_SLWP_INTRINSIC
206 UNSPECV_LWPVAL_INTRINSIC
207 UNSPECV_LWPINS_INTRINSIC
208 UNSPECV_RDFSBASE
209 UNSPECV_RDGSBASE
210 UNSPECV_WRFSBASE
211 UNSPECV_WRGSBASE
212 UNSPECV_FXSAVE
213 UNSPECV_FXRSTOR
214 UNSPECV_FXSAVE64
215 UNSPECV_FXRSTOR64
216 UNSPECV_XSAVE
217 UNSPECV_XRSTOR
218 UNSPECV_XSAVE64
219 UNSPECV_XRSTOR64
220 UNSPECV_XSAVEOPT
221 UNSPECV_XSAVEOPT64
222 UNSPECV_XSAVES
223 UNSPECV_XRSTORS
224 UNSPECV_XSAVES64
225 UNSPECV_XRSTORS64
226 UNSPECV_XSAVEC
227 UNSPECV_XSAVEC64
228 UNSPECV_XGETBV
229 UNSPECV_XSETBV
230 UNSPECV_WBINVD
231 UNSPECV_WBNOINVD
232
233 ;; For atomic compound assignments.
234 UNSPECV_FNSTENV
235 UNSPECV_FLDENV
236 UNSPECV_FNSTSW
237 UNSPECV_FNCLEX
238
239 ;; For RDRAND support
240 UNSPECV_RDRAND
241
242 ;; For RDSEED support
243 UNSPECV_RDSEED
244
245 ;; For RTM support
246 UNSPECV_XBEGIN
247 UNSPECV_XEND
248 UNSPECV_XABORT
249 UNSPECV_XTEST
250
251 UNSPECV_NLGR
252
253 ;; For CLWB support
254 UNSPECV_CLWB
255
256 ;; For CLFLUSHOPT support
257 UNSPECV_CLFLUSHOPT
258
259 ;; For MONITORX and MWAITX support
260 UNSPECV_MONITORX
261 UNSPECV_MWAITX
262
263 ;; For CLZERO support
264 UNSPECV_CLZERO
265
266 ;; For RDPKRU and WRPKRU support
267 UNSPECV_PKU
268
269 ;; For RDPID support
270 UNSPECV_RDPID
271
272 ;; For CET support
273 UNSPECV_NOP_ENDBR
274 UNSPECV_NOP_RDSSP
275 UNSPECV_INCSSP
276 UNSPECV_SAVEPREVSSP
277 UNSPECV_RSTORSSP
278 UNSPECV_WRSS
279 UNSPECV_WRUSS
280 UNSPECV_SETSSBSY
281 UNSPECV_CLRSSBSY
282
283 ;; For MOVDIRI and MOVDIR64B support
284 UNSPECV_MOVDIRI
285 UNSPECV_MOVDIR64B
286
287 ;; For WAITPKG support
288 UNSPECV_UMWAIT
289 UNSPECV_UMONITOR
290 UNSPECV_TPAUSE
291
292 ;; For CLDEMOTE support
293 UNSPECV_CLDEMOTE
294
295 ;; For Speculation Barrier support
296 UNSPECV_SPECULATION_BARRIER
297
298 UNSPECV_PTWRITE
299
300 ;; For ENQCMD and ENQCMDS support
301 UNSPECV_ENQCMD
302 UNSPECV_ENQCMDS
303 ])
304
305 ;; Constants to represent rounding modes in the ROUND instruction
306 (define_constants
307 [(ROUND_ROUNDEVEN 0x0)
308 (ROUND_FLOOR 0x1)
309 (ROUND_CEIL 0x2)
310 (ROUND_TRUNC 0x3)
311 (ROUND_MXCSR 0x4)
312 (ROUND_NO_EXC 0x8)
313 ])
314
315 ;; Constants to represent AVX512F embeded rounding
316 (define_constants
317 [(ROUND_NEAREST_INT 0)
318 (ROUND_NEG_INF 1)
319 (ROUND_POS_INF 2)
320 (ROUND_ZERO 3)
321 (NO_ROUND 4)
322 (ROUND_SAE 8)
323 ])
324
325 ;; Constants to represent pcomtrue/pcomfalse variants
326 (define_constants
327 [(PCOM_FALSE 0)
328 (PCOM_TRUE 1)
329 (COM_FALSE_S 2)
330 (COM_FALSE_P 3)
331 (COM_TRUE_S 4)
332 (COM_TRUE_P 5)
333 ])
334
335 ;; Constants used in the XOP pperm instruction
336 (define_constants
337 [(PPERM_SRC 0x00) /* copy source */
338 (PPERM_INVERT 0x20) /* invert source */
339 (PPERM_REVERSE 0x40) /* bit reverse source */
340 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
341 (PPERM_ZERO 0x80) /* all 0's */
342 (PPERM_ONES 0xa0) /* all 1's */
343 (PPERM_SIGN 0xc0) /* propagate sign bit */
344 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
345 (PPERM_SRC1 0x00) /* use first source byte */
346 (PPERM_SRC2 0x10) /* use second source byte */
347 ])
348
349 ;; Registers by name.
350 (define_constants
351 [(AX_REG 0)
352 (DX_REG 1)
353 (CX_REG 2)
354 (BX_REG 3)
355 (SI_REG 4)
356 (DI_REG 5)
357 (BP_REG 6)
358 (SP_REG 7)
359 (ST0_REG 8)
360 (ST1_REG 9)
361 (ST2_REG 10)
362 (ST3_REG 11)
363 (ST4_REG 12)
364 (ST5_REG 13)
365 (ST6_REG 14)
366 (ST7_REG 15)
367 (ARGP_REG 16)
368 (FLAGS_REG 17)
369 (FPSR_REG 18)
370 (FRAME_REG 19)
371 (XMM0_REG 20)
372 (XMM1_REG 21)
373 (XMM2_REG 22)
374 (XMM3_REG 23)
375 (XMM4_REG 24)
376 (XMM5_REG 25)
377 (XMM6_REG 26)
378 (XMM7_REG 27)
379 (MM0_REG 28)
380 (MM1_REG 29)
381 (MM2_REG 30)
382 (MM3_REG 31)
383 (MM4_REG 32)
384 (MM5_REG 33)
385 (MM6_REG 34)
386 (MM7_REG 35)
387 (R8_REG 36)
388 (R9_REG 37)
389 (R10_REG 38)
390 (R11_REG 39)
391 (R12_REG 40)
392 (R13_REG 41)
393 (R14_REG 42)
394 (R15_REG 43)
395 (XMM8_REG 44)
396 (XMM9_REG 45)
397 (XMM10_REG 46)
398 (XMM11_REG 47)
399 (XMM12_REG 48)
400 (XMM13_REG 49)
401 (XMM14_REG 50)
402 (XMM15_REG 51)
403 (XMM16_REG 52)
404 (XMM17_REG 53)
405 (XMM18_REG 54)
406 (XMM19_REG 55)
407 (XMM20_REG 56)
408 (XMM21_REG 57)
409 (XMM22_REG 58)
410 (XMM23_REG 59)
411 (XMM24_REG 60)
412 (XMM25_REG 61)
413 (XMM26_REG 62)
414 (XMM27_REG 63)
415 (XMM28_REG 64)
416 (XMM29_REG 65)
417 (XMM30_REG 66)
418 (XMM31_REG 67)
419 (MASK0_REG 68)
420 (MASK1_REG 69)
421 (MASK2_REG 70)
422 (MASK3_REG 71)
423 (MASK4_REG 72)
424 (MASK5_REG 73)
425 (MASK6_REG 74)
426 (MASK7_REG 75)
427 (FIRST_PSEUDO_REG 76)
428 ])
429
430 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
431 ;; from i386.c.
432
433 ;; In C guard expressions, put expressions which may be compile-time
434 ;; constants first. This allows for better optimization. For
435 ;; example, write "TARGET_64BIT && reload_completed", not
436 ;; "reload_completed && TARGET_64BIT".
437
438 \f
439 ;; Processor type.
440 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
441 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
442 bdver4,btver2,znver1,znver2"
443 (const (symbol_ref "ix86_schedule")))
444
445 ;; A basic instruction type. Refinements due to arguments to be
446 ;; provided in other attributes.
447 (define_attr "type"
448 "other,multi,
449 alu,alu1,negnot,imov,imovx,lea,
450 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
451 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
452 push,pop,call,callv,leave,
453 str,bitmanip,
454 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
455 fxch,fistp,fisttp,frndint,
456 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
457 ssemul,sseimul,ssediv,sselog,sselog1,
458 sseishft,sseishft1,ssecmp,ssecomi,
459 ssecvt,ssecvt1,sseicvt,sseins,
460 sseshuf,sseshuf1,ssemuladd,sse4arg,
461 lwp,mskmov,msklog,
462 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
463 (const_string "other"))
464
465 ;; Main data type used by the insn
466 (define_attr "mode"
467 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
468 V2DF,V2SF,V1DF,V8DF"
469 (const_string "unknown"))
470
471 ;; The CPU unit operations uses.
472 (define_attr "unit" "integer,i387,sse,mmx,unknown"
473 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
474 fxch,fistp,fisttp,frndint")
475 (const_string "i387")
476 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
477 ssemul,sseimul,ssediv,sselog,sselog1,
478 sseishft,sseishft1,ssecmp,ssecomi,
479 ssecvt,ssecvt1,sseicvt,sseins,
480 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
481 (const_string "sse")
482 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
483 (const_string "mmx")
484 (eq_attr "type" "other")
485 (const_string "unknown")]
486 (const_string "integer")))
487
488 ;; The (bounding maximum) length of an instruction immediate.
489 (define_attr "length_immediate" ""
490 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
491 bitmanip,imulx,msklog,mskmov")
492 (const_int 0)
493 (eq_attr "unit" "i387,sse,mmx")
494 (const_int 0)
495 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
496 rotate,rotatex,rotate1,imul,icmp,push,pop")
497 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
498 (eq_attr "type" "imov,test")
499 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
500 (eq_attr "type" "call")
501 (if_then_else (match_operand 0 "constant_call_address_operand")
502 (const_int 4)
503 (const_int 0))
504 (eq_attr "type" "callv")
505 (if_then_else (match_operand 1 "constant_call_address_operand")
506 (const_int 4)
507 (const_int 0))
508 ;; We don't know the size before shorten_branches. Expect
509 ;; the instruction to fit for better scheduling.
510 (eq_attr "type" "ibr")
511 (const_int 1)
512 ]
513 (symbol_ref "/* Update immediate_length and other attributes! */
514 gcc_unreachable (),1")))
515
516 ;; The (bounding maximum) length of an instruction address.
517 (define_attr "length_address" ""
518 (cond [(eq_attr "type" "str,other,multi,fxch")
519 (const_int 0)
520 (and (eq_attr "type" "call")
521 (match_operand 0 "constant_call_address_operand"))
522 (const_int 0)
523 (and (eq_attr "type" "callv")
524 (match_operand 1 "constant_call_address_operand"))
525 (const_int 0)
526 ]
527 (symbol_ref "ix86_attr_length_address_default (insn)")))
528
529 ;; Set when length prefix is used.
530 (define_attr "prefix_data16" ""
531 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
532 (const_int 0)
533 (eq_attr "mode" "HI")
534 (const_int 1)
535 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
536 (const_int 1)
537 ]
538 (const_int 0)))
539
540 ;; Set when string REP prefix is used.
541 (define_attr "prefix_rep" ""
542 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
543 (const_int 0)
544 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
545 (const_int 1)
546 ]
547 (const_int 0)))
548
549 ;; Set when 0f opcode prefix is used.
550 (define_attr "prefix_0f" ""
551 (if_then_else
552 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
553 (eq_attr "unit" "sse,mmx"))
554 (const_int 1)
555 (const_int 0)))
556
557 ;; Set when REX opcode prefix is used.
558 (define_attr "prefix_rex" ""
559 (cond [(not (match_test "TARGET_64BIT"))
560 (const_int 0)
561 (and (eq_attr "mode" "DI")
562 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
563 (eq_attr "unit" "!mmx")))
564 (const_int 1)
565 (and (eq_attr "mode" "QI")
566 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
567 (const_int 1)
568 (match_test "x86_extended_reg_mentioned_p (insn)")
569 (const_int 1)
570 (and (eq_attr "type" "imovx")
571 (match_operand:QI 1 "ext_QIreg_operand"))
572 (const_int 1)
573 ]
574 (const_int 0)))
575
576 ;; There are also additional prefixes in 3DNOW, SSSE3.
577 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
578 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
579 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
580 (define_attr "prefix_extra" ""
581 (cond [(eq_attr "type" "ssemuladd,sse4arg")
582 (const_int 2)
583 (eq_attr "type" "sseiadd1,ssecvt1")
584 (const_int 1)
585 ]
586 (const_int 0)))
587
588 ;; Prefix used: original, VEX or maybe VEX.
589 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
590 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
591 (const_string "vex")
592 (eq_attr "mode" "XI,V16SF,V8DF")
593 (const_string "evex")
594 ]
595 (const_string "orig")))
596
597 ;; VEX W bit is used.
598 (define_attr "prefix_vex_w" "" (const_int 0))
599
600 ;; The length of VEX prefix
601 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
602 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
603 ;; still prefix_0f 1, with prefix_extra 1.
604 (define_attr "length_vex" ""
605 (if_then_else (and (eq_attr "prefix_0f" "1")
606 (eq_attr "prefix_extra" "0"))
607 (if_then_else (eq_attr "prefix_vex_w" "1")
608 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
609 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
610 (if_then_else (eq_attr "prefix_vex_w" "1")
611 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
612 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
613
614 ;; 4-bytes evex prefix and 1 byte opcode.
615 (define_attr "length_evex" "" (const_int 5))
616
617 ;; Set when modrm byte is used.
618 (define_attr "modrm" ""
619 (cond [(eq_attr "type" "str,leave")
620 (const_int 0)
621 (eq_attr "unit" "i387")
622 (const_int 0)
623 (and (eq_attr "type" "incdec")
624 (and (not (match_test "TARGET_64BIT"))
625 (ior (match_operand:SI 1 "register_operand")
626 (match_operand:HI 1 "register_operand"))))
627 (const_int 0)
628 (and (eq_attr "type" "push")
629 (not (match_operand 1 "memory_operand")))
630 (const_int 0)
631 (and (eq_attr "type" "pop")
632 (not (match_operand 0 "memory_operand")))
633 (const_int 0)
634 (and (eq_attr "type" "imov")
635 (and (not (eq_attr "mode" "DI"))
636 (ior (and (match_operand 0 "register_operand")
637 (match_operand 1 "immediate_operand"))
638 (ior (and (match_operand 0 "ax_reg_operand")
639 (match_operand 1 "memory_displacement_only_operand"))
640 (and (match_operand 0 "memory_displacement_only_operand")
641 (match_operand 1 "ax_reg_operand"))))))
642 (const_int 0)
643 (and (eq_attr "type" "call")
644 (match_operand 0 "constant_call_address_operand"))
645 (const_int 0)
646 (and (eq_attr "type" "callv")
647 (match_operand 1 "constant_call_address_operand"))
648 (const_int 0)
649 (and (eq_attr "type" "alu,alu1,icmp,test")
650 (match_operand 0 "ax_reg_operand"))
651 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
652 ]
653 (const_int 1)))
654
655 ;; The (bounding maximum) length of an instruction in bytes.
656 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
657 ;; Later we may want to split them and compute proper length as for
658 ;; other insns.
659 (define_attr "length" ""
660 (cond [(eq_attr "type" "other,multi,fistp,frndint")
661 (const_int 16)
662 (eq_attr "type" "fcmp")
663 (const_int 4)
664 (eq_attr "unit" "i387")
665 (plus (const_int 2)
666 (plus (attr "prefix_data16")
667 (attr "length_address")))
668 (ior (eq_attr "prefix" "evex")
669 (and (ior (eq_attr "prefix" "maybe_evex")
670 (eq_attr "prefix" "maybe_vex"))
671 (match_test "TARGET_AVX512F")))
672 (plus (attr "length_evex")
673 (plus (attr "length_immediate")
674 (plus (attr "modrm")
675 (attr "length_address"))))
676 (ior (eq_attr "prefix" "vex")
677 (and (ior (eq_attr "prefix" "maybe_vex")
678 (eq_attr "prefix" "maybe_evex"))
679 (match_test "TARGET_AVX")))
680 (plus (attr "length_vex")
681 (plus (attr "length_immediate")
682 (plus (attr "modrm")
683 (attr "length_address"))))]
684 (plus (plus (attr "modrm")
685 (plus (attr "prefix_0f")
686 (plus (attr "prefix_rex")
687 (plus (attr "prefix_extra")
688 (const_int 1)))))
689 (plus (attr "prefix_rep")
690 (plus (attr "prefix_data16")
691 (plus (attr "length_immediate")
692 (attr "length_address")))))))
693
694 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
695 ;; `store' if there is a simple memory reference therein, or `unknown'
696 ;; if the instruction is complex.
697
698 (define_attr "memory" "none,load,store,both,unknown"
699 (cond [(eq_attr "type" "other,multi,str,lwp")
700 (const_string "unknown")
701 (eq_attr "type" "lea,fcmov,fpspc")
702 (const_string "none")
703 (eq_attr "type" "fistp,leave")
704 (const_string "both")
705 (eq_attr "type" "frndint")
706 (const_string "load")
707 (eq_attr "type" "push")
708 (if_then_else (match_operand 1 "memory_operand")
709 (const_string "both")
710 (const_string "store"))
711 (eq_attr "type" "pop")
712 (if_then_else (match_operand 0 "memory_operand")
713 (const_string "both")
714 (const_string "load"))
715 (eq_attr "type" "setcc")
716 (if_then_else (match_operand 0 "memory_operand")
717 (const_string "store")
718 (const_string "none"))
719 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
720 (if_then_else (ior (match_operand 0 "memory_operand")
721 (match_operand 1 "memory_operand"))
722 (const_string "load")
723 (const_string "none"))
724 (eq_attr "type" "ibr")
725 (if_then_else (match_operand 0 "memory_operand")
726 (const_string "load")
727 (const_string "none"))
728 (eq_attr "type" "call")
729 (if_then_else (match_operand 0 "constant_call_address_operand")
730 (const_string "none")
731 (const_string "load"))
732 (eq_attr "type" "callv")
733 (if_then_else (match_operand 1 "constant_call_address_operand")
734 (const_string "none")
735 (const_string "load"))
736 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
737 (match_operand 1 "memory_operand"))
738 (const_string "both")
739 (and (match_operand 0 "memory_operand")
740 (match_operand 1 "memory_operand"))
741 (const_string "both")
742 (match_operand 0 "memory_operand")
743 (const_string "store")
744 (match_operand 1 "memory_operand")
745 (const_string "load")
746 (and (eq_attr "type"
747 "!alu1,negnot,ishift1,rotate1,
748 imov,imovx,icmp,test,bitmanip,
749 fmov,fcmp,fsgn,
750 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
751 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
752 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
753 (match_operand 2 "memory_operand"))
754 (const_string "load")
755 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
756 (match_operand 3 "memory_operand"))
757 (const_string "load")
758 ]
759 (const_string "none")))
760
761 ;; Indicates if an instruction has both an immediate and a displacement.
762
763 (define_attr "imm_disp" "false,true,unknown"
764 (cond [(eq_attr "type" "other,multi")
765 (const_string "unknown")
766 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
767 (and (match_operand 0 "memory_displacement_operand")
768 (match_operand 1 "immediate_operand")))
769 (const_string "true")
770 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
771 (and (match_operand 0 "memory_displacement_operand")
772 (match_operand 2 "immediate_operand")))
773 (const_string "true")
774 ]
775 (const_string "false")))
776
777 ;; Indicates if an FP operation has an integer source.
778
779 (define_attr "fp_int_src" "false,true"
780 (const_string "false"))
781
782 ;; Defines rounding mode of an FP operation.
783
784 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
785 (const_string "any"))
786
787 ;; Define attribute to indicate AVX insns with partial XMM register update.
788 (define_attr "avx_partial_xmm_update" "false,true"
789 (const_string "false"))
790
791 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
792 (define_attr "use_carry" "0,1" (const_string "0"))
793
794 ;; Define attribute to indicate unaligned ssemov insns
795 (define_attr "movu" "0,1" (const_string "0"))
796
797 ;; Used to control the "enabled" attribute on a per-instruction basis.
798 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
799 sse_noavx,sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
800 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
801 avx512bw,noavx512bw,avx512dq,noavx512dq,
802 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
803 (const_string "base"))
804
805 ;; Define instruction set of MMX instructions
806 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
807 (const_string "base"))
808
809 (define_attr "enabled" ""
810 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
811 (eq_attr "isa" "x64_sse2")
812 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
813 (eq_attr "isa" "x64_sse4")
814 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
815 (eq_attr "isa" "x64_sse4_noavx")
816 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
817 (eq_attr "isa" "x64_avx")
818 (symbol_ref "TARGET_64BIT && TARGET_AVX")
819 (eq_attr "isa" "x64_avx512dq")
820 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
821 (eq_attr "isa" "x64_avx512bw")
822 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
823 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
824 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
825 (eq_attr "isa" "sse_noavx")
826 (symbol_ref "TARGET_SSE && !TARGET_AVX")
827 (eq_attr "isa" "sse2_noavx")
828 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
829 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
830 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
831 (eq_attr "isa" "sse4_noavx")
832 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
833 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
834 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
835 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
836 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
837 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
838 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
839 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
840 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
841 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
842 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
843 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
844 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
845 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
846 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
847 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
848 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
849
850 (eq_attr "mmx_isa" "native")
851 (symbol_ref "!TARGET_MMX_WITH_SSE")
852 (eq_attr "mmx_isa" "sse")
853 (symbol_ref "TARGET_MMX_WITH_SSE")
854 (eq_attr "mmx_isa" "sse_noavx")
855 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
856 (eq_attr "mmx_isa" "avx")
857 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
858 ]
859 (const_int 1)))
860
861 (define_attr "preferred_for_size" "" (const_int 1))
862 (define_attr "preferred_for_speed" "" (const_int 1))
863
864 ;; Describe a user's asm statement.
865 (define_asm_attributes
866 [(set_attr "length" "128")
867 (set_attr "type" "multi")])
868
869 (define_code_iterator plusminus [plus minus])
870
871 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
872
873 (define_code_iterator multdiv [mult div])
874
875 ;; Base name for define_insn
876 (define_code_attr plusminus_insn
877 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
878 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
879
880 ;; Base name for insn mnemonic.
881 (define_code_attr plusminus_mnemonic
882 [(plus "add") (ss_plus "adds") (us_plus "addus")
883 (minus "sub") (ss_minus "subs") (us_minus "subus")])
884 (define_code_attr multdiv_mnemonic
885 [(mult "mul") (div "div")])
886
887 ;; Mark commutative operators as such in constraints.
888 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
889 (minus "") (ss_minus "") (us_minus "")])
890
891 ;; Mapping of max and min
892 (define_code_iterator maxmin [smax smin umax umin])
893
894 ;; Mapping of signed max and min
895 (define_code_iterator smaxmin [smax smin])
896
897 ;; Mapping of unsigned max and min
898 (define_code_iterator umaxmin [umax umin])
899
900 ;; Base name for integer and FP insn mnemonic
901 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
902 (umax "maxu") (umin "minu")])
903 (define_code_attr maxmin_float [(smax "max") (smin "min")])
904
905 (define_int_iterator IEEE_MAXMIN
906 [UNSPEC_IEEE_MAX
907 UNSPEC_IEEE_MIN])
908
909 (define_int_attr ieee_maxmin
910 [(UNSPEC_IEEE_MAX "max")
911 (UNSPEC_IEEE_MIN "min")])
912
913 ;; Mapping of logic operators
914 (define_code_iterator any_logic [and ior xor])
915 (define_code_iterator any_or [ior xor])
916 (define_code_iterator fpint_logic [and xor])
917
918 ;; Base name for insn mnemonic.
919 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
920
921 ;; Mapping of logic-shift operators
922 (define_code_iterator any_lshift [ashift lshiftrt])
923
924 ;; Mapping of shift-right operators
925 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
926
927 ;; Mapping of all shift operators
928 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
929
930 ;; Base name for define_insn
931 (define_code_attr shift_insn
932 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
933
934 ;; Base name for insn mnemonic.
935 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
936 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
937
938 ;; Mapping of rotate operators
939 (define_code_iterator any_rotate [rotate rotatert])
940
941 ;; Base name for define_insn
942 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
943
944 ;; Base name for insn mnemonic.
945 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
946
947 ;; Mapping of abs neg operators
948 (define_code_iterator absneg [abs neg])
949
950 ;; Base name for x87 insn mnemonic.
951 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
952
953 ;; Used in signed and unsigned widening multiplications.
954 (define_code_iterator any_extend [sign_extend zero_extend])
955
956 ;; Prefix for insn menmonic.
957 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
958 (div "i") (udiv "")])
959 ;; Prefix for define_insn
960 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
961 (define_code_attr u [(sign_extend "") (zero_extend "u")
962 (div "") (udiv "u")])
963 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
964 (div "false") (udiv "true")])
965
966 ;; Used in signed and unsigned truncations.
967 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
968 ;; Instruction suffix for truncations.
969 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
970
971 ;; Used in signed and unsigned fix.
972 (define_code_iterator any_fix [fix unsigned_fix])
973 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
974 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
975 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
976
977 ;; Used in signed and unsigned float.
978 (define_code_iterator any_float [float unsigned_float])
979 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
980 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
981 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
982
983 ;; All integer modes.
984 (define_mode_iterator SWI1248x [QI HI SI DI])
985
986 ;; All integer modes without QImode.
987 (define_mode_iterator SWI248x [HI SI DI])
988
989 ;; All integer modes without QImode and HImode.
990 (define_mode_iterator SWI48x [SI DI])
991
992 ;; All integer modes without SImode and DImode.
993 (define_mode_iterator SWI12 [QI HI])
994
995 ;; All integer modes without DImode.
996 (define_mode_iterator SWI124 [QI HI SI])
997
998 ;; All integer modes without QImode and DImode.
999 (define_mode_iterator SWI24 [HI SI])
1000
1001 ;; Single word integer modes.
1002 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1003
1004 ;; Single word integer modes without QImode.
1005 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1006
1007 ;; Single word integer modes without QImode and HImode.
1008 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1009
1010 ;; All math-dependant single and double word integer modes.
1011 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1012 (HI "TARGET_HIMODE_MATH")
1013 SI DI (TI "TARGET_64BIT")])
1014
1015 ;; Math-dependant single word integer modes.
1016 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1017 (HI "TARGET_HIMODE_MATH")
1018 SI (DI "TARGET_64BIT")])
1019
1020 ;; Math-dependant integer modes without DImode.
1021 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1022 (HI "TARGET_HIMODE_MATH")
1023 SI])
1024
1025 ;; Math-dependant integer modes with DImode (enabled for 32bit with STV).
1026 (define_mode_iterator SWIM1248s
1027 [(QI "TARGET_QIMODE_MATH")
1028 (HI "TARGET_HIMODE_MATH")
1029 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
1030
1031 ;; Math-dependant single word integer modes without QImode.
1032 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1033 SI (DI "TARGET_64BIT")])
1034
1035 ;; Double word integer modes.
1036 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1037 (TI "TARGET_64BIT")])
1038
1039 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1040 ;; compile time constant, it is faster to use <MODE_SIZE> than
1041 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1042 ;; command line options just use GET_MODE_SIZE macro.
1043 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1044 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1045 (V16QI "16") (V32QI "32") (V64QI "64")
1046 (V8HI "16") (V16HI "32") (V32HI "64")
1047 (V4SI "16") (V8SI "32") (V16SI "64")
1048 (V2DI "16") (V4DI "32") (V8DI "64")
1049 (V1TI "16") (V2TI "32") (V4TI "64")
1050 (V2DF "16") (V4DF "32") (V8DF "64")
1051 (V4SF "16") (V8SF "32") (V16SF "64")])
1052
1053 ;; Double word integer modes as mode attribute.
1054 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1055 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1056
1057 ;; LEA mode corresponding to an integer mode
1058 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1059
1060 ;; Half mode for double word integer modes.
1061 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1062 (DI "TARGET_64BIT")])
1063
1064 ;; Instruction suffix for integer modes.
1065 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1066
1067 ;; Instruction suffix for masks.
1068 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1069
1070 ;; Pointer size prefix for integer modes (Intel asm dialect)
1071 (define_mode_attr iptrsize [(QI "BYTE")
1072 (HI "WORD")
1073 (SI "DWORD")
1074 (DI "QWORD")])
1075
1076 ;; Register class for integer modes.
1077 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1078
1079 ;; Immediate operand constraint for integer modes.
1080 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1081
1082 ;; General operand constraint for word modes.
1083 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1084
1085 ;; Immediate operand constraint for double integer modes.
1086 (define_mode_attr di [(SI "nF") (DI "Wd")])
1087
1088 ;; Immediate operand constraint for shifts.
1089 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1090
1091 ;; Print register name in the specified mode.
1092 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1093
1094 ;; General operand predicate for integer modes.
1095 (define_mode_attr general_operand
1096 [(QI "general_operand")
1097 (HI "general_operand")
1098 (SI "x86_64_general_operand")
1099 (DI "x86_64_general_operand")
1100 (TI "x86_64_general_operand")])
1101
1102 ;; General operand predicate for integer modes, where for TImode
1103 ;; we need both words of the operand to be general operands.
1104 (define_mode_attr general_hilo_operand
1105 [(QI "general_operand")
1106 (HI "general_operand")
1107 (SI "x86_64_general_operand")
1108 (DI "x86_64_general_operand")
1109 (TI "x86_64_hilo_general_operand")])
1110
1111 ;; General sign extend operand predicate for integer modes,
1112 ;; which disallows VOIDmode operands and thus it is suitable
1113 ;; for use inside sign_extend.
1114 (define_mode_attr general_sext_operand
1115 [(QI "sext_operand")
1116 (HI "sext_operand")
1117 (SI "x86_64_sext_operand")
1118 (DI "x86_64_sext_operand")])
1119
1120 ;; General sign/zero extend operand predicate for integer modes.
1121 (define_mode_attr general_szext_operand
1122 [(QI "general_operand")
1123 (HI "general_operand")
1124 (SI "x86_64_szext_general_operand")
1125 (DI "x86_64_szext_general_operand")])
1126
1127 (define_mode_attr nonmemory_szext_operand
1128 [(QI "nonmemory_operand")
1129 (HI "nonmemory_operand")
1130 (SI "x86_64_szext_nonmemory_operand")
1131 (DI "x86_64_szext_nonmemory_operand")])
1132
1133 ;; Immediate operand predicate for integer modes.
1134 (define_mode_attr immediate_operand
1135 [(QI "immediate_operand")
1136 (HI "immediate_operand")
1137 (SI "x86_64_immediate_operand")
1138 (DI "x86_64_immediate_operand")])
1139
1140 ;; Nonmemory operand predicate for integer modes.
1141 (define_mode_attr nonmemory_operand
1142 [(QI "nonmemory_operand")
1143 (HI "nonmemory_operand")
1144 (SI "x86_64_nonmemory_operand")
1145 (DI "x86_64_nonmemory_operand")])
1146
1147 ;; Operand predicate for shifts.
1148 (define_mode_attr shift_operand
1149 [(QI "nonimmediate_operand")
1150 (HI "nonimmediate_operand")
1151 (SI "nonimmediate_operand")
1152 (DI "shiftdi_operand")
1153 (TI "register_operand")])
1154
1155 ;; Operand predicate for shift argument.
1156 (define_mode_attr shift_immediate_operand
1157 [(QI "const_1_to_31_operand")
1158 (HI "const_1_to_31_operand")
1159 (SI "const_1_to_31_operand")
1160 (DI "const_1_to_63_operand")])
1161
1162 ;; Input operand predicate for arithmetic left shifts.
1163 (define_mode_attr ashl_input_operand
1164 [(QI "nonimmediate_operand")
1165 (HI "nonimmediate_operand")
1166 (SI "nonimmediate_operand")
1167 (DI "ashldi_input_operand")
1168 (TI "reg_or_pm1_operand")])
1169
1170 ;; SSE and x87 SFmode and DFmode floating point modes
1171 (define_mode_iterator MODEF [SF DF])
1172
1173 ;; All x87 floating point modes
1174 (define_mode_iterator X87MODEF [SF DF XF])
1175
1176 ;; All SSE floating point modes
1177 (define_mode_iterator SSEMODEF [SF DF TF])
1178 (define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")])
1179
1180 ;; SSE instruction suffix for various modes
1181 (define_mode_attr ssemodesuffix
1182 [(SF "ss") (DF "sd")
1183 (V16SF "ps") (V8DF "pd")
1184 (V8SF "ps") (V4DF "pd")
1185 (V4SF "ps") (V2DF "pd")
1186 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1187 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1188 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1189
1190 ;; SSE vector suffix for floating point modes
1191 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1192
1193 ;; SSE vector mode corresponding to a scalar mode
1194 (define_mode_attr ssevecmode
1195 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1196 (define_mode_attr ssevecmodelower
1197 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1198
1199 ;; AVX512F vector mode corresponding to a scalar mode
1200 (define_mode_attr avx512fvecmode
1201 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1202
1203 ;; Instruction suffix for REX 64bit operators.
1204 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1205 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1206
1207 ;; This mode iterator allows :P to be used for patterns that operate on
1208 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1209 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1210
1211 ;; This mode iterator allows :W to be used for patterns that operate on
1212 ;; word_mode sized quantities.
1213 (define_mode_iterator W
1214 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1215
1216 ;; This mode iterator allows :PTR to be used for patterns that operate on
1217 ;; ptr_mode sized quantities.
1218 (define_mode_iterator PTR
1219 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1220 \f
1221 ;; Scheduling descriptions
1222
1223 (include "pentium.md")
1224 (include "ppro.md")
1225 (include "k6.md")
1226 (include "athlon.md")
1227 (include "bdver1.md")
1228 (include "bdver3.md")
1229 (include "btver2.md")
1230 (include "znver1.md")
1231 (include "geode.md")
1232 (include "atom.md")
1233 (include "slm.md")
1234 (include "glm.md")
1235 (include "core2.md")
1236 (include "haswell.md")
1237
1238 \f
1239 ;; Operand and operator predicates and constraints
1240
1241 (include "predicates.md")
1242 (include "constraints.md")
1243
1244 \f
1245 ;; Compare and branch/compare and store instructions.
1246
1247 (define_expand "cbranch<mode>4"
1248 [(set (reg:CC FLAGS_REG)
1249 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1250 (match_operand:SDWIM 2 "<general_operand>")))
1251 (set (pc) (if_then_else
1252 (match_operator 0 "ordered_comparison_operator"
1253 [(reg:CC FLAGS_REG) (const_int 0)])
1254 (label_ref (match_operand 3))
1255 (pc)))]
1256 ""
1257 {
1258 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1259 operands[1] = force_reg (<MODE>mode, operands[1]);
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:SWIM 2 "nonimmediate_operand")
1268 (match_operand:SWIM 3 "<general_operand>")))
1269 (set (match_operand:QI 0 "register_operand")
1270 (match_operator 1 "ordered_comparison_operator"
1271 [(reg:CC FLAGS_REG) (const_int 0)]))]
1272 ""
1273 {
1274 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1275 operands[2] = force_reg (<MODE>mode, operands[2]);
1276 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1277 operands[2], operands[3]);
1278 DONE;
1279 })
1280
1281 (define_expand "@cmp<mode>_1"
1282 [(set (reg:CC FLAGS_REG)
1283 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1284 (match_operand:SWI48 1 "<general_operand>")))])
1285
1286 (define_mode_iterator SWI1248_AVX512BWDQ_64
1287 [(QI "TARGET_AVX512DQ") HI
1288 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1289
1290 (define_insn "*cmp<mode>_ccz_1"
1291 [(set (reg FLAGS_REG)
1292 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1293 "nonimmediate_operand" "<r>,?m<r>,$k")
1294 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1295 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1296 "@
1297 test{<imodesuffix>}\t%0, %0
1298 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1299 kortest<mskmodesuffix>\t%0, %0"
1300 [(set_attr "type" "test,icmp,msklog")
1301 (set_attr "length_immediate" "0,1,*")
1302 (set_attr "prefix" "*,*,vex")
1303 (set_attr "mode" "<MODE>")])
1304
1305 (define_insn "*cmp<mode>_ccno_1"
1306 [(set (reg FLAGS_REG)
1307 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1308 (match_operand:SWI 1 "const0_operand")))]
1309 "ix86_match_ccmode (insn, CCNOmode)"
1310 "@
1311 test{<imodesuffix>}\t%0, %0
1312 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1313 [(set_attr "type" "test,icmp")
1314 (set_attr "length_immediate" "0,1")
1315 (set_attr "mode" "<MODE>")])
1316
1317 (define_insn "*cmp<mode>_1"
1318 [(set (reg FLAGS_REG)
1319 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1320 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1321 "ix86_match_ccmode (insn, CCmode)"
1322 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1323 [(set_attr "type" "icmp")
1324 (set_attr "mode" "<MODE>")])
1325
1326 (define_insn "*cmp<mode>_minus_1"
1327 [(set (reg FLAGS_REG)
1328 (compare
1329 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1330 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1331 (const_int 0)))]
1332 "ix86_match_ccmode (insn, CCGOCmode)"
1333 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1334 [(set_attr "type" "icmp")
1335 (set_attr "mode" "<MODE>")])
1336
1337 (define_insn "*cmpqi_ext_1"
1338 [(set (reg FLAGS_REG)
1339 (compare
1340 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1341 (subreg:QI
1342 (zero_extract:SI
1343 (match_operand 1 "ext_register_operand" "Q,Q")
1344 (const_int 8)
1345 (const_int 8)) 0)))]
1346 "ix86_match_ccmode (insn, CCmode)"
1347 "cmp{b}\t{%h1, %0|%0, %h1}"
1348 [(set_attr "isa" "*,nox64")
1349 (set_attr "type" "icmp")
1350 (set_attr "mode" "QI")])
1351
1352 (define_insn "*cmpqi_ext_2"
1353 [(set (reg FLAGS_REG)
1354 (compare
1355 (subreg:QI
1356 (zero_extract:SI
1357 (match_operand 0 "ext_register_operand" "Q")
1358 (const_int 8)
1359 (const_int 8)) 0)
1360 (match_operand:QI 1 "const0_operand")))]
1361 "ix86_match_ccmode (insn, CCNOmode)"
1362 "test{b}\t%h0, %h0"
1363 [(set_attr "type" "test")
1364 (set_attr "length_immediate" "0")
1365 (set_attr "mode" "QI")])
1366
1367 (define_expand "cmpqi_ext_3"
1368 [(set (reg:CC FLAGS_REG)
1369 (compare:CC
1370 (subreg:QI
1371 (zero_extract:SI
1372 (match_operand 0 "ext_register_operand")
1373 (const_int 8)
1374 (const_int 8)) 0)
1375 (match_operand:QI 1 "const_int_operand")))])
1376
1377 (define_insn "*cmpqi_ext_3"
1378 [(set (reg FLAGS_REG)
1379 (compare
1380 (subreg:QI
1381 (zero_extract:SI
1382 (match_operand 0 "ext_register_operand" "Q,Q")
1383 (const_int 8)
1384 (const_int 8)) 0)
1385 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1386 "ix86_match_ccmode (insn, CCmode)"
1387 "cmp{b}\t{%1, %h0|%h0, %1}"
1388 [(set_attr "isa" "*,nox64")
1389 (set_attr "type" "icmp")
1390 (set_attr "mode" "QI")])
1391
1392 (define_insn "*cmpqi_ext_4"
1393 [(set (reg FLAGS_REG)
1394 (compare
1395 (subreg:QI
1396 (zero_extract:SI
1397 (match_operand 0 "ext_register_operand" "Q")
1398 (const_int 8)
1399 (const_int 8)) 0)
1400 (subreg:QI
1401 (zero_extract:SI
1402 (match_operand 1 "ext_register_operand" "Q")
1403 (const_int 8)
1404 (const_int 8)) 0)))]
1405 "ix86_match_ccmode (insn, CCmode)"
1406 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1407 [(set_attr "type" "icmp")
1408 (set_attr "mode" "QI")])
1409
1410 ;; These implement float point compares.
1411 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1412 ;; which would allow mix and match FP modes on the compares. Which is what
1413 ;; the old patterns did, but with many more of them.
1414
1415 (define_expand "cbranchxf4"
1416 [(set (reg:CC FLAGS_REG)
1417 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1418 (match_operand:XF 2 "nonmemory_operand")))
1419 (set (pc) (if_then_else
1420 (match_operator 0 "ix86_fp_comparison_operator"
1421 [(reg:CC FLAGS_REG)
1422 (const_int 0)])
1423 (label_ref (match_operand 3))
1424 (pc)))]
1425 "TARGET_80387"
1426 {
1427 ix86_expand_branch (GET_CODE (operands[0]),
1428 operands[1], operands[2], operands[3]);
1429 DONE;
1430 })
1431
1432 (define_expand "cstorexf4"
1433 [(set (reg:CC FLAGS_REG)
1434 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1435 (match_operand:XF 3 "nonmemory_operand")))
1436 (set (match_operand:QI 0 "register_operand")
1437 (match_operator 1 "ix86_fp_comparison_operator"
1438 [(reg:CC FLAGS_REG)
1439 (const_int 0)]))]
1440 "TARGET_80387"
1441 {
1442 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1443 operands[2], operands[3]);
1444 DONE;
1445 })
1446
1447 (define_expand "cbranch<mode>4"
1448 [(set (reg:CC FLAGS_REG)
1449 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1450 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1451 (set (pc) (if_then_else
1452 (match_operator 0 "ix86_fp_comparison_operator"
1453 [(reg:CC FLAGS_REG)
1454 (const_int 0)])
1455 (label_ref (match_operand 3))
1456 (pc)))]
1457 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1458 {
1459 ix86_expand_branch (GET_CODE (operands[0]),
1460 operands[1], operands[2], operands[3]);
1461 DONE;
1462 })
1463
1464 (define_expand "cstore<mode>4"
1465 [(set (reg:CC FLAGS_REG)
1466 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1467 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1468 (set (match_operand:QI 0 "register_operand")
1469 (match_operator 1 "ix86_fp_comparison_operator"
1470 [(reg:CC FLAGS_REG)
1471 (const_int 0)]))]
1472 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1473 {
1474 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1475 operands[2], operands[3]);
1476 DONE;
1477 })
1478
1479 (define_expand "cbranchcc4"
1480 [(set (pc) (if_then_else
1481 (match_operator 0 "comparison_operator"
1482 [(match_operand 1 "flags_reg_operand")
1483 (match_operand 2 "const0_operand")])
1484 (label_ref (match_operand 3))
1485 (pc)))]
1486 ""
1487 {
1488 ix86_expand_branch (GET_CODE (operands[0]),
1489 operands[1], operands[2], operands[3]);
1490 DONE;
1491 })
1492
1493 (define_expand "cstorecc4"
1494 [(set (match_operand:QI 0 "register_operand")
1495 (match_operator 1 "comparison_operator"
1496 [(match_operand 2 "flags_reg_operand")
1497 (match_operand 3 "const0_operand")]))]
1498 ""
1499 {
1500 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1501 operands[2], operands[3]);
1502 DONE;
1503 })
1504
1505 ;; FP compares, step 1:
1506 ;; Set the FP condition codes and move fpsr to ax.
1507
1508 ;; We may not use "#" to split and emit these
1509 ;; due to reg-stack pops killing fpsr.
1510
1511 (define_insn "*cmpxf_i387"
1512 [(set (match_operand:HI 0 "register_operand" "=a")
1513 (unspec:HI
1514 [(compare:CCFP
1515 (match_operand:XF 1 "register_operand" "f")
1516 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1517 UNSPEC_FNSTSW))]
1518 "TARGET_80387"
1519 "* return output_fp_compare (insn, operands, false, false);"
1520 [(set_attr "type" "multi")
1521 (set_attr "unit" "i387")
1522 (set_attr "mode" "XF")])
1523
1524 (define_insn "*cmp<mode>_i387"
1525 [(set (match_operand:HI 0 "register_operand" "=a")
1526 (unspec:HI
1527 [(compare:CCFP
1528 (match_operand:MODEF 1 "register_operand" "f")
1529 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1530 UNSPEC_FNSTSW))]
1531 "TARGET_80387"
1532 "* return output_fp_compare (insn, operands, false, false);"
1533 [(set_attr "type" "multi")
1534 (set_attr "unit" "i387")
1535 (set_attr "mode" "<MODE>")])
1536
1537 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1538 [(set (match_operand:HI 0 "register_operand" "=a")
1539 (unspec:HI
1540 [(compare:CCFP
1541 (match_operand:X87MODEF 1 "register_operand" "f")
1542 (float:X87MODEF
1543 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1544 UNSPEC_FNSTSW))]
1545 "TARGET_80387
1546 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1547 || optimize_function_for_size_p (cfun))"
1548 "* return output_fp_compare (insn, operands, false, false);"
1549 [(set_attr "type" "multi")
1550 (set_attr "unit" "i387")
1551 (set_attr "fp_int_src" "true")
1552 (set_attr "mode" "<SWI24:MODE>")])
1553
1554 (define_insn "*cmpu<mode>_i387"
1555 [(set (match_operand:HI 0 "register_operand" "=a")
1556 (unspec:HI
1557 [(unspec:CCFP
1558 [(compare:CCFP
1559 (match_operand:X87MODEF 1 "register_operand" "f")
1560 (match_operand:X87MODEF 2 "register_operand" "f"))]
1561 UNSPEC_NOTRAP)]
1562 UNSPEC_FNSTSW))]
1563 "TARGET_80387"
1564 "* return output_fp_compare (insn, operands, false, true);"
1565 [(set_attr "type" "multi")
1566 (set_attr "unit" "i387")
1567 (set_attr "mode" "<MODE>")])
1568
1569 ;; FP compares, step 2:
1570 ;; Get ax into flags, general case.
1571
1572 (define_insn "x86_sahf_1"
1573 [(set (reg:CC FLAGS_REG)
1574 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1575 UNSPEC_SAHF))]
1576 "TARGET_SAHF"
1577 {
1578 #ifndef HAVE_AS_IX86_SAHF
1579 if (TARGET_64BIT)
1580 return ASM_BYTE "0x9e";
1581 else
1582 #endif
1583 return "sahf";
1584 }
1585 [(set_attr "length" "1")
1586 (set_attr "athlon_decode" "vector")
1587 (set_attr "amdfam10_decode" "direct")
1588 (set_attr "bdver1_decode" "direct")
1589 (set_attr "mode" "SI")])
1590
1591 ;; Pentium Pro can do both steps in one go.
1592 ;; (these instructions set flags directly)
1593
1594 (define_subst_attr "unord" "unord_subst" "" "u")
1595 (define_subst_attr "unordered" "unord_subst" "false" "true")
1596
1597 (define_subst "unord_subst"
1598 [(set (match_operand:CCFP 0)
1599 (match_operand:CCFP 1))]
1600 ""
1601 [(set (match_dup 0)
1602 (unspec:CCFP
1603 [(match_dup 1)]
1604 UNSPEC_NOTRAP))])
1605
1606 (define_insn "*cmpi<unord>xf_i387"
1607 [(set (reg:CCFP FLAGS_REG)
1608 (compare:CCFP
1609 (match_operand:XF 0 "register_operand" "f")
1610 (match_operand:XF 1 "register_operand" "f")))]
1611 "TARGET_80387 && TARGET_CMOVE"
1612 "* return output_fp_compare (insn, operands, true, <unordered>);"
1613 [(set_attr "type" "fcmp")
1614 (set_attr "mode" "XF")
1615 (set_attr "athlon_decode" "vector")
1616 (set_attr "amdfam10_decode" "direct")
1617 (set_attr "bdver1_decode" "double")
1618 (set_attr "znver1_decode" "double")])
1619
1620 (define_insn "*cmpi<unord><MODEF:mode>"
1621 [(set (reg:CCFP FLAGS_REG)
1622 (compare:CCFP
1623 (match_operand:MODEF 0 "register_operand" "f,v")
1624 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1625 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1626 || (TARGET_80387 && TARGET_CMOVE)"
1627 "@
1628 * return output_fp_compare (insn, operands, true, <unordered>);
1629 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1630 [(set_attr "type" "fcmp,ssecomi")
1631 (set_attr "prefix" "orig,maybe_vex")
1632 (set_attr "mode" "<MODEF:MODE>")
1633 (set_attr "prefix_rep" "*,0")
1634 (set (attr "prefix_data16")
1635 (cond [(eq_attr "alternative" "0")
1636 (const_string "*")
1637 (eq_attr "mode" "DF")
1638 (const_string "1")
1639 ]
1640 (const_string "0")))
1641 (set_attr "athlon_decode" "vector")
1642 (set_attr "amdfam10_decode" "direct")
1643 (set_attr "bdver1_decode" "double")
1644 (set_attr "znver1_decode" "double")
1645 (set (attr "enabled")
1646 (if_then_else
1647 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1648 (if_then_else
1649 (eq_attr "alternative" "0")
1650 (symbol_ref "TARGET_MIX_SSE_I387")
1651 (symbol_ref "true"))
1652 (if_then_else
1653 (eq_attr "alternative" "0")
1654 (symbol_ref "true")
1655 (symbol_ref "false"))))])
1656 \f
1657 ;; Push/pop instructions.
1658
1659 (define_insn "*push<mode>2"
1660 [(set (match_operand:DWI 0 "push_operand" "=<")
1661 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1662 ""
1663 "#"
1664 [(set_attr "type" "multi")
1665 (set_attr "mode" "<MODE>")])
1666
1667 (define_split
1668 [(set (match_operand:DWI 0 "push_operand")
1669 (match_operand:DWI 1 "general_gr_operand"))]
1670 "reload_completed"
1671 [(const_int 0)]
1672 "ix86_split_long_move (operands); DONE;")
1673
1674 (define_insn "*pushdi2_rex64"
1675 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1676 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1677 "TARGET_64BIT"
1678 "@
1679 push{q}\t%1
1680 #"
1681 [(set_attr "type" "push,multi")
1682 (set_attr "mode" "DI")])
1683
1684 ;; Convert impossible pushes of immediate to existing instructions.
1685 ;; First try to get scratch register and go through it. In case this
1686 ;; fails, push sign extended lower part first and then overwrite
1687 ;; upper part by 32bit move.
1688 (define_peephole2
1689 [(match_scratch:DI 2 "r")
1690 (set (match_operand:DI 0 "push_operand")
1691 (match_operand:DI 1 "immediate_operand"))]
1692 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1693 && !x86_64_immediate_operand (operands[1], DImode)"
1694 [(set (match_dup 2) (match_dup 1))
1695 (set (match_dup 0) (match_dup 2))])
1696
1697 ;; We need to define this as both peepholer and splitter for case
1698 ;; peephole2 pass is not run.
1699 ;; "&& 1" is needed to keep it from matching the previous pattern.
1700 (define_peephole2
1701 [(set (match_operand:DI 0 "push_operand")
1702 (match_operand:DI 1 "immediate_operand"))]
1703 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1704 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1705 [(set (match_dup 0) (match_dup 1))
1706 (set (match_dup 2) (match_dup 3))]
1707 {
1708 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1709
1710 operands[1] = gen_lowpart (DImode, operands[2]);
1711 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1712 GEN_INT (4)));
1713 })
1714
1715 (define_split
1716 [(set (match_operand:DI 0 "push_operand")
1717 (match_operand:DI 1 "immediate_operand"))]
1718 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1719 ? epilogue_completed : reload_completed)
1720 && !symbolic_operand (operands[1], DImode)
1721 && !x86_64_immediate_operand (operands[1], DImode)"
1722 [(set (match_dup 0) (match_dup 1))
1723 (set (match_dup 2) (match_dup 3))]
1724 {
1725 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1726
1727 operands[1] = gen_lowpart (DImode, operands[2]);
1728 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1729 GEN_INT (4)));
1730 })
1731
1732 (define_insn "*pushsi2"
1733 [(set (match_operand:SI 0 "push_operand" "=<")
1734 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1735 "!TARGET_64BIT"
1736 "push{l}\t%1"
1737 [(set_attr "type" "push")
1738 (set_attr "mode" "SI")])
1739
1740 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1741 ;; "push a byte/word". But actually we use pushl, which has the effect
1742 ;; of rounding the amount pushed up to a word.
1743
1744 ;; For TARGET_64BIT we always round up to 8 bytes.
1745 (define_insn "*push<mode>2_rex64"
1746 [(set (match_operand:SWI124 0 "push_operand" "=X")
1747 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1748 "TARGET_64BIT"
1749 "push{q}\t%q1"
1750 [(set_attr "type" "push")
1751 (set_attr "mode" "DI")])
1752
1753 (define_insn "*push<mode>2"
1754 [(set (match_operand:SWI12 0 "push_operand" "=X")
1755 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1756 "!TARGET_64BIT"
1757 "push{l}\t%k1"
1758 [(set_attr "type" "push")
1759 (set_attr "mode" "SI")])
1760
1761 (define_insn "*push<mode>2_prologue"
1762 [(set (match_operand:W 0 "push_operand" "=<")
1763 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1764 (clobber (mem:BLK (scratch)))]
1765 ""
1766 "push{<imodesuffix>}\t%1"
1767 [(set_attr "type" "push")
1768 (set_attr "mode" "<MODE>")])
1769
1770 (define_insn "*pop<mode>1"
1771 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1772 (match_operand:W 1 "pop_operand" ">"))]
1773 ""
1774 "pop{<imodesuffix>}\t%0"
1775 [(set_attr "type" "pop")
1776 (set_attr "mode" "<MODE>")])
1777
1778 (define_insn "*pop<mode>1_epilogue"
1779 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1780 (match_operand:W 1 "pop_operand" ">"))
1781 (clobber (mem:BLK (scratch)))]
1782 ""
1783 "pop{<imodesuffix>}\t%0"
1784 [(set_attr "type" "pop")
1785 (set_attr "mode" "<MODE>")])
1786
1787 (define_insn "*pushfl<mode>2"
1788 [(set (match_operand:W 0 "push_operand" "=<")
1789 (match_operand:W 1 "flags_reg_operand"))]
1790 ""
1791 "pushf{<imodesuffix>}"
1792 [(set_attr "type" "push")
1793 (set_attr "mode" "<MODE>")])
1794
1795 (define_insn "*popfl<mode>1"
1796 [(set (match_operand:W 0 "flags_reg_operand")
1797 (match_operand:W 1 "pop_operand" ">"))]
1798 ""
1799 "popf{<imodesuffix>}"
1800 [(set_attr "type" "pop")
1801 (set_attr "mode" "<MODE>")])
1802
1803 \f
1804 ;; Reload patterns to support multi-word load/store
1805 ;; with non-offsetable address.
1806 (define_expand "reload_noff_store"
1807 [(parallel [(match_operand 0 "memory_operand" "=m")
1808 (match_operand 1 "register_operand" "r")
1809 (match_operand:DI 2 "register_operand" "=&r")])]
1810 "TARGET_64BIT"
1811 {
1812 rtx mem = operands[0];
1813 rtx addr = XEXP (mem, 0);
1814
1815 emit_move_insn (operands[2], addr);
1816 mem = replace_equiv_address_nv (mem, operands[2]);
1817
1818 emit_insn (gen_rtx_SET (mem, operands[1]));
1819 DONE;
1820 })
1821
1822 (define_expand "reload_noff_load"
1823 [(parallel [(match_operand 0 "register_operand" "=r")
1824 (match_operand 1 "memory_operand" "m")
1825 (match_operand:DI 2 "register_operand" "=r")])]
1826 "TARGET_64BIT"
1827 {
1828 rtx mem = operands[1];
1829 rtx addr = XEXP (mem, 0);
1830
1831 emit_move_insn (operands[2], addr);
1832 mem = replace_equiv_address_nv (mem, operands[2]);
1833
1834 emit_insn (gen_rtx_SET (operands[0], mem));
1835 DONE;
1836 })
1837
1838 ;; Move instructions.
1839
1840 (define_expand "movxi"
1841 [(set (match_operand:XI 0 "nonimmediate_operand")
1842 (match_operand:XI 1 "general_operand"))]
1843 "TARGET_AVX512F"
1844 "ix86_expand_vector_move (XImode, operands); DONE;")
1845
1846 (define_expand "movoi"
1847 [(set (match_operand:OI 0 "nonimmediate_operand")
1848 (match_operand:OI 1 "general_operand"))]
1849 "TARGET_AVX"
1850 "ix86_expand_vector_move (OImode, operands); DONE;")
1851
1852 (define_expand "movti"
1853 [(set (match_operand:TI 0 "nonimmediate_operand")
1854 (match_operand:TI 1 "general_operand"))]
1855 "TARGET_64BIT || TARGET_SSE"
1856 {
1857 if (TARGET_64BIT)
1858 ix86_expand_move (TImode, operands);
1859 else
1860 ix86_expand_vector_move (TImode, operands);
1861 DONE;
1862 })
1863
1864 ;; This expands to what emit_move_complex would generate if we didn't
1865 ;; have a movti pattern. Having this avoids problems with reload on
1866 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1867 ;; to have around all the time.
1868 (define_expand "movcdi"
1869 [(set (match_operand:CDI 0 "nonimmediate_operand")
1870 (match_operand:CDI 1 "general_operand"))]
1871 ""
1872 {
1873 if (push_operand (operands[0], CDImode))
1874 emit_move_complex_push (CDImode, operands[0], operands[1]);
1875 else
1876 emit_move_complex_parts (operands[0], operands[1]);
1877 DONE;
1878 })
1879
1880 (define_expand "mov<mode>"
1881 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1882 (match_operand:SWI1248x 1 "general_operand"))]
1883 ""
1884 "ix86_expand_move (<MODE>mode, operands); DONE;")
1885
1886 (define_insn "*mov<mode>_xor"
1887 [(set (match_operand:SWI48 0 "register_operand" "=r")
1888 (match_operand:SWI48 1 "const0_operand"))
1889 (clobber (reg:CC FLAGS_REG))]
1890 "reload_completed"
1891 "xor{l}\t%k0, %k0"
1892 [(set_attr "type" "alu1")
1893 (set_attr "mode" "SI")
1894 (set_attr "length_immediate" "0")])
1895
1896 (define_insn "*mov<mode>_or"
1897 [(set (match_operand:SWI48 0 "register_operand" "=r")
1898 (match_operand:SWI48 1 "constm1_operand"))
1899 (clobber (reg:CC FLAGS_REG))]
1900 "reload_completed"
1901 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1902 [(set_attr "type" "alu1")
1903 (set_attr "mode" "<MODE>")
1904 (set_attr "length_immediate" "1")])
1905
1906 (define_insn "*movxi_internal_avx512f"
1907 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1908 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1909 "TARGET_AVX512F
1910 && (register_operand (operands[0], XImode)
1911 || register_operand (operands[1], XImode))"
1912 {
1913 switch (get_attr_type (insn))
1914 {
1915 case TYPE_SSELOG1:
1916 return standard_sse_constant_opcode (insn, operands);
1917
1918 case TYPE_SSEMOV:
1919 if (misaligned_operand (operands[0], XImode)
1920 || misaligned_operand (operands[1], XImode))
1921 return "vmovdqu32\t{%1, %0|%0, %1}";
1922 else
1923 return "vmovdqa32\t{%1, %0|%0, %1}";
1924
1925 default:
1926 gcc_unreachable ();
1927 }
1928 }
1929 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1930 (set_attr "prefix" "evex")
1931 (set_attr "mode" "XI")])
1932
1933 (define_insn "*movoi_internal_avx"
1934 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1935 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1936 "TARGET_AVX
1937 && (register_operand (operands[0], OImode)
1938 || register_operand (operands[1], OImode))"
1939 {
1940 switch (get_attr_type (insn))
1941 {
1942 case TYPE_SSELOG1:
1943 return standard_sse_constant_opcode (insn, operands);
1944
1945 case TYPE_SSEMOV:
1946 if (misaligned_operand (operands[0], OImode)
1947 || misaligned_operand (operands[1], OImode))
1948 {
1949 if (get_attr_mode (insn) == MODE_V8SF)
1950 return "vmovups\t{%1, %0|%0, %1}";
1951 else if (get_attr_mode (insn) == MODE_XI)
1952 return "vmovdqu32\t{%1, %0|%0, %1}";
1953 else
1954 return "vmovdqu\t{%1, %0|%0, %1}";
1955 }
1956 else
1957 {
1958 if (get_attr_mode (insn) == MODE_V8SF)
1959 return "vmovaps\t{%1, %0|%0, %1}";
1960 else if (get_attr_mode (insn) == MODE_XI)
1961 return "vmovdqa32\t{%1, %0|%0, %1}";
1962 else
1963 return "vmovdqa\t{%1, %0|%0, %1}";
1964 }
1965
1966 default:
1967 gcc_unreachable ();
1968 }
1969 }
1970 [(set_attr "isa" "*,avx2,*,*")
1971 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1972 (set_attr "prefix" "vex")
1973 (set (attr "mode")
1974 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1975 (match_operand 1 "ext_sse_reg_operand"))
1976 (const_string "XI")
1977 (and (eq_attr "alternative" "1")
1978 (match_test "TARGET_AVX512VL"))
1979 (const_string "XI")
1980 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1981 (and (eq_attr "alternative" "3")
1982 (match_test "TARGET_SSE_TYPELESS_STORES")))
1983 (const_string "V8SF")
1984 ]
1985 (const_string "OI")))])
1986
1987 (define_insn "*movti_internal"
1988 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1989 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
1990 "(TARGET_64BIT
1991 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1992 || (TARGET_SSE
1993 && nonimmediate_or_sse_const_operand (operands[1], TImode)
1994 && (register_operand (operands[0], TImode)
1995 || register_operand (operands[1], TImode)))"
1996 {
1997 switch (get_attr_type (insn))
1998 {
1999 case TYPE_MULTI:
2000 return "#";
2001
2002 case TYPE_SSELOG1:
2003 return standard_sse_constant_opcode (insn, operands);
2004
2005 case TYPE_SSEMOV:
2006 /* TDmode values are passed as TImode on the stack. Moving them
2007 to stack may result in unaligned memory access. */
2008 if (misaligned_operand (operands[0], TImode)
2009 || misaligned_operand (operands[1], TImode))
2010 {
2011 if (get_attr_mode (insn) == MODE_V4SF)
2012 return "%vmovups\t{%1, %0|%0, %1}";
2013 else if (get_attr_mode (insn) == MODE_XI)
2014 return "vmovdqu32\t{%1, %0|%0, %1}";
2015 else
2016 return "%vmovdqu\t{%1, %0|%0, %1}";
2017 }
2018 else
2019 {
2020 if (get_attr_mode (insn) == MODE_V4SF)
2021 return "%vmovaps\t{%1, %0|%0, %1}";
2022 else if (get_attr_mode (insn) == MODE_XI)
2023 return "vmovdqa32\t{%1, %0|%0, %1}";
2024 else
2025 return "%vmovdqa\t{%1, %0|%0, %1}";
2026 }
2027
2028 default:
2029 gcc_unreachable ();
2030 }
2031 }
2032 [(set (attr "isa")
2033 (cond [(eq_attr "alternative" "0,1,6,7")
2034 (const_string "x64")
2035 (eq_attr "alternative" "3")
2036 (const_string "sse2")
2037 ]
2038 (const_string "*")))
2039 (set (attr "type")
2040 (cond [(eq_attr "alternative" "0,1,6,7")
2041 (const_string "multi")
2042 (eq_attr "alternative" "2,3")
2043 (const_string "sselog1")
2044 ]
2045 (const_string "ssemov")))
2046 (set (attr "prefix")
2047 (if_then_else (eq_attr "type" "sselog1,ssemov")
2048 (const_string "maybe_vex")
2049 (const_string "orig")))
2050 (set (attr "mode")
2051 (cond [(eq_attr "alternative" "0,1")
2052 (const_string "DI")
2053 (ior (match_operand 0 "ext_sse_reg_operand")
2054 (match_operand 1 "ext_sse_reg_operand"))
2055 (const_string "XI")
2056 (and (eq_attr "alternative" "3")
2057 (match_test "TARGET_AVX512VL"))
2058 (const_string "XI")
2059 (ior (not (match_test "TARGET_SSE2"))
2060 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2061 (and (eq_attr "alternative" "5")
2062 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2063 (const_string "V4SF")
2064 (match_test "TARGET_AVX")
2065 (const_string "TI")
2066 (match_test "optimize_function_for_size_p (cfun)")
2067 (const_string "V4SF")
2068 ]
2069 (const_string "TI")))
2070 (set (attr "preferred_for_speed")
2071 (cond [(eq_attr "alternative" "6")
2072 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2073 (eq_attr "alternative" "7")
2074 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2075 ]
2076 (symbol_ref "true")))])
2077
2078 (define_split
2079 [(set (match_operand:TI 0 "sse_reg_operand")
2080 (match_operand:TI 1 "general_reg_operand"))]
2081 "TARGET_64BIT && TARGET_SSE4_1
2082 && reload_completed"
2083 [(set (match_dup 2)
2084 (vec_merge:V2DI
2085 (vec_duplicate:V2DI (match_dup 3))
2086 (match_dup 2)
2087 (const_int 2)))]
2088 {
2089 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2090 operands[3] = gen_highpart (DImode, operands[1]);
2091
2092 emit_move_insn (gen_lowpart (DImode, operands[0]),
2093 gen_lowpart (DImode, operands[1]));
2094 })
2095
2096 (define_insn "*movdi_internal"
2097 [(set (match_operand:DI 0 "nonimmediate_operand"
2098 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k")
2099 (match_operand:DI 1 "general_operand"
2100 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k,CBC"))]
2101 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2102 {
2103 switch (get_attr_type (insn))
2104 {
2105 case TYPE_MSKMOV:
2106 return "kmovq\t{%1, %0|%0, %1}";
2107
2108 case TYPE_MSKLOG:
2109 if (operands[1] == const0_rtx)
2110 return "kxorq\t%0, %0, %0";
2111 else if (operands[1] == constm1_rtx)
2112 return "kxnorq\t%0, %0, %0";
2113 gcc_unreachable ();
2114
2115 case TYPE_MULTI:
2116 return "#";
2117
2118 case TYPE_MMX:
2119 return "pxor\t%0, %0";
2120
2121 case TYPE_MMXMOV:
2122 /* Handle broken assemblers that require movd instead of movq. */
2123 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2124 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2125 return "movd\t{%1, %0|%0, %1}";
2126 return "movq\t{%1, %0|%0, %1}";
2127
2128 case TYPE_SSELOG1:
2129 return standard_sse_constant_opcode (insn, operands);
2130
2131 case TYPE_SSEMOV:
2132 switch (get_attr_mode (insn))
2133 {
2134 case MODE_DI:
2135 /* Handle broken assemblers that require movd instead of movq. */
2136 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2137 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2138 return "%vmovd\t{%1, %0|%0, %1}";
2139 return "%vmovq\t{%1, %0|%0, %1}";
2140
2141 case MODE_TI:
2142 /* Handle AVX512 registers set. */
2143 if (EXT_REX_SSE_REG_P (operands[0])
2144 || EXT_REX_SSE_REG_P (operands[1]))
2145 return "vmovdqa64\t{%1, %0|%0, %1}";
2146 return "%vmovdqa\t{%1, %0|%0, %1}";
2147
2148 case MODE_V2SF:
2149 gcc_assert (!TARGET_AVX);
2150 return "movlps\t{%1, %0|%0, %1}";
2151 case MODE_V4SF:
2152 return "%vmovaps\t{%1, %0|%0, %1}";
2153
2154 default:
2155 gcc_unreachable ();
2156 }
2157
2158 case TYPE_SSECVT:
2159 if (SSE_REG_P (operands[0]))
2160 return "movq2dq\t{%1, %0|%0, %1}";
2161 else
2162 return "movdq2q\t{%1, %0|%0, %1}";
2163
2164 case TYPE_LEA:
2165 return "lea{q}\t{%E1, %0|%0, %E1}";
2166
2167 case TYPE_IMOV:
2168 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2169 if (get_attr_mode (insn) == MODE_SI)
2170 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2171 else if (which_alternative == 4)
2172 return "movabs{q}\t{%1, %0|%0, %1}";
2173 else if (ix86_use_lea_for_mov (insn, operands))
2174 return "lea{q}\t{%E1, %0|%0, %E1}";
2175 else
2176 return "mov{q}\t{%1, %0|%0, %1}";
2177
2178 default:
2179 gcc_unreachable ();
2180 }
2181 }
2182 [(set (attr "isa")
2183 (cond [(eq_attr "alternative" "0,1,17,18")
2184 (const_string "nox64")
2185 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2186 (const_string "x64")
2187 (eq_attr "alternative" "19,20")
2188 (const_string "x64_sse2")
2189 (eq_attr "alternative" "21,22")
2190 (const_string "sse2")
2191 ]
2192 (const_string "*")))
2193 (set (attr "type")
2194 (cond [(eq_attr "alternative" "0,1,17,18")
2195 (const_string "multi")
2196 (eq_attr "alternative" "6")
2197 (const_string "mmx")
2198 (eq_attr "alternative" "7,8,9,10,11")
2199 (const_string "mmxmov")
2200 (eq_attr "alternative" "12")
2201 (const_string "sselog1")
2202 (eq_attr "alternative" "13,14,15,16,19,20")
2203 (const_string "ssemov")
2204 (eq_attr "alternative" "21,22")
2205 (const_string "ssecvt")
2206 (eq_attr "alternative" "23,24,25,26")
2207 (const_string "mskmov")
2208 (eq_attr "alternative" "27")
2209 (const_string "msklog")
2210 (and (match_operand 0 "register_operand")
2211 (match_operand 1 "pic_32bit_operand"))
2212 (const_string "lea")
2213 ]
2214 (const_string "imov")))
2215 (set (attr "modrm")
2216 (if_then_else
2217 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2218 (const_string "0")
2219 (const_string "*")))
2220 (set (attr "length_immediate")
2221 (if_then_else
2222 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2223 (const_string "8")
2224 (const_string "*")))
2225 (set (attr "prefix_rex")
2226 (if_then_else
2227 (eq_attr "alternative" "10,11,19,20")
2228 (const_string "1")
2229 (const_string "*")))
2230 (set (attr "prefix")
2231 (if_then_else (eq_attr "type" "sselog1,ssemov")
2232 (const_string "maybe_vex")
2233 (const_string "orig")))
2234 (set (attr "prefix_data16")
2235 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2236 (const_string "1")
2237 (const_string "*")))
2238 (set (attr "mode")
2239 (cond [(eq_attr "alternative" "2")
2240 (const_string "SI")
2241 (eq_attr "alternative" "12,13")
2242 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2243 (match_operand 1 "ext_sse_reg_operand"))
2244 (const_string "TI")
2245 (ior (not (match_test "TARGET_SSE2"))
2246 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2247 (const_string "V4SF")
2248 (match_test "TARGET_AVX")
2249 (const_string "TI")
2250 (match_test "optimize_function_for_size_p (cfun)")
2251 (const_string "V4SF")
2252 ]
2253 (const_string "TI"))
2254
2255 (and (eq_attr "alternative" "14,15,16")
2256 (not (match_test "TARGET_SSE2")))
2257 (const_string "V2SF")
2258 ]
2259 (const_string "DI")))
2260 (set (attr "preferred_for_speed")
2261 (cond [(eq_attr "alternative" "10,17,19")
2262 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2263 (eq_attr "alternative" "11,18,20")
2264 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2265 ]
2266 (symbol_ref "true")))
2267 (set (attr "enabled")
2268 (cond [(eq_attr "alternative" "15")
2269 (if_then_else
2270 (match_test "TARGET_STV && TARGET_SSE2")
2271 (symbol_ref "false")
2272 (const_string "*"))
2273 (eq_attr "alternative" "16")
2274 (if_then_else
2275 (match_test "TARGET_STV && TARGET_SSE2")
2276 (symbol_ref "true")
2277 (symbol_ref "false"))
2278 ]
2279 (const_string "*")))])
2280
2281 (define_split
2282 [(set (match_operand:<DWI> 0 "general_reg_operand")
2283 (match_operand:<DWI> 1 "sse_reg_operand"))]
2284 "TARGET_SSE4_1
2285 && reload_completed"
2286 [(set (match_dup 2)
2287 (vec_select:DWIH
2288 (match_dup 3)
2289 (parallel [(const_int 1)])))]
2290 {
2291 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2292 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2293
2294 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2295 gen_lowpart (<MODE>mode, operands[1]));
2296 })
2297
2298 (define_split
2299 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2300 (match_operand:DWI 1 "general_gr_operand"))]
2301 "reload_completed"
2302 [(const_int 0)]
2303 "ix86_split_long_move (operands); DONE;")
2304
2305 (define_split
2306 [(set (match_operand:DI 0 "sse_reg_operand")
2307 (match_operand:DI 1 "general_reg_operand"))]
2308 "!TARGET_64BIT && TARGET_SSE4_1
2309 && reload_completed"
2310 [(set (match_dup 2)
2311 (vec_merge:V4SI
2312 (vec_duplicate:V4SI (match_dup 3))
2313 (match_dup 2)
2314 (const_int 2)))]
2315 {
2316 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2317 operands[3] = gen_highpart (SImode, operands[1]);
2318
2319 emit_move_insn (gen_lowpart (SImode, operands[0]),
2320 gen_lowpart (SImode, operands[1]));
2321 })
2322
2323 ;; movabsq $0x0012345678000000, %rax is longer
2324 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2325 (define_peephole2
2326 [(set (match_operand:DI 0 "register_operand")
2327 (match_operand:DI 1 "const_int_operand"))]
2328 "TARGET_64BIT
2329 && optimize_insn_for_size_p ()
2330 && LEGACY_INT_REG_P (operands[0])
2331 && !x86_64_immediate_operand (operands[1], DImode)
2332 && !x86_64_zext_immediate_operand (operands[1], DImode)
2333 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2334 & ~(HOST_WIDE_INT) 0xffffffff)
2335 && peep2_regno_dead_p (0, FLAGS_REG)"
2336 [(set (match_dup 0) (match_dup 1))
2337 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2338 (clobber (reg:CC FLAGS_REG))])]
2339 {
2340 int shift = ctz_hwi (UINTVAL (operands[1]));
2341 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2342 operands[2] = gen_int_mode (shift, QImode);
2343 })
2344
2345 (define_insn "*movsi_internal"
2346 [(set (match_operand:SI 0 "nonimmediate_operand"
2347 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2348 (match_operand:SI 1 "general_operand"
2349 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
2350 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2351 {
2352 switch (get_attr_type (insn))
2353 {
2354 case TYPE_SSELOG1:
2355 return standard_sse_constant_opcode (insn, operands);
2356
2357 case TYPE_MSKMOV:
2358 return "kmovd\t{%1, %0|%0, %1}";
2359
2360 case TYPE_MSKLOG:
2361 if (operands[1] == const0_rtx)
2362 return "kxord\t%0, %0, %0";
2363 else if (operands[1] == constm1_rtx)
2364 return "kxnord\t%0, %0, %0";
2365 gcc_unreachable ();
2366
2367 case TYPE_SSEMOV:
2368 switch (get_attr_mode (insn))
2369 {
2370 case MODE_SI:
2371 return "%vmovd\t{%1, %0|%0, %1}";
2372 case MODE_TI:
2373 return "%vmovdqa\t{%1, %0|%0, %1}";
2374 case MODE_XI:
2375 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2376
2377 case MODE_V4SF:
2378 return "%vmovaps\t{%1, %0|%0, %1}";
2379
2380 case MODE_SF:
2381 gcc_assert (!TARGET_AVX);
2382 return "movss\t{%1, %0|%0, %1}";
2383
2384 default:
2385 gcc_unreachable ();
2386 }
2387
2388 case TYPE_MMX:
2389 return "pxor\t%0, %0";
2390
2391 case TYPE_MMXMOV:
2392 switch (get_attr_mode (insn))
2393 {
2394 case MODE_DI:
2395 return "movq\t{%1, %0|%0, %1}";
2396 case MODE_SI:
2397 return "movd\t{%1, %0|%0, %1}";
2398
2399 default:
2400 gcc_unreachable ();
2401 }
2402
2403 case TYPE_LEA:
2404 return "lea{l}\t{%E1, %0|%0, %E1}";
2405
2406 case TYPE_IMOV:
2407 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2408 if (ix86_use_lea_for_mov (insn, operands))
2409 return "lea{l}\t{%E1, %0|%0, %E1}";
2410 else
2411 return "mov{l}\t{%1, %0|%0, %1}";
2412
2413 default:
2414 gcc_unreachable ();
2415 }
2416 }
2417 [(set (attr "isa")
2418 (cond [(eq_attr "alternative" "12,13")
2419 (const_string "sse2")
2420 ]
2421 (const_string "*")))
2422 (set (attr "type")
2423 (cond [(eq_attr "alternative" "2")
2424 (const_string "mmx")
2425 (eq_attr "alternative" "3,4,5,6,7")
2426 (const_string "mmxmov")
2427 (eq_attr "alternative" "8")
2428 (const_string "sselog1")
2429 (eq_attr "alternative" "9,10,11,12,13")
2430 (const_string "ssemov")
2431 (eq_attr "alternative" "14,15,16")
2432 (const_string "mskmov")
2433 (eq_attr "alternative" "17")
2434 (const_string "msklog")
2435 (and (match_operand 0 "register_operand")
2436 (match_operand 1 "pic_32bit_operand"))
2437 (const_string "lea")
2438 ]
2439 (const_string "imov")))
2440 (set (attr "prefix")
2441 (if_then_else (eq_attr "type" "sselog1,ssemov")
2442 (const_string "maybe_vex")
2443 (const_string "orig")))
2444 (set (attr "prefix_data16")
2445 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2446 (const_string "1")
2447 (const_string "*")))
2448 (set (attr "mode")
2449 (cond [(eq_attr "alternative" "2,3")
2450 (const_string "DI")
2451 (eq_attr "alternative" "8,9")
2452 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2453 (match_operand 1 "ext_sse_reg_operand"))
2454 (const_string "XI")
2455 (ior (not (match_test "TARGET_SSE2"))
2456 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2457 (const_string "V4SF")
2458 (match_test "TARGET_AVX")
2459 (const_string "TI")
2460 (match_test "optimize_function_for_size_p (cfun)")
2461 (const_string "V4SF")
2462 ]
2463 (const_string "TI"))
2464
2465 (and (eq_attr "alternative" "10,11")
2466 (not (match_test "TARGET_SSE2")))
2467 (const_string "SF")
2468 ]
2469 (const_string "SI")))
2470 (set (attr "preferred_for_speed")
2471 (cond [(eq_attr "alternative" "6,12")
2472 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2473 (eq_attr "alternative" "7,13")
2474 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2475 ]
2476 (symbol_ref "true")))])
2477
2478 (define_insn "*movhi_internal"
2479 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k")
2480 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k,CBC"))]
2481 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482 {
2483 switch (get_attr_type (insn))
2484 {
2485 case TYPE_IMOVX:
2486 /* movzwl is faster than movw on p2 due to partial word stalls,
2487 though not as fast as an aligned movl. */
2488 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2489
2490 case TYPE_MSKMOV:
2491 switch (which_alternative)
2492 {
2493 case 4:
2494 return "kmovw\t{%k1, %0|%0, %k1}";
2495 case 6:
2496 return "kmovw\t{%1, %k0|%k0, %1}";
2497 case 5:
2498 case 7:
2499 return "kmovw\t{%1, %0|%0, %1}";
2500 default:
2501 gcc_unreachable ();
2502 }
2503
2504 case TYPE_MSKLOG:
2505 if (operands[1] == const0_rtx)
2506 return "kxorw\t%0, %0, %0";
2507 else if (operands[1] == constm1_rtx)
2508 return "kxnorw\t%0, %0, %0";
2509 gcc_unreachable ();
2510
2511 default:
2512 if (get_attr_mode (insn) == MODE_SI)
2513 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2514 else
2515 return "mov{w}\t{%1, %0|%0, %1}";
2516 }
2517 }
2518 [(set (attr "type")
2519 (cond [(eq_attr "alternative" "4,5,6,7")
2520 (const_string "mskmov")
2521 (eq_attr "alternative" "8")
2522 (const_string "msklog")
2523 (match_test "optimize_function_for_size_p (cfun)")
2524 (const_string "imov")
2525 (and (eq_attr "alternative" "0")
2526 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2527 (not (match_test "TARGET_HIMODE_MATH"))))
2528 (const_string "imov")
2529 (and (eq_attr "alternative" "1,2")
2530 (match_operand:HI 1 "aligned_operand"))
2531 (const_string "imov")
2532 (and (match_test "TARGET_MOVX")
2533 (eq_attr "alternative" "0,2"))
2534 (const_string "imovx")
2535 ]
2536 (const_string "imov")))
2537 (set (attr "prefix")
2538 (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2539 (const_string "vex")
2540 (const_string "orig")))
2541 (set (attr "mode")
2542 (cond [(eq_attr "type" "imovx")
2543 (const_string "SI")
2544 (and (eq_attr "alternative" "1,2")
2545 (match_operand:HI 1 "aligned_operand"))
2546 (const_string "SI")
2547 (and (eq_attr "alternative" "0")
2548 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2549 (not (match_test "TARGET_HIMODE_MATH"))))
2550 (const_string "SI")
2551 ]
2552 (const_string "HI")))])
2553
2554 ;; Situation is quite tricky about when to choose full sized (SImode) move
2555 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2556 ;; partial register dependency machines (such as AMD Athlon), where QImode
2557 ;; moves issue extra dependency and for partial register stalls machines
2558 ;; that don't use QImode patterns (and QImode move cause stall on the next
2559 ;; instruction).
2560 ;;
2561 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2562 ;; register stall machines with, where we use QImode instructions, since
2563 ;; partial register stall can be caused there. Then we use movzx.
2564
2565 (define_insn "*movqi_internal"
2566 [(set (match_operand:QI 0 "nonimmediate_operand"
2567 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k")
2568 (match_operand:QI 1 "general_operand"
2569 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))]
2570 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2571 {
2572 char buf[128];
2573 const char *ops;
2574 const char *suffix;
2575
2576 switch (get_attr_type (insn))
2577 {
2578 case TYPE_IMOVX:
2579 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2580 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2581
2582 case TYPE_MSKMOV:
2583 switch (which_alternative)
2584 {
2585 case 9:
2586 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2587 break;
2588 case 11:
2589 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2590 break;
2591 case 12:
2592 case 13:
2593 gcc_assert (TARGET_AVX512DQ);
2594 /* FALLTHRU */
2595 case 10:
2596 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2597 break;
2598 default:
2599 gcc_unreachable ();
2600 }
2601
2602 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2603
2604 snprintf (buf, sizeof (buf), ops, suffix);
2605 output_asm_insn (buf, operands);
2606 return "";
2607
2608 case TYPE_MSKLOG:
2609 if (operands[1] == const0_rtx)
2610 {
2611 if (get_attr_mode (insn) == MODE_HI)
2612 return "kxorw\t%0, %0, %0";
2613 else
2614 return "kxorb\t%0, %0, %0";
2615 }
2616 else if (operands[1] == constm1_rtx)
2617 {
2618 gcc_assert (TARGET_AVX512DQ);
2619 return "kxnorb\t%0, %0, %0";
2620 }
2621 gcc_unreachable ();
2622
2623 default:
2624 if (get_attr_mode (insn) == MODE_SI)
2625 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2626 else
2627 return "mov{b}\t{%1, %0|%0, %1}";
2628 }
2629 }
2630 [(set (attr "isa")
2631 (cond [(eq_attr "alternative" "1,2")
2632 (const_string "x64")
2633 (eq_attr "alternative" "12,13,15")
2634 (const_string "avx512dq")
2635 ]
2636 (const_string "*")))
2637 (set (attr "type")
2638 (cond [(eq_attr "alternative" "9,10,11,12,13")
2639 (const_string "mskmov")
2640 (eq_attr "alternative" "14,15")
2641 (const_string "msklog")
2642 (and (eq_attr "alternative" "7")
2643 (not (match_operand:QI 1 "aligned_operand")))
2644 (const_string "imovx")
2645 (match_test "optimize_function_for_size_p (cfun)")
2646 (const_string "imov")
2647 (and (eq_attr "alternative" "5")
2648 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2649 (not (match_test "TARGET_QIMODE_MATH"))))
2650 (const_string "imov")
2651 (eq_attr "alternative" "5,7")
2652 (const_string "imovx")
2653 (and (match_test "TARGET_MOVX")
2654 (eq_attr "alternative" "4"))
2655 (const_string "imovx")
2656 ]
2657 (const_string "imov")))
2658 (set (attr "prefix")
2659 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2660 (const_string "vex")
2661 (const_string "orig")))
2662 (set (attr "mode")
2663 (cond [(eq_attr "alternative" "5,6,7")
2664 (const_string "SI")
2665 (eq_attr "alternative" "8")
2666 (const_string "QI")
2667 (and (eq_attr "alternative" "9,10,11,14")
2668 (not (match_test "TARGET_AVX512DQ")))
2669 (const_string "HI")
2670 (eq_attr "type" "imovx")
2671 (const_string "SI")
2672 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2673 ;; ones.
2674 (and (eq_attr "type" "imov")
2675 (and (eq_attr "alternative" "3")
2676 (match_test "optimize_function_for_size_p (cfun)")))
2677 (const_string "QI")
2678 ;; For -Os, movl where one or both operands are NON_Q_REGS
2679 ;; and both are LEGACY_REGS is shorter than movb.
2680 ;; Otherwise movb and movl sizes are the same, so decide purely
2681 ;; based on speed factors.
2682 (and (eq_attr "type" "imov")
2683 (and (eq_attr "alternative" "1")
2684 (match_test "optimize_function_for_size_p (cfun)")))
2685 (const_string "SI")
2686 (and (eq_attr "type" "imov")
2687 (and (eq_attr "alternative" "0,1,2,3")
2688 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2689 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2690 (const_string "SI")
2691 ;; Avoid partial register stalls when not using QImode arithmetic
2692 (and (eq_attr "type" "imov")
2693 (and (eq_attr "alternative" "0,1,2,3")
2694 (and (match_test "TARGET_PARTIAL_REG_STALL")
2695 (not (match_test "TARGET_QIMODE_MATH")))))
2696 (const_string "SI")
2697 ]
2698 (const_string "QI")))])
2699
2700 ;; Stores and loads of ax to arbitrary constant address.
2701 ;; We fake an second form of instruction to force reload to load address
2702 ;; into register when rax is not available
2703 (define_insn "*movabs<mode>_1"
2704 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2705 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2706 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2707 {
2708 /* Recover the full memory rtx. */
2709 operands[0] = SET_DEST (PATTERN (insn));
2710 switch (which_alternative)
2711 {
2712 case 0:
2713 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2714 case 1:
2715 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2716 default:
2717 gcc_unreachable ();
2718 }
2719 }
2720 [(set_attr "type" "imov")
2721 (set_attr "modrm" "0,*")
2722 (set_attr "length_address" "8,0")
2723 (set_attr "length_immediate" "0,*")
2724 (set_attr "memory" "store")
2725 (set_attr "mode" "<MODE>")])
2726
2727 (define_insn "*movabs<mode>_2"
2728 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2729 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2730 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2731 {
2732 /* Recover the full memory rtx. */
2733 operands[1] = SET_SRC (PATTERN (insn));
2734 switch (which_alternative)
2735 {
2736 case 0:
2737 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2738 case 1:
2739 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2740 default:
2741 gcc_unreachable ();
2742 }
2743 }
2744 [(set_attr "type" "imov")
2745 (set_attr "modrm" "0,*")
2746 (set_attr "length_address" "8,0")
2747 (set_attr "length_immediate" "0")
2748 (set_attr "memory" "load")
2749 (set_attr "mode" "<MODE>")])
2750
2751 (define_insn "*swap<mode>"
2752 [(set (match_operand:SWI48 0 "register_operand" "+r")
2753 (match_operand:SWI48 1 "register_operand" "+r"))
2754 (set (match_dup 1)
2755 (match_dup 0))]
2756 ""
2757 "xchg{<imodesuffix>}\t%1, %0"
2758 [(set_attr "type" "imov")
2759 (set_attr "mode" "<MODE>")
2760 (set_attr "pent_pair" "np")
2761 (set_attr "athlon_decode" "vector")
2762 (set_attr "amdfam10_decode" "double")
2763 (set_attr "bdver1_decode" "double")])
2764
2765 (define_insn "*swap<mode>"
2766 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2767 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2768 (set (match_dup 1)
2769 (match_dup 0))]
2770 ""
2771 "@
2772 xchg{<imodesuffix>}\t%1, %0
2773 xchg{l}\t%k1, %k0"
2774 [(set_attr "type" "imov")
2775 (set_attr "mode" "<MODE>,SI")
2776 (set (attr "preferred_for_size")
2777 (cond [(eq_attr "alternative" "0")
2778 (symbol_ref "false")]
2779 (symbol_ref "true")))
2780 ;; Potential partial reg stall on alternative 1.
2781 (set (attr "preferred_for_speed")
2782 (cond [(eq_attr "alternative" "1")
2783 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2784 (symbol_ref "true")))
2785 (set_attr "pent_pair" "np")
2786 (set_attr "athlon_decode" "vector")
2787 (set_attr "amdfam10_decode" "double")
2788 (set_attr "bdver1_decode" "double")])
2789
2790 (define_peephole2
2791 [(set (match_operand:SWI 0 "general_reg_operand")
2792 (match_operand:SWI 1 "general_reg_operand"))
2793 (set (match_dup 1)
2794 (match_operand:SWI 2 "general_reg_operand"))
2795 (set (match_dup 2) (match_dup 0))]
2796 "peep2_reg_dead_p (3, operands[0])
2797 && optimize_insn_for_size_p ()"
2798 [(parallel [(set (match_dup 1) (match_dup 2))
2799 (set (match_dup 2) (match_dup 1))])])
2800
2801 (define_expand "movstrict<mode>"
2802 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
2803 (match_operand:SWI12 1 "general_operand"))]
2804 ""
2805 {
2806 gcc_assert (SUBREG_P (operands[0]));
2807 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2808 || GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2809 FAIL;
2810 })
2811
2812 (define_insn "*movstrict<mode>_1"
2813 [(set (strict_low_part
2814 (match_operand:SWI12 0 "register_operand" "+<r>"))
2815 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
2816 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2817 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2818 [(set_attr "type" "imov")
2819 (set_attr "mode" "<MODE>")])
2820
2821 (define_insn "*movstrict<mode>_xor"
2822 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2823 (match_operand:SWI12 1 "const0_operand"))
2824 (clobber (reg:CC FLAGS_REG))]
2825 "reload_completed"
2826 "xor{<imodesuffix>}\t%0, %0"
2827 [(set_attr "type" "alu1")
2828 (set_attr "mode" "<MODE>")
2829 (set_attr "length_immediate" "0")])
2830
2831 (define_expand "extv<mode>"
2832 [(set (match_operand:SWI24 0 "register_operand")
2833 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2834 (match_operand:SI 2 "const_int_operand")
2835 (match_operand:SI 3 "const_int_operand")))]
2836 ""
2837 {
2838 /* Handle extractions from %ah et al. */
2839 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2840 FAIL;
2841
2842 unsigned int regno = reg_or_subregno (operands[1]);
2843
2844 /* Be careful to expand only with registers having upper parts. */
2845 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2846 operands[1] = copy_to_reg (operands[1]);
2847 })
2848
2849 (define_insn "*extv<mode>"
2850 [(set (match_operand:SWI24 0 "register_operand" "=R")
2851 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2852 (const_int 8)
2853 (const_int 8)))]
2854 ""
2855 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2856 [(set_attr "type" "imovx")
2857 (set_attr "mode" "SI")])
2858
2859 (define_expand "extzv<mode>"
2860 [(set (match_operand:SWI248 0 "register_operand")
2861 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2862 (match_operand:SI 2 "const_int_operand")
2863 (match_operand:SI 3 "const_int_operand")))]
2864 ""
2865 {
2866 if (ix86_expand_pextr (operands))
2867 DONE;
2868
2869 /* Handle extractions from %ah et al. */
2870 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2871 FAIL;
2872
2873 unsigned int regno = reg_or_subregno (operands[1]);
2874
2875 /* Be careful to expand only with registers having upper parts. */
2876 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2877 operands[1] = copy_to_reg (operands[1]);
2878 })
2879
2880 (define_insn "*extzvqi_mem_rex64"
2881 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2882 (subreg:QI
2883 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2884 (const_int 8)
2885 (const_int 8)) 0))]
2886 "TARGET_64BIT && reload_completed"
2887 "mov{b}\t{%h1, %0|%0, %h1}"
2888 [(set_attr "type" "imov")
2889 (set_attr "mode" "QI")])
2890
2891 (define_insn "*extzv<mode>"
2892 [(set (match_operand:SWI248 0 "register_operand" "=R")
2893 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2894 (const_int 8)
2895 (const_int 8)))]
2896 ""
2897 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2898 [(set_attr "type" "imovx")
2899 (set_attr "mode" "SI")])
2900
2901 (define_insn "*extzvqi"
2902 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2903 (subreg:QI
2904 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2905 (const_int 8)
2906 (const_int 8)) 0))]
2907 ""
2908 {
2909 switch (get_attr_type (insn))
2910 {
2911 case TYPE_IMOVX:
2912 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2913 default:
2914 return "mov{b}\t{%h1, %0|%0, %h1}";
2915 }
2916 }
2917 [(set_attr "isa" "*,*,nox64")
2918 (set (attr "type")
2919 (if_then_else (and (match_operand:QI 0 "register_operand")
2920 (ior (not (match_operand:QI 0 "QIreg_operand"))
2921 (match_test "TARGET_MOVX")))
2922 (const_string "imovx")
2923 (const_string "imov")))
2924 (set (attr "mode")
2925 (if_then_else (eq_attr "type" "imovx")
2926 (const_string "SI")
2927 (const_string "QI")))])
2928
2929 (define_peephole2
2930 [(set (match_operand:QI 0 "register_operand")
2931 (subreg:QI
2932 (zero_extract:SI (match_operand 1 "ext_register_operand")
2933 (const_int 8)
2934 (const_int 8)) 0))
2935 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2936 "TARGET_64BIT
2937 && peep2_reg_dead_p (2, operands[0])"
2938 [(set (match_dup 2)
2939 (subreg:QI
2940 (zero_extract:SI (match_dup 1)
2941 (const_int 8)
2942 (const_int 8)) 0))])
2943
2944 (define_expand "insv<mode>"
2945 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2946 (match_operand:SI 1 "const_int_operand")
2947 (match_operand:SI 2 "const_int_operand"))
2948 (match_operand:SWI248 3 "register_operand"))]
2949 ""
2950 {
2951 rtx dst;
2952
2953 if (ix86_expand_pinsr (operands))
2954 DONE;
2955
2956 /* Handle insertions to %ah et al. */
2957 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2958 FAIL;
2959
2960 unsigned int regno = reg_or_subregno (operands[0]);
2961
2962 /* Be careful to expand only with registers having upper parts. */
2963 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2964 dst = copy_to_reg (operands[0]);
2965 else
2966 dst = operands[0];
2967
2968 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2969
2970 /* Fix up the destination if needed. */
2971 if (dst != operands[0])
2972 emit_move_insn (operands[0], dst);
2973
2974 DONE;
2975 })
2976
2977 (define_insn "*insvqi_1_mem_rex64"
2978 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2979 (const_int 8)
2980 (const_int 8))
2981 (subreg:SI
2982 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2983 "TARGET_64BIT && reload_completed"
2984 "mov{b}\t{%1, %h0|%h0, %1}"
2985 [(set_attr "type" "imov")
2986 (set_attr "mode" "QI")])
2987
2988 (define_insn "insv<mode>_1"
2989 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2990 (const_int 8)
2991 (const_int 8))
2992 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2993 ""
2994 {
2995 if (CONST_INT_P (operands[1]))
2996 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2997 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2998 }
2999 [(set_attr "isa" "*,nox64")
3000 (set_attr "type" "imov")
3001 (set_attr "mode" "QI")])
3002
3003 (define_insn "*insvqi_1"
3004 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3005 (const_int 8)
3006 (const_int 8))
3007 (subreg:SI
3008 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3009 ""
3010 "mov{b}\t{%1, %h0|%h0, %1}"
3011 [(set_attr "isa" "*,nox64")
3012 (set_attr "type" "imov")
3013 (set_attr "mode" "QI")])
3014
3015 (define_peephole2
3016 [(set (match_operand:QI 0 "register_operand")
3017 (match_operand:QI 1 "norex_memory_operand"))
3018 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3019 (const_int 8)
3020 (const_int 8))
3021 (subreg:SI (match_dup 0) 0))]
3022 "TARGET_64BIT
3023 && peep2_reg_dead_p (2, operands[0])"
3024 [(set (zero_extract:SI (match_dup 2)
3025 (const_int 8)
3026 (const_int 8))
3027 (subreg:SI (match_dup 1) 0))])
3028
3029 (define_code_iterator any_extract [sign_extract zero_extract])
3030
3031 (define_insn "*insvqi_2"
3032 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3033 (const_int 8)
3034 (const_int 8))
3035 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3036 (const_int 8)
3037 (const_int 8)))]
3038 ""
3039 "mov{b}\t{%h1, %h0|%h0, %h1}"
3040 [(set_attr "type" "imov")
3041 (set_attr "mode" "QI")])
3042
3043 (define_insn "*insvqi_3"
3044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3045 (const_int 8)
3046 (const_int 8))
3047 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3048 (const_int 8)))]
3049 ""
3050 "mov{b}\t{%h1, %h0|%h0, %h1}"
3051 [(set_attr "type" "imov")
3052 (set_attr "mode" "QI")])
3053 \f
3054 ;; Floating point push instructions.
3055
3056 (define_insn "*pushtf"
3057 [(set (match_operand:TF 0 "push_operand" "=<,<")
3058 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3059 "TARGET_64BIT || TARGET_SSE"
3060 {
3061 /* This insn should be already split before reg-stack. */
3062 gcc_unreachable ();
3063 }
3064 [(set_attr "isa" "*,x64")
3065 (set_attr "type" "multi")
3066 (set_attr "unit" "sse,*")
3067 (set_attr "mode" "TF,DI")])
3068
3069 ;; %%% Kill this when call knows how to work this out.
3070 (define_split
3071 [(set (match_operand:TF 0 "push_operand")
3072 (match_operand:TF 1 "sse_reg_operand"))]
3073 "TARGET_SSE && reload_completed"
3074 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3075 (set (match_dup 0) (match_dup 1))]
3076 {
3077 /* Preserve memory attributes. */
3078 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3079 })
3080
3081 (define_insn_and_split "*pushxf_rounded"
3082 [(set (mem:XF
3083 (pre_modify:P
3084 (reg:P SP_REG)
3085 (plus:P (reg:P SP_REG) (const_int -16))))
3086 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3087 "TARGET_64BIT"
3088 "#"
3089 "&& 1"
3090 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3091 (set (match_dup 1) (match_dup 0))]
3092 {
3093 rtx pat = PATTERN (curr_insn);
3094 operands[1] = SET_DEST (pat);
3095
3096 /* Preserve memory attributes. */
3097 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3098 }
3099 [(set_attr "type" "multi")
3100 (set_attr "unit" "i387,*,*,*")
3101 (set (attr "mode")
3102 (cond [(eq_attr "alternative" "1,2,3")
3103 (const_string "DI")
3104 ]
3105 (const_string "XF")))
3106 (set (attr "preferred_for_size")
3107 (cond [(eq_attr "alternative" "1")
3108 (symbol_ref "false")]
3109 (symbol_ref "true")))])
3110
3111 (define_insn "*pushxf"
3112 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3113 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3114 ""
3115 {
3116 /* This insn should be already split before reg-stack. */
3117 gcc_unreachable ();
3118 }
3119 [(set_attr "isa" "*,*,*,nox64,x64")
3120 (set_attr "type" "multi")
3121 (set_attr "unit" "i387,*,*,*,*")
3122 (set (attr "mode")
3123 (cond [(eq_attr "alternative" "1,2,3,4")
3124 (if_then_else (match_test "TARGET_64BIT")
3125 (const_string "DI")
3126 (const_string "SI"))
3127 ]
3128 (const_string "XF")))
3129 (set (attr "preferred_for_size")
3130 (cond [(eq_attr "alternative" "1")
3131 (symbol_ref "false")]
3132 (symbol_ref "true")))])
3133
3134 ;; %%% Kill this when call knows how to work this out.
3135 (define_split
3136 [(set (match_operand:XF 0 "push_operand")
3137 (match_operand:XF 1 "fp_register_operand"))]
3138 "reload_completed"
3139 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3140 (set (match_dup 0) (match_dup 1))]
3141 {
3142 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3143 /* Preserve memory attributes. */
3144 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3145 })
3146
3147 (define_insn "*pushdf"
3148 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3149 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3150 ""
3151 {
3152 /* This insn should be already split before reg-stack. */
3153 gcc_unreachable ();
3154 }
3155 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3156 (set_attr "type" "multi")
3157 (set_attr "unit" "i387,*,*,*,*,sse")
3158 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3159 (set (attr "preferred_for_size")
3160 (cond [(eq_attr "alternative" "1")
3161 (symbol_ref "false")]
3162 (symbol_ref "true")))
3163 (set (attr "preferred_for_speed")
3164 (cond [(eq_attr "alternative" "1")
3165 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3166 (symbol_ref "true")))])
3167
3168 ;; %%% Kill this when call knows how to work this out.
3169 (define_split
3170 [(set (match_operand:DF 0 "push_operand")
3171 (match_operand:DF 1 "any_fp_register_operand"))]
3172 "reload_completed"
3173 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3174 (set (match_dup 0) (match_dup 1))]
3175 {
3176 /* Preserve memory attributes. */
3177 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3178 })
3179
3180 (define_insn "*pushsf_rex64"
3181 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3182 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3183 "TARGET_64BIT"
3184 {
3185 /* Anything else should be already split before reg-stack. */
3186 gcc_assert (which_alternative == 1);
3187 return "push{q}\t%q1";
3188 }
3189 [(set_attr "type" "multi,push,multi")
3190 (set_attr "unit" "i387,*,*")
3191 (set_attr "mode" "SF,DI,SF")])
3192
3193 (define_insn "*pushsf"
3194 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3195 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3196 "!TARGET_64BIT"
3197 {
3198 /* Anything else should be already split before reg-stack. */
3199 gcc_assert (which_alternative == 1);
3200 return "push{l}\t%1";
3201 }
3202 [(set_attr "type" "multi,push,multi")
3203 (set_attr "unit" "i387,*,*")
3204 (set_attr "mode" "SF,SI,SF")])
3205
3206 ;; %%% Kill this when call knows how to work this out.
3207 (define_split
3208 [(set (match_operand:SF 0 "push_operand")
3209 (match_operand:SF 1 "any_fp_register_operand"))]
3210 "reload_completed"
3211 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3212 (set (match_dup 0) (match_dup 1))]
3213 {
3214 rtx op = XEXP (operands[0], 0);
3215 if (GET_CODE (op) == PRE_DEC)
3216 {
3217 gcc_assert (!TARGET_64BIT);
3218 op = GEN_INT (-4);
3219 }
3220 else
3221 {
3222 op = XEXP (XEXP (op, 1), 1);
3223 gcc_assert (CONST_INT_P (op));
3224 }
3225 operands[2] = op;
3226 /* Preserve memory attributes. */
3227 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3228 })
3229
3230 (define_split
3231 [(set (match_operand:SF 0 "push_operand")
3232 (match_operand:SF 1 "memory_operand"))]
3233 "reload_completed
3234 && find_constant_src (insn)"
3235 [(set (match_dup 0) (match_dup 2))]
3236 "operands[2] = find_constant_src (curr_insn);")
3237
3238 (define_split
3239 [(set (match_operand 0 "push_operand")
3240 (match_operand 1 "general_gr_operand"))]
3241 "reload_completed
3242 && (GET_MODE (operands[0]) == TFmode
3243 || GET_MODE (operands[0]) == XFmode
3244 || GET_MODE (operands[0]) == DFmode)"
3245 [(const_int 0)]
3246 "ix86_split_long_move (operands); DONE;")
3247 \f
3248 ;; Floating point move instructions.
3249
3250 (define_expand "movtf"
3251 [(set (match_operand:TF 0 "nonimmediate_operand")
3252 (match_operand:TF 1 "nonimmediate_operand"))]
3253 "TARGET_64BIT || TARGET_SSE"
3254 "ix86_expand_move (TFmode, operands); DONE;")
3255
3256 (define_expand "mov<mode>"
3257 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3258 (match_operand:X87MODEF 1 "general_operand"))]
3259 ""
3260 "ix86_expand_move (<MODE>mode, operands); DONE;")
3261
3262 (define_insn "*movtf_internal"
3263 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3264 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3265 "(TARGET_64BIT || TARGET_SSE)
3266 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3267 && (lra_in_progress || reload_completed
3268 || !CONST_DOUBLE_P (operands[1])
3269 || ((optimize_function_for_size_p (cfun)
3270 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3271 && standard_sse_constant_p (operands[1], TFmode) == 1
3272 && !memory_operand (operands[0], TFmode))
3273 || (!TARGET_MEMORY_MISMATCH_STALL
3274 && memory_operand (operands[0], TFmode)))"
3275 {
3276 switch (get_attr_type (insn))
3277 {
3278 case TYPE_SSELOG1:
3279 return standard_sse_constant_opcode (insn, operands);
3280
3281 case TYPE_SSEMOV:
3282 /* Handle misaligned load/store since we
3283 don't have movmisaligntf pattern. */
3284 if (misaligned_operand (operands[0], TFmode)
3285 || misaligned_operand (operands[1], TFmode))
3286 {
3287 if (get_attr_mode (insn) == MODE_V4SF)
3288 return "%vmovups\t{%1, %0|%0, %1}";
3289 else if (TARGET_AVX512VL
3290 && (EXT_REX_SSE_REG_P (operands[0])
3291 || EXT_REX_SSE_REG_P (operands[1])))
3292 return "vmovdqu64\t{%1, %0|%0, %1}";
3293 else
3294 return "%vmovdqu\t{%1, %0|%0, %1}";
3295 }
3296 else
3297 {
3298 if (get_attr_mode (insn) == MODE_V4SF)
3299 return "%vmovaps\t{%1, %0|%0, %1}";
3300 else if (TARGET_AVX512VL
3301 && (EXT_REX_SSE_REG_P (operands[0])
3302 || EXT_REX_SSE_REG_P (operands[1])))
3303 return "vmovdqa64\t{%1, %0|%0, %1}";
3304 else
3305 return "%vmovdqa\t{%1, %0|%0, %1}";
3306 }
3307
3308 case TYPE_MULTI:
3309 return "#";
3310
3311 default:
3312 gcc_unreachable ();
3313 }
3314 }
3315 [(set_attr "isa" "*,*,*,x64,x64")
3316 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3317 (set (attr "prefix")
3318 (if_then_else (eq_attr "type" "sselog1,ssemov")
3319 (const_string "maybe_vex")
3320 (const_string "orig")))
3321 (set (attr "mode")
3322 (cond [(eq_attr "alternative" "3,4")
3323 (const_string "DI")
3324 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3325 (const_string "V4SF")
3326 (and (eq_attr "alternative" "2")
3327 (match_test "TARGET_SSE_TYPELESS_STORES"))
3328 (const_string "V4SF")
3329 (match_test "TARGET_AVX")
3330 (const_string "TI")
3331 (ior (not (match_test "TARGET_SSE2"))
3332 (match_test "optimize_function_for_size_p (cfun)"))
3333 (const_string "V4SF")
3334 ]
3335 (const_string "TI")))])
3336
3337 (define_split
3338 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3339 (match_operand:TF 1 "general_gr_operand"))]
3340 "reload_completed"
3341 [(const_int 0)]
3342 "ix86_split_long_move (operands); DONE;")
3343
3344 ;; Possible store forwarding (partial memory) stall
3345 ;; in alternatives 4, 6, 7 and 8.
3346 (define_insn "*movxf_internal"
3347 [(set (match_operand:XF 0 "nonimmediate_operand"
3348 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3349 (match_operand:XF 1 "general_operand"
3350 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3351 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3352 && (lra_in_progress || reload_completed
3353 || !CONST_DOUBLE_P (operands[1])
3354 || ((optimize_function_for_size_p (cfun)
3355 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3356 && standard_80387_constant_p (operands[1]) > 0
3357 && !memory_operand (operands[0], XFmode))
3358 || (!TARGET_MEMORY_MISMATCH_STALL
3359 && memory_operand (operands[0], XFmode))
3360 || !TARGET_HARD_XF_REGS)"
3361 {
3362 switch (get_attr_type (insn))
3363 {
3364 case TYPE_FMOV:
3365 if (which_alternative == 2)
3366 return standard_80387_constant_opcode (operands[1]);
3367 return output_387_reg_move (insn, operands);
3368
3369 case TYPE_MULTI:
3370 return "#";
3371
3372 default:
3373 gcc_unreachable ();
3374 }
3375 }
3376 [(set (attr "isa")
3377 (cond [(eq_attr "alternative" "7,10")
3378 (const_string "nox64")
3379 (eq_attr "alternative" "8,11")
3380 (const_string "x64")
3381 ]
3382 (const_string "*")))
3383 (set (attr "type")
3384 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3385 (const_string "multi")
3386 ]
3387 (const_string "fmov")))
3388 (set (attr "mode")
3389 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3390 (if_then_else (match_test "TARGET_64BIT")
3391 (const_string "DI")
3392 (const_string "SI"))
3393 ]
3394 (const_string "XF")))
3395 (set (attr "preferred_for_size")
3396 (cond [(eq_attr "alternative" "3,4")
3397 (symbol_ref "false")]
3398 (symbol_ref "true")))
3399 (set (attr "enabled")
3400 (cond [(eq_attr "alternative" "9,10,11")
3401 (if_then_else
3402 (match_test "TARGET_HARD_XF_REGS")
3403 (symbol_ref "false")
3404 (const_string "*"))
3405 (not (match_test "TARGET_HARD_XF_REGS"))
3406 (symbol_ref "false")
3407 ]
3408 (const_string "*")))])
3409
3410 (define_split
3411 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3412 (match_operand:XF 1 "general_gr_operand"))]
3413 "reload_completed"
3414 [(const_int 0)]
3415 "ix86_split_long_move (operands); DONE;")
3416
3417 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3418 (define_insn "*movdf_internal"
3419 [(set (match_operand:DF 0 "nonimmediate_operand"
3420 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r ,o ,r ,m")
3421 (match_operand:DF 1 "general_operand"
3422 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))]
3423 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3424 && (lra_in_progress || reload_completed
3425 || !CONST_DOUBLE_P (operands[1])
3426 || ((optimize_function_for_size_p (cfun)
3427 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3428 && ((IS_STACK_MODE (DFmode)
3429 && standard_80387_constant_p (operands[1]) > 0)
3430 || (TARGET_SSE2 && TARGET_SSE_MATH
3431 && standard_sse_constant_p (operands[1], DFmode) == 1))
3432 && !memory_operand (operands[0], DFmode))
3433 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3434 && memory_operand (operands[0], DFmode))
3435 || !TARGET_HARD_DF_REGS)"
3436 {
3437 switch (get_attr_type (insn))
3438 {
3439 case TYPE_FMOV:
3440 if (which_alternative == 2)
3441 return standard_80387_constant_opcode (operands[1]);
3442 return output_387_reg_move (insn, operands);
3443
3444 case TYPE_MULTI:
3445 return "#";
3446
3447 case TYPE_IMOV:
3448 if (get_attr_mode (insn) == MODE_SI)
3449 return "mov{l}\t{%1, %k0|%k0, %1}";
3450 else if (which_alternative == 11)
3451 return "movabs{q}\t{%1, %0|%0, %1}";
3452 else
3453 return "mov{q}\t{%1, %0|%0, %1}";
3454
3455 case TYPE_SSELOG1:
3456 return standard_sse_constant_opcode (insn, operands);
3457
3458 case TYPE_SSEMOV:
3459 switch (get_attr_mode (insn))
3460 {
3461 case MODE_DF:
3462 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3463 return "vmovsd\t{%d1, %0|%0, %d1}";
3464 return "%vmovsd\t{%1, %0|%0, %1}";
3465
3466 case MODE_V4SF:
3467 return "%vmovaps\t{%1, %0|%0, %1}";
3468 case MODE_V8DF:
3469 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3470 case MODE_V2DF:
3471 return "%vmovapd\t{%1, %0|%0, %1}";
3472
3473 case MODE_V2SF:
3474 gcc_assert (!TARGET_AVX);
3475 return "movlps\t{%1, %0|%0, %1}";
3476 case MODE_V1DF:
3477 gcc_assert (!TARGET_AVX);
3478 return "movlpd\t{%1, %0|%0, %1}";
3479
3480 case MODE_DI:
3481 /* Handle broken assemblers that require movd instead of movq. */
3482 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3483 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3484 return "%vmovd\t{%1, %0|%0, %1}";
3485 return "%vmovq\t{%1, %0|%0, %1}";
3486
3487 default:
3488 gcc_unreachable ();
3489 }
3490
3491 default:
3492 gcc_unreachable ();
3493 }
3494 }
3495 [(set (attr "isa")
3496 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3497 (const_string "nox64")
3498 (eq_attr "alternative" "8,9,10,11,24,25")
3499 (const_string "x64")
3500 (eq_attr "alternative" "12,13,14,15")
3501 (const_string "sse2")
3502 (eq_attr "alternative" "20,21")
3503 (const_string "x64_sse2")
3504 ]
3505 (const_string "*")))
3506 (set (attr "type")
3507 (cond [(eq_attr "alternative" "0,1,2")
3508 (const_string "fmov")
3509 (eq_attr "alternative" "3,4,5,6,7,22,23")
3510 (const_string "multi")
3511 (eq_attr "alternative" "8,9,10,11,24,25")
3512 (const_string "imov")
3513 (eq_attr "alternative" "12,16")
3514 (const_string "sselog1")
3515 ]
3516 (const_string "ssemov")))
3517 (set (attr "modrm")
3518 (if_then_else (eq_attr "alternative" "11")
3519 (const_string "0")
3520 (const_string "*")))
3521 (set (attr "length_immediate")
3522 (if_then_else (eq_attr "alternative" "11")
3523 (const_string "8")
3524 (const_string "*")))
3525 (set (attr "prefix")
3526 (if_then_else (eq_attr "type" "sselog1,ssemov")
3527 (const_string "maybe_vex")
3528 (const_string "orig")))
3529 (set (attr "prefix_data16")
3530 (if_then_else
3531 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3532 (eq_attr "mode" "V1DF"))
3533 (const_string "1")
3534 (const_string "*")))
3535 (set (attr "mode")
3536 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3537 (const_string "SI")
3538 (eq_attr "alternative" "8,9,11,20,21,24,25")
3539 (const_string "DI")
3540
3541 /* xorps is one byte shorter for non-AVX targets. */
3542 (eq_attr "alternative" "12,16")
3543 (cond [(not (match_test "TARGET_SSE2"))
3544 (const_string "V4SF")
3545 (and (match_test "TARGET_AVX512F")
3546 (not (match_test "TARGET_PREFER_AVX256")))
3547 (const_string "XI")
3548 (match_test "TARGET_AVX")
3549 (const_string "V2DF")
3550 (match_test "optimize_function_for_size_p (cfun)")
3551 (const_string "V4SF")
3552 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3553 (const_string "TI")
3554 ]
3555 (const_string "V2DF"))
3556
3557 /* For architectures resolving dependencies on
3558 whole SSE registers use movapd to break dependency
3559 chains, otherwise use short move to avoid extra work. */
3560
3561 /* movaps is one byte shorter for non-AVX targets. */
3562 (eq_attr "alternative" "13,17")
3563 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3564 (not (match_test "TARGET_AVX512VL")))
3565 (ior (match_operand 0 "ext_sse_reg_operand")
3566 (match_operand 1 "ext_sse_reg_operand")))
3567 (const_string "V8DF")
3568 (ior (not (match_test "TARGET_SSE2"))
3569 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3570 (const_string "V4SF")
3571 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3572 (const_string "V2DF")
3573 (match_test "TARGET_AVX")
3574 (const_string "DF")
3575 (match_test "optimize_function_for_size_p (cfun)")
3576 (const_string "V4SF")
3577 ]
3578 (const_string "DF"))
3579
3580 /* For architectures resolving dependencies on register
3581 parts we may avoid extra work to zero out upper part
3582 of register. */
3583 (eq_attr "alternative" "14,18")
3584 (cond [(not (match_test "TARGET_SSE2"))
3585 (const_string "V2SF")
3586 (match_test "TARGET_AVX")
3587 (const_string "DF")
3588 (match_test "TARGET_SSE_SPLIT_REGS")
3589 (const_string "V1DF")
3590 ]
3591 (const_string "DF"))
3592
3593 (and (eq_attr "alternative" "15,19")
3594 (not (match_test "TARGET_SSE2")))
3595 (const_string "V2SF")
3596 ]
3597 (const_string "DF")))
3598 (set (attr "preferred_for_size")
3599 (cond [(eq_attr "alternative" "3,4")
3600 (symbol_ref "false")]
3601 (symbol_ref "true")))
3602 (set (attr "preferred_for_speed")
3603 (cond [(eq_attr "alternative" "3,4")
3604 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3605 (eq_attr "alternative" "20")
3606 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3607 (eq_attr "alternative" "21")
3608 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3609 ]
3610 (symbol_ref "true")))
3611 (set (attr "enabled")
3612 (cond [(eq_attr "alternative" "22,23,24,25")
3613 (if_then_else
3614 (match_test "TARGET_HARD_DF_REGS")
3615 (symbol_ref "false")
3616 (const_string "*"))
3617 (not (match_test "TARGET_HARD_DF_REGS"))
3618 (symbol_ref "false")
3619 ]
3620 (const_string "*")))])
3621
3622 (define_split
3623 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3624 (match_operand:DF 1 "general_gr_operand"))]
3625 "!TARGET_64BIT && reload_completed"
3626 [(const_int 0)]
3627 "ix86_split_long_move (operands); DONE;")
3628
3629 (define_insn "*movsf_internal"
3630 [(set (match_operand:SF 0 "nonimmediate_operand"
3631 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3632 (match_operand:SF 1 "general_operand"
3633 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3634 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3635 && (lra_in_progress || reload_completed
3636 || !CONST_DOUBLE_P (operands[1])
3637 || ((optimize_function_for_size_p (cfun)
3638 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3639 && ((IS_STACK_MODE (SFmode)
3640 && standard_80387_constant_p (operands[1]) > 0)
3641 || (TARGET_SSE && TARGET_SSE_MATH
3642 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3643 || memory_operand (operands[0], SFmode)
3644 || !TARGET_HARD_SF_REGS)"
3645 {
3646 switch (get_attr_type (insn))
3647 {
3648 case TYPE_FMOV:
3649 if (which_alternative == 2)
3650 return standard_80387_constant_opcode (operands[1]);
3651 return output_387_reg_move (insn, operands);
3652
3653 case TYPE_IMOV:
3654 return "mov{l}\t{%1, %0|%0, %1}";
3655
3656 case TYPE_SSELOG1:
3657 return standard_sse_constant_opcode (insn, operands);
3658
3659 case TYPE_SSEMOV:
3660 switch (get_attr_mode (insn))
3661 {
3662 case MODE_SF:
3663 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3664 return "vmovss\t{%d1, %0|%0, %d1}";
3665 return "%vmovss\t{%1, %0|%0, %1}";
3666
3667 case MODE_V16SF:
3668 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3669 case MODE_V4SF:
3670 return "%vmovaps\t{%1, %0|%0, %1}";
3671
3672 case MODE_SI:
3673 return "%vmovd\t{%1, %0|%0, %1}";
3674
3675 default:
3676 gcc_unreachable ();
3677 }
3678
3679 case TYPE_MMXMOV:
3680 switch (get_attr_mode (insn))
3681 {
3682 case MODE_DI:
3683 return "movq\t{%1, %0|%0, %1}";
3684 case MODE_SI:
3685 return "movd\t{%1, %0|%0, %1}";
3686
3687 default:
3688 gcc_unreachable ();
3689 }
3690
3691 default:
3692 gcc_unreachable ();
3693 }
3694 }
3695 [(set (attr "isa")
3696 (cond [(eq_attr "alternative" "14,15")
3697 (const_string "sse2")
3698 ]
3699 (const_string "*")))
3700 (set (attr "type")
3701 (cond [(eq_attr "alternative" "0,1,2")
3702 (const_string "fmov")
3703 (eq_attr "alternative" "3,4,16,17")
3704 (const_string "imov")
3705 (eq_attr "alternative" "5")
3706 (const_string "sselog1")
3707 (eq_attr "alternative" "11,12,13,14,15")
3708 (const_string "mmxmov")
3709 ]
3710 (const_string "ssemov")))
3711 (set (attr "prefix")
3712 (if_then_else (eq_attr "type" "sselog1,ssemov")
3713 (const_string "maybe_vex")
3714 (const_string "orig")))
3715 (set (attr "prefix_data16")
3716 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3717 (const_string "1")
3718 (const_string "*")))
3719 (set (attr "mode")
3720 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3721 (const_string "SI")
3722 (eq_attr "alternative" "11")
3723 (const_string "DI")
3724 (eq_attr "alternative" "5")
3725 (cond [(not (match_test "TARGET_SSE2"))
3726 (const_string "V4SF")
3727 (and (match_test "TARGET_AVX512F")
3728 (not (match_test "TARGET_PREFER_AVX256")))
3729 (const_string "V16SF")
3730 (match_test "TARGET_AVX")
3731 (const_string "V4SF")
3732 (match_test "optimize_function_for_size_p (cfun)")
3733 (const_string "V4SF")
3734 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3735 (const_string "TI")
3736 ]
3737 (const_string "V4SF"))
3738
3739 /* For architectures resolving dependencies on
3740 whole SSE registers use APS move to break dependency
3741 chains, otherwise use short move to avoid extra work.
3742
3743 Do the same for architectures resolving dependencies on
3744 the parts. While in DF mode it is better to always handle
3745 just register parts, the SF mode is different due to lack
3746 of instructions to load just part of the register. It is
3747 better to maintain the whole registers in single format
3748 to avoid problems on using packed logical operations. */
3749 (eq_attr "alternative" "6")
3750 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3751 (not (match_test "TARGET_AVX512VL")))
3752 (ior (match_operand 0 "ext_sse_reg_operand")
3753 (match_operand 1 "ext_sse_reg_operand")))
3754 (const_string "V16SF")
3755 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3756 (match_test "TARGET_SSE_SPLIT_REGS"))
3757 (const_string "V4SF")
3758 ]
3759 (const_string "SF"))
3760 ]
3761 (const_string "SF")))
3762 (set (attr "preferred_for_speed")
3763 (cond [(eq_attr "alternative" "9,14")
3764 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3765 (eq_attr "alternative" "10,15")
3766 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3767 ]
3768 (symbol_ref "true")))
3769 (set (attr "enabled")
3770 (cond [(eq_attr "alternative" "16,17")
3771 (if_then_else
3772 (match_test "TARGET_HARD_SF_REGS")
3773 (symbol_ref "false")
3774 (const_string "*"))
3775 (not (match_test "TARGET_HARD_SF_REGS"))
3776 (symbol_ref "false")
3777 ]
3778 (const_string "*")))])
3779
3780 (define_split
3781 [(set (match_operand 0 "any_fp_register_operand")
3782 (match_operand 1 "memory_operand"))]
3783 "reload_completed
3784 && (GET_MODE (operands[0]) == TFmode
3785 || GET_MODE (operands[0]) == XFmode
3786 || GET_MODE (operands[0]) == DFmode
3787 || GET_MODE (operands[0]) == SFmode)
3788 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3789 [(set (match_dup 0) (match_dup 2))]
3790 "operands[2] = find_constant_src (curr_insn);")
3791
3792 (define_split
3793 [(set (match_operand 0 "any_fp_register_operand")
3794 (float_extend (match_operand 1 "memory_operand")))]
3795 "reload_completed
3796 && (GET_MODE (operands[0]) == TFmode
3797 || GET_MODE (operands[0]) == XFmode
3798 || GET_MODE (operands[0]) == DFmode)
3799 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3800 [(set (match_dup 0) (match_dup 2))]
3801 "operands[2] = find_constant_src (curr_insn);")
3802
3803 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3804 (define_split
3805 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3806 (match_operand:X87MODEF 1 "immediate_operand"))]
3807 "reload_completed
3808 && (standard_80387_constant_p (operands[1]) == 8
3809 || standard_80387_constant_p (operands[1]) == 9)"
3810 [(set (match_dup 0)(match_dup 1))
3811 (set (match_dup 0)
3812 (neg:X87MODEF (match_dup 0)))]
3813 {
3814 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3815 operands[1] = CONST0_RTX (<MODE>mode);
3816 else
3817 operands[1] = CONST1_RTX (<MODE>mode);
3818 })
3819
3820 (define_insn "*swapxf"
3821 [(set (match_operand:XF 0 "register_operand" "+f")
3822 (match_operand:XF 1 "register_operand" "+f"))
3823 (set (match_dup 1)
3824 (match_dup 0))]
3825 "TARGET_80387"
3826 {
3827 if (STACK_TOP_P (operands[0]))
3828 return "fxch\t%1";
3829 else
3830 return "fxch\t%0";
3831 }
3832 [(set_attr "type" "fxch")
3833 (set_attr "mode" "XF")])
3834 \f
3835
3836 ;; Zero extension instructions
3837
3838 (define_expand "zero_extendsidi2"
3839 [(set (match_operand:DI 0 "nonimmediate_operand")
3840 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3841
3842 (define_insn "*zero_extendsidi2"
3843 [(set (match_operand:DI 0 "nonimmediate_operand"
3844 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3845 (zero_extend:DI
3846 (match_operand:SI 1 "x86_64_zext_operand"
3847 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
3848 ""
3849 {
3850 switch (get_attr_type (insn))
3851 {
3852 case TYPE_IMOVX:
3853 if (ix86_use_lea_for_mov (insn, operands))
3854 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3855 else
3856 return "mov{l}\t{%1, %k0|%k0, %1}";
3857
3858 case TYPE_MULTI:
3859 return "#";
3860
3861 case TYPE_MMXMOV:
3862 return "movd\t{%1, %0|%0, %1}";
3863
3864 case TYPE_SSEMOV:
3865 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3866 {
3867 if (EXT_REX_SSE_REG_P (operands[0])
3868 || EXT_REX_SSE_REG_P (operands[1]))
3869 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3870 else
3871 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3872 }
3873
3874 if (GENERAL_REG_P (operands[0]))
3875 return "%vmovd\t{%1, %k0|%k0, %1}";
3876
3877 return "%vmovd\t{%1, %0|%0, %1}";
3878
3879 case TYPE_MSKMOV:
3880 return "kmovd\t{%1, %k0|%k0, %1}";
3881
3882 default:
3883 gcc_unreachable ();
3884 }
3885 }
3886 [(set (attr "isa")
3887 (cond [(eq_attr "alternative" "0,1,2")
3888 (const_string "nox64")
3889 (eq_attr "alternative" "3")
3890 (const_string "x64")
3891 (eq_attr "alternative" "7,8,9")
3892 (const_string "sse2")
3893 (eq_attr "alternative" "10")
3894 (const_string "sse4")
3895 (eq_attr "alternative" "11")
3896 (const_string "avx512f")
3897 (eq_attr "alternative" "12")
3898 (const_string "x64_avx512bw")
3899 (eq_attr "alternative" "13")
3900 (const_string "avx512bw")
3901 ]
3902 (const_string "*")))
3903 (set (attr "mmx_isa")
3904 (if_then_else (eq_attr "alternative" "5,6")
3905 (const_string "native")
3906 (const_string "*")))
3907 (set (attr "type")
3908 (cond [(eq_attr "alternative" "0,1,2,4")
3909 (const_string "multi")
3910 (eq_attr "alternative" "5,6")
3911 (const_string "mmxmov")
3912 (eq_attr "alternative" "7")
3913 (if_then_else (match_test "TARGET_64BIT")
3914 (const_string "ssemov")
3915 (const_string "multi"))
3916 (eq_attr "alternative" "8,9,10,11")
3917 (const_string "ssemov")
3918 (eq_attr "alternative" "12,13")
3919 (const_string "mskmov")
3920 ]
3921 (const_string "imovx")))
3922 (set (attr "prefix_extra")
3923 (if_then_else (eq_attr "alternative" "10,11")
3924 (const_string "1")
3925 (const_string "*")))
3926 (set (attr "prefix")
3927 (if_then_else (eq_attr "type" "ssemov")
3928 (const_string "maybe_vex")
3929 (const_string "orig")))
3930 (set (attr "prefix_0f")
3931 (if_then_else (eq_attr "type" "imovx")
3932 (const_string "0")
3933 (const_string "*")))
3934 (set (attr "mode")
3935 (cond [(eq_attr "alternative" "5,6")
3936 (const_string "DI")
3937 (and (eq_attr "alternative" "7")
3938 (match_test "TARGET_64BIT"))
3939 (const_string "TI")
3940 (eq_attr "alternative" "8,10,11")
3941 (const_string "TI")
3942 ]
3943 (const_string "SI")))
3944 (set (attr "preferred_for_speed")
3945 (cond [(eq_attr "alternative" "7")
3946 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3947 (eq_attr "alternative" "5,8")
3948 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3949 ]
3950 (symbol_ref "true")))])
3951
3952 (define_split
3953 [(set (match_operand:DI 0 "memory_operand")
3954 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3955 "reload_completed"
3956 [(set (match_dup 4) (const_int 0))]
3957 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3958
3959 (define_split
3960 [(set (match_operand:DI 0 "general_reg_operand")
3961 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3962 "!TARGET_64BIT && reload_completed
3963 && REGNO (operands[0]) == REGNO (operands[1])"
3964 [(set (match_dup 4) (const_int 0))]
3965 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3966
3967 (define_split
3968 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3969 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3970 "!TARGET_64BIT && reload_completed
3971 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3972 [(set (match_dup 3) (match_dup 1))
3973 (set (match_dup 4) (const_int 0))]
3974 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3975
3976 (define_mode_attr kmov_isa
3977 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3978
3979 (define_insn "zero_extend<mode>di2"
3980 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3981 (zero_extend:DI
3982 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3983 "TARGET_64BIT"
3984 "@
3985 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3986 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3987 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3988 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3989 (set_attr "type" "imovx,mskmov,mskmov")
3990 (set_attr "mode" "SI,<MODE>,<MODE>")])
3991
3992 (define_expand "zero_extend<mode>si2"
3993 [(set (match_operand:SI 0 "register_operand")
3994 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3995 ""
3996 {
3997 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3998 {
3999 operands[1] = force_reg (<MODE>mode, operands[1]);
4000 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4001 DONE;
4002 }
4003 })
4004
4005 (define_insn_and_split "zero_extend<mode>si2_and"
4006 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4007 (zero_extend:SI
4008 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4009 (clobber (reg:CC FLAGS_REG))]
4010 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4011 "#"
4012 "&& reload_completed"
4013 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4014 (clobber (reg:CC FLAGS_REG))])]
4015 {
4016 if (!REG_P (operands[1])
4017 || REGNO (operands[0]) != REGNO (operands[1]))
4018 {
4019 ix86_expand_clear (operands[0]);
4020
4021 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4022 emit_insn (gen_rtx_SET
4023 (gen_rtx_STRICT_LOW_PART
4024 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4025 operands[1]));
4026 DONE;
4027 }
4028
4029 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4030 }
4031 [(set_attr "type" "alu1")
4032 (set_attr "mode" "SI")])
4033
4034 (define_insn "*zero_extend<mode>si2"
4035 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4036 (zero_extend:SI
4037 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4038 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4039 "@
4040 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4041 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4042 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4043 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4044 (set_attr "type" "imovx,mskmov,mskmov")
4045 (set_attr "mode" "SI,<MODE>,<MODE>")])
4046
4047 (define_expand "zero_extendqihi2"
4048 [(set (match_operand:HI 0 "register_operand")
4049 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4050 ""
4051 {
4052 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4053 {
4054 operands[1] = force_reg (QImode, operands[1]);
4055 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4056 DONE;
4057 }
4058 })
4059
4060 (define_insn_and_split "zero_extendqihi2_and"
4061 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4062 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4063 (clobber (reg:CC FLAGS_REG))]
4064 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4065 "#"
4066 "&& reload_completed"
4067 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4068 (clobber (reg:CC FLAGS_REG))])]
4069 {
4070 if (!REG_P (operands[1])
4071 || REGNO (operands[0]) != REGNO (operands[1]))
4072 {
4073 ix86_expand_clear (operands[0]);
4074
4075 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4076 emit_insn (gen_rtx_SET
4077 (gen_rtx_STRICT_LOW_PART
4078 (VOIDmode, gen_lowpart (QImode, operands[0])),
4079 operands[1]));
4080 DONE;
4081 }
4082
4083 operands[0] = gen_lowpart (SImode, operands[0]);
4084 }
4085 [(set_attr "type" "alu1")
4086 (set_attr "mode" "SI")])
4087
4088 ; zero extend to SImode to avoid partial register stalls
4089 (define_insn "*zero_extendqihi2"
4090 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4091 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4092 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4093 "@
4094 movz{bl|x}\t{%1, %k0|%k0, %1}
4095 kmovb\t{%1, %k0|%k0, %1}
4096 kmovb\t{%1, %0|%0, %1}"
4097 [(set_attr "isa" "*,avx512dq,avx512dq")
4098 (set_attr "type" "imovx,mskmov,mskmov")
4099 (set_attr "mode" "SI,QI,QI")])
4100 \f
4101 ;; Sign extension instructions
4102
4103 (define_expand "extendsidi2"
4104 [(set (match_operand:DI 0 "register_operand")
4105 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4106 ""
4107 {
4108 if (!TARGET_64BIT)
4109 {
4110 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4111 DONE;
4112 }
4113 })
4114
4115 (define_insn "*extendsidi2_rex64"
4116 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4117 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4118 "TARGET_64BIT"
4119 "@
4120 {cltq|cdqe}
4121 movs{lq|x}\t{%1, %0|%0, %1}"
4122 [(set_attr "type" "imovx")
4123 (set_attr "mode" "DI")
4124 (set_attr "prefix_0f" "0")
4125 (set_attr "modrm" "0,1")])
4126
4127 (define_insn "extendsidi2_1"
4128 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4129 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4130 (clobber (reg:CC FLAGS_REG))
4131 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4132 "!TARGET_64BIT"
4133 "#")
4134
4135 ;; Split the memory case. If the source register doesn't die, it will stay
4136 ;; this way, if it does die, following peephole2s take care of it.
4137 (define_split
4138 [(set (match_operand:DI 0 "memory_operand")
4139 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4140 (clobber (reg:CC FLAGS_REG))
4141 (clobber (match_operand:SI 2 "register_operand"))]
4142 "reload_completed"
4143 [(const_int 0)]
4144 {
4145 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4146
4147 emit_move_insn (operands[3], operands[1]);
4148
4149 /* Generate a cltd if possible and doing so it profitable. */
4150 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4151 && REGNO (operands[1]) == AX_REG
4152 && REGNO (operands[2]) == DX_REG)
4153 {
4154 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4155 }
4156 else
4157 {
4158 emit_move_insn (operands[2], operands[1]);
4159 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4160 }
4161 emit_move_insn (operands[4], operands[2]);
4162 DONE;
4163 })
4164
4165 ;; Peepholes for the case where the source register does die, after
4166 ;; being split with the above splitter.
4167 (define_peephole2
4168 [(set (match_operand:SI 0 "memory_operand")
4169 (match_operand:SI 1 "general_reg_operand"))
4170 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4171 (parallel [(set (match_dup 2)
4172 (ashiftrt:SI (match_dup 2) (const_int 31)))
4173 (clobber (reg:CC FLAGS_REG))])
4174 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4175 "REGNO (operands[1]) != REGNO (operands[2])
4176 && peep2_reg_dead_p (2, operands[1])
4177 && peep2_reg_dead_p (4, operands[2])
4178 && !reg_mentioned_p (operands[2], operands[3])"
4179 [(set (match_dup 0) (match_dup 1))
4180 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4181 (clobber (reg:CC FLAGS_REG))])
4182 (set (match_dup 3) (match_dup 1))])
4183
4184 (define_peephole2
4185 [(set (match_operand:SI 0 "memory_operand")
4186 (match_operand:SI 1 "general_reg_operand"))
4187 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4188 (ashiftrt:SI (match_dup 1) (const_int 31)))
4189 (clobber (reg:CC FLAGS_REG))])
4190 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4191 "/* cltd is shorter than sarl $31, %eax */
4192 !optimize_function_for_size_p (cfun)
4193 && REGNO (operands[1]) == AX_REG
4194 && REGNO (operands[2]) == DX_REG
4195 && peep2_reg_dead_p (2, operands[1])
4196 && peep2_reg_dead_p (3, operands[2])
4197 && !reg_mentioned_p (operands[2], operands[3])"
4198 [(set (match_dup 0) (match_dup 1))
4199 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4200 (clobber (reg:CC FLAGS_REG))])
4201 (set (match_dup 3) (match_dup 1))])
4202
4203 ;; Extend to register case. Optimize case where source and destination
4204 ;; registers match and cases where we can use cltd.
4205 (define_split
4206 [(set (match_operand:DI 0 "register_operand")
4207 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4208 (clobber (reg:CC FLAGS_REG))
4209 (clobber (match_scratch:SI 2))]
4210 "reload_completed"
4211 [(const_int 0)]
4212 {
4213 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4214
4215 if (REGNO (operands[3]) != REGNO (operands[1]))
4216 emit_move_insn (operands[3], operands[1]);
4217
4218 /* Generate a cltd if possible and doing so it profitable. */
4219 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4220 && REGNO (operands[3]) == AX_REG
4221 && REGNO (operands[4]) == DX_REG)
4222 {
4223 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4224 DONE;
4225 }
4226
4227 if (REGNO (operands[4]) != REGNO (operands[1]))
4228 emit_move_insn (operands[4], operands[1]);
4229
4230 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4231 DONE;
4232 })
4233
4234 (define_insn "extend<mode>di2"
4235 [(set (match_operand:DI 0 "register_operand" "=r")
4236 (sign_extend:DI
4237 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4238 "TARGET_64BIT"
4239 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4240 [(set_attr "type" "imovx")
4241 (set_attr "mode" "DI")])
4242
4243 (define_insn "extendhisi2"
4244 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4245 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4246 ""
4247 {
4248 switch (get_attr_prefix_0f (insn))
4249 {
4250 case 0:
4251 return "{cwtl|cwde}";
4252 default:
4253 return "movs{wl|x}\t{%1, %0|%0, %1}";
4254 }
4255 }
4256 [(set_attr "type" "imovx")
4257 (set_attr "mode" "SI")
4258 (set (attr "prefix_0f")
4259 ;; movsx is short decodable while cwtl is vector decoded.
4260 (if_then_else (and (eq_attr "cpu" "!k6")
4261 (eq_attr "alternative" "0"))
4262 (const_string "0")
4263 (const_string "1")))
4264 (set (attr "znver1_decode")
4265 (if_then_else (eq_attr "prefix_0f" "0")
4266 (const_string "double")
4267 (const_string "direct")))
4268 (set (attr "modrm")
4269 (if_then_else (eq_attr "prefix_0f" "0")
4270 (const_string "0")
4271 (const_string "1")))])
4272
4273 (define_insn "*extendhisi2_zext"
4274 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4275 (zero_extend:DI
4276 (sign_extend:SI
4277 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4278 "TARGET_64BIT"
4279 {
4280 switch (get_attr_prefix_0f (insn))
4281 {
4282 case 0:
4283 return "{cwtl|cwde}";
4284 default:
4285 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4286 }
4287 }
4288 [(set_attr "type" "imovx")
4289 (set_attr "mode" "SI")
4290 (set (attr "prefix_0f")
4291 ;; movsx is short decodable while cwtl is vector decoded.
4292 (if_then_else (and (eq_attr "cpu" "!k6")
4293 (eq_attr "alternative" "0"))
4294 (const_string "0")
4295 (const_string "1")))
4296 (set (attr "modrm")
4297 (if_then_else (eq_attr "prefix_0f" "0")
4298 (const_string "0")
4299 (const_string "1")))])
4300
4301 (define_insn "extendqisi2"
4302 [(set (match_operand:SI 0 "register_operand" "=r")
4303 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4304 ""
4305 "movs{bl|x}\t{%1, %0|%0, %1}"
4306 [(set_attr "type" "imovx")
4307 (set_attr "mode" "SI")])
4308
4309 (define_insn "*extendqisi2_zext"
4310 [(set (match_operand:DI 0 "register_operand" "=r")
4311 (zero_extend:DI
4312 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4313 "TARGET_64BIT"
4314 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4315 [(set_attr "type" "imovx")
4316 (set_attr "mode" "SI")])
4317
4318 (define_insn "extendqihi2"
4319 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4320 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4321 ""
4322 {
4323 switch (get_attr_prefix_0f (insn))
4324 {
4325 case 0:
4326 return "{cbtw|cbw}";
4327 default:
4328 return "movs{bw|x}\t{%1, %0|%0, %1}";
4329 }
4330 }
4331 [(set_attr "type" "imovx")
4332 (set_attr "mode" "HI")
4333 (set (attr "prefix_0f")
4334 ;; movsx is short decodable while cwtl is vector decoded.
4335 (if_then_else (and (eq_attr "cpu" "!k6")
4336 (eq_attr "alternative" "0"))
4337 (const_string "0")
4338 (const_string "1")))
4339 (set (attr "modrm")
4340 (if_then_else (eq_attr "prefix_0f" "0")
4341 (const_string "0")
4342 (const_string "1")))])
4343 \f
4344 ;; Conversions between float and double.
4345
4346 ;; These are all no-ops in the model used for the 80387.
4347 ;; So just emit moves.
4348
4349 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4350 (define_split
4351 [(set (match_operand:DF 0 "push_operand")
4352 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4353 "reload_completed"
4354 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4355 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4356
4357 (define_split
4358 [(set (match_operand:XF 0 "push_operand")
4359 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4360 "reload_completed"
4361 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4362 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4363 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4364
4365 (define_expand "extendsfdf2"
4366 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4367 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4368 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4369 {
4370 /* ??? Needed for compress_float_constant since all fp constants
4371 are TARGET_LEGITIMATE_CONSTANT_P. */
4372 if (CONST_DOUBLE_P (operands[1]))
4373 {
4374 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4375 && standard_80387_constant_p (operands[1]) > 0)
4376 {
4377 operands[1] = simplify_const_unary_operation
4378 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4379 emit_move_insn_1 (operands[0], operands[1]);
4380 DONE;
4381 }
4382 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4383 }
4384 })
4385
4386 (define_insn "*extendsfdf2"
4387 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4388 (float_extend:DF
4389 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4390 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4391 {
4392 switch (which_alternative)
4393 {
4394 case 0:
4395 case 1:
4396 return output_387_reg_move (insn, operands);
4397
4398 case 2:
4399 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4400 case 3:
4401 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4402
4403 default:
4404 gcc_unreachable ();
4405 }
4406 }
4407 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4408 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4409 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4410 (set_attr "mode" "SF,XF,DF,DF")
4411 (set (attr "enabled")
4412 (if_then_else
4413 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4414 (if_then_else
4415 (eq_attr "alternative" "0,1")
4416 (symbol_ref "TARGET_MIX_SSE_I387")
4417 (symbol_ref "true"))
4418 (if_then_else
4419 (eq_attr "alternative" "0,1")
4420 (symbol_ref "true")
4421 (symbol_ref "false"))))])
4422
4423 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4424 cvtss2sd:
4425 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4426 cvtps2pd xmm2,xmm1
4427 We do the conversion post reload to avoid producing of 128bit spills
4428 that might lead to ICE on 32bit target. The sequence unlikely combine
4429 anyway. */
4430 (define_split
4431 [(set (match_operand:DF 0 "sse_reg_operand")
4432 (float_extend:DF
4433 (match_operand:SF 1 "nonimmediate_operand")))]
4434 "TARGET_USE_VECTOR_FP_CONVERTS
4435 && optimize_insn_for_speed_p ()
4436 && reload_completed
4437 && (!EXT_REX_SSE_REG_P (operands[0])
4438 || TARGET_AVX512VL)"
4439 [(set (match_dup 2)
4440 (float_extend:V2DF
4441 (vec_select:V2SF
4442 (match_dup 3)
4443 (parallel [(const_int 0) (const_int 1)]))))]
4444 {
4445 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4446 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4447 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4448 Try to avoid move when unpacking can be done in source. */
4449 if (REG_P (operands[1]))
4450 {
4451 /* If it is unsafe to overwrite upper half of source, we need
4452 to move to destination and unpack there. */
4453 if (REGNO (operands[0]) != REGNO (operands[1])
4454 || (EXT_REX_SSE_REG_P (operands[1])
4455 && !TARGET_AVX512VL))
4456 {
4457 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4458 emit_move_insn (tmp, operands[1]);
4459 }
4460 else
4461 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4462 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4463 =v, v, then vbroadcastss will be only needed for AVX512F without
4464 AVX512VL. */
4465 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4466 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4467 operands[3]));
4468 else
4469 {
4470 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4471 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4472 }
4473 }
4474 else
4475 emit_insn (gen_vec_setv4sf_0 (operands[3],
4476 CONST0_RTX (V4SFmode), operands[1]));
4477 })
4478
4479 ;; It's more profitable to split and then extend in the same register.
4480 (define_peephole2
4481 [(set (match_operand:DF 0 "sse_reg_operand")
4482 (float_extend:DF
4483 (match_operand:SF 1 "memory_operand")))]
4484 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4485 && optimize_insn_for_speed_p ()"
4486 [(set (match_dup 2) (match_dup 1))
4487 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4488 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4489
4490 ;; Break partial SSE register dependency stall. This splitter should split
4491 ;; late in the pass sequence (after register rename pass), so allocated
4492 ;; registers won't change anymore
4493
4494 (define_split
4495 [(set (match_operand:DF 0 "sse_reg_operand")
4496 (float_extend:DF
4497 (match_operand:SF 1 "nonimmediate_operand")))]
4498 "!TARGET_AVX
4499 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4500 && optimize_function_for_speed_p (cfun)
4501 && (!REG_P (operands[1])
4502 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4503 && (!EXT_REX_SSE_REG_P (operands[0])
4504 || TARGET_AVX512VL)"
4505 [(set (match_dup 0)
4506 (vec_merge:V2DF
4507 (vec_duplicate:V2DF
4508 (float_extend:DF
4509 (match_dup 1)))
4510 (match_dup 0)
4511 (const_int 1)))]
4512 {
4513 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4514 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4515 })
4516
4517 (define_expand "extend<mode>xf2"
4518 [(set (match_operand:XF 0 "nonimmediate_operand")
4519 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4520 "TARGET_80387"
4521 {
4522 /* ??? Needed for compress_float_constant since all fp constants
4523 are TARGET_LEGITIMATE_CONSTANT_P. */
4524 if (CONST_DOUBLE_P (operands[1]))
4525 {
4526 if (standard_80387_constant_p (operands[1]) > 0)
4527 {
4528 operands[1] = simplify_const_unary_operation
4529 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4530 emit_move_insn_1 (operands[0], operands[1]);
4531 DONE;
4532 }
4533 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4534 }
4535 })
4536
4537 (define_insn "*extend<mode>xf2_i387"
4538 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4539 (float_extend:XF
4540 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4541 "TARGET_80387"
4542 "* return output_387_reg_move (insn, operands);"
4543 [(set_attr "type" "fmov")
4544 (set_attr "mode" "<MODE>,XF")])
4545
4546 ;; %%% This seems like bad news.
4547 ;; This cannot output into an f-reg because there is no way to be sure
4548 ;; of truncating in that case. Otherwise this is just like a simple move
4549 ;; insn. So we pretend we can output to a reg in order to get better
4550 ;; register preferencing, but we really use a stack slot.
4551
4552 ;; Conversion from DFmode to SFmode.
4553
4554 (define_insn "truncdfsf2"
4555 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4556 (float_truncate:SF
4557 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4558 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4559 {
4560 switch (which_alternative)
4561 {
4562 case 0:
4563 case 1:
4564 return output_387_reg_move (insn, operands);
4565
4566 case 2:
4567 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4568 case 3:
4569 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4570
4571 default:
4572 gcc_unreachable ();
4573 }
4574 }
4575 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4576 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4577 (set_attr "mode" "SF")
4578 (set (attr "enabled")
4579 (if_then_else
4580 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4581 (cond [(eq_attr "alternative" "0")
4582 (symbol_ref "TARGET_MIX_SSE_I387")
4583 (eq_attr "alternative" "1")
4584 (symbol_ref "TARGET_MIX_SSE_I387
4585 && flag_unsafe_math_optimizations")
4586 ]
4587 (symbol_ref "true"))
4588 (cond [(eq_attr "alternative" "0")
4589 (symbol_ref "true")
4590 (eq_attr "alternative" "1")
4591 (symbol_ref "flag_unsafe_math_optimizations")
4592 ]
4593 (symbol_ref "false"))))])
4594
4595 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4596 cvtsd2ss:
4597 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4598 cvtpd2ps xmm2,xmm1
4599 We do the conversion post reload to avoid producing of 128bit spills
4600 that might lead to ICE on 32bit target. The sequence unlikely combine
4601 anyway. */
4602 (define_split
4603 [(set (match_operand:SF 0 "sse_reg_operand")
4604 (float_truncate:SF
4605 (match_operand:DF 1 "nonimmediate_operand")))]
4606 "TARGET_USE_VECTOR_FP_CONVERTS
4607 && optimize_insn_for_speed_p ()
4608 && reload_completed
4609 && (!EXT_REX_SSE_REG_P (operands[0])
4610 || TARGET_AVX512VL)"
4611 [(set (match_dup 2)
4612 (vec_concat:V4SF
4613 (float_truncate:V2SF
4614 (match_dup 4))
4615 (match_dup 3)))]
4616 {
4617 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4618 operands[3] = CONST0_RTX (V2SFmode);
4619 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4620 /* Use movsd for loading from memory, unpcklpd for registers.
4621 Try to avoid move when unpacking can be done in source, or SSE3
4622 movddup is available. */
4623 if (REG_P (operands[1]))
4624 {
4625 if (!TARGET_SSE3
4626 && REGNO (operands[0]) != REGNO (operands[1]))
4627 {
4628 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4629 emit_move_insn (tmp, operands[1]);
4630 operands[1] = tmp;
4631 }
4632 else if (!TARGET_SSE3)
4633 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4634 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4635 }
4636 else
4637 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4638 CONST0_RTX (DFmode)));
4639 })
4640
4641 ;; It's more profitable to split and then truncate in the same register.
4642 (define_peephole2
4643 [(set (match_operand:SF 0 "sse_reg_operand")
4644 (float_truncate:SF
4645 (match_operand:DF 1 "memory_operand")))]
4646 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4647 && optimize_insn_for_speed_p ()"
4648 [(set (match_dup 2) (match_dup 1))
4649 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4650 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4651
4652 ;; Break partial SSE register dependency stall. This splitter should split
4653 ;; late in the pass sequence (after register rename pass), so allocated
4654 ;; registers won't change anymore
4655
4656 (define_split
4657 [(set (match_operand:SF 0 "sse_reg_operand")
4658 (float_truncate:SF
4659 (match_operand:DF 1 "nonimmediate_operand")))]
4660 "!TARGET_AVX
4661 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4662 && optimize_function_for_speed_p (cfun)
4663 && (!REG_P (operands[1])
4664 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4665 && (!EXT_REX_SSE_REG_P (operands[0])
4666 || TARGET_AVX512VL)"
4667 [(set (match_dup 0)
4668 (vec_merge:V4SF
4669 (vec_duplicate:V4SF
4670 (float_truncate:SF
4671 (match_dup 1)))
4672 (match_dup 0)
4673 (const_int 1)))]
4674 {
4675 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4676 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4677 })
4678
4679 ;; Conversion from XFmode to {SF,DF}mode
4680
4681 (define_insn "truncxf<mode>2"
4682 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4683 (float_truncate:MODEF
4684 (match_operand:XF 1 "register_operand" "f,f")))]
4685 "TARGET_80387"
4686 "* return output_387_reg_move (insn, operands);"
4687 [(set_attr "type" "fmov")
4688 (set_attr "mode" "<MODE>")
4689 (set (attr "enabled")
4690 (cond [(eq_attr "alternative" "1")
4691 (symbol_ref "flag_unsafe_math_optimizations")
4692 ]
4693 (symbol_ref "true")))])
4694 \f
4695 ;; Signed conversion to DImode.
4696
4697 (define_expand "fix_truncxfdi2"
4698 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4699 (fix:DI (match_operand:XF 1 "register_operand")))
4700 (clobber (reg:CC FLAGS_REG))])]
4701 "TARGET_80387"
4702 {
4703 if (TARGET_FISTTP)
4704 {
4705 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4706 DONE;
4707 }
4708 })
4709
4710 (define_expand "fix_trunc<mode>di2"
4711 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4712 (fix:DI (match_operand:MODEF 1 "register_operand")))
4713 (clobber (reg:CC FLAGS_REG))])]
4714 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4715 {
4716 if (TARGET_FISTTP
4717 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4718 {
4719 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4720 DONE;
4721 }
4722 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4723 {
4724 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4725 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4726 if (out != operands[0])
4727 emit_move_insn (operands[0], out);
4728 DONE;
4729 }
4730 })
4731
4732 ;; Signed conversion to SImode.
4733
4734 (define_expand "fix_truncxfsi2"
4735 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4736 (fix:SI (match_operand:XF 1 "register_operand")))
4737 (clobber (reg:CC FLAGS_REG))])]
4738 "TARGET_80387"
4739 {
4740 if (TARGET_FISTTP)
4741 {
4742 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4743 DONE;
4744 }
4745 })
4746
4747 (define_expand "fix_trunc<mode>si2"
4748 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4749 (fix:SI (match_operand:MODEF 1 "register_operand")))
4750 (clobber (reg:CC FLAGS_REG))])]
4751 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4752 {
4753 if (TARGET_FISTTP
4754 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4755 {
4756 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4757 DONE;
4758 }
4759 if (SSE_FLOAT_MODE_P (<MODE>mode))
4760 {
4761 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4762 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4763 if (out != operands[0])
4764 emit_move_insn (operands[0], out);
4765 DONE;
4766 }
4767 })
4768
4769 ;; Signed conversion to HImode.
4770
4771 (define_expand "fix_trunc<mode>hi2"
4772 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4773 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4774 (clobber (reg:CC FLAGS_REG))])]
4775 "TARGET_80387
4776 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4777 {
4778 if (TARGET_FISTTP)
4779 {
4780 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4781 DONE;
4782 }
4783 })
4784
4785 ;; Unsigned conversion to DImode
4786
4787 (define_insn "fixuns_trunc<mode>di2"
4788 [(set (match_operand:DI 0 "register_operand" "=r")
4789 (unsigned_fix:DI
4790 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4791 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4792 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4793 [(set_attr "type" "sseicvt")
4794 (set_attr "prefix" "evex")
4795 (set_attr "mode" "DI")])
4796
4797 ;; Unsigned conversion to SImode.
4798
4799 (define_expand "fixuns_trunc<mode>si2"
4800 [(parallel
4801 [(set (match_operand:SI 0 "register_operand")
4802 (unsigned_fix:SI
4803 (match_operand:MODEF 1 "nonimmediate_operand")))
4804 (use (match_dup 2))
4805 (clobber (match_scratch:<ssevecmode> 3))
4806 (clobber (match_scratch:<ssevecmode> 4))])]
4807 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4808 {
4809 machine_mode mode = <MODE>mode;
4810 machine_mode vecmode = <ssevecmode>mode;
4811 REAL_VALUE_TYPE TWO31r;
4812 rtx two31;
4813
4814 if (TARGET_AVX512F)
4815 {
4816 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4817 DONE;
4818 }
4819
4820 if (optimize_insn_for_size_p ())
4821 FAIL;
4822
4823 real_ldexp (&TWO31r, &dconst1, 31);
4824 two31 = const_double_from_real_value (TWO31r, mode);
4825 two31 = ix86_build_const_vector (vecmode, true, two31);
4826 operands[2] = force_reg (vecmode, two31);
4827 })
4828
4829 (define_insn "fixuns_trunc<mode>si2_avx512f"
4830 [(set (match_operand:SI 0 "register_operand" "=r")
4831 (unsigned_fix:SI
4832 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4833 "TARGET_AVX512F && TARGET_SSE_MATH"
4834 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4835 [(set_attr "type" "sseicvt")
4836 (set_attr "prefix" "evex")
4837 (set_attr "mode" "SI")])
4838
4839 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4840 [(set (match_operand:DI 0 "register_operand" "=r")
4841 (zero_extend:DI
4842 (unsigned_fix:SI
4843 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4844 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4845 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4846 [(set_attr "type" "sseicvt")
4847 (set_attr "prefix" "evex")
4848 (set_attr "mode" "SI")])
4849
4850 (define_insn_and_split "*fixuns_trunc<mode>_1"
4851 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4852 (unsigned_fix:SI
4853 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4854 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4855 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4856 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4857 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4858 && optimize_function_for_speed_p (cfun)"
4859 "#"
4860 "&& reload_completed"
4861 [(const_int 0)]
4862 {
4863 ix86_split_convert_uns_si_sse (operands);
4864 DONE;
4865 })
4866
4867 ;; Unsigned conversion to HImode.
4868 ;; Without these patterns, we'll try the unsigned SI conversion which
4869 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4870
4871 (define_expand "fixuns_trunc<mode>hi2"
4872 [(set (match_dup 2)
4873 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4874 (set (match_operand:HI 0 "nonimmediate_operand")
4875 (subreg:HI (match_dup 2) 0))]
4876 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4877 "operands[2] = gen_reg_rtx (SImode);")
4878
4879 ;; When SSE is available, it is always faster to use it!
4880 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4881 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4882 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4883 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4884 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4885 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4886 [(set_attr "type" "sseicvt")
4887 (set_attr "prefix" "maybe_vex")
4888 (set (attr "prefix_rex")
4889 (if_then_else
4890 (match_test "<SWI48:MODE>mode == DImode")
4891 (const_string "1")
4892 (const_string "*")))
4893 (set_attr "mode" "<MODEF:MODE>")
4894 (set_attr "athlon_decode" "double,vector")
4895 (set_attr "amdfam10_decode" "double,double")
4896 (set_attr "bdver1_decode" "double,double")])
4897
4898 ;; Avoid vector decoded forms of the instruction.
4899 (define_peephole2
4900 [(match_scratch:MODEF 2 "x")
4901 (set (match_operand:SWI48 0 "register_operand")
4902 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4903 "TARGET_AVOID_VECTOR_DECODE
4904 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4905 && optimize_insn_for_speed_p ()"
4906 [(set (match_dup 2) (match_dup 1))
4907 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4908
4909 (define_insn "fix_trunc<mode>_i387_fisttp"
4910 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4911 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4912 (clobber (match_scratch:XF 2 "=&f"))]
4913 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4914 && TARGET_FISTTP
4915 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4916 && (TARGET_64BIT || <MODE>mode != DImode))
4917 && TARGET_SSE_MATH)"
4918 "* return output_fix_trunc (insn, operands, true);"
4919 [(set_attr "type" "fisttp")
4920 (set_attr "mode" "<MODE>")])
4921
4922 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4923 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4924 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4925 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4926 ;; function in i386.c.
4927 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4928 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4929 (fix:SWI248x (match_operand 1 "register_operand")))
4930 (clobber (reg:CC FLAGS_REG))]
4931 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4932 && !TARGET_FISTTP
4933 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4934 && (TARGET_64BIT || <MODE>mode != DImode))
4935 && ix86_pre_reload_split ()"
4936 "#"
4937 "&& 1"
4938 [(const_int 0)]
4939 {
4940 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4941
4942 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4943 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4944
4945 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4946 operands[2], operands[3]));
4947 DONE;
4948 }
4949 [(set_attr "type" "fistp")
4950 (set_attr "i387_cw" "trunc")
4951 (set_attr "mode" "<MODE>")])
4952
4953 (define_insn "fix_truncdi_i387"
4954 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4955 (fix:DI (match_operand 1 "register_operand" "f")))
4956 (use (match_operand:HI 2 "memory_operand" "m"))
4957 (use (match_operand:HI 3 "memory_operand" "m"))
4958 (clobber (match_scratch:XF 4 "=&f"))]
4959 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4960 && !TARGET_FISTTP
4961 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4962 "* return output_fix_trunc (insn, operands, false);"
4963 [(set_attr "type" "fistp")
4964 (set_attr "i387_cw" "trunc")
4965 (set_attr "mode" "DI")])
4966
4967 (define_insn "fix_trunc<mode>_i387"
4968 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4969 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4970 (use (match_operand:HI 2 "memory_operand" "m"))
4971 (use (match_operand:HI 3 "memory_operand" "m"))]
4972 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4973 && !TARGET_FISTTP
4974 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4975 "* return output_fix_trunc (insn, operands, false);"
4976 [(set_attr "type" "fistp")
4977 (set_attr "i387_cw" "trunc")
4978 (set_attr "mode" "<MODE>")])
4979
4980 (define_insn "x86_fnstcw_1"
4981 [(set (match_operand:HI 0 "memory_operand" "=m")
4982 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4983 "TARGET_80387"
4984 "fnstcw\t%0"
4985 [(set (attr "length")
4986 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4987 (set_attr "mode" "HI")
4988 (set_attr "unit" "i387")
4989 (set_attr "bdver1_decode" "vector")])
4990 \f
4991 ;; Conversion between fixed point and floating point.
4992
4993 ;; Even though we only accept memory inputs, the backend _really_
4994 ;; wants to be able to do this between registers. Thankfully, LRA
4995 ;; will fix this up for us during register allocation.
4996
4997 (define_insn "floathi<mode>2"
4998 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4999 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5000 "TARGET_80387
5001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5002 || TARGET_MIX_SSE_I387)"
5003 "fild%Z1\t%1"
5004 [(set_attr "type" "fmov")
5005 (set_attr "mode" "<MODE>")
5006 (set_attr "znver1_decode" "double")
5007 (set_attr "fp_int_src" "true")])
5008
5009 (define_insn "float<SWI48x:mode>xf2"
5010 [(set (match_operand:XF 0 "register_operand" "=f")
5011 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5012 "TARGET_80387"
5013 "fild%Z1\t%1"
5014 [(set_attr "type" "fmov")
5015 (set_attr "mode" "XF")
5016 (set_attr "znver1_decode" "double")
5017 (set_attr "fp_int_src" "true")])
5018
5019 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5020 [(set (match_operand:MODEF 0 "register_operand")
5021 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5022 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5023 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5024 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5025
5026 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5027 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5028 (float:MODEF
5029 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5030 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5031 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5032 "@
5033 fild%Z1\t%1
5034 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5035 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5036 [(set_attr "type" "fmov,sseicvt,sseicvt")
5037 (set_attr "avx_partial_xmm_update" "false,true,true")
5038 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5039 (set_attr "mode" "<MODEF:MODE>")
5040 (set (attr "prefix_rex")
5041 (if_then_else
5042 (and (eq_attr "prefix" "maybe_vex")
5043 (match_test "<SWI48:MODE>mode == DImode"))
5044 (const_string "1")
5045 (const_string "*")))
5046 (set_attr "unit" "i387,*,*")
5047 (set_attr "athlon_decode" "*,double,direct")
5048 (set_attr "amdfam10_decode" "*,vector,double")
5049 (set_attr "bdver1_decode" "*,double,direct")
5050 (set_attr "znver1_decode" "double,*,*")
5051 (set_attr "fp_int_src" "true")
5052 (set (attr "enabled")
5053 (if_then_else
5054 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5055 (if_then_else
5056 (eq_attr "alternative" "0")
5057 (symbol_ref "TARGET_MIX_SSE_I387
5058 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5059 <SWI48:MODE>mode)")
5060 (symbol_ref "true"))
5061 (if_then_else
5062 (eq_attr "alternative" "0")
5063 (symbol_ref "true")
5064 (symbol_ref "false"))))
5065 (set (attr "preferred_for_speed")
5066 (cond [(eq_attr "alternative" "1")
5067 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5068 (symbol_ref "true")))])
5069
5070 (define_insn "*floatdi<MODEF:mode>2_i387"
5071 [(set (match_operand:MODEF 0 "register_operand" "=f")
5072 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5073 "!TARGET_64BIT
5074 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5075 "fild%Z1\t%1"
5076 [(set_attr "type" "fmov")
5077 (set_attr "mode" "<MODEF:MODE>")
5078 (set_attr "znver1_decode" "double")
5079 (set_attr "fp_int_src" "true")])
5080
5081 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5082 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5083 ;; alternative in sse2_loadld.
5084 (define_split
5085 [(set (match_operand:MODEF 0 "sse_reg_operand")
5086 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5087 "TARGET_SSE2
5088 && TARGET_USE_VECTOR_CONVERTS
5089 && optimize_function_for_speed_p (cfun)
5090 && reload_completed
5091 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5092 && (!EXT_REX_SSE_REG_P (operands[0])
5093 || TARGET_AVX512VL)"
5094 [(const_int 0)]
5095 {
5096 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5097 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5098
5099 emit_insn (gen_sse2_loadld (operands[4],
5100 CONST0_RTX (V4SImode), operands[1]));
5101
5102 if (<ssevecmode>mode == V4SFmode)
5103 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5104 else
5105 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5106 DONE;
5107 })
5108
5109 ;; Avoid store forwarding (partial memory) stall penalty
5110 ;; by passing DImode value through XMM registers. */
5111
5112 (define_split
5113 [(set (match_operand:X87MODEF 0 "register_operand")
5114 (float:X87MODEF
5115 (match_operand:DI 1 "register_operand")))]
5116 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5117 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5118 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5119 && can_create_pseudo_p ()"
5120 [(const_int 0)]
5121 {
5122 emit_insn (gen_floatdi<mode>2_i387_with_xmm
5123 (operands[0], operands[1],
5124 assign_386_stack_local (DImode, SLOT_TEMP)));
5125 DONE;
5126 })
5127
5128 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5129 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5130 (float:X87MODEF
5131 (match_operand:DI 1 "register_operand" "r,r")))
5132 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5133 (clobber (match_scratch:V4SI 3 "=x,x"))
5134 (clobber (match_scratch:V4SI 4 "=X,x"))]
5135 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5136 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5137 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5138 "#"
5139 "&& reload_completed"
5140 [(set (match_dup 2) (match_dup 3))
5141 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5142 {
5143 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5144 Assemble the 64-bit DImode value in an xmm register. */
5145 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5146 gen_lowpart (SImode, operands[1])));
5147 if (TARGET_SSE4_1)
5148 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5149 gen_highpart (SImode, operands[1]),
5150 GEN_INT (2)));
5151 else
5152 {
5153 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5154 gen_highpart (SImode, operands[1])));
5155 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5156 operands[4]));
5157 }
5158 operands[3] = gen_lowpart (DImode, operands[3]);
5159 }
5160 [(set_attr "isa" "sse4,*")
5161 (set_attr "type" "multi")
5162 (set_attr "mode" "<X87MODEF:MODE>")
5163 (set_attr "unit" "i387")
5164 (set_attr "fp_int_src" "true")])
5165
5166 ;; Break partial SSE register dependency stall. This splitter should split
5167 ;; late in the pass sequence (after register rename pass), so allocated
5168 ;; registers won't change anymore
5169
5170 (define_split
5171 [(set (match_operand:MODEF 0 "sse_reg_operand")
5172 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5173 "!TARGET_AVX
5174 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5175 && optimize_function_for_speed_p (cfun)
5176 && (!EXT_REX_SSE_REG_P (operands[0])
5177 || TARGET_AVX512VL)"
5178 [(set (match_dup 0)
5179 (vec_merge:<MODEF:ssevecmode>
5180 (vec_duplicate:<MODEF:ssevecmode>
5181 (float:MODEF
5182 (match_dup 1)))
5183 (match_dup 0)
5184 (const_int 1)))]
5185 {
5186 const machine_mode vmode = <MODEF:ssevecmode>mode;
5187
5188 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5189 emit_move_insn (operands[0], CONST0_RTX (vmode));
5190 })
5191
5192 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5193 [(set (match_operand:MODEF 0 "register_operand")
5194 (unsigned_float:MODEF
5195 (match_operand:SWI12 1 "nonimmediate_operand")))]
5196 "!TARGET_64BIT
5197 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5198 {
5199 operands[1] = convert_to_mode (SImode, operands[1], 1);
5200 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5201 DONE;
5202 })
5203
5204 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5205 [(set (match_operand:MODEF 0 "register_operand" "=v")
5206 (unsigned_float:MODEF
5207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5208 "TARGET_AVX512F && TARGET_SSE_MATH"
5209 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5210 [(set_attr "type" "sseicvt")
5211 (set_attr "avx_partial_xmm_update" "true")
5212 (set_attr "prefix" "evex")
5213 (set_attr "mode" "<MODEF:MODE>")])
5214
5215 ;; Avoid store forwarding (partial memory) stall penalty by extending
5216 ;; SImode value to DImode through XMM register instead of pushing two
5217 ;; SImode values to stack. Also note that fild loads from memory only.
5218
5219 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5220 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5221 (unsigned_float:X87MODEF
5222 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5223 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5224 (clobber (match_scratch:DI 3 "=x"))]
5225 "!TARGET_64BIT
5226 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5227 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5228 "#"
5229 "&& reload_completed"
5230 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5231 (set (match_dup 2) (match_dup 3))
5232 (set (match_dup 0)
5233 (float:X87MODEF (match_dup 2)))]
5234 ""
5235 [(set_attr "type" "multi")
5236 (set_attr "mode" "<MODE>")])
5237
5238 (define_expand "floatunssi<mode>2"
5239 [(set (match_operand:X87MODEF 0 "register_operand")
5240 (unsigned_float:X87MODEF
5241 (match_operand:SI 1 "nonimmediate_operand")))]
5242 "(!TARGET_64BIT
5243 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5244 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5245 || ((!TARGET_64BIT || TARGET_AVX512F)
5246 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5247 {
5248 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5249 {
5250 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5251 (operands[0], operands[1],
5252 assign_386_stack_local (DImode, SLOT_TEMP)));
5253 DONE;
5254 }
5255 if (!TARGET_AVX512F)
5256 {
5257 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5258 DONE;
5259 }
5260 })
5261
5262 (define_expand "floatunsdisf2"
5263 [(set (match_operand:SF 0 "register_operand")
5264 (unsigned_float:SF
5265 (match_operand:DI 1 "nonimmediate_operand")))]
5266 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5267 {
5268 if (!TARGET_AVX512F)
5269 {
5270 x86_emit_floatuns (operands);
5271 DONE;
5272 }
5273 })
5274
5275 (define_expand "floatunsdidf2"
5276 [(set (match_operand:DF 0 "register_operand")
5277 (unsigned_float:DF
5278 (match_operand:DI 1 "nonimmediate_operand")))]
5279 "((TARGET_64BIT && TARGET_AVX512F)
5280 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5281 && TARGET_SSE2 && TARGET_SSE_MATH"
5282 {
5283 if (!TARGET_64BIT)
5284 {
5285 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5286 DONE;
5287 }
5288 if (!TARGET_AVX512F)
5289 {
5290 x86_emit_floatuns (operands);
5291 DONE;
5292 }
5293 })
5294 \f
5295 ;; Load effective address instructions
5296
5297 (define_insn_and_split "*lea<mode>"
5298 [(set (match_operand:SWI48 0 "register_operand" "=r")
5299 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5300 ""
5301 {
5302 if (SImode_address_operand (operands[1], VOIDmode))
5303 {
5304 gcc_assert (TARGET_64BIT);
5305 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5306 }
5307 else
5308 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5309 }
5310 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5311 [(const_int 0)]
5312 {
5313 machine_mode mode = <MODE>mode;
5314 rtx pat;
5315
5316 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5317 change operands[] array behind our back. */
5318 pat = PATTERN (curr_insn);
5319
5320 operands[0] = SET_DEST (pat);
5321 operands[1] = SET_SRC (pat);
5322
5323 /* Emit all operations in SImode for zero-extended addresses. */
5324 if (SImode_address_operand (operands[1], VOIDmode))
5325 mode = SImode;
5326
5327 ix86_split_lea_for_addr (curr_insn, operands, mode);
5328
5329 /* Zero-extend return register to DImode for zero-extended addresses. */
5330 if (mode != <MODE>mode)
5331 emit_insn (gen_zero_extendsidi2
5332 (operands[0], gen_lowpart (mode, operands[0])));
5333
5334 DONE;
5335 }
5336 [(set_attr "type" "lea")
5337 (set (attr "mode")
5338 (if_then_else
5339 (match_operand 1 "SImode_address_operand")
5340 (const_string "SI")
5341 (const_string "<MODE>")))])
5342 \f
5343 ;; Add instructions
5344
5345 (define_expand "add<mode>3"
5346 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5347 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5348 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5349 ""
5350 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5351
5352 (define_insn_and_split "*add<dwi>3_doubleword"
5353 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
5354 (plus:<DWI>
5355 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5356 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
5357 (clobber (reg:CC FLAGS_REG))]
5358 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5359 "#"
5360 "reload_completed"
5361 [(parallel [(set (reg:CCC FLAGS_REG)
5362 (compare:CCC
5363 (plus:DWIH (match_dup 1) (match_dup 2))
5364 (match_dup 1)))
5365 (set (match_dup 0)
5366 (plus:DWIH (match_dup 1) (match_dup 2)))])
5367 (parallel [(set (match_dup 3)
5368 (plus:DWIH
5369 (plus:DWIH
5370 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5371 (match_dup 4))
5372 (match_dup 5)))
5373 (clobber (reg:CC FLAGS_REG))])]
5374 {
5375 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5376 if (operands[2] == const0_rtx)
5377 {
5378 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5379 DONE;
5380 }
5381 })
5382
5383 (define_insn "*add<mode>_1"
5384 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
5385 (plus:SWI48
5386 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5387 (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le")))
5388 (clobber (reg:CC FLAGS_REG))]
5389 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5390 {
5391 switch (get_attr_type (insn))
5392 {
5393 case TYPE_LEA:
5394 return "#";
5395
5396 case TYPE_INCDEC:
5397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398 if (operands[2] == const1_rtx)
5399 return "inc{<imodesuffix>}\t%0";
5400 else
5401 {
5402 gcc_assert (operands[2] == constm1_rtx);
5403 return "dec{<imodesuffix>}\t%0";
5404 }
5405
5406 default:
5407 /* For most processors, ADD is faster than LEA. This alternative
5408 was added to use ADD as much as possible. */
5409 if (which_alternative == 2)
5410 std::swap (operands[1], operands[2]);
5411
5412 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5413 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5414 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5415
5416 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5417 }
5418 }
5419 [(set (attr "type")
5420 (cond [(eq_attr "alternative" "3")
5421 (const_string "lea")
5422 (match_operand:SWI48 2 "incdec_operand")
5423 (const_string "incdec")
5424 ]
5425 (const_string "alu")))
5426 (set (attr "length_immediate")
5427 (if_then_else
5428 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5429 (const_string "1")
5430 (const_string "*")))
5431 (set_attr "mode" "<MODE>")])
5432
5433 ;; It may seem that nonimmediate operand is proper one for operand 1.
5434 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5435 ;; we take care in ix86_binary_operator_ok to not allow two memory
5436 ;; operands so proper swapping will be done in reload. This allow
5437 ;; patterns constructed from addsi_1 to match.
5438
5439 (define_insn "addsi_1_zext"
5440 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5441 (zero_extend:DI
5442 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5443 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5444 (clobber (reg:CC FLAGS_REG))]
5445 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5446 {
5447 switch (get_attr_type (insn))
5448 {
5449 case TYPE_LEA:
5450 return "#";
5451
5452 case TYPE_INCDEC:
5453 if (operands[2] == const1_rtx)
5454 return "inc{l}\t%k0";
5455 else
5456 {
5457 gcc_assert (operands[2] == constm1_rtx);
5458 return "dec{l}\t%k0";
5459 }
5460
5461 default:
5462 /* For most processors, ADD is faster than LEA. This alternative
5463 was added to use ADD as much as possible. */
5464 if (which_alternative == 1)
5465 std::swap (operands[1], operands[2]);
5466
5467 if (x86_maybe_negate_const_int (&operands[2], SImode))
5468 return "sub{l}\t{%2, %k0|%k0, %2}";
5469
5470 return "add{l}\t{%2, %k0|%k0, %2}";
5471 }
5472 }
5473 [(set (attr "type")
5474 (cond [(eq_attr "alternative" "2")
5475 (const_string "lea")
5476 (match_operand:SI 2 "incdec_operand")
5477 (const_string "incdec")
5478 ]
5479 (const_string "alu")))
5480 (set (attr "length_immediate")
5481 (if_then_else
5482 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5483 (const_string "1")
5484 (const_string "*")))
5485 (set_attr "mode" "SI")])
5486
5487 (define_insn "*addhi_1"
5488 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5489 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5490 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
5491 (clobber (reg:CC FLAGS_REG))]
5492 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5493 {
5494 switch (get_attr_type (insn))
5495 {
5496 case TYPE_LEA:
5497 return "#";
5498
5499 case TYPE_INCDEC:
5500 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5501 if (operands[2] == const1_rtx)
5502 return "inc{w}\t%0";
5503 else
5504 {
5505 gcc_assert (operands[2] == constm1_rtx);
5506 return "dec{w}\t%0";
5507 }
5508
5509 default:
5510 /* For most processors, ADD is faster than LEA. This alternative
5511 was added to use ADD as much as possible. */
5512 if (which_alternative == 2)
5513 std::swap (operands[1], operands[2]);
5514
5515 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5516 if (x86_maybe_negate_const_int (&operands[2], HImode))
5517 return "sub{w}\t{%2, %0|%0, %2}";
5518
5519 return "add{w}\t{%2, %0|%0, %2}";
5520 }
5521 }
5522 [(set (attr "type")
5523 (cond [(eq_attr "alternative" "3")
5524 (const_string "lea")
5525 (match_operand:HI 2 "incdec_operand")
5526 (const_string "incdec")
5527 ]
5528 (const_string "alu")))
5529 (set (attr "length_immediate")
5530 (if_then_else
5531 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5532 (const_string "1")
5533 (const_string "*")))
5534 (set_attr "mode" "HI,HI,HI,SI")])
5535
5536 (define_insn "*addqi_1"
5537 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5538 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5539 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
5540 (clobber (reg:CC FLAGS_REG))]
5541 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5542 {
5543 bool widen = (get_attr_mode (insn) != MODE_QI);
5544
5545 switch (get_attr_type (insn))
5546 {
5547 case TYPE_LEA:
5548 return "#";
5549
5550 case TYPE_INCDEC:
5551 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5552 if (operands[2] == const1_rtx)
5553 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5554 else
5555 {
5556 gcc_assert (operands[2] == constm1_rtx);
5557 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5558 }
5559
5560 default:
5561 /* For most processors, ADD is faster than LEA. These alternatives
5562 were added to use ADD as much as possible. */
5563 if (which_alternative == 2 || which_alternative == 4)
5564 std::swap (operands[1], operands[2]);
5565
5566 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5567 if (x86_maybe_negate_const_int (&operands[2], QImode))
5568 {
5569 if (widen)
5570 return "sub{l}\t{%2, %k0|%k0, %2}";
5571 else
5572 return "sub{b}\t{%2, %0|%0, %2}";
5573 }
5574 if (widen)
5575 return "add{l}\t{%k2, %k0|%k0, %k2}";
5576 else
5577 return "add{b}\t{%2, %0|%0, %2}";
5578 }
5579 }
5580 [(set (attr "type")
5581 (cond [(eq_attr "alternative" "5")
5582 (const_string "lea")
5583 (match_operand:QI 2 "incdec_operand")
5584 (const_string "incdec")
5585 ]
5586 (const_string "alu")))
5587 (set (attr "length_immediate")
5588 (if_then_else
5589 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5590 (const_string "1")
5591 (const_string "*")))
5592 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5593 ;; Potential partial reg stall on alternatives 3 and 4.
5594 (set (attr "preferred_for_speed")
5595 (cond [(eq_attr "alternative" "3,4")
5596 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5597 (symbol_ref "true")))])
5598
5599 (define_insn "*add<mode>_1_slp"
5600 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
5601 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
5602 (match_operand:SWI12 2 "general_operand" "<r>mn")))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5605 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
5606 && (rtx_equal_p (operands[0], operands[1])
5607 || rtx_equal_p (operands[0], operands[2]))"
5608 {
5609 switch (get_attr_type (insn))
5610 {
5611 case TYPE_INCDEC:
5612 if (operands[2] == const1_rtx)
5613 return "inc{<imodesuffix>}\t%0";
5614 else
5615 {
5616 gcc_assert (operands[2] == constm1_rtx);
5617 return "dec{<imodesuffix>}\t%0";
5618 }
5619
5620 default:
5621 if (x86_maybe_negate_const_int (&operands[2], QImode))
5622 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5623
5624 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5625 }
5626 }
5627 [(set (attr "type")
5628 (if_then_else (match_operand:QI 2 "incdec_operand")
5629 (const_string "incdec")
5630 (const_string "alu")))
5631 (set_attr "mode" "<MODE>")])
5632
5633 ;; Split non destructive adds if we cannot use lea.
5634 (define_split
5635 [(set (match_operand:SWI48 0 "register_operand")
5636 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5637 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5638 (clobber (reg:CC FLAGS_REG))]
5639 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5640 [(set (match_dup 0) (match_dup 1))
5641 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5642 (clobber (reg:CC FLAGS_REG))])])
5643
5644 ;; Split non destructive adds if we cannot use lea.
5645 (define_split
5646 [(set (match_operand:DI 0 "register_operand")
5647 (zero_extend:DI
5648 (plus:SI (match_operand:SI 1 "register_operand")
5649 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5650 (clobber (reg:CC FLAGS_REG))]
5651 "TARGET_64BIT
5652 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5653 [(set (match_dup 3) (match_dup 1))
5654 (parallel [(set (match_dup 0)
5655 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5656 (clobber (reg:CC FLAGS_REG))])]
5657 "operands[3] = gen_lowpart (SImode, operands[0]);")
5658
5659 ;; Convert add to the lea pattern to avoid flags dependency.
5660 (define_split
5661 [(set (match_operand:SWI 0 "register_operand")
5662 (plus:SWI (match_operand:SWI 1 "register_operand")
5663 (match_operand:SWI 2 "<nonmemory_operand>")))
5664 (clobber (reg:CC FLAGS_REG))]
5665 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5666 [(set (match_dup 0)
5667 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5668 {
5669 if (<MODE>mode != <LEAMODE>mode)
5670 {
5671 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5672 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5673 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5674 }
5675 })
5676
5677 ;; Convert add to the lea pattern to avoid flags dependency.
5678 (define_split
5679 [(set (match_operand:DI 0 "register_operand")
5680 (zero_extend:DI
5681 (plus:SI (match_operand:SI 1 "register_operand")
5682 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5683 (clobber (reg:CC FLAGS_REG))]
5684 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5685 [(set (match_dup 0)
5686 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5687
5688 (define_insn "*add<mode>_2"
5689 [(set (reg FLAGS_REG)
5690 (compare
5691 (plus:SWI
5692 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5693 (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0"))
5694 (const_int 0)))
5695 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
5696 (plus:SWI (match_dup 1) (match_dup 2)))]
5697 "ix86_match_ccmode (insn, CCGOCmode)
5698 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5699 {
5700 switch (get_attr_type (insn))
5701 {
5702 case TYPE_INCDEC:
5703 if (operands[2] == const1_rtx)
5704 return "inc{<imodesuffix>}\t%0";
5705 else
5706 {
5707 gcc_assert (operands[2] == constm1_rtx);
5708 return "dec{<imodesuffix>}\t%0";
5709 }
5710
5711 default:
5712 if (which_alternative == 2)
5713 std::swap (operands[1], operands[2]);
5714
5715 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5717 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5718
5719 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5720 }
5721 }
5722 [(set (attr "type")
5723 (if_then_else (match_operand:SWI 2 "incdec_operand")
5724 (const_string "incdec")
5725 (const_string "alu")))
5726 (set (attr "length_immediate")
5727 (if_then_else
5728 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5729 (const_string "1")
5730 (const_string "*")))
5731 (set_attr "mode" "<MODE>")])
5732
5733 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5734 (define_insn "*addsi_2_zext"
5735 [(set (reg FLAGS_REG)
5736 (compare
5737 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5738 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5739 (const_int 0)))
5740 (set (match_operand:DI 0 "register_operand" "=r,r")
5741 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5743 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5744 {
5745 switch (get_attr_type (insn))
5746 {
5747 case TYPE_INCDEC:
5748 if (operands[2] == const1_rtx)
5749 return "inc{l}\t%k0";
5750 else
5751 {
5752 gcc_assert (operands[2] == constm1_rtx);
5753 return "dec{l}\t%k0";
5754 }
5755
5756 default:
5757 if (which_alternative == 1)
5758 std::swap (operands[1], operands[2]);
5759
5760 if (x86_maybe_negate_const_int (&operands[2], SImode))
5761 return "sub{l}\t{%2, %k0|%k0, %2}";
5762
5763 return "add{l}\t{%2, %k0|%k0, %2}";
5764 }
5765 }
5766 [(set (attr "type")
5767 (if_then_else (match_operand:SI 2 "incdec_operand")
5768 (const_string "incdec")
5769 (const_string "alu")))
5770 (set (attr "length_immediate")
5771 (if_then_else
5772 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5773 (const_string "1")
5774 (const_string "*")))
5775 (set_attr "mode" "SI")])
5776
5777 (define_insn "*add<mode>_3"
5778 [(set (reg FLAGS_REG)
5779 (compare
5780 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5781 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5782 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5783 "ix86_match_ccmode (insn, CCZmode)
5784 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5785 {
5786 switch (get_attr_type (insn))
5787 {
5788 case TYPE_INCDEC:
5789 if (operands[2] == const1_rtx)
5790 return "inc{<imodesuffix>}\t%0";
5791 else
5792 {
5793 gcc_assert (operands[2] == constm1_rtx);
5794 return "dec{<imodesuffix>}\t%0";
5795 }
5796
5797 default:
5798 if (which_alternative == 1)
5799 std::swap (operands[1], operands[2]);
5800
5801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5802 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5803 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5804
5805 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5806 }
5807 }
5808 [(set (attr "type")
5809 (if_then_else (match_operand:SWI 2 "incdec_operand")
5810 (const_string "incdec")
5811 (const_string "alu")))
5812 (set (attr "length_immediate")
5813 (if_then_else
5814 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5815 (const_string "1")
5816 (const_string "*")))
5817 (set_attr "mode" "<MODE>")])
5818
5819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5820 (define_insn "*addsi_3_zext"
5821 [(set (reg FLAGS_REG)
5822 (compare
5823 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5824 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5825 (set (match_operand:DI 0 "register_operand" "=r,r")
5826 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5827 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5828 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5829 {
5830 switch (get_attr_type (insn))
5831 {
5832 case TYPE_INCDEC:
5833 if (operands[2] == const1_rtx)
5834 return "inc{l}\t%k0";
5835 else
5836 {
5837 gcc_assert (operands[2] == constm1_rtx);
5838 return "dec{l}\t%k0";
5839 }
5840
5841 default:
5842 if (which_alternative == 1)
5843 std::swap (operands[1], operands[2]);
5844
5845 if (x86_maybe_negate_const_int (&operands[2], SImode))
5846 return "sub{l}\t{%2, %k0|%k0, %2}";
5847
5848 return "add{l}\t{%2, %k0|%k0, %2}";
5849 }
5850 }
5851 [(set (attr "type")
5852 (if_then_else (match_operand:SI 2 "incdec_operand")
5853 (const_string "incdec")
5854 (const_string "alu")))
5855 (set (attr "length_immediate")
5856 (if_then_else
5857 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5858 (const_string "1")
5859 (const_string "*")))
5860 (set_attr "mode" "SI")])
5861
5862 ; For comparisons against 1, -1 and 128, we may generate better code
5863 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5864 ; is matched then. We can't accept general immediate, because for
5865 ; case of overflows, the result is messed up.
5866 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5867 ; only for comparisons not depending on it.
5868
5869 (define_insn "*adddi_4"
5870 [(set (reg FLAGS_REG)
5871 (compare
5872 (match_operand:DI 1 "nonimmediate_operand" "0")
5873 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5874 (clobber (match_scratch:DI 0 "=rm"))]
5875 "TARGET_64BIT
5876 && ix86_match_ccmode (insn, CCGCmode)"
5877 {
5878 switch (get_attr_type (insn))
5879 {
5880 case TYPE_INCDEC:
5881 if (operands[2] == constm1_rtx)
5882 return "inc{q}\t%0";
5883 else
5884 {
5885 gcc_assert (operands[2] == const1_rtx);
5886 return "dec{q}\t%0";
5887 }
5888
5889 default:
5890 if (x86_maybe_negate_const_int (&operands[2], DImode))
5891 return "add{q}\t{%2, %0|%0, %2}";
5892
5893 return "sub{q}\t{%2, %0|%0, %2}";
5894 }
5895 }
5896 [(set (attr "type")
5897 (if_then_else (match_operand:DI 2 "incdec_operand")
5898 (const_string "incdec")
5899 (const_string "alu")))
5900 (set (attr "length_immediate")
5901 (if_then_else
5902 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5903 (const_string "1")
5904 (const_string "*")))
5905 (set_attr "mode" "DI")])
5906
5907 ; For comparisons against 1, -1 and 128, we may generate better code
5908 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5909 ; is matched then. We can't accept general immediate, because for
5910 ; case of overflows, the result is messed up.
5911 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5912 ; only for comparisons not depending on it.
5913
5914 (define_insn "*add<mode>_4"
5915 [(set (reg FLAGS_REG)
5916 (compare
5917 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5918 (match_operand:SWI124 2 "const_int_operand" "n")))
5919 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5920 "ix86_match_ccmode (insn, CCGCmode)"
5921 {
5922 switch (get_attr_type (insn))
5923 {
5924 case TYPE_INCDEC:
5925 if (operands[2] == constm1_rtx)
5926 return "inc{<imodesuffix>}\t%0";
5927 else
5928 {
5929 gcc_assert (operands[2] == const1_rtx);
5930 return "dec{<imodesuffix>}\t%0";
5931 }
5932
5933 default:
5934 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5935 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5936
5937 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5938 }
5939 }
5940 [(set (attr "type")
5941 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5942 (const_string "incdec")
5943 (const_string "alu")))
5944 (set (attr "length_immediate")
5945 (if_then_else
5946 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5947 (const_string "1")
5948 (const_string "*")))
5949 (set_attr "mode" "<MODE>")])
5950
5951 (define_insn "*add<mode>_5"
5952 [(set (reg FLAGS_REG)
5953 (compare
5954 (plus:SWI
5955 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5956 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5957 (const_int 0)))
5958 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5959 "ix86_match_ccmode (insn, CCGOCmode)
5960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5961 {
5962 switch (get_attr_type (insn))
5963 {
5964 case TYPE_INCDEC:
5965 if (operands[2] == const1_rtx)
5966 return "inc{<imodesuffix>}\t%0";
5967 else
5968 {
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return "dec{<imodesuffix>}\t%0";
5971 }
5972
5973 default:
5974 if (which_alternative == 1)
5975 std::swap (operands[1], operands[2]);
5976
5977 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5978 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5979 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5980
5981 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5982 }
5983 }
5984 [(set (attr "type")
5985 (if_then_else (match_operand:SWI 2 "incdec_operand")
5986 (const_string "incdec")
5987 (const_string "alu")))
5988 (set (attr "length_immediate")
5989 (if_then_else
5990 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5991 (const_string "1")
5992 (const_string "*")))
5993 (set_attr "mode" "<MODE>")])
5994
5995 (define_insn "addqi_ext_1"
5996 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
5997 (const_int 8)
5998 (const_int 8))
5999 (subreg:SI
6000 (plus:QI
6001 (subreg:QI
6002 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6003 (const_int 8)
6004 (const_int 8)) 0)
6005 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6006 (clobber (reg:CC FLAGS_REG))]
6007 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6008 rtx_equal_p (operands[0], operands[1])"
6009 {
6010 switch (get_attr_type (insn))
6011 {
6012 case TYPE_INCDEC:
6013 if (operands[2] == const1_rtx)
6014 return "inc{b}\t%h0";
6015 else
6016 {
6017 gcc_assert (operands[2] == constm1_rtx);
6018 return "dec{b}\t%h0";
6019 }
6020
6021 default:
6022 return "add{b}\t{%2, %h0|%h0, %2}";
6023 }
6024 }
6025 [(set_attr "isa" "*,nox64")
6026 (set (attr "type")
6027 (if_then_else (match_operand:QI 2 "incdec_operand")
6028 (const_string "incdec")
6029 (const_string "alu")))
6030 (set_attr "mode" "QI")])
6031
6032 (define_insn "*addqi_ext_2"
6033 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6034 (const_int 8)
6035 (const_int 8))
6036 (subreg:SI
6037 (plus:QI
6038 (subreg:QI
6039 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6040 (const_int 8)
6041 (const_int 8)) 0)
6042 (subreg:QI
6043 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6044 (const_int 8)
6045 (const_int 8)) 0)) 0))
6046 (clobber (reg:CC FLAGS_REG))]
6047 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6048 rtx_equal_p (operands[0], operands[1])
6049 || rtx_equal_p (operands[0], operands[2])"
6050 "add{b}\t{%h2, %h0|%h0, %h2}"
6051 [(set_attr "type" "alu")
6052 (set_attr "mode" "QI")])
6053
6054 ;; Add with jump on overflow.
6055 (define_expand "addv<mode>4"
6056 [(parallel [(set (reg:CCO FLAGS_REG)
6057 (eq:CCO (plus:<DWI>
6058 (sign_extend:<DWI>
6059 (match_operand:SWI 1 "nonimmediate_operand"))
6060 (match_dup 4))
6061 (sign_extend:<DWI>
6062 (plus:SWI (match_dup 1)
6063 (match_operand:SWI 2
6064 "<general_operand>")))))
6065 (set (match_operand:SWI 0 "register_operand")
6066 (plus:SWI (match_dup 1) (match_dup 2)))])
6067 (set (pc) (if_then_else
6068 (eq (reg:CCO FLAGS_REG) (const_int 0))
6069 (label_ref (match_operand 3))
6070 (pc)))]
6071 ""
6072 {
6073 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6074 if (CONST_INT_P (operands[2]))
6075 operands[4] = operands[2];
6076 else
6077 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6078 })
6079
6080 (define_insn "*addv<mode>4"
6081 [(set (reg:CCO FLAGS_REG)
6082 (eq:CCO (plus:<DWI>
6083 (sign_extend:<DWI>
6084 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6085 (sign_extend:<DWI>
6086 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6087 (sign_extend:<DWI>
6088 (plus:SWI (match_dup 1) (match_dup 2)))))
6089 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6090 (plus:SWI (match_dup 1) (match_dup 2)))]
6091 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6092 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6093 [(set_attr "type" "alu")
6094 (set_attr "mode" "<MODE>")])
6095
6096 (define_insn "*addv<mode>4_1"
6097 [(set (reg:CCO FLAGS_REG)
6098 (eq:CCO (plus:<DWI>
6099 (sign_extend:<DWI>
6100 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6101 (match_operand:<DWI> 3 "const_int_operand" "i"))
6102 (sign_extend:<DWI>
6103 (plus:SWI
6104 (match_dup 1)
6105 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6106 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6107 (plus:SWI (match_dup 1) (match_dup 2)))]
6108 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6109 && CONST_INT_P (operands[2])
6110 && INTVAL (operands[2]) == INTVAL (operands[3])"
6111 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6112 [(set_attr "type" "alu")
6113 (set_attr "mode" "<MODE>")
6114 (set (attr "length_immediate")
6115 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6116 (const_string "1")
6117 (match_test "<MODE_SIZE> == 8")
6118 (const_string "4")]
6119 (const_string "<MODE_SIZE>")))])
6120
6121 (define_expand "uaddv<mode>4"
6122 [(parallel [(set (reg:CCC FLAGS_REG)
6123 (compare:CCC
6124 (plus:SWI
6125 (match_operand:SWI 1 "nonimmediate_operand")
6126 (match_operand:SWI 2 "<general_operand>"))
6127 (match_dup 1)))
6128 (set (match_operand:SWI 0 "register_operand")
6129 (plus:SWI (match_dup 1) (match_dup 2)))])
6130 (set (pc) (if_then_else
6131 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6132 (label_ref (match_operand 3))
6133 (pc)))]
6134 ""
6135 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6136
6137 ;; The lea patterns for modes less than 32 bits need to be matched by
6138 ;; several insns converted to real lea by splitters.
6139
6140 (define_insn_and_split "*lea<mode>_general_1"
6141 [(set (match_operand:SWI12 0 "register_operand" "=r")
6142 (plus:SWI12
6143 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6144 (match_operand:SWI12 2 "register_operand" "r"))
6145 (match_operand:SWI12 3 "immediate_operand" "i")))]
6146 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6147 "#"
6148 "&& reload_completed"
6149 [(set (match_dup 0)
6150 (plus:SI
6151 (plus:SI (match_dup 1) (match_dup 2))
6152 (match_dup 3)))]
6153 {
6154 operands[0] = gen_lowpart (SImode, operands[0]);
6155 operands[1] = gen_lowpart (SImode, operands[1]);
6156 operands[2] = gen_lowpart (SImode, operands[2]);
6157 operands[3] = gen_lowpart (SImode, operands[3]);
6158 }
6159 [(set_attr "type" "lea")
6160 (set_attr "mode" "SI")])
6161
6162 (define_insn_and_split "*lea<mode>_general_2"
6163 [(set (match_operand:SWI12 0 "register_operand" "=r")
6164 (plus:SWI12
6165 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6166 (match_operand 2 "const248_operand" "n"))
6167 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6168 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6169 "#"
6170 "&& reload_completed"
6171 [(set (match_dup 0)
6172 (plus:SI
6173 (mult:SI (match_dup 1) (match_dup 2))
6174 (match_dup 3)))]
6175 {
6176 operands[0] = gen_lowpart (SImode, operands[0]);
6177 operands[1] = gen_lowpart (SImode, operands[1]);
6178 operands[3] = gen_lowpart (SImode, operands[3]);
6179 }
6180 [(set_attr "type" "lea")
6181 (set_attr "mode" "SI")])
6182
6183 (define_insn_and_split "*lea<mode>_general_2b"
6184 [(set (match_operand:SWI12 0 "register_operand" "=r")
6185 (plus:SWI12
6186 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6187 (match_operand 2 "const123_operand" "n"))
6188 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6189 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6190 "#"
6191 "&& reload_completed"
6192 [(set (match_dup 0)
6193 (plus:SI
6194 (ashift:SI (match_dup 1) (match_dup 2))
6195 (match_dup 3)))]
6196 {
6197 operands[0] = gen_lowpart (SImode, operands[0]);
6198 operands[1] = gen_lowpart (SImode, operands[1]);
6199 operands[3] = gen_lowpart (SImode, operands[3]);
6200 }
6201 [(set_attr "type" "lea")
6202 (set_attr "mode" "SI")])
6203
6204 (define_insn_and_split "*lea<mode>_general_3"
6205 [(set (match_operand:SWI12 0 "register_operand" "=r")
6206 (plus:SWI12
6207 (plus:SWI12
6208 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6209 (match_operand 2 "const248_operand" "n"))
6210 (match_operand:SWI12 3 "register_operand" "r"))
6211 (match_operand:SWI12 4 "immediate_operand" "i")))]
6212 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6213 "#"
6214 "&& reload_completed"
6215 [(set (match_dup 0)
6216 (plus:SI
6217 (plus:SI
6218 (mult:SI (match_dup 1) (match_dup 2))
6219 (match_dup 3))
6220 (match_dup 4)))]
6221 {
6222 operands[0] = gen_lowpart (SImode, operands[0]);
6223 operands[1] = gen_lowpart (SImode, operands[1]);
6224 operands[3] = gen_lowpart (SImode, operands[3]);
6225 operands[4] = gen_lowpart (SImode, operands[4]);
6226 }
6227 [(set_attr "type" "lea")
6228 (set_attr "mode" "SI")])
6229
6230 (define_insn_and_split "*lea<mode>_general_3b"
6231 [(set (match_operand:SWI12 0 "register_operand" "=r")
6232 (plus:SWI12
6233 (plus:SWI12
6234 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6235 (match_operand 2 "const123_operand" "n"))
6236 (match_operand:SWI12 3 "register_operand" "r"))
6237 (match_operand:SWI12 4 "immediate_operand" "i")))]
6238 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6239 "#"
6240 "&& reload_completed"
6241 [(set (match_dup 0)
6242 (plus:SI
6243 (plus:SI
6244 (ashift:SI (match_dup 1) (match_dup 2))
6245 (match_dup 3))
6246 (match_dup 4)))]
6247 {
6248 operands[0] = gen_lowpart (SImode, operands[0]);
6249 operands[1] = gen_lowpart (SImode, operands[1]);
6250 operands[3] = gen_lowpart (SImode, operands[3]);
6251 operands[4] = gen_lowpart (SImode, operands[4]);
6252 }
6253 [(set_attr "type" "lea")
6254 (set_attr "mode" "SI")])
6255
6256 (define_insn_and_split "*lea<mode>_general_4"
6257 [(set (match_operand:SWI12 0 "register_operand" "=r")
6258 (any_or:SWI12
6259 (ashift:SWI12
6260 (match_operand:SWI12 1 "index_register_operand" "l")
6261 (match_operand 2 "const_0_to_3_operand" "n"))
6262 (match_operand 3 "const_int_operand" "n")))]
6263 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6264 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6265 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6266 "#"
6267 "&& reload_completed"
6268 [(set (match_dup 0)
6269 (plus:SI
6270 (mult:SI (match_dup 1) (match_dup 2))
6271 (match_dup 3)))]
6272 {
6273 operands[0] = gen_lowpart (SImode, operands[0]);
6274 operands[1] = gen_lowpart (SImode, operands[1]);
6275 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6276 }
6277 [(set_attr "type" "lea")
6278 (set_attr "mode" "SI")])
6279
6280 (define_insn_and_split "*lea<mode>_general_4"
6281 [(set (match_operand:SWI48 0 "register_operand" "=r")
6282 (any_or:SWI48
6283 (ashift:SWI48
6284 (match_operand:SWI48 1 "index_register_operand" "l")
6285 (match_operand 2 "const_0_to_3_operand" "n"))
6286 (match_operand 3 "const_int_operand" "n")))]
6287 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6288 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6289 "#"
6290 "&& reload_completed"
6291 [(set (match_dup 0)
6292 (plus:SWI48
6293 (mult:SWI48 (match_dup 1) (match_dup 2))
6294 (match_dup 3)))]
6295 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6296 [(set_attr "type" "lea")
6297 (set_attr "mode" "<MODE>")])
6298 \f
6299 ;; Subtract instructions
6300
6301 (define_expand "sub<mode>3"
6302 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6303 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6304 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6305 ""
6306 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6307
6308 (define_insn_and_split "*sub<dwi>3_doubleword"
6309 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6310 (minus:<DWI>
6311 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6312 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6313 (clobber (reg:CC FLAGS_REG))]
6314 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6315 "#"
6316 "reload_completed"
6317 [(parallel [(set (reg:CC FLAGS_REG)
6318 (compare:CC (match_dup 1) (match_dup 2)))
6319 (set (match_dup 0)
6320 (minus:DWIH (match_dup 1) (match_dup 2)))])
6321 (parallel [(set (match_dup 3)
6322 (minus:DWIH
6323 (minus:DWIH
6324 (match_dup 4)
6325 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6326 (match_dup 5)))
6327 (clobber (reg:CC FLAGS_REG))])]
6328 {
6329 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6330 if (operands[2] == const0_rtx)
6331 {
6332 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6333 DONE;
6334 }
6335 })
6336
6337 (define_insn "*sub<mode>_1"
6338 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6339 (minus:SWI
6340 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6341 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6342 (clobber (reg:CC FLAGS_REG))]
6343 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6344 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6345 [(set_attr "type" "alu")
6346 (set_attr "mode" "<MODE>")])
6347
6348 (define_insn "*subsi_1_zext"
6349 [(set (match_operand:DI 0 "register_operand" "=r")
6350 (zero_extend:DI
6351 (minus:SI (match_operand:SI 1 "register_operand" "0")
6352 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6353 (clobber (reg:CC FLAGS_REG))]
6354 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6355 "sub{l}\t{%2, %k0|%k0, %2}"
6356 [(set_attr "type" "alu")
6357 (set_attr "mode" "SI")])
6358
6359 (define_insn "*sub<mode>_1_slp"
6360 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
6361 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0")
6362 (match_operand:SWI12 2 "general_operand" "<r>mn")))
6363 (clobber (reg:CC FLAGS_REG))]
6364 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6365 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
6366 && rtx_equal_p (operands[0], operands[1])"
6367 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6368 [(set_attr "type" "alu")
6369 (set_attr "mode" "<MODE>")])
6370
6371 (define_insn "*sub<mode>_2"
6372 [(set (reg FLAGS_REG)
6373 (compare
6374 (minus:SWI
6375 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6376 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6377 (const_int 0)))
6378 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6379 (minus:SWI (match_dup 1) (match_dup 2)))]
6380 "ix86_match_ccmode (insn, CCGOCmode)
6381 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6382 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6383 [(set_attr "type" "alu")
6384 (set_attr "mode" "<MODE>")])
6385
6386 (define_insn "*subsi_2_zext"
6387 [(set (reg FLAGS_REG)
6388 (compare
6389 (minus:SI (match_operand:SI 1 "register_operand" "0")
6390 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6391 (const_int 0)))
6392 (set (match_operand:DI 0 "register_operand" "=r")
6393 (zero_extend:DI
6394 (minus:SI (match_dup 1)
6395 (match_dup 2))))]
6396 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6397 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6398 "sub{l}\t{%2, %k0|%k0, %2}"
6399 [(set_attr "type" "alu")
6400 (set_attr "mode" "SI")])
6401
6402 ;; Subtract with jump on overflow.
6403 (define_expand "subv<mode>4"
6404 [(parallel [(set (reg:CCO FLAGS_REG)
6405 (eq:CCO (minus:<DWI>
6406 (sign_extend:<DWI>
6407 (match_operand:SWI 1 "nonimmediate_operand"))
6408 (match_dup 4))
6409 (sign_extend:<DWI>
6410 (minus:SWI (match_dup 1)
6411 (match_operand:SWI 2
6412 "<general_operand>")))))
6413 (set (match_operand:SWI 0 "register_operand")
6414 (minus:SWI (match_dup 1) (match_dup 2)))])
6415 (set (pc) (if_then_else
6416 (eq (reg:CCO FLAGS_REG) (const_int 0))
6417 (label_ref (match_operand 3))
6418 (pc)))]
6419 ""
6420 {
6421 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6422 if (CONST_INT_P (operands[2]))
6423 operands[4] = operands[2];
6424 else
6425 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6426 })
6427
6428 (define_insn "*subv<mode>4"
6429 [(set (reg:CCO FLAGS_REG)
6430 (eq:CCO (minus:<DWI>
6431 (sign_extend:<DWI>
6432 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6433 (sign_extend:<DWI>
6434 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6435 (sign_extend:<DWI>
6436 (minus:SWI (match_dup 1) (match_dup 2)))))
6437 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6438 (minus:SWI (match_dup 1) (match_dup 2)))]
6439 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6440 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6441 [(set_attr "type" "alu")
6442 (set_attr "mode" "<MODE>")])
6443
6444 (define_insn "*subv<mode>4_1"
6445 [(set (reg:CCO FLAGS_REG)
6446 (eq:CCO (minus:<DWI>
6447 (sign_extend:<DWI>
6448 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6449 (match_operand:<DWI> 3 "const_int_operand" "i"))
6450 (sign_extend:<DWI>
6451 (minus:SWI
6452 (match_dup 1)
6453 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6454 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6455 (minus:SWI (match_dup 1) (match_dup 2)))]
6456 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6457 && CONST_INT_P (operands[2])
6458 && INTVAL (operands[2]) == INTVAL (operands[3])"
6459 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6460 [(set_attr "type" "alu")
6461 (set_attr "mode" "<MODE>")
6462 (set (attr "length_immediate")
6463 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6464 (const_string "1")
6465 (match_test "<MODE_SIZE> == 8")
6466 (const_string "4")]
6467 (const_string "<MODE_SIZE>")))])
6468
6469 (define_expand "usubv<mode>4"
6470 [(parallel [(set (reg:CC FLAGS_REG)
6471 (compare:CC
6472 (match_operand:SWI 1 "nonimmediate_operand")
6473 (match_operand:SWI 2 "<general_operand>")))
6474 (set (match_operand:SWI 0 "register_operand")
6475 (minus:SWI (match_dup 1) (match_dup 2)))])
6476 (set (pc) (if_then_else
6477 (ltu (reg:CC FLAGS_REG) (const_int 0))
6478 (label_ref (match_operand 3))
6479 (pc)))]
6480 ""
6481 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6482
6483 (define_insn "*sub<mode>_3"
6484 [(set (reg FLAGS_REG)
6485 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6487 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6488 (minus:SWI (match_dup 1) (match_dup 2)))]
6489 "ix86_match_ccmode (insn, CCmode)
6490 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6491 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "<MODE>")])
6494
6495 (define_peephole2
6496 [(parallel
6497 [(set (reg:CC FLAGS_REG)
6498 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6499 (match_operand:SWI 1 "general_gr_operand")))
6500 (set (match_dup 0)
6501 (minus:SWI (match_dup 0) (match_dup 1)))])]
6502 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6503 [(set (reg:CC FLAGS_REG)
6504 (compare:CC (match_dup 0) (match_dup 1)))])
6505
6506 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
6507 ;; subl $1, %eax; jnc .Lxx;
6508 (define_peephole2
6509 [(parallel
6510 [(set (match_operand:SWI 0 "general_reg_operand")
6511 (plus:SWI (match_dup 0) (const_int -1)))
6512 (clobber (reg FLAGS_REG))])
6513 (set (reg:CCZ FLAGS_REG)
6514 (compare:CCZ (match_dup 0) (const_int -1)))
6515 (set (pc)
6516 (if_then_else (match_operator 1 "bt_comparison_operator"
6517 [(reg:CCZ FLAGS_REG) (const_int 0)])
6518 (match_operand 2)
6519 (pc)))]
6520 "peep2_regno_dead_p (3, FLAGS_REG)"
6521 [(parallel
6522 [(set (reg:CC FLAGS_REG)
6523 (compare:CC (match_dup 0) (const_int 1)))
6524 (set (match_dup 0)
6525 (minus:SWI (match_dup 0) (const_int 1)))])
6526 (set (pc)
6527 (if_then_else (match_dup 3)
6528 (match_dup 2)
6529 (pc)))]
6530 {
6531 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
6532 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
6533 ? GEU : LTU, VOIDmode, cc, const0_rtx);
6534 })
6535
6536 (define_insn "*subsi_3_zext"
6537 [(set (reg FLAGS_REG)
6538 (compare (match_operand:SI 1 "register_operand" "0")
6539 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6540 (set (match_operand:DI 0 "register_operand" "=r")
6541 (zero_extend:DI
6542 (minus:SI (match_dup 1)
6543 (match_dup 2))))]
6544 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6545 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6546 "sub{l}\t{%2, %1|%1, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "mode" "SI")])
6549 \f
6550 ;; Add with carry and subtract with borrow
6551
6552 (define_insn "@add<mode>3_carry"
6553 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6554 (plus:SWI
6555 (plus:SWI
6556 (match_operator:SWI 4 "ix86_carry_flag_operator"
6557 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6558 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6559 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "use_carry" "1")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "<MODE>")])
6567
6568 (define_insn "*add<mode>3_carry_0"
6569 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6570 (plus:SWI
6571 (match_operator:SWI 3 "ix86_carry_flag_operator"
6572 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6573 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6574 (clobber (reg:CC FLAGS_REG))]
6575 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6576 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6577 [(set_attr "type" "alu")
6578 (set_attr "use_carry" "1")
6579 (set_attr "pent_pair" "pu")
6580 (set_attr "mode" "<MODE>")])
6581
6582 (define_insn "*addsi3_carry_zext"
6583 [(set (match_operand:DI 0 "register_operand" "=r")
6584 (zero_extend:DI
6585 (plus:SI
6586 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6587 [(reg FLAGS_REG) (const_int 0)])
6588 (match_operand:SI 1 "register_operand" "%0"))
6589 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6590 (clobber (reg:CC FLAGS_REG))]
6591 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6592 "adc{l}\t{%2, %k0|%k0, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "use_carry" "1")
6595 (set_attr "pent_pair" "pu")
6596 (set_attr "mode" "SI")])
6597
6598 (define_insn "*addsi3_carry_zext_0"
6599 [(set (match_operand:DI 0 "register_operand" "=r")
6600 (zero_extend:DI
6601 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6602 [(reg FLAGS_REG) (const_int 0)])
6603 (match_operand:SI 1 "register_operand" "0"))))
6604 (clobber (reg:CC FLAGS_REG))]
6605 "TARGET_64BIT"
6606 "adc{l}\t{$0, %k0|%k0, 0}"
6607 [(set_attr "type" "alu")
6608 (set_attr "use_carry" "1")
6609 (set_attr "pent_pair" "pu")
6610 (set_attr "mode" "SI")])
6611
6612 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6613
6614 (define_insn "addcarry<mode>"
6615 [(set (reg:CCC FLAGS_REG)
6616 (compare:CCC
6617 (zero_extend:<DWI>
6618 (plus:SWI48
6619 (plus:SWI48
6620 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6621 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6622 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6623 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6624 (plus:<DWI>
6625 (zero_extend:<DWI> (match_dup 2))
6626 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6627 [(match_dup 3) (const_int 0)]))))
6628 (set (match_operand:SWI48 0 "register_operand" "=r")
6629 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6630 [(match_dup 3) (const_int 0)])
6631 (match_dup 1))
6632 (match_dup 2)))]
6633 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6634 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6635 [(set_attr "type" "alu")
6636 (set_attr "use_carry" "1")
6637 (set_attr "pent_pair" "pu")
6638 (set_attr "mode" "<MODE>")])
6639
6640 (define_expand "addcarry<mode>_0"
6641 [(parallel
6642 [(set (reg:CCC FLAGS_REG)
6643 (compare:CCC
6644 (plus:SWI48
6645 (match_operand:SWI48 1 "nonimmediate_operand")
6646 (match_operand:SWI48 2 "x86_64_general_operand"))
6647 (match_dup 1)))
6648 (set (match_operand:SWI48 0 "register_operand")
6649 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6650 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6651
6652 (define_insn "@sub<mode>3_carry"
6653 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6654 (minus:SWI
6655 (minus:SWI
6656 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6657 (match_operator:SWI 4 "ix86_carry_flag_operator"
6658 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6659 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6662 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6663 [(set_attr "type" "alu")
6664 (set_attr "use_carry" "1")
6665 (set_attr "pent_pair" "pu")
6666 (set_attr "mode" "<MODE>")])
6667
6668 (define_insn "*sub<mode>3_carry_0"
6669 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6670 (minus:SWI
6671 (match_operand:SWI 1 "nonimmediate_operand" "0")
6672 (match_operator:SWI 3 "ix86_carry_flag_operator"
6673 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6674 (clobber (reg:CC FLAGS_REG))]
6675 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6676 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6677 [(set_attr "type" "alu")
6678 (set_attr "use_carry" "1")
6679 (set_attr "pent_pair" "pu")
6680 (set_attr "mode" "<MODE>")])
6681
6682 (define_insn "*subsi3_carry_zext"
6683 [(set (match_operand:DI 0 "register_operand" "=r")
6684 (zero_extend:DI
6685 (minus:SI
6686 (minus:SI
6687 (match_operand:SI 1 "register_operand" "0")
6688 (match_operator:SI 3 "ix86_carry_flag_operator"
6689 [(reg FLAGS_REG) (const_int 0)]))
6690 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6691 (clobber (reg:CC FLAGS_REG))]
6692 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693 "sbb{l}\t{%2, %k0|%k0, %2}"
6694 [(set_attr "type" "alu")
6695 (set_attr "use_carry" "1")
6696 (set_attr "pent_pair" "pu")
6697 (set_attr "mode" "SI")])
6698
6699 (define_insn "*subsi3_carry_zext_0"
6700 [(set (match_operand:DI 0 "register_operand" "=r")
6701 (zero_extend:DI
6702 (minus:SI
6703 (match_operand:SI 1 "register_operand" "0")
6704 (match_operator:SI 2 "ix86_carry_flag_operator"
6705 [(reg FLAGS_REG) (const_int 0)]))))
6706 (clobber (reg:CC FLAGS_REG))]
6707 "TARGET_64BIT"
6708 "sbb{l}\t{$0, %k0|%k0, 0}"
6709 [(set_attr "type" "alu")
6710 (set_attr "use_carry" "1")
6711 (set_attr "pent_pair" "pu")
6712 (set_attr "mode" "SI")])
6713
6714 (define_insn "@sub<mode>3_carry_ccc"
6715 [(set (reg:CCC FLAGS_REG)
6716 (compare:CCC
6717 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6718 (plus:<DWI>
6719 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6720 (zero_extend:<DWI>
6721 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6722 (clobber (match_scratch:DWIH 0 "=r"))]
6723 ""
6724 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "<MODE>")])
6727
6728 (define_insn "*sub<mode>3_carry_ccc_1"
6729 [(set (reg:CCC FLAGS_REG)
6730 (compare:CCC
6731 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6732 (plus:<DWI>
6733 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6734 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6735 (clobber (match_scratch:DWIH 0 "=r"))]
6736 ""
6737 {
6738 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6739 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6740 }
6741 [(set_attr "type" "alu")
6742 (set_attr "mode" "<MODE>")])
6743
6744 ;; The sign flag is set from the
6745 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6746 ;; result, the overflow flag likewise, but the overflow flag is also
6747 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6748 (define_insn "@sub<mode>3_carry_ccgz"
6749 [(set (reg:CCGZ FLAGS_REG)
6750 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6751 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6752 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6753 UNSPEC_SBB))
6754 (clobber (match_scratch:DWIH 0 "=r"))]
6755 ""
6756 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6757 [(set_attr "type" "alu")
6758 (set_attr "mode" "<MODE>")])
6759
6760 (define_insn "subborrow<mode>"
6761 [(set (reg:CCC FLAGS_REG)
6762 (compare:CCC
6763 (zero_extend:<DWI>
6764 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6765 (plus:<DWI>
6766 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6767 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6768 (zero_extend:<DWI>
6769 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6770 (set (match_operand:SWI48 0 "register_operand" "=r")
6771 (minus:SWI48 (minus:SWI48
6772 (match_dup 1)
6773 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6774 [(match_dup 3) (const_int 0)]))
6775 (match_dup 2)))]
6776 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6777 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "use_carry" "1")
6780 (set_attr "pent_pair" "pu")
6781 (set_attr "mode" "<MODE>")])
6782
6783 (define_expand "subborrow<mode>_0"
6784 [(parallel
6785 [(set (reg:CC FLAGS_REG)
6786 (compare:CC
6787 (match_operand:SWI48 1 "nonimmediate_operand")
6788 (match_operand:SWI48 2 "<general_operand>")))
6789 (set (match_operand:SWI48 0 "register_operand")
6790 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6791 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6792 \f
6793 ;; Overflow setting add instructions
6794
6795 (define_expand "addqi3_cconly_overflow"
6796 [(parallel
6797 [(set (reg:CCC FLAGS_REG)
6798 (compare:CCC
6799 (plus:QI
6800 (match_operand:QI 0 "nonimmediate_operand")
6801 (match_operand:QI 1 "general_operand"))
6802 (match_dup 0)))
6803 (clobber (match_scratch:QI 2))])]
6804 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6805
6806 (define_insn "*add<mode>3_cconly_overflow_1"
6807 [(set (reg:CCC FLAGS_REG)
6808 (compare:CCC
6809 (plus:SWI
6810 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6811 (match_operand:SWI 2 "<general_operand>" "<g>"))
6812 (match_dup 1)))
6813 (clobber (match_scratch:SWI 0 "=<r>"))]
6814 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6815 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6816 [(set_attr "type" "alu")
6817 (set_attr "mode" "<MODE>")])
6818
6819 (define_insn "*add<mode>3_cc_overflow_1"
6820 [(set (reg:CCC FLAGS_REG)
6821 (compare:CCC
6822 (plus:SWI
6823 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6824 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6825 (match_dup 1)))
6826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6827 (plus:SWI (match_dup 1) (match_dup 2)))]
6828 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6829 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6830 [(set_attr "type" "alu")
6831 (set_attr "mode" "<MODE>")])
6832
6833 (define_insn "*addsi3_zext_cc_overflow_1"
6834 [(set (reg:CCC FLAGS_REG)
6835 (compare:CCC
6836 (plus:SI
6837 (match_operand:SI 1 "nonimmediate_operand" "%0")
6838 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6839 (match_dup 1)))
6840 (set (match_operand:DI 0 "register_operand" "=r")
6841 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6842 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6843 "add{l}\t{%2, %k0|%k0, %2}"
6844 [(set_attr "type" "alu")
6845 (set_attr "mode" "SI")])
6846
6847 (define_insn "*add<mode>3_cconly_overflow_2"
6848 [(set (reg:CCC FLAGS_REG)
6849 (compare:CCC
6850 (plus:SWI
6851 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6852 (match_operand:SWI 2 "<general_operand>" "<g>"))
6853 (match_dup 2)))
6854 (clobber (match_scratch:SWI 0 "=<r>"))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6857 [(set_attr "type" "alu")
6858 (set_attr "mode" "<MODE>")])
6859
6860 (define_insn "*add<mode>3_cc_overflow_2"
6861 [(set (reg:CCC FLAGS_REG)
6862 (compare:CCC
6863 (plus:SWI
6864 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6865 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6866 (match_dup 2)))
6867 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6868 (plus:SWI (match_dup 1) (match_dup 2)))]
6869 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6870 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6871 [(set_attr "type" "alu")
6872 (set_attr "mode" "<MODE>")])
6873
6874 (define_insn "*addsi3_zext_cc_overflow_2"
6875 [(set (reg:CCC FLAGS_REG)
6876 (compare:CCC
6877 (plus:SI
6878 (match_operand:SI 1 "nonimmediate_operand" "%0")
6879 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6880 (match_dup 2)))
6881 (set (match_operand:DI 0 "register_operand" "=r")
6882 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6883 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6884 "add{l}\t{%2, %k0|%k0, %2}"
6885 [(set_attr "type" "alu")
6886 (set_attr "mode" "SI")])
6887
6888 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
6889 ;; test, where the latter is preferrable if we have some carry consuming
6890 ;; instruction.
6891 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
6892 ;; + (1 - CF).
6893 (define_insn_and_split "*add<mode>3_eq"
6894 [(set (match_operand:SWI 0 "nonimmediate_operand")
6895 (plus:SWI
6896 (plus:SWI
6897 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
6898 (match_operand:SWI 1 "nonimmediate_operand"))
6899 (match_operand:SWI 2 "<general_operand>")))
6900 (clobber (reg:CC FLAGS_REG))]
6901 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6902 && ix86_pre_reload_split ()"
6903 "#"
6904 "&& 1"
6905 [(set (reg:CC FLAGS_REG)
6906 (compare:CC (match_dup 3) (const_int 1)))
6907 (parallel [(set (match_dup 0)
6908 (plus:SWI
6909 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
6910 (match_dup 1))
6911 (match_dup 2)))
6912 (clobber (reg:CC FLAGS_REG))])])
6913
6914 (define_insn_and_split "*add<mode>3_ne"
6915 [(set (match_operand:SWI 0 "nonimmediate_operand")
6916 (plus:SWI
6917 (plus:SWI
6918 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
6919 (match_operand:SWI 1 "nonimmediate_operand"))
6920 (match_operand:SWI 2 "<immediate_operand>")))
6921 (clobber (reg:CC FLAGS_REG))]
6922 "CONST_INT_P (operands[2])
6923 && (<MODE>mode != DImode
6924 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
6925 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6926 && ix86_pre_reload_split ()"
6927 "#"
6928 "&& 1"
6929 [(set (reg:CC FLAGS_REG)
6930 (compare:CC (match_dup 3) (const_int 1)))
6931 (parallel [(set (match_dup 0)
6932 (minus:SWI
6933 (minus:SWI (match_dup 1)
6934 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
6935 (match_dup 2)))
6936 (clobber (reg:CC FLAGS_REG))])]
6937 {
6938 operands[2] = gen_int_mode (~INTVAL (operands[2]),
6939 <MODE>mode == DImode ? SImode : <MODE>mode);
6940 })
6941
6942 (define_insn_and_split "*add<mode>3_eq_0"
6943 [(set (match_operand:SWI 0 "nonimmediate_operand")
6944 (plus:SWI
6945 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
6946 (match_operand:SWI 1 "<general_operand>")))
6947 (clobber (reg:CC FLAGS_REG))]
6948 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
6949 && ix86_pre_reload_split ()"
6950 "#"
6951 "&& 1"
6952 [(set (reg:CC FLAGS_REG)
6953 (compare:CC (match_dup 2) (const_int 1)))
6954 (parallel [(set (match_dup 0)
6955 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
6956 (match_dup 1)))
6957 (clobber (reg:CC FLAGS_REG))])]
6958 {
6959 if (!nonimmediate_operand (operands[1], <MODE>mode))
6960 operands[1] = force_reg (<MODE>mode, operands[1]);
6961 })
6962
6963 (define_insn_and_split "*add<mode>3_ne_0"
6964 [(set (match_operand:SWI 0 "nonimmediate_operand")
6965 (plus:SWI
6966 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
6967 (match_operand:SWI 1 "<general_operand>")))
6968 (clobber (reg:CC FLAGS_REG))]
6969 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
6970 && ix86_pre_reload_split ()"
6971 "#"
6972 "&& 1"
6973 [(set (reg:CC FLAGS_REG)
6974 (compare:CC (match_dup 2) (const_int 1)))
6975 (parallel [(set (match_dup 0)
6976 (minus:SWI (minus:SWI
6977 (match_dup 1)
6978 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
6979 (const_int -1)))
6980 (clobber (reg:CC FLAGS_REG))])]
6981 {
6982 if (!nonimmediate_operand (operands[1], <MODE>mode))
6983 operands[1] = force_reg (<MODE>mode, operands[1]);
6984 })
6985
6986 (define_insn_and_split "*sub<mode>3_eq"
6987 [(set (match_operand:SWI 0 "nonimmediate_operand")
6988 (minus:SWI
6989 (minus:SWI
6990 (match_operand:SWI 1 "nonimmediate_operand")
6991 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
6992 (const_int 0)))
6993 (match_operand:SWI 2 "<general_operand>")))
6994 (clobber (reg:CC FLAGS_REG))]
6995 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6996 && ix86_pre_reload_split ()"
6997 "#"
6998 "&& 1"
6999 [(set (reg:CC FLAGS_REG)
7000 (compare:CC (match_dup 3) (const_int 1)))
7001 (parallel [(set (match_dup 0)
7002 (minus:SWI
7003 (minus:SWI (match_dup 1)
7004 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7005 (match_dup 2)))
7006 (clobber (reg:CC FLAGS_REG))])])
7007
7008 (define_insn_and_split "*sub<mode>3_ne"
7009 [(set (match_operand:SWI 0 "nonimmediate_operand")
7010 (plus:SWI
7011 (minus:SWI
7012 (match_operand:SWI 1 "nonimmediate_operand")
7013 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
7014 (const_int 0)))
7015 (match_operand:SWI 2 "<immediate_operand>")))
7016 (clobber (reg:CC FLAGS_REG))]
7017 "CONST_INT_P (operands[2])
7018 && (<MODE>mode != DImode
7019 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7020 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7021 && ix86_pre_reload_split ()"
7022 "#"
7023 "&& 1"
7024 [(set (reg:CC FLAGS_REG)
7025 (compare:CC (match_dup 3) (const_int 1)))
7026 (parallel [(set (match_dup 0)
7027 (plus:SWI
7028 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7029 (match_dup 1))
7030 (match_dup 2)))
7031 (clobber (reg:CC FLAGS_REG))])]
7032 {
7033 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
7034 <MODE>mode == DImode ? SImode : <MODE>mode);
7035 })
7036
7037 (define_insn_and_split "*sub<mode>3_eq_1"
7038 [(set (match_operand:SWI 0 "nonimmediate_operand")
7039 (plus:SWI
7040 (minus:SWI
7041 (match_operand:SWI 1 "nonimmediate_operand")
7042 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7043 (const_int 0)))
7044 (match_operand:SWI 2 "<immediate_operand>")))
7045 (clobber (reg:CC FLAGS_REG))]
7046 "CONST_INT_P (operands[2])
7047 && (<MODE>mode != DImode
7048 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7049 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7050 && ix86_pre_reload_split ()"
7051 "#"
7052 "&& 1"
7053 [(set (reg:CC FLAGS_REG)
7054 (compare:CC (match_dup 3) (const_int 1)))
7055 (parallel [(set (match_dup 0)
7056 (minus:SWI
7057 (minus:SWI (match_dup 1)
7058 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7059 (match_dup 2)))
7060 (clobber (reg:CC FLAGS_REG))])]
7061 {
7062 operands[2] = gen_int_mode (-INTVAL (operands[2]),
7063 <MODE>mode == DImode ? SImode : <MODE>mode);
7064 })
7065
7066 (define_insn_and_split "*sub<mode>3_eq_0"
7067 [(set (match_operand:SWI 0 "nonimmediate_operand")
7068 (minus:SWI
7069 (match_operand:SWI 1 "<general_operand>")
7070 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7071 (clobber (reg:CC FLAGS_REG))]
7072 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7073 && ix86_pre_reload_split ()"
7074 "#"
7075 "&& 1"
7076 [(set (reg:CC FLAGS_REG)
7077 (compare:CC (match_dup 2) (const_int 1)))
7078 (parallel [(set (match_dup 0)
7079 (minus:SWI (match_dup 1)
7080 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
7081 (clobber (reg:CC FLAGS_REG))])]
7082 {
7083 if (!nonimmediate_operand (operands[1], <MODE>mode))
7084 operands[1] = force_reg (<MODE>mode, operands[1]);
7085 })
7086
7087 (define_insn_and_split "*sub<mode>3_ne_0"
7088 [(set (match_operand:SWI 0 "nonimmediate_operand")
7089 (minus:SWI
7090 (match_operand:SWI 1 "<general_operand>")
7091 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7092 (clobber (reg:CC FLAGS_REG))]
7093 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7094 && ix86_pre_reload_split ()"
7095 "#"
7096 "&& 1"
7097 [(set (reg:CC FLAGS_REG)
7098 (compare:CC (match_dup 2) (const_int 1)))
7099 (parallel [(set (match_dup 0)
7100 (plus:SWI (plus:SWI
7101 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7102 (match_dup 1))
7103 (const_int -1)))
7104 (clobber (reg:CC FLAGS_REG))])]
7105 {
7106 if (!nonimmediate_operand (operands[1], <MODE>mode))
7107 operands[1] = force_reg (<MODE>mode, operands[1]);
7108 })
7109
7110 ;; The patterns that match these are at the end of this file.
7111
7112 (define_expand "<plusminus_insn>xf3"
7113 [(set (match_operand:XF 0 "register_operand")
7114 (plusminus:XF
7115 (match_operand:XF 1 "register_operand")
7116 (match_operand:XF 2 "register_operand")))]
7117 "TARGET_80387")
7118
7119 (define_expand "<plusminus_insn><mode>3"
7120 [(set (match_operand:MODEF 0 "register_operand")
7121 (plusminus:MODEF
7122 (match_operand:MODEF 1 "register_operand")
7123 (match_operand:MODEF 2 "nonimmediate_operand")))]
7124 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7125 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7126 \f
7127 ;; Multiply instructions
7128
7129 (define_expand "mul<mode>3"
7130 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7131 (mult:SWIM248
7132 (match_operand:SWIM248 1 "register_operand")
7133 (match_operand:SWIM248 2 "<general_operand>")))
7134 (clobber (reg:CC FLAGS_REG))])])
7135
7136 (define_expand "mulqi3"
7137 [(parallel [(set (match_operand:QI 0 "register_operand")
7138 (mult:QI
7139 (match_operand:QI 1 "register_operand")
7140 (match_operand:QI 2 "nonimmediate_operand")))
7141 (clobber (reg:CC FLAGS_REG))])]
7142 "TARGET_QIMODE_MATH")
7143
7144 ;; On AMDFAM10
7145 ;; IMUL reg32/64, reg32/64, imm8 Direct
7146 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7147 ;; IMUL reg32/64, reg32/64, imm32 Direct
7148 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7149 ;; IMUL reg32/64, reg32/64 Direct
7150 ;; IMUL reg32/64, mem32/64 Direct
7151 ;;
7152 ;; On BDVER1, all above IMULs use DirectPath
7153 ;;
7154 ;; On AMDFAM10
7155 ;; IMUL reg16, reg16, imm8 VectorPath
7156 ;; IMUL reg16, mem16, imm8 VectorPath
7157 ;; IMUL reg16, reg16, imm16 VectorPath
7158 ;; IMUL reg16, mem16, imm16 VectorPath
7159 ;; IMUL reg16, reg16 Direct
7160 ;; IMUL reg16, mem16 Direct
7161 ;;
7162 ;; On BDVER1, all HI MULs use DoublePath
7163
7164 (define_insn "*mul<mode>3_1"
7165 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7166 (mult:SWIM248
7167 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7168 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7169 (clobber (reg:CC FLAGS_REG))]
7170 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7171 "@
7172 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7173 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7174 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7175 [(set_attr "type" "imul")
7176 (set_attr "prefix_0f" "0,0,1")
7177 (set (attr "athlon_decode")
7178 (cond [(eq_attr "cpu" "athlon")
7179 (const_string "vector")
7180 (eq_attr "alternative" "1")
7181 (const_string "vector")
7182 (and (eq_attr "alternative" "2")
7183 (ior (match_test "<MODE>mode == HImode")
7184 (match_operand 1 "memory_operand")))
7185 (const_string "vector")]
7186 (const_string "direct")))
7187 (set (attr "amdfam10_decode")
7188 (cond [(and (eq_attr "alternative" "0,1")
7189 (ior (match_test "<MODE>mode == HImode")
7190 (match_operand 1 "memory_operand")))
7191 (const_string "vector")]
7192 (const_string "direct")))
7193 (set (attr "bdver1_decode")
7194 (if_then_else
7195 (match_test "<MODE>mode == HImode")
7196 (const_string "double")
7197 (const_string "direct")))
7198 (set_attr "mode" "<MODE>")])
7199
7200 (define_insn "*mulsi3_1_zext"
7201 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7202 (zero_extend:DI
7203 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7204 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7205 (clobber (reg:CC FLAGS_REG))]
7206 "TARGET_64BIT
7207 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7208 "@
7209 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7210 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7211 imul{l}\t{%2, %k0|%k0, %2}"
7212 [(set_attr "type" "imul")
7213 (set_attr "prefix_0f" "0,0,1")
7214 (set (attr "athlon_decode")
7215 (cond [(eq_attr "cpu" "athlon")
7216 (const_string "vector")
7217 (eq_attr "alternative" "1")
7218 (const_string "vector")
7219 (and (eq_attr "alternative" "2")
7220 (match_operand 1 "memory_operand"))
7221 (const_string "vector")]
7222 (const_string "direct")))
7223 (set (attr "amdfam10_decode")
7224 (cond [(and (eq_attr "alternative" "0,1")
7225 (match_operand 1 "memory_operand"))
7226 (const_string "vector")]
7227 (const_string "direct")))
7228 (set_attr "bdver1_decode" "direct")
7229 (set_attr "mode" "SI")])
7230
7231 ;;On AMDFAM10 and BDVER1
7232 ;; MUL reg8 Direct
7233 ;; MUL mem8 Direct
7234
7235 (define_insn "*mulqi3_1"
7236 [(set (match_operand:QI 0 "register_operand" "=a")
7237 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7238 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7239 (clobber (reg:CC FLAGS_REG))]
7240 "TARGET_QIMODE_MATH
7241 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7242 "mul{b}\t%2"
7243 [(set_attr "type" "imul")
7244 (set_attr "length_immediate" "0")
7245 (set (attr "athlon_decode")
7246 (if_then_else (eq_attr "cpu" "athlon")
7247 (const_string "vector")
7248 (const_string "direct")))
7249 (set_attr "amdfam10_decode" "direct")
7250 (set_attr "bdver1_decode" "direct")
7251 (set_attr "mode" "QI")])
7252
7253 ;; Multiply with jump on overflow.
7254 (define_expand "mulv<mode>4"
7255 [(parallel [(set (reg:CCO FLAGS_REG)
7256 (eq:CCO (mult:<DWI>
7257 (sign_extend:<DWI>
7258 (match_operand:SWI248 1 "register_operand"))
7259 (match_dup 4))
7260 (sign_extend:<DWI>
7261 (mult:SWI248 (match_dup 1)
7262 (match_operand:SWI248 2
7263 "<general_operand>")))))
7264 (set (match_operand:SWI248 0 "register_operand")
7265 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7266 (set (pc) (if_then_else
7267 (eq (reg:CCO FLAGS_REG) (const_int 0))
7268 (label_ref (match_operand 3))
7269 (pc)))]
7270 ""
7271 {
7272 if (CONST_INT_P (operands[2]))
7273 operands[4] = operands[2];
7274 else
7275 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7276 })
7277
7278 (define_insn "*mulv<mode>4"
7279 [(set (reg:CCO FLAGS_REG)
7280 (eq:CCO (mult:<DWI>
7281 (sign_extend:<DWI>
7282 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7283 (sign_extend:<DWI>
7284 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7285 (sign_extend:<DWI>
7286 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7287 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7288 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7289 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7290 "@
7291 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7292 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7293 [(set_attr "type" "imul")
7294 (set_attr "prefix_0f" "0,1")
7295 (set (attr "athlon_decode")
7296 (cond [(eq_attr "cpu" "athlon")
7297 (const_string "vector")
7298 (eq_attr "alternative" "0")
7299 (const_string "vector")
7300 (and (eq_attr "alternative" "1")
7301 (match_operand 1 "memory_operand"))
7302 (const_string "vector")]
7303 (const_string "direct")))
7304 (set (attr "amdfam10_decode")
7305 (cond [(and (eq_attr "alternative" "1")
7306 (match_operand 1 "memory_operand"))
7307 (const_string "vector")]
7308 (const_string "direct")))
7309 (set_attr "bdver1_decode" "direct")
7310 (set_attr "mode" "<MODE>")])
7311
7312 (define_insn "*mulvhi4"
7313 [(set (reg:CCO FLAGS_REG)
7314 (eq:CCO (mult:SI
7315 (sign_extend:SI
7316 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7317 (sign_extend:SI
7318 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7319 (sign_extend:SI
7320 (mult:HI (match_dup 1) (match_dup 2)))))
7321 (set (match_operand:HI 0 "register_operand" "=r")
7322 (mult:HI (match_dup 1) (match_dup 2)))]
7323 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7324 "imul{w}\t{%2, %0|%0, %2}"
7325 [(set_attr "type" "imul")
7326 (set_attr "prefix_0f" "1")
7327 (set_attr "athlon_decode" "vector")
7328 (set_attr "amdfam10_decode" "direct")
7329 (set_attr "bdver1_decode" "double")
7330 (set_attr "mode" "HI")])
7331
7332 (define_insn "*mulv<mode>4_1"
7333 [(set (reg:CCO FLAGS_REG)
7334 (eq:CCO (mult:<DWI>
7335 (sign_extend:<DWI>
7336 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7337 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7338 (sign_extend:<DWI>
7339 (mult:SWI248 (match_dup 1)
7340 (match_operand:SWI248 2
7341 "<immediate_operand>" "K,<i>")))))
7342 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7343 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7344 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7345 && CONST_INT_P (operands[2])
7346 && INTVAL (operands[2]) == INTVAL (operands[3])"
7347 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7348 [(set_attr "type" "imul")
7349 (set (attr "prefix_0f")
7350 (if_then_else
7351 (match_test "<MODE>mode == HImode")
7352 (const_string "0")
7353 (const_string "*")))
7354 (set (attr "athlon_decode")
7355 (cond [(eq_attr "cpu" "athlon")
7356 (const_string "vector")
7357 (eq_attr "alternative" "1")
7358 (const_string "vector")]
7359 (const_string "direct")))
7360 (set (attr "amdfam10_decode")
7361 (cond [(ior (match_test "<MODE>mode == HImode")
7362 (match_operand 1 "memory_operand"))
7363 (const_string "vector")]
7364 (const_string "direct")))
7365 (set (attr "bdver1_decode")
7366 (if_then_else
7367 (match_test "<MODE>mode == HImode")
7368 (const_string "double")
7369 (const_string "direct")))
7370 (set_attr "mode" "<MODE>")
7371 (set (attr "length_immediate")
7372 (cond [(eq_attr "alternative" "0")
7373 (const_string "1")
7374 (match_test "<MODE_SIZE> == 8")
7375 (const_string "4")]
7376 (const_string "<MODE_SIZE>")))])
7377
7378 (define_expand "umulv<mode>4"
7379 [(parallel [(set (reg:CCO FLAGS_REG)
7380 (eq:CCO (mult:<DWI>
7381 (zero_extend:<DWI>
7382 (match_operand:SWI248 1
7383 "nonimmediate_operand"))
7384 (zero_extend:<DWI>
7385 (match_operand:SWI248 2
7386 "nonimmediate_operand")))
7387 (zero_extend:<DWI>
7388 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7389 (set (match_operand:SWI248 0 "register_operand")
7390 (mult:SWI248 (match_dup 1) (match_dup 2)))
7391 (clobber (match_scratch:SWI248 4))])
7392 (set (pc) (if_then_else
7393 (eq (reg:CCO FLAGS_REG) (const_int 0))
7394 (label_ref (match_operand 3))
7395 (pc)))]
7396 ""
7397 {
7398 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7399 operands[1] = force_reg (<MODE>mode, operands[1]);
7400 })
7401
7402 (define_insn "*umulv<mode>4"
7403 [(set (reg:CCO FLAGS_REG)
7404 (eq:CCO (mult:<DWI>
7405 (zero_extend:<DWI>
7406 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7407 (zero_extend:<DWI>
7408 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7409 (zero_extend:<DWI>
7410 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7411 (set (match_operand:SWI248 0 "register_operand" "=a")
7412 (mult:SWI248 (match_dup 1) (match_dup 2)))
7413 (clobber (match_scratch:SWI248 3 "=d"))]
7414 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7415 "mul{<imodesuffix>}\t%2"
7416 [(set_attr "type" "imul")
7417 (set_attr "length_immediate" "0")
7418 (set (attr "athlon_decode")
7419 (if_then_else (eq_attr "cpu" "athlon")
7420 (const_string "vector")
7421 (const_string "double")))
7422 (set_attr "amdfam10_decode" "double")
7423 (set_attr "bdver1_decode" "direct")
7424 (set_attr "mode" "<MODE>")])
7425
7426 (define_expand "<u>mulvqi4"
7427 [(parallel [(set (reg:CCO FLAGS_REG)
7428 (eq:CCO (mult:HI
7429 (any_extend:HI
7430 (match_operand:QI 1 "nonimmediate_operand"))
7431 (any_extend:HI
7432 (match_operand:QI 2 "nonimmediate_operand")))
7433 (any_extend:HI
7434 (mult:QI (match_dup 1) (match_dup 2)))))
7435 (set (match_operand:QI 0 "register_operand")
7436 (mult:QI (match_dup 1) (match_dup 2)))])
7437 (set (pc) (if_then_else
7438 (eq (reg:CCO FLAGS_REG) (const_int 0))
7439 (label_ref (match_operand 3))
7440 (pc)))]
7441 "TARGET_QIMODE_MATH"
7442 {
7443 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7444 operands[1] = force_reg (QImode, operands[1]);
7445 })
7446
7447 (define_insn "*<u>mulvqi4"
7448 [(set (reg:CCO FLAGS_REG)
7449 (eq:CCO (mult:HI
7450 (any_extend:HI
7451 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7452 (any_extend:HI
7453 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7454 (any_extend:HI
7455 (mult:QI (match_dup 1) (match_dup 2)))))
7456 (set (match_operand:QI 0 "register_operand" "=a")
7457 (mult:QI (match_dup 1) (match_dup 2)))]
7458 "TARGET_QIMODE_MATH
7459 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7460 "<sgnprefix>mul{b}\t%2"
7461 [(set_attr "type" "imul")
7462 (set_attr "length_immediate" "0")
7463 (set (attr "athlon_decode")
7464 (if_then_else (eq_attr "cpu" "athlon")
7465 (const_string "vector")
7466 (const_string "direct")))
7467 (set_attr "amdfam10_decode" "direct")
7468 (set_attr "bdver1_decode" "direct")
7469 (set_attr "mode" "QI")])
7470
7471 (define_expand "<u>mul<mode><dwi>3"
7472 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7473 (mult:<DWI>
7474 (any_extend:<DWI>
7475 (match_operand:DWIH 1 "nonimmediate_operand"))
7476 (any_extend:<DWI>
7477 (match_operand:DWIH 2 "register_operand"))))
7478 (clobber (reg:CC FLAGS_REG))])])
7479
7480 (define_expand "<u>mulqihi3"
7481 [(parallel [(set (match_operand:HI 0 "register_operand")
7482 (mult:HI
7483 (any_extend:HI
7484 (match_operand:QI 1 "nonimmediate_operand"))
7485 (any_extend:HI
7486 (match_operand:QI 2 "register_operand"))))
7487 (clobber (reg:CC FLAGS_REG))])]
7488 "TARGET_QIMODE_MATH")
7489
7490 (define_insn "*bmi2_umul<mode><dwi>3_1"
7491 [(set (match_operand:DWIH 0 "register_operand" "=r")
7492 (mult:DWIH
7493 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7494 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7495 (set (match_operand:DWIH 1 "register_operand" "=r")
7496 (truncate:DWIH
7497 (lshiftrt:<DWI>
7498 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7499 (zero_extend:<DWI> (match_dup 3)))
7500 (match_operand:QI 4 "const_int_operand" "n"))))]
7501 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7502 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7503 "mulx\t{%3, %0, %1|%1, %0, %3}"
7504 [(set_attr "type" "imulx")
7505 (set_attr "prefix" "vex")
7506 (set_attr "mode" "<MODE>")])
7507
7508 (define_insn "*umul<mode><dwi>3_1"
7509 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7510 (mult:<DWI>
7511 (zero_extend:<DWI>
7512 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7513 (zero_extend:<DWI>
7514 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7515 (clobber (reg:CC FLAGS_REG))]
7516 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7517 "@
7518 #
7519 mul{<imodesuffix>}\t%2"
7520 [(set_attr "isa" "bmi2,*")
7521 (set_attr "type" "imulx,imul")
7522 (set_attr "length_immediate" "*,0")
7523 (set (attr "athlon_decode")
7524 (cond [(eq_attr "alternative" "1")
7525 (if_then_else (eq_attr "cpu" "athlon")
7526 (const_string "vector")
7527 (const_string "double"))]
7528 (const_string "*")))
7529 (set_attr "amdfam10_decode" "*,double")
7530 (set_attr "bdver1_decode" "*,direct")
7531 (set_attr "prefix" "vex,orig")
7532 (set_attr "mode" "<MODE>")])
7533
7534 ;; Convert mul to the mulx pattern to avoid flags dependency.
7535 (define_split
7536 [(set (match_operand:<DWI> 0 "register_operand")
7537 (mult:<DWI>
7538 (zero_extend:<DWI>
7539 (match_operand:DWIH 1 "register_operand"))
7540 (zero_extend:<DWI>
7541 (match_operand:DWIH 2 "nonimmediate_operand"))))
7542 (clobber (reg:CC FLAGS_REG))]
7543 "TARGET_BMI2 && reload_completed
7544 && REGNO (operands[1]) == DX_REG"
7545 [(parallel [(set (match_dup 3)
7546 (mult:DWIH (match_dup 1) (match_dup 2)))
7547 (set (match_dup 4)
7548 (truncate:DWIH
7549 (lshiftrt:<DWI>
7550 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7551 (zero_extend:<DWI> (match_dup 2)))
7552 (match_dup 5))))])]
7553 {
7554 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7555
7556 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7557 })
7558
7559 (define_insn "*mul<mode><dwi>3_1"
7560 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7561 (mult:<DWI>
7562 (sign_extend:<DWI>
7563 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7564 (sign_extend:<DWI>
7565 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7568 "imul{<imodesuffix>}\t%2"
7569 [(set_attr "type" "imul")
7570 (set_attr "length_immediate" "0")
7571 (set (attr "athlon_decode")
7572 (if_then_else (eq_attr "cpu" "athlon")
7573 (const_string "vector")
7574 (const_string "double")))
7575 (set_attr "amdfam10_decode" "double")
7576 (set_attr "bdver1_decode" "direct")
7577 (set_attr "mode" "<MODE>")])
7578
7579 (define_insn "*<u>mulqihi3_1"
7580 [(set (match_operand:HI 0 "register_operand" "=a")
7581 (mult:HI
7582 (any_extend:HI
7583 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7584 (any_extend:HI
7585 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7586 (clobber (reg:CC FLAGS_REG))]
7587 "TARGET_QIMODE_MATH
7588 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7589 "<sgnprefix>mul{b}\t%2"
7590 [(set_attr "type" "imul")
7591 (set_attr "length_immediate" "0")
7592 (set (attr "athlon_decode")
7593 (if_then_else (eq_attr "cpu" "athlon")
7594 (const_string "vector")
7595 (const_string "direct")))
7596 (set_attr "amdfam10_decode" "direct")
7597 (set_attr "bdver1_decode" "direct")
7598 (set_attr "mode" "QI")])
7599
7600 (define_expand "<s>mul<mode>3_highpart"
7601 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7602 (truncate:DWIH
7603 (lshiftrt:<DWI>
7604 (mult:<DWI>
7605 (any_extend:<DWI>
7606 (match_operand:DWIH 1 "nonimmediate_operand"))
7607 (any_extend:<DWI>
7608 (match_operand:DWIH 2 "register_operand")))
7609 (match_dup 3))))
7610 (clobber (match_scratch:DWIH 4))
7611 (clobber (reg:CC FLAGS_REG))])]
7612 ""
7613 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7614
7615 (define_insn "*<s>muldi3_highpart_1"
7616 [(set (match_operand:DI 0 "register_operand" "=d")
7617 (truncate:DI
7618 (lshiftrt:TI
7619 (mult:TI
7620 (any_extend:TI
7621 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7622 (any_extend:TI
7623 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7624 (const_int 64))))
7625 (clobber (match_scratch:DI 3 "=1"))
7626 (clobber (reg:CC FLAGS_REG))]
7627 "TARGET_64BIT
7628 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7629 "<sgnprefix>mul{q}\t%2"
7630 [(set_attr "type" "imul")
7631 (set_attr "length_immediate" "0")
7632 (set (attr "athlon_decode")
7633 (if_then_else (eq_attr "cpu" "athlon")
7634 (const_string "vector")
7635 (const_string "double")))
7636 (set_attr "amdfam10_decode" "double")
7637 (set_attr "bdver1_decode" "direct")
7638 (set_attr "mode" "DI")])
7639
7640 (define_insn "*<s>mulsi3_highpart_zext"
7641 [(set (match_operand:DI 0 "register_operand" "=d")
7642 (zero_extend:DI (truncate:SI
7643 (lshiftrt:DI
7644 (mult:DI (any_extend:DI
7645 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7646 (any_extend:DI
7647 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7648 (const_int 32)))))
7649 (clobber (match_scratch:SI 3 "=1"))
7650 (clobber (reg:CC FLAGS_REG))]
7651 "TARGET_64BIT
7652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7653 "<sgnprefix>mul{l}\t%2"
7654 [(set_attr "type" "imul")
7655 (set_attr "length_immediate" "0")
7656 (set (attr "athlon_decode")
7657 (if_then_else (eq_attr "cpu" "athlon")
7658 (const_string "vector")
7659 (const_string "double")))
7660 (set_attr "amdfam10_decode" "double")
7661 (set_attr "bdver1_decode" "direct")
7662 (set_attr "mode" "SI")])
7663
7664 (define_insn "*<s>mulsi3_highpart_1"
7665 [(set (match_operand:SI 0 "register_operand" "=d")
7666 (truncate:SI
7667 (lshiftrt:DI
7668 (mult:DI
7669 (any_extend:DI
7670 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7671 (any_extend:DI
7672 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7673 (const_int 32))))
7674 (clobber (match_scratch:SI 3 "=1"))
7675 (clobber (reg:CC FLAGS_REG))]
7676 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7677 "<sgnprefix>mul{l}\t%2"
7678 [(set_attr "type" "imul")
7679 (set_attr "length_immediate" "0")
7680 (set (attr "athlon_decode")
7681 (if_then_else (eq_attr "cpu" "athlon")
7682 (const_string "vector")
7683 (const_string "double")))
7684 (set_attr "amdfam10_decode" "double")
7685 (set_attr "bdver1_decode" "direct")
7686 (set_attr "mode" "SI")])
7687
7688 ;; The patterns that match these are at the end of this file.
7689
7690 (define_expand "mulxf3"
7691 [(set (match_operand:XF 0 "register_operand")
7692 (mult:XF (match_operand:XF 1 "register_operand")
7693 (match_operand:XF 2 "register_operand")))]
7694 "TARGET_80387")
7695
7696 (define_expand "mul<mode>3"
7697 [(set (match_operand:MODEF 0 "register_operand")
7698 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7699 (match_operand:MODEF 2 "nonimmediate_operand")))]
7700 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7701 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7702 \f
7703 ;; Divide instructions
7704
7705 ;; The patterns that match these are at the end of this file.
7706
7707 (define_expand "divxf3"
7708 [(set (match_operand:XF 0 "register_operand")
7709 (div:XF (match_operand:XF 1 "register_operand")
7710 (match_operand:XF 2 "register_operand")))]
7711 "TARGET_80387")
7712
7713 (define_expand "div<mode>3"
7714 [(set (match_operand:MODEF 0 "register_operand")
7715 (div:MODEF (match_operand:MODEF 1 "register_operand")
7716 (match_operand:MODEF 2 "nonimmediate_operand")))]
7717 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7718 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7719 {
7720 if (<MODE>mode == SFmode
7721 && TARGET_SSE && TARGET_SSE_MATH
7722 && TARGET_RECIP_DIV
7723 && optimize_insn_for_speed_p ()
7724 && flag_finite_math_only && !flag_trapping_math
7725 && flag_unsafe_math_optimizations)
7726 {
7727 ix86_emit_swdivsf (operands[0], operands[1],
7728 operands[2], SFmode);
7729 DONE;
7730 }
7731 })
7732 \f
7733 ;; Divmod instructions.
7734
7735 (define_code_iterator any_div [div udiv])
7736 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
7737
7738 (define_expand "<u>divmod<mode>4"
7739 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7740 (any_div:SWIM248
7741 (match_operand:SWIM248 1 "register_operand")
7742 (match_operand:SWIM248 2 "nonimmediate_operand")))
7743 (set (match_operand:SWIM248 3 "register_operand")
7744 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
7745 (clobber (reg:CC FLAGS_REG))])])
7746
7747 ;; Split with 8bit unsigned divide:
7748 ;; if (dividend an divisor are in [0-255])
7749 ;; use 8bit unsigned integer divide
7750 ;; else
7751 ;; use original integer divide
7752 (define_split
7753 [(set (match_operand:SWI48 0 "register_operand")
7754 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
7755 (match_operand:SWI48 3 "nonimmediate_operand")))
7756 (set (match_operand:SWI48 1 "register_operand")
7757 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
7758 (clobber (reg:CC FLAGS_REG))]
7759 "TARGET_USE_8BIT_IDIV
7760 && TARGET_QIMODE_MATH
7761 && can_create_pseudo_p ()
7762 && !optimize_insn_for_size_p ()"
7763 [(const_int 0)]
7764 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
7765
7766 (define_split
7767 [(set (match_operand:DI 0 "register_operand")
7768 (zero_extend:DI
7769 (any_div:SI (match_operand:SI 2 "register_operand")
7770 (match_operand:SI 3 "nonimmediate_operand"))))
7771 (set (match_operand:SI 1 "register_operand")
7772 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "TARGET_64BIT
7775 && TARGET_USE_8BIT_IDIV
7776 && TARGET_QIMODE_MATH
7777 && can_create_pseudo_p ()
7778 && !optimize_insn_for_size_p ()"
7779 [(const_int 0)]
7780 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7781
7782 (define_split
7783 [(set (match_operand:DI 1 "register_operand")
7784 (zero_extend:DI
7785 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
7786 (match_operand:SI 3 "nonimmediate_operand"))))
7787 (set (match_operand:SI 0 "register_operand")
7788 (any_div:SI (match_dup 2) (match_dup 3)))
7789 (clobber (reg:CC FLAGS_REG))]
7790 "TARGET_64BIT
7791 && TARGET_USE_8BIT_IDIV
7792 && TARGET_QIMODE_MATH
7793 && can_create_pseudo_p ()
7794 && !optimize_insn_for_size_p ()"
7795 [(const_int 0)]
7796 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7797
7798 (define_insn_and_split "divmod<mode>4_1"
7799 [(set (match_operand:SWI48 0 "register_operand" "=a")
7800 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7801 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7802 (set (match_operand:SWI48 1 "register_operand" "=&d")
7803 (mod:SWI48 (match_dup 2) (match_dup 3)))
7804 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7805 (clobber (reg:CC FLAGS_REG))]
7806 ""
7807 "#"
7808 "reload_completed"
7809 [(parallel [(set (match_dup 1)
7810 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7811 (clobber (reg:CC FLAGS_REG))])
7812 (parallel [(set (match_dup 0)
7813 (div:SWI48 (match_dup 2) (match_dup 3)))
7814 (set (match_dup 1)
7815 (mod:SWI48 (match_dup 2) (match_dup 3)))
7816 (use (match_dup 1))
7817 (clobber (reg:CC FLAGS_REG))])]
7818 {
7819 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7820
7821 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7822 operands[4] = operands[2];
7823 else
7824 {
7825 /* Avoid use of cltd in favor of a mov+shift. */
7826 emit_move_insn (operands[1], operands[2]);
7827 operands[4] = operands[1];
7828 }
7829 }
7830 [(set_attr "type" "multi")
7831 (set_attr "mode" "<MODE>")])
7832
7833 (define_insn_and_split "udivmod<mode>4_1"
7834 [(set (match_operand:SWI48 0 "register_operand" "=a")
7835 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7836 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7837 (set (match_operand:SWI48 1 "register_operand" "=&d")
7838 (umod:SWI48 (match_dup 2) (match_dup 3)))
7839 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7840 (clobber (reg:CC FLAGS_REG))]
7841 ""
7842 "#"
7843 "reload_completed"
7844 [(set (match_dup 1) (const_int 0))
7845 (parallel [(set (match_dup 0)
7846 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7847 (set (match_dup 1)
7848 (umod:SWI48 (match_dup 2) (match_dup 3)))
7849 (use (match_dup 1))
7850 (clobber (reg:CC FLAGS_REG))])]
7851 ""
7852 [(set_attr "type" "multi")
7853 (set_attr "mode" "<MODE>")])
7854
7855 (define_insn_and_split "divmodsi4_zext_1"
7856 [(set (match_operand:DI 0 "register_operand" "=a")
7857 (zero_extend:DI
7858 (div:SI (match_operand:SI 2 "register_operand" "0")
7859 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7860 (set (match_operand:SI 1 "register_operand" "=&d")
7861 (mod:SI (match_dup 2) (match_dup 3)))
7862 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7863 (clobber (reg:CC FLAGS_REG))]
7864 "TARGET_64BIT"
7865 "#"
7866 "&& reload_completed"
7867 [(parallel [(set (match_dup 1)
7868 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7869 (clobber (reg:CC FLAGS_REG))])
7870 (parallel [(set (match_dup 0)
7871 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7872 (set (match_dup 1)
7873 (mod:SI (match_dup 2) (match_dup 3)))
7874 (use (match_dup 1))
7875 (clobber (reg:CC FLAGS_REG))])]
7876 {
7877 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7878
7879 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7880 operands[4] = operands[2];
7881 else
7882 {
7883 /* Avoid use of cltd in favor of a mov+shift. */
7884 emit_move_insn (operands[1], operands[2]);
7885 operands[4] = operands[1];
7886 }
7887 }
7888 [(set_attr "type" "multi")
7889 (set_attr "mode" "SI")])
7890
7891 (define_insn_and_split "udivmodsi4_zext_1"
7892 [(set (match_operand:DI 0 "register_operand" "=a")
7893 (zero_extend:DI
7894 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7895 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7896 (set (match_operand:SI 1 "register_operand" "=&d")
7897 (umod:SI (match_dup 2) (match_dup 3)))
7898 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7899 (clobber (reg:CC FLAGS_REG))]
7900 "TARGET_64BIT"
7901 "#"
7902 "&& reload_completed"
7903 [(set (match_dup 1) (const_int 0))
7904 (parallel [(set (match_dup 0)
7905 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7906 (set (match_dup 1)
7907 (umod:SI (match_dup 2) (match_dup 3)))
7908 (use (match_dup 1))
7909 (clobber (reg:CC FLAGS_REG))])]
7910 ""
7911 [(set_attr "type" "multi")
7912 (set_attr "mode" "SI")])
7913
7914 (define_insn_and_split "divmodsi4_zext_2"
7915 [(set (match_operand:DI 1 "register_operand" "=&d")
7916 (zero_extend:DI
7917 (mod:SI (match_operand:SI 2 "register_operand" "0")
7918 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7919 (set (match_operand:SI 0 "register_operand" "=a")
7920 (div:SI (match_dup 2) (match_dup 3)))
7921 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7922 (clobber (reg:CC FLAGS_REG))]
7923 "TARGET_64BIT"
7924 "#"
7925 "&& reload_completed"
7926 [(parallel [(set (match_dup 6)
7927 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7928 (clobber (reg:CC FLAGS_REG))])
7929 (parallel [(set (match_dup 1)
7930 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7931 (set (match_dup 0)
7932 (div:SI (match_dup 2) (match_dup 3)))
7933 (use (match_dup 6))
7934 (clobber (reg:CC FLAGS_REG))])]
7935 {
7936 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7937 operands[6] = gen_lowpart (SImode, operands[1]);
7938
7939 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7940 operands[4] = operands[2];
7941 else
7942 {
7943 /* Avoid use of cltd in favor of a mov+shift. */
7944 emit_move_insn (operands[6], operands[2]);
7945 operands[4] = operands[6];
7946 }
7947 }
7948 [(set_attr "type" "multi")
7949 (set_attr "mode" "SI")])
7950
7951 (define_insn_and_split "udivmodsi4_zext_2"
7952 [(set (match_operand:DI 1 "register_operand" "=&d")
7953 (zero_extend:DI
7954 (umod:SI (match_operand:SI 2 "register_operand" "0")
7955 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7956 (set (match_operand:SI 0 "register_operand" "=a")
7957 (udiv:SI (match_dup 2) (match_dup 3)))
7958 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7959 (clobber (reg:CC FLAGS_REG))]
7960 "TARGET_64BIT"
7961 "#"
7962 "&& reload_completed"
7963 [(set (match_dup 4) (const_int 0))
7964 (parallel [(set (match_dup 1)
7965 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7966 (set (match_dup 0)
7967 (udiv:SI (match_dup 2) (match_dup 3)))
7968 (use (match_dup 4))
7969 (clobber (reg:CC FLAGS_REG))])]
7970 "operands[4] = gen_lowpart (SImode, operands[1]);"
7971 [(set_attr "type" "multi")
7972 (set_attr "mode" "SI")])
7973
7974 (define_insn_and_split "*divmod<mode>4"
7975 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7976 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7977 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7978 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7979 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7980 (clobber (reg:CC FLAGS_REG))]
7981 ""
7982 "#"
7983 "reload_completed"
7984 [(parallel [(set (match_dup 1)
7985 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7986 (clobber (reg:CC FLAGS_REG))])
7987 (parallel [(set (match_dup 0)
7988 (div:SWIM248 (match_dup 2) (match_dup 3)))
7989 (set (match_dup 1)
7990 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7991 (use (match_dup 1))
7992 (clobber (reg:CC FLAGS_REG))])]
7993 {
7994 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7995
7996 if (<MODE>mode != HImode
7997 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7998 operands[4] = operands[2];
7999 else
8000 {
8001 /* Avoid use of cltd in favor of a mov+shift. */
8002 emit_move_insn (operands[1], operands[2]);
8003 operands[4] = operands[1];
8004 }
8005 }
8006 [(set_attr "type" "multi")
8007 (set_attr "mode" "<MODE>")])
8008
8009 (define_insn_and_split "*udivmod<mode>4"
8010 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8011 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8012 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8013 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8014 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8015 (clobber (reg:CC FLAGS_REG))]
8016 ""
8017 "#"
8018 "reload_completed"
8019 [(set (match_dup 1) (const_int 0))
8020 (parallel [(set (match_dup 0)
8021 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8022 (set (match_dup 1)
8023 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8024 (use (match_dup 1))
8025 (clobber (reg:CC FLAGS_REG))])]
8026 ""
8027 [(set_attr "type" "multi")
8028 (set_attr "mode" "<MODE>")])
8029
8030 ;; Optimize division or modulo by constant power of 2, if the constant
8031 ;; materializes only after expansion.
8032 (define_insn_and_split "*udivmod<mode>4_pow2"
8033 [(set (match_operand:SWI48 0 "register_operand" "=r")
8034 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8035 (match_operand:SWI48 3 "const_int_operand" "n")))
8036 (set (match_operand:SWI48 1 "register_operand" "=r")
8037 (umod:SWI48 (match_dup 2) (match_dup 3)))
8038 (clobber (reg:CC FLAGS_REG))]
8039 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
8040 "#"
8041 "&& reload_completed"
8042 [(set (match_dup 1) (match_dup 2))
8043 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8044 (clobber (reg:CC FLAGS_REG))])
8045 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8046 (clobber (reg:CC FLAGS_REG))])]
8047 {
8048 int v = exact_log2 (UINTVAL (operands[3]));
8049 operands[4] = GEN_INT (v);
8050 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8051 }
8052 [(set_attr "type" "multi")
8053 (set_attr "mode" "<MODE>")])
8054
8055 (define_insn_and_split "*divmodsi4_zext_1"
8056 [(set (match_operand:DI 0 "register_operand" "=a")
8057 (zero_extend:DI
8058 (div:SI (match_operand:SI 2 "register_operand" "0")
8059 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8060 (set (match_operand:SI 1 "register_operand" "=&d")
8061 (mod:SI (match_dup 2) (match_dup 3)))
8062 (clobber (reg:CC FLAGS_REG))]
8063 "TARGET_64BIT"
8064 "#"
8065 "&& reload_completed"
8066 [(parallel [(set (match_dup 1)
8067 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8068 (clobber (reg:CC FLAGS_REG))])
8069 (parallel [(set (match_dup 0)
8070 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8071 (set (match_dup 1)
8072 (mod:SI (match_dup 2) (match_dup 3)))
8073 (use (match_dup 1))
8074 (clobber (reg:CC FLAGS_REG))])]
8075 {
8076 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8077
8078 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8079 operands[4] = operands[2];
8080 else
8081 {
8082 /* Avoid use of cltd in favor of a mov+shift. */
8083 emit_move_insn (operands[1], operands[2]);
8084 operands[4] = operands[1];
8085 }
8086 }
8087 [(set_attr "type" "multi")
8088 (set_attr "mode" "SI")])
8089
8090 (define_insn_and_split "*udivmodsi4_zext_1"
8091 [(set (match_operand:DI 0 "register_operand" "=a")
8092 (zero_extend:DI
8093 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8094 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8095 (set (match_operand:SI 1 "register_operand" "=&d")
8096 (umod:SI (match_dup 2) (match_dup 3)))
8097 (clobber (reg:CC FLAGS_REG))]
8098 "TARGET_64BIT"
8099 "#"
8100 "&& reload_completed"
8101 [(set (match_dup 1) (const_int 0))
8102 (parallel [(set (match_dup 0)
8103 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8104 (set (match_dup 1)
8105 (umod:SI (match_dup 2) (match_dup 3)))
8106 (use (match_dup 1))
8107 (clobber (reg:CC FLAGS_REG))])]
8108 ""
8109 [(set_attr "type" "multi")
8110 (set_attr "mode" "SI")])
8111
8112 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8113 [(set (match_operand:DI 0 "register_operand" "=r")
8114 (zero_extend:DI
8115 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8116 (match_operand:SI 3 "const_int_operand" "n"))))
8117 (set (match_operand:SI 1 "register_operand" "=r")
8118 (umod:SI (match_dup 2) (match_dup 3)))
8119 (clobber (reg:CC FLAGS_REG))]
8120 "TARGET_64BIT
8121 && exact_log2 (UINTVAL (operands[3])) > 0"
8122 "#"
8123 "&& reload_completed"
8124 [(set (match_dup 1) (match_dup 2))
8125 (parallel [(set (match_dup 0)
8126 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8127 (clobber (reg:CC FLAGS_REG))])
8128 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8129 (clobber (reg:CC FLAGS_REG))])]
8130 {
8131 int v = exact_log2 (UINTVAL (operands[3]));
8132 operands[4] = GEN_INT (v);
8133 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8134 }
8135 [(set_attr "type" "multi")
8136 (set_attr "mode" "SI")])
8137
8138 (define_insn_and_split "*divmodsi4_zext_2"
8139 [(set (match_operand:DI 1 "register_operand" "=&d")
8140 (zero_extend:DI
8141 (mod:SI (match_operand:SI 2 "register_operand" "0")
8142 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8143 (set (match_operand:SI 0 "register_operand" "=a")
8144 (div:SI (match_dup 2) (match_dup 3)))
8145 (clobber (reg:CC FLAGS_REG))]
8146 "TARGET_64BIT"
8147 "#"
8148 "&& reload_completed"
8149 [(parallel [(set (match_dup 6)
8150 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8151 (clobber (reg:CC FLAGS_REG))])
8152 (parallel [(set (match_dup 1)
8153 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8154 (set (match_dup 0)
8155 (div:SI (match_dup 2) (match_dup 3)))
8156 (use (match_dup 6))
8157 (clobber (reg:CC FLAGS_REG))])]
8158 {
8159 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8160 operands[6] = gen_lowpart (SImode, operands[1]);
8161
8162 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8163 operands[4] = operands[2];
8164 else
8165 {
8166 /* Avoid use of cltd in favor of a mov+shift. */
8167 emit_move_insn (operands[6], operands[2]);
8168 operands[4] = operands[6];
8169 }
8170 }
8171 [(set_attr "type" "multi")
8172 (set_attr "mode" "SI")])
8173
8174 (define_insn_and_split "*udivmodsi4_zext_2"
8175 [(set (match_operand:DI 1 "register_operand" "=&d")
8176 (zero_extend:DI
8177 (umod:SI (match_operand:SI 2 "register_operand" "0")
8178 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8179 (set (match_operand:SI 0 "register_operand" "=a")
8180 (udiv:SI (match_dup 2) (match_dup 3)))
8181 (clobber (reg:CC FLAGS_REG))]
8182 "TARGET_64BIT"
8183 "#"
8184 "&& reload_completed"
8185 [(set (match_dup 4) (const_int 0))
8186 (parallel [(set (match_dup 1)
8187 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8188 (set (match_dup 0)
8189 (udiv:SI (match_dup 2) (match_dup 3)))
8190 (use (match_dup 4))
8191 (clobber (reg:CC FLAGS_REG))])]
8192 "operands[4] = gen_lowpart (SImode, operands[1]);"
8193 [(set_attr "type" "multi")
8194 (set_attr "mode" "SI")])
8195
8196 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8197 [(set (match_operand:DI 1 "register_operand" "=r")
8198 (zero_extend:DI
8199 (umod:SI (match_operand:SI 2 "register_operand" "0")
8200 (match_operand:SI 3 "const_int_operand" "n"))))
8201 (set (match_operand:SI 0 "register_operand" "=r")
8202 (umod:SI (match_dup 2) (match_dup 3)))
8203 (clobber (reg:CC FLAGS_REG))]
8204 "TARGET_64BIT
8205 && exact_log2 (UINTVAL (operands[3])) > 0"
8206 "#"
8207 "&& reload_completed"
8208 [(set (match_dup 1) (match_dup 2))
8209 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8210 (clobber (reg:CC FLAGS_REG))])
8211 (parallel [(set (match_dup 1)
8212 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8213 (clobber (reg:CC FLAGS_REG))])]
8214 {
8215 int v = exact_log2 (UINTVAL (operands[3]));
8216 operands[4] = GEN_INT (v);
8217 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8218 }
8219 [(set_attr "type" "multi")
8220 (set_attr "mode" "SI")])
8221
8222 (define_insn "*<u>divmod<mode>4_noext"
8223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8224 (any_div:SWIM248
8225 (match_operand:SWIM248 2 "register_operand" "0")
8226 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8227 (set (match_operand:SWIM248 1 "register_operand" "=d")
8228 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
8229 (use (match_operand:SWIM248 4 "register_operand" "1"))
8230 (clobber (reg:CC FLAGS_REG))]
8231 ""
8232 "<sgnprefix>div{<imodesuffix>}\t%3"
8233 [(set_attr "type" "idiv")
8234 (set_attr "mode" "<MODE>")])
8235
8236 (define_insn "*<u>divmodsi4_noext_zext_1"
8237 [(set (match_operand:DI 0 "register_operand" "=a")
8238 (zero_extend:DI
8239 (any_div:SI (match_operand:SI 2 "register_operand" "0")
8240 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8241 (set (match_operand:SI 1 "register_operand" "=d")
8242 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8243 (use (match_operand:SI 4 "register_operand" "1"))
8244 (clobber (reg:CC FLAGS_REG))]
8245 "TARGET_64BIT"
8246 "<sgnprefix>div{l}\t%3"
8247 [(set_attr "type" "idiv")
8248 (set_attr "mode" "SI")])
8249
8250 (define_insn "*<u>divmodsi4_noext_zext_2"
8251 [(set (match_operand:DI 1 "register_operand" "=d")
8252 (zero_extend:DI
8253 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
8254 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8255 (set (match_operand:SI 0 "register_operand" "=a")
8256 (any_div:SI (match_dup 2) (match_dup 3)))
8257 (use (match_operand:SI 4 "register_operand" "1"))
8258 (clobber (reg:CC FLAGS_REG))]
8259 "TARGET_64BIT"
8260 "<sgnprefix>div{l}\t%3"
8261 [(set_attr "type" "idiv")
8262 (set_attr "mode" "SI")])
8263
8264 (define_expand "divmodqi4"
8265 [(parallel [(set (match_operand:QI 0 "register_operand")
8266 (div:QI
8267 (match_operand:QI 1 "register_operand")
8268 (match_operand:QI 2 "nonimmediate_operand")))
8269 (set (match_operand:QI 3 "register_operand")
8270 (mod:QI (match_dup 1) (match_dup 2)))
8271 (clobber (reg:CC FLAGS_REG))])]
8272 "TARGET_QIMODE_MATH"
8273 {
8274 rtx div, mod;
8275 rtx tmp0, tmp1;
8276
8277 tmp0 = gen_reg_rtx (HImode);
8278 tmp1 = gen_reg_rtx (HImode);
8279
8280 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8281 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8282 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8283
8284 /* Extract remainder from AH. */
8285 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8286 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8287 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8288
8289 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8290 set_unique_reg_note (insn, REG_EQUAL, mod);
8291
8292 /* Extract quotient from AL. */
8293 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8294
8295 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8296 set_unique_reg_note (insn, REG_EQUAL, div);
8297
8298 DONE;
8299 })
8300
8301 (define_expand "udivmodqi4"
8302 [(parallel [(set (match_operand:QI 0 "register_operand")
8303 (udiv:QI
8304 (match_operand:QI 1 "register_operand")
8305 (match_operand:QI 2 "nonimmediate_operand")))
8306 (set (match_operand:QI 3 "register_operand")
8307 (umod:QI (match_dup 1) (match_dup 2)))
8308 (clobber (reg:CC FLAGS_REG))])]
8309 "TARGET_QIMODE_MATH"
8310 {
8311 rtx div, mod;
8312 rtx tmp0, tmp1;
8313
8314 tmp0 = gen_reg_rtx (HImode);
8315 tmp1 = gen_reg_rtx (HImode);
8316
8317 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8318 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8319 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8320
8321 /* Extract remainder from AH. */
8322 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8323 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8324 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8325
8326 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8327 set_unique_reg_note (insn, REG_EQUAL, mod);
8328
8329 /* Extract quotient from AL. */
8330 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8331
8332 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8333 set_unique_reg_note (insn, REG_EQUAL, div);
8334
8335 DONE;
8336 })
8337
8338 ;; Divide AX by r/m8, with result stored in
8339 ;; AL <- Quotient
8340 ;; AH <- Remainder
8341 ;; Change div/mod to HImode and extend the second argument to HImode
8342 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8343 ;; combine may fail.
8344 (define_insn "<u>divmodhiqi3"
8345 [(set (match_operand:HI 0 "register_operand" "=a")
8346 (ior:HI
8347 (ashift:HI
8348 (zero_extend:HI
8349 (truncate:QI
8350 (mod:HI (match_operand:HI 1 "register_operand" "0")
8351 (any_extend:HI
8352 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8353 (const_int 8))
8354 (zero_extend:HI
8355 (truncate:QI
8356 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8357 (clobber (reg:CC FLAGS_REG))]
8358 "TARGET_QIMODE_MATH"
8359 "<sgnprefix>div{b}\t%2"
8360 [(set_attr "type" "idiv")
8361 (set_attr "mode" "QI")])
8362
8363 ;; We cannot use div/idiv for double division, because it causes
8364 ;; "division by zero" on the overflow and that's not what we expect
8365 ;; from truncate. Because true (non truncating) double division is
8366 ;; never generated, we can't create this insn anyway.
8367 ;
8368 ;(define_insn ""
8369 ; [(set (match_operand:SI 0 "register_operand" "=a")
8370 ; (truncate:SI
8371 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8372 ; (zero_extend:DI
8373 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8374 ; (set (match_operand:SI 3 "register_operand" "=d")
8375 ; (truncate:SI
8376 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8377 ; (clobber (reg:CC FLAGS_REG))]
8378 ; ""
8379 ; "div{l}\t{%2, %0|%0, %2}"
8380 ; [(set_attr "type" "idiv")])
8381 \f
8382 ;;- Logical AND instructions
8383
8384 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8385 ;; Note that this excludes ah.
8386
8387 (define_expand "@test<mode>_ccno_1"
8388 [(set (reg:CCNO FLAGS_REG)
8389 (compare:CCNO
8390 (and:SWI48
8391 (match_operand:SWI48 0 "nonimmediate_operand")
8392 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
8393 (const_int 0)))])
8394
8395 (define_expand "testqi_ccz_1"
8396 [(set (reg:CCZ FLAGS_REG)
8397 (compare:CCZ
8398 (and:QI
8399 (match_operand:QI 0 "nonimmediate_operand")
8400 (match_operand:QI 1 "nonmemory_operand"))
8401 (const_int 0)))])
8402
8403 (define_insn "*testdi_1"
8404 [(set (reg FLAGS_REG)
8405 (compare
8406 (and:DI
8407 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
8408 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
8409 (const_int 0)))]
8410 "TARGET_64BIT
8411 && ix86_match_ccmode
8412 (insn,
8413 /* If we are going to emit testl instead of testq, and the operands[1]
8414 constant might have the SImode sign bit set, make sure the sign
8415 flag isn't tested, because the instruction will set the sign flag
8416 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8417 conservatively assume it might have bit 31 set. */
8418 (satisfies_constraint_Z (operands[1])
8419 && (!CONST_INT_P (operands[1])
8420 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
8421 ? CCZmode : CCNOmode)"
8422 "@
8423 test{l}\t{%k1, %k0|%k0, %k1}
8424 test{q}\t{%1, %0|%0, %1}"
8425 [(set_attr "type" "test")
8426 (set_attr "mode" "SI,DI")])
8427
8428 (define_insn "*testqi_1_maybe_si"
8429 [(set (reg FLAGS_REG)
8430 (compare
8431 (and:QI
8432 (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
8433 (match_operand:QI 1 "nonmemory_operand" "q,n,n,n"))
8434 (const_int 0)))]
8435 "ix86_match_ccmode (insn,
8436 CONST_INT_P (operands[1])
8437 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8438 {
8439 if (which_alternative == 3)
8440 {
8441 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8442 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8443 return "test{l}\t{%1, %k0|%k0, %1}";
8444 }
8445 return "test{b}\t{%1, %0|%0, %1}";
8446 }
8447 [(set_attr "type" "test")
8448 (set_attr "mode" "QI,QI,QI,SI")
8449 (set_attr "pent_pair" "uv,uv,np,np")])
8450
8451 (define_insn "*test<mode>_1"
8452 [(set (reg FLAGS_REG)
8453 (compare
8454 (and:SWI124
8455 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
8456 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
8457 (const_int 0)))]
8458 "ix86_match_ccmode (insn, CCNOmode)"
8459 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8460 [(set_attr "type" "test")
8461 (set_attr "mode" "<MODE>")
8462 (set_attr "pent_pair" "uv,uv,np")])
8463
8464 (define_expand "testqi_ext_1_ccno"
8465 [(set (reg:CCNO FLAGS_REG)
8466 (compare:CCNO
8467 (and:QI
8468 (subreg:QI
8469 (zero_extract:SI (match_operand 0 "ext_register_operand")
8470 (const_int 8)
8471 (const_int 8)) 0)
8472 (match_operand 1 "const_int_operand"))
8473 (const_int 0)))])
8474
8475 (define_insn "*testqi_ext_1"
8476 [(set (reg FLAGS_REG)
8477 (compare
8478 (and:QI
8479 (subreg:QI
8480 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8481 (const_int 8)
8482 (const_int 8)) 0)
8483 (match_operand:QI 1 "general_operand" "QnBc,m"))
8484 (const_int 0)))]
8485 "ix86_match_ccmode (insn, CCNOmode)"
8486 "test{b}\t{%1, %h0|%h0, %1}"
8487 [(set_attr "isa" "*,nox64")
8488 (set_attr "type" "test")
8489 (set_attr "mode" "QI")])
8490
8491 (define_insn "*testqi_ext_2"
8492 [(set (reg FLAGS_REG)
8493 (compare
8494 (and:QI
8495 (subreg:QI
8496 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8497 (const_int 8)
8498 (const_int 8)) 0)
8499 (subreg:QI
8500 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8501 (const_int 8)
8502 (const_int 8)) 0))
8503 (const_int 0)))]
8504 "ix86_match_ccmode (insn, CCNOmode)"
8505 "test{b}\t{%h1, %h0|%h0, %h1}"
8506 [(set_attr "type" "test")
8507 (set_attr "mode" "QI")])
8508
8509 ;; Combine likes to form bit extractions for some tests. Humor it.
8510 (define_insn_and_split "*testqi_ext_3"
8511 [(set (match_operand 0 "flags_reg_operand")
8512 (match_operator 1 "compare_operator"
8513 [(zero_extract:SWI248
8514 (match_operand 2 "nonimmediate_operand" "rm")
8515 (match_operand 3 "const_int_operand" "n")
8516 (match_operand 4 "const_int_operand" "n"))
8517 (const_int 0)]))]
8518 "ix86_match_ccmode (insn, CCNOmode)
8519 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8520 || GET_MODE (operands[2]) == SImode
8521 || GET_MODE (operands[2]) == HImode
8522 || GET_MODE (operands[2]) == QImode)
8523 /* Ensure that resulting mask is zero or sign extended operand. */
8524 && INTVAL (operands[4]) >= 0
8525 && ((INTVAL (operands[3]) > 0
8526 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8527 || (<MODE>mode == DImode
8528 && INTVAL (operands[3]) > 32
8529 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8530 "#"
8531 "&& 1"
8532 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8533 {
8534 rtx val = operands[2];
8535 HOST_WIDE_INT len = INTVAL (operands[3]);
8536 HOST_WIDE_INT pos = INTVAL (operands[4]);
8537 machine_mode mode = GET_MODE (val);
8538
8539 if (SUBREG_P (val))
8540 {
8541 machine_mode submode = GET_MODE (SUBREG_REG (val));
8542
8543 /* Narrow paradoxical subregs to prevent partial register stalls. */
8544 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8545 && GET_MODE_CLASS (submode) == MODE_INT)
8546 {
8547 val = SUBREG_REG (val);
8548 mode = submode;
8549 }
8550 }
8551
8552 /* Small HImode tests can be converted to QImode. */
8553 if (register_operand (val, HImode) && pos + len <= 8)
8554 {
8555 val = gen_lowpart (QImode, val);
8556 mode = QImode;
8557 }
8558
8559 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8560
8561 wide_int mask
8562 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8563
8564 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8565 })
8566
8567 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8568 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8569 ;; this is relatively important trick.
8570 ;; Do the conversion only post-reload to avoid limiting of the register class
8571 ;; to QI regs.
8572 (define_split
8573 [(set (match_operand 0 "flags_reg_operand")
8574 (match_operator 1 "compare_operator"
8575 [(and (match_operand 2 "QIreg_operand")
8576 (match_operand 3 "const_int_operand"))
8577 (const_int 0)]))]
8578 "reload_completed
8579 && GET_MODE (operands[2]) != QImode
8580 && ((ix86_match_ccmode (insn, CCZmode)
8581 && !(INTVAL (operands[3]) & ~(255 << 8)))
8582 || (ix86_match_ccmode (insn, CCNOmode)
8583 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8584 [(set (match_dup 0)
8585 (match_op_dup 1
8586 [(and:QI
8587 (subreg:QI
8588 (zero_extract:SI (match_dup 2)
8589 (const_int 8)
8590 (const_int 8)) 0)
8591 (match_dup 3))
8592 (const_int 0)]))]
8593 {
8594 operands[2] = gen_lowpart (SImode, operands[2]);
8595 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8596 })
8597
8598 (define_split
8599 [(set (match_operand 0 "flags_reg_operand")
8600 (match_operator 1 "compare_operator"
8601 [(and (match_operand 2 "nonimmediate_operand")
8602 (match_operand 3 "const_int_operand"))
8603 (const_int 0)]))]
8604 "reload_completed
8605 && GET_MODE (operands[2]) != QImode
8606 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8607 && ((ix86_match_ccmode (insn, CCZmode)
8608 && !(INTVAL (operands[3]) & ~255))
8609 || (ix86_match_ccmode (insn, CCNOmode)
8610 && !(INTVAL (operands[3]) & ~127)))"
8611 [(set (match_dup 0)
8612 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8613 (const_int 0)]))]
8614 {
8615 operands[2] = gen_lowpart (QImode, operands[2]);
8616 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8617 })
8618
8619 ;; %%% This used to optimize known byte-wide and operations to memory,
8620 ;; and sometimes to QImode registers. If this is considered useful,
8621 ;; it should be done with splitters.
8622
8623 (define_expand "and<mode>3"
8624 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
8625 (and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
8626 (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
8627 ""
8628 {
8629 machine_mode mode = <MODE>mode;
8630
8631 if (<MODE>mode == DImode && !TARGET_64BIT)
8632 ;
8633 else if (const_int_operand (operands[2], <MODE>mode)
8634 && register_operand (operands[0], <MODE>mode)
8635 && !(TARGET_ZERO_EXTEND_WITH_AND
8636 && optimize_function_for_speed_p (cfun)))
8637 {
8638 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8639
8640 if (ival == GET_MODE_MASK (SImode))
8641 mode = SImode;
8642 else if (ival == GET_MODE_MASK (HImode))
8643 mode = HImode;
8644 else if (ival == GET_MODE_MASK (QImode))
8645 mode = QImode;
8646 }
8647
8648 if (mode != <MODE>mode)
8649 emit_insn (gen_extend_insn
8650 (operands[0], gen_lowpart (mode, operands[1]),
8651 <MODE>mode, mode, 1));
8652 else
8653 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8654
8655 DONE;
8656 })
8657
8658 (define_insn_and_split "*anddi3_doubleword"
8659 [(set (match_operand:DI 0 "nonimmediate_operand")
8660 (and:DI
8661 (match_operand:DI 1 "nonimmediate_operand")
8662 (match_operand:DI 2 "x86_64_szext_general_operand")))
8663 (clobber (reg:CC FLAGS_REG))]
8664 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8665 && ix86_binary_operator_ok (AND, DImode, operands)
8666 && ix86_pre_reload_split ()"
8667 "#"
8668 "&& 1"
8669 [(const_int 0)]
8670 {
8671 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8672
8673 if (operands[2] == const0_rtx)
8674 emit_move_insn (operands[0], const0_rtx);
8675 else if (operands[2] == constm1_rtx)
8676 emit_move_insn (operands[0], operands[1]);
8677 else
8678 emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
8679
8680 if (operands[5] == const0_rtx)
8681 emit_move_insn (operands[3], const0_rtx);
8682 else if (operands[5] == constm1_rtx)
8683 emit_move_insn (operands[3], operands[4]);
8684 else
8685 emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
8686
8687 DONE;
8688 })
8689
8690 (define_insn "*anddi_1"
8691 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8692 (and:DI
8693 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8694 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L")))
8695 (clobber (reg:CC FLAGS_REG))]
8696 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8697 "@
8698 and{l}\t{%k2, %k0|%k0, %k2}
8699 and{q}\t{%2, %0|%0, %2}
8700 and{q}\t{%2, %0|%0, %2}
8701 #"
8702 [(set_attr "type" "alu,alu,alu,imovx")
8703 (set_attr "length_immediate" "*,*,*,0")
8704 (set (attr "prefix_rex")
8705 (if_then_else
8706 (and (eq_attr "type" "imovx")
8707 (and (match_test "INTVAL (operands[2]) == 0xff")
8708 (match_operand 1 "ext_QIreg_operand")))
8709 (const_string "1")
8710 (const_string "*")))
8711 (set_attr "mode" "SI,DI,DI,SI")])
8712
8713 (define_insn_and_split "*anddi_1_btr"
8714 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8715 (and:DI
8716 (match_operand:DI 1 "nonimmediate_operand" "%0")
8717 (match_operand:DI 2 "const_int_operand" "n")))
8718 (clobber (reg:CC FLAGS_REG))]
8719 "TARGET_64BIT && TARGET_USE_BT
8720 && ix86_binary_operator_ok (AND, DImode, operands)
8721 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8722 "#"
8723 "&& reload_completed"
8724 [(parallel [(set (zero_extract:DI (match_dup 0)
8725 (const_int 1)
8726 (match_dup 3))
8727 (const_int 0))
8728 (clobber (reg:CC FLAGS_REG))])]
8729 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8730 [(set_attr "type" "alu1")
8731 (set_attr "prefix_0f" "1")
8732 (set_attr "znver1_decode" "double")
8733 (set_attr "mode" "DI")])
8734
8735 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8736 (define_split
8737 [(set (match_operand:DI 0 "register_operand")
8738 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8739 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8740 (clobber (reg:CC FLAGS_REG))]
8741 "TARGET_64BIT"
8742 [(parallel [(set (match_dup 0)
8743 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8744 (clobber (reg:CC FLAGS_REG))])]
8745 {
8746 if (GET_CODE (operands[2]) == SYMBOL_REF
8747 || GET_CODE (operands[2]) == LABEL_REF)
8748 {
8749 operands[2] = shallow_copy_rtx (operands[2]);
8750 PUT_MODE (operands[2], SImode);
8751 }
8752 else if (GET_CODE (operands[2]) == CONST)
8753 {
8754 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
8755 operands[2] = copy_rtx (operands[2]);
8756 PUT_MODE (operands[2], SImode);
8757 PUT_MODE (XEXP (operands[2], 0), SImode);
8758 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
8759 }
8760 else
8761 operands[2] = gen_lowpart (SImode, operands[2]);
8762 })
8763
8764 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8765 (define_insn "*andsi_1_zext"
8766 [(set (match_operand:DI 0 "register_operand" "=r")
8767 (zero_extend:DI
8768 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8769 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8770 (clobber (reg:CC FLAGS_REG))]
8771 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8772 "and{l}\t{%2, %k0|%k0, %2}"
8773 [(set_attr "type" "alu")
8774 (set_attr "mode" "SI")])
8775
8776 (define_insn "*and<mode>_1"
8777 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8778 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8779 (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L")))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8782 "@
8783 and{<imodesuffix>}\t{%2, %0|%0, %2}
8784 and{<imodesuffix>}\t{%2, %0|%0, %2}
8785 #"
8786 [(set_attr "type" "alu,alu,imovx")
8787 (set_attr "length_immediate" "*,*,0")
8788 (set (attr "prefix_rex")
8789 (if_then_else
8790 (and (eq_attr "type" "imovx")
8791 (and (match_test "INTVAL (operands[2]) == 0xff")
8792 (match_operand 1 "ext_QIreg_operand")))
8793 (const_string "1")
8794 (const_string "*")))
8795 (set_attr "mode" "<MODE>,<MODE>,SI")])
8796
8797 (define_insn "*andqi_1"
8798 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8799 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8800 (match_operand:QI 2 "general_operand" "qn,m,rn")))
8801 (clobber (reg:CC FLAGS_REG))]
8802 "ix86_binary_operator_ok (AND, QImode, operands)"
8803 "@
8804 and{b}\t{%2, %0|%0, %2}
8805 and{b}\t{%2, %0|%0, %2}
8806 and{l}\t{%k2, %k0|%k0, %k2}"
8807 [(set_attr "type" "alu")
8808 (set_attr "mode" "QI,QI,SI")
8809 ;; Potential partial reg stall on alternative 2.
8810 (set (attr "preferred_for_speed")
8811 (cond [(eq_attr "alternative" "2")
8812 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8813 (symbol_ref "true")))])
8814
8815 (define_insn "*and<mode>_1_slp"
8816 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
8817 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
8818 (match_operand:SWI12 2 "general_operand" "<r>mn")))
8819 (clobber (reg:CC FLAGS_REG))]
8820 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8821 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
8822 && (rtx_equal_p (operands[0], operands[1])
8823 || rtx_equal_p (operands[0], operands[2]))"
8824 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8825 [(set_attr "type" "alu")
8826 (set_attr "mode" "<MODE>")])
8827
8828 (define_split
8829 [(set (match_operand:SWI248 0 "register_operand")
8830 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8831 (match_operand:SWI248 2 "const_int_operand")))
8832 (clobber (reg:CC FLAGS_REG))]
8833 "reload_completed
8834 && (!REG_P (operands[1])
8835 || REGNO (operands[0]) != REGNO (operands[1]))"
8836 [(const_int 0)]
8837 {
8838 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8839 machine_mode mode;
8840
8841 if (ival == GET_MODE_MASK (SImode))
8842 mode = SImode;
8843 else if (ival == GET_MODE_MASK (HImode))
8844 mode = HImode;
8845 else if (ival == GET_MODE_MASK (QImode))
8846 mode = QImode;
8847 else
8848 gcc_unreachable ();
8849
8850 /* Zero extend to SImode to avoid partial register stalls. */
8851 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
8852 operands[0] = gen_lowpart (SImode, operands[0]);
8853
8854 emit_insn (gen_extend_insn
8855 (operands[0], gen_lowpart (mode, operands[1]),
8856 GET_MODE (operands[0]), mode, 1));
8857 DONE;
8858 })
8859
8860 (define_split
8861 [(set (match_operand:SWI48 0 "register_operand")
8862 (and:SWI48 (match_dup 0)
8863 (const_int -65536)))
8864 (clobber (reg:CC FLAGS_REG))]
8865 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8866 || optimize_function_for_size_p (cfun)"
8867 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8868 "operands[1] = gen_lowpart (HImode, operands[0]);")
8869
8870 (define_split
8871 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8872 (and:SWI248 (match_dup 0)
8873 (const_int -256)))
8874 (clobber (reg:CC FLAGS_REG))]
8875 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8876 && reload_completed"
8877 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8878 "operands[1] = gen_lowpart (QImode, operands[0]);")
8879
8880 (define_split
8881 [(set (match_operand:SWI248 0 "QIreg_operand")
8882 (and:SWI248 (match_dup 0)
8883 (const_int -65281)))
8884 (clobber (reg:CC FLAGS_REG))]
8885 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8886 && reload_completed"
8887 [(parallel
8888 [(set (zero_extract:SI (match_dup 0)
8889 (const_int 8)
8890 (const_int 8))
8891 (subreg:SI
8892 (xor:QI
8893 (subreg:QI
8894 (zero_extract:SI (match_dup 0)
8895 (const_int 8)
8896 (const_int 8)) 0)
8897 (subreg:QI
8898 (zero_extract:SI (match_dup 0)
8899 (const_int 8)
8900 (const_int 8)) 0)) 0))
8901 (clobber (reg:CC FLAGS_REG))])]
8902 "operands[0] = gen_lowpart (SImode, operands[0]);")
8903
8904 (define_insn "*anddi_2"
8905 [(set (reg FLAGS_REG)
8906 (compare
8907 (and:DI
8908 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8909 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
8910 (const_int 0)))
8911 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8912 (and:DI (match_dup 1) (match_dup 2)))]
8913 "TARGET_64BIT
8914 && ix86_match_ccmode
8915 (insn,
8916 /* If we are going to emit andl instead of andq, and the operands[2]
8917 constant might have the SImode sign bit set, make sure the sign
8918 flag isn't tested, because the instruction will set the sign flag
8919 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8920 conservatively assume it might have bit 31 set. */
8921 (satisfies_constraint_Z (operands[2])
8922 && (!CONST_INT_P (operands[2])
8923 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8924 ? CCZmode : CCNOmode)
8925 && ix86_binary_operator_ok (AND, DImode, operands)"
8926 "@
8927 and{l}\t{%k2, %k0|%k0, %k2}
8928 and{q}\t{%2, %0|%0, %2}
8929 and{q}\t{%2, %0|%0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "mode" "SI,DI,DI")])
8932
8933 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8934 (define_insn "*andsi_2_zext"
8935 [(set (reg FLAGS_REG)
8936 (compare (and:SI
8937 (match_operand:SI 1 "nonimmediate_operand" "%0")
8938 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8939 (const_int 0)))
8940 (set (match_operand:DI 0 "register_operand" "=r")
8941 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8942 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8943 && ix86_binary_operator_ok (AND, SImode, operands)"
8944 "and{l}\t{%2, %k0|%k0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "SI")])
8947
8948 (define_insn "*andqi_2_maybe_si"
8949 [(set (reg FLAGS_REG)
8950 (compare (and:QI
8951 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8952 (match_operand:QI 2 "general_operand" "qn,m,n"))
8953 (const_int 0)))
8954 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8955 (and:QI (match_dup 1) (match_dup 2)))]
8956 "ix86_binary_operator_ok (AND, QImode, operands)
8957 && ix86_match_ccmode (insn,
8958 CONST_INT_P (operands[2])
8959 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8960 {
8961 if (which_alternative == 2)
8962 {
8963 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8964 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8965 return "and{l}\t{%2, %k0|%k0, %2}";
8966 }
8967 return "and{b}\t{%2, %0|%0, %2}";
8968 }
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "QI,QI,SI")
8971 ;; Potential partial reg stall on alternative 2.
8972 (set (attr "preferred_for_speed")
8973 (cond [(eq_attr "alternative" "2")
8974 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8975 (symbol_ref "true")))])
8976
8977 (define_insn "*and<mode>_2"
8978 [(set (reg FLAGS_REG)
8979 (compare (and:SWI124
8980 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8981 (match_operand:SWI124 2 "<general_operand>" "<r><i>,m"))
8982 (const_int 0)))
8983 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
8984 (and:SWI124 (match_dup 1) (match_dup 2)))]
8985 "ix86_match_ccmode (insn, CCNOmode)
8986 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8987 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "<MODE>")])
8990
8991 (define_insn "andqi_ext_1"
8992 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8993 (const_int 8)
8994 (const_int 8))
8995 (subreg:SI
8996 (and:QI
8997 (subreg:QI
8998 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8999 (const_int 8)
9000 (const_int 8)) 0)
9001 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9002 (clobber (reg:CC FLAGS_REG))]
9003 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9004 rtx_equal_p (operands[0], operands[1])"
9005 "and{b}\t{%2, %h0|%h0, %2}"
9006 [(set_attr "isa" "*,nox64")
9007 (set_attr "type" "alu")
9008 (set_attr "mode" "QI")])
9009
9010 ;; Generated by peephole translating test to and. This shows up
9011 ;; often in fp comparisons.
9012 (define_insn "*andqi_ext_1_cc"
9013 [(set (reg FLAGS_REG)
9014 (compare
9015 (and:QI
9016 (subreg:QI
9017 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9018 (const_int 8)
9019 (const_int 8)) 0)
9020 (match_operand:QI 2 "general_operand" "QnBc,m"))
9021 (const_int 0)))
9022 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9023 (const_int 8)
9024 (const_int 8))
9025 (subreg:SI
9026 (and:QI
9027 (subreg:QI
9028 (zero_extract:SI (match_dup 1)
9029 (const_int 8)
9030 (const_int 8)) 0)
9031 (match_dup 2)) 0))]
9032 "ix86_match_ccmode (insn, CCNOmode)
9033 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9034 && rtx_equal_p (operands[0], operands[1])"
9035 "and{b}\t{%2, %h0|%h0, %2}"
9036 [(set_attr "isa" "*,nox64")
9037 (set_attr "type" "alu")
9038 (set_attr "mode" "QI")])
9039
9040 (define_insn "*andqi_ext_2"
9041 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9042 (const_int 8)
9043 (const_int 8))
9044 (subreg:SI
9045 (and:QI
9046 (subreg:QI
9047 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9048 (const_int 8)
9049 (const_int 8)) 0)
9050 (subreg:QI
9051 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9052 (const_int 8)
9053 (const_int 8)) 0)) 0))
9054 (clobber (reg:CC FLAGS_REG))]
9055 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9056 rtx_equal_p (operands[0], operands[1])
9057 || rtx_equal_p (operands[0], operands[2])"
9058 "and{b}\t{%h2, %h0|%h0, %h2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "QI")])
9061
9062 ;; Convert wide AND instructions with immediate operand to shorter QImode
9063 ;; equivalents when possible.
9064 ;; Don't do the splitting with memory operands, since it introduces risk
9065 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9066 ;; for size, but that can (should?) be handled by generic code instead.
9067 (define_split
9068 [(set (match_operand:SWI248 0 "QIreg_operand")
9069 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9070 (match_operand:SWI248 2 "const_int_operand")))
9071 (clobber (reg:CC FLAGS_REG))]
9072 "reload_completed
9073 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9074 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9075 [(parallel
9076 [(set (zero_extract:SI (match_dup 0)
9077 (const_int 8)
9078 (const_int 8))
9079 (subreg:SI
9080 (and:QI
9081 (subreg:QI
9082 (zero_extract:SI (match_dup 1)
9083 (const_int 8)
9084 (const_int 8)) 0)
9085 (match_dup 2)) 0))
9086 (clobber (reg:CC FLAGS_REG))])]
9087 {
9088 operands[0] = gen_lowpart (SImode, operands[0]);
9089 operands[1] = gen_lowpart (SImode, operands[1]);
9090 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9091 })
9092
9093 ;; Since AND can be encoded with sign extended immediate, this is only
9094 ;; profitable when 7th bit is not set.
9095 (define_split
9096 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9097 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9098 (match_operand:SWI248 2 "const_int_operand")))
9099 (clobber (reg:CC FLAGS_REG))]
9100 "reload_completed
9101 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9102 && !(~INTVAL (operands[2]) & ~255)
9103 && !(INTVAL (operands[2]) & 128)"
9104 [(parallel [(set (strict_low_part (match_dup 0))
9105 (and:QI (match_dup 1)
9106 (match_dup 2)))
9107 (clobber (reg:CC FLAGS_REG))])]
9108 {
9109 operands[0] = gen_lowpart (QImode, operands[0]);
9110 operands[1] = gen_lowpart (QImode, operands[1]);
9111 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9112 })
9113
9114 (define_insn "*andndi3_doubleword"
9115 [(set (match_operand:DI 0 "register_operand")
9116 (and:DI
9117 (not:DI (match_operand:DI 1 "register_operand"))
9118 (match_operand:DI 2 "nonimmediate_operand")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9121 && ix86_pre_reload_split ()"
9122 "#")
9123
9124 (define_split
9125 [(set (match_operand:DI 0 "register_operand")
9126 (and:DI
9127 (not:DI (match_operand:DI 1 "register_operand"))
9128 (match_operand:DI 2 "nonimmediate_operand")))
9129 (clobber (reg:CC FLAGS_REG))]
9130 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9131 && can_create_pseudo_p ()"
9132 [(parallel [(set (match_dup 0)
9133 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9134 (clobber (reg:CC FLAGS_REG))])
9135 (parallel [(set (match_dup 3)
9136 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9137 (clobber (reg:CC FLAGS_REG))])]
9138 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9139
9140 (define_split
9141 [(set (match_operand:DI 0 "register_operand")
9142 (and:DI
9143 (not:DI (match_operand:DI 1 "register_operand"))
9144 (match_operand:DI 2 "nonimmediate_operand")))
9145 (clobber (reg:CC FLAGS_REG))]
9146 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9147 && can_create_pseudo_p ()"
9148 [(set (match_dup 6) (not:SI (match_dup 1)))
9149 (parallel [(set (match_dup 0)
9150 (and:SI (match_dup 6) (match_dup 2)))
9151 (clobber (reg:CC FLAGS_REG))])
9152 (set (match_dup 7) (not:SI (match_dup 4)))
9153 (parallel [(set (match_dup 3)
9154 (and:SI (match_dup 7) (match_dup 5)))
9155 (clobber (reg:CC FLAGS_REG))])]
9156 {
9157 operands[6] = gen_reg_rtx (SImode);
9158 operands[7] = gen_reg_rtx (SImode);
9159
9160 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9161 })
9162
9163 (define_insn "*andn<mode>_1"
9164 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9165 (and:SWI48
9166 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9167 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "TARGET_BMI"
9170 "andn\t{%2, %1, %0|%0, %1, %2}"
9171 [(set_attr "type" "bitmanip")
9172 (set_attr "btver2_decode" "direct, double")
9173 (set_attr "mode" "<MODE>")])
9174
9175 (define_insn "*andn<mode>_1"
9176 [(set (match_operand:SWI12 0 "register_operand" "=r")
9177 (and:SWI12
9178 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9179 (match_operand:SWI12 2 "register_operand" "r")))
9180 (clobber (reg:CC FLAGS_REG))]
9181 "TARGET_BMI"
9182 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9183 [(set_attr "type" "bitmanip")
9184 (set_attr "btver2_decode" "direct")
9185 (set_attr "mode" "SI")])
9186
9187 (define_insn "*andn_<mode>_ccno"
9188 [(set (reg FLAGS_REG)
9189 (compare
9190 (and:SWI48
9191 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9192 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9193 (const_int 0)))
9194 (clobber (match_scratch:SWI48 0 "=r,r"))]
9195 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9196 "andn\t{%2, %1, %0|%0, %1, %2}"
9197 [(set_attr "type" "bitmanip")
9198 (set_attr "btver2_decode" "direct, double")
9199 (set_attr "mode" "<MODE>")])
9200 \f
9201 ;; Logical inclusive and exclusive OR instructions
9202
9203 ;; %%% This used to optimize known byte-wide and operations to memory.
9204 ;; If this is considered useful, it should be done with splitters.
9205
9206 (define_expand "<code><mode>3"
9207 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9208 (any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9209 (match_operand:SWIM1248s 2 "<general_operand>")))]
9210 ""
9211 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9212
9213 (define_insn_and_split "*<code>di3_doubleword"
9214 [(set (match_operand:DI 0 "nonimmediate_operand")
9215 (any_or:DI
9216 (match_operand:DI 1 "nonimmediate_operand")
9217 (match_operand:DI 2 "x86_64_szext_general_operand")))
9218 (clobber (reg:CC FLAGS_REG))]
9219 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9220 && ix86_binary_operator_ok (<CODE>, DImode, operands)
9221 && ix86_pre_reload_split ()"
9222 "#"
9223 "&& 1"
9224 [(const_int 0)]
9225 {
9226 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9227
9228 if (operands[2] == const0_rtx)
9229 emit_move_insn (operands[0], operands[1]);
9230 else if (operands[2] == constm1_rtx)
9231 {
9232 if (<CODE> == IOR)
9233 emit_move_insn (operands[0], constm1_rtx);
9234 else
9235 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9236 }
9237 else
9238 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9239
9240 if (operands[5] == const0_rtx)
9241 emit_move_insn (operands[3], operands[4]);
9242 else if (operands[5] == constm1_rtx)
9243 {
9244 if (<CODE> == IOR)
9245 emit_move_insn (operands[3], constm1_rtx);
9246 else
9247 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9248 }
9249 else
9250 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9251
9252 DONE;
9253 })
9254
9255 (define_insn "*<code><mode>_1"
9256 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r")
9257 (any_or:SWI248
9258 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9259 (match_operand:SWI248 2 "<general_operand>" "r<i>,m")))
9260 (clobber (reg:CC FLAGS_REG))]
9261 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9262 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9263 [(set_attr "type" "alu")
9264 (set_attr "mode" "<MODE>")])
9265
9266 (define_insn_and_split "*iordi_1_bts"
9267 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9268 (ior:DI
9269 (match_operand:DI 1 "nonimmediate_operand" "%0")
9270 (match_operand:DI 2 "const_int_operand" "n")))
9271 (clobber (reg:CC FLAGS_REG))]
9272 "TARGET_64BIT && TARGET_USE_BT
9273 && ix86_binary_operator_ok (IOR, DImode, operands)
9274 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9275 "#"
9276 "&& reload_completed"
9277 [(parallel [(set (zero_extract:DI (match_dup 0)
9278 (const_int 1)
9279 (match_dup 3))
9280 (const_int 1))
9281 (clobber (reg:CC FLAGS_REG))])]
9282 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9283 [(set_attr "type" "alu1")
9284 (set_attr "prefix_0f" "1")
9285 (set_attr "znver1_decode" "double")
9286 (set_attr "mode" "DI")])
9287
9288 (define_insn_and_split "*xordi_1_btc"
9289 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9290 (xor:DI
9291 (match_operand:DI 1 "nonimmediate_operand" "%0")
9292 (match_operand:DI 2 "const_int_operand" "n")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "TARGET_64BIT && TARGET_USE_BT
9295 && ix86_binary_operator_ok (XOR, DImode, operands)
9296 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9297 "#"
9298 "&& reload_completed"
9299 [(parallel [(set (zero_extract:DI (match_dup 0)
9300 (const_int 1)
9301 (match_dup 3))
9302 (not:DI (zero_extract:DI (match_dup 0)
9303 (const_int 1)
9304 (match_dup 3))))
9305 (clobber (reg:CC FLAGS_REG))])]
9306 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9307 [(set_attr "type" "alu1")
9308 (set_attr "prefix_0f" "1")
9309 (set_attr "znver1_decode" "double")
9310 (set_attr "mode" "DI")])
9311
9312 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9313 (define_insn "*<code>si_1_zext"
9314 [(set (match_operand:DI 0 "register_operand" "=r")
9315 (zero_extend:DI
9316 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9317 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9318 (clobber (reg:CC FLAGS_REG))]
9319 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9320 "<logic>{l}\t{%2, %k0|%k0, %2}"
9321 [(set_attr "type" "alu")
9322 (set_attr "mode" "SI")])
9323
9324 (define_insn "*<code>si_1_zext_imm"
9325 [(set (match_operand:DI 0 "register_operand" "=r")
9326 (any_or:DI
9327 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9328 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9329 (clobber (reg:CC FLAGS_REG))]
9330 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9331 "<logic>{l}\t{%2, %k0|%k0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "SI")])
9334
9335 (define_insn "*<code>qi_1"
9336 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9337 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9338 (match_operand:QI 2 "general_operand" "qn,m,rn")))
9339 (clobber (reg:CC FLAGS_REG))]
9340 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9341 "@
9342 <logic>{b}\t{%2, %0|%0, %2}
9343 <logic>{b}\t{%2, %0|%0, %2}
9344 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "QI,QI,SI")
9347 ;; Potential partial reg stall on alternative 2.
9348 (set (attr "preferred_for_speed")
9349 (cond [(eq_attr "alternative" "2")
9350 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9351 (symbol_ref "true")))])
9352
9353 (define_insn "*<code><mode>_1_slp"
9354 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9355 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9356 (match_operand:SWI12 2 "general_operand" "<r>mn")))
9357 (clobber (reg:CC FLAGS_REG))]
9358 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9359 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9360 && (rtx_equal_p (operands[0], operands[1])
9361 || rtx_equal_p (operands[0], operands[2]))"
9362 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9363 [(set_attr "type" "alu")
9364 (set_attr "mode" "<MODE>")])
9365
9366 (define_insn "*<code><mode>_2"
9367 [(set (reg FLAGS_REG)
9368 (compare (any_or:SWI
9369 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9370 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
9371 (const_int 0)))
9372 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9373 (any_or:SWI (match_dup 1) (match_dup 2)))]
9374 "ix86_match_ccmode (insn, CCNOmode)
9375 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9376 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9377 [(set_attr "type" "alu")
9378 (set_attr "mode" "<MODE>")])
9379
9380 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9381 ;; ??? Special case for immediate operand is missing - it is tricky.
9382 (define_insn "*<code>si_2_zext"
9383 [(set (reg FLAGS_REG)
9384 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9385 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9386 (const_int 0)))
9387 (set (match_operand:DI 0 "register_operand" "=r")
9388 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9389 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9390 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9391 "<logic>{l}\t{%2, %k0|%k0, %2}"
9392 [(set_attr "type" "alu")
9393 (set_attr "mode" "SI")])
9394
9395 (define_insn "*<code>si_2_zext_imm"
9396 [(set (reg FLAGS_REG)
9397 (compare (any_or:SI
9398 (match_operand:SI 1 "nonimmediate_operand" "%0")
9399 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9400 (const_int 0)))
9401 (set (match_operand:DI 0 "register_operand" "=r")
9402 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9403 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9404 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9405 "<logic>{l}\t{%2, %k0|%k0, %2}"
9406 [(set_attr "type" "alu")
9407 (set_attr "mode" "SI")])
9408
9409 (define_insn "*<code><mode>_3"
9410 [(set (reg FLAGS_REG)
9411 (compare (any_or:SWI
9412 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9413 (match_operand:SWI 2 "<general_operand>" "<g>"))
9414 (const_int 0)))
9415 (clobber (match_scratch:SWI 0 "=<r>"))]
9416 "ix86_match_ccmode (insn, CCNOmode)
9417 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9418 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9419 [(set_attr "type" "alu")
9420 (set_attr "mode" "<MODE>")])
9421
9422 (define_insn "*<code>qi_ext_1"
9423 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9424 (const_int 8)
9425 (const_int 8))
9426 (subreg:SI
9427 (any_or:QI
9428 (subreg:QI
9429 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9430 (const_int 8)
9431 (const_int 8)) 0)
9432 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9433 (clobber (reg:CC FLAGS_REG))]
9434 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9435 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9436 && rtx_equal_p (operands[0], operands[1])"
9437 "<logic>{b}\t{%2, %h0|%h0, %2}"
9438 [(set_attr "isa" "*,nox64")
9439 (set_attr "type" "alu")
9440 (set_attr "mode" "QI")])
9441
9442 (define_insn "*<code>qi_ext_2"
9443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9444 (const_int 8)
9445 (const_int 8))
9446 (subreg:SI
9447 (any_or:QI
9448 (subreg:QI
9449 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9450 (const_int 8)
9451 (const_int 8)) 0)
9452 (subreg:QI
9453 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9454 (const_int 8)
9455 (const_int 8)) 0)) 0))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9458 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9459 && (rtx_equal_p (operands[0], operands[1])
9460 || rtx_equal_p (operands[0], operands[2]))"
9461 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9462 [(set_attr "type" "alu")
9463 (set_attr "mode" "QI")])
9464
9465 ;; Convert wide OR instructions with immediate operand to shorter QImode
9466 ;; equivalents when possible.
9467 ;; Don't do the splitting with memory operands, since it introduces risk
9468 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9469 ;; for size, but that can (should?) be handled by generic code instead.
9470 (define_split
9471 [(set (match_operand:SWI248 0 "QIreg_operand")
9472 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9473 (match_operand:SWI248 2 "const_int_operand")))
9474 (clobber (reg:CC FLAGS_REG))]
9475 "reload_completed
9476 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9477 && !(INTVAL (operands[2]) & ~(255 << 8))"
9478 [(parallel
9479 [(set (zero_extract:SI (match_dup 0)
9480 (const_int 8)
9481 (const_int 8))
9482 (subreg:SI
9483 (any_or:QI
9484 (subreg:QI
9485 (zero_extract:SI (match_dup 1)
9486 (const_int 8)
9487 (const_int 8)) 0)
9488 (match_dup 2)) 0))
9489 (clobber (reg:CC FLAGS_REG))])]
9490 {
9491 operands[0] = gen_lowpart (SImode, operands[0]);
9492 operands[1] = gen_lowpart (SImode, operands[1]);
9493 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9494 })
9495
9496 ;; Since OR can be encoded with sign extended immediate, this is only
9497 ;; profitable when 7th bit is set.
9498 (define_split
9499 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9500 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9501 (match_operand:SWI248 2 "const_int_operand")))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "reload_completed
9504 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9505 && !(INTVAL (operands[2]) & ~255)
9506 && (INTVAL (operands[2]) & 128)"
9507 [(parallel [(set (strict_low_part (match_dup 0))
9508 (any_or:QI (match_dup 1)
9509 (match_dup 2)))
9510 (clobber (reg:CC FLAGS_REG))])]
9511 {
9512 operands[0] = gen_lowpart (QImode, operands[0]);
9513 operands[1] = gen_lowpart (QImode, operands[1]);
9514 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9515 })
9516
9517 (define_expand "xorqi_ext_1_cc"
9518 [(parallel [
9519 (set (reg:CCNO FLAGS_REG)
9520 (compare:CCNO
9521 (xor:QI
9522 (subreg:QI
9523 (zero_extract:SI (match_operand 1 "ext_register_operand")
9524 (const_int 8)
9525 (const_int 8)) 0)
9526 (match_operand 2 "const_int_operand"))
9527 (const_int 0)))
9528 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9529 (const_int 8)
9530 (const_int 8))
9531 (subreg:SI
9532 (xor:QI
9533 (subreg:QI
9534 (zero_extract:SI (match_dup 1)
9535 (const_int 8)
9536 (const_int 8)) 0)
9537 (match_dup 2)) 0))])])
9538
9539 (define_insn "*xorqi_ext_1_cc"
9540 [(set (reg FLAGS_REG)
9541 (compare
9542 (xor:QI
9543 (subreg:QI
9544 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9545 (const_int 8)
9546 (const_int 8)) 0)
9547 (match_operand:QI 2 "general_operand" "QnBc,m"))
9548 (const_int 0)))
9549 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9550 (const_int 8)
9551 (const_int 8))
9552 (subreg:SI
9553 (xor:QI
9554 (subreg:QI
9555 (zero_extract:SI (match_dup 1)
9556 (const_int 8)
9557 (const_int 8)) 0)
9558 (match_dup 2)) 0))]
9559 "ix86_match_ccmode (insn, CCNOmode)
9560 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9561 && rtx_equal_p (operands[0], operands[1])"
9562 "xor{b}\t{%2, %h0|%h0, %2}"
9563 [(set_attr "isa" "*,nox64")
9564 (set_attr "type" "alu")
9565 (set_attr "mode" "QI")])
9566 \f
9567 ;; Negation instructions
9568
9569 (define_expand "neg<mode>2"
9570 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9571 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9572 ""
9573 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9574
9575 (define_insn_and_split "*neg<dwi>2_doubleword"
9576 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9577 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9578 (clobber (reg:CC FLAGS_REG))]
9579 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9580 "#"
9581 "reload_completed"
9582 [(parallel
9583 [(set (reg:CCZ FLAGS_REG)
9584 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9585 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9586 (parallel
9587 [(set (match_dup 2)
9588 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9589 (match_dup 3))
9590 (const_int 0)))
9591 (clobber (reg:CC FLAGS_REG))])
9592 (parallel
9593 [(set (match_dup 2)
9594 (neg:DWIH (match_dup 2)))
9595 (clobber (reg:CC FLAGS_REG))])]
9596 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9597
9598 (define_insn "*neg<mode>2_1"
9599 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9600 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9601 (clobber (reg:CC FLAGS_REG))]
9602 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9603 "neg{<imodesuffix>}\t%0"
9604 [(set_attr "type" "negnot")
9605 (set_attr "mode" "<MODE>")])
9606
9607 (define_insn "*negsi2_1_zext"
9608 [(set (match_operand:DI 0 "register_operand" "=r")
9609 (zero_extend:DI
9610 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
9611 (clobber (reg:CC FLAGS_REG))]
9612 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9613 "neg{l}\t%k0"
9614 [(set_attr "type" "negnot")
9615 (set_attr "mode" "SI")])
9616
9617 ;; The problem with neg is that it does not perform (compare x 0),
9618 ;; it really performs (compare 0 x), which leaves us with the zero
9619 ;; flag being the only useful item.
9620
9621 (define_insn "*neg<mode>2_cmpz"
9622 [(set (reg:CCZ FLAGS_REG)
9623 (compare:CCZ
9624 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9625 (const_int 0)))
9626 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9627 (neg:SWI (match_dup 1)))]
9628 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9629 "neg{<imodesuffix>}\t%0"
9630 [(set_attr "type" "negnot")
9631 (set_attr "mode" "<MODE>")])
9632
9633 (define_insn "*negsi2_cmpz_zext"
9634 [(set (reg:CCZ FLAGS_REG)
9635 (compare:CCZ
9636 (neg:SI (match_operand:SI 1 "register_operand" "0"))
9637 (const_int 0)))
9638 (set (match_operand:DI 0 "register_operand" "=r")
9639 (zero_extend:DI
9640 (neg:SI (match_dup 1))))]
9641 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9642 "neg{l}\t%k0"
9643 [(set_attr "type" "negnot")
9644 (set_attr "mode" "SI")])
9645
9646 ;; Negate with jump on overflow.
9647 (define_expand "negv<mode>3"
9648 [(parallel [(set (reg:CCO FLAGS_REG)
9649 (ne:CCO (match_operand:SWI 1 "register_operand")
9650 (match_dup 3)))
9651 (set (match_operand:SWI 0 "register_operand")
9652 (neg:SWI (match_dup 1)))])
9653 (set (pc) (if_then_else
9654 (eq (reg:CCO FLAGS_REG) (const_int 0))
9655 (label_ref (match_operand 2))
9656 (pc)))]
9657 ""
9658 {
9659 operands[3]
9660 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9661 <MODE>mode);
9662 })
9663
9664 (define_insn "*negv<mode>3"
9665 [(set (reg:CCO FLAGS_REG)
9666 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9667 (match_operand:SWI 2 "const_int_operand")))
9668 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9669 (neg:SWI (match_dup 1)))]
9670 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9671 && mode_signbit_p (<MODE>mode, operands[2])"
9672 "neg{<imodesuffix>}\t%0"
9673 [(set_attr "type" "negnot")
9674 (set_attr "mode" "<MODE>")])
9675
9676 (define_expand "<code>tf2"
9677 [(set (match_operand:TF 0 "register_operand")
9678 (absneg:TF (match_operand:TF 1 "register_operand")))]
9679 "TARGET_SSE"
9680 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9681
9682 (define_insn "*<code>tf2_1"
9683 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
9684 (absneg:TF
9685 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
9686 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))
9687 (clobber (reg:CC FLAGS_REG))]
9688 "TARGET_SSE"
9689 "#"
9690 [(set_attr "isa" "noavx,noavx,avx,avx")])
9691
9692 (define_insn "*nabstf2_1"
9693 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
9694 (neg:TF
9695 (abs:TF
9696 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
9697 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
9698 "TARGET_SSE"
9699 "#"
9700 [(set_attr "isa" "noavx,noavx,avx,avx")])
9701
9702 ;; Special expand pattern to handle integer mode abs
9703
9704 (define_expand "abs<mode>2"
9705 [(set (match_operand:SWI48x 0 "register_operand")
9706 (abs:SWI48x
9707 (match_operand:SWI48x 1 "register_operand")))]
9708 "TARGET_EXPAND_ABS"
9709 {
9710 machine_mode mode = <MODE>mode;
9711
9712 /* Generate rtx abs using abs (x) = (((signed) x >> (W-1)) ^ x) -
9713 ((signed) x >> (W-1)) */
9714 rtx shift_amount = gen_int_shift_amount (mode,
9715 GET_MODE_PRECISION (mode)
9716 - 1);
9717 shift_amount = convert_modes (E_QImode, GET_MODE (shift_amount),
9718 shift_amount, 1);
9719 rtx shift_dst = gen_reg_rtx (mode);
9720 rtx shift_op = gen_rtx_SET (shift_dst,
9721 gen_rtx_fmt_ee (ASHIFTRT, mode,
9722 operands[1], shift_amount));
9723 rtx clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode,
9724 FLAGS_REG));
9725 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, shift_op,
9726 clobber)));
9727
9728 rtx xor_op = gen_rtx_SET (operands[0],
9729 gen_rtx_fmt_ee (XOR, mode, shift_dst,
9730 operands[1]));
9731 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, xor_op, clobber)));
9732
9733 rtx minus_op = gen_rtx_SET (operands[0],
9734 gen_rtx_fmt_ee (MINUS, mode,
9735 operands[0], shift_dst));
9736 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, minus_op,
9737 clobber)));
9738 DONE;
9739 })
9740
9741 (define_expand "<code><mode>2"
9742 [(set (match_operand:X87MODEF 0 "register_operand")
9743 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9744 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9745 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9746
9747 ;; Changing of sign for FP values is doable using integer unit too.
9748 (define_insn "*<code><mode>2_i387_1"
9749 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9750 (absneg:X87MODEF
9751 (match_operand:X87MODEF 1 "register_operand" "0,0")))
9752 (clobber (reg:CC FLAGS_REG))]
9753 "TARGET_80387"
9754 "#")
9755
9756 (define_split
9757 [(set (match_operand:X87MODEF 0 "fp_register_operand")
9758 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
9759 (clobber (reg:CC FLAGS_REG))]
9760 "TARGET_80387 && reload_completed"
9761 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
9762
9763 (define_split
9764 [(set (match_operand:X87MODEF 0 "general_reg_operand")
9765 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
9766 (clobber (reg:CC FLAGS_REG))]
9767 "TARGET_80387 && reload_completed"
9768 [(const_int 0)]
9769 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9770
9771 (define_insn "*<code><mode>2_1"
9772 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
9773 (absneg:MODEF
9774 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
9775 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9778 "#"
9779 [(set_attr "isa" "noavx,noavx,avx,*,*")
9780 (set (attr "enabled")
9781 (if_then_else
9782 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9783 (if_then_else
9784 (eq_attr "alternative" "3,4")
9785 (symbol_ref "TARGET_MIX_SSE_I387")
9786 (const_string "*"))
9787 (if_then_else
9788 (eq_attr "alternative" "3,4")
9789 (symbol_ref "true")
9790 (symbol_ref "false"))))])
9791
9792 (define_split
9793 [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
9794 (absneg:SSEMODEF
9795 (match_operand:SSEMODEF 1 "vector_operand")))
9796 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9799 || (TARGET_SSE && (<MODE>mode == TFmode)))
9800 && reload_completed"
9801 [(set (match_dup 0) (match_dup 3))]
9802 {
9803 machine_mode mode = <MODE>mode;
9804 machine_mode vmode = <ssevecmodef>mode;
9805 enum rtx_code absneg_op = <CODE> == ABS ? AND : XOR;
9806
9807 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9808 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9809
9810 if (TARGET_AVX)
9811 {
9812 if (MEM_P (operands[1]))
9813 std::swap (operands[1], operands[2]);
9814 }
9815 else
9816 {
9817 if (operands_match_p (operands[0], operands[2]))
9818 std::swap (operands[1], operands[2]);
9819 }
9820
9821 operands[3]
9822 = gen_rtx_fmt_ee (absneg_op, vmode, operands[1], operands[2]);
9823 })
9824
9825 (define_split
9826 [(set (match_operand:MODEF 0 "fp_register_operand")
9827 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
9828 (use (match_operand 2))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "TARGET_80387 && reload_completed"
9831 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
9832
9833 (define_split
9834 [(set (match_operand:MODEF 0 "general_reg_operand")
9835 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
9836 (use (match_operand 2))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "TARGET_80387 && reload_completed"
9839 [(const_int 0)]
9840 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9841
9842 (define_insn "*nabs<mode>2_1"
9843 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
9844 (neg:MODEF
9845 (abs:MODEF
9846 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
9847 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
9848 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9849 "#"
9850 [(set_attr "isa" "noavx,noavx,avx")])
9851
9852 (define_split
9853 [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
9854 (neg:SSEMODEF
9855 (abs:SSEMODEF
9856 (match_operand:SSEMODEF 1 "vector_operand"))))
9857 (use (match_operand:<ssevecmodef> 2 "vector_operand"))]
9858 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9859 || (TARGET_SSE && (<MODE>mode == TFmode)))
9860 && reload_completed"
9861 [(set (match_dup 0) (match_dup 3))]
9862 {
9863 machine_mode mode = <MODE>mode;
9864 machine_mode vmode = <ssevecmodef>mode;
9865
9866 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9867 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9868
9869 if (TARGET_AVX)
9870 {
9871 if (MEM_P (operands[1]))
9872 std::swap (operands[1], operands[2]);
9873 }
9874 else
9875 {
9876 if (operands_match_p (operands[0], operands[2]))
9877 std::swap (operands[1], operands[2]);
9878 }
9879
9880 operands[3]
9881 = gen_rtx_fmt_ee (IOR, vmode, operands[1], operands[2]);
9882 })
9883
9884 ;; Conditionalize these after reload. If they match before reload, we
9885 ;; lose the clobber and ability to use integer instructions.
9886
9887 (define_insn "*<code><mode>2_i387"
9888 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9889 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9890 "TARGET_80387 && reload_completed"
9891 "<absneg_mnemonic>"
9892 [(set_attr "type" "fsgn")
9893 (set_attr "mode" "<MODE>")])
9894
9895 ;; Copysign instructions
9896
9897 (define_expand "copysign<mode>3"
9898 [(match_operand:SSEMODEF 0 "register_operand")
9899 (match_operand:SSEMODEF 1 "nonmemory_operand")
9900 (match_operand:SSEMODEF 2 "register_operand")]
9901 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9902 || (TARGET_SSE && (<MODE>mode == TFmode))"
9903 "ix86_expand_copysign (operands); DONE;")
9904
9905 (define_insn_and_split "@copysign<mode>3_const"
9906 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv")
9907 (unspec:SSEMODEF
9908 [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC")
9909 (match_operand:SSEMODEF 2 "register_operand" "0")
9910 (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")]
9911 UNSPEC_COPYSIGN))]
9912 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9913 || (TARGET_SSE && (<MODE>mode == TFmode))"
9914 "#"
9915 "&& reload_completed"
9916 [(const_int 0)]
9917 "ix86_split_copysign_const (operands); DONE;")
9918
9919 (define_insn "@copysign<mode>3_var"
9920 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9921 (unspec:SSEMODEF
9922 [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv")
9923 (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv")
9924 (match_operand:<ssevecmodef> 4
9925 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9926 (match_operand:<ssevecmodef> 5
9927 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9928 UNSPEC_COPYSIGN))
9929 (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9930 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9931 || (TARGET_SSE && (<MODE>mode == TFmode))"
9932 "#")
9933
9934 (define_split
9935 [(set (match_operand:SSEMODEF 0 "register_operand")
9936 (unspec:SSEMODEF
9937 [(match_operand:SSEMODEF 2 "register_operand")
9938 (match_operand:SSEMODEF 3 "register_operand")
9939 (match_operand:<ssevecmodef> 4)
9940 (match_operand:<ssevecmodef> 5)]
9941 UNSPEC_COPYSIGN))
9942 (clobber (match_scratch:<ssevecmodef> 1))]
9943 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9944 || (TARGET_SSE && (<MODE>mode == TFmode)))
9945 && reload_completed"
9946 [(const_int 0)]
9947 "ix86_split_copysign_var (operands); DONE;")
9948
9949 (define_expand "xorsign<mode>3"
9950 [(match_operand:MODEF 0 "register_operand")
9951 (match_operand:MODEF 1 "register_operand")
9952 (match_operand:MODEF 2 "register_operand")]
9953 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9954 "ix86_expand_xorsign (operands); DONE;")
9955
9956 (define_insn_and_split "@xorsign<mode>3_1"
9957 [(set (match_operand:MODEF 0 "register_operand" "=Yv")
9958 (unspec:MODEF
9959 [(match_operand:MODEF 1 "register_operand" "Yv")
9960 (match_operand:MODEF 2 "register_operand" "0")
9961 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
9962 UNSPEC_XORSIGN))]
9963 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9964 "#"
9965 "&& reload_completed"
9966 [(const_int 0)]
9967 "ix86_split_xorsign (operands); DONE;")
9968 \f
9969 ;; One complement instructions
9970
9971 (define_expand "one_cmpl<mode>2"
9972 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9973 (not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
9974 ""
9975 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9976
9977 (define_insn_and_split "*one_cmpldi2_doubleword"
9978 [(set (match_operand:DI 0 "nonimmediate_operand")
9979 (not:DI (match_operand:DI 1 "nonimmediate_operand")))]
9980 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9981 && ix86_unary_operator_ok (NOT, DImode, operands)
9982 && ix86_pre_reload_split ()"
9983 "#"
9984 "&& 1"
9985 [(set (match_dup 0)
9986 (not:SI (match_dup 1)))
9987 (set (match_dup 2)
9988 (not:SI (match_dup 3)))]
9989 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9990
9991 (define_insn "*one_cmpl<mode>2_1"
9992 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9993 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9994 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9995 "not{<imodesuffix>}\t%0"
9996 [(set_attr "type" "negnot")
9997 (set_attr "mode" "<MODE>")])
9998
9999 (define_insn "*one_cmplsi2_1_zext"
10000 [(set (match_operand:DI 0 "register_operand" "=r")
10001 (zero_extend:DI
10002 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10003 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10004 "not{l}\t%k0"
10005 [(set_attr "type" "negnot")
10006 (set_attr "mode" "SI")])
10007
10008 (define_insn "*one_cmplqi2_1"
10009 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10010 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10011 "ix86_unary_operator_ok (NOT, QImode, operands)"
10012 "@
10013 not{b}\t%0
10014 not{l}\t%k0"
10015 [(set_attr "type" "negnot")
10016 (set_attr "mode" "QI,SI")
10017 ;; Potential partial reg stall on alternative 1.
10018 (set (attr "preferred_for_speed")
10019 (cond [(eq_attr "alternative" "1")
10020 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10021 (symbol_ref "true")))])
10022
10023 (define_insn "*one_cmpl<mode>2_2"
10024 [(set (reg FLAGS_REG)
10025 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10026 (const_int 0)))
10027 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10028 (not:SWI (match_dup 1)))]
10029 "ix86_match_ccmode (insn, CCNOmode)
10030 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10031 "#"
10032 [(set_attr "type" "alu1")
10033 (set_attr "mode" "<MODE>")])
10034
10035 (define_split
10036 [(set (match_operand 0 "flags_reg_operand")
10037 (match_operator 2 "compare_operator"
10038 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10039 (const_int 0)]))
10040 (set (match_operand:SWI 1 "nonimmediate_operand")
10041 (not:SWI (match_dup 3)))]
10042 "ix86_match_ccmode (insn, CCNOmode)"
10043 [(parallel [(set (match_dup 0)
10044 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10045 (const_int 0)]))
10046 (set (match_dup 1)
10047 (xor:SWI (match_dup 3) (const_int -1)))])])
10048
10049 (define_insn "*one_cmplsi2_2_zext"
10050 [(set (reg FLAGS_REG)
10051 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10052 (const_int 0)))
10053 (set (match_operand:DI 0 "register_operand" "=r")
10054 (zero_extend:DI (not:SI (match_dup 1))))]
10055 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10056 && ix86_unary_operator_ok (NOT, SImode, operands)"
10057 "#"
10058 [(set_attr "type" "alu1")
10059 (set_attr "mode" "SI")])
10060
10061 (define_split
10062 [(set (match_operand 0 "flags_reg_operand")
10063 (match_operator 2 "compare_operator"
10064 [(not:SI (match_operand:SI 3 "register_operand"))
10065 (const_int 0)]))
10066 (set (match_operand:DI 1 "register_operand")
10067 (zero_extend:DI (not:SI (match_dup 3))))]
10068 "ix86_match_ccmode (insn, CCNOmode)"
10069 [(parallel [(set (match_dup 0)
10070 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10071 (const_int 0)]))
10072 (set (match_dup 1)
10073 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10074 \f
10075 ;; Shift instructions
10076
10077 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10078 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10079 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10080 ;; from the assembler input.
10081 ;;
10082 ;; This instruction shifts the target reg/mem as usual, but instead of
10083 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10084 ;; is a left shift double, bits are taken from the high order bits of
10085 ;; reg, else if the insn is a shift right double, bits are taken from the
10086 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10087 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10088 ;;
10089 ;; Since sh[lr]d does not change the `reg' operand, that is done
10090 ;; separately, making all shifts emit pairs of shift double and normal
10091 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10092 ;; support a 63 bit shift, each shift where the count is in a reg expands
10093 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10094 ;;
10095 ;; If the shift count is a constant, we need never emit more than one
10096 ;; shift pair, instead using moves and sign extension for counts greater
10097 ;; than 31.
10098
10099 (define_expand "ashl<mode>3"
10100 [(set (match_operand:SDWIM 0 "<shift_operand>")
10101 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10102 (match_operand:QI 2 "nonmemory_operand")))]
10103 ""
10104 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10105
10106 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10107 [(set (match_operand:<DWI> 0 "register_operand")
10108 (ashift:<DWI>
10109 (match_operand:<DWI> 1 "register_operand")
10110 (subreg:QI
10111 (and:SI
10112 (match_operand:SI 2 "register_operand" "c")
10113 (match_operand:SI 3 "const_int_operand")) 0)))
10114 (clobber (reg:CC FLAGS_REG))]
10115 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10116 && ix86_pre_reload_split ()"
10117 "#"
10118 "&& 1"
10119 [(parallel
10120 [(set (match_dup 6)
10121 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10122 (lshiftrt:DWIH (match_dup 5)
10123 (minus:QI (match_dup 8) (match_dup 2)))))
10124 (clobber (reg:CC FLAGS_REG))])
10125 (parallel
10126 [(set (match_dup 4)
10127 (ashift:DWIH (match_dup 5) (match_dup 2)))
10128 (clobber (reg:CC FLAGS_REG))])]
10129 {
10130 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10131
10132 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10133
10134 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10135 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10136 {
10137 rtx tem = gen_reg_rtx (SImode);
10138 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10139 operands[2] = tem;
10140 }
10141
10142 operands[2] = gen_lowpart (QImode, operands[2]);
10143
10144 if (!rtx_equal_p (operands[6], operands[7]))
10145 emit_move_insn (operands[6], operands[7]);
10146 })
10147
10148 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10149 [(set (match_operand:<DWI> 0 "register_operand")
10150 (ashift:<DWI>
10151 (match_operand:<DWI> 1 "register_operand")
10152 (and:QI
10153 (match_operand:QI 2 "register_operand" "c")
10154 (match_operand:QI 3 "const_int_operand"))))
10155 (clobber (reg:CC FLAGS_REG))]
10156 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10157 && ix86_pre_reload_split ()"
10158 "#"
10159 "&& 1"
10160 [(parallel
10161 [(set (match_dup 6)
10162 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10163 (lshiftrt:DWIH (match_dup 5)
10164 (minus:QI (match_dup 8) (match_dup 2)))))
10165 (clobber (reg:CC FLAGS_REG))])
10166 (parallel
10167 [(set (match_dup 4)
10168 (ashift:DWIH (match_dup 5) (match_dup 2)))
10169 (clobber (reg:CC FLAGS_REG))])]
10170 {
10171 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10172
10173 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10174
10175 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10176 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10177 {
10178 rtx tem = gen_reg_rtx (QImode);
10179 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10180 operands[2] = tem;
10181 }
10182
10183 if (!rtx_equal_p (operands[6], operands[7]))
10184 emit_move_insn (operands[6], operands[7]);
10185 })
10186
10187 (define_insn "*ashl<mode>3_doubleword"
10188 [(set (match_operand:DWI 0 "register_operand" "=&r")
10189 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10190 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10191 (clobber (reg:CC FLAGS_REG))]
10192 ""
10193 "#"
10194 [(set_attr "type" "multi")])
10195
10196 (define_split
10197 [(set (match_operand:DWI 0 "register_operand")
10198 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10199 (match_operand:QI 2 "nonmemory_operand")))
10200 (clobber (reg:CC FLAGS_REG))]
10201 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10202 [(const_int 0)]
10203 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10204
10205 ;; By default we don't ask for a scratch register, because when DWImode
10206 ;; values are manipulated, registers are already at a premium. But if
10207 ;; we have one handy, we won't turn it away.
10208
10209 (define_peephole2
10210 [(match_scratch:DWIH 3 "r")
10211 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10212 (ashift:<DWI>
10213 (match_operand:<DWI> 1 "nonmemory_operand")
10214 (match_operand:QI 2 "nonmemory_operand")))
10215 (clobber (reg:CC FLAGS_REG))])
10216 (match_dup 3)]
10217 "TARGET_CMOVE"
10218 [(const_int 0)]
10219 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10220
10221 (define_insn "x86_64_shld"
10222 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10223 (ior:DI (ashift:DI (match_dup 0)
10224 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10225 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10226 (minus:QI (const_int 64) (match_dup 2)))))
10227 (clobber (reg:CC FLAGS_REG))]
10228 "TARGET_64BIT"
10229 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10230 [(set_attr "type" "ishift")
10231 (set_attr "prefix_0f" "1")
10232 (set_attr "mode" "DI")
10233 (set_attr "athlon_decode" "vector")
10234 (set_attr "amdfam10_decode" "vector")
10235 (set_attr "bdver1_decode" "vector")])
10236
10237 (define_insn "x86_shld"
10238 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10239 (ior:SI (ashift:SI (match_dup 0)
10240 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10241 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10242 (minus:QI (const_int 32) (match_dup 2)))))
10243 (clobber (reg:CC FLAGS_REG))]
10244 ""
10245 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10246 [(set_attr "type" "ishift")
10247 (set_attr "prefix_0f" "1")
10248 (set_attr "mode" "SI")
10249 (set_attr "pent_pair" "np")
10250 (set_attr "athlon_decode" "vector")
10251 (set_attr "amdfam10_decode" "vector")
10252 (set_attr "bdver1_decode" "vector")])
10253
10254 (define_expand "@x86_shift<mode>_adj_1"
10255 [(set (reg:CCZ FLAGS_REG)
10256 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10257 (match_dup 4))
10258 (const_int 0)))
10259 (set (match_operand:SWI48 0 "register_operand")
10260 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10261 (match_operand:SWI48 1 "register_operand")
10262 (match_dup 0)))
10263 (set (match_dup 1)
10264 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10265 (match_operand:SWI48 3 "register_operand")
10266 (match_dup 1)))]
10267 "TARGET_CMOVE"
10268 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10269
10270 (define_expand "@x86_shift<mode>_adj_2"
10271 [(use (match_operand:SWI48 0 "register_operand"))
10272 (use (match_operand:SWI48 1 "register_operand"))
10273 (use (match_operand:QI 2 "register_operand"))]
10274 ""
10275 {
10276 rtx_code_label *label = gen_label_rtx ();
10277 rtx tmp;
10278
10279 emit_insn (gen_testqi_ccz_1 (operands[2],
10280 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10281
10282 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10283 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10284 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10285 gen_rtx_LABEL_REF (VOIDmode, label),
10286 pc_rtx);
10287 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10288 JUMP_LABEL (tmp) = label;
10289
10290 emit_move_insn (operands[0], operands[1]);
10291 ix86_expand_clear (operands[1]);
10292
10293 emit_label (label);
10294 LABEL_NUSES (label) = 1;
10295
10296 DONE;
10297 })
10298
10299 ;; Avoid useless masking of count operand.
10300 (define_insn_and_split "*ashl<mode>3_mask"
10301 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10302 (ashift:SWI48
10303 (match_operand:SWI48 1 "nonimmediate_operand")
10304 (subreg:QI
10305 (and:SI
10306 (match_operand:SI 2 "register_operand" "c,r")
10307 (match_operand:SI 3 "const_int_operand")) 0)))
10308 (clobber (reg:CC FLAGS_REG))]
10309 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10310 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10311 == GET_MODE_BITSIZE (<MODE>mode)-1
10312 && ix86_pre_reload_split ()"
10313 "#"
10314 "&& 1"
10315 [(parallel
10316 [(set (match_dup 0)
10317 (ashift:SWI48 (match_dup 1)
10318 (match_dup 2)))
10319 (clobber (reg:CC FLAGS_REG))])]
10320 "operands[2] = gen_lowpart (QImode, operands[2]);"
10321 [(set_attr "isa" "*,bmi2")])
10322
10323 (define_insn_and_split "*ashl<mode>3_mask_1"
10324 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10325 (ashift:SWI48
10326 (match_operand:SWI48 1 "nonimmediate_operand")
10327 (and:QI
10328 (match_operand:QI 2 "register_operand" "c,r")
10329 (match_operand:QI 3 "const_int_operand"))))
10330 (clobber (reg:CC FLAGS_REG))]
10331 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10332 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10333 == GET_MODE_BITSIZE (<MODE>mode)-1
10334 && ix86_pre_reload_split ()"
10335 "#"
10336 "&& 1"
10337 [(parallel
10338 [(set (match_dup 0)
10339 (ashift:SWI48 (match_dup 1)
10340 (match_dup 2)))
10341 (clobber (reg:CC FLAGS_REG))])]
10342 ""
10343 [(set_attr "isa" "*,bmi2")])
10344
10345 (define_insn "*bmi2_ashl<mode>3_1"
10346 [(set (match_operand:SWI48 0 "register_operand" "=r")
10347 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10348 (match_operand:SWI48 2 "register_operand" "r")))]
10349 "TARGET_BMI2"
10350 "shlx\t{%2, %1, %0|%0, %1, %2}"
10351 [(set_attr "type" "ishiftx")
10352 (set_attr "mode" "<MODE>")])
10353
10354 (define_insn "*ashl<mode>3_1"
10355 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10356 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10357 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10358 (clobber (reg:CC FLAGS_REG))]
10359 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10360 {
10361 switch (get_attr_type (insn))
10362 {
10363 case TYPE_LEA:
10364 case TYPE_ISHIFTX:
10365 return "#";
10366
10367 case TYPE_ALU:
10368 gcc_assert (operands[2] == const1_rtx);
10369 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10370 return "add{<imodesuffix>}\t%0, %0";
10371
10372 default:
10373 if (operands[2] == const1_rtx
10374 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10375 return "sal{<imodesuffix>}\t%0";
10376 else
10377 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10378 }
10379 }
10380 [(set_attr "isa" "*,*,bmi2")
10381 (set (attr "type")
10382 (cond [(eq_attr "alternative" "1")
10383 (const_string "lea")
10384 (eq_attr "alternative" "2")
10385 (const_string "ishiftx")
10386 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10387 (match_operand 0 "register_operand"))
10388 (match_operand 2 "const1_operand"))
10389 (const_string "alu")
10390 ]
10391 (const_string "ishift")))
10392 (set (attr "length_immediate")
10393 (if_then_else
10394 (ior (eq_attr "type" "alu")
10395 (and (eq_attr "type" "ishift")
10396 (and (match_operand 2 "const1_operand")
10397 (ior (match_test "TARGET_SHIFT1")
10398 (match_test "optimize_function_for_size_p (cfun)")))))
10399 (const_string "0")
10400 (const_string "*")))
10401 (set_attr "mode" "<MODE>")])
10402
10403 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10404 (define_split
10405 [(set (match_operand:SWI48 0 "register_operand")
10406 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10407 (match_operand:QI 2 "register_operand")))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "TARGET_BMI2 && reload_completed"
10410 [(set (match_dup 0)
10411 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10412 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10413
10414 (define_insn "*bmi2_ashlsi3_1_zext"
10415 [(set (match_operand:DI 0 "register_operand" "=r")
10416 (zero_extend:DI
10417 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10418 (match_operand:SI 2 "register_operand" "r"))))]
10419 "TARGET_64BIT && TARGET_BMI2"
10420 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10421 [(set_attr "type" "ishiftx")
10422 (set_attr "mode" "SI")])
10423
10424 (define_insn "*ashlsi3_1_zext"
10425 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10426 (zero_extend:DI
10427 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10428 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10429 (clobber (reg:CC FLAGS_REG))]
10430 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10431 {
10432 switch (get_attr_type (insn))
10433 {
10434 case TYPE_LEA:
10435 case TYPE_ISHIFTX:
10436 return "#";
10437
10438 case TYPE_ALU:
10439 gcc_assert (operands[2] == const1_rtx);
10440 return "add{l}\t%k0, %k0";
10441
10442 default:
10443 if (operands[2] == const1_rtx
10444 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10445 return "sal{l}\t%k0";
10446 else
10447 return "sal{l}\t{%2, %k0|%k0, %2}";
10448 }
10449 }
10450 [(set_attr "isa" "*,*,bmi2")
10451 (set (attr "type")
10452 (cond [(eq_attr "alternative" "1")
10453 (const_string "lea")
10454 (eq_attr "alternative" "2")
10455 (const_string "ishiftx")
10456 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10457 (match_operand 2 "const1_operand"))
10458 (const_string "alu")
10459 ]
10460 (const_string "ishift")))
10461 (set (attr "length_immediate")
10462 (if_then_else
10463 (ior (eq_attr "type" "alu")
10464 (and (eq_attr "type" "ishift")
10465 (and (match_operand 2 "const1_operand")
10466 (ior (match_test "TARGET_SHIFT1")
10467 (match_test "optimize_function_for_size_p (cfun)")))))
10468 (const_string "0")
10469 (const_string "*")))
10470 (set_attr "mode" "SI")])
10471
10472 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10473 (define_split
10474 [(set (match_operand:DI 0 "register_operand")
10475 (zero_extend:DI
10476 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10477 (match_operand:QI 2 "register_operand"))))
10478 (clobber (reg:CC FLAGS_REG))]
10479 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10480 [(set (match_dup 0)
10481 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10482 "operands[2] = gen_lowpart (SImode, operands[2]);")
10483
10484 (define_insn "*ashlhi3_1"
10485 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10486 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10487 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10488 (clobber (reg:CC FLAGS_REG))]
10489 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10490 {
10491 switch (get_attr_type (insn))
10492 {
10493 case TYPE_LEA:
10494 return "#";
10495
10496 case TYPE_ALU:
10497 gcc_assert (operands[2] == const1_rtx);
10498 return "add{w}\t%0, %0";
10499
10500 default:
10501 if (operands[2] == const1_rtx
10502 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10503 return "sal{w}\t%0";
10504 else
10505 return "sal{w}\t{%2, %0|%0, %2}";
10506 }
10507 }
10508 [(set (attr "type")
10509 (cond [(eq_attr "alternative" "1")
10510 (const_string "lea")
10511 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10512 (match_operand 0 "register_operand"))
10513 (match_operand 2 "const1_operand"))
10514 (const_string "alu")
10515 ]
10516 (const_string "ishift")))
10517 (set (attr "length_immediate")
10518 (if_then_else
10519 (ior (eq_attr "type" "alu")
10520 (and (eq_attr "type" "ishift")
10521 (and (match_operand 2 "const1_operand")
10522 (ior (match_test "TARGET_SHIFT1")
10523 (match_test "optimize_function_for_size_p (cfun)")))))
10524 (const_string "0")
10525 (const_string "*")))
10526 (set_attr "mode" "HI,SI")])
10527
10528 (define_insn "*ashlqi3_1"
10529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10530 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10531 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10532 (clobber (reg:CC FLAGS_REG))]
10533 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10534 {
10535 switch (get_attr_type (insn))
10536 {
10537 case TYPE_LEA:
10538 return "#";
10539
10540 case TYPE_ALU:
10541 gcc_assert (operands[2] == const1_rtx);
10542 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10543 return "add{l}\t%k0, %k0";
10544 else
10545 return "add{b}\t%0, %0";
10546
10547 default:
10548 if (operands[2] == const1_rtx
10549 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10550 {
10551 if (get_attr_mode (insn) == MODE_SI)
10552 return "sal{l}\t%k0";
10553 else
10554 return "sal{b}\t%0";
10555 }
10556 else
10557 {
10558 if (get_attr_mode (insn) == MODE_SI)
10559 return "sal{l}\t{%2, %k0|%k0, %2}";
10560 else
10561 return "sal{b}\t{%2, %0|%0, %2}";
10562 }
10563 }
10564 }
10565 [(set (attr "type")
10566 (cond [(eq_attr "alternative" "2")
10567 (const_string "lea")
10568 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10569 (match_operand 0 "register_operand"))
10570 (match_operand 2 "const1_operand"))
10571 (const_string "alu")
10572 ]
10573 (const_string "ishift")))
10574 (set (attr "length_immediate")
10575 (if_then_else
10576 (ior (eq_attr "type" "alu")
10577 (and (eq_attr "type" "ishift")
10578 (and (match_operand 2 "const1_operand")
10579 (ior (match_test "TARGET_SHIFT1")
10580 (match_test "optimize_function_for_size_p (cfun)")))))
10581 (const_string "0")
10582 (const_string "*")))
10583 (set_attr "mode" "QI,SI,SI")
10584 ;; Potential partial reg stall on alternative 1.
10585 (set (attr "preferred_for_speed")
10586 (cond [(eq_attr "alternative" "1")
10587 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10588 (symbol_ref "true")))])
10589
10590 (define_insn "*ashl<mode>3_1_slp"
10591 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
10592 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0")
10593 (match_operand:QI 2 "nonmemory_operand" "cI")))
10594 (clobber (reg:CC FLAGS_REG))]
10595 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10596 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
10597 && rtx_equal_p (operands[0], operands[1])"
10598 {
10599 switch (get_attr_type (insn))
10600 {
10601 case TYPE_ALU:
10602 gcc_assert (operands[2] == const1_rtx);
10603 return "add{<imodesuffix>}\t%0, %0";
10604
10605 default:
10606 if (operands[2] == const1_rtx
10607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10608 return "sal{<imodesuffix>}\t%0";
10609 else
10610 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10611 }
10612 }
10613 [(set (attr "type")
10614 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10615 (match_operand 2 "const1_operand"))
10616 (const_string "alu")
10617 ]
10618 (const_string "ishift")))
10619 (set (attr "length_immediate")
10620 (if_then_else
10621 (ior (eq_attr "type" "alu")
10622 (and (eq_attr "type" "ishift")
10623 (and (match_operand 2 "const1_operand")
10624 (ior (match_test "TARGET_SHIFT1")
10625 (match_test "optimize_function_for_size_p (cfun)")))))
10626 (const_string "0")
10627 (const_string "*")))
10628 (set_attr "mode" "<MODE>")])
10629
10630 ;; Convert ashift to the lea pattern to avoid flags dependency.
10631 (define_split
10632 [(set (match_operand:SWI 0 "register_operand")
10633 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10634 (match_operand 2 "const_0_to_3_operand")))
10635 (clobber (reg:CC FLAGS_REG))]
10636 "reload_completed
10637 && REGNO (operands[0]) != REGNO (operands[1])"
10638 [(set (match_dup 0)
10639 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10640 {
10641 if (<MODE>mode != <LEAMODE>mode)
10642 {
10643 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10644 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10645 }
10646 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10647 })
10648
10649 ;; Convert ashift to the lea pattern to avoid flags dependency.
10650 (define_split
10651 [(set (match_operand:DI 0 "register_operand")
10652 (zero_extend:DI
10653 (ashift:SI (match_operand:SI 1 "index_register_operand")
10654 (match_operand 2 "const_0_to_3_operand"))))
10655 (clobber (reg:CC FLAGS_REG))]
10656 "TARGET_64BIT && reload_completed
10657 && REGNO (operands[0]) != REGNO (operands[1])"
10658 [(set (match_dup 0)
10659 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10660 {
10661 operands[1] = gen_lowpart (SImode, operands[1]);
10662 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10663 })
10664
10665 ;; This pattern can't accept a variable shift count, since shifts by
10666 ;; zero don't affect the flags. We assume that shifts by constant
10667 ;; zero are optimized away.
10668 (define_insn "*ashl<mode>3_cmp"
10669 [(set (reg FLAGS_REG)
10670 (compare
10671 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10672 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10673 (const_int 0)))
10674 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10675 (ashift:SWI (match_dup 1) (match_dup 2)))]
10676 "(optimize_function_for_size_p (cfun)
10677 || !TARGET_PARTIAL_FLAG_REG_STALL
10678 || (operands[2] == const1_rtx
10679 && (TARGET_SHIFT1
10680 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10681 && ix86_match_ccmode (insn, CCGOCmode)
10682 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10683 {
10684 switch (get_attr_type (insn))
10685 {
10686 case TYPE_ALU:
10687 gcc_assert (operands[2] == const1_rtx);
10688 return "add{<imodesuffix>}\t%0, %0";
10689
10690 default:
10691 if (operands[2] == const1_rtx
10692 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10693 return "sal{<imodesuffix>}\t%0";
10694 else
10695 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10696 }
10697 }
10698 [(set (attr "type")
10699 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10700 (match_operand 0 "register_operand"))
10701 (match_operand 2 "const1_operand"))
10702 (const_string "alu")
10703 ]
10704 (const_string "ishift")))
10705 (set (attr "length_immediate")
10706 (if_then_else
10707 (ior (eq_attr "type" "alu")
10708 (and (eq_attr "type" "ishift")
10709 (and (match_operand 2 "const1_operand")
10710 (ior (match_test "TARGET_SHIFT1")
10711 (match_test "optimize_function_for_size_p (cfun)")))))
10712 (const_string "0")
10713 (const_string "*")))
10714 (set_attr "mode" "<MODE>")])
10715
10716 (define_insn "*ashlsi3_cmp_zext"
10717 [(set (reg FLAGS_REG)
10718 (compare
10719 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10720 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10721 (const_int 0)))
10722 (set (match_operand:DI 0 "register_operand" "=r")
10723 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10724 "TARGET_64BIT
10725 && (optimize_function_for_size_p (cfun)
10726 || !TARGET_PARTIAL_FLAG_REG_STALL
10727 || (operands[2] == const1_rtx
10728 && (TARGET_SHIFT1
10729 || TARGET_DOUBLE_WITH_ADD)))
10730 && ix86_match_ccmode (insn, CCGOCmode)
10731 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10732 {
10733 switch (get_attr_type (insn))
10734 {
10735 case TYPE_ALU:
10736 gcc_assert (operands[2] == const1_rtx);
10737 return "add{l}\t%k0, %k0";
10738
10739 default:
10740 if (operands[2] == const1_rtx
10741 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10742 return "sal{l}\t%k0";
10743 else
10744 return "sal{l}\t{%2, %k0|%k0, %2}";
10745 }
10746 }
10747 [(set (attr "type")
10748 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10749 (match_operand 2 "const1_operand"))
10750 (const_string "alu")
10751 ]
10752 (const_string "ishift")))
10753 (set (attr "length_immediate")
10754 (if_then_else
10755 (ior (eq_attr "type" "alu")
10756 (and (eq_attr "type" "ishift")
10757 (and (match_operand 2 "const1_operand")
10758 (ior (match_test "TARGET_SHIFT1")
10759 (match_test "optimize_function_for_size_p (cfun)")))))
10760 (const_string "0")
10761 (const_string "*")))
10762 (set_attr "mode" "SI")])
10763
10764 (define_insn "*ashl<mode>3_cconly"
10765 [(set (reg FLAGS_REG)
10766 (compare
10767 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10768 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10769 (const_int 0)))
10770 (clobber (match_scratch:SWI 0 "=<r>"))]
10771 "(optimize_function_for_size_p (cfun)
10772 || !TARGET_PARTIAL_FLAG_REG_STALL
10773 || (operands[2] == const1_rtx
10774 && (TARGET_SHIFT1
10775 || TARGET_DOUBLE_WITH_ADD)))
10776 && ix86_match_ccmode (insn, CCGOCmode)"
10777 {
10778 switch (get_attr_type (insn))
10779 {
10780 case TYPE_ALU:
10781 gcc_assert (operands[2] == const1_rtx);
10782 return "add{<imodesuffix>}\t%0, %0";
10783
10784 default:
10785 if (operands[2] == const1_rtx
10786 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10787 return "sal{<imodesuffix>}\t%0";
10788 else
10789 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10790 }
10791 }
10792 [(set (attr "type")
10793 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10794 (match_operand 0 "register_operand"))
10795 (match_operand 2 "const1_operand"))
10796 (const_string "alu")
10797 ]
10798 (const_string "ishift")))
10799 (set (attr "length_immediate")
10800 (if_then_else
10801 (ior (eq_attr "type" "alu")
10802 (and (eq_attr "type" "ishift")
10803 (and (match_operand 2 "const1_operand")
10804 (ior (match_test "TARGET_SHIFT1")
10805 (match_test "optimize_function_for_size_p (cfun)")))))
10806 (const_string "0")
10807 (const_string "*")))
10808 (set_attr "mode" "<MODE>")])
10809
10810 ;; See comment above `ashl<mode>3' about how this works.
10811
10812 (define_expand "<shift_insn><mode>3"
10813 [(set (match_operand:SDWIM 0 "<shift_operand>")
10814 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10815 (match_operand:QI 2 "nonmemory_operand")))]
10816 ""
10817 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10818
10819 ;; Avoid useless masking of count operand.
10820 (define_insn_and_split "*<shift_insn><mode>3_mask"
10821 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10822 (any_shiftrt:SWI48
10823 (match_operand:SWI48 1 "nonimmediate_operand")
10824 (subreg:QI
10825 (and:SI
10826 (match_operand:SI 2 "register_operand" "c,r")
10827 (match_operand:SI 3 "const_int_operand")) 0)))
10828 (clobber (reg:CC FLAGS_REG))]
10829 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10830 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10831 == GET_MODE_BITSIZE (<MODE>mode)-1
10832 && ix86_pre_reload_split ()"
10833 "#"
10834 "&& 1"
10835 [(parallel
10836 [(set (match_dup 0)
10837 (any_shiftrt:SWI48 (match_dup 1)
10838 (match_dup 2)))
10839 (clobber (reg:CC FLAGS_REG))])]
10840 "operands[2] = gen_lowpart (QImode, operands[2]);"
10841 [(set_attr "isa" "*,bmi2")])
10842
10843 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10844 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10845 (any_shiftrt:SWI48
10846 (match_operand:SWI48 1 "nonimmediate_operand")
10847 (and:QI
10848 (match_operand:QI 2 "register_operand" "c,r")
10849 (match_operand:QI 3 "const_int_operand"))))
10850 (clobber (reg:CC FLAGS_REG))]
10851 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10852 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10853 == GET_MODE_BITSIZE (<MODE>mode)-1
10854 && ix86_pre_reload_split ()"
10855 "#"
10856 "&& 1"
10857 [(parallel
10858 [(set (match_dup 0)
10859 (any_shiftrt:SWI48 (match_dup 1)
10860 (match_dup 2)))
10861 (clobber (reg:CC FLAGS_REG))])]
10862 ""
10863 [(set_attr "isa" "*,bmi2")])
10864
10865 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
10866 [(set (match_operand:<DWI> 0 "register_operand")
10867 (any_shiftrt:<DWI>
10868 (match_operand:<DWI> 1 "register_operand")
10869 (subreg:QI
10870 (and:SI
10871 (match_operand:SI 2 "register_operand" "c")
10872 (match_operand:SI 3 "const_int_operand")) 0)))
10873 (clobber (reg:CC FLAGS_REG))]
10874 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10875 && ix86_pre_reload_split ()"
10876 "#"
10877 "&& 1"
10878 [(parallel
10879 [(set (match_dup 4)
10880 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10881 (ashift:DWIH (match_dup 7)
10882 (minus:QI (match_dup 8) (match_dup 2)))))
10883 (clobber (reg:CC FLAGS_REG))])
10884 (parallel
10885 [(set (match_dup 6)
10886 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10887 (clobber (reg:CC FLAGS_REG))])]
10888 {
10889 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10890
10891 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10892
10893 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10894 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10895 {
10896 rtx tem = gen_reg_rtx (SImode);
10897 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10898 operands[2] = tem;
10899 }
10900
10901 operands[2] = gen_lowpart (QImode, operands[2]);
10902
10903 if (!rtx_equal_p (operands[4], operands[5]))
10904 emit_move_insn (operands[4], operands[5]);
10905 })
10906
10907 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
10908 [(set (match_operand:<DWI> 0 "register_operand")
10909 (any_shiftrt:<DWI>
10910 (match_operand:<DWI> 1 "register_operand")
10911 (and:QI
10912 (match_operand:QI 2 "register_operand" "c")
10913 (match_operand:QI 3 "const_int_operand"))))
10914 (clobber (reg:CC FLAGS_REG))]
10915 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10916 && ix86_pre_reload_split ()"
10917 "#"
10918 "&& 1"
10919 [(parallel
10920 [(set (match_dup 4)
10921 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10922 (ashift:DWIH (match_dup 7)
10923 (minus:QI (match_dup 8) (match_dup 2)))))
10924 (clobber (reg:CC FLAGS_REG))])
10925 (parallel
10926 [(set (match_dup 6)
10927 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10928 (clobber (reg:CC FLAGS_REG))])]
10929 {
10930 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10931
10932 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10933
10934 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10935 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10936 {
10937 rtx tem = gen_reg_rtx (QImode);
10938 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10939 operands[2] = tem;
10940 }
10941
10942 if (!rtx_equal_p (operands[4], operands[5]))
10943 emit_move_insn (operands[4], operands[5]);
10944 })
10945
10946 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10947 [(set (match_operand:DWI 0 "register_operand" "=&r")
10948 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10949 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10950 (clobber (reg:CC FLAGS_REG))]
10951 ""
10952 "#"
10953 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10954 [(const_int 0)]
10955 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10956 [(set_attr "type" "multi")])
10957
10958 ;; By default we don't ask for a scratch register, because when DWImode
10959 ;; values are manipulated, registers are already at a premium. But if
10960 ;; we have one handy, we won't turn it away.
10961
10962 (define_peephole2
10963 [(match_scratch:DWIH 3 "r")
10964 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10965 (any_shiftrt:<DWI>
10966 (match_operand:<DWI> 1 "register_operand")
10967 (match_operand:QI 2 "nonmemory_operand")))
10968 (clobber (reg:CC FLAGS_REG))])
10969 (match_dup 3)]
10970 "TARGET_CMOVE"
10971 [(const_int 0)]
10972 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10973
10974 (define_insn "x86_64_shrd"
10975 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10976 (ior:DI (lshiftrt:DI (match_dup 0)
10977 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10978 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10979 (minus:QI (const_int 64) (match_dup 2)))))
10980 (clobber (reg:CC FLAGS_REG))]
10981 "TARGET_64BIT"
10982 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10983 [(set_attr "type" "ishift")
10984 (set_attr "prefix_0f" "1")
10985 (set_attr "mode" "DI")
10986 (set_attr "athlon_decode" "vector")
10987 (set_attr "amdfam10_decode" "vector")
10988 (set_attr "bdver1_decode" "vector")])
10989
10990 (define_insn "x86_shrd"
10991 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10992 (ior:SI (lshiftrt:SI (match_dup 0)
10993 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10994 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10995 (minus:QI (const_int 32) (match_dup 2)))))
10996 (clobber (reg:CC FLAGS_REG))]
10997 ""
10998 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10999 [(set_attr "type" "ishift")
11000 (set_attr "prefix_0f" "1")
11001 (set_attr "mode" "SI")
11002 (set_attr "pent_pair" "np")
11003 (set_attr "athlon_decode" "vector")
11004 (set_attr "amdfam10_decode" "vector")
11005 (set_attr "bdver1_decode" "vector")])
11006
11007 ;; Base name for insn mnemonic.
11008 (define_mode_attr cvt_mnemonic
11009 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
11010
11011 (define_insn "ashr<mode>3_cvt"
11012 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
11013 (ashiftrt:SWI48
11014 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
11015 (match_operand:QI 2 "const_int_operand")))
11016 (clobber (reg:CC FLAGS_REG))]
11017 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
11018 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11019 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
11020 "@
11021 <cvt_mnemonic>
11022 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
11023 [(set_attr "type" "imovx,ishift")
11024 (set_attr "prefix_0f" "0,*")
11025 (set_attr "length_immediate" "0,*")
11026 (set_attr "modrm" "0,1")
11027 (set_attr "mode" "<MODE>")])
11028
11029 (define_insn "*ashrsi3_cvt_zext"
11030 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11031 (zero_extend:DI
11032 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11033 (match_operand:QI 2 "const_int_operand"))))
11034 (clobber (reg:CC FLAGS_REG))]
11035 "TARGET_64BIT && INTVAL (operands[2]) == 31
11036 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11037 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11038 "@
11039 {cltd|cdq}
11040 sar{l}\t{%2, %k0|%k0, %2}"
11041 [(set_attr "type" "imovx,ishift")
11042 (set_attr "prefix_0f" "0,*")
11043 (set_attr "length_immediate" "0,*")
11044 (set_attr "modrm" "0,1")
11045 (set_attr "mode" "SI")])
11046
11047 (define_expand "@x86_shift<mode>_adj_3"
11048 [(use (match_operand:SWI48 0 "register_operand"))
11049 (use (match_operand:SWI48 1 "register_operand"))
11050 (use (match_operand:QI 2 "register_operand"))]
11051 ""
11052 {
11053 rtx_code_label *label = gen_label_rtx ();
11054 rtx tmp;
11055
11056 emit_insn (gen_testqi_ccz_1 (operands[2],
11057 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11058
11059 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11060 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11061 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11062 gen_rtx_LABEL_REF (VOIDmode, label),
11063 pc_rtx);
11064 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11065 JUMP_LABEL (tmp) = label;
11066
11067 emit_move_insn (operands[0], operands[1]);
11068 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11069 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11070 emit_label (label);
11071 LABEL_NUSES (label) = 1;
11072
11073 DONE;
11074 })
11075
11076 (define_insn "*bmi2_<shift_insn><mode>3_1"
11077 [(set (match_operand:SWI48 0 "register_operand" "=r")
11078 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11079 (match_operand:SWI48 2 "register_operand" "r")))]
11080 "TARGET_BMI2"
11081 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11082 [(set_attr "type" "ishiftx")
11083 (set_attr "mode" "<MODE>")])
11084
11085 (define_insn "*<shift_insn><mode>3_1"
11086 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11087 (any_shiftrt:SWI48
11088 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11089 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11090 (clobber (reg:CC FLAGS_REG))]
11091 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11092 {
11093 switch (get_attr_type (insn))
11094 {
11095 case TYPE_ISHIFTX:
11096 return "#";
11097
11098 default:
11099 if (operands[2] == const1_rtx
11100 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11101 return "<shift>{<imodesuffix>}\t%0";
11102 else
11103 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11104 }
11105 }
11106 [(set_attr "isa" "*,bmi2")
11107 (set_attr "type" "ishift,ishiftx")
11108 (set (attr "length_immediate")
11109 (if_then_else
11110 (and (match_operand 2 "const1_operand")
11111 (ior (match_test "TARGET_SHIFT1")
11112 (match_test "optimize_function_for_size_p (cfun)")))
11113 (const_string "0")
11114 (const_string "*")))
11115 (set_attr "mode" "<MODE>")])
11116
11117 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11118 (define_split
11119 [(set (match_operand:SWI48 0 "register_operand")
11120 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11121 (match_operand:QI 2 "register_operand")))
11122 (clobber (reg:CC FLAGS_REG))]
11123 "TARGET_BMI2 && reload_completed"
11124 [(set (match_dup 0)
11125 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11126 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11127
11128 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11129 [(set (match_operand:DI 0 "register_operand" "=r")
11130 (zero_extend:DI
11131 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11132 (match_operand:SI 2 "register_operand" "r"))))]
11133 "TARGET_64BIT && TARGET_BMI2"
11134 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11135 [(set_attr "type" "ishiftx")
11136 (set_attr "mode" "SI")])
11137
11138 (define_insn "*<shift_insn>si3_1_zext"
11139 [(set (match_operand:DI 0 "register_operand" "=r,r")
11140 (zero_extend:DI
11141 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11142 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11143 (clobber (reg:CC FLAGS_REG))]
11144 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11145 {
11146 switch (get_attr_type (insn))
11147 {
11148 case TYPE_ISHIFTX:
11149 return "#";
11150
11151 default:
11152 if (operands[2] == const1_rtx
11153 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11154 return "<shift>{l}\t%k0";
11155 else
11156 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11157 }
11158 }
11159 [(set_attr "isa" "*,bmi2")
11160 (set_attr "type" "ishift,ishiftx")
11161 (set (attr "length_immediate")
11162 (if_then_else
11163 (and (match_operand 2 "const1_operand")
11164 (ior (match_test "TARGET_SHIFT1")
11165 (match_test "optimize_function_for_size_p (cfun)")))
11166 (const_string "0")
11167 (const_string "*")))
11168 (set_attr "mode" "SI")])
11169
11170 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11171 (define_split
11172 [(set (match_operand:DI 0 "register_operand")
11173 (zero_extend:DI
11174 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11175 (match_operand:QI 2 "register_operand"))))
11176 (clobber (reg:CC FLAGS_REG))]
11177 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11178 [(set (match_dup 0)
11179 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11180 "operands[2] = gen_lowpart (SImode, operands[2]);")
11181
11182 (define_insn "*<shift_insn><mode>3_1"
11183 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11184 (any_shiftrt:SWI12
11185 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11186 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11187 (clobber (reg:CC FLAGS_REG))]
11188 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11189 {
11190 if (operands[2] == const1_rtx
11191 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11192 return "<shift>{<imodesuffix>}\t%0";
11193 else
11194 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11195 }
11196 [(set_attr "type" "ishift")
11197 (set (attr "length_immediate")
11198 (if_then_else
11199 (and (match_operand 2 "const1_operand")
11200 (ior (match_test "TARGET_SHIFT1")
11201 (match_test "optimize_function_for_size_p (cfun)")))
11202 (const_string "0")
11203 (const_string "*")))
11204 (set_attr "mode" "<MODE>")])
11205
11206 (define_insn "*<shift_insn><mode>3_1_slp"
11207 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11208 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11209 (match_operand:QI 2 "nonmemory_operand" "cI")))
11210 (clobber (reg:CC FLAGS_REG))]
11211 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11212 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11213 && rtx_equal_p (operands[0], operands[1])"
11214 {
11215 if (operands[2] == const1_rtx
11216 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11217 return "<shift>{<imodesuffix>}\t%0";
11218 else
11219 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11220 }
11221 [(set_attr "type" "ishift")
11222 (set (attr "length_immediate")
11223 (if_then_else
11224 (and (match_operand 2 "const1_operand")
11225 (ior (match_test "TARGET_SHIFT1")
11226 (match_test "optimize_function_for_size_p (cfun)")))
11227 (const_string "0")
11228 (const_string "*")))
11229 (set_attr "mode" "<MODE>")])
11230
11231 ;; This pattern can't accept a variable shift count, since shifts by
11232 ;; zero don't affect the flags. We assume that shifts by constant
11233 ;; zero are optimized away.
11234 (define_insn "*<shift_insn><mode>3_cmp"
11235 [(set (reg FLAGS_REG)
11236 (compare
11237 (any_shiftrt:SWI
11238 (match_operand:SWI 1 "nonimmediate_operand" "0")
11239 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11240 (const_int 0)))
11241 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11242 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11243 "(optimize_function_for_size_p (cfun)
11244 || !TARGET_PARTIAL_FLAG_REG_STALL
11245 || (operands[2] == const1_rtx
11246 && TARGET_SHIFT1))
11247 && ix86_match_ccmode (insn, CCGOCmode)
11248 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11249 {
11250 if (operands[2] == const1_rtx
11251 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11252 return "<shift>{<imodesuffix>}\t%0";
11253 else
11254 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11255 }
11256 [(set_attr "type" "ishift")
11257 (set (attr "length_immediate")
11258 (if_then_else
11259 (and (match_operand 2 "const1_operand")
11260 (ior (match_test "TARGET_SHIFT1")
11261 (match_test "optimize_function_for_size_p (cfun)")))
11262 (const_string "0")
11263 (const_string "*")))
11264 (set_attr "mode" "<MODE>")])
11265
11266 (define_insn "*<shift_insn>si3_cmp_zext"
11267 [(set (reg FLAGS_REG)
11268 (compare
11269 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11270 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11271 (const_int 0)))
11272 (set (match_operand:DI 0 "register_operand" "=r")
11273 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11274 "TARGET_64BIT
11275 && (optimize_function_for_size_p (cfun)
11276 || !TARGET_PARTIAL_FLAG_REG_STALL
11277 || (operands[2] == const1_rtx
11278 && TARGET_SHIFT1))
11279 && ix86_match_ccmode (insn, CCGOCmode)
11280 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11281 {
11282 if (operands[2] == const1_rtx
11283 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11284 return "<shift>{l}\t%k0";
11285 else
11286 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11287 }
11288 [(set_attr "type" "ishift")
11289 (set (attr "length_immediate")
11290 (if_then_else
11291 (and (match_operand 2 "const1_operand")
11292 (ior (match_test "TARGET_SHIFT1")
11293 (match_test "optimize_function_for_size_p (cfun)")))
11294 (const_string "0")
11295 (const_string "*")))
11296 (set_attr "mode" "SI")])
11297
11298 (define_insn "*<shift_insn><mode>3_cconly"
11299 [(set (reg FLAGS_REG)
11300 (compare
11301 (any_shiftrt:SWI
11302 (match_operand:SWI 1 "register_operand" "0")
11303 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11304 (const_int 0)))
11305 (clobber (match_scratch:SWI 0 "=<r>"))]
11306 "(optimize_function_for_size_p (cfun)
11307 || !TARGET_PARTIAL_FLAG_REG_STALL
11308 || (operands[2] == const1_rtx
11309 && TARGET_SHIFT1))
11310 && ix86_match_ccmode (insn, CCGOCmode)"
11311 {
11312 if (operands[2] == const1_rtx
11313 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11314 return "<shift>{<imodesuffix>}\t%0";
11315 else
11316 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11317 }
11318 [(set_attr "type" "ishift")
11319 (set (attr "length_immediate")
11320 (if_then_else
11321 (and (match_operand 2 "const1_operand")
11322 (ior (match_test "TARGET_SHIFT1")
11323 (match_test "optimize_function_for_size_p (cfun)")))
11324 (const_string "0")
11325 (const_string "*")))
11326 (set_attr "mode" "<MODE>")])
11327 \f
11328 ;; Rotate instructions
11329
11330 (define_expand "<rotate_insn>ti3"
11331 [(set (match_operand:TI 0 "register_operand")
11332 (any_rotate:TI (match_operand:TI 1 "register_operand")
11333 (match_operand:QI 2 "nonmemory_operand")))]
11334 "TARGET_64BIT"
11335 {
11336 if (const_1_to_63_operand (operands[2], VOIDmode))
11337 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11338 (operands[0], operands[1], operands[2]));
11339 else
11340 FAIL;
11341
11342 DONE;
11343 })
11344
11345 (define_expand "<rotate_insn>di3"
11346 [(set (match_operand:DI 0 "shiftdi_operand")
11347 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11348 (match_operand:QI 2 "nonmemory_operand")))]
11349 ""
11350 {
11351 if (TARGET_64BIT)
11352 ix86_expand_binary_operator (<CODE>, DImode, operands);
11353 else if (const_1_to_31_operand (operands[2], VOIDmode))
11354 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11355 (operands[0], operands[1], operands[2]));
11356 else
11357 FAIL;
11358
11359 DONE;
11360 })
11361
11362 (define_expand "<rotate_insn><mode>3"
11363 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11364 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11365 (match_operand:QI 2 "nonmemory_operand")))]
11366 ""
11367 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11368
11369 ;; Avoid useless masking of count operand.
11370 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11371 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11372 (any_rotate:SWI48
11373 (match_operand:SWI48 1 "nonimmediate_operand")
11374 (subreg:QI
11375 (and:SI
11376 (match_operand:SI 2 "register_operand" "c")
11377 (match_operand:SI 3 "const_int_operand")) 0)))
11378 (clobber (reg:CC FLAGS_REG))]
11379 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11380 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11381 == GET_MODE_BITSIZE (<MODE>mode)-1
11382 && ix86_pre_reload_split ()"
11383 "#"
11384 "&& 1"
11385 [(parallel
11386 [(set (match_dup 0)
11387 (any_rotate:SWI48 (match_dup 1)
11388 (match_dup 2)))
11389 (clobber (reg:CC FLAGS_REG))])]
11390 "operands[2] = gen_lowpart (QImode, operands[2]);")
11391
11392 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11393 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11394 (any_rotate:SWI48
11395 (match_operand:SWI48 1 "nonimmediate_operand")
11396 (and:QI
11397 (match_operand:QI 2 "register_operand" "c")
11398 (match_operand:QI 3 "const_int_operand"))))
11399 (clobber (reg:CC FLAGS_REG))]
11400 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11401 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11402 == GET_MODE_BITSIZE (<MODE>mode)-1
11403 && ix86_pre_reload_split ()"
11404 "#"
11405 "&& 1"
11406 [(parallel
11407 [(set (match_dup 0)
11408 (any_rotate:SWI48 (match_dup 1)
11409 (match_dup 2)))
11410 (clobber (reg:CC FLAGS_REG))])])
11411
11412 ;; Implement rotation using two double-precision
11413 ;; shift instructions and a scratch register.
11414
11415 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11416 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11417 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11418 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11419 (clobber (reg:CC FLAGS_REG))
11420 (clobber (match_scratch:DWIH 3 "=&r"))]
11421 ""
11422 "#"
11423 "reload_completed"
11424 [(set (match_dup 3) (match_dup 4))
11425 (parallel
11426 [(set (match_dup 4)
11427 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11428 (lshiftrt:DWIH (match_dup 5)
11429 (minus:QI (match_dup 6) (match_dup 2)))))
11430 (clobber (reg:CC FLAGS_REG))])
11431 (parallel
11432 [(set (match_dup 5)
11433 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11434 (lshiftrt:DWIH (match_dup 3)
11435 (minus:QI (match_dup 6) (match_dup 2)))))
11436 (clobber (reg:CC FLAGS_REG))])]
11437 {
11438 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11439
11440 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11441 })
11442
11443 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11444 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11445 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11446 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11447 (clobber (reg:CC FLAGS_REG))
11448 (clobber (match_scratch:DWIH 3 "=&r"))]
11449 ""
11450 "#"
11451 "reload_completed"
11452 [(set (match_dup 3) (match_dup 4))
11453 (parallel
11454 [(set (match_dup 4)
11455 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11456 (ashift:DWIH (match_dup 5)
11457 (minus:QI (match_dup 6) (match_dup 2)))))
11458 (clobber (reg:CC FLAGS_REG))])
11459 (parallel
11460 [(set (match_dup 5)
11461 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11462 (ashift:DWIH (match_dup 3)
11463 (minus:QI (match_dup 6) (match_dup 2)))))
11464 (clobber (reg:CC FLAGS_REG))])]
11465 {
11466 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11467
11468 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11469 })
11470
11471 (define_mode_attr rorx_immediate_operand
11472 [(SI "const_0_to_31_operand")
11473 (DI "const_0_to_63_operand")])
11474
11475 (define_insn "*bmi2_rorx<mode>3_1"
11476 [(set (match_operand:SWI48 0 "register_operand" "=r")
11477 (rotatert:SWI48
11478 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11479 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11480 "TARGET_BMI2"
11481 "rorx\t{%2, %1, %0|%0, %1, %2}"
11482 [(set_attr "type" "rotatex")
11483 (set_attr "mode" "<MODE>")])
11484
11485 (define_insn "*<rotate_insn><mode>3_1"
11486 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11487 (any_rotate:SWI48
11488 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11489 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11490 (clobber (reg:CC FLAGS_REG))]
11491 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11492 {
11493 switch (get_attr_type (insn))
11494 {
11495 case TYPE_ROTATEX:
11496 return "#";
11497
11498 default:
11499 if (operands[2] == const1_rtx
11500 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11501 return "<rotate>{<imodesuffix>}\t%0";
11502 else
11503 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11504 }
11505 }
11506 [(set_attr "isa" "*,bmi2")
11507 (set_attr "type" "rotate,rotatex")
11508 (set (attr "length_immediate")
11509 (if_then_else
11510 (and (eq_attr "type" "rotate")
11511 (and (match_operand 2 "const1_operand")
11512 (ior (match_test "TARGET_SHIFT1")
11513 (match_test "optimize_function_for_size_p (cfun)"))))
11514 (const_string "0")
11515 (const_string "*")))
11516 (set_attr "mode" "<MODE>")])
11517
11518 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11519 (define_split
11520 [(set (match_operand:SWI48 0 "register_operand")
11521 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11522 (match_operand:QI 2 "const_int_operand")))
11523 (clobber (reg:CC FLAGS_REG))]
11524 "TARGET_BMI2 && reload_completed"
11525 [(set (match_dup 0)
11526 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11527 {
11528 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11529
11530 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11531 })
11532
11533 (define_split
11534 [(set (match_operand:SWI48 0 "register_operand")
11535 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11536 (match_operand:QI 2 "const_int_operand")))
11537 (clobber (reg:CC FLAGS_REG))]
11538 "TARGET_BMI2 && reload_completed"
11539 [(set (match_dup 0)
11540 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11541
11542 (define_insn "*bmi2_rorxsi3_1_zext"
11543 [(set (match_operand:DI 0 "register_operand" "=r")
11544 (zero_extend:DI
11545 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11546 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11547 "TARGET_64BIT && TARGET_BMI2"
11548 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11549 [(set_attr "type" "rotatex")
11550 (set_attr "mode" "SI")])
11551
11552 (define_insn "*<rotate_insn>si3_1_zext"
11553 [(set (match_operand:DI 0 "register_operand" "=r,r")
11554 (zero_extend:DI
11555 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11556 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11557 (clobber (reg:CC FLAGS_REG))]
11558 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11559 {
11560 switch (get_attr_type (insn))
11561 {
11562 case TYPE_ROTATEX:
11563 return "#";
11564
11565 default:
11566 if (operands[2] == const1_rtx
11567 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11568 return "<rotate>{l}\t%k0";
11569 else
11570 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11571 }
11572 }
11573 [(set_attr "isa" "*,bmi2")
11574 (set_attr "type" "rotate,rotatex")
11575 (set (attr "length_immediate")
11576 (if_then_else
11577 (and (eq_attr "type" "rotate")
11578 (and (match_operand 2 "const1_operand")
11579 (ior (match_test "TARGET_SHIFT1")
11580 (match_test "optimize_function_for_size_p (cfun)"))))
11581 (const_string "0")
11582 (const_string "*")))
11583 (set_attr "mode" "SI")])
11584
11585 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11586 (define_split
11587 [(set (match_operand:DI 0 "register_operand")
11588 (zero_extend:DI
11589 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11590 (match_operand:QI 2 "const_int_operand"))))
11591 (clobber (reg:CC FLAGS_REG))]
11592 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11593 [(set (match_dup 0)
11594 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11595 {
11596 int bitsize = GET_MODE_BITSIZE (SImode);
11597
11598 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11599 })
11600
11601 (define_split
11602 [(set (match_operand:DI 0 "register_operand")
11603 (zero_extend:DI
11604 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11605 (match_operand:QI 2 "const_int_operand"))))
11606 (clobber (reg:CC FLAGS_REG))]
11607 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11608 [(set (match_dup 0)
11609 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11610
11611 (define_insn "*<rotate_insn><mode>3_1"
11612 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11613 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11614 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11615 (clobber (reg:CC FLAGS_REG))]
11616 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11617 {
11618 if (operands[2] == const1_rtx
11619 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11620 return "<rotate>{<imodesuffix>}\t%0";
11621 else
11622 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11623 }
11624 [(set_attr "type" "rotate")
11625 (set (attr "length_immediate")
11626 (if_then_else
11627 (and (match_operand 2 "const1_operand")
11628 (ior (match_test "TARGET_SHIFT1")
11629 (match_test "optimize_function_for_size_p (cfun)")))
11630 (const_string "0")
11631 (const_string "*")))
11632 (set_attr "mode" "<MODE>")])
11633
11634 (define_insn "*<rotate_insn><mode>3_1_slp"
11635 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11636 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11637 (match_operand:QI 2 "nonmemory_operand" "cI")))
11638 (clobber (reg:CC FLAGS_REG))]
11639 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11640 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11641 && rtx_equal_p (operands[0], operands[1])"
11642 {
11643 if (operands[2] == const1_rtx
11644 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11645 return "<rotate>{<imodesuffix>}\t%0";
11646 else
11647 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11648 }
11649 [(set_attr "type" "rotate")
11650 (set (attr "length_immediate")
11651 (if_then_else
11652 (and (match_operand 2 "const1_operand")
11653 (ior (match_test "TARGET_SHIFT1")
11654 (match_test "optimize_function_for_size_p (cfun)")))
11655 (const_string "0")
11656 (const_string "*")))
11657 (set_attr "mode" "<MODE>")])
11658
11659 (define_split
11660 [(set (match_operand:HI 0 "QIreg_operand")
11661 (any_rotate:HI (match_dup 0) (const_int 8)))
11662 (clobber (reg:CC FLAGS_REG))]
11663 "reload_completed
11664 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11665 [(parallel [(set (strict_low_part (match_dup 0))
11666 (bswap:HI (match_dup 0)))
11667 (clobber (reg:CC FLAGS_REG))])])
11668 \f
11669 ;; Bit set / bit test instructions
11670
11671 ;; %%% bts, btr, btc
11672
11673 ;; These instructions are *slow* when applied to memory.
11674
11675 (define_code_attr btsc [(ior "bts") (xor "btc")])
11676
11677 (define_insn "*<btsc><mode>"
11678 [(set (match_operand:SWI48 0 "register_operand" "=r")
11679 (any_or:SWI48
11680 (ashift:SWI48 (const_int 1)
11681 (match_operand:QI 2 "register_operand" "r"))
11682 (match_operand:SWI48 1 "register_operand" "0")))
11683 (clobber (reg:CC FLAGS_REG))]
11684 "TARGET_USE_BT"
11685 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11686 [(set_attr "type" "alu1")
11687 (set_attr "prefix_0f" "1")
11688 (set_attr "znver1_decode" "double")
11689 (set_attr "mode" "<MODE>")])
11690
11691 ;; Avoid useless masking of count operand.
11692 (define_insn_and_split "*<btsc><mode>_mask"
11693 [(set (match_operand:SWI48 0 "register_operand")
11694 (any_or:SWI48
11695 (ashift:SWI48
11696 (const_int 1)
11697 (subreg:QI
11698 (and:SI
11699 (match_operand:SI 1 "register_operand")
11700 (match_operand:SI 2 "const_int_operand")) 0))
11701 (match_operand:SWI48 3 "register_operand")))
11702 (clobber (reg:CC FLAGS_REG))]
11703 "TARGET_USE_BT
11704 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11705 == GET_MODE_BITSIZE (<MODE>mode)-1
11706 && ix86_pre_reload_split ()"
11707 "#"
11708 "&& 1"
11709 [(parallel
11710 [(set (match_dup 0)
11711 (any_or:SWI48
11712 (ashift:SWI48 (const_int 1)
11713 (match_dup 1))
11714 (match_dup 3)))
11715 (clobber (reg:CC FLAGS_REG))])]
11716 "operands[1] = gen_lowpart (QImode, operands[1]);")
11717
11718 (define_insn_and_split "*<btsc><mode>_mask_1"
11719 [(set (match_operand:SWI48 0 "register_operand")
11720 (any_or:SWI48
11721 (ashift:SWI48
11722 (const_int 1)
11723 (and:QI
11724 (match_operand:QI 1 "register_operand")
11725 (match_operand:QI 2 "const_int_operand")))
11726 (match_operand:SWI48 3 "register_operand")))
11727 (clobber (reg:CC FLAGS_REG))]
11728 "TARGET_USE_BT
11729 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11730 == GET_MODE_BITSIZE (<MODE>mode)-1
11731 && ix86_pre_reload_split ()"
11732 "#"
11733 "&& 1"
11734 [(parallel
11735 [(set (match_dup 0)
11736 (any_or:SWI48
11737 (ashift:SWI48 (const_int 1)
11738 (match_dup 1))
11739 (match_dup 3)))
11740 (clobber (reg:CC FLAGS_REG))])])
11741
11742 (define_insn "*btr<mode>"
11743 [(set (match_operand:SWI48 0 "register_operand" "=r")
11744 (and:SWI48
11745 (rotate:SWI48 (const_int -2)
11746 (match_operand:QI 2 "register_operand" "r"))
11747 (match_operand:SWI48 1 "register_operand" "0")))
11748 (clobber (reg:CC FLAGS_REG))]
11749 "TARGET_USE_BT"
11750 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11751 [(set_attr "type" "alu1")
11752 (set_attr "prefix_0f" "1")
11753 (set_attr "znver1_decode" "double")
11754 (set_attr "mode" "<MODE>")])
11755
11756 ;; Avoid useless masking of count operand.
11757 (define_insn_and_split "*btr<mode>_mask"
11758 [(set (match_operand:SWI48 0 "register_operand")
11759 (and:SWI48
11760 (rotate:SWI48
11761 (const_int -2)
11762 (subreg:QI
11763 (and:SI
11764 (match_operand:SI 1 "register_operand")
11765 (match_operand:SI 2 "const_int_operand")) 0))
11766 (match_operand:SWI48 3 "register_operand")))
11767 (clobber (reg:CC FLAGS_REG))]
11768 "TARGET_USE_BT
11769 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11770 == GET_MODE_BITSIZE (<MODE>mode)-1
11771 && ix86_pre_reload_split ()"
11772 "#"
11773 "&& 1"
11774 [(parallel
11775 [(set (match_dup 0)
11776 (and:SWI48
11777 (rotate:SWI48 (const_int -2)
11778 (match_dup 1))
11779 (match_dup 3)))
11780 (clobber (reg:CC FLAGS_REG))])]
11781 "operands[1] = gen_lowpart (QImode, operands[1]);")
11782
11783 (define_insn_and_split "*btr<mode>_mask_1"
11784 [(set (match_operand:SWI48 0 "register_operand")
11785 (and:SWI48
11786 (rotate:SWI48
11787 (const_int -2)
11788 (and:QI
11789 (match_operand:QI 1 "register_operand")
11790 (match_operand:QI 2 "const_int_operand")))
11791 (match_operand:SWI48 3 "register_operand")))
11792 (clobber (reg:CC FLAGS_REG))]
11793 "TARGET_USE_BT
11794 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11795 == GET_MODE_BITSIZE (<MODE>mode)-1
11796 && ix86_pre_reload_split ()"
11797 "#"
11798 "&& 1"
11799 [(parallel
11800 [(set (match_dup 0)
11801 (and:SWI48
11802 (rotate:SWI48 (const_int -2)
11803 (match_dup 1))
11804 (match_dup 3)))
11805 (clobber (reg:CC FLAGS_REG))])])
11806
11807 ;; These instructions are never faster than the corresponding
11808 ;; and/ior/xor operations when using immediate operand, so with
11809 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11810 ;; relevant immediates within the instruction itself, so operating
11811 ;; on bits in the high 32-bits of a register becomes easier.
11812 ;;
11813 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11814 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11815 ;; negdf respectively, so they can never be disabled entirely.
11816
11817 (define_insn "*btsq_imm"
11818 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11819 (const_int 1)
11820 (match_operand 1 "const_0_to_63_operand" "J"))
11821 (const_int 1))
11822 (clobber (reg:CC FLAGS_REG))]
11823 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11824 "bts{q}\t{%1, %0|%0, %1}"
11825 [(set_attr "type" "alu1")
11826 (set_attr "prefix_0f" "1")
11827 (set_attr "znver1_decode" "double")
11828 (set_attr "mode" "DI")])
11829
11830 (define_insn "*btrq_imm"
11831 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11832 (const_int 1)
11833 (match_operand 1 "const_0_to_63_operand" "J"))
11834 (const_int 0))
11835 (clobber (reg:CC FLAGS_REG))]
11836 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11837 "btr{q}\t{%1, %0|%0, %1}"
11838 [(set_attr "type" "alu1")
11839 (set_attr "prefix_0f" "1")
11840 (set_attr "znver1_decode" "double")
11841 (set_attr "mode" "DI")])
11842
11843 (define_insn "*btcq_imm"
11844 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11845 (const_int 1)
11846 (match_operand 1 "const_0_to_63_operand" "J"))
11847 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11848 (clobber (reg:CC FLAGS_REG))]
11849 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11850 "btc{q}\t{%1, %0|%0, %1}"
11851 [(set_attr "type" "alu1")
11852 (set_attr "prefix_0f" "1")
11853 (set_attr "znver1_decode" "double")
11854 (set_attr "mode" "DI")])
11855
11856 ;; Allow Nocona to avoid these instructions if a register is available.
11857
11858 (define_peephole2
11859 [(match_scratch:DI 2 "r")
11860 (parallel [(set (zero_extract:DI
11861 (match_operand:DI 0 "nonimmediate_operand")
11862 (const_int 1)
11863 (match_operand 1 "const_0_to_63_operand"))
11864 (const_int 1))
11865 (clobber (reg:CC FLAGS_REG))])]
11866 "TARGET_64BIT && !TARGET_USE_BT"
11867 [(parallel [(set (match_dup 0)
11868 (ior:DI (match_dup 0) (match_dup 3)))
11869 (clobber (reg:CC FLAGS_REG))])]
11870 {
11871 int i = INTVAL (operands[1]);
11872
11873 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11874
11875 if (!x86_64_immediate_operand (operands[3], DImode))
11876 {
11877 emit_move_insn (operands[2], operands[3]);
11878 operands[3] = operands[2];
11879 }
11880 })
11881
11882 (define_peephole2
11883 [(match_scratch:DI 2 "r")
11884 (parallel [(set (zero_extract:DI
11885 (match_operand:DI 0 "nonimmediate_operand")
11886 (const_int 1)
11887 (match_operand 1 "const_0_to_63_operand"))
11888 (const_int 0))
11889 (clobber (reg:CC FLAGS_REG))])]
11890 "TARGET_64BIT && !TARGET_USE_BT"
11891 [(parallel [(set (match_dup 0)
11892 (and:DI (match_dup 0) (match_dup 3)))
11893 (clobber (reg:CC FLAGS_REG))])]
11894 {
11895 int i = INTVAL (operands[1]);
11896
11897 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11898
11899 if (!x86_64_immediate_operand (operands[3], DImode))
11900 {
11901 emit_move_insn (operands[2], operands[3]);
11902 operands[3] = operands[2];
11903 }
11904 })
11905
11906 (define_peephole2
11907 [(match_scratch:DI 2 "r")
11908 (parallel [(set (zero_extract:DI
11909 (match_operand:DI 0 "nonimmediate_operand")
11910 (const_int 1)
11911 (match_operand 1 "const_0_to_63_operand"))
11912 (not:DI (zero_extract:DI
11913 (match_dup 0) (const_int 1) (match_dup 1))))
11914 (clobber (reg:CC FLAGS_REG))])]
11915 "TARGET_64BIT && !TARGET_USE_BT"
11916 [(parallel [(set (match_dup 0)
11917 (xor:DI (match_dup 0) (match_dup 3)))
11918 (clobber (reg:CC FLAGS_REG))])]
11919 {
11920 int i = INTVAL (operands[1]);
11921
11922 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11923
11924 if (!x86_64_immediate_operand (operands[3], DImode))
11925 {
11926 emit_move_insn (operands[2], operands[3]);
11927 operands[3] = operands[2];
11928 }
11929 })
11930
11931 ;; %%% bt
11932
11933 (define_insn "*bt<mode>"
11934 [(set (reg:CCC FLAGS_REG)
11935 (compare:CCC
11936 (zero_extract:SWI48
11937 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11938 (const_int 1)
11939 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11940 (const_int 0)))]
11941 ""
11942 {
11943 switch (get_attr_mode (insn))
11944 {
11945 case MODE_SI:
11946 return "bt{l}\t{%1, %k0|%k0, %1}";
11947
11948 case MODE_DI:
11949 return "bt{q}\t{%q1, %0|%0, %q1}";
11950
11951 default:
11952 gcc_unreachable ();
11953 }
11954 }
11955 [(set_attr "type" "alu1")
11956 (set_attr "prefix_0f" "1")
11957 (set (attr "mode")
11958 (if_then_else
11959 (and (match_test "CONST_INT_P (operands[1])")
11960 (match_test "INTVAL (operands[1]) < 32"))
11961 (const_string "SI")
11962 (const_string "<MODE>")))])
11963
11964 (define_insn_and_split "*jcc_bt<mode>"
11965 [(set (pc)
11966 (if_then_else (match_operator 0 "bt_comparison_operator"
11967 [(zero_extract:SWI48
11968 (match_operand:SWI48 1 "nonimmediate_operand")
11969 (const_int 1)
11970 (match_operand:SI 2 "nonmemory_operand"))
11971 (const_int 0)])
11972 (label_ref (match_operand 3))
11973 (pc)))
11974 (clobber (reg:CC FLAGS_REG))]
11975 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11976 && (CONST_INT_P (operands[2])
11977 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11978 && INTVAL (operands[2])
11979 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11980 : !memory_operand (operands[1], <MODE>mode))
11981 && ix86_pre_reload_split ()"
11982 "#"
11983 "&& 1"
11984 [(set (reg:CCC FLAGS_REG)
11985 (compare:CCC
11986 (zero_extract:SWI48
11987 (match_dup 1)
11988 (const_int 1)
11989 (match_dup 2))
11990 (const_int 0)))
11991 (set (pc)
11992 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11993 (label_ref (match_dup 3))
11994 (pc)))]
11995 {
11996 operands[0] = shallow_copy_rtx (operands[0]);
11997 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11998 })
11999
12000 (define_insn_and_split "*jcc_bt<mode>_1"
12001 [(set (pc)
12002 (if_then_else (match_operator 0 "bt_comparison_operator"
12003 [(zero_extract:SWI48
12004 (match_operand:SWI48 1 "register_operand")
12005 (const_int 1)
12006 (zero_extend:SI
12007 (match_operand:QI 2 "register_operand")))
12008 (const_int 0)])
12009 (label_ref (match_operand 3))
12010 (pc)))
12011 (clobber (reg:CC FLAGS_REG))]
12012 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12013 && ix86_pre_reload_split ()"
12014 "#"
12015 "&& 1"
12016 [(set (reg:CCC FLAGS_REG)
12017 (compare:CCC
12018 (zero_extract:SWI48
12019 (match_dup 1)
12020 (const_int 1)
12021 (match_dup 2))
12022 (const_int 0)))
12023 (set (pc)
12024 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12025 (label_ref (match_dup 3))
12026 (pc)))]
12027 {
12028 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12029 operands[0] = shallow_copy_rtx (operands[0]);
12030 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12031 })
12032
12033 ;; Avoid useless masking of bit offset operand.
12034 (define_insn_and_split "*jcc_bt<mode>_mask"
12035 [(set (pc)
12036 (if_then_else (match_operator 0 "bt_comparison_operator"
12037 [(zero_extract:SWI48
12038 (match_operand:SWI48 1 "register_operand")
12039 (const_int 1)
12040 (and:SI
12041 (match_operand:SI 2 "register_operand")
12042 (match_operand 3 "const_int_operand")))])
12043 (label_ref (match_operand 4))
12044 (pc)))
12045 (clobber (reg:CC FLAGS_REG))]
12046 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12047 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12048 == GET_MODE_BITSIZE (<MODE>mode)-1
12049 && ix86_pre_reload_split ()"
12050 "#"
12051 "&& 1"
12052 [(set (reg:CCC FLAGS_REG)
12053 (compare:CCC
12054 (zero_extract:SWI48
12055 (match_dup 1)
12056 (const_int 1)
12057 (match_dup 2))
12058 (const_int 0)))
12059 (set (pc)
12060 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12061 (label_ref (match_dup 4))
12062 (pc)))]
12063 {
12064 operands[0] = shallow_copy_rtx (operands[0]);
12065 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12066 })
12067 \f
12068 ;; Store-flag instructions.
12069
12070 ;; For all sCOND expanders, also expand the compare or test insn that
12071 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12072
12073 (define_insn_and_split "*setcc_di_1"
12074 [(set (match_operand:DI 0 "register_operand" "=q")
12075 (match_operator:DI 1 "ix86_comparison_operator"
12076 [(reg FLAGS_REG) (const_int 0)]))]
12077 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12078 "#"
12079 "&& reload_completed"
12080 [(set (match_dup 2) (match_dup 1))
12081 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12082 {
12083 operands[1] = shallow_copy_rtx (operands[1]);
12084 PUT_MODE (operands[1], QImode);
12085 operands[2] = gen_lowpart (QImode, operands[0]);
12086 })
12087
12088 (define_insn_and_split "*setcc_si_1_and"
12089 [(set (match_operand:SI 0 "register_operand" "=q")
12090 (match_operator:SI 1 "ix86_comparison_operator"
12091 [(reg FLAGS_REG) (const_int 0)]))
12092 (clobber (reg:CC FLAGS_REG))]
12093 "!TARGET_PARTIAL_REG_STALL
12094 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12095 "#"
12096 "&& reload_completed"
12097 [(set (match_dup 2) (match_dup 1))
12098 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12099 (clobber (reg:CC FLAGS_REG))])]
12100 {
12101 operands[1] = shallow_copy_rtx (operands[1]);
12102 PUT_MODE (operands[1], QImode);
12103 operands[2] = gen_lowpart (QImode, operands[0]);
12104 })
12105
12106 (define_insn_and_split "*setcc_si_1_movzbl"
12107 [(set (match_operand:SI 0 "register_operand" "=q")
12108 (match_operator:SI 1 "ix86_comparison_operator"
12109 [(reg FLAGS_REG) (const_int 0)]))]
12110 "!TARGET_PARTIAL_REG_STALL
12111 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12112 "#"
12113 "&& reload_completed"
12114 [(set (match_dup 2) (match_dup 1))
12115 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12116 {
12117 operands[1] = shallow_copy_rtx (operands[1]);
12118 PUT_MODE (operands[1], QImode);
12119 operands[2] = gen_lowpart (QImode, operands[0]);
12120 })
12121
12122 (define_insn "*setcc_qi"
12123 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12124 (match_operator:QI 1 "ix86_comparison_operator"
12125 [(reg FLAGS_REG) (const_int 0)]))]
12126 ""
12127 "set%C1\t%0"
12128 [(set_attr "type" "setcc")
12129 (set_attr "mode" "QI")])
12130
12131 (define_insn "*setcc_qi_slp"
12132 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
12133 (match_operator:QI 1 "ix86_comparison_operator"
12134 [(reg FLAGS_REG) (const_int 0)]))]
12135 ""
12136 "set%C1\t%0"
12137 [(set_attr "type" "setcc")
12138 (set_attr "mode" "QI")])
12139
12140 ;; In general it is not safe to assume too much about CCmode registers,
12141 ;; so simplify-rtx stops when it sees a second one. Under certain
12142 ;; conditions this is safe on x86, so help combine not create
12143 ;;
12144 ;; seta %al
12145 ;; testb %al, %al
12146 ;; sete %al
12147
12148 (define_split
12149 [(set (match_operand:QI 0 "nonimmediate_operand")
12150 (ne:QI (match_operator 1 "ix86_comparison_operator"
12151 [(reg FLAGS_REG) (const_int 0)])
12152 (const_int 0)))]
12153 ""
12154 [(set (match_dup 0) (match_dup 1))]
12155 {
12156 operands[1] = shallow_copy_rtx (operands[1]);
12157 PUT_MODE (operands[1], QImode);
12158 })
12159
12160 (define_split
12161 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12162 (ne:QI (match_operator 1 "ix86_comparison_operator"
12163 [(reg FLAGS_REG) (const_int 0)])
12164 (const_int 0)))]
12165 ""
12166 [(set (match_dup 0) (match_dup 1))]
12167 {
12168 operands[1] = shallow_copy_rtx (operands[1]);
12169 PUT_MODE (operands[1], QImode);
12170 })
12171
12172 (define_split
12173 [(set (match_operand:QI 0 "nonimmediate_operand")
12174 (eq:QI (match_operator 1 "ix86_comparison_operator"
12175 [(reg FLAGS_REG) (const_int 0)])
12176 (const_int 0)))]
12177 ""
12178 [(set (match_dup 0) (match_dup 1))]
12179 {
12180 operands[1] = shallow_copy_rtx (operands[1]);
12181 PUT_MODE (operands[1], QImode);
12182 PUT_CODE (operands[1],
12183 ix86_reverse_condition (GET_CODE (operands[1]),
12184 GET_MODE (XEXP (operands[1], 0))));
12185
12186 /* Make sure that (a) the CCmode we have for the flags is strong
12187 enough for the reversed compare or (b) we have a valid FP compare. */
12188 if (! ix86_comparison_operator (operands[1], VOIDmode))
12189 FAIL;
12190 })
12191
12192 (define_split
12193 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12194 (eq:QI (match_operator 1 "ix86_comparison_operator"
12195 [(reg FLAGS_REG) (const_int 0)])
12196 (const_int 0)))]
12197 ""
12198 [(set (match_dup 0) (match_dup 1))]
12199 {
12200 operands[1] = shallow_copy_rtx (operands[1]);
12201 PUT_MODE (operands[1], QImode);
12202 PUT_CODE (operands[1],
12203 ix86_reverse_condition (GET_CODE (operands[1]),
12204 GET_MODE (XEXP (operands[1], 0))));
12205
12206 /* Make sure that (a) the CCmode we have for the flags is strong
12207 enough for the reversed compare or (b) we have a valid FP compare. */
12208 if (! ix86_comparison_operator (operands[1], VOIDmode))
12209 FAIL;
12210 })
12211
12212 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12213 ;; subsequent logical operations are used to imitate conditional moves.
12214 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12215 ;; it directly.
12216
12217 (define_insn "setcc_<mode>_sse"
12218 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12219 (match_operator:MODEF 3 "sse_comparison_operator"
12220 [(match_operand:MODEF 1 "register_operand" "0,x")
12221 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12222 "SSE_FLOAT_MODE_P (<MODE>mode)"
12223 "@
12224 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12225 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12226 [(set_attr "isa" "noavx,avx")
12227 (set_attr "type" "ssecmp")
12228 (set_attr "length_immediate" "1")
12229 (set_attr "prefix" "orig,vex")
12230 (set_attr "mode" "<MODE>")])
12231 \f
12232 ;; Basic conditional jump instructions.
12233 ;; We ignore the overflow flag for signed branch instructions.
12234
12235 (define_insn "*jcc"
12236 [(set (pc)
12237 (if_then_else (match_operator 1 "ix86_comparison_operator"
12238 [(reg FLAGS_REG) (const_int 0)])
12239 (label_ref (match_operand 0))
12240 (pc)))]
12241 ""
12242 "%!%+j%C1\t%l0"
12243 [(set_attr "type" "ibr")
12244 (set_attr "modrm" "0")
12245 (set (attr "length")
12246 (if_then_else
12247 (and (ge (minus (match_dup 0) (pc))
12248 (const_int -126))
12249 (lt (minus (match_dup 0) (pc))
12250 (const_int 128)))
12251 (const_int 2)
12252 (const_int 6)))])
12253
12254 ;; In general it is not safe to assume too much about CCmode registers,
12255 ;; so simplify-rtx stops when it sees a second one. Under certain
12256 ;; conditions this is safe on x86, so help combine not create
12257 ;;
12258 ;; seta %al
12259 ;; testb %al, %al
12260 ;; je Lfoo
12261
12262 (define_split
12263 [(set (pc)
12264 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12265 [(reg FLAGS_REG) (const_int 0)])
12266 (const_int 0))
12267 (label_ref (match_operand 1))
12268 (pc)))]
12269 ""
12270 [(set (pc)
12271 (if_then_else (match_dup 0)
12272 (label_ref (match_dup 1))
12273 (pc)))]
12274 {
12275 operands[0] = shallow_copy_rtx (operands[0]);
12276 PUT_MODE (operands[0], VOIDmode);
12277 })
12278
12279 (define_split
12280 [(set (pc)
12281 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12282 [(reg FLAGS_REG) (const_int 0)])
12283 (const_int 0))
12284 (label_ref (match_operand 1))
12285 (pc)))]
12286 ""
12287 [(set (pc)
12288 (if_then_else (match_dup 0)
12289 (label_ref (match_dup 1))
12290 (pc)))]
12291 {
12292 operands[0] = shallow_copy_rtx (operands[0]);
12293 PUT_MODE (operands[0], VOIDmode);
12294 PUT_CODE (operands[0],
12295 ix86_reverse_condition (GET_CODE (operands[0]),
12296 GET_MODE (XEXP (operands[0], 0))));
12297
12298 /* Make sure that (a) the CCmode we have for the flags is strong
12299 enough for the reversed compare or (b) we have a valid FP compare. */
12300 if (! ix86_comparison_operator (operands[0], VOIDmode))
12301 FAIL;
12302 })
12303 \f
12304 ;; Unconditional and other jump instructions
12305
12306 (define_insn "jump"
12307 [(set (pc)
12308 (label_ref (match_operand 0)))]
12309 ""
12310 "%!jmp\t%l0"
12311 [(set_attr "type" "ibr")
12312 (set_attr "modrm" "0")
12313 (set (attr "length")
12314 (if_then_else
12315 (and (ge (minus (match_dup 0) (pc))
12316 (const_int -126))
12317 (lt (minus (match_dup 0) (pc))
12318 (const_int 128)))
12319 (const_int 2)
12320 (const_int 5)))])
12321
12322 (define_expand "indirect_jump"
12323 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12324 ""
12325 {
12326 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12327 operands[0] = convert_memory_address (word_mode, operands[0]);
12328 cfun->machine->has_local_indirect_jump = true;
12329 })
12330
12331 (define_insn "*indirect_jump"
12332 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12333 ""
12334 "* return ix86_output_indirect_jmp (operands[0]);"
12335 [(set (attr "type")
12336 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12337 != indirect_branch_keep)")
12338 (const_string "multi")
12339 (const_string "ibr")))
12340 (set_attr "length_immediate" "0")])
12341
12342 (define_expand "tablejump"
12343 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12344 (use (label_ref (match_operand 1)))])]
12345 ""
12346 {
12347 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12348 relative. Convert the relative address to an absolute address. */
12349 if (flag_pic)
12350 {
12351 rtx op0, op1;
12352 enum rtx_code code;
12353
12354 /* We can't use @GOTOFF for text labels on VxWorks;
12355 see gotoff_operand. */
12356 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12357 {
12358 code = PLUS;
12359 op0 = operands[0];
12360 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12361 }
12362 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12363 {
12364 code = PLUS;
12365 op0 = operands[0];
12366 op1 = pic_offset_table_rtx;
12367 }
12368 else
12369 {
12370 code = MINUS;
12371 op0 = pic_offset_table_rtx;
12372 op1 = operands[0];
12373 }
12374
12375 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12376 OPTAB_DIRECT);
12377 }
12378
12379 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12380 operands[0] = convert_memory_address (word_mode, operands[0]);
12381 cfun->machine->has_local_indirect_jump = true;
12382 })
12383
12384 (define_insn "*tablejump_1"
12385 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12386 (use (label_ref (match_operand 1)))]
12387 ""
12388 "* return ix86_output_indirect_jmp (operands[0]);"
12389 [(set (attr "type")
12390 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12391 != indirect_branch_keep)")
12392 (const_string "multi")
12393 (const_string "ibr")))
12394 (set_attr "length_immediate" "0")])
12395 \f
12396 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12397
12398 (define_peephole2
12399 [(set (reg FLAGS_REG) (match_operand 0))
12400 (set (match_operand:QI 1 "register_operand")
12401 (match_operator:QI 2 "ix86_comparison_operator"
12402 [(reg FLAGS_REG) (const_int 0)]))
12403 (set (match_operand 3 "any_QIreg_operand")
12404 (zero_extend (match_dup 1)))]
12405 "(peep2_reg_dead_p (3, operands[1])
12406 || operands_match_p (operands[1], operands[3]))
12407 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12408 && peep2_regno_dead_p (0, FLAGS_REG)"
12409 [(set (match_dup 4) (match_dup 0))
12410 (set (strict_low_part (match_dup 5))
12411 (match_dup 2))]
12412 {
12413 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12414 operands[5] = gen_lowpart (QImode, operands[3]);
12415 ix86_expand_clear (operands[3]);
12416 })
12417
12418 (define_peephole2
12419 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12420 (match_operand 4)])
12421 (set (match_operand:QI 1 "register_operand")
12422 (match_operator:QI 2 "ix86_comparison_operator"
12423 [(reg FLAGS_REG) (const_int 0)]))
12424 (set (match_operand 3 "any_QIreg_operand")
12425 (zero_extend (match_dup 1)))]
12426 "(peep2_reg_dead_p (3, operands[1])
12427 || operands_match_p (operands[1], operands[3]))
12428 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12429 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12430 && ! reg_set_p (operands[3], operands[4])
12431 && peep2_regno_dead_p (0, FLAGS_REG)"
12432 [(parallel [(set (match_dup 5) (match_dup 0))
12433 (match_dup 4)])
12434 (set (strict_low_part (match_dup 6))
12435 (match_dup 2))]
12436 {
12437 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12438 operands[6] = gen_lowpart (QImode, operands[3]);
12439 ix86_expand_clear (operands[3]);
12440 })
12441
12442 (define_peephole2
12443 [(set (reg FLAGS_REG) (match_operand 0))
12444 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12445 (match_operand 5)])
12446 (set (match_operand:QI 2 "register_operand")
12447 (match_operator:QI 3 "ix86_comparison_operator"
12448 [(reg FLAGS_REG) (const_int 0)]))
12449 (set (match_operand 4 "any_QIreg_operand")
12450 (zero_extend (match_dup 2)))]
12451 "(peep2_reg_dead_p (4, operands[2])
12452 || operands_match_p (operands[2], operands[4]))
12453 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12454 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12455 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12456 && ! reg_set_p (operands[4], operands[5])
12457 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12458 && peep2_regno_dead_p (0, FLAGS_REG)"
12459 [(set (match_dup 6) (match_dup 0))
12460 (parallel [(set (match_dup 7) (match_dup 1))
12461 (match_dup 5)])
12462 (set (strict_low_part (match_dup 8))
12463 (match_dup 3))]
12464 {
12465 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12466 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12467 operands[8] = gen_lowpart (QImode, operands[4]);
12468 ix86_expand_clear (operands[4]);
12469 })
12470
12471 ;; Similar, but match zero extend with andsi3.
12472
12473 (define_peephole2
12474 [(set (reg FLAGS_REG) (match_operand 0))
12475 (set (match_operand:QI 1 "register_operand")
12476 (match_operator:QI 2 "ix86_comparison_operator"
12477 [(reg FLAGS_REG) (const_int 0)]))
12478 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12479 (and:SI (match_dup 3) (const_int 255)))
12480 (clobber (reg:CC FLAGS_REG))])]
12481 "REGNO (operands[1]) == REGNO (operands[3])
12482 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12483 && peep2_regno_dead_p (0, FLAGS_REG)"
12484 [(set (match_dup 4) (match_dup 0))
12485 (set (strict_low_part (match_dup 5))
12486 (match_dup 2))]
12487 {
12488 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12489 operands[5] = gen_lowpart (QImode, operands[3]);
12490 ix86_expand_clear (operands[3]);
12491 })
12492
12493 (define_peephole2
12494 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12495 (match_operand 4)])
12496 (set (match_operand:QI 1 "register_operand")
12497 (match_operator:QI 2 "ix86_comparison_operator"
12498 [(reg FLAGS_REG) (const_int 0)]))
12499 (parallel [(set (match_operand 3 "any_QIreg_operand")
12500 (zero_extend (match_dup 1)))
12501 (clobber (reg:CC FLAGS_REG))])]
12502 "(peep2_reg_dead_p (3, operands[1])
12503 || operands_match_p (operands[1], operands[3]))
12504 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12505 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12506 && ! reg_set_p (operands[3], operands[4])
12507 && peep2_regno_dead_p (0, FLAGS_REG)"
12508 [(parallel [(set (match_dup 5) (match_dup 0))
12509 (match_dup 4)])
12510 (set (strict_low_part (match_dup 6))
12511 (match_dup 2))]
12512 {
12513 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12514 operands[6] = gen_lowpart (QImode, operands[3]);
12515 ix86_expand_clear (operands[3]);
12516 })
12517
12518 (define_peephole2
12519 [(set (reg FLAGS_REG) (match_operand 0))
12520 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12521 (match_operand 5)])
12522 (set (match_operand:QI 2 "register_operand")
12523 (match_operator:QI 3 "ix86_comparison_operator"
12524 [(reg FLAGS_REG) (const_int 0)]))
12525 (parallel [(set (match_operand 4 "any_QIreg_operand")
12526 (zero_extend (match_dup 2)))
12527 (clobber (reg:CC FLAGS_REG))])]
12528 "(peep2_reg_dead_p (4, operands[2])
12529 || operands_match_p (operands[2], operands[4]))
12530 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12531 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12532 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12533 && ! reg_set_p (operands[4], operands[5])
12534 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12535 && peep2_regno_dead_p (0, FLAGS_REG)"
12536 [(set (match_dup 6) (match_dup 0))
12537 (parallel [(set (match_dup 7) (match_dup 1))
12538 (match_dup 5)])
12539 (set (strict_low_part (match_dup 8))
12540 (match_dup 3))]
12541 {
12542 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12543 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12544 operands[8] = gen_lowpart (QImode, operands[4]);
12545 ix86_expand_clear (operands[4]);
12546 })
12547 \f
12548 ;; Call instructions.
12549
12550 ;; The predicates normally associated with named expanders are not properly
12551 ;; checked for calls. This is a bug in the generic code, but it isn't that
12552 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12553
12554 ;; P6 processors will jump to the address after the decrement when %esp
12555 ;; is used as a call operand, so they will execute return address as a code.
12556 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12557
12558 ;; Register constraint for call instruction.
12559 (define_mode_attr c [(SI "l") (DI "r")])
12560
12561 ;; Call subroutine returning no value.
12562
12563 (define_expand "call"
12564 [(call (match_operand:QI 0)
12565 (match_operand 1))
12566 (use (match_operand 2))]
12567 ""
12568 {
12569 ix86_expand_call (NULL, operands[0], operands[1],
12570 operands[2], NULL, false);
12571 DONE;
12572 })
12573
12574 (define_expand "sibcall"
12575 [(call (match_operand:QI 0)
12576 (match_operand 1))
12577 (use (match_operand 2))]
12578 ""
12579 {
12580 ix86_expand_call (NULL, operands[0], operands[1],
12581 operands[2], NULL, true);
12582 DONE;
12583 })
12584
12585 (define_insn "*call"
12586 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12587 (match_operand 1))]
12588 "!SIBLING_CALL_P (insn)"
12589 "* return ix86_output_call_insn (insn, operands[0]);"
12590 [(set_attr "type" "call")])
12591
12592 ;; This covers both call and sibcall since only GOT slot is allowed.
12593 (define_insn "*call_got_x32"
12594 [(call (mem:QI (zero_extend:DI
12595 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12596 (match_operand 1))]
12597 "TARGET_X32"
12598 {
12599 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12600 return ix86_output_call_insn (insn, fnaddr);
12601 }
12602 [(set_attr "type" "call")])
12603
12604 ;; Since sibcall never returns, we can only use call-clobbered register
12605 ;; as GOT base.
12606 (define_insn "*sibcall_GOT_32"
12607 [(call (mem:QI
12608 (mem:SI (plus:SI
12609 (match_operand:SI 0 "register_no_elim_operand" "U")
12610 (match_operand:SI 1 "GOT32_symbol_operand"))))
12611 (match_operand 2))]
12612 "!TARGET_MACHO
12613 && !TARGET_64BIT
12614 && !TARGET_INDIRECT_BRANCH_REGISTER
12615 && SIBLING_CALL_P (insn)"
12616 {
12617 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12618 fnaddr = gen_const_mem (SImode, fnaddr);
12619 return ix86_output_call_insn (insn, fnaddr);
12620 }
12621 [(set_attr "type" "call")])
12622
12623 (define_insn "*sibcall"
12624 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12625 (match_operand 1))]
12626 "SIBLING_CALL_P (insn)"
12627 "* return ix86_output_call_insn (insn, operands[0]);"
12628 [(set_attr "type" "call")])
12629
12630 (define_insn "*sibcall_memory"
12631 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12632 (match_operand 1))
12633 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12634 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12635 "* return ix86_output_call_insn (insn, operands[0]);"
12636 [(set_attr "type" "call")])
12637
12638 (define_peephole2
12639 [(set (match_operand:W 0 "register_operand")
12640 (match_operand:W 1 "memory_operand"))
12641 (call (mem:QI (match_dup 0))
12642 (match_operand 3))]
12643 "!TARGET_X32
12644 && !TARGET_INDIRECT_BRANCH_REGISTER
12645 && SIBLING_CALL_P (peep2_next_insn (1))
12646 && !reg_mentioned_p (operands[0],
12647 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12648 [(parallel [(call (mem:QI (match_dup 1))
12649 (match_dup 3))
12650 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12651
12652 (define_peephole2
12653 [(set (match_operand:W 0 "register_operand")
12654 (match_operand:W 1 "memory_operand"))
12655 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12656 (call (mem:QI (match_dup 0))
12657 (match_operand 3))]
12658 "!TARGET_X32
12659 && !TARGET_INDIRECT_BRANCH_REGISTER
12660 && SIBLING_CALL_P (peep2_next_insn (2))
12661 && !reg_mentioned_p (operands[0],
12662 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12663 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12664 (parallel [(call (mem:QI (match_dup 1))
12665 (match_dup 3))
12666 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12667
12668 (define_expand "call_pop"
12669 [(parallel [(call (match_operand:QI 0)
12670 (match_operand:SI 1))
12671 (set (reg:SI SP_REG)
12672 (plus:SI (reg:SI SP_REG)
12673 (match_operand:SI 3)))])]
12674 "!TARGET_64BIT"
12675 {
12676 ix86_expand_call (NULL, operands[0], operands[1],
12677 operands[2], operands[3], false);
12678 DONE;
12679 })
12680
12681 (define_insn "*call_pop"
12682 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12683 (match_operand 1))
12684 (set (reg:SI SP_REG)
12685 (plus:SI (reg:SI SP_REG)
12686 (match_operand:SI 2 "immediate_operand" "i")))]
12687 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12688 "* return ix86_output_call_insn (insn, operands[0]);"
12689 [(set_attr "type" "call")])
12690
12691 (define_insn "*sibcall_pop"
12692 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12693 (match_operand 1))
12694 (set (reg:SI SP_REG)
12695 (plus:SI (reg:SI SP_REG)
12696 (match_operand:SI 2 "immediate_operand" "i")))]
12697 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12698 "* return ix86_output_call_insn (insn, operands[0]);"
12699 [(set_attr "type" "call")])
12700
12701 (define_insn "*sibcall_pop_memory"
12702 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12703 (match_operand 1))
12704 (set (reg:SI SP_REG)
12705 (plus:SI (reg:SI SP_REG)
12706 (match_operand:SI 2 "immediate_operand" "i")))
12707 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12708 "!TARGET_64BIT"
12709 "* return ix86_output_call_insn (insn, operands[0]);"
12710 [(set_attr "type" "call")])
12711
12712 (define_peephole2
12713 [(set (match_operand:SI 0 "register_operand")
12714 (match_operand:SI 1 "memory_operand"))
12715 (parallel [(call (mem:QI (match_dup 0))
12716 (match_operand 3))
12717 (set (reg:SI SP_REG)
12718 (plus:SI (reg:SI SP_REG)
12719 (match_operand:SI 4 "immediate_operand")))])]
12720 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12721 && !reg_mentioned_p (operands[0],
12722 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12723 [(parallel [(call (mem:QI (match_dup 1))
12724 (match_dup 3))
12725 (set (reg:SI SP_REG)
12726 (plus:SI (reg:SI SP_REG)
12727 (match_dup 4)))
12728 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12729
12730 (define_peephole2
12731 [(set (match_operand:SI 0 "register_operand")
12732 (match_operand:SI 1 "memory_operand"))
12733 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12734 (parallel [(call (mem:QI (match_dup 0))
12735 (match_operand 3))
12736 (set (reg:SI SP_REG)
12737 (plus:SI (reg:SI SP_REG)
12738 (match_operand:SI 4 "immediate_operand")))])]
12739 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12740 && !reg_mentioned_p (operands[0],
12741 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12742 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12743 (parallel [(call (mem:QI (match_dup 1))
12744 (match_dup 3))
12745 (set (reg:SI SP_REG)
12746 (plus:SI (reg:SI SP_REG)
12747 (match_dup 4)))
12748 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12749
12750 ;; Combining simple memory jump instruction
12751
12752 (define_peephole2
12753 [(set (match_operand:W 0 "register_operand")
12754 (match_operand:W 1 "memory_operand"))
12755 (set (pc) (match_dup 0))]
12756 "!TARGET_X32
12757 && !TARGET_INDIRECT_BRANCH_REGISTER
12758 && peep2_reg_dead_p (2, operands[0])"
12759 [(set (pc) (match_dup 1))])
12760
12761 ;; Call subroutine, returning value in operand 0
12762
12763 (define_expand "call_value"
12764 [(set (match_operand 0)
12765 (call (match_operand:QI 1)
12766 (match_operand 2)))
12767 (use (match_operand 3))]
12768 ""
12769 {
12770 ix86_expand_call (operands[0], operands[1], operands[2],
12771 operands[3], NULL, false);
12772 DONE;
12773 })
12774
12775 (define_expand "sibcall_value"
12776 [(set (match_operand 0)
12777 (call (match_operand:QI 1)
12778 (match_operand 2)))
12779 (use (match_operand 3))]
12780 ""
12781 {
12782 ix86_expand_call (operands[0], operands[1], operands[2],
12783 operands[3], NULL, true);
12784 DONE;
12785 })
12786
12787 (define_insn "*call_value"
12788 [(set (match_operand 0)
12789 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12790 (match_operand 2)))]
12791 "!SIBLING_CALL_P (insn)"
12792 "* return ix86_output_call_insn (insn, operands[1]);"
12793 [(set_attr "type" "callv")])
12794
12795 ;; This covers both call and sibcall since only GOT slot is allowed.
12796 (define_insn "*call_value_got_x32"
12797 [(set (match_operand 0)
12798 (call (mem:QI
12799 (zero_extend:DI
12800 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12801 (match_operand 2)))]
12802 "TARGET_X32"
12803 {
12804 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12805 return ix86_output_call_insn (insn, fnaddr);
12806 }
12807 [(set_attr "type" "callv")])
12808
12809 ;; Since sibcall never returns, we can only use call-clobbered register
12810 ;; as GOT base.
12811 (define_insn "*sibcall_value_GOT_32"
12812 [(set (match_operand 0)
12813 (call (mem:QI
12814 (mem:SI (plus:SI
12815 (match_operand:SI 1 "register_no_elim_operand" "U")
12816 (match_operand:SI 2 "GOT32_symbol_operand"))))
12817 (match_operand 3)))]
12818 "!TARGET_MACHO
12819 && !TARGET_64BIT
12820 && !TARGET_INDIRECT_BRANCH_REGISTER
12821 && SIBLING_CALL_P (insn)"
12822 {
12823 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12824 fnaddr = gen_const_mem (SImode, fnaddr);
12825 return ix86_output_call_insn (insn, fnaddr);
12826 }
12827 [(set_attr "type" "callv")])
12828
12829 (define_insn "*sibcall_value"
12830 [(set (match_operand 0)
12831 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12832 (match_operand 2)))]
12833 "SIBLING_CALL_P (insn)"
12834 "* return ix86_output_call_insn (insn, operands[1]);"
12835 [(set_attr "type" "callv")])
12836
12837 (define_insn "*sibcall_value_memory"
12838 [(set (match_operand 0)
12839 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12840 (match_operand 2)))
12841 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12842 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12843 "* return ix86_output_call_insn (insn, operands[1]);"
12844 [(set_attr "type" "callv")])
12845
12846 (define_peephole2
12847 [(set (match_operand:W 0 "register_operand")
12848 (match_operand:W 1 "memory_operand"))
12849 (set (match_operand 2)
12850 (call (mem:QI (match_dup 0))
12851 (match_operand 3)))]
12852 "!TARGET_X32
12853 && !TARGET_INDIRECT_BRANCH_REGISTER
12854 && SIBLING_CALL_P (peep2_next_insn (1))
12855 && !reg_mentioned_p (operands[0],
12856 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12857 [(parallel [(set (match_dup 2)
12858 (call (mem:QI (match_dup 1))
12859 (match_dup 3)))
12860 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12861
12862 (define_peephole2
12863 [(set (match_operand:W 0 "register_operand")
12864 (match_operand:W 1 "memory_operand"))
12865 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12866 (set (match_operand 2)
12867 (call (mem:QI (match_dup 0))
12868 (match_operand 3)))]
12869 "!TARGET_X32
12870 && !TARGET_INDIRECT_BRANCH_REGISTER
12871 && SIBLING_CALL_P (peep2_next_insn (2))
12872 && !reg_mentioned_p (operands[0],
12873 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12874 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12875 (parallel [(set (match_dup 2)
12876 (call (mem:QI (match_dup 1))
12877 (match_dup 3)))
12878 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12879
12880 (define_expand "call_value_pop"
12881 [(parallel [(set (match_operand 0)
12882 (call (match_operand:QI 1)
12883 (match_operand:SI 2)))
12884 (set (reg:SI SP_REG)
12885 (plus:SI (reg:SI SP_REG)
12886 (match_operand:SI 4)))])]
12887 "!TARGET_64BIT"
12888 {
12889 ix86_expand_call (operands[0], operands[1], operands[2],
12890 operands[3], operands[4], false);
12891 DONE;
12892 })
12893
12894 (define_insn "*call_value_pop"
12895 [(set (match_operand 0)
12896 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12897 (match_operand 2)))
12898 (set (reg:SI SP_REG)
12899 (plus:SI (reg:SI SP_REG)
12900 (match_operand:SI 3 "immediate_operand" "i")))]
12901 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12902 "* return ix86_output_call_insn (insn, operands[1]);"
12903 [(set_attr "type" "callv")])
12904
12905 (define_insn "*sibcall_value_pop"
12906 [(set (match_operand 0)
12907 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12908 (match_operand 2)))
12909 (set (reg:SI SP_REG)
12910 (plus:SI (reg:SI SP_REG)
12911 (match_operand:SI 3 "immediate_operand" "i")))]
12912 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12913 "* return ix86_output_call_insn (insn, operands[1]);"
12914 [(set_attr "type" "callv")])
12915
12916 (define_insn "*sibcall_value_pop_memory"
12917 [(set (match_operand 0)
12918 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12919 (match_operand 2)))
12920 (set (reg:SI SP_REG)
12921 (plus:SI (reg:SI SP_REG)
12922 (match_operand:SI 3 "immediate_operand" "i")))
12923 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12924 "!TARGET_64BIT"
12925 "* return ix86_output_call_insn (insn, operands[1]);"
12926 [(set_attr "type" "callv")])
12927
12928 (define_peephole2
12929 [(set (match_operand:SI 0 "register_operand")
12930 (match_operand:SI 1 "memory_operand"))
12931 (parallel [(set (match_operand 2)
12932 (call (mem:QI (match_dup 0))
12933 (match_operand 3)))
12934 (set (reg:SI SP_REG)
12935 (plus:SI (reg:SI SP_REG)
12936 (match_operand:SI 4 "immediate_operand")))])]
12937 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12938 && !reg_mentioned_p (operands[0],
12939 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12940 [(parallel [(set (match_dup 2)
12941 (call (mem:QI (match_dup 1))
12942 (match_dup 3)))
12943 (set (reg:SI SP_REG)
12944 (plus:SI (reg:SI SP_REG)
12945 (match_dup 4)))
12946 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12947
12948 (define_peephole2
12949 [(set (match_operand:SI 0 "register_operand")
12950 (match_operand:SI 1 "memory_operand"))
12951 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12952 (parallel [(set (match_operand 2)
12953 (call (mem:QI (match_dup 0))
12954 (match_operand 3)))
12955 (set (reg:SI SP_REG)
12956 (plus:SI (reg:SI SP_REG)
12957 (match_operand:SI 4 "immediate_operand")))])]
12958 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12959 && !reg_mentioned_p (operands[0],
12960 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12961 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12962 (parallel [(set (match_dup 2)
12963 (call (mem:QI (match_dup 1))
12964 (match_dup 3)))
12965 (set (reg:SI SP_REG)
12966 (plus:SI (reg:SI SP_REG)
12967 (match_dup 4)))
12968 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12969
12970 ;; Call subroutine returning any type.
12971
12972 (define_expand "untyped_call"
12973 [(parallel [(call (match_operand 0)
12974 (const_int 0))
12975 (match_operand 1)
12976 (match_operand 2)])]
12977 ""
12978 {
12979 int i;
12980
12981 /* In order to give reg-stack an easier job in validating two
12982 coprocessor registers as containing a possible return value,
12983 simply pretend the untyped call returns a complex long double
12984 value.
12985
12986 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12987 and should have the default ABI. */
12988
12989 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12990 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12991 operands[0], const0_rtx,
12992 GEN_INT ((TARGET_64BIT
12993 ? (ix86_abi == SYSV_ABI
12994 ? X86_64_SSE_REGPARM_MAX
12995 : X86_64_MS_SSE_REGPARM_MAX)
12996 : X86_32_SSE_REGPARM_MAX)
12997 - 1),
12998 NULL, false);
12999
13000 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13001 {
13002 rtx set = XVECEXP (operands[2], 0, i);
13003 emit_move_insn (SET_DEST (set), SET_SRC (set));
13004 }
13005
13006 /* The optimizer does not know that the call sets the function value
13007 registers we stored in the result block. We avoid problems by
13008 claiming that all hard registers are used and clobbered at this
13009 point. */
13010 emit_insn (gen_blockage ());
13011
13012 DONE;
13013 })
13014 \f
13015 ;; Prologue and epilogue instructions
13016
13017 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13018 ;; all of memory. This blocks insns from being moved across this point.
13019
13020 (define_insn "blockage"
13021 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13022 ""
13023 ""
13024 [(set_attr "length" "0")])
13025
13026 ;; Do not schedule instructions accessing memory across this point.
13027
13028 (define_expand "memory_blockage"
13029 [(set (match_dup 0)
13030 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13031 ""
13032 {
13033 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13034 MEM_VOLATILE_P (operands[0]) = 1;
13035 })
13036
13037 (define_insn "*memory_blockage"
13038 [(set (match_operand:BLK 0)
13039 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13040 ""
13041 ""
13042 [(set_attr "length" "0")])
13043
13044 ;; As USE insns aren't meaningful after reload, this is used instead
13045 ;; to prevent deleting instructions setting registers for PIC code
13046 (define_insn "prologue_use"
13047 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13048 ""
13049 ""
13050 [(set_attr "length" "0")])
13051
13052 ;; Insn emitted into the body of a function to return from a function.
13053 ;; This is only done if the function's epilogue is known to be simple.
13054 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13055
13056 (define_expand "return"
13057 [(simple_return)]
13058 "ix86_can_use_return_insn_p ()"
13059 {
13060 if (crtl->args.pops_args)
13061 {
13062 rtx popc = GEN_INT (crtl->args.pops_args);
13063 emit_jump_insn (gen_simple_return_pop_internal (popc));
13064 DONE;
13065 }
13066 })
13067
13068 ;; We need to disable this for TARGET_SEH, as otherwise
13069 ;; shrink-wrapped prologue gets enabled too. This might exceed
13070 ;; the maximum size of prologue in unwind information.
13071 ;; Also disallow shrink-wrapping if using stack slot to pass the
13072 ;; static chain pointer - the first instruction has to be pushl %esi
13073 ;; and it can't be moved around, as we use alternate entry points
13074 ;; in that case.
13075
13076 (define_expand "simple_return"
13077 [(simple_return)]
13078 "!TARGET_SEH && !ix86_static_chain_on_stack"
13079 {
13080 if (crtl->args.pops_args)
13081 {
13082 rtx popc = GEN_INT (crtl->args.pops_args);
13083 emit_jump_insn (gen_simple_return_pop_internal (popc));
13084 DONE;
13085 }
13086 })
13087
13088 (define_insn "simple_return_internal"
13089 [(simple_return)]
13090 "reload_completed"
13091 "* return ix86_output_function_return (false);"
13092 [(set_attr "length" "1")
13093 (set_attr "atom_unit" "jeu")
13094 (set_attr "length_immediate" "0")
13095 (set_attr "modrm" "0")])
13096
13097 (define_insn "interrupt_return"
13098 [(simple_return)
13099 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13100 "reload_completed"
13101 {
13102 return TARGET_64BIT ? "iretq" : "iret";
13103 })
13104
13105 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13106 ;; instruction Athlon and K8 have.
13107
13108 (define_insn "simple_return_internal_long"
13109 [(simple_return)
13110 (unspec [(const_int 0)] UNSPEC_REP)]
13111 "reload_completed"
13112 "* return ix86_output_function_return (true);"
13113 [(set_attr "length" "2")
13114 (set_attr "atom_unit" "jeu")
13115 (set_attr "length_immediate" "0")
13116 (set_attr "prefix_rep" "1")
13117 (set_attr "modrm" "0")])
13118
13119 (define_insn_and_split "simple_return_pop_internal"
13120 [(simple_return)
13121 (use (match_operand:SI 0 "const_int_operand"))]
13122 "reload_completed"
13123 "%!ret\t%0"
13124 "&& cfun->machine->function_return_type != indirect_branch_keep"
13125 [(const_int 0)]
13126 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13127 [(set_attr "length" "3")
13128 (set_attr "atom_unit" "jeu")
13129 (set_attr "length_immediate" "2")
13130 (set_attr "modrm" "0")])
13131
13132 (define_expand "simple_return_indirect_internal"
13133 [(parallel
13134 [(simple_return)
13135 (use (match_operand 0 "register_operand"))])])
13136
13137 (define_insn "*simple_return_indirect_internal<mode>"
13138 [(simple_return)
13139 (use (match_operand:W 0 "register_operand" "r"))]
13140 "reload_completed"
13141 "* return ix86_output_indirect_function_return (operands[0]);"
13142 [(set (attr "type")
13143 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13144 != indirect_branch_keep)")
13145 (const_string "multi")
13146 (const_string "ibr")))
13147 (set_attr "length_immediate" "0")])
13148
13149 (define_insn "nop"
13150 [(const_int 0)]
13151 ""
13152 "nop"
13153 [(set_attr "length" "1")
13154 (set_attr "length_immediate" "0")
13155 (set_attr "modrm" "0")])
13156
13157 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13158 (define_insn "nops"
13159 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13160 UNSPECV_NOPS)]
13161 "reload_completed"
13162 {
13163 int num = INTVAL (operands[0]);
13164
13165 gcc_assert (IN_RANGE (num, 1, 8));
13166
13167 while (num--)
13168 fputs ("\tnop\n", asm_out_file);
13169
13170 return "";
13171 }
13172 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13173 (set_attr "length_immediate" "0")
13174 (set_attr "modrm" "0")])
13175
13176 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13177 ;; branch prediction penalty for the third jump in a 16-byte
13178 ;; block on K8.
13179
13180 (define_insn "pad"
13181 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13182 ""
13183 {
13184 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13185 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13186 #else
13187 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13188 The align insn is used to avoid 3 jump instructions in the row to improve
13189 branch prediction and the benefits hardly outweigh the cost of extra 8
13190 nops on the average inserted by full alignment pseudo operation. */
13191 #endif
13192 return "";
13193 }
13194 [(set_attr "length" "16")])
13195
13196 (define_expand "prologue"
13197 [(const_int 0)]
13198 ""
13199 "ix86_expand_prologue (); DONE;")
13200
13201 (define_expand "set_got"
13202 [(parallel
13203 [(set (match_operand:SI 0 "register_operand")
13204 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13205 (clobber (reg:CC FLAGS_REG))])]
13206 "!TARGET_64BIT"
13207 {
13208 if (flag_pic && !TARGET_VXWORKS_RTP)
13209 ix86_pc_thunk_call_expanded = true;
13210 })
13211
13212 (define_insn "*set_got"
13213 [(set (match_operand:SI 0 "register_operand" "=r")
13214 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13215 (clobber (reg:CC FLAGS_REG))]
13216 "!TARGET_64BIT"
13217 "* return output_set_got (operands[0], NULL_RTX);"
13218 [(set_attr "type" "multi")
13219 (set_attr "length" "12")])
13220
13221 (define_expand "set_got_labelled"
13222 [(parallel
13223 [(set (match_operand:SI 0 "register_operand")
13224 (unspec:SI [(label_ref (match_operand 1))]
13225 UNSPEC_SET_GOT))
13226 (clobber (reg:CC FLAGS_REG))])]
13227 "!TARGET_64BIT"
13228 {
13229 if (flag_pic && !TARGET_VXWORKS_RTP)
13230 ix86_pc_thunk_call_expanded = true;
13231 })
13232
13233 (define_insn "*set_got_labelled"
13234 [(set (match_operand:SI 0 "register_operand" "=r")
13235 (unspec:SI [(label_ref (match_operand 1))]
13236 UNSPEC_SET_GOT))
13237 (clobber (reg:CC FLAGS_REG))]
13238 "!TARGET_64BIT"
13239 "* return output_set_got (operands[0], operands[1]);"
13240 [(set_attr "type" "multi")
13241 (set_attr "length" "12")])
13242
13243 (define_insn "set_got_rex64"
13244 [(set (match_operand:DI 0 "register_operand" "=r")
13245 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13246 "TARGET_64BIT"
13247 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13248 [(set_attr "type" "lea")
13249 (set_attr "length_address" "4")
13250 (set_attr "mode" "DI")])
13251
13252 (define_insn "set_rip_rex64"
13253 [(set (match_operand:DI 0 "register_operand" "=r")
13254 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13255 "TARGET_64BIT"
13256 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13257 [(set_attr "type" "lea")
13258 (set_attr "length_address" "4")
13259 (set_attr "mode" "DI")])
13260
13261 (define_insn "set_got_offset_rex64"
13262 [(set (match_operand:DI 0 "register_operand" "=r")
13263 (unspec:DI
13264 [(label_ref (match_operand 1))]
13265 UNSPEC_SET_GOT_OFFSET))]
13266 "TARGET_LP64"
13267 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13268 [(set_attr "type" "imov")
13269 (set_attr "length_immediate" "0")
13270 (set_attr "length_address" "8")
13271 (set_attr "mode" "DI")])
13272
13273 (define_expand "epilogue"
13274 [(const_int 0)]
13275 ""
13276 "ix86_expand_epilogue (1); DONE;")
13277
13278 (define_expand "sibcall_epilogue"
13279 [(const_int 0)]
13280 ""
13281 "ix86_expand_epilogue (0); DONE;")
13282
13283 (define_expand "eh_return"
13284 [(use (match_operand 0 "register_operand"))]
13285 ""
13286 {
13287 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13288
13289 /* Tricky bit: we write the address of the handler to which we will
13290 be returning into someone else's stack frame, one word below the
13291 stack address we wish to restore. */
13292 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13293 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13294 /* Return address is always in word_mode. */
13295 tmp = gen_rtx_MEM (word_mode, tmp);
13296 if (GET_MODE (ra) != word_mode)
13297 ra = convert_to_mode (word_mode, ra, 1);
13298 emit_move_insn (tmp, ra);
13299
13300 emit_jump_insn (gen_eh_return_internal ());
13301 emit_barrier ();
13302 DONE;
13303 })
13304
13305 (define_insn_and_split "eh_return_internal"
13306 [(eh_return)]
13307 ""
13308 "#"
13309 "epilogue_completed"
13310 [(const_int 0)]
13311 "ix86_expand_epilogue (2); DONE;")
13312
13313 (define_expand "@leave_<mode>"
13314 [(parallel
13315 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
13316 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
13317 (clobber (mem:BLK (scratch)))])]
13318 ""
13319 "operands[0] = GEN_INT (<MODE_SIZE>);")
13320
13321 (define_insn "*leave"
13322 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13323 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13324 (clobber (mem:BLK (scratch)))]
13325 "!TARGET_64BIT"
13326 "leave"
13327 [(set_attr "type" "leave")])
13328
13329 (define_insn "*leave_rex64"
13330 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13331 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13332 (clobber (mem:BLK (scratch)))]
13333 "TARGET_64BIT"
13334 "leave"
13335 [(set_attr "type" "leave")])
13336 \f
13337 ;; Handle -fsplit-stack.
13338
13339 (define_expand "split_stack_prologue"
13340 [(const_int 0)]
13341 ""
13342 {
13343 ix86_expand_split_stack_prologue ();
13344 DONE;
13345 })
13346
13347 ;; In order to support the call/return predictor, we use a return
13348 ;; instruction which the middle-end doesn't see.
13349 (define_insn "split_stack_return"
13350 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13351 UNSPECV_SPLIT_STACK_RETURN)]
13352 ""
13353 {
13354 if (operands[0] == const0_rtx)
13355 return "ret";
13356 else
13357 return "ret\t%0";
13358 }
13359 [(set_attr "atom_unit" "jeu")
13360 (set_attr "modrm" "0")
13361 (set (attr "length")
13362 (if_then_else (match_operand:SI 0 "const0_operand")
13363 (const_int 1)
13364 (const_int 3)))
13365 (set (attr "length_immediate")
13366 (if_then_else (match_operand:SI 0 "const0_operand")
13367 (const_int 0)
13368 (const_int 2)))])
13369
13370 ;; If there are operand 0 bytes available on the stack, jump to
13371 ;; operand 1.
13372
13373 (define_expand "split_stack_space_check"
13374 [(set (pc) (if_then_else
13375 (ltu (minus (reg SP_REG)
13376 (match_operand 0 "register_operand"))
13377 (match_dup 2))
13378 (label_ref (match_operand 1))
13379 (pc)))]
13380 ""
13381 {
13382 rtx reg = gen_reg_rtx (Pmode);
13383
13384 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13385
13386 operands[2] = ix86_split_stack_guard ();
13387 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13388
13389 DONE;
13390 })
13391 \f
13392 ;; Bit manipulation instructions.
13393
13394 (define_expand "ffs<mode>2"
13395 [(set (match_dup 2) (const_int -1))
13396 (parallel [(set (match_dup 3) (match_dup 4))
13397 (set (match_operand:SWI48 0 "register_operand")
13398 (ctz:SWI48
13399 (match_operand:SWI48 1 "nonimmediate_operand")))])
13400 (set (match_dup 0) (if_then_else:SWI48
13401 (eq (match_dup 3) (const_int 0))
13402 (match_dup 2)
13403 (match_dup 0)))
13404 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13405 (clobber (reg:CC FLAGS_REG))])]
13406 ""
13407 {
13408 machine_mode flags_mode;
13409
13410 if (<MODE>mode == SImode && !TARGET_CMOVE)
13411 {
13412 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13413 DONE;
13414 }
13415
13416 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13417
13418 operands[2] = gen_reg_rtx (<MODE>mode);
13419 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13420 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13421 })
13422
13423 (define_insn_and_split "ffssi2_no_cmove"
13424 [(set (match_operand:SI 0 "register_operand" "=r")
13425 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13426 (clobber (match_scratch:SI 2 "=&q"))
13427 (clobber (reg:CC FLAGS_REG))]
13428 "!TARGET_CMOVE"
13429 "#"
13430 "&& reload_completed"
13431 [(parallel [(set (match_dup 4) (match_dup 5))
13432 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13433 (set (strict_low_part (match_dup 3))
13434 (eq:QI (match_dup 4) (const_int 0)))
13435 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13436 (clobber (reg:CC FLAGS_REG))])
13437 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13438 (clobber (reg:CC FLAGS_REG))])
13439 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13440 (clobber (reg:CC FLAGS_REG))])]
13441 {
13442 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13443
13444 operands[3] = gen_lowpart (QImode, operands[2]);
13445 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13446 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13447
13448 ix86_expand_clear (operands[2]);
13449 })
13450
13451 (define_insn_and_split "*tzcnt<mode>_1"
13452 [(set (reg:CCC FLAGS_REG)
13453 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13454 (const_int 0)))
13455 (set (match_operand:SWI48 0 "register_operand" "=r")
13456 (ctz:SWI48 (match_dup 1)))]
13457 "TARGET_BMI"
13458 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13459 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13460 && optimize_function_for_speed_p (cfun)
13461 && !reg_mentioned_p (operands[0], operands[1])"
13462 [(parallel
13463 [(set (reg:CCC FLAGS_REG)
13464 (compare:CCC (match_dup 1) (const_int 0)))
13465 (set (match_dup 0)
13466 (ctz:SWI48 (match_dup 1)))
13467 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13468 "ix86_expand_clear (operands[0]);"
13469 [(set_attr "type" "alu1")
13470 (set_attr "prefix_0f" "1")
13471 (set_attr "prefix_rep" "1")
13472 (set_attr "btver2_decode" "double")
13473 (set_attr "mode" "<MODE>")])
13474
13475 ; False dependency happens when destination is only updated by tzcnt,
13476 ; lzcnt or popcnt. There is no false dependency when destination is
13477 ; also used in source.
13478 (define_insn "*tzcnt<mode>_1_falsedep"
13479 [(set (reg:CCC FLAGS_REG)
13480 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13481 (const_int 0)))
13482 (set (match_operand:SWI48 0 "register_operand" "=r")
13483 (ctz:SWI48 (match_dup 1)))
13484 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13485 UNSPEC_INSN_FALSE_DEP)]
13486 "TARGET_BMI"
13487 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13488 [(set_attr "type" "alu1")
13489 (set_attr "prefix_0f" "1")
13490 (set_attr "prefix_rep" "1")
13491 (set_attr "btver2_decode" "double")
13492 (set_attr "mode" "<MODE>")])
13493
13494 (define_insn "*bsf<mode>_1"
13495 [(set (reg:CCZ FLAGS_REG)
13496 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13497 (const_int 0)))
13498 (set (match_operand:SWI48 0 "register_operand" "=r")
13499 (ctz:SWI48 (match_dup 1)))]
13500 ""
13501 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13502 [(set_attr "type" "alu1")
13503 (set_attr "prefix_0f" "1")
13504 (set_attr "btver2_decode" "double")
13505 (set_attr "znver1_decode" "vector")
13506 (set_attr "mode" "<MODE>")])
13507
13508 (define_insn_and_split "ctz<mode>2"
13509 [(set (match_operand:SWI48 0 "register_operand" "=r")
13510 (ctz:SWI48
13511 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13512 (clobber (reg:CC FLAGS_REG))]
13513 ""
13514 {
13515 if (TARGET_BMI)
13516 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13517 else if (optimize_function_for_size_p (cfun))
13518 ;
13519 else if (TARGET_GENERIC)
13520 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13521 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13522
13523 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13524 }
13525 "(TARGET_BMI || TARGET_GENERIC)
13526 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13527 && optimize_function_for_speed_p (cfun)
13528 && !reg_mentioned_p (operands[0], operands[1])"
13529 [(parallel
13530 [(set (match_dup 0)
13531 (ctz:SWI48 (match_dup 1)))
13532 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13533 (clobber (reg:CC FLAGS_REG))])]
13534 "ix86_expand_clear (operands[0]);"
13535 [(set_attr "type" "alu1")
13536 (set_attr "prefix_0f" "1")
13537 (set (attr "prefix_rep")
13538 (if_then_else
13539 (ior (match_test "TARGET_BMI")
13540 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13541 (match_test "TARGET_GENERIC")))
13542 (const_string "1")
13543 (const_string "0")))
13544 (set_attr "mode" "<MODE>")])
13545
13546 ; False dependency happens when destination is only updated by tzcnt,
13547 ; lzcnt or popcnt. There is no false dependency when destination is
13548 ; also used in source.
13549 (define_insn "*ctz<mode>2_falsedep"
13550 [(set (match_operand:SWI48 0 "register_operand" "=r")
13551 (ctz:SWI48
13552 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13553 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13554 UNSPEC_INSN_FALSE_DEP)
13555 (clobber (reg:CC FLAGS_REG))]
13556 ""
13557 {
13558 if (TARGET_BMI)
13559 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13560 else if (TARGET_GENERIC)
13561 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13562 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13563 else
13564 gcc_unreachable ();
13565 }
13566 [(set_attr "type" "alu1")
13567 (set_attr "prefix_0f" "1")
13568 (set_attr "prefix_rep" "1")
13569 (set_attr "mode" "<MODE>")])
13570
13571 (define_insn "bsr_rex64"
13572 [(set (match_operand:DI 0 "register_operand" "=r")
13573 (minus:DI (const_int 63)
13574 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13575 (clobber (reg:CC FLAGS_REG))]
13576 "TARGET_64BIT"
13577 "bsr{q}\t{%1, %0|%0, %1}"
13578 [(set_attr "type" "alu1")
13579 (set_attr "prefix_0f" "1")
13580 (set_attr "znver1_decode" "vector")
13581 (set_attr "mode" "DI")])
13582
13583 (define_insn "bsr"
13584 [(set (match_operand:SI 0 "register_operand" "=r")
13585 (minus:SI (const_int 31)
13586 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13587 (clobber (reg:CC FLAGS_REG))]
13588 ""
13589 "bsr{l}\t{%1, %0|%0, %1}"
13590 [(set_attr "type" "alu1")
13591 (set_attr "prefix_0f" "1")
13592 (set_attr "znver1_decode" "vector")
13593 (set_attr "mode" "SI")])
13594
13595 (define_insn "*bsrhi"
13596 [(set (match_operand:HI 0 "register_operand" "=r")
13597 (minus:HI (const_int 15)
13598 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13599 (clobber (reg:CC FLAGS_REG))]
13600 ""
13601 "bsr{w}\t{%1, %0|%0, %1}"
13602 [(set_attr "type" "alu1")
13603 (set_attr "prefix_0f" "1")
13604 (set_attr "znver1_decode" "vector")
13605 (set_attr "mode" "HI")])
13606
13607 (define_expand "clz<mode>2"
13608 [(parallel
13609 [(set (match_operand:SWI48 0 "register_operand")
13610 (minus:SWI48
13611 (match_dup 2)
13612 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13613 (clobber (reg:CC FLAGS_REG))])
13614 (parallel
13615 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13616 (clobber (reg:CC FLAGS_REG))])]
13617 ""
13618 {
13619 if (TARGET_LZCNT)
13620 {
13621 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13622 DONE;
13623 }
13624 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13625 })
13626
13627 (define_insn_and_split "clz<mode>2_lzcnt"
13628 [(set (match_operand:SWI48 0 "register_operand" "=r")
13629 (clz:SWI48
13630 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13631 (clobber (reg:CC FLAGS_REG))]
13632 "TARGET_LZCNT"
13633 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13634 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13635 && optimize_function_for_speed_p (cfun)
13636 && !reg_mentioned_p (operands[0], operands[1])"
13637 [(parallel
13638 [(set (match_dup 0)
13639 (clz:SWI48 (match_dup 1)))
13640 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13641 (clobber (reg:CC FLAGS_REG))])]
13642 "ix86_expand_clear (operands[0]);"
13643 [(set_attr "prefix_rep" "1")
13644 (set_attr "type" "bitmanip")
13645 (set_attr "mode" "<MODE>")])
13646
13647 ; False dependency happens when destination is only updated by tzcnt,
13648 ; lzcnt or popcnt. There is no false dependency when destination is
13649 ; also used in source.
13650 (define_insn "*clz<mode>2_lzcnt_falsedep"
13651 [(set (match_operand:SWI48 0 "register_operand" "=r")
13652 (clz:SWI48
13653 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13654 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13655 UNSPEC_INSN_FALSE_DEP)
13656 (clobber (reg:CC FLAGS_REG))]
13657 "TARGET_LZCNT"
13658 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13659 [(set_attr "prefix_rep" "1")
13660 (set_attr "type" "bitmanip")
13661 (set_attr "mode" "<MODE>")])
13662
13663 (define_int_iterator LT_ZCNT
13664 [(UNSPEC_TZCNT "TARGET_BMI")
13665 (UNSPEC_LZCNT "TARGET_LZCNT")])
13666
13667 (define_int_attr lt_zcnt
13668 [(UNSPEC_TZCNT "tzcnt")
13669 (UNSPEC_LZCNT "lzcnt")])
13670
13671 (define_int_attr lt_zcnt_type
13672 [(UNSPEC_TZCNT "alu1")
13673 (UNSPEC_LZCNT "bitmanip")])
13674
13675 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13676 ;; provides operand size as output when source operand is zero.
13677
13678 (define_insn_and_split "<lt_zcnt>_<mode>"
13679 [(set (match_operand:SWI48 0 "register_operand" "=r")
13680 (unspec:SWI48
13681 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13682 (clobber (reg:CC FLAGS_REG))]
13683 ""
13684 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13685 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13686 && optimize_function_for_speed_p (cfun)
13687 && !reg_mentioned_p (operands[0], operands[1])"
13688 [(parallel
13689 [(set (match_dup 0)
13690 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13691 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13692 (clobber (reg:CC FLAGS_REG))])]
13693 "ix86_expand_clear (operands[0]);"
13694 [(set_attr "type" "<lt_zcnt_type>")
13695 (set_attr "prefix_0f" "1")
13696 (set_attr "prefix_rep" "1")
13697 (set_attr "mode" "<MODE>")])
13698
13699 ; False dependency happens when destination is only updated by tzcnt,
13700 ; lzcnt or popcnt. There is no false dependency when destination is
13701 ; also used in source.
13702 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13703 [(set (match_operand:SWI48 0 "register_operand" "=r")
13704 (unspec:SWI48
13705 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13706 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13707 UNSPEC_INSN_FALSE_DEP)
13708 (clobber (reg:CC FLAGS_REG))]
13709 ""
13710 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13711 [(set_attr "type" "<lt_zcnt_type>")
13712 (set_attr "prefix_0f" "1")
13713 (set_attr "prefix_rep" "1")
13714 (set_attr "mode" "<MODE>")])
13715
13716 (define_insn "<lt_zcnt>_hi"
13717 [(set (match_operand:HI 0 "register_operand" "=r")
13718 (unspec:HI
13719 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13720 (clobber (reg:CC FLAGS_REG))]
13721 ""
13722 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13723 [(set_attr "type" "<lt_zcnt_type>")
13724 (set_attr "prefix_0f" "1")
13725 (set_attr "prefix_rep" "1")
13726 (set_attr "mode" "HI")])
13727
13728 ;; BMI instructions.
13729
13730 (define_insn "bmi_bextr_<mode>"
13731 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13732 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13733 (match_operand:SWI48 2 "register_operand" "r,r")]
13734 UNSPEC_BEXTR))
13735 (clobber (reg:CC FLAGS_REG))]
13736 "TARGET_BMI"
13737 "bextr\t{%2, %1, %0|%0, %1, %2}"
13738 [(set_attr "type" "bitmanip")
13739 (set_attr "btver2_decode" "direct, double")
13740 (set_attr "mode" "<MODE>")])
13741
13742 (define_insn "*bmi_bextr_<mode>_ccz"
13743 [(set (reg:CCZ FLAGS_REG)
13744 (compare:CCZ
13745 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13746 (match_operand:SWI48 2 "register_operand" "r,r")]
13747 UNSPEC_BEXTR)
13748 (const_int 0)))
13749 (clobber (match_scratch:SWI48 0 "=r,r"))]
13750 "TARGET_BMI"
13751 "bextr\t{%2, %1, %0|%0, %1, %2}"
13752 [(set_attr "type" "bitmanip")
13753 (set_attr "btver2_decode" "direct, double")
13754 (set_attr "mode" "<MODE>")])
13755
13756 (define_insn "*bmi_blsi_<mode>"
13757 [(set (match_operand:SWI48 0 "register_operand" "=r")
13758 (and:SWI48
13759 (neg:SWI48
13760 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13761 (match_dup 1)))
13762 (clobber (reg:CC FLAGS_REG))]
13763 "TARGET_BMI"
13764 "blsi\t{%1, %0|%0, %1}"
13765 [(set_attr "type" "bitmanip")
13766 (set_attr "btver2_decode" "double")
13767 (set_attr "mode" "<MODE>")])
13768
13769 (define_insn "*bmi_blsmsk_<mode>"
13770 [(set (match_operand:SWI48 0 "register_operand" "=r")
13771 (xor:SWI48
13772 (plus:SWI48
13773 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13774 (const_int -1))
13775 (match_dup 1)))
13776 (clobber (reg:CC FLAGS_REG))]
13777 "TARGET_BMI"
13778 "blsmsk\t{%1, %0|%0, %1}"
13779 [(set_attr "type" "bitmanip")
13780 (set_attr "btver2_decode" "double")
13781 (set_attr "mode" "<MODE>")])
13782
13783 (define_insn "*bmi_blsr_<mode>"
13784 [(set (match_operand:SWI48 0 "register_operand" "=r")
13785 (and:SWI48
13786 (plus:SWI48
13787 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13788 (const_int -1))
13789 (match_dup 1)))
13790 (clobber (reg:CC FLAGS_REG))]
13791 "TARGET_BMI"
13792 "blsr\t{%1, %0|%0, %1}"
13793 [(set_attr "type" "bitmanip")
13794 (set_attr "btver2_decode" "double")
13795 (set_attr "mode" "<MODE>")])
13796
13797 (define_insn "*bmi_blsr_<mode>_cmp"
13798 [(set (reg:CCZ FLAGS_REG)
13799 (compare:CCZ
13800 (and:SWI48
13801 (plus:SWI48
13802 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13803 (const_int -1))
13804 (match_dup 1))
13805 (const_int 0)))
13806 (set (match_operand:SWI48 0 "register_operand" "=r")
13807 (and:SWI48
13808 (plus:SWI48
13809 (match_dup 1)
13810 (const_int -1))
13811 (match_dup 1)))]
13812 "TARGET_BMI"
13813 "blsr\t{%1, %0|%0, %1}"
13814 [(set_attr "type" "bitmanip")
13815 (set_attr "btver2_decode" "double")
13816 (set_attr "mode" "<MODE>")])
13817
13818 (define_insn "*bmi_blsr_<mode>_ccz"
13819 [(set (reg:CCZ FLAGS_REG)
13820 (compare:CCZ
13821 (and:SWI48
13822 (plus:SWI48
13823 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13824 (const_int -1))
13825 (match_dup 1))
13826 (const_int 0)))
13827 (clobber (match_scratch:SWI48 0 "=r"))]
13828 "TARGET_BMI"
13829 "blsr\t{%1, %0|%0, %1}"
13830 [(set_attr "type" "bitmanip")
13831 (set_attr "btver2_decode" "double")
13832 (set_attr "mode" "<MODE>")])
13833
13834 ;; BMI2 instructions.
13835 (define_expand "bmi2_bzhi_<mode>3"
13836 [(parallel
13837 [(set (match_operand:SWI48 0 "register_operand")
13838 (if_then_else:SWI48
13839 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
13840 (const_int 255))
13841 (const_int 0))
13842 (zero_extract:SWI48
13843 (match_operand:SWI48 1 "nonimmediate_operand")
13844 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13845 (match_dup 3))
13846 (const_int 0))
13847 (const_int 0)))
13848 (clobber (reg:CC FLAGS_REG))])]
13849 "TARGET_BMI2"
13850 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13851
13852 (define_insn "*bmi2_bzhi_<mode>3"
13853 [(set (match_operand:SWI48 0 "register_operand" "=r")
13854 (if_then_else:SWI48
13855 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13856 (const_int 255))
13857 (const_int 0))
13858 (zero_extract:SWI48
13859 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13860 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13861 (match_operand:SWI48 3 "const_int_operand" "n"))
13862 (const_int 0))
13863 (const_int 0)))
13864 (clobber (reg:CC FLAGS_REG))]
13865 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13866 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13867 [(set_attr "type" "bitmanip")
13868 (set_attr "prefix" "vex")
13869 (set_attr "mode" "<MODE>")])
13870
13871 (define_insn "*bmi2_bzhi_<mode>3_1"
13872 [(set (match_operand:SWI48 0 "register_operand" "=r")
13873 (if_then_else:SWI48
13874 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13875 (zero_extract:SWI48
13876 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13877 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13878 (match_operand:SWI48 3 "const_int_operand" "n"))
13879 (const_int 0))
13880 (const_int 0)))
13881 (clobber (reg:CC FLAGS_REG))]
13882 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13883 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13884 [(set_attr "type" "bitmanip")
13885 (set_attr "prefix" "vex")
13886 (set_attr "mode" "<MODE>")])
13887
13888 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13889 [(set (reg:CCZ FLAGS_REG)
13890 (compare:CCZ
13891 (if_then_else:SWI48
13892 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13893 (zero_extract:SWI48
13894 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13895 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13896 (match_operand:SWI48 3 "const_int_operand" "n"))
13897 (const_int 0))
13898 (const_int 0))
13899 (const_int 0)))
13900 (clobber (match_scratch:SWI48 0 "=r"))]
13901 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13902 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13903 [(set_attr "type" "bitmanip")
13904 (set_attr "prefix" "vex")
13905 (set_attr "mode" "<MODE>")])
13906
13907 (define_insn "bmi2_pdep_<mode>3"
13908 [(set (match_operand:SWI48 0 "register_operand" "=r")
13909 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13910 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13911 UNSPEC_PDEP))]
13912 "TARGET_BMI2"
13913 "pdep\t{%2, %1, %0|%0, %1, %2}"
13914 [(set_attr "type" "bitmanip")
13915 (set_attr "prefix" "vex")
13916 (set_attr "mode" "<MODE>")])
13917
13918 (define_insn "bmi2_pext_<mode>3"
13919 [(set (match_operand:SWI48 0 "register_operand" "=r")
13920 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13921 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13922 UNSPEC_PEXT))]
13923 "TARGET_BMI2"
13924 "pext\t{%2, %1, %0|%0, %1, %2}"
13925 [(set_attr "type" "bitmanip")
13926 (set_attr "prefix" "vex")
13927 (set_attr "mode" "<MODE>")])
13928
13929 ;; TBM instructions.
13930 (define_expand "tbm_bextri_<mode>"
13931 [(parallel
13932 [(set (match_operand:SWI48 0 "register_operand")
13933 (zero_extract:SWI48
13934 (match_operand:SWI48 1 "nonimmediate_operand")
13935 (match_operand 2 "const_0_to_255_operand" "N")
13936 (match_operand 3 "const_0_to_255_operand" "N")))
13937 (clobber (reg:CC FLAGS_REG))])]
13938 "TARGET_TBM"
13939 {
13940 if (operands[2] == const0_rtx
13941 || INTVAL (operands[3]) >= <MODE_SIZE> * BITS_PER_UNIT)
13942 {
13943 emit_move_insn (operands[0], const0_rtx);
13944 DONE;
13945 }
13946 if (INTVAL (operands[2]) + INTVAL (operands[3])
13947 > <MODE_SIZE> * BITS_PER_UNIT)
13948 operands[2] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - INTVAL (operands[3]));
13949 })
13950
13951 (define_insn "*tbm_bextri_<mode>"
13952 [(set (match_operand:SWI48 0 "register_operand" "=r")
13953 (zero_extract:SWI48
13954 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13955 (match_operand 2 "const_0_to_255_operand" "N")
13956 (match_operand 3 "const_0_to_255_operand" "N")))
13957 (clobber (reg:CC FLAGS_REG))]
13958 "TARGET_TBM"
13959 {
13960 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13961 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13962 }
13963 [(set_attr "type" "bitmanip")
13964 (set_attr "mode" "<MODE>")])
13965
13966 (define_insn "*tbm_blcfill_<mode>"
13967 [(set (match_operand:SWI48 0 "register_operand" "=r")
13968 (and:SWI48
13969 (plus:SWI48
13970 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13971 (const_int 1))
13972 (match_dup 1)))
13973 (clobber (reg:CC FLAGS_REG))]
13974 "TARGET_TBM"
13975 "blcfill\t{%1, %0|%0, %1}"
13976 [(set_attr "type" "bitmanip")
13977 (set_attr "mode" "<MODE>")])
13978
13979 (define_insn "*tbm_blci_<mode>"
13980 [(set (match_operand:SWI48 0 "register_operand" "=r")
13981 (ior:SWI48
13982 (not:SWI48
13983 (plus:SWI48
13984 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13985 (const_int 1)))
13986 (match_dup 1)))
13987 (clobber (reg:CC FLAGS_REG))]
13988 "TARGET_TBM"
13989 "blci\t{%1, %0|%0, %1}"
13990 [(set_attr "type" "bitmanip")
13991 (set_attr "mode" "<MODE>")])
13992
13993 (define_insn "*tbm_blcic_<mode>"
13994 [(set (match_operand:SWI48 0 "register_operand" "=r")
13995 (and:SWI48
13996 (plus:SWI48
13997 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13998 (const_int 1))
13999 (not:SWI48
14000 (match_dup 1))))
14001 (clobber (reg:CC FLAGS_REG))]
14002 "TARGET_TBM"
14003 "blcic\t{%1, %0|%0, %1}"
14004 [(set_attr "type" "bitmanip")
14005 (set_attr "mode" "<MODE>")])
14006
14007 (define_insn "*tbm_blcmsk_<mode>"
14008 [(set (match_operand:SWI48 0 "register_operand" "=r")
14009 (xor:SWI48
14010 (plus:SWI48
14011 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14012 (const_int 1))
14013 (match_dup 1)))
14014 (clobber (reg:CC FLAGS_REG))]
14015 "TARGET_TBM"
14016 "blcmsk\t{%1, %0|%0, %1}"
14017 [(set_attr "type" "bitmanip")
14018 (set_attr "mode" "<MODE>")])
14019
14020 (define_insn "*tbm_blcs_<mode>"
14021 [(set (match_operand:SWI48 0 "register_operand" "=r")
14022 (ior:SWI48
14023 (plus:SWI48
14024 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14025 (const_int 1))
14026 (match_dup 1)))
14027 (clobber (reg:CC FLAGS_REG))]
14028 "TARGET_TBM"
14029 "blcs\t{%1, %0|%0, %1}"
14030 [(set_attr "type" "bitmanip")
14031 (set_attr "mode" "<MODE>")])
14032
14033 (define_insn "*tbm_blsfill_<mode>"
14034 [(set (match_operand:SWI48 0 "register_operand" "=r")
14035 (ior:SWI48
14036 (plus:SWI48
14037 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14038 (const_int -1))
14039 (match_dup 1)))
14040 (clobber (reg:CC FLAGS_REG))]
14041 "TARGET_TBM"
14042 "blsfill\t{%1, %0|%0, %1}"
14043 [(set_attr "type" "bitmanip")
14044 (set_attr "mode" "<MODE>")])
14045
14046 (define_insn "*tbm_blsic_<mode>"
14047 [(set (match_operand:SWI48 0 "register_operand" "=r")
14048 (ior:SWI48
14049 (plus:SWI48
14050 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14051 (const_int -1))
14052 (not:SWI48
14053 (match_dup 1))))
14054 (clobber (reg:CC FLAGS_REG))]
14055 "TARGET_TBM"
14056 "blsic\t{%1, %0|%0, %1}"
14057 [(set_attr "type" "bitmanip")
14058 (set_attr "mode" "<MODE>")])
14059
14060 (define_insn "*tbm_t1mskc_<mode>"
14061 [(set (match_operand:SWI48 0 "register_operand" "=r")
14062 (ior:SWI48
14063 (plus:SWI48
14064 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14065 (const_int 1))
14066 (not:SWI48
14067 (match_dup 1))))
14068 (clobber (reg:CC FLAGS_REG))]
14069 "TARGET_TBM"
14070 "t1mskc\t{%1, %0|%0, %1}"
14071 [(set_attr "type" "bitmanip")
14072 (set_attr "mode" "<MODE>")])
14073
14074 (define_insn "*tbm_tzmsk_<mode>"
14075 [(set (match_operand:SWI48 0 "register_operand" "=r")
14076 (and:SWI48
14077 (plus:SWI48
14078 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14079 (const_int -1))
14080 (not:SWI48
14081 (match_dup 1))))
14082 (clobber (reg:CC FLAGS_REG))]
14083 "TARGET_TBM"
14084 "tzmsk\t{%1, %0|%0, %1}"
14085 [(set_attr "type" "bitmanip")
14086 (set_attr "mode" "<MODE>")])
14087
14088 (define_insn_and_split "popcount<mode>2"
14089 [(set (match_operand:SWI48 0 "register_operand" "=r")
14090 (popcount:SWI48
14091 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14092 (clobber (reg:CC FLAGS_REG))]
14093 "TARGET_POPCNT"
14094 {
14095 #if TARGET_MACHO
14096 return "popcnt\t{%1, %0|%0, %1}";
14097 #else
14098 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14099 #endif
14100 }
14101 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14102 && optimize_function_for_speed_p (cfun)
14103 && !reg_mentioned_p (operands[0], operands[1])"
14104 [(parallel
14105 [(set (match_dup 0)
14106 (popcount:SWI48 (match_dup 1)))
14107 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14108 (clobber (reg:CC FLAGS_REG))])]
14109 "ix86_expand_clear (operands[0]);"
14110 [(set_attr "prefix_rep" "1")
14111 (set_attr "type" "bitmanip")
14112 (set_attr "mode" "<MODE>")])
14113
14114 ; False dependency happens when destination is only updated by tzcnt,
14115 ; lzcnt or popcnt. There is no false dependency when destination is
14116 ; also used in source.
14117 (define_insn "*popcount<mode>2_falsedep"
14118 [(set (match_operand:SWI48 0 "register_operand" "=r")
14119 (popcount:SWI48
14120 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14121 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14122 UNSPEC_INSN_FALSE_DEP)
14123 (clobber (reg:CC FLAGS_REG))]
14124 "TARGET_POPCNT"
14125 {
14126 #if TARGET_MACHO
14127 return "popcnt\t{%1, %0|%0, %1}";
14128 #else
14129 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14130 #endif
14131 }
14132 [(set_attr "prefix_rep" "1")
14133 (set_attr "type" "bitmanip")
14134 (set_attr "mode" "<MODE>")])
14135
14136 (define_insn_and_split "*popcounthi2_1"
14137 [(set (match_operand:SI 0 "register_operand")
14138 (popcount:SI
14139 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14140 (clobber (reg:CC FLAGS_REG))]
14141 "TARGET_POPCNT
14142 && ix86_pre_reload_split ()"
14143 "#"
14144 "&& 1"
14145 [(const_int 0)]
14146 {
14147 rtx tmp = gen_reg_rtx (HImode);
14148
14149 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14150 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14151 DONE;
14152 })
14153
14154 (define_insn "popcounthi2"
14155 [(set (match_operand:HI 0 "register_operand" "=r")
14156 (popcount:HI
14157 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14158 (clobber (reg:CC FLAGS_REG))]
14159 "TARGET_POPCNT"
14160 {
14161 #if TARGET_MACHO
14162 return "popcnt\t{%1, %0|%0, %1}";
14163 #else
14164 return "popcnt{w}\t{%1, %0|%0, %1}";
14165 #endif
14166 }
14167 [(set_attr "prefix_rep" "1")
14168 (set_attr "type" "bitmanip")
14169 (set_attr "mode" "HI")])
14170
14171 (define_expand "bswapdi2"
14172 [(set (match_operand:DI 0 "register_operand")
14173 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14174 "TARGET_64BIT"
14175 {
14176 if (!TARGET_MOVBE)
14177 operands[1] = force_reg (DImode, operands[1]);
14178 })
14179
14180 (define_expand "bswapsi2"
14181 [(set (match_operand:SI 0 "register_operand")
14182 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14183 ""
14184 {
14185 if (TARGET_MOVBE)
14186 ;
14187 else if (TARGET_BSWAP)
14188 operands[1] = force_reg (SImode, operands[1]);
14189 else
14190 {
14191 rtx x = operands[0];
14192
14193 emit_move_insn (x, operands[1]);
14194 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14195 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14196 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14197 DONE;
14198 }
14199 })
14200
14201 (define_insn "*bswap<mode>2_movbe"
14202 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14203 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14204 "TARGET_MOVBE
14205 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14206 "@
14207 bswap\t%0
14208 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14209 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14210 [(set_attr "type" "bitmanip,imov,imov")
14211 (set_attr "modrm" "0,1,1")
14212 (set_attr "prefix_0f" "*,1,1")
14213 (set_attr "prefix_extra" "*,1,1")
14214 (set_attr "mode" "<MODE>")])
14215
14216 (define_insn "*bswap<mode>2"
14217 [(set (match_operand:SWI48 0 "register_operand" "=r")
14218 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14219 "TARGET_BSWAP"
14220 "bswap\t%0"
14221 [(set_attr "type" "bitmanip")
14222 (set_attr "modrm" "0")
14223 (set_attr "mode" "<MODE>")])
14224
14225 (define_expand "bswaphi2"
14226 [(set (match_operand:HI 0 "register_operand")
14227 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14228 "TARGET_MOVBE")
14229
14230 (define_insn "*bswaphi2_movbe"
14231 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14232 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14233 "TARGET_MOVBE
14234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14235 "@
14236 xchg{b}\t{%h0, %b0|%b0, %h0}
14237 movbe{w}\t{%1, %0|%0, %1}
14238 movbe{w}\t{%1, %0|%0, %1}"
14239 [(set_attr "type" "imov")
14240 (set_attr "modrm" "*,1,1")
14241 (set_attr "prefix_0f" "*,1,1")
14242 (set_attr "prefix_extra" "*,1,1")
14243 (set_attr "pent_pair" "np,*,*")
14244 (set_attr "athlon_decode" "vector,*,*")
14245 (set_attr "amdfam10_decode" "double,*,*")
14246 (set_attr "bdver1_decode" "double,*,*")
14247 (set_attr "mode" "QI,HI,HI")])
14248
14249 (define_peephole2
14250 [(set (match_operand:HI 0 "general_reg_operand")
14251 (bswap:HI (match_dup 0)))]
14252 "TARGET_MOVBE
14253 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14254 && peep2_regno_dead_p (0, FLAGS_REG)"
14255 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14256 (clobber (reg:CC FLAGS_REG))])])
14257
14258 (define_insn "bswaphi_lowpart"
14259 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14260 (bswap:HI (match_dup 0)))
14261 (clobber (reg:CC FLAGS_REG))]
14262 ""
14263 "@
14264 xchg{b}\t{%h0, %b0|%b0, %h0}
14265 rol{w}\t{$8, %0|%0, 8}"
14266 [(set (attr "preferred_for_size")
14267 (cond [(eq_attr "alternative" "0")
14268 (symbol_ref "true")]
14269 (symbol_ref "false")))
14270 (set (attr "preferred_for_speed")
14271 (cond [(eq_attr "alternative" "0")
14272 (symbol_ref "TARGET_USE_XCHGB")]
14273 (symbol_ref "!TARGET_USE_XCHGB")))
14274 (set_attr "length" "2,4")
14275 (set_attr "mode" "QI,HI")])
14276
14277 (define_expand "paritydi2"
14278 [(set (match_operand:DI 0 "register_operand")
14279 (parity:DI (match_operand:DI 1 "register_operand")))]
14280 "! TARGET_POPCNT"
14281 {
14282 rtx scratch = gen_reg_rtx (QImode);
14283
14284 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14285 NULL_RTX, operands[1]));
14286
14287 ix86_expand_setcc (scratch, ORDERED,
14288 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14289
14290 if (TARGET_64BIT)
14291 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14292 else
14293 {
14294 rtx tmp = gen_reg_rtx (SImode);
14295
14296 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14297 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14298 }
14299 DONE;
14300 })
14301
14302 (define_expand "paritysi2"
14303 [(set (match_operand:SI 0 "register_operand")
14304 (parity:SI (match_operand:SI 1 "register_operand")))]
14305 "! TARGET_POPCNT"
14306 {
14307 rtx scratch = gen_reg_rtx (QImode);
14308
14309 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14310
14311 ix86_expand_setcc (scratch, ORDERED,
14312 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14313
14314 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14315 DONE;
14316 })
14317
14318 (define_insn_and_split "paritydi2_cmp"
14319 [(set (reg:CC FLAGS_REG)
14320 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14321 UNSPEC_PARITY))
14322 (clobber (match_scratch:DI 0 "=r"))
14323 (clobber (match_scratch:SI 1 "=&r"))
14324 (clobber (match_scratch:HI 2 "=Q"))]
14325 "! TARGET_POPCNT"
14326 "#"
14327 "&& reload_completed"
14328 [(parallel
14329 [(set (match_dup 1)
14330 (xor:SI (match_dup 1) (match_dup 4)))
14331 (clobber (reg:CC FLAGS_REG))])
14332 (parallel
14333 [(set (reg:CC FLAGS_REG)
14334 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14335 (clobber (match_dup 1))
14336 (clobber (match_dup 2))])]
14337 {
14338 operands[4] = gen_lowpart (SImode, operands[3]);
14339
14340 if (TARGET_64BIT)
14341 {
14342 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14343 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14344 }
14345 else
14346 operands[1] = gen_highpart (SImode, operands[3]);
14347 })
14348
14349 (define_insn_and_split "paritysi2_cmp"
14350 [(set (reg:CC FLAGS_REG)
14351 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14352 UNSPEC_PARITY))
14353 (clobber (match_scratch:SI 0 "=r"))
14354 (clobber (match_scratch:HI 1 "=&Q"))]
14355 "! TARGET_POPCNT"
14356 "#"
14357 "&& reload_completed"
14358 [(parallel
14359 [(set (match_dup 1)
14360 (xor:HI (match_dup 1) (match_dup 3)))
14361 (clobber (reg:CC FLAGS_REG))])
14362 (parallel
14363 [(set (reg:CC FLAGS_REG)
14364 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14365 (clobber (match_dup 1))])]
14366 {
14367 operands[3] = gen_lowpart (HImode, operands[2]);
14368
14369 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14370 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14371 })
14372
14373 (define_insn "*parityhi2_cmp"
14374 [(set (reg:CC FLAGS_REG)
14375 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14376 UNSPEC_PARITY))
14377 (clobber (match_scratch:HI 0 "=Q"))]
14378 "! TARGET_POPCNT"
14379 "xor{b}\t{%h0, %b0|%b0, %h0}"
14380 [(set_attr "length" "2")
14381 (set_attr "mode" "HI")])
14382
14383 \f
14384 ;; Thread-local storage patterns for ELF.
14385 ;;
14386 ;; Note that these code sequences must appear exactly as shown
14387 ;; in order to allow linker relaxation.
14388
14389 (define_insn "*tls_global_dynamic_32_gnu"
14390 [(set (match_operand:SI 0 "register_operand" "=a")
14391 (unspec:SI
14392 [(match_operand:SI 1 "register_operand" "Yb")
14393 (match_operand 2 "tls_symbolic_operand")
14394 (match_operand 3 "constant_call_address_operand" "Bz")
14395 (reg:SI SP_REG)]
14396 UNSPEC_TLS_GD))
14397 (clobber (match_scratch:SI 4 "=d"))
14398 (clobber (match_scratch:SI 5 "=c"))
14399 (clobber (reg:CC FLAGS_REG))]
14400 "!TARGET_64BIT && TARGET_GNU_TLS"
14401 {
14402 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14403 output_asm_insn
14404 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14405 else
14406 output_asm_insn
14407 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14408 if (TARGET_SUN_TLS)
14409 #ifdef HAVE_AS_IX86_TLSGDPLT
14410 return "call\t%a2@tlsgdplt";
14411 #else
14412 return "call\t%p3@plt";
14413 #endif
14414 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14415 return "call\t%P3";
14416 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14417 }
14418 [(set_attr "type" "multi")
14419 (set_attr "length" "12")])
14420
14421 (define_expand "tls_global_dynamic_32"
14422 [(parallel
14423 [(set (match_operand:SI 0 "register_operand")
14424 (unspec:SI [(match_operand:SI 2 "register_operand")
14425 (match_operand 1 "tls_symbolic_operand")
14426 (match_operand 3 "constant_call_address_operand")
14427 (reg:SI SP_REG)]
14428 UNSPEC_TLS_GD))
14429 (clobber (match_scratch:SI 4))
14430 (clobber (match_scratch:SI 5))
14431 (clobber (reg:CC FLAGS_REG))])]
14432 ""
14433 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14434
14435 (define_insn "*tls_global_dynamic_64_<mode>"
14436 [(set (match_operand:P 0 "register_operand" "=a")
14437 (call:P
14438 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14439 (match_operand 3)))
14440 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14441 (reg:P SP_REG)]
14442 UNSPEC_TLS_GD)]
14443 "TARGET_64BIT"
14444 {
14445 if (!TARGET_X32)
14446 /* The .loc directive has effect for 'the immediately following assembly
14447 instruction'. So for a sequence:
14448 .loc f l
14449 .byte x
14450 insn1
14451 the 'immediately following assembly instruction' is insn1.
14452 We want to emit an insn prefix here, but if we use .byte (as shown in
14453 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14454 inside the insn sequence, rather than to the start. After relaxation
14455 of the sequence by the linker, the .loc might point inside an insn.
14456 Use data16 prefix instead, which doesn't have this problem. */
14457 fputs ("\tdata16", asm_out_file);
14458 output_asm_insn
14459 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14460 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14461 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14462 else
14463 fputs (ASM_BYTE "0x66\n", asm_out_file);
14464 fputs ("\trex64\n", asm_out_file);
14465 if (TARGET_SUN_TLS)
14466 return "call\t%p2@plt";
14467 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14468 return "call\t%P2";
14469 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14470 }
14471 [(set_attr "type" "multi")
14472 (set (attr "length")
14473 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14474
14475 (define_insn "*tls_global_dynamic_64_largepic"
14476 [(set (match_operand:DI 0 "register_operand" "=a")
14477 (call:DI
14478 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14479 (match_operand:DI 3 "immediate_operand" "i")))
14480 (match_operand 4)))
14481 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14482 (reg:DI SP_REG)]
14483 UNSPEC_TLS_GD)]
14484 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14485 && GET_CODE (operands[3]) == CONST
14486 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14487 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14488 {
14489 output_asm_insn
14490 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14491 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14492 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14493 return "call\t{*%%rax|rax}";
14494 }
14495 [(set_attr "type" "multi")
14496 (set_attr "length" "22")])
14497
14498 (define_expand "@tls_global_dynamic_64_<mode>"
14499 [(parallel
14500 [(set (match_operand:P 0 "register_operand")
14501 (call:P
14502 (mem:QI (match_operand 2))
14503 (const_int 0)))
14504 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14505 (reg:P SP_REG)]
14506 UNSPEC_TLS_GD)])]
14507 "TARGET_64BIT"
14508 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14509
14510 (define_insn "*tls_local_dynamic_base_32_gnu"
14511 [(set (match_operand:SI 0 "register_operand" "=a")
14512 (unspec:SI
14513 [(match_operand:SI 1 "register_operand" "Yb")
14514 (match_operand 2 "constant_call_address_operand" "Bz")
14515 (reg:SI SP_REG)]
14516 UNSPEC_TLS_LD_BASE))
14517 (clobber (match_scratch:SI 3 "=d"))
14518 (clobber (match_scratch:SI 4 "=c"))
14519 (clobber (reg:CC FLAGS_REG))]
14520 "!TARGET_64BIT && TARGET_GNU_TLS"
14521 {
14522 output_asm_insn
14523 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14524 if (TARGET_SUN_TLS)
14525 {
14526 if (HAVE_AS_IX86_TLSLDMPLT)
14527 return "call\t%&@tlsldmplt";
14528 else
14529 return "call\t%p2@plt";
14530 }
14531 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14532 return "call\t%P2";
14533 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14534 }
14535 [(set_attr "type" "multi")
14536 (set_attr "length" "11")])
14537
14538 (define_expand "tls_local_dynamic_base_32"
14539 [(parallel
14540 [(set (match_operand:SI 0 "register_operand")
14541 (unspec:SI
14542 [(match_operand:SI 1 "register_operand")
14543 (match_operand 2 "constant_call_address_operand")
14544 (reg:SI SP_REG)]
14545 UNSPEC_TLS_LD_BASE))
14546 (clobber (match_scratch:SI 3))
14547 (clobber (match_scratch:SI 4))
14548 (clobber (reg:CC FLAGS_REG))])]
14549 ""
14550 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14551
14552 (define_insn "*tls_local_dynamic_base_64_<mode>"
14553 [(set (match_operand:P 0 "register_operand" "=a")
14554 (call:P
14555 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14556 (match_operand 2)))
14557 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14558 "TARGET_64BIT"
14559 {
14560 output_asm_insn
14561 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14562 if (TARGET_SUN_TLS)
14563 return "call\t%p1@plt";
14564 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14565 return "call\t%P1";
14566 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14567 }
14568 [(set_attr "type" "multi")
14569 (set_attr "length" "12")])
14570
14571 (define_insn "*tls_local_dynamic_base_64_largepic"
14572 [(set (match_operand:DI 0 "register_operand" "=a")
14573 (call:DI
14574 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14575 (match_operand:DI 2 "immediate_operand" "i")))
14576 (match_operand 3)))
14577 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14578 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14579 && GET_CODE (operands[2]) == CONST
14580 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14581 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14582 {
14583 output_asm_insn
14584 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14585 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14586 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14587 return "call\t{*%%rax|rax}";
14588 }
14589 [(set_attr "type" "multi")
14590 (set_attr "length" "22")])
14591
14592 (define_expand "@tls_local_dynamic_base_64_<mode>"
14593 [(parallel
14594 [(set (match_operand:P 0 "register_operand")
14595 (call:P
14596 (mem:QI (match_operand 1))
14597 (const_int 0)))
14598 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14599 "TARGET_64BIT"
14600 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14601
14602 ;; Local dynamic of a single variable is a lose. Show combine how
14603 ;; to convert that back to global dynamic.
14604
14605 (define_insn_and_split "*tls_local_dynamic_32_once"
14606 [(set (match_operand:SI 0 "register_operand" "=a")
14607 (plus:SI
14608 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14609 (match_operand 2 "constant_call_address_operand" "Bz")
14610 (reg:SI SP_REG)]
14611 UNSPEC_TLS_LD_BASE)
14612 (const:SI (unspec:SI
14613 [(match_operand 3 "tls_symbolic_operand")]
14614 UNSPEC_DTPOFF))))
14615 (clobber (match_scratch:SI 4 "=d"))
14616 (clobber (match_scratch:SI 5 "=c"))
14617 (clobber (reg:CC FLAGS_REG))]
14618 ""
14619 "#"
14620 ""
14621 [(parallel
14622 [(set (match_dup 0)
14623 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14624 (reg:SI SP_REG)]
14625 UNSPEC_TLS_GD))
14626 (clobber (match_dup 4))
14627 (clobber (match_dup 5))
14628 (clobber (reg:CC FLAGS_REG))])])
14629
14630 ;; Load and add the thread base pointer from %<tp_seg>:0.
14631 (define_insn_and_split "*load_tp_<mode>"
14632 [(set (match_operand:PTR 0 "register_operand" "=r")
14633 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14634 ""
14635 "#"
14636 ""
14637 [(set (match_dup 0)
14638 (match_dup 1))]
14639 {
14640 addr_space_t as = DEFAULT_TLS_SEG_REG;
14641
14642 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14643 set_mem_addr_space (operands[1], as);
14644 })
14645
14646 (define_insn_and_split "*load_tp_x32_zext"
14647 [(set (match_operand:DI 0 "register_operand" "=r")
14648 (zero_extend:DI
14649 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14650 "TARGET_X32"
14651 "#"
14652 ""
14653 [(set (match_dup 0)
14654 (zero_extend:DI (match_dup 1)))]
14655 {
14656 addr_space_t as = DEFAULT_TLS_SEG_REG;
14657
14658 operands[1] = gen_const_mem (SImode, const0_rtx);
14659 set_mem_addr_space (operands[1], as);
14660 })
14661
14662 (define_insn_and_split "*add_tp_<mode>"
14663 [(set (match_operand:PTR 0 "register_operand" "=r")
14664 (plus:PTR
14665 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14666 (match_operand:PTR 1 "register_operand" "0")))
14667 (clobber (reg:CC FLAGS_REG))]
14668 ""
14669 "#"
14670 ""
14671 [(parallel
14672 [(set (match_dup 0)
14673 (plus:PTR (match_dup 1) (match_dup 2)))
14674 (clobber (reg:CC FLAGS_REG))])]
14675 {
14676 addr_space_t as = DEFAULT_TLS_SEG_REG;
14677
14678 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14679 set_mem_addr_space (operands[2], as);
14680 })
14681
14682 (define_insn_and_split "*add_tp_x32_zext"
14683 [(set (match_operand:DI 0 "register_operand" "=r")
14684 (zero_extend:DI
14685 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14686 (match_operand:SI 1 "register_operand" "0"))))
14687 (clobber (reg:CC FLAGS_REG))]
14688 "TARGET_X32"
14689 "#"
14690 ""
14691 [(parallel
14692 [(set (match_dup 0)
14693 (zero_extend:DI
14694 (plus:SI (match_dup 1) (match_dup 2))))
14695 (clobber (reg:CC FLAGS_REG))])]
14696 {
14697 addr_space_t as = DEFAULT_TLS_SEG_REG;
14698
14699 operands[2] = gen_const_mem (SImode, const0_rtx);
14700 set_mem_addr_space (operands[2], as);
14701 })
14702
14703 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14704 ;; %rax as destination of the initial executable code sequence.
14705 (define_insn "tls_initial_exec_64_sun"
14706 [(set (match_operand:DI 0 "register_operand" "=a")
14707 (unspec:DI
14708 [(match_operand 1 "tls_symbolic_operand")]
14709 UNSPEC_TLS_IE_SUN))
14710 (clobber (reg:CC FLAGS_REG))]
14711 "TARGET_64BIT && TARGET_SUN_TLS"
14712 {
14713 output_asm_insn
14714 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14715 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14716 }
14717 [(set_attr "type" "multi")])
14718
14719 ;; GNU2 TLS patterns can be split.
14720
14721 (define_expand "tls_dynamic_gnu2_32"
14722 [(set (match_dup 3)
14723 (plus:SI (match_operand:SI 2 "register_operand")
14724 (const:SI
14725 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14726 UNSPEC_TLSDESC))))
14727 (parallel
14728 [(set (match_operand:SI 0 "register_operand")
14729 (unspec:SI [(match_dup 1) (match_dup 3)
14730 (match_dup 2) (reg:SI SP_REG)]
14731 UNSPEC_TLSDESC))
14732 (clobber (reg:CC FLAGS_REG))])]
14733 "!TARGET_64BIT && TARGET_GNU2_TLS"
14734 {
14735 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14736 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14737 })
14738
14739 (define_insn "*tls_dynamic_gnu2_lea_32"
14740 [(set (match_operand:SI 0 "register_operand" "=r")
14741 (plus:SI (match_operand:SI 1 "register_operand" "b")
14742 (const:SI
14743 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14744 UNSPEC_TLSDESC))))]
14745 "!TARGET_64BIT && TARGET_GNU2_TLS"
14746 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14747 [(set_attr "type" "lea")
14748 (set_attr "mode" "SI")
14749 (set_attr "length" "6")
14750 (set_attr "length_address" "4")])
14751
14752 (define_insn "*tls_dynamic_gnu2_call_32"
14753 [(set (match_operand:SI 0 "register_operand" "=a")
14754 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14755 (match_operand:SI 2 "register_operand" "0")
14756 ;; we have to make sure %ebx still points to the GOT
14757 (match_operand:SI 3 "register_operand" "b")
14758 (reg:SI SP_REG)]
14759 UNSPEC_TLSDESC))
14760 (clobber (reg:CC FLAGS_REG))]
14761 "!TARGET_64BIT && TARGET_GNU2_TLS"
14762 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14763 [(set_attr "type" "call")
14764 (set_attr "length" "2")
14765 (set_attr "length_address" "0")])
14766
14767 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14768 [(set (match_operand:SI 0 "register_operand" "=&a")
14769 (plus:SI
14770 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14771 (match_operand:SI 4)
14772 (match_operand:SI 2 "register_operand" "b")
14773 (reg:SI SP_REG)]
14774 UNSPEC_TLSDESC)
14775 (const:SI (unspec:SI
14776 [(match_operand 1 "tls_symbolic_operand")]
14777 UNSPEC_DTPOFF))))
14778 (clobber (reg:CC FLAGS_REG))]
14779 "!TARGET_64BIT && TARGET_GNU2_TLS"
14780 "#"
14781 ""
14782 [(set (match_dup 0) (match_dup 5))]
14783 {
14784 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14785 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14786 })
14787
14788 (define_expand "tls_dynamic_gnu2_64"
14789 [(set (match_dup 2)
14790 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14791 UNSPEC_TLSDESC))
14792 (parallel
14793 [(set (match_operand:DI 0 "register_operand")
14794 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14795 UNSPEC_TLSDESC))
14796 (clobber (reg:CC FLAGS_REG))])]
14797 "TARGET_64BIT && TARGET_GNU2_TLS"
14798 {
14799 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14800 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14801 })
14802
14803 (define_insn "*tls_dynamic_gnu2_lea_64"
14804 [(set (match_operand:DI 0 "register_operand" "=r")
14805 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14806 UNSPEC_TLSDESC))]
14807 "TARGET_64BIT && TARGET_GNU2_TLS"
14808 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14809 [(set_attr "type" "lea")
14810 (set_attr "mode" "DI")
14811 (set_attr "length" "7")
14812 (set_attr "length_address" "4")])
14813
14814 (define_insn "*tls_dynamic_gnu2_call_64"
14815 [(set (match_operand:DI 0 "register_operand" "=a")
14816 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14817 (match_operand:DI 2 "register_operand" "0")
14818 (reg:DI SP_REG)]
14819 UNSPEC_TLSDESC))
14820 (clobber (reg:CC FLAGS_REG))]
14821 "TARGET_64BIT && TARGET_GNU2_TLS"
14822 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14823 [(set_attr "type" "call")
14824 (set_attr "length" "2")
14825 (set_attr "length_address" "0")])
14826
14827 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14828 [(set (match_operand:DI 0 "register_operand" "=&a")
14829 (plus:DI
14830 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14831 (match_operand:DI 3)
14832 (reg:DI SP_REG)]
14833 UNSPEC_TLSDESC)
14834 (const:DI (unspec:DI
14835 [(match_operand 1 "tls_symbolic_operand")]
14836 UNSPEC_DTPOFF))))
14837 (clobber (reg:CC FLAGS_REG))]
14838 "TARGET_64BIT && TARGET_GNU2_TLS"
14839 "#"
14840 ""
14841 [(set (match_dup 0) (match_dup 4))]
14842 {
14843 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14844 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14845 })
14846
14847 (define_split
14848 [(match_operand 0 "tls_address_pattern")]
14849 "TARGET_TLS_DIRECT_SEG_REFS"
14850 [(match_dup 0)]
14851 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14852
14853 \f
14854 ;; These patterns match the binary 387 instructions for addM3, subM3,
14855 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14856 ;; SFmode. The first is the normal insn, the second the same insn but
14857 ;; with one operand a conversion, and the third the same insn but with
14858 ;; the other operand a conversion. The conversion may be SFmode or
14859 ;; SImode if the target mode DFmode, but only SImode if the target mode
14860 ;; is SFmode.
14861
14862 ;; Gcc is slightly more smart about handling normal two address instructions
14863 ;; so use special patterns for add and mull.
14864
14865 (define_insn "*fop_xf_comm_i387"
14866 [(set (match_operand:XF 0 "register_operand" "=f")
14867 (match_operator:XF 3 "binary_fp_operator"
14868 [(match_operand:XF 1 "register_operand" "%0")
14869 (match_operand:XF 2 "register_operand" "f")]))]
14870 "TARGET_80387
14871 && COMMUTATIVE_ARITH_P (operands[3])"
14872 "* return output_387_binary_op (insn, operands);"
14873 [(set (attr "type")
14874 (if_then_else (match_operand:XF 3 "mult_operator")
14875 (const_string "fmul")
14876 (const_string "fop")))
14877 (set_attr "mode" "XF")])
14878
14879 (define_insn "*fop_<mode>_comm"
14880 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14881 (match_operator:MODEF 3 "binary_fp_operator"
14882 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14883 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14884 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14885 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14886 && COMMUTATIVE_ARITH_P (operands[3])
14887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14888 "* return output_387_binary_op (insn, operands);"
14889 [(set (attr "type")
14890 (if_then_else (eq_attr "alternative" "1,2")
14891 (if_then_else (match_operand:MODEF 3 "mult_operator")
14892 (const_string "ssemul")
14893 (const_string "sseadd"))
14894 (if_then_else (match_operand:MODEF 3 "mult_operator")
14895 (const_string "fmul")
14896 (const_string "fop"))))
14897 (set_attr "isa" "*,noavx,avx")
14898 (set_attr "prefix" "orig,orig,vex")
14899 (set_attr "mode" "<MODE>")
14900 (set (attr "enabled")
14901 (if_then_else
14902 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14903 (if_then_else
14904 (eq_attr "alternative" "0")
14905 (symbol_ref "TARGET_MIX_SSE_I387
14906 && X87_ENABLE_ARITH (<MODE>mode)")
14907 (const_string "*"))
14908 (if_then_else
14909 (eq_attr "alternative" "0")
14910 (symbol_ref "true")
14911 (symbol_ref "false"))))])
14912
14913 (define_insn "*rcpsf2_sse"
14914 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14915 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14916 UNSPEC_RCP))]
14917 "TARGET_SSE && TARGET_SSE_MATH"
14918 "@
14919 %vrcpss\t{%d1, %0|%0, %d1}
14920 %vrcpss\t{%d1, %0|%0, %d1}
14921 %vrcpss\t{%1, %d0|%d0, %1}"
14922 [(set_attr "type" "sse")
14923 (set_attr "atom_sse_attr" "rcp")
14924 (set_attr "btver2_sse_attr" "rcp")
14925 (set_attr "prefix" "maybe_vex")
14926 (set_attr "mode" "SF")
14927 (set_attr "avx_partial_xmm_update" "false,false,true")
14928 (set (attr "preferred_for_speed")
14929 (cond [(match_test "TARGET_AVX")
14930 (symbol_ref "true")
14931 (eq_attr "alternative" "1,2")
14932 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14933 ]
14934 (symbol_ref "true")))])
14935
14936 (define_insn "*fop_xf_1_i387"
14937 [(set (match_operand:XF 0 "register_operand" "=f,f")
14938 (match_operator:XF 3 "binary_fp_operator"
14939 [(match_operand:XF 1 "register_operand" "0,f")
14940 (match_operand:XF 2 "register_operand" "f,0")]))]
14941 "TARGET_80387
14942 && !COMMUTATIVE_ARITH_P (operands[3])"
14943 "* return output_387_binary_op (insn, operands);"
14944 [(set (attr "type")
14945 (if_then_else (match_operand:XF 3 "div_operator")
14946 (const_string "fdiv")
14947 (const_string "fop")))
14948 (set_attr "mode" "XF")])
14949
14950 (define_insn "*fop_<mode>_1"
14951 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14952 (match_operator:MODEF 3 "binary_fp_operator"
14953 [(match_operand:MODEF 1
14954 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14955 (match_operand:MODEF 2
14956 "nonimmediate_operand" "fm,0,xm,vm")]))]
14957 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14958 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14959 && !COMMUTATIVE_ARITH_P (operands[3])
14960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14961 "* return output_387_binary_op (insn, operands);"
14962 [(set (attr "type")
14963 (if_then_else (eq_attr "alternative" "2,3")
14964 (if_then_else (match_operand:MODEF 3 "div_operator")
14965 (const_string "ssediv")
14966 (const_string "sseadd"))
14967 (if_then_else (match_operand:MODEF 3 "div_operator")
14968 (const_string "fdiv")
14969 (const_string "fop"))))
14970 (set_attr "isa" "*,*,noavx,avx")
14971 (set_attr "prefix" "orig,orig,orig,vex")
14972 (set_attr "mode" "<MODE>")
14973 (set (attr "enabled")
14974 (if_then_else
14975 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14976 (if_then_else
14977 (eq_attr "alternative" "0,1")
14978 (symbol_ref "TARGET_MIX_SSE_I387
14979 && X87_ENABLE_ARITH (<MODE>mode)")
14980 (const_string "*"))
14981 (if_then_else
14982 (eq_attr "alternative" "0,1")
14983 (symbol_ref "true")
14984 (symbol_ref "false"))))])
14985
14986 (define_insn "*fop_<X87MODEF:mode>_2_i387"
14987 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14988 (match_operator:X87MODEF 3 "binary_fp_operator"
14989 [(float:X87MODEF
14990 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14991 (match_operand:X87MODEF 2 "register_operand" "0")]))]
14992 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14993 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14994 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14995 || optimize_function_for_size_p (cfun))"
14996 "* return output_387_binary_op (insn, operands);"
14997 [(set (attr "type")
14998 (cond [(match_operand:X87MODEF 3 "mult_operator")
14999 (const_string "fmul")
15000 (match_operand:X87MODEF 3 "div_operator")
15001 (const_string "fdiv")
15002 ]
15003 (const_string "fop")))
15004 (set_attr "fp_int_src" "true")
15005 (set_attr "mode" "<SWI24:MODE>")])
15006
15007 (define_insn "*fop_<X87MODEF:mode>_3_i387"
15008 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15009 (match_operator:X87MODEF 3 "binary_fp_operator"
15010 [(match_operand:X87MODEF 1 "register_operand" "0")
15011 (float:X87MODEF
15012 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15013 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
15014 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15015 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15016 || optimize_function_for_size_p (cfun))"
15017 "* return output_387_binary_op (insn, operands);"
15018 [(set (attr "type")
15019 (cond [(match_operand:X87MODEF 3 "mult_operator")
15020 (const_string "fmul")
15021 (match_operand:X87MODEF 3 "div_operator")
15022 (const_string "fdiv")
15023 ]
15024 (const_string "fop")))
15025 (set_attr "fp_int_src" "true")
15026 (set_attr "mode" "<SWI24:MODE>")])
15027
15028 (define_insn "*fop_xf_4_i387"
15029 [(set (match_operand:XF 0 "register_operand" "=f,f")
15030 (match_operator:XF 3 "binary_fp_operator"
15031 [(float_extend:XF
15032 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15033 (match_operand:XF 2 "register_operand" "0,f")]))]
15034 "TARGET_80387"
15035 "* return output_387_binary_op (insn, operands);"
15036 [(set (attr "type")
15037 (cond [(match_operand:XF 3 "mult_operator")
15038 (const_string "fmul")
15039 (match_operand:XF 3 "div_operator")
15040 (const_string "fdiv")
15041 ]
15042 (const_string "fop")))
15043 (set_attr "mode" "<MODE>")])
15044
15045 (define_insn "*fop_df_4_i387"
15046 [(set (match_operand:DF 0 "register_operand" "=f,f")
15047 (match_operator:DF 3 "binary_fp_operator"
15048 [(float_extend:DF
15049 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15050 (match_operand:DF 2 "register_operand" "0,f")]))]
15051 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15052 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15053 "* return output_387_binary_op (insn, operands);"
15054 [(set (attr "type")
15055 (cond [(match_operand:DF 3 "mult_operator")
15056 (const_string "fmul")
15057 (match_operand:DF 3 "div_operator")
15058 (const_string "fdiv")
15059 ]
15060 (const_string "fop")))
15061 (set_attr "mode" "SF")])
15062
15063 (define_insn "*fop_xf_5_i387"
15064 [(set (match_operand:XF 0 "register_operand" "=f,f")
15065 (match_operator:XF 3 "binary_fp_operator"
15066 [(match_operand:XF 1 "register_operand" "0,f")
15067 (float_extend:XF
15068 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15069 "TARGET_80387"
15070 "* return output_387_binary_op (insn, operands);"
15071 [(set (attr "type")
15072 (cond [(match_operand:XF 3 "mult_operator")
15073 (const_string "fmul")
15074 (match_operand:XF 3 "div_operator")
15075 (const_string "fdiv")
15076 ]
15077 (const_string "fop")))
15078 (set_attr "mode" "<MODE>")])
15079
15080 (define_insn "*fop_df_5_i387"
15081 [(set (match_operand:DF 0 "register_operand" "=f,f")
15082 (match_operator:DF 3 "binary_fp_operator"
15083 [(match_operand:DF 1 "register_operand" "0,f")
15084 (float_extend:DF
15085 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15086 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15087 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15088 "* return output_387_binary_op (insn, operands);"
15089 [(set (attr "type")
15090 (cond [(match_operand:DF 3 "mult_operator")
15091 (const_string "fmul")
15092 (match_operand:DF 3 "div_operator")
15093 (const_string "fdiv")
15094 ]
15095 (const_string "fop")))
15096 (set_attr "mode" "SF")])
15097
15098 (define_insn "*fop_xf_6_i387"
15099 [(set (match_operand:XF 0 "register_operand" "=f,f")
15100 (match_operator:XF 3 "binary_fp_operator"
15101 [(float_extend:XF
15102 (match_operand:MODEF 1 "register_operand" "0,f"))
15103 (float_extend:XF
15104 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15105 "TARGET_80387"
15106 "* return output_387_binary_op (insn, operands);"
15107 [(set (attr "type")
15108 (cond [(match_operand:XF 3 "mult_operator")
15109 (const_string "fmul")
15110 (match_operand:XF 3 "div_operator")
15111 (const_string "fdiv")
15112 ]
15113 (const_string "fop")))
15114 (set_attr "mode" "<MODE>")])
15115
15116 (define_insn "*fop_df_6_i387"
15117 [(set (match_operand:DF 0 "register_operand" "=f,f")
15118 (match_operator:DF 3 "binary_fp_operator"
15119 [(float_extend:DF
15120 (match_operand:SF 1 "register_operand" "0,f"))
15121 (float_extend:DF
15122 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15123 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15124 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15125 "* return output_387_binary_op (insn, operands);"
15126 [(set (attr "type")
15127 (cond [(match_operand:DF 3 "mult_operator")
15128 (const_string "fmul")
15129 (match_operand:DF 3 "div_operator")
15130 (const_string "fdiv")
15131 ]
15132 (const_string "fop")))
15133 (set_attr "mode" "SF")])
15134 \f
15135 ;; FPU special functions.
15136
15137 ;; This pattern implements a no-op XFmode truncation for
15138 ;; all fancy i386 XFmode math functions.
15139
15140 (define_insn "truncxf<mode>2_i387_noop_unspec"
15141 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
15142 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15143 UNSPEC_TRUNC_NOOP))]
15144 "TARGET_USE_FANCY_MATH_387"
15145 "* return output_387_reg_move (insn, operands);"
15146 [(set_attr "type" "fmov")
15147 (set_attr "mode" "<MODE>")])
15148
15149 (define_insn "sqrtxf2"
15150 [(set (match_operand:XF 0 "register_operand" "=f")
15151 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15152 "TARGET_USE_FANCY_MATH_387"
15153 "fsqrt"
15154 [(set_attr "type" "fpspc")
15155 (set_attr "mode" "XF")
15156 (set_attr "athlon_decode" "direct")
15157 (set_attr "amdfam10_decode" "direct")
15158 (set_attr "bdver1_decode" "direct")])
15159
15160 (define_insn "*rsqrtsf2_sse"
15161 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
15162 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
15163 UNSPEC_RSQRT))]
15164 "TARGET_SSE && TARGET_SSE_MATH"
15165 "@
15166 %vrsqrtss\t{%d1, %0|%0, %d1}
15167 %vrsqrtss\t{%d1, %0|%0, %d1}
15168 %vrsqrtss\t{%1, %d0|%d0, %1}"
15169 [(set_attr "type" "sse")
15170 (set_attr "atom_sse_attr" "rcp")
15171 (set_attr "btver2_sse_attr" "rcp")
15172 (set_attr "prefix" "maybe_vex")
15173 (set_attr "mode" "SF")
15174 (set_attr "avx_partial_xmm_update" "false,false,true")
15175 (set (attr "preferred_for_speed")
15176 (cond [(match_test "TARGET_AVX")
15177 (symbol_ref "true")
15178 (eq_attr "alternative" "1,2")
15179 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15180 ]
15181 (symbol_ref "true")))])
15182
15183 (define_expand "rsqrtsf2"
15184 [(set (match_operand:SF 0 "register_operand")
15185 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15186 UNSPEC_RSQRT))]
15187 "TARGET_SSE && TARGET_SSE_MATH"
15188 {
15189 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15190 DONE;
15191 })
15192
15193 (define_insn "*sqrt<mode>2_sse"
15194 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
15195 (sqrt:MODEF
15196 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
15197 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15198 "@
15199 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15200 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15201 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15202 [(set_attr "type" "sse")
15203 (set_attr "atom_sse_attr" "sqrt")
15204 (set_attr "btver2_sse_attr" "sqrt")
15205 (set_attr "prefix" "maybe_vex")
15206 (set_attr "avx_partial_xmm_update" "false,false,true")
15207 (set_attr "mode" "<MODE>")
15208 (set (attr "preferred_for_speed")
15209 (cond [(match_test "TARGET_AVX")
15210 (symbol_ref "true")
15211 (eq_attr "alternative" "1,2")
15212 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15213 ]
15214 (symbol_ref "true")))])
15215
15216 (define_expand "sqrt<mode>2"
15217 [(set (match_operand:MODEF 0 "register_operand")
15218 (sqrt:MODEF
15219 (match_operand:MODEF 1 "nonimmediate_operand")))]
15220 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15221 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15222 {
15223 if (<MODE>mode == SFmode
15224 && TARGET_SSE && TARGET_SSE_MATH
15225 && TARGET_RECIP_SQRT
15226 && !optimize_function_for_size_p (cfun)
15227 && flag_finite_math_only && !flag_trapping_math
15228 && flag_unsafe_math_optimizations)
15229 {
15230 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15231 DONE;
15232 }
15233
15234 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15235 {
15236 rtx op0 = gen_reg_rtx (XFmode);
15237 rtx op1 = gen_reg_rtx (XFmode);
15238
15239 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15240 emit_insn (gen_sqrtxf2 (op0, op1));
15241 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15242 DONE;
15243 }
15244 })
15245
15246 (define_expand "hypot<mode>3"
15247 [(use (match_operand:MODEF 0 "register_operand"))
15248 (use (match_operand:MODEF 1 "general_operand"))
15249 (use (match_operand:MODEF 2 "general_operand"))]
15250 "TARGET_USE_FANCY_MATH_387
15251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15252 || TARGET_MIX_SSE_I387)
15253 && flag_finite_math_only
15254 && flag_unsafe_math_optimizations"
15255 {
15256 rtx op0 = gen_reg_rtx (XFmode);
15257 rtx op1 = gen_reg_rtx (XFmode);
15258 rtx op2 = gen_reg_rtx (XFmode);
15259
15260 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15261 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15262
15263 emit_insn (gen_mulxf3 (op1, op1, op1));
15264 emit_insn (gen_mulxf3 (op2, op2, op2));
15265 emit_insn (gen_addxf3 (op0, op2, op1));
15266 emit_insn (gen_sqrtxf2 (op0, op0));
15267
15268 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15269 DONE;
15270 })
15271
15272 (define_insn "x86_fnstsw_1"
15273 [(set (match_operand:HI 0 "register_operand" "=a")
15274 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
15275 "TARGET_80387"
15276 "fnstsw\t%0"
15277 [(set_attr "length" "2")
15278 (set_attr "mode" "SI")
15279 (set_attr "unit" "i387")])
15280
15281 (define_insn "fpremxf4_i387"
15282 [(set (match_operand:XF 0 "register_operand" "=f")
15283 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15284 (match_operand:XF 3 "register_operand" "1")]
15285 UNSPEC_FPREM_F))
15286 (set (match_operand:XF 1 "register_operand" "=f")
15287 (unspec:XF [(match_dup 2) (match_dup 3)]
15288 UNSPEC_FPREM_U))
15289 (set (reg:CCFP FPSR_REG)
15290 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15291 UNSPEC_C2_FLAG))]
15292 "TARGET_USE_FANCY_MATH_387
15293 && flag_finite_math_only"
15294 "fprem"
15295 [(set_attr "type" "fpspc")
15296 (set_attr "znver1_decode" "vector")
15297 (set_attr "mode" "XF")])
15298
15299 (define_expand "fmodxf3"
15300 [(use (match_operand:XF 0 "register_operand"))
15301 (use (match_operand:XF 1 "general_operand"))
15302 (use (match_operand:XF 2 "general_operand"))]
15303 "TARGET_USE_FANCY_MATH_387
15304 && flag_finite_math_only"
15305 {
15306 rtx_code_label *label = gen_label_rtx ();
15307
15308 rtx op1 = gen_reg_rtx (XFmode);
15309 rtx op2 = gen_reg_rtx (XFmode);
15310
15311 emit_move_insn (op2, operands[2]);
15312 emit_move_insn (op1, operands[1]);
15313
15314 emit_label (label);
15315 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15316 ix86_emit_fp_unordered_jump (label);
15317 LABEL_NUSES (label) = 1;
15318
15319 emit_move_insn (operands[0], op1);
15320 DONE;
15321 })
15322
15323 (define_expand "fmod<mode>3"
15324 [(use (match_operand:MODEF 0 "register_operand"))
15325 (use (match_operand:MODEF 1 "general_operand"))
15326 (use (match_operand:MODEF 2 "general_operand"))]
15327 "TARGET_USE_FANCY_MATH_387
15328 && flag_finite_math_only"
15329 {
15330 rtx (*gen_truncxf) (rtx, rtx);
15331
15332 rtx_code_label *label = gen_label_rtx ();
15333
15334 rtx op1 = gen_reg_rtx (XFmode);
15335 rtx op2 = gen_reg_rtx (XFmode);
15336
15337 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15338 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15339
15340 emit_label (label);
15341 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15342 ix86_emit_fp_unordered_jump (label);
15343 LABEL_NUSES (label) = 1;
15344
15345 /* Truncate the result properly for strict SSE math. */
15346 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15347 && !TARGET_MIX_SSE_I387)
15348 gen_truncxf = gen_truncxf<mode>2;
15349 else
15350 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15351
15352 emit_insn (gen_truncxf (operands[0], op1));
15353 DONE;
15354 })
15355
15356 (define_insn "fprem1xf4_i387"
15357 [(set (match_operand:XF 0 "register_operand" "=f")
15358 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15359 (match_operand:XF 3 "register_operand" "1")]
15360 UNSPEC_FPREM1_F))
15361 (set (match_operand:XF 1 "register_operand" "=f")
15362 (unspec:XF [(match_dup 2) (match_dup 3)]
15363 UNSPEC_FPREM1_U))
15364 (set (reg:CCFP FPSR_REG)
15365 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15366 UNSPEC_C2_FLAG))]
15367 "TARGET_USE_FANCY_MATH_387
15368 && flag_finite_math_only"
15369 "fprem1"
15370 [(set_attr "type" "fpspc")
15371 (set_attr "znver1_decode" "vector")
15372 (set_attr "mode" "XF")])
15373
15374 (define_expand "remainderxf3"
15375 [(use (match_operand:XF 0 "register_operand"))
15376 (use (match_operand:XF 1 "general_operand"))
15377 (use (match_operand:XF 2 "general_operand"))]
15378 "TARGET_USE_FANCY_MATH_387
15379 && flag_finite_math_only"
15380 {
15381 rtx_code_label *label = gen_label_rtx ();
15382
15383 rtx op1 = gen_reg_rtx (XFmode);
15384 rtx op2 = gen_reg_rtx (XFmode);
15385
15386 emit_move_insn (op2, operands[2]);
15387 emit_move_insn (op1, operands[1]);
15388
15389 emit_label (label);
15390 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15391 ix86_emit_fp_unordered_jump (label);
15392 LABEL_NUSES (label) = 1;
15393
15394 emit_move_insn (operands[0], op1);
15395 DONE;
15396 })
15397
15398 (define_expand "remainder<mode>3"
15399 [(use (match_operand:MODEF 0 "register_operand"))
15400 (use (match_operand:MODEF 1 "general_operand"))
15401 (use (match_operand:MODEF 2 "general_operand"))]
15402 "TARGET_USE_FANCY_MATH_387
15403 && flag_finite_math_only"
15404 {
15405 rtx (*gen_truncxf) (rtx, rtx);
15406
15407 rtx_code_label *label = gen_label_rtx ();
15408
15409 rtx op1 = gen_reg_rtx (XFmode);
15410 rtx op2 = gen_reg_rtx (XFmode);
15411
15412 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15413 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15414
15415 emit_label (label);
15416
15417 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15418 ix86_emit_fp_unordered_jump (label);
15419 LABEL_NUSES (label) = 1;
15420
15421 /* Truncate the result properly for strict SSE math. */
15422 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15423 && !TARGET_MIX_SSE_I387)
15424 gen_truncxf = gen_truncxf<mode>2;
15425 else
15426 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15427
15428 emit_insn (gen_truncxf (operands[0], op1));
15429 DONE;
15430 })
15431
15432 (define_int_iterator SINCOS
15433 [UNSPEC_SIN
15434 UNSPEC_COS])
15435
15436 (define_int_attr sincos
15437 [(UNSPEC_SIN "sin")
15438 (UNSPEC_COS "cos")])
15439
15440 (define_insn "<sincos>xf2"
15441 [(set (match_operand:XF 0 "register_operand" "=f")
15442 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15443 SINCOS))]
15444 "TARGET_USE_FANCY_MATH_387
15445 && flag_unsafe_math_optimizations"
15446 "f<sincos>"
15447 [(set_attr "type" "fpspc")
15448 (set_attr "znver1_decode" "vector")
15449 (set_attr "mode" "XF")])
15450
15451 (define_expand "<sincos><mode>2"
15452 [(set (match_operand:MODEF 0 "register_operand")
15453 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15454 SINCOS))]
15455 "TARGET_USE_FANCY_MATH_387
15456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15457 || TARGET_MIX_SSE_I387)
15458 && flag_unsafe_math_optimizations"
15459 {
15460 rtx op0 = gen_reg_rtx (XFmode);
15461 rtx op1 = gen_reg_rtx (XFmode);
15462
15463 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15464 emit_insn (gen_<sincos>xf2 (op0, op1));
15465 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15466 DONE;
15467 })
15468
15469 (define_insn "sincosxf3"
15470 [(set (match_operand:XF 0 "register_operand" "=f")
15471 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15472 UNSPEC_SINCOS_COS))
15473 (set (match_operand:XF 1 "register_operand" "=f")
15474 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15475 "TARGET_USE_FANCY_MATH_387
15476 && flag_unsafe_math_optimizations"
15477 "fsincos"
15478 [(set_attr "type" "fpspc")
15479 (set_attr "znver1_decode" "vector")
15480 (set_attr "mode" "XF")])
15481
15482 (define_expand "sincos<mode>3"
15483 [(use (match_operand:MODEF 0 "register_operand"))
15484 (use (match_operand:MODEF 1 "register_operand"))
15485 (use (match_operand:MODEF 2 "general_operand"))]
15486 "TARGET_USE_FANCY_MATH_387
15487 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15488 || TARGET_MIX_SSE_I387)
15489 && flag_unsafe_math_optimizations"
15490 {
15491 rtx op0 = gen_reg_rtx (XFmode);
15492 rtx op1 = gen_reg_rtx (XFmode);
15493 rtx op2 = gen_reg_rtx (XFmode);
15494
15495 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15496 emit_insn (gen_sincosxf3 (op0, op1, op2));
15497 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15498 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15499 DONE;
15500 })
15501
15502 (define_insn "fptanxf4_i387"
15503 [(set (match_operand:SF 0 "register_operand" "=f")
15504 (match_operand:SF 3 "const1_operand"))
15505 (set (match_operand:XF 1 "register_operand" "=f")
15506 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15507 UNSPEC_TAN))]
15508 "TARGET_USE_FANCY_MATH_387
15509 && flag_unsafe_math_optimizations"
15510 "fptan"
15511 [(set_attr "type" "fpspc")
15512 (set_attr "znver1_decode" "vector")
15513 (set_attr "mode" "XF")])
15514
15515 (define_expand "tanxf2"
15516 [(use (match_operand:XF 0 "register_operand"))
15517 (use (match_operand:XF 1 "register_operand"))]
15518 "TARGET_USE_FANCY_MATH_387
15519 && flag_unsafe_math_optimizations"
15520 {
15521 rtx one = gen_reg_rtx (SFmode);
15522 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15523 CONST1_RTX (SFmode)));
15524 DONE;
15525 })
15526
15527 (define_expand "tan<mode>2"
15528 [(use (match_operand:MODEF 0 "register_operand"))
15529 (use (match_operand:MODEF 1 "general_operand"))]
15530 "TARGET_USE_FANCY_MATH_387
15531 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15532 || TARGET_MIX_SSE_I387)
15533 && flag_unsafe_math_optimizations"
15534 {
15535 rtx op0 = gen_reg_rtx (XFmode);
15536 rtx op1 = gen_reg_rtx (XFmode);
15537
15538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15539 emit_insn (gen_tanxf2 (op0, op1));
15540 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15541 DONE;
15542 })
15543
15544 (define_insn "atan2xf3"
15545 [(set (match_operand:XF 0 "register_operand" "=f")
15546 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15547 (match_operand:XF 2 "register_operand" "f")]
15548 UNSPEC_FPATAN))
15549 (clobber (match_scratch:XF 3 "=2"))]
15550 "TARGET_USE_FANCY_MATH_387
15551 && flag_unsafe_math_optimizations"
15552 "fpatan"
15553 [(set_attr "type" "fpspc")
15554 (set_attr "znver1_decode" "vector")
15555 (set_attr "mode" "XF")])
15556
15557 (define_expand "atan2<mode>3"
15558 [(use (match_operand:MODEF 0 "register_operand"))
15559 (use (match_operand:MODEF 1 "general_operand"))
15560 (use (match_operand:MODEF 2 "general_operand"))]
15561 "TARGET_USE_FANCY_MATH_387
15562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15563 || TARGET_MIX_SSE_I387)
15564 && flag_unsafe_math_optimizations"
15565 {
15566 rtx op0 = gen_reg_rtx (XFmode);
15567 rtx op1 = gen_reg_rtx (XFmode);
15568 rtx op2 = gen_reg_rtx (XFmode);
15569
15570 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15571 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15572
15573 emit_insn (gen_atan2xf3 (op0, op2, op1));
15574 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15575 DONE;
15576 })
15577
15578 (define_expand "atanxf2"
15579 [(parallel [(set (match_operand:XF 0 "register_operand")
15580 (unspec:XF [(match_dup 2)
15581 (match_operand:XF 1 "register_operand")]
15582 UNSPEC_FPATAN))
15583 (clobber (match_scratch:XF 3))])]
15584 "TARGET_USE_FANCY_MATH_387
15585 && flag_unsafe_math_optimizations"
15586 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15587
15588 (define_expand "atan<mode>2"
15589 [(use (match_operand:MODEF 0 "register_operand"))
15590 (use (match_operand:MODEF 1 "general_operand"))]
15591 "TARGET_USE_FANCY_MATH_387
15592 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15593 || TARGET_MIX_SSE_I387)
15594 && flag_unsafe_math_optimizations"
15595 {
15596 rtx op0 = gen_reg_rtx (XFmode);
15597 rtx op1 = gen_reg_rtx (XFmode);
15598
15599 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15600 emit_insn (gen_atanxf2 (op0, op1));
15601 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15602 DONE;
15603 })
15604
15605 (define_expand "asinxf2"
15606 [(set (match_dup 2)
15607 (mult:XF (match_operand:XF 1 "register_operand")
15608 (match_dup 1)))
15609 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15610 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15611 (parallel [(set (match_operand:XF 0 "register_operand")
15612 (unspec:XF [(match_dup 5) (match_dup 1)]
15613 UNSPEC_FPATAN))
15614 (clobber (match_scratch:XF 6))])]
15615 "TARGET_USE_FANCY_MATH_387
15616 && flag_unsafe_math_optimizations"
15617 {
15618 int i;
15619
15620 for (i = 2; i < 6; i++)
15621 operands[i] = gen_reg_rtx (XFmode);
15622
15623 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15624 })
15625
15626 (define_expand "asin<mode>2"
15627 [(use (match_operand:MODEF 0 "register_operand"))
15628 (use (match_operand:MODEF 1 "general_operand"))]
15629 "TARGET_USE_FANCY_MATH_387
15630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15631 || TARGET_MIX_SSE_I387)
15632 && flag_unsafe_math_optimizations"
15633 {
15634 rtx op0 = gen_reg_rtx (XFmode);
15635 rtx op1 = gen_reg_rtx (XFmode);
15636
15637 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15638 emit_insn (gen_asinxf2 (op0, op1));
15639 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15640 DONE;
15641 })
15642
15643 (define_expand "acosxf2"
15644 [(set (match_dup 2)
15645 (mult:XF (match_operand:XF 1 "register_operand")
15646 (match_dup 1)))
15647 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15648 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15649 (parallel [(set (match_operand:XF 0 "register_operand")
15650 (unspec:XF [(match_dup 1) (match_dup 5)]
15651 UNSPEC_FPATAN))
15652 (clobber (match_scratch:XF 6))])]
15653 "TARGET_USE_FANCY_MATH_387
15654 && flag_unsafe_math_optimizations"
15655 {
15656 int i;
15657
15658 for (i = 2; i < 6; i++)
15659 operands[i] = gen_reg_rtx (XFmode);
15660
15661 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15662 })
15663
15664 (define_expand "acos<mode>2"
15665 [(use (match_operand:MODEF 0 "register_operand"))
15666 (use (match_operand:MODEF 1 "general_operand"))]
15667 "TARGET_USE_FANCY_MATH_387
15668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15669 || TARGET_MIX_SSE_I387)
15670 && flag_unsafe_math_optimizations"
15671 {
15672 rtx op0 = gen_reg_rtx (XFmode);
15673 rtx op1 = gen_reg_rtx (XFmode);
15674
15675 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15676 emit_insn (gen_acosxf2 (op0, op1));
15677 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15678 DONE;
15679 })
15680
15681 (define_expand "sinhxf2"
15682 [(use (match_operand:XF 0 "register_operand"))
15683 (use (match_operand:XF 1 "register_operand"))]
15684 "TARGET_USE_FANCY_MATH_387
15685 && flag_finite_math_only
15686 && flag_unsafe_math_optimizations"
15687 {
15688 ix86_emit_i387_sinh (operands[0], operands[1]);
15689 DONE;
15690 })
15691
15692 (define_expand "sinh<mode>2"
15693 [(use (match_operand:MODEF 0 "register_operand"))
15694 (use (match_operand:MODEF 1 "general_operand"))]
15695 "TARGET_USE_FANCY_MATH_387
15696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15697 || TARGET_MIX_SSE_I387)
15698 && flag_finite_math_only
15699 && flag_unsafe_math_optimizations"
15700 {
15701 rtx op0 = gen_reg_rtx (XFmode);
15702 rtx op1 = gen_reg_rtx (XFmode);
15703
15704 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15705 emit_insn (gen_sinhxf2 (op0, op1));
15706 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15707 DONE;
15708 })
15709
15710 (define_expand "coshxf2"
15711 [(use (match_operand:XF 0 "register_operand"))
15712 (use (match_operand:XF 1 "register_operand"))]
15713 "TARGET_USE_FANCY_MATH_387
15714 && flag_unsafe_math_optimizations"
15715 {
15716 ix86_emit_i387_cosh (operands[0], operands[1]);
15717 DONE;
15718 })
15719
15720 (define_expand "cosh<mode>2"
15721 [(use (match_operand:MODEF 0 "register_operand"))
15722 (use (match_operand:MODEF 1 "general_operand"))]
15723 "TARGET_USE_FANCY_MATH_387
15724 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15725 || TARGET_MIX_SSE_I387)
15726 && flag_unsafe_math_optimizations"
15727 {
15728 rtx op0 = gen_reg_rtx (XFmode);
15729 rtx op1 = gen_reg_rtx (XFmode);
15730
15731 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15732 emit_insn (gen_coshxf2 (op0, op1));
15733 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15734 DONE;
15735 })
15736
15737 (define_expand "tanhxf2"
15738 [(use (match_operand:XF 0 "register_operand"))
15739 (use (match_operand:XF 1 "register_operand"))]
15740 "TARGET_USE_FANCY_MATH_387
15741 && flag_unsafe_math_optimizations"
15742 {
15743 ix86_emit_i387_tanh (operands[0], operands[1]);
15744 DONE;
15745 })
15746
15747 (define_expand "tanh<mode>2"
15748 [(use (match_operand:MODEF 0 "register_operand"))
15749 (use (match_operand:MODEF 1 "general_operand"))]
15750 "TARGET_USE_FANCY_MATH_387
15751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15752 || TARGET_MIX_SSE_I387)
15753 && flag_unsafe_math_optimizations"
15754 {
15755 rtx op0 = gen_reg_rtx (XFmode);
15756 rtx op1 = gen_reg_rtx (XFmode);
15757
15758 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15759 emit_insn (gen_tanhxf2 (op0, op1));
15760 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15761 DONE;
15762 })
15763
15764 (define_expand "asinhxf2"
15765 [(use (match_operand:XF 0 "register_operand"))
15766 (use (match_operand:XF 1 "register_operand"))]
15767 "TARGET_USE_FANCY_MATH_387
15768 && flag_finite_math_only
15769 && flag_unsafe_math_optimizations"
15770 {
15771 ix86_emit_i387_asinh (operands[0], operands[1]);
15772 DONE;
15773 })
15774
15775 (define_expand "asinh<mode>2"
15776 [(use (match_operand:MODEF 0 "register_operand"))
15777 (use (match_operand:MODEF 1 "general_operand"))]
15778 "TARGET_USE_FANCY_MATH_387
15779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15780 || TARGET_MIX_SSE_I387)
15781 && flag_finite_math_only
15782 && flag_unsafe_math_optimizations"
15783 {
15784 rtx op0 = gen_reg_rtx (XFmode);
15785 rtx op1 = gen_reg_rtx (XFmode);
15786
15787 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15788 emit_insn (gen_asinhxf2 (op0, op1));
15789 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15790 DONE;
15791 })
15792
15793 (define_expand "acoshxf2"
15794 [(use (match_operand:XF 0 "register_operand"))
15795 (use (match_operand:XF 1 "register_operand"))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && flag_unsafe_math_optimizations"
15798 {
15799 ix86_emit_i387_acosh (operands[0], operands[1]);
15800 DONE;
15801 })
15802
15803 (define_expand "acosh<mode>2"
15804 [(use (match_operand:MODEF 0 "register_operand"))
15805 (use (match_operand:MODEF 1 "general_operand"))]
15806 "TARGET_USE_FANCY_MATH_387
15807 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15808 || TARGET_MIX_SSE_I387)
15809 && flag_unsafe_math_optimizations"
15810 {
15811 rtx op0 = gen_reg_rtx (XFmode);
15812 rtx op1 = gen_reg_rtx (XFmode);
15813
15814 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15815 emit_insn (gen_acoshxf2 (op0, op1));
15816 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15817 DONE;
15818 })
15819
15820 (define_expand "atanhxf2"
15821 [(use (match_operand:XF 0 "register_operand"))
15822 (use (match_operand:XF 1 "register_operand"))]
15823 "TARGET_USE_FANCY_MATH_387
15824 && flag_unsafe_math_optimizations"
15825 {
15826 ix86_emit_i387_atanh (operands[0], operands[1]);
15827 DONE;
15828 })
15829
15830 (define_expand "atanh<mode>2"
15831 [(use (match_operand:MODEF 0 "register_operand"))
15832 (use (match_operand:MODEF 1 "general_operand"))]
15833 "TARGET_USE_FANCY_MATH_387
15834 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15835 || TARGET_MIX_SSE_I387)
15836 && flag_unsafe_math_optimizations"
15837 {
15838 rtx op0 = gen_reg_rtx (XFmode);
15839 rtx op1 = gen_reg_rtx (XFmode);
15840
15841 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15842 emit_insn (gen_atanhxf2 (op0, op1));
15843 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15844 DONE;
15845 })
15846
15847 (define_insn "fyl2xxf3_i387"
15848 [(set (match_operand:XF 0 "register_operand" "=f")
15849 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15850 (match_operand:XF 2 "register_operand" "f")]
15851 UNSPEC_FYL2X))
15852 (clobber (match_scratch:XF 3 "=2"))]
15853 "TARGET_USE_FANCY_MATH_387
15854 && flag_unsafe_math_optimizations"
15855 "fyl2x"
15856 [(set_attr "type" "fpspc")
15857 (set_attr "znver1_decode" "vector")
15858 (set_attr "mode" "XF")])
15859
15860 (define_expand "logxf2"
15861 [(parallel [(set (match_operand:XF 0 "register_operand")
15862 (unspec:XF [(match_operand:XF 1 "register_operand")
15863 (match_dup 2)] UNSPEC_FYL2X))
15864 (clobber (match_scratch:XF 3))])]
15865 "TARGET_USE_FANCY_MATH_387
15866 && flag_unsafe_math_optimizations"
15867 {
15868 operands[2]
15869 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
15870 })
15871
15872 (define_expand "log<mode>2"
15873 [(use (match_operand:MODEF 0 "register_operand"))
15874 (use (match_operand:MODEF 1 "general_operand"))]
15875 "TARGET_USE_FANCY_MATH_387
15876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15877 || TARGET_MIX_SSE_I387)
15878 && flag_unsafe_math_optimizations"
15879 {
15880 rtx op0 = gen_reg_rtx (XFmode);
15881 rtx op1 = gen_reg_rtx (XFmode);
15882
15883 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15884 emit_insn (gen_logxf2 (op0, op1));
15885 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15886 DONE;
15887 })
15888
15889 (define_expand "log10xf2"
15890 [(parallel [(set (match_operand:XF 0 "register_operand")
15891 (unspec:XF [(match_operand:XF 1 "register_operand")
15892 (match_dup 2)] UNSPEC_FYL2X))
15893 (clobber (match_scratch:XF 3))])]
15894 "TARGET_USE_FANCY_MATH_387
15895 && flag_unsafe_math_optimizations"
15896 {
15897 operands[2]
15898 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
15899 })
15900
15901 (define_expand "log10<mode>2"
15902 [(use (match_operand:MODEF 0 "register_operand"))
15903 (use (match_operand:MODEF 1 "general_operand"))]
15904 "TARGET_USE_FANCY_MATH_387
15905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15906 || TARGET_MIX_SSE_I387)
15907 && flag_unsafe_math_optimizations"
15908 {
15909 rtx op0 = gen_reg_rtx (XFmode);
15910 rtx op1 = gen_reg_rtx (XFmode);
15911
15912 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15913 emit_insn (gen_log10xf2 (op0, op1));
15914 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15915 DONE;
15916 })
15917
15918 (define_expand "log2xf2"
15919 [(parallel [(set (match_operand:XF 0 "register_operand")
15920 (unspec:XF [(match_operand:XF 1 "register_operand")
15921 (match_dup 2)] UNSPEC_FYL2X))
15922 (clobber (match_scratch:XF 3))])]
15923 "TARGET_USE_FANCY_MATH_387
15924 && flag_unsafe_math_optimizations"
15925 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15926
15927 (define_expand "log2<mode>2"
15928 [(use (match_operand:MODEF 0 "register_operand"))
15929 (use (match_operand:MODEF 1 "general_operand"))]
15930 "TARGET_USE_FANCY_MATH_387
15931 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15932 || TARGET_MIX_SSE_I387)
15933 && flag_unsafe_math_optimizations"
15934 {
15935 rtx op0 = gen_reg_rtx (XFmode);
15936 rtx op1 = gen_reg_rtx (XFmode);
15937
15938 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15939 emit_insn (gen_log2xf2 (op0, op1));
15940 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15941 DONE;
15942 })
15943
15944 (define_insn "fyl2xp1xf3_i387"
15945 [(set (match_operand:XF 0 "register_operand" "=f")
15946 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15947 (match_operand:XF 2 "register_operand" "f")]
15948 UNSPEC_FYL2XP1))
15949 (clobber (match_scratch:XF 3 "=2"))]
15950 "TARGET_USE_FANCY_MATH_387
15951 && flag_unsafe_math_optimizations"
15952 "fyl2xp1"
15953 [(set_attr "type" "fpspc")
15954 (set_attr "znver1_decode" "vector")
15955 (set_attr "mode" "XF")])
15956
15957 (define_expand "log1pxf2"
15958 [(use (match_operand:XF 0 "register_operand"))
15959 (use (match_operand:XF 1 "register_operand"))]
15960 "TARGET_USE_FANCY_MATH_387
15961 && flag_unsafe_math_optimizations"
15962 {
15963 ix86_emit_i387_log1p (operands[0], operands[1]);
15964 DONE;
15965 })
15966
15967 (define_expand "log1p<mode>2"
15968 [(use (match_operand:MODEF 0 "register_operand"))
15969 (use (match_operand:MODEF 1 "general_operand"))]
15970 "TARGET_USE_FANCY_MATH_387
15971 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15972 || TARGET_MIX_SSE_I387)
15973 && flag_unsafe_math_optimizations"
15974 {
15975 rtx op0 = gen_reg_rtx (XFmode);
15976 rtx op1 = gen_reg_rtx (XFmode);
15977
15978 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15979 emit_insn (gen_log1pxf2 (op0, op1));
15980 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15981 DONE;
15982 })
15983
15984 (define_insn "fxtractxf3_i387"
15985 [(set (match_operand:XF 0 "register_operand" "=f")
15986 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15987 UNSPEC_XTRACT_FRACT))
15988 (set (match_operand:XF 1 "register_operand" "=f")
15989 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15990 "TARGET_USE_FANCY_MATH_387
15991 && flag_unsafe_math_optimizations"
15992 "fxtract"
15993 [(set_attr "type" "fpspc")
15994 (set_attr "znver1_decode" "vector")
15995 (set_attr "mode" "XF")])
15996
15997 (define_expand "logbxf2"
15998 [(parallel [(set (match_dup 2)
15999 (unspec:XF [(match_operand:XF 1 "register_operand")]
16000 UNSPEC_XTRACT_FRACT))
16001 (set (match_operand:XF 0 "register_operand")
16002 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16003 "TARGET_USE_FANCY_MATH_387
16004 && flag_unsafe_math_optimizations"
16005 "operands[2] = gen_reg_rtx (XFmode);")
16006
16007 (define_expand "logb<mode>2"
16008 [(use (match_operand:MODEF 0 "register_operand"))
16009 (use (match_operand:MODEF 1 "general_operand"))]
16010 "TARGET_USE_FANCY_MATH_387
16011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16012 || TARGET_MIX_SSE_I387)
16013 && flag_unsafe_math_optimizations"
16014 {
16015 rtx op0 = gen_reg_rtx (XFmode);
16016 rtx op1 = gen_reg_rtx (XFmode);
16017
16018 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16019 emit_insn (gen_logbxf2 (op0, op1));
16020 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16021 DONE;
16022 })
16023
16024 (define_expand "ilogbxf2"
16025 [(use (match_operand:SI 0 "register_operand"))
16026 (use (match_operand:XF 1 "register_operand"))]
16027 "TARGET_USE_FANCY_MATH_387
16028 && flag_unsafe_math_optimizations"
16029 {
16030 rtx op0, op1;
16031
16032 if (optimize_insn_for_size_p ())
16033 FAIL;
16034
16035 op0 = gen_reg_rtx (XFmode);
16036 op1 = gen_reg_rtx (XFmode);
16037
16038 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16039 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16040 DONE;
16041 })
16042
16043 (define_expand "ilogb<mode>2"
16044 [(use (match_operand:SI 0 "register_operand"))
16045 (use (match_operand:MODEF 1 "general_operand"))]
16046 "TARGET_USE_FANCY_MATH_387
16047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16048 || TARGET_MIX_SSE_I387)
16049 && flag_unsafe_math_optimizations"
16050 {
16051 rtx op0, op1, op2;
16052
16053 if (optimize_insn_for_size_p ())
16054 FAIL;
16055
16056 op0 = gen_reg_rtx (XFmode);
16057 op1 = gen_reg_rtx (XFmode);
16058 op2 = gen_reg_rtx (XFmode);
16059
16060 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
16061 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
16062 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16063 DONE;
16064 })
16065
16066 (define_insn "*f2xm1xf2_i387"
16067 [(set (match_operand:XF 0 "register_operand" "=f")
16068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16069 UNSPEC_F2XM1))]
16070 "TARGET_USE_FANCY_MATH_387
16071 && flag_unsafe_math_optimizations"
16072 "f2xm1"
16073 [(set_attr "type" "fpspc")
16074 (set_attr "znver1_decode" "vector")
16075 (set_attr "mode" "XF")])
16076
16077 (define_insn "fscalexf4_i387"
16078 [(set (match_operand:XF 0 "register_operand" "=f")
16079 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16080 (match_operand:XF 3 "register_operand" "1")]
16081 UNSPEC_FSCALE_FRACT))
16082 (set (match_operand:XF 1 "register_operand" "=f")
16083 (unspec:XF [(match_dup 2) (match_dup 3)]
16084 UNSPEC_FSCALE_EXP))]
16085 "TARGET_USE_FANCY_MATH_387
16086 && flag_unsafe_math_optimizations"
16087 "fscale"
16088 [(set_attr "type" "fpspc")
16089 (set_attr "znver1_decode" "vector")
16090 (set_attr "mode" "XF")])
16091
16092 (define_expand "expNcorexf3"
16093 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16094 (match_operand:XF 2 "register_operand")))
16095 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16096 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16097 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16098 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16099 (parallel [(set (match_operand:XF 0 "register_operand")
16100 (unspec:XF [(match_dup 8) (match_dup 4)]
16101 UNSPEC_FSCALE_FRACT))
16102 (set (match_dup 9)
16103 (unspec:XF [(match_dup 8) (match_dup 4)]
16104 UNSPEC_FSCALE_EXP))])]
16105 "TARGET_USE_FANCY_MATH_387
16106 && flag_unsafe_math_optimizations"
16107 {
16108 int i;
16109
16110 for (i = 3; i < 10; i++)
16111 operands[i] = gen_reg_rtx (XFmode);
16112
16113 emit_move_insn (operands[7], CONST1_RTX (XFmode));
16114 })
16115
16116 (define_expand "expxf2"
16117 [(use (match_operand:XF 0 "register_operand"))
16118 (use (match_operand:XF 1 "register_operand"))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && flag_unsafe_math_optimizations"
16121 {
16122 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
16123
16124 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16125 DONE;
16126 })
16127
16128 (define_expand "exp<mode>2"
16129 [(use (match_operand:MODEF 0 "register_operand"))
16130 (use (match_operand:MODEF 1 "general_operand"))]
16131 "TARGET_USE_FANCY_MATH_387
16132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16133 || TARGET_MIX_SSE_I387)
16134 && flag_unsafe_math_optimizations"
16135 {
16136 rtx op0 = gen_reg_rtx (XFmode);
16137 rtx op1 = gen_reg_rtx (XFmode);
16138
16139 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16140 emit_insn (gen_expxf2 (op0, op1));
16141 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16142 DONE;
16143 })
16144
16145 (define_expand "exp10xf2"
16146 [(use (match_operand:XF 0 "register_operand"))
16147 (use (match_operand:XF 1 "register_operand"))]
16148 "TARGET_USE_FANCY_MATH_387
16149 && flag_unsafe_math_optimizations"
16150 {
16151 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
16152
16153 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16154 DONE;
16155 })
16156
16157 (define_expand "exp10<mode>2"
16158 [(use (match_operand:MODEF 0 "register_operand"))
16159 (use (match_operand:MODEF 1 "general_operand"))]
16160 "TARGET_USE_FANCY_MATH_387
16161 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16162 || TARGET_MIX_SSE_I387)
16163 && flag_unsafe_math_optimizations"
16164 {
16165 rtx op0 = gen_reg_rtx (XFmode);
16166 rtx op1 = gen_reg_rtx (XFmode);
16167
16168 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16169 emit_insn (gen_exp10xf2 (op0, op1));
16170 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16171 DONE;
16172 })
16173
16174 (define_expand "exp2xf2"
16175 [(use (match_operand:XF 0 "register_operand"))
16176 (use (match_operand:XF 1 "register_operand"))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && flag_unsafe_math_optimizations"
16179 {
16180 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
16181
16182 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16183 DONE;
16184 })
16185
16186 (define_expand "exp2<mode>2"
16187 [(use (match_operand:MODEF 0 "register_operand"))
16188 (use (match_operand:MODEF 1 "general_operand"))]
16189 "TARGET_USE_FANCY_MATH_387
16190 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16191 || TARGET_MIX_SSE_I387)
16192 && flag_unsafe_math_optimizations"
16193 {
16194 rtx op0 = gen_reg_rtx (XFmode);
16195 rtx op1 = gen_reg_rtx (XFmode);
16196
16197 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16198 emit_insn (gen_exp2xf2 (op0, op1));
16199 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16200 DONE;
16201 })
16202
16203 (define_expand "expm1xf2"
16204 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16205 (match_dup 2)))
16206 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16207 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16208 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16209 (parallel [(set (match_dup 7)
16210 (unspec:XF [(match_dup 6) (match_dup 4)]
16211 UNSPEC_FSCALE_FRACT))
16212 (set (match_dup 8)
16213 (unspec:XF [(match_dup 6) (match_dup 4)]
16214 UNSPEC_FSCALE_EXP))])
16215 (parallel [(set (match_dup 10)
16216 (unspec:XF [(match_dup 9) (match_dup 8)]
16217 UNSPEC_FSCALE_FRACT))
16218 (set (match_dup 11)
16219 (unspec:XF [(match_dup 9) (match_dup 8)]
16220 UNSPEC_FSCALE_EXP))])
16221 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16222 (set (match_operand:XF 0 "register_operand")
16223 (plus:XF (match_dup 12) (match_dup 7)))]
16224 "TARGET_USE_FANCY_MATH_387
16225 && flag_unsafe_math_optimizations"
16226 {
16227 int i;
16228
16229 for (i = 2; i < 13; i++)
16230 operands[i] = gen_reg_rtx (XFmode);
16231
16232 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16233 emit_move_insn (operands[9], CONST1_RTX (XFmode));
16234 })
16235
16236 (define_expand "expm1<mode>2"
16237 [(use (match_operand:MODEF 0 "register_operand"))
16238 (use (match_operand:MODEF 1 "general_operand"))]
16239 "TARGET_USE_FANCY_MATH_387
16240 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16241 || TARGET_MIX_SSE_I387)
16242 && flag_unsafe_math_optimizations"
16243 {
16244 rtx op0 = gen_reg_rtx (XFmode);
16245 rtx op1 = gen_reg_rtx (XFmode);
16246
16247 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16248 emit_insn (gen_expm1xf2 (op0, op1));
16249 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16250 DONE;
16251 })
16252
16253 (define_expand "ldexpxf3"
16254 [(match_operand:XF 0 "register_operand")
16255 (match_operand:XF 1 "register_operand")
16256 (match_operand:SI 2 "register_operand")]
16257 "TARGET_USE_FANCY_MATH_387
16258 && flag_unsafe_math_optimizations"
16259 {
16260 rtx tmp1 = gen_reg_rtx (XFmode);
16261 rtx tmp2 = gen_reg_rtx (XFmode);
16262
16263 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16264 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16265 operands[1], tmp1));
16266 DONE;
16267 })
16268
16269 (define_expand "ldexp<mode>3"
16270 [(use (match_operand:MODEF 0 "register_operand"))
16271 (use (match_operand:MODEF 1 "general_operand"))
16272 (use (match_operand:SI 2 "register_operand"))]
16273 "TARGET_USE_FANCY_MATH_387
16274 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16275 || TARGET_MIX_SSE_I387)
16276 && flag_unsafe_math_optimizations"
16277 {
16278 rtx op0 = gen_reg_rtx (XFmode);
16279 rtx op1 = gen_reg_rtx (XFmode);
16280
16281 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16282 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16283 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16284 DONE;
16285 })
16286
16287 (define_expand "scalbxf3"
16288 [(parallel [(set (match_operand:XF 0 " register_operand")
16289 (unspec:XF [(match_operand:XF 1 "register_operand")
16290 (match_operand:XF 2 "register_operand")]
16291 UNSPEC_FSCALE_FRACT))
16292 (set (match_dup 3)
16293 (unspec:XF [(match_dup 1) (match_dup 2)]
16294 UNSPEC_FSCALE_EXP))])]
16295 "TARGET_USE_FANCY_MATH_387
16296 && flag_unsafe_math_optimizations"
16297 "operands[3] = gen_reg_rtx (XFmode);")
16298
16299 (define_expand "scalb<mode>3"
16300 [(use (match_operand:MODEF 0 "register_operand"))
16301 (use (match_operand:MODEF 1 "general_operand"))
16302 (use (match_operand:MODEF 2 "general_operand"))]
16303 "TARGET_USE_FANCY_MATH_387
16304 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16305 || TARGET_MIX_SSE_I387)
16306 && flag_unsafe_math_optimizations"
16307 {
16308 rtx op0 = gen_reg_rtx (XFmode);
16309 rtx op1 = gen_reg_rtx (XFmode);
16310 rtx op2 = gen_reg_rtx (XFmode);
16311
16312 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16313 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16314 emit_insn (gen_scalbxf3 (op0, op1, op2));
16315 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16316 DONE;
16317 })
16318
16319 (define_expand "significandxf2"
16320 [(parallel [(set (match_operand:XF 0 "register_operand")
16321 (unspec:XF [(match_operand:XF 1 "register_operand")]
16322 UNSPEC_XTRACT_FRACT))
16323 (set (match_dup 2)
16324 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16325 "TARGET_USE_FANCY_MATH_387
16326 && flag_unsafe_math_optimizations"
16327 "operands[2] = gen_reg_rtx (XFmode);")
16328
16329 (define_expand "significand<mode>2"
16330 [(use (match_operand:MODEF 0 "register_operand"))
16331 (use (match_operand:MODEF 1 "general_operand"))]
16332 "TARGET_USE_FANCY_MATH_387
16333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16334 || TARGET_MIX_SSE_I387)
16335 && flag_unsafe_math_optimizations"
16336 {
16337 rtx op0 = gen_reg_rtx (XFmode);
16338 rtx op1 = gen_reg_rtx (XFmode);
16339
16340 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16341 emit_insn (gen_significandxf2 (op0, op1));
16342 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16343 DONE;
16344 })
16345 \f
16346
16347 (define_insn "sse4_1_round<mode>2"
16348 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v,v")
16349 (unspec:MODEF
16350 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,v,m")
16351 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n,n")]
16352 UNSPEC_ROUND))]
16353 "TARGET_SSE4_1"
16354 "@
16355 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16356 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16357 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16358 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16359 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16360 [(set_attr "type" "ssecvt")
16361 (set_attr "prefix_extra" "1,1,1,*,*")
16362 (set_attr "length_immediate" "*,*,*,1,1")
16363 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
16364 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
16365 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
16366 (set_attr "mode" "<MODE>")
16367 (set (attr "preferred_for_speed")
16368 (cond [(match_test "TARGET_AVX")
16369 (symbol_ref "true")
16370 (eq_attr "alternative" "1,2")
16371 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16372 ]
16373 (symbol_ref "true")))])
16374
16375 (define_insn "rintxf2"
16376 [(set (match_operand:XF 0 "register_operand" "=f")
16377 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16378 UNSPEC_FRNDINT))]
16379 "TARGET_USE_FANCY_MATH_387"
16380 "frndint"
16381 [(set_attr "type" "fpspc")
16382 (set_attr "znver1_decode" "vector")
16383 (set_attr "mode" "XF")])
16384
16385 (define_expand "rint<mode>2"
16386 [(use (match_operand:MODEF 0 "register_operand"))
16387 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16388 "TARGET_USE_FANCY_MATH_387
16389 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16390 {
16391 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16392 {
16393 if (TARGET_SSE4_1)
16394 emit_insn (gen_sse4_1_round<mode>2
16395 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16396 else
16397 ix86_expand_rint (operands[0], operands[1]);
16398 }
16399 else
16400 {
16401 rtx op0 = gen_reg_rtx (XFmode);
16402 rtx op1 = gen_reg_rtx (XFmode);
16403
16404 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16405 emit_insn (gen_rintxf2 (op0, op1));
16406 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16407 }
16408 DONE;
16409 })
16410
16411 (define_expand "nearbyintxf2"
16412 [(set (match_operand:XF 0 "register_operand")
16413 (unspec:XF [(match_operand:XF 1 "register_operand")]
16414 UNSPEC_FRNDINT))]
16415 "TARGET_USE_FANCY_MATH_387
16416 && !flag_trapping_math")
16417
16418 (define_expand "nearbyint<mode>2"
16419 [(use (match_operand:MODEF 0 "register_operand"))
16420 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16421 "(TARGET_USE_FANCY_MATH_387
16422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16423 || TARGET_MIX_SSE_I387)
16424 && !flag_trapping_math)
16425 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
16426 {
16427 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
16428 emit_insn (gen_sse4_1_round<mode>2
16429 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
16430 | ROUND_NO_EXC)));
16431 else
16432 {
16433 rtx op0 = gen_reg_rtx (XFmode);
16434 rtx op1 = gen_reg_rtx (XFmode);
16435
16436 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16437 emit_insn (gen_nearbyintxf2 (op0, op1));
16438 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16439 }
16440 DONE;
16441 })
16442
16443 (define_expand "round<mode>2"
16444 [(match_operand:X87MODEF 0 "register_operand")
16445 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16446 "(TARGET_USE_FANCY_MATH_387
16447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16448 || TARGET_MIX_SSE_I387)
16449 && flag_unsafe_math_optimizations
16450 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16451 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16452 && !flag_trapping_math && !flag_rounding_math)"
16453 {
16454 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16455 && !flag_trapping_math && !flag_rounding_math)
16456 {
16457 if (TARGET_SSE4_1)
16458 {
16459 operands[1] = force_reg (<MODE>mode, operands[1]);
16460 ix86_expand_round_sse4 (operands[0], operands[1]);
16461 }
16462 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16463 ix86_expand_round (operands[0], operands[1]);
16464 else
16465 ix86_expand_rounddf_32 (operands[0], operands[1]);
16466 }
16467 else
16468 {
16469 operands[1] = force_reg (<MODE>mode, operands[1]);
16470 ix86_emit_i387_round (operands[0], operands[1]);
16471 }
16472 DONE;
16473 })
16474
16475 (define_insn "lrintxfdi2"
16476 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16477 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16478 UNSPEC_FIST))
16479 (clobber (match_scratch:XF 2 "=&f"))]
16480 "TARGET_USE_FANCY_MATH_387"
16481 "* return output_fix_trunc (insn, operands, false);"
16482 [(set_attr "type" "fpspc")
16483 (set_attr "mode" "DI")])
16484
16485 (define_insn "lrintxf<mode>2"
16486 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16487 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16488 UNSPEC_FIST))]
16489 "TARGET_USE_FANCY_MATH_387"
16490 "* return output_fix_trunc (insn, operands, false);"
16491 [(set_attr "type" "fpspc")
16492 (set_attr "mode" "<MODE>")])
16493
16494 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16495 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16496 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16497 UNSPEC_FIX_NOTRUNC))]
16498 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16499
16500 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16501 [(match_operand:SWI248x 0 "nonimmediate_operand")
16502 (match_operand:X87MODEF 1 "register_operand")]
16503 "(TARGET_USE_FANCY_MATH_387
16504 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16505 || TARGET_MIX_SSE_I387)
16506 && flag_unsafe_math_optimizations)
16507 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16508 && <SWI248x:MODE>mode != HImode
16509 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16510 && !flag_trapping_math && !flag_rounding_math)"
16511 {
16512 if (optimize_insn_for_size_p ())
16513 FAIL;
16514
16515 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16516 && <SWI248x:MODE>mode != HImode
16517 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16518 && !flag_trapping_math && !flag_rounding_math)
16519 ix86_expand_lround (operands[0], operands[1]);
16520 else
16521 ix86_emit_i387_round (operands[0], operands[1]);
16522 DONE;
16523 })
16524
16525 (define_int_iterator FRNDINT_ROUNDING
16526 [UNSPEC_FRNDINT_ROUNDEVEN
16527 UNSPEC_FRNDINT_FLOOR
16528 UNSPEC_FRNDINT_CEIL
16529 UNSPEC_FRNDINT_TRUNC])
16530
16531 (define_int_iterator FIST_ROUNDING
16532 [UNSPEC_FIST_FLOOR
16533 UNSPEC_FIST_CEIL])
16534
16535 ;; Base name for define_insn
16536 (define_int_attr rounding_insn
16537 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
16538 (UNSPEC_FRNDINT_FLOOR "floor")
16539 (UNSPEC_FRNDINT_CEIL "ceil")
16540 (UNSPEC_FRNDINT_TRUNC "btrunc")
16541 (UNSPEC_FIST_FLOOR "floor")
16542 (UNSPEC_FIST_CEIL "ceil")])
16543
16544 (define_int_attr rounding
16545 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
16546 (UNSPEC_FRNDINT_FLOOR "floor")
16547 (UNSPEC_FRNDINT_CEIL "ceil")
16548 (UNSPEC_FRNDINT_TRUNC "trunc")
16549 (UNSPEC_FIST_FLOOR "floor")
16550 (UNSPEC_FIST_CEIL "ceil")])
16551
16552 (define_int_attr ROUNDING
16553 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
16554 (UNSPEC_FRNDINT_FLOOR "FLOOR")
16555 (UNSPEC_FRNDINT_CEIL "CEIL")
16556 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16557 (UNSPEC_FIST_FLOOR "FLOOR")
16558 (UNSPEC_FIST_CEIL "CEIL")])
16559
16560 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16561 (define_insn_and_split "frndintxf2_<rounding>"
16562 [(set (match_operand:XF 0 "register_operand")
16563 (unspec:XF [(match_operand:XF 1 "register_operand")]
16564 FRNDINT_ROUNDING))
16565 (clobber (reg:CC FLAGS_REG))]
16566 "TARGET_USE_FANCY_MATH_387
16567 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16568 && ix86_pre_reload_split ()"
16569 "#"
16570 "&& 1"
16571 [(const_int 0)]
16572 {
16573 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16574
16575 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16576 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16577
16578 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16579 operands[2], operands[3]));
16580 DONE;
16581 }
16582 [(set_attr "type" "frndint")
16583 (set_attr "i387_cw" "<rounding>")
16584 (set_attr "mode" "XF")])
16585
16586 (define_insn "frndintxf2_<rounding>_i387"
16587 [(set (match_operand:XF 0 "register_operand" "=f")
16588 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16589 FRNDINT_ROUNDING))
16590 (use (match_operand:HI 2 "memory_operand" "m"))
16591 (use (match_operand:HI 3 "memory_operand" "m"))]
16592 "TARGET_USE_FANCY_MATH_387
16593 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16594 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16595 [(set_attr "type" "frndint")
16596 (set_attr "i387_cw" "<rounding>")
16597 (set_attr "mode" "XF")])
16598
16599 (define_expand "<rounding_insn>xf2"
16600 [(parallel [(set (match_operand:XF 0 "register_operand")
16601 (unspec:XF [(match_operand:XF 1 "register_operand")]
16602 FRNDINT_ROUNDING))
16603 (clobber (reg:CC FLAGS_REG))])]
16604 "TARGET_USE_FANCY_MATH_387
16605 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16606
16607 (define_expand "<rounding_insn><mode>2"
16608 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16609 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16610 FRNDINT_ROUNDING))
16611 (clobber (reg:CC FLAGS_REG))])]
16612 "(TARGET_USE_FANCY_MATH_387
16613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16614 || TARGET_MIX_SSE_I387)
16615 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16616 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16617 && (TARGET_SSE4_1
16618 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
16619 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
16620 {
16621 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16622 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math))
16623 {
16624 if (TARGET_SSE4_1)
16625 emit_insn (gen_sse4_1_round<mode>2
16626 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16627 | ROUND_NO_EXC)));
16628 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16629 {
16630 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16631 ix86_expand_floorceil (operands[0], operands[1], true);
16632 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16633 ix86_expand_floorceil (operands[0], operands[1], false);
16634 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16635 ix86_expand_trunc (operands[0], operands[1]);
16636 else
16637 gcc_unreachable ();
16638 }
16639 else
16640 {
16641 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16642 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16643 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16644 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16645 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16646 ix86_expand_truncdf_32 (operands[0], operands[1]);
16647 else
16648 gcc_unreachable ();
16649 }
16650 }
16651 else
16652 {
16653 rtx op0 = gen_reg_rtx (XFmode);
16654 rtx op1 = gen_reg_rtx (XFmode);
16655
16656 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16657 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16658 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16659 }
16660 DONE;
16661 })
16662
16663 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16664 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16665 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16666 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16667 FIST_ROUNDING))
16668 (clobber (reg:CC FLAGS_REG))]
16669 "TARGET_USE_FANCY_MATH_387
16670 && flag_unsafe_math_optimizations
16671 && ix86_pre_reload_split ()"
16672 "#"
16673 "&& 1"
16674 [(const_int 0)]
16675 {
16676 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16677
16678 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16679 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16680
16681 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16682 operands[2], operands[3]));
16683 DONE;
16684 }
16685 [(set_attr "type" "fistp")
16686 (set_attr "i387_cw" "<rounding>")
16687 (set_attr "mode" "<MODE>")])
16688
16689 (define_insn "fistdi2_<rounding>"
16690 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16691 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16692 FIST_ROUNDING))
16693 (use (match_operand:HI 2 "memory_operand" "m"))
16694 (use (match_operand:HI 3 "memory_operand" "m"))
16695 (clobber (match_scratch:XF 4 "=&f"))]
16696 "TARGET_USE_FANCY_MATH_387
16697 && flag_unsafe_math_optimizations"
16698 "* return output_fix_trunc (insn, operands, false);"
16699 [(set_attr "type" "fistp")
16700 (set_attr "i387_cw" "<rounding>")
16701 (set_attr "mode" "DI")])
16702
16703 (define_insn "fist<mode>2_<rounding>"
16704 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16705 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16706 FIST_ROUNDING))
16707 (use (match_operand:HI 2 "memory_operand" "m"))
16708 (use (match_operand:HI 3 "memory_operand" "m"))]
16709 "TARGET_USE_FANCY_MATH_387
16710 && flag_unsafe_math_optimizations"
16711 "* return output_fix_trunc (insn, operands, false);"
16712 [(set_attr "type" "fistp")
16713 (set_attr "i387_cw" "<rounding>")
16714 (set_attr "mode" "<MODE>")])
16715
16716 (define_expand "l<rounding_insn>xf<mode>2"
16717 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16718 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16719 FIST_ROUNDING))
16720 (clobber (reg:CC FLAGS_REG))])]
16721 "TARGET_USE_FANCY_MATH_387
16722 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16723 && flag_unsafe_math_optimizations")
16724
16725 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16726 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16727 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16728 FIST_ROUNDING))
16729 (clobber (reg:CC FLAGS_REG))])]
16730 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16731 && (TARGET_SSE4_1 || !flag_trapping_math)"
16732 {
16733 if (TARGET_SSE4_1)
16734 {
16735 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16736
16737 emit_insn (gen_sse4_1_round<MODEF:mode>2
16738 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16739 | ROUND_NO_EXC)));
16740 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16741 (operands[0], tmp));
16742 }
16743 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16744 ix86_expand_lfloorceil (operands[0], operands[1], true);
16745 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16746 ix86_expand_lfloorceil (operands[0], operands[1], false);
16747 else
16748 gcc_unreachable ();
16749
16750 DONE;
16751 })
16752
16753 (define_insn "fxam<mode>2_i387"
16754 [(set (match_operand:HI 0 "register_operand" "=a")
16755 (unspec:HI
16756 [(match_operand:X87MODEF 1 "register_operand" "f")]
16757 UNSPEC_FXAM))]
16758 "TARGET_USE_FANCY_MATH_387"
16759 "fxam\n\tfnstsw\t%0"
16760 [(set_attr "type" "multi")
16761 (set_attr "length" "4")
16762 (set_attr "unit" "i387")
16763 (set_attr "mode" "<MODE>")])
16764
16765 (define_expand "signbittf2"
16766 [(use (match_operand:SI 0 "register_operand"))
16767 (use (match_operand:TF 1 "register_operand"))]
16768 "TARGET_SSE"
16769 {
16770 if (TARGET_SSE4_1)
16771 {
16772 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16773 rtx scratch = gen_reg_rtx (QImode);
16774
16775 emit_insn (gen_ptesttf2 (operands[1], mask));
16776 ix86_expand_setcc (scratch, NE,
16777 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16778
16779 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16780 }
16781 else
16782 {
16783 emit_insn (gen_sse_movmskps (operands[0],
16784 gen_lowpart (V4SFmode, operands[1])));
16785 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16786 }
16787 DONE;
16788 })
16789
16790 (define_expand "signbitxf2"
16791 [(use (match_operand:SI 0 "register_operand"))
16792 (use (match_operand:XF 1 "register_operand"))]
16793 "TARGET_USE_FANCY_MATH_387"
16794 {
16795 rtx scratch = gen_reg_rtx (HImode);
16796
16797 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16798 emit_insn (gen_andsi3 (operands[0],
16799 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16800 DONE;
16801 })
16802
16803 (define_insn "movmsk_df"
16804 [(set (match_operand:SI 0 "register_operand" "=r")
16805 (unspec:SI
16806 [(match_operand:DF 1 "register_operand" "x")]
16807 UNSPEC_MOVMSK))]
16808 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16809 "%vmovmskpd\t{%1, %0|%0, %1}"
16810 [(set_attr "type" "ssemov")
16811 (set_attr "prefix" "maybe_vex")
16812 (set_attr "mode" "DF")])
16813
16814 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16815 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16816 (define_expand "signbitdf2"
16817 [(use (match_operand:SI 0 "register_operand"))
16818 (use (match_operand:DF 1 "register_operand"))]
16819 "TARGET_USE_FANCY_MATH_387
16820 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16821 {
16822 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16823 {
16824 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16825 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16826 }
16827 else
16828 {
16829 rtx scratch = gen_reg_rtx (HImode);
16830
16831 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16832 emit_insn (gen_andsi3 (operands[0],
16833 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16834 }
16835 DONE;
16836 })
16837
16838 (define_expand "signbitsf2"
16839 [(use (match_operand:SI 0 "register_operand"))
16840 (use (match_operand:SF 1 "register_operand"))]
16841 "TARGET_USE_FANCY_MATH_387
16842 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16843 {
16844 rtx scratch = gen_reg_rtx (HImode);
16845
16846 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16847 emit_insn (gen_andsi3 (operands[0],
16848 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16849 DONE;
16850 })
16851 \f
16852 ;; Block operation instructions
16853
16854 (define_insn "cld"
16855 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16856 ""
16857 "cld"
16858 [(set_attr "length" "1")
16859 (set_attr "length_immediate" "0")
16860 (set_attr "modrm" "0")])
16861
16862 (define_expand "cpymem<mode>"
16863 [(use (match_operand:BLK 0 "memory_operand"))
16864 (use (match_operand:BLK 1 "memory_operand"))
16865 (use (match_operand:SWI48 2 "nonmemory_operand"))
16866 (use (match_operand:SWI48 3 "const_int_operand"))
16867 (use (match_operand:SI 4 "const_int_operand"))
16868 (use (match_operand:SI 5 "const_int_operand"))
16869 (use (match_operand:SI 6 ""))
16870 (use (match_operand:SI 7 ""))
16871 (use (match_operand:SI 8 ""))]
16872 ""
16873 {
16874 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
16875 operands[2], NULL, operands[3],
16876 operands[4], operands[5],
16877 operands[6], operands[7],
16878 operands[8], false))
16879 DONE;
16880 else
16881 FAIL;
16882 })
16883
16884 ;; Most CPUs don't like single string operations
16885 ;; Handle this case here to simplify previous expander.
16886
16887 (define_expand "strmov"
16888 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16889 (set (match_operand 1 "memory_operand") (match_dup 4))
16890 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16891 (clobber (reg:CC FLAGS_REG))])
16892 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16893 (clobber (reg:CC FLAGS_REG))])]
16894 ""
16895 {
16896 /* Can't use this for non-default address spaces. */
16897 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16898 FAIL;
16899
16900 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16901
16902 /* If .md ever supports :P for Pmode, these can be directly
16903 in the pattern above. */
16904 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16905 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16906
16907 /* Can't use this if the user has appropriated esi or edi. */
16908 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16909 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16910 {
16911 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16912 operands[2], operands[3],
16913 operands[5], operands[6]));
16914 DONE;
16915 }
16916
16917 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16918 })
16919
16920 (define_expand "strmov_singleop"
16921 [(parallel [(set (match_operand 1 "memory_operand")
16922 (match_operand 3 "memory_operand"))
16923 (set (match_operand 0 "register_operand")
16924 (match_operand 4))
16925 (set (match_operand 2 "register_operand")
16926 (match_operand 5))])]
16927 ""
16928 {
16929 if (TARGET_CLD)
16930 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16931 })
16932
16933 (define_insn "*strmovdi_rex_1"
16934 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16935 (mem:DI (match_operand:P 3 "register_operand" "1")))
16936 (set (match_operand:P 0 "register_operand" "=D")
16937 (plus:P (match_dup 2)
16938 (const_int 8)))
16939 (set (match_operand:P 1 "register_operand" "=S")
16940 (plus:P (match_dup 3)
16941 (const_int 8)))]
16942 "TARGET_64BIT
16943 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16944 && ix86_check_no_addr_space (insn)"
16945 "%^movsq"
16946 [(set_attr "type" "str")
16947 (set_attr "memory" "both")
16948 (set_attr "mode" "DI")])
16949
16950 (define_insn "*strmovsi_1"
16951 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16952 (mem:SI (match_operand:P 3 "register_operand" "1")))
16953 (set (match_operand:P 0 "register_operand" "=D")
16954 (plus:P (match_dup 2)
16955 (const_int 4)))
16956 (set (match_operand:P 1 "register_operand" "=S")
16957 (plus:P (match_dup 3)
16958 (const_int 4)))]
16959 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16960 && ix86_check_no_addr_space (insn)"
16961 "%^movs{l|d}"
16962 [(set_attr "type" "str")
16963 (set_attr "memory" "both")
16964 (set_attr "mode" "SI")])
16965
16966 (define_insn "*strmovhi_1"
16967 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16968 (mem:HI (match_operand:P 3 "register_operand" "1")))
16969 (set (match_operand:P 0 "register_operand" "=D")
16970 (plus:P (match_dup 2)
16971 (const_int 2)))
16972 (set (match_operand:P 1 "register_operand" "=S")
16973 (plus:P (match_dup 3)
16974 (const_int 2)))]
16975 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16976 && ix86_check_no_addr_space (insn)"
16977 "%^movsw"
16978 [(set_attr "type" "str")
16979 (set_attr "memory" "both")
16980 (set_attr "mode" "HI")])
16981
16982 (define_insn "*strmovqi_1"
16983 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16984 (mem:QI (match_operand:P 3 "register_operand" "1")))
16985 (set (match_operand:P 0 "register_operand" "=D")
16986 (plus:P (match_dup 2)
16987 (const_int 1)))
16988 (set (match_operand:P 1 "register_operand" "=S")
16989 (plus:P (match_dup 3)
16990 (const_int 1)))]
16991 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16992 && ix86_check_no_addr_space (insn)"
16993 "%^movsb"
16994 [(set_attr "type" "str")
16995 (set_attr "memory" "both")
16996 (set (attr "prefix_rex")
16997 (if_then_else
16998 (match_test "<P:MODE>mode == DImode")
16999 (const_string "0")
17000 (const_string "*")))
17001 (set_attr "mode" "QI")])
17002
17003 (define_expand "rep_mov"
17004 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17005 (set (match_operand 0 "register_operand")
17006 (match_operand 5))
17007 (set (match_operand 2 "register_operand")
17008 (match_operand 6))
17009 (set (match_operand 1 "memory_operand")
17010 (match_operand 3 "memory_operand"))
17011 (use (match_dup 4))])]
17012 ""
17013 {
17014 if (TARGET_CLD)
17015 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17016 })
17017
17018 (define_insn "*rep_movdi_rex64"
17019 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17020 (set (match_operand:P 0 "register_operand" "=D")
17021 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17022 (const_int 3))
17023 (match_operand:P 3 "register_operand" "0")))
17024 (set (match_operand:P 1 "register_operand" "=S")
17025 (plus:P (ashift:P (match_dup 5) (const_int 3))
17026 (match_operand:P 4 "register_operand" "1")))
17027 (set (mem:BLK (match_dup 3))
17028 (mem:BLK (match_dup 4)))
17029 (use (match_dup 5))]
17030 "TARGET_64BIT
17031 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17032 && ix86_check_no_addr_space (insn)"
17033 "%^rep{%;} movsq"
17034 [(set_attr "type" "str")
17035 (set_attr "prefix_rep" "1")
17036 (set_attr "memory" "both")
17037 (set_attr "mode" "DI")])
17038
17039 (define_insn "*rep_movsi"
17040 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17041 (set (match_operand:P 0 "register_operand" "=D")
17042 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17043 (const_int 2))
17044 (match_operand:P 3 "register_operand" "0")))
17045 (set (match_operand:P 1 "register_operand" "=S")
17046 (plus:P (ashift:P (match_dup 5) (const_int 2))
17047 (match_operand:P 4 "register_operand" "1")))
17048 (set (mem:BLK (match_dup 3))
17049 (mem:BLK (match_dup 4)))
17050 (use (match_dup 5))]
17051 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17052 && ix86_check_no_addr_space (insn)"
17053 "%^rep{%;} movs{l|d}"
17054 [(set_attr "type" "str")
17055 (set_attr "prefix_rep" "1")
17056 (set_attr "memory" "both")
17057 (set_attr "mode" "SI")])
17058
17059 (define_insn "*rep_movqi"
17060 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17061 (set (match_operand:P 0 "register_operand" "=D")
17062 (plus:P (match_operand:P 3 "register_operand" "0")
17063 (match_operand:P 5 "register_operand" "2")))
17064 (set (match_operand:P 1 "register_operand" "=S")
17065 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17066 (set (mem:BLK (match_dup 3))
17067 (mem:BLK (match_dup 4)))
17068 (use (match_dup 5))]
17069 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17070 && ix86_check_no_addr_space (insn)"
17071 "%^rep{%;} movsb"
17072 [(set_attr "type" "str")
17073 (set_attr "prefix_rep" "1")
17074 (set_attr "memory" "both")
17075 (set_attr "mode" "QI")])
17076
17077 (define_expand "setmem<mode>"
17078 [(use (match_operand:BLK 0 "memory_operand"))
17079 (use (match_operand:SWI48 1 "nonmemory_operand"))
17080 (use (match_operand:QI 2 "nonmemory_operand"))
17081 (use (match_operand 3 "const_int_operand"))
17082 (use (match_operand:SI 4 "const_int_operand"))
17083 (use (match_operand:SI 5 "const_int_operand"))
17084 (use (match_operand:SI 6 ""))
17085 (use (match_operand:SI 7 ""))
17086 (use (match_operand:SI 8 ""))]
17087 ""
17088 {
17089 if (ix86_expand_set_or_cpymem (operands[0], NULL,
17090 operands[1], operands[2],
17091 operands[3], operands[4],
17092 operands[5], operands[6],
17093 operands[7], operands[8], true))
17094 DONE;
17095 else
17096 FAIL;
17097 })
17098
17099 ;; Most CPUs don't like single string operations
17100 ;; Handle this case here to simplify previous expander.
17101
17102 (define_expand "strset"
17103 [(set (match_operand 1 "memory_operand")
17104 (match_operand 2 "register_operand"))
17105 (parallel [(set (match_operand 0 "register_operand")
17106 (match_dup 3))
17107 (clobber (reg:CC FLAGS_REG))])]
17108 ""
17109 {
17110 /* Can't use this for non-default address spaces. */
17111 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17112 FAIL;
17113
17114 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17115 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17116
17117 /* If .md ever supports :P for Pmode, this can be directly
17118 in the pattern above. */
17119 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17120 GEN_INT (GET_MODE_SIZE (GET_MODE
17121 (operands[2]))));
17122 /* Can't use this if the user has appropriated eax or edi. */
17123 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17124 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17125 {
17126 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17127 operands[3]));
17128 DONE;
17129 }
17130 })
17131
17132 (define_expand "strset_singleop"
17133 [(parallel [(set (match_operand 1 "memory_operand")
17134 (match_operand 2 "register_operand"))
17135 (set (match_operand 0 "register_operand")
17136 (match_operand 3))
17137 (unspec [(const_int 0)] UNSPEC_STOS)])]
17138 ""
17139 {
17140 if (TARGET_CLD)
17141 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17142 })
17143
17144 (define_insn "*strsetdi_rex_1"
17145 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17146 (match_operand:DI 2 "register_operand" "a"))
17147 (set (match_operand:P 0 "register_operand" "=D")
17148 (plus:P (match_dup 1)
17149 (const_int 8)))
17150 (unspec [(const_int 0)] UNSPEC_STOS)]
17151 "TARGET_64BIT
17152 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17153 && ix86_check_no_addr_space (insn)"
17154 "%^stosq"
17155 [(set_attr "type" "str")
17156 (set_attr "memory" "store")
17157 (set_attr "mode" "DI")])
17158
17159 (define_insn "*strsetsi_1"
17160 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17161 (match_operand:SI 2 "register_operand" "a"))
17162 (set (match_operand:P 0 "register_operand" "=D")
17163 (plus:P (match_dup 1)
17164 (const_int 4)))
17165 (unspec [(const_int 0)] UNSPEC_STOS)]
17166 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17167 && ix86_check_no_addr_space (insn)"
17168 "%^stos{l|d}"
17169 [(set_attr "type" "str")
17170 (set_attr "memory" "store")
17171 (set_attr "mode" "SI")])
17172
17173 (define_insn "*strsethi_1"
17174 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17175 (match_operand:HI 2 "register_operand" "a"))
17176 (set (match_operand:P 0 "register_operand" "=D")
17177 (plus:P (match_dup 1)
17178 (const_int 2)))
17179 (unspec [(const_int 0)] UNSPEC_STOS)]
17180 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17181 && ix86_check_no_addr_space (insn)"
17182 "%^stosw"
17183 [(set_attr "type" "str")
17184 (set_attr "memory" "store")
17185 (set_attr "mode" "HI")])
17186
17187 (define_insn "*strsetqi_1"
17188 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17189 (match_operand:QI 2 "register_operand" "a"))
17190 (set (match_operand:P 0 "register_operand" "=D")
17191 (plus:P (match_dup 1)
17192 (const_int 1)))
17193 (unspec [(const_int 0)] UNSPEC_STOS)]
17194 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17195 && ix86_check_no_addr_space (insn)"
17196 "%^stosb"
17197 [(set_attr "type" "str")
17198 (set_attr "memory" "store")
17199 (set (attr "prefix_rex")
17200 (if_then_else
17201 (match_test "<P:MODE>mode == DImode")
17202 (const_string "0")
17203 (const_string "*")))
17204 (set_attr "mode" "QI")])
17205
17206 (define_expand "rep_stos"
17207 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17208 (set (match_operand 0 "register_operand")
17209 (match_operand 4))
17210 (set (match_operand 2 "memory_operand") (const_int 0))
17211 (use (match_operand 3 "register_operand"))
17212 (use (match_dup 1))])]
17213 ""
17214 {
17215 if (TARGET_CLD)
17216 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17217 })
17218
17219 (define_insn "*rep_stosdi_rex64"
17220 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17221 (set (match_operand:P 0 "register_operand" "=D")
17222 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17223 (const_int 3))
17224 (match_operand:P 3 "register_operand" "0")))
17225 (set (mem:BLK (match_dup 3))
17226 (const_int 0))
17227 (use (match_operand:DI 2 "register_operand" "a"))
17228 (use (match_dup 4))]
17229 "TARGET_64BIT
17230 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17231 && ix86_check_no_addr_space (insn)"
17232 "%^rep{%;} stosq"
17233 [(set_attr "type" "str")
17234 (set_attr "prefix_rep" "1")
17235 (set_attr "memory" "store")
17236 (set_attr "mode" "DI")])
17237
17238 (define_insn "*rep_stossi"
17239 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17240 (set (match_operand:P 0 "register_operand" "=D")
17241 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17242 (const_int 2))
17243 (match_operand:P 3 "register_operand" "0")))
17244 (set (mem:BLK (match_dup 3))
17245 (const_int 0))
17246 (use (match_operand:SI 2 "register_operand" "a"))
17247 (use (match_dup 4))]
17248 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17249 && ix86_check_no_addr_space (insn)"
17250 "%^rep{%;} stos{l|d}"
17251 [(set_attr "type" "str")
17252 (set_attr "prefix_rep" "1")
17253 (set_attr "memory" "store")
17254 (set_attr "mode" "SI")])
17255
17256 (define_insn "*rep_stosqi"
17257 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17258 (set (match_operand:P 0 "register_operand" "=D")
17259 (plus:P (match_operand:P 3 "register_operand" "0")
17260 (match_operand:P 4 "register_operand" "1")))
17261 (set (mem:BLK (match_dup 3))
17262 (const_int 0))
17263 (use (match_operand:QI 2 "register_operand" "a"))
17264 (use (match_dup 4))]
17265 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17266 && ix86_check_no_addr_space (insn)"
17267 "%^rep{%;} stosb"
17268 [(set_attr "type" "str")
17269 (set_attr "prefix_rep" "1")
17270 (set_attr "memory" "store")
17271 (set (attr "prefix_rex")
17272 (if_then_else
17273 (match_test "<P:MODE>mode == DImode")
17274 (const_string "0")
17275 (const_string "*")))
17276 (set_attr "mode" "QI")])
17277
17278 (define_expand "cmpstrnsi"
17279 [(set (match_operand:SI 0 "register_operand")
17280 (compare:SI (match_operand:BLK 1 "general_operand")
17281 (match_operand:BLK 2 "general_operand")))
17282 (use (match_operand 3 "general_operand"))
17283 (use (match_operand 4 "immediate_operand"))]
17284 ""
17285 {
17286 rtx addr1, addr2, countreg, align, out;
17287
17288 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17289 FAIL;
17290
17291 /* Can't use this if the user has appropriated ecx, esi or edi. */
17292 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17293 FAIL;
17294
17295 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17296 will have rewritten the length arg to be the minimum of the const string
17297 length and the actual length arg. If both strings are the same and
17298 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17299 will incorrectly base the results on chars past the 0 byte. */
17300 tree t1 = MEM_EXPR (operands[1]);
17301 tree t2 = MEM_EXPR (operands[2]);
17302 if (!((t1 && TREE_CODE (t1) == MEM_REF
17303 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17304 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17305 || (t2 && TREE_CODE (t2) == MEM_REF
17306 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17307 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17308 FAIL;
17309
17310 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17311 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17312 if (addr1 != XEXP (operands[1], 0))
17313 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17314 if (addr2 != XEXP (operands[2], 0))
17315 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17316
17317 countreg = ix86_zero_extend_to_Pmode (operands[3]);
17318
17319 /* %%% Iff we are testing strict equality, we can use known alignment
17320 to good advantage. This may be possible with combine, particularly
17321 once cc0 is dead. */
17322 align = operands[4];
17323
17324 if (CONST_INT_P (operands[3]))
17325 {
17326 if (operands[3] == const0_rtx)
17327 {
17328 emit_move_insn (operands[0], const0_rtx);
17329 DONE;
17330 }
17331 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17332 operands[1], operands[2]));
17333 }
17334 else
17335 {
17336 emit_insn (gen_cmp_1 (Pmode, countreg, countreg));
17337 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17338 operands[1], operands[2]));
17339 }
17340
17341 out = gen_lowpart (QImode, operands[0]);
17342 emit_insn (gen_cmpintqi (out));
17343 emit_move_insn (operands[0], gen_rtx_SIGN_EXTEND (SImode, out));
17344
17345 DONE;
17346 })
17347
17348 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17349
17350 (define_expand "cmpintqi"
17351 [(set (match_dup 1)
17352 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17353 (set (match_dup 2)
17354 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17355 (parallel [(set (match_operand:QI 0 "register_operand")
17356 (minus:QI (match_dup 1)
17357 (match_dup 2)))
17358 (clobber (reg:CC FLAGS_REG))])]
17359 ""
17360 {
17361 operands[1] = gen_reg_rtx (QImode);
17362 operands[2] = gen_reg_rtx (QImode);
17363 })
17364
17365 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17366 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17367
17368 (define_expand "cmpstrnqi_nz_1"
17369 [(parallel [(set (reg:CC FLAGS_REG)
17370 (compare:CC (match_operand 4 "memory_operand")
17371 (match_operand 5 "memory_operand")))
17372 (use (match_operand 2 "register_operand"))
17373 (use (match_operand:SI 3 "immediate_operand"))
17374 (clobber (match_operand 0 "register_operand"))
17375 (clobber (match_operand 1 "register_operand"))
17376 (clobber (match_dup 2))])]
17377 ""
17378 {
17379 if (TARGET_CLD)
17380 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17381 })
17382
17383 (define_insn "*cmpstrnqi_nz_1"
17384 [(set (reg:CC FLAGS_REG)
17385 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17386 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17387 (use (match_operand:P 6 "register_operand" "2"))
17388 (use (match_operand:SI 3 "immediate_operand" "i"))
17389 (clobber (match_operand:P 0 "register_operand" "=S"))
17390 (clobber (match_operand:P 1 "register_operand" "=D"))
17391 (clobber (match_operand:P 2 "register_operand" "=c"))]
17392 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17393 && ix86_check_no_addr_space (insn)"
17394 "%^repz{%;} cmpsb"
17395 [(set_attr "type" "str")
17396 (set_attr "mode" "QI")
17397 (set (attr "prefix_rex")
17398 (if_then_else
17399 (match_test "<P:MODE>mode == DImode")
17400 (const_string "0")
17401 (const_string "*")))
17402 (set_attr "prefix_rep" "1")])
17403
17404 ;; The same, but the count is not known to not be zero.
17405
17406 (define_expand "cmpstrnqi_1"
17407 [(parallel [(set (reg:CC FLAGS_REG)
17408 (if_then_else:CC (ne (match_operand 2 "register_operand")
17409 (const_int 0))
17410 (compare:CC (match_operand 4 "memory_operand")
17411 (match_operand 5 "memory_operand"))
17412 (const_int 0)))
17413 (use (match_operand:SI 3 "immediate_operand"))
17414 (use (reg:CC FLAGS_REG))
17415 (clobber (match_operand 0 "register_operand"))
17416 (clobber (match_operand 1 "register_operand"))
17417 (clobber (match_dup 2))])]
17418 ""
17419 {
17420 if (TARGET_CLD)
17421 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17422 })
17423
17424 (define_insn "*cmpstrnqi_1"
17425 [(set (reg:CC FLAGS_REG)
17426 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17427 (const_int 0))
17428 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17429 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17430 (const_int 0)))
17431 (use (match_operand:SI 3 "immediate_operand" "i"))
17432 (use (reg:CC FLAGS_REG))
17433 (clobber (match_operand:P 0 "register_operand" "=S"))
17434 (clobber (match_operand:P 1 "register_operand" "=D"))
17435 (clobber (match_operand:P 2 "register_operand" "=c"))]
17436 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17437 && ix86_check_no_addr_space (insn)"
17438 "%^repz{%;} cmpsb"
17439 [(set_attr "type" "str")
17440 (set_attr "mode" "QI")
17441 (set (attr "prefix_rex")
17442 (if_then_else
17443 (match_test "<P:MODE>mode == DImode")
17444 (const_string "0")
17445 (const_string "*")))
17446 (set_attr "prefix_rep" "1")])
17447
17448 (define_expand "strlen<mode>"
17449 [(set (match_operand:P 0 "register_operand")
17450 (unspec:P [(match_operand:BLK 1 "general_operand")
17451 (match_operand:QI 2 "immediate_operand")
17452 (match_operand 3 "immediate_operand")]
17453 UNSPEC_SCAS))]
17454 ""
17455 {
17456 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17457 DONE;
17458 else
17459 FAIL;
17460 })
17461
17462 (define_expand "strlenqi_1"
17463 [(parallel [(set (match_operand 0 "register_operand")
17464 (match_operand 2))
17465 (clobber (match_operand 1 "register_operand"))
17466 (clobber (reg:CC FLAGS_REG))])]
17467 ""
17468 {
17469 if (TARGET_CLD)
17470 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17471 })
17472
17473 (define_insn "*strlenqi_1"
17474 [(set (match_operand:P 0 "register_operand" "=&c")
17475 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17476 (match_operand:QI 2 "register_operand" "a")
17477 (match_operand:P 3 "immediate_operand" "i")
17478 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17479 (clobber (match_operand:P 1 "register_operand" "=D"))
17480 (clobber (reg:CC FLAGS_REG))]
17481 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17482 && ix86_check_no_addr_space (insn)"
17483 "%^repnz{%;} scasb"
17484 [(set_attr "type" "str")
17485 (set_attr "mode" "QI")
17486 (set (attr "prefix_rex")
17487 (if_then_else
17488 (match_test "<P:MODE>mode == DImode")
17489 (const_string "0")
17490 (const_string "*")))
17491 (set_attr "prefix_rep" "1")])
17492
17493 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17494 ;; handled in combine, but it is not currently up to the task.
17495 ;; When used for their truth value, the cmpstrn* expanders generate
17496 ;; code like this:
17497 ;;
17498 ;; repz cmpsb
17499 ;; seta %al
17500 ;; setb %dl
17501 ;; cmpb %al, %dl
17502 ;; jcc label
17503 ;;
17504 ;; The intermediate three instructions are unnecessary.
17505
17506 ;; This one handles cmpstrn*_nz_1...
17507 (define_peephole2
17508 [(parallel[
17509 (set (reg:CC FLAGS_REG)
17510 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17511 (mem:BLK (match_operand 5 "register_operand"))))
17512 (use (match_operand 6 "register_operand"))
17513 (use (match_operand:SI 3 "immediate_operand"))
17514 (clobber (match_operand 0 "register_operand"))
17515 (clobber (match_operand 1 "register_operand"))
17516 (clobber (match_operand 2 "register_operand"))])
17517 (set (match_operand:QI 7 "register_operand")
17518 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17519 (set (match_operand:QI 8 "register_operand")
17520 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17521 (set (reg FLAGS_REG)
17522 (compare (match_dup 7) (match_dup 8)))
17523 ]
17524 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17525 [(parallel[
17526 (set (reg:CC FLAGS_REG)
17527 (compare:CC (mem:BLK (match_dup 4))
17528 (mem:BLK (match_dup 5))))
17529 (use (match_dup 6))
17530 (use (match_dup 3))
17531 (clobber (match_dup 0))
17532 (clobber (match_dup 1))
17533 (clobber (match_dup 2))])])
17534
17535 ;; ...and this one handles cmpstrn*_1.
17536 (define_peephole2
17537 [(parallel[
17538 (set (reg:CC FLAGS_REG)
17539 (if_then_else:CC (ne (match_operand 6 "register_operand")
17540 (const_int 0))
17541 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17542 (mem:BLK (match_operand 5 "register_operand")))
17543 (const_int 0)))
17544 (use (match_operand:SI 3 "immediate_operand"))
17545 (use (reg:CC FLAGS_REG))
17546 (clobber (match_operand 0 "register_operand"))
17547 (clobber (match_operand 1 "register_operand"))
17548 (clobber (match_operand 2 "register_operand"))])
17549 (set (match_operand:QI 7 "register_operand")
17550 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17551 (set (match_operand:QI 8 "register_operand")
17552 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17553 (set (reg FLAGS_REG)
17554 (compare (match_dup 7) (match_dup 8)))
17555 ]
17556 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17557 [(parallel[
17558 (set (reg:CC FLAGS_REG)
17559 (if_then_else:CC (ne (match_dup 6)
17560 (const_int 0))
17561 (compare:CC (mem:BLK (match_dup 4))
17562 (mem:BLK (match_dup 5)))
17563 (const_int 0)))
17564 (use (match_dup 3))
17565 (use (reg:CC FLAGS_REG))
17566 (clobber (match_dup 0))
17567 (clobber (match_dup 1))
17568 (clobber (match_dup 2))])])
17569 \f
17570 ;; Conditional move instructions.
17571
17572 (define_expand "mov<mode>cc"
17573 [(set (match_operand:SWIM 0 "register_operand")
17574 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17575 (match_operand:SWIM 2 "<general_operand>")
17576 (match_operand:SWIM 3 "<general_operand>")))]
17577 ""
17578 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17579
17580 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17581 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17582 ;; So just document what we're doing explicitly.
17583
17584 (define_expand "x86_mov<mode>cc_0_m1"
17585 [(parallel
17586 [(set (match_operand:SWI48 0 "register_operand")
17587 (if_then_else:SWI48
17588 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17589 [(match_operand 1 "flags_reg_operand")
17590 (const_int 0)])
17591 (const_int -1)
17592 (const_int 0)))
17593 (clobber (reg:CC FLAGS_REG))])])
17594
17595 (define_insn "*x86_mov<mode>cc_0_m1"
17596 [(set (match_operand:SWI48 0 "register_operand" "=r")
17597 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17598 [(reg FLAGS_REG) (const_int 0)])
17599 (const_int -1)
17600 (const_int 0)))
17601 (clobber (reg:CC FLAGS_REG))]
17602 ""
17603 "sbb{<imodesuffix>}\t%0, %0"
17604 [(set_attr "type" "alu1")
17605 (set_attr "use_carry" "1")
17606 (set_attr "pent_pair" "pu")
17607 (set_attr "mode" "<MODE>")
17608 (set_attr "length_immediate" "0")])
17609
17610 (define_insn "*x86_mov<mode>cc_0_m1_se"
17611 [(set (match_operand:SWI48 0 "register_operand" "=r")
17612 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17613 [(reg FLAGS_REG) (const_int 0)])
17614 (const_int 1)
17615 (const_int 0)))
17616 (clobber (reg:CC FLAGS_REG))]
17617 ""
17618 "sbb{<imodesuffix>}\t%0, %0"
17619 [(set_attr "type" "alu1")
17620 (set_attr "use_carry" "1")
17621 (set_attr "pent_pair" "pu")
17622 (set_attr "mode" "<MODE>")
17623 (set_attr "length_immediate" "0")])
17624
17625 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17626 [(set (match_operand:SWI48 0 "register_operand" "=r")
17627 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17628 [(reg FLAGS_REG) (const_int 0)])))
17629 (clobber (reg:CC FLAGS_REG))]
17630 ""
17631 "sbb{<imodesuffix>}\t%0, %0"
17632 [(set_attr "type" "alu1")
17633 (set_attr "use_carry" "1")
17634 (set_attr "pent_pair" "pu")
17635 (set_attr "mode" "<MODE>")
17636 (set_attr "length_immediate" "0")])
17637
17638 (define_insn_and_split "*x86_mov<SWI48:mode>cc_0_m1_neg_leu<SWI:mode>"
17639 [(set (match_operand:SWI48 0 "register_operand" "=r")
17640 (neg:SWI48
17641 (leu:SWI48
17642 (match_operand:SWI 1 "nonimmediate_operand" "<SWI:r>m")
17643 (match_operand:SWI 2 "<SWI:immediate_operand>" "<SWI:i>"))))
17644 (clobber (reg:CC FLAGS_REG))]
17645 "CONST_INT_P (operands[2])
17646 && INTVAL (operands[2]) != -1
17647 && INTVAL (operands[2]) != 2147483647"
17648 "#"
17649 ""
17650 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
17651 (parallel [(set (match_dup 0)
17652 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
17653 (clobber (reg:CC FLAGS_REG))])]
17654 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
17655
17656 (define_insn "*mov<mode>cc_noc"
17657 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17658 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17659 [(reg FLAGS_REG) (const_int 0)])
17660 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17661 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17662 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17663 "@
17664 cmov%O2%C1\t{%2, %0|%0, %2}
17665 cmov%O2%c1\t{%3, %0|%0, %3}"
17666 [(set_attr "type" "icmov")
17667 (set_attr "mode" "<MODE>")])
17668
17669 (define_insn "*movsicc_noc_zext"
17670 [(set (match_operand:DI 0 "register_operand" "=r,r")
17671 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17672 [(reg FLAGS_REG) (const_int 0)])
17673 (zero_extend:DI
17674 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17675 (zero_extend:DI
17676 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17677 "TARGET_64BIT
17678 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17679 "@
17680 cmov%O2%C1\t{%2, %k0|%k0, %2}
17681 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17682 [(set_attr "type" "icmov")
17683 (set_attr "mode" "SI")])
17684
17685 ;; Don't do conditional moves with memory inputs. This splitter helps
17686 ;; register starved x86_32 by forcing inputs into registers before reload.
17687 (define_split
17688 [(set (match_operand:SWI248 0 "register_operand")
17689 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17690 [(reg FLAGS_REG) (const_int 0)])
17691 (match_operand:SWI248 2 "nonimmediate_operand")
17692 (match_operand:SWI248 3 "nonimmediate_operand")))]
17693 "!TARGET_64BIT && TARGET_CMOVE
17694 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17695 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17696 && can_create_pseudo_p ()
17697 && optimize_insn_for_speed_p ()"
17698 [(set (match_dup 0)
17699 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17700 {
17701 if (MEM_P (operands[2]))
17702 operands[2] = force_reg (<MODE>mode, operands[2]);
17703 if (MEM_P (operands[3]))
17704 operands[3] = force_reg (<MODE>mode, operands[3]);
17705 })
17706
17707 (define_insn "*movqicc_noc"
17708 [(set (match_operand:QI 0 "register_operand" "=r,r")
17709 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17710 [(reg FLAGS_REG) (const_int 0)])
17711 (match_operand:QI 2 "register_operand" "r,0")
17712 (match_operand:QI 3 "register_operand" "0,r")))]
17713 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17714 "#"
17715 [(set_attr "type" "icmov")
17716 (set_attr "mode" "QI")])
17717
17718 (define_split
17719 [(set (match_operand:SWI12 0 "register_operand")
17720 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17721 [(reg FLAGS_REG) (const_int 0)])
17722 (match_operand:SWI12 2 "register_operand")
17723 (match_operand:SWI12 3 "register_operand")))]
17724 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17725 && reload_completed"
17726 [(set (match_dup 0)
17727 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17728 {
17729 operands[0] = gen_lowpart (SImode, operands[0]);
17730 operands[2] = gen_lowpart (SImode, operands[2]);
17731 operands[3] = gen_lowpart (SImode, operands[3]);
17732 })
17733
17734 ;; Don't do conditional moves with memory inputs
17735 (define_peephole2
17736 [(match_scratch:SWI248 4 "r")
17737 (set (match_operand:SWI248 0 "register_operand")
17738 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17739 [(reg FLAGS_REG) (const_int 0)])
17740 (match_operand:SWI248 2 "nonimmediate_operand")
17741 (match_operand:SWI248 3 "nonimmediate_operand")))]
17742 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17743 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17744 && optimize_insn_for_speed_p ()"
17745 [(set (match_dup 4) (match_dup 5))
17746 (set (match_dup 0)
17747 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17748 {
17749 if (MEM_P (operands[2]))
17750 {
17751 operands[5] = operands[2];
17752 operands[2] = operands[4];
17753 }
17754 else if (MEM_P (operands[3]))
17755 {
17756 operands[5] = operands[3];
17757 operands[3] = operands[4];
17758 }
17759 else
17760 gcc_unreachable ();
17761 })
17762
17763 (define_peephole2
17764 [(match_scratch:SI 4 "r")
17765 (set (match_operand:DI 0 "register_operand")
17766 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17767 [(reg FLAGS_REG) (const_int 0)])
17768 (zero_extend:DI
17769 (match_operand:SI 2 "nonimmediate_operand"))
17770 (zero_extend:DI
17771 (match_operand:SI 3 "nonimmediate_operand"))))]
17772 "TARGET_64BIT
17773 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17774 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17775 && optimize_insn_for_speed_p ()"
17776 [(set (match_dup 4) (match_dup 5))
17777 (set (match_dup 0)
17778 (if_then_else:DI (match_dup 1)
17779 (zero_extend:DI (match_dup 2))
17780 (zero_extend:DI (match_dup 3))))]
17781 {
17782 if (MEM_P (operands[2]))
17783 {
17784 operands[5] = operands[2];
17785 operands[2] = operands[4];
17786 }
17787 else if (MEM_P (operands[3]))
17788 {
17789 operands[5] = operands[3];
17790 operands[3] = operands[4];
17791 }
17792 else
17793 gcc_unreachable ();
17794 })
17795
17796 (define_expand "mov<mode>cc"
17797 [(set (match_operand:X87MODEF 0 "register_operand")
17798 (if_then_else:X87MODEF
17799 (match_operand 1 "comparison_operator")
17800 (match_operand:X87MODEF 2 "register_operand")
17801 (match_operand:X87MODEF 3 "register_operand")))]
17802 "(TARGET_80387 && TARGET_CMOVE)
17803 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17804 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17805
17806 (define_insn "*movxfcc_1"
17807 [(set (match_operand:XF 0 "register_operand" "=f,f")
17808 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17809 [(reg FLAGS_REG) (const_int 0)])
17810 (match_operand:XF 2 "register_operand" "f,0")
17811 (match_operand:XF 3 "register_operand" "0,f")))]
17812 "TARGET_80387 && TARGET_CMOVE"
17813 "@
17814 fcmov%F1\t{%2, %0|%0, %2}
17815 fcmov%f1\t{%3, %0|%0, %3}"
17816 [(set_attr "type" "fcmov")
17817 (set_attr "mode" "XF")])
17818
17819 (define_insn "*movdfcc_1"
17820 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17821 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17822 [(reg FLAGS_REG) (const_int 0)])
17823 (match_operand:DF 2 "nonimmediate_operand"
17824 "f ,0,rm,0 ,rm,0")
17825 (match_operand:DF 3 "nonimmediate_operand"
17826 "0 ,f,0 ,rm,0, rm")))]
17827 "TARGET_80387 && TARGET_CMOVE
17828 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17829 "@
17830 fcmov%F1\t{%2, %0|%0, %2}
17831 fcmov%f1\t{%3, %0|%0, %3}
17832 #
17833 #
17834 cmov%O2%C1\t{%2, %0|%0, %2}
17835 cmov%O2%c1\t{%3, %0|%0, %3}"
17836 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17837 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17838 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17839
17840 (define_split
17841 [(set (match_operand:DF 0 "general_reg_operand")
17842 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17843 [(reg FLAGS_REG) (const_int 0)])
17844 (match_operand:DF 2 "nonimmediate_operand")
17845 (match_operand:DF 3 "nonimmediate_operand")))]
17846 "!TARGET_64BIT && reload_completed"
17847 [(set (match_dup 2)
17848 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17849 (set (match_dup 3)
17850 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17851 {
17852 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17853 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17854 })
17855
17856 (define_insn "*movsfcc_1_387"
17857 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17858 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17859 [(reg FLAGS_REG) (const_int 0)])
17860 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17861 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17862 "TARGET_80387 && TARGET_CMOVE
17863 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17864 "@
17865 fcmov%F1\t{%2, %0|%0, %2}
17866 fcmov%f1\t{%3, %0|%0, %3}
17867 cmov%O2%C1\t{%2, %0|%0, %2}
17868 cmov%O2%c1\t{%3, %0|%0, %3}"
17869 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17870 (set_attr "mode" "SF,SF,SI,SI")])
17871
17872 ;; Don't do conditional moves with memory inputs. This splitter helps
17873 ;; register starved x86_32 by forcing inputs into registers before reload.
17874 (define_split
17875 [(set (match_operand:MODEF 0 "register_operand")
17876 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17877 [(reg FLAGS_REG) (const_int 0)])
17878 (match_operand:MODEF 2 "nonimmediate_operand")
17879 (match_operand:MODEF 3 "nonimmediate_operand")))]
17880 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17881 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17882 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17883 && can_create_pseudo_p ()
17884 && optimize_insn_for_speed_p ()"
17885 [(set (match_dup 0)
17886 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17887 {
17888 if (MEM_P (operands[2]))
17889 operands[2] = force_reg (<MODE>mode, operands[2]);
17890 if (MEM_P (operands[3]))
17891 operands[3] = force_reg (<MODE>mode, operands[3]);
17892 })
17893
17894 ;; Don't do conditional moves with memory inputs
17895 (define_peephole2
17896 [(match_scratch:MODEF 4 "r")
17897 (set (match_operand:MODEF 0 "general_reg_operand")
17898 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17899 [(reg FLAGS_REG) (const_int 0)])
17900 (match_operand:MODEF 2 "nonimmediate_operand")
17901 (match_operand:MODEF 3 "nonimmediate_operand")))]
17902 "(<MODE>mode != DFmode || TARGET_64BIT)
17903 && TARGET_80387 && TARGET_CMOVE
17904 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17905 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17906 && optimize_insn_for_speed_p ()"
17907 [(set (match_dup 4) (match_dup 5))
17908 (set (match_dup 0)
17909 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17910 {
17911 if (MEM_P (operands[2]))
17912 {
17913 operands[5] = operands[2];
17914 operands[2] = operands[4];
17915 }
17916 else if (MEM_P (operands[3]))
17917 {
17918 operands[5] = operands[3];
17919 operands[3] = operands[4];
17920 }
17921 else
17922 gcc_unreachable ();
17923 })
17924
17925 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17926 ;; the scalar versions to have only XMM registers as operands.
17927
17928 ;; XOP conditional move
17929 (define_insn "*xop_pcmov_<mode>"
17930 [(set (match_operand:MODEF 0 "register_operand" "=x")
17931 (if_then_else:MODEF
17932 (match_operand:MODEF 1 "register_operand" "x")
17933 (match_operand:MODEF 2 "register_operand" "x")
17934 (match_operand:MODEF 3 "register_operand" "x")))]
17935 "TARGET_XOP"
17936 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17937 [(set_attr "type" "sse4arg")])
17938
17939 ;; These versions of the min/max patterns are intentionally ignorant of
17940 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17941 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17942 ;; are undefined in this condition, we're certain this is correct.
17943
17944 (define_insn "<code><mode>3"
17945 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17946 (smaxmin:MODEF
17947 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17948 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17949 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17950 "@
17951 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17952 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17953 [(set_attr "isa" "noavx,avx")
17954 (set_attr "prefix" "orig,vex")
17955 (set_attr "type" "sseadd")
17956 (set_attr "mode" "<MODE>")])
17957
17958 ;; These versions of the min/max patterns implement exactly the operations
17959 ;; min = (op1 < op2 ? op1 : op2)
17960 ;; max = (!(op1 < op2) ? op1 : op2)
17961 ;; Their operands are not commutative, and thus they may be used in the
17962 ;; presence of -0.0 and NaN.
17963
17964 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17965 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17966 (unspec:MODEF
17967 [(match_operand:MODEF 1 "register_operand" "0,v")
17968 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17969 IEEE_MAXMIN))]
17970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17971 "@
17972 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17973 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17974 [(set_attr "isa" "noavx,avx")
17975 (set_attr "prefix" "orig,maybe_evex")
17976 (set_attr "type" "sseadd")
17977 (set_attr "mode" "<MODE>")])
17978
17979 ;; Make two stack loads independent:
17980 ;; fld aa fld aa
17981 ;; fld %st(0) -> fld bb
17982 ;; fmul bb fmul %st(1), %st
17983 ;;
17984 ;; Actually we only match the last two instructions for simplicity.
17985
17986 (define_peephole2
17987 [(set (match_operand 0 "fp_register_operand")
17988 (match_operand 1 "fp_register_operand"))
17989 (set (match_dup 0)
17990 (match_operator 2 "binary_fp_operator"
17991 [(match_dup 0)
17992 (match_operand 3 "memory_operand")]))]
17993 "REGNO (operands[0]) != REGNO (operands[1])"
17994 [(set (match_dup 0) (match_dup 3))
17995 (set (match_dup 0)
17996 (match_op_dup 2
17997 [(match_dup 5) (match_dup 4)]))]
17998 {
17999 operands[4] = operands[0];
18000 operands[5] = operands[1];
18001
18002 /* The % modifier is not operational anymore in peephole2's, so we have to
18003 swap the operands manually in the case of addition and multiplication. */
18004 if (COMMUTATIVE_ARITH_P (operands[2]))
18005 std::swap (operands[4], operands[5]);
18006 })
18007
18008 (define_peephole2
18009 [(set (match_operand 0 "fp_register_operand")
18010 (match_operand 1 "fp_register_operand"))
18011 (set (match_dup 0)
18012 (match_operator 2 "binary_fp_operator"
18013 [(match_operand 3 "memory_operand")
18014 (match_dup 0)]))]
18015 "REGNO (operands[0]) != REGNO (operands[1])"
18016 [(set (match_dup 0) (match_dup 3))
18017 (set (match_dup 0)
18018 (match_op_dup 2
18019 [(match_dup 4) (match_dup 5)]))]
18020 {
18021 operands[4] = operands[0];
18022 operands[5] = operands[1];
18023
18024 /* The % modifier is not operational anymore in peephole2's, so we have to
18025 swap the operands manually in the case of addition and multiplication. */
18026 if (COMMUTATIVE_ARITH_P (operands[2]))
18027 std::swap (operands[4], operands[5]);
18028 })
18029
18030 ;; Conditional addition patterns
18031 (define_expand "add<mode>cc"
18032 [(match_operand:SWI 0 "register_operand")
18033 (match_operand 1 "ordered_comparison_operator")
18034 (match_operand:SWI 2 "register_operand")
18035 (match_operand:SWI 3 "const_int_operand")]
18036 ""
18037 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18038
18039 ;; min/max patterns
18040
18041 (define_mode_iterator MAXMIN_IMODE
18042 [(SI "TARGET_SSE4_1") (DI "TARGET_AVX512VL")])
18043 (define_code_attr maxmin_rel
18044 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
18045
18046 (define_expand "<code><mode>3"
18047 [(parallel
18048 [(set (match_operand:MAXMIN_IMODE 0 "register_operand")
18049 (maxmin:MAXMIN_IMODE
18050 (match_operand:MAXMIN_IMODE 1 "register_operand")
18051 (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand")))
18052 (clobber (reg:CC FLAGS_REG))])]
18053 "TARGET_STV")
18054
18055 (define_insn_and_split "*<code><mode>3_1"
18056 [(set (match_operand:MAXMIN_IMODE 0 "register_operand")
18057 (maxmin:MAXMIN_IMODE
18058 (match_operand:MAXMIN_IMODE 1 "register_operand")
18059 (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand")))
18060 (clobber (reg:CC FLAGS_REG))]
18061 "(TARGET_64BIT || <MODE>mode != DImode) && TARGET_STV
18062 && ix86_pre_reload_split ()"
18063 "#"
18064 "&& 1"
18065 [(set (match_dup 0)
18066 (if_then_else:MAXMIN_IMODE (match_dup 3)
18067 (match_dup 1)
18068 (match_dup 2)))]
18069 {
18070 machine_mode mode = <MODE>mode;
18071
18072 if (!register_operand (operands[2], mode))
18073 operands[2] = force_reg (mode, operands[2]);
18074
18075 enum rtx_code code = <maxmin_rel>;
18076 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], operands[2]);
18077 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
18078
18079 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], operands[2]);
18080 emit_insn (gen_rtx_SET (flags, tmp));
18081
18082 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
18083 })
18084
18085 (define_insn_and_split "*<code>di3_doubleword"
18086 [(set (match_operand:DI 0 "register_operand")
18087 (maxmin:DI (match_operand:DI 1 "register_operand")
18088 (match_operand:DI 2 "nonimmediate_operand")))
18089 (clobber (reg:CC FLAGS_REG))]
18090 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
18091 && ix86_pre_reload_split ()"
18092 "#"
18093 "&& 1"
18094 [(set (match_dup 0)
18095 (if_then_else:SI (match_dup 6)
18096 (match_dup 1)
18097 (match_dup 2)))
18098 (set (match_dup 3)
18099 (if_then_else:SI (match_dup 6)
18100 (match_dup 4)
18101 (match_dup 5)))]
18102 {
18103 if (!register_operand (operands[2], DImode))
18104 operands[2] = force_reg (DImode, operands[2]);
18105
18106 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
18107
18108 rtx cmplo[2] = { operands[1], operands[2] };
18109 rtx cmphi[2] = { operands[4], operands[5] };
18110
18111 enum rtx_code code = <maxmin_rel>;
18112
18113 switch (code)
18114 {
18115 case LE: case LEU:
18116 std::swap (cmplo[0], cmplo[1]);
18117 std::swap (cmphi[0], cmphi[1]);
18118 code = swap_condition (code);
18119 /* FALLTHRU */
18120
18121 case GE: case GEU:
18122 {
18123 bool uns = (code == GEU);
18124 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
18125 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
18126
18127 emit_insn (gen_cmp_1 (SImode, cmplo[0], cmplo[1]));
18128
18129 rtx tmp = gen_rtx_SCRATCH (SImode);
18130 emit_insn (sbb_insn (SImode, tmp, cmphi[0], cmphi[1]));
18131
18132 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
18133 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
18134
18135 break;
18136 }
18137
18138 default:
18139 gcc_unreachable ();
18140 }
18141 })
18142 \f
18143 ;; Misc patterns (?)
18144
18145 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18146 ;; Otherwise there will be nothing to keep
18147 ;;
18148 ;; [(set (reg ebp) (reg esp))]
18149 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18150 ;; (clobber (eflags)]
18151 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18152 ;;
18153 ;; in proper program order.
18154
18155 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
18156 [(set (match_operand:P 0 "register_operand" "=r,r")
18157 (plus:P (match_operand:P 1 "register_operand" "0,r")
18158 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18159 (clobber (reg:CC FLAGS_REG))
18160 (clobber (mem:BLK (scratch)))]
18161 ""
18162 {
18163 switch (get_attr_type (insn))
18164 {
18165 case TYPE_IMOV:
18166 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18167
18168 case TYPE_ALU:
18169 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18170 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18171 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18172
18173 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18174
18175 default:
18176 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18177 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18178 }
18179 }
18180 [(set (attr "type")
18181 (cond [(and (eq_attr "alternative" "0")
18182 (not (match_test "TARGET_OPT_AGU")))
18183 (const_string "alu")
18184 (match_operand:<MODE> 2 "const0_operand")
18185 (const_string "imov")
18186 ]
18187 (const_string "lea")))
18188 (set (attr "length_immediate")
18189 (cond [(eq_attr "type" "imov")
18190 (const_string "0")
18191 (and (eq_attr "type" "alu")
18192 (match_operand 2 "const128_operand"))
18193 (const_string "1")
18194 ]
18195 (const_string "*")))
18196 (set_attr "mode" "<MODE>")])
18197
18198 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
18199 [(set (match_operand:P 0 "register_operand" "=r")
18200 (minus:P (match_operand:P 1 "register_operand" "0")
18201 (match_operand:P 2 "register_operand" "r")))
18202 (clobber (reg:CC FLAGS_REG))
18203 (clobber (mem:BLK (scratch)))]
18204 ""
18205 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18206 [(set_attr "type" "alu")
18207 (set_attr "mode" "<MODE>")])
18208
18209 (define_insn "@allocate_stack_worker_probe_<mode>"
18210 [(set (match_operand:P 0 "register_operand" "=a")
18211 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18212 UNSPECV_STACK_PROBE))
18213 (clobber (reg:CC FLAGS_REG))]
18214 "ix86_target_stack_probe ()"
18215 "call\t___chkstk_ms"
18216 [(set_attr "type" "multi")
18217 (set_attr "length" "5")])
18218
18219 (define_expand "allocate_stack"
18220 [(match_operand 0 "register_operand")
18221 (match_operand 1 "general_operand")]
18222 "ix86_target_stack_probe ()"
18223 {
18224 rtx x;
18225
18226 #ifndef CHECK_STACK_LIMIT
18227 #define CHECK_STACK_LIMIT 0
18228 #endif
18229
18230 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18231 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18232 x = operands[1];
18233 else
18234 {
18235 x = copy_to_mode_reg (Pmode, operands[1]);
18236
18237 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
18238 }
18239
18240 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18241 stack_pointer_rtx, 0, OPTAB_DIRECT);
18242
18243 if (x != stack_pointer_rtx)
18244 emit_move_insn (stack_pointer_rtx, x);
18245
18246 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18247 DONE;
18248 })
18249
18250 (define_expand "probe_stack"
18251 [(match_operand 0 "memory_operand")]
18252 ""
18253 {
18254 emit_insn (gen_probe_stack_1
18255 (word_mode, operands[0], const0_rtx));
18256 DONE;
18257 })
18258
18259 ;; Use OR for stack probes, this is shorter.
18260 (define_insn "@probe_stack_1_<mode>"
18261 [(set (match_operand:W 0 "memory_operand" "=m")
18262 (unspec:W [(match_operand:W 1 "const0_operand")]
18263 UNSPEC_PROBE_STACK))
18264 (clobber (reg:CC FLAGS_REG))]
18265 ""
18266 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18267 [(set_attr "type" "alu1")
18268 (set_attr "mode" "<MODE>")
18269 (set_attr "length_immediate" "1")])
18270
18271 (define_insn "@adjust_stack_and_probe_<mode>"
18272 [(set (match_operand:P 0 "register_operand" "=r")
18273 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18274 UNSPECV_PROBE_STACK_RANGE))
18275 (set (reg:P SP_REG)
18276 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18277 (clobber (reg:CC FLAGS_REG))
18278 (clobber (mem:BLK (scratch)))]
18279 ""
18280 "* return output_adjust_stack_and_probe (operands[0]);"
18281 [(set_attr "type" "multi")])
18282
18283 (define_insn "@probe_stack_range_<mode>"
18284 [(set (match_operand:P 0 "register_operand" "=r")
18285 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18286 (match_operand:P 2 "const_int_operand" "n")]
18287 UNSPECV_PROBE_STACK_RANGE))
18288 (clobber (reg:CC FLAGS_REG))]
18289 ""
18290 "* return output_probe_stack_range (operands[0], operands[2]);"
18291 [(set_attr "type" "multi")])
18292
18293 (define_expand "builtin_setjmp_receiver"
18294 [(label_ref (match_operand 0))]
18295 "!TARGET_64BIT && flag_pic"
18296 {
18297 #if TARGET_MACHO
18298 if (TARGET_MACHO)
18299 {
18300 rtx xops[3];
18301 rtx_code_label *label_rtx = gen_label_rtx ();
18302 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18303 xops[0] = xops[1] = pic_offset_table_rtx;
18304 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18305 ix86_expand_binary_operator (MINUS, SImode, xops);
18306 }
18307 else
18308 #endif
18309 emit_insn (gen_set_got (pic_offset_table_rtx));
18310 DONE;
18311 })
18312
18313 (define_expand "save_stack_nonlocal"
18314 [(set (match_operand 0 "memory_operand")
18315 (match_operand 1 "register_operand"))]
18316 ""
18317 {
18318 rtx stack_slot;
18319 if ((flag_cf_protection & CF_RETURN))
18320 {
18321 /* Copy shadow stack pointer to the first slot and stack ppointer
18322 to the second slot. */
18323 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18324 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18325 rtx ssp = gen_reg_rtx (word_mode);
18326 emit_insn ((word_mode == SImode)
18327 ? gen_rdsspsi (ssp)
18328 : gen_rdsspdi (ssp));
18329 emit_move_insn (ssp_slot, ssp);
18330 }
18331 else
18332 stack_slot = adjust_address (operands[0], Pmode, 0);
18333 emit_move_insn (stack_slot, operands[1]);
18334 DONE;
18335 })
18336
18337 (define_expand "restore_stack_nonlocal"
18338 [(set (match_operand 0 "register_operand" "")
18339 (match_operand 1 "memory_operand" ""))]
18340 ""
18341 {
18342 rtx stack_slot;
18343 if ((flag_cf_protection & CF_RETURN))
18344 {
18345 /* Restore shadow stack pointer from the first slot and stack
18346 pointer from the second slot. */
18347 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18348 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18349
18350 rtx flags, jump, noadj_label, inc_label, loop_label;
18351 rtx reg_adj, reg_ssp, tmp, clob;
18352
18353 /* Get the current shadow stack pointer. The code below will check if
18354 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18355 is a NOP. */
18356 reg_ssp = gen_reg_rtx (word_mode);
18357 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18358 emit_insn ((word_mode == SImode)
18359 ? gen_rdsspsi (reg_ssp)
18360 : gen_rdsspdi (reg_ssp));
18361
18362 /* Compare through substraction the saved and the current ssp to decide
18363 if ssp has to be adjusted. */
18364 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18365 ssp_slot));
18366 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18367 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18368 emit_insn (tmp);
18369
18370 /* Compare and jump over adjustment code. */
18371 noadj_label = gen_label_rtx ();
18372 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18373 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18374 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18375 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18376 pc_rtx);
18377 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18378 JUMP_LABEL (jump) = noadj_label;
18379
18380 /* Compute the numebr of frames to adjust. */
18381 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18382 tmp = gen_rtx_SET (reg_adj,
18383 gen_rtx_LSHIFTRT (ptr_mode,
18384 negate_rtx (ptr_mode, reg_adj),
18385 GEN_INT ((word_mode == SImode)
18386 ? 2
18387 : 3)));
18388 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18389 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18390 emit_insn (tmp);
18391
18392 /* Check if number of frames <= 255 so no loop is needed. */
18393 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18394 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18395 emit_insn (gen_rtx_SET (flags, tmp));
18396
18397 inc_label = gen_label_rtx ();
18398 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18399 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18400 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18401 pc_rtx);
18402 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18403 JUMP_LABEL (jump) = inc_label;
18404
18405 rtx reg_255 = gen_reg_rtx (word_mode);
18406 emit_move_insn (reg_255, GEN_INT (255));
18407
18408 /* Adjust the ssp in a loop. */
18409 loop_label = gen_label_rtx ();
18410 emit_label (loop_label);
18411 LABEL_NUSES (loop_label) = 1;
18412
18413 emit_insn ((word_mode == SImode)
18414 ? gen_incsspsi (reg_255)
18415 : gen_incsspdi (reg_255));
18416 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18417 reg_adj,
18418 GEN_INT (255)));
18419 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18420 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18421 emit_insn (tmp);
18422
18423 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18424 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18425 emit_insn (gen_rtx_SET (flags, tmp));
18426
18427 /* Jump to the loop label. */
18428 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18429 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18430 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18431 pc_rtx);
18432 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18433 JUMP_LABEL (jump) = loop_label;
18434
18435 emit_label (inc_label);
18436 LABEL_NUSES (inc_label) = 1;
18437 emit_insn ((word_mode == SImode)
18438 ? gen_incsspsi (reg_ssp)
18439 : gen_incsspdi (reg_ssp));
18440
18441 emit_label (noadj_label);
18442 LABEL_NUSES (noadj_label) = 1;
18443 }
18444 else
18445 stack_slot = adjust_address (operands[1], Pmode, 0);
18446 emit_move_insn (operands[0], stack_slot);
18447 DONE;
18448 })
18449
18450
18451 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18452 ;; Do not split instructions with mask registers.
18453 (define_split
18454 [(set (match_operand 0 "general_reg_operand")
18455 (match_operator 3 "promotable_binary_operator"
18456 [(match_operand 1 "general_reg_operand")
18457 (match_operand 2 "aligned_operand")]))
18458 (clobber (reg:CC FLAGS_REG))]
18459 "! TARGET_PARTIAL_REG_STALL && reload_completed
18460 && ((GET_MODE (operands[0]) == HImode
18461 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18462 /* ??? next two lines just !satisfies_constraint_K (...) */
18463 || !CONST_INT_P (operands[2])
18464 || satisfies_constraint_K (operands[2])))
18465 || (GET_MODE (operands[0]) == QImode
18466 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18467 [(parallel [(set (match_dup 0)
18468 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18469 (clobber (reg:CC FLAGS_REG))])]
18470 {
18471 operands[0] = gen_lowpart (SImode, operands[0]);
18472 operands[1] = gen_lowpart (SImode, operands[1]);
18473 if (GET_CODE (operands[3]) != ASHIFT)
18474 operands[2] = gen_lowpart (SImode, operands[2]);
18475 operands[3] = shallow_copy_rtx (operands[3]);
18476 PUT_MODE (operands[3], SImode);
18477 })
18478
18479 ; Promote the QImode tests, as i386 has encoding of the AND
18480 ; instruction with 32-bit sign-extended immediate and thus the
18481 ; instruction size is unchanged, except in the %eax case for
18482 ; which it is increased by one byte, hence the ! optimize_size.
18483 (define_split
18484 [(set (match_operand 0 "flags_reg_operand")
18485 (match_operator 2 "compare_operator"
18486 [(and (match_operand 3 "aligned_operand")
18487 (match_operand 4 "const_int_operand"))
18488 (const_int 0)]))
18489 (set (match_operand 1 "register_operand")
18490 (and (match_dup 3) (match_dup 4)))]
18491 "! TARGET_PARTIAL_REG_STALL && reload_completed
18492 && optimize_insn_for_speed_p ()
18493 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18494 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18495 /* Ensure that the operand will remain sign-extended immediate. */
18496 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18497 [(parallel [(set (match_dup 0)
18498 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18499 (const_int 0)]))
18500 (set (match_dup 1)
18501 (and:SI (match_dup 3) (match_dup 4)))])]
18502 {
18503 operands[4]
18504 = gen_int_mode (INTVAL (operands[4])
18505 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18506 operands[1] = gen_lowpart (SImode, operands[1]);
18507 operands[3] = gen_lowpart (SImode, operands[3]);
18508 })
18509
18510 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18511 ; the TEST instruction with 32-bit sign-extended immediate and thus
18512 ; the instruction size would at least double, which is not what we
18513 ; want even with ! optimize_size.
18514 (define_split
18515 [(set (match_operand 0 "flags_reg_operand")
18516 (match_operator 1 "compare_operator"
18517 [(and (match_operand:HI 2 "aligned_operand")
18518 (match_operand:HI 3 "const_int_operand"))
18519 (const_int 0)]))]
18520 "! TARGET_PARTIAL_REG_STALL && reload_completed
18521 && ! TARGET_FAST_PREFIX
18522 && optimize_insn_for_speed_p ()
18523 /* Ensure that the operand will remain sign-extended immediate. */
18524 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18525 [(set (match_dup 0)
18526 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18527 (const_int 0)]))]
18528 {
18529 operands[3]
18530 = gen_int_mode (INTVAL (operands[3])
18531 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18532 operands[2] = gen_lowpart (SImode, operands[2]);
18533 })
18534
18535 (define_split
18536 [(set (match_operand 0 "register_operand")
18537 (neg (match_operand 1 "register_operand")))
18538 (clobber (reg:CC FLAGS_REG))]
18539 "! TARGET_PARTIAL_REG_STALL && reload_completed
18540 && (GET_MODE (operands[0]) == HImode
18541 || (GET_MODE (operands[0]) == QImode
18542 && (TARGET_PROMOTE_QImode
18543 || optimize_insn_for_size_p ())))"
18544 [(parallel [(set (match_dup 0)
18545 (neg:SI (match_dup 1)))
18546 (clobber (reg:CC FLAGS_REG))])]
18547 {
18548 operands[0] = gen_lowpart (SImode, operands[0]);
18549 operands[1] = gen_lowpart (SImode, operands[1]);
18550 })
18551
18552 ;; Do not split instructions with mask regs.
18553 (define_split
18554 [(set (match_operand 0 "general_reg_operand")
18555 (not (match_operand 1 "general_reg_operand")))]
18556 "! TARGET_PARTIAL_REG_STALL && reload_completed
18557 && (GET_MODE (operands[0]) == HImode
18558 || (GET_MODE (operands[0]) == QImode
18559 && (TARGET_PROMOTE_QImode
18560 || optimize_insn_for_size_p ())))"
18561 [(set (match_dup 0)
18562 (not:SI (match_dup 1)))]
18563 {
18564 operands[0] = gen_lowpart (SImode, operands[0]);
18565 operands[1] = gen_lowpart (SImode, operands[1]);
18566 })
18567 \f
18568 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18569 ;; transform a complex memory operation into two memory to register operations.
18570
18571 ;; Don't push memory operands
18572 (define_peephole2
18573 [(set (match_operand:SWI 0 "push_operand")
18574 (match_operand:SWI 1 "memory_operand"))
18575 (match_scratch:SWI 2 "<r>")]
18576 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18577 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18578 [(set (match_dup 2) (match_dup 1))
18579 (set (match_dup 0) (match_dup 2))])
18580
18581 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18582 ;; SImode pushes.
18583 (define_peephole2
18584 [(set (match_operand:SF 0 "push_operand")
18585 (match_operand:SF 1 "memory_operand"))
18586 (match_scratch:SF 2 "r")]
18587 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18588 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18589 [(set (match_dup 2) (match_dup 1))
18590 (set (match_dup 0) (match_dup 2))])
18591
18592 ;; Don't move an immediate directly to memory when the instruction
18593 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18594 (define_peephole2
18595 [(match_scratch:SWI124 1 "<r>")
18596 (set (match_operand:SWI124 0 "memory_operand")
18597 (const_int 0))]
18598 "optimize_insn_for_speed_p ()
18599 && ((<MODE>mode == HImode
18600 && TARGET_LCP_STALL)
18601 || (!TARGET_USE_MOV0
18602 && TARGET_SPLIT_LONG_MOVES
18603 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18604 && peep2_regno_dead_p (0, FLAGS_REG)"
18605 [(parallel [(set (match_dup 2) (const_int 0))
18606 (clobber (reg:CC FLAGS_REG))])
18607 (set (match_dup 0) (match_dup 1))]
18608 "operands[2] = gen_lowpart (SImode, operands[1]);")
18609
18610 (define_peephole2
18611 [(match_scratch:SWI124 2 "<r>")
18612 (set (match_operand:SWI124 0 "memory_operand")
18613 (match_operand:SWI124 1 "immediate_operand"))]
18614 "optimize_insn_for_speed_p ()
18615 && ((<MODE>mode == HImode
18616 && TARGET_LCP_STALL)
18617 || (TARGET_SPLIT_LONG_MOVES
18618 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18619 [(set (match_dup 2) (match_dup 1))
18620 (set (match_dup 0) (match_dup 2))])
18621
18622 ;; Don't compare memory with zero, load and use a test instead.
18623 (define_peephole2
18624 [(set (match_operand 0 "flags_reg_operand")
18625 (match_operator 1 "compare_operator"
18626 [(match_operand:SI 2 "memory_operand")
18627 (const_int 0)]))
18628 (match_scratch:SI 3 "r")]
18629 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18630 [(set (match_dup 3) (match_dup 2))
18631 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18632
18633 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18634 ;; Don't split NOTs with a displacement operand, because resulting XOR
18635 ;; will not be pairable anyway.
18636 ;;
18637 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18638 ;; represented using a modRM byte. The XOR replacement is long decoded,
18639 ;; so this split helps here as well.
18640 ;;
18641 ;; Note: Can't do this as a regular split because we can't get proper
18642 ;; lifetime information then.
18643
18644 (define_peephole2
18645 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18646 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18647 "optimize_insn_for_speed_p ()
18648 && ((TARGET_NOT_UNPAIRABLE
18649 && (!MEM_P (operands[0])
18650 || !memory_displacement_operand (operands[0], <MODE>mode)))
18651 || (TARGET_NOT_VECTORMODE
18652 && long_memory_operand (operands[0], <MODE>mode)))
18653 && peep2_regno_dead_p (0, FLAGS_REG)"
18654 [(parallel [(set (match_dup 0)
18655 (xor:SWI124 (match_dup 1) (const_int -1)))
18656 (clobber (reg:CC FLAGS_REG))])])
18657
18658 ;; Non pairable "test imm, reg" instructions can be translated to
18659 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18660 ;; byte opcode instead of two, have a short form for byte operands),
18661 ;; so do it for other CPUs as well. Given that the value was dead,
18662 ;; this should not create any new dependencies. Pass on the sub-word
18663 ;; versions if we're concerned about partial register stalls.
18664
18665 (define_peephole2
18666 [(set (match_operand 0 "flags_reg_operand")
18667 (match_operator 1 "compare_operator"
18668 [(and:SI (match_operand:SI 2 "register_operand")
18669 (match_operand:SI 3 "immediate_operand"))
18670 (const_int 0)]))]
18671 "ix86_match_ccmode (insn, CCNOmode)
18672 && (REGNO (operands[2]) != AX_REG
18673 || satisfies_constraint_K (operands[3]))
18674 && peep2_reg_dead_p (1, operands[2])"
18675 [(parallel
18676 [(set (match_dup 0)
18677 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18678 (const_int 0)]))
18679 (set (match_dup 2)
18680 (and:SI (match_dup 2) (match_dup 3)))])])
18681
18682 ;; We don't need to handle HImode case, because it will be promoted to SImode
18683 ;; on ! TARGET_PARTIAL_REG_STALL
18684
18685 (define_peephole2
18686 [(set (match_operand 0 "flags_reg_operand")
18687 (match_operator 1 "compare_operator"
18688 [(and:QI (match_operand:QI 2 "register_operand")
18689 (match_operand:QI 3 "immediate_operand"))
18690 (const_int 0)]))]
18691 "! TARGET_PARTIAL_REG_STALL
18692 && ix86_match_ccmode (insn, CCNOmode)
18693 && REGNO (operands[2]) != AX_REG
18694 && peep2_reg_dead_p (1, operands[2])"
18695 [(parallel
18696 [(set (match_dup 0)
18697 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18698 (const_int 0)]))
18699 (set (match_dup 2)
18700 (and:QI (match_dup 2) (match_dup 3)))])])
18701
18702 (define_peephole2
18703 [(set (match_operand 0 "flags_reg_operand")
18704 (match_operator 1 "compare_operator"
18705 [(and:QI
18706 (subreg:QI
18707 (zero_extract:SI (match_operand 2 "QIreg_operand")
18708 (const_int 8)
18709 (const_int 8)) 0)
18710 (match_operand 3 "const_int_operand"))
18711 (const_int 0)]))]
18712 "! TARGET_PARTIAL_REG_STALL
18713 && ix86_match_ccmode (insn, CCNOmode)
18714 && REGNO (operands[2]) != AX_REG
18715 && peep2_reg_dead_p (1, operands[2])"
18716 [(parallel
18717 [(set (match_dup 0)
18718 (match_op_dup 1
18719 [(and:QI
18720 (subreg:QI
18721 (zero_extract:SI (match_dup 2)
18722 (const_int 8)
18723 (const_int 8)) 0)
18724 (match_dup 3))
18725 (const_int 0)]))
18726 (set (zero_extract:SI (match_dup 2)
18727 (const_int 8)
18728 (const_int 8))
18729 (subreg:SI
18730 (and:QI
18731 (subreg:QI
18732 (zero_extract:SI (match_dup 2)
18733 (const_int 8)
18734 (const_int 8)) 0)
18735 (match_dup 3)) 0))])])
18736
18737 ;; Don't do logical operations with memory inputs.
18738 (define_peephole2
18739 [(match_scratch:SWI 2 "<r>")
18740 (parallel [(set (match_operand:SWI 0 "register_operand")
18741 (match_operator:SWI 3 "arith_or_logical_operator"
18742 [(match_dup 0)
18743 (match_operand:SWI 1 "memory_operand")]))
18744 (clobber (reg:CC FLAGS_REG))])]
18745 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18746 [(set (match_dup 2) (match_dup 1))
18747 (parallel [(set (match_dup 0)
18748 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18749 (clobber (reg:CC FLAGS_REG))])])
18750
18751 (define_peephole2
18752 [(match_scratch:SWI 2 "<r>")
18753 (parallel [(set (match_operand:SWI 0 "register_operand")
18754 (match_operator:SWI 3 "arith_or_logical_operator"
18755 [(match_operand:SWI 1 "memory_operand")
18756 (match_dup 0)]))
18757 (clobber (reg:CC FLAGS_REG))])]
18758 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18759 [(set (match_dup 2) (match_dup 1))
18760 (parallel [(set (match_dup 0)
18761 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18762 (clobber (reg:CC FLAGS_REG))])])
18763
18764 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18765 ;; the memory address refers to the destination of the load!
18766
18767 (define_peephole2
18768 [(set (match_operand:SWI 0 "general_reg_operand")
18769 (match_operand:SWI 1 "general_reg_operand"))
18770 (parallel [(set (match_dup 0)
18771 (match_operator:SWI 3 "commutative_operator"
18772 [(match_dup 0)
18773 (match_operand:SWI 2 "memory_operand")]))
18774 (clobber (reg:CC FLAGS_REG))])]
18775 "REGNO (operands[0]) != REGNO (operands[1])
18776 && (<MODE>mode != QImode
18777 || any_QIreg_operand (operands[1], QImode))"
18778 [(set (match_dup 0) (match_dup 4))
18779 (parallel [(set (match_dup 0)
18780 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18781 (clobber (reg:CC FLAGS_REG))])]
18782 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18783
18784 (define_peephole2
18785 [(set (match_operand 0 "mmx_reg_operand")
18786 (match_operand 1 "mmx_reg_operand"))
18787 (set (match_dup 0)
18788 (match_operator 3 "commutative_operator"
18789 [(match_dup 0)
18790 (match_operand 2 "memory_operand")]))]
18791 "REGNO (operands[0]) != REGNO (operands[1])"
18792 [(set (match_dup 0) (match_dup 2))
18793 (set (match_dup 0)
18794 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18795
18796 (define_peephole2
18797 [(set (match_operand 0 "sse_reg_operand")
18798 (match_operand 1 "sse_reg_operand"))
18799 (set (match_dup 0)
18800 (match_operator 3 "commutative_operator"
18801 [(match_dup 0)
18802 (match_operand 2 "memory_operand")]))]
18803 "REGNO (operands[0]) != REGNO (operands[1])"
18804 [(set (match_dup 0) (match_dup 2))
18805 (set (match_dup 0)
18806 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18807
18808 ; Don't do logical operations with memory outputs
18809 ;
18810 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18811 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18812 ; the same decoder scheduling characteristics as the original.
18813
18814 (define_peephole2
18815 [(match_scratch:SWI 2 "<r>")
18816 (parallel [(set (match_operand:SWI 0 "memory_operand")
18817 (match_operator:SWI 3 "arith_or_logical_operator"
18818 [(match_dup 0)
18819 (match_operand:SWI 1 "<nonmemory_operand>")]))
18820 (clobber (reg:CC FLAGS_REG))])]
18821 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18822 [(set (match_dup 2) (match_dup 0))
18823 (parallel [(set (match_dup 2)
18824 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18825 (clobber (reg:CC FLAGS_REG))])
18826 (set (match_dup 0) (match_dup 2))])
18827
18828 (define_peephole2
18829 [(match_scratch:SWI 2 "<r>")
18830 (parallel [(set (match_operand:SWI 0 "memory_operand")
18831 (match_operator:SWI 3 "arith_or_logical_operator"
18832 [(match_operand:SWI 1 "<nonmemory_operand>")
18833 (match_dup 0)]))
18834 (clobber (reg:CC FLAGS_REG))])]
18835 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18836 [(set (match_dup 2) (match_dup 0))
18837 (parallel [(set (match_dup 2)
18838 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18839 (clobber (reg:CC FLAGS_REG))])
18840 (set (match_dup 0) (match_dup 2))])
18841
18842 ;; Attempt to use arith or logical operations with memory outputs with
18843 ;; setting of flags.
18844 (define_peephole2
18845 [(set (match_operand:SWI 0 "register_operand")
18846 (match_operand:SWI 1 "memory_operand"))
18847 (parallel [(set (match_dup 0)
18848 (match_operator:SWI 3 "plusminuslogic_operator"
18849 [(match_dup 0)
18850 (match_operand:SWI 2 "<nonmemory_operand>")]))
18851 (clobber (reg:CC FLAGS_REG))])
18852 (set (match_dup 1) (match_dup 0))
18853 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18854 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18855 && peep2_reg_dead_p (4, operands[0])
18856 && !reg_overlap_mentioned_p (operands[0], operands[1])
18857 && !reg_overlap_mentioned_p (operands[0], operands[2])
18858 && (<MODE>mode != QImode
18859 || immediate_operand (operands[2], QImode)
18860 || any_QIreg_operand (operands[2], QImode))
18861 && ix86_match_ccmode (peep2_next_insn (3),
18862 (GET_CODE (operands[3]) == PLUS
18863 || GET_CODE (operands[3]) == MINUS)
18864 ? CCGOCmode : CCNOmode)"
18865 [(parallel [(set (match_dup 4) (match_dup 6))
18866 (set (match_dup 1) (match_dup 5))])]
18867 {
18868 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18869 operands[5]
18870 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18871 copy_rtx (operands[1]),
18872 operands[2]);
18873 operands[6]
18874 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18875 copy_rtx (operands[5]),
18876 const0_rtx);
18877 })
18878
18879 ;; Likewise for cmpelim optimized pattern.
18880 (define_peephole2
18881 [(set (match_operand:SWI 0 "register_operand")
18882 (match_operand:SWI 1 "memory_operand"))
18883 (parallel [(set (reg FLAGS_REG)
18884 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18885 [(match_dup 0)
18886 (match_operand:SWI 2 "<nonmemory_operand>")])
18887 (const_int 0)))
18888 (set (match_dup 0) (match_dup 3))])
18889 (set (match_dup 1) (match_dup 0))]
18890 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18891 && peep2_reg_dead_p (3, operands[0])
18892 && !reg_overlap_mentioned_p (operands[0], operands[1])
18893 && !reg_overlap_mentioned_p (operands[0], operands[2])
18894 && ix86_match_ccmode (peep2_next_insn (1),
18895 (GET_CODE (operands[3]) == PLUS
18896 || GET_CODE (operands[3]) == MINUS)
18897 ? CCGOCmode : CCNOmode)"
18898 [(parallel [(set (match_dup 4) (match_dup 6))
18899 (set (match_dup 1) (match_dup 5))])]
18900 {
18901 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18902 operands[5]
18903 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18904 copy_rtx (operands[1]), operands[2]);
18905 operands[6]
18906 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
18907 const0_rtx);
18908 })
18909
18910 ;; Likewise for instances where we have a lea pattern.
18911 (define_peephole2
18912 [(set (match_operand:SWI 0 "register_operand")
18913 (match_operand:SWI 1 "memory_operand"))
18914 (set (match_operand:<LEAMODE> 3 "register_operand")
18915 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
18916 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
18917 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
18918 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18919 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18920 && REGNO (operands[4]) == REGNO (operands[0])
18921 && REGNO (operands[5]) == REGNO (operands[3])
18922 && peep2_reg_dead_p (4, operands[3])
18923 && ((REGNO (operands[0]) == REGNO (operands[3]))
18924 || peep2_reg_dead_p (2, operands[0]))
18925 && !reg_overlap_mentioned_p (operands[0], operands[1])
18926 && !reg_overlap_mentioned_p (operands[3], operands[1])
18927 && !reg_overlap_mentioned_p (operands[0], operands[2])
18928 && (<MODE>mode != QImode
18929 || immediate_operand (operands[2], QImode)
18930 || any_QIreg_operand (operands[2], QImode))
18931 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18932 [(parallel [(set (match_dup 6) (match_dup 8))
18933 (set (match_dup 1) (match_dup 7))])]
18934 {
18935 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
18936 operands[7]
18937 = gen_rtx_PLUS (<MODE>mode,
18938 copy_rtx (operands[1]),
18939 gen_lowpart (<MODE>mode, operands[2]));
18940 operands[8]
18941 = gen_rtx_COMPARE (GET_MODE (operands[6]),
18942 copy_rtx (operands[7]),
18943 const0_rtx);
18944 })
18945
18946 (define_peephole2
18947 [(parallel [(set (match_operand:SWI 0 "register_operand")
18948 (match_operator:SWI 2 "plusminuslogic_operator"
18949 [(match_dup 0)
18950 (match_operand:SWI 1 "memory_operand")]))
18951 (clobber (reg:CC FLAGS_REG))])
18952 (set (match_dup 1) (match_dup 0))
18953 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18954 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18955 && COMMUTATIVE_ARITH_P (operands[2])
18956 && peep2_reg_dead_p (3, operands[0])
18957 && !reg_overlap_mentioned_p (operands[0], operands[1])
18958 && ix86_match_ccmode (peep2_next_insn (2),
18959 GET_CODE (operands[2]) == PLUS
18960 ? CCGOCmode : CCNOmode)"
18961 [(parallel [(set (match_dup 3) (match_dup 5))
18962 (set (match_dup 1) (match_dup 4))])]
18963 {
18964 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18965 operands[4]
18966 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18967 copy_rtx (operands[1]),
18968 operands[0]);
18969 operands[5]
18970 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18971 copy_rtx (operands[4]),
18972 const0_rtx);
18973 })
18974
18975 ;; Likewise for cmpelim optimized pattern.
18976 (define_peephole2
18977 [(parallel [(set (reg FLAGS_REG)
18978 (compare (match_operator:SWI 2 "plusminuslogic_operator"
18979 [(match_operand:SWI 0 "register_operand")
18980 (match_operand:SWI 1 "memory_operand")])
18981 (const_int 0)))
18982 (set (match_dup 0) (match_dup 2))])
18983 (set (match_dup 1) (match_dup 0))]
18984 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18985 && COMMUTATIVE_ARITH_P (operands[2])
18986 && peep2_reg_dead_p (2, operands[0])
18987 && !reg_overlap_mentioned_p (operands[0], operands[1])
18988 && ix86_match_ccmode (peep2_next_insn (0),
18989 GET_CODE (operands[2]) == PLUS
18990 ? CCGOCmode : CCNOmode)"
18991 [(parallel [(set (match_dup 3) (match_dup 5))
18992 (set (match_dup 1) (match_dup 4))])]
18993 {
18994 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
18995 operands[4]
18996 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18997 copy_rtx (operands[1]), operands[0]);
18998 operands[5]
18999 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19000 const0_rtx);
19001 })
19002
19003 (define_peephole2
19004 [(set (match_operand:SWI12 0 "register_operand")
19005 (match_operand:SWI12 1 "memory_operand"))
19006 (parallel [(set (match_operand:SI 4 "register_operand")
19007 (match_operator:SI 3 "plusminuslogic_operator"
19008 [(match_dup 4)
19009 (match_operand:SI 2 "nonmemory_operand")]))
19010 (clobber (reg:CC FLAGS_REG))])
19011 (set (match_dup 1) (match_dup 0))
19012 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19013 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19014 && REGNO (operands[0]) == REGNO (operands[4])
19015 && peep2_reg_dead_p (4, operands[0])
19016 && (<MODE>mode != QImode
19017 || immediate_operand (operands[2], SImode)
19018 || any_QIreg_operand (operands[2], SImode))
19019 && !reg_overlap_mentioned_p (operands[0], operands[1])
19020 && !reg_overlap_mentioned_p (operands[0], operands[2])
19021 && ix86_match_ccmode (peep2_next_insn (3),
19022 (GET_CODE (operands[3]) == PLUS
19023 || GET_CODE (operands[3]) == MINUS)
19024 ? CCGOCmode : CCNOmode)"
19025 [(parallel [(set (match_dup 5) (match_dup 7))
19026 (set (match_dup 1) (match_dup 6))])]
19027 {
19028 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
19029 operands[6]
19030 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19031 copy_rtx (operands[1]),
19032 gen_lowpart (<MODE>mode, operands[2]));
19033 operands[7]
19034 = gen_rtx_COMPARE (GET_MODE (operands[5]),
19035 copy_rtx (operands[6]),
19036 const0_rtx);
19037 })
19038
19039 ;; peephole2 comes before regcprop, so deal also with a case that
19040 ;; would be cleaned up by regcprop.
19041 (define_peephole2
19042 [(set (match_operand:SWI 0 "register_operand")
19043 (match_operand:SWI 1 "memory_operand"))
19044 (parallel [(set (match_dup 0)
19045 (match_operator:SWI 3 "plusminuslogic_operator"
19046 [(match_dup 0)
19047 (match_operand:SWI 2 "<nonmemory_operand>")]))
19048 (clobber (reg:CC FLAGS_REG))])
19049 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
19050 (set (match_dup 1) (match_dup 4))
19051 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
19052 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19053 && peep2_reg_dead_p (3, operands[0])
19054 && peep2_reg_dead_p (5, operands[4])
19055 && !reg_overlap_mentioned_p (operands[0], operands[1])
19056 && !reg_overlap_mentioned_p (operands[0], operands[2])
19057 && !reg_overlap_mentioned_p (operands[4], operands[1])
19058 && (<MODE>mode != QImode
19059 || immediate_operand (operands[2], QImode)
19060 || any_QIreg_operand (operands[2], QImode))
19061 && ix86_match_ccmode (peep2_next_insn (4),
19062 (GET_CODE (operands[3]) == PLUS
19063 || GET_CODE (operands[3]) == MINUS)
19064 ? CCGOCmode : CCNOmode)"
19065 [(parallel [(set (match_dup 5) (match_dup 7))
19066 (set (match_dup 1) (match_dup 6))])]
19067 {
19068 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
19069 operands[6]
19070 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19071 copy_rtx (operands[1]),
19072 operands[2]);
19073 operands[7]
19074 = gen_rtx_COMPARE (GET_MODE (operands[5]),
19075 copy_rtx (operands[6]),
19076 const0_rtx);
19077 })
19078
19079 (define_peephole2
19080 [(set (match_operand:SWI12 0 "register_operand")
19081 (match_operand:SWI12 1 "memory_operand"))
19082 (parallel [(set (match_operand:SI 4 "register_operand")
19083 (match_operator:SI 3 "plusminuslogic_operator"
19084 [(match_dup 4)
19085 (match_operand:SI 2 "nonmemory_operand")]))
19086 (clobber (reg:CC FLAGS_REG))])
19087 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
19088 (set (match_dup 1) (match_dup 5))
19089 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
19090 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19091 && REGNO (operands[0]) == REGNO (operands[4])
19092 && peep2_reg_dead_p (3, operands[0])
19093 && peep2_reg_dead_p (5, operands[5])
19094 && (<MODE>mode != QImode
19095 || immediate_operand (operands[2], SImode)
19096 || any_QIreg_operand (operands[2], SImode))
19097 && !reg_overlap_mentioned_p (operands[0], operands[1])
19098 && !reg_overlap_mentioned_p (operands[0], operands[2])
19099 && !reg_overlap_mentioned_p (operands[5], operands[1])
19100 && ix86_match_ccmode (peep2_next_insn (4),
19101 (GET_CODE (operands[3]) == PLUS
19102 || GET_CODE (operands[3]) == MINUS)
19103 ? CCGOCmode : CCNOmode)"
19104 [(parallel [(set (match_dup 6) (match_dup 8))
19105 (set (match_dup 1) (match_dup 7))])]
19106 {
19107 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
19108 operands[7]
19109 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19110 copy_rtx (operands[1]),
19111 gen_lowpart (<MODE>mode, operands[2]));
19112 operands[8]
19113 = gen_rtx_COMPARE (GET_MODE (operands[6]),
19114 copy_rtx (operands[7]),
19115 const0_rtx);
19116 })
19117
19118 ;; Likewise for cmpelim optimized pattern.
19119 (define_peephole2
19120 [(set (match_operand:SWI 0 "register_operand")
19121 (match_operand:SWI 1 "memory_operand"))
19122 (parallel [(set (reg FLAGS_REG)
19123 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19124 [(match_dup 0)
19125 (match_operand:SWI 2 "<nonmemory_operand>")])
19126 (const_int 0)))
19127 (set (match_dup 0) (match_dup 3))])
19128 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
19129 (set (match_dup 1) (match_dup 4))]
19130 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19131 && peep2_reg_dead_p (3, operands[0])
19132 && peep2_reg_dead_p (4, operands[4])
19133 && !reg_overlap_mentioned_p (operands[0], operands[1])
19134 && !reg_overlap_mentioned_p (operands[0], operands[2])
19135 && !reg_overlap_mentioned_p (operands[4], operands[1])
19136 && ix86_match_ccmode (peep2_next_insn (1),
19137 (GET_CODE (operands[3]) == PLUS
19138 || GET_CODE (operands[3]) == MINUS)
19139 ? CCGOCmode : CCNOmode)"
19140 [(parallel [(set (match_dup 5) (match_dup 7))
19141 (set (match_dup 1) (match_dup 6))])]
19142 {
19143 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19144 operands[6]
19145 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19146 copy_rtx (operands[1]), operands[2]);
19147 operands[7]
19148 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
19149 const0_rtx);
19150 })
19151
19152 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
19153 ;; into x = z; x ^= y; x != z
19154 (define_peephole2
19155 [(set (match_operand:SWI 0 "register_operand")
19156 (match_operand:SWI 1 "memory_operand"))
19157 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
19158 (parallel [(set (match_operand:SWI 4 "register_operand")
19159 (xor:SWI (match_dup 4)
19160 (match_operand:SWI 2 "<nonmemory_operand>")))
19161 (clobber (reg:CC FLAGS_REG))])
19162 (set (match_dup 1) (match_dup 4))
19163 (set (reg:CCZ FLAGS_REG)
19164 (compare:CCZ (match_operand:SWI 5 "register_operand")
19165 (match_operand:SWI 6 "<nonmemory_operand>")))]
19166 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19167 && (REGNO (operands[4]) == REGNO (operands[0])
19168 || REGNO (operands[4]) == REGNO (operands[3]))
19169 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
19170 ? 3 : 0], operands[5])
19171 ? rtx_equal_p (operands[2], operands[6])
19172 : rtx_equal_p (operands[2], operands[5])
19173 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
19174 ? 3 : 0], operands[6]))
19175 && peep2_reg_dead_p (4, operands[4])
19176 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
19177 ? 3 : 0])
19178 && !reg_overlap_mentioned_p (operands[0], operands[1])
19179 && !reg_overlap_mentioned_p (operands[0], operands[2])
19180 && !reg_overlap_mentioned_p (operands[3], operands[0])
19181 && !reg_overlap_mentioned_p (operands[3], operands[1])
19182 && !reg_overlap_mentioned_p (operands[3], operands[2])
19183 && (<MODE>mode != QImode
19184 || immediate_operand (operands[2], QImode)
19185 || any_QIreg_operand (operands[2], QImode))"
19186 [(parallel [(set (match_dup 7) (match_dup 9))
19187 (set (match_dup 1) (match_dup 8))])]
19188 {
19189 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
19190 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
19191 operands[2]);
19192 operands[9]
19193 = gen_rtx_COMPARE (GET_MODE (operands[7]),
19194 copy_rtx (operands[8]),
19195 const0_rtx);
19196 })
19197
19198 (define_peephole2
19199 [(set (match_operand:SWI12 0 "register_operand")
19200 (match_operand:SWI12 1 "memory_operand"))
19201 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
19202 (parallel [(set (match_operand:SI 4 "register_operand")
19203 (xor:SI (match_dup 4)
19204 (match_operand:SI 2 "<nonmemory_operand>")))
19205 (clobber (reg:CC FLAGS_REG))])
19206 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
19207 (set (reg:CCZ FLAGS_REG)
19208 (compare:CCZ (match_operand:SWI12 6 "register_operand")
19209 (match_operand:SWI12 7 "<nonmemory_operand>")))]
19210 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19211 && (REGNO (operands[5]) == REGNO (operands[0])
19212 || REGNO (operands[5]) == REGNO (operands[3]))
19213 && REGNO (operands[5]) == REGNO (operands[4])
19214 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
19215 ? 3 : 0], operands[6])
19216 ? (REG_P (operands[2])
19217 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
19218 : rtx_equal_p (operands[2], operands[7]))
19219 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
19220 ? 3 : 0], operands[7])
19221 && REG_P (operands[2])
19222 && REGNO (operands[2]) == REGNO (operands[6])))
19223 && peep2_reg_dead_p (4, operands[5])
19224 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
19225 ? 3 : 0])
19226 && !reg_overlap_mentioned_p (operands[0], operands[1])
19227 && !reg_overlap_mentioned_p (operands[0], operands[2])
19228 && !reg_overlap_mentioned_p (operands[3], operands[0])
19229 && !reg_overlap_mentioned_p (operands[3], operands[1])
19230 && !reg_overlap_mentioned_p (operands[3], operands[2])
19231 && (<MODE>mode != QImode
19232 || immediate_operand (operands[2], SImode)
19233 || any_QIreg_operand (operands[2], SImode))"
19234 [(parallel [(set (match_dup 8) (match_dup 10))
19235 (set (match_dup 1) (match_dup 9))])]
19236 {
19237 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
19238 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
19239 gen_lowpart (<MODE>mode, operands[2]));
19240 operands[10]
19241 = gen_rtx_COMPARE (GET_MODE (operands[8]),
19242 copy_rtx (operands[9]),
19243 const0_rtx);
19244 })
19245
19246 ;; Attempt to optimize away memory stores of values the memory already
19247 ;; has. See PR79593.
19248 (define_peephole2
19249 [(set (match_operand 0 "register_operand")
19250 (match_operand 1 "memory_operand"))
19251 (set (match_operand 2 "memory_operand") (match_dup 0))]
19252 "!MEM_VOLATILE_P (operands[1])
19253 && !MEM_VOLATILE_P (operands[2])
19254 && rtx_equal_p (operands[1], operands[2])
19255 && !reg_overlap_mentioned_p (operands[0], operands[2])"
19256 [(set (match_dup 0) (match_dup 1))])
19257
19258 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19259 (define_peephole2
19260 [(set (match_operand 0 "general_reg_operand")
19261 (match_operand 1 "const0_operand"))]
19262 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19263 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19264 && peep2_regno_dead_p (0, FLAGS_REG)"
19265 [(parallel [(set (match_dup 0) (const_int 0))
19266 (clobber (reg:CC FLAGS_REG))])]
19267 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19268
19269 (define_peephole2
19270 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19271 (const_int 0))]
19272 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19273 && peep2_regno_dead_p (0, FLAGS_REG)"
19274 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19275 (clobber (reg:CC FLAGS_REG))])])
19276
19277 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19278 (define_peephole2
19279 [(set (match_operand:SWI248 0 "general_reg_operand")
19280 (const_int -1))]
19281 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19282 && peep2_regno_dead_p (0, FLAGS_REG)"
19283 [(parallel [(set (match_dup 0) (const_int -1))
19284 (clobber (reg:CC FLAGS_REG))])]
19285 {
19286 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19287 operands[0] = gen_lowpart (SImode, operands[0]);
19288 })
19289
19290 ;; Attempt to convert simple lea to add/shift.
19291 ;; These can be created by move expanders.
19292 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19293 ;; relevant lea instructions were already split.
19294
19295 (define_peephole2
19296 [(set (match_operand:SWI48 0 "register_operand")
19297 (plus:SWI48 (match_dup 0)
19298 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19299 "!TARGET_OPT_AGU
19300 && peep2_regno_dead_p (0, FLAGS_REG)"
19301 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19302 (clobber (reg:CC FLAGS_REG))])])
19303
19304 (define_peephole2
19305 [(set (match_operand:SWI48 0 "register_operand")
19306 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19307 (match_dup 0)))]
19308 "!TARGET_OPT_AGU
19309 && peep2_regno_dead_p (0, FLAGS_REG)"
19310 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19311 (clobber (reg:CC FLAGS_REG))])])
19312
19313 (define_peephole2
19314 [(set (match_operand:DI 0 "register_operand")
19315 (zero_extend:DI
19316 (plus:SI (match_operand:SI 1 "register_operand")
19317 (match_operand:SI 2 "nonmemory_operand"))))]
19318 "TARGET_64BIT && !TARGET_OPT_AGU
19319 && REGNO (operands[0]) == REGNO (operands[1])
19320 && peep2_regno_dead_p (0, FLAGS_REG)"
19321 [(parallel [(set (match_dup 0)
19322 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19323 (clobber (reg:CC FLAGS_REG))])])
19324
19325 (define_peephole2
19326 [(set (match_operand:DI 0 "register_operand")
19327 (zero_extend:DI
19328 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19329 (match_operand:SI 2 "register_operand"))))]
19330 "TARGET_64BIT && !TARGET_OPT_AGU
19331 && REGNO (operands[0]) == REGNO (operands[2])
19332 && peep2_regno_dead_p (0, FLAGS_REG)"
19333 [(parallel [(set (match_dup 0)
19334 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19335 (clobber (reg:CC FLAGS_REG))])])
19336
19337 (define_peephole2
19338 [(set (match_operand:SWI48 0 "register_operand")
19339 (mult:SWI48 (match_dup 0)
19340 (match_operand:SWI48 1 "const_int_operand")))]
19341 "pow2p_hwi (INTVAL (operands[1]))
19342 && peep2_regno_dead_p (0, FLAGS_REG)"
19343 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19344 (clobber (reg:CC FLAGS_REG))])]
19345 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19346
19347 (define_peephole2
19348 [(set (match_operand:DI 0 "register_operand")
19349 (zero_extend:DI
19350 (mult:SI (match_operand:SI 1 "register_operand")
19351 (match_operand:SI 2 "const_int_operand"))))]
19352 "TARGET_64BIT
19353 && pow2p_hwi (INTVAL (operands[2]))
19354 && REGNO (operands[0]) == REGNO (operands[1])
19355 && peep2_regno_dead_p (0, FLAGS_REG)"
19356 [(parallel [(set (match_dup 0)
19357 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19358 (clobber (reg:CC FLAGS_REG))])]
19359 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19360
19361 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19362 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19363 ;; On many CPUs it is also faster, since special hardware to avoid esp
19364 ;; dependencies is present.
19365
19366 ;; While some of these conversions may be done using splitters, we use
19367 ;; peepholes in order to allow combine_stack_adjustments pass to see
19368 ;; nonobfuscated RTL.
19369
19370 ;; Convert prologue esp subtractions to push.
19371 ;; We need register to push. In order to keep verify_flow_info happy we have
19372 ;; two choices
19373 ;; - use scratch and clobber it in order to avoid dependencies
19374 ;; - use already live register
19375 ;; We can't use the second way right now, since there is no reliable way how to
19376 ;; verify that given register is live. First choice will also most likely in
19377 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19378 ;; call clobbered registers are dead. We may want to use base pointer as an
19379 ;; alternative when no register is available later.
19380
19381 (define_peephole2
19382 [(match_scratch:W 1 "r")
19383 (parallel [(set (reg:P SP_REG)
19384 (plus:P (reg:P SP_REG)
19385 (match_operand:P 0 "const_int_operand")))
19386 (clobber (reg:CC FLAGS_REG))
19387 (clobber (mem:BLK (scratch)))])]
19388 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19389 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19390 && ix86_red_zone_size == 0"
19391 [(clobber (match_dup 1))
19392 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19393 (clobber (mem:BLK (scratch)))])])
19394
19395 (define_peephole2
19396 [(match_scratch:W 1 "r")
19397 (parallel [(set (reg:P SP_REG)
19398 (plus:P (reg:P SP_REG)
19399 (match_operand:P 0 "const_int_operand")))
19400 (clobber (reg:CC FLAGS_REG))
19401 (clobber (mem:BLK (scratch)))])]
19402 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19403 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19404 && ix86_red_zone_size == 0"
19405 [(clobber (match_dup 1))
19406 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19407 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19408 (clobber (mem:BLK (scratch)))])])
19409
19410 ;; Convert esp subtractions to push.
19411 (define_peephole2
19412 [(match_scratch:W 1 "r")
19413 (parallel [(set (reg:P SP_REG)
19414 (plus:P (reg:P SP_REG)
19415 (match_operand:P 0 "const_int_operand")))
19416 (clobber (reg:CC FLAGS_REG))])]
19417 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19418 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19419 && ix86_red_zone_size == 0"
19420 [(clobber (match_dup 1))
19421 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19422
19423 (define_peephole2
19424 [(match_scratch:W 1 "r")
19425 (parallel [(set (reg:P SP_REG)
19426 (plus:P (reg:P SP_REG)
19427 (match_operand:P 0 "const_int_operand")))
19428 (clobber (reg:CC FLAGS_REG))])]
19429 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19430 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19431 && ix86_red_zone_size == 0"
19432 [(clobber (match_dup 1))
19433 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19434 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19435
19436 ;; Convert epilogue deallocator to pop.
19437 (define_peephole2
19438 [(match_scratch:W 1 "r")
19439 (parallel [(set (reg:P SP_REG)
19440 (plus:P (reg:P SP_REG)
19441 (match_operand:P 0 "const_int_operand")))
19442 (clobber (reg:CC FLAGS_REG))
19443 (clobber (mem:BLK (scratch)))])]
19444 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19445 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19446 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19447 (clobber (mem:BLK (scratch)))])])
19448
19449 ;; Two pops case is tricky, since pop causes dependency
19450 ;; on destination register. We use two registers if available.
19451 (define_peephole2
19452 [(match_scratch:W 1 "r")
19453 (match_scratch:W 2 "r")
19454 (parallel [(set (reg:P SP_REG)
19455 (plus:P (reg:P SP_REG)
19456 (match_operand:P 0 "const_int_operand")))
19457 (clobber (reg:CC FLAGS_REG))
19458 (clobber (mem:BLK (scratch)))])]
19459 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19460 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19461 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19462 (clobber (mem:BLK (scratch)))])
19463 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19464
19465 (define_peephole2
19466 [(match_scratch:W 1 "r")
19467 (parallel [(set (reg:P SP_REG)
19468 (plus:P (reg:P SP_REG)
19469 (match_operand:P 0 "const_int_operand")))
19470 (clobber (reg:CC FLAGS_REG))
19471 (clobber (mem:BLK (scratch)))])]
19472 "optimize_insn_for_size_p ()
19473 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19474 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19475 (clobber (mem:BLK (scratch)))])
19476 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19477
19478 ;; Convert esp additions to pop.
19479 (define_peephole2
19480 [(match_scratch:W 1 "r")
19481 (parallel [(set (reg:P SP_REG)
19482 (plus:P (reg:P SP_REG)
19483 (match_operand:P 0 "const_int_operand")))
19484 (clobber (reg:CC FLAGS_REG))])]
19485 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19486 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19487
19488 ;; Two pops case is tricky, since pop causes dependency
19489 ;; on destination register. We use two registers if available.
19490 (define_peephole2
19491 [(match_scratch:W 1 "r")
19492 (match_scratch:W 2 "r")
19493 (parallel [(set (reg:P SP_REG)
19494 (plus:P (reg:P SP_REG)
19495 (match_operand:P 0 "const_int_operand")))
19496 (clobber (reg:CC FLAGS_REG))])]
19497 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19498 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19499 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19500
19501 (define_peephole2
19502 [(match_scratch:W 1 "r")
19503 (parallel [(set (reg:P SP_REG)
19504 (plus:P (reg:P SP_REG)
19505 (match_operand:P 0 "const_int_operand")))
19506 (clobber (reg:CC FLAGS_REG))])]
19507 "optimize_insn_for_size_p ()
19508 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19509 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19510 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19511 \f
19512 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19513 ;; required and register dies. Similarly for 128 to -128.
19514 (define_peephole2
19515 [(set (match_operand 0 "flags_reg_operand")
19516 (match_operator 1 "compare_operator"
19517 [(match_operand 2 "register_operand")
19518 (match_operand 3 "const_int_operand")]))]
19519 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19520 && incdec_operand (operands[3], GET_MODE (operands[3])))
19521 || (!TARGET_FUSE_CMP_AND_BRANCH
19522 && INTVAL (operands[3]) == 128))
19523 && ix86_match_ccmode (insn, CCGCmode)
19524 && peep2_reg_dead_p (1, operands[2])"
19525 [(parallel [(set (match_dup 0)
19526 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19527 (clobber (match_dup 2))])])
19528 \f
19529 ;; Convert imul by three, five and nine into lea
19530 (define_peephole2
19531 [(parallel
19532 [(set (match_operand:SWI48 0 "register_operand")
19533 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19534 (match_operand:SWI48 2 "const359_operand")))
19535 (clobber (reg:CC FLAGS_REG))])]
19536 "!TARGET_PARTIAL_REG_STALL
19537 || <MODE>mode == SImode
19538 || optimize_function_for_size_p (cfun)"
19539 [(set (match_dup 0)
19540 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19541 (match_dup 1)))]
19542 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19543
19544 (define_peephole2
19545 [(parallel
19546 [(set (match_operand:SWI48 0 "register_operand")
19547 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19548 (match_operand:SWI48 2 "const359_operand")))
19549 (clobber (reg:CC FLAGS_REG))])]
19550 "optimize_insn_for_speed_p ()
19551 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19552 [(set (match_dup 0) (match_dup 1))
19553 (set (match_dup 0)
19554 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19555 (match_dup 0)))]
19556 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19557
19558 ;; imul $32bit_imm, mem, reg is vector decoded, while
19559 ;; imul $32bit_imm, reg, reg is direct decoded.
19560 (define_peephole2
19561 [(match_scratch:SWI48 3 "r")
19562 (parallel [(set (match_operand:SWI48 0 "register_operand")
19563 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19564 (match_operand:SWI48 2 "immediate_operand")))
19565 (clobber (reg:CC FLAGS_REG))])]
19566 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19567 && !satisfies_constraint_K (operands[2])"
19568 [(set (match_dup 3) (match_dup 1))
19569 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19570 (clobber (reg:CC FLAGS_REG))])])
19571
19572 (define_peephole2
19573 [(match_scratch:SI 3 "r")
19574 (parallel [(set (match_operand:DI 0 "register_operand")
19575 (zero_extend:DI
19576 (mult:SI (match_operand:SI 1 "memory_operand")
19577 (match_operand:SI 2 "immediate_operand"))))
19578 (clobber (reg:CC FLAGS_REG))])]
19579 "TARGET_64BIT
19580 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19581 && !satisfies_constraint_K (operands[2])"
19582 [(set (match_dup 3) (match_dup 1))
19583 (parallel [(set (match_dup 0)
19584 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19585 (clobber (reg:CC FLAGS_REG))])])
19586
19587 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19588 ;; Convert it into imul reg, reg
19589 ;; It would be better to force assembler to encode instruction using long
19590 ;; immediate, but there is apparently no way to do so.
19591 (define_peephole2
19592 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19593 (mult:SWI248
19594 (match_operand:SWI248 1 "nonimmediate_operand")
19595 (match_operand:SWI248 2 "const_int_operand")))
19596 (clobber (reg:CC FLAGS_REG))])
19597 (match_scratch:SWI248 3 "r")]
19598 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19599 && satisfies_constraint_K (operands[2])"
19600 [(set (match_dup 3) (match_dup 2))
19601 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19602 (clobber (reg:CC FLAGS_REG))])]
19603 {
19604 if (!rtx_equal_p (operands[0], operands[1]))
19605 emit_move_insn (operands[0], operands[1]);
19606 })
19607
19608 ;; After splitting up read-modify operations, array accesses with memory
19609 ;; operands might end up in form:
19610 ;; sall $2, %eax
19611 ;; movl 4(%esp), %edx
19612 ;; addl %edx, %eax
19613 ;; instead of pre-splitting:
19614 ;; sall $2, %eax
19615 ;; addl 4(%esp), %eax
19616 ;; Turn it into:
19617 ;; movl 4(%esp), %edx
19618 ;; leal (%edx,%eax,4), %eax
19619
19620 (define_peephole2
19621 [(match_scratch:W 5 "r")
19622 (parallel [(set (match_operand 0 "register_operand")
19623 (ashift (match_operand 1 "register_operand")
19624 (match_operand 2 "const_int_operand")))
19625 (clobber (reg:CC FLAGS_REG))])
19626 (parallel [(set (match_operand 3 "register_operand")
19627 (plus (match_dup 0)
19628 (match_operand 4 "x86_64_general_operand")))
19629 (clobber (reg:CC FLAGS_REG))])]
19630 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19631 /* Validate MODE for lea. */
19632 && ((!TARGET_PARTIAL_REG_STALL
19633 && (GET_MODE (operands[0]) == QImode
19634 || GET_MODE (operands[0]) == HImode))
19635 || GET_MODE (operands[0]) == SImode
19636 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19637 && (rtx_equal_p (operands[0], operands[3])
19638 || peep2_reg_dead_p (2, operands[0]))
19639 /* We reorder load and the shift. */
19640 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19641 [(set (match_dup 5) (match_dup 4))
19642 (set (match_dup 0) (match_dup 1))]
19643 {
19644 machine_mode op1mode = GET_MODE (operands[1]);
19645 machine_mode mode = op1mode == DImode ? DImode : SImode;
19646 int scale = 1 << INTVAL (operands[2]);
19647 rtx index = gen_lowpart (word_mode, operands[1]);
19648 rtx base = gen_lowpart (word_mode, operands[5]);
19649 rtx dest = gen_lowpart (mode, operands[3]);
19650
19651 operands[1] = gen_rtx_PLUS (word_mode, base,
19652 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19653 if (mode != word_mode)
19654 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19655
19656 operands[5] = base;
19657 if (op1mode != word_mode)
19658 operands[5] = gen_lowpart (op1mode, operands[5]);
19659
19660 operands[0] = dest;
19661 })
19662 \f
19663 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19664 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19665 ;; caught for use by garbage collectors and the like. Using an insn that
19666 ;; maps to SIGILL makes it more likely the program will rightfully die.
19667 ;; Keeping with tradition, "6" is in honor of #UD.
19668 (define_insn "trap"
19669 [(trap_if (const_int 1) (const_int 6))]
19670 ""
19671 {
19672 #ifdef HAVE_AS_IX86_UD2
19673 return "ud2";
19674 #else
19675 return ASM_SHORT "0x0b0f";
19676 #endif
19677 }
19678 [(set_attr "length" "2")])
19679
19680 (define_insn "ud2"
19681 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19682 ""
19683 {
19684 #ifdef HAVE_AS_IX86_UD2
19685 return "ud2";
19686 #else
19687 return ASM_SHORT "0x0b0f";
19688 #endif
19689 }
19690 [(set_attr "length" "2")])
19691
19692 (define_expand "prefetch"
19693 [(prefetch (match_operand 0 "address_operand")
19694 (match_operand:SI 1 "const_int_operand")
19695 (match_operand:SI 2 "const_int_operand"))]
19696 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19697 {
19698 bool write = operands[1] != const0_rtx;
19699 int locality = INTVAL (operands[2]);
19700
19701 gcc_assert (IN_RANGE (locality, 0, 3));
19702
19703 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19704 supported by SSE counterpart (non-SSE2 athlon machines) or the
19705 SSE prefetch is not available (K6 machines). Otherwise use SSE
19706 prefetch as it allows specifying of locality. */
19707
19708 if (write)
19709 {
19710 if (TARGET_PREFETCHWT1)
19711 operands[2] = GEN_INT (MAX (locality, 2));
19712 else if (TARGET_PRFCHW)
19713 operands[2] = GEN_INT (3);
19714 else if (TARGET_3DNOW && !TARGET_SSE2)
19715 operands[2] = GEN_INT (3);
19716 else if (TARGET_PREFETCH_SSE)
19717 operands[1] = const0_rtx;
19718 else
19719 {
19720 gcc_assert (TARGET_3DNOW);
19721 operands[2] = GEN_INT (3);
19722 }
19723 }
19724 else
19725 {
19726 if (TARGET_PREFETCH_SSE)
19727 ;
19728 else
19729 {
19730 gcc_assert (TARGET_3DNOW);
19731 operands[2] = GEN_INT (3);
19732 }
19733 }
19734 })
19735
19736 (define_insn "*prefetch_sse"
19737 [(prefetch (match_operand 0 "address_operand" "p")
19738 (const_int 0)
19739 (match_operand:SI 1 "const_int_operand"))]
19740 "TARGET_PREFETCH_SSE"
19741 {
19742 static const char * const patterns[4] = {
19743 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19744 };
19745
19746 int locality = INTVAL (operands[1]);
19747 gcc_assert (IN_RANGE (locality, 0, 3));
19748
19749 return patterns[locality];
19750 }
19751 [(set_attr "type" "sse")
19752 (set_attr "atom_sse_attr" "prefetch")
19753 (set (attr "length_address")
19754 (symbol_ref "memory_address_length (operands[0], false)"))
19755 (set_attr "memory" "none")])
19756
19757 (define_insn "*prefetch_3dnow"
19758 [(prefetch (match_operand 0 "address_operand" "p")
19759 (match_operand:SI 1 "const_int_operand" "n")
19760 (const_int 3))]
19761 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19762 {
19763 if (operands[1] == const0_rtx)
19764 return "prefetch\t%a0";
19765 else
19766 return "prefetchw\t%a0";
19767 }
19768 [(set_attr "type" "mmx")
19769 (set (attr "length_address")
19770 (symbol_ref "memory_address_length (operands[0], false)"))
19771 (set_attr "memory" "none")])
19772
19773 (define_insn "*prefetch_prefetchwt1"
19774 [(prefetch (match_operand 0 "address_operand" "p")
19775 (const_int 1)
19776 (const_int 2))]
19777 "TARGET_PREFETCHWT1"
19778 "prefetchwt1\t%a0";
19779 [(set_attr "type" "sse")
19780 (set (attr "length_address")
19781 (symbol_ref "memory_address_length (operands[0], false)"))
19782 (set_attr "memory" "none")])
19783
19784 (define_expand "stack_protect_set"
19785 [(match_operand 0 "memory_operand")
19786 (match_operand 1 "memory_operand")]
19787 ""
19788 {
19789 emit_insn (gen_stack_protect_set_1
19790 (ptr_mode, operands[0], operands[1]));
19791 DONE;
19792 })
19793
19794 (define_insn "@stack_protect_set_1_<mode>"
19795 [(set (match_operand:PTR 0 "memory_operand" "=m")
19796 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19797 UNSPEC_SP_SET))
19798 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19799 (clobber (reg:CC FLAGS_REG))]
19800 ""
19801 {
19802 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
19803 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
19804 return "xor{l}\t%k2, %k2";
19805 }
19806 [(set_attr "type" "multi")])
19807
19808 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
19809 ;; immediately followed by *mov{s,d}i_internal to the same register,
19810 ;; where we can avoid the xor{l} above. We don't split this, so that
19811 ;; scheduling or anything else doesn't separate the *stack_protect_set*
19812 ;; pattern from the set of the register that overwrites the register
19813 ;; with a new value.
19814 (define_insn "*stack_protect_set_2_<mode>"
19815 [(set (match_operand:PTR 0 "memory_operand" "=m")
19816 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
19817 UNSPEC_SP_SET))
19818 (set (match_operand:SI 1 "register_operand" "=&r")
19819 (match_operand:SI 2 "general_operand" "g"))
19820 (clobber (reg:CC FLAGS_REG))]
19821 "reload_completed
19822 && !reg_overlap_mentioned_p (operands[1], operands[2])"
19823 {
19824 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
19825 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
19826 if (pic_32bit_operand (operands[2], SImode)
19827 || ix86_use_lea_for_mov (insn, operands + 1))
19828 return "lea{l}\t{%E2, %1|%1, %E2}";
19829 else
19830 return "mov{l}\t{%2, %1|%1, %2}";
19831 }
19832 [(set_attr "type" "multi")
19833 (set_attr "length" "24")])
19834
19835 (define_peephole2
19836 [(parallel [(set (match_operand:PTR 0 "memory_operand")
19837 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
19838 UNSPEC_SP_SET))
19839 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
19840 (clobber (reg:CC FLAGS_REG))])
19841 (set (match_operand:SI 3 "general_reg_operand")
19842 (match_operand:SI 4))]
19843 "REGNO (operands[2]) == REGNO (operands[3])
19844 && (general_reg_operand (operands[4], SImode)
19845 || memory_operand (operands[4], SImode)
19846 || immediate_operand (operands[4], SImode))
19847 && !reg_overlap_mentioned_p (operands[3], operands[4])"
19848 [(parallel [(set (match_dup 0)
19849 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
19850 (set (match_dup 3) (match_dup 4))
19851 (clobber (reg:CC FLAGS_REG))])])
19852
19853 (define_insn "*stack_protect_set_3"
19854 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
19855 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
19856 UNSPEC_SP_SET))
19857 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
19858 (match_operand:DI 2 "general_operand" "Z,rem,i"))
19859 (clobber (reg:CC FLAGS_REG))]
19860 "TARGET_64BIT
19861 && reload_completed
19862 && !reg_overlap_mentioned_p (operands[1], operands[2])"
19863 {
19864 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
19865 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
19866 if (pic_32bit_operand (operands[2], DImode))
19867 return "lea{q}\t{%E2, %1|%1, %E2}";
19868 else if (which_alternative == 0)
19869 return "mov{l}\t{%k2, %k1|%k1, %k2}";
19870 else if (which_alternative == 2)
19871 return "movabs{q}\t{%2, %1|%1, %2}";
19872 else if (ix86_use_lea_for_mov (insn, operands + 1))
19873 return "lea{q}\t{%E2, %1|%1, %E2}";
19874 else
19875 return "mov{q}\t{%2, %1|%1, %2}";
19876 }
19877 [(set_attr "type" "multi")
19878 (set_attr "length" "24")])
19879
19880 (define_peephole2
19881 [(parallel [(set (match_operand:DI 0 "memory_operand")
19882 (unspec:DI [(match_operand:DI 1 "memory_operand")]
19883 UNSPEC_SP_SET))
19884 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
19885 (clobber (reg:CC FLAGS_REG))])
19886 (set (match_dup 2) (match_operand:DI 3))]
19887 "TARGET_64BIT
19888 && (general_reg_operand (operands[3], DImode)
19889 || memory_operand (operands[3], DImode)
19890 || x86_64_zext_immediate_operand (operands[3], DImode)
19891 || x86_64_immediate_operand (operands[3], DImode)
19892 || (CONSTANT_P (operands[3])
19893 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
19894 && !reg_overlap_mentioned_p (operands[2], operands[3])"
19895 [(parallel [(set (match_dup 0)
19896 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
19897 (set (match_dup 2) (match_dup 3))
19898 (clobber (reg:CC FLAGS_REG))])])
19899
19900 (define_expand "stack_protect_test"
19901 [(match_operand 0 "memory_operand")
19902 (match_operand 1 "memory_operand")
19903 (match_operand 2)]
19904 ""
19905 {
19906 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19907
19908 emit_insn (gen_stack_protect_test_1
19909 (ptr_mode, flags, operands[0], operands[1]));
19910
19911 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19912 flags, const0_rtx, operands[2]));
19913 DONE;
19914 })
19915
19916 (define_insn "@stack_protect_test_1_<mode>"
19917 [(set (match_operand:CCZ 0 "flags_reg_operand")
19918 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19919 (match_operand:PTR 2 "memory_operand" "m")]
19920 UNSPEC_SP_TEST))
19921 (clobber (match_scratch:PTR 3 "=&r"))]
19922 ""
19923 {
19924 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
19925 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
19926 }
19927 [(set_attr "type" "multi")])
19928
19929 (define_insn "sse4_2_crc32<mode>"
19930 [(set (match_operand:SI 0 "register_operand" "=r")
19931 (unspec:SI
19932 [(match_operand:SI 1 "register_operand" "0")
19933 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19934 UNSPEC_CRC32))]
19935 "TARGET_SSE4_2 || TARGET_CRC32"
19936 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19937 [(set_attr "type" "sselog1")
19938 (set_attr "prefix_rep" "1")
19939 (set_attr "prefix_extra" "1")
19940 (set (attr "prefix_data16")
19941 (if_then_else (match_operand:HI 2)
19942 (const_string "1")
19943 (const_string "*")))
19944 (set (attr "prefix_rex")
19945 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19946 (const_string "1")
19947 (const_string "*")))
19948 (set_attr "mode" "SI")])
19949
19950 (define_insn "sse4_2_crc32di"
19951 [(set (match_operand:DI 0 "register_operand" "=r")
19952 (unspec:DI
19953 [(match_operand:DI 1 "register_operand" "0")
19954 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19955 UNSPEC_CRC32))]
19956 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19957 "crc32{q}\t{%2, %0|%0, %2}"
19958 [(set_attr "type" "sselog1")
19959 (set_attr "prefix_rep" "1")
19960 (set_attr "prefix_extra" "1")
19961 (set_attr "mode" "DI")])
19962
19963 (define_insn "rdpmc"
19964 [(set (match_operand:DI 0 "register_operand" "=A")
19965 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19966 UNSPECV_RDPMC))]
19967 "!TARGET_64BIT"
19968 "rdpmc"
19969 [(set_attr "type" "other")
19970 (set_attr "length" "2")])
19971
19972 (define_insn "rdpmc_rex64"
19973 [(set (match_operand:DI 0 "register_operand" "=a")
19974 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19975 UNSPECV_RDPMC))
19976 (set (match_operand:DI 1 "register_operand" "=d")
19977 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19978 "TARGET_64BIT"
19979 "rdpmc"
19980 [(set_attr "type" "other")
19981 (set_attr "length" "2")])
19982
19983 (define_insn "rdtsc"
19984 [(set (match_operand:DI 0 "register_operand" "=A")
19985 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19986 "!TARGET_64BIT"
19987 "rdtsc"
19988 [(set_attr "type" "other")
19989 (set_attr "length" "2")])
19990
19991 (define_insn "rdtsc_rex64"
19992 [(set (match_operand:DI 0 "register_operand" "=a")
19993 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19994 (set (match_operand:DI 1 "register_operand" "=d")
19995 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19996 "TARGET_64BIT"
19997 "rdtsc"
19998 [(set_attr "type" "other")
19999 (set_attr "length" "2")])
20000
20001 (define_insn "rdtscp"
20002 [(set (match_operand:DI 0 "register_operand" "=A")
20003 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20004 (set (match_operand:SI 1 "register_operand" "=c")
20005 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20006 "!TARGET_64BIT"
20007 "rdtscp"
20008 [(set_attr "type" "other")
20009 (set_attr "length" "3")])
20010
20011 (define_insn "rdtscp_rex64"
20012 [(set (match_operand:DI 0 "register_operand" "=a")
20013 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20014 (set (match_operand:DI 1 "register_operand" "=d")
20015 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20016 (set (match_operand:SI 2 "register_operand" "=c")
20017 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20018 "TARGET_64BIT"
20019 "rdtscp"
20020 [(set_attr "type" "other")
20021 (set_attr "length" "3")])
20022
20023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20024 ;;
20025 ;; FXSR, XSAVE and XSAVEOPT instructions
20026 ;;
20027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20028
20029 (define_insn "fxsave"
20030 [(set (match_operand:BLK 0 "memory_operand" "=m")
20031 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20032 "TARGET_FXSR"
20033 "fxsave\t%0"
20034 [(set_attr "type" "other")
20035 (set_attr "memory" "store")
20036 (set (attr "length")
20037 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20038
20039 (define_insn "fxsave64"
20040 [(set (match_operand:BLK 0 "memory_operand" "=m")
20041 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20042 "TARGET_64BIT && TARGET_FXSR"
20043 "fxsave64\t%0"
20044 [(set_attr "type" "other")
20045 (set_attr "memory" "store")
20046 (set (attr "length")
20047 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20048
20049 (define_insn "fxrstor"
20050 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20051 UNSPECV_FXRSTOR)]
20052 "TARGET_FXSR"
20053 "fxrstor\t%0"
20054 [(set_attr "type" "other")
20055 (set_attr "memory" "load")
20056 (set (attr "length")
20057 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20058
20059 (define_insn "fxrstor64"
20060 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20061 UNSPECV_FXRSTOR64)]
20062 "TARGET_64BIT && TARGET_FXSR"
20063 "fxrstor64\t%0"
20064 [(set_attr "type" "other")
20065 (set_attr "memory" "load")
20066 (set (attr "length")
20067 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20068
20069 (define_int_iterator ANY_XSAVE
20070 [UNSPECV_XSAVE
20071 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20072 (UNSPECV_XSAVEC "TARGET_XSAVEC")
20073 (UNSPECV_XSAVES "TARGET_XSAVES")])
20074
20075 (define_int_iterator ANY_XSAVE64
20076 [UNSPECV_XSAVE64
20077 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20078 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20079 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20080
20081 (define_int_attr xsave
20082 [(UNSPECV_XSAVE "xsave")
20083 (UNSPECV_XSAVE64 "xsave64")
20084 (UNSPECV_XSAVEOPT "xsaveopt")
20085 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20086 (UNSPECV_XSAVEC "xsavec")
20087 (UNSPECV_XSAVEC64 "xsavec64")
20088 (UNSPECV_XSAVES "xsaves")
20089 (UNSPECV_XSAVES64 "xsaves64")])
20090
20091 (define_int_iterator ANY_XRSTOR
20092 [UNSPECV_XRSTOR
20093 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20094
20095 (define_int_iterator ANY_XRSTOR64
20096 [UNSPECV_XRSTOR64
20097 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20098
20099 (define_int_attr xrstor
20100 [(UNSPECV_XRSTOR "xrstor")
20101 (UNSPECV_XRSTOR64 "xrstor")
20102 (UNSPECV_XRSTORS "xrstors")
20103 (UNSPECV_XRSTORS64 "xrstors")])
20104
20105 (define_insn "<xsave>"
20106 [(set (match_operand:BLK 0 "memory_operand" "=m")
20107 (unspec_volatile:BLK
20108 [(match_operand:DI 1 "register_operand" "A")]
20109 ANY_XSAVE))]
20110 "!TARGET_64BIT && TARGET_XSAVE"
20111 "<xsave>\t%0"
20112 [(set_attr "type" "other")
20113 (set_attr "memory" "store")
20114 (set (attr "length")
20115 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20116
20117 (define_insn "<xsave>_rex64"
20118 [(set (match_operand:BLK 0 "memory_operand" "=m")
20119 (unspec_volatile:BLK
20120 [(match_operand:SI 1 "register_operand" "a")
20121 (match_operand:SI 2 "register_operand" "d")]
20122 ANY_XSAVE))]
20123 "TARGET_64BIT && TARGET_XSAVE"
20124 "<xsave>\t%0"
20125 [(set_attr "type" "other")
20126 (set_attr "memory" "store")
20127 (set (attr "length")
20128 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20129
20130 (define_insn "<xsave>"
20131 [(set (match_operand:BLK 0 "memory_operand" "=m")
20132 (unspec_volatile:BLK
20133 [(match_operand:SI 1 "register_operand" "a")
20134 (match_operand:SI 2 "register_operand" "d")]
20135 ANY_XSAVE64))]
20136 "TARGET_64BIT && TARGET_XSAVE"
20137 "<xsave>\t%0"
20138 [(set_attr "type" "other")
20139 (set_attr "memory" "store")
20140 (set (attr "length")
20141 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20142
20143 (define_insn "<xrstor>"
20144 [(unspec_volatile:BLK
20145 [(match_operand:BLK 0 "memory_operand" "m")
20146 (match_operand:DI 1 "register_operand" "A")]
20147 ANY_XRSTOR)]
20148 "!TARGET_64BIT && TARGET_XSAVE"
20149 "<xrstor>\t%0"
20150 [(set_attr "type" "other")
20151 (set_attr "memory" "load")
20152 (set (attr "length")
20153 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20154
20155 (define_insn "<xrstor>_rex64"
20156 [(unspec_volatile:BLK
20157 [(match_operand:BLK 0 "memory_operand" "m")
20158 (match_operand:SI 1 "register_operand" "a")
20159 (match_operand:SI 2 "register_operand" "d")]
20160 ANY_XRSTOR)]
20161 "TARGET_64BIT && TARGET_XSAVE"
20162 "<xrstor>\t%0"
20163 [(set_attr "type" "other")
20164 (set_attr "memory" "load")
20165 (set (attr "length")
20166 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20167
20168 (define_insn "<xrstor>64"
20169 [(unspec_volatile:BLK
20170 [(match_operand:BLK 0 "memory_operand" "m")
20171 (match_operand:SI 1 "register_operand" "a")
20172 (match_operand:SI 2 "register_operand" "d")]
20173 ANY_XRSTOR64)]
20174 "TARGET_64BIT && TARGET_XSAVE"
20175 "<xrstor>64\t%0"
20176 [(set_attr "type" "other")
20177 (set_attr "memory" "load")
20178 (set (attr "length")
20179 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20180
20181 (define_insn "xsetbv"
20182 [(unspec_volatile:SI
20183 [(match_operand:SI 0 "register_operand" "c")
20184 (match_operand:DI 1 "register_operand" "A")]
20185 UNSPECV_XSETBV)]
20186 "!TARGET_64BIT && TARGET_XSAVE"
20187 "xsetbv"
20188 [(set_attr "type" "other")])
20189
20190 (define_insn "xsetbv_rex64"
20191 [(unspec_volatile:SI
20192 [(match_operand:SI 0 "register_operand" "c")
20193 (match_operand:SI 1 "register_operand" "a")
20194 (match_operand:SI 2 "register_operand" "d")]
20195 UNSPECV_XSETBV)]
20196 "TARGET_64BIT && TARGET_XSAVE"
20197 "xsetbv"
20198 [(set_attr "type" "other")])
20199
20200 (define_insn "xgetbv"
20201 [(set (match_operand:DI 0 "register_operand" "=A")
20202 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20203 UNSPECV_XGETBV))]
20204 "!TARGET_64BIT && TARGET_XSAVE"
20205 "xgetbv"
20206 [(set_attr "type" "other")])
20207
20208 (define_insn "xgetbv_rex64"
20209 [(set (match_operand:DI 0 "register_operand" "=a")
20210 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20211 UNSPECV_XGETBV))
20212 (set (match_operand:DI 1 "register_operand" "=d")
20213 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20214 "TARGET_64BIT && TARGET_XSAVE"
20215 "xgetbv"
20216 [(set_attr "type" "other")])
20217
20218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20219 ;;
20220 ;; Floating-point instructions for atomic compound assignments
20221 ;;
20222 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20223
20224 ; Clobber all floating-point registers on environment save and restore
20225 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20226 (define_insn "fnstenv"
20227 [(set (match_operand:BLK 0 "memory_operand" "=m")
20228 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20229 (clobber (reg:XF ST0_REG))
20230 (clobber (reg:XF ST1_REG))
20231 (clobber (reg:XF ST2_REG))
20232 (clobber (reg:XF ST3_REG))
20233 (clobber (reg:XF ST4_REG))
20234 (clobber (reg:XF ST5_REG))
20235 (clobber (reg:XF ST6_REG))
20236 (clobber (reg:XF ST7_REG))]
20237 "TARGET_80387"
20238 "fnstenv\t%0"
20239 [(set_attr "type" "other")
20240 (set_attr "memory" "store")
20241 (set (attr "length")
20242 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20243
20244 (define_insn "fldenv"
20245 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20246 UNSPECV_FLDENV)
20247 (clobber (reg:XF ST0_REG))
20248 (clobber (reg:XF ST1_REG))
20249 (clobber (reg:XF ST2_REG))
20250 (clobber (reg:XF ST3_REG))
20251 (clobber (reg:XF ST4_REG))
20252 (clobber (reg:XF ST5_REG))
20253 (clobber (reg:XF ST6_REG))
20254 (clobber (reg:XF ST7_REG))]
20255 "TARGET_80387"
20256 "fldenv\t%0"
20257 [(set_attr "type" "other")
20258 (set_attr "memory" "load")
20259 (set (attr "length")
20260 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20261
20262 (define_insn "fnstsw"
20263 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20264 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20265 "TARGET_80387"
20266 "fnstsw\t%0"
20267 [(set_attr "type" "other,other")
20268 (set_attr "memory" "none,store")
20269 (set (attr "length")
20270 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20271
20272 (define_insn "fnclex"
20273 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20274 "TARGET_80387"
20275 "fnclex"
20276 [(set_attr "type" "other")
20277 (set_attr "memory" "none")
20278 (set_attr "length" "2")])
20279
20280 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20281 ;;
20282 ;; LWP instructions
20283 ;;
20284 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20285
20286 (define_expand "lwp_llwpcb"
20287 [(unspec_volatile [(match_operand 0 "register_operand")]
20288 UNSPECV_LLWP_INTRINSIC)]
20289 "TARGET_LWP")
20290
20291 (define_insn "*lwp_llwpcb<mode>_1"
20292 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20293 UNSPECV_LLWP_INTRINSIC)]
20294 "TARGET_LWP"
20295 "llwpcb\t%0"
20296 [(set_attr "type" "lwp")
20297 (set_attr "mode" "<MODE>")
20298 (set_attr "length" "5")])
20299
20300 (define_expand "lwp_slwpcb"
20301 [(set (match_operand 0 "register_operand")
20302 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20303 "TARGET_LWP"
20304 "emit_insn (gen_lwp_slwpcb_1 (Pmode, operands[0])); DONE;")
20305
20306 (define_insn "@lwp_slwpcb<mode>_1"
20307 [(set (match_operand:P 0 "register_operand" "=r")
20308 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20309 "TARGET_LWP"
20310 "slwpcb\t%0"
20311 [(set_attr "type" "lwp")
20312 (set_attr "mode" "<MODE>")
20313 (set_attr "length" "5")])
20314
20315 (define_expand "lwp_lwpval<mode>3"
20316 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20317 (match_operand:SI 2 "nonimmediate_operand")
20318 (match_operand:SI 3 "const_int_operand")]
20319 UNSPECV_LWPVAL_INTRINSIC)]
20320 "TARGET_LWP"
20321 ;; Avoid unused variable warning.
20322 "(void) operands[0];")
20323
20324 (define_insn "*lwp_lwpval<mode>3_1"
20325 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20326 (match_operand:SI 1 "nonimmediate_operand" "rm")
20327 (match_operand:SI 2 "const_int_operand" "i")]
20328 UNSPECV_LWPVAL_INTRINSIC)]
20329 "TARGET_LWP"
20330 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20331 [(set_attr "type" "lwp")
20332 (set_attr "mode" "<MODE>")
20333 (set (attr "length")
20334 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20335
20336 (define_expand "lwp_lwpins<mode>3"
20337 [(set (reg:CCC FLAGS_REG)
20338 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20339 (match_operand:SI 2 "nonimmediate_operand")
20340 (match_operand:SI 3 "const_int_operand")]
20341 UNSPECV_LWPINS_INTRINSIC))
20342 (set (match_operand:QI 0 "nonimmediate_operand")
20343 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20344 "TARGET_LWP")
20345
20346 (define_insn "*lwp_lwpins<mode>3_1"
20347 [(set (reg:CCC FLAGS_REG)
20348 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20349 (match_operand:SI 1 "nonimmediate_operand" "rm")
20350 (match_operand:SI 2 "const_int_operand" "i")]
20351 UNSPECV_LWPINS_INTRINSIC))]
20352 "TARGET_LWP"
20353 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20354 [(set_attr "type" "lwp")
20355 (set_attr "mode" "<MODE>")
20356 (set (attr "length")
20357 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20358
20359 (define_int_iterator RDFSGSBASE
20360 [UNSPECV_RDFSBASE
20361 UNSPECV_RDGSBASE])
20362
20363 (define_int_iterator WRFSGSBASE
20364 [UNSPECV_WRFSBASE
20365 UNSPECV_WRGSBASE])
20366
20367 (define_int_attr fsgs
20368 [(UNSPECV_RDFSBASE "fs")
20369 (UNSPECV_RDGSBASE "gs")
20370 (UNSPECV_WRFSBASE "fs")
20371 (UNSPECV_WRGSBASE "gs")])
20372
20373 (define_insn "rd<fsgs>base<mode>"
20374 [(set (match_operand:SWI48 0 "register_operand" "=r")
20375 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20376 "TARGET_64BIT && TARGET_FSGSBASE"
20377 "rd<fsgs>base\t%0"
20378 [(set_attr "type" "other")
20379 (set_attr "prefix_extra" "2")])
20380
20381 (define_insn "wr<fsgs>base<mode>"
20382 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20383 WRFSGSBASE)]
20384 "TARGET_64BIT && TARGET_FSGSBASE"
20385 "wr<fsgs>base\t%0"
20386 [(set_attr "type" "other")
20387 (set_attr "prefix_extra" "2")])
20388
20389 (define_insn "ptwrite<mode>"
20390 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
20391 UNSPECV_PTWRITE)]
20392 "TARGET_PTWRITE"
20393 "ptwrite\t%0"
20394 [(set_attr "type" "other")
20395 (set_attr "prefix_extra" "2")])
20396
20397 (define_insn "rdrand<mode>_1"
20398 [(set (match_operand:SWI248 0 "register_operand" "=r")
20399 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20400 (set (reg:CCC FLAGS_REG)
20401 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20402 "TARGET_RDRND"
20403 "rdrand\t%0"
20404 [(set_attr "type" "other")
20405 (set_attr "prefix_extra" "1")])
20406
20407 (define_insn "rdseed<mode>_1"
20408 [(set (match_operand:SWI248 0 "register_operand" "=r")
20409 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20410 (set (reg:CCC FLAGS_REG)
20411 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20412 "TARGET_RDSEED"
20413 "rdseed\t%0"
20414 [(set_attr "type" "other")
20415 (set_attr "prefix_extra" "1")])
20416
20417 (define_expand "pause"
20418 [(set (match_dup 0)
20419 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20420 ""
20421 {
20422 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20423 MEM_VOLATILE_P (operands[0]) = 1;
20424 })
20425
20426 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20427 ;; They have the same encoding.
20428 (define_insn "*pause"
20429 [(set (match_operand:BLK 0)
20430 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20431 ""
20432 "rep%; nop"
20433 [(set_attr "length" "2")
20434 (set_attr "memory" "unknown")])
20435
20436 ;; CET instructions
20437 (define_insn "rdssp<mode>"
20438 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20439 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20440 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20441 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20442 [(set_attr "length" "6")
20443 (set_attr "type" "other")])
20444
20445 (define_insn "incssp<mode>"
20446 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20447 UNSPECV_INCSSP)]
20448 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20449 "incssp<mskmodesuffix>\t%0"
20450 [(set_attr "length" "4")
20451 (set_attr "type" "other")])
20452
20453 (define_insn "saveprevssp"
20454 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20455 "TARGET_SHSTK"
20456 "saveprevssp"
20457 [(set_attr "length" "5")
20458 (set_attr "type" "other")])
20459
20460 (define_expand "rstorssp"
20461 [(unspec_volatile [(match_operand 0 "memory_operand")]
20462 UNSPECV_RSTORSSP)]
20463 "TARGET_SHSTK")
20464
20465 (define_insn "*rstorssp<mode>"
20466 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20467 UNSPECV_RSTORSSP)]
20468 "TARGET_SHSTK"
20469 "rstorssp\t%0"
20470 [(set_attr "length" "5")
20471 (set_attr "type" "other")])
20472
20473 (define_insn "wrss<mode>"
20474 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20475 (match_operand:SWI48x 1 "memory_operand" "m")]
20476 UNSPECV_WRSS)]
20477 "TARGET_SHSTK"
20478 "wrss<mskmodesuffix>\t%0, %1"
20479 [(set_attr "length" "3")
20480 (set_attr "type" "other")])
20481
20482 (define_insn "wruss<mode>"
20483 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20484 (match_operand:SWI48x 1 "memory_operand" "m")]
20485 UNSPECV_WRUSS)]
20486 "TARGET_SHSTK"
20487 "wruss<mskmodesuffix>\t%0, %1"
20488 [(set_attr "length" "4")
20489 (set_attr "type" "other")])
20490
20491 (define_insn "setssbsy"
20492 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20493 "TARGET_SHSTK"
20494 "setssbsy"
20495 [(set_attr "length" "4")
20496 (set_attr "type" "other")])
20497
20498 (define_expand "clrssbsy"
20499 [(unspec_volatile [(match_operand 0 "memory_operand")]
20500 UNSPECV_CLRSSBSY)]
20501 "TARGET_SHSTK")
20502
20503 (define_insn "*clrssbsy<mode>"
20504 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20505 UNSPECV_CLRSSBSY)]
20506 "TARGET_SHSTK"
20507 "clrssbsy\t%0"
20508 [(set_attr "length" "4")
20509 (set_attr "type" "other")])
20510
20511 (define_insn "nop_endbr"
20512 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20513 "(flag_cf_protection & CF_BRANCH)"
20514 {
20515 return TARGET_64BIT ? "endbr64" : "endbr32";
20516 }
20517 [(set_attr "length" "4")
20518 (set_attr "length_immediate" "0")
20519 (set_attr "modrm" "0")])
20520
20521 ;; For RTM support
20522 (define_expand "xbegin"
20523 [(set (match_operand:SI 0 "register_operand")
20524 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20525 "TARGET_RTM"
20526 {
20527 rtx_code_label *label = gen_label_rtx ();
20528
20529 /* xbegin is emitted as jump_insn, so reload won't be able
20530 to reload its operand. Force the value into AX hard register. */
20531 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20532 emit_move_insn (ax_reg, constm1_rtx);
20533
20534 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20535
20536 emit_label (label);
20537 LABEL_NUSES (label) = 1;
20538
20539 emit_move_insn (operands[0], ax_reg);
20540
20541 DONE;
20542 })
20543
20544 (define_insn "xbegin_1"
20545 [(set (pc)
20546 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20547 (const_int 0))
20548 (label_ref (match_operand 1))
20549 (pc)))
20550 (set (match_operand:SI 0 "register_operand" "+a")
20551 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20552 "TARGET_RTM"
20553 "xbegin\t%l1"
20554 [(set_attr "type" "other")
20555 (set_attr "length" "6")])
20556
20557 (define_insn "xend"
20558 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20559 "TARGET_RTM"
20560 "xend"
20561 [(set_attr "type" "other")
20562 (set_attr "length" "3")])
20563
20564 (define_insn "xabort"
20565 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20566 UNSPECV_XABORT)]
20567 "TARGET_RTM"
20568 "xabort\t%0"
20569 [(set_attr "type" "other")
20570 (set_attr "length" "3")])
20571
20572 (define_expand "xtest"
20573 [(set (match_operand:QI 0 "register_operand")
20574 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20575 "TARGET_RTM"
20576 {
20577 emit_insn (gen_xtest_1 ());
20578
20579 ix86_expand_setcc (operands[0], NE,
20580 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20581 DONE;
20582 })
20583
20584 (define_insn "xtest_1"
20585 [(set (reg:CCZ FLAGS_REG)
20586 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20587 "TARGET_RTM"
20588 "xtest"
20589 [(set_attr "type" "other")
20590 (set_attr "length" "3")])
20591
20592 (define_insn "clwb"
20593 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20594 UNSPECV_CLWB)]
20595 "TARGET_CLWB"
20596 "clwb\t%a0"
20597 [(set_attr "type" "sse")
20598 (set_attr "atom_sse_attr" "fence")
20599 (set_attr "memory" "unknown")])
20600
20601 (define_insn "clflushopt"
20602 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20603 UNSPECV_CLFLUSHOPT)]
20604 "TARGET_CLFLUSHOPT"
20605 "clflushopt\t%a0"
20606 [(set_attr "type" "sse")
20607 (set_attr "atom_sse_attr" "fence")
20608 (set_attr "memory" "unknown")])
20609
20610 ;; MONITORX and MWAITX
20611 (define_insn "mwaitx"
20612 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20613 (match_operand:SI 1 "register_operand" "a")
20614 (match_operand:SI 2 "register_operand" "b")]
20615 UNSPECV_MWAITX)]
20616 "TARGET_MWAITX"
20617 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20618 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20619 ;; we only need to set up 32bit registers.
20620 "mwaitx"
20621 [(set_attr "length" "3")])
20622
20623 (define_insn "@monitorx_<mode>"
20624 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20625 (match_operand:SI 1 "register_operand" "c")
20626 (match_operand:SI 2 "register_operand" "d")]
20627 UNSPECV_MONITORX)]
20628 "TARGET_MWAITX"
20629 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20630 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20631 ;; zero extended to 64bit, we only need to set up 32bit registers.
20632 "%^monitorx"
20633 [(set (attr "length")
20634 (symbol_ref ("(Pmode != word_mode) + 3")))])
20635
20636 ;; CLZERO
20637 (define_insn "@clzero_<mode>"
20638 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20639 UNSPECV_CLZERO)]
20640 "TARGET_CLZERO"
20641 "clzero"
20642 [(set_attr "length" "3")
20643 (set_attr "memory" "unknown")])
20644
20645 ;; RDPKRU and WRPKRU
20646
20647 (define_expand "rdpkru"
20648 [(parallel
20649 [(set (match_operand:SI 0 "register_operand")
20650 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20651 (set (match_dup 2) (const_int 0))])]
20652 "TARGET_PKU"
20653 {
20654 operands[1] = force_reg (SImode, const0_rtx);
20655 operands[2] = gen_reg_rtx (SImode);
20656 })
20657
20658 (define_insn "*rdpkru"
20659 [(set (match_operand:SI 0 "register_operand" "=a")
20660 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20661 UNSPECV_PKU))
20662 (set (match_operand:SI 1 "register_operand" "=d")
20663 (const_int 0))]
20664 "TARGET_PKU"
20665 "rdpkru"
20666 [(set_attr "type" "other")])
20667
20668 (define_expand "wrpkru"
20669 [(unspec_volatile:SI
20670 [(match_operand:SI 0 "register_operand")
20671 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20672 "TARGET_PKU"
20673 {
20674 operands[1] = force_reg (SImode, const0_rtx);
20675 operands[2] = force_reg (SImode, const0_rtx);
20676 })
20677
20678 (define_insn "*wrpkru"
20679 [(unspec_volatile:SI
20680 [(match_operand:SI 0 "register_operand" "a")
20681 (match_operand:SI 1 "register_operand" "d")
20682 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20683 "TARGET_PKU"
20684 "wrpkru"
20685 [(set_attr "type" "other")])
20686
20687 (define_insn "rdpid"
20688 [(set (match_operand:SI 0 "register_operand" "=r")
20689 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20690 "!TARGET_64BIT && TARGET_RDPID"
20691 "rdpid\t%0"
20692 [(set_attr "type" "other")])
20693
20694 (define_insn "rdpid_rex64"
20695 [(set (match_operand:DI 0 "register_operand" "=r")
20696 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20697 "TARGET_64BIT && TARGET_RDPID"
20698 "rdpid\t%0"
20699 [(set_attr "type" "other")])
20700
20701 ;; Intirinsics for > i486
20702
20703 (define_insn "wbinvd"
20704 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20705 ""
20706 "wbinvd"
20707 [(set_attr "type" "other")])
20708
20709 (define_insn "wbnoinvd"
20710 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20711 "TARGET_WBNOINVD"
20712 "wbnoinvd"
20713 [(set_attr "type" "other")])
20714
20715 ;; MOVDIRI and MOVDIR64B
20716
20717 (define_insn "movdiri<mode>"
20718 [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20719 (match_operand:SWI48 1 "register_operand" "r")]
20720 UNSPECV_MOVDIRI)]
20721 "TARGET_MOVDIRI"
20722 "movdiri\t{%1, %0|%0, %1}"
20723 [(set_attr "type" "other")])
20724
20725 (define_insn "@movdir64b_<mode>"
20726 [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20727 (match_operand:XI 1 "memory_operand")]
20728 UNSPECV_MOVDIR64B)]
20729 "TARGET_MOVDIR64B"
20730 "movdir64b\t{%1, %0|%0, %1}"
20731 [(set_attr "type" "other")])
20732
20733 ;; ENQCMD and ENQCMDS
20734
20735 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
20736 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
20737
20738 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
20739 [(set (reg:CCZ FLAGS_REG)
20740 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
20741 (match_operand:XI 1 "memory_operand" "m")]
20742 ENQCMD))]
20743 "TARGET_ENQCMD"
20744 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
20745 [(set_attr "type" "other")])
20746
20747 ;; WAITPKG
20748
20749 (define_insn "umwait"
20750 [(set (reg:CCC FLAGS_REG)
20751 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20752 (match_operand:DI 1 "register_operand" "A")]
20753 UNSPECV_UMWAIT))]
20754 "!TARGET_64BIT && TARGET_WAITPKG"
20755 "umwait\t%0"
20756 [(set_attr "length" "3")])
20757
20758 (define_insn "umwait_rex64"
20759 [(set (reg:CCC FLAGS_REG)
20760 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20761 (match_operand:SI 1 "register_operand" "a")
20762 (match_operand:SI 2 "register_operand" "d")]
20763 UNSPECV_UMWAIT))]
20764 "TARGET_64BIT && TARGET_WAITPKG"
20765 "umwait\t%0"
20766 [(set_attr "length" "3")])
20767
20768 (define_insn "@umonitor_<mode>"
20769 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20770 UNSPECV_UMONITOR)]
20771 "TARGET_WAITPKG"
20772 "umonitor\t%0"
20773 [(set (attr "length")
20774 (symbol_ref ("(Pmode != word_mode) + 3")))])
20775
20776 (define_insn "tpause"
20777 [(set (reg:CCC FLAGS_REG)
20778 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20779 (match_operand:DI 1 "register_operand" "A")]
20780 UNSPECV_TPAUSE))]
20781 "!TARGET_64BIT && TARGET_WAITPKG"
20782 "tpause\t%0"
20783 [(set_attr "length" "3")])
20784
20785 (define_insn "tpause_rex64"
20786 [(set (reg:CCC FLAGS_REG)
20787 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20788 (match_operand:SI 1 "register_operand" "a")
20789 (match_operand:SI 2 "register_operand" "d")]
20790 UNSPECV_TPAUSE))]
20791 "TARGET_64BIT && TARGET_WAITPKG"
20792 "tpause\t%0"
20793 [(set_attr "length" "3")])
20794
20795 (define_insn "cldemote"
20796 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20797 UNSPECV_CLDEMOTE)]
20798 "TARGET_CLDEMOTE"
20799 "cldemote\t%a0"
20800 [(set_attr "type" "other")
20801 (set_attr "memory" "unknown")])
20802
20803 (define_insn "speculation_barrier"
20804 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
20805 ""
20806 "lfence"
20807 [(set_attr "type" "other")
20808 (set_attr "length" "3")])
20809
20810 (include "mmx.md")
20811 (include "sse.md")
20812 (include "sync.md")