]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
i386: Fix split condition of *<insn>qi_ext<mode>_1_slp patterns
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2023 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 UNSPEC_CC_NE
117 UNSPEC_STC
118 UNSPEC_PUSHFL
119 UNSPEC_POPFL
120
121 ;; For SSE/MMX support:
122 UNSPEC_FIX_NOTRUNC
123 UNSPEC_MASKMOV
124 UNSPEC_MOVCC_MASK
125 UNSPEC_MOVMSK
126 UNSPEC_INSERTPS
127 UNSPEC_BLENDV
128 UNSPEC_PSHUFB
129 UNSPEC_XOP_PERMUTE
130 UNSPEC_RCP
131 UNSPEC_RSQRT
132 UNSPEC_PSADBW
133
134 ;; Different from generic us_truncate RTX
135 ;; as it does unsigned saturation of signed source.
136 UNSPEC_US_TRUNCATE
137
138 ;; For AVX/AVX512F support
139 UNSPEC_SCALEF
140 UNSPEC_PCMP
141 UNSPEC_CVTBFSF
142
143 ;; Generic math support
144 UNSPEC_IEEE_MIN ; not commutative
145 UNSPEC_IEEE_MAX ; not commutative
146
147 ;; x87 Floating point
148 UNSPEC_SIN
149 UNSPEC_COS
150 UNSPEC_FPATAN
151 UNSPEC_FYL2X
152 UNSPEC_FYL2XP1
153 UNSPEC_FRNDINT
154 UNSPEC_FIST
155 UNSPEC_F2XM1
156 UNSPEC_TAN
157 UNSPEC_FXAM
158
159 ;; x87 Rounding
160 UNSPEC_FRNDINT_ROUNDEVEN
161 UNSPEC_FRNDINT_FLOOR
162 UNSPEC_FRNDINT_CEIL
163 UNSPEC_FRNDINT_TRUNC
164 UNSPEC_FIST_FLOOR
165 UNSPEC_FIST_CEIL
166
167 ;; x87 Double output FP
168 UNSPEC_SINCOS_COS
169 UNSPEC_SINCOS_SIN
170 UNSPEC_XTRACT_FRACT
171 UNSPEC_XTRACT_EXP
172 UNSPEC_FSCALE_FRACT
173 UNSPEC_FSCALE_EXP
174 UNSPEC_FPREM_F
175 UNSPEC_FPREM_U
176 UNSPEC_FPREM1_F
177 UNSPEC_FPREM1_U
178
179 UNSPEC_C2_FLAG
180 UNSPEC_FXAM_MEM
181
182 ;; SSP patterns
183 UNSPEC_SP_SET
184 UNSPEC_SP_TEST
185
186 ;; For ROUND support
187 UNSPEC_ROUND
188
189 ;; For CRC32 support
190 UNSPEC_CRC32
191
192 ;; For LZCNT suppoprt
193 UNSPEC_LZCNT
194
195 ;; For BMI support
196 UNSPEC_TZCNT
197 UNSPEC_BEXTR
198
199 ;; For BMI2 support
200 UNSPEC_PDEP
201 UNSPEC_PEXT
202
203 ;; IRET support
204 UNSPEC_INTERRUPT_RETURN
205
206 ;; For MOVDIRI and MOVDIR64B support
207 UNSPEC_MOVDIRI
208 UNSPEC_MOVDIR64B
209
210 ;; For insn_callee_abi:
211 UNSPEC_CALLEE_ABI
212
213 ;; For PUSH2/POP2 support
214 UNSPEC_APXPUSH2
215 UNSPEC_APXPOP2_LOW
216 UNSPEC_APXPOP2_HIGH
217 ])
218
219 (define_c_enum "unspecv" [
220 UNSPECV_UD2
221 UNSPECV_BLOCKAGE
222 UNSPECV_STACK_PROBE
223 UNSPECV_PROBE_STACK_RANGE
224 UNSPECV_ALIGN
225 UNSPECV_PROLOGUE_USE
226 UNSPECV_SPLIT_STACK_RETURN
227 UNSPECV_CLD
228 UNSPECV_NOPS
229 UNSPECV_RDTSC
230 UNSPECV_RDTSCP
231 UNSPECV_RDPMC
232 UNSPECV_LLWP_INTRINSIC
233 UNSPECV_SLWP_INTRINSIC
234 UNSPECV_LWPVAL_INTRINSIC
235 UNSPECV_LWPINS_INTRINSIC
236 UNSPECV_RDFSBASE
237 UNSPECV_RDGSBASE
238 UNSPECV_WRFSBASE
239 UNSPECV_WRGSBASE
240 UNSPECV_FXSAVE
241 UNSPECV_FXRSTOR
242 UNSPECV_FXSAVE64
243 UNSPECV_FXRSTOR64
244 UNSPECV_XSAVE
245 UNSPECV_XRSTOR
246 UNSPECV_XSAVE64
247 UNSPECV_XRSTOR64
248 UNSPECV_XSAVEOPT
249 UNSPECV_XSAVEOPT64
250 UNSPECV_XSAVES
251 UNSPECV_XRSTORS
252 UNSPECV_XSAVES64
253 UNSPECV_XRSTORS64
254 UNSPECV_XSAVEC
255 UNSPECV_XSAVEC64
256 UNSPECV_XGETBV
257 UNSPECV_XSETBV
258 UNSPECV_WBINVD
259 UNSPECV_WBNOINVD
260
261 ;; For atomic compound assignments.
262 UNSPECV_FNSTENV
263 UNSPECV_FLDENV
264 UNSPECV_FNSTSW
265 UNSPECV_FNCLEX
266
267 ;; For RDRAND support
268 UNSPECV_RDRAND
269
270 ;; For RDSEED support
271 UNSPECV_RDSEED
272
273 ;; For RTM support
274 UNSPECV_XBEGIN
275 UNSPECV_XEND
276 UNSPECV_XABORT
277 UNSPECV_XTEST
278
279 UNSPECV_NLGR
280
281 ;; For CLWB support
282 UNSPECV_CLWB
283
284 ;; For CLFLUSHOPT support
285 UNSPECV_CLFLUSHOPT
286
287 ;; For MONITORX and MWAITX support
288 UNSPECV_MONITORX
289 UNSPECV_MWAITX
290
291 ;; For CLZERO support
292 UNSPECV_CLZERO
293
294 ;; For RDPKRU and WRPKRU support
295 UNSPECV_PKU
296
297 ;; For RDPID support
298 UNSPECV_RDPID
299
300 ;; For CET support
301 UNSPECV_NOP_ENDBR
302 UNSPECV_NOP_RDSSP
303 UNSPECV_INCSSP
304 UNSPECV_SAVEPREVSSP
305 UNSPECV_RSTORSSP
306 UNSPECV_WRSS
307 UNSPECV_WRUSS
308 UNSPECV_SETSSBSY
309 UNSPECV_CLRSSBSY
310
311 ;; For TSXLDTRK support
312 UNSPECV_XSUSLDTRK
313 UNSPECV_XRESLDTRK
314
315 ;; For WAITPKG support
316 UNSPECV_UMWAIT
317 UNSPECV_UMONITOR
318 UNSPECV_TPAUSE
319
320 ;; For UINTR support
321 UNSPECV_CLUI
322 UNSPECV_STUI
323 UNSPECV_TESTUI
324 UNSPECV_SENDUIPI
325
326 ;; For CLDEMOTE support
327 UNSPECV_CLDEMOTE
328
329 ;; For Speculation Barrier support
330 UNSPECV_SPECULATION_BARRIER
331
332 UNSPECV_PTWRITE
333
334 ;; For ENQCMD and ENQCMDS support
335 UNSPECV_ENQCMD
336 UNSPECV_ENQCMDS
337
338 ;; For SERIALIZE support
339 UNSPECV_SERIALIZE
340
341 ;; For patchable area support
342 UNSPECV_PATCHABLE_AREA
343
344 ;; For HRESET support
345 UNSPECV_HRESET
346
347 ;; For PREFETCHI support
348 UNSPECV_PREFETCHI
349
350 ;; For USER_MSR support
351 UNSPECV_URDMSR
352 UNSPECV_UWRMSR
353 ])
354
355 ;; Constants to represent rounding modes in the ROUND instruction
356 (define_constants
357 [(ROUND_ROUNDEVEN 0x0)
358 (ROUND_FLOOR 0x1)
359 (ROUND_CEIL 0x2)
360 (ROUND_TRUNC 0x3)
361 (ROUND_MXCSR 0x4)
362 (ROUND_NO_EXC 0x8)
363 ])
364
365 ;; Constants to represent AVX512F embeded rounding
366 (define_constants
367 [(ROUND_NEAREST_INT 0)
368 (ROUND_NEG_INF 1)
369 (ROUND_POS_INF 2)
370 (ROUND_ZERO 3)
371 (NO_ROUND 4)
372 (ROUND_SAE 8)
373 ])
374
375 ;; Constants to represent pcomtrue/pcomfalse variants
376 (define_constants
377 [(PCOM_FALSE 0)
378 (PCOM_TRUE 1)
379 (COM_FALSE_S 2)
380 (COM_FALSE_P 3)
381 (COM_TRUE_S 4)
382 (COM_TRUE_P 5)
383 ])
384
385 ;; Constants used in the XOP pperm instruction
386 (define_constants
387 [(PPERM_SRC 0x00) /* copy source */
388 (PPERM_INVERT 0x20) /* invert source */
389 (PPERM_REVERSE 0x40) /* bit reverse source */
390 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
391 (PPERM_ZERO 0x80) /* all 0's */
392 (PPERM_ONES 0xa0) /* all 1's */
393 (PPERM_SIGN 0xc0) /* propagate sign bit */
394 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
395 (PPERM_SRC1 0x00) /* use first source byte */
396 (PPERM_SRC2 0x10) /* use second source byte */
397 ])
398
399 ;; Registers by name.
400 (define_constants
401 [(AX_REG 0)
402 (DX_REG 1)
403 (CX_REG 2)
404 (BX_REG 3)
405 (SI_REG 4)
406 (DI_REG 5)
407 (BP_REG 6)
408 (SP_REG 7)
409 (ST0_REG 8)
410 (ST1_REG 9)
411 (ST2_REG 10)
412 (ST3_REG 11)
413 (ST4_REG 12)
414 (ST5_REG 13)
415 (ST6_REG 14)
416 (ST7_REG 15)
417 (ARGP_REG 16)
418 (FLAGS_REG 17)
419 (FPSR_REG 18)
420 (FRAME_REG 19)
421 (XMM0_REG 20)
422 (XMM1_REG 21)
423 (XMM2_REG 22)
424 (XMM3_REG 23)
425 (XMM4_REG 24)
426 (XMM5_REG 25)
427 (XMM6_REG 26)
428 (XMM7_REG 27)
429 (MM0_REG 28)
430 (MM1_REG 29)
431 (MM2_REG 30)
432 (MM3_REG 31)
433 (MM4_REG 32)
434 (MM5_REG 33)
435 (MM6_REG 34)
436 (MM7_REG 35)
437 (R8_REG 36)
438 (R9_REG 37)
439 (R10_REG 38)
440 (R11_REG 39)
441 (R12_REG 40)
442 (R13_REG 41)
443 (R14_REG 42)
444 (R15_REG 43)
445 (XMM8_REG 44)
446 (XMM9_REG 45)
447 (XMM10_REG 46)
448 (XMM11_REG 47)
449 (XMM12_REG 48)
450 (XMM13_REG 49)
451 (XMM14_REG 50)
452 (XMM15_REG 51)
453 (XMM16_REG 52)
454 (XMM17_REG 53)
455 (XMM18_REG 54)
456 (XMM19_REG 55)
457 (XMM20_REG 56)
458 (XMM21_REG 57)
459 (XMM22_REG 58)
460 (XMM23_REG 59)
461 (XMM24_REG 60)
462 (XMM25_REG 61)
463 (XMM26_REG 62)
464 (XMM27_REG 63)
465 (XMM28_REG 64)
466 (XMM29_REG 65)
467 (XMM30_REG 66)
468 (XMM31_REG 67)
469 (MASK0_REG 68)
470 (MASK1_REG 69)
471 (MASK2_REG 70)
472 (MASK3_REG 71)
473 (MASK4_REG 72)
474 (MASK5_REG 73)
475 (MASK6_REG 74)
476 (MASK7_REG 75)
477 (R16_REG 76)
478 (R17_REG 77)
479 (R18_REG 78)
480 (R19_REG 79)
481 (R20_REG 80)
482 (R21_REG 81)
483 (R22_REG 82)
484 (R23_REG 83)
485 (R24_REG 84)
486 (R25_REG 85)
487 (R26_REG 86)
488 (R27_REG 87)
489 (R28_REG 88)
490 (R29_REG 89)
491 (R30_REG 90)
492 (R31_REG 91)
493 (FIRST_PSEUDO_REG 92)
494 ])
495
496 ;; Insn callee abi index.
497 (define_constants
498 [(ABI_DEFAULT 0)
499 (ABI_VZEROUPPER 1)
500 (ABI_UNKNOWN 2)])
501
502 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
503 ;; from i386.cc.
504
505 ;; In C guard expressions, put expressions which may be compile-time
506 ;; constants first. This allows for better optimization. For
507 ;; example, write "TARGET_64BIT && reload_completed", not
508 ;; "reload_completed && TARGET_64BIT".
509
510 \f
511 ;; Processor type.
512 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
513 atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
514 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
515 (const (symbol_ref "ix86_schedule")))
516
517 ;; A basic instruction type. Refinements due to arguments to be
518 ;; provided in other attributes.
519 (define_attr "type"
520 "other,multi,
521 alu,alu1,negnot,imov,imovx,lea,
522 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
523 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
524 push,pop,call,callv,leave,
525 str,bitmanip,
526 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
527 fxch,fistp,fisttp,frndint,
528 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
529 ssemul,sseimul,ssediv,sselog,sselog1,
530 sseishft,sseishft1,ssecmp,ssecomi,
531 ssecvt,ssecvt1,sseicvt,sseins,
532 sseshuf,sseshuf1,ssemuladd,sse4arg,
533 lwp,mskmov,msklog,
534 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
535 (const_string "other"))
536
537 ;; Main data type used by the insn
538 (define_attr "mode"
539 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
540 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
541 (const_string "unknown"))
542
543 ;; The CPU unit operations uses.
544 (define_attr "unit" "integer,i387,sse,mmx,unknown"
545 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
546 fxch,fistp,fisttp,frndint")
547 (const_string "i387")
548 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
549 ssemul,sseimul,ssediv,sselog,sselog1,
550 sseishft,sseishft1,ssecmp,ssecomi,
551 ssecvt,ssecvt1,sseicvt,sseins,
552 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
553 (const_string "sse")
554 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
555 (const_string "mmx")
556 (eq_attr "type" "other")
557 (const_string "unknown")]
558 (const_string "integer")))
559
560 ;; Used to control the "enabled" attribute on a per-instruction basis.
561 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
562 x64_avx,x64_avx512bw,x64_avx512dq,aes,
563 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
564 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
565 noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
566 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
567 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
568 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
569 (const_string "base"))
570
571 ;; The (bounding maximum) length of an instruction immediate.
572 (define_attr "length_immediate" ""
573 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
574 bitmanip,imulx,msklog,mskmov")
575 (const_int 0)
576 (ior (eq_attr "type" "sse4arg")
577 (eq_attr "isa" "fma4"))
578 (const_int 1)
579 (eq_attr "unit" "i387,sse,mmx")
580 (const_int 0)
581 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
582 rotate,rotatex,rotate1,imul,icmp,push,pop")
583 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
584 (eq_attr "type" "imov,test")
585 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
586 (eq_attr "type" "call")
587 (if_then_else (match_operand 0 "constant_call_address_operand")
588 (const_int 4)
589 (const_int 0))
590 (eq_attr "type" "callv")
591 (if_then_else (match_operand 1 "constant_call_address_operand")
592 (const_int 4)
593 (const_int 0))
594 ;; We don't know the size before shorten_branches. Expect
595 ;; the instruction to fit for better scheduling.
596 (eq_attr "type" "ibr")
597 (const_int 1)
598 ]
599 (symbol_ref "/* Update immediate_length and other attributes! */
600 gcc_unreachable (),1")))
601
602 ;; The (bounding maximum) length of an instruction address.
603 (define_attr "length_address" ""
604 (cond [(eq_attr "type" "str,other,multi,fxch")
605 (const_int 0)
606 (and (eq_attr "type" "call")
607 (match_operand 0 "constant_call_address_operand"))
608 (const_int 0)
609 (and (eq_attr "type" "callv")
610 (match_operand 1 "constant_call_address_operand"))
611 (const_int 0)
612 ]
613 (symbol_ref "ix86_attr_length_address_default (insn)")))
614
615 ;; Set when length prefix is used.
616 (define_attr "prefix_data16" ""
617 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
618 (const_int 0)
619 (eq_attr "mode" "HI")
620 (const_int 1)
621 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
622 (const_int 1)
623 ]
624 (const_int 0)))
625
626 ;; Set when string REP prefix is used.
627 (define_attr "prefix_rep" ""
628 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
629 (const_int 0)
630 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
631 (const_int 1)
632 ]
633 (const_int 0)))
634
635 ;; Set when 0f opcode prefix is used.
636 (define_attr "prefix_0f" ""
637 (if_then_else
638 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
639 (eq_attr "unit" "sse,mmx"))
640 (const_int 1)
641 (const_int 0)))
642
643 ;; Set when REX opcode prefix is used.
644 (define_attr "prefix_rex" ""
645 (cond [(not (match_test "TARGET_64BIT"))
646 (const_int 0)
647 (and (eq_attr "mode" "DI")
648 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
649 (eq_attr "unit" "!mmx")))
650 (const_int 1)
651 (and (eq_attr "mode" "QI")
652 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
653 (const_int 1)
654 (match_test "x86_extended_reg_mentioned_p (insn)")
655 (const_int 1)
656 (and (eq_attr "type" "imovx")
657 (match_operand:QI 1 "ext_QIreg_operand"))
658 (const_int 1)
659 ]
660 (const_int 0)))
661
662 ;; There are also additional prefixes in 3DNOW, SSSE3.
663 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
664 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
665 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
666 (define_attr "prefix_extra" ""
667 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
668 (const_int 1)
669 ]
670 (const_int 0)))
671
672 ;; Prefix used: original, VEX or maybe VEX.
673 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
674 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
675 (const_string "vex")
676 (eq_attr "mode" "XI,V16SF,V8DF")
677 (const_string "evex")
678 (eq_attr "type" "ssemuladd")
679 (if_then_else (eq_attr "isa" "fma4")
680 (const_string "vex")
681 (const_string "maybe_evex"))
682 (eq_attr "type" "sse4arg")
683 (const_string "vex")
684 ]
685 (const_string "orig")))
686
687 ;; VEX W bit is used.
688 (define_attr "prefix_vex_w" "" (const_int 0))
689
690 ;; The length of VEX prefix
691 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
692 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
693 ;; still prefix_0f 1, with prefix_extra 1.
694 (define_attr "length_vex" ""
695 (if_then_else (and (eq_attr "prefix_0f" "1")
696 (eq_attr "prefix_extra" "0"))
697 (if_then_else (eq_attr "prefix_vex_w" "1")
698 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
699 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
700 (if_then_else (eq_attr "prefix_vex_w" "1")
701 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
702 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
703
704 ;; 4-bytes evex prefix and 1 byte opcode.
705 (define_attr "length_evex" "" (const_int 5))
706
707 ;; Set when modrm byte is used.
708 (define_attr "modrm" ""
709 (cond [(eq_attr "type" "str,leave")
710 (const_int 0)
711 (eq_attr "unit" "i387")
712 (const_int 0)
713 (and (eq_attr "type" "incdec")
714 (and (not (match_test "TARGET_64BIT"))
715 (ior (match_operand:SI 1 "register_operand")
716 (match_operand:HI 1 "register_operand"))))
717 (const_int 0)
718 (and (eq_attr "type" "push")
719 (not (match_operand 1 "memory_operand")))
720 (const_int 0)
721 (and (eq_attr "type" "pop")
722 (not (match_operand 0 "memory_operand")))
723 (const_int 0)
724 (and (eq_attr "type" "imov")
725 (and (not (eq_attr "mode" "DI"))
726 (ior (and (match_operand 0 "register_operand")
727 (match_operand 1 "immediate_operand"))
728 (ior (and (match_operand 0 "ax_reg_operand")
729 (match_operand 1 "memory_displacement_only_operand"))
730 (and (match_operand 0 "memory_displacement_only_operand")
731 (match_operand 1 "ax_reg_operand"))))))
732 (const_int 0)
733 (and (eq_attr "type" "call")
734 (match_operand 0 "constant_call_address_operand"))
735 (const_int 0)
736 (and (eq_attr "type" "callv")
737 (match_operand 1 "constant_call_address_operand"))
738 (const_int 0)
739 (and (eq_attr "type" "alu,alu1,icmp,test")
740 (match_operand 0 "ax_reg_operand"))
741 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
742 ]
743 (const_int 1)))
744
745 ;; The (bounding maximum) length of an instruction in bytes.
746 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
747 ;; Later we may want to split them and compute proper length as for
748 ;; other insns.
749 (define_attr "length" ""
750 (cond [(eq_attr "type" "other,multi,fistp,frndint")
751 (const_int 16)
752 (eq_attr "type" "fcmp")
753 (const_int 4)
754 (eq_attr "unit" "i387")
755 (plus (const_int 2)
756 (plus (attr "prefix_data16")
757 (attr "length_address")))
758 (ior (eq_attr "prefix" "evex")
759 (and (ior (eq_attr "prefix" "maybe_evex")
760 (eq_attr "prefix" "maybe_vex"))
761 (match_test "TARGET_AVX512F")))
762 (plus (attr "length_evex")
763 (plus (attr "length_immediate")
764 (plus (attr "modrm")
765 (attr "length_address"))))
766 (ior (eq_attr "prefix" "vex")
767 (and (ior (eq_attr "prefix" "maybe_vex")
768 (eq_attr "prefix" "maybe_evex"))
769 (match_test "TARGET_AVX")))
770 (plus (attr "length_vex")
771 (plus (attr "length_immediate")
772 (plus (attr "modrm")
773 (attr "length_address"))))]
774 (plus (plus (attr "modrm")
775 (plus (attr "prefix_0f")
776 (plus (attr "prefix_rex")
777 (plus (attr "prefix_extra")
778 (const_int 1)))))
779 (plus (attr "prefix_rep")
780 (plus (attr "prefix_data16")
781 (plus (attr "length_immediate")
782 (attr "length_address")))))))
783
784 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
785 ;; `store' if there is a simple memory reference therein, or `unknown'
786 ;; if the instruction is complex.
787
788 (define_attr "memory" "none,load,store,both,unknown"
789 (cond [(eq_attr "type" "other,multi,str,lwp")
790 (const_string "unknown")
791 (eq_attr "type" "lea,fcmov,fpspc")
792 (const_string "none")
793 (eq_attr "type" "fistp,leave")
794 (const_string "both")
795 (eq_attr "type" "frndint")
796 (const_string "load")
797 (eq_attr "type" "push")
798 (if_then_else (match_operand 1 "memory_operand")
799 (const_string "both")
800 (const_string "store"))
801 (eq_attr "type" "pop")
802 (if_then_else (match_operand 0 "memory_operand")
803 (const_string "both")
804 (const_string "load"))
805 (eq_attr "type" "setcc")
806 (if_then_else (match_operand 0 "memory_operand")
807 (const_string "store")
808 (const_string "none"))
809 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
810 (if_then_else (ior (match_operand 0 "memory_operand")
811 (match_operand 1 "memory_operand"))
812 (const_string "load")
813 (const_string "none"))
814 (eq_attr "type" "ibr")
815 (if_then_else (match_operand 0 "memory_operand")
816 (const_string "load")
817 (const_string "none"))
818 (eq_attr "type" "call")
819 (if_then_else (match_operand 0 "constant_call_address_operand")
820 (const_string "none")
821 (const_string "load"))
822 (eq_attr "type" "callv")
823 (if_then_else (match_operand 1 "constant_call_address_operand")
824 (const_string "none")
825 (const_string "load"))
826 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
827 (match_operand 1 "memory_operand"))
828 (const_string "both")
829 (and (match_operand 0 "memory_operand")
830 (match_operand 1 "memory_operand"))
831 (const_string "both")
832 (match_operand 0 "memory_operand")
833 (const_string "store")
834 (match_operand 1 "memory_operand")
835 (const_string "load")
836 (and (eq_attr "type"
837 "!alu1,negnot,ishift1,rotate1,
838 imov,imovx,icmp,test,bitmanip,
839 fmov,fcmp,fsgn,
840 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
841 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
842 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
843 (match_operand 2 "memory_operand"))
844 (const_string "load")
845 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
846 (match_operand 3 "memory_operand"))
847 (const_string "load")
848 ]
849 (const_string "none")))
850
851 ;; Indicates if an instruction has both an immediate and a displacement.
852
853 (define_attr "imm_disp" "false,true,unknown"
854 (cond [(eq_attr "type" "other,multi")
855 (const_string "unknown")
856 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
857 (and (match_operand 0 "memory_displacement_operand")
858 (match_operand 1 "immediate_operand")))
859 (const_string "true")
860 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
861 (and (match_operand 0 "memory_displacement_operand")
862 (match_operand 2 "immediate_operand")))
863 (const_string "true")
864 ]
865 (const_string "false")))
866
867 ;; Indicates if an FP operation has an integer source.
868
869 (define_attr "fp_int_src" "false,true"
870 (const_string "false"))
871
872 ;; Defines rounding mode of an FP operation.
873
874 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
875 (const_string "any"))
876
877 ;; Define attribute to indicate AVX insns with partial XMM register update.
878 (define_attr "avx_partial_xmm_update" "false,true"
879 (const_string "false"))
880
881 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
882 (define_attr "use_carry" "0,1" (const_string "0"))
883
884 ;; Define attribute to indicate unaligned ssemov insns
885 (define_attr "movu" "0,1" (const_string "0"))
886
887 ;; Define attribute to limit memory address register set.
888 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
889
890 ;; Define instruction set of MMX instructions
891 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
892 (const_string "base"))
893
894 (define_attr "enabled" ""
895 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
896 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
897 (eq_attr "isa" "x64_sse2")
898 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
899 (eq_attr "isa" "x64_sse4")
900 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
901 (eq_attr "isa" "x64_sse4_noavx")
902 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
903 (eq_attr "isa" "x64_avx")
904 (symbol_ref "TARGET_64BIT && TARGET_AVX")
905 (eq_attr "isa" "x64_avx512bw")
906 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
907 (eq_attr "isa" "x64_avx512dq")
908 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
909 (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
910 (eq_attr "isa" "sse_noavx")
911 (symbol_ref "TARGET_SSE && !TARGET_AVX")
912 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
913 (eq_attr "isa" "sse2_noavx")
914 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
915 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
916 (eq_attr "isa" "sse3_noavx")
917 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
918 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
919 (eq_attr "isa" "sse4_noavx")
920 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
921 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
922 (eq_attr "isa" "avx_noavx512f")
923 (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
924 (eq_attr "isa" "avx_noavx512vl")
925 (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
926 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
927 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
928 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
929 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
930 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
931 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
932 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
933 (eq_attr "isa" "fma_or_avx512vl")
934 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
935 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
936 (eq_attr "isa" "avx512f_512")
937 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
938 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
939 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
940 (eq_attr "isa" "avx512bw_512")
941 (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
942 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
943 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
944 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
945 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
946 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
947 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
948 (eq_attr "isa" "avx512vnnivl")
949 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
950 (eq_attr "isa" "avx512fp16")
951 (symbol_ref "TARGET_AVX512FP16")
952 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
953 (eq_attr "isa" "avx512ifmavl")
954 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
955 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
956 (eq_attr "isa" "avx512bf16vl")
957 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
958 (eq_attr "isa" "vpclmulqdqvl")
959 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
960
961 (eq_attr "mmx_isa" "native")
962 (symbol_ref "!TARGET_MMX_WITH_SSE")
963 (eq_attr "mmx_isa" "sse")
964 (symbol_ref "TARGET_MMX_WITH_SSE")
965 (eq_attr "mmx_isa" "sse_noavx")
966 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
967 (eq_attr "mmx_isa" "avx")
968 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
969 ]
970 (const_int 1)))
971
972 (define_attr "preferred_for_size" "" (const_int 1))
973 (define_attr "preferred_for_speed" "" (const_int 1))
974
975 ;; Describe a user's asm statement.
976 (define_asm_attributes
977 [(set_attr "length" "128")
978 (set_attr "type" "multi")])
979
980 (define_code_iterator plusminus [plus minus])
981 (define_code_iterator plusminusmult [plus minus mult])
982 (define_code_iterator plusminusmultdiv [plus minus mult div])
983
984 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
985
986 ;; Base name for insn mnemonic.
987 (define_code_attr plusminus_mnemonic
988 [(plus "add") (ss_plus "adds") (us_plus "addus")
989 (minus "sub") (ss_minus "subs") (us_minus "subus")])
990
991 (define_code_iterator multdiv [mult div])
992
993 (define_code_attr multdiv_mnemonic
994 [(mult "mul") (div "div")])
995
996 ;; Mark commutative operators as such in constraints.
997 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
998 (minus "") (ss_minus "") (us_minus "")
999 (mult "%") (div "")])
1000
1001 ;; Mapping of max and min
1002 (define_code_iterator maxmin [smax smin umax umin])
1003
1004 ;; Mapping of signed max and min
1005 (define_code_iterator smaxmin [smax smin])
1006
1007 ;; Mapping of unsigned max and min
1008 (define_code_iterator umaxmin [umax umin])
1009
1010 ;; Base name for integer and FP insn mnemonic
1011 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1012 (umax "maxu") (umin "minu")])
1013 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1014
1015 (define_int_iterator IEEE_MAXMIN
1016 [UNSPEC_IEEE_MAX
1017 UNSPEC_IEEE_MIN])
1018
1019 (define_int_attr ieee_maxmin
1020 [(UNSPEC_IEEE_MAX "max")
1021 (UNSPEC_IEEE_MIN "min")])
1022
1023 ;; Mapping of logic operators
1024 (define_code_iterator any_logic [and ior xor])
1025 (define_code_iterator any_or [ior xor])
1026 (define_code_iterator fpint_logic [and xor])
1027
1028 ;; Base name for insn mnemonic.
1029 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1030
1031 ;; Mapping of logic-shift operators
1032 (define_code_iterator any_lshift [ashift lshiftrt])
1033
1034 ;; Mapping of shift-right operators
1035 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1036
1037 ;; Mapping of all shift operators
1038 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1039
1040 ;; Base name for insn mnemonic.
1041 (define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
1042 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1043
1044 ;; Mapping of rotate operators
1045 (define_code_iterator any_rotate [rotate rotatert])
1046
1047 ;; Base name for insn mnemonic.
1048 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1049
1050 ;; Mapping of abs neg operators
1051 (define_code_iterator absneg [abs neg])
1052
1053 ;; Mapping of abs neg operators to logic operation
1054 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1055
1056 ;; Base name for x87 insn mnemonic.
1057 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1058
1059 ;; Mapping of extend operators
1060 (define_code_iterator any_extend [sign_extend zero_extend])
1061
1062 ;; Mapping of highpart multiply operators
1063 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1064
1065 ;; Prefix for insn menmonic.
1066 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1067 (smul_highpart "i") (umul_highpart "")
1068 (div "i") (udiv "")])
1069 ;; Prefix for define_insn
1070 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1071 (smul_highpart "s") (umul_highpart "u")])
1072 (define_code_attr u [(sign_extend "") (zero_extend "u")
1073 (div "") (udiv "u")])
1074 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1075 (div "false") (udiv "true")])
1076
1077 ;; Used in signed and unsigned truncations.
1078 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1079 ;; Instruction suffix for truncations.
1080 (define_code_attr trunsuffix
1081 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1082
1083 ;; Instruction suffix for SSE sign and zero extensions.
1084 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1085
1086 ;; Used in signed and unsigned fix.
1087 (define_code_iterator any_fix [fix unsigned_fix])
1088 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1089 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1090 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1091
1092 ;; Used in signed and unsigned float.
1093 (define_code_iterator any_float [float unsigned_float])
1094 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1095 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1096 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1097
1098 ;; Base name for expression
1099 (define_code_attr insn
1100 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1101 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1102 (sign_extend "extend") (zero_extend "zero_extend")
1103 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1104 (rotate "rotl") (rotatert "rotr")
1105 (mult "mul") (div "div")])
1106
1107 ;; All integer modes.
1108 (define_mode_iterator SWI1248x [QI HI SI DI])
1109
1110 ;; All integer modes without QImode.
1111 (define_mode_iterator SWI248x [HI SI DI])
1112
1113 ;; All integer modes without QImode and HImode.
1114 (define_mode_iterator SWI48x [SI DI])
1115
1116 ;; All integer modes without SImode and DImode.
1117 (define_mode_iterator SWI12 [QI HI])
1118
1119 ;; All integer modes without DImode.
1120 (define_mode_iterator SWI124 [QI HI SI])
1121
1122 ;; All integer modes without QImode and DImode.
1123 (define_mode_iterator SWI24 [HI SI])
1124
1125 ;; Single word integer modes.
1126 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1127
1128 ;; Single word integer modes without QImode.
1129 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1130
1131 ;; Single word integer modes without QImode and HImode.
1132 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1133
1134 ;; All math-dependant single and double word integer modes.
1135 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1136 (HI "TARGET_HIMODE_MATH")
1137 SI DI (TI "TARGET_64BIT")])
1138
1139 ;; Math-dependant single word integer modes.
1140 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1141 (HI "TARGET_HIMODE_MATH")
1142 SI (DI "TARGET_64BIT")])
1143
1144 ;; Math-dependant integer modes without DImode.
1145 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1146 (HI "TARGET_HIMODE_MATH")
1147 SI])
1148
1149 ;; Math-dependant integer modes with DImode.
1150 (define_mode_iterator SWIM1248x
1151 [(QI "TARGET_QIMODE_MATH")
1152 (HI "TARGET_HIMODE_MATH")
1153 SI DI])
1154
1155 ;; Math-dependant single word integer modes without QImode.
1156 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1157 SI (DI "TARGET_64BIT")])
1158
1159 ;; Double word integer modes.
1160 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1161 (TI "TARGET_64BIT")])
1162
1163 ;; SWI and DWI together.
1164 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1165
1166 ;; SWI48 and DWI together.
1167 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1168
1169 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1170 ;; compile time constant, it is faster to use <MODE_SIZE> than
1171 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1172 ;; command line options just use GET_MODE_SIZE macro.
1173 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1174 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1175 (XF "GET_MODE_SIZE (XFmode)")
1176 (V16QI "16") (V32QI "32") (V64QI "64")
1177 (V8HI "16") (V16HI "32") (V32HI "64")
1178 (V4SI "16") (V8SI "32") (V16SI "64")
1179 (V2DI "16") (V4DI "32") (V8DI "64")
1180 (V1TI "16") (V2TI "32") (V4TI "64")
1181 (V2DF "16") (V4DF "32") (V8DF "64")
1182 (V4SF "16") (V8SF "32") (V16SF "64")
1183 (V8HF "16") (V16HF "32") (V32HF "64")
1184 (V4HF "8") (V2HF "4")
1185 (V8BF "16") (V16BF "32") (V32BF "64")
1186 (V4BF "8") (V2BF "4")])
1187
1188 ;; Double word integer modes as mode attribute.
1189 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1190 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1191
1192 ;; Half sized integer modes.
1193 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1194 (define_mode_attr half [(TI "di") (DI "si")])
1195
1196 ;; LEA mode corresponding to an integer mode
1197 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1198
1199 ;; Half mode for double word integer modes.
1200 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1201 (DI "TARGET_64BIT")])
1202
1203 ;; Instruction suffix for integer modes.
1204 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1205
1206 ;; Instruction suffix for masks.
1207 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1208
1209 ;; Pointer size prefix for integer modes (Intel asm dialect)
1210 (define_mode_attr iptrsize [(QI "BYTE")
1211 (HI "WORD")
1212 (SI "DWORD")
1213 (DI "QWORD")])
1214
1215 ;; Register class for integer modes.
1216 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1217
1218 ;; Immediate operand constraint for integer modes.
1219 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1220
1221 ;; General operand constraint for word modes.
1222 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1223
1224 ;; Memory operand constraint for word modes.
1225 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1226
1227 ;; Immediate operand constraint for double integer modes.
1228 (define_mode_attr di [(SI "nF") (DI "Wd")])
1229
1230 ;; Immediate operand constraint for shifts.
1231 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1232 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1233
1234 ;; Print register name in the specified mode.
1235 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1236
1237 ;; General operand predicate for integer modes.
1238 (define_mode_attr general_operand
1239 [(QI "general_operand")
1240 (HI "general_operand")
1241 (SI "x86_64_general_operand")
1242 (DI "x86_64_general_operand")
1243 (TI "x86_64_general_operand")])
1244
1245 ;; General operand predicate for integer modes, where for TImode
1246 ;; we need both words of the operand to be general operands.
1247 (define_mode_attr general_hilo_operand
1248 [(QI "general_operand")
1249 (HI "general_operand")
1250 (SI "x86_64_general_operand")
1251 (DI "x86_64_general_operand")
1252 (TI "x86_64_hilo_general_operand")])
1253
1254 ;; General sign extend operand predicate for integer modes,
1255 ;; which disallows VOIDmode operands and thus it is suitable
1256 ;; for use inside sign_extend.
1257 (define_mode_attr general_sext_operand
1258 [(QI "sext_operand")
1259 (HI "sext_operand")
1260 (SI "x86_64_sext_operand")
1261 (DI "x86_64_sext_operand")])
1262
1263 ;; General sign/zero extend operand predicate for integer modes.
1264 (define_mode_attr general_szext_operand
1265 [(QI "general_operand")
1266 (HI "general_operand")
1267 (SI "x86_64_szext_general_operand")
1268 (DI "x86_64_szext_general_operand")
1269 (TI "x86_64_hilo_general_operand")])
1270
1271 (define_mode_attr nonmemory_szext_operand
1272 [(QI "nonmemory_operand")
1273 (HI "nonmemory_operand")
1274 (SI "x86_64_szext_nonmemory_operand")
1275 (DI "x86_64_szext_nonmemory_operand")])
1276
1277 ;; Immediate operand predicate for integer modes.
1278 (define_mode_attr immediate_operand
1279 [(QI "immediate_operand")
1280 (HI "immediate_operand")
1281 (SI "x86_64_immediate_operand")
1282 (DI "x86_64_immediate_operand")])
1283
1284 ;; Nonmemory operand predicate for integer modes.
1285 (define_mode_attr nonmemory_operand
1286 [(QI "nonmemory_operand")
1287 (HI "nonmemory_operand")
1288 (SI "x86_64_nonmemory_operand")
1289 (DI "x86_64_nonmemory_operand")])
1290
1291 ;; Operand predicate for shifts.
1292 (define_mode_attr shift_operand
1293 [(QI "nonimmediate_operand")
1294 (HI "nonimmediate_operand")
1295 (SI "nonimmediate_operand")
1296 (DI "shiftdi_operand")
1297 (TI "register_operand")])
1298
1299 ;; Operand predicate for shift argument.
1300 (define_mode_attr shift_immediate_operand
1301 [(QI "const_1_to_31_operand")
1302 (HI "const_1_to_31_operand")
1303 (SI "const_1_to_31_operand")
1304 (DI "const_1_to_63_operand")])
1305
1306 ;; Input operand predicate for arithmetic left shifts.
1307 (define_mode_attr ashl_input_operand
1308 [(QI "nonimmediate_operand")
1309 (HI "nonimmediate_operand")
1310 (SI "nonimmediate_operand")
1311 (DI "ashldi_input_operand")
1312 (TI "reg_or_pm1_operand")])
1313
1314 ;; SSE and x87 SFmode and DFmode floating point modes
1315 (define_mode_iterator MODEF [SF DF])
1316
1317 ;; SSE floating point modes
1318 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1319
1320 ;; All x87 floating point modes
1321 (define_mode_iterator X87MODEF [SF DF XF])
1322
1323 ;; All x87 floating point modes plus HFmode
1324 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1325
1326 ;; All SSE floating point modes
1327 (define_mode_iterator SSEMODEF [HF SF DF TF])
1328 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1329
1330 ;; SSE instruction suffix for various modes
1331 (define_mode_attr ssemodesuffix
1332 [(HF "sh") (SF "ss") (DF "sd")
1333 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1334 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1335 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1336 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1337 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1338 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1339
1340 ;; SSE vector suffix for floating point modes
1341 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1342
1343 ;; SSE vector mode corresponding to a scalar mode
1344 (define_mode_attr ssevecmode
1345 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1346 (define_mode_attr ssevecmodelower
1347 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1348
1349 ;; AVX512F vector mode corresponding to a scalar mode
1350 (define_mode_attr avx512fvecmode
1351 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1352
1353 ;; Instruction suffix for REX 64bit operators.
1354 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1355 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1356
1357 ;; This mode iterator allows :P to be used for patterns that operate on
1358 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1359 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1360
1361 ;; This mode iterator allows :W to be used for patterns that operate on
1362 ;; word_mode sized quantities.
1363 (define_mode_iterator W
1364 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1365
1366 ;; This mode iterator allows :PTR to be used for patterns that operate on
1367 ;; ptr_mode sized quantities.
1368 (define_mode_iterator PTR
1369 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1370 \f
1371 ;; Scheduling descriptions
1372
1373 (include "pentium.md")
1374 (include "ppro.md")
1375 (include "k6.md")
1376 (include "athlon.md")
1377 (include "bdver1.md")
1378 (include "bdver3.md")
1379 (include "btver2.md")
1380 (include "znver.md")
1381 (include "znver4.md")
1382 (include "geode.md")
1383 (include "atom.md")
1384 (include "slm.md")
1385 (include "glm.md")
1386 (include "core2.md")
1387 (include "haswell.md")
1388 (include "lujiazui.md")
1389 (include "yongfeng.md")
1390
1391 \f
1392 ;; Operand and operator predicates and constraints
1393
1394 (include "predicates.md")
1395 (include "constraints.md")
1396
1397 \f
1398 ;; Compare and branch/compare and store instructions.
1399
1400 (define_expand "cbranch<mode>4"
1401 [(set (reg:CC FLAGS_REG)
1402 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1403 (match_operand:SWIM1248x 2 "<general_operand>")))
1404 (set (pc) (if_then_else
1405 (match_operator 0 "ordered_comparison_operator"
1406 [(reg:CC FLAGS_REG) (const_int 0)])
1407 (label_ref (match_operand 3))
1408 (pc)))]
1409 ""
1410 {
1411 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1412 operands[1] = force_reg (<MODE>mode, operands[1]);
1413 ix86_expand_branch (GET_CODE (operands[0]),
1414 operands[1], operands[2], operands[3]);
1415 DONE;
1416 })
1417
1418 (define_expand "cbranchti4"
1419 [(set (reg:CC FLAGS_REG)
1420 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1421 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1422 (set (pc) (if_then_else
1423 (match_operator 0 "ix86_timode_comparison_operator"
1424 [(reg:CC FLAGS_REG) (const_int 0)])
1425 (label_ref (match_operand 3))
1426 (pc)))]
1427 "TARGET_64BIT || TARGET_SSE4_1"
1428 {
1429 ix86_expand_branch (GET_CODE (operands[0]),
1430 operands[1], operands[2], operands[3]);
1431 DONE;
1432 })
1433
1434 (define_expand "cbranchoi4"
1435 [(set (reg:CC FLAGS_REG)
1436 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1437 (match_operand:OI 2 "nonimmediate_operand")))
1438 (set (pc) (if_then_else
1439 (match_operator 0 "bt_comparison_operator"
1440 [(reg:CC FLAGS_REG) (const_int 0)])
1441 (label_ref (match_operand 3))
1442 (pc)))]
1443 "TARGET_AVX"
1444 {
1445 ix86_expand_branch (GET_CODE (operands[0]),
1446 operands[1], operands[2], operands[3]);
1447 DONE;
1448 })
1449
1450 (define_expand "cbranchxi4"
1451 [(set (reg:CC FLAGS_REG)
1452 (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1453 (match_operand:XI 2 "nonimmediate_operand")))
1454 (set (pc) (if_then_else
1455 (match_operator 0 "bt_comparison_operator"
1456 [(reg:CC FLAGS_REG) (const_int 0)])
1457 (label_ref (match_operand 3))
1458 (pc)))]
1459 "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1460 {
1461 ix86_expand_branch (GET_CODE (operands[0]),
1462 operands[1], operands[2], operands[3]);
1463 DONE;
1464 })
1465
1466 (define_expand "cstore<mode>4"
1467 [(set (reg:CC FLAGS_REG)
1468 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1469 (match_operand:SDWIM 3 "<general_operand>")))
1470 (set (match_operand:QI 0 "register_operand")
1471 (match_operator 1 "ordered_comparison_operator"
1472 [(reg:CC FLAGS_REG) (const_int 0)]))]
1473 ""
1474 {
1475 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1476 {
1477 if (GET_CODE (operands[1]) != EQ
1478 && GET_CODE (operands[1]) != NE)
1479 FAIL;
1480 }
1481 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1482 operands[2] = force_reg (<MODE>mode, operands[2]);
1483 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1484 operands[2], operands[3]);
1485 DONE;
1486 })
1487
1488 (define_expand "@cmp<mode>_1"
1489 [(set (reg:CC FLAGS_REG)
1490 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1491 (match_operand:SWI48 1 "<general_operand>")))])
1492
1493 (define_mode_iterator SWI1248_AVX512BWDQ_64
1494 [(QI "TARGET_AVX512DQ") HI
1495 (SI "TARGET_AVX512BW")
1496 (DI "TARGET_AVX512BW && TARGET_EVEX512 && TARGET_64BIT")])
1497
1498 (define_insn "*cmp<mode>_ccz_1"
1499 [(set (reg FLAGS_REG)
1500 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1501 "nonimmediate_operand" "<r>,?m<r>,$k")
1502 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1503 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1504 "@
1505 test{<imodesuffix>}\t%0, %0
1506 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1507 kortest<mskmodesuffix>\t%0, %0"
1508 [(set_attr "type" "test,icmp,msklog")
1509 (set_attr "length_immediate" "0,1,*")
1510 (set_attr "prefix" "*,*,vex")
1511 (set_attr "mode" "<MODE>")])
1512
1513 (define_insn "*cmp<mode>_ccno_1"
1514 [(set (reg FLAGS_REG)
1515 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1516 (match_operand:SWI 1 "const0_operand")))]
1517 "ix86_match_ccmode (insn, CCNOmode)"
1518 "@
1519 test{<imodesuffix>}\t%0, %0
1520 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1521 [(set_attr "type" "test,icmp")
1522 (set_attr "length_immediate" "0,1")
1523 (set_attr "mode" "<MODE>")])
1524
1525 (define_insn "*cmp<mode>_1"
1526 [(set (reg FLAGS_REG)
1527 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1528 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1529 "ix86_match_ccmode (insn, CCmode)"
1530 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1531 [(set_attr "type" "icmp")
1532 (set_attr "mode" "<MODE>")])
1533
1534 (define_insn "*cmp<mode>_minus_1"
1535 [(set (reg FLAGS_REG)
1536 (compare
1537 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1538 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1539 (const_int 0)))]
1540 "ix86_match_ccmode (insn, CCGOCmode)"
1541 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1542 [(set_attr "type" "icmp")
1543 (set_attr "mode" "<MODE>")])
1544
1545 (define_insn "*cmpqi_ext<mode>_1"
1546 [(set (reg FLAGS_REG)
1547 (compare
1548 (match_operand:QI 0 "nonimmediate_operand" "QBn")
1549 (subreg:QI
1550 (match_operator:SWI248 2 "extract_operator"
1551 [(match_operand 1 "int248_register_operand" "Q")
1552 (const_int 8)
1553 (const_int 8)]) 0)))]
1554 "ix86_match_ccmode (insn, CCmode)"
1555 "cmp{b}\t{%h1, %0|%0, %h1}"
1556 [(set_attr "addr" "gpr8")
1557 (set_attr "type" "icmp")
1558 (set_attr "mode" "QI")])
1559
1560 (define_insn "*cmpqi_ext<mode>_2"
1561 [(set (reg FLAGS_REG)
1562 (compare
1563 (subreg:QI
1564 (match_operator:SWI248 2 "extract_operator"
1565 [(match_operand 0 "int248_register_operand" "Q")
1566 (const_int 8)
1567 (const_int 8)]) 0)
1568 (match_operand:QI 1 "const0_operand")))]
1569 "ix86_match_ccmode (insn, CCNOmode)"
1570 "test{b}\t%h0, %h0"
1571 [(set_attr "type" "test")
1572 (set_attr "length_immediate" "0")
1573 (set_attr "mode" "QI")])
1574
1575 (define_expand "cmpqi_ext_3"
1576 [(set (reg:CC FLAGS_REG)
1577 (compare:CC
1578 (subreg:QI
1579 (zero_extract:HI
1580 (match_operand:HI 0 "register_operand")
1581 (const_int 8)
1582 (const_int 8)) 0)
1583 (match_operand:QI 1 "const_int_operand")))])
1584
1585 (define_insn "*cmpqi_ext<mode>_3"
1586 [(set (reg FLAGS_REG)
1587 (compare
1588 (subreg:QI
1589 (match_operator:SWI248 2 "extract_operator"
1590 [(match_operand 0 "int248_register_operand" "Q")
1591 (const_int 8)
1592 (const_int 8)]) 0)
1593 (match_operand:QI 1 "general_operand" "QnBn")))]
1594 "ix86_match_ccmode (insn, CCmode)"
1595 "cmp{b}\t{%1, %h0|%h0, %1}"
1596 [(set_attr "addr" "gpr8")
1597 (set_attr "type" "icmp")
1598 (set_attr "mode" "QI")])
1599
1600 (define_insn "*cmpqi_ext<mode>_4"
1601 [(set (reg FLAGS_REG)
1602 (compare
1603 (subreg:QI
1604 (match_operator:SWI248 2 "extract_operator"
1605 [(match_operand 0 "int248_register_operand" "Q")
1606 (const_int 8)
1607 (const_int 8)]) 0)
1608 (subreg:QI
1609 (match_operator:SWI248 3 "extract_operator"
1610 [(match_operand 1 "int248_register_operand" "Q")
1611 (const_int 8)
1612 (const_int 8)]) 0)))]
1613 "ix86_match_ccmode (insn, CCmode)"
1614 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1615 [(set_attr "type" "icmp")
1616 (set_attr "mode" "QI")])
1617
1618 (define_insn_and_split "*cmp<dwi>_doubleword"
1619 [(set (reg:CCZ FLAGS_REG)
1620 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1621 (match_operand:<DWI> 1 "general_operand")))]
1622 "ix86_pre_reload_split ()"
1623 "#"
1624 "&& 1"
1625 [(parallel [(set (reg:CCZ FLAGS_REG)
1626 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1627 (const_int 0)))
1628 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1629 {
1630 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1631 /* Placing the SUBREG pieces in pseudos helps reload. */
1632 for (int i = 0; i < 4; i++)
1633 if (SUBREG_P (operands[i]))
1634 operands[i] = force_reg (<MODE>mode, operands[i]);
1635
1636 operands[4] = gen_reg_rtx (<MODE>mode);
1637
1638 /* Special case comparisons against -1. */
1639 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1640 {
1641 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1642 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1643 DONE;
1644 }
1645
1646 if (operands[1] == const0_rtx)
1647 emit_move_insn (operands[4], operands[0]);
1648 else if (operands[0] == const0_rtx)
1649 emit_move_insn (operands[4], operands[1]);
1650 else if (operands[1] == constm1_rtx)
1651 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1652 else if (operands[0] == constm1_rtx)
1653 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1654 else
1655 {
1656 if (CONST_SCALAR_INT_P (operands[1])
1657 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1658 operands[1] = force_reg (<MODE>mode, operands[1]);
1659 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1660 }
1661
1662 if (operands[3] == const0_rtx)
1663 operands[5] = operands[2];
1664 else if (operands[2] == const0_rtx)
1665 operands[5] = operands[3];
1666 else
1667 {
1668 operands[5] = gen_reg_rtx (<MODE>mode);
1669 if (operands[3] == constm1_rtx)
1670 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1671 else if (operands[2] == constm1_rtx)
1672 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1673 else
1674 {
1675 if (CONST_SCALAR_INT_P (operands[3])
1676 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1677 operands[3] = force_reg (<MODE>mode, operands[3]);
1678 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1679 }
1680 }
1681 })
1682
1683 ;; These implement float point compares.
1684 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1685 ;; which would allow mix and match FP modes on the compares. Which is what
1686 ;; the old patterns did, but with many more of them.
1687
1688 (define_expand "cbranchxf4"
1689 [(set (reg:CC FLAGS_REG)
1690 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1691 (match_operand:XF 2 "nonmemory_operand")))
1692 (set (pc) (if_then_else
1693 (match_operator 0 "ix86_fp_comparison_operator"
1694 [(reg:CC FLAGS_REG)
1695 (const_int 0)])
1696 (label_ref (match_operand 3))
1697 (pc)))]
1698 "TARGET_80387"
1699 {
1700 ix86_expand_branch (GET_CODE (operands[0]),
1701 operands[1], operands[2], operands[3]);
1702 DONE;
1703 })
1704
1705 (define_expand "cstorexf4"
1706 [(set (reg:CC FLAGS_REG)
1707 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1708 (match_operand:XF 3 "nonmemory_operand")))
1709 (set (match_operand:QI 0 "register_operand")
1710 (match_operator 1 "ix86_fp_comparison_operator"
1711 [(reg:CC FLAGS_REG)
1712 (const_int 0)]))]
1713 "TARGET_80387"
1714 {
1715 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1716 operands[2], operands[3]);
1717 DONE;
1718 })
1719
1720 (define_expand "cbranchhf4"
1721 [(set (reg:CC FLAGS_REG)
1722 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1723 (match_operand:HF 2 "cmp_fp_expander_operand")))
1724 (set (pc) (if_then_else
1725 (match_operator 0 "ix86_fp_comparison_operator"
1726 [(reg:CC FLAGS_REG)
1727 (const_int 0)])
1728 (label_ref (match_operand 3))
1729 (pc)))]
1730 "TARGET_AVX512FP16"
1731 {
1732 ix86_expand_branch (GET_CODE (operands[0]),
1733 operands[1], operands[2], operands[3]);
1734 DONE;
1735 })
1736
1737 (define_expand "cbranch<mode>4"
1738 [(set (reg:CC FLAGS_REG)
1739 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1740 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1741 (set (pc) (if_then_else
1742 (match_operator 0 "ix86_fp_comparison_operator"
1743 [(reg:CC FLAGS_REG)
1744 (const_int 0)])
1745 (label_ref (match_operand 3))
1746 (pc)))]
1747 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1748 {
1749 ix86_expand_branch (GET_CODE (operands[0]),
1750 operands[1], operands[2], operands[3]);
1751 DONE;
1752 })
1753
1754 (define_expand "cbranchbf4"
1755 [(set (reg:CC FLAGS_REG)
1756 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1757 (match_operand:BF 2 "cmp_fp_expander_operand")))
1758 (set (pc) (if_then_else
1759 (match_operator 0 "comparison_operator"
1760 [(reg:CC FLAGS_REG)
1761 (const_int 0)])
1762 (label_ref (match_operand 3))
1763 (pc)))]
1764 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1765 {
1766 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1767 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1768 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1769 SFmode, NULL_RTX, NULL,
1770 as_a <rtx_code_label *> (operands[3]),
1771 /* Unfortunately this isn't propagated. */
1772 profile_probability::even ());
1773 DONE;
1774 })
1775
1776 (define_expand "cstorehf4"
1777 [(set (reg:CC FLAGS_REG)
1778 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1779 (match_operand:HF 3 "cmp_fp_expander_operand")))
1780 (set (match_operand:QI 0 "register_operand")
1781 (match_operator 1 "ix86_fp_comparison_operator"
1782 [(reg:CC FLAGS_REG)
1783 (const_int 0)]))]
1784 "TARGET_AVX512FP16"
1785 {
1786 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1787 operands[2], operands[3]);
1788 DONE;
1789 })
1790
1791 (define_expand "cstorebf4"
1792 [(set (reg:CC FLAGS_REG)
1793 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1794 (match_operand:BF 3 "cmp_fp_expander_operand")))
1795 (set (match_operand:QI 0 "register_operand")
1796 (match_operator 1 "comparison_operator"
1797 [(reg:CC FLAGS_REG)
1798 (const_int 0)]))]
1799 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1800 {
1801 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1802 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1803 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1804 op1, op2, SFmode, 0, 1);
1805 if (!rtx_equal_p (res, operands[0]))
1806 emit_move_insn (operands[0], res);
1807 DONE;
1808 })
1809
1810 (define_expand "cstore<mode>4"
1811 [(set (reg:CC FLAGS_REG)
1812 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1813 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1814 (set (match_operand:QI 0 "register_operand")
1815 (match_operator 1 "ix86_fp_comparison_operator"
1816 [(reg:CC FLAGS_REG)
1817 (const_int 0)]))]
1818 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1819 {
1820 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1821 operands[2], operands[3]);
1822 DONE;
1823 })
1824
1825 (define_expand "cbranchcc4"
1826 [(set (pc) (if_then_else
1827 (match_operator 0 "comparison_operator"
1828 [(match_operand 1 "flags_reg_operand")
1829 (match_operand 2 "const0_operand")])
1830 (label_ref (match_operand 3))
1831 (pc)))]
1832 ""
1833 {
1834 ix86_expand_branch (GET_CODE (operands[0]),
1835 operands[1], operands[2], operands[3]);
1836 DONE;
1837 })
1838
1839 (define_expand "cstorecc4"
1840 [(set (match_operand:QI 0 "register_operand")
1841 (match_operator 1 "comparison_operator"
1842 [(match_operand 2 "flags_reg_operand")
1843 (match_operand 3 "const0_operand")]))]
1844 ""
1845 {
1846 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1847 operands[2], operands[3]);
1848 DONE;
1849 })
1850
1851 ;; FP compares, step 1:
1852 ;; Set the FP condition codes and move fpsr to ax.
1853
1854 ;; We may not use "#" to split and emit these
1855 ;; due to reg-stack pops killing fpsr.
1856
1857 (define_insn "*cmpxf_i387"
1858 [(set (match_operand:HI 0 "register_operand" "=a")
1859 (unspec:HI
1860 [(compare:CCFP
1861 (match_operand:XF 1 "register_operand" "f")
1862 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1863 UNSPEC_FNSTSW))]
1864 "TARGET_80387"
1865 "* return output_fp_compare (insn, operands, false, false);"
1866 [(set_attr "type" "multi")
1867 (set_attr "unit" "i387")
1868 (set_attr "mode" "XF")])
1869
1870 (define_insn "*cmp<mode>_i387"
1871 [(set (match_operand:HI 0 "register_operand" "=a")
1872 (unspec:HI
1873 [(compare:CCFP
1874 (match_operand:MODEF 1 "register_operand" "f")
1875 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1876 UNSPEC_FNSTSW))]
1877 "TARGET_80387"
1878 "* return output_fp_compare (insn, operands, false, false);"
1879 [(set_attr "type" "multi")
1880 (set_attr "unit" "i387")
1881 (set_attr "mode" "<MODE>")])
1882
1883 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1884 [(set (match_operand:HI 0 "register_operand" "=a")
1885 (unspec:HI
1886 [(compare:CCFP
1887 (match_operand:X87MODEF 1 "register_operand" "f")
1888 (float:X87MODEF
1889 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1890 UNSPEC_FNSTSW))]
1891 "TARGET_80387
1892 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1893 || optimize_function_for_size_p (cfun))"
1894 "* return output_fp_compare (insn, operands, false, false);"
1895 [(set_attr "type" "multi")
1896 (set_attr "unit" "i387")
1897 (set_attr "fp_int_src" "true")
1898 (set_attr "mode" "<SWI24:MODE>")])
1899
1900 (define_insn "*cmpu<mode>_i387"
1901 [(set (match_operand:HI 0 "register_operand" "=a")
1902 (unspec:HI
1903 [(unspec:CCFP
1904 [(compare:CCFP
1905 (match_operand:X87MODEF 1 "register_operand" "f")
1906 (match_operand:X87MODEF 2 "register_operand" "f"))]
1907 UNSPEC_NOTRAP)]
1908 UNSPEC_FNSTSW))]
1909 "TARGET_80387"
1910 "* return output_fp_compare (insn, operands, false, true);"
1911 [(set_attr "type" "multi")
1912 (set_attr "unit" "i387")
1913 (set_attr "mode" "<MODE>")])
1914
1915 ;; FP compares, step 2:
1916 ;; Get ax into flags, general case.
1917
1918 (define_insn "x86_sahf_1"
1919 [(set (reg:CC FLAGS_REG)
1920 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1921 UNSPEC_SAHF))]
1922 "TARGET_SAHF"
1923 {
1924 #ifndef HAVE_AS_IX86_SAHF
1925 if (TARGET_64BIT)
1926 return ASM_BYTE "0x9e";
1927 else
1928 #endif
1929 return "sahf";
1930 }
1931 [(set_attr "length" "1")
1932 (set_attr "athlon_decode" "vector")
1933 (set_attr "amdfam10_decode" "direct")
1934 (set_attr "bdver1_decode" "direct")
1935 (set_attr "mode" "SI")])
1936
1937 ;; Pentium Pro can do both steps in one go.
1938 ;; (these instructions set flags directly)
1939
1940 (define_subst_attr "unord" "unord_subst" "" "u")
1941 (define_subst_attr "unordered" "unord_subst" "false" "true")
1942
1943 (define_subst "unord_subst"
1944 [(set (match_operand:CCFP 0)
1945 (match_operand:CCFP 1))]
1946 ""
1947 [(set (match_dup 0)
1948 (unspec:CCFP
1949 [(match_dup 1)]
1950 UNSPEC_NOTRAP))])
1951
1952 (define_insn "*cmpi<unord>xf_i387"
1953 [(set (reg:CCFP FLAGS_REG)
1954 (compare:CCFP
1955 (match_operand:XF 0 "register_operand" "f")
1956 (match_operand:XF 1 "register_operand" "f")))]
1957 "TARGET_80387 && TARGET_CMOVE"
1958 "* return output_fp_compare (insn, operands, true, <unordered>);"
1959 [(set_attr "type" "fcmp")
1960 (set_attr "mode" "XF")
1961 (set_attr "athlon_decode" "vector")
1962 (set_attr "amdfam10_decode" "direct")
1963 (set_attr "bdver1_decode" "double")
1964 (set_attr "znver1_decode" "double")])
1965
1966 (define_insn "*cmpi<unord><MODEF:mode>"
1967 [(set (reg:CCFP FLAGS_REG)
1968 (compare:CCFP
1969 (match_operand:MODEF 0 "register_operand" "f,v")
1970 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1971 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1972 || (TARGET_80387 && TARGET_CMOVE)"
1973 "@
1974 * return output_fp_compare (insn, operands, true, <unordered>);
1975 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1976 [(set_attr "type" "fcmp,ssecomi")
1977 (set_attr "prefix" "orig,maybe_vex")
1978 (set_attr "mode" "<MODEF:MODE>")
1979 (set_attr "prefix_rep" "*,0")
1980 (set (attr "prefix_data16")
1981 (cond [(eq_attr "alternative" "0")
1982 (const_string "*")
1983 (eq_attr "mode" "DF")
1984 (const_string "1")
1985 ]
1986 (const_string "0")))
1987 (set_attr "athlon_decode" "vector")
1988 (set_attr "amdfam10_decode" "direct")
1989 (set_attr "bdver1_decode" "double")
1990 (set_attr "znver1_decode" "double")
1991 (set (attr "enabled")
1992 (if_then_else
1993 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1994 (if_then_else
1995 (eq_attr "alternative" "0")
1996 (symbol_ref "TARGET_MIX_SSE_I387")
1997 (symbol_ref "true"))
1998 (if_then_else
1999 (eq_attr "alternative" "0")
2000 (symbol_ref "true")
2001 (symbol_ref "false"))))])
2002
2003 (define_insn "*cmpi<unord>hf"
2004 [(set (reg:CCFP FLAGS_REG)
2005 (compare:CCFP
2006 (match_operand:HF 0 "register_operand" "v")
2007 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2008 "TARGET_AVX512FP16"
2009 "v<unord>comish\t{%1, %0|%0, %1}"
2010 [(set_attr "type" "ssecomi")
2011 (set_attr "prefix" "evex")
2012 (set_attr "mode" "HF")])
2013
2014 ;; Set carry flag.
2015 (define_insn "x86_stc"
2016 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2017 ""
2018 "stc"
2019 [(set_attr "length" "1")
2020 (set_attr "length_immediate" "0")
2021 (set_attr "modrm" "0")])
2022
2023 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2024 (define_peephole2
2025 [(match_scratch:QI 0 "r")
2026 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2027 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2028 [(set (match_dup 0) (const_int 1))
2029 (parallel
2030 [(set (reg:CCC FLAGS_REG)
2031 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2032 (match_dup 0)))
2033 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2034
2035 ;; Complement carry flag.
2036 (define_insn "*x86_cmc"
2037 [(set (reg:CCC FLAGS_REG)
2038 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2039 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2040 ""
2041 "cmc"
2042 [(set_attr "length" "1")
2043 (set_attr "length_immediate" "0")
2044 (set_attr "use_carry" "1")
2045 (set_attr "modrm" "0")])
2046
2047 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2048 (define_peephole2
2049 [(match_scratch:QI 0 "r")
2050 (set (reg:CCC FLAGS_REG)
2051 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2052 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2053 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2054 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2055 (parallel
2056 [(set (reg:CCC FLAGS_REG)
2057 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2058 (match_dup 0)))
2059 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2060 \f
2061 ;; Push/pop instructions.
2062
2063 (define_insn_and_split "*pushv1ti2"
2064 [(set (match_operand:V1TI 0 "push_operand" "=<")
2065 (match_operand:V1TI 1 "register_operand" "v"))]
2066 "TARGET_64BIT && TARGET_STV"
2067 "#"
2068 "&& reload_completed"
2069 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2070 (set (match_dup 0) (match_dup 1))]
2071 {
2072 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2073 /* Preserve memory attributes. */
2074 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2075 }
2076 [(set_attr "type" "multi")
2077 (set_attr "mode" "TI")])
2078
2079 (define_insn "*push<mode>2"
2080 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2081 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2082 ""
2083 "#"
2084 [(set_attr "type" "multi")
2085 (set_attr "mode" "<MODE>")])
2086
2087 (define_split
2088 [(set (match_operand:DWI 0 "push_operand")
2089 (match_operand:DWI 1 "general_gr_operand"))]
2090 "reload_completed"
2091 [(const_int 0)]
2092 "ix86_split_long_move (operands); DONE;")
2093
2094 (define_insn "*pushdi2_rex64"
2095 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2096 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2097 "TARGET_64BIT"
2098 "@
2099 push{q}\t%1
2100 #
2101 #"
2102 [(set_attr "type" "push,multi,multi")
2103 (set_attr "mode" "DI")])
2104
2105 ;; Convert impossible pushes of immediate to existing instructions.
2106 ;; First try to get scratch register and go through it. In case this
2107 ;; fails, push sign extended lower part first and then overwrite
2108 ;; upper part by 32bit move.
2109
2110 (define_peephole2
2111 [(match_scratch:DI 2 "r")
2112 (set (match_operand:DI 0 "push_operand")
2113 (match_operand:DI 1 "immediate_operand"))]
2114 "TARGET_64BIT
2115 && !symbolic_operand (operands[1], DImode)
2116 && !x86_64_immediate_operand (operands[1], DImode)"
2117 [(set (match_dup 2) (match_dup 1))
2118 (set (match_dup 0) (match_dup 2))])
2119
2120 (define_split
2121 [(set (match_operand:DI 0 "push_operand")
2122 (match_operand:DI 1 "immediate_operand"))]
2123 "TARGET_64BIT && epilogue_completed
2124 && !symbolic_operand (operands[1], DImode)
2125 && !x86_64_immediate_operand (operands[1], DImode)"
2126 [(set (match_dup 0) (match_dup 1))
2127 (set (match_dup 2) (match_dup 3))]
2128 {
2129 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2130
2131 operands[1] = gen_lowpart (DImode, operands[2]);
2132 operands[2] = gen_rtx_MEM (SImode,
2133 plus_constant (Pmode, stack_pointer_rtx, 4));
2134 })
2135
2136 ;; For TARGET_64BIT we always round up to 8 bytes.
2137 (define_insn "*pushsi2_rex64"
2138 [(set (match_operand:SI 0 "push_operand" "=X,X")
2139 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2140 "TARGET_64BIT"
2141 "@
2142 push{q}\t%q1
2143 #"
2144 [(set_attr "type" "push,multi")
2145 (set_attr "mode" "DI")])
2146
2147 (define_insn "*pushsi2"
2148 [(set (match_operand:SI 0 "push_operand" "=<,<")
2149 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2150 "!TARGET_64BIT"
2151 "@
2152 push{l}\t%1
2153 #"
2154 [(set_attr "type" "push,multi")
2155 (set_attr "mode" "SI")])
2156
2157 (define_split
2158 [(set (match_operand:SWI48DWI 0 "push_operand")
2159 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2160 "TARGET_SSE && reload_completed"
2161 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2162 (set (match_dup 0) (match_dup 1))]
2163 {
2164 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2165 /* Preserve memory attributes. */
2166 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2167 })
2168
2169 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2170 ;; "push a byte/word". But actually we use push{l,q}, which has
2171 ;; the effect of rounding the amount pushed up to a word.
2172
2173 (define_insn "*push<mode>2"
2174 [(set (match_operand:SWI12 0 "push_operand" "=X")
2175 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2176 ""
2177 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2178 [(set_attr "type" "push")
2179 (set (attr "mode")
2180 (if_then_else (match_test "TARGET_64BIT")
2181 (const_string "DI")
2182 (const_string "SI")))])
2183
2184 (define_insn "*push<mode>2_prologue"
2185 [(set (match_operand:W 0 "push_operand" "=<")
2186 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2187 (clobber (mem:BLK (scratch)))]
2188 ""
2189 "push{<imodesuffix>}\t%1"
2190 [(set_attr "type" "push")
2191 (set_attr "mode" "<MODE>")])
2192
2193 (define_insn "*pop<mode>1"
2194 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2195 (match_operand:W 1 "pop_operand" ">"))]
2196 ""
2197 "pop{<imodesuffix>}\t%0"
2198 [(set_attr "type" "pop")
2199 (set_attr "mode" "<MODE>")])
2200
2201 (define_insn "*pop<mode>1_epilogue"
2202 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2203 (match_operand:W 1 "pop_operand" ">"))
2204 (clobber (mem:BLK (scratch)))]
2205 ""
2206 "pop{<imodesuffix>}\t%0"
2207 [(set_attr "type" "pop")
2208 (set_attr "mode" "<MODE>")])
2209
2210 (define_insn "@pushfl<mode>2"
2211 [(set (match_operand:W 0 "push_operand" "=<")
2212 (unspec:W [(match_operand:CC 1 "flags_reg_operand")]
2213 UNSPEC_PUSHFL))]
2214 ""
2215 "pushf{<imodesuffix>}"
2216 [(set_attr "type" "push")
2217 (set_attr "mode" "<MODE>")])
2218
2219 (define_insn "@popfl<mode>1"
2220 [(set (match_operand:CC 0 "flags_reg_operand")
2221 (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
2222 UNSPEC_POPFL))]
2223 ""
2224 "popf{<imodesuffix>}"
2225 [(set_attr "type" "pop")
2226 (set_attr "mode" "<MODE>")])
2227
2228 \f
2229 ;; Reload patterns to support multi-word load/store
2230 ;; with non-offsetable address.
2231 (define_expand "reload_noff_store"
2232 [(parallel [(match_operand 0 "memory_operand" "=m")
2233 (match_operand 1 "register_operand" "r")
2234 (match_operand:DI 2 "register_operand" "=&r")])]
2235 "TARGET_64BIT"
2236 {
2237 rtx mem = operands[0];
2238 rtx addr = XEXP (mem, 0);
2239
2240 emit_move_insn (operands[2], addr);
2241 mem = replace_equiv_address_nv (mem, operands[2]);
2242
2243 emit_insn (gen_rtx_SET (mem, operands[1]));
2244 DONE;
2245 })
2246
2247 (define_expand "reload_noff_load"
2248 [(parallel [(match_operand 0 "register_operand" "=r")
2249 (match_operand 1 "memory_operand" "m")
2250 (match_operand:DI 2 "register_operand" "=r")])]
2251 "TARGET_64BIT"
2252 {
2253 rtx mem = operands[1];
2254 rtx addr = XEXP (mem, 0);
2255
2256 emit_move_insn (operands[2], addr);
2257 mem = replace_equiv_address_nv (mem, operands[2]);
2258
2259 emit_insn (gen_rtx_SET (operands[0], mem));
2260 DONE;
2261 })
2262
2263 ;; Move instructions.
2264
2265 (define_expand "movxi"
2266 [(set (match_operand:XI 0 "nonimmediate_operand")
2267 (match_operand:XI 1 "general_operand"))]
2268 "TARGET_AVX512F && TARGET_EVEX512"
2269 "ix86_expand_vector_move (XImode, operands); DONE;")
2270
2271 (define_expand "movoi"
2272 [(set (match_operand:OI 0 "nonimmediate_operand")
2273 (match_operand:OI 1 "general_operand"))]
2274 "TARGET_AVX"
2275 "ix86_expand_vector_move (OImode, operands); DONE;")
2276
2277 (define_expand "movti"
2278 [(set (match_operand:TI 0 "nonimmediate_operand")
2279 (match_operand:TI 1 "general_operand"))]
2280 "TARGET_64BIT || TARGET_SSE"
2281 {
2282 if (TARGET_64BIT)
2283 ix86_expand_move (TImode, operands);
2284 else
2285 ix86_expand_vector_move (TImode, operands);
2286 DONE;
2287 })
2288
2289 ;; This expands to what emit_move_complex would generate if we didn't
2290 ;; have a movti pattern. Having this avoids problems with reload on
2291 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2292 ;; to have around all the time.
2293 (define_expand "movcdi"
2294 [(set (match_operand:CDI 0 "nonimmediate_operand")
2295 (match_operand:CDI 1 "general_operand"))]
2296 ""
2297 {
2298 if (push_operand (operands[0], CDImode))
2299 emit_move_complex_push (CDImode, operands[0], operands[1]);
2300 else
2301 emit_move_complex_parts (operands[0], operands[1]);
2302 DONE;
2303 })
2304
2305 (define_expand "mov<mode>"
2306 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2307 (match_operand:SWI1248x 1 "general_operand"))]
2308 ""
2309 "ix86_expand_move (<MODE>mode, operands); DONE;")
2310
2311 (define_insn "*mov<mode>_xor"
2312 [(set (match_operand:SWI48 0 "register_operand" "=r")
2313 (match_operand:SWI48 1 "const0_operand"))
2314 (clobber (reg:CC FLAGS_REG))]
2315 "reload_completed"
2316 "xor{l}\t%k0, %k0"
2317 [(set_attr "type" "alu1")
2318 (set_attr "mode" "SI")
2319 (set_attr "length_immediate" "0")])
2320
2321 (define_insn "*mov<mode>_and"
2322 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2323 (match_operand:SWI248 1 "const0_operand"))
2324 (clobber (reg:CC FLAGS_REG))]
2325 "reload_completed"
2326 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2327 [(set_attr "type" "alu1")
2328 (set_attr "mode" "<MODE>")
2329 (set_attr "length_immediate" "1")])
2330
2331 (define_insn "*mov<mode>_or"
2332 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2333 (match_operand:SWI248 1 "constm1_operand"))
2334 (clobber (reg:CC FLAGS_REG))]
2335 "reload_completed"
2336 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2337 [(set_attr "type" "alu1")
2338 (set_attr "mode" "<MODE>")
2339 (set_attr "length_immediate" "1")])
2340
2341 (define_insn "*movxi_internal_avx512f"
2342 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2343 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2344 "TARGET_AVX512F && TARGET_EVEX512
2345 && (register_operand (operands[0], XImode)
2346 || register_operand (operands[1], XImode))"
2347 {
2348 switch (get_attr_type (insn))
2349 {
2350 case TYPE_SSELOG1:
2351 return standard_sse_constant_opcode (insn, operands);
2352
2353 case TYPE_SSEMOV:
2354 return ix86_output_ssemov (insn, operands);
2355
2356 default:
2357 gcc_unreachable ();
2358 }
2359 }
2360 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2361 (set_attr "prefix" "evex")
2362 (set_attr "mode" "XI")])
2363
2364 (define_insn "*movoi_internal_avx"
2365 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2366 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2367 "TARGET_AVX
2368 && (register_operand (operands[0], OImode)
2369 || register_operand (operands[1], OImode))"
2370 {
2371 switch (get_attr_type (insn))
2372 {
2373 case TYPE_SSELOG1:
2374 return standard_sse_constant_opcode (insn, operands);
2375
2376 case TYPE_SSEMOV:
2377 return ix86_output_ssemov (insn, operands);
2378
2379 default:
2380 gcc_unreachable ();
2381 }
2382 }
2383 [(set_attr "isa" "*,avx2,*,*")
2384 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2385 (set_attr "prefix" "vex")
2386 (set_attr "mode" "OI")])
2387
2388 (define_insn "*movti_internal"
2389 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
2390 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,jc"))]
2391 "(TARGET_64BIT
2392 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2393 || (TARGET_SSE
2394 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2395 && (register_operand (operands[0], TImode)
2396 || register_operand (operands[1], TImode)))"
2397 {
2398 switch (get_attr_type (insn))
2399 {
2400 case TYPE_MULTI:
2401 return "#";
2402
2403 case TYPE_SSELOG1:
2404 return standard_sse_constant_opcode (insn, operands);
2405
2406 case TYPE_SSEMOV:
2407 return ix86_output_ssemov (insn, operands);
2408
2409 default:
2410 gcc_unreachable ();
2411 }
2412 }
2413 [(set (attr "isa")
2414 (cond [(eq_attr "alternative" "0,1,6,7")
2415 (const_string "x64")
2416 (eq_attr "alternative" "3")
2417 (const_string "sse2")
2418 ]
2419 (const_string "*")))
2420 (set (attr "type")
2421 (cond [(eq_attr "alternative" "0,1,6,7")
2422 (const_string "multi")
2423 (eq_attr "alternative" "2,3")
2424 (const_string "sselog1")
2425 ]
2426 (const_string "ssemov")))
2427 (set (attr "prefix")
2428 (if_then_else (eq_attr "type" "sselog1,ssemov")
2429 (const_string "maybe_vex")
2430 (const_string "orig")))
2431 (set (attr "mode")
2432 (cond [(eq_attr "alternative" "0,1")
2433 (const_string "DI")
2434 (match_test "TARGET_AVX")
2435 (const_string "TI")
2436 (ior (not (match_test "TARGET_SSE2"))
2437 (match_test "optimize_function_for_size_p (cfun)"))
2438 (const_string "V4SF")
2439 (and (eq_attr "alternative" "5")
2440 (match_test "TARGET_SSE_TYPELESS_STORES"))
2441 (const_string "V4SF")
2442 ]
2443 (const_string "TI")))
2444 (set (attr "preferred_for_speed")
2445 (cond [(eq_attr "alternative" "6")
2446 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2447 (eq_attr "alternative" "7")
2448 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2449 ]
2450 (symbol_ref "true")))])
2451
2452 (define_split
2453 [(set (match_operand:TI 0 "sse_reg_operand")
2454 (match_operand:TI 1 "general_reg_operand"))]
2455 "TARGET_64BIT && TARGET_SSE4_1
2456 && reload_completed"
2457 [(set (match_dup 2)
2458 (vec_merge:V2DI
2459 (vec_duplicate:V2DI (match_dup 3))
2460 (match_dup 2)
2461 (const_int 2)))]
2462 {
2463 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2464 operands[3] = gen_highpart (DImode, operands[1]);
2465
2466 emit_move_insn (gen_lowpart (DImode, operands[0]),
2467 gen_lowpart (DImode, operands[1]));
2468 })
2469
2470 (define_insn "*movdi_internal"
2471 [(set (match_operand:DI 0 "nonimmediate_operand"
2472 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?jc,?*Yd,?r,?v,?*y,?*x,*k,*k ,*r,*m,*k")
2473 (match_operand:DI 1 "general_operand"
2474 "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,v,*Yd,jc ,?v,r ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2475 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2476 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2477 {
2478 switch (get_attr_type (insn))
2479 {
2480 case TYPE_MSKMOV:
2481 return "kmovq\t{%1, %0|%0, %1}";
2482
2483 case TYPE_MSKLOG:
2484 if (operands[1] == const0_rtx)
2485 return "kxorq\t%0, %0, %0";
2486 else if (operands[1] == constm1_rtx)
2487 return "kxnorq\t%0, %0, %0";
2488 gcc_unreachable ();
2489
2490 case TYPE_MULTI:
2491 return "#";
2492
2493 case TYPE_MMX:
2494 return "pxor\t%0, %0";
2495
2496 case TYPE_MMXMOV:
2497 /* Handle broken assemblers that require movd instead of movq. */
2498 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2499 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2500 return "movd\t{%1, %0|%0, %1}";
2501 return "movq\t{%1, %0|%0, %1}";
2502
2503 case TYPE_SSELOG1:
2504 return standard_sse_constant_opcode (insn, operands);
2505
2506 case TYPE_SSEMOV:
2507 return ix86_output_ssemov (insn, operands);
2508
2509 case TYPE_SSECVT:
2510 if (SSE_REG_P (operands[0]))
2511 return "movq2dq\t{%1, %0|%0, %1}";
2512 else
2513 return "movdq2q\t{%1, %0|%0, %1}";
2514
2515 case TYPE_LEA:
2516 return "lea{q}\t{%E1, %0|%0, %E1}";
2517
2518 case TYPE_IMOV:
2519 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2520 if (get_attr_mode (insn) == MODE_SI)
2521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2522 else if (which_alternative == 4)
2523 return "movabs{q}\t{%1, %0|%0, %1}";
2524 else if (ix86_use_lea_for_mov (insn, operands))
2525 return "lea{q}\t{%E1, %0|%0, %E1}";
2526 else
2527 return "mov{q}\t{%1, %0|%0, %1}";
2528
2529 default:
2530 gcc_unreachable ();
2531 }
2532 }
2533 [(set (attr "isa")
2534 (cond [(eq_attr "alternative" "0,1,17,18")
2535 (const_string "nox64")
2536 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2537 (const_string "x64")
2538 (eq_attr "alternative" "19,20")
2539 (const_string "x64_sse2")
2540 (eq_attr "alternative" "21,22")
2541 (const_string "sse2")
2542 ]
2543 (const_string "*")))
2544 (set (attr "type")
2545 (cond [(eq_attr "alternative" "0,1,17,18")
2546 (const_string "multi")
2547 (eq_attr "alternative" "6")
2548 (const_string "mmx")
2549 (eq_attr "alternative" "7,8,9,10,11")
2550 (const_string "mmxmov")
2551 (eq_attr "alternative" "12")
2552 (const_string "sselog1")
2553 (eq_attr "alternative" "13,14,15,16,19,20")
2554 (const_string "ssemov")
2555 (eq_attr "alternative" "21,22")
2556 (const_string "ssecvt")
2557 (eq_attr "alternative" "23,24,25,26")
2558 (const_string "mskmov")
2559 (eq_attr "alternative" "27")
2560 (const_string "msklog")
2561 (and (match_operand 0 "register_operand")
2562 (match_operand 1 "pic_32bit_operand"))
2563 (const_string "lea")
2564 ]
2565 (const_string "imov")))
2566 (set (attr "modrm")
2567 (if_then_else
2568 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2569 (const_string "0")
2570 (const_string "*")))
2571 (set (attr "length_immediate")
2572 (if_then_else
2573 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2574 (const_string "8")
2575 (const_string "*")))
2576 (set (attr "prefix_rex")
2577 (if_then_else
2578 (eq_attr "alternative" "10,11,19,20")
2579 (const_string "1")
2580 (const_string "*")))
2581 (set (attr "prefix")
2582 (if_then_else (eq_attr "type" "sselog1,ssemov")
2583 (const_string "maybe_vex")
2584 (const_string "orig")))
2585 (set (attr "prefix_data16")
2586 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2587 (const_string "1")
2588 (const_string "*")))
2589 (set (attr "mode")
2590 (cond [(eq_attr "alternative" "2")
2591 (const_string "SI")
2592 (eq_attr "alternative" "12")
2593 (cond [(match_test "TARGET_AVX")
2594 (const_string "TI")
2595 (ior (not (match_test "TARGET_SSE2"))
2596 (match_test "optimize_function_for_size_p (cfun)"))
2597 (const_string "V4SF")
2598 ]
2599 (const_string "TI"))
2600 (eq_attr "alternative" "13")
2601 (cond [(match_test "TARGET_AVX512VL")
2602 (const_string "TI")
2603 (match_test "TARGET_AVX512F")
2604 (const_string "DF")
2605 (match_test "TARGET_AVX")
2606 (const_string "TI")
2607 (ior (not (match_test "TARGET_SSE2"))
2608 (match_test "optimize_function_for_size_p (cfun)"))
2609 (const_string "V4SF")
2610 ]
2611 (const_string "TI"))
2612
2613 (and (eq_attr "alternative" "14,15,16")
2614 (not (match_test "TARGET_SSE2")))
2615 (const_string "V2SF")
2616 ]
2617 (const_string "DI")))
2618 (set (attr "preferred_for_speed")
2619 (cond [(eq_attr "alternative" "10,17,19")
2620 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2621 (eq_attr "alternative" "11,18,20")
2622 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2623 ]
2624 (symbol_ref "true")))
2625 (set (attr "enabled")
2626 (cond [(eq_attr "alternative" "15")
2627 (if_then_else
2628 (match_test "TARGET_STV && TARGET_SSE2")
2629 (symbol_ref "false")
2630 (const_string "*"))
2631 (eq_attr "alternative" "16")
2632 (if_then_else
2633 (match_test "TARGET_STV && TARGET_SSE2")
2634 (symbol_ref "true")
2635 (symbol_ref "false"))
2636 ]
2637 (const_string "*")))])
2638
2639 (define_split
2640 [(set (match_operand:<DWI> 0 "general_reg_operand")
2641 (match_operand:<DWI> 1 "sse_reg_operand"))]
2642 "TARGET_SSE4_1
2643 && reload_completed"
2644 [(set (match_dup 2)
2645 (vec_select:DWIH
2646 (match_dup 3)
2647 (parallel [(const_int 1)])))]
2648 {
2649 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2650 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2651
2652 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2653 gen_lowpart (<MODE>mode, operands[1]));
2654 })
2655
2656 (define_split
2657 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2658 (match_operand:DWI 1 "general_gr_operand"))]
2659 "reload_completed"
2660 [(const_int 0)]
2661 "ix86_split_long_move (operands); DONE;")
2662
2663 (define_split
2664 [(set (match_operand:DI 0 "sse_reg_operand")
2665 (match_operand:DI 1 "general_reg_operand"))]
2666 "!TARGET_64BIT && TARGET_SSE4_1
2667 && reload_completed"
2668 [(set (match_dup 2)
2669 (vec_merge:V4SI
2670 (vec_duplicate:V4SI (match_dup 3))
2671 (match_dup 2)
2672 (const_int 2)))]
2673 {
2674 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2675 operands[3] = gen_highpart (SImode, operands[1]);
2676
2677 emit_move_insn (gen_lowpart (SImode, operands[0]),
2678 gen_lowpart (SImode, operands[1]));
2679 })
2680
2681 ;; movabsq $0x0012345678000000, %rax is longer
2682 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2683 (define_peephole2
2684 [(set (match_operand:DI 0 "register_operand")
2685 (match_operand:DI 1 "const_int_operand"))]
2686 "TARGET_64BIT
2687 && optimize_insn_for_size_p ()
2688 && LEGACY_INT_REG_P (operands[0])
2689 && !x86_64_immediate_operand (operands[1], DImode)
2690 && !x86_64_zext_immediate_operand (operands[1], DImode)
2691 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2692 & ~(HOST_WIDE_INT) 0xffffffff)
2693 && peep2_regno_dead_p (0, FLAGS_REG)"
2694 [(set (match_dup 0) (match_dup 1))
2695 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2696 (clobber (reg:CC FLAGS_REG))])]
2697 {
2698 int shift = ctz_hwi (UINTVAL (operands[1]));
2699 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2700 operands[2] = gen_int_mode (shift, QImode);
2701 })
2702
2703 (define_insn "*movsi_internal"
2704 [(set (match_operand:SI 0 "nonimmediate_operand"
2705 "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2706 (match_operand:SI 1 "general_operand"
2707 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2708 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2709 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2710 {
2711 switch (get_attr_type (insn))
2712 {
2713 case TYPE_SSELOG1:
2714 return standard_sse_constant_opcode (insn, operands);
2715
2716 case TYPE_MSKMOV:
2717 return "kmovd\t{%1, %0|%0, %1}";
2718
2719 case TYPE_MSKLOG:
2720 if (operands[1] == const0_rtx)
2721 return "kxord\t%0, %0, %0";
2722 else if (operands[1] == constm1_rtx)
2723 return "kxnord\t%0, %0, %0";
2724 gcc_unreachable ();
2725
2726 case TYPE_SSEMOV:
2727 return ix86_output_ssemov (insn, operands);
2728
2729 case TYPE_MMX:
2730 return "pxor\t%0, %0";
2731
2732 case TYPE_MMXMOV:
2733 switch (get_attr_mode (insn))
2734 {
2735 case MODE_DI:
2736 return "movq\t{%1, %0|%0, %1}";
2737 case MODE_SI:
2738 return "movd\t{%1, %0|%0, %1}";
2739
2740 default:
2741 gcc_unreachable ();
2742 }
2743
2744 case TYPE_LEA:
2745 return "lea{l}\t{%E1, %0|%0, %E1}";
2746
2747 case TYPE_IMOV:
2748 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2749 if (ix86_use_lea_for_mov (insn, operands))
2750 return "lea{l}\t{%E1, %0|%0, %E1}";
2751 else
2752 return "mov{l}\t{%1, %0|%0, %1}";
2753
2754 default:
2755 gcc_unreachable ();
2756 }
2757 }
2758 [(set (attr "isa")
2759 (cond [(eq_attr "alternative" "12,13")
2760 (const_string "sse2")
2761 ]
2762 (const_string "*")))
2763 (set (attr "type")
2764 (cond [(eq_attr "alternative" "2")
2765 (const_string "mmx")
2766 (eq_attr "alternative" "3,4,5,6,7")
2767 (const_string "mmxmov")
2768 (eq_attr "alternative" "8")
2769 (const_string "sselog1")
2770 (eq_attr "alternative" "9,10,11,12,13")
2771 (const_string "ssemov")
2772 (eq_attr "alternative" "14,15,16")
2773 (const_string "mskmov")
2774 (eq_attr "alternative" "17")
2775 (const_string "msklog")
2776 (and (match_operand 0 "register_operand")
2777 (match_operand 1 "pic_32bit_operand"))
2778 (const_string "lea")
2779 ]
2780 (const_string "imov")))
2781 (set (attr "prefix")
2782 (if_then_else (eq_attr "type" "sselog1,ssemov")
2783 (const_string "maybe_vex")
2784 (const_string "orig")))
2785 (set (attr "prefix_data16")
2786 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2787 (const_string "1")
2788 (const_string "*")))
2789 (set (attr "mode")
2790 (cond [(eq_attr "alternative" "2,3")
2791 (const_string "DI")
2792 (eq_attr "alternative" "8")
2793 (cond [(match_test "TARGET_AVX")
2794 (const_string "TI")
2795 (ior (not (match_test "TARGET_SSE2"))
2796 (match_test "optimize_function_for_size_p (cfun)"))
2797 (const_string "V4SF")
2798 ]
2799 (const_string "TI"))
2800 (eq_attr "alternative" "9")
2801 (cond [(match_test "TARGET_AVX512VL")
2802 (const_string "TI")
2803 (match_test "TARGET_AVX512F")
2804 (const_string "SF")
2805 (match_test "TARGET_AVX")
2806 (const_string "TI")
2807 (ior (not (match_test "TARGET_SSE2"))
2808 (match_test "optimize_function_for_size_p (cfun)"))
2809 (const_string "V4SF")
2810 ]
2811 (const_string "TI"))
2812
2813 (and (eq_attr "alternative" "10,11")
2814 (not (match_test "TARGET_SSE2")))
2815 (const_string "SF")
2816 ]
2817 (const_string "SI")))
2818 (set (attr "preferred_for_speed")
2819 (cond [(eq_attr "alternative" "6,12")
2820 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2821 (eq_attr "alternative" "7,13")
2822 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2823 ]
2824 (symbol_ref "true")))])
2825
2826 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2827 (define_peephole2
2828 [(set (match_operand:SWI248 0 "general_reg_operand")
2829 (match_operand:SWI248 1 "const_int_operand"))]
2830 "optimize_insn_for_size_p () && optimize_size > 1
2831 && operands[1] != const0_rtx
2832 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2833 && !ix86_red_zone_used
2834 && REGNO (operands[0]) != SP_REG"
2835 [(set (match_dup 2) (match_dup 1))
2836 (set (match_dup 0) (match_dup 3))]
2837 {
2838 if (GET_MODE (operands[0]) != word_mode)
2839 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2840
2841 operands[2] = gen_rtx_MEM (word_mode,
2842 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2843 operands[3] = gen_rtx_MEM (word_mode,
2844 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2845 })
2846
2847 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2848 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2849 (define_peephole2
2850 [(set (match_operand:SWI248 0 "memory_operand")
2851 (match_operand:SWI248 1 "const_int_operand"))]
2852 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2853 && optimize_insn_for_size_p () && optimize_size > 1
2854 && peep2_regno_dead_p (0, FLAGS_REG)"
2855 [(parallel [(set (match_dup 0) (match_dup 1))
2856 (clobber (reg:CC FLAGS_REG))])])
2857
2858 (define_insn "*movhi_internal"
2859 [(set (match_operand:HI 0 "nonimmediate_operand"
2860 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2861 (match_operand:HI 1 "general_operand"
2862 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*x,*v"))]
2863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2865 {
2866 switch (get_attr_type (insn))
2867 {
2868 case TYPE_IMOVX:
2869 /* movzwl is faster than movw on p2 due to partial word stalls,
2870 though not as fast as an aligned movl. */
2871 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2872
2873 case TYPE_MSKMOV:
2874 switch (which_alternative)
2875 {
2876 case 4:
2877 return "kmovw\t{%k1, %0|%0, %k1}";
2878 case 6:
2879 return "kmovw\t{%1, %k0|%k0, %1}";
2880 case 5:
2881 case 7:
2882 return "kmovw\t{%1, %0|%0, %1}";
2883 default:
2884 gcc_unreachable ();
2885 }
2886
2887 case TYPE_SSEMOV:
2888 return ix86_output_ssemov (insn, operands);
2889
2890 case TYPE_SSELOG1:
2891 if (satisfies_constraint_C (operands[1]))
2892 return standard_sse_constant_opcode (insn, operands);
2893
2894 if (SSE_REG_P (operands[0]))
2895 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2896 else
2897 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2898
2899 case TYPE_MSKLOG:
2900 if (operands[1] == const0_rtx)
2901 return "kxorw\t%0, %0, %0";
2902 else if (operands[1] == constm1_rtx)
2903 return "kxnorw\t%0, %0, %0";
2904 gcc_unreachable ();
2905
2906 default:
2907 if (get_attr_mode (insn) == MODE_SI)
2908 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2909 else
2910 return "mov{w}\t{%1, %0|%0, %1}";
2911 }
2912 }
2913 [(set (attr "isa")
2914 (cond [(eq_attr "alternative" "9,10,11,12,13")
2915 (const_string "sse2")
2916 (eq_attr "alternative" "14")
2917 (const_string "sse4_noavx")
2918 (eq_attr "alternative" "15")
2919 (const_string "avx")
2920 ]
2921 (const_string "*")))
2922 (set (attr "addr")
2923 (if_then_else (eq_attr "alternative" "14")
2924 (const_string "gpr16")
2925 (const_string "*")))
2926 (set (attr "type")
2927 (cond [(eq_attr "alternative" "4,5,6,7")
2928 (const_string "mskmov")
2929 (eq_attr "alternative" "8")
2930 (const_string "msklog")
2931 (eq_attr "alternative" "13,14,15")
2932 (if_then_else (match_test "TARGET_AVX512FP16")
2933 (const_string "ssemov")
2934 (const_string "sselog1"))
2935 (eq_attr "alternative" "11")
2936 (const_string "sselog1")
2937 (eq_attr "alternative" "9,10,12")
2938 (const_string "ssemov")
2939 (match_test "optimize_function_for_size_p (cfun)")
2940 (const_string "imov")
2941 (and (eq_attr "alternative" "0")
2942 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2943 (not (match_test "TARGET_HIMODE_MATH"))))
2944 (const_string "imov")
2945 (and (eq_attr "alternative" "1,2")
2946 (match_operand:HI 1 "aligned_operand"))
2947 (const_string "imov")
2948 (and (match_test "TARGET_MOVX")
2949 (eq_attr "alternative" "0,2"))
2950 (const_string "imovx")
2951 ]
2952 (const_string "imov")))
2953 (set (attr "prefix")
2954 (cond [(eq_attr "alternative" "4,5,6,7,8")
2955 (const_string "vex")
2956 (eq_attr "alternative" "9,10,11,12,13,14,15")
2957 (const_string "maybe_evex")
2958 ]
2959 (const_string "orig")))
2960 (set (attr "mode")
2961 (cond [(eq_attr "alternative" "9,10")
2962 (if_then_else (match_test "TARGET_AVX512FP16")
2963 (const_string "HI")
2964 (const_string "SI"))
2965 (eq_attr "alternative" "13,14,15")
2966 (if_then_else (match_test "TARGET_AVX512FP16")
2967 (const_string "HI")
2968 (const_string "TI"))
2969 (eq_attr "alternative" "11")
2970 (cond [(match_test "TARGET_AVX")
2971 (const_string "TI")
2972 (ior (not (match_test "TARGET_SSE2"))
2973 (match_test "optimize_function_for_size_p (cfun)"))
2974 (const_string "V4SF")
2975 ]
2976 (const_string "TI"))
2977 (eq_attr "alternative" "12")
2978 (cond [(match_test "TARGET_AVX512VL")
2979 (const_string "TI")
2980 (match_test "TARGET_AVX512FP16")
2981 (const_string "HF")
2982 (match_test "TARGET_AVX512F")
2983 (const_string "SF")
2984 (match_test "TARGET_AVX")
2985 (const_string "TI")
2986 (ior (not (match_test "TARGET_SSE2"))
2987 (match_test "optimize_function_for_size_p (cfun)"))
2988 (const_string "V4SF")
2989 ]
2990 (const_string "TI"))
2991 (eq_attr "type" "imovx")
2992 (const_string "SI")
2993 (and (eq_attr "alternative" "1,2")
2994 (match_operand:HI 1 "aligned_operand"))
2995 (const_string "SI")
2996 (and (eq_attr "alternative" "0")
2997 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2998 (not (match_test "TARGET_HIMODE_MATH"))))
2999 (const_string "SI")
3000 ]
3001 (const_string "HI")))
3002 (set (attr "preferred_for_speed")
3003 (cond [(eq_attr "alternative" "9")
3004 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3005 (eq_attr "alternative" "10")
3006 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3007 ]
3008 (symbol_ref "true")))])
3009
3010 ;; Situation is quite tricky about when to choose full sized (SImode) move
3011 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
3012 ;; partial register dependency machines (such as AMD Athlon), where QImode
3013 ;; moves issue extra dependency and for partial register stalls machines
3014 ;; that don't use QImode patterns (and QImode move cause stall on the next
3015 ;; instruction).
3016 ;;
3017 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3018 ;; register stall machines with, where we use QImode instructions, since
3019 ;; partial register stall can be caused there. Then we use movzx.
3020
3021 (define_insn "*movqi_internal"
3022 [(set (match_operand:QI 0 "nonimmediate_operand"
3023 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3024 (match_operand:QI 1 "general_operand"
3025 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3026 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3027 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3028
3029 {
3030 char buf[128];
3031 const char *ops;
3032 const char *suffix;
3033
3034 switch (get_attr_type (insn))
3035 {
3036 case TYPE_IMOVX:
3037 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3038 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3039
3040 case TYPE_MSKMOV:
3041 switch (which_alternative)
3042 {
3043 case 9:
3044 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3045 break;
3046 case 11:
3047 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3048 break;
3049 case 12:
3050 case 13:
3051 gcc_assert (TARGET_AVX512DQ);
3052 /* FALLTHRU */
3053 case 10:
3054 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3055 break;
3056 default:
3057 gcc_unreachable ();
3058 }
3059
3060 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3061
3062 snprintf (buf, sizeof (buf), ops, suffix);
3063 output_asm_insn (buf, operands);
3064 return "";
3065
3066 case TYPE_MSKLOG:
3067 if (operands[1] == const0_rtx)
3068 {
3069 if (get_attr_mode (insn) == MODE_HI)
3070 return "kxorw\t%0, %0, %0";
3071 else
3072 return "kxorb\t%0, %0, %0";
3073 }
3074 else if (operands[1] == constm1_rtx)
3075 {
3076 gcc_assert (TARGET_AVX512DQ);
3077 return "kxnorb\t%0, %0, %0";
3078 }
3079 gcc_unreachable ();
3080
3081 default:
3082 if (get_attr_mode (insn) == MODE_SI)
3083 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3084 else
3085 return "mov{b}\t{%1, %0|%0, %1}";
3086 }
3087 }
3088 [(set (attr "isa")
3089 (cond [(eq_attr "alternative" "1,2")
3090 (const_string "x64")
3091 (eq_attr "alternative" "12,13,15")
3092 (const_string "avx512dq")
3093 ]
3094 (const_string "*")))
3095 (set (attr "type")
3096 (cond [(eq_attr "alternative" "9,10,11,12,13")
3097 (const_string "mskmov")
3098 (eq_attr "alternative" "14,15")
3099 (const_string "msklog")
3100 (and (eq_attr "alternative" "7")
3101 (not (match_operand:QI 1 "aligned_operand")))
3102 (const_string "imovx")
3103 (match_test "optimize_function_for_size_p (cfun)")
3104 (const_string "imov")
3105 (and (eq_attr "alternative" "5")
3106 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3107 (not (match_test "TARGET_QIMODE_MATH"))))
3108 (const_string "imov")
3109 (eq_attr "alternative" "5,7")
3110 (const_string "imovx")
3111 (and (match_test "TARGET_MOVX")
3112 (eq_attr "alternative" "4"))
3113 (const_string "imovx")
3114 ]
3115 (const_string "imov")))
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3118 (const_string "vex")
3119 (const_string "orig")))
3120 (set (attr "mode")
3121 (cond [(eq_attr "alternative" "5,6,7")
3122 (const_string "SI")
3123 (eq_attr "alternative" "8")
3124 (const_string "QI")
3125 (and (eq_attr "alternative" "9,10,11,14")
3126 (not (match_test "TARGET_AVX512DQ")))
3127 (const_string "HI")
3128 (eq_attr "type" "imovx")
3129 (const_string "SI")
3130 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3131 ;; ones.
3132 (and (eq_attr "type" "imov")
3133 (and (eq_attr "alternative" "3")
3134 (match_test "optimize_function_for_size_p (cfun)")))
3135 (const_string "QI")
3136 ;; For -Os, movl where one or both operands are NON_Q_REGS
3137 ;; and both are LEGACY_REGS is shorter than movb.
3138 ;; Otherwise movb and movl sizes are the same, so decide purely
3139 ;; based on speed factors.
3140 (and (eq_attr "type" "imov")
3141 (and (eq_attr "alternative" "1")
3142 (match_test "optimize_function_for_size_p (cfun)")))
3143 (const_string "SI")
3144 (and (eq_attr "type" "imov")
3145 (and (eq_attr "alternative" "0,1,2,3")
3146 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3147 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3148 (const_string "SI")
3149 ;; Avoid partial register stalls when not using QImode arithmetic
3150 (and (eq_attr "type" "imov")
3151 (and (eq_attr "alternative" "0,1,2,3")
3152 (and (match_test "TARGET_PARTIAL_REG_STALL")
3153 (not (match_test "TARGET_QIMODE_MATH")))))
3154 (const_string "SI")
3155 ]
3156 (const_string "QI")))])
3157
3158 /* Reload dislikes loading 0/-1 directly into mask registers.
3159 Try to tidy things up here. */
3160 (define_peephole2
3161 [(set (match_operand:SWI 0 "general_reg_operand")
3162 (match_operand:SWI 1 "immediate_operand"))
3163 (set (match_operand:SWI 2 "mask_reg_operand")
3164 (match_dup 0))]
3165 "peep2_reg_dead_p (2, operands[0])
3166 && (const0_operand (operands[1], <MODE>mode)
3167 || (constm1_operand (operands[1], <MODE>mode)
3168 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3169 [(set (match_dup 2) (match_dup 1))])
3170
3171 ;; Stores and loads of ax to arbitrary constant address.
3172 ;; We fake an second form of instruction to force reload to load address
3173 ;; into register when rax is not available
3174 (define_insn "*movabs<mode>_1"
3175 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3176 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3177 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3178 {
3179 /* Recover the full memory rtx. */
3180 operands[0] = SET_DEST (PATTERN (insn));
3181 switch (which_alternative)
3182 {
3183 case 0:
3184 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3185 case 1:
3186 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3187 default:
3188 gcc_unreachable ();
3189 }
3190 }
3191 [(set_attr "type" "imov")
3192 (set_attr "modrm" "0,*")
3193 (set_attr "length_address" "8,0")
3194 (set_attr "length_immediate" "0,*")
3195 (set_attr "memory" "store")
3196 (set_attr "mode" "<MODE>")])
3197
3198 (define_insn "*movabs<mode>_2"
3199 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3200 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3201 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3202 {
3203 /* Recover the full memory rtx. */
3204 operands[1] = SET_SRC (PATTERN (insn));
3205 switch (which_alternative)
3206 {
3207 case 0:
3208 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3209 case 1:
3210 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3211 default:
3212 gcc_unreachable ();
3213 }
3214 }
3215 [(set_attr "type" "imov")
3216 (set_attr "modrm" "0,*")
3217 (set_attr "length_address" "8,0")
3218 (set_attr "length_immediate" "0")
3219 (set_attr "memory" "load")
3220 (set_attr "mode" "<MODE>")])
3221
3222 (define_insn "swap<mode>"
3223 [(set (match_operand:SWI48 0 "register_operand" "+r")
3224 (match_operand:SWI48 1 "register_operand" "+r"))
3225 (set (match_dup 1)
3226 (match_dup 0))]
3227 ""
3228 "xchg{<imodesuffix>}\t%1, %0"
3229 [(set_attr "type" "imov")
3230 (set_attr "mode" "<MODE>")
3231 (set_attr "pent_pair" "np")
3232 (set_attr "athlon_decode" "vector")
3233 (set_attr "amdfam10_decode" "double")
3234 (set_attr "bdver1_decode" "double")])
3235
3236 (define_insn "*swap<mode>"
3237 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3238 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3239 (set (match_dup 1)
3240 (match_dup 0))]
3241 ""
3242 "@
3243 xchg{<imodesuffix>}\t%1, %0
3244 xchg{l}\t%k1, %k0"
3245 [(set_attr "type" "imov")
3246 (set_attr "mode" "<MODE>,SI")
3247 (set (attr "preferred_for_size")
3248 (cond [(eq_attr "alternative" "0")
3249 (symbol_ref "false")]
3250 (symbol_ref "true")))
3251 ;; Potential partial reg stall on alternative 1.
3252 (set (attr "preferred_for_speed")
3253 (cond [(eq_attr "alternative" "1")
3254 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3255 (symbol_ref "true")))
3256 (set_attr "pent_pair" "np")
3257 (set_attr "athlon_decode" "vector")
3258 (set_attr "amdfam10_decode" "double")
3259 (set_attr "bdver1_decode" "double")])
3260
3261 (define_peephole2
3262 [(set (match_operand:SWI 0 "general_reg_operand")
3263 (match_operand:SWI 1 "general_reg_operand"))
3264 (set (match_dup 1)
3265 (match_operand:SWI 2 "general_reg_operand"))
3266 (set (match_dup 2) (match_dup 0))]
3267 "peep2_reg_dead_p (3, operands[0])
3268 && optimize_insn_for_size_p ()"
3269 [(parallel [(set (match_dup 1) (match_dup 2))
3270 (set (match_dup 2) (match_dup 1))])])
3271
3272 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3273 (define_peephole2
3274 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3275 (match_operand:SWI 1 "general_reg_operand"))
3276 (set (match_dup 1) (match_dup 0))])]
3277 "((REGNO (operands[0]) != AX_REG
3278 && REGNO (operands[1]) != AX_REG)
3279 || optimize_size < 2
3280 || !optimize_insn_for_size_p ())
3281 && peep2_reg_dead_p (1, operands[0])"
3282 [(set (match_dup 1) (match_dup 0))])
3283
3284 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3285 (define_peephole2
3286 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3287 (match_operand:SWI 1 "general_reg_operand"))
3288 (set (match_dup 1) (match_dup 0))])]
3289 "((REGNO (operands[0]) != AX_REG
3290 && REGNO (operands[1]) != AX_REG)
3291 || optimize_size < 2
3292 || !optimize_insn_for_size_p ())
3293 && peep2_reg_dead_p (1, operands[1])"
3294 [(set (match_dup 0) (match_dup 1))])
3295
3296 ;; Convert moves to/from AX_REG into xchg with -Oz.
3297 (define_peephole2
3298 [(set (match_operand:SWI48 0 "general_reg_operand")
3299 (match_operand:SWI48 1 "general_reg_operand"))]
3300 "optimize_size > 1
3301 && ((REGNO (operands[0]) == AX_REG)
3302 != (REGNO (operands[1]) == AX_REG))
3303 && optimize_insn_for_size_p ()
3304 && peep2_reg_dead_p (1, operands[1])"
3305 [(parallel [(set (match_dup 0) (match_dup 1))
3306 (set (match_dup 1) (match_dup 0))])])
3307
3308 (define_expand "movstrict<mode>"
3309 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3310 (match_operand:SWI12 1 "general_operand"))]
3311 ""
3312 {
3313 gcc_assert (SUBREG_P (operands[0]));
3314 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3315 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3316 FAIL;
3317 })
3318
3319 (define_insn "*movstrict<mode>_1"
3320 [(set (strict_low_part
3321 (match_operand:SWI12 0 "register_operand" "+<r>"))
3322 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3323 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3324 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3325 [(set_attr "type" "imov")
3326 (set_attr "mode" "<MODE>")])
3327
3328 (define_insn "*movstrict<mode>_xor"
3329 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3330 (match_operand:SWI12 1 "const0_operand"))
3331 (clobber (reg:CC FLAGS_REG))]
3332 "reload_completed"
3333 "xor{<imodesuffix>}\t%0, %0"
3334 [(set_attr "type" "alu1")
3335 (set_attr "mode" "<MODE>")
3336 (set_attr "length_immediate" "0")])
3337
3338 (define_expand "extv<mode>"
3339 [(set (match_operand:SWI24 0 "register_operand")
3340 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3341 (match_operand:QI 2 "const_int_operand")
3342 (match_operand:QI 3 "const_int_operand")))]
3343 ""
3344 {
3345 /* Handle extractions from %ah et al. */
3346 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3347 FAIL;
3348
3349 unsigned int regno = reg_or_subregno (operands[1]);
3350
3351 /* Be careful to expand only with registers having upper parts. */
3352 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3353 operands[1] = copy_to_reg (operands[1]);
3354 })
3355
3356 (define_insn "*extv<mode>"
3357 [(set (match_operand:SWI24 0 "register_operand" "=R")
3358 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3359 (const_int 8)
3360 (const_int 8)))]
3361 ""
3362 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3363 [(set_attr "type" "imovx")
3364 (set_attr "mode" "SI")])
3365
3366 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3367 (define_insn_and_split "*extv<mode>_1_0"
3368 [(set (match_operand:SWI48 0 "register_operand" "=r")
3369 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3370 (const_int 1)
3371 (const_int 0)))
3372 (clobber (reg:CC FLAGS_REG))]
3373 ""
3374 "#"
3375 ""
3376 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3377 (clobber (reg:CC FLAGS_REG))])
3378 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3379 (clobber (reg:CC FLAGS_REG))])])
3380
3381 (define_expand "extzv<mode>"
3382 [(set (match_operand:SWI248 0 "register_operand")
3383 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3384 (match_operand:QI 2 "const_int_operand")
3385 (match_operand:QI 3 "const_int_operand")))]
3386 ""
3387 {
3388 if (ix86_expand_pextr (operands))
3389 DONE;
3390
3391 /* Handle extractions from %ah et al. */
3392 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3393 FAIL;
3394
3395 unsigned int regno = reg_or_subregno (operands[1]);
3396
3397 /* Be careful to expand only with registers having upper parts. */
3398 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3399 operands[1] = copy_to_reg (operands[1]);
3400 })
3401
3402 (define_insn "*extzv<mode>"
3403 [(set (match_operand:SWI248 0 "register_operand" "=R")
3404 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3405 (const_int 8)
3406 (const_int 8)))]
3407 ""
3408 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3409 [(set_attr "type" "imovx")
3410 (set_attr "mode" "SI")])
3411
3412 (define_insn "*extzvqi"
3413 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3414 (subreg:QI
3415 (match_operator:SWI248 2 "extract_operator"
3416 [(match_operand 1 "int248_register_operand" "Q,Q")
3417 (const_int 8)
3418 (const_int 8)]) 0))]
3419 ""
3420 {
3421 switch (get_attr_type (insn))
3422 {
3423 case TYPE_IMOVX:
3424 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3425 default:
3426 return "mov{b}\t{%h1, %0|%0, %h1}";
3427 }
3428 }
3429 [(set_attr "addr" "gpr8,*")
3430 (set (attr "type")
3431 (if_then_else (and (match_operand:QI 0 "register_operand")
3432 (ior (not (match_operand:QI 0 "QIreg_operand"))
3433 (match_test "TARGET_MOVX")))
3434 (const_string "imovx")
3435 (const_string "imov")))
3436 (set (attr "mode")
3437 (if_then_else (eq_attr "type" "imovx")
3438 (const_string "SI")
3439 (const_string "QI")))])
3440
3441 (define_expand "insv<mode>"
3442 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3443 (match_operand:QI 1 "const_int_operand")
3444 (match_operand:QI 2 "const_int_operand"))
3445 (match_operand:SWI248 3 "register_operand"))]
3446 ""
3447 {
3448 rtx dst;
3449
3450 if (ix86_expand_pinsr (operands))
3451 DONE;
3452
3453 /* Handle insertions to %ah et al. */
3454 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3455 FAIL;
3456
3457 unsigned int regno = reg_or_subregno (operands[0]);
3458
3459 /* Be careful to expand only with registers having upper parts. */
3460 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3461 dst = copy_to_reg (operands[0]);
3462 else
3463 dst = operands[0];
3464
3465 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3466
3467 /* Fix up the destination if needed. */
3468 if (dst != operands[0])
3469 emit_move_insn (operands[0], dst);
3470
3471 DONE;
3472 })
3473
3474 (define_insn "@insv<mode>_1"
3475 [(set (zero_extract:SWI248
3476 (match_operand 0 "int248_register_operand" "+Q")
3477 (const_int 8)
3478 (const_int 8))
3479 (match_operand:SWI248 1 "general_operand" "QnBn"))]
3480 ""
3481 {
3482 if (CONST_INT_P (operands[1]))
3483 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3484 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3485 }
3486 [(set_attr "addr" "gpr8")
3487 (set_attr "type" "imov")
3488 (set_attr "mode" "QI")])
3489
3490 (define_insn "*insvqi_1"
3491 [(set (zero_extract:SWI248
3492 (match_operand 0 "int248_register_operand" "+Q")
3493 (const_int 8)
3494 (const_int 8))
3495 (subreg:SWI248
3496 (match_operand:QI 1 "general_operand" "QnBn") 0))]
3497 ""
3498 "mov{b}\t{%1, %h0|%h0, %1}"
3499 [(set_attr "addr" "gpr8")
3500 (set_attr "type" "imov")
3501 (set_attr "mode" "QI")])
3502
3503 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3504 (define_peephole2
3505 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3506 (const_int 0))
3507 (clobber (reg:CC FLAGS_REG))])
3508 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3509 (const_int 8)
3510 (const_int 8))
3511 (const_int 0))]
3512 "REGNO (operands[0]) == REGNO (operands[1])"
3513 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3514 (const_int 0))
3515 (clobber (reg:CC FLAGS_REG))])])
3516
3517 ;; Combine movl followed by movb.
3518 (define_peephole2
3519 [(set (match_operand:SWI48 0 "general_reg_operand")
3520 (match_operand:SWI48 1 "const_int_operand"))
3521 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3522 (const_int 8)
3523 (const_int 8))
3524 (match_operand:SWI248 3 "const_int_operand"))]
3525 "REGNO (operands[0]) == REGNO (operands[2])"
3526 [(set (match_operand:SWI48 0 "general_reg_operand")
3527 (match_dup 4))]
3528 {
3529 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3530 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3531 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3532 })
3533
3534 (define_insn "*insvqi_2"
3535 [(set (zero_extract:SWI248
3536 (match_operand 0 "int248_register_operand" "+Q")
3537 (const_int 8)
3538 (const_int 8))
3539 (match_operator:SWI248 2 "extract_operator"
3540 [(match_operand 1 "int248_register_operand" "Q")
3541 (const_int 8)
3542 (const_int 8)]))]
3543 ""
3544 "mov{b}\t{%h1, %h0|%h0, %h1}"
3545 [(set_attr "type" "imov")
3546 (set_attr "mode" "QI")])
3547
3548 (define_insn "*insvqi_3"
3549 [(set (zero_extract:SWI248
3550 (match_operand 0 "int248_register_operand" "+Q")
3551 (const_int 8)
3552 (const_int 8))
3553 (any_shiftrt:SWI248
3554 (match_operand:SWI248 1 "register_operand" "Q")
3555 (const_int 8)))]
3556 ""
3557 "mov{b}\t{%h1, %h0|%h0, %h1}"
3558 [(set_attr "type" "imov")
3559 (set_attr "mode" "QI")])
3560
3561 (define_code_iterator any_or_plus [plus ior xor])
3562
3563 (define_insn_and_split "*insvti_highpart_1"
3564 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3565 (any_or_plus:TI
3566 (and:TI
3567 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3568 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3569 (ashift:TI
3570 (zero_extend:TI
3571 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3572 (const_int 64))))]
3573 "TARGET_64BIT
3574 && CONST_WIDE_INT_P (operands[3])
3575 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3576 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3577 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3578 "#"
3579 "&& reload_completed"
3580 [(const_int 0)]
3581 {
3582 operands[4] = gen_lowpart (DImode, operands[1]);
3583 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3584 DONE;
3585 })
3586
3587 (define_insn_and_split "*insvti_lowpart_1"
3588 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3589 (any_or_plus:TI
3590 (and:TI
3591 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3592 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3593 (zero_extend:TI
3594 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3595 "TARGET_64BIT
3596 && CONST_WIDE_INT_P (operands[3])
3597 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3598 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3599 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3600 "#"
3601 "&& reload_completed"
3602 [(const_int 0)]
3603 {
3604 operands[4] = gen_highpart (DImode, operands[1]);
3605 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3606 DONE;
3607 })
3608
3609 (define_insn_and_split "*insvdi_lowpart_1"
3610 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3611 (any_or_plus:DI
3612 (and:DI
3613 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3614 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3615 (zero_extend:DI
3616 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3617 "!TARGET_64BIT
3618 && CONST_INT_P (operands[3])
3619 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3620 "#"
3621 "&& reload_completed"
3622 [(const_int 0)]
3623 {
3624 operands[4] = gen_highpart (SImode, operands[1]);
3625 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3626 DONE;
3627 })
3628 \f
3629 ;; Floating point push instructions.
3630
3631 (define_insn "*pushtf"
3632 [(set (match_operand:TF 0 "push_operand" "=<,<")
3633 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3634 "TARGET_64BIT || TARGET_SSE"
3635 {
3636 /* This insn should be already split before reg-stack. */
3637 return "#";
3638 }
3639 [(set_attr "isa" "*,x64")
3640 (set_attr "type" "multi")
3641 (set_attr "unit" "sse,*")
3642 (set_attr "mode" "TF,DI")])
3643
3644 ;; %%% Kill this when call knows how to work this out.
3645 (define_split
3646 [(set (match_operand:TF 0 "push_operand")
3647 (match_operand:TF 1 "sse_reg_operand"))]
3648 "TARGET_SSE && reload_completed"
3649 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3650 (set (match_dup 0) (match_dup 1))]
3651 {
3652 /* Preserve memory attributes. */
3653 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3654 })
3655
3656 (define_insn "*pushxf"
3657 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3658 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3659 ""
3660 {
3661 /* This insn should be already split before reg-stack. */
3662 return "#";
3663 }
3664 [(set_attr "isa" "*,*,*,nox64,x64")
3665 (set_attr "type" "multi")
3666 (set_attr "unit" "i387,*,*,*,*")
3667 (set (attr "mode")
3668 (cond [(eq_attr "alternative" "1,2,3,4")
3669 (if_then_else (match_test "TARGET_64BIT")
3670 (const_string "DI")
3671 (const_string "SI"))
3672 ]
3673 (const_string "XF")))
3674 (set (attr "preferred_for_size")
3675 (cond [(eq_attr "alternative" "1")
3676 (symbol_ref "false")]
3677 (symbol_ref "true")))])
3678
3679 ;; %%% Kill this when call knows how to work this out.
3680 (define_split
3681 [(set (match_operand:XF 0 "push_operand")
3682 (match_operand:XF 1 "fp_register_operand"))]
3683 "reload_completed"
3684 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3685 (set (match_dup 0) (match_dup 1))]
3686 {
3687 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3688 /* Preserve memory attributes. */
3689 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3690 })
3691
3692 (define_insn "*pushdf"
3693 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3694 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3695 ""
3696 {
3697 /* This insn should be already split before reg-stack. */
3698 return "#";
3699 }
3700 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3701 (set_attr "type" "multi")
3702 (set_attr "unit" "i387,*,*,*,*,sse")
3703 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3704 (set (attr "preferred_for_size")
3705 (cond [(eq_attr "alternative" "1")
3706 (symbol_ref "false")]
3707 (symbol_ref "true")))
3708 (set (attr "preferred_for_speed")
3709 (cond [(eq_attr "alternative" "1")
3710 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3711 (symbol_ref "true")))])
3712
3713 ;; %%% Kill this when call knows how to work this out.
3714 (define_split
3715 [(set (match_operand:DF 0 "push_operand")
3716 (match_operand:DF 1 "any_fp_register_operand"))]
3717 "reload_completed"
3718 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3719 (set (match_dup 0) (match_dup 1))]
3720 {
3721 /* Preserve memory attributes. */
3722 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3723 })
3724
3725 (define_mode_iterator HFBF [HF BF])
3726
3727 (define_insn "*push<mode>_rex64"
3728 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3729 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3730 "TARGET_64BIT"
3731 {
3732 /* Anything else should be already split before reg-stack. */
3733 gcc_assert (which_alternative == 0);
3734 return "push{q}\t%q1";
3735 }
3736 [(set_attr "isa" "*,sse4")
3737 (set_attr "type" "push,multi")
3738 (set_attr "mode" "DI,TI")])
3739
3740 (define_insn "*push<mode>"
3741 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3742 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3743 "!TARGET_64BIT"
3744 {
3745 /* Anything else should be already split before reg-stack. */
3746 gcc_assert (which_alternative == 0);
3747 return "push{l}\t%k1";
3748 }
3749 [(set_attr "isa" "*,sse4")
3750 (set_attr "type" "push,multi")
3751 (set_attr "mode" "SI,TI")])
3752
3753 (define_insn "push2_di"
3754 [(set (match_operand:TI 0 "push_operand" "=<")
3755 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3756 (match_operand:DI 2 "register_operand" "r")]
3757 UNSPEC_APXPUSH2))]
3758 "TARGET_APX_PUSH2POP2"
3759 "push2\t%1, %2"
3760 [(set_attr "mode" "TI")
3761 (set_attr "type" "multi")
3762 (set_attr "prefix" "evex")])
3763
3764 (define_insn "pop2_di"
3765 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3766 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3767 UNSPEC_APXPOP2_LOW))
3768 (set (match_operand:DI 2 "register_operand" "=r")
3769 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3770 "TARGET_APX_PUSH2POP2"
3771 "pop2\t%0, %2"
3772 [(set_attr "mode" "TI")
3773 (set_attr "prefix" "evex")])
3774
3775 (define_insn "*pushsf_rex64"
3776 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3777 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3778 "TARGET_64BIT"
3779 {
3780 /* Anything else should be already split before reg-stack. */
3781 if (which_alternative != 1)
3782 return "#";
3783 return "push{q}\t%q1";
3784 }
3785 [(set_attr "type" "multi,push,multi")
3786 (set_attr "unit" "i387,*,*")
3787 (set_attr "mode" "SF,DI,SF")])
3788
3789 (define_insn "*pushsf"
3790 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3791 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3792 "!TARGET_64BIT"
3793 {
3794 /* Anything else should be already split before reg-stack. */
3795 if (which_alternative != 1)
3796 return "#";
3797 return "push{l}\t%1";
3798 }
3799 [(set_attr "type" "multi,push,multi")
3800 (set_attr "unit" "i387,*,*")
3801 (set_attr "mode" "SF,SI,SF")])
3802
3803 (define_mode_iterator MODESH [SF HF BF])
3804 ;; %%% Kill this when call knows how to work this out.
3805 (define_split
3806 [(set (match_operand:MODESH 0 "push_operand")
3807 (match_operand:MODESH 1 "any_fp_register_operand"))]
3808 "reload_completed"
3809 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3810 (set (match_dup 0) (match_dup 1))]
3811 {
3812 rtx op = XEXP (operands[0], 0);
3813 if (GET_CODE (op) == PRE_DEC)
3814 {
3815 gcc_assert (!TARGET_64BIT);
3816 op = GEN_INT (-4);
3817 }
3818 else
3819 {
3820 op = XEXP (XEXP (op, 1), 1);
3821 gcc_assert (CONST_INT_P (op));
3822 }
3823 operands[2] = op;
3824 /* Preserve memory attributes. */
3825 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3826 })
3827
3828 (define_split
3829 [(set (match_operand:SF 0 "push_operand")
3830 (match_operand:SF 1 "memory_operand"))]
3831 "reload_completed
3832 && find_constant_src (insn)"
3833 [(set (match_dup 0) (match_dup 2))]
3834 "operands[2] = find_constant_src (curr_insn);")
3835
3836 (define_split
3837 [(set (match_operand 0 "push_operand")
3838 (match_operand 1 "general_gr_operand"))]
3839 "reload_completed
3840 && (GET_MODE (operands[0]) == TFmode
3841 || GET_MODE (operands[0]) == XFmode
3842 || GET_MODE (operands[0]) == DFmode)"
3843 [(const_int 0)]
3844 "ix86_split_long_move (operands); DONE;")
3845 \f
3846 ;; Floating point move instructions.
3847
3848 (define_expand "movtf"
3849 [(set (match_operand:TF 0 "nonimmediate_operand")
3850 (match_operand:TF 1 "nonimmediate_operand"))]
3851 "TARGET_64BIT || TARGET_SSE"
3852 "ix86_expand_move (TFmode, operands); DONE;")
3853
3854 (define_expand "mov<mode>"
3855 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3856 (match_operand:X87MODEFH 1 "general_operand"))]
3857 ""
3858 "ix86_expand_move (<MODE>mode, operands); DONE;")
3859
3860 (define_insn "*movtf_internal"
3861 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3862 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3863 "(TARGET_64BIT || TARGET_SSE)
3864 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3865 && (lra_in_progress || reload_completed
3866 || !CONST_DOUBLE_P (operands[1])
3867 || (standard_sse_constant_p (operands[1], TFmode) == 1
3868 && !memory_operand (operands[0], TFmode))
3869 || (!TARGET_MEMORY_MISMATCH_STALL
3870 && memory_operand (operands[0], TFmode)))"
3871 {
3872 switch (get_attr_type (insn))
3873 {
3874 case TYPE_SSELOG1:
3875 return standard_sse_constant_opcode (insn, operands);
3876
3877 case TYPE_SSEMOV:
3878 return ix86_output_ssemov (insn, operands);
3879
3880 case TYPE_MULTI:
3881 return "#";
3882
3883 default:
3884 gcc_unreachable ();
3885 }
3886 }
3887 [(set_attr "isa" "*,*,*,x64,x64")
3888 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3889 (set (attr "prefix")
3890 (if_then_else (eq_attr "type" "sselog1,ssemov")
3891 (const_string "maybe_vex")
3892 (const_string "orig")))
3893 (set (attr "mode")
3894 (cond [(eq_attr "alternative" "3,4")
3895 (const_string "DI")
3896 (match_test "TARGET_AVX")
3897 (const_string "TI")
3898 (ior (not (match_test "TARGET_SSE2"))
3899 (match_test "optimize_function_for_size_p (cfun)"))
3900 (const_string "V4SF")
3901 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3902 (const_string "V4SF")
3903 (and (eq_attr "alternative" "2")
3904 (match_test "TARGET_SSE_TYPELESS_STORES"))
3905 (const_string "V4SF")
3906 ]
3907 (const_string "TI")))])
3908
3909 (define_split
3910 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3911 (match_operand:TF 1 "general_gr_operand"))]
3912 "reload_completed"
3913 [(const_int 0)]
3914 "ix86_split_long_move (operands); DONE;")
3915
3916 ;; Possible store forwarding (partial memory) stall
3917 ;; in alternatives 4, 6, 7 and 8.
3918 (define_insn "*movxf_internal"
3919 [(set (match_operand:XF 0 "nonimmediate_operand"
3920 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3921 (match_operand:XF 1 "general_operand"
3922 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3923 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3924 && (lra_in_progress || reload_completed
3925 || !CONST_DOUBLE_P (operands[1])
3926 || ((optimize_function_for_size_p (cfun)
3927 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3928 && standard_80387_constant_p (operands[1]) > 0
3929 && !memory_operand (operands[0], XFmode))
3930 || (!TARGET_MEMORY_MISMATCH_STALL
3931 && memory_operand (operands[0], XFmode))
3932 || !TARGET_HARD_XF_REGS)"
3933 {
3934 switch (get_attr_type (insn))
3935 {
3936 case TYPE_FMOV:
3937 if (which_alternative == 2)
3938 return standard_80387_constant_opcode (operands[1]);
3939 return output_387_reg_move (insn, operands);
3940
3941 case TYPE_MULTI:
3942 return "#";
3943
3944 default:
3945 gcc_unreachable ();
3946 }
3947 }
3948 [(set (attr "isa")
3949 (cond [(eq_attr "alternative" "7,10")
3950 (const_string "nox64")
3951 (eq_attr "alternative" "8,11")
3952 (const_string "x64")
3953 ]
3954 (const_string "*")))
3955 (set (attr "type")
3956 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3957 (const_string "multi")
3958 ]
3959 (const_string "fmov")))
3960 (set (attr "mode")
3961 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3962 (if_then_else (match_test "TARGET_64BIT")
3963 (const_string "DI")
3964 (const_string "SI"))
3965 ]
3966 (const_string "XF")))
3967 (set (attr "preferred_for_size")
3968 (cond [(eq_attr "alternative" "3,4")
3969 (symbol_ref "false")]
3970 (symbol_ref "true")))
3971 (set (attr "enabled")
3972 (cond [(eq_attr "alternative" "9,10,11")
3973 (if_then_else
3974 (match_test "TARGET_HARD_XF_REGS")
3975 (symbol_ref "false")
3976 (const_string "*"))
3977 (not (match_test "TARGET_HARD_XF_REGS"))
3978 (symbol_ref "false")
3979 ]
3980 (const_string "*")))])
3981
3982 (define_split
3983 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3984 (match_operand:XF 1 "general_gr_operand"))]
3985 "reload_completed"
3986 [(const_int 0)]
3987 "ix86_split_long_move (operands); DONE;")
3988
3989 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3990 (define_insn "*movdf_internal"
3991 [(set (match_operand:DF 0 "nonimmediate_operand"
3992 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,Yv,v,v,m,*x,*x,*x,m ,?r,?v,r ,o ,r ,m")
3993 (match_operand:DF 1 "general_operand"
3994 "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"))]
3995 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3996 && (lra_in_progress || reload_completed
3997 || !CONST_DOUBLE_P (operands[1])
3998 || ((optimize_function_for_size_p (cfun)
3999 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4000 && IS_STACK_MODE (DFmode)
4001 && standard_80387_constant_p (operands[1]) > 0
4002 && !memory_operand (operands[0], DFmode))
4003 || (TARGET_SSE2 && TARGET_SSE_MATH
4004 && standard_sse_constant_p (operands[1], DFmode) == 1
4005 && !memory_operand (operands[0], DFmode))
4006 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4007 && memory_operand (operands[0], DFmode))
4008 || !TARGET_HARD_DF_REGS)"
4009 {
4010 switch (get_attr_type (insn))
4011 {
4012 case TYPE_FMOV:
4013 if (which_alternative == 2)
4014 return standard_80387_constant_opcode (operands[1]);
4015 return output_387_reg_move (insn, operands);
4016
4017 case TYPE_MULTI:
4018 return "#";
4019
4020 case TYPE_IMOV:
4021 if (get_attr_mode (insn) == MODE_SI)
4022 return "mov{l}\t{%1, %k0|%k0, %1}";
4023 else if (which_alternative == 11)
4024 return "movabs{q}\t{%1, %0|%0, %1}";
4025 else
4026 return "mov{q}\t{%1, %0|%0, %1}";
4027
4028 case TYPE_SSELOG1:
4029 return standard_sse_constant_opcode (insn, operands);
4030
4031 case TYPE_SSEMOV:
4032 return ix86_output_ssemov (insn, operands);
4033
4034 default:
4035 gcc_unreachable ();
4036 }
4037 }
4038 [(set (attr "isa")
4039 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4040 (const_string "nox64")
4041 (eq_attr "alternative" "8,9,10,11,24,25")
4042 (const_string "x64")
4043 (eq_attr "alternative" "12,13,14,15")
4044 (const_string "sse2")
4045 (eq_attr "alternative" "20,21")
4046 (const_string "x64_sse2")
4047 ]
4048 (const_string "*")))
4049 (set (attr "type")
4050 (cond [(eq_attr "alternative" "0,1,2")
4051 (const_string "fmov")
4052 (eq_attr "alternative" "3,4,5,6,7,22,23")
4053 (const_string "multi")
4054 (eq_attr "alternative" "8,9,10,11,24,25")
4055 (const_string "imov")
4056 (eq_attr "alternative" "12,16")
4057 (const_string "sselog1")
4058 ]
4059 (const_string "ssemov")))
4060 (set (attr "modrm")
4061 (if_then_else (eq_attr "alternative" "11")
4062 (const_string "0")
4063 (const_string "*")))
4064 (set (attr "length_immediate")
4065 (if_then_else (eq_attr "alternative" "11")
4066 (const_string "8")
4067 (const_string "*")))
4068 (set (attr "prefix")
4069 (if_then_else (eq_attr "type" "sselog1,ssemov")
4070 (const_string "maybe_vex")
4071 (const_string "orig")))
4072 (set (attr "prefix_data16")
4073 (if_then_else
4074 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4075 (eq_attr "mode" "V1DF"))
4076 (const_string "1")
4077 (const_string "*")))
4078 (set (attr "mode")
4079 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4080 (const_string "SI")
4081 (eq_attr "alternative" "8,9,11,20,21,24,25")
4082 (const_string "DI")
4083
4084 /* xorps is one byte shorter for non-AVX targets. */
4085 (eq_attr "alternative" "12,16")
4086 (cond [(match_test "TARGET_AVX")
4087 (const_string "V2DF")
4088 (ior (not (match_test "TARGET_SSE2"))
4089 (match_test "optimize_function_for_size_p (cfun)"))
4090 (const_string "V4SF")
4091 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4092 (const_string "TI")
4093 ]
4094 (const_string "V2DF"))
4095
4096 /* For architectures resolving dependencies on
4097 whole SSE registers use movapd to break dependency
4098 chains, otherwise use short move to avoid extra work. */
4099
4100 /* movaps is one byte shorter for non-AVX targets. */
4101 (eq_attr "alternative" "13,17")
4102 (cond [(match_test "TARGET_AVX512VL")
4103 (const_string "V2DF")
4104 (match_test "TARGET_AVX512F")
4105 (const_string "DF")
4106 (match_test "TARGET_AVX")
4107 (const_string "V2DF")
4108 (ior (not (match_test "TARGET_SSE2"))
4109 (match_test "optimize_function_for_size_p (cfun)"))
4110 (const_string "V4SF")
4111 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4112 (const_string "V4SF")
4113 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4114 (const_string "V2DF")
4115 ]
4116 (const_string "DF"))
4117
4118 /* For architectures resolving dependencies on register
4119 parts we may avoid extra work to zero out upper part
4120 of register. */
4121 (eq_attr "alternative" "14,18")
4122 (cond [(not (match_test "TARGET_SSE2"))
4123 (const_string "V2SF")
4124 (match_test "TARGET_AVX")
4125 (const_string "DF")
4126 (match_test "TARGET_SSE_SPLIT_REGS")
4127 (const_string "V1DF")
4128 ]
4129 (const_string "DF"))
4130
4131 (and (eq_attr "alternative" "15,19")
4132 (not (match_test "TARGET_SSE2")))
4133 (const_string "V2SF")
4134 ]
4135 (const_string "DF")))
4136 (set (attr "preferred_for_size")
4137 (cond [(eq_attr "alternative" "3,4")
4138 (symbol_ref "false")]
4139 (symbol_ref "true")))
4140 (set (attr "preferred_for_speed")
4141 (cond [(eq_attr "alternative" "3,4")
4142 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4143 (eq_attr "alternative" "20")
4144 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4145 (eq_attr "alternative" "21")
4146 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4147 ]
4148 (symbol_ref "true")))
4149 (set (attr "enabled")
4150 (cond [(eq_attr "alternative" "22,23,24,25")
4151 (if_then_else
4152 (match_test "TARGET_HARD_DF_REGS")
4153 (symbol_ref "false")
4154 (const_string "*"))
4155 (not (match_test "TARGET_HARD_DF_REGS"))
4156 (symbol_ref "false")
4157 ]
4158 (const_string "*")))])
4159
4160 (define_split
4161 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4162 (match_operand:DF 1 "general_gr_operand"))]
4163 "!TARGET_64BIT && reload_completed"
4164 [(const_int 0)]
4165 "ix86_split_long_move (operands); DONE;")
4166
4167 (define_insn "*movsf_internal"
4168 [(set (match_operand:SF 0 "nonimmediate_operand"
4169 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4170 (match_operand:SF 1 "general_operand"
4171 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4172 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4173 && (lra_in_progress || reload_completed
4174 || !CONST_DOUBLE_P (operands[1])
4175 || ((optimize_function_for_size_p (cfun)
4176 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4177 && IS_STACK_MODE (SFmode)
4178 && standard_80387_constant_p (operands[1]) > 0)
4179 || (TARGET_SSE && TARGET_SSE_MATH
4180 && standard_sse_constant_p (operands[1], SFmode) == 1)
4181 || memory_operand (operands[0], SFmode)
4182 || !TARGET_HARD_SF_REGS)"
4183 {
4184 switch (get_attr_type (insn))
4185 {
4186 case TYPE_FMOV:
4187 if (which_alternative == 2)
4188 return standard_80387_constant_opcode (operands[1]);
4189 return output_387_reg_move (insn, operands);
4190
4191 case TYPE_IMOV:
4192 return "mov{l}\t{%1, %0|%0, %1}";
4193
4194 case TYPE_SSELOG1:
4195 return standard_sse_constant_opcode (insn, operands);
4196
4197 case TYPE_SSEMOV:
4198 return ix86_output_ssemov (insn, operands);
4199
4200 case TYPE_MMXMOV:
4201 switch (get_attr_mode (insn))
4202 {
4203 case MODE_DI:
4204 return "movq\t{%1, %0|%0, %1}";
4205 case MODE_SI:
4206 return "movd\t{%1, %0|%0, %1}";
4207
4208 default:
4209 gcc_unreachable ();
4210 }
4211
4212 default:
4213 gcc_unreachable ();
4214 }
4215 }
4216 [(set (attr "isa")
4217 (cond [(eq_attr "alternative" "9,10")
4218 (const_string "sse2")
4219 ]
4220 (const_string "*")))
4221 (set (attr "type")
4222 (cond [(eq_attr "alternative" "0,1,2")
4223 (const_string "fmov")
4224 (eq_attr "alternative" "3,4,16,17")
4225 (const_string "imov")
4226 (eq_attr "alternative" "5")
4227 (const_string "sselog1")
4228 (eq_attr "alternative" "11,12,13,14,15")
4229 (const_string "mmxmov")
4230 ]
4231 (const_string "ssemov")))
4232 (set (attr "prefix")
4233 (if_then_else (eq_attr "type" "sselog1,ssemov")
4234 (const_string "maybe_vex")
4235 (const_string "orig")))
4236 (set (attr "prefix_data16")
4237 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4238 (const_string "1")
4239 (const_string "*")))
4240 (set (attr "mode")
4241 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4242 (const_string "SI")
4243 (eq_attr "alternative" "11")
4244 (const_string "DI")
4245 (eq_attr "alternative" "5")
4246 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4247 (not (match_test "TARGET_PREFER_AVX256")))
4248 (const_string "V16SF")
4249 (match_test "TARGET_AVX")
4250 (const_string "V4SF")
4251 (ior (not (match_test "TARGET_SSE2"))
4252 (match_test "optimize_function_for_size_p (cfun)"))
4253 (const_string "V4SF")
4254 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4255 (const_string "TI")
4256 ]
4257 (const_string "V4SF"))
4258
4259 /* For architectures resolving dependencies on
4260 whole SSE registers use APS move to break dependency
4261 chains, otherwise use short move to avoid extra work.
4262
4263 Do the same for architectures resolving dependencies on
4264 the parts. While in DF mode it is better to always handle
4265 just register parts, the SF mode is different due to lack
4266 of instructions to load just part of the register. It is
4267 better to maintain the whole registers in single format
4268 to avoid problems on using packed logical operations. */
4269 (eq_attr "alternative" "6")
4270 (cond [(match_test "TARGET_AVX512VL")
4271 (const_string "V4SF")
4272 (match_test "TARGET_AVX512F")
4273 (const_string "SF")
4274 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4275 (match_test "TARGET_SSE_SPLIT_REGS"))
4276 (const_string "V4SF")
4277 ]
4278 (const_string "SF"))
4279 ]
4280 (const_string "SF")))
4281 (set (attr "preferred_for_speed")
4282 (cond [(eq_attr "alternative" "9,14")
4283 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4284 (eq_attr "alternative" "10,15")
4285 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4286 ]
4287 (symbol_ref "true")))
4288 (set (attr "enabled")
4289 (cond [(eq_attr "alternative" "16,17")
4290 (if_then_else
4291 (match_test "TARGET_HARD_SF_REGS")
4292 (symbol_ref "false")
4293 (const_string "*"))
4294 (not (match_test "TARGET_HARD_SF_REGS"))
4295 (symbol_ref "false")
4296 ]
4297 (const_string "*")))])
4298
4299 (define_mode_attr hfbfconstf
4300 [(HF "F") (BF "")])
4301
4302 (define_insn "*mov<mode>_internal"
4303 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4304 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4305 (match_operand:HFBF 1 "general_operand"
4306 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4307 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4308 && (lra_in_progress
4309 || reload_completed
4310 || !CONST_DOUBLE_P (operands[1])
4311 || (TARGET_SSE2
4312 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4313 || memory_operand (operands[0], <MODE>mode))"
4314 {
4315 switch (get_attr_type (insn))
4316 {
4317 case TYPE_IMOVX:
4318 /* movzwl is faster than movw on p2 due to partial word stalls,
4319 though not as fast as an aligned movl. */
4320 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4321
4322 case TYPE_SSEMOV:
4323 return ix86_output_ssemov (insn, operands);
4324
4325 case TYPE_SSELOG1:
4326 if (satisfies_constraint_C (operands[1]))
4327 return standard_sse_constant_opcode (insn, operands);
4328
4329 if (SSE_REG_P (operands[0]))
4330 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4331 else
4332 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4333
4334 default:
4335 if (get_attr_mode (insn) == MODE_SI)
4336 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4337 else
4338 return "mov{w}\t{%1, %0|%0, %1}";
4339 }
4340 }
4341 [(set (attr "isa")
4342 (cond [(eq_attr "alternative" "4,5,6,9,10")
4343 (const_string "sse2")
4344 (eq_attr "alternative" "7")
4345 (const_string "sse4_noavx")
4346 (eq_attr "alternative" "8")
4347 (const_string "avx")
4348 ]
4349 (const_string "*")))
4350 (set (attr "addr")
4351 (if_then_else (eq_attr "alternative" "7")
4352 (const_string "gpr16")
4353 (const_string "*")))
4354 (set (attr "type")
4355 (cond [(eq_attr "alternative" "4")
4356 (const_string "sselog1")
4357 (eq_attr "alternative" "5,6,9")
4358 (const_string "ssemov")
4359 (eq_attr "alternative" "7,8,10")
4360 (if_then_else
4361 (match_test ("TARGET_AVX512FP16"))
4362 (const_string "ssemov")
4363 (const_string "sselog1"))
4364 (match_test "optimize_function_for_size_p (cfun)")
4365 (const_string "imov")
4366 (and (eq_attr "alternative" "0")
4367 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4368 (not (match_test "TARGET_HIMODE_MATH"))))
4369 (const_string "imov")
4370 (and (eq_attr "alternative" "1,2")
4371 (match_operand:HI 1 "aligned_operand"))
4372 (const_string "imov")
4373 (and (match_test "TARGET_MOVX")
4374 (eq_attr "alternative" "0,2"))
4375 (const_string "imovx")
4376 ]
4377 (const_string "imov")))
4378 (set (attr "prefix")
4379 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4380 (const_string "maybe_vex")
4381 ]
4382 (const_string "orig")))
4383 (set (attr "mode")
4384 (cond [(eq_attr "alternative" "4")
4385 (const_string "V4SF")
4386 (eq_attr "alternative" "6,9")
4387 (if_then_else
4388 (match_test "TARGET_AVX512FP16")
4389 (const_string "HI")
4390 (const_string "SI"))
4391 (eq_attr "alternative" "7,8,10")
4392 (if_then_else
4393 (match_test "TARGET_AVX512FP16")
4394 (const_string "HI")
4395 (const_string "TI"))
4396 (eq_attr "alternative" "5")
4397 (cond [(match_test "TARGET_AVX512VL")
4398 (const_string "V4SF")
4399 (match_test "TARGET_AVX512FP16")
4400 (const_string "HF")
4401 (match_test "TARGET_AVX512F")
4402 (const_string "SF")
4403 (match_test "TARGET_AVX")
4404 (const_string "V4SF")
4405 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4406 (match_test "TARGET_SSE_SPLIT_REGS"))
4407 (const_string "V4SF")
4408 ]
4409 (const_string "SF"))
4410 (eq_attr "type" "imovx")
4411 (const_string "SI")
4412 (and (eq_attr "alternative" "1,2")
4413 (match_operand:HI 1 "aligned_operand"))
4414 (const_string "SI")
4415 (and (eq_attr "alternative" "0")
4416 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4417 (not (match_test "TARGET_HIMODE_MATH"))))
4418 (const_string "SI")
4419 ]
4420 (const_string "HI")))
4421 (set (attr "enabled")
4422 (cond [(and (match_test "<MODE>mode == BFmode")
4423 (eq_attr "alternative" "1"))
4424 (symbol_ref "false")
4425 ]
4426 (const_string "*")))])
4427
4428 (define_split
4429 [(set (match_operand 0 "any_fp_register_operand")
4430 (match_operand 1 "memory_operand"))]
4431 "reload_completed
4432 && (GET_MODE (operands[0]) == TFmode
4433 || GET_MODE (operands[0]) == XFmode
4434 || GET_MODE (operands[0]) == DFmode
4435 || GET_MODE (operands[0]) == SFmode)
4436 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4437 [(set (match_dup 0) (match_dup 2))]
4438 "operands[2] = find_constant_src (curr_insn);")
4439
4440 (define_split
4441 [(set (match_operand 0 "any_fp_register_operand")
4442 (float_extend (match_operand 1 "memory_operand")))]
4443 "reload_completed
4444 && (GET_MODE (operands[0]) == TFmode
4445 || GET_MODE (operands[0]) == XFmode
4446 || GET_MODE (operands[0]) == DFmode)
4447 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4448 [(set (match_dup 0) (match_dup 2))]
4449 "operands[2] = find_constant_src (curr_insn);")
4450
4451 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4452 (define_split
4453 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4454 (match_operand:X87MODEF 1 "immediate_operand"))]
4455 "reload_completed
4456 && (standard_80387_constant_p (operands[1]) == 8
4457 || standard_80387_constant_p (operands[1]) == 9)"
4458 [(set (match_dup 0)(match_dup 1))
4459 (set (match_dup 0)
4460 (neg:X87MODEF (match_dup 0)))]
4461 {
4462 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4463 operands[1] = CONST0_RTX (<MODE>mode);
4464 else
4465 operands[1] = CONST1_RTX (<MODE>mode);
4466 })
4467
4468 (define_insn "*swapxf"
4469 [(set (match_operand:XF 0 "register_operand" "+f")
4470 (match_operand:XF 1 "register_operand" "+f"))
4471 (set (match_dup 1)
4472 (match_dup 0))]
4473 "TARGET_80387"
4474 {
4475 if (STACK_TOP_P (operands[0]))
4476 return "fxch\t%1";
4477 else
4478 return "fxch\t%0";
4479 }
4480 [(set_attr "type" "fxch")
4481 (set_attr "mode" "XF")])
4482 \f
4483
4484 ;; Zero extension instructions
4485
4486 (define_insn_and_split "zero_extendditi2"
4487 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4488 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4489 "TARGET_64BIT"
4490 "#"
4491 "&& reload_completed"
4492 [(set (match_dup 3) (match_dup 1))
4493 (set (match_dup 4) (const_int 0))]
4494 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4495
4496 (define_expand "zero_extendsidi2"
4497 [(set (match_operand:DI 0 "nonimmediate_operand")
4498 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4499
4500 (define_insn "*zero_extendsidi2"
4501 [(set (match_operand:DI 0 "nonimmediate_operand"
4502 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4503 (zero_extend:DI
4504 (match_operand:SI 1 "x86_64_zext_operand"
4505 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4506 ""
4507 {
4508 switch (get_attr_type (insn))
4509 {
4510 case TYPE_IMOVX:
4511 if (ix86_use_lea_for_mov (insn, operands))
4512 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4513 else
4514 return "mov{l}\t{%1, %k0|%k0, %1}";
4515
4516 case TYPE_MULTI:
4517 return "#";
4518
4519 case TYPE_MMXMOV:
4520 return "movd\t{%1, %0|%0, %1}";
4521
4522 case TYPE_SSEMOV:
4523 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4524 {
4525 if (EXT_REX_SSE_REG_P (operands[0])
4526 || EXT_REX_SSE_REG_P (operands[1]))
4527 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4528 else
4529 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4530 }
4531
4532 if (GENERAL_REG_P (operands[0]))
4533 return "%vmovd\t{%1, %k0|%k0, %1}";
4534
4535 return "%vmovd\t{%1, %0|%0, %1}";
4536
4537 case TYPE_MSKMOV:
4538 return "kmovd\t{%1, %k0|%k0, %1}";
4539
4540 default:
4541 gcc_unreachable ();
4542 }
4543 }
4544 [(set (attr "isa")
4545 (cond [(eq_attr "alternative" "0,1,2")
4546 (const_string "nox64")
4547 (eq_attr "alternative" "3")
4548 (const_string "x64")
4549 (eq_attr "alternative" "7,8,9")
4550 (const_string "sse2")
4551 (eq_attr "alternative" "10")
4552 (const_string "sse4")
4553 (eq_attr "alternative" "11")
4554 (const_string "avx512f")
4555 (eq_attr "alternative" "12")
4556 (const_string "x64_avx512bw")
4557 (eq_attr "alternative" "13")
4558 (const_string "avx512bw_512")
4559 ]
4560 (const_string "*")))
4561 (set (attr "mmx_isa")
4562 (if_then_else (eq_attr "alternative" "5,6")
4563 (const_string "native")
4564 (const_string "*")))
4565 (set (attr "type")
4566 (cond [(eq_attr "alternative" "0,1,2,4")
4567 (const_string "multi")
4568 (eq_attr "alternative" "5,6")
4569 (const_string "mmxmov")
4570 (eq_attr "alternative" "7")
4571 (if_then_else (match_test "TARGET_64BIT")
4572 (const_string "ssemov")
4573 (const_string "multi"))
4574 (eq_attr "alternative" "8,9,10,11")
4575 (const_string "ssemov")
4576 (eq_attr "alternative" "12,13")
4577 (const_string "mskmov")
4578 ]
4579 (const_string "imovx")))
4580 (set (attr "prefix_extra")
4581 (if_then_else (eq_attr "alternative" "10,11")
4582 (const_string "1")
4583 (const_string "*")))
4584 (set (attr "prefix")
4585 (if_then_else (eq_attr "type" "ssemov")
4586 (const_string "maybe_vex")
4587 (const_string "orig")))
4588 (set (attr "prefix_0f")
4589 (if_then_else (eq_attr "type" "imovx")
4590 (const_string "0")
4591 (const_string "*")))
4592 (set (attr "mode")
4593 (cond [(eq_attr "alternative" "5,6")
4594 (const_string "DI")
4595 (and (eq_attr "alternative" "7")
4596 (match_test "TARGET_64BIT"))
4597 (const_string "TI")
4598 (eq_attr "alternative" "8,10,11")
4599 (const_string "TI")
4600 ]
4601 (const_string "SI")))
4602 (set (attr "preferred_for_speed")
4603 (cond [(eq_attr "alternative" "7")
4604 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4605 (eq_attr "alternative" "5,8")
4606 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4607 ]
4608 (symbol_ref "true")))])
4609
4610 (define_split
4611 [(set (match_operand:DI 0 "memory_operand")
4612 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4613 "reload_completed"
4614 [(set (match_dup 4) (const_int 0))]
4615 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4616
4617 (define_split
4618 [(set (match_operand:DI 0 "general_reg_operand")
4619 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4620 "!TARGET_64BIT && reload_completed
4621 && REGNO (operands[0]) == REGNO (operands[1])"
4622 [(set (match_dup 4) (const_int 0))]
4623 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4624
4625 (define_split
4626 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4627 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4628 "!TARGET_64BIT && reload_completed
4629 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4630 [(set (match_dup 3) (match_dup 1))
4631 (set (match_dup 4) (const_int 0))]
4632 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4633
4634 (define_mode_attr kmov_isa
4635 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4636
4637 (define_insn "zero_extend<mode>di2"
4638 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4639 (zero_extend:DI
4640 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4641 "TARGET_64BIT"
4642 "@
4643 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4644 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4645 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4646 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4647 (set_attr "type" "imovx,mskmov,mskmov")
4648 (set_attr "mode" "SI,<MODE>,<MODE>")])
4649
4650 (define_expand "zero_extend<mode>si2"
4651 [(set (match_operand:SI 0 "register_operand")
4652 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4653 ""
4654 {
4655 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4656 {
4657 operands[1] = force_reg (<MODE>mode, operands[1]);
4658 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4659 DONE;
4660 }
4661 })
4662
4663 (define_insn_and_split "zero_extend<mode>si2_and"
4664 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4665 (zero_extend:SI
4666 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4667 (clobber (reg:CC FLAGS_REG))]
4668 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4669 "#"
4670 "&& reload_completed"
4671 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4672 (clobber (reg:CC FLAGS_REG))])]
4673 {
4674 if (!REG_P (operands[1])
4675 || REGNO (operands[0]) != REGNO (operands[1]))
4676 {
4677 ix86_expand_clear (operands[0]);
4678
4679 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4680 emit_insn (gen_rtx_SET
4681 (gen_rtx_STRICT_LOW_PART
4682 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4683 operands[1]));
4684 DONE;
4685 }
4686
4687 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4688 }
4689 [(set_attr "type" "alu1")
4690 (set_attr "mode" "SI")])
4691
4692 (define_insn "*zero_extend<mode>si2"
4693 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4694 (zero_extend:SI
4695 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4696 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4697 "@
4698 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4699 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4700 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4701 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4702 (set_attr "type" "imovx,mskmov,mskmov")
4703 (set_attr "mode" "SI,<MODE>,<MODE>")])
4704
4705 (define_expand "zero_extendqihi2"
4706 [(set (match_operand:HI 0 "register_operand")
4707 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4708 ""
4709 {
4710 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4711 {
4712 operands[1] = force_reg (QImode, operands[1]);
4713 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4714 DONE;
4715 }
4716 })
4717
4718 (define_insn_and_split "zero_extendqihi2_and"
4719 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4720 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4721 (clobber (reg:CC FLAGS_REG))]
4722 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4723 "#"
4724 "&& reload_completed"
4725 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4726 (clobber (reg:CC FLAGS_REG))])]
4727 {
4728 if (!REG_P (operands[1])
4729 || REGNO (operands[0]) != REGNO (operands[1]))
4730 {
4731 ix86_expand_clear (operands[0]);
4732
4733 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4734 emit_insn (gen_rtx_SET
4735 (gen_rtx_STRICT_LOW_PART
4736 (VOIDmode, gen_lowpart (QImode, operands[0])),
4737 operands[1]));
4738 DONE;
4739 }
4740
4741 operands[0] = gen_lowpart (SImode, operands[0]);
4742 }
4743 [(set_attr "type" "alu1")
4744 (set_attr "mode" "SI")])
4745
4746 ; zero extend to SImode to avoid partial register stalls
4747 (define_insn "*zero_extendqihi2"
4748 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4749 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4750 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4751 "@
4752 movz{bl|x}\t{%1, %k0|%k0, %1}
4753 kmovb\t{%1, %k0|%k0, %1}
4754 kmovb\t{%1, %0|%0, %1}"
4755 [(set_attr "isa" "*,avx512dq,avx512dq")
4756 (set_attr "type" "imovx,mskmov,mskmov")
4757 (set_attr "mode" "SI,QI,QI")])
4758
4759 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4760 (define_peephole2
4761 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4762 (const_int 0))
4763 (clobber (reg:CC FLAGS_REG))])
4764 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4765 (match_operand:SWI12 2 "nonimmediate_operand"))]
4766 "REGNO (operands[0]) == REGNO (operands[1])
4767 && (<SWI48:MODE>mode != SImode
4768 || !TARGET_ZERO_EXTEND_WITH_AND
4769 || !optimize_function_for_speed_p (cfun))"
4770 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4771
4772 ;; Likewise, but preserving FLAGS_REG.
4773 (define_peephole2
4774 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4775 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4776 (match_operand:SWI12 2 "nonimmediate_operand"))]
4777 "REGNO (operands[0]) == REGNO (operands[1])
4778 && (<SWI48:MODE>mode != SImode
4779 || !TARGET_ZERO_EXTEND_WITH_AND
4780 || !optimize_function_for_speed_p (cfun))"
4781 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4782 \f
4783 ;; Sign extension instructions
4784
4785 (define_expand "extendsidi2"
4786 [(set (match_operand:DI 0 "register_operand")
4787 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4788 ""
4789 {
4790 if (!TARGET_64BIT)
4791 {
4792 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4793 DONE;
4794 }
4795 })
4796
4797 (define_insn "*extendsidi2_rex64"
4798 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4799 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4800 "TARGET_64BIT"
4801 "@
4802 {cltq|cdqe}
4803 movs{lq|x}\t{%1, %0|%0, %1}"
4804 [(set_attr "type" "imovx")
4805 (set_attr "mode" "DI")
4806 (set_attr "prefix_0f" "0")
4807 (set_attr "modrm" "0,1")])
4808
4809 (define_insn "extendsidi2_1"
4810 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4811 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4812 (clobber (reg:CC FLAGS_REG))
4813 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4814 "!TARGET_64BIT"
4815 "#")
4816
4817 (define_insn "extendditi2"
4818 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4819 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4820 (clobber (reg:CC FLAGS_REG))
4821 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4822 "TARGET_64BIT"
4823 "#")
4824
4825 ;; Split the memory case. If the source register doesn't die, it will stay
4826 ;; this way, if it does die, following peephole2s take care of it.
4827 (define_split
4828 [(set (match_operand:<DWI> 0 "memory_operand")
4829 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4830 (clobber (reg:CC FLAGS_REG))
4831 (clobber (match_operand:DWIH 2 "register_operand"))]
4832 "reload_completed"
4833 [(const_int 0)]
4834 {
4835 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4836
4837 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4838
4839 emit_move_insn (operands[3], operands[1]);
4840
4841 /* Generate a cltd if possible and doing so it profitable. */
4842 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4843 && REGNO (operands[1]) == AX_REG
4844 && REGNO (operands[2]) == DX_REG)
4845 {
4846 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4847 }
4848 else
4849 {
4850 emit_move_insn (operands[2], operands[1]);
4851 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4852 }
4853 emit_move_insn (operands[4], operands[2]);
4854 DONE;
4855 })
4856
4857 ;; Peepholes for the case where the source register does die, after
4858 ;; being split with the above splitter.
4859 (define_peephole2
4860 [(set (match_operand:DWIH 0 "memory_operand")
4861 (match_operand:DWIH 1 "general_reg_operand"))
4862 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4863 (parallel [(set (match_dup 2)
4864 (ashiftrt:DWIH (match_dup 2)
4865 (match_operand 4 "const_int_operand")))
4866 (clobber (reg:CC FLAGS_REG))])
4867 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4868 "REGNO (operands[1]) != REGNO (operands[2])
4869 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4870 && peep2_reg_dead_p (2, operands[1])
4871 && peep2_reg_dead_p (4, operands[2])
4872 && !reg_mentioned_p (operands[2], operands[3])"
4873 [(set (match_dup 0) (match_dup 1))
4874 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4875 (clobber (reg:CC FLAGS_REG))])
4876 (set (match_dup 3) (match_dup 1))])
4877
4878 (define_peephole2
4879 [(set (match_operand:DWIH 0 "memory_operand")
4880 (match_operand:DWIH 1 "general_reg_operand"))
4881 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4882 (ashiftrt:DWIH (match_dup 1)
4883 (match_operand 4 "const_int_operand")))
4884 (clobber (reg:CC FLAGS_REG))])
4885 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4886 "/* cltd is shorter than sarl $31, %eax */
4887 !optimize_function_for_size_p (cfun)
4888 && REGNO (operands[1]) == AX_REG
4889 && REGNO (operands[2]) == DX_REG
4890 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4891 && peep2_reg_dead_p (2, operands[1])
4892 && peep2_reg_dead_p (3, operands[2])
4893 && !reg_mentioned_p (operands[2], operands[3])"
4894 [(set (match_dup 0) (match_dup 1))
4895 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4896 (clobber (reg:CC FLAGS_REG))])
4897 (set (match_dup 3) (match_dup 1))])
4898
4899 ;; Extend to register case. Optimize case where source and destination
4900 ;; registers match and cases where we can use cltd.
4901 (define_split
4902 [(set (match_operand:<DWI> 0 "register_operand")
4903 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4904 (clobber (reg:CC FLAGS_REG))
4905 (clobber (match_scratch:DWIH 2))]
4906 "reload_completed"
4907 [(const_int 0)]
4908 {
4909 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4910
4911 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4912
4913 if (REGNO (operands[3]) != REGNO (operands[1]))
4914 emit_move_insn (operands[3], operands[1]);
4915
4916 rtx src = operands[1];
4917 if (REGNO (operands[3]) == AX_REG)
4918 src = operands[3];
4919
4920 /* Generate a cltd if possible and doing so it profitable. */
4921 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4922 && REGNO (src) == AX_REG
4923 && REGNO (operands[4]) == DX_REG)
4924 {
4925 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4926 DONE;
4927 }
4928
4929 if (REGNO (operands[4]) != REGNO (operands[1]))
4930 emit_move_insn (operands[4], operands[1]);
4931
4932 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4933 DONE;
4934 })
4935
4936 (define_insn "extend<mode>di2"
4937 [(set (match_operand:DI 0 "register_operand" "=r")
4938 (sign_extend:DI
4939 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4940 "TARGET_64BIT"
4941 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4942 [(set_attr "type" "imovx")
4943 (set_attr "mode" "DI")])
4944
4945 (define_insn "extendhisi2"
4946 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4947 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4948 ""
4949 {
4950 switch (get_attr_prefix_0f (insn))
4951 {
4952 case 0:
4953 return "{cwtl|cwde}";
4954 default:
4955 return "movs{wl|x}\t{%1, %0|%0, %1}";
4956 }
4957 }
4958 [(set_attr "type" "imovx")
4959 (set_attr "mode" "SI")
4960 (set (attr "prefix_0f")
4961 ;; movsx is short decodable while cwtl is vector decoded.
4962 (if_then_else (and (eq_attr "cpu" "!k6")
4963 (eq_attr "alternative" "0"))
4964 (const_string "0")
4965 (const_string "1")))
4966 (set (attr "znver1_decode")
4967 (if_then_else (eq_attr "prefix_0f" "0")
4968 (const_string "double")
4969 (const_string "direct")))
4970 (set (attr "modrm")
4971 (if_then_else (eq_attr "prefix_0f" "0")
4972 (const_string "0")
4973 (const_string "1")))])
4974
4975 (define_insn "*extendhisi2_zext"
4976 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4977 (zero_extend:DI
4978 (sign_extend:SI
4979 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4980 "TARGET_64BIT"
4981 {
4982 switch (get_attr_prefix_0f (insn))
4983 {
4984 case 0:
4985 return "{cwtl|cwde}";
4986 default:
4987 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4988 }
4989 }
4990 [(set_attr "type" "imovx")
4991 (set_attr "mode" "SI")
4992 (set (attr "prefix_0f")
4993 ;; movsx is short decodable while cwtl is vector decoded.
4994 (if_then_else (and (eq_attr "cpu" "!k6")
4995 (eq_attr "alternative" "0"))
4996 (const_string "0")
4997 (const_string "1")))
4998 (set (attr "modrm")
4999 (if_then_else (eq_attr "prefix_0f" "0")
5000 (const_string "0")
5001 (const_string "1")))])
5002
5003 (define_insn "extendqisi2"
5004 [(set (match_operand:SI 0 "register_operand" "=r")
5005 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5006 ""
5007 "movs{bl|x}\t{%1, %0|%0, %1}"
5008 [(set_attr "type" "imovx")
5009 (set_attr "mode" "SI")])
5010
5011 (define_insn "*extendqisi2_zext"
5012 [(set (match_operand:DI 0 "register_operand" "=r")
5013 (zero_extend:DI
5014 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5015 "TARGET_64BIT"
5016 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5017 [(set_attr "type" "imovx")
5018 (set_attr "mode" "SI")])
5019
5020 (define_insn "extendqihi2"
5021 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5022 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5023 ""
5024 {
5025 switch (get_attr_prefix_0f (insn))
5026 {
5027 case 0:
5028 return "{cbtw|cbw}";
5029 default:
5030 return "movs{bw|x}\t{%1, %0|%0, %1}";
5031 }
5032 }
5033 [(set_attr "type" "imovx")
5034 (set_attr "mode" "HI")
5035 (set (attr "prefix_0f")
5036 ;; movsx is short decodable while cwtl is vector decoded.
5037 (if_then_else (and (eq_attr "cpu" "!k6")
5038 (eq_attr "alternative" "0"))
5039 (const_string "0")
5040 (const_string "1")))
5041 (set (attr "modrm")
5042 (if_then_else (eq_attr "prefix_0f" "0")
5043 (const_string "0")
5044 (const_string "1")))])
5045
5046 (define_insn "*extendqi<SWI24:mode>_ext_1"
5047 [(set (match_operand:SWI24 0 "register_operand" "=R")
5048 (sign_extend:SWI24
5049 (subreg:QI
5050 (match_operator:SWI248 2 "extract_operator"
5051 [(match_operand 1 "int248_register_operand" "Q")
5052 (const_int 8)
5053 (const_int 8)]) 0)))]
5054 ""
5055 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5056 [(set_attr "type" "imovx")
5057 (set_attr "mode" "<SWI24:MODE>")])
5058 \f
5059 ;; Conversions between float and double.
5060
5061 ;; These are all no-ops in the model used for the 80387.
5062 ;; So just emit moves.
5063
5064 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5065 (define_split
5066 [(set (match_operand:DF 0 "push_operand")
5067 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5068 "reload_completed"
5069 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5070 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5071
5072 (define_split
5073 [(set (match_operand:XF 0 "push_operand")
5074 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5075 "reload_completed"
5076 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5077 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5078 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5079
5080 (define_expand "extendsfdf2"
5081 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5082 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5083 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5084 {
5085 /* ??? Needed for compress_float_constant since all fp constants
5086 are TARGET_LEGITIMATE_CONSTANT_P. */
5087 if (CONST_DOUBLE_P (operands[1]))
5088 {
5089 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5090 && standard_80387_constant_p (operands[1]) > 0)
5091 {
5092 operands[1] = simplify_const_unary_operation
5093 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5094 emit_move_insn_1 (operands[0], operands[1]);
5095 DONE;
5096 }
5097 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5098 }
5099 })
5100
5101 (define_insn "*extendsfdf2"
5102 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5103 (float_extend:DF
5104 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5105 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5106 {
5107 switch (which_alternative)
5108 {
5109 case 0:
5110 case 1:
5111 return output_387_reg_move (insn, operands);
5112
5113 case 2:
5114 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5115 case 3:
5116 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5117
5118 default:
5119 gcc_unreachable ();
5120 }
5121 }
5122 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5123 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5124 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5125 (set_attr "mode" "SF,XF,DF,DF")
5126 (set (attr "enabled")
5127 (if_then_else
5128 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5129 (if_then_else
5130 (eq_attr "alternative" "0,1")
5131 (symbol_ref "TARGET_MIX_SSE_I387")
5132 (symbol_ref "true"))
5133 (if_then_else
5134 (eq_attr "alternative" "0,1")
5135 (symbol_ref "true")
5136 (symbol_ref "false"))))])
5137
5138 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5139 cvtss2sd:
5140 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5141 cvtps2pd xmm2,xmm1
5142 We do the conversion post reload to avoid producing of 128bit spills
5143 that might lead to ICE on 32bit target. The sequence unlikely combine
5144 anyway. */
5145 (define_split
5146 [(set (match_operand:DF 0 "sse_reg_operand")
5147 (float_extend:DF
5148 (match_operand:SF 1 "nonimmediate_operand")))]
5149 "TARGET_USE_VECTOR_FP_CONVERTS
5150 && optimize_insn_for_speed_p ()
5151 && reload_completed
5152 && (!EXT_REX_SSE_REG_P (operands[0])
5153 || TARGET_AVX512VL || TARGET_EVEX512)"
5154 [(set (match_dup 2)
5155 (float_extend:V2DF
5156 (vec_select:V2SF
5157 (match_dup 3)
5158 (parallel [(const_int 0) (const_int 1)]))))]
5159 {
5160 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5161 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5162 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5163 Try to avoid move when unpacking can be done in source. */
5164 if (REG_P (operands[1]))
5165 {
5166 /* If it is unsafe to overwrite upper half of source, we need
5167 to move to destination and unpack there. */
5168 if (REGNO (operands[0]) != REGNO (operands[1])
5169 || (EXT_REX_SSE_REG_P (operands[1])
5170 && !TARGET_AVX512VL))
5171 {
5172 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5173 emit_move_insn (tmp, operands[1]);
5174 }
5175 else
5176 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5177 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5178 =v, v, then vbroadcastss will be only needed for AVX512F without
5179 AVX512VL. */
5180 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5181 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5182 operands[3]));
5183 else
5184 {
5185 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5186 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5187 }
5188 }
5189 else
5190 emit_insn (gen_vec_setv4sf_0 (operands[3],
5191 CONST0_RTX (V4SFmode), operands[1]));
5192 })
5193
5194 ;; It's more profitable to split and then extend in the same register.
5195 (define_peephole2
5196 [(set (match_operand:DF 0 "sse_reg_operand")
5197 (float_extend:DF
5198 (match_operand:SF 1 "memory_operand")))]
5199 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5200 && optimize_insn_for_speed_p ()"
5201 [(set (match_dup 2) (match_dup 1))
5202 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5203 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5204
5205 ;; Break partial SSE register dependency stall. This splitter should split
5206 ;; late in the pass sequence (after register rename pass), so allocated
5207 ;; registers won't change anymore
5208
5209 (define_split
5210 [(set (match_operand:DF 0 "sse_reg_operand")
5211 (float_extend:DF
5212 (match_operand:SF 1 "nonimmediate_operand")))]
5213 "!TARGET_AVX
5214 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5215 && epilogue_completed
5216 && optimize_function_for_speed_p (cfun)
5217 && (!REG_P (operands[1])
5218 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5219 && (!EXT_REX_SSE_REG_P (operands[0])
5220 || TARGET_AVX512VL)"
5221 [(set (match_dup 0)
5222 (vec_merge:V2DF
5223 (vec_duplicate:V2DF
5224 (float_extend:DF
5225 (match_dup 1)))
5226 (match_dup 0)
5227 (const_int 1)))]
5228 {
5229 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5230 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5231 })
5232
5233 (define_expand "extendhfsf2"
5234 [(set (match_operand:SF 0 "register_operand")
5235 (float_extend:SF
5236 (match_operand:HF 1 "nonimmediate_operand")))]
5237 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5238 {
5239 if (!TARGET_AVX512FP16)
5240 {
5241 rtx res = gen_reg_rtx (V4SFmode);
5242 rtx tmp = gen_reg_rtx (V8HFmode);
5243 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5244
5245 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5246 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5247 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5248 DONE;
5249 }
5250 })
5251
5252 (define_expand "extendhfdf2"
5253 [(set (match_operand:DF 0 "register_operand")
5254 (float_extend:DF
5255 (match_operand:HF 1 "nonimmediate_operand")))]
5256 "TARGET_AVX512FP16")
5257
5258 (define_insn "*extendhf<mode>2"
5259 [(set (match_operand:MODEF 0 "register_operand" "=v")
5260 (float_extend:MODEF
5261 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5262 "TARGET_AVX512FP16"
5263 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5264 [(set_attr "type" "ssecvt")
5265 (set_attr "prefix" "evex")
5266 (set_attr "mode" "<MODE>")])
5267
5268 (define_expand "extendbfsf2"
5269 [(set (match_operand:SF 0 "register_operand")
5270 (unspec:SF
5271 [(match_operand:BF 1 "register_operand")]
5272 UNSPEC_CVTBFSF))]
5273 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5274
5275 ;; Don't use float_extend since psrlld doesn't raise
5276 ;; exceptions and turn a sNaN into a qNaN.
5277 (define_insn "extendbfsf2_1"
5278 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5279 (unspec:SF
5280 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5281 UNSPEC_CVTBFSF))]
5282 "TARGET_SSE2"
5283 "@
5284 pslld\t{$16, %0|%0, 16}
5285 vpslld\t{$16, %1, %0|%0, %1, 16}
5286 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5287 [(set_attr "isa" "noavx,avx,*")
5288 (set_attr "type" "sseishft1")
5289 (set_attr "length_immediate" "1")
5290 (set_attr "prefix_data16" "1,*,*")
5291 (set_attr "prefix" "orig,maybe_evex,evex")
5292 (set_attr "mode" "TI,TI,XI")
5293 (set_attr "memory" "none")
5294 (set (attr "enabled")
5295 (if_then_else (eq_attr "alternative" "2")
5296 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5297 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5298 (const_string "*")))])
5299
5300 (define_expand "extend<mode>xf2"
5301 [(set (match_operand:XF 0 "nonimmediate_operand")
5302 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5303 "TARGET_80387"
5304 {
5305 /* ??? Needed for compress_float_constant since all fp constants
5306 are TARGET_LEGITIMATE_CONSTANT_P. */
5307 if (CONST_DOUBLE_P (operands[1]))
5308 {
5309 if (standard_80387_constant_p (operands[1]) > 0)
5310 {
5311 operands[1] = simplify_const_unary_operation
5312 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5313 emit_move_insn_1 (operands[0], operands[1]);
5314 DONE;
5315 }
5316 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5317 }
5318 })
5319
5320 (define_insn "*extend<mode>xf2_i387"
5321 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5322 (float_extend:XF
5323 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5324 "TARGET_80387"
5325 "* return output_387_reg_move (insn, operands);"
5326 [(set_attr "type" "fmov")
5327 (set_attr "mode" "<MODE>,XF")])
5328
5329 ;; %%% This seems like bad news.
5330 ;; This cannot output into an f-reg because there is no way to be sure
5331 ;; of truncating in that case. Otherwise this is just like a simple move
5332 ;; insn. So we pretend we can output to a reg in order to get better
5333 ;; register preferencing, but we really use a stack slot.
5334
5335 ;; Conversion from DFmode to SFmode.
5336
5337 (define_insn "truncdfsf2"
5338 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5339 (float_truncate:SF
5340 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5341 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5342 {
5343 switch (which_alternative)
5344 {
5345 case 0:
5346 case 1:
5347 return output_387_reg_move (insn, operands);
5348
5349 case 2:
5350 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5351 case 3:
5352 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5353
5354 default:
5355 gcc_unreachable ();
5356 }
5357 }
5358 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5359 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5360 (set_attr "mode" "SF")
5361 (set (attr "enabled")
5362 (if_then_else
5363 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5364 (cond [(eq_attr "alternative" "0")
5365 (symbol_ref "TARGET_MIX_SSE_I387")
5366 (eq_attr "alternative" "1")
5367 (symbol_ref "TARGET_MIX_SSE_I387
5368 && flag_unsafe_math_optimizations")
5369 ]
5370 (symbol_ref "true"))
5371 (cond [(eq_attr "alternative" "0")
5372 (symbol_ref "true")
5373 (eq_attr "alternative" "1")
5374 (symbol_ref "flag_unsafe_math_optimizations")
5375 ]
5376 (symbol_ref "false"))))])
5377
5378 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5379 cvtsd2ss:
5380 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5381 cvtpd2ps xmm2,xmm1
5382 We do the conversion post reload to avoid producing of 128bit spills
5383 that might lead to ICE on 32bit target. The sequence unlikely combine
5384 anyway. */
5385 (define_split
5386 [(set (match_operand:SF 0 "sse_reg_operand")
5387 (float_truncate:SF
5388 (match_operand:DF 1 "nonimmediate_operand")))]
5389 "TARGET_USE_VECTOR_FP_CONVERTS
5390 && optimize_insn_for_speed_p ()
5391 && reload_completed
5392 && (!EXT_REX_SSE_REG_P (operands[0])
5393 || TARGET_AVX512VL)"
5394 [(set (match_dup 2)
5395 (vec_concat:V4SF
5396 (float_truncate:V2SF
5397 (match_dup 4))
5398 (match_dup 3)))]
5399 {
5400 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5401 operands[3] = CONST0_RTX (V2SFmode);
5402 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5403 /* Use movsd for loading from memory, unpcklpd for registers.
5404 Try to avoid move when unpacking can be done in source, or SSE3
5405 movddup is available. */
5406 if (REG_P (operands[1]))
5407 {
5408 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5409 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5410 {
5411 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5412 emit_move_insn (tmp, operands[1]);
5413 operands[1] = tmp;
5414 }
5415 else if (!TARGET_SSE3)
5416 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5417 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5418 }
5419 else
5420 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5421 CONST0_RTX (DFmode)));
5422 })
5423
5424 ;; It's more profitable to split and then truncate in the same register.
5425 (define_peephole2
5426 [(set (match_operand:SF 0 "sse_reg_operand")
5427 (float_truncate:SF
5428 (match_operand:DF 1 "memory_operand")))]
5429 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5430 && optimize_insn_for_speed_p ()"
5431 [(set (match_dup 2) (match_dup 1))
5432 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5433 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5434
5435 ;; Break partial SSE register dependency stall. This splitter should split
5436 ;; late in the pass sequence (after register rename pass), so allocated
5437 ;; registers won't change anymore
5438
5439 (define_split
5440 [(set (match_operand:SF 0 "sse_reg_operand")
5441 (float_truncate:SF
5442 (match_operand:DF 1 "nonimmediate_operand")))]
5443 "!TARGET_AVX
5444 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5445 && epilogue_completed
5446 && optimize_function_for_speed_p (cfun)
5447 && (!REG_P (operands[1])
5448 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5449 && (!EXT_REX_SSE_REG_P (operands[0])
5450 || TARGET_AVX512VL)"
5451 [(set (match_dup 0)
5452 (vec_merge:V4SF
5453 (vec_duplicate:V4SF
5454 (float_truncate:SF
5455 (match_dup 1)))
5456 (match_dup 0)
5457 (const_int 1)))]
5458 {
5459 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5460 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5461 })
5462
5463 ;; Conversion from XFmode to {SF,DF}mode
5464
5465 (define_insn "truncxf<mode>2"
5466 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5467 (float_truncate:MODEF
5468 (match_operand:XF 1 "register_operand" "f,f")))]
5469 "TARGET_80387"
5470 "* return output_387_reg_move (insn, operands);"
5471 [(set_attr "type" "fmov")
5472 (set_attr "mode" "<MODE>")
5473 (set (attr "enabled")
5474 (cond [(eq_attr "alternative" "1")
5475 (symbol_ref "flag_unsafe_math_optimizations")
5476 ]
5477 (symbol_ref "true")))])
5478
5479 ;; Conversion from {SF,DF}mode to HFmode.
5480
5481 (define_expand "truncsfhf2"
5482 [(set (match_operand:HF 0 "register_operand")
5483 (float_truncate:HF
5484 (match_operand:SF 1 "nonimmediate_operand")))]
5485 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5486 {
5487 if (!TARGET_AVX512FP16)
5488 {
5489 rtx res = gen_reg_rtx (V8HFmode);
5490 rtx tmp = gen_reg_rtx (V4SFmode);
5491 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5492
5493 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5494 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5495 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5496 DONE;
5497 }
5498 })
5499
5500 (define_expand "truncdfhf2"
5501 [(set (match_operand:HF 0 "register_operand")
5502 (float_truncate:HF
5503 (match_operand:DF 1 "nonimmediate_operand")))]
5504 "TARGET_AVX512FP16")
5505
5506 (define_insn "*trunc<mode>hf2"
5507 [(set (match_operand:HF 0 "register_operand" "=v")
5508 (float_truncate:HF
5509 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5510 "TARGET_AVX512FP16"
5511 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5512 [(set_attr "type" "ssecvt")
5513 (set_attr "prefix" "evex")
5514 (set_attr "mode" "HF")])
5515
5516 (define_insn "truncsfbf2"
5517 [(set (match_operand:BF 0 "register_operand" "=x, v")
5518 (float_truncate:BF
5519 (match_operand:SF 1 "register_operand" "x,v")))]
5520 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5521 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5522 "@
5523 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5524 vcvtneps2bf16\t{%1, %0|%0, %1}"
5525 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5526 (set_attr "prefix" "vex,evex")])
5527
5528 ;; Signed conversion to DImode.
5529
5530 (define_expand "fix_truncxfdi2"
5531 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5532 (fix:DI (match_operand:XF 1 "register_operand")))
5533 (clobber (reg:CC FLAGS_REG))])]
5534 "TARGET_80387"
5535 {
5536 if (TARGET_FISTTP)
5537 {
5538 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5539 DONE;
5540 }
5541 })
5542
5543 (define_expand "fix_trunc<mode>di2"
5544 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5545 (fix:DI (match_operand:MODEF 1 "register_operand")))
5546 (clobber (reg:CC FLAGS_REG))])]
5547 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5548 {
5549 if (TARGET_FISTTP
5550 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5551 {
5552 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5553 DONE;
5554 }
5555 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5556 {
5557 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5558 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5559 if (out != operands[0])
5560 emit_move_insn (operands[0], out);
5561 DONE;
5562 }
5563 })
5564
5565 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5566 [(set (match_operand:SWI48 0 "register_operand" "=r")
5567 (any_fix:SWI48
5568 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5569 "TARGET_AVX512FP16"
5570 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5571 [(set_attr "type" "sseicvt")
5572 (set_attr "prefix" "evex")
5573 (set_attr "mode" "<MODE>")])
5574
5575 ;; Signed conversion to SImode.
5576
5577 (define_expand "fix_truncxfsi2"
5578 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5579 (fix:SI (match_operand:XF 1 "register_operand")))
5580 (clobber (reg:CC FLAGS_REG))])]
5581 "TARGET_80387"
5582 {
5583 if (TARGET_FISTTP)
5584 {
5585 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5586 DONE;
5587 }
5588 })
5589
5590 (define_expand "fix_trunc<mode>si2"
5591 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5592 (fix:SI (match_operand:MODEF 1 "register_operand")))
5593 (clobber (reg:CC FLAGS_REG))])]
5594 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5595 {
5596 if (TARGET_FISTTP
5597 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5598 {
5599 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5600 DONE;
5601 }
5602 if (SSE_FLOAT_MODE_P (<MODE>mode))
5603 {
5604 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5605 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5606 if (out != operands[0])
5607 emit_move_insn (operands[0], out);
5608 DONE;
5609 }
5610 })
5611
5612 ;; Signed conversion to HImode.
5613
5614 (define_expand "fix_trunc<mode>hi2"
5615 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5616 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5617 (clobber (reg:CC FLAGS_REG))])]
5618 "TARGET_80387
5619 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5620 {
5621 if (TARGET_FISTTP)
5622 {
5623 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5624 DONE;
5625 }
5626 })
5627
5628 ;; Unsigned conversion to DImode
5629
5630 (define_insn "fixuns_trunc<mode>di2"
5631 [(set (match_operand:DI 0 "register_operand" "=r")
5632 (unsigned_fix:DI
5633 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5634 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5635 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5636 [(set_attr "type" "sseicvt")
5637 (set_attr "prefix" "evex")
5638 (set_attr "mode" "DI")])
5639
5640 ;; Unsigned conversion to SImode.
5641
5642 (define_expand "fixuns_trunc<mode>si2"
5643 [(parallel
5644 [(set (match_operand:SI 0 "register_operand")
5645 (unsigned_fix:SI
5646 (match_operand:MODEF 1 "nonimmediate_operand")))
5647 (use (match_dup 2))
5648 (clobber (scratch:<ssevecmode>))
5649 (clobber (scratch:<ssevecmode>))])]
5650 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5651 {
5652 machine_mode mode = <MODE>mode;
5653 machine_mode vecmode = <ssevecmode>mode;
5654 REAL_VALUE_TYPE TWO31r;
5655 rtx two31;
5656
5657 if (TARGET_AVX512F)
5658 {
5659 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5660 DONE;
5661 }
5662
5663 if (optimize_insn_for_size_p ())
5664 FAIL;
5665
5666 real_ldexp (&TWO31r, &dconst1, 31);
5667 two31 = const_double_from_real_value (TWO31r, mode);
5668 two31 = ix86_build_const_vector (vecmode, true, two31);
5669 operands[2] = force_reg (vecmode, two31);
5670 })
5671
5672 (define_insn "fixuns_trunc<mode>si2_avx512f"
5673 [(set (match_operand:SI 0 "register_operand" "=r")
5674 (unsigned_fix:SI
5675 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5676 "TARGET_AVX512F && TARGET_SSE_MATH"
5677 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5678 [(set_attr "type" "sseicvt")
5679 (set_attr "prefix" "evex")
5680 (set_attr "mode" "SI")])
5681
5682 (define_insn "*fixuns_trunchfsi2zext"
5683 [(set (match_operand:DI 0 "register_operand" "=r")
5684 (zero_extend:DI
5685 (unsigned_fix:SI
5686 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5687 "TARGET_64BIT && TARGET_AVX512FP16"
5688 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5689 [(set_attr "type" "sseicvt")
5690 (set_attr "prefix" "evex")
5691 (set_attr "mode" "SI")])
5692
5693 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5694 [(set (match_operand:DI 0 "register_operand" "=r")
5695 (zero_extend:DI
5696 (unsigned_fix:SI
5697 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5698 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5699 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5700 [(set_attr "type" "sseicvt")
5701 (set_attr "prefix" "evex")
5702 (set_attr "mode" "SI")])
5703
5704 (define_insn_and_split "*fixuns_trunc<mode>_1"
5705 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5706 (unsigned_fix:SI
5707 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5708 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5709 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5710 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5711 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5712 && optimize_function_for_speed_p (cfun)"
5713 "#"
5714 "&& reload_completed"
5715 [(const_int 0)]
5716 {
5717 ix86_split_convert_uns_si_sse (operands);
5718 DONE;
5719 })
5720
5721 ;; Unsigned conversion to HImode.
5722 ;; Without these patterns, we'll try the unsigned SI conversion which
5723 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5724
5725 (define_expand "fixuns_trunchfhi2"
5726 [(set (match_dup 2)
5727 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5728 (set (match_operand:HI 0 "nonimmediate_operand")
5729 (subreg:HI (match_dup 2) 0))]
5730 "TARGET_AVX512FP16"
5731 "operands[2] = gen_reg_rtx (SImode);")
5732
5733 (define_expand "fixuns_trunc<mode>hi2"
5734 [(set (match_dup 2)
5735 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5736 (set (match_operand:HI 0 "nonimmediate_operand")
5737 (subreg:HI (match_dup 2) 0))]
5738 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5739 "operands[2] = gen_reg_rtx (SImode);")
5740
5741 ;; When SSE is available, it is always faster to use it!
5742 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5743 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5744 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5745 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5746 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5747 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5748 [(set_attr "type" "sseicvt")
5749 (set_attr "prefix" "maybe_vex")
5750 (set (attr "prefix_rex")
5751 (if_then_else
5752 (match_test "<SWI48:MODE>mode == DImode")
5753 (const_string "1")
5754 (const_string "*")))
5755 (set_attr "mode" "<MODEF:MODE>")
5756 (set_attr "athlon_decode" "double,vector")
5757 (set_attr "amdfam10_decode" "double,double")
5758 (set_attr "bdver1_decode" "double,double")])
5759
5760 ;; Avoid vector decoded forms of the instruction.
5761 (define_peephole2
5762 [(match_scratch:MODEF 2 "x")
5763 (set (match_operand:SWI48 0 "register_operand")
5764 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5765 "TARGET_AVOID_VECTOR_DECODE
5766 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5767 && optimize_insn_for_speed_p ()"
5768 [(set (match_dup 2) (match_dup 1))
5769 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5770
5771 (define_insn "fix_trunc<mode>_i387_fisttp"
5772 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5773 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5774 (clobber (match_scratch:XF 2 "=&f"))]
5775 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5776 && TARGET_FISTTP
5777 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5778 && (TARGET_64BIT || <MODE>mode != DImode))
5779 && TARGET_SSE_MATH)"
5780 "* return output_fix_trunc (insn, operands, true);"
5781 [(set_attr "type" "fisttp")
5782 (set_attr "mode" "<MODE>")])
5783
5784 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5785 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5786 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5787 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5788 ;; function in i386.cc.
5789 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5790 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5791 (fix:SWI248x (match_operand 1 "register_operand")))
5792 (clobber (reg:CC FLAGS_REG))]
5793 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5794 && !TARGET_FISTTP
5795 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5796 && (TARGET_64BIT || <MODE>mode != DImode))
5797 && ix86_pre_reload_split ()"
5798 "#"
5799 "&& 1"
5800 [(const_int 0)]
5801 {
5802 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5803
5804 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5805 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5806
5807 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5808 operands[2], operands[3]));
5809 DONE;
5810 }
5811 [(set_attr "type" "fistp")
5812 (set_attr "i387_cw" "trunc")
5813 (set_attr "mode" "<MODE>")])
5814
5815 (define_insn "fix_truncdi_i387"
5816 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5817 (fix:DI (match_operand 1 "register_operand" "f")))
5818 (use (match_operand:HI 2 "memory_operand" "m"))
5819 (use (match_operand:HI 3 "memory_operand" "m"))
5820 (clobber (match_scratch:XF 4 "=&f"))]
5821 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5822 && !TARGET_FISTTP
5823 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5824 "* return output_fix_trunc (insn, operands, false);"
5825 [(set_attr "type" "fistp")
5826 (set_attr "i387_cw" "trunc")
5827 (set_attr "mode" "DI")])
5828
5829 (define_insn "fix_trunc<mode>_i387"
5830 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5831 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5832 (use (match_operand:HI 2 "memory_operand" "m"))
5833 (use (match_operand:HI 3 "memory_operand" "m"))]
5834 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5835 && !TARGET_FISTTP
5836 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5837 "* return output_fix_trunc (insn, operands, false);"
5838 [(set_attr "type" "fistp")
5839 (set_attr "i387_cw" "trunc")
5840 (set_attr "mode" "<MODE>")])
5841
5842 (define_insn "x86_fnstcw_1"
5843 [(set (match_operand:HI 0 "memory_operand" "=m")
5844 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5845 "TARGET_80387"
5846 "fnstcw\t%0"
5847 [(set (attr "length")
5848 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5849 (set_attr "mode" "HI")
5850 (set_attr "unit" "i387")
5851 (set_attr "bdver1_decode" "vector")])
5852 \f
5853 ;; Conversion between fixed point and floating point.
5854
5855 ;; Even though we only accept memory inputs, the backend _really_
5856 ;; wants to be able to do this between registers. Thankfully, LRA
5857 ;; will fix this up for us during register allocation.
5858
5859 (define_insn "floathi<mode>2"
5860 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5861 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5862 "TARGET_80387
5863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5864 || TARGET_MIX_SSE_I387)"
5865 "fild%Z1\t%1"
5866 [(set_attr "type" "fmov")
5867 (set_attr "mode" "<MODE>")
5868 (set_attr "znver1_decode" "double")
5869 (set_attr "fp_int_src" "true")])
5870
5871 (define_insn "float<SWI48x:mode>xf2"
5872 [(set (match_operand:XF 0 "register_operand" "=f")
5873 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5874 "TARGET_80387"
5875 "fild%Z1\t%1"
5876 [(set_attr "type" "fmov")
5877 (set_attr "mode" "XF")
5878 (set_attr "znver1_decode" "double")
5879 (set_attr "fp_int_src" "true")])
5880
5881 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5882 [(set (match_operand:MODEF 0 "register_operand")
5883 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5884 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5885 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5886 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5887
5888 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5889 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5890 (float:MODEF
5891 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5892 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5893 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5894 "@
5895 fild%Z1\t%1
5896 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5897 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5898 [(set_attr "type" "fmov,sseicvt,sseicvt")
5899 (set_attr "avx_partial_xmm_update" "false,true,true")
5900 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5901 (set_attr "mode" "<MODEF:MODE>")
5902 (set (attr "prefix_rex")
5903 (if_then_else
5904 (and (eq_attr "prefix" "maybe_vex")
5905 (match_test "<SWI48:MODE>mode == DImode"))
5906 (const_string "1")
5907 (const_string "*")))
5908 (set_attr "unit" "i387,*,*")
5909 (set_attr "athlon_decode" "*,double,direct")
5910 (set_attr "amdfam10_decode" "*,vector,double")
5911 (set_attr "bdver1_decode" "*,double,direct")
5912 (set_attr "znver1_decode" "double,*,*")
5913 (set_attr "fp_int_src" "true")
5914 (set (attr "enabled")
5915 (if_then_else
5916 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5917 (if_then_else
5918 (eq_attr "alternative" "0")
5919 (symbol_ref "TARGET_MIX_SSE_I387
5920 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5921 <SWI48:MODE>mode)")
5922 (symbol_ref "true"))
5923 (if_then_else
5924 (eq_attr "alternative" "0")
5925 (symbol_ref "true")
5926 (symbol_ref "false"))))
5927 (set (attr "preferred_for_speed")
5928 (cond [(eq_attr "alternative" "1")
5929 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5930 (symbol_ref "true")))])
5931
5932 (define_insn "float<floatunssuffix><mode>hf2"
5933 [(set (match_operand:HF 0 "register_operand" "=v")
5934 (any_float:HF
5935 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5936 "TARGET_AVX512FP16"
5937 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5938 [(set_attr "type" "sseicvt")
5939 (set_attr "prefix" "evex")
5940 (set_attr "mode" "HF")])
5941
5942 (define_insn "*floatdi<MODEF:mode>2_i387"
5943 [(set (match_operand:MODEF 0 "register_operand" "=f")
5944 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5945 "!TARGET_64BIT
5946 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5947 "fild%Z1\t%1"
5948 [(set_attr "type" "fmov")
5949 (set_attr "mode" "<MODEF:MODE>")
5950 (set_attr "znver1_decode" "double")
5951 (set_attr "fp_int_src" "true")])
5952
5953 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5954 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5955 ;; alternative in sse2_loadld.
5956 (define_split
5957 [(set (match_operand:MODEF 0 "sse_reg_operand")
5958 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5959 "TARGET_SSE2
5960 && TARGET_USE_VECTOR_CONVERTS
5961 && optimize_function_for_speed_p (cfun)
5962 && reload_completed
5963 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5964 && (!EXT_REX_SSE_REG_P (operands[0])
5965 || TARGET_AVX512VL)"
5966 [(const_int 0)]
5967 {
5968 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5969 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5970
5971 emit_insn (gen_sse2_loadld (operands[4],
5972 CONST0_RTX (V4SImode), operands[1]));
5973
5974 if (<ssevecmode>mode == V4SFmode)
5975 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5976 else
5977 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5978 DONE;
5979 })
5980
5981 ;; Avoid store forwarding (partial memory) stall penalty
5982 ;; by passing DImode value through XMM registers. */
5983
5984 (define_split
5985 [(set (match_operand:X87MODEF 0 "register_operand")
5986 (float:X87MODEF
5987 (match_operand:DI 1 "register_operand")))]
5988 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5989 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5990 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5991 && can_create_pseudo_p ()"
5992 [(const_int 0)]
5993 {
5994 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5995 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5996 DONE;
5997 })
5998
5999 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6000 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6001 (float:X87MODEF
6002 (match_operand:DI 1 "register_operand" "r,r")))
6003 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6004 (clobber (match_scratch:V4SI 3 "=x,x"))
6005 (clobber (match_scratch:V4SI 4 "=X,x"))]
6006 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6007 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6008 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6009 "#"
6010 "&& reload_completed"
6011 [(set (match_dup 2) (match_dup 3))
6012 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6013 {
6014 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6015 Assemble the 64-bit DImode value in an xmm register. */
6016 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6017 gen_lowpart (SImode, operands[1])));
6018 if (TARGET_SSE4_1)
6019 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6020 gen_highpart (SImode, operands[1]),
6021 GEN_INT (2)));
6022 else
6023 {
6024 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6025 gen_highpart (SImode, operands[1])));
6026 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6027 operands[4]));
6028 }
6029 operands[3] = gen_lowpart (DImode, operands[3]);
6030 }
6031 [(set_attr "isa" "sse4,*")
6032 (set_attr "type" "multi")
6033 (set_attr "mode" "<X87MODEF:MODE>")
6034 (set_attr "unit" "i387")
6035 (set_attr "fp_int_src" "true")])
6036
6037 ;; Break partial SSE register dependency stall. This splitter should split
6038 ;; late in the pass sequence (after register rename pass), so allocated
6039 ;; registers won't change anymore
6040
6041 (define_split
6042 [(set (match_operand:MODEF 0 "sse_reg_operand")
6043 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6044 "!TARGET_AVX
6045 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6046 && epilogue_completed
6047 && optimize_function_for_speed_p (cfun)
6048 && (!EXT_REX_SSE_REG_P (operands[0])
6049 || TARGET_AVX512VL)"
6050 [(set (match_dup 0)
6051 (vec_merge:<MODEF:ssevecmode>
6052 (vec_duplicate:<MODEF:ssevecmode>
6053 (float:MODEF
6054 (match_dup 1)))
6055 (match_dup 0)
6056 (const_int 1)))]
6057 {
6058 const machine_mode vmode = <MODEF:ssevecmode>mode;
6059
6060 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6061 emit_move_insn (operands[0], CONST0_RTX (vmode));
6062 })
6063
6064 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6065 [(set (match_operand:MODEF 0 "register_operand")
6066 (unsigned_float:MODEF
6067 (match_operand:SWI12 1 "nonimmediate_operand")))]
6068 "!TARGET_64BIT
6069 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6070 {
6071 operands[1] = convert_to_mode (SImode, operands[1], 1);
6072 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6073 DONE;
6074 })
6075
6076 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6077 [(set (match_operand:MODEF 0 "register_operand" "=v")
6078 (unsigned_float:MODEF
6079 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6080 "TARGET_AVX512F && TARGET_SSE_MATH"
6081 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6082 [(set_attr "type" "sseicvt")
6083 (set_attr "avx_partial_xmm_update" "true")
6084 (set_attr "prefix" "evex")
6085 (set_attr "mode" "<MODEF:MODE>")])
6086
6087 ;; Avoid store forwarding (partial memory) stall penalty by extending
6088 ;; SImode value to DImode through XMM register instead of pushing two
6089 ;; SImode values to stack. Also note that fild loads from memory only.
6090
6091 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6092 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6093 (unsigned_float:X87MODEF
6094 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6095 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6096 (clobber (match_scratch:DI 3 "=x"))]
6097 "!TARGET_64BIT
6098 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6099 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6100 "#"
6101 "&& reload_completed"
6102 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6103 (set (match_dup 2) (match_dup 3))
6104 (set (match_dup 0)
6105 (float:X87MODEF (match_dup 2)))]
6106 ""
6107 [(set_attr "type" "multi")
6108 (set_attr "mode" "<MODE>")])
6109
6110 (define_expand "floatunssi<mode>2"
6111 [(set (match_operand:X87MODEF 0 "register_operand")
6112 (unsigned_float:X87MODEF
6113 (match_operand:SI 1 "nonimmediate_operand")))]
6114 "(!TARGET_64BIT
6115 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6116 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6117 || ((!TARGET_64BIT || TARGET_AVX512F)
6118 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6119 {
6120 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6121 {
6122 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6123 (operands[0], operands[1],
6124 assign_386_stack_local (DImode, SLOT_TEMP)));
6125 DONE;
6126 }
6127 if (!TARGET_AVX512F)
6128 {
6129 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6130 DONE;
6131 }
6132 })
6133
6134 (define_expand "floatunsdisf2"
6135 [(set (match_operand:SF 0 "register_operand")
6136 (unsigned_float:SF
6137 (match_operand:DI 1 "nonimmediate_operand")))]
6138 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6139 {
6140 if (!TARGET_AVX512F)
6141 {
6142 x86_emit_floatuns (operands);
6143 DONE;
6144 }
6145 })
6146
6147 (define_expand "floatunsdidf2"
6148 [(set (match_operand:DF 0 "register_operand")
6149 (unsigned_float:DF
6150 (match_operand:DI 1 "nonimmediate_operand")))]
6151 "((TARGET_64BIT && TARGET_AVX512F)
6152 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6153 && TARGET_SSE2 && TARGET_SSE_MATH"
6154 {
6155 if (!TARGET_64BIT)
6156 {
6157 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6158 DONE;
6159 }
6160 if (!TARGET_AVX512F)
6161 {
6162 x86_emit_floatuns (operands);
6163 DONE;
6164 }
6165 })
6166 \f
6167 ;; Load effective address instructions
6168
6169 (define_insn "*lea<mode>"
6170 [(set (match_operand:SWI48 0 "register_operand" "=r")
6171 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6172 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6173 {
6174 if (SImode_address_operand (operands[1], VOIDmode))
6175 {
6176 gcc_assert (TARGET_64BIT);
6177 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6178 }
6179 else
6180 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6181 }
6182 [(set_attr "type" "lea")
6183 (set (attr "mode")
6184 (if_then_else
6185 (match_operand 1 "SImode_address_operand")
6186 (const_string "SI")
6187 (const_string "<MODE>")))])
6188
6189 (define_peephole2
6190 [(set (match_operand:SWI48 0 "register_operand")
6191 (match_operand:SWI48 1 "address_no_seg_operand"))]
6192 "ix86_hardreg_mov_ok (operands[0], operands[1])
6193 && peep2_regno_dead_p (0, FLAGS_REG)
6194 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6195 [(const_int 0)]
6196 {
6197 machine_mode mode = <MODE>mode;
6198
6199 /* Emit all operations in SImode for zero-extended addresses. */
6200 if (SImode_address_operand (operands[1], VOIDmode))
6201 mode = SImode;
6202
6203 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6204
6205 /* Zero-extend return register to DImode for zero-extended addresses. */
6206 if (mode != <MODE>mode)
6207 emit_insn (gen_zero_extendsidi2 (operands[0],
6208 gen_lowpart (mode, operands[0])));
6209
6210 DONE;
6211 })
6212
6213 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6214 ;; peephole2 optimized back into a lea. Split that into the shift during
6215 ;; the following split pass.
6216 (define_split
6217 [(set (match_operand:SWI48 0 "general_reg_operand")
6218 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6219 (clobber (reg:CC FLAGS_REG))]
6220 "reload_completed"
6221 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6222 (clobber (reg:CC FLAGS_REG))])]
6223 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6224 \f
6225 ;; Add instructions
6226
6227 (define_expand "add<mode>3"
6228 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6229 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6230 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6231 ""
6232 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6233
6234 (define_insn_and_split "*add<dwi>3_doubleword"
6235 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6236 (plus:<DWI>
6237 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6238 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6239 (clobber (reg:CC FLAGS_REG))]
6240 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6241 "#"
6242 "&& reload_completed"
6243 [(parallel [(set (reg:CCC FLAGS_REG)
6244 (compare:CCC
6245 (plus:DWIH (match_dup 1) (match_dup 2))
6246 (match_dup 1)))
6247 (set (match_dup 0)
6248 (plus:DWIH (match_dup 1) (match_dup 2)))])
6249 (parallel [(set (match_dup 3)
6250 (plus:DWIH
6251 (plus:DWIH
6252 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6253 (match_dup 4))
6254 (match_dup 5)))
6255 (clobber (reg:CC FLAGS_REG))])]
6256 {
6257 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6258 if (operands[2] == const0_rtx)
6259 {
6260 if (operands[5] != const0_rtx)
6261 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6262 else if (!rtx_equal_p (operands[3], operands[4]))
6263 emit_move_insn (operands[3], operands[4]);
6264 else
6265 emit_note (NOTE_INSN_DELETED);
6266 DONE;
6267 }
6268 })
6269
6270 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6271 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6272 (plus:<DWI>
6273 (zero_extend:<DWI>
6274 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6275 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6276 (clobber (reg:CC FLAGS_REG))]
6277 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6278 "#"
6279 "&& reload_completed"
6280 [(parallel [(set (reg:CCC FLAGS_REG)
6281 (compare:CCC
6282 (plus:DWIH (match_dup 1) (match_dup 2))
6283 (match_dup 1)))
6284 (set (match_dup 0)
6285 (plus:DWIH (match_dup 1) (match_dup 2)))])
6286 (parallel [(set (match_dup 3)
6287 (plus:DWIH
6288 (plus:DWIH
6289 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6290 (match_dup 4))
6291 (const_int 0)))
6292 (clobber (reg:CC FLAGS_REG))])]
6293 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6294
6295 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6296 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6297 (plus:<DWI>
6298 (any_or_plus:<DWI>
6299 (ashift:<DWI>
6300 (zero_extend:<DWI>
6301 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6302 (match_operand:QI 3 "const_int_operand"))
6303 (zero_extend:<DWI>
6304 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6305 (match_operand:<DWI> 1 "register_operand" "0")))
6306 (clobber (reg:CC FLAGS_REG))]
6307 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6308 "#"
6309 "&& reload_completed"
6310 [(parallel [(set (reg:CCC FLAGS_REG)
6311 (compare:CCC
6312 (plus:DWIH (match_dup 1) (match_dup 4))
6313 (match_dup 1)))
6314 (set (match_dup 0)
6315 (plus:DWIH (match_dup 1) (match_dup 4)))])
6316 (parallel [(set (match_dup 5)
6317 (plus:DWIH
6318 (plus:DWIH
6319 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6320 (match_dup 6))
6321 (match_dup 2)))
6322 (clobber (reg:CC FLAGS_REG))])]
6323 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6324
6325 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6326 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6327 (plus:<DWI>
6328 (any_or_plus:<DWI>
6329 (ashift:<DWI>
6330 (zero_extend:<DWI>
6331 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6332 (match_operand:QI 3 "const_int_operand"))
6333 (zero_extend:<DWI>
6334 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6335 (zero_extend:<DWI>
6336 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6337 (clobber (reg:CC FLAGS_REG))]
6338 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6339 "#"
6340 "&& reload_completed"
6341 [(set (match_dup 0) (match_dup 4))
6342 (set (match_dup 5) (match_dup 2))
6343 (parallel [(set (reg:CCC FLAGS_REG)
6344 (compare:CCC
6345 (plus:DWIH (match_dup 0) (match_dup 1))
6346 (match_dup 0)))
6347 (set (match_dup 0)
6348 (plus:DWIH (match_dup 0) (match_dup 1)))])
6349 (parallel [(set (match_dup 5)
6350 (plus:DWIH
6351 (plus:DWIH
6352 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6353 (match_dup 5))
6354 (const_int 0)))
6355 (clobber (reg:CC FLAGS_REG))])]
6356 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6357
6358 (define_insn "*add<mode>_1"
6359 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6360 (plus:SWI48
6361 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6362 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6363 (clobber (reg:CC FLAGS_REG))]
6364 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6365 {
6366 switch (get_attr_type (insn))
6367 {
6368 case TYPE_LEA:
6369 return "#";
6370
6371 case TYPE_INCDEC:
6372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6373 if (operands[2] == const1_rtx)
6374 return "inc{<imodesuffix>}\t%0";
6375 else
6376 {
6377 gcc_assert (operands[2] == constm1_rtx);
6378 return "dec{<imodesuffix>}\t%0";
6379 }
6380
6381 default:
6382 /* For most processors, ADD is faster than LEA. This alternative
6383 was added to use ADD as much as possible. */
6384 if (which_alternative == 2)
6385 std::swap (operands[1], operands[2]);
6386
6387 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6388 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6389 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6390
6391 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6392 }
6393 }
6394 [(set (attr "type")
6395 (cond [(eq_attr "alternative" "3")
6396 (const_string "lea")
6397 (match_operand:SWI48 2 "incdec_operand")
6398 (const_string "incdec")
6399 ]
6400 (const_string "alu")))
6401 (set (attr "length_immediate")
6402 (if_then_else
6403 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6404 (const_string "1")
6405 (const_string "*")))
6406 (set_attr "mode" "<MODE>")])
6407
6408 ;; It may seem that nonimmediate operand is proper one for operand 1.
6409 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6410 ;; we take care in ix86_binary_operator_ok to not allow two memory
6411 ;; operands so proper swapping will be done in reload. This allow
6412 ;; patterns constructed from addsi_1 to match.
6413
6414 (define_insn "addsi_1_zext"
6415 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6416 (zero_extend:DI
6417 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6418 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6419 (clobber (reg:CC FLAGS_REG))]
6420 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6421 {
6422 switch (get_attr_type (insn))
6423 {
6424 case TYPE_LEA:
6425 return "#";
6426
6427 case TYPE_INCDEC:
6428 if (operands[2] == const1_rtx)
6429 return "inc{l}\t%k0";
6430 else
6431 {
6432 gcc_assert (operands[2] == constm1_rtx);
6433 return "dec{l}\t%k0";
6434 }
6435
6436 default:
6437 /* For most processors, ADD is faster than LEA. This alternative
6438 was added to use ADD as much as possible. */
6439 if (which_alternative == 1)
6440 std::swap (operands[1], operands[2]);
6441
6442 if (x86_maybe_negate_const_int (&operands[2], SImode))
6443 return "sub{l}\t{%2, %k0|%k0, %2}";
6444
6445 return "add{l}\t{%2, %k0|%k0, %2}";
6446 }
6447 }
6448 [(set (attr "type")
6449 (cond [(eq_attr "alternative" "2")
6450 (const_string "lea")
6451 (match_operand:SI 2 "incdec_operand")
6452 (const_string "incdec")
6453 ]
6454 (const_string "alu")))
6455 (set (attr "length_immediate")
6456 (if_then_else
6457 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6458 (const_string "1")
6459 (const_string "*")))
6460 (set_attr "mode" "SI")])
6461
6462 (define_insn "*addhi_1"
6463 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6464 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6465 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6468 {
6469 switch (get_attr_type (insn))
6470 {
6471 case TYPE_LEA:
6472 return "#";
6473
6474 case TYPE_INCDEC:
6475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6476 if (operands[2] == const1_rtx)
6477 return "inc{w}\t%0";
6478 else
6479 {
6480 gcc_assert (operands[2] == constm1_rtx);
6481 return "dec{w}\t%0";
6482 }
6483
6484 default:
6485 /* For most processors, ADD is faster than LEA. This alternative
6486 was added to use ADD as much as possible. */
6487 if (which_alternative == 2)
6488 std::swap (operands[1], operands[2]);
6489
6490 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6491 if (x86_maybe_negate_const_int (&operands[2], HImode))
6492 return "sub{w}\t{%2, %0|%0, %2}";
6493
6494 return "add{w}\t{%2, %0|%0, %2}";
6495 }
6496 }
6497 [(set (attr "type")
6498 (cond [(eq_attr "alternative" "3")
6499 (const_string "lea")
6500 (match_operand:HI 2 "incdec_operand")
6501 (const_string "incdec")
6502 ]
6503 (const_string "alu")))
6504 (set (attr "length_immediate")
6505 (if_then_else
6506 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6507 (const_string "1")
6508 (const_string "*")))
6509 (set_attr "mode" "HI,HI,HI,SI")])
6510
6511 (define_insn "*addqi_1"
6512 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6513 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6514 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6515 (clobber (reg:CC FLAGS_REG))]
6516 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6517 {
6518 bool widen = (get_attr_mode (insn) != MODE_QI);
6519
6520 switch (get_attr_type (insn))
6521 {
6522 case TYPE_LEA:
6523 return "#";
6524
6525 case TYPE_INCDEC:
6526 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6527 if (operands[2] == const1_rtx)
6528 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6529 else
6530 {
6531 gcc_assert (operands[2] == constm1_rtx);
6532 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6533 }
6534
6535 default:
6536 /* For most processors, ADD is faster than LEA. These alternatives
6537 were added to use ADD as much as possible. */
6538 if (which_alternative == 2 || which_alternative == 4)
6539 std::swap (operands[1], operands[2]);
6540
6541 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6542 if (x86_maybe_negate_const_int (&operands[2], QImode))
6543 {
6544 if (widen)
6545 return "sub{l}\t{%2, %k0|%k0, %2}";
6546 else
6547 return "sub{b}\t{%2, %0|%0, %2}";
6548 }
6549 if (widen)
6550 return "add{l}\t{%k2, %k0|%k0, %k2}";
6551 else
6552 return "add{b}\t{%2, %0|%0, %2}";
6553 }
6554 }
6555 [(set (attr "type")
6556 (cond [(eq_attr "alternative" "5")
6557 (const_string "lea")
6558 (match_operand:QI 2 "incdec_operand")
6559 (const_string "incdec")
6560 ]
6561 (const_string "alu")))
6562 (set (attr "length_immediate")
6563 (if_then_else
6564 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6565 (const_string "1")
6566 (const_string "*")))
6567 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6568 ;; Potential partial reg stall on alternatives 3 and 4.
6569 (set (attr "preferred_for_speed")
6570 (cond [(eq_attr "alternative" "3,4")
6571 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6572 (symbol_ref "true")))])
6573
6574 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6575 (define_insn_and_split "*add<mode>_1_slp"
6576 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6577 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6578 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6579 (clobber (reg:CC FLAGS_REG))]
6580 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6581 {
6582 if (which_alternative)
6583 return "#";
6584
6585 switch (get_attr_type (insn))
6586 {
6587 case TYPE_INCDEC:
6588 if (operands[2] == const1_rtx)
6589 return "inc{<imodesuffix>}\t%0";
6590 else
6591 {
6592 gcc_assert (operands[2] == constm1_rtx);
6593 return "dec{<imodesuffix>}\t%0";
6594 }
6595
6596 default:
6597 if (x86_maybe_negate_const_int (&operands[2], QImode))
6598 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6599
6600 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6601 }
6602 }
6603 "&& reload_completed
6604 && !(rtx_equal_p (operands[0], operands[1])
6605 || rtx_equal_p (operands[0], operands[2]))"
6606 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6607 (parallel
6608 [(set (strict_low_part (match_dup 0))
6609 (plus:SWI12 (match_dup 0) (match_dup 2)))
6610 (clobber (reg:CC FLAGS_REG))])]
6611 ""
6612 [(set (attr "type")
6613 (if_then_else (match_operand:QI 2 "incdec_operand")
6614 (const_string "incdec")
6615 (const_string "alu")))
6616 (set_attr "mode" "<MODE>")])
6617
6618 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6619 (define_insn_and_split "*addqi_ext<mode>_1_slp"
6620 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
6621 (plus:QI
6622 (subreg:QI
6623 (match_operator:SWI248 3 "extract_operator"
6624 [(match_operand 2 "int248_register_operand" "Q,Q")
6625 (const_int 8)
6626 (const_int 8)]) 0)
6627 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
6628 (clobber (reg:CC FLAGS_REG))]
6629 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6630 "@
6631 add{b}\t{%h2, %0|%0, %h2}
6632 #"
6633 "&& reload_completed
6634 && !rtx_equal_p (operands[0], operands[1])"
6635 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6636 (parallel
6637 [(set (strict_low_part (match_dup 0))
6638 (plus:QI
6639 (subreg:QI
6640 (match_op_dup 3
6641 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
6642 (match_dup 0)))
6643 (clobber (reg:CC FLAGS_REG))])]
6644 ""
6645 [(set_attr "type" "alu")
6646 (set_attr "mode" "QI")])
6647
6648 ;; Split non destructive adds if we cannot use lea.
6649 (define_split
6650 [(set (match_operand:SWI48 0 "register_operand")
6651 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6652 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6653 (clobber (reg:CC FLAGS_REG))]
6654 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6655 [(set (match_dup 0) (match_dup 1))
6656 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6657 (clobber (reg:CC FLAGS_REG))])])
6658
6659 ;; Split non destructive adds if we cannot use lea.
6660 (define_split
6661 [(set (match_operand:DI 0 "register_operand")
6662 (zero_extend:DI
6663 (plus:SI (match_operand:SI 1 "register_operand")
6664 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6665 (clobber (reg:CC FLAGS_REG))]
6666 "TARGET_64BIT
6667 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6668 [(set (match_dup 3) (match_dup 1))
6669 (parallel [(set (match_dup 0)
6670 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6671 (clobber (reg:CC FLAGS_REG))])]
6672 "operands[3] = gen_lowpart (SImode, operands[0]);")
6673
6674 ;; Convert add to the lea pattern to avoid flags dependency.
6675 (define_split
6676 [(set (match_operand:SWI 0 "register_operand")
6677 (plus:SWI (match_operand:SWI 1 "register_operand")
6678 (match_operand:SWI 2 "<nonmemory_operand>")))
6679 (clobber (reg:CC FLAGS_REG))]
6680 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6681 [(set (match_dup 0)
6682 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6683 {
6684 if (<MODE>mode != <LEAMODE>mode)
6685 {
6686 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6687 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6688 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6689 }
6690 })
6691
6692 ;; Convert add to the lea pattern to avoid flags dependency.
6693 (define_split
6694 [(set (match_operand:DI 0 "register_operand")
6695 (zero_extend:DI
6696 (plus:SI (match_operand:SI 1 "register_operand")
6697 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6698 (clobber (reg:CC FLAGS_REG))]
6699 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6700 [(set (match_dup 0)
6701 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6702
6703 (define_insn "*add<mode>_2"
6704 [(set (reg FLAGS_REG)
6705 (compare
6706 (plus:SWI
6707 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6708 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6709 (const_int 0)))
6710 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6711 (plus:SWI (match_dup 1) (match_dup 2)))]
6712 "ix86_match_ccmode (insn, CCGOCmode)
6713 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6714 {
6715 switch (get_attr_type (insn))
6716 {
6717 case TYPE_INCDEC:
6718 if (operands[2] == const1_rtx)
6719 return "inc{<imodesuffix>}\t%0";
6720 else
6721 {
6722 gcc_assert (operands[2] == constm1_rtx);
6723 return "dec{<imodesuffix>}\t%0";
6724 }
6725
6726 default:
6727 if (which_alternative == 2)
6728 std::swap (operands[1], operands[2]);
6729
6730 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6731 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6732 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6733
6734 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6735 }
6736 }
6737 [(set (attr "type")
6738 (if_then_else (match_operand:SWI 2 "incdec_operand")
6739 (const_string "incdec")
6740 (const_string "alu")))
6741 (set (attr "length_immediate")
6742 (if_then_else
6743 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6744 (const_string "1")
6745 (const_string "*")))
6746 (set_attr "mode" "<MODE>")])
6747
6748 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6749 (define_insn "*addsi_2_zext"
6750 [(set (reg FLAGS_REG)
6751 (compare
6752 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6753 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6754 (const_int 0)))
6755 (set (match_operand:DI 0 "register_operand" "=r,r")
6756 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6757 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6758 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6759 {
6760 switch (get_attr_type (insn))
6761 {
6762 case TYPE_INCDEC:
6763 if (operands[2] == const1_rtx)
6764 return "inc{l}\t%k0";
6765 else
6766 {
6767 gcc_assert (operands[2] == constm1_rtx);
6768 return "dec{l}\t%k0";
6769 }
6770
6771 default:
6772 if (which_alternative == 1)
6773 std::swap (operands[1], operands[2]);
6774
6775 if (x86_maybe_negate_const_int (&operands[2], SImode))
6776 return "sub{l}\t{%2, %k0|%k0, %2}";
6777
6778 return "add{l}\t{%2, %k0|%k0, %2}";
6779 }
6780 }
6781 [(set (attr "type")
6782 (if_then_else (match_operand:SI 2 "incdec_operand")
6783 (const_string "incdec")
6784 (const_string "alu")))
6785 (set (attr "length_immediate")
6786 (if_then_else
6787 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6788 (const_string "1")
6789 (const_string "*")))
6790 (set_attr "mode" "SI")])
6791
6792 (define_insn "*add<mode>_3"
6793 [(set (reg FLAGS_REG)
6794 (compare
6795 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6796 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6797 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6798 "ix86_match_ccmode (insn, CCZmode)
6799 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6800 {
6801 switch (get_attr_type (insn))
6802 {
6803 case TYPE_INCDEC:
6804 if (operands[2] == const1_rtx)
6805 return "inc{<imodesuffix>}\t%0";
6806 else
6807 {
6808 gcc_assert (operands[2] == constm1_rtx);
6809 return "dec{<imodesuffix>}\t%0";
6810 }
6811
6812 default:
6813 if (which_alternative == 1)
6814 std::swap (operands[1], operands[2]);
6815
6816 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6817 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6818 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6819
6820 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6821 }
6822 }
6823 [(set (attr "type")
6824 (if_then_else (match_operand:SWI 2 "incdec_operand")
6825 (const_string "incdec")
6826 (const_string "alu")))
6827 (set (attr "length_immediate")
6828 (if_then_else
6829 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6830 (const_string "1")
6831 (const_string "*")))
6832 (set_attr "mode" "<MODE>")])
6833
6834 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6835 (define_insn "*addsi_3_zext"
6836 [(set (reg FLAGS_REG)
6837 (compare
6838 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6839 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6840 (set (match_operand:DI 0 "register_operand" "=r,r")
6841 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6842 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6843 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6844 {
6845 switch (get_attr_type (insn))
6846 {
6847 case TYPE_INCDEC:
6848 if (operands[2] == const1_rtx)
6849 return "inc{l}\t%k0";
6850 else
6851 {
6852 gcc_assert (operands[2] == constm1_rtx);
6853 return "dec{l}\t%k0";
6854 }
6855
6856 default:
6857 if (which_alternative == 1)
6858 std::swap (operands[1], operands[2]);
6859
6860 if (x86_maybe_negate_const_int (&operands[2], SImode))
6861 return "sub{l}\t{%2, %k0|%k0, %2}";
6862
6863 return "add{l}\t{%2, %k0|%k0, %2}";
6864 }
6865 }
6866 [(set (attr "type")
6867 (if_then_else (match_operand:SI 2 "incdec_operand")
6868 (const_string "incdec")
6869 (const_string "alu")))
6870 (set (attr "length_immediate")
6871 (if_then_else
6872 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6873 (const_string "1")
6874 (const_string "*")))
6875 (set_attr "mode" "SI")])
6876
6877 ; For comparisons against 1, -1 and 128, we may generate better code
6878 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6879 ; is matched then. We can't accept general immediate, because for
6880 ; case of overflows, the result is messed up.
6881 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6882 ; only for comparisons not depending on it.
6883
6884 (define_insn "*adddi_4"
6885 [(set (reg FLAGS_REG)
6886 (compare
6887 (match_operand:DI 1 "nonimmediate_operand" "0")
6888 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6889 (clobber (match_scratch:DI 0 "=r"))]
6890 "TARGET_64BIT
6891 && ix86_match_ccmode (insn, CCGCmode)"
6892 {
6893 switch (get_attr_type (insn))
6894 {
6895 case TYPE_INCDEC:
6896 if (operands[2] == constm1_rtx)
6897 return "inc{q}\t%0";
6898 else
6899 {
6900 gcc_assert (operands[2] == const1_rtx);
6901 return "dec{q}\t%0";
6902 }
6903
6904 default:
6905 if (x86_maybe_negate_const_int (&operands[2], DImode))
6906 return "add{q}\t{%2, %0|%0, %2}";
6907
6908 return "sub{q}\t{%2, %0|%0, %2}";
6909 }
6910 }
6911 [(set (attr "type")
6912 (if_then_else (match_operand:DI 2 "incdec_operand")
6913 (const_string "incdec")
6914 (const_string "alu")))
6915 (set (attr "length_immediate")
6916 (if_then_else
6917 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6918 (const_string "1")
6919 (const_string "*")))
6920 (set_attr "mode" "DI")])
6921
6922 ; For comparisons against 1, -1 and 128, we may generate better code
6923 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6924 ; is matched then. We can't accept general immediate, because for
6925 ; case of overflows, the result is messed up.
6926 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6927 ; only for comparisons not depending on it.
6928
6929 (define_insn "*add<mode>_4"
6930 [(set (reg FLAGS_REG)
6931 (compare
6932 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6933 (match_operand:SWI124 2 "const_int_operand")))
6934 (clobber (match_scratch:SWI124 0 "=<r>"))]
6935 "ix86_match_ccmode (insn, CCGCmode)"
6936 {
6937 switch (get_attr_type (insn))
6938 {
6939 case TYPE_INCDEC:
6940 if (operands[2] == constm1_rtx)
6941 return "inc{<imodesuffix>}\t%0";
6942 else
6943 {
6944 gcc_assert (operands[2] == const1_rtx);
6945 return "dec{<imodesuffix>}\t%0";
6946 }
6947
6948 default:
6949 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6950 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6951
6952 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6953 }
6954 }
6955 [(set (attr "type")
6956 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6957 (const_string "incdec")
6958 (const_string "alu")))
6959 (set (attr "length_immediate")
6960 (if_then_else
6961 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6962 (const_string "1")
6963 (const_string "*")))
6964 (set_attr "mode" "<MODE>")])
6965
6966 (define_insn "*add<mode>_5"
6967 [(set (reg FLAGS_REG)
6968 (compare
6969 (plus:SWI
6970 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6971 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6972 (const_int 0)))
6973 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6974 "ix86_match_ccmode (insn, CCGOCmode)
6975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6976 {
6977 switch (get_attr_type (insn))
6978 {
6979 case TYPE_INCDEC:
6980 if (operands[2] == const1_rtx)
6981 return "inc{<imodesuffix>}\t%0";
6982 else
6983 {
6984 gcc_assert (operands[2] == constm1_rtx);
6985 return "dec{<imodesuffix>}\t%0";
6986 }
6987
6988 default:
6989 if (which_alternative == 1)
6990 std::swap (operands[1], operands[2]);
6991
6992 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6993 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6994 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6995
6996 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6997 }
6998 }
6999 [(set (attr "type")
7000 (if_then_else (match_operand:SWI 2 "incdec_operand")
7001 (const_string "incdec")
7002 (const_string "alu")))
7003 (set (attr "length_immediate")
7004 (if_then_else
7005 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7006 (const_string "1")
7007 (const_string "*")))
7008 (set_attr "mode" "<MODE>")])
7009
7010 (define_insn "*addqi_ext<mode>_0"
7011 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7012 (plus:QI
7013 (subreg:QI
7014 (match_operator:SWI248 3 "extract_operator"
7015 [(match_operand 2 "int248_register_operand" "Q")
7016 (const_int 8)
7017 (const_int 8)]) 0)
7018 (match_operand:QI 1 "nonimmediate_operand" "0")))
7019 (clobber (reg:CC FLAGS_REG))]
7020 ""
7021 "add{b}\t{%h2, %0|%0, %h2}"
7022 [(set_attr "addr" "gpr8")
7023 (set_attr "type" "alu")
7024 (set_attr "mode" "QI")])
7025
7026 (define_expand "addqi_ext_1"
7027 [(parallel
7028 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7029 (const_int 8)
7030 (const_int 8))
7031 (subreg:HI
7032 (plus:QI
7033 (subreg:QI
7034 (zero_extract:HI (match_operand:HI 1 "register_operand")
7035 (const_int 8)
7036 (const_int 8)) 0)
7037 (match_operand:QI 2 "const_int_operand")) 0))
7038 (clobber (reg:CC FLAGS_REG))])])
7039
7040 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7041 (define_insn_and_split "*addqi_ext<mode>_1"
7042 [(set (zero_extract:SWI248
7043 (match_operand 0 "int248_register_operand" "+Q,&Q")
7044 (const_int 8)
7045 (const_int 8))
7046 (subreg:SWI248
7047 (plus:QI
7048 (subreg:QI
7049 (match_operator:SWI248 3 "extract_operator"
7050 [(match_operand 1 "int248_register_operand" "0,!Q")
7051 (const_int 8)
7052 (const_int 8)]) 0)
7053 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7054 (clobber (reg:CC FLAGS_REG))]
7055 ""
7056 {
7057 if (which_alternative)
7058 return "#";
7059
7060 switch (get_attr_type (insn))
7061 {
7062 case TYPE_INCDEC:
7063 if (operands[2] == const1_rtx)
7064 return "inc{b}\t%h0";
7065 else
7066 {
7067 gcc_assert (operands[2] == constm1_rtx);
7068 return "dec{b}\t%h0";
7069 }
7070
7071 default:
7072 return "add{b}\t{%2, %h0|%h0, %2}";
7073 }
7074 }
7075 "reload_completed
7076 && !rtx_equal_p (operands[0], operands[1])"
7077 [(set (zero_extract:SWI248
7078 (match_dup 0) (const_int 8) (const_int 8))
7079 (zero_extract:SWI248
7080 (match_dup 1) (const_int 8) (const_int 8)))
7081 (parallel
7082 [(set (zero_extract:SWI248
7083 (match_dup 0) (const_int 8) (const_int 8))
7084 (subreg:SWI248
7085 (plus:QI
7086 (subreg:QI
7087 (match_op_dup 3
7088 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7089 (match_dup 2)) 0))
7090 (clobber (reg:CC FLAGS_REG))])]
7091 ""
7092 [(set_attr "addr" "gpr8")
7093 (set (attr "type")
7094 (if_then_else (match_operand:QI 2 "incdec_operand")
7095 (const_string "incdec")
7096 (const_string "alu")))
7097 (set_attr "mode" "QI")])
7098
7099 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7100 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7101 [(set (zero_extract:SWI248
7102 (match_operand 0 "int248_register_operand" "+Q,&Q")
7103 (const_int 8)
7104 (const_int 8))
7105 (subreg:SWI248
7106 (plusminus:QI
7107 (subreg:QI
7108 (match_operator:SWI248 3 "extract_operator"
7109 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7110 (const_int 8)
7111 (const_int 8)]) 0)
7112 (subreg:QI
7113 (match_operator:SWI248 4 "extract_operator"
7114 [(match_operand 2 "int248_register_operand" "Q,Q")
7115 (const_int 8)
7116 (const_int 8)]) 0)) 0))
7117 (clobber (reg:CC FLAGS_REG))]
7118 ""
7119 "@
7120 <insn>{b}\t{%h2, %h0|%h0, %h2}
7121 #"
7122 "reload_completed
7123 && !(rtx_equal_p (operands[0], operands[1])
7124 || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7125 [(set (zero_extract:SWI248
7126 (match_dup 0) (const_int 8) (const_int 8))
7127 (zero_extract:SWI248
7128 (match_dup 1) (const_int 8) (const_int 8)))
7129 (parallel
7130 [(set (zero_extract:SWI248
7131 (match_dup 0) (const_int 8) (const_int 8))
7132 (subreg:SWI248
7133 (plusminus:QI
7134 (subreg:QI
7135 (match_op_dup 3
7136 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7137 (subreg:QI
7138 (match_op_dup 4
7139 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7140 (clobber (reg:CC FLAGS_REG))])]
7141 ""
7142 [(set_attr "type" "alu")
7143 (set_attr "mode" "QI")])
7144
7145 ;; Like DWI, but use POImode instead of OImode.
7146 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7147
7148 ;; Add with jump on overflow.
7149 (define_expand "addv<mode>4"
7150 [(parallel [(set (reg:CCO FLAGS_REG)
7151 (eq:CCO
7152 (plus:<DPWI>
7153 (sign_extend:<DPWI>
7154 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7155 (match_dup 4))
7156 (sign_extend:<DPWI>
7157 (plus:SWIDWI (match_dup 1)
7158 (match_operand:SWIDWI 2
7159 "<general_hilo_operand>")))))
7160 (set (match_operand:SWIDWI 0 "register_operand")
7161 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7162 (set (pc) (if_then_else
7163 (eq (reg:CCO FLAGS_REG) (const_int 0))
7164 (label_ref (match_operand 3))
7165 (pc)))]
7166 ""
7167 {
7168 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7169 if (CONST_SCALAR_INT_P (operands[2]))
7170 operands[4] = operands[2];
7171 else
7172 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7173 })
7174
7175 (define_insn "*addv<mode>4"
7176 [(set (reg:CCO FLAGS_REG)
7177 (eq:CCO (plus:<DWI>
7178 (sign_extend:<DWI>
7179 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7180 (sign_extend:<DWI>
7181 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7182 (sign_extend:<DWI>
7183 (plus:SWI (match_dup 1) (match_dup 2)))))
7184 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7185 (plus:SWI (match_dup 1) (match_dup 2)))]
7186 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7187 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7188 [(set_attr "type" "alu")
7189 (set_attr "mode" "<MODE>")])
7190
7191 (define_insn "addv<mode>4_1"
7192 [(set (reg:CCO FLAGS_REG)
7193 (eq:CCO (plus:<DWI>
7194 (sign_extend:<DWI>
7195 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7196 (match_operand:<DWI> 3 "const_int_operand"))
7197 (sign_extend:<DWI>
7198 (plus:SWI
7199 (match_dup 1)
7200 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7201 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7202 (plus:SWI (match_dup 1) (match_dup 2)))]
7203 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7204 && CONST_INT_P (operands[2])
7205 && INTVAL (operands[2]) == INTVAL (operands[3])"
7206 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7207 [(set_attr "type" "alu")
7208 (set_attr "mode" "<MODE>")
7209 (set (attr "length_immediate")
7210 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7211 (const_string "1")
7212 (match_test "<MODE_SIZE> == 8")
7213 (const_string "4")]
7214 (const_string "<MODE_SIZE>")))])
7215
7216 ;; Quad word integer modes as mode attribute.
7217 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7218
7219 (define_insn_and_split "*addv<dwi>4_doubleword"
7220 [(set (reg:CCO FLAGS_REG)
7221 (eq:CCO
7222 (plus:<QPWI>
7223 (sign_extend:<QPWI>
7224 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7225 (sign_extend:<QPWI>
7226 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7227 (sign_extend:<QPWI>
7228 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7229 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7230 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7231 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7232 "#"
7233 "&& reload_completed"
7234 [(parallel [(set (reg:CCC FLAGS_REG)
7235 (compare:CCC
7236 (plus:DWIH (match_dup 1) (match_dup 2))
7237 (match_dup 1)))
7238 (set (match_dup 0)
7239 (plus:DWIH (match_dup 1) (match_dup 2)))])
7240 (parallel [(set (reg:CCO FLAGS_REG)
7241 (eq:CCO
7242 (plus:<DWI>
7243 (plus:<DWI>
7244 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7245 (sign_extend:<DWI> (match_dup 4)))
7246 (sign_extend:<DWI> (match_dup 5)))
7247 (sign_extend:<DWI>
7248 (plus:DWIH
7249 (plus:DWIH
7250 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7251 (match_dup 4))
7252 (match_dup 5)))))
7253 (set (match_dup 3)
7254 (plus:DWIH
7255 (plus:DWIH
7256 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7257 (match_dup 4))
7258 (match_dup 5)))])]
7259 {
7260 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7261 })
7262
7263 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7264 [(set (reg:CCO FLAGS_REG)
7265 (eq:CCO
7266 (plus:<QPWI>
7267 (sign_extend:<QPWI>
7268 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7269 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7270 (sign_extend:<QPWI>
7271 (plus:<DWI>
7272 (match_dup 1)
7273 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7274 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7275 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7276 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7277 && CONST_SCALAR_INT_P (operands[2])
7278 && rtx_equal_p (operands[2], operands[3])"
7279 "#"
7280 "&& reload_completed"
7281 [(parallel [(set (reg:CCC FLAGS_REG)
7282 (compare:CCC
7283 (plus:DWIH (match_dup 1) (match_dup 2))
7284 (match_dup 1)))
7285 (set (match_dup 0)
7286 (plus:DWIH (match_dup 1) (match_dup 2)))])
7287 (parallel [(set (reg:CCO FLAGS_REG)
7288 (eq:CCO
7289 (plus:<DWI>
7290 (plus:<DWI>
7291 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7292 (sign_extend:<DWI> (match_dup 4)))
7293 (match_dup 5))
7294 (sign_extend:<DWI>
7295 (plus:DWIH
7296 (plus:DWIH
7297 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7298 (match_dup 4))
7299 (match_dup 5)))))
7300 (set (match_dup 3)
7301 (plus:DWIH
7302 (plus:DWIH
7303 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7304 (match_dup 4))
7305 (match_dup 5)))])]
7306 {
7307 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7308 if (operands[2] == const0_rtx)
7309 {
7310 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7311 operands[5]));
7312 DONE;
7313 }
7314 })
7315
7316 (define_insn "*addv<mode>4_overflow_1"
7317 [(set (reg:CCO FLAGS_REG)
7318 (eq:CCO
7319 (plus:<DWI>
7320 (plus:<DWI>
7321 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7322 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7323 (sign_extend:<DWI>
7324 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7325 (sign_extend:<DWI>
7326 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7327 (sign_extend:<DWI>
7328 (plus:SWI
7329 (plus:SWI
7330 (match_operator:SWI 5 "ix86_carry_flag_operator"
7331 [(match_dup 3) (const_int 0)])
7332 (match_dup 1))
7333 (match_dup 2)))))
7334 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7335 (plus:SWI
7336 (plus:SWI
7337 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7338 (match_dup 1))
7339 (match_dup 2)))]
7340 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7341 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7342 [(set_attr "type" "alu")
7343 (set_attr "mode" "<MODE>")])
7344
7345 (define_insn "*addv<mode>4_overflow_2"
7346 [(set (reg:CCO FLAGS_REG)
7347 (eq:CCO
7348 (plus:<DWI>
7349 (plus:<DWI>
7350 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7351 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7352 (sign_extend:<DWI>
7353 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7354 (match_operand:<DWI> 6 "const_int_operand" "n"))
7355 (sign_extend:<DWI>
7356 (plus:SWI
7357 (plus:SWI
7358 (match_operator:SWI 5 "ix86_carry_flag_operator"
7359 [(match_dup 3) (const_int 0)])
7360 (match_dup 1))
7361 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7362 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7363 (plus:SWI
7364 (plus:SWI
7365 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7366 (match_dup 1))
7367 (match_dup 2)))]
7368 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7369 && CONST_INT_P (operands[2])
7370 && INTVAL (operands[2]) == INTVAL (operands[6])"
7371 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7372 [(set_attr "type" "alu")
7373 (set_attr "mode" "<MODE>")
7374 (set (attr "length_immediate")
7375 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7376 (const_string "1")
7377 (const_string "4")))])
7378
7379 (define_expand "uaddv<mode>4"
7380 [(parallel [(set (reg:CCC FLAGS_REG)
7381 (compare:CCC
7382 (plus:SWIDWI
7383 (match_operand:SWIDWI 1 "nonimmediate_operand")
7384 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7385 (match_dup 1)))
7386 (set (match_operand:SWIDWI 0 "register_operand")
7387 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7388 (set (pc) (if_then_else
7389 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7390 (label_ref (match_operand 3))
7391 (pc)))]
7392 ""
7393 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7394
7395 ;; The lea patterns for modes less than 32 bits need to be matched by
7396 ;; several insns converted to real lea by splitters.
7397
7398 (define_insn_and_split "*lea<mode>_general_1"
7399 [(set (match_operand:SWI12 0 "register_operand" "=r")
7400 (plus:SWI12
7401 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7402 (match_operand:SWI12 2 "register_operand" "r"))
7403 (match_operand:SWI12 3 "immediate_operand" "i")))]
7404 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7405 "#"
7406 "&& reload_completed"
7407 [(set (match_dup 0)
7408 (plus:SI
7409 (plus:SI (match_dup 1) (match_dup 2))
7410 (match_dup 3)))]
7411 {
7412 operands[0] = gen_lowpart (SImode, operands[0]);
7413 operands[1] = gen_lowpart (SImode, operands[1]);
7414 operands[2] = gen_lowpart (SImode, operands[2]);
7415 operands[3] = gen_lowpart (SImode, operands[3]);
7416 }
7417 [(set_attr "type" "lea")
7418 (set_attr "mode" "SI")])
7419
7420 (define_insn_and_split "*lea<mode>_general_2"
7421 [(set (match_operand:SWI12 0 "register_operand" "=r")
7422 (plus:SWI12
7423 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7424 (match_operand 2 "const248_operand" "n"))
7425 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7426 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7427 "#"
7428 "&& reload_completed"
7429 [(set (match_dup 0)
7430 (plus:SI
7431 (mult:SI (match_dup 1) (match_dup 2))
7432 (match_dup 3)))]
7433 {
7434 operands[0] = gen_lowpart (SImode, operands[0]);
7435 operands[1] = gen_lowpart (SImode, operands[1]);
7436 operands[3] = gen_lowpart (SImode, operands[3]);
7437 }
7438 [(set_attr "type" "lea")
7439 (set_attr "mode" "SI")])
7440
7441 (define_insn_and_split "*lea<mode>_general_2b"
7442 [(set (match_operand:SWI12 0 "register_operand" "=r")
7443 (plus:SWI12
7444 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7445 (match_operand 2 "const123_operand" "n"))
7446 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7448 "#"
7449 "&& reload_completed"
7450 [(set (match_dup 0)
7451 (plus:SI
7452 (ashift:SI (match_dup 1) (match_dup 2))
7453 (match_dup 3)))]
7454 {
7455 operands[0] = gen_lowpart (SImode, operands[0]);
7456 operands[1] = gen_lowpart (SImode, operands[1]);
7457 operands[3] = gen_lowpart (SImode, operands[3]);
7458 }
7459 [(set_attr "type" "lea")
7460 (set_attr "mode" "SI")])
7461
7462 (define_insn_and_split "*lea<mode>_general_3"
7463 [(set (match_operand:SWI12 0 "register_operand" "=r")
7464 (plus:SWI12
7465 (plus:SWI12
7466 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7467 (match_operand 2 "const248_operand" "n"))
7468 (match_operand:SWI12 3 "register_operand" "r"))
7469 (match_operand:SWI12 4 "immediate_operand" "i")))]
7470 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7471 "#"
7472 "&& reload_completed"
7473 [(set (match_dup 0)
7474 (plus:SI
7475 (plus:SI
7476 (mult:SI (match_dup 1) (match_dup 2))
7477 (match_dup 3))
7478 (match_dup 4)))]
7479 {
7480 operands[0] = gen_lowpart (SImode, operands[0]);
7481 operands[1] = gen_lowpart (SImode, operands[1]);
7482 operands[3] = gen_lowpart (SImode, operands[3]);
7483 operands[4] = gen_lowpart (SImode, operands[4]);
7484 }
7485 [(set_attr "type" "lea")
7486 (set_attr "mode" "SI")])
7487
7488 (define_insn_and_split "*lea<mode>_general_3b"
7489 [(set (match_operand:SWI12 0 "register_operand" "=r")
7490 (plus:SWI12
7491 (plus:SWI12
7492 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7493 (match_operand 2 "const123_operand" "n"))
7494 (match_operand:SWI12 3 "register_operand" "r"))
7495 (match_operand:SWI12 4 "immediate_operand" "i")))]
7496 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7497 "#"
7498 "&& reload_completed"
7499 [(set (match_dup 0)
7500 (plus:SI
7501 (plus:SI
7502 (ashift:SI (match_dup 1) (match_dup 2))
7503 (match_dup 3))
7504 (match_dup 4)))]
7505 {
7506 operands[0] = gen_lowpart (SImode, operands[0]);
7507 operands[1] = gen_lowpart (SImode, operands[1]);
7508 operands[3] = gen_lowpart (SImode, operands[3]);
7509 operands[4] = gen_lowpart (SImode, operands[4]);
7510 }
7511 [(set_attr "type" "lea")
7512 (set_attr "mode" "SI")])
7513
7514 (define_insn_and_split "*lea<mode>_general_4"
7515 [(set (match_operand:SWI12 0 "register_operand" "=r")
7516 (any_or:SWI12
7517 (ashift:SWI12
7518 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7519 (match_operand 2 "const_0_to_3_operand"))
7520 (match_operand 3 "const_int_operand")))]
7521 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7522 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7523 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7524 "#"
7525 "&& reload_completed"
7526 [(set (match_dup 0)
7527 (plus:SI
7528 (mult:SI (match_dup 1) (match_dup 2))
7529 (match_dup 3)))]
7530 {
7531 operands[0] = gen_lowpart (SImode, operands[0]);
7532 operands[1] = gen_lowpart (SImode, operands[1]);
7533 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7534 }
7535 [(set_attr "type" "lea")
7536 (set_attr "mode" "SI")])
7537
7538 (define_insn_and_split "*lea<mode>_general_4"
7539 [(set (match_operand:SWI48 0 "register_operand" "=r")
7540 (any_or:SWI48
7541 (ashift:SWI48
7542 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7543 (match_operand 2 "const_0_to_3_operand"))
7544 (match_operand 3 "const_int_operand")))]
7545 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7546 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7547 "#"
7548 "&& reload_completed"
7549 [(set (match_dup 0)
7550 (plus:SWI48
7551 (mult:SWI48 (match_dup 1) (match_dup 2))
7552 (match_dup 3)))]
7553 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7554 [(set_attr "type" "lea")
7555 (set_attr "mode" "<MODE>")])
7556 \f
7557 ;; Subtract instructions
7558
7559 (define_expand "sub<mode>3"
7560 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7561 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7562 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7563 ""
7564 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7565
7566 (define_insn_and_split "*sub<dwi>3_doubleword"
7567 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7568 (minus:<DWI>
7569 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7570 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7571 (clobber (reg:CC FLAGS_REG))]
7572 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7573 "#"
7574 "&& reload_completed"
7575 [(parallel [(set (reg:CC FLAGS_REG)
7576 (compare:CC (match_dup 1) (match_dup 2)))
7577 (set (match_dup 0)
7578 (minus:DWIH (match_dup 1) (match_dup 2)))])
7579 (parallel [(set (match_dup 3)
7580 (minus:DWIH
7581 (minus:DWIH
7582 (match_dup 4)
7583 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7584 (match_dup 5)))
7585 (clobber (reg:CC FLAGS_REG))])]
7586 {
7587 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7588 if (operands[2] == const0_rtx)
7589 {
7590 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7591 DONE;
7592 }
7593 })
7594
7595 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7596 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7597 (minus:<DWI>
7598 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7599 (zero_extend:<DWI>
7600 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7601 (clobber (reg:CC FLAGS_REG))]
7602 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7603 "#"
7604 "&& reload_completed"
7605 [(parallel [(set (reg:CC FLAGS_REG)
7606 (compare:CC (match_dup 1) (match_dup 2)))
7607 (set (match_dup 0)
7608 (minus:DWIH (match_dup 1) (match_dup 2)))])
7609 (parallel [(set (match_dup 3)
7610 (minus:DWIH
7611 (minus:DWIH
7612 (match_dup 4)
7613 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7614 (const_int 0)))
7615 (clobber (reg:CC FLAGS_REG))])]
7616 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7617
7618 (define_insn "*sub<mode>_1"
7619 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7620 (minus:SWI
7621 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7622 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7625 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7626 [(set_attr "type" "alu")
7627 (set_attr "mode" "<MODE>")])
7628
7629 (define_insn "*subsi_1_zext"
7630 [(set (match_operand:DI 0 "register_operand" "=r")
7631 (zero_extend:DI
7632 (minus:SI (match_operand:SI 1 "register_operand" "0")
7633 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7634 (clobber (reg:CC FLAGS_REG))]
7635 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7636 "sub{l}\t{%2, %k0|%k0, %2}"
7637 [(set_attr "type" "alu")
7638 (set_attr "mode" "SI")])
7639
7640 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7641 (define_insn_and_split "*sub<mode>_1_slp"
7642 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7643 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7644 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7645 (clobber (reg:CC FLAGS_REG))]
7646 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7647 "@
7648 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7649 #"
7650 "&& reload_completed
7651 && !(rtx_equal_p (operands[0], operands[1]))"
7652 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7653 (parallel
7654 [(set (strict_low_part (match_dup 0))
7655 (minus:SWI12 (match_dup 0) (match_dup 2)))
7656 (clobber (reg:CC FLAGS_REG))])]
7657 ""
7658 [(set_attr "type" "alu")
7659 (set_attr "mode" "<MODE>")])
7660
7661 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7662 (define_insn_and_split "*subqi_ext<mode>_1_slp"
7663 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
7664 (minus:QI
7665 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
7666 (subreg:QI
7667 (match_operator:SWI248 3 "extract_operator"
7668 [(match_operand 2 "int248_register_operand" "Q,Q")
7669 (const_int 8)
7670 (const_int 8)]) 0)))
7671 (clobber (reg:CC FLAGS_REG))]
7672 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7673 "@
7674 sub{b}\t{%h2, %0|%0, %h2}
7675 #"
7676 "&& reload_completed
7677 && !rtx_equal_p (operands[0], operands[1])"
7678 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7679 (parallel
7680 [(set (strict_low_part (match_dup 0))
7681 (minus:QI
7682 (match_dup 0)
7683 (subreg:QI
7684 (match_op_dup 3
7685 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7686 (clobber (reg:CC FLAGS_REG))])]
7687 ""
7688 [(set_attr "type" "alu")
7689 (set_attr "mode" "QI")])
7690
7691 (define_insn "*sub<mode>_2"
7692 [(set (reg FLAGS_REG)
7693 (compare
7694 (minus:SWI
7695 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7696 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7697 (const_int 0)))
7698 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7699 (minus:SWI (match_dup 1) (match_dup 2)))]
7700 "ix86_match_ccmode (insn, CCGOCmode)
7701 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7702 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7703 [(set_attr "type" "alu")
7704 (set_attr "mode" "<MODE>")])
7705
7706 (define_insn "*subsi_2_zext"
7707 [(set (reg FLAGS_REG)
7708 (compare
7709 (minus:SI (match_operand:SI 1 "register_operand" "0")
7710 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7711 (const_int 0)))
7712 (set (match_operand:DI 0 "register_operand" "=r")
7713 (zero_extend:DI
7714 (minus:SI (match_dup 1)
7715 (match_dup 2))))]
7716 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7717 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7718 "sub{l}\t{%2, %k0|%k0, %2}"
7719 [(set_attr "type" "alu")
7720 (set_attr "mode" "SI")])
7721
7722 (define_insn "*subqi_ext<mode>_0"
7723 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7724 (minus:QI
7725 (match_operand:QI 1 "nonimmediate_operand" "0")
7726 (subreg:QI
7727 (match_operator:SWI248 3 "extract_operator"
7728 [(match_operand 2 "int248_register_operand" "Q")
7729 (const_int 8)
7730 (const_int 8)]) 0)))
7731 (clobber (reg:CC FLAGS_REG))]
7732 ""
7733 "sub{b}\t{%h2, %0|%0, %h2}"
7734 [(set_attr "addr" "gpr8")
7735 (set_attr "type" "alu")
7736 (set_attr "mode" "QI")])
7737
7738 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7739 (define_insn_and_split "*subqi_ext<mode>_1"
7740 [(set (zero_extract:SWI248
7741 (match_operand 0 "int248_register_operand" "+Q,&Q")
7742 (const_int 8)
7743 (const_int 8))
7744 (subreg:SWI248
7745 (minus:QI
7746 (subreg:QI
7747 (match_operator:SWI248 3 "extract_operator"
7748 [(match_operand 1 "int248_register_operand" "0,!Q")
7749 (const_int 8)
7750 (const_int 8)]) 0)
7751 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7752 (clobber (reg:CC FLAGS_REG))]
7753 ""
7754 "@
7755 sub{b}\t{%2, %h0|%h0, %2}
7756 #"
7757 "reload_completed
7758 && !(rtx_equal_p (operands[0], operands[1]))"
7759 [(set (zero_extract:SWI248
7760 (match_dup 0) (const_int 8) (const_int 8))
7761 (zero_extract:SWI248
7762 (match_dup 1) (const_int 8) (const_int 8)))
7763 (parallel
7764 [(set (zero_extract:SWI248
7765 (match_dup 0) (const_int 8) (const_int 8))
7766 (subreg:SWI248
7767 (minus:QI
7768 (subreg:QI
7769 (match_op_dup 3
7770 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7771 (match_dup 2)) 0))
7772 (clobber (reg:CC FLAGS_REG))])]
7773 ""
7774 [(set_attr "addr" "gpr8")
7775 (set_attr "type" "alu")
7776 (set_attr "mode" "QI")])
7777
7778 ;; Subtract with jump on overflow.
7779 (define_expand "subv<mode>4"
7780 [(parallel [(set (reg:CCO FLAGS_REG)
7781 (eq:CCO
7782 (minus:<DPWI>
7783 (sign_extend:<DPWI>
7784 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7785 (match_dup 4))
7786 (sign_extend:<DPWI>
7787 (minus:SWIDWI (match_dup 1)
7788 (match_operand:SWIDWI 2
7789 "<general_hilo_operand>")))))
7790 (set (match_operand:SWIDWI 0 "register_operand")
7791 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7792 (set (pc) (if_then_else
7793 (eq (reg:CCO FLAGS_REG) (const_int 0))
7794 (label_ref (match_operand 3))
7795 (pc)))]
7796 ""
7797 {
7798 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7799 if (CONST_SCALAR_INT_P (operands[2]))
7800 operands[4] = operands[2];
7801 else
7802 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7803 })
7804
7805 (define_insn "*subv<mode>4"
7806 [(set (reg:CCO FLAGS_REG)
7807 (eq:CCO (minus:<DWI>
7808 (sign_extend:<DWI>
7809 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7810 (sign_extend:<DWI>
7811 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7812 (sign_extend:<DWI>
7813 (minus:SWI (match_dup 1) (match_dup 2)))))
7814 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7815 (minus:SWI (match_dup 1) (match_dup 2)))]
7816 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7817 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7818 [(set_attr "type" "alu")
7819 (set_attr "mode" "<MODE>")])
7820
7821 (define_insn "subv<mode>4_1"
7822 [(set (reg:CCO FLAGS_REG)
7823 (eq:CCO (minus:<DWI>
7824 (sign_extend:<DWI>
7825 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7826 (match_operand:<DWI> 3 "const_int_operand"))
7827 (sign_extend:<DWI>
7828 (minus:SWI
7829 (match_dup 1)
7830 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7831 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7832 (minus:SWI (match_dup 1) (match_dup 2)))]
7833 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7834 && CONST_INT_P (operands[2])
7835 && INTVAL (operands[2]) == INTVAL (operands[3])"
7836 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7837 [(set_attr "type" "alu")
7838 (set_attr "mode" "<MODE>")
7839 (set (attr "length_immediate")
7840 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7841 (const_string "1")
7842 (match_test "<MODE_SIZE> == 8")
7843 (const_string "4")]
7844 (const_string "<MODE_SIZE>")))])
7845
7846 (define_insn_and_split "*subv<dwi>4_doubleword"
7847 [(set (reg:CCO FLAGS_REG)
7848 (eq:CCO
7849 (minus:<QPWI>
7850 (sign_extend:<QPWI>
7851 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7852 (sign_extend:<QPWI>
7853 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7854 (sign_extend:<QPWI>
7855 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7856 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7857 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7858 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7859 "#"
7860 "&& reload_completed"
7861 [(parallel [(set (reg:CC FLAGS_REG)
7862 (compare:CC (match_dup 1) (match_dup 2)))
7863 (set (match_dup 0)
7864 (minus:DWIH (match_dup 1) (match_dup 2)))])
7865 (parallel [(set (reg:CCO FLAGS_REG)
7866 (eq:CCO
7867 (minus:<DWI>
7868 (minus:<DWI>
7869 (sign_extend:<DWI> (match_dup 4))
7870 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7871 (sign_extend:<DWI> (match_dup 5)))
7872 (sign_extend:<DWI>
7873 (minus:DWIH
7874 (minus:DWIH
7875 (match_dup 4)
7876 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7877 (match_dup 5)))))
7878 (set (match_dup 3)
7879 (minus:DWIH
7880 (minus:DWIH
7881 (match_dup 4)
7882 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7883 (match_dup 5)))])]
7884 {
7885 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7886 })
7887
7888 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7889 [(set (reg:CCO FLAGS_REG)
7890 (eq:CCO
7891 (minus:<QPWI>
7892 (sign_extend:<QPWI>
7893 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7894 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7895 (sign_extend:<QPWI>
7896 (minus:<DWI>
7897 (match_dup 1)
7898 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7899 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7900 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7901 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7902 && CONST_SCALAR_INT_P (operands[2])
7903 && rtx_equal_p (operands[2], operands[3])"
7904 "#"
7905 "&& reload_completed"
7906 [(parallel [(set (reg:CC FLAGS_REG)
7907 (compare:CC (match_dup 1) (match_dup 2)))
7908 (set (match_dup 0)
7909 (minus:DWIH (match_dup 1) (match_dup 2)))])
7910 (parallel [(set (reg:CCO FLAGS_REG)
7911 (eq:CCO
7912 (minus:<DWI>
7913 (minus:<DWI>
7914 (sign_extend:<DWI> (match_dup 4))
7915 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7916 (match_dup 5))
7917 (sign_extend:<DWI>
7918 (minus:DWIH
7919 (minus:DWIH
7920 (match_dup 4)
7921 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7922 (match_dup 5)))))
7923 (set (match_dup 3)
7924 (minus:DWIH
7925 (minus:DWIH
7926 (match_dup 4)
7927 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7928 (match_dup 5)))])]
7929 {
7930 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7931 if (operands[2] == const0_rtx)
7932 {
7933 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7934 operands[5]));
7935 DONE;
7936 }
7937 })
7938
7939 (define_insn "*subv<mode>4_overflow_1"
7940 [(set (reg:CCO FLAGS_REG)
7941 (eq:CCO
7942 (minus:<DWI>
7943 (minus:<DWI>
7944 (sign_extend:<DWI>
7945 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7946 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7947 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7948 (sign_extend:<DWI>
7949 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7950 (sign_extend:<DWI>
7951 (minus:SWI
7952 (minus:SWI
7953 (match_dup 1)
7954 (match_operator:SWI 5 "ix86_carry_flag_operator"
7955 [(match_dup 3) (const_int 0)]))
7956 (match_dup 2)))))
7957 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7958 (minus:SWI
7959 (minus:SWI
7960 (match_dup 1)
7961 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7962 (match_dup 2)))]
7963 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7964 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "<MODE>")])
7967
7968 (define_insn "*subv<mode>4_overflow_2"
7969 [(set (reg:CCO FLAGS_REG)
7970 (eq:CCO
7971 (minus:<DWI>
7972 (minus:<DWI>
7973 (sign_extend:<DWI>
7974 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7975 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7976 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7977 (match_operand:<DWI> 6 "const_int_operand" "n"))
7978 (sign_extend:<DWI>
7979 (minus:SWI
7980 (minus:SWI
7981 (match_dup 1)
7982 (match_operator:SWI 5 "ix86_carry_flag_operator"
7983 [(match_dup 3) (const_int 0)]))
7984 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7985 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7986 (minus:SWI
7987 (minus:SWI
7988 (match_dup 1)
7989 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7990 (match_dup 2)))]
7991 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7992 && CONST_INT_P (operands[2])
7993 && INTVAL (operands[2]) == INTVAL (operands[6])"
7994 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7995 [(set_attr "type" "alu")
7996 (set_attr "mode" "<MODE>")
7997 (set (attr "length_immediate")
7998 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7999 (const_string "1")
8000 (const_string "4")))])
8001
8002 (define_expand "usubv<mode>4"
8003 [(parallel [(set (reg:CC FLAGS_REG)
8004 (compare:CC
8005 (match_operand:SWI 1 "nonimmediate_operand")
8006 (match_operand:SWI 2 "<general_operand>")))
8007 (set (match_operand:SWI 0 "register_operand")
8008 (minus:SWI (match_dup 1) (match_dup 2)))])
8009 (set (pc) (if_then_else
8010 (ltu (reg:CC FLAGS_REG) (const_int 0))
8011 (label_ref (match_operand 3))
8012 (pc)))]
8013 ""
8014 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
8015
8016 (define_insn "*sub<mode>_3"
8017 [(set (reg FLAGS_REG)
8018 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8019 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8020 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8021 (minus:SWI (match_dup 1) (match_dup 2)))]
8022 "ix86_match_ccmode (insn, CCmode)
8023 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8024 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
8025 [(set_attr "type" "alu")
8026 (set_attr "mode" "<MODE>")])
8027
8028 (define_peephole2
8029 [(parallel
8030 [(set (reg:CC FLAGS_REG)
8031 (compare:CC (match_operand:SWI 0 "general_reg_operand")
8032 (match_operand:SWI 1 "general_gr_operand")))
8033 (set (match_dup 0)
8034 (minus:SWI (match_dup 0) (match_dup 1)))])]
8035 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8036 [(set (reg:CC FLAGS_REG)
8037 (compare:CC (match_dup 0) (match_dup 1)))])
8038
8039 (define_peephole2
8040 [(set (match_operand:SWI 0 "general_reg_operand")
8041 (match_operand:SWI 1 "memory_operand"))
8042 (parallel [(set (reg:CC FLAGS_REG)
8043 (compare:CC (match_dup 0)
8044 (match_operand:SWI 2 "memory_operand")))
8045 (set (match_dup 0)
8046 (minus:SWI (match_dup 0) (match_dup 2)))])
8047 (set (match_dup 1) (match_dup 0))]
8048 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8049 && peep2_reg_dead_p (3, operands[0])
8050 && !reg_overlap_mentioned_p (operands[0], operands[1])
8051 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8052 [(set (match_dup 0) (match_dup 2))
8053 (parallel [(set (reg:CC FLAGS_REG)
8054 (compare:CC (match_dup 1) (match_dup 0)))
8055 (set (match_dup 1)
8056 (minus:SWI (match_dup 1) (match_dup 0)))])])
8057
8058 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8059 ;; subl $1, %eax; jnc .Lxx;
8060 (define_peephole2
8061 [(parallel
8062 [(set (match_operand:SWI 0 "general_reg_operand")
8063 (plus:SWI (match_dup 0) (const_int -1)))
8064 (clobber (reg FLAGS_REG))])
8065 (set (reg:CCZ FLAGS_REG)
8066 (compare:CCZ (match_dup 0) (const_int -1)))
8067 (set (pc)
8068 (if_then_else (match_operator 1 "bt_comparison_operator"
8069 [(reg:CCZ FLAGS_REG) (const_int 0)])
8070 (match_operand 2)
8071 (pc)))]
8072 "peep2_regno_dead_p (3, FLAGS_REG)"
8073 [(parallel
8074 [(set (reg:CC FLAGS_REG)
8075 (compare:CC (match_dup 0) (const_int 1)))
8076 (set (match_dup 0)
8077 (minus:SWI (match_dup 0) (const_int 1)))])
8078 (set (pc)
8079 (if_then_else (match_dup 3)
8080 (match_dup 2)
8081 (pc)))]
8082 {
8083 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8084 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8085 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8086 })
8087
8088 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8089 (define_insn_and_split "*dec_cmov<mode>"
8090 [(set (match_operand:SWI248 0 "register_operand" "=r")
8091 (if_then_else:SWI248
8092 (match_operator 1 "bt_comparison_operator"
8093 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8094 (plus:SWI248 (match_dup 2) (const_int -1))
8095 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8096 (clobber (reg:CC FLAGS_REG))]
8097 "TARGET_CMOVE"
8098 "#"
8099 "&& reload_completed"
8100 [(parallel [(set (reg:CC FLAGS_REG)
8101 (compare:CC (match_dup 2) (const_int 1)))
8102 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8103 (set (match_dup 0)
8104 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8105 {
8106 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8107 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8108 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8109 })
8110
8111 (define_insn "*subsi_3_zext"
8112 [(set (reg FLAGS_REG)
8113 (compare (match_operand:SI 1 "register_operand" "0")
8114 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
8115 (set (match_operand:DI 0 "register_operand" "=r")
8116 (zero_extend:DI
8117 (minus:SI (match_dup 1)
8118 (match_dup 2))))]
8119 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8120 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8121 "sub{l}\t{%2, %1|%1, %2}"
8122 [(set_attr "type" "alu")
8123 (set_attr "mode" "SI")])
8124 \f
8125 ;; Add with carry and subtract with borrow
8126
8127 (define_insn "@add<mode>3_carry"
8128 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8129 (plus:SWI
8130 (plus:SWI
8131 (match_operator:SWI 4 "ix86_carry_flag_operator"
8132 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8133 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8134 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8137 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8138 [(set_attr "type" "alu")
8139 (set_attr "use_carry" "1")
8140 (set_attr "pent_pair" "pu")
8141 (set_attr "mode" "<MODE>")])
8142
8143 (define_peephole2
8144 [(set (match_operand:SWI 0 "general_reg_operand")
8145 (match_operand:SWI 1 "memory_operand"))
8146 (parallel [(set (match_dup 0)
8147 (plus:SWI
8148 (plus:SWI
8149 (match_operator:SWI 4 "ix86_carry_flag_operator"
8150 [(match_operand 3 "flags_reg_operand")
8151 (const_int 0)])
8152 (match_dup 0))
8153 (match_operand:SWI 2 "memory_operand")))
8154 (clobber (reg:CC FLAGS_REG))])
8155 (set (match_dup 1) (match_dup 0))]
8156 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8157 && peep2_reg_dead_p (3, operands[0])
8158 && !reg_overlap_mentioned_p (operands[0], operands[1])
8159 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8160 [(set (match_dup 0) (match_dup 2))
8161 (parallel [(set (match_dup 1)
8162 (plus:SWI (plus:SWI (match_op_dup 4
8163 [(match_dup 3) (const_int 0)])
8164 (match_dup 1))
8165 (match_dup 0)))
8166 (clobber (reg:CC FLAGS_REG))])])
8167
8168 (define_peephole2
8169 [(set (match_operand:SWI 0 "general_reg_operand")
8170 (match_operand:SWI 1 "memory_operand"))
8171 (parallel [(set (match_dup 0)
8172 (plus:SWI
8173 (plus:SWI
8174 (match_operator:SWI 4 "ix86_carry_flag_operator"
8175 [(match_operand 3 "flags_reg_operand")
8176 (const_int 0)])
8177 (match_dup 0))
8178 (match_operand:SWI 2 "memory_operand")))
8179 (clobber (reg:CC FLAGS_REG))])
8180 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8181 (set (match_dup 1) (match_dup 5))]
8182 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8183 && peep2_reg_dead_p (3, operands[0])
8184 && peep2_reg_dead_p (4, operands[5])
8185 && !reg_overlap_mentioned_p (operands[0], operands[1])
8186 && !reg_overlap_mentioned_p (operands[0], operands[2])
8187 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8188 [(set (match_dup 0) (match_dup 2))
8189 (parallel [(set (match_dup 1)
8190 (plus:SWI (plus:SWI (match_op_dup 4
8191 [(match_dup 3) (const_int 0)])
8192 (match_dup 1))
8193 (match_dup 0)))
8194 (clobber (reg:CC FLAGS_REG))])])
8195
8196 (define_insn "*add<mode>3_carry_0"
8197 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8198 (plus:SWI
8199 (match_operator:SWI 2 "ix86_carry_flag_operator"
8200 [(reg FLAGS_REG) (const_int 0)])
8201 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8202 (clobber (reg:CC FLAGS_REG))]
8203 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8204 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8205 [(set_attr "type" "alu")
8206 (set_attr "use_carry" "1")
8207 (set_attr "pent_pair" "pu")
8208 (set_attr "mode" "<MODE>")])
8209
8210 (define_insn "*add<mode>3_carry_0r"
8211 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8212 (plus:SWI
8213 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8214 [(reg FLAGS_REG) (const_int 0)])
8215 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8218 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8219 [(set_attr "type" "alu")
8220 (set_attr "use_carry" "1")
8221 (set_attr "pent_pair" "pu")
8222 (set_attr "mode" "<MODE>")])
8223
8224 (define_insn "*addsi3_carry_zext"
8225 [(set (match_operand:DI 0 "register_operand" "=r")
8226 (zero_extend:DI
8227 (plus:SI
8228 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8229 [(reg FLAGS_REG) (const_int 0)])
8230 (match_operand:SI 1 "register_operand" "%0"))
8231 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8232 (clobber (reg:CC FLAGS_REG))]
8233 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8234 "adc{l}\t{%2, %k0|%k0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "use_carry" "1")
8237 (set_attr "pent_pair" "pu")
8238 (set_attr "mode" "SI")])
8239
8240 (define_insn "*addsi3_carry_zext_0"
8241 [(set (match_operand:DI 0 "register_operand" "=r")
8242 (zero_extend:DI
8243 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8244 [(reg FLAGS_REG) (const_int 0)])
8245 (match_operand:SI 1 "register_operand" "0"))))
8246 (clobber (reg:CC FLAGS_REG))]
8247 "TARGET_64BIT"
8248 "adc{l}\t{$0, %k0|%k0, 0}"
8249 [(set_attr "type" "alu")
8250 (set_attr "use_carry" "1")
8251 (set_attr "pent_pair" "pu")
8252 (set_attr "mode" "SI")])
8253
8254 (define_insn "*addsi3_carry_zext_0r"
8255 [(set (match_operand:DI 0 "register_operand" "=r")
8256 (zero_extend:DI
8257 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8258 [(reg FLAGS_REG) (const_int 0)])
8259 (match_operand:SI 1 "register_operand" "0"))))
8260 (clobber (reg:CC FLAGS_REG))]
8261 "TARGET_64BIT"
8262 "sbb{l}\t{$-1, %k0|%k0, -1}"
8263 [(set_attr "type" "alu")
8264 (set_attr "use_carry" "1")
8265 (set_attr "pent_pair" "pu")
8266 (set_attr "mode" "SI")])
8267
8268 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8269
8270 (define_insn "addcarry<mode>"
8271 [(set (reg:CCC FLAGS_REG)
8272 (compare:CCC
8273 (zero_extend:<DWI>
8274 (plus:SWI48
8275 (plus:SWI48
8276 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8277 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8278 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8279 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8280 (plus:<DWI>
8281 (zero_extend:<DWI> (match_dup 2))
8282 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8283 [(match_dup 3) (const_int 0)]))))
8284 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8285 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8286 [(match_dup 3) (const_int 0)])
8287 (match_dup 1))
8288 (match_dup 2)))]
8289 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8290 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8291 [(set_attr "type" "alu")
8292 (set_attr "use_carry" "1")
8293 (set_attr "pent_pair" "pu")
8294 (set_attr "mode" "<MODE>")])
8295
8296 (define_peephole2
8297 [(parallel [(set (reg:CCC FLAGS_REG)
8298 (compare:CCC
8299 (zero_extend:<DWI>
8300 (plus:SWI48
8301 (plus:SWI48
8302 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8303 [(match_operand 2 "flags_reg_operand")
8304 (const_int 0)])
8305 (match_operand:SWI48 0 "general_reg_operand"))
8306 (match_operand:SWI48 1 "memory_operand")))
8307 (plus:<DWI>
8308 (zero_extend:<DWI> (match_dup 1))
8309 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8310 [(match_dup 2) (const_int 0)]))))
8311 (set (match_dup 0)
8312 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8313 [(match_dup 2) (const_int 0)])
8314 (match_dup 0))
8315 (match_dup 1)))])
8316 (set (match_dup 1) (match_dup 0))]
8317 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8318 && peep2_reg_dead_p (2, operands[0])
8319 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8320 [(parallel [(set (reg:CCC FLAGS_REG)
8321 (compare:CCC
8322 (zero_extend:<DWI>
8323 (plus:SWI48
8324 (plus:SWI48
8325 (match_op_dup 4
8326 [(match_dup 2) (const_int 0)])
8327 (match_dup 1))
8328 (match_dup 0)))
8329 (plus:<DWI>
8330 (zero_extend:<DWI> (match_dup 0))
8331 (match_op_dup 3
8332 [(match_dup 2) (const_int 0)]))))
8333 (set (match_dup 1)
8334 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8335 [(match_dup 2) (const_int 0)])
8336 (match_dup 1))
8337 (match_dup 0)))])])
8338
8339 (define_peephole2
8340 [(set (match_operand:SWI48 0 "general_reg_operand")
8341 (match_operand:SWI48 1 "memory_operand"))
8342 (parallel [(set (reg:CCC FLAGS_REG)
8343 (compare:CCC
8344 (zero_extend:<DWI>
8345 (plus:SWI48
8346 (plus:SWI48
8347 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8348 [(match_operand 3 "flags_reg_operand")
8349 (const_int 0)])
8350 (match_dup 0))
8351 (match_operand:SWI48 2 "memory_operand")))
8352 (plus:<DWI>
8353 (zero_extend:<DWI> (match_dup 2))
8354 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8355 [(match_dup 3) (const_int 0)]))))
8356 (set (match_dup 0)
8357 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8358 [(match_dup 3) (const_int 0)])
8359 (match_dup 0))
8360 (match_dup 2)))])
8361 (set (match_dup 1) (match_dup 0))]
8362 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8363 && peep2_reg_dead_p (3, operands[0])
8364 && !reg_overlap_mentioned_p (operands[0], operands[1])
8365 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8366 [(set (match_dup 0) (match_dup 2))
8367 (parallel [(set (reg:CCC FLAGS_REG)
8368 (compare:CCC
8369 (zero_extend:<DWI>
8370 (plus:SWI48
8371 (plus:SWI48
8372 (match_op_dup 5
8373 [(match_dup 3) (const_int 0)])
8374 (match_dup 1))
8375 (match_dup 0)))
8376 (plus:<DWI>
8377 (zero_extend:<DWI> (match_dup 0))
8378 (match_op_dup 4
8379 [(match_dup 3) (const_int 0)]))))
8380 (set (match_dup 1)
8381 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8382 [(match_dup 3) (const_int 0)])
8383 (match_dup 1))
8384 (match_dup 0)))])])
8385
8386 (define_peephole2
8387 [(parallel [(set (reg:CCC FLAGS_REG)
8388 (compare:CCC
8389 (zero_extend:<DWI>
8390 (plus:SWI48
8391 (plus:SWI48
8392 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8393 [(match_operand 2 "flags_reg_operand")
8394 (const_int 0)])
8395 (match_operand:SWI48 0 "general_reg_operand"))
8396 (match_operand:SWI48 1 "memory_operand")))
8397 (plus:<DWI>
8398 (zero_extend:<DWI> (match_dup 1))
8399 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8400 [(match_dup 2) (const_int 0)]))))
8401 (set (match_dup 0)
8402 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8403 [(match_dup 2) (const_int 0)])
8404 (match_dup 0))
8405 (match_dup 1)))])
8406 (set (match_operand:QI 5 "general_reg_operand")
8407 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8408 (set (match_operand:SWI48 6 "general_reg_operand")
8409 (zero_extend:SWI48 (match_dup 5)))
8410 (set (match_dup 1) (match_dup 0))]
8411 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8412 && peep2_reg_dead_p (4, operands[0])
8413 && !reg_overlap_mentioned_p (operands[0], operands[1])
8414 && !reg_overlap_mentioned_p (operands[0], operands[5])
8415 && !reg_overlap_mentioned_p (operands[5], operands[1])
8416 && !reg_overlap_mentioned_p (operands[0], operands[6])
8417 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8418 [(parallel [(set (reg:CCC FLAGS_REG)
8419 (compare:CCC
8420 (zero_extend:<DWI>
8421 (plus:SWI48
8422 (plus:SWI48
8423 (match_op_dup 4
8424 [(match_dup 2) (const_int 0)])
8425 (match_dup 1))
8426 (match_dup 0)))
8427 (plus:<DWI>
8428 (zero_extend:<DWI> (match_dup 0))
8429 (match_op_dup 3
8430 [(match_dup 2) (const_int 0)]))))
8431 (set (match_dup 1)
8432 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8433 [(match_dup 2) (const_int 0)])
8434 (match_dup 1))
8435 (match_dup 0)))])
8436 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8437 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8438
8439 (define_expand "addcarry<mode>_0"
8440 [(parallel
8441 [(set (reg:CCC FLAGS_REG)
8442 (compare:CCC
8443 (plus:SWI48
8444 (match_operand:SWI48 1 "nonimmediate_operand")
8445 (match_operand:SWI48 2 "x86_64_general_operand"))
8446 (match_dup 1)))
8447 (set (match_operand:SWI48 0 "nonimmediate_operand")
8448 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8449 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8450
8451 (define_insn "*addcarry<mode>_1"
8452 [(set (reg:CCC FLAGS_REG)
8453 (compare:CCC
8454 (zero_extend:<DWI>
8455 (plus:SWI48
8456 (plus:SWI48
8457 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8458 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8459 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8460 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8461 (plus:<DWI>
8462 (match_operand:<DWI> 6 "const_scalar_int_operand")
8463 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8464 [(match_dup 3) (const_int 0)]))))
8465 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8466 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8467 [(match_dup 3) (const_int 0)])
8468 (match_dup 1))
8469 (match_dup 2)))]
8470 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8471 && CONST_INT_P (operands[2])
8472 /* Check that operands[6] is operands[2] zero extended from
8473 <MODE>mode to <DWI>mode. */
8474 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8475 ? (CONST_INT_P (operands[6])
8476 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8477 & GET_MODE_MASK (<MODE>mode)))
8478 : (CONST_WIDE_INT_P (operands[6])
8479 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8480 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8481 == UINTVAL (operands[2]))
8482 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8483 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "use_carry" "1")
8486 (set_attr "pent_pair" "pu")
8487 (set_attr "mode" "<MODE>")
8488 (set (attr "length_immediate")
8489 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8490 (const_string "1")
8491 (const_string "4")))])
8492
8493 (define_insn "@sub<mode>3_carry"
8494 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8495 (minus:SWI
8496 (minus:SWI
8497 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8498 (match_operator:SWI 4 "ix86_carry_flag_operator"
8499 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8500 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8501 (clobber (reg:CC FLAGS_REG))]
8502 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8503 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "use_carry" "1")
8506 (set_attr "pent_pair" "pu")
8507 (set_attr "mode" "<MODE>")])
8508
8509 (define_peephole2
8510 [(set (match_operand:SWI 0 "general_reg_operand")
8511 (match_operand:SWI 1 "memory_operand"))
8512 (parallel [(set (match_dup 0)
8513 (minus:SWI
8514 (minus:SWI
8515 (match_dup 0)
8516 (match_operator:SWI 4 "ix86_carry_flag_operator"
8517 [(match_operand 3 "flags_reg_operand")
8518 (const_int 0)]))
8519 (match_operand:SWI 2 "memory_operand")))
8520 (clobber (reg:CC FLAGS_REG))])
8521 (set (match_dup 1) (match_dup 0))]
8522 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8523 && peep2_reg_dead_p (3, operands[0])
8524 && !reg_overlap_mentioned_p (operands[0], operands[1])
8525 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8526 [(set (match_dup 0) (match_dup 2))
8527 (parallel [(set (match_dup 1)
8528 (minus:SWI (minus:SWI (match_dup 1)
8529 (match_op_dup 4
8530 [(match_dup 3) (const_int 0)]))
8531 (match_dup 0)))
8532 (clobber (reg:CC FLAGS_REG))])])
8533
8534 (define_peephole2
8535 [(set (match_operand:SWI 0 "general_reg_operand")
8536 (match_operand:SWI 1 "memory_operand"))
8537 (parallel [(set (match_dup 0)
8538 (minus:SWI
8539 (minus:SWI
8540 (match_dup 0)
8541 (match_operator:SWI 4 "ix86_carry_flag_operator"
8542 [(match_operand 3 "flags_reg_operand")
8543 (const_int 0)]))
8544 (match_operand:SWI 2 "memory_operand")))
8545 (clobber (reg:CC FLAGS_REG))])
8546 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8547 (set (match_dup 1) (match_dup 5))]
8548 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8549 && peep2_reg_dead_p (3, operands[0])
8550 && peep2_reg_dead_p (4, operands[5])
8551 && !reg_overlap_mentioned_p (operands[0], operands[1])
8552 && !reg_overlap_mentioned_p (operands[0], operands[2])
8553 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8554 [(set (match_dup 0) (match_dup 2))
8555 (parallel [(set (match_dup 1)
8556 (minus:SWI (minus:SWI (match_dup 1)
8557 (match_op_dup 4
8558 [(match_dup 3) (const_int 0)]))
8559 (match_dup 0)))
8560 (clobber (reg:CC FLAGS_REG))])])
8561
8562 (define_insn "*sub<mode>3_carry_0"
8563 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8564 (minus:SWI
8565 (match_operand:SWI 1 "nonimmediate_operand" "0")
8566 (match_operator:SWI 2 "ix86_carry_flag_operator"
8567 [(reg FLAGS_REG) (const_int 0)])))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8570 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8571 [(set_attr "type" "alu")
8572 (set_attr "use_carry" "1")
8573 (set_attr "pent_pair" "pu")
8574 (set_attr "mode" "<MODE>")])
8575
8576 (define_insn "*sub<mode>3_carry_0r"
8577 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8578 (minus:SWI
8579 (match_operand:SWI 1 "nonimmediate_operand" "0")
8580 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8581 [(reg FLAGS_REG) (const_int 0)])))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8584 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8585 [(set_attr "type" "alu")
8586 (set_attr "use_carry" "1")
8587 (set_attr "pent_pair" "pu")
8588 (set_attr "mode" "<MODE>")])
8589
8590 (define_insn "*subsi3_carry_zext"
8591 [(set (match_operand:DI 0 "register_operand" "=r")
8592 (zero_extend:DI
8593 (minus:SI
8594 (minus:SI
8595 (match_operand:SI 1 "register_operand" "0")
8596 (match_operator:SI 3 "ix86_carry_flag_operator"
8597 [(reg FLAGS_REG) (const_int 0)]))
8598 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8601 "sbb{l}\t{%2, %k0|%k0, %2}"
8602 [(set_attr "type" "alu")
8603 (set_attr "use_carry" "1")
8604 (set_attr "pent_pair" "pu")
8605 (set_attr "mode" "SI")])
8606
8607 (define_insn "*subsi3_carry_zext_0"
8608 [(set (match_operand:DI 0 "register_operand" "=r")
8609 (zero_extend:DI
8610 (minus:SI
8611 (match_operand:SI 1 "register_operand" "0")
8612 (match_operator:SI 2 "ix86_carry_flag_operator"
8613 [(reg FLAGS_REG) (const_int 0)]))))
8614 (clobber (reg:CC FLAGS_REG))]
8615 "TARGET_64BIT"
8616 "sbb{l}\t{$0, %k0|%k0, 0}"
8617 [(set_attr "type" "alu")
8618 (set_attr "use_carry" "1")
8619 (set_attr "pent_pair" "pu")
8620 (set_attr "mode" "SI")])
8621
8622 (define_insn "*subsi3_carry_zext_0r"
8623 [(set (match_operand:DI 0 "register_operand" "=r")
8624 (zero_extend:DI
8625 (minus:SI
8626 (match_operand:SI 1 "register_operand" "0")
8627 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8628 [(reg FLAGS_REG) (const_int 0)]))))
8629 (clobber (reg:CC FLAGS_REG))]
8630 "TARGET_64BIT"
8631 "adc{l}\t{$-1, %k0|%k0, -1}"
8632 [(set_attr "type" "alu")
8633 (set_attr "use_carry" "1")
8634 (set_attr "pent_pair" "pu")
8635 (set_attr "mode" "SI")])
8636
8637 (define_insn "@sub<mode>3_carry_ccc"
8638 [(set (reg:CCC FLAGS_REG)
8639 (compare:CCC
8640 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8641 (plus:<DWI>
8642 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8643 (zero_extend:<DWI>
8644 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8645 (clobber (match_scratch:DWIH 0 "=r"))]
8646 ""
8647 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "mode" "<MODE>")])
8650
8651 (define_insn "*sub<mode>3_carry_ccc_1"
8652 [(set (reg:CCC FLAGS_REG)
8653 (compare:CCC
8654 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8655 (plus:<DWI>
8656 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8657 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8658 (clobber (match_scratch:DWIH 0 "=r"))]
8659 ""
8660 {
8661 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8662 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8663 }
8664 [(set_attr "type" "alu")
8665 (set_attr "mode" "<MODE>")])
8666
8667 ;; The sign flag is set from the
8668 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8669 ;; result, the overflow flag likewise, but the overflow flag is also
8670 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8671 (define_insn "@sub<mode>3_carry_ccgz"
8672 [(set (reg:CCGZ FLAGS_REG)
8673 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8674 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8675 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8676 UNSPEC_SBB))
8677 (clobber (match_scratch:DWIH 0 "=r"))]
8678 ""
8679 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8680 [(set_attr "type" "alu")
8681 (set_attr "mode" "<MODE>")])
8682
8683 (define_insn "subborrow<mode>"
8684 [(set (reg:CCC FLAGS_REG)
8685 (compare:CCC
8686 (zero_extend:<DWI>
8687 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8688 (plus:<DWI>
8689 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8690 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8691 (zero_extend:<DWI>
8692 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8693 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8694 (minus:SWI48 (minus:SWI48
8695 (match_dup 1)
8696 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8697 [(match_dup 3) (const_int 0)]))
8698 (match_dup 2)))]
8699 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8700 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8701 [(set_attr "type" "alu")
8702 (set_attr "use_carry" "1")
8703 (set_attr "pent_pair" "pu")
8704 (set_attr "mode" "<MODE>")])
8705
8706 (define_peephole2
8707 [(set (match_operand:SWI48 0 "general_reg_operand")
8708 (match_operand:SWI48 1 "memory_operand"))
8709 (parallel [(set (reg:CCC FLAGS_REG)
8710 (compare:CCC
8711 (zero_extend:<DWI> (match_dup 0))
8712 (plus:<DWI>
8713 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8714 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8715 (zero_extend:<DWI>
8716 (match_operand:SWI48 2 "memory_operand")))))
8717 (set (match_dup 0)
8718 (minus:SWI48
8719 (minus:SWI48
8720 (match_dup 0)
8721 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8722 [(match_dup 3) (const_int 0)]))
8723 (match_dup 2)))])
8724 (set (match_dup 1) (match_dup 0))]
8725 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8726 && peep2_reg_dead_p (3, operands[0])
8727 && !reg_overlap_mentioned_p (operands[0], operands[1])
8728 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8729 [(set (match_dup 0) (match_dup 2))
8730 (parallel [(set (reg:CCC FLAGS_REG)
8731 (compare:CCC
8732 (zero_extend:<DWI> (match_dup 1))
8733 (plus:<DWI> (match_op_dup 4
8734 [(match_dup 3) (const_int 0)])
8735 (zero_extend:<DWI> (match_dup 0)))))
8736 (set (match_dup 1)
8737 (minus:SWI48 (minus:SWI48 (match_dup 1)
8738 (match_op_dup 5
8739 [(match_dup 3) (const_int 0)]))
8740 (match_dup 0)))])])
8741
8742 (define_peephole2
8743 [(set (match_operand:SWI48 6 "general_reg_operand")
8744 (match_operand:SWI48 7 "memory_operand"))
8745 (set (match_operand:SWI48 8 "general_reg_operand")
8746 (match_operand:SWI48 9 "memory_operand"))
8747 (parallel [(set (reg:CCC FLAGS_REG)
8748 (compare:CCC
8749 (zero_extend:<DWI>
8750 (match_operand:SWI48 0 "general_reg_operand"))
8751 (plus:<DWI>
8752 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8753 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8754 (zero_extend:<DWI>
8755 (match_operand:SWI48 2 "general_reg_operand")))))
8756 (set (match_dup 0)
8757 (minus:SWI48
8758 (minus:SWI48
8759 (match_dup 0)
8760 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8761 [(match_dup 3) (const_int 0)]))
8762 (match_dup 2)))])
8763 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8764 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8765 && peep2_reg_dead_p (4, operands[0])
8766 && peep2_reg_dead_p (3, operands[2])
8767 && !reg_overlap_mentioned_p (operands[0], operands[1])
8768 && !reg_overlap_mentioned_p (operands[2], operands[1])
8769 && !reg_overlap_mentioned_p (operands[6], operands[9])
8770 && (rtx_equal_p (operands[6], operands[0])
8771 ? (rtx_equal_p (operands[7], operands[1])
8772 && rtx_equal_p (operands[8], operands[2]))
8773 : (rtx_equal_p (operands[8], operands[0])
8774 && rtx_equal_p (operands[9], operands[1])
8775 && rtx_equal_p (operands[6], operands[2])))"
8776 [(set (match_dup 0) (match_dup 9))
8777 (parallel [(set (reg:CCC FLAGS_REG)
8778 (compare:CCC
8779 (zero_extend:<DWI> (match_dup 1))
8780 (plus:<DWI> (match_op_dup 4
8781 [(match_dup 3) (const_int 0)])
8782 (zero_extend:<DWI> (match_dup 0)))))
8783 (set (match_dup 1)
8784 (minus:SWI48 (minus:SWI48 (match_dup 1)
8785 (match_op_dup 5
8786 [(match_dup 3) (const_int 0)]))
8787 (match_dup 0)))])]
8788 {
8789 if (!rtx_equal_p (operands[6], operands[0]))
8790 operands[9] = operands[7];
8791 })
8792
8793 (define_peephole2
8794 [(set (match_operand:SWI48 6 "general_reg_operand")
8795 (match_operand:SWI48 7 "memory_operand"))
8796 (set (match_operand:SWI48 8 "general_reg_operand")
8797 (match_operand:SWI48 9 "memory_operand"))
8798 (parallel [(set (reg:CCC FLAGS_REG)
8799 (compare:CCC
8800 (zero_extend:<DWI>
8801 (match_operand:SWI48 0 "general_reg_operand"))
8802 (plus:<DWI>
8803 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8804 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8805 (zero_extend:<DWI>
8806 (match_operand:SWI48 2 "general_reg_operand")))))
8807 (set (match_dup 0)
8808 (minus:SWI48
8809 (minus:SWI48
8810 (match_dup 0)
8811 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8812 [(match_dup 3) (const_int 0)]))
8813 (match_dup 2)))])
8814 (set (match_operand:QI 10 "general_reg_operand")
8815 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8816 (set (match_operand:SWI48 11 "general_reg_operand")
8817 (zero_extend:SWI48 (match_dup 10)))
8818 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8819 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8820 && peep2_reg_dead_p (6, operands[0])
8821 && peep2_reg_dead_p (3, operands[2])
8822 && !reg_overlap_mentioned_p (operands[0], operands[1])
8823 && !reg_overlap_mentioned_p (operands[2], operands[1])
8824 && !reg_overlap_mentioned_p (operands[6], operands[9])
8825 && !reg_overlap_mentioned_p (operands[0], operands[10])
8826 && !reg_overlap_mentioned_p (operands[10], operands[1])
8827 && !reg_overlap_mentioned_p (operands[0], operands[11])
8828 && !reg_overlap_mentioned_p (operands[11], operands[1])
8829 && (rtx_equal_p (operands[6], operands[0])
8830 ? (rtx_equal_p (operands[7], operands[1])
8831 && rtx_equal_p (operands[8], operands[2]))
8832 : (rtx_equal_p (operands[8], operands[0])
8833 && rtx_equal_p (operands[9], operands[1])
8834 && rtx_equal_p (operands[6], operands[2])))"
8835 [(set (match_dup 0) (match_dup 9))
8836 (parallel [(set (reg:CCC FLAGS_REG)
8837 (compare:CCC
8838 (zero_extend:<DWI> (match_dup 1))
8839 (plus:<DWI> (match_op_dup 4
8840 [(match_dup 3) (const_int 0)])
8841 (zero_extend:<DWI> (match_dup 0)))))
8842 (set (match_dup 1)
8843 (minus:SWI48 (minus:SWI48 (match_dup 1)
8844 (match_op_dup 5
8845 [(match_dup 3) (const_int 0)]))
8846 (match_dup 0)))])
8847 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8848 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8849 {
8850 if (!rtx_equal_p (operands[6], operands[0]))
8851 operands[9] = operands[7];
8852 })
8853
8854 (define_expand "subborrow<mode>_0"
8855 [(parallel
8856 [(set (reg:CC FLAGS_REG)
8857 (compare:CC
8858 (match_operand:SWI48 1 "nonimmediate_operand")
8859 (match_operand:SWI48 2 "<general_operand>")))
8860 (set (match_operand:SWI48 0 "register_operand")
8861 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8862 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8863
8864 (define_expand "uaddc<mode>5"
8865 [(match_operand:SWI48 0 "register_operand")
8866 (match_operand:SWI48 1 "register_operand")
8867 (match_operand:SWI48 2 "register_operand")
8868 (match_operand:SWI48 3 "register_operand")
8869 (match_operand:SWI48 4 "nonmemory_operand")]
8870 ""
8871 {
8872 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8873 if (operands[4] == const0_rtx)
8874 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8875 else
8876 {
8877 ix86_expand_carry (operands[4]);
8878 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8879 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8880 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8881 cf, pat, pat2));
8882 }
8883 rtx cc = gen_reg_rtx (QImode);
8884 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8885 emit_insn (gen_rtx_SET (cc, pat));
8886 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8887 DONE;
8888 })
8889
8890 (define_expand "usubc<mode>5"
8891 [(match_operand:SWI48 0 "register_operand")
8892 (match_operand:SWI48 1 "register_operand")
8893 (match_operand:SWI48 2 "register_operand")
8894 (match_operand:SWI48 3 "register_operand")
8895 (match_operand:SWI48 4 "nonmemory_operand")]
8896 ""
8897 {
8898 rtx cf, pat, pat2;
8899 if (operands[4] == const0_rtx)
8900 {
8901 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8902 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8903 operands[3]));
8904 }
8905 else
8906 {
8907 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8908 ix86_expand_carry (operands[4]);
8909 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8910 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8911 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8912 cf, pat, pat2));
8913 }
8914 rtx cc = gen_reg_rtx (QImode);
8915 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8916 emit_insn (gen_rtx_SET (cc, pat));
8917 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8918 DONE;
8919 })
8920
8921 (define_mode_iterator CC_CCC [CC CCC])
8922
8923 ;; Pre-reload splitter to optimize
8924 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8925 ;; operand and no intervening flags modifications into nothing.
8926 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8927 [(set (reg:CCC FLAGS_REG)
8928 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8929 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8930 "ix86_pre_reload_split ()"
8931 "#"
8932 "&& 1"
8933 [(const_int 0)]
8934 "emit_note (NOTE_INSN_DELETED); DONE;")
8935
8936 ;; Set the carry flag from the carry flag.
8937 (define_insn_and_split "*setccc"
8938 [(set (reg:CCC FLAGS_REG)
8939 (reg:CCC FLAGS_REG))]
8940 "ix86_pre_reload_split ()"
8941 "#"
8942 "&& 1"
8943 [(const_int 0)]
8944 "emit_note (NOTE_INSN_DELETED); DONE;")
8945
8946 ;; Set the carry flag from the carry flag.
8947 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8948 [(set (reg:CCC FLAGS_REG)
8949 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8950 "ix86_pre_reload_split ()"
8951 "#"
8952 "&& 1"
8953 [(const_int 0)]
8954 "emit_note (NOTE_INSN_DELETED); DONE;")
8955
8956 ;; Set the carry flag from the carry flag.
8957 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8958 [(set (reg:CCC FLAGS_REG)
8959 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8960 (const_int 0)] UNSPEC_CC_NE))]
8961 "ix86_pre_reload_split ()"
8962 "#"
8963 "&& 1"
8964 [(const_int 0)]
8965 "emit_note (NOTE_INSN_DELETED); DONE;")
8966 \f
8967 ;; Overflow setting add instructions
8968
8969 (define_expand "addqi3_cconly_overflow"
8970 [(parallel
8971 [(set (reg:CCC FLAGS_REG)
8972 (compare:CCC
8973 (plus:QI
8974 (match_operand:QI 0 "nonimmediate_operand")
8975 (match_operand:QI 1 "general_operand"))
8976 (match_dup 0)))
8977 (clobber (scratch:QI))])]
8978 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8979
8980 (define_insn "*add<mode>3_cconly_overflow_1"
8981 [(set (reg:CCC FLAGS_REG)
8982 (compare:CCC
8983 (plus:SWI
8984 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8985 (match_operand:SWI 2 "<general_operand>" "<g>"))
8986 (match_dup 1)))
8987 (clobber (match_scratch:SWI 0 "=<r>"))]
8988 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8989 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8990 [(set_attr "type" "alu")
8991 (set_attr "mode" "<MODE>")])
8992
8993 (define_insn "@add<mode>3_cc_overflow_1"
8994 [(set (reg:CCC FLAGS_REG)
8995 (compare:CCC
8996 (plus:SWI
8997 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8998 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8999 (match_dup 1)))
9000 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9001 (plus:SWI (match_dup 1) (match_dup 2)))]
9002 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9003 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9004 [(set_attr "type" "alu")
9005 (set_attr "mode" "<MODE>")])
9006
9007 (define_peephole2
9008 [(parallel [(set (reg:CCC FLAGS_REG)
9009 (compare:CCC
9010 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9011 (match_operand:SWI 1 "memory_operand"))
9012 (match_dup 0)))
9013 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9014 (set (match_dup 1) (match_dup 0))]
9015 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9016 && peep2_reg_dead_p (2, operands[0])
9017 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9018 [(parallel [(set (reg:CCC FLAGS_REG)
9019 (compare:CCC
9020 (plus:SWI (match_dup 1) (match_dup 0))
9021 (match_dup 1)))
9022 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9023
9024 (define_peephole2
9025 [(set (match_operand:SWI 0 "general_reg_operand")
9026 (match_operand:SWI 1 "memory_operand"))
9027 (parallel [(set (reg:CCC FLAGS_REG)
9028 (compare:CCC
9029 (plus:SWI (match_dup 0)
9030 (match_operand:SWI 2 "memory_operand"))
9031 (match_dup 0)))
9032 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9033 (set (match_dup 1) (match_dup 0))]
9034 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9035 && peep2_reg_dead_p (3, operands[0])
9036 && !reg_overlap_mentioned_p (operands[0], operands[1])
9037 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9038 [(set (match_dup 0) (match_dup 2))
9039 (parallel [(set (reg:CCC FLAGS_REG)
9040 (compare:CCC
9041 (plus:SWI (match_dup 1) (match_dup 0))
9042 (match_dup 1)))
9043 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9044
9045 (define_insn "*addsi3_zext_cc_overflow_1"
9046 [(set (reg:CCC FLAGS_REG)
9047 (compare:CCC
9048 (plus:SI
9049 (match_operand:SI 1 "nonimmediate_operand" "%0")
9050 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9051 (match_dup 1)))
9052 (set (match_operand:DI 0 "register_operand" "=r")
9053 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9054 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9055 "add{l}\t{%2, %k0|%k0, %2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "SI")])
9058
9059 (define_insn "*add<mode>3_cconly_overflow_2"
9060 [(set (reg:CCC FLAGS_REG)
9061 (compare:CCC
9062 (plus:SWI
9063 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9064 (match_operand:SWI 2 "<general_operand>" "<g>"))
9065 (match_dup 2)))
9066 (clobber (match_scratch:SWI 0 "=<r>"))]
9067 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9068 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "mode" "<MODE>")])
9071
9072 (define_insn "*add<mode>3_cc_overflow_2"
9073 [(set (reg:CCC FLAGS_REG)
9074 (compare:CCC
9075 (plus:SWI
9076 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9077 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9078 (match_dup 2)))
9079 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9080 (plus:SWI (match_dup 1) (match_dup 2)))]
9081 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9082 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9083 [(set_attr "type" "alu")
9084 (set_attr "mode" "<MODE>")])
9085
9086 (define_insn "*addsi3_zext_cc_overflow_2"
9087 [(set (reg:CCC FLAGS_REG)
9088 (compare:CCC
9089 (plus:SI
9090 (match_operand:SI 1 "nonimmediate_operand" "%0")
9091 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9092 (match_dup 2)))
9093 (set (match_operand:DI 0 "register_operand" "=r")
9094 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9095 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9096 "add{l}\t{%2, %k0|%k0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "SI")])
9099
9100 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9101 [(set (reg:CCC FLAGS_REG)
9102 (compare:CCC
9103 (plus:<DWI>
9104 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
9105 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
9106 (match_dup 1)))
9107 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
9108 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9109 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
9110 "#"
9111 "&& reload_completed"
9112 [(parallel [(set (reg:CCC FLAGS_REG)
9113 (compare:CCC
9114 (plus:DWIH (match_dup 1) (match_dup 2))
9115 (match_dup 1)))
9116 (set (match_dup 0)
9117 (plus:DWIH (match_dup 1) (match_dup 2)))])
9118 (parallel [(set (reg:CCC FLAGS_REG)
9119 (compare:CCC
9120 (zero_extend:<DWI>
9121 (plus:DWIH
9122 (plus:DWIH
9123 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9124 (match_dup 4))
9125 (match_dup 5)))
9126 (plus:<DWI>
9127 (match_dup 6)
9128 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9129 (set (match_dup 3)
9130 (plus:DWIH
9131 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9132 (match_dup 4))
9133 (match_dup 5)))])]
9134 {
9135 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9136 if (operands[2] == const0_rtx)
9137 {
9138 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9139 DONE;
9140 }
9141 if (CONST_INT_P (operands[5]))
9142 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9143 operands[5], <MODE>mode);
9144 else
9145 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9146 })
9147
9148 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9149 ;; test, where the latter is preferrable if we have some carry consuming
9150 ;; instruction.
9151 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9152 ;; + (1 - CF).
9153 (define_insn_and_split "*add<mode>3_eq"
9154 [(set (match_operand:SWI 0 "nonimmediate_operand")
9155 (plus:SWI
9156 (plus:SWI
9157 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9158 (match_operand:SWI 1 "nonimmediate_operand"))
9159 (match_operand:SWI 2 "<general_operand>")))
9160 (clobber (reg:CC FLAGS_REG))]
9161 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9162 && ix86_pre_reload_split ()"
9163 "#"
9164 "&& 1"
9165 [(set (reg:CC FLAGS_REG)
9166 (compare:CC (match_dup 3) (const_int 1)))
9167 (parallel [(set (match_dup 0)
9168 (plus:SWI
9169 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9170 (match_dup 1))
9171 (match_dup 2)))
9172 (clobber (reg:CC FLAGS_REG))])])
9173
9174 (define_insn_and_split "*add<mode>3_ne"
9175 [(set (match_operand:SWI 0 "nonimmediate_operand")
9176 (plus:SWI
9177 (plus:SWI
9178 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9179 (match_operand:SWI 1 "nonimmediate_operand"))
9180 (match_operand:SWI 2 "<immediate_operand>")))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "CONST_INT_P (operands[2])
9183 && (<MODE>mode != DImode
9184 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9185 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9186 && ix86_pre_reload_split ()"
9187 "#"
9188 "&& 1"
9189 [(set (reg:CC FLAGS_REG)
9190 (compare:CC (match_dup 3) (const_int 1)))
9191 (parallel [(set (match_dup 0)
9192 (minus:SWI
9193 (minus:SWI (match_dup 1)
9194 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9195 (match_dup 2)))
9196 (clobber (reg:CC FLAGS_REG))])]
9197 {
9198 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9199 <MODE>mode == DImode ? SImode : <MODE>mode);
9200 })
9201
9202 (define_insn_and_split "*add<mode>3_eq_0"
9203 [(set (match_operand:SWI 0 "nonimmediate_operand")
9204 (plus:SWI
9205 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9206 (match_operand:SWI 1 "<general_operand>")))
9207 (clobber (reg:CC FLAGS_REG))]
9208 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9209 && ix86_pre_reload_split ()"
9210 "#"
9211 "&& 1"
9212 [(set (reg:CC FLAGS_REG)
9213 (compare:CC (match_dup 2) (const_int 1)))
9214 (parallel [(set (match_dup 0)
9215 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9216 (match_dup 1)))
9217 (clobber (reg:CC FLAGS_REG))])]
9218 {
9219 if (!nonimmediate_operand (operands[1], <MODE>mode))
9220 operands[1] = force_reg (<MODE>mode, operands[1]);
9221 })
9222
9223 (define_insn_and_split "*add<mode>3_ne_0"
9224 [(set (match_operand:SWI 0 "nonimmediate_operand")
9225 (plus:SWI
9226 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9227 (match_operand:SWI 1 "<general_operand>")))
9228 (clobber (reg:CC FLAGS_REG))]
9229 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9230 && ix86_pre_reload_split ()"
9231 "#"
9232 "&& 1"
9233 [(set (reg:CC FLAGS_REG)
9234 (compare:CC (match_dup 2) (const_int 1)))
9235 (parallel [(set (match_dup 0)
9236 (minus:SWI (minus:SWI
9237 (match_dup 1)
9238 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9239 (const_int -1)))
9240 (clobber (reg:CC FLAGS_REG))])]
9241 {
9242 if (!nonimmediate_operand (operands[1], <MODE>mode))
9243 operands[1] = force_reg (<MODE>mode, operands[1]);
9244 })
9245
9246 (define_insn_and_split "*sub<mode>3_eq"
9247 [(set (match_operand:SWI 0 "nonimmediate_operand")
9248 (minus:SWI
9249 (minus:SWI
9250 (match_operand:SWI 1 "nonimmediate_operand")
9251 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9252 (const_int 0)))
9253 (match_operand:SWI 2 "<general_operand>")))
9254 (clobber (reg:CC FLAGS_REG))]
9255 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9256 && ix86_pre_reload_split ()"
9257 "#"
9258 "&& 1"
9259 [(set (reg:CC FLAGS_REG)
9260 (compare:CC (match_dup 3) (const_int 1)))
9261 (parallel [(set (match_dup 0)
9262 (minus:SWI
9263 (minus:SWI (match_dup 1)
9264 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9265 (match_dup 2)))
9266 (clobber (reg:CC FLAGS_REG))])])
9267
9268 (define_insn_and_split "*sub<mode>3_ne"
9269 [(set (match_operand:SWI 0 "nonimmediate_operand")
9270 (plus:SWI
9271 (minus:SWI
9272 (match_operand:SWI 1 "nonimmediate_operand")
9273 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9274 (const_int 0)))
9275 (match_operand:SWI 2 "<immediate_operand>")))
9276 (clobber (reg:CC FLAGS_REG))]
9277 "CONST_INT_P (operands[2])
9278 && (<MODE>mode != DImode
9279 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9280 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9281 && ix86_pre_reload_split ()"
9282 "#"
9283 "&& 1"
9284 [(set (reg:CC FLAGS_REG)
9285 (compare:CC (match_dup 3) (const_int 1)))
9286 (parallel [(set (match_dup 0)
9287 (plus:SWI
9288 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9289 (match_dup 1))
9290 (match_dup 2)))
9291 (clobber (reg:CC FLAGS_REG))])]
9292 {
9293 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9294 <MODE>mode == DImode ? SImode : <MODE>mode);
9295 })
9296
9297 (define_insn_and_split "*sub<mode>3_eq_1"
9298 [(set (match_operand:SWI 0 "nonimmediate_operand")
9299 (plus:SWI
9300 (minus:SWI
9301 (match_operand:SWI 1 "nonimmediate_operand")
9302 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9303 (const_int 0)))
9304 (match_operand:SWI 2 "<immediate_operand>")))
9305 (clobber (reg:CC FLAGS_REG))]
9306 "CONST_INT_P (operands[2])
9307 && (<MODE>mode != DImode
9308 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9309 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9310 && ix86_pre_reload_split ()"
9311 "#"
9312 "&& 1"
9313 [(set (reg:CC FLAGS_REG)
9314 (compare:CC (match_dup 3) (const_int 1)))
9315 (parallel [(set (match_dup 0)
9316 (minus:SWI
9317 (minus:SWI (match_dup 1)
9318 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9319 (match_dup 2)))
9320 (clobber (reg:CC FLAGS_REG))])]
9321 {
9322 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9323 <MODE>mode == DImode ? SImode : <MODE>mode);
9324 })
9325
9326 (define_insn_and_split "*sub<mode>3_eq_0"
9327 [(set (match_operand:SWI 0 "nonimmediate_operand")
9328 (minus:SWI
9329 (match_operand:SWI 1 "<general_operand>")
9330 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9333 && ix86_pre_reload_split ()"
9334 "#"
9335 "&& 1"
9336 [(set (reg:CC FLAGS_REG)
9337 (compare:CC (match_dup 2) (const_int 1)))
9338 (parallel [(set (match_dup 0)
9339 (minus:SWI (match_dup 1)
9340 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9341 (clobber (reg:CC FLAGS_REG))])]
9342 {
9343 if (!nonimmediate_operand (operands[1], <MODE>mode))
9344 operands[1] = force_reg (<MODE>mode, operands[1]);
9345 })
9346
9347 (define_insn_and_split "*sub<mode>3_ne_0"
9348 [(set (match_operand:SWI 0 "nonimmediate_operand")
9349 (minus:SWI
9350 (match_operand:SWI 1 "<general_operand>")
9351 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9352 (clobber (reg:CC FLAGS_REG))]
9353 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9354 && ix86_pre_reload_split ()"
9355 "#"
9356 "&& 1"
9357 [(set (reg:CC FLAGS_REG)
9358 (compare:CC (match_dup 2) (const_int 1)))
9359 (parallel [(set (match_dup 0)
9360 (plus:SWI (plus:SWI
9361 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9362 (match_dup 1))
9363 (const_int -1)))
9364 (clobber (reg:CC FLAGS_REG))])]
9365 {
9366 if (!nonimmediate_operand (operands[1], <MODE>mode))
9367 operands[1] = force_reg (<MODE>mode, operands[1]);
9368 })
9369
9370 ;; The patterns that match these are at the end of this file.
9371
9372 (define_expand "<insn>xf3"
9373 [(set (match_operand:XF 0 "register_operand")
9374 (plusminus:XF
9375 (match_operand:XF 1 "register_operand")
9376 (match_operand:XF 2 "register_operand")))]
9377 "TARGET_80387")
9378
9379 (define_expand "<insn>hf3"
9380 [(set (match_operand:HF 0 "register_operand")
9381 (plusminus:HF
9382 (match_operand:HF 1 "register_operand")
9383 (match_operand:HF 2 "nonimmediate_operand")))]
9384 "TARGET_AVX512FP16")
9385
9386 (define_expand "<insn><mode>3"
9387 [(set (match_operand:MODEF 0 "register_operand")
9388 (plusminus:MODEF
9389 (match_operand:MODEF 1 "register_operand")
9390 (match_operand:MODEF 2 "nonimmediate_operand")))]
9391 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9392 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9393 \f
9394 ;; Multiply instructions
9395
9396 (define_expand "mul<mode>3"
9397 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9398 (mult:SWIM248
9399 (match_operand:SWIM248 1 "register_operand")
9400 (match_operand:SWIM248 2 "<general_operand>")))
9401 (clobber (reg:CC FLAGS_REG))])])
9402
9403 (define_expand "mulqi3"
9404 [(parallel [(set (match_operand:QI 0 "register_operand")
9405 (mult:QI
9406 (match_operand:QI 1 "register_operand")
9407 (match_operand:QI 2 "nonimmediate_operand")))
9408 (clobber (reg:CC FLAGS_REG))])]
9409 "TARGET_QIMODE_MATH")
9410
9411 ;; On AMDFAM10
9412 ;; IMUL reg32/64, reg32/64, imm8 Direct
9413 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9414 ;; IMUL reg32/64, reg32/64, imm32 Direct
9415 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9416 ;; IMUL reg32/64, reg32/64 Direct
9417 ;; IMUL reg32/64, mem32/64 Direct
9418 ;;
9419 ;; On BDVER1, all above IMULs use DirectPath
9420 ;;
9421 ;; On AMDFAM10
9422 ;; IMUL reg16, reg16, imm8 VectorPath
9423 ;; IMUL reg16, mem16, imm8 VectorPath
9424 ;; IMUL reg16, reg16, imm16 VectorPath
9425 ;; IMUL reg16, mem16, imm16 VectorPath
9426 ;; IMUL reg16, reg16 Direct
9427 ;; IMUL reg16, mem16 Direct
9428 ;;
9429 ;; On BDVER1, all HI MULs use DoublePath
9430
9431 (define_insn "*mul<mode>3_1"
9432 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9433 (mult:SWIM248
9434 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9435 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9436 (clobber (reg:CC FLAGS_REG))]
9437 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9438 "@
9439 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9440 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9441 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9442 [(set_attr "type" "imul")
9443 (set_attr "prefix_0f" "0,0,1")
9444 (set (attr "athlon_decode")
9445 (cond [(eq_attr "cpu" "athlon")
9446 (const_string "vector")
9447 (eq_attr "alternative" "1")
9448 (const_string "vector")
9449 (and (eq_attr "alternative" "2")
9450 (ior (match_test "<MODE>mode == HImode")
9451 (match_operand 1 "memory_operand")))
9452 (const_string "vector")]
9453 (const_string "direct")))
9454 (set (attr "amdfam10_decode")
9455 (cond [(and (eq_attr "alternative" "0,1")
9456 (ior (match_test "<MODE>mode == HImode")
9457 (match_operand 1 "memory_operand")))
9458 (const_string "vector")]
9459 (const_string "direct")))
9460 (set (attr "bdver1_decode")
9461 (if_then_else
9462 (match_test "<MODE>mode == HImode")
9463 (const_string "double")
9464 (const_string "direct")))
9465 (set_attr "mode" "<MODE>")])
9466
9467 (define_insn "*mulsi3_1_zext"
9468 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9469 (zero_extend:DI
9470 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9471 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9472 (clobber (reg:CC FLAGS_REG))]
9473 "TARGET_64BIT
9474 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9475 "@
9476 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9477 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9478 imul{l}\t{%2, %k0|%k0, %2}"
9479 [(set_attr "type" "imul")
9480 (set_attr "prefix_0f" "0,0,1")
9481 (set (attr "athlon_decode")
9482 (cond [(eq_attr "cpu" "athlon")
9483 (const_string "vector")
9484 (eq_attr "alternative" "1")
9485 (const_string "vector")
9486 (and (eq_attr "alternative" "2")
9487 (match_operand 1 "memory_operand"))
9488 (const_string "vector")]
9489 (const_string "direct")))
9490 (set (attr "amdfam10_decode")
9491 (cond [(and (eq_attr "alternative" "0,1")
9492 (match_operand 1 "memory_operand"))
9493 (const_string "vector")]
9494 (const_string "direct")))
9495 (set_attr "bdver1_decode" "direct")
9496 (set_attr "mode" "SI")])
9497
9498 ;;On AMDFAM10 and BDVER1
9499 ;; MUL reg8 Direct
9500 ;; MUL mem8 Direct
9501
9502 (define_insn "*mulqi3_1"
9503 [(set (match_operand:QI 0 "register_operand" "=a")
9504 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9505 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9506 (clobber (reg:CC FLAGS_REG))]
9507 "TARGET_QIMODE_MATH
9508 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9509 "mul{b}\t%2"
9510 [(set_attr "type" "imul")
9511 (set_attr "length_immediate" "0")
9512 (set (attr "athlon_decode")
9513 (if_then_else (eq_attr "cpu" "athlon")
9514 (const_string "vector")
9515 (const_string "direct")))
9516 (set_attr "amdfam10_decode" "direct")
9517 (set_attr "bdver1_decode" "direct")
9518 (set_attr "mode" "QI")])
9519
9520 ;; Multiply with jump on overflow.
9521 (define_expand "mulv<mode>4"
9522 [(parallel [(set (reg:CCO FLAGS_REG)
9523 (eq:CCO (mult:<DWI>
9524 (sign_extend:<DWI>
9525 (match_operand:SWI248 1 "register_operand"))
9526 (match_dup 4))
9527 (sign_extend:<DWI>
9528 (mult:SWI248 (match_dup 1)
9529 (match_operand:SWI248 2
9530 "<general_operand>")))))
9531 (set (match_operand:SWI248 0 "register_operand")
9532 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9533 (set (pc) (if_then_else
9534 (eq (reg:CCO FLAGS_REG) (const_int 0))
9535 (label_ref (match_operand 3))
9536 (pc)))]
9537 ""
9538 {
9539 if (CONST_INT_P (operands[2]))
9540 operands[4] = operands[2];
9541 else
9542 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9543 })
9544
9545 (define_insn "*mulv<mode>4"
9546 [(set (reg:CCO FLAGS_REG)
9547 (eq:CCO (mult:<DWI>
9548 (sign_extend:<DWI>
9549 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9550 (sign_extend:<DWI>
9551 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9552 (sign_extend:<DWI>
9553 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9554 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9555 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9556 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9557 "@
9558 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9559 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9560 [(set_attr "type" "imul")
9561 (set_attr "prefix_0f" "0,1")
9562 (set (attr "athlon_decode")
9563 (cond [(eq_attr "cpu" "athlon")
9564 (const_string "vector")
9565 (eq_attr "alternative" "0")
9566 (const_string "vector")
9567 (and (eq_attr "alternative" "1")
9568 (match_operand 1 "memory_operand"))
9569 (const_string "vector")]
9570 (const_string "direct")))
9571 (set (attr "amdfam10_decode")
9572 (cond [(and (eq_attr "alternative" "1")
9573 (match_operand 1 "memory_operand"))
9574 (const_string "vector")]
9575 (const_string "direct")))
9576 (set_attr "bdver1_decode" "direct")
9577 (set_attr "mode" "<MODE>")])
9578
9579 (define_insn "*mulvhi4"
9580 [(set (reg:CCO FLAGS_REG)
9581 (eq:CCO (mult:SI
9582 (sign_extend:SI
9583 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9584 (sign_extend:SI
9585 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9586 (sign_extend:SI
9587 (mult:HI (match_dup 1) (match_dup 2)))))
9588 (set (match_operand:HI 0 "register_operand" "=r")
9589 (mult:HI (match_dup 1) (match_dup 2)))]
9590 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9591 "imul{w}\t{%2, %0|%0, %2}"
9592 [(set_attr "type" "imul")
9593 (set_attr "prefix_0f" "1")
9594 (set_attr "athlon_decode" "vector")
9595 (set_attr "amdfam10_decode" "direct")
9596 (set_attr "bdver1_decode" "double")
9597 (set_attr "mode" "HI")])
9598
9599 (define_insn "*mulv<mode>4_1"
9600 [(set (reg:CCO FLAGS_REG)
9601 (eq:CCO (mult:<DWI>
9602 (sign_extend:<DWI>
9603 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9604 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9605 (sign_extend:<DWI>
9606 (mult:SWI248 (match_dup 1)
9607 (match_operand:SWI248 2
9608 "<immediate_operand>" "K,<i>")))))
9609 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9610 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9611 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9612 && CONST_INT_P (operands[2])
9613 && INTVAL (operands[2]) == INTVAL (operands[3])"
9614 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9615 [(set_attr "type" "imul")
9616 (set (attr "prefix_0f")
9617 (if_then_else
9618 (match_test "<MODE>mode == HImode")
9619 (const_string "0")
9620 (const_string "*")))
9621 (set (attr "athlon_decode")
9622 (cond [(eq_attr "cpu" "athlon")
9623 (const_string "vector")
9624 (eq_attr "alternative" "1")
9625 (const_string "vector")]
9626 (const_string "direct")))
9627 (set (attr "amdfam10_decode")
9628 (cond [(ior (match_test "<MODE>mode == HImode")
9629 (match_operand 1 "memory_operand"))
9630 (const_string "vector")]
9631 (const_string "direct")))
9632 (set (attr "bdver1_decode")
9633 (if_then_else
9634 (match_test "<MODE>mode == HImode")
9635 (const_string "double")
9636 (const_string "direct")))
9637 (set_attr "mode" "<MODE>")
9638 (set (attr "length_immediate")
9639 (cond [(eq_attr "alternative" "0")
9640 (const_string "1")
9641 (match_test "<MODE_SIZE> == 8")
9642 (const_string "4")]
9643 (const_string "<MODE_SIZE>")))])
9644
9645 (define_expand "umulv<mode>4"
9646 [(parallel [(set (reg:CCO FLAGS_REG)
9647 (eq:CCO (mult:<DWI>
9648 (zero_extend:<DWI>
9649 (match_operand:SWI248 1
9650 "nonimmediate_operand"))
9651 (zero_extend:<DWI>
9652 (match_operand:SWI248 2
9653 "nonimmediate_operand")))
9654 (zero_extend:<DWI>
9655 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9656 (set (match_operand:SWI248 0 "register_operand")
9657 (mult:SWI248 (match_dup 1) (match_dup 2)))
9658 (clobber (scratch:SWI248))])
9659 (set (pc) (if_then_else
9660 (eq (reg:CCO FLAGS_REG) (const_int 0))
9661 (label_ref (match_operand 3))
9662 (pc)))]
9663 ""
9664 {
9665 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9666 operands[1] = force_reg (<MODE>mode, operands[1]);
9667 })
9668
9669 (define_insn "*umulv<mode>4"
9670 [(set (reg:CCO FLAGS_REG)
9671 (eq:CCO (mult:<DWI>
9672 (zero_extend:<DWI>
9673 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9674 (zero_extend:<DWI>
9675 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9676 (zero_extend:<DWI>
9677 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9678 (set (match_operand:SWI248 0 "register_operand" "=a")
9679 (mult:SWI248 (match_dup 1) (match_dup 2)))
9680 (clobber (match_scratch:SWI248 3 "=d"))]
9681 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9682 "mul{<imodesuffix>}\t%2"
9683 [(set_attr "type" "imul")
9684 (set_attr "length_immediate" "0")
9685 (set (attr "athlon_decode")
9686 (if_then_else (eq_attr "cpu" "athlon")
9687 (const_string "vector")
9688 (const_string "double")))
9689 (set_attr "amdfam10_decode" "double")
9690 (set_attr "bdver1_decode" "direct")
9691 (set_attr "mode" "<MODE>")])
9692
9693 (define_expand "<u>mulvqi4"
9694 [(parallel [(set (reg:CCO FLAGS_REG)
9695 (eq:CCO (mult:HI
9696 (any_extend:HI
9697 (match_operand:QI 1 "nonimmediate_operand"))
9698 (any_extend:HI
9699 (match_operand:QI 2 "nonimmediate_operand")))
9700 (any_extend:HI
9701 (mult:QI (match_dup 1) (match_dup 2)))))
9702 (set (match_operand:QI 0 "register_operand")
9703 (mult:QI (match_dup 1) (match_dup 2)))])
9704 (set (pc) (if_then_else
9705 (eq (reg:CCO FLAGS_REG) (const_int 0))
9706 (label_ref (match_operand 3))
9707 (pc)))]
9708 "TARGET_QIMODE_MATH"
9709 {
9710 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9711 operands[1] = force_reg (QImode, operands[1]);
9712 })
9713
9714 (define_insn "*<u>mulvqi4"
9715 [(set (reg:CCO FLAGS_REG)
9716 (eq:CCO (mult:HI
9717 (any_extend:HI
9718 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9719 (any_extend:HI
9720 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9721 (any_extend:HI
9722 (mult:QI (match_dup 1) (match_dup 2)))))
9723 (set (match_operand:QI 0 "register_operand" "=a")
9724 (mult:QI (match_dup 1) (match_dup 2)))]
9725 "TARGET_QIMODE_MATH
9726 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9727 "<sgnprefix>mul{b}\t%2"
9728 [(set_attr "type" "imul")
9729 (set_attr "length_immediate" "0")
9730 (set (attr "athlon_decode")
9731 (if_then_else (eq_attr "cpu" "athlon")
9732 (const_string "vector")
9733 (const_string "direct")))
9734 (set_attr "amdfam10_decode" "direct")
9735 (set_attr "bdver1_decode" "direct")
9736 (set_attr "mode" "QI")])
9737
9738 (define_expand "<u>mul<mode><dwi>3"
9739 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9740 (mult:<DWI>
9741 (any_extend:<DWI>
9742 (match_operand:DWIH 1 "register_operand"))
9743 (any_extend:<DWI>
9744 (match_operand:DWIH 2 "nonimmediate_operand"))))
9745 (clobber (reg:CC FLAGS_REG))])])
9746
9747 (define_expand "<u>mulqihi3"
9748 [(parallel [(set (match_operand:HI 0 "register_operand")
9749 (mult:HI
9750 (any_extend:HI
9751 (match_operand:QI 1 "register_operand"))
9752 (any_extend:HI
9753 (match_operand:QI 2 "nonimmediate_operand"))))
9754 (clobber (reg:CC FLAGS_REG))])]
9755 "TARGET_QIMODE_MATH")
9756
9757 (define_insn "*bmi2_umul<mode><dwi>3_1"
9758 [(set (match_operand:DWIH 0 "register_operand" "=r")
9759 (mult:DWIH
9760 (match_operand:DWIH 2 "register_operand" "%d")
9761 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9762 (set (match_operand:DWIH 1 "register_operand" "=r")
9763 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9764 "TARGET_BMI2"
9765 "mulx\t{%3, %0, %1|%1, %0, %3}"
9766 [(set_attr "type" "imulx")
9767 (set_attr "prefix" "vex")
9768 (set_attr "mode" "<MODE>")])
9769
9770 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
9771 (define_peephole2
9772 [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
9773 (mult:DWIH (match_operand:DWIH 2 "register_operand")
9774 (match_operand:DWIH 3 "nonimmediate_operand")))
9775 (set (match_operand:DWIH 1 "general_reg_operand")
9776 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
9777 (set (match_operand:DWIH 4 "general_reg_operand")
9778 (match_operand:DWIH 5 "general_reg_operand"))]
9779 "TARGET_BMI2
9780 && ((REGNO (operands[5]) == REGNO (operands[0])
9781 && REGNO (operands[1]) != REGNO (operands[4]))
9782 || (REGNO (operands[5]) == REGNO (operands[1])
9783 && REGNO (operands[0]) != REGNO (operands[4])))
9784 && peep2_reg_dead_p (2, operands[5])"
9785 [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
9786 (set (match_dup 1)
9787 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
9788 {
9789 if (REGNO (operands[5]) == REGNO (operands[0]))
9790 operands[0] = operands[4];
9791 else
9792 operands[1] = operands[4];
9793 })
9794
9795 (define_insn "*umul<mode><dwi>3_1"
9796 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9797 (mult:<DWI>
9798 (zero_extend:<DWI>
9799 (match_operand:DWIH 1 "register_operand" "%d,a"))
9800 (zero_extend:<DWI>
9801 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9804 "@
9805 #
9806 mul{<imodesuffix>}\t%2"
9807 [(set_attr "isa" "bmi2,*")
9808 (set_attr "type" "imulx,imul")
9809 (set_attr "length_immediate" "*,0")
9810 (set (attr "athlon_decode")
9811 (cond [(eq_attr "alternative" "1")
9812 (if_then_else (eq_attr "cpu" "athlon")
9813 (const_string "vector")
9814 (const_string "double"))]
9815 (const_string "*")))
9816 (set_attr "amdfam10_decode" "*,double")
9817 (set_attr "bdver1_decode" "*,direct")
9818 (set_attr "prefix" "vex,orig")
9819 (set_attr "mode" "<MODE>")])
9820
9821 ;; Convert mul to the mulx pattern to avoid flags dependency.
9822 (define_split
9823 [(set (match_operand:<DWI> 0 "register_operand")
9824 (mult:<DWI>
9825 (zero_extend:<DWI>
9826 (match_operand:DWIH 1 "register_operand"))
9827 (zero_extend:<DWI>
9828 (match_operand:DWIH 2 "nonimmediate_operand"))))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "TARGET_BMI2 && reload_completed
9831 && REGNO (operands[1]) == DX_REG"
9832 [(parallel [(set (match_dup 3)
9833 (mult:DWIH (match_dup 1) (match_dup 2)))
9834 (set (match_dup 4)
9835 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9836 {
9837 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9838
9839 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9840 })
9841
9842 (define_insn "*mul<mode><dwi>3_1"
9843 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9844 (mult:<DWI>
9845 (sign_extend:<DWI>
9846 (match_operand:DWIH 1 "register_operand" "%a"))
9847 (sign_extend:<DWI>
9848 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9849 (clobber (reg:CC FLAGS_REG))]
9850 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9851 "imul{<imodesuffix>}\t%2"
9852 [(set_attr "type" "imul")
9853 (set_attr "length_immediate" "0")
9854 (set (attr "athlon_decode")
9855 (if_then_else (eq_attr "cpu" "athlon")
9856 (const_string "vector")
9857 (const_string "double")))
9858 (set_attr "amdfam10_decode" "double")
9859 (set_attr "bdver1_decode" "direct")
9860 (set_attr "mode" "<MODE>")])
9861
9862 (define_insn "*<u>mulqihi3_1"
9863 [(set (match_operand:HI 0 "register_operand" "=a")
9864 (mult:HI
9865 (any_extend:HI
9866 (match_operand:QI 1 "register_operand" "%0"))
9867 (any_extend:HI
9868 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9869 (clobber (reg:CC FLAGS_REG))]
9870 "TARGET_QIMODE_MATH
9871 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9872 "<sgnprefix>mul{b}\t%2"
9873 [(set_attr "type" "imul")
9874 (set_attr "length_immediate" "0")
9875 (set (attr "athlon_decode")
9876 (if_then_else (eq_attr "cpu" "athlon")
9877 (const_string "vector")
9878 (const_string "direct")))
9879 (set_attr "amdfam10_decode" "direct")
9880 (set_attr "bdver1_decode" "direct")
9881 (set_attr "mode" "QI")])
9882
9883 ;; Widening multiplication peephole2s to tweak register allocation.
9884 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
9885 (define_peephole2
9886 [(set (match_operand:DWIH 0 "general_reg_operand")
9887 (match_operand:DWIH 1 "immediate_operand"))
9888 (set (match_operand:DWIH 2 "general_reg_operand")
9889 (match_operand:DWIH 3 "general_reg_operand"))
9890 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9891 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9892 (zero_extend:<DWI> (match_dup 0))))
9893 (clobber (reg:CC FLAGS_REG))])]
9894 "REGNO (operands[3]) != AX_REG
9895 && REGNO (operands[0]) != REGNO (operands[2])
9896 && REGNO (operands[0]) != REGNO (operands[3])
9897 && (REGNO (operands[0]) == REGNO (operands[4])
9898 || REGNO (operands[0]) == DX_REG
9899 || peep2_reg_dead_p (3, operands[0]))"
9900 [(set (match_dup 2) (match_dup 1))
9901 (parallel [(set (match_dup 4)
9902 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9903 (zero_extend:<DWI> (match_dup 3))))
9904 (clobber (reg:CC FLAGS_REG))])])
9905
9906 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
9907 (define_peephole2
9908 [(set (match_operand:DWIH 0 "general_reg_operand")
9909 (match_operand:DWIH 1 "immediate_operand"))
9910 (set (match_operand:DWIH 2 "general_reg_operand")
9911 (match_operand:DWIH 3 "general_reg_operand"))
9912 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9913 (mult:DWIH (match_dup 2) (match_dup 0)))
9914 (set (match_operand:DWIH 5 "general_reg_operand")
9915 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9916 "REGNO (operands[3]) != DX_REG
9917 && REGNO (operands[0]) != REGNO (operands[2])
9918 && REGNO (operands[0]) != REGNO (operands[3])
9919 && (REGNO (operands[0]) == REGNO (operands[4])
9920 || REGNO (operands[0]) == REGNO (operands[5])
9921 || peep2_reg_dead_p (3, operands[0]))"
9922 [(set (match_dup 2) (match_dup 1))
9923 (parallel [(set (match_dup 4)
9924 (mult:DWIH (match_dup 2) (match_dup 3)))
9925 (set (match_dup 5)
9926 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
9927
9928 ;; Highpart multiplication patterns
9929 (define_insn "<s>mul<mode>3_highpart"
9930 [(set (match_operand:DWIH 0 "register_operand" "=d")
9931 (any_mul_highpart:DWIH
9932 (match_operand:DWIH 1 "register_operand" "%a")
9933 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9934 (clobber (match_scratch:DWIH 3 "=1"))
9935 (clobber (reg:CC FLAGS_REG))]
9936 ""
9937 "<sgnprefix>mul{<imodesuffix>}\t%2"
9938 [(set_attr "type" "imul")
9939 (set_attr "length_immediate" "0")
9940 (set (attr "athlon_decode")
9941 (if_then_else (eq_attr "cpu" "athlon")
9942 (const_string "vector")
9943 (const_string "double")))
9944 (set_attr "amdfam10_decode" "double")
9945 (set_attr "bdver1_decode" "direct")
9946 (set_attr "mode" "<MODE>")])
9947
9948 (define_insn "*<s>mulsi3_highpart_zext"
9949 [(set (match_operand:DI 0 "register_operand" "=d")
9950 (zero_extend:DI
9951 (any_mul_highpart:SI
9952 (match_operand:SI 1 "register_operand" "%a")
9953 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9954 (clobber (match_scratch:SI 3 "=1"))
9955 (clobber (reg:CC FLAGS_REG))]
9956 "TARGET_64BIT"
9957 "<sgnprefix>mul{l}\t%2"
9958 [(set_attr "type" "imul")
9959 (set_attr "length_immediate" "0")
9960 (set (attr "athlon_decode")
9961 (if_then_else (eq_attr "cpu" "athlon")
9962 (const_string "vector")
9963 (const_string "double")))
9964 (set_attr "amdfam10_decode" "double")
9965 (set_attr "bdver1_decode" "direct")
9966 (set_attr "mode" "SI")])
9967
9968 (define_insn "*<s>muldi3_highpart_1"
9969 [(set (match_operand:DI 0 "register_operand" "=d")
9970 (truncate:DI
9971 (lshiftrt:TI
9972 (mult:TI
9973 (any_extend:TI
9974 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9975 (any_extend:TI
9976 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9977 (const_int 64))))
9978 (clobber (match_scratch:DI 3 "=1"))
9979 (clobber (reg:CC FLAGS_REG))]
9980 "TARGET_64BIT
9981 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9982 "<sgnprefix>mul{q}\t%2"
9983 [(set_attr "type" "imul")
9984 (set_attr "length_immediate" "0")
9985 (set (attr "athlon_decode")
9986 (if_then_else (eq_attr "cpu" "athlon")
9987 (const_string "vector")
9988 (const_string "double")))
9989 (set_attr "amdfam10_decode" "double")
9990 (set_attr "bdver1_decode" "direct")
9991 (set_attr "mode" "DI")])
9992
9993 (define_insn "*<s>mulsi3_highpart_zext"
9994 [(set (match_operand:DI 0 "register_operand" "=d")
9995 (zero_extend:DI (truncate:SI
9996 (lshiftrt:DI
9997 (mult:DI (any_extend:DI
9998 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9999 (any_extend:DI
10000 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10001 (const_int 32)))))
10002 (clobber (match_scratch:SI 3 "=1"))
10003 (clobber (reg:CC FLAGS_REG))]
10004 "TARGET_64BIT
10005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10006 "<sgnprefix>mul{l}\t%2"
10007 [(set_attr "type" "imul")
10008 (set_attr "length_immediate" "0")
10009 (set (attr "athlon_decode")
10010 (if_then_else (eq_attr "cpu" "athlon")
10011 (const_string "vector")
10012 (const_string "double")))
10013 (set_attr "amdfam10_decode" "double")
10014 (set_attr "bdver1_decode" "direct")
10015 (set_attr "mode" "SI")])
10016
10017 (define_insn "*<s>mulsi3_highpart_1"
10018 [(set (match_operand:SI 0 "register_operand" "=d")
10019 (truncate:SI
10020 (lshiftrt:DI
10021 (mult:DI
10022 (any_extend:DI
10023 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10024 (any_extend:DI
10025 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10026 (const_int 32))))
10027 (clobber (match_scratch:SI 3 "=1"))
10028 (clobber (reg:CC FLAGS_REG))]
10029 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10030 "<sgnprefix>mul{l}\t%2"
10031 [(set_attr "type" "imul")
10032 (set_attr "length_immediate" "0")
10033 (set (attr "athlon_decode")
10034 (if_then_else (eq_attr "cpu" "athlon")
10035 (const_string "vector")
10036 (const_string "double")))
10037 (set_attr "amdfam10_decode" "double")
10038 (set_attr "bdver1_decode" "direct")
10039 (set_attr "mode" "SI")])
10040
10041 ;; Highpart multiplication peephole2s to tweak register allocation.
10042 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
10043 (define_peephole2
10044 [(set (match_operand:SWI48 0 "general_reg_operand")
10045 (match_operand:SWI48 1 "immediate_operand"))
10046 (set (match_operand:SWI48 2 "general_reg_operand")
10047 (match_operand:SWI48 3 "general_reg_operand"))
10048 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
10049 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
10050 (clobber (match_dup 2))
10051 (clobber (reg:CC FLAGS_REG))])]
10052 "REGNO (operands[3]) != AX_REG
10053 && REGNO (operands[0]) != REGNO (operands[2])
10054 && REGNO (operands[0]) != REGNO (operands[3])
10055 && (REGNO (operands[0]) == REGNO (operands[4])
10056 || peep2_reg_dead_p (3, operands[0]))"
10057 [(set (match_dup 2) (match_dup 1))
10058 (parallel [(set (match_dup 4)
10059 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10060 (clobber (match_dup 2))
10061 (clobber (reg:CC FLAGS_REG))])])
10062
10063 (define_peephole2
10064 [(set (match_operand:SI 0 "general_reg_operand")
10065 (match_operand:SI 1 "immediate_operand"))
10066 (set (match_operand:SI 2 "general_reg_operand")
10067 (match_operand:SI 3 "general_reg_operand"))
10068 (parallel [(set (match_operand:DI 4 "general_reg_operand")
10069 (zero_extend:DI
10070 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10071 (clobber (match_dup 2))
10072 (clobber (reg:CC FLAGS_REG))])]
10073 "TARGET_64BIT
10074 && REGNO (operands[3]) != AX_REG
10075 && REGNO (operands[0]) != REGNO (operands[2])
10076 && REGNO (operands[2]) != REGNO (operands[3])
10077 && REGNO (operands[0]) != REGNO (operands[3])
10078 && (REGNO (operands[0]) == REGNO (operands[4])
10079 || peep2_reg_dead_p (3, operands[0]))"
10080 [(set (match_dup 2) (match_dup 1))
10081 (parallel [(set (match_dup 4)
10082 (zero_extend:DI
10083 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10084 (clobber (match_dup 2))
10085 (clobber (reg:CC FLAGS_REG))])])
10086
10087 ;; The patterns that match these are at the end of this file.
10088
10089 (define_expand "mulxf3"
10090 [(set (match_operand:XF 0 "register_operand")
10091 (mult:XF (match_operand:XF 1 "register_operand")
10092 (match_operand:XF 2 "register_operand")))]
10093 "TARGET_80387")
10094
10095 (define_expand "mulhf3"
10096 [(set (match_operand:HF 0 "register_operand")
10097 (mult:HF (match_operand:HF 1 "register_operand")
10098 (match_operand:HF 2 "nonimmediate_operand")))]
10099 "TARGET_AVX512FP16")
10100
10101 (define_expand "mul<mode>3"
10102 [(set (match_operand:MODEF 0 "register_operand")
10103 (mult:MODEF (match_operand:MODEF 1 "register_operand")
10104 (match_operand:MODEF 2 "nonimmediate_operand")))]
10105 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10106 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10107 \f
10108 ;; Divide instructions
10109
10110 ;; The patterns that match these are at the end of this file.
10111
10112 (define_expand "divxf3"
10113 [(set (match_operand:XF 0 "register_operand")
10114 (div:XF (match_operand:XF 1 "register_operand")
10115 (match_operand:XF 2 "register_operand")))]
10116 "TARGET_80387")
10117
10118 /* There is no more precision loss than Newton-Rhapson approximation
10119 when using HFmode rcp/rsqrt, so do the transformation directly under
10120 TARGET_RECIP_DIV and fast-math. */
10121 (define_expand "divhf3"
10122 [(set (match_operand:HF 0 "register_operand")
10123 (div:HF (match_operand:HF 1 "register_operand")
10124 (match_operand:HF 2 "nonimmediate_operand")))]
10125 "TARGET_AVX512FP16"
10126 {
10127 if (TARGET_RECIP_DIV
10128 && optimize_insn_for_speed_p ()
10129 && flag_finite_math_only && !flag_trapping_math
10130 && flag_unsafe_math_optimizations)
10131 {
10132 rtx op = gen_reg_rtx (HFmode);
10133 operands[2] = force_reg (HFmode, operands[2]);
10134 emit_insn (gen_rcphf2 (op, operands[2]));
10135 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10136 DONE;
10137 }
10138 })
10139
10140 (define_expand "div<mode>3"
10141 [(set (match_operand:MODEF 0 "register_operand")
10142 (div:MODEF (match_operand:MODEF 1 "register_operand")
10143 (match_operand:MODEF 2 "nonimmediate_operand")))]
10144 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10145 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10146 {
10147 if (<MODE>mode == SFmode
10148 && TARGET_SSE && TARGET_SSE_MATH
10149 && TARGET_RECIP_DIV
10150 && optimize_insn_for_speed_p ()
10151 && flag_finite_math_only && !flag_trapping_math
10152 && flag_unsafe_math_optimizations)
10153 {
10154 ix86_emit_swdivsf (operands[0], operands[1],
10155 operands[2], SFmode);
10156 DONE;
10157 }
10158 })
10159 \f
10160 ;; Divmod instructions.
10161
10162 (define_code_iterator any_div [div udiv])
10163 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10164
10165 (define_expand "<u>divmod<mode>4"
10166 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10167 (any_div:SWIM248
10168 (match_operand:SWIM248 1 "register_operand")
10169 (match_operand:SWIM248 2 "nonimmediate_operand")))
10170 (set (match_operand:SWIM248 3 "register_operand")
10171 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10172 (clobber (reg:CC FLAGS_REG))])])
10173
10174 ;; Split with 8bit unsigned divide:
10175 ;; if (dividend an divisor are in [0-255])
10176 ;; use 8bit unsigned integer divide
10177 ;; else
10178 ;; use original integer divide
10179 (define_split
10180 [(set (match_operand:SWI48 0 "register_operand")
10181 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10182 (match_operand:SWI48 3 "nonimmediate_operand")))
10183 (set (match_operand:SWI48 1 "register_operand")
10184 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10185 (clobber (reg:CC FLAGS_REG))]
10186 "TARGET_USE_8BIT_IDIV
10187 && TARGET_QIMODE_MATH
10188 && can_create_pseudo_p ()
10189 && !optimize_insn_for_size_p ()"
10190 [(const_int 0)]
10191 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10192
10193 (define_split
10194 [(set (match_operand:DI 0 "register_operand")
10195 (zero_extend:DI
10196 (any_div:SI (match_operand:SI 2 "register_operand")
10197 (match_operand:SI 3 "nonimmediate_operand"))))
10198 (set (match_operand:SI 1 "register_operand")
10199 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10200 (clobber (reg:CC FLAGS_REG))]
10201 "TARGET_64BIT
10202 && TARGET_USE_8BIT_IDIV
10203 && TARGET_QIMODE_MATH
10204 && can_create_pseudo_p ()
10205 && !optimize_insn_for_size_p ()"
10206 [(const_int 0)]
10207 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10208
10209 (define_split
10210 [(set (match_operand:DI 1 "register_operand")
10211 (zero_extend:DI
10212 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10213 (match_operand:SI 3 "nonimmediate_operand"))))
10214 (set (match_operand:SI 0 "register_operand")
10215 (any_div:SI (match_dup 2) (match_dup 3)))
10216 (clobber (reg:CC FLAGS_REG))]
10217 "TARGET_64BIT
10218 && TARGET_USE_8BIT_IDIV
10219 && TARGET_QIMODE_MATH
10220 && can_create_pseudo_p ()
10221 && !optimize_insn_for_size_p ()"
10222 [(const_int 0)]
10223 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10224
10225 (define_insn_and_split "divmod<mode>4_1"
10226 [(set (match_operand:SWI48 0 "register_operand" "=a")
10227 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10228 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10229 (set (match_operand:SWI48 1 "register_operand" "=&d")
10230 (mod:SWI48 (match_dup 2) (match_dup 3)))
10231 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10232 (clobber (reg:CC FLAGS_REG))]
10233 ""
10234 "#"
10235 "reload_completed"
10236 [(parallel [(set (match_dup 1)
10237 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10238 (clobber (reg:CC FLAGS_REG))])
10239 (parallel [(set (match_dup 0)
10240 (div:SWI48 (match_dup 2) (match_dup 3)))
10241 (set (match_dup 1)
10242 (mod:SWI48 (match_dup 2) (match_dup 3)))
10243 (use (match_dup 1))
10244 (clobber (reg:CC FLAGS_REG))])]
10245 {
10246 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10247
10248 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10249 operands[4] = operands[2];
10250 else
10251 {
10252 /* Avoid use of cltd in favor of a mov+shift. */
10253 emit_move_insn (operands[1], operands[2]);
10254 operands[4] = operands[1];
10255 }
10256 }
10257 [(set_attr "type" "multi")
10258 (set_attr "mode" "<MODE>")])
10259
10260 (define_insn_and_split "udivmod<mode>4_1"
10261 [(set (match_operand:SWI48 0 "register_operand" "=a")
10262 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10263 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10264 (set (match_operand:SWI48 1 "register_operand" "=&d")
10265 (umod:SWI48 (match_dup 2) (match_dup 3)))
10266 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10267 (clobber (reg:CC FLAGS_REG))]
10268 ""
10269 "#"
10270 "reload_completed"
10271 [(set (match_dup 1) (const_int 0))
10272 (parallel [(set (match_dup 0)
10273 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10274 (set (match_dup 1)
10275 (umod:SWI48 (match_dup 2) (match_dup 3)))
10276 (use (match_dup 1))
10277 (clobber (reg:CC FLAGS_REG))])]
10278 ""
10279 [(set_attr "type" "multi")
10280 (set_attr "mode" "<MODE>")])
10281
10282 (define_insn_and_split "divmodsi4_zext_1"
10283 [(set (match_operand:DI 0 "register_operand" "=a")
10284 (zero_extend:DI
10285 (div:SI (match_operand:SI 2 "register_operand" "0")
10286 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10287 (set (match_operand:SI 1 "register_operand" "=&d")
10288 (mod:SI (match_dup 2) (match_dup 3)))
10289 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10290 (clobber (reg:CC FLAGS_REG))]
10291 "TARGET_64BIT"
10292 "#"
10293 "&& reload_completed"
10294 [(parallel [(set (match_dup 1)
10295 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10296 (clobber (reg:CC FLAGS_REG))])
10297 (parallel [(set (match_dup 0)
10298 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10299 (set (match_dup 1)
10300 (mod:SI (match_dup 2) (match_dup 3)))
10301 (use (match_dup 1))
10302 (clobber (reg:CC FLAGS_REG))])]
10303 {
10304 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10305
10306 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10307 operands[4] = operands[2];
10308 else
10309 {
10310 /* Avoid use of cltd in favor of a mov+shift. */
10311 emit_move_insn (operands[1], operands[2]);
10312 operands[4] = operands[1];
10313 }
10314 }
10315 [(set_attr "type" "multi")
10316 (set_attr "mode" "SI")])
10317
10318 (define_insn_and_split "udivmodsi4_zext_1"
10319 [(set (match_operand:DI 0 "register_operand" "=a")
10320 (zero_extend:DI
10321 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10322 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10323 (set (match_operand:SI 1 "register_operand" "=&d")
10324 (umod:SI (match_dup 2) (match_dup 3)))
10325 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10326 (clobber (reg:CC FLAGS_REG))]
10327 "TARGET_64BIT"
10328 "#"
10329 "&& reload_completed"
10330 [(set (match_dup 1) (const_int 0))
10331 (parallel [(set (match_dup 0)
10332 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10333 (set (match_dup 1)
10334 (umod:SI (match_dup 2) (match_dup 3)))
10335 (use (match_dup 1))
10336 (clobber (reg:CC FLAGS_REG))])]
10337 ""
10338 [(set_attr "type" "multi")
10339 (set_attr "mode" "SI")])
10340
10341 (define_insn_and_split "divmodsi4_zext_2"
10342 [(set (match_operand:DI 1 "register_operand" "=&d")
10343 (zero_extend:DI
10344 (mod:SI (match_operand:SI 2 "register_operand" "0")
10345 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10346 (set (match_operand:SI 0 "register_operand" "=a")
10347 (div:SI (match_dup 2) (match_dup 3)))
10348 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10349 (clobber (reg:CC FLAGS_REG))]
10350 "TARGET_64BIT"
10351 "#"
10352 "&& reload_completed"
10353 [(parallel [(set (match_dup 6)
10354 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10355 (clobber (reg:CC FLAGS_REG))])
10356 (parallel [(set (match_dup 1)
10357 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10358 (set (match_dup 0)
10359 (div:SI (match_dup 2) (match_dup 3)))
10360 (use (match_dup 6))
10361 (clobber (reg:CC FLAGS_REG))])]
10362 {
10363 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10364 operands[6] = gen_lowpart (SImode, operands[1]);
10365
10366 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10367 operands[4] = operands[2];
10368 else
10369 {
10370 /* Avoid use of cltd in favor of a mov+shift. */
10371 emit_move_insn (operands[6], operands[2]);
10372 operands[4] = operands[6];
10373 }
10374 }
10375 [(set_attr "type" "multi")
10376 (set_attr "mode" "SI")])
10377
10378 (define_insn_and_split "udivmodsi4_zext_2"
10379 [(set (match_operand:DI 1 "register_operand" "=&d")
10380 (zero_extend:DI
10381 (umod:SI (match_operand:SI 2 "register_operand" "0")
10382 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10383 (set (match_operand:SI 0 "register_operand" "=a")
10384 (udiv:SI (match_dup 2) (match_dup 3)))
10385 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10386 (clobber (reg:CC FLAGS_REG))]
10387 "TARGET_64BIT"
10388 "#"
10389 "&& reload_completed"
10390 [(set (match_dup 4) (const_int 0))
10391 (parallel [(set (match_dup 1)
10392 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10393 (set (match_dup 0)
10394 (udiv:SI (match_dup 2) (match_dup 3)))
10395 (use (match_dup 4))
10396 (clobber (reg:CC FLAGS_REG))])]
10397 "operands[4] = gen_lowpart (SImode, operands[1]);"
10398 [(set_attr "type" "multi")
10399 (set_attr "mode" "SI")])
10400
10401 (define_insn_and_split "*divmod<mode>4"
10402 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10403 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10404 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10405 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10406 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10407 (clobber (reg:CC FLAGS_REG))]
10408 ""
10409 "#"
10410 "reload_completed"
10411 [(parallel [(set (match_dup 1)
10412 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10413 (clobber (reg:CC FLAGS_REG))])
10414 (parallel [(set (match_dup 0)
10415 (div:SWIM248 (match_dup 2) (match_dup 3)))
10416 (set (match_dup 1)
10417 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10418 (use (match_dup 1))
10419 (clobber (reg:CC FLAGS_REG))])]
10420 {
10421 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10422
10423 if (<MODE>mode != HImode
10424 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10425 operands[4] = operands[2];
10426 else
10427 {
10428 /* Avoid use of cltd in favor of a mov+shift. */
10429 emit_move_insn (operands[1], operands[2]);
10430 operands[4] = operands[1];
10431 }
10432 }
10433 [(set_attr "type" "multi")
10434 (set_attr "mode" "<MODE>")])
10435
10436 (define_insn_and_split "*udivmod<mode>4"
10437 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10438 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10439 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10440 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10441 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10442 (clobber (reg:CC FLAGS_REG))]
10443 ""
10444 "#"
10445 "reload_completed"
10446 [(set (match_dup 1) (const_int 0))
10447 (parallel [(set (match_dup 0)
10448 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10449 (set (match_dup 1)
10450 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10451 (use (match_dup 1))
10452 (clobber (reg:CC FLAGS_REG))])]
10453 ""
10454 [(set_attr "type" "multi")
10455 (set_attr "mode" "<MODE>")])
10456
10457 ;; Optimize division or modulo by constant power of 2, if the constant
10458 ;; materializes only after expansion.
10459 (define_insn_and_split "*udivmod<mode>4_pow2"
10460 [(set (match_operand:SWI48 0 "register_operand" "=r")
10461 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10462 (match_operand:SWI48 3 "const_int_operand")))
10463 (set (match_operand:SWI48 1 "register_operand" "=r")
10464 (umod:SWI48 (match_dup 2) (match_dup 3)))
10465 (clobber (reg:CC FLAGS_REG))]
10466 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10467 "#"
10468 "&& reload_completed"
10469 [(set (match_dup 1) (match_dup 2))
10470 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10471 (clobber (reg:CC FLAGS_REG))])
10472 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10473 (clobber (reg:CC FLAGS_REG))])]
10474 {
10475 int v = exact_log2 (UINTVAL (operands[3]));
10476 operands[4] = GEN_INT (v);
10477 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10478 }
10479 [(set_attr "type" "multi")
10480 (set_attr "mode" "<MODE>")])
10481
10482 (define_insn_and_split "*divmodsi4_zext_1"
10483 [(set (match_operand:DI 0 "register_operand" "=a")
10484 (zero_extend:DI
10485 (div:SI (match_operand:SI 2 "register_operand" "0")
10486 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10487 (set (match_operand:SI 1 "register_operand" "=&d")
10488 (mod:SI (match_dup 2) (match_dup 3)))
10489 (clobber (reg:CC FLAGS_REG))]
10490 "TARGET_64BIT"
10491 "#"
10492 "&& reload_completed"
10493 [(parallel [(set (match_dup 1)
10494 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10495 (clobber (reg:CC FLAGS_REG))])
10496 (parallel [(set (match_dup 0)
10497 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10498 (set (match_dup 1)
10499 (mod:SI (match_dup 2) (match_dup 3)))
10500 (use (match_dup 1))
10501 (clobber (reg:CC FLAGS_REG))])]
10502 {
10503 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10504
10505 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10506 operands[4] = operands[2];
10507 else
10508 {
10509 /* Avoid use of cltd in favor of a mov+shift. */
10510 emit_move_insn (operands[1], operands[2]);
10511 operands[4] = operands[1];
10512 }
10513 }
10514 [(set_attr "type" "multi")
10515 (set_attr "mode" "SI")])
10516
10517 (define_insn_and_split "*udivmodsi4_zext_1"
10518 [(set (match_operand:DI 0 "register_operand" "=a")
10519 (zero_extend:DI
10520 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10521 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10522 (set (match_operand:SI 1 "register_operand" "=&d")
10523 (umod:SI (match_dup 2) (match_dup 3)))
10524 (clobber (reg:CC FLAGS_REG))]
10525 "TARGET_64BIT"
10526 "#"
10527 "&& reload_completed"
10528 [(set (match_dup 1) (const_int 0))
10529 (parallel [(set (match_dup 0)
10530 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10531 (set (match_dup 1)
10532 (umod:SI (match_dup 2) (match_dup 3)))
10533 (use (match_dup 1))
10534 (clobber (reg:CC FLAGS_REG))])]
10535 ""
10536 [(set_attr "type" "multi")
10537 (set_attr "mode" "SI")])
10538
10539 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10540 [(set (match_operand:DI 0 "register_operand" "=r")
10541 (zero_extend:DI
10542 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10543 (match_operand:SI 3 "const_int_operand"))))
10544 (set (match_operand:SI 1 "register_operand" "=r")
10545 (umod:SI (match_dup 2) (match_dup 3)))
10546 (clobber (reg:CC FLAGS_REG))]
10547 "TARGET_64BIT
10548 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10549 "#"
10550 "&& reload_completed"
10551 [(set (match_dup 1) (match_dup 2))
10552 (parallel [(set (match_dup 0)
10553 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10554 (clobber (reg:CC FLAGS_REG))])
10555 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10556 (clobber (reg:CC FLAGS_REG))])]
10557 {
10558 int v = exact_log2 (UINTVAL (operands[3]));
10559 operands[4] = GEN_INT (v);
10560 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10561 }
10562 [(set_attr "type" "multi")
10563 (set_attr "mode" "SI")])
10564
10565 (define_insn_and_split "*divmodsi4_zext_2"
10566 [(set (match_operand:DI 1 "register_operand" "=&d")
10567 (zero_extend:DI
10568 (mod:SI (match_operand:SI 2 "register_operand" "0")
10569 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10570 (set (match_operand:SI 0 "register_operand" "=a")
10571 (div:SI (match_dup 2) (match_dup 3)))
10572 (clobber (reg:CC FLAGS_REG))]
10573 "TARGET_64BIT"
10574 "#"
10575 "&& reload_completed"
10576 [(parallel [(set (match_dup 6)
10577 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10578 (clobber (reg:CC FLAGS_REG))])
10579 (parallel [(set (match_dup 1)
10580 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10581 (set (match_dup 0)
10582 (div:SI (match_dup 2) (match_dup 3)))
10583 (use (match_dup 6))
10584 (clobber (reg:CC FLAGS_REG))])]
10585 {
10586 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10587 operands[6] = gen_lowpart (SImode, operands[1]);
10588
10589 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10590 operands[4] = operands[2];
10591 else
10592 {
10593 /* Avoid use of cltd in favor of a mov+shift. */
10594 emit_move_insn (operands[6], operands[2]);
10595 operands[4] = operands[6];
10596 }
10597 }
10598 [(set_attr "type" "multi")
10599 (set_attr "mode" "SI")])
10600
10601 (define_insn_and_split "*udivmodsi4_zext_2"
10602 [(set (match_operand:DI 1 "register_operand" "=&d")
10603 (zero_extend:DI
10604 (umod:SI (match_operand:SI 2 "register_operand" "0")
10605 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10606 (set (match_operand:SI 0 "register_operand" "=a")
10607 (udiv:SI (match_dup 2) (match_dup 3)))
10608 (clobber (reg:CC FLAGS_REG))]
10609 "TARGET_64BIT"
10610 "#"
10611 "&& reload_completed"
10612 [(set (match_dup 4) (const_int 0))
10613 (parallel [(set (match_dup 1)
10614 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10615 (set (match_dup 0)
10616 (udiv:SI (match_dup 2) (match_dup 3)))
10617 (use (match_dup 4))
10618 (clobber (reg:CC FLAGS_REG))])]
10619 "operands[4] = gen_lowpart (SImode, operands[1]);"
10620 [(set_attr "type" "multi")
10621 (set_attr "mode" "SI")])
10622
10623 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10624 [(set (match_operand:DI 1 "register_operand" "=r")
10625 (zero_extend:DI
10626 (umod:SI (match_operand:SI 2 "register_operand" "0")
10627 (match_operand:SI 3 "const_int_operand"))))
10628 (set (match_operand:SI 0 "register_operand" "=r")
10629 (udiv:SI (match_dup 2) (match_dup 3)))
10630 (clobber (reg:CC FLAGS_REG))]
10631 "TARGET_64BIT
10632 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10633 "#"
10634 "&& reload_completed"
10635 [(set (match_dup 1) (match_dup 2))
10636 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10637 (clobber (reg:CC FLAGS_REG))])
10638 (parallel [(set (match_dup 1)
10639 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10640 (clobber (reg:CC FLAGS_REG))])]
10641 {
10642 int v = exact_log2 (UINTVAL (operands[3]));
10643 operands[4] = GEN_INT (v);
10644 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10645 }
10646 [(set_attr "type" "multi")
10647 (set_attr "mode" "SI")])
10648
10649 (define_insn "*<u>divmod<mode>4_noext"
10650 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10651 (any_div:SWIM248
10652 (match_operand:SWIM248 2 "register_operand" "0")
10653 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10654 (set (match_operand:SWIM248 1 "register_operand" "=d")
10655 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10656 (use (match_operand:SWIM248 4 "register_operand" "1"))
10657 (clobber (reg:CC FLAGS_REG))]
10658 ""
10659 "<sgnprefix>div{<imodesuffix>}\t%3"
10660 [(set_attr "type" "idiv")
10661 (set_attr "mode" "<MODE>")])
10662
10663 (define_insn "*<u>divmodsi4_noext_zext_1"
10664 [(set (match_operand:DI 0 "register_operand" "=a")
10665 (zero_extend:DI
10666 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10667 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10668 (set (match_operand:SI 1 "register_operand" "=d")
10669 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10670 (use (match_operand:SI 4 "register_operand" "1"))
10671 (clobber (reg:CC FLAGS_REG))]
10672 "TARGET_64BIT"
10673 "<sgnprefix>div{l}\t%3"
10674 [(set_attr "type" "idiv")
10675 (set_attr "mode" "SI")])
10676
10677 (define_insn "*<u>divmodsi4_noext_zext_2"
10678 [(set (match_operand:DI 1 "register_operand" "=d")
10679 (zero_extend:DI
10680 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10681 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10682 (set (match_operand:SI 0 "register_operand" "=a")
10683 (any_div:SI (match_dup 2) (match_dup 3)))
10684 (use (match_operand:SI 4 "register_operand" "1"))
10685 (clobber (reg:CC FLAGS_REG))]
10686 "TARGET_64BIT"
10687 "<sgnprefix>div{l}\t%3"
10688 [(set_attr "type" "idiv")
10689 (set_attr "mode" "SI")])
10690
10691 ;; Avoid sign-extension (using cdq) for constant numerators.
10692 (define_insn_and_split "*divmodsi4_const"
10693 [(set (match_operand:SI 0 "register_operand" "=&a")
10694 (div:SI (match_operand:SI 2 "const_int_operand")
10695 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10696 (set (match_operand:SI 1 "register_operand" "=&d")
10697 (mod:SI (match_dup 2) (match_dup 3)))
10698 (clobber (reg:CC FLAGS_REG))]
10699 "!optimize_function_for_size_p (cfun)"
10700 "#"
10701 "&& reload_completed"
10702 [(set (match_dup 0) (match_dup 2))
10703 (set (match_dup 1) (match_dup 4))
10704 (parallel [(set (match_dup 0)
10705 (div:SI (match_dup 0) (match_dup 3)))
10706 (set (match_dup 1)
10707 (mod:SI (match_dup 0) (match_dup 3)))
10708 (use (match_dup 1))
10709 (clobber (reg:CC FLAGS_REG))])]
10710 {
10711 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10712 }
10713 [(set_attr "type" "multi")
10714 (set_attr "mode" "SI")])
10715
10716 (define_expand "divmodqi4"
10717 [(parallel [(set (match_operand:QI 0 "register_operand")
10718 (div:QI
10719 (match_operand:QI 1 "register_operand")
10720 (match_operand:QI 2 "nonimmediate_operand")))
10721 (set (match_operand:QI 3 "register_operand")
10722 (mod:QI (match_dup 1) (match_dup 2)))
10723 (clobber (reg:CC FLAGS_REG))])]
10724 "TARGET_QIMODE_MATH"
10725 {
10726 rtx div, mod;
10727 rtx tmp0, tmp1;
10728
10729 tmp0 = gen_reg_rtx (HImode);
10730 tmp1 = gen_reg_rtx (HImode);
10731
10732 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10733 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10734 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10735
10736 /* Extract remainder from AH. */
10737 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10738 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10739 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10740
10741 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10742 set_unique_reg_note (insn, REG_EQUAL, mod);
10743
10744 /* Extract quotient from AL. */
10745 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10746
10747 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10748 set_unique_reg_note (insn, REG_EQUAL, div);
10749
10750 DONE;
10751 })
10752
10753 (define_expand "udivmodqi4"
10754 [(parallel [(set (match_operand:QI 0 "register_operand")
10755 (udiv:QI
10756 (match_operand:QI 1 "register_operand")
10757 (match_operand:QI 2 "nonimmediate_operand")))
10758 (set (match_operand:QI 3 "register_operand")
10759 (umod:QI (match_dup 1) (match_dup 2)))
10760 (clobber (reg:CC FLAGS_REG))])]
10761 "TARGET_QIMODE_MATH"
10762 {
10763 rtx div, mod;
10764 rtx tmp0, tmp1;
10765
10766 tmp0 = gen_reg_rtx (HImode);
10767 tmp1 = gen_reg_rtx (HImode);
10768
10769 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10770 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10771 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10772
10773 /* Extract remainder from AH. */
10774 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10775 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10776 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10777
10778 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10779 set_unique_reg_note (insn, REG_EQUAL, mod);
10780
10781 /* Extract quotient from AL. */
10782 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10783
10784 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10785 set_unique_reg_note (insn, REG_EQUAL, div);
10786
10787 DONE;
10788 })
10789
10790 ;; Divide AX by r/m8, with result stored in
10791 ;; AL <- Quotient
10792 ;; AH <- Remainder
10793 ;; Change div/mod to HImode and extend the second argument to HImode
10794 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10795 ;; combine may fail.
10796 (define_insn "<u>divmodhiqi3"
10797 [(set (match_operand:HI 0 "register_operand" "=a")
10798 (ior:HI
10799 (ashift:HI
10800 (zero_extend:HI
10801 (truncate:QI
10802 (mod:HI (match_operand:HI 1 "register_operand" "0")
10803 (any_extend:HI
10804 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10805 (const_int 8))
10806 (zero_extend:HI
10807 (truncate:QI
10808 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10809 (clobber (reg:CC FLAGS_REG))]
10810 "TARGET_QIMODE_MATH"
10811 "<sgnprefix>div{b}\t%2"
10812 [(set_attr "type" "idiv")
10813 (set_attr "mode" "QI")])
10814
10815 ;; We cannot use div/idiv for double division, because it causes
10816 ;; "division by zero" on the overflow and that's not what we expect
10817 ;; from truncate. Because true (non truncating) double division is
10818 ;; never generated, we can't create this insn anyway.
10819 ;
10820 ;(define_insn ""
10821 ; [(set (match_operand:SI 0 "register_operand" "=a")
10822 ; (truncate:SI
10823 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10824 ; (zero_extend:DI
10825 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10826 ; (set (match_operand:SI 3 "register_operand" "=d")
10827 ; (truncate:SI
10828 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10829 ; (clobber (reg:CC FLAGS_REG))]
10830 ; ""
10831 ; "div{l}\t{%2, %0|%0, %2}"
10832 ; [(set_attr "type" "idiv")])
10833 \f
10834 ;;- Logical AND instructions
10835
10836 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10837 ;; Note that this excludes ah.
10838
10839 (define_expand "@test<mode>_ccno_1"
10840 [(set (reg:CCNO FLAGS_REG)
10841 (compare:CCNO
10842 (and:SWI48
10843 (match_operand:SWI48 0 "nonimmediate_operand")
10844 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10845 (const_int 0)))])
10846
10847 (define_expand "testqi_ccz_1"
10848 [(set (reg:CCZ FLAGS_REG)
10849 (compare:CCZ
10850 (and:QI
10851 (match_operand:QI 0 "nonimmediate_operand")
10852 (match_operand:QI 1 "nonmemory_operand"))
10853 (const_int 0)))])
10854
10855 (define_insn "*testdi_1"
10856 [(set (reg FLAGS_REG)
10857 (compare
10858 (and:DI
10859 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10860 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10861 (const_int 0)))]
10862 "TARGET_64BIT
10863 && ix86_match_ccmode
10864 (insn,
10865 /* If we are going to emit testl instead of testq, and the operands[1]
10866 constant might have the SImode sign bit set, make sure the sign
10867 flag isn't tested, because the instruction will set the sign flag
10868 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10869 conservatively assume it might have bit 31 set. */
10870 (satisfies_constraint_Z (operands[1])
10871 && (!CONST_INT_P (operands[1])
10872 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10873 ? CCZmode : CCNOmode)"
10874 "@
10875 test{l}\t{%k1, %k0|%k0, %k1}
10876 test{q}\t{%1, %0|%0, %1}"
10877 [(set_attr "type" "test")
10878 (set_attr "mode" "SI,DI")])
10879
10880 (define_insn "*testqi_1_maybe_si"
10881 [(set (reg FLAGS_REG)
10882 (compare
10883 (and:QI
10884 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10885 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10886 (const_int 0)))]
10887 "ix86_match_ccmode (insn,
10888 CONST_INT_P (operands[1])
10889 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10890 {
10891 if (get_attr_mode (insn) == MODE_SI)
10892 {
10893 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10894 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10895 return "test{l}\t{%1, %k0|%k0, %1}";
10896 }
10897 return "test{b}\t{%1, %0|%0, %1}";
10898 }
10899 [(set_attr "type" "test")
10900 (set (attr "mode")
10901 (cond [(eq_attr "alternative" "2")
10902 (const_string "SI")
10903 (and (match_test "optimize_insn_for_size_p ()")
10904 (and (match_operand 0 "ext_QIreg_operand")
10905 (match_operand 1 "const_0_to_127_operand")))
10906 (const_string "SI")
10907 ]
10908 (const_string "QI")))
10909 (set_attr "pent_pair" "uv,np,np")])
10910
10911 (define_insn "*test<mode>_1"
10912 [(set (reg FLAGS_REG)
10913 (compare
10914 (and:SWI124
10915 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10916 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10917 (const_int 0)))]
10918 "ix86_match_ccmode (insn, CCNOmode)"
10919 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10920 [(set_attr "type" "test")
10921 (set_attr "mode" "<MODE>")
10922 (set_attr "pent_pair" "uv,uv,np")])
10923
10924 (define_expand "testqi_ext_1_ccno"
10925 [(set (reg:CCNO FLAGS_REG)
10926 (compare:CCNO
10927 (and:QI
10928 (subreg:QI
10929 (zero_extract:HI
10930 (match_operand:HI 0 "register_operand")
10931 (const_int 8)
10932 (const_int 8)) 0)
10933 (match_operand:QI 1 "const_int_operand"))
10934 (const_int 0)))])
10935
10936 (define_insn "*testqi_ext<mode>_1"
10937 [(set (reg FLAGS_REG)
10938 (compare
10939 (and:QI
10940 (subreg:QI
10941 (match_operator:SWI248 2 "extract_operator"
10942 [(match_operand 0 "int248_register_operand" "Q")
10943 (const_int 8)
10944 (const_int 8)]) 0)
10945 (match_operand:QI 1 "general_operand" "QnBn"))
10946 (const_int 0)))]
10947 "ix86_match_ccmode (insn, CCNOmode)"
10948 "test{b}\t{%1, %h0|%h0, %1}"
10949 [(set_attr "addr" "gpr8")
10950 (set_attr "type" "test")
10951 (set_attr "mode" "QI")])
10952
10953 (define_insn "*testqi_ext<mode>_2"
10954 [(set (reg FLAGS_REG)
10955 (compare
10956 (and:QI
10957 (subreg:QI
10958 (match_operator:SWI248 2 "extract_operator"
10959 [(match_operand 0 "int248_register_operand" "Q")
10960 (const_int 8)
10961 (const_int 8)]) 0)
10962 (subreg:QI
10963 (match_operator:SWI248 3 "extract_operator"
10964 [(match_operand 1 "int248_register_operand" "Q")
10965 (const_int 8)
10966 (const_int 8)]) 0))
10967 (const_int 0)))]
10968 "ix86_match_ccmode (insn, CCNOmode)"
10969 "test{b}\t{%h1, %h0|%h0, %h1}"
10970 [(set_attr "type" "test")
10971 (set_attr "mode" "QI")])
10972
10973 ;; Provide a *testti instruction that STV can implement using ptest.
10974 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10975 (define_insn_and_split "*testti_doubleword"
10976 [(set (reg:CCZ FLAGS_REG)
10977 (compare:CCZ
10978 (and:TI (match_operand:TI 0 "register_operand")
10979 (match_operand:TI 1 "general_operand"))
10980 (const_int 0)))]
10981 "TARGET_64BIT
10982 && ix86_pre_reload_split ()"
10983 "#"
10984 "&& 1"
10985 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10986 (clobber (reg:CC FLAGS_REG))])
10987 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10988 {
10989 operands[2] = gen_reg_rtx (TImode);
10990 if (!x86_64_hilo_general_operand (operands[1], TImode))
10991 operands[1] = force_reg (TImode, operands[1]);
10992 })
10993
10994 ;; Combine likes to form bit extractions for some tests. Humor it.
10995 (define_insn_and_split "*testqi_ext_3"
10996 [(set (match_operand 0 "flags_reg_operand")
10997 (match_operator 1 "compare_operator"
10998 [(zero_extract:SWI248
10999 (match_operand 2 "int_nonimmediate_operand" "rm")
11000 (match_operand:QI 3 "const_int_operand")
11001 (match_operand:QI 4 "const_int_operand"))
11002 (const_int 0)]))]
11003 "/* Ensure that resulting mask is zero or sign extended operand. */
11004 INTVAL (operands[4]) >= 0
11005 && ((INTVAL (operands[3]) > 0
11006 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
11007 || (<MODE>mode == DImode
11008 && INTVAL (operands[3]) > 32
11009 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
11010 && ix86_match_ccmode (insn,
11011 /* If zero_extract mode precision is the same
11012 as len, the SF of the zero_extract
11013 comparison will be the most significant
11014 extracted bit, but this could be matched
11015 after splitting only for pos 0 len all bits
11016 trivial extractions. Require CCZmode. */
11017 (GET_MODE_PRECISION (<MODE>mode)
11018 == INTVAL (operands[3]))
11019 /* Otherwise, require CCZmode if we'd use a mask
11020 with the most significant bit set and can't
11021 widen it to wider mode. *testdi_1 also
11022 requires CCZmode if the mask has bit
11023 31 set and all bits above it clear. */
11024 || (INTVAL (operands[3]) + INTVAL (operands[4])
11025 >= 32)
11026 /* We can't widen also if val is not a REG. */
11027 || (INTVAL (operands[3]) + INTVAL (operands[4])
11028 == GET_MODE_PRECISION (GET_MODE (operands[2]))
11029 && !register_operand (operands[2],
11030 GET_MODE (operands[2])))
11031 /* And we shouldn't widen if
11032 TARGET_PARTIAL_REG_STALL. */
11033 || (TARGET_PARTIAL_REG_STALL
11034 && (INTVAL (operands[3]) + INTVAL (operands[4])
11035 >= (paradoxical_subreg_p (operands[2])
11036 && (GET_MODE_CLASS
11037 (GET_MODE (SUBREG_REG (operands[2])))
11038 == MODE_INT)
11039 ? GET_MODE_PRECISION
11040 (GET_MODE (SUBREG_REG (operands[2])))
11041 : GET_MODE_PRECISION
11042 (GET_MODE (operands[2])))))
11043 ? CCZmode : CCNOmode)"
11044 "#"
11045 "&& 1"
11046 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11047 {
11048 rtx val = operands[2];
11049 HOST_WIDE_INT len = INTVAL (operands[3]);
11050 HOST_WIDE_INT pos = INTVAL (operands[4]);
11051 machine_mode mode = GET_MODE (val);
11052
11053 if (SUBREG_P (val))
11054 {
11055 machine_mode submode = GET_MODE (SUBREG_REG (val));
11056
11057 /* Narrow paradoxical subregs to prevent partial register stalls. */
11058 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
11059 && GET_MODE_CLASS (submode) == MODE_INT
11060 && (GET_MODE (operands[0]) == CCZmode
11061 || pos + len < GET_MODE_PRECISION (submode)
11062 || REG_P (SUBREG_REG (val))))
11063 {
11064 val = SUBREG_REG (val);
11065 mode = submode;
11066 }
11067 }
11068
11069 /* Small HImode tests can be converted to QImode. */
11070 if (pos + len <= 8
11071 && register_operand (val, HImode))
11072 {
11073 rtx nval = gen_lowpart (QImode, val);
11074 if (!MEM_P (nval)
11075 || GET_MODE (operands[0]) == CCZmode
11076 || pos + len < 8)
11077 {
11078 val = nval;
11079 mode = QImode;
11080 }
11081 }
11082
11083 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11084
11085 /* If the mask is going to have the sign bit set in the mode
11086 we want to do the comparison in and user isn't interested just
11087 in the zero flag, then we must widen the target mode. */
11088 if (pos + len == GET_MODE_PRECISION (mode)
11089 && GET_MODE (operands[0]) != CCZmode)
11090 {
11091 gcc_assert (pos + len < 32 && !MEM_P (val));
11092 mode = SImode;
11093 val = gen_lowpart (mode, val);
11094 }
11095
11096 wide_int mask
11097 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11098
11099 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11100 })
11101
11102 ;; Split and;cmp (as optimized by combine) into not;test
11103 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11104 (define_insn_and_split "*test<mode>_not"
11105 [(set (reg:CCZ FLAGS_REG)
11106 (compare:CCZ
11107 (and:SWI
11108 (not:SWI (match_operand:SWI 0 "register_operand"))
11109 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11110 (const_int 0)))]
11111 "ix86_pre_reload_split ()
11112 && (!TARGET_BMI || !REG_P (operands[1]))"
11113 "#"
11114 "&& 1"
11115 [(set (match_dup 2) (not:SWI (match_dup 0)))
11116 (set (reg:CCZ FLAGS_REG)
11117 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11118 (const_int 0)))]
11119 "operands[2] = gen_reg_rtx (<MODE>mode);")
11120
11121 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11122 (define_insn_and_split "*test<mode>_not_doubleword"
11123 [(set (reg:CCZ FLAGS_REG)
11124 (compare:CCZ
11125 (and:DWI
11126 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11127 (match_operand:DWI 1 "nonimmediate_operand"))
11128 (const_int 0)))]
11129 "ix86_pre_reload_split ()"
11130 "#"
11131 "&& 1"
11132 [(parallel
11133 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11134 (clobber (reg:CC FLAGS_REG))])
11135 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11136 {
11137 operands[0] = force_reg (<MODE>mode, operands[0]);
11138 operands[2] = gen_reg_rtx (<MODE>mode);
11139 })
11140
11141 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11142 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11143 ;; this is relatively important trick.
11144 ;; Do the conversion only post-reload to avoid limiting of the register class
11145 ;; to QI regs.
11146 (define_split
11147 [(set (match_operand 0 "flags_reg_operand")
11148 (match_operator 1 "compare_operator"
11149 [(and (match_operand 2 "QIreg_operand")
11150 (match_operand 3 "const_int_operand"))
11151 (const_int 0)]))]
11152 "reload_completed
11153 && GET_MODE (operands[2]) != QImode
11154 && ((ix86_match_ccmode (insn, CCZmode)
11155 && !(INTVAL (operands[3]) & ~(255 << 8)))
11156 || (ix86_match_ccmode (insn, CCNOmode)
11157 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11158 [(set (match_dup 0)
11159 (match_op_dup 1
11160 [(and:QI
11161 (subreg:QI
11162 (zero_extract:HI (match_dup 2)
11163 (const_int 8)
11164 (const_int 8)) 0)
11165 (match_dup 3))
11166 (const_int 0)]))]
11167 {
11168 operands[2] = gen_lowpart (HImode, operands[2]);
11169 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11170 })
11171
11172 (define_split
11173 [(set (match_operand 0 "flags_reg_operand")
11174 (match_operator 1 "compare_operator"
11175 [(and (match_operand 2 "nonimmediate_operand")
11176 (match_operand 3 "const_int_operand"))
11177 (const_int 0)]))]
11178 "reload_completed
11179 && GET_MODE (operands[2]) != QImode
11180 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11181 && ((ix86_match_ccmode (insn, CCZmode)
11182 && !(INTVAL (operands[3]) & ~255))
11183 || (ix86_match_ccmode (insn, CCNOmode)
11184 && !(INTVAL (operands[3]) & ~127)))"
11185 [(set (match_dup 0)
11186 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11187 (const_int 0)]))]
11188 {
11189 operands[2] = gen_lowpart (QImode, operands[2]);
11190 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11191 })
11192
11193 ;; Narrow test instructions with immediate operands that test
11194 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11195 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11196 ;; targets where reading (possibly unaligned) part of memory
11197 ;; location after a large write to the same address causes
11198 ;; store-to-load forwarding stall.
11199 (define_peephole2
11200 [(set (reg:CCZ FLAGS_REG)
11201 (compare:CCZ
11202 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11203 (match_operand 1 "const_int_operand"))
11204 (const_int 0)))]
11205 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11206 [(set (reg:CCZ FLAGS_REG)
11207 (compare:CCZ (match_dup 2) (const_int 0)))]
11208 {
11209 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11210 int first_nonzero_byte, bitsize;
11211 rtx new_addr, new_const;
11212 machine_mode new_mode;
11213
11214 if (ival == 0)
11215 FAIL;
11216
11217 /* Clear bits outside mode width. */
11218 ival &= GET_MODE_MASK (<MODE>mode);
11219
11220 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11221
11222 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11223
11224 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11225
11226 if (bitsize <= GET_MODE_BITSIZE (QImode))
11227 new_mode = QImode;
11228 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11229 new_mode = HImode;
11230 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11231 new_mode = SImode;
11232 else
11233 new_mode = DImode;
11234
11235 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11236 FAIL;
11237
11238 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11239 new_const = gen_int_mode (ival, new_mode);
11240
11241 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11242 })
11243
11244 ;; %%% This used to optimize known byte-wide and operations to memory,
11245 ;; and sometimes to QImode registers. If this is considered useful,
11246 ;; it should be done with splitters.
11247
11248 (define_expand "and<mode>3"
11249 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11250 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11251 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11252 ""
11253 {
11254 machine_mode mode = <MODE>mode;
11255
11256 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11257 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11258 operands[2] = force_reg (<MODE>mode, operands[2]);
11259
11260 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11261 && const_int_operand (operands[2], <MODE>mode)
11262 && register_operand (operands[0], <MODE>mode)
11263 && !(TARGET_ZERO_EXTEND_WITH_AND
11264 && optimize_function_for_speed_p (cfun)))
11265 {
11266 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11267
11268 if (ival == GET_MODE_MASK (SImode))
11269 mode = SImode;
11270 else if (ival == GET_MODE_MASK (HImode))
11271 mode = HImode;
11272 else if (ival == GET_MODE_MASK (QImode))
11273 mode = QImode;
11274 }
11275
11276 if (mode != <MODE>mode)
11277 emit_insn (gen_extend_insn
11278 (operands[0], gen_lowpart (mode, operands[1]),
11279 <MODE>mode, mode, 1));
11280 else
11281 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11282
11283 DONE;
11284 })
11285
11286 (define_insn_and_split "*and<dwi>3_doubleword"
11287 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11288 (and:<DWI>
11289 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11290 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11291 (clobber (reg:CC FLAGS_REG))]
11292 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11293 "#"
11294 "&& reload_completed"
11295 [(const_int:DWIH 0)]
11296 {
11297 bool emit_insn_deleted_note_p = false;
11298
11299 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11300
11301 if (operands[2] == const0_rtx)
11302 emit_move_insn (operands[0], const0_rtx);
11303 else if (operands[2] == constm1_rtx)
11304 emit_insn_deleted_note_p = true;
11305 else
11306 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11307
11308 if (operands[5] == const0_rtx)
11309 emit_move_insn (operands[3], const0_rtx);
11310 else if (operands[5] == constm1_rtx)
11311 {
11312 if (emit_insn_deleted_note_p)
11313 emit_note (NOTE_INSN_DELETED);
11314 }
11315 else
11316 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11317
11318 DONE;
11319 })
11320
11321 (define_insn "*anddi_1"
11322 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11323 (and:DI
11324 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11325 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11326 (clobber (reg:CC FLAGS_REG))]
11327 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11328 "@
11329 and{l}\t{%k2, %k0|%k0, %k2}
11330 and{q}\t{%2, %0|%0, %2}
11331 and{q}\t{%2, %0|%0, %2}
11332 #
11333 #"
11334 [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11335 (set_attr "type" "alu,alu,alu,imovx,msklog")
11336 (set_attr "length_immediate" "*,*,*,0,*")
11337 (set (attr "prefix_rex")
11338 (if_then_else
11339 (and (eq_attr "type" "imovx")
11340 (and (match_test "INTVAL (operands[2]) == 0xff")
11341 (match_operand 1 "ext_QIreg_operand")))
11342 (const_string "1")
11343 (const_string "*")))
11344 (set_attr "mode" "SI,DI,DI,SI,DI")])
11345
11346 (define_insn_and_split "*anddi_1_btr"
11347 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11348 (and:DI
11349 (match_operand:DI 1 "nonimmediate_operand" "%0")
11350 (match_operand:DI 2 "const_int_operand" "n")))
11351 (clobber (reg:CC FLAGS_REG))]
11352 "TARGET_64BIT && TARGET_USE_BT
11353 && ix86_binary_operator_ok (AND, DImode, operands)
11354 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11355 "#"
11356 "&& reload_completed"
11357 [(parallel [(set (zero_extract:DI (match_dup 0)
11358 (const_int 1)
11359 (match_dup 3))
11360 (const_int 0))
11361 (clobber (reg:CC FLAGS_REG))])]
11362 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11363 [(set_attr "type" "alu1")
11364 (set_attr "prefix_0f" "1")
11365 (set_attr "znver1_decode" "double")
11366 (set_attr "mode" "DI")])
11367
11368 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11369 (define_split
11370 [(set (match_operand:DI 0 "register_operand")
11371 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11372 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11373 (clobber (reg:CC FLAGS_REG))]
11374 "TARGET_64BIT"
11375 [(parallel [(set (match_dup 0)
11376 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11377 (clobber (reg:CC FLAGS_REG))])]
11378 {
11379 if (GET_CODE (operands[2]) == SYMBOL_REF
11380 || GET_CODE (operands[2]) == LABEL_REF)
11381 {
11382 operands[2] = shallow_copy_rtx (operands[2]);
11383 PUT_MODE (operands[2], SImode);
11384 }
11385 else if (GET_CODE (operands[2]) == CONST)
11386 {
11387 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11388 operands[2] = copy_rtx (operands[2]);
11389 PUT_MODE (operands[2], SImode);
11390 PUT_MODE (XEXP (operands[2], 0), SImode);
11391 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11392 }
11393 else
11394 operands[2] = gen_lowpart (SImode, operands[2]);
11395 })
11396
11397 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11398 (define_insn "*andsi_1_zext"
11399 [(set (match_operand:DI 0 "register_operand" "=r")
11400 (zero_extend:DI
11401 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11402 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11403 (clobber (reg:CC FLAGS_REG))]
11404 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11405 "and{l}\t{%2, %k0|%k0, %2}"
11406 [(set_attr "type" "alu")
11407 (set_attr "mode" "SI")])
11408
11409 (define_insn "*and<mode>_1"
11410 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11411 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11412 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11415 "@
11416 and{<imodesuffix>}\t{%2, %0|%0, %2}
11417 and{<imodesuffix>}\t{%2, %0|%0, %2}
11418 #
11419 #"
11420 [(set (attr "isa")
11421 (cond [(eq_attr "alternative" "3")
11422 (if_then_else (eq_attr "mode" "SI")
11423 (const_string "avx512bw")
11424 (const_string "avx512f"))
11425 ]
11426 (const_string "*")))
11427 (set_attr "type" "alu,alu,imovx,msklog")
11428 (set_attr "length_immediate" "*,*,0,*")
11429 (set (attr "prefix_rex")
11430 (if_then_else
11431 (and (eq_attr "type" "imovx")
11432 (and (match_test "INTVAL (operands[2]) == 0xff")
11433 (match_operand 1 "ext_QIreg_operand")))
11434 (const_string "1")
11435 (const_string "*")))
11436 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11437
11438 (define_insn "*andqi_1"
11439 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11440 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11441 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11442 (clobber (reg:CC FLAGS_REG))]
11443 "ix86_binary_operator_ok (AND, QImode, operands)"
11444 "@
11445 and{b}\t{%2, %0|%0, %2}
11446 and{b}\t{%2, %0|%0, %2}
11447 and{l}\t{%k2, %k0|%k0, %k2}
11448 #"
11449 [(set_attr "type" "alu,alu,alu,msklog")
11450 (set (attr "mode")
11451 (cond [(eq_attr "alternative" "2")
11452 (const_string "SI")
11453 (and (eq_attr "alternative" "3")
11454 (match_test "!TARGET_AVX512DQ"))
11455 (const_string "HI")
11456 ]
11457 (const_string "QI")))
11458 ;; Potential partial reg stall on alternative 2.
11459 (set (attr "preferred_for_speed")
11460 (cond [(eq_attr "alternative" "2")
11461 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11462 (symbol_ref "true")))])
11463
11464 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11465 (define_insn_and_split "*<code><mode>_1_slp"
11466 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11467 (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11468 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11469 (clobber (reg:CC FLAGS_REG))]
11470 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11471 "@
11472 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11473 #"
11474 "&& reload_completed
11475 && !(rtx_equal_p (operands[0], operands[1])
11476 || rtx_equal_p (operands[0], operands[2]))"
11477 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11478 (parallel
11479 [(set (strict_low_part (match_dup 0))
11480 (any_logic:SWI12 (match_dup 0) (match_dup 2)))
11481 (clobber (reg:CC FLAGS_REG))])]
11482 ""
11483 [(set_attr "type" "alu")
11484 (set_attr "mode" "<MODE>")])
11485
11486 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11487 (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
11488 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
11489 (any_logic:QI
11490 (subreg:QI
11491 (match_operator:SWI248 3 "extract_operator"
11492 [(match_operand 2 "int248_register_operand" "Q,Q")
11493 (const_int 8)
11494 (const_int 8)]) 0)
11495 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
11496 (clobber (reg:CC FLAGS_REG))]
11497 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11498 "@
11499 <logic>{b}\t{%h2, %0|%0, %h2}
11500 #"
11501 "&& reload_completed
11502 && !rtx_equal_p (operands[0], operands[1])"
11503 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11504 (parallel
11505 [(set (strict_low_part (match_dup 0))
11506 (any_logic:QI
11507 (subreg:QI
11508 (match_op_dup 3
11509 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
11510 (match_dup 0)
11511 (clobber (reg:CC FLAGS_REG))])]
11512 ""
11513 [(set_attr "type" "alu")
11514 (set_attr "mode" "QI")])
11515
11516 (define_split
11517 [(set (match_operand:SWI248 0 "register_operand")
11518 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11519 (match_operand:SWI248 2 "const_int_operand")))
11520 (clobber (reg:CC FLAGS_REG))]
11521 "reload_completed
11522 && (!REG_P (operands[1])
11523 || REGNO (operands[0]) != REGNO (operands[1]))"
11524 [(const_int 0)]
11525 {
11526 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11527 machine_mode mode;
11528
11529 if (ival == GET_MODE_MASK (SImode))
11530 mode = SImode;
11531 else if (ival == GET_MODE_MASK (HImode))
11532 mode = HImode;
11533 else if (ival == GET_MODE_MASK (QImode))
11534 mode = QImode;
11535 else
11536 gcc_unreachable ();
11537
11538 /* Zero extend to SImode to avoid partial register stalls. */
11539 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11540 operands[0] = gen_lowpart (SImode, operands[0]);
11541
11542 emit_insn (gen_extend_insn
11543 (operands[0], gen_lowpart (mode, operands[1]),
11544 GET_MODE (operands[0]), mode, 1));
11545 DONE;
11546 })
11547
11548 (define_split
11549 [(set (match_operand:SWI48 0 "register_operand")
11550 (and:SWI48 (match_dup 0)
11551 (const_int -65536)))
11552 (clobber (reg:CC FLAGS_REG))]
11553 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11554 || optimize_function_for_size_p (cfun)"
11555 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11556 "operands[1] = gen_lowpart (HImode, operands[0]);")
11557
11558 (define_split
11559 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11560 (and:SWI248 (match_dup 0)
11561 (const_int -256)))
11562 (clobber (reg:CC FLAGS_REG))]
11563 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11564 && reload_completed"
11565 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11566 "operands[1] = gen_lowpart (QImode, operands[0]);")
11567
11568 (define_split
11569 [(set (match_operand:SWI248 0 "QIreg_operand")
11570 (and:SWI248 (match_dup 0)
11571 (const_int -65281)))
11572 (clobber (reg:CC FLAGS_REG))]
11573 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11574 && reload_completed"
11575 [(parallel
11576 [(set (zero_extract:HI (match_dup 0)
11577 (const_int 8)
11578 (const_int 8))
11579 (subreg:HI
11580 (xor:QI
11581 (subreg:QI
11582 (zero_extract:HI (match_dup 0)
11583 (const_int 8)
11584 (const_int 8)) 0)
11585 (subreg:QI
11586 (zero_extract:HI (match_dup 0)
11587 (const_int 8)
11588 (const_int 8)) 0)) 0))
11589 (clobber (reg:CC FLAGS_REG))])]
11590 "operands[0] = gen_lowpart (HImode, operands[0]);")
11591
11592 (define_insn "*anddi_2"
11593 [(set (reg FLAGS_REG)
11594 (compare
11595 (and:DI
11596 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11597 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11598 (const_int 0)))
11599 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11600 (and:DI (match_dup 1) (match_dup 2)))]
11601 "TARGET_64BIT
11602 && ix86_match_ccmode
11603 (insn,
11604 /* If we are going to emit andl instead of andq, and the operands[2]
11605 constant might have the SImode sign bit set, make sure the sign
11606 flag isn't tested, because the instruction will set the sign flag
11607 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11608 conservatively assume it might have bit 31 set. */
11609 (satisfies_constraint_Z (operands[2])
11610 && (!CONST_INT_P (operands[2])
11611 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11612 ? CCZmode : CCNOmode)
11613 && ix86_binary_operator_ok (AND, DImode, operands)"
11614 "@
11615 and{l}\t{%k2, %k0|%k0, %k2}
11616 and{q}\t{%2, %0|%0, %2}
11617 and{q}\t{%2, %0|%0, %2}"
11618 [(set_attr "type" "alu")
11619 (set_attr "mode" "SI,DI,DI")])
11620
11621 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11622 (define_insn "*andsi_2_zext"
11623 [(set (reg FLAGS_REG)
11624 (compare (and:SI
11625 (match_operand:SI 1 "nonimmediate_operand" "%0")
11626 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11627 (const_int 0)))
11628 (set (match_operand:DI 0 "register_operand" "=r")
11629 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11630 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11631 && ix86_binary_operator_ok (AND, SImode, operands)"
11632 "and{l}\t{%2, %k0|%k0, %2}"
11633 [(set_attr "type" "alu")
11634 (set_attr "mode" "SI")])
11635
11636 (define_insn "*andqi_2_maybe_si"
11637 [(set (reg FLAGS_REG)
11638 (compare (and:QI
11639 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11640 (match_operand:QI 2 "general_operand" "qn,m,n"))
11641 (const_int 0)))
11642 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11643 (and:QI (match_dup 1) (match_dup 2)))]
11644 "ix86_binary_operator_ok (AND, QImode, operands)
11645 && ix86_match_ccmode (insn,
11646 CONST_INT_P (operands[2])
11647 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11648 {
11649 if (get_attr_mode (insn) == MODE_SI)
11650 {
11651 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11652 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11653 return "and{l}\t{%2, %k0|%k0, %2}";
11654 }
11655 return "and{b}\t{%2, %0|%0, %2}";
11656 }
11657 [(set_attr "type" "alu")
11658 (set (attr "mode")
11659 (cond [(eq_attr "alternative" "2")
11660 (const_string "SI")
11661 (and (match_test "optimize_insn_for_size_p ()")
11662 (and (match_operand 0 "ext_QIreg_operand")
11663 (match_operand 2 "const_0_to_127_operand")))
11664 (const_string "SI")
11665 ]
11666 (const_string "QI")))
11667 ;; Potential partial reg stall on alternative 2.
11668 (set (attr "preferred_for_speed")
11669 (cond [(eq_attr "alternative" "2")
11670 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11671 (symbol_ref "true")))])
11672
11673 (define_insn "*and<mode>_2"
11674 [(set (reg FLAGS_REG)
11675 (compare (and:SWI124
11676 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11677 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11678 (const_int 0)))
11679 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11680 (and:SWI124 (match_dup 1) (match_dup 2)))]
11681 "ix86_match_ccmode (insn, CCNOmode)
11682 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11683 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11684 [(set_attr "type" "alu")
11685 (set_attr "mode" "<MODE>")])
11686
11687 (define_insn "*<code>qi_ext<mode>_0"
11688 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
11689 (any_logic:QI
11690 (subreg:QI
11691 (match_operator:SWI248 3 "extract_operator"
11692 [(match_operand 2 "int248_register_operand" "Q")
11693 (const_int 8)
11694 (const_int 8)]) 0)
11695 (match_operand:QI 1 "nonimmediate_operand" "0")))
11696 (clobber (reg:CC FLAGS_REG))]
11697 ""
11698 "<logic>{b}\t{%h2, %0|%0, %h2}"
11699 [(set_attr "addr" "gpr8")
11700 (set_attr "type" "alu")
11701 (set_attr "mode" "QI")])
11702
11703 (define_expand "andqi_ext_1"
11704 [(parallel
11705 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11706 (const_int 8)
11707 (const_int 8))
11708 (subreg:HI
11709 (and:QI
11710 (subreg:QI
11711 (zero_extract:HI (match_operand:HI 1 "register_operand")
11712 (const_int 8)
11713 (const_int 8)) 0)
11714 (match_operand:QI 2 "const_int_operand")) 0))
11715 (clobber (reg:CC FLAGS_REG))])])
11716
11717 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11718 (define_insn_and_split "*<code>qi_ext<mode>_1"
11719 [(set (zero_extract:SWI248
11720 (match_operand 0 "int248_register_operand" "+Q,&Q")
11721 (const_int 8)
11722 (const_int 8))
11723 (subreg:SWI248
11724 (any_logic:QI
11725 (subreg:QI
11726 (match_operator:SWI248 3 "extract_operator"
11727 [(match_operand 1 "int248_register_operand" "0,!Q")
11728 (const_int 8)
11729 (const_int 8)]) 0)
11730 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
11731 (clobber (reg:CC FLAGS_REG))]
11732 ""
11733 "@
11734 <logic>{b}\t{%2, %h0|%h0, %2}
11735 #"
11736 "reload_completed
11737 && !(rtx_equal_p (operands[0], operands[1]))"
11738 [(set (zero_extract:SWI248
11739 (match_dup 0) (const_int 8) (const_int 8))
11740 (zero_extract:SWI248
11741 (match_dup 1) (const_int 8) (const_int 8)))
11742 (parallel
11743 [(set (zero_extract:SWI248
11744 (match_dup 0) (const_int 8) (const_int 8))
11745 (subreg:SWI248
11746 (any_logic:QI
11747 (subreg:QI
11748 (match_op_dup 3
11749 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11750 (match_dup 2)) 0))
11751 (clobber (reg:CC FLAGS_REG))])]
11752 ""
11753 [(set_attr "addr" "gpr8")
11754 (set_attr "type" "alu")
11755 (set_attr "mode" "QI")])
11756
11757 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11758 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
11759 [(set (match_operand 4 "flags_reg_operand")
11760 (match_operator 5 "compare_operator"
11761 [(any_logic:QI
11762 (subreg:QI
11763 (match_operator:SWI248 3 "extract_operator"
11764 [(match_operand 1 "int248_register_operand" "0,!Q")
11765 (const_int 8)
11766 (const_int 8)]) 0)
11767 (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
11768 (const_int 0)]))
11769 (set (zero_extract:SWI248
11770 (match_operand 0 "int248_register_operand" "+Q,&Q")
11771 (const_int 8)
11772 (const_int 8))
11773 (subreg:SWI248
11774 (any_logic:QI
11775 (subreg:QI
11776 (match_op_dup 3
11777 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11778 (match_dup 2)) 0))]
11779 "ix86_match_ccmode (insn, CCNOmode)"
11780 "@
11781 <logic>{b}\t{%2, %h0|%h0, %2}
11782 #"
11783 "&& reload_completed
11784 && !(rtx_equal_p (operands[0], operands[1]))"
11785 [(set (zero_extract:SWI248
11786 (match_dup 0) (const_int 8) (const_int 8))
11787 (zero_extract:SWI248
11788 (match_dup 1) (const_int 8) (const_int 8)))
11789 (parallel
11790 [(set (match_dup 4)
11791 (match_op_dup 5
11792 [(any_logic:QI
11793 (subreg:QI
11794 (match_op_dup 3
11795 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11796 (match_dup 2))
11797 (const_int 0)]))
11798 (set (zero_extract:SWI248
11799 (match_dup 0) (const_int 8) (const_int 8))
11800 (subreg:SWI248
11801 (any_logic:QI
11802 (subreg:QI
11803 (match_op_dup 3
11804 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11805 (match_dup 2)) 0))])]
11806 ""
11807 [(set_attr "addr" "gpr8")
11808 (set_attr "type" "alu")
11809 (set_attr "mode" "QI")])
11810
11811 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11812 (define_insn_and_split "*<code>qi_ext<mode>_2"
11813 [(set (zero_extract:SWI248
11814 (match_operand 0 "int248_register_operand" "+Q,&Q")
11815 (const_int 8)
11816 (const_int 8))
11817 (subreg:SWI248
11818 (any_logic:QI
11819 (subreg:QI
11820 (match_operator:SWI248 3 "extract_operator"
11821 [(match_operand 1 "int248_register_operand" "%0,!Q")
11822 (const_int 8)
11823 (const_int 8)]) 0)
11824 (subreg:QI
11825 (match_operator:SWI248 4 "extract_operator"
11826 [(match_operand 2 "int248_register_operand" "Q,Q")
11827 (const_int 8)
11828 (const_int 8)]) 0)) 0))
11829 (clobber (reg:CC FLAGS_REG))]
11830 ""
11831 "@
11832 <logic>{b}\t{%h2, %h0|%h0, %h2}
11833 #"
11834 "reload_completed
11835 && !(rtx_equal_p (operands[0], operands[1])
11836 || rtx_equal_p (operands[0], operands[2]))"
11837 [(set (zero_extract:SWI248
11838 (match_dup 0) (const_int 8) (const_int 8))
11839 (zero_extract:SWI248
11840 (match_dup 1) (const_int 8) (const_int 8)))
11841 (parallel
11842 [(set (zero_extract:SWI248
11843 (match_dup 0) (const_int 8) (const_int 8))
11844 (subreg:SWI248
11845 (any_logic:QI
11846 (subreg:QI
11847 (match_op_dup 3
11848 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11849 (subreg:QI
11850 (match_op_dup 4
11851 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
11852 (clobber (reg:CC FLAGS_REG))])]
11853 ""
11854 [(set_attr "type" "alu")
11855 (set_attr "mode" "QI")])
11856
11857 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11858 (define_insn_and_split "*<code>qi_ext<mode>_3"
11859 [(set (zero_extract:SWI248
11860 (match_operand 0 "int248_register_operand" "+Q,&Q")
11861 (const_int 8)
11862 (const_int 8))
11863 (match_operator:SWI248 3 "extract_operator"
11864 [(any_logic
11865 (match_operand 1 "int248_register_operand" "%0,!Q")
11866 (match_operand 2 "int248_register_operand" "Q,Q"))
11867 (const_int 8)
11868 (const_int 8)]))
11869 (clobber (reg:CC FLAGS_REG))]
11870 "GET_MODE (operands[1]) == GET_MODE (operands[2])"
11871 "@
11872 <logic>{b}\t{%h2, %h0|%h0, %h2}
11873 #"
11874 "&& reload_completed
11875 && !(rtx_equal_p (operands[0], operands[1])
11876 || rtx_equal_p (operands[0], operands[2]))"
11877 [(set (zero_extract:SWI248
11878 (match_dup 0) (const_int 8) (const_int 8))
11879 (zero_extract:SWI248
11880 (match_dup 1) (const_int 8) (const_int 8)))
11881 (parallel
11882 [(set (zero_extract:SWI248
11883 (match_dup 0) (const_int 8) (const_int 8))
11884 (match_op_dup 3
11885 [(any_logic (match_dup 4) (match_dup 2))
11886 (const_int 8) (const_int 8)]))
11887 (clobber (reg:CC FLAGS_REG))])]
11888 "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
11889 [(set_attr "type" "alu")
11890 (set_attr "mode" "QI")])
11891
11892 ;; Convert wide AND instructions with immediate operand to shorter QImode
11893 ;; equivalents when possible.
11894 ;; Don't do the splitting with memory operands, since it introduces risk
11895 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11896 ;; for size, but that can (should?) be handled by generic code instead.
11897 (define_split
11898 [(set (match_operand:SWI248 0 "QIreg_operand")
11899 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11900 (match_operand:SWI248 2 "const_int_operand")))
11901 (clobber (reg:CC FLAGS_REG))]
11902 "reload_completed
11903 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11904 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11905 [(parallel
11906 [(set (zero_extract:HI (match_dup 0)
11907 (const_int 8)
11908 (const_int 8))
11909 (subreg:HI
11910 (and:QI
11911 (subreg:QI
11912 (zero_extract:HI (match_dup 1)
11913 (const_int 8)
11914 (const_int 8)) 0)
11915 (match_dup 2)) 0))
11916 (clobber (reg:CC FLAGS_REG))])]
11917 {
11918 operands[0] = gen_lowpart (HImode, operands[0]);
11919 operands[1] = gen_lowpart (HImode, operands[1]);
11920 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11921 })
11922
11923 ;; Since AND can be encoded with sign extended immediate, this is only
11924 ;; profitable when 7th bit is not set.
11925 (define_split
11926 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11927 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11928 (match_operand:SWI248 2 "const_int_operand")))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "reload_completed
11931 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11932 && !(~INTVAL (operands[2]) & ~255)
11933 && !(INTVAL (operands[2]) & 128)"
11934 [(parallel [(set (strict_low_part (match_dup 0))
11935 (and:QI (match_dup 1)
11936 (match_dup 2)))
11937 (clobber (reg:CC FLAGS_REG))])]
11938 {
11939 operands[0] = gen_lowpart (QImode, operands[0]);
11940 operands[1] = gen_lowpart (QImode, operands[1]);
11941 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11942 })
11943
11944 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11945 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11946 (and:<DWI>
11947 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11948 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11949 (clobber (reg:CC FLAGS_REG))]
11950 "TARGET_BMI"
11951 "#"
11952 "&& reload_completed"
11953 [(parallel [(set (match_dup 0)
11954 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11955 (clobber (reg:CC FLAGS_REG))])
11956 (parallel [(set (match_dup 3)
11957 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11958 (clobber (reg:CC FLAGS_REG))])]
11959 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11960
11961 (define_insn_and_split "*andn<mode>3_doubleword"
11962 [(set (match_operand:DWI 0 "register_operand")
11963 (and:DWI
11964 (not:DWI (match_operand:DWI 1 "register_operand"))
11965 (match_operand:DWI 2 "nonimmediate_operand")))
11966 (clobber (reg:CC FLAGS_REG))]
11967 "!TARGET_BMI
11968 && ix86_pre_reload_split ()"
11969 "#"
11970 "&& 1"
11971 [(set (match_dup 3) (not:DWI (match_dup 1)))
11972 (parallel [(set (match_dup 0)
11973 (and:DWI (match_dup 3) (match_dup 2)))
11974 (clobber (reg:CC FLAGS_REG))])]
11975 "operands[3] = gen_reg_rtx (<MODE>mode);")
11976
11977 (define_insn "*andn<mode>_1"
11978 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11979 (and:SWI48
11980 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11981 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11982 (clobber (reg:CC FLAGS_REG))]
11983 "TARGET_BMI
11984 || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
11985 "@
11986 andn\t{%2, %1, %0|%0, %1, %2}
11987 andn\t{%2, %1, %0|%0, %1, %2}
11988 #"
11989 [(set_attr "isa" "bmi,bmi,<kmov_isa>")
11990 (set_attr "type" "bitmanip,bitmanip,msklog")
11991 (set_attr "btver2_decode" "direct, double,*")
11992 (set_attr "mode" "<MODE>")])
11993
11994 (define_insn "*andn<mode>_1"
11995 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11996 (and:SWI12
11997 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11998 (match_operand:SWI12 2 "register_operand" "r,k")))
11999 (clobber (reg:CC FLAGS_REG))]
12000 "TARGET_BMI || TARGET_AVX512BW"
12001 "@
12002 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
12003 #"
12004 [(set_attr "isa" "bmi,avx512f")
12005 (set_attr "type" "bitmanip,msklog")
12006 (set_attr "btver2_decode" "direct,*")
12007 (set (attr "mode")
12008 (cond [(eq_attr "alternative" "0")
12009 (const_string "SI")
12010 (and (eq_attr "alternative" "1")
12011 (match_test "!TARGET_AVX512DQ"))
12012 (const_string "HI")
12013 ]
12014 (const_string "<MODE>")))])
12015
12016 (define_insn "*andn_<mode>_ccno"
12017 [(set (reg FLAGS_REG)
12018 (compare
12019 (and:SWI48
12020 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12021 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12022 (const_int 0)))
12023 (clobber (match_scratch:SWI48 0 "=r,r"))]
12024 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12025 "andn\t{%2, %1, %0|%0, %1, %2}"
12026 [(set_attr "type" "bitmanip")
12027 (set_attr "btver2_decode" "direct, double")
12028 (set_attr "mode" "<MODE>")])
12029
12030 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
12031 (define_split
12032 [(set (match_operand:SI 0 "register_operand")
12033 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
12034 (match_operand:SI 2 "nonimmediate_operand")))
12035 (clobber (reg:CC FLAGS_REG))]
12036 "reload_completed
12037 && optimize_insn_for_size_p () && optimize_size > 1
12038 && REGNO (operands[0]) == REGNO (operands[1])
12039 && LEGACY_INT_REG_P (operands[0])
12040 && !REX_INT_REG_P (operands[2])
12041 && !reg_overlap_mentioned_p (operands[0], operands[2])"
12042 [(set (match_dup 0) (not:SI (match_dup 1)))
12043 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
12044 (clobber (reg:CC FLAGS_REG))])])
12045
12046 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
12047 (define_split
12048 [(set (match_operand 0 "flags_reg_operand")
12049 (match_operator 1 "compare_operator"
12050 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
12051 (match_operand:SI 3 "nonimmediate_operand"))
12052 (const_int 0)]))
12053 (clobber (match_dup 2))]
12054 "reload_completed
12055 && optimize_insn_for_size_p () && optimize_size > 1
12056 && LEGACY_INT_REG_P (operands[2])
12057 && !REX_INT_REG_P (operands[3])
12058 && !reg_overlap_mentioned_p (operands[2], operands[3])"
12059 [(set (match_dup 2) (not:SI (match_dup 2)))
12060 (set (match_dup 0) (match_op_dup 1
12061 [(and:SI (match_dup 3) (match_dup 2))
12062 (const_int 0)]))])
12063
12064 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
12065 (define_split
12066 [(set (match_operand:SWI48 0 "register_operand")
12067 (xor:SWI48
12068 (xor:SWI48
12069 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12070 (match_operand:SWI48 2 "nonimmediate_operand"))
12071 (match_dup 1))
12072 (match_operand:SWI48 3 "nonimmediate_operand")))
12073 (clobber (reg:CC FLAGS_REG))]
12074 "TARGET_BMI"
12075 [(parallel
12076 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12077 (clobber (reg:CC FLAGS_REG))])
12078 (parallel
12079 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12080 (clobber (reg:CC FLAGS_REG))])]
12081 "operands[4] = gen_reg_rtx (<MODE>mode);")
12082
12083 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
12084 (define_split
12085 [(set (match_operand:SWI48 0 "register_operand")
12086 (xor:SWI48
12087 (xor:SWI48
12088 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12089 (match_operand:SWI48 2 "register_operand"))
12090 (match_dup 2))
12091 (match_operand:SWI48 3 "nonimmediate_operand")))
12092 (clobber (reg:CC FLAGS_REG))]
12093 "TARGET_BMI"
12094 [(parallel
12095 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12096 (clobber (reg:CC FLAGS_REG))])
12097 (parallel
12098 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12099 (clobber (reg:CC FLAGS_REG))])]
12100 "operands[4] = gen_reg_rtx (<MODE>mode);")
12101
12102 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
12103 (define_split
12104 [(set (match_operand:SWI48 0 "register_operand")
12105 (xor:SWI48
12106 (xor:SWI48
12107 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12108 (match_operand:SWI48 2 "nonimmediate_operand"))
12109 (match_operand:SWI48 3 "nonimmediate_operand"))
12110 (match_dup 1)))
12111 (clobber (reg:CC FLAGS_REG))]
12112 "TARGET_BMI"
12113 [(parallel
12114 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12115 (clobber (reg:CC FLAGS_REG))])
12116 (parallel
12117 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12118 (clobber (reg:CC FLAGS_REG))])]
12119 "operands[4] = gen_reg_rtx (<MODE>mode);")
12120
12121 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
12122 (define_split
12123 [(set (match_operand:SWI48 0 "register_operand")
12124 (xor:SWI48
12125 (xor:SWI48
12126 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12127 (match_operand:SWI48 2 "register_operand"))
12128 (match_operand:SWI48 3 "nonimmediate_operand"))
12129 (match_dup 2)))
12130 (clobber (reg:CC FLAGS_REG))]
12131 "TARGET_BMI"
12132 [(parallel
12133 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12134 (clobber (reg:CC FLAGS_REG))])
12135 (parallel
12136 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12137 (clobber (reg:CC FLAGS_REG))])]
12138 "operands[4] = gen_reg_rtx (<MODE>mode);")
12139 \f
12140 ;; Logical inclusive and exclusive OR instructions
12141
12142 ;; %%% This used to optimize known byte-wide and operations to memory.
12143 ;; If this is considered useful, it should be done with splitters.
12144
12145 (define_expand "<code><mode>3"
12146 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12147 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12148 (match_operand:SDWIM 2 "<general_operand>")))]
12149 ""
12150 {
12151 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12152 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12153 operands[2] = force_reg (<MODE>mode, operands[2]);
12154
12155 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
12156 DONE;
12157 })
12158
12159 (define_insn_and_split "*<code><dwi>3_doubleword"
12160 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12161 (any_or:<DWI>
12162 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
12163 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
12164 (clobber (reg:CC FLAGS_REG))]
12165 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
12166 "#"
12167 "&& reload_completed"
12168 [(const_int:DWIH 0)]
12169 {
12170 /* This insn may disappear completely when operands[2] == const0_rtx
12171 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
12172 bool emit_insn_deleted_note_p = false;
12173
12174 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12175
12176 if (operands[2] == const0_rtx)
12177 emit_insn_deleted_note_p = true;
12178 else if (operands[2] == constm1_rtx)
12179 {
12180 if (<CODE> == IOR)
12181 emit_move_insn (operands[0], constm1_rtx);
12182 else
12183 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
12184 }
12185 else
12186 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
12187
12188 if (operands[5] == const0_rtx)
12189 {
12190 if (emit_insn_deleted_note_p)
12191 emit_note (NOTE_INSN_DELETED);
12192 }
12193 else if (operands[5] == constm1_rtx)
12194 {
12195 if (<CODE> == IOR)
12196 emit_move_insn (operands[3], constm1_rtx);
12197 else
12198 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
12199 }
12200 else
12201 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
12202
12203 DONE;
12204 })
12205
12206 (define_insn "*<code><mode>_1"
12207 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12208 (any_or:SWI248
12209 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12210 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12213 "@
12214 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12215 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12216 #"
12217 [(set_attr "isa" "*,*,<kmov_isa>")
12218 (set_attr "type" "alu, alu, msklog")
12219 (set_attr "mode" "<MODE>")])
12220
12221 (define_insn_and_split "*notxor<mode>_1"
12222 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12223 (not:SWI248
12224 (xor:SWI248
12225 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12226 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
12227 (clobber (reg:CC FLAGS_REG))]
12228 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
12229 "#"
12230 "&& reload_completed"
12231 [(parallel
12232 [(set (match_dup 0)
12233 (xor:SWI248 (match_dup 1) (match_dup 2)))
12234 (clobber (reg:CC FLAGS_REG))])
12235 (set (match_dup 0)
12236 (not:SWI248 (match_dup 0)))]
12237 {
12238 if (MASK_REG_P (operands[0]))
12239 {
12240 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12241 DONE;
12242 }
12243 }
12244 [(set_attr "isa" "*,*,<kmov_isa>")
12245 (set_attr "type" "alu, alu, msklog")
12246 (set_attr "mode" "<MODE>")])
12247
12248 (define_insn_and_split "*iordi_1_bts"
12249 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12250 (ior:DI
12251 (match_operand:DI 1 "nonimmediate_operand" "%0")
12252 (match_operand:DI 2 "const_int_operand" "n")))
12253 (clobber (reg:CC FLAGS_REG))]
12254 "TARGET_64BIT && TARGET_USE_BT
12255 && ix86_binary_operator_ok (IOR, DImode, operands)
12256 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12257 "#"
12258 "&& reload_completed"
12259 [(parallel [(set (zero_extract:DI (match_dup 0)
12260 (const_int 1)
12261 (match_dup 3))
12262 (const_int 1))
12263 (clobber (reg:CC FLAGS_REG))])]
12264 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12265 [(set_attr "type" "alu1")
12266 (set_attr "prefix_0f" "1")
12267 (set_attr "znver1_decode" "double")
12268 (set_attr "mode" "DI")])
12269
12270 (define_insn_and_split "*xordi_1_btc"
12271 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12272 (xor:DI
12273 (match_operand:DI 1 "nonimmediate_operand" "%0")
12274 (match_operand:DI 2 "const_int_operand" "n")))
12275 (clobber (reg:CC FLAGS_REG))]
12276 "TARGET_64BIT && TARGET_USE_BT
12277 && ix86_binary_operator_ok (XOR, DImode, operands)
12278 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12279 "#"
12280 "&& reload_completed"
12281 [(parallel [(set (zero_extract:DI (match_dup 0)
12282 (const_int 1)
12283 (match_dup 3))
12284 (not:DI (zero_extract:DI (match_dup 0)
12285 (const_int 1)
12286 (match_dup 3))))
12287 (clobber (reg:CC FLAGS_REG))])]
12288 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12289 [(set_attr "type" "alu1")
12290 (set_attr "prefix_0f" "1")
12291 (set_attr "znver1_decode" "double")
12292 (set_attr "mode" "DI")])
12293
12294 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12295 (define_insn_and_split "*xor2andn"
12296 [(set (match_operand:SWI248 0 "register_operand")
12297 (xor:SWI248
12298 (and:SWI248
12299 (xor:SWI248
12300 (match_operand:SWI248 1 "nonimmediate_operand")
12301 (match_operand:SWI248 2 "nonimmediate_operand"))
12302 (match_operand:SWI248 3 "nonimmediate_operand"))
12303 (match_dup 1)))
12304 (clobber (reg:CC FLAGS_REG))]
12305 "TARGET_BMI && ix86_pre_reload_split ()"
12306 "#"
12307 "&& 1"
12308 [(parallel [(set (match_dup 4)
12309 (and:SWI248
12310 (not:SWI248
12311 (match_dup 3))
12312 (match_dup 1)))
12313 (clobber (reg:CC FLAGS_REG))])
12314 (parallel [(set (match_dup 5)
12315 (and:SWI248
12316 (match_dup 3)
12317 (match_dup 2)))
12318 (clobber (reg:CC FLAGS_REG))])
12319 (parallel [(set (match_dup 0)
12320 (ior:SWI248
12321 (match_dup 4)
12322 (match_dup 5)))
12323 (clobber (reg:CC FLAGS_REG))])]
12324 {
12325 operands[1] = force_reg (<MODE>mode, operands[1]);
12326 operands[3] = force_reg (<MODE>mode, operands[3]);
12327 operands[4] = gen_reg_rtx (<MODE>mode);
12328 operands[5] = gen_reg_rtx (<MODE>mode);
12329 })
12330
12331 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12332 (define_insn "*<code>si_1_zext"
12333 [(set (match_operand:DI 0 "register_operand" "=r")
12334 (zero_extend:DI
12335 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12336 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12337 (clobber (reg:CC FLAGS_REG))]
12338 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12339 "<logic>{l}\t{%2, %k0|%k0, %2}"
12340 [(set_attr "type" "alu")
12341 (set_attr "mode" "SI")])
12342
12343 (define_insn "*<code>si_1_zext_imm"
12344 [(set (match_operand:DI 0 "register_operand" "=r")
12345 (any_or:DI
12346 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12347 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12350 "<logic>{l}\t{%2, %k0|%k0, %2}"
12351 [(set_attr "type" "alu")
12352 (set_attr "mode" "SI")])
12353
12354 (define_insn "*<code>qi_1"
12355 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12356 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12357 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12358 (clobber (reg:CC FLAGS_REG))]
12359 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12360 "@
12361 <logic>{b}\t{%2, %0|%0, %2}
12362 <logic>{b}\t{%2, %0|%0, %2}
12363 <logic>{l}\t{%k2, %k0|%k0, %k2}
12364 #"
12365 [(set_attr "isa" "*,*,*,avx512f")
12366 (set_attr "type" "alu,alu,alu,msklog")
12367 (set (attr "mode")
12368 (cond [(eq_attr "alternative" "2")
12369 (const_string "SI")
12370 (and (eq_attr "alternative" "3")
12371 (match_test "!TARGET_AVX512DQ"))
12372 (const_string "HI")
12373 ]
12374 (const_string "QI")))
12375 ;; Potential partial reg stall on alternative 2.
12376 (set (attr "preferred_for_speed")
12377 (cond [(eq_attr "alternative" "2")
12378 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12379 (symbol_ref "true")))])
12380
12381 (define_insn_and_split "*notxorqi_1"
12382 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12383 (not:QI
12384 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12385 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12386 (clobber (reg:CC FLAGS_REG))]
12387 "ix86_binary_operator_ok (XOR, QImode, operands)"
12388 "#"
12389 "&& reload_completed"
12390 [(parallel
12391 [(set (match_dup 0)
12392 (xor:QI (match_dup 1) (match_dup 2)))
12393 (clobber (reg:CC FLAGS_REG))])
12394 (set (match_dup 0)
12395 (not:QI (match_dup 0)))]
12396 {
12397 if (mask_reg_operand (operands[0], QImode))
12398 {
12399 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12400 DONE;
12401 }
12402 }
12403 [(set_attr "isa" "*,*,*,avx512f")
12404 (set_attr "type" "alu,alu,alu,msklog")
12405 (set (attr "mode")
12406 (cond [(eq_attr "alternative" "2")
12407 (const_string "SI")
12408 (and (eq_attr "alternative" "3")
12409 (match_test "!TARGET_AVX512DQ"))
12410 (const_string "HI")
12411 ]
12412 (const_string "QI")))
12413 ;; Potential partial reg stall on alternative 2.
12414 (set (attr "preferred_for_speed")
12415 (cond [(eq_attr "alternative" "2")
12416 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12417 (symbol_ref "true")))])
12418
12419 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12420 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12421 ;; This eliminates sign extension after logic operation.
12422
12423 (define_split
12424 [(set (match_operand:SWI248 0 "register_operand")
12425 (sign_extend:SWI248
12426 (any_logic:QI (match_operand:QI 1 "memory_operand")
12427 (match_operand:QI 2 "const_int_operand"))))]
12428 ""
12429 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12430 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12431 "operands[3] = gen_reg_rtx (<MODE>mode);")
12432
12433 (define_split
12434 [(set (match_operand:SWI48 0 "register_operand")
12435 (sign_extend:SWI48
12436 (any_logic:HI (match_operand:HI 1 "memory_operand")
12437 (match_operand:HI 2 "const_int_operand"))))]
12438 ""
12439 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12440 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12441 "operands[3] = gen_reg_rtx (<MODE>mode);")
12442
12443 (define_split
12444 [(set (match_operand:DI 0 "register_operand")
12445 (sign_extend:DI
12446 (any_logic:SI (match_operand:SI 1 "memory_operand")
12447 (match_operand:SI 2 "const_int_operand"))))]
12448 "TARGET_64BIT"
12449 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12450 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12451 "operands[3] = gen_reg_rtx (DImode);")
12452
12453 (define_insn "*<code><mode>_2"
12454 [(set (reg FLAGS_REG)
12455 (compare (any_or:SWI
12456 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12457 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12458 (const_int 0)))
12459 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12460 (any_or:SWI (match_dup 1) (match_dup 2)))]
12461 "ix86_match_ccmode (insn, CCNOmode)
12462 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12463 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12464 [(set_attr "type" "alu")
12465 (set_attr "mode" "<MODE>")])
12466
12467 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12468 ;; ??? Special case for immediate operand is missing - it is tricky.
12469 (define_insn "*<code>si_2_zext"
12470 [(set (reg FLAGS_REG)
12471 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12472 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12473 (const_int 0)))
12474 (set (match_operand:DI 0 "register_operand" "=r")
12475 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12476 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12477 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12478 "<logic>{l}\t{%2, %k0|%k0, %2}"
12479 [(set_attr "type" "alu")
12480 (set_attr "mode" "SI")])
12481
12482 (define_insn "*<code>si_2_zext_imm"
12483 [(set (reg FLAGS_REG)
12484 (compare (any_or:SI
12485 (match_operand:SI 1 "nonimmediate_operand" "%0")
12486 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12487 (const_int 0)))
12488 (set (match_operand:DI 0 "register_operand" "=r")
12489 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12490 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12491 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12492 "<logic>{l}\t{%2, %k0|%k0, %2}"
12493 [(set_attr "type" "alu")
12494 (set_attr "mode" "SI")])
12495
12496 (define_insn "*<code><mode>_3"
12497 [(set (reg FLAGS_REG)
12498 (compare (any_or:SWI
12499 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12500 (match_operand:SWI 2 "<general_operand>" "<g>"))
12501 (const_int 0)))
12502 (clobber (match_scratch:SWI 0 "=<r>"))]
12503 "ix86_match_ccmode (insn, CCNOmode)
12504 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12505 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12506 [(set_attr "type" "alu")
12507 (set_attr "mode" "<MODE>")])
12508
12509 ;; Convert wide OR instructions with immediate operand to shorter QImode
12510 ;; equivalents when possible.
12511 ;; Don't do the splitting with memory operands, since it introduces risk
12512 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12513 ;; for size, but that can (should?) be handled by generic code instead.
12514 (define_split
12515 [(set (match_operand:SWI248 0 "QIreg_operand")
12516 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12517 (match_operand:SWI248 2 "const_int_operand")))
12518 (clobber (reg:CC FLAGS_REG))]
12519 "reload_completed
12520 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12521 && !(INTVAL (operands[2]) & ~(255 << 8))"
12522 [(parallel
12523 [(set (zero_extract:HI (match_dup 0)
12524 (const_int 8)
12525 (const_int 8))
12526 (subreg:HI
12527 (any_or:QI
12528 (subreg:QI
12529 (zero_extract:HI (match_dup 1)
12530 (const_int 8)
12531 (const_int 8)) 0)
12532 (match_dup 2)) 0))
12533 (clobber (reg:CC FLAGS_REG))])]
12534 {
12535 /* Handle the case where INTVAL (operands[2]) == 0. */
12536 if (operands[2] == const0_rtx)
12537 {
12538 if (!rtx_equal_p (operands[0], operands[1]))
12539 emit_move_insn (operands[0], operands[1]);
12540 else
12541 emit_note (NOTE_INSN_DELETED);
12542 DONE;
12543 }
12544 operands[0] = gen_lowpart (HImode, operands[0]);
12545 operands[1] = gen_lowpart (HImode, operands[1]);
12546 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12547 })
12548
12549 ;; Since OR can be encoded with sign extended immediate, this is only
12550 ;; profitable when 7th bit is set.
12551 (define_split
12552 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12553 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12554 (match_operand:SWI248 2 "const_int_operand")))
12555 (clobber (reg:CC FLAGS_REG))]
12556 "reload_completed
12557 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12558 && !(INTVAL (operands[2]) & ~255)
12559 && (INTVAL (operands[2]) & 128)"
12560 [(parallel [(set (strict_low_part (match_dup 0))
12561 (any_or:QI (match_dup 1)
12562 (match_dup 2)))
12563 (clobber (reg:CC FLAGS_REG))])]
12564 {
12565 operands[0] = gen_lowpart (QImode, operands[0]);
12566 operands[1] = gen_lowpart (QImode, operands[1]);
12567 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12568 })
12569
12570 (define_expand "xorqi_ext_1_cc"
12571 [(parallel
12572 [(set (reg:CCNO FLAGS_REG)
12573 (compare:CCNO
12574 (xor:QI
12575 (subreg:QI
12576 (zero_extract:HI (match_operand:HI 1 "register_operand")
12577 (const_int 8)
12578 (const_int 8)) 0)
12579 (match_operand:QI 2 "const_int_operand"))
12580 (const_int 0)))
12581 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12582 (const_int 8)
12583 (const_int 8))
12584 (subreg:HI
12585 (xor:QI
12586 (subreg:QI
12587 (zero_extract:HI (match_dup 1)
12588 (const_int 8)
12589 (const_int 8)) 0)
12590 (match_dup 2)) 0))])])
12591
12592 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12593 (define_peephole2
12594 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12595 (const_int 0))
12596 (clobber (reg:CC FLAGS_REG))])
12597 (parallel [(set (match_dup 0)
12598 (any_or_plus:SWI (match_dup 0)
12599 (match_operand:SWI 1 "<general_operand>")))
12600 (clobber (reg:CC FLAGS_REG))])]
12601 "!reg_mentioned_p (operands[0], operands[1])"
12602 [(set (match_dup 0) (match_dup 1))])
12603
12604 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12605 (define_peephole2
12606 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12607 (const_int 0))
12608 (clobber (reg:CC FLAGS_REG))])
12609 (parallel [(set (match_dup 0)
12610 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12611 (clobber (reg:CC FLAGS_REG))])]
12612 ""
12613 [(parallel [(set (match_dup 0) (const_int 0))
12614 (clobber (reg:CC FLAGS_REG))])])
12615
12616 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12617 (define_insn_and_split "*concat<mode><dwi>3_1"
12618 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12619 (any_or_plus:<DWI>
12620 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12621 (match_operand:QI 2 "const_int_operand"))
12622 (zero_extend:<DWI>
12623 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12624 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12625 "#"
12626 "&& reload_completed"
12627 [(const_int 0)]
12628 {
12629 split_double_concat (<DWI>mode, operands[0], operands[3],
12630 gen_lowpart (<MODE>mode, operands[1]));
12631 DONE;
12632 })
12633
12634 (define_insn_and_split "*concat<mode><dwi>3_2"
12635 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12636 (any_or_plus:<DWI>
12637 (zero_extend:<DWI>
12638 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12639 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12640 (match_operand:QI 3 "const_int_operand"))))]
12641 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12642 "#"
12643 "&& reload_completed"
12644 [(const_int 0)]
12645 {
12646 split_double_concat (<DWI>mode, operands[0], operands[1],
12647 gen_lowpart (<MODE>mode, operands[2]));
12648 DONE;
12649 })
12650
12651 (define_insn_and_split "*concat<mode><dwi>3_3"
12652 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12653 (any_or_plus:<DWI>
12654 (ashift:<DWI>
12655 (zero_extend:<DWI>
12656 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12657 (match_operand:QI 2 "const_int_operand"))
12658 (zero_extend:<DWI>
12659 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12660 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12661 "#"
12662 "&& reload_completed"
12663 [(const_int 0)]
12664 {
12665 if (SSE_REG_P (operands[0]))
12666 {
12667 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12668 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12669 }
12670 else
12671 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12672 DONE;
12673 }
12674 [(set_attr "isa" "*,*,*,x64,x64")])
12675
12676 (define_insn_and_split "*concat<mode><dwi>3_4"
12677 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12678 (any_or_plus:<DWI>
12679 (zero_extend:<DWI>
12680 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12681 (ashift:<DWI>
12682 (zero_extend:<DWI>
12683 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12684 (match_operand:QI 3 "const_int_operand"))))]
12685 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12686 "#"
12687 "&& reload_completed"
12688 [(const_int 0)]
12689 {
12690 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12691 DONE;
12692 }
12693 [(set_attr "isa" "*,*,*,x64")])
12694
12695 (define_insn_and_split "*concat<half><mode>3_5"
12696 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12697 (any_or_plus:DWI
12698 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12699 (match_operand:QI 2 "const_int_operand"))
12700 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12701 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12702 && (<MODE>mode == DImode
12703 ? CONST_INT_P (operands[3])
12704 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12705 : CONST_INT_P (operands[3])
12706 ? INTVAL (operands[3]) >= 0
12707 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12708 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12709 && !(CONST_INT_P (operands[3])
12710 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12711 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12712 0)),
12713 VOIDmode))"
12714 "#"
12715 "&& reload_completed"
12716 [(const_int 0)]
12717 {
12718 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12719 split_double_concat (<MODE>mode, operands[0], op3,
12720 gen_lowpart (<HALF>mode, operands[1]));
12721 DONE;
12722 }
12723 [(set_attr "isa" "*,nox64,x64")])
12724
12725 (define_insn_and_split "*concat<mode><dwi>3_6"
12726 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12727 (any_or_plus:<DWI>
12728 (ashift:<DWI>
12729 (zero_extend:<DWI>
12730 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12731 (match_operand:QI 2 "const_int_operand"))
12732 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12733 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12734 && (<DWI>mode == DImode
12735 ? CONST_INT_P (operands[3])
12736 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12737 : CONST_INT_P (operands[3])
12738 ? INTVAL (operands[3]) >= 0
12739 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12740 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12741 && !(CONST_INT_P (operands[3])
12742 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12743 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12744 0)),
12745 VOIDmode))"
12746 "#"
12747 "&& reload_completed"
12748 [(const_int 0)]
12749 {
12750 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12751 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12752 DONE;
12753 }
12754 [(set_attr "isa" "*,nox64,x64,*")])
12755
12756 (define_insn_and_split "*concat<mode><dwi>3_7"
12757 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12758 (any_or_plus:<DWI>
12759 (zero_extend:<DWI>
12760 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12761 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12762 "<DWI>mode == DImode
12763 ? CONST_INT_P (operands[2])
12764 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12765 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12766 : CONST_WIDE_INT_P (operands[2])
12767 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12768 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12769 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12770 1)),
12771 VOIDmode)"
12772 "#"
12773 "&& reload_completed"
12774 [(const_int 0)]
12775 {
12776 rtx op2;
12777 if (<DWI>mode == DImode)
12778 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12779 else
12780 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12781 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12782 DONE;
12783 }
12784 [(set_attr "isa" "*,nox64,x64,*")])
12785 \f
12786 ;; Negation instructions
12787
12788 (define_expand "neg<mode>2"
12789 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12790 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12791 ""
12792 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12793
12794 (define_insn_and_split "*neg<dwi>2_doubleword"
12795 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12796 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12797 (clobber (reg:CC FLAGS_REG))]
12798 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12799 "#"
12800 "&& reload_completed"
12801 [(parallel
12802 [(set (reg:CCC FLAGS_REG)
12803 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12804 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12805 (parallel
12806 [(set (match_dup 2)
12807 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12808 (match_dup 3))
12809 (const_int 0)))
12810 (clobber (reg:CC FLAGS_REG))])
12811 (parallel
12812 [(set (match_dup 2)
12813 (neg:DWIH (match_dup 2)))
12814 (clobber (reg:CC FLAGS_REG))])]
12815 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12816
12817 ;; Convert:
12818 ;; mov %esi, %edx
12819 ;; negl %eax
12820 ;; adcl $0, %edx
12821 ;; negl %edx
12822 ;; to:
12823 ;; xorl %edx, %edx
12824 ;; negl %eax
12825 ;; sbbl %esi, %edx
12826
12827 (define_peephole2
12828 [(set (match_operand:SWI48 0 "general_reg_operand")
12829 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12830 (parallel
12831 [(set (reg:CCC FLAGS_REG)
12832 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12833 (const_int 0)] UNSPEC_CC_NE))
12834 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12835 (parallel
12836 [(set (match_dup 0)
12837 (plus:SWI48 (plus:SWI48
12838 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12839 (match_dup 0))
12840 (const_int 0)))
12841 (clobber (reg:CC FLAGS_REG))])
12842 (parallel
12843 [(set (match_dup 0)
12844 (neg:SWI48 (match_dup 0)))
12845 (clobber (reg:CC FLAGS_REG))])]
12846 "REGNO (operands[0]) != REGNO (operands[2])
12847 && !reg_mentioned_p (operands[0], operands[1])
12848 && !reg_mentioned_p (operands[2], operands[1])"
12849 [(parallel
12850 [(set (reg:CCC FLAGS_REG)
12851 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12852 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12853 (parallel
12854 [(set (match_dup 0)
12855 (minus:SWI48 (minus:SWI48
12856 (match_dup 0)
12857 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12858 (match_dup 1)))
12859 (clobber (reg:CC FLAGS_REG))])]
12860 "ix86_expand_clear (operands[0]);")
12861
12862 ;; Convert:
12863 ;; xorl %edx, %edx
12864 ;; negl %eax
12865 ;; adcl $0, %edx
12866 ;; negl %edx
12867 ;; to:
12868 ;; negl %eax
12869 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12870
12871 (define_peephole2
12872 [(parallel
12873 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12874 (clobber (reg:CC FLAGS_REG))])
12875 (parallel
12876 [(set (reg:CCC FLAGS_REG)
12877 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12878 (const_int 0)] UNSPEC_CC_NE))
12879 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12880 (parallel
12881 [(set (match_dup 0)
12882 (plus:SWI48 (plus:SWI48
12883 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12884 (match_dup 0))
12885 (const_int 0)))
12886 (clobber (reg:CC FLAGS_REG))])
12887 (parallel
12888 [(set (match_dup 0)
12889 (neg:SWI48 (match_dup 0)))
12890 (clobber (reg:CC FLAGS_REG))])]
12891 "REGNO (operands[0]) != REGNO (operands[1])"
12892 [(parallel
12893 [(set (reg:CCC FLAGS_REG)
12894 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12895 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12896 (parallel
12897 [(set (match_dup 0)
12898 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12899 (const_int -1)
12900 (const_int 0)))
12901 (clobber (reg:CC FLAGS_REG))])])
12902
12903 (define_insn "*neg<mode>_1"
12904 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12905 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12906 (clobber (reg:CC FLAGS_REG))]
12907 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12908 "neg{<imodesuffix>}\t%0"
12909 [(set_attr "type" "negnot")
12910 (set_attr "mode" "<MODE>")])
12911
12912 (define_insn "*negsi_1_zext"
12913 [(set (match_operand:DI 0 "register_operand" "=r")
12914 (zero_extend:DI
12915 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12916 (clobber (reg:CC FLAGS_REG))]
12917 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12918 "neg{l}\t%k0"
12919 [(set_attr "type" "negnot")
12920 (set_attr "mode" "SI")])
12921
12922 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12923 (define_insn_and_split "*neg<mode>_1_slp"
12924 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12925 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12926 (clobber (reg:CC FLAGS_REG))]
12927 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12928 "@
12929 neg{<imodesuffix>}\t%0
12930 #"
12931 "&& reload_completed
12932 && !(rtx_equal_p (operands[0], operands[1]))"
12933 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12934 (parallel
12935 [(set (strict_low_part (match_dup 0))
12936 (neg:SWI12 (match_dup 0)))
12937 (clobber (reg:CC FLAGS_REG))])]
12938 ""
12939 [(set_attr "type" "negnot")
12940 (set_attr "mode" "<MODE>")])
12941
12942 (define_insn "*neg<mode>_2"
12943 [(set (reg FLAGS_REG)
12944 (compare
12945 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12946 (const_int 0)))
12947 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12948 (neg:SWI (match_dup 1)))]
12949 "ix86_match_ccmode (insn, CCGOCmode)
12950 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12951 "neg{<imodesuffix>}\t%0"
12952 [(set_attr "type" "negnot")
12953 (set_attr "mode" "<MODE>")])
12954
12955 (define_insn "*negsi_2_zext"
12956 [(set (reg FLAGS_REG)
12957 (compare
12958 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12959 (const_int 0)))
12960 (set (match_operand:DI 0 "register_operand" "=r")
12961 (zero_extend:DI
12962 (neg:SI (match_dup 1))))]
12963 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12964 && ix86_unary_operator_ok (NEG, SImode, operands)"
12965 "neg{l}\t%k0"
12966 [(set_attr "type" "negnot")
12967 (set_attr "mode" "SI")])
12968
12969 (define_insn "*neg<mode>_ccc_1"
12970 [(set (reg:CCC FLAGS_REG)
12971 (unspec:CCC
12972 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12973 (const_int 0)] UNSPEC_CC_NE))
12974 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12975 (neg:SWI (match_dup 1)))]
12976 ""
12977 "neg{<imodesuffix>}\t%0"
12978 [(set_attr "type" "negnot")
12979 (set_attr "mode" "<MODE>")])
12980
12981 (define_insn "*neg<mode>_ccc_2"
12982 [(set (reg:CCC FLAGS_REG)
12983 (unspec:CCC
12984 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12985 (const_int 0)] UNSPEC_CC_NE))
12986 (clobber (match_scratch:SWI 0 "=<r>"))]
12987 ""
12988 "neg{<imodesuffix>}\t%0"
12989 [(set_attr "type" "negnot")
12990 (set_attr "mode" "<MODE>")])
12991
12992 (define_expand "x86_neg<mode>_ccc"
12993 [(parallel
12994 [(set (reg:CCC FLAGS_REG)
12995 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12996 (const_int 0)] UNSPEC_CC_NE))
12997 (set (match_operand:SWI48 0 "register_operand")
12998 (neg:SWI48 (match_dup 1)))])])
12999
13000 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13001 (define_insn_and_split "*negqi_ext<mode>_1"
13002 [(set (zero_extract:SWI248
13003 (match_operand 0 "int248_register_operand" "+Q,&Q")
13004 (const_int 8)
13005 (const_int 8))
13006 (subreg:SWI248
13007 (neg:QI
13008 (subreg:QI
13009 (match_operator:SWI248 2 "extract_operator"
13010 [(match_operand 1 "int248_register_operand" "0,!Q")
13011 (const_int 8)
13012 (const_int 8)]) 0)) 0))
13013 (clobber (reg:CC FLAGS_REG))]
13014 ""
13015 "@
13016 neg{b}\t%h0
13017 #"
13018 "reload_completed
13019 && !(rtx_equal_p (operands[0], operands[1]))"
13020 [(set (zero_extract:SWI248
13021 (match_dup 0) (const_int 8) (const_int 8))
13022 (zero_extract:SWI248
13023 (match_dup 1) (const_int 8) (const_int 8)))
13024 (parallel
13025 [(set (zero_extract:SWI248
13026 (match_dup 0) (const_int 8) (const_int 8))
13027 (subreg:SWI248
13028 (neg:QI
13029 (subreg:QI
13030 (match_op_dup 2
13031 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
13032 (clobber (reg:CC FLAGS_REG))])]
13033 ""
13034 [(set_attr "type" "negnot")
13035 (set_attr "mode" "QI")])
13036
13037 ;; Negate with jump on overflow.
13038 (define_expand "negv<mode>3"
13039 [(parallel [(set (reg:CCO FLAGS_REG)
13040 (unspec:CCO
13041 [(match_operand:SWI 1 "register_operand")
13042 (match_dup 3)] UNSPEC_CC_NE))
13043 (set (match_operand:SWI 0 "register_operand")
13044 (neg:SWI (match_dup 1)))])
13045 (set (pc) (if_then_else
13046 (eq (reg:CCO FLAGS_REG) (const_int 0))
13047 (label_ref (match_operand 2))
13048 (pc)))]
13049 ""
13050 {
13051 operands[3]
13052 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
13053 <MODE>mode);
13054 })
13055
13056 (define_insn "*negv<mode>3"
13057 [(set (reg:CCO FLAGS_REG)
13058 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
13059 (match_operand:SWI 2 "const_int_operand")]
13060 UNSPEC_CC_NE))
13061 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13062 (neg:SWI (match_dup 1)))]
13063 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
13064 && mode_signbit_p (<MODE>mode, operands[2])"
13065 "neg{<imodesuffix>}\t%0"
13066 [(set_attr "type" "negnot")
13067 (set_attr "mode" "<MODE>")])
13068
13069 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
13070 (define_peephole2
13071 [(set (match_operand:SWI 0 "general_reg_operand")
13072 (match_operand:SWI 1 "general_reg_operand"))
13073 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
13074 (clobber (reg:CC FLAGS_REG))])
13075 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
13076 ""
13077 [(set (match_dup 0) (match_dup 1))
13078 (parallel [(set (reg:CCZ FLAGS_REG)
13079 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
13080 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
13081
13082 ;; Special expand pattern to handle integer mode abs
13083
13084 (define_expand "abs<mode>2"
13085 [(parallel
13086 [(set (match_operand:SDWIM 0 "register_operand")
13087 (abs:SDWIM
13088 (match_operand:SDWIM 1 "general_operand")))
13089 (clobber (reg:CC FLAGS_REG))])]
13090 "TARGET_CMOVE
13091 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13092 {
13093 if (TARGET_EXPAND_ABS)
13094 {
13095 machine_mode mode = <MODE>mode;
13096 operands[1] = force_reg (mode, operands[1]);
13097
13098 /* Generate rtx abs using:
13099 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13100
13101 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13102 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13103 shift_amount, NULL_RTX,
13104 0, OPTAB_DIRECT);
13105 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13106 operands[0], 0, OPTAB_DIRECT);
13107 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13108 operands[0], 0, OPTAB_DIRECT);
13109 if (!rtx_equal_p (minus_dst, operands[0]))
13110 emit_move_insn (operands[0], minus_dst);
13111 DONE;
13112 }
13113 })
13114
13115 (define_insn_and_split "*abs<dwi>2_doubleword"
13116 [(set (match_operand:<DWI> 0 "register_operand")
13117 (abs:<DWI>
13118 (match_operand:<DWI> 1 "general_operand")))
13119 (clobber (reg:CC FLAGS_REG))]
13120 "TARGET_CMOVE
13121 && ix86_pre_reload_split ()"
13122 "#"
13123 "&& 1"
13124 [(parallel
13125 [(set (reg:CCC FLAGS_REG)
13126 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13127 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13128 (parallel
13129 [(set (match_dup 5)
13130 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13131 (match_dup 4))
13132 (const_int 0)))
13133 (clobber (reg:CC FLAGS_REG))])
13134 (parallel
13135 [(set (reg:CCGOC FLAGS_REG)
13136 (compare:CCGOC
13137 (neg:DWIH (match_dup 5))
13138 (const_int 0)))
13139 (set (match_dup 5)
13140 (neg:DWIH (match_dup 5)))])
13141 (set (match_dup 0)
13142 (if_then_else:DWIH
13143 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13144 (match_dup 2)
13145 (match_dup 1)))
13146 (set (match_dup 3)
13147 (if_then_else:DWIH
13148 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13149 (match_dup 5)
13150 (match_dup 4)))]
13151 {
13152 operands[1] = force_reg (<DWI>mode, operands[1]);
13153 operands[2] = gen_reg_rtx (<DWI>mode);
13154
13155 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13156 })
13157
13158 (define_insn_and_split "*nabs<dwi>2_doubleword"
13159 [(set (match_operand:<DWI> 0 "register_operand")
13160 (neg:<DWI>
13161 (abs:<DWI>
13162 (match_operand:<DWI> 1 "general_operand"))))
13163 (clobber (reg:CC FLAGS_REG))]
13164 "TARGET_CMOVE
13165 && ix86_pre_reload_split ()"
13166 "#"
13167 "&& 1"
13168 [(parallel
13169 [(set (reg:CCC FLAGS_REG)
13170 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13171 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13172 (parallel
13173 [(set (match_dup 5)
13174 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13175 (match_dup 4))
13176 (const_int 0)))
13177 (clobber (reg:CC FLAGS_REG))])
13178 (parallel
13179 [(set (reg:CCGOC FLAGS_REG)
13180 (compare:CCGOC
13181 (neg:DWIH (match_dup 5))
13182 (const_int 0)))
13183 (set (match_dup 5)
13184 (neg:DWIH (match_dup 5)))])
13185 (set (match_dup 0)
13186 (if_then_else:DWIH
13187 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13188 (match_dup 2)
13189 (match_dup 1)))
13190 (set (match_dup 3)
13191 (if_then_else:DWIH
13192 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13193 (match_dup 5)
13194 (match_dup 4)))]
13195 {
13196 operands[1] = force_reg (<DWI>mode, operands[1]);
13197 operands[2] = gen_reg_rtx (<DWI>mode);
13198
13199 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13200 })
13201
13202 (define_insn_and_split "*abs<mode>2_1"
13203 [(set (match_operand:SWI 0 "register_operand")
13204 (abs:SWI
13205 (match_operand:SWI 1 "general_operand")))
13206 (clobber (reg:CC FLAGS_REG))]
13207 "TARGET_CMOVE
13208 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13209 && ix86_pre_reload_split ()"
13210 "#"
13211 "&& 1"
13212 [(parallel
13213 [(set (reg:CCGOC FLAGS_REG)
13214 (compare:CCGOC
13215 (neg:SWI (match_dup 1))
13216 (const_int 0)))
13217 (set (match_dup 2)
13218 (neg:SWI (match_dup 1)))])
13219 (set (match_dup 0)
13220 (if_then_else:SWI
13221 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13222 (match_dup 2)
13223 (match_dup 1)))]
13224 {
13225 operands[1] = force_reg (<MODE>mode, operands[1]);
13226 operands[2] = gen_reg_rtx (<MODE>mode);
13227 })
13228
13229 (define_insn_and_split "*nabs<mode>2_1"
13230 [(set (match_operand:SWI 0 "register_operand")
13231 (neg:SWI
13232 (abs:SWI
13233 (match_operand:SWI 1 "general_operand"))))
13234 (clobber (reg:CC FLAGS_REG))]
13235 "TARGET_CMOVE
13236 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13237 && ix86_pre_reload_split ()"
13238 "#"
13239 "&& 1"
13240 [(parallel
13241 [(set (reg:CCGOC FLAGS_REG)
13242 (compare:CCGOC
13243 (neg:SWI (match_dup 1))
13244 (const_int 0)))
13245 (set (match_dup 2)
13246 (neg:SWI (match_dup 1)))])
13247 (set (match_dup 0)
13248 (if_then_else:SWI
13249 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13250 (match_dup 2)
13251 (match_dup 1)))]
13252 {
13253 operands[1] = force_reg (<MODE>mode, operands[1]);
13254 operands[2] = gen_reg_rtx (<MODE>mode);
13255 })
13256
13257 (define_expand "<code>tf2"
13258 [(set (match_operand:TF 0 "register_operand")
13259 (absneg:TF (match_operand:TF 1 "register_operand")))]
13260 "TARGET_SSE"
13261 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13262
13263 (define_insn_and_split "*<code>tf2_1"
13264 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13265 (absneg:TF
13266 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13267 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13268 "TARGET_SSE"
13269 "#"
13270 "&& reload_completed"
13271 [(set (match_dup 0)
13272 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13273 {
13274 if (TARGET_AVX)
13275 {
13276 if (MEM_P (operands[1]))
13277 std::swap (operands[1], operands[2]);
13278 }
13279 else
13280 {
13281 if (operands_match_p (operands[0], operands[2]))
13282 std::swap (operands[1], operands[2]);
13283 }
13284 }
13285 [(set_attr "isa" "noavx,noavx,avx,avx")])
13286
13287 (define_insn_and_split "*nabstf2_1"
13288 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13289 (neg:TF
13290 (abs:TF
13291 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13292 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13293 "TARGET_SSE"
13294 "#"
13295 "&& reload_completed"
13296 [(set (match_dup 0)
13297 (ior:TF (match_dup 1) (match_dup 2)))]
13298 {
13299 if (TARGET_AVX)
13300 {
13301 if (MEM_P (operands[1]))
13302 std::swap (operands[1], operands[2]);
13303 }
13304 else
13305 {
13306 if (operands_match_p (operands[0], operands[2]))
13307 std::swap (operands[1], operands[2]);
13308 }
13309 }
13310 [(set_attr "isa" "noavx,noavx,avx,avx")])
13311
13312 (define_expand "<code>hf2"
13313 [(set (match_operand:HF 0 "register_operand")
13314 (absneg:HF (match_operand:HF 1 "register_operand")))]
13315 "TARGET_AVX512FP16"
13316 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13317
13318 (define_expand "<code><mode>2"
13319 [(set (match_operand:X87MODEF 0 "register_operand")
13320 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13321 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13322 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13323
13324 ;; Changing of sign for FP values is doable using integer unit too.
13325 (define_insn "*<code><mode>2_i387_1"
13326 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13327 (absneg:X87MODEF
13328 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13329 (clobber (reg:CC FLAGS_REG))]
13330 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13331 "#")
13332
13333 (define_split
13334 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13335 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13336 (clobber (reg:CC FLAGS_REG))]
13337 "TARGET_80387 && reload_completed"
13338 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13339
13340 (define_split
13341 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13342 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13343 (clobber (reg:CC FLAGS_REG))]
13344 "TARGET_80387 && reload_completed"
13345 [(const_int 0)]
13346 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13347
13348 (define_insn_and_split "*<code>hf2_1"
13349 [(set (match_operand:HF 0 "register_operand" "=Yv")
13350 (absneg:HF
13351 (match_operand:HF 1 "register_operand" "Yv")))
13352 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13353 (clobber (reg:CC FLAGS_REG))]
13354 "TARGET_AVX512FP16"
13355 "#"
13356 "&& reload_completed"
13357 [(set (match_dup 0)
13358 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13359 {
13360 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13361 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13362 })
13363
13364 (define_insn "*<code><mode>2_1"
13365 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13366 (absneg:MODEF
13367 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13368 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13369 (clobber (reg:CC FLAGS_REG))]
13370 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13371 "#"
13372 [(set_attr "isa" "noavx,noavx,avx,*,*")
13373 (set (attr "enabled")
13374 (if_then_else
13375 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13376 (if_then_else
13377 (eq_attr "alternative" "3,4")
13378 (symbol_ref "TARGET_MIX_SSE_I387")
13379 (const_string "*"))
13380 (if_then_else
13381 (eq_attr "alternative" "3,4")
13382 (symbol_ref "true")
13383 (symbol_ref "false"))))])
13384
13385 (define_split
13386 [(set (match_operand:MODEF 0 "sse_reg_operand")
13387 (absneg:MODEF
13388 (match_operand:MODEF 1 "sse_reg_operand")))
13389 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13390 (clobber (reg:CC FLAGS_REG))]
13391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13392 && reload_completed"
13393 [(set (match_dup 0)
13394 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13395 {
13396 machine_mode mode = <MODE>mode;
13397 machine_mode vmode = <ssevecmodef>mode;
13398
13399 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13400 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13401
13402 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13403 std::swap (operands[1], operands[2]);
13404 })
13405
13406 (define_split
13407 [(set (match_operand:MODEF 0 "fp_register_operand")
13408 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13409 (use (match_operand 2))
13410 (clobber (reg:CC FLAGS_REG))]
13411 "TARGET_80387 && reload_completed"
13412 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13413
13414 (define_split
13415 [(set (match_operand:MODEF 0 "general_reg_operand")
13416 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13417 (use (match_operand 2))
13418 (clobber (reg:CC FLAGS_REG))]
13419 "TARGET_80387 && reload_completed"
13420 [(const_int 0)]
13421 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13422
13423 (define_insn_and_split "*nabs<mode>2_1"
13424 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13425 (neg:MODEF
13426 (abs:MODEF
13427 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13428 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13429 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13430 "#"
13431 "&& reload_completed"
13432 [(set (match_dup 0)
13433 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13434 {
13435 machine_mode mode = <MODE>mode;
13436 machine_mode vmode = <ssevecmodef>mode;
13437
13438 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13439 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13440
13441 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13442 std::swap (operands[1], operands[2]);
13443 }
13444 [(set_attr "isa" "noavx,noavx,avx")])
13445
13446 ;; Conditionalize these after reload. If they match before reload, we
13447 ;; lose the clobber and ability to use integer instructions.
13448
13449 (define_insn "*<code><mode>2_i387"
13450 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13451 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13452 "TARGET_80387 && reload_completed"
13453 "<absneg_mnemonic>"
13454 [(set_attr "type" "fsgn")
13455 (set_attr "mode" "<MODE>")])
13456
13457 ;; Copysign instructions
13458
13459 (define_expand "copysign<mode>3"
13460 [(match_operand:SSEMODEF 0 "register_operand")
13461 (match_operand:SSEMODEF 1 "nonmemory_operand")
13462 (match_operand:SSEMODEF 2 "register_operand")]
13463 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13464 || (TARGET_SSE && (<MODE>mode == TFmode))
13465 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13466 "ix86_expand_copysign (operands); DONE;")
13467
13468 (define_expand "xorsign<mode>3"
13469 [(match_operand:MODEFH 0 "register_operand")
13470 (match_operand:MODEFH 1 "register_operand")
13471 (match_operand:MODEFH 2 "register_operand")]
13472 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13473 || <MODE>mode == HFmode"
13474 {
13475 if (rtx_equal_p (operands[1], operands[2]))
13476 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13477 else
13478 ix86_expand_xorsign (operands);
13479 DONE;
13480 })
13481 \f
13482 ;; One complement instructions
13483
13484 (define_expand "one_cmpl<mode>2"
13485 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13486 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13487 ""
13488 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13489
13490 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13491 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13492 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13493 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13494 "#"
13495 "&& reload_completed"
13496 [(set (match_dup 0)
13497 (not:DWIH (match_dup 1)))
13498 (set (match_dup 2)
13499 (not:DWIH (match_dup 3)))]
13500 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13501
13502 (define_insn "*one_cmpl<mode>2_1"
13503 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13504 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13505 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13506 "@
13507 not{<imodesuffix>}\t%0
13508 #"
13509 [(set_attr "isa" "*,<kmov_isa>")
13510 (set_attr "type" "negnot,msklog")
13511 (set_attr "mode" "<MODE>")])
13512
13513 (define_insn "*one_cmplsi2_1_zext"
13514 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13515 (zero_extend:DI
13516 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13517 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13518 "@
13519 not{l}\t%k0
13520 #"
13521 [(set_attr "isa" "x64,avx512bw_512")
13522 (set_attr "type" "negnot,msklog")
13523 (set_attr "mode" "SI,SI")])
13524
13525 (define_insn "*one_cmplqi2_1"
13526 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13527 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13528 "ix86_unary_operator_ok (NOT, QImode, operands)"
13529 "@
13530 not{b}\t%0
13531 not{l}\t%k0
13532 #"
13533 [(set_attr "isa" "*,*,avx512f")
13534 (set_attr "type" "negnot,negnot,msklog")
13535 (set (attr "mode")
13536 (cond [(eq_attr "alternative" "1")
13537 (const_string "SI")
13538 (and (eq_attr "alternative" "2")
13539 (match_test "!TARGET_AVX512DQ"))
13540 (const_string "HI")
13541 ]
13542 (const_string "QI")))
13543 ;; Potential partial reg stall on alternative 1.
13544 (set (attr "preferred_for_speed")
13545 (cond [(eq_attr "alternative" "1")
13546 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13547 (symbol_ref "true")))])
13548
13549 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13550 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13551 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13552 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13553 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13554 "@
13555 not{<imodesuffix>}\t%0
13556 #"
13557 "&& reload_completed
13558 && !(rtx_equal_p (operands[0], operands[1]))"
13559 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13560 (set (strict_low_part (match_dup 0))
13561 (not:SWI12 (match_dup 0)))]
13562 ""
13563 [(set_attr "type" "negnot")
13564 (set_attr "mode" "<MODE>")])
13565
13566 (define_insn "*one_cmpl<mode>2_2"
13567 [(set (reg FLAGS_REG)
13568 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13569 (const_int 0)))
13570 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13571 (not:SWI (match_dup 1)))]
13572 "ix86_match_ccmode (insn, CCNOmode)
13573 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13574 "#"
13575 [(set_attr "type" "alu1")
13576 (set_attr "mode" "<MODE>")])
13577
13578 (define_split
13579 [(set (match_operand 0 "flags_reg_operand")
13580 (match_operator 2 "compare_operator"
13581 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13582 (const_int 0)]))
13583 (set (match_operand:SWI 1 "nonimmediate_operand")
13584 (not:SWI (match_dup 3)))]
13585 "ix86_match_ccmode (insn, CCNOmode)"
13586 [(parallel [(set (match_dup 0)
13587 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13588 (const_int 0)]))
13589 (set (match_dup 1)
13590 (xor:SWI (match_dup 3) (const_int -1)))])])
13591
13592 (define_insn "*one_cmplsi2_2_zext"
13593 [(set (reg FLAGS_REG)
13594 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13595 (const_int 0)))
13596 (set (match_operand:DI 0 "register_operand" "=r")
13597 (zero_extend:DI (not:SI (match_dup 1))))]
13598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13599 && ix86_unary_operator_ok (NOT, SImode, operands)"
13600 "#"
13601 [(set_attr "type" "alu1")
13602 (set_attr "mode" "SI")])
13603
13604 (define_split
13605 [(set (match_operand 0 "flags_reg_operand")
13606 (match_operator 2 "compare_operator"
13607 [(not:SI (match_operand:SI 3 "register_operand"))
13608 (const_int 0)]))
13609 (set (match_operand:DI 1 "register_operand")
13610 (zero_extend:DI (not:SI (match_dup 3))))]
13611 "ix86_match_ccmode (insn, CCNOmode)"
13612 [(parallel [(set (match_dup 0)
13613 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13614 (const_int 0)]))
13615 (set (match_dup 1)
13616 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13617
13618 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13619 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
13620 [(set (zero_extract:SWI248
13621 (match_operand 0 "int248_register_operand" "+Q,&Q")
13622 (const_int 8)
13623 (const_int 8))
13624 (subreg:SWI248
13625 (not:QI
13626 (subreg:QI
13627 (match_operator:SWI248 2 "extract_operator"
13628 [(match_operand 1 "int248_register_operand" "0,!Q")
13629 (const_int 8)
13630 (const_int 8)]) 0)) 0))]
13631 ""
13632 "@
13633 not{b}\t%h0
13634 #"
13635 "reload_completed
13636 && !(rtx_equal_p (operands[0], operands[1]))"
13637 [(set (zero_extract:SWI248
13638 (match_dup 0) (const_int 8) (const_int 8))
13639 (zero_extract:SWI248
13640 (match_dup 1) (const_int 8) (const_int 8)))
13641 (set (zero_extract:SWI248
13642 (match_dup 0) (const_int 8) (const_int 8))
13643 (subreg:SWI248
13644 (not:QI
13645 (subreg:QI
13646 (match_op_dup 2
13647 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
13648 ""
13649 [(set_attr "type" "negnot")
13650 (set_attr "mode" "QI")])
13651 \f
13652 ;; Shift instructions
13653
13654 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13655 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13656 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13657 ;; from the assembler input.
13658 ;;
13659 ;; This instruction shifts the target reg/mem as usual, but instead of
13660 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13661 ;; is a left shift double, bits are taken from the high order bits of
13662 ;; reg, else if the insn is a shift right double, bits are taken from the
13663 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13664 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13665 ;;
13666 ;; Since sh[lr]d does not change the `reg' operand, that is done
13667 ;; separately, making all shifts emit pairs of shift double and normal
13668 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13669 ;; support a 63 bit shift, each shift where the count is in a reg expands
13670 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13671 ;;
13672 ;; If the shift count is a constant, we need never emit more than one
13673 ;; shift pair, instead using moves and sign extension for counts greater
13674 ;; than 31.
13675
13676 (define_expand "ashl<mode>3"
13677 [(set (match_operand:SDWIM 0 "<shift_operand>")
13678 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13679 (match_operand:QI 2 "nonmemory_operand")))]
13680 ""
13681 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13682
13683 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13684 [(set (match_operand:<DWI> 0 "register_operand")
13685 (ashift:<DWI>
13686 (match_operand:<DWI> 1 "register_operand")
13687 (subreg:QI
13688 (and
13689 (match_operand 2 "int248_register_operand" "c")
13690 (match_operand 3 "const_int_operand")) 0)))
13691 (clobber (reg:CC FLAGS_REG))]
13692 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13693 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13694 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13695 && ix86_pre_reload_split ()"
13696 "#"
13697 "&& 1"
13698 [(parallel
13699 [(set (match_dup 6)
13700 (ior:DWIH (ashift:DWIH (match_dup 6)
13701 (and:QI (match_dup 2) (match_dup 8)))
13702 (subreg:DWIH
13703 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13704 (minus:QI (match_dup 9)
13705 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13706 (clobber (reg:CC FLAGS_REG))])
13707 (parallel
13708 [(set (match_dup 4)
13709 (ashift:DWIH (match_dup 5) (match_dup 2)))
13710 (clobber (reg:CC FLAGS_REG))])]
13711 {
13712 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13713 {
13714 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13715 operands[2] = gen_lowpart (QImode, operands[2]);
13716 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13717 operands[2]));
13718 DONE;
13719 }
13720
13721 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13722
13723 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13724 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13725
13726 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13727 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13728 {
13729 rtx xops[3];
13730 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13731 xops[1] = operands[2];
13732 xops[2] = GEN_INT (INTVAL (operands[3])
13733 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13734 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13735 operands[2] = xops[0];
13736 }
13737
13738 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13739 operands[2] = gen_lowpart (QImode, operands[2]);
13740
13741 if (!rtx_equal_p (operands[6], operands[7]))
13742 emit_move_insn (operands[6], operands[7]);
13743 })
13744
13745 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13746 [(set (match_operand:<DWI> 0 "register_operand")
13747 (ashift:<DWI>
13748 (match_operand:<DWI> 1 "register_operand")
13749 (and:QI
13750 (match_operand:QI 2 "register_operand" "c")
13751 (match_operand:QI 3 "const_int_operand"))))
13752 (clobber (reg:CC FLAGS_REG))]
13753 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13754 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13755 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13756 && ix86_pre_reload_split ()"
13757 "#"
13758 "&& 1"
13759 [(parallel
13760 [(set (match_dup 6)
13761 (ior:DWIH (ashift:DWIH (match_dup 6)
13762 (and:QI (match_dup 2) (match_dup 8)))
13763 (subreg:DWIH
13764 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13765 (minus:QI (match_dup 9)
13766 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13767 (clobber (reg:CC FLAGS_REG))])
13768 (parallel
13769 [(set (match_dup 4)
13770 (ashift:DWIH (match_dup 5) (match_dup 2)))
13771 (clobber (reg:CC FLAGS_REG))])]
13772 {
13773 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13774 {
13775 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13776 operands[2]));
13777 DONE;
13778 }
13779
13780 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13781
13782 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13783 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13784
13785 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13786 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13787 {
13788 rtx tem = gen_reg_rtx (QImode);
13789 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13790 operands[2] = tem;
13791 }
13792
13793 if (!rtx_equal_p (operands[6], operands[7]))
13794 emit_move_insn (operands[6], operands[7]);
13795 })
13796
13797 (define_insn "ashl<mode>3_doubleword"
13798 [(set (match_operand:DWI 0 "register_operand" "=&r")
13799 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13800 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13801 (clobber (reg:CC FLAGS_REG))]
13802 ""
13803 "#"
13804 [(set_attr "type" "multi")])
13805
13806 (define_split
13807 [(set (match_operand:DWI 0 "register_operand")
13808 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13809 (match_operand:QI 2 "nonmemory_operand")))
13810 (clobber (reg:CC FLAGS_REG))]
13811 "epilogue_completed"
13812 [(const_int 0)]
13813 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13814
13815 ;; By default we don't ask for a scratch register, because when DWImode
13816 ;; values are manipulated, registers are already at a premium. But if
13817 ;; we have one handy, we won't turn it away.
13818
13819 (define_peephole2
13820 [(match_scratch:DWIH 3 "r")
13821 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13822 (ashift:<DWI>
13823 (match_operand:<DWI> 1 "nonmemory_operand")
13824 (match_operand:QI 2 "nonmemory_operand")))
13825 (clobber (reg:CC FLAGS_REG))])
13826 (match_dup 3)]
13827 "TARGET_CMOVE"
13828 [(const_int 0)]
13829 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13830
13831 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13832 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13833 (ashift:<DWI>
13834 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13835 (match_operand:QI 2 "const_int_operand")))
13836 (clobber (reg:CC FLAGS_REG))]
13837 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13838 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13839 "#"
13840 "&& reload_completed"
13841 [(const_int 0)]
13842 {
13843 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13844 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13845 if (!rtx_equal_p (operands[3], operands[1]))
13846 emit_move_insn (operands[3], operands[1]);
13847 if (bits > 0)
13848 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13849 ix86_expand_clear (operands[0]);
13850 DONE;
13851 })
13852
13853 (define_insn "x86_64_shld"
13854 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13855 (ior:DI (ashift:DI (match_dup 0)
13856 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13857 (const_int 63)))
13858 (subreg:DI
13859 (lshiftrt:TI
13860 (zero_extend:TI
13861 (match_operand:DI 1 "register_operand" "r"))
13862 (minus:QI (const_int 64)
13863 (and:QI (match_dup 2) (const_int 63)))) 0)))
13864 (clobber (reg:CC FLAGS_REG))]
13865 "TARGET_64BIT"
13866 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13867 [(set_attr "type" "ishift")
13868 (set_attr "prefix_0f" "1")
13869 (set_attr "mode" "DI")
13870 (set_attr "athlon_decode" "vector")
13871 (set_attr "amdfam10_decode" "vector")
13872 (set_attr "bdver1_decode" "vector")])
13873
13874 (define_insn "x86_64_shld_1"
13875 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13876 (ior:DI (ashift:DI (match_dup 0)
13877 (match_operand:QI 2 "const_0_to_63_operand"))
13878 (subreg:DI
13879 (lshiftrt:TI
13880 (zero_extend:TI
13881 (match_operand:DI 1 "register_operand" "r"))
13882 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13883 (clobber (reg:CC FLAGS_REG))]
13884 "TARGET_64BIT
13885 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13886 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13887 [(set_attr "type" "ishift")
13888 (set_attr "prefix_0f" "1")
13889 (set_attr "mode" "DI")
13890 (set_attr "length_immediate" "1")
13891 (set_attr "athlon_decode" "vector")
13892 (set_attr "amdfam10_decode" "vector")
13893 (set_attr "bdver1_decode" "vector")])
13894
13895 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13896 [(set (match_operand:DI 0 "nonimmediate_operand")
13897 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13898 (match_operand:QI 2 "const_0_to_63_operand"))
13899 (lshiftrt:DI
13900 (match_operand:DI 1 "nonimmediate_operand")
13901 (match_operand:QI 3 "const_0_to_63_operand"))))
13902 (clobber (reg:CC FLAGS_REG))]
13903 "TARGET_64BIT
13904 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13905 && ix86_pre_reload_split ()"
13906 "#"
13907 "&& 1"
13908 [(const_int 0)]
13909 {
13910 if (rtx_equal_p (operands[4], operands[0]))
13911 {
13912 operands[1] = force_reg (DImode, operands[1]);
13913 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13914 }
13915 else if (rtx_equal_p (operands[1], operands[0]))
13916 {
13917 operands[4] = force_reg (DImode, operands[4]);
13918 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13919 }
13920 else
13921 {
13922 operands[1] = force_reg (DImode, operands[1]);
13923 rtx tmp = gen_reg_rtx (DImode);
13924 emit_move_insn (tmp, operands[4]);
13925 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13926 emit_move_insn (operands[0], tmp);
13927 }
13928 DONE;
13929 })
13930
13931 (define_insn_and_split "*x86_64_shld_2"
13932 [(set (match_operand:DI 0 "nonimmediate_operand")
13933 (ior:DI (ashift:DI (match_dup 0)
13934 (match_operand:QI 2 "nonmemory_operand"))
13935 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13936 (minus:QI (const_int 64) (match_dup 2)))))
13937 (clobber (reg:CC FLAGS_REG))]
13938 "TARGET_64BIT && ix86_pre_reload_split ()"
13939 "#"
13940 "&& 1"
13941 [(parallel [(set (match_dup 0)
13942 (ior:DI (ashift:DI (match_dup 0)
13943 (and:QI (match_dup 2) (const_int 63)))
13944 (subreg:DI
13945 (lshiftrt:TI
13946 (zero_extend:TI (match_dup 1))
13947 (minus:QI (const_int 64)
13948 (and:QI (match_dup 2)
13949 (const_int 63)))) 0)))
13950 (clobber (reg:CC FLAGS_REG))])])
13951
13952 (define_insn "x86_shld"
13953 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13954 (ior:SI (ashift:SI (match_dup 0)
13955 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13956 (const_int 31)))
13957 (subreg:SI
13958 (lshiftrt:DI
13959 (zero_extend:DI
13960 (match_operand:SI 1 "register_operand" "r"))
13961 (minus:QI (const_int 32)
13962 (and:QI (match_dup 2) (const_int 31)))) 0)))
13963 (clobber (reg:CC FLAGS_REG))]
13964 ""
13965 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13966 [(set_attr "type" "ishift")
13967 (set_attr "prefix_0f" "1")
13968 (set_attr "mode" "SI")
13969 (set_attr "pent_pair" "np")
13970 (set_attr "athlon_decode" "vector")
13971 (set_attr "amdfam10_decode" "vector")
13972 (set_attr "bdver1_decode" "vector")])
13973
13974 (define_insn "x86_shld_1"
13975 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13976 (ior:SI (ashift:SI (match_dup 0)
13977 (match_operand:QI 2 "const_0_to_31_operand"))
13978 (subreg:SI
13979 (lshiftrt:DI
13980 (zero_extend:DI
13981 (match_operand:SI 1 "register_operand" "r"))
13982 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13983 (clobber (reg:CC FLAGS_REG))]
13984 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13985 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13986 [(set_attr "type" "ishift")
13987 (set_attr "prefix_0f" "1")
13988 (set_attr "length_immediate" "1")
13989 (set_attr "mode" "SI")
13990 (set_attr "pent_pair" "np")
13991 (set_attr "athlon_decode" "vector")
13992 (set_attr "amdfam10_decode" "vector")
13993 (set_attr "bdver1_decode" "vector")])
13994
13995 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13996 [(set (match_operand:SI 0 "nonimmediate_operand")
13997 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13998 (match_operand:QI 2 "const_0_to_31_operand"))
13999 (lshiftrt:SI
14000 (match_operand:SI 1 "nonimmediate_operand")
14001 (match_operand:QI 3 "const_0_to_31_operand"))))
14002 (clobber (reg:CC FLAGS_REG))]
14003 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14004 && ix86_pre_reload_split ()"
14005 "#"
14006 "&& 1"
14007 [(const_int 0)]
14008 {
14009 if (rtx_equal_p (operands[4], operands[0]))
14010 {
14011 operands[1] = force_reg (SImode, operands[1]);
14012 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14013 }
14014 else if (rtx_equal_p (operands[1], operands[0]))
14015 {
14016 operands[4] = force_reg (SImode, operands[4]);
14017 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14018 }
14019 else
14020 {
14021 operands[1] = force_reg (SImode, operands[1]);
14022 rtx tmp = gen_reg_rtx (SImode);
14023 emit_move_insn (tmp, operands[4]);
14024 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
14025 emit_move_insn (operands[0], tmp);
14026 }
14027 DONE;
14028 })
14029
14030 (define_insn_and_split "*x86_shld_2"
14031 [(set (match_operand:SI 0 "nonimmediate_operand")
14032 (ior:SI (ashift:SI (match_dup 0)
14033 (match_operand:QI 2 "nonmemory_operand"))
14034 (lshiftrt:SI (match_operand:SI 1 "register_operand")
14035 (minus:QI (const_int 32) (match_dup 2)))))
14036 (clobber (reg:CC FLAGS_REG))]
14037 "TARGET_64BIT && ix86_pre_reload_split ()"
14038 "#"
14039 "&& 1"
14040 [(parallel [(set (match_dup 0)
14041 (ior:SI (ashift:SI (match_dup 0)
14042 (and:QI (match_dup 2) (const_int 31)))
14043 (subreg:SI
14044 (lshiftrt:DI
14045 (zero_extend:DI (match_dup 1))
14046 (minus:QI (const_int 32)
14047 (and:QI (match_dup 2)
14048 (const_int 31)))) 0)))
14049 (clobber (reg:CC FLAGS_REG))])])
14050
14051 (define_expand "@x86_shift<mode>_adj_1"
14052 [(set (reg:CCZ FLAGS_REG)
14053 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
14054 (match_dup 4))
14055 (const_int 0)))
14056 (set (match_operand:SWI48 0 "register_operand")
14057 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14058 (match_operand:SWI48 1 "register_operand")
14059 (match_dup 0)))
14060 (set (match_dup 1)
14061 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14062 (match_operand:SWI48 3 "register_operand")
14063 (match_dup 1)))]
14064 "TARGET_CMOVE"
14065 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
14066
14067 (define_expand "@x86_shift<mode>_adj_2"
14068 [(use (match_operand:SWI48 0 "register_operand"))
14069 (use (match_operand:SWI48 1 "register_operand"))
14070 (use (match_operand:QI 2 "register_operand"))]
14071 ""
14072 {
14073 rtx_code_label *label = gen_label_rtx ();
14074 rtx tmp;
14075
14076 emit_insn (gen_testqi_ccz_1 (operands[2],
14077 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14078
14079 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14080 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14081 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14082 gen_rtx_LABEL_REF (VOIDmode, label),
14083 pc_rtx);
14084 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14085 JUMP_LABEL (tmp) = label;
14086
14087 emit_move_insn (operands[0], operands[1]);
14088 ix86_expand_clear (operands[1]);
14089
14090 emit_label (label);
14091 LABEL_NUSES (label) = 1;
14092
14093 DONE;
14094 })
14095
14096 ;; Avoid useless masking of count operand.
14097 (define_insn_and_split "*ashl<mode>3_mask"
14098 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14099 (ashift:SWI48
14100 (match_operand:SWI48 1 "nonimmediate_operand")
14101 (subreg:QI
14102 (and
14103 (match_operand 2 "int248_register_operand" "c,r")
14104 (match_operand 3 "const_int_operand")) 0)))
14105 (clobber (reg:CC FLAGS_REG))]
14106 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14107 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14108 == GET_MODE_BITSIZE (<MODE>mode)-1
14109 && ix86_pre_reload_split ()"
14110 "#"
14111 "&& 1"
14112 [(parallel
14113 [(set (match_dup 0)
14114 (ashift:SWI48 (match_dup 1)
14115 (match_dup 2)))
14116 (clobber (reg:CC FLAGS_REG))])]
14117 {
14118 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14119 operands[2] = gen_lowpart (QImode, operands[2]);
14120 }
14121 [(set_attr "isa" "*,bmi2")])
14122
14123 (define_insn_and_split "*ashl<mode>3_mask_1"
14124 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14125 (ashift:SWI48
14126 (match_operand:SWI48 1 "nonimmediate_operand")
14127 (and:QI
14128 (match_operand:QI 2 "register_operand" "c,r")
14129 (match_operand:QI 3 "const_int_operand"))))
14130 (clobber (reg:CC FLAGS_REG))]
14131 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14132 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14133 == GET_MODE_BITSIZE (<MODE>mode)-1
14134 && ix86_pre_reload_split ()"
14135 "#"
14136 "&& 1"
14137 [(parallel
14138 [(set (match_dup 0)
14139 (ashift:SWI48 (match_dup 1)
14140 (match_dup 2)))
14141 (clobber (reg:CC FLAGS_REG))])]
14142 ""
14143 [(set_attr "isa" "*,bmi2")])
14144
14145 (define_insn "*bmi2_ashl<mode>3_1"
14146 [(set (match_operand:SWI48 0 "register_operand" "=r")
14147 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14148 (match_operand:SWI48 2 "register_operand" "r")))]
14149 "TARGET_BMI2"
14150 "shlx\t{%2, %1, %0|%0, %1, %2}"
14151 [(set_attr "type" "ishiftx")
14152 (set_attr "mode" "<MODE>")])
14153
14154 (define_insn "*ashl<mode>3_1"
14155 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
14156 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
14157 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
14158 (clobber (reg:CC FLAGS_REG))]
14159 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14160 {
14161 switch (get_attr_type (insn))
14162 {
14163 case TYPE_LEA:
14164 case TYPE_ISHIFTX:
14165 case TYPE_MSKLOG:
14166 return "#";
14167
14168 case TYPE_ALU:
14169 gcc_assert (operands[2] == const1_rtx);
14170 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14171 return "add{<imodesuffix>}\t%0, %0";
14172
14173 default:
14174 if (operands[2] == const1_rtx
14175 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14176 return "sal{<imodesuffix>}\t%0";
14177 else
14178 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14179 }
14180 }
14181 [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14182 (set (attr "type")
14183 (cond [(eq_attr "alternative" "1")
14184 (const_string "lea")
14185 (eq_attr "alternative" "2")
14186 (const_string "ishiftx")
14187 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14188 (match_operand 0 "register_operand"))
14189 (match_operand 2 "const1_operand"))
14190 (const_string "alu")
14191 (eq_attr "alternative" "3")
14192 (const_string "msklog")
14193 ]
14194 (const_string "ishift")))
14195 (set (attr "length_immediate")
14196 (if_then_else
14197 (ior (eq_attr "type" "alu")
14198 (and (eq_attr "type" "ishift")
14199 (and (match_operand 2 "const1_operand")
14200 (ior (match_test "TARGET_SHIFT1")
14201 (match_test "optimize_function_for_size_p (cfun)")))))
14202 (const_string "0")
14203 (const_string "*")))
14204 (set_attr "mode" "<MODE>")])
14205
14206 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14207 (define_split
14208 [(set (match_operand:SWI48 0 "register_operand")
14209 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14210 (match_operand:QI 2 "register_operand")))
14211 (clobber (reg:CC FLAGS_REG))]
14212 "TARGET_BMI2 && reload_completed"
14213 [(set (match_dup 0)
14214 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14215 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14216
14217 (define_insn "*bmi2_ashlsi3_1_zext"
14218 [(set (match_operand:DI 0 "register_operand" "=r")
14219 (zero_extend:DI
14220 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14221 (match_operand:SI 2 "register_operand" "r"))))]
14222 "TARGET_64BIT && TARGET_BMI2"
14223 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14224 [(set_attr "type" "ishiftx")
14225 (set_attr "mode" "SI")])
14226
14227 (define_insn "*ashlsi3_1_zext"
14228 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14229 (zero_extend:DI
14230 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14231 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14232 (clobber (reg:CC FLAGS_REG))]
14233 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14234 {
14235 switch (get_attr_type (insn))
14236 {
14237 case TYPE_LEA:
14238 case TYPE_ISHIFTX:
14239 return "#";
14240
14241 case TYPE_ALU:
14242 gcc_assert (operands[2] == const1_rtx);
14243 return "add{l}\t%k0, %k0";
14244
14245 default:
14246 if (operands[2] == const1_rtx
14247 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14248 return "sal{l}\t%k0";
14249 else
14250 return "sal{l}\t{%2, %k0|%k0, %2}";
14251 }
14252 }
14253 [(set_attr "isa" "*,*,bmi2")
14254 (set (attr "type")
14255 (cond [(eq_attr "alternative" "1")
14256 (const_string "lea")
14257 (eq_attr "alternative" "2")
14258 (const_string "ishiftx")
14259 (and (match_test "TARGET_DOUBLE_WITH_ADD")
14260 (match_operand 2 "const1_operand"))
14261 (const_string "alu")
14262 ]
14263 (const_string "ishift")))
14264 (set (attr "length_immediate")
14265 (if_then_else
14266 (ior (eq_attr "type" "alu")
14267 (and (eq_attr "type" "ishift")
14268 (and (match_operand 2 "const1_operand")
14269 (ior (match_test "TARGET_SHIFT1")
14270 (match_test "optimize_function_for_size_p (cfun)")))))
14271 (const_string "0")
14272 (const_string "*")))
14273 (set_attr "mode" "SI")])
14274
14275 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14276 (define_split
14277 [(set (match_operand:DI 0 "register_operand")
14278 (zero_extend:DI
14279 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14280 (match_operand:QI 2 "register_operand"))))
14281 (clobber (reg:CC FLAGS_REG))]
14282 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14283 [(set (match_dup 0)
14284 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14285 "operands[2] = gen_lowpart (SImode, operands[2]);")
14286
14287 (define_insn "*ashlhi3_1"
14288 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14289 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14290 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14291 (clobber (reg:CC FLAGS_REG))]
14292 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14293 {
14294 switch (get_attr_type (insn))
14295 {
14296 case TYPE_LEA:
14297 case TYPE_MSKLOG:
14298 return "#";
14299
14300 case TYPE_ALU:
14301 gcc_assert (operands[2] == const1_rtx);
14302 return "add{w}\t%0, %0";
14303
14304 default:
14305 if (operands[2] == const1_rtx
14306 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14307 return "sal{w}\t%0";
14308 else
14309 return "sal{w}\t{%2, %0|%0, %2}";
14310 }
14311 }
14312 [(set_attr "isa" "*,*,avx512f")
14313 (set (attr "type")
14314 (cond [(eq_attr "alternative" "1")
14315 (const_string "lea")
14316 (eq_attr "alternative" "2")
14317 (const_string "msklog")
14318 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14319 (match_operand 0 "register_operand"))
14320 (match_operand 2 "const1_operand"))
14321 (const_string "alu")
14322 ]
14323 (const_string "ishift")))
14324 (set (attr "length_immediate")
14325 (if_then_else
14326 (ior (eq_attr "type" "alu")
14327 (and (eq_attr "type" "ishift")
14328 (and (match_operand 2 "const1_operand")
14329 (ior (match_test "TARGET_SHIFT1")
14330 (match_test "optimize_function_for_size_p (cfun)")))))
14331 (const_string "0")
14332 (const_string "*")))
14333 (set_attr "mode" "HI,SI,HI")])
14334
14335 (define_insn "*ashlqi3_1"
14336 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14337 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14338 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14339 (clobber (reg:CC FLAGS_REG))]
14340 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14341 {
14342 switch (get_attr_type (insn))
14343 {
14344 case TYPE_LEA:
14345 case TYPE_MSKLOG:
14346 return "#";
14347
14348 case TYPE_ALU:
14349 gcc_assert (operands[2] == const1_rtx);
14350 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14351 return "add{l}\t%k0, %k0";
14352 else
14353 return "add{b}\t%0, %0";
14354
14355 default:
14356 if (operands[2] == const1_rtx
14357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14358 {
14359 if (get_attr_mode (insn) == MODE_SI)
14360 return "sal{l}\t%k0";
14361 else
14362 return "sal{b}\t%0";
14363 }
14364 else
14365 {
14366 if (get_attr_mode (insn) == MODE_SI)
14367 return "sal{l}\t{%2, %k0|%k0, %2}";
14368 else
14369 return "sal{b}\t{%2, %0|%0, %2}";
14370 }
14371 }
14372 }
14373 [(set_attr "isa" "*,*,*,avx512dq")
14374 (set (attr "type")
14375 (cond [(eq_attr "alternative" "2")
14376 (const_string "lea")
14377 (eq_attr "alternative" "3")
14378 (const_string "msklog")
14379 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14380 (match_operand 0 "register_operand"))
14381 (match_operand 2 "const1_operand"))
14382 (const_string "alu")
14383 ]
14384 (const_string "ishift")))
14385 (set (attr "length_immediate")
14386 (if_then_else
14387 (ior (eq_attr "type" "alu")
14388 (and (eq_attr "type" "ishift")
14389 (and (match_operand 2 "const1_operand")
14390 (ior (match_test "TARGET_SHIFT1")
14391 (match_test "optimize_function_for_size_p (cfun)")))))
14392 (const_string "0")
14393 (const_string "*")))
14394 (set_attr "mode" "QI,SI,SI,QI")
14395 ;; Potential partial reg stall on alternative 1.
14396 (set (attr "preferred_for_speed")
14397 (cond [(eq_attr "alternative" "1")
14398 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14399 (symbol_ref "true")))])
14400
14401 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14402 (define_insn_and_split "*ashl<mode>3_1_slp"
14403 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14404 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14405 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14406 (clobber (reg:CC FLAGS_REG))]
14407 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14408 {
14409 if (which_alternative)
14410 return "#";
14411
14412 switch (get_attr_type (insn))
14413 {
14414 case TYPE_ALU:
14415 gcc_assert (operands[2] == const1_rtx);
14416 return "add{<imodesuffix>}\t%0, %0";
14417
14418 default:
14419 if (operands[2] == const1_rtx
14420 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14421 return "sal{<imodesuffix>}\t%0";
14422 else
14423 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14424 }
14425 }
14426 "&& reload_completed
14427 && !(rtx_equal_p (operands[0], operands[1]))"
14428 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14429 (parallel
14430 [(set (strict_low_part (match_dup 0))
14431 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14432 (clobber (reg:CC FLAGS_REG))])]
14433 ""
14434 [(set (attr "type")
14435 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14436 (match_operand 2 "const1_operand"))
14437 (const_string "alu")
14438 ]
14439 (const_string "ishift")))
14440 (set (attr "length_immediate")
14441 (if_then_else
14442 (ior (eq_attr "type" "alu")
14443 (and (eq_attr "type" "ishift")
14444 (and (match_operand 2 "const1_operand")
14445 (ior (match_test "TARGET_SHIFT1")
14446 (match_test "optimize_function_for_size_p (cfun)")))))
14447 (const_string "0")
14448 (const_string "*")))
14449 (set_attr "mode" "<MODE>")])
14450
14451 ;; Convert ashift to the lea pattern to avoid flags dependency.
14452 (define_split
14453 [(set (match_operand:SWI 0 "general_reg_operand")
14454 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14455 (match_operand 2 "const_0_to_3_operand")))
14456 (clobber (reg:CC FLAGS_REG))]
14457 "reload_completed
14458 && REGNO (operands[0]) != REGNO (operands[1])"
14459 [(set (match_dup 0)
14460 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14461 {
14462 if (<MODE>mode != <LEAMODE>mode)
14463 {
14464 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14465 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14466 }
14467 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14468 })
14469
14470 ;; Convert ashift to the lea pattern to avoid flags dependency.
14471 (define_split
14472 [(set (match_operand:DI 0 "general_reg_operand")
14473 (zero_extend:DI
14474 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14475 (match_operand 2 "const_0_to_3_operand"))))
14476 (clobber (reg:CC FLAGS_REG))]
14477 "TARGET_64BIT && reload_completed
14478 && REGNO (operands[0]) != REGNO (operands[1])"
14479 [(set (match_dup 0)
14480 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14481 {
14482 operands[1] = gen_lowpart (SImode, operands[1]);
14483 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14484 })
14485
14486 ;; This pattern can't accept a variable shift count, since shifts by
14487 ;; zero don't affect the flags. We assume that shifts by constant
14488 ;; zero are optimized away.
14489 (define_insn "*ashl<mode>3_cmp"
14490 [(set (reg FLAGS_REG)
14491 (compare
14492 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14493 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14494 (const_int 0)))
14495 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14496 (ashift:SWI (match_dup 1) (match_dup 2)))]
14497 "(optimize_function_for_size_p (cfun)
14498 || !TARGET_PARTIAL_FLAG_REG_STALL
14499 || (operands[2] == const1_rtx
14500 && (TARGET_SHIFT1
14501 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14502 && ix86_match_ccmode (insn, CCGOCmode)
14503 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14504 {
14505 switch (get_attr_type (insn))
14506 {
14507 case TYPE_ALU:
14508 gcc_assert (operands[2] == const1_rtx);
14509 return "add{<imodesuffix>}\t%0, %0";
14510
14511 default:
14512 if (operands[2] == const1_rtx
14513 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14514 return "sal{<imodesuffix>}\t%0";
14515 else
14516 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14517 }
14518 }
14519 [(set (attr "type")
14520 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14521 (match_operand 0 "register_operand"))
14522 (match_operand 2 "const1_operand"))
14523 (const_string "alu")
14524 ]
14525 (const_string "ishift")))
14526 (set (attr "length_immediate")
14527 (if_then_else
14528 (ior (eq_attr "type" "alu")
14529 (and (eq_attr "type" "ishift")
14530 (and (match_operand 2 "const1_operand")
14531 (ior (match_test "TARGET_SHIFT1")
14532 (match_test "optimize_function_for_size_p (cfun)")))))
14533 (const_string "0")
14534 (const_string "*")))
14535 (set_attr "mode" "<MODE>")])
14536
14537 (define_insn "*ashlsi3_cmp_zext"
14538 [(set (reg FLAGS_REG)
14539 (compare
14540 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14541 (match_operand:QI 2 "const_1_to_31_operand"))
14542 (const_int 0)))
14543 (set (match_operand:DI 0 "register_operand" "=r")
14544 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14545 "TARGET_64BIT
14546 && (optimize_function_for_size_p (cfun)
14547 || !TARGET_PARTIAL_FLAG_REG_STALL
14548 || (operands[2] == const1_rtx
14549 && (TARGET_SHIFT1
14550 || TARGET_DOUBLE_WITH_ADD)))
14551 && ix86_match_ccmode (insn, CCGOCmode)
14552 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14553 {
14554 switch (get_attr_type (insn))
14555 {
14556 case TYPE_ALU:
14557 gcc_assert (operands[2] == const1_rtx);
14558 return "add{l}\t%k0, %k0";
14559
14560 default:
14561 if (operands[2] == const1_rtx
14562 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14563 return "sal{l}\t%k0";
14564 else
14565 return "sal{l}\t{%2, %k0|%k0, %2}";
14566 }
14567 }
14568 [(set (attr "type")
14569 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14570 (match_operand 2 "const1_operand"))
14571 (const_string "alu")
14572 ]
14573 (const_string "ishift")))
14574 (set (attr "length_immediate")
14575 (if_then_else
14576 (ior (eq_attr "type" "alu")
14577 (and (eq_attr "type" "ishift")
14578 (and (match_operand 2 "const1_operand")
14579 (ior (match_test "TARGET_SHIFT1")
14580 (match_test "optimize_function_for_size_p (cfun)")))))
14581 (const_string "0")
14582 (const_string "*")))
14583 (set_attr "mode" "SI")])
14584
14585 (define_insn "*ashl<mode>3_cconly"
14586 [(set (reg FLAGS_REG)
14587 (compare
14588 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14589 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14590 (const_int 0)))
14591 (clobber (match_scratch:SWI 0 "=<r>"))]
14592 "(optimize_function_for_size_p (cfun)
14593 || !TARGET_PARTIAL_FLAG_REG_STALL
14594 || (operands[2] == const1_rtx
14595 && (TARGET_SHIFT1
14596 || TARGET_DOUBLE_WITH_ADD)))
14597 && ix86_match_ccmode (insn, CCGOCmode)"
14598 {
14599 switch (get_attr_type (insn))
14600 {
14601 case TYPE_ALU:
14602 gcc_assert (operands[2] == const1_rtx);
14603 return "add{<imodesuffix>}\t%0, %0";
14604
14605 default:
14606 if (operands[2] == const1_rtx
14607 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14608 return "sal{<imodesuffix>}\t%0";
14609 else
14610 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14611 }
14612 }
14613 [(set (attr "type")
14614 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14615 (match_operand 0 "register_operand"))
14616 (match_operand 2 "const1_operand"))
14617 (const_string "alu")
14618 ]
14619 (const_string "ishift")))
14620 (set (attr "length_immediate")
14621 (if_then_else
14622 (ior (eq_attr "type" "alu")
14623 (and (eq_attr "type" "ishift")
14624 (and (match_operand 2 "const1_operand")
14625 (ior (match_test "TARGET_SHIFT1")
14626 (match_test "optimize_function_for_size_p (cfun)")))))
14627 (const_string "0")
14628 (const_string "*")))
14629 (set_attr "mode" "<MODE>")])
14630
14631 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14632 (define_insn_and_split "*ashlqi_ext<mode>_1"
14633 [(set (zero_extract:SWI248
14634 (match_operand 0 "int248_register_operand" "+Q,&Q")
14635 (const_int 8)
14636 (const_int 8))
14637 (subreg:SWI248
14638 (ashift:QI
14639 (subreg:QI
14640 (match_operator:SWI248 3 "extract_operator"
14641 [(match_operand 1 "int248_register_operand" "0,!Q")
14642 (const_int 8)
14643 (const_int 8)]) 0)
14644 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
14645 (clobber (reg:CC FLAGS_REG))]
14646 ""
14647 {
14648 if (which_alternative)
14649 return "#";
14650
14651 switch (get_attr_type (insn))
14652 {
14653 case TYPE_ALU:
14654 gcc_assert (operands[2] == const1_rtx);
14655 return "add{b}\t%h0, %h0";
14656
14657 default:
14658 if (operands[2] == const1_rtx
14659 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14660 return "sal{b}\t%h0";
14661 else
14662 return "sal{b}\t{%2, %h0|%h0, %2}";
14663 }
14664 }
14665 "reload_completed
14666 && !(rtx_equal_p (operands[0], operands[1]))"
14667 [(set (zero_extract:SWI248
14668 (match_dup 0) (const_int 8) (const_int 8))
14669 (match_dup 1))
14670 (parallel
14671 [(set (zero_extract:SWI248
14672 (match_dup 0) (const_int 8) (const_int 8))
14673 (subreg:SWI248
14674 (ashift:QI
14675 (subreg:QI
14676 (match_op_dup 3
14677 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
14678 (match_dup 2)) 0))
14679 (clobber (reg:CC FLAGS_REG))])]
14680 ""
14681 [(set (attr "type")
14682 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14683 (match_operand 2 "const1_operand"))
14684 (const_string "alu")
14685 ]
14686 (const_string "ishift")))
14687 (set (attr "length_immediate")
14688 (if_then_else
14689 (ior (eq_attr "type" "alu")
14690 (and (eq_attr "type" "ishift")
14691 (and (match_operand 2 "const1_operand")
14692 (ior (match_test "TARGET_SHIFT1")
14693 (match_test "optimize_function_for_size_p (cfun)")))))
14694 (const_string "0")
14695 (const_string "*")))
14696 (set_attr "mode" "QI")])
14697
14698 ;; See comment above `ashl<mode>3' about how this works.
14699
14700 (define_expand "<insn><mode>3"
14701 [(set (match_operand:SDWIM 0 "<shift_operand>")
14702 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14703 (match_operand:QI 2 "nonmemory_operand")))]
14704 ""
14705 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14706
14707 ;; Avoid useless masking of count operand.
14708 (define_insn_and_split "*<insn><mode>3_mask"
14709 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14710 (any_shiftrt:SWI48
14711 (match_operand:SWI48 1 "nonimmediate_operand")
14712 (subreg:QI
14713 (and
14714 (match_operand 2 "int248_register_operand" "c,r")
14715 (match_operand 3 "const_int_operand")) 0)))
14716 (clobber (reg:CC FLAGS_REG))]
14717 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14718 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14719 == GET_MODE_BITSIZE (<MODE>mode)-1
14720 && ix86_pre_reload_split ()"
14721 "#"
14722 "&& 1"
14723 [(parallel
14724 [(set (match_dup 0)
14725 (any_shiftrt:SWI48 (match_dup 1)
14726 (match_dup 2)))
14727 (clobber (reg:CC FLAGS_REG))])]
14728 {
14729 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14730 operands[2] = gen_lowpart (QImode, operands[2]);
14731 }
14732 [(set_attr "isa" "*,bmi2")])
14733
14734 (define_insn_and_split "*<insn><mode>3_mask_1"
14735 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14736 (any_shiftrt:SWI48
14737 (match_operand:SWI48 1 "nonimmediate_operand")
14738 (and:QI
14739 (match_operand:QI 2 "register_operand" "c,r")
14740 (match_operand:QI 3 "const_int_operand"))))
14741 (clobber (reg:CC FLAGS_REG))]
14742 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14743 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14744 == GET_MODE_BITSIZE (<MODE>mode)-1
14745 && ix86_pre_reload_split ()"
14746 "#"
14747 "&& 1"
14748 [(parallel
14749 [(set (match_dup 0)
14750 (any_shiftrt:SWI48 (match_dup 1)
14751 (match_dup 2)))
14752 (clobber (reg:CC FLAGS_REG))])]
14753 ""
14754 [(set_attr "isa" "*,bmi2")])
14755
14756 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14757 [(set (match_operand:<DWI> 0 "register_operand")
14758 (any_shiftrt:<DWI>
14759 (match_operand:<DWI> 1 "register_operand")
14760 (subreg:QI
14761 (and
14762 (match_operand 2 "int248_register_operand" "c")
14763 (match_operand 3 "const_int_operand")) 0)))
14764 (clobber (reg:CC FLAGS_REG))]
14765 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14766 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14767 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14768 && ix86_pre_reload_split ()"
14769 "#"
14770 "&& 1"
14771 [(parallel
14772 [(set (match_dup 4)
14773 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14774 (and:QI (match_dup 2) (match_dup 8)))
14775 (subreg:DWIH
14776 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14777 (minus:QI (match_dup 9)
14778 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14779 (clobber (reg:CC FLAGS_REG))])
14780 (parallel
14781 [(set (match_dup 6)
14782 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14783 (clobber (reg:CC FLAGS_REG))])]
14784 {
14785 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14786 {
14787 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14788 operands[2] = gen_lowpart (QImode, operands[2]);
14789 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14790 operands[2]));
14791 DONE;
14792 }
14793
14794 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14795
14796 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14797 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14798
14799 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14800 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14801 {
14802 rtx xops[3];
14803 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14804 xops[1] = operands[2];
14805 xops[2] = GEN_INT (INTVAL (operands[3])
14806 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14807 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14808 operands[2] = xops[0];
14809 }
14810
14811 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14812 operands[2] = gen_lowpart (QImode, operands[2]);
14813
14814 if (!rtx_equal_p (operands[4], operands[5]))
14815 emit_move_insn (operands[4], operands[5]);
14816 })
14817
14818 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14819 [(set (match_operand:<DWI> 0 "register_operand")
14820 (any_shiftrt:<DWI>
14821 (match_operand:<DWI> 1 "register_operand")
14822 (and:QI
14823 (match_operand:QI 2 "register_operand" "c")
14824 (match_operand:QI 3 "const_int_operand"))))
14825 (clobber (reg:CC FLAGS_REG))]
14826 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14827 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14828 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14829 && ix86_pre_reload_split ()"
14830 "#"
14831 "&& 1"
14832 [(parallel
14833 [(set (match_dup 4)
14834 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14835 (and:QI (match_dup 2) (match_dup 8)))
14836 (subreg:DWIH
14837 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14838 (minus:QI (match_dup 9)
14839 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14840 (clobber (reg:CC FLAGS_REG))])
14841 (parallel
14842 [(set (match_dup 6)
14843 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14844 (clobber (reg:CC FLAGS_REG))])]
14845 {
14846 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14847 {
14848 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14849 operands[2]));
14850 DONE;
14851 }
14852
14853 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14854
14855 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14856 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14857
14858 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14859 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14860 {
14861 rtx tem = gen_reg_rtx (QImode);
14862 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14863 operands[2] = tem;
14864 }
14865
14866 if (!rtx_equal_p (operands[4], operands[5]))
14867 emit_move_insn (operands[4], operands[5]);
14868 })
14869
14870 (define_insn_and_split "<insn><mode>3_doubleword"
14871 [(set (match_operand:DWI 0 "register_operand" "=&r")
14872 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14873 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14874 (clobber (reg:CC FLAGS_REG))]
14875 ""
14876 "#"
14877 "epilogue_completed"
14878 [(const_int 0)]
14879 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14880 [(set_attr "type" "multi")])
14881
14882 ;; By default we don't ask for a scratch register, because when DWImode
14883 ;; values are manipulated, registers are already at a premium. But if
14884 ;; we have one handy, we won't turn it away.
14885
14886 (define_peephole2
14887 [(match_scratch:DWIH 3 "r")
14888 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14889 (any_shiftrt:<DWI>
14890 (match_operand:<DWI> 1 "register_operand")
14891 (match_operand:QI 2 "nonmemory_operand")))
14892 (clobber (reg:CC FLAGS_REG))])
14893 (match_dup 3)]
14894 "TARGET_CMOVE"
14895 [(const_int 0)]
14896 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14897
14898 ;; Split truncations of double word right shifts into x86_shrd_1.
14899 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
14900 [(set (match_operand:DWIH 0 "register_operand" "=&r")
14901 (subreg:DWIH
14902 (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
14903 (match_operand:QI 2 "const_int_operand")) 0))
14904 (clobber (reg:CC FLAGS_REG))]
14905 "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
14906 "#"
14907 "&& reload_completed"
14908 [(parallel
14909 [(set (match_dup 0)
14910 (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
14911 (subreg:DWIH
14912 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
14913 (match_dup 4)) 0)))
14914 (clobber (reg:CC FLAGS_REG))])]
14915 {
14916 split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
14917 operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
14918 if (!rtx_equal_p (operands[0], operands[1]))
14919 emit_move_insn (operands[0], operands[1]);
14920 })
14921
14922 (define_insn "x86_64_shrd"
14923 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14924 (ior:DI (lshiftrt:DI (match_dup 0)
14925 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14926 (const_int 63)))
14927 (subreg:DI
14928 (ashift:TI
14929 (zero_extend:TI
14930 (match_operand:DI 1 "register_operand" "r"))
14931 (minus:QI (const_int 64)
14932 (and:QI (match_dup 2) (const_int 63)))) 0)))
14933 (clobber (reg:CC FLAGS_REG))]
14934 "TARGET_64BIT"
14935 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14936 [(set_attr "type" "ishift")
14937 (set_attr "prefix_0f" "1")
14938 (set_attr "mode" "DI")
14939 (set_attr "athlon_decode" "vector")
14940 (set_attr "amdfam10_decode" "vector")
14941 (set_attr "bdver1_decode" "vector")])
14942
14943 (define_insn "x86_64_shrd_1"
14944 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14945 (ior:DI (lshiftrt:DI (match_dup 0)
14946 (match_operand:QI 2 "const_0_to_63_operand"))
14947 (subreg:DI
14948 (ashift:TI
14949 (zero_extend:TI
14950 (match_operand:DI 1 "register_operand" "r"))
14951 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14952 (clobber (reg:CC FLAGS_REG))]
14953 "TARGET_64BIT
14954 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14955 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14956 [(set_attr "type" "ishift")
14957 (set_attr "prefix_0f" "1")
14958 (set_attr "length_immediate" "1")
14959 (set_attr "mode" "DI")
14960 (set_attr "athlon_decode" "vector")
14961 (set_attr "amdfam10_decode" "vector")
14962 (set_attr "bdver1_decode" "vector")])
14963
14964 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14965 [(set (match_operand:DI 0 "nonimmediate_operand")
14966 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14967 (match_operand:QI 2 "const_0_to_63_operand"))
14968 (ashift:DI
14969 (match_operand:DI 1 "nonimmediate_operand")
14970 (match_operand:QI 3 "const_0_to_63_operand"))))
14971 (clobber (reg:CC FLAGS_REG))]
14972 "TARGET_64BIT
14973 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14974 && ix86_pre_reload_split ()"
14975 "#"
14976 "&& 1"
14977 [(const_int 0)]
14978 {
14979 if (rtx_equal_p (operands[4], operands[0]))
14980 {
14981 operands[1] = force_reg (DImode, operands[1]);
14982 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14983 }
14984 else if (rtx_equal_p (operands[1], operands[0]))
14985 {
14986 operands[4] = force_reg (DImode, operands[4]);
14987 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14988 }
14989 else
14990 {
14991 operands[1] = force_reg (DImode, operands[1]);
14992 rtx tmp = gen_reg_rtx (DImode);
14993 emit_move_insn (tmp, operands[4]);
14994 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14995 emit_move_insn (operands[0], tmp);
14996 }
14997 DONE;
14998 })
14999
15000 (define_insn_and_split "*x86_64_shrd_2"
15001 [(set (match_operand:DI 0 "nonimmediate_operand")
15002 (ior:DI (lshiftrt:DI (match_dup 0)
15003 (match_operand:QI 2 "nonmemory_operand"))
15004 (ashift:DI (match_operand:DI 1 "register_operand")
15005 (minus:QI (const_int 64) (match_dup 2)))))
15006 (clobber (reg:CC FLAGS_REG))]
15007 "TARGET_64BIT && ix86_pre_reload_split ()"
15008 "#"
15009 "&& 1"
15010 [(parallel [(set (match_dup 0)
15011 (ior:DI (lshiftrt:DI (match_dup 0)
15012 (and:QI (match_dup 2) (const_int 63)))
15013 (subreg:DI
15014 (ashift:TI
15015 (zero_extend:TI (match_dup 1))
15016 (minus:QI (const_int 64)
15017 (and:QI (match_dup 2)
15018 (const_int 63)))) 0)))
15019 (clobber (reg:CC FLAGS_REG))])])
15020
15021 (define_insn "x86_shrd"
15022 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15023 (ior:SI (lshiftrt:SI (match_dup 0)
15024 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
15025 (const_int 31)))
15026 (subreg:SI
15027 (ashift:DI
15028 (zero_extend:DI
15029 (match_operand:SI 1 "register_operand" "r"))
15030 (minus:QI (const_int 32)
15031 (and:QI (match_dup 2) (const_int 31)))) 0)))
15032 (clobber (reg:CC FLAGS_REG))]
15033 ""
15034 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
15035 [(set_attr "type" "ishift")
15036 (set_attr "prefix_0f" "1")
15037 (set_attr "mode" "SI")
15038 (set_attr "pent_pair" "np")
15039 (set_attr "athlon_decode" "vector")
15040 (set_attr "amdfam10_decode" "vector")
15041 (set_attr "bdver1_decode" "vector")])
15042
15043 (define_insn "x86_shrd_1"
15044 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15045 (ior:SI (lshiftrt:SI (match_dup 0)
15046 (match_operand:QI 2 "const_0_to_31_operand"))
15047 (subreg:SI
15048 (ashift:DI
15049 (zero_extend:DI
15050 (match_operand:SI 1 "register_operand" "r"))
15051 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
15052 (clobber (reg:CC FLAGS_REG))]
15053 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
15054 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
15055 [(set_attr "type" "ishift")
15056 (set_attr "prefix_0f" "1")
15057 (set_attr "length_immediate" "1")
15058 (set_attr "mode" "SI")
15059 (set_attr "pent_pair" "np")
15060 (set_attr "athlon_decode" "vector")
15061 (set_attr "amdfam10_decode" "vector")
15062 (set_attr "bdver1_decode" "vector")])
15063
15064 (define_insn_and_split "*x86_shrd_shld_1_nozext"
15065 [(set (match_operand:SI 0 "nonimmediate_operand")
15066 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
15067 (match_operand:QI 2 "const_0_to_31_operand"))
15068 (ashift:SI
15069 (match_operand:SI 1 "nonimmediate_operand")
15070 (match_operand:QI 3 "const_0_to_31_operand"))))
15071 (clobber (reg:CC FLAGS_REG))]
15072 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15073 && ix86_pre_reload_split ()"
15074 "#"
15075 "&& 1"
15076 [(const_int 0)]
15077 {
15078 if (rtx_equal_p (operands[4], operands[0]))
15079 {
15080 operands[1] = force_reg (SImode, operands[1]);
15081 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
15082 }
15083 else if (rtx_equal_p (operands[1], operands[0]))
15084 {
15085 operands[4] = force_reg (SImode, operands[4]);
15086 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15087 }
15088 else
15089 {
15090 operands[1] = force_reg (SImode, operands[1]);
15091 rtx tmp = gen_reg_rtx (SImode);
15092 emit_move_insn (tmp, operands[4]);
15093 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15094 emit_move_insn (operands[0], tmp);
15095 }
15096 DONE;
15097 })
15098
15099 (define_insn_and_split "*x86_shrd_2"
15100 [(set (match_operand:SI 0 "nonimmediate_operand")
15101 (ior:SI (lshiftrt:SI (match_dup 0)
15102 (match_operand:QI 2 "nonmemory_operand"))
15103 (ashift:SI (match_operand:SI 1 "register_operand")
15104 (minus:QI (const_int 32) (match_dup 2)))))
15105 (clobber (reg:CC FLAGS_REG))]
15106 "TARGET_64BIT && ix86_pre_reload_split ()"
15107 "#"
15108 "&& 1"
15109 [(parallel [(set (match_dup 0)
15110 (ior:SI (lshiftrt:SI (match_dup 0)
15111 (and:QI (match_dup 2) (const_int 31)))
15112 (subreg:SI
15113 (ashift:DI
15114 (zero_extend:DI (match_dup 1))
15115 (minus:QI (const_int 32)
15116 (and:QI (match_dup 2)
15117 (const_int 31)))) 0)))
15118 (clobber (reg:CC FLAGS_REG))])])
15119
15120 ;; Base name for insn mnemonic.
15121 (define_mode_attr cvt_mnemonic
15122 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
15123
15124 (define_insn "ashr<mode>3_cvt"
15125 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
15126 (ashiftrt:SWI48
15127 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
15128 (match_operand:QI 2 "const_int_operand")))
15129 (clobber (reg:CC FLAGS_REG))]
15130 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
15131 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15132 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15133 "@
15134 <cvt_mnemonic>
15135 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
15136 [(set_attr "type" "imovx,ishift")
15137 (set_attr "prefix_0f" "0,*")
15138 (set_attr "length_immediate" "0,*")
15139 (set_attr "modrm" "0,1")
15140 (set_attr "mode" "<MODE>")])
15141
15142 (define_insn "*ashrsi3_cvt_zext"
15143 [(set (match_operand:DI 0 "register_operand" "=*d,r")
15144 (zero_extend:DI
15145 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
15146 (match_operand:QI 2 "const_int_operand"))))
15147 (clobber (reg:CC FLAGS_REG))]
15148 "TARGET_64BIT && INTVAL (operands[2]) == 31
15149 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15150 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
15151 "@
15152 {cltd|cdq}
15153 sar{l}\t{%2, %k0|%k0, %2}"
15154 [(set_attr "type" "imovx,ishift")
15155 (set_attr "prefix_0f" "0,*")
15156 (set_attr "length_immediate" "0,*")
15157 (set_attr "modrm" "0,1")
15158 (set_attr "mode" "SI")])
15159
15160 (define_expand "@x86_shift<mode>_adj_3"
15161 [(use (match_operand:SWI48 0 "register_operand"))
15162 (use (match_operand:SWI48 1 "register_operand"))
15163 (use (match_operand:QI 2 "register_operand"))]
15164 ""
15165 {
15166 rtx_code_label *label = gen_label_rtx ();
15167 rtx tmp;
15168
15169 emit_insn (gen_testqi_ccz_1 (operands[2],
15170 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15171
15172 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15173 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15174 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15175 gen_rtx_LABEL_REF (VOIDmode, label),
15176 pc_rtx);
15177 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15178 JUMP_LABEL (tmp) = label;
15179
15180 emit_move_insn (operands[0], operands[1]);
15181 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
15182 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
15183 emit_label (label);
15184 LABEL_NUSES (label) = 1;
15185
15186 DONE;
15187 })
15188
15189 (define_insn "*bmi2_<insn><mode>3_1"
15190 [(set (match_operand:SWI48 0 "register_operand" "=r")
15191 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15192 (match_operand:SWI48 2 "register_operand" "r")))]
15193 "TARGET_BMI2"
15194 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
15195 [(set_attr "type" "ishiftx")
15196 (set_attr "mode" "<MODE>")])
15197
15198 (define_insn "*ashr<mode>3_1"
15199 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15200 (ashiftrt:SWI48
15201 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15202 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
15203 (clobber (reg:CC FLAGS_REG))]
15204 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15205 {
15206 switch (get_attr_type (insn))
15207 {
15208 case TYPE_ISHIFTX:
15209 return "#";
15210
15211 default:
15212 if (operands[2] == const1_rtx
15213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15214 return "sar{<imodesuffix>}\t%0";
15215 else
15216 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15217 }
15218 }
15219 [(set_attr "isa" "*,bmi2")
15220 (set_attr "type" "ishift,ishiftx")
15221 (set (attr "length_immediate")
15222 (if_then_else
15223 (and (match_operand 2 "const1_operand")
15224 (ior (match_test "TARGET_SHIFT1")
15225 (match_test "optimize_function_for_size_p (cfun)")))
15226 (const_string "0")
15227 (const_string "*")))
15228 (set_attr "mode" "<MODE>")])
15229
15230 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15231 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15232 (define_insn_and_split "*highpartdisi2"
15233 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15234 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15235 (const_int 32)))
15236 (clobber (reg:CC FLAGS_REG))]
15237 "TARGET_64BIT"
15238 "#"
15239 "&& reload_completed"
15240 [(parallel
15241 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15242 (clobber (reg:CC FLAGS_REG))])]
15243 {
15244 if (SSE_REG_P (operands[0]))
15245 {
15246 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15247 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15248 const1_rtx, const1_rtx,
15249 GEN_INT (5), GEN_INT (5)));
15250 DONE;
15251 }
15252 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15253 })
15254
15255 (define_insn "*lshr<mode>3_1"
15256 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15257 (lshiftrt:SWI48
15258 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15259 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15260 (clobber (reg:CC FLAGS_REG))]
15261 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15262 {
15263 switch (get_attr_type (insn))
15264 {
15265 case TYPE_ISHIFTX:
15266 case TYPE_MSKLOG:
15267 return "#";
15268
15269 default:
15270 if (operands[2] == const1_rtx
15271 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15272 return "shr{<imodesuffix>}\t%0";
15273 else
15274 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15275 }
15276 }
15277 [(set_attr "isa" "*,bmi2,<kmov_isa>")
15278 (set_attr "type" "ishift,ishiftx,msklog")
15279 (set (attr "length_immediate")
15280 (if_then_else
15281 (and (and (match_operand 2 "const1_operand")
15282 (eq_attr "alternative" "0"))
15283 (ior (match_test "TARGET_SHIFT1")
15284 (match_test "optimize_function_for_size_p (cfun)")))
15285 (const_string "0")
15286 (const_string "*")))
15287 (set_attr "mode" "<MODE>")])
15288
15289 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15290 (define_split
15291 [(set (match_operand:SWI48 0 "register_operand")
15292 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15293 (match_operand:QI 2 "register_operand")))
15294 (clobber (reg:CC FLAGS_REG))]
15295 "TARGET_BMI2 && reload_completed"
15296 [(set (match_dup 0)
15297 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15298 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15299
15300 (define_insn "*bmi2_<insn>si3_1_zext"
15301 [(set (match_operand:DI 0 "register_operand" "=r")
15302 (zero_extend:DI
15303 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15304 (match_operand:SI 2 "register_operand" "r"))))]
15305 "TARGET_64BIT && TARGET_BMI2"
15306 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15307 [(set_attr "type" "ishiftx")
15308 (set_attr "mode" "SI")])
15309
15310 (define_insn "*<insn>si3_1_zext"
15311 [(set (match_operand:DI 0 "register_operand" "=r,r")
15312 (zero_extend:DI
15313 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15314 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15315 (clobber (reg:CC FLAGS_REG))]
15316 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15317 {
15318 switch (get_attr_type (insn))
15319 {
15320 case TYPE_ISHIFTX:
15321 return "#";
15322
15323 default:
15324 if (operands[2] == const1_rtx
15325 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15326 return "<shift>{l}\t%k0";
15327 else
15328 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15329 }
15330 }
15331 [(set_attr "isa" "*,bmi2")
15332 (set_attr "type" "ishift,ishiftx")
15333 (set (attr "length_immediate")
15334 (if_then_else
15335 (and (match_operand 2 "const1_operand")
15336 (ior (match_test "TARGET_SHIFT1")
15337 (match_test "optimize_function_for_size_p (cfun)")))
15338 (const_string "0")
15339 (const_string "*")))
15340 (set_attr "mode" "SI")])
15341
15342 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15343 (define_split
15344 [(set (match_operand:DI 0 "register_operand")
15345 (zero_extend:DI
15346 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15347 (match_operand:QI 2 "register_operand"))))
15348 (clobber (reg:CC FLAGS_REG))]
15349 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15350 [(set (match_dup 0)
15351 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15352 "operands[2] = gen_lowpart (SImode, operands[2]);")
15353
15354 (define_insn "*ashr<mode>3_1"
15355 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15356 (ashiftrt:SWI12
15357 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15358 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15359 (clobber (reg:CC FLAGS_REG))]
15360 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15361 {
15362 if (operands[2] == const1_rtx
15363 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15364 return "sar{<imodesuffix>}\t%0";
15365 else
15366 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15367 }
15368 [(set_attr "type" "ishift")
15369 (set (attr "length_immediate")
15370 (if_then_else
15371 (and (match_operand 2 "const1_operand")
15372 (ior (match_test "TARGET_SHIFT1")
15373 (match_test "optimize_function_for_size_p (cfun)")))
15374 (const_string "0")
15375 (const_string "*")))
15376 (set_attr "mode" "<MODE>")])
15377
15378 (define_insn "*lshrqi3_1"
15379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15380 (lshiftrt:QI
15381 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15382 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15383 (clobber (reg:CC FLAGS_REG))]
15384 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15385 {
15386 switch (get_attr_type (insn))
15387 {
15388 case TYPE_ISHIFT:
15389 if (operands[2] == const1_rtx
15390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15391 return "shr{b}\t%0";
15392 else
15393 return "shr{b}\t{%2, %0|%0, %2}";
15394 case TYPE_MSKLOG:
15395 return "#";
15396 default:
15397 gcc_unreachable ();
15398 }
15399 }
15400 [(set_attr "isa" "*,avx512dq")
15401 (set_attr "type" "ishift,msklog")
15402 (set (attr "length_immediate")
15403 (if_then_else
15404 (and (and (match_operand 2 "const1_operand")
15405 (eq_attr "alternative" "0"))
15406 (ior (match_test "TARGET_SHIFT1")
15407 (match_test "optimize_function_for_size_p (cfun)")))
15408 (const_string "0")
15409 (const_string "*")))
15410 (set_attr "mode" "QI")])
15411
15412 (define_insn "*lshrhi3_1"
15413 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15414 (lshiftrt:HI
15415 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15416 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15417 (clobber (reg:CC FLAGS_REG))]
15418 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15419 {
15420 switch (get_attr_type (insn))
15421 {
15422 case TYPE_ISHIFT:
15423 if (operands[2] == const1_rtx
15424 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15425 return "shr{w}\t%0";
15426 else
15427 return "shr{w}\t{%2, %0|%0, %2}";
15428 case TYPE_MSKLOG:
15429 return "#";
15430 default:
15431 gcc_unreachable ();
15432 }
15433 }
15434 [(set_attr "isa" "*, avx512f")
15435 (set_attr "type" "ishift,msklog")
15436 (set (attr "length_immediate")
15437 (if_then_else
15438 (and (and (match_operand 2 "const1_operand")
15439 (eq_attr "alternative" "0"))
15440 (ior (match_test "TARGET_SHIFT1")
15441 (match_test "optimize_function_for_size_p (cfun)")))
15442 (const_string "0")
15443 (const_string "*")))
15444 (set_attr "mode" "HI")])
15445
15446 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15447 (define_insn_and_split "*<insn><mode>3_1_slp"
15448 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15449 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15450 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15451 (clobber (reg:CC FLAGS_REG))]
15452 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15453 {
15454 if (which_alternative)
15455 return "#";
15456
15457 if (operands[2] == const1_rtx
15458 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15459 return "<shift>{<imodesuffix>}\t%0";
15460 else
15461 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15462 }
15463 "&& reload_completed
15464 && !(rtx_equal_p (operands[0], operands[1]))"
15465 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15466 (parallel
15467 [(set (strict_low_part (match_dup 0))
15468 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15469 (clobber (reg:CC FLAGS_REG))])]
15470 ""
15471 [(set_attr "type" "ishift")
15472 (set (attr "length_immediate")
15473 (if_then_else
15474 (and (match_operand 2 "const1_operand")
15475 (ior (match_test "TARGET_SHIFT1")
15476 (match_test "optimize_function_for_size_p (cfun)")))
15477 (const_string "0")
15478 (const_string "*")))
15479 (set_attr "mode" "<MODE>")])
15480
15481 ;; This pattern can't accept a variable shift count, since shifts by
15482 ;; zero don't affect the flags. We assume that shifts by constant
15483 ;; zero are optimized away.
15484 (define_insn "*<insn><mode>3_cmp"
15485 [(set (reg FLAGS_REG)
15486 (compare
15487 (any_shiftrt:SWI
15488 (match_operand:SWI 1 "nonimmediate_operand" "0")
15489 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15490 (const_int 0)))
15491 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15492 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15493 "(optimize_function_for_size_p (cfun)
15494 || !TARGET_PARTIAL_FLAG_REG_STALL
15495 || (operands[2] == const1_rtx
15496 && TARGET_SHIFT1))
15497 && ix86_match_ccmode (insn, CCGOCmode)
15498 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15499 {
15500 if (operands[2] == const1_rtx
15501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15502 return "<shift>{<imodesuffix>}\t%0";
15503 else
15504 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15505 }
15506 [(set_attr "type" "ishift")
15507 (set (attr "length_immediate")
15508 (if_then_else
15509 (and (match_operand 2 "const1_operand")
15510 (ior (match_test "TARGET_SHIFT1")
15511 (match_test "optimize_function_for_size_p (cfun)")))
15512 (const_string "0")
15513 (const_string "*")))
15514 (set_attr "mode" "<MODE>")])
15515
15516 (define_insn "*<insn>si3_cmp_zext"
15517 [(set (reg FLAGS_REG)
15518 (compare
15519 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15520 (match_operand:QI 2 "const_1_to_31_operand"))
15521 (const_int 0)))
15522 (set (match_operand:DI 0 "register_operand" "=r")
15523 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15524 "TARGET_64BIT
15525 && (optimize_function_for_size_p (cfun)
15526 || !TARGET_PARTIAL_FLAG_REG_STALL
15527 || (operands[2] == const1_rtx
15528 && TARGET_SHIFT1))
15529 && ix86_match_ccmode (insn, CCGOCmode)
15530 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15531 {
15532 if (operands[2] == const1_rtx
15533 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15534 return "<shift>{l}\t%k0";
15535 else
15536 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15537 }
15538 [(set_attr "type" "ishift")
15539 (set (attr "length_immediate")
15540 (if_then_else
15541 (and (match_operand 2 "const1_operand")
15542 (ior (match_test "TARGET_SHIFT1")
15543 (match_test "optimize_function_for_size_p (cfun)")))
15544 (const_string "0")
15545 (const_string "*")))
15546 (set_attr "mode" "SI")])
15547
15548 (define_insn "*<insn><mode>3_cconly"
15549 [(set (reg FLAGS_REG)
15550 (compare
15551 (any_shiftrt:SWI
15552 (match_operand:SWI 1 "register_operand" "0")
15553 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15554 (const_int 0)))
15555 (clobber (match_scratch:SWI 0 "=<r>"))]
15556 "(optimize_function_for_size_p (cfun)
15557 || !TARGET_PARTIAL_FLAG_REG_STALL
15558 || (operands[2] == const1_rtx
15559 && TARGET_SHIFT1))
15560 && ix86_match_ccmode (insn, CCGOCmode)"
15561 {
15562 if (operands[2] == const1_rtx
15563 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15564 return "<shift>{<imodesuffix>}\t%0";
15565 else
15566 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15567 }
15568 [(set_attr "type" "ishift")
15569 (set (attr "length_immediate")
15570 (if_then_else
15571 (and (match_operand 2 "const1_operand")
15572 (ior (match_test "TARGET_SHIFT1")
15573 (match_test "optimize_function_for_size_p (cfun)")))
15574 (const_string "0")
15575 (const_string "*")))
15576 (set_attr "mode" "<MODE>")])
15577
15578 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15579 (define_insn_and_split "*<insn>qi_ext<mode>_1"
15580 [(set (zero_extract:SWI248
15581 (match_operand 0 "int248_register_operand" "+Q,&Q")
15582 (const_int 8)
15583 (const_int 8))
15584 (subreg:SWI248
15585 (any_shiftrt:QI
15586 (subreg:QI
15587 (match_operator:SWI248 3 "extract_operator"
15588 [(match_operand 1 "int248_register_operand" "0,!Q")
15589 (const_int 8)
15590 (const_int 8)]) 0)
15591 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
15592 (clobber (reg:CC FLAGS_REG))]
15593 ""
15594 {
15595 if (which_alternative)
15596 return "#";
15597
15598 if (operands[2] == const1_rtx
15599 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15600 return "<shift>{b}\t%h0";
15601 else
15602 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15603 }
15604 "reload_completed
15605 && !(rtx_equal_p (operands[0], operands[1]))"
15606 [(set (zero_extract:SWI248
15607 (match_dup 0) (const_int 8) (const_int 8))
15608 (match_dup 1))
15609 (parallel
15610 [(set (zero_extract:SWI248
15611 (match_dup 0) (const_int 8) (const_int 8))
15612 (subreg:SWI248
15613 (any_shiftrt:QI
15614 (subreg:QI
15615 (match_op_dup 3
15616 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
15617 (match_dup 2)) 0))
15618 (clobber (reg:CC FLAGS_REG))])]
15619 ""
15620 [(set_attr "type" "ishift")
15621 (set (attr "length_immediate")
15622 (if_then_else
15623 (and (match_operand 2 "const1_operand")
15624 (ior (match_test "TARGET_SHIFT1")
15625 (match_test "optimize_function_for_size_p (cfun)")))
15626 (const_string "0")
15627 (const_string "*")))
15628 (set_attr "mode" "QI")])
15629
15630 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15631 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15632 (ashiftrt:<DWI>
15633 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15634 (match_operand:QI 2 "const_int_operand"))
15635 (match_operand:QI 3 "const_int_operand")))
15636 (clobber (reg:CC FLAGS_REG))]
15637 "INTVAL (operands[2]) == INTVAL (operands[3])
15638 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15639 "#"
15640 "&& reload_completed"
15641 [(parallel [(set (match_dup 4)
15642 (ashift:DWIH (match_dup 4) (match_dup 2)))
15643 (clobber (reg:CC FLAGS_REG))])
15644 (parallel [(set (match_dup 4)
15645 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15646 (clobber (reg:CC FLAGS_REG))])]
15647 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15648
15649 (define_insn_and_split "*extendv2di2_highpart_stv"
15650 [(set (match_operand:V2DI 0 "register_operand" "=v")
15651 (ashiftrt:V2DI
15652 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15653 (match_operand:QI 2 "const_int_operand"))
15654 (match_operand:QI 3 "const_int_operand")))]
15655 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15656 && INTVAL (operands[2]) == INTVAL (operands[3])
15657 && UINTVAL (operands[2]) < 32"
15658 "#"
15659 "&& reload_completed"
15660 [(set (match_dup 0)
15661 (ashift:V2DI (match_dup 1) (match_dup 2)))
15662 (set (match_dup 0)
15663 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15664 \f
15665 ;; Rotate instructions
15666
15667 (define_expand "<insn>ti3"
15668 [(set (match_operand:TI 0 "register_operand")
15669 (any_rotate:TI (match_operand:TI 1 "register_operand")
15670 (match_operand:QI 2 "nonmemory_operand")))]
15671 "TARGET_64BIT"
15672 {
15673 if (const_1_to_63_operand (operands[2], VOIDmode))
15674 emit_insn (gen_ix86_<insn>ti3_doubleword
15675 (operands[0], operands[1], operands[2]));
15676 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15677 {
15678 operands[1] = force_reg (TImode, operands[1]);
15679 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15680 }
15681 else
15682 {
15683 rtx amount = force_reg (QImode, operands[2]);
15684 rtx src_lo = gen_lowpart (DImode, operands[1]);
15685 rtx src_hi = gen_highpart (DImode, operands[1]);
15686 rtx tmp_lo = gen_reg_rtx (DImode);
15687 rtx tmp_hi = gen_reg_rtx (DImode);
15688 emit_move_insn (tmp_lo, src_lo);
15689 emit_move_insn (tmp_hi, src_hi);
15690 rtx (*shiftd) (rtx, rtx, rtx)
15691 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15692 emit_insn (shiftd (tmp_lo, src_hi, amount));
15693 emit_insn (shiftd (tmp_hi, src_lo, amount));
15694 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15695 rtx dst_hi = gen_highpart (DImode, operands[0]);
15696 emit_move_insn (dst_lo, tmp_lo);
15697 emit_move_insn (dst_hi, tmp_hi);
15698 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15699 }
15700 DONE;
15701 })
15702
15703 (define_expand "<insn>di3"
15704 [(set (match_operand:DI 0 "shiftdi_operand")
15705 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15706 (match_operand:QI 2 "nonmemory_operand")))]
15707 ""
15708 {
15709 if (TARGET_64BIT)
15710 ix86_expand_binary_operator (<CODE>, DImode, operands);
15711 else if (const_1_to_31_operand (operands[2], VOIDmode))
15712 emit_insn (gen_ix86_<insn>di3_doubleword
15713 (operands[0], operands[1], operands[2]));
15714 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15715 {
15716 operands[1] = force_reg (DImode, operands[1]);
15717 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15718 }
15719 else
15720 FAIL;
15721
15722 DONE;
15723 })
15724
15725 (define_expand "<insn><mode>3"
15726 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15727 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15728 (match_operand:QI 2 "nonmemory_operand")))]
15729 ""
15730 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15731
15732 ;; Avoid useless masking of count operand.
15733 (define_insn_and_split "*<insn><mode>3_mask"
15734 [(set (match_operand:SWI 0 "nonimmediate_operand")
15735 (any_rotate:SWI
15736 (match_operand:SWI 1 "nonimmediate_operand")
15737 (subreg:QI
15738 (and
15739 (match_operand 2 "int248_register_operand" "c")
15740 (match_operand 3 "const_int_operand")) 0)))
15741 (clobber (reg:CC FLAGS_REG))]
15742 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15743 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15744 == GET_MODE_BITSIZE (<MODE>mode)-1
15745 && ix86_pre_reload_split ()"
15746 "#"
15747 "&& 1"
15748 [(parallel
15749 [(set (match_dup 0)
15750 (any_rotate:SWI (match_dup 1)
15751 (match_dup 2)))
15752 (clobber (reg:CC FLAGS_REG))])]
15753 {
15754 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15755 operands[2] = gen_lowpart (QImode, operands[2]);
15756 })
15757
15758 (define_split
15759 [(set (match_operand:SWI 0 "register_operand")
15760 (any_rotate:SWI
15761 (match_operand:SWI 1 "const_int_operand")
15762 (subreg:QI
15763 (and
15764 (match_operand 2 "int248_register_operand")
15765 (match_operand 3 "const_int_operand")) 0)))]
15766 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15767 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15768 [(set (match_dup 4) (match_dup 1))
15769 (set (match_dup 0)
15770 (any_rotate:SWI (match_dup 4)
15771 (subreg:QI (match_dup 2) 0)))]
15772 "operands[4] = gen_reg_rtx (<MODE>mode);")
15773
15774 (define_insn_and_split "*<insn><mode>3_mask_1"
15775 [(set (match_operand:SWI 0 "nonimmediate_operand")
15776 (any_rotate:SWI
15777 (match_operand:SWI 1 "nonimmediate_operand")
15778 (and:QI
15779 (match_operand:QI 2 "register_operand" "c")
15780 (match_operand:QI 3 "const_int_operand"))))
15781 (clobber (reg:CC FLAGS_REG))]
15782 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15783 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15784 == GET_MODE_BITSIZE (<MODE>mode)-1
15785 && ix86_pre_reload_split ()"
15786 "#"
15787 "&& 1"
15788 [(parallel
15789 [(set (match_dup 0)
15790 (any_rotate:SWI (match_dup 1)
15791 (match_dup 2)))
15792 (clobber (reg:CC FLAGS_REG))])])
15793
15794 (define_split
15795 [(set (match_operand:SWI 0 "register_operand")
15796 (any_rotate:SWI
15797 (match_operand:SWI 1 "const_int_operand")
15798 (and:QI
15799 (match_operand:QI 2 "register_operand")
15800 (match_operand:QI 3 "const_int_operand"))))]
15801 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15802 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15803 [(set (match_dup 4) (match_dup 1))
15804 (set (match_dup 0)
15805 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15806 "operands[4] = gen_reg_rtx (<MODE>mode);")
15807
15808 ;; Implement rotation using two double-precision
15809 ;; shift instructions and a scratch register.
15810
15811 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15812 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15813 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15814 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15815 (clobber (reg:CC FLAGS_REG))
15816 (clobber (match_scratch:DWIH 3 "=&r"))]
15817 ""
15818 "#"
15819 "reload_completed"
15820 [(set (match_dup 3) (match_dup 4))
15821 (parallel
15822 [(set (match_dup 4)
15823 (ior:DWIH (ashift:DWIH (match_dup 4)
15824 (and:QI (match_dup 2) (match_dup 6)))
15825 (subreg:DWIH
15826 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15827 (minus:QI (match_dup 7)
15828 (and:QI (match_dup 2)
15829 (match_dup 6)))) 0)))
15830 (clobber (reg:CC FLAGS_REG))])
15831 (parallel
15832 [(set (match_dup 5)
15833 (ior:DWIH (ashift:DWIH (match_dup 5)
15834 (and:QI (match_dup 2) (match_dup 6)))
15835 (subreg:DWIH
15836 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15837 (minus:QI (match_dup 7)
15838 (and:QI (match_dup 2)
15839 (match_dup 6)))) 0)))
15840 (clobber (reg:CC FLAGS_REG))])]
15841 {
15842 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15843 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15844
15845 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15846 })
15847
15848 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15849 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15850 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15851 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15852 (clobber (reg:CC FLAGS_REG))
15853 (clobber (match_scratch:DWIH 3 "=&r"))]
15854 ""
15855 "#"
15856 "reload_completed"
15857 [(set (match_dup 3) (match_dup 4))
15858 (parallel
15859 [(set (match_dup 4)
15860 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15861 (and:QI (match_dup 2) (match_dup 6)))
15862 (subreg:DWIH
15863 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15864 (minus:QI (match_dup 7)
15865 (and:QI (match_dup 2)
15866 (match_dup 6)))) 0)))
15867 (clobber (reg:CC FLAGS_REG))])
15868 (parallel
15869 [(set (match_dup 5)
15870 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15871 (and:QI (match_dup 2) (match_dup 6)))
15872 (subreg:DWIH
15873 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15874 (minus:QI (match_dup 7)
15875 (and:QI (match_dup 2)
15876 (match_dup 6)))) 0)))
15877 (clobber (reg:CC FLAGS_REG))])]
15878 {
15879 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15880 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15881
15882 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15883 })
15884
15885 (define_insn_and_split "<insn>32di2_doubleword"
15886 [(set (match_operand:DI 0 "register_operand" "=r,r")
15887 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
15888 (const_int 32)))]
15889 "!TARGET_64BIT"
15890 "#"
15891 "&& reload_completed"
15892 [(set (match_dup 0) (match_dup 3))
15893 (set (match_dup 2) (match_dup 1))]
15894 {
15895 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15896 if (rtx_equal_p (operands[0], operands[1]))
15897 {
15898 emit_insn (gen_swapsi (operands[0], operands[2]));
15899 DONE;
15900 }
15901 })
15902
15903 (define_insn_and_split "<insn>64ti2_doubleword"
15904 [(set (match_operand:TI 0 "register_operand" "=r,r")
15905 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
15906 (const_int 64)))]
15907 "TARGET_64BIT"
15908 "#"
15909 "&& reload_completed"
15910 [(set (match_dup 0) (match_dup 3))
15911 (set (match_dup 2) (match_dup 1))]
15912 {
15913 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15914 if (rtx_equal_p (operands[0], operands[1]))
15915 {
15916 emit_insn (gen_swapdi (operands[0], operands[2]));
15917 DONE;
15918 }
15919 })
15920
15921 (define_mode_attr rorx_immediate_operand
15922 [(SI "const_0_to_31_operand")
15923 (DI "const_0_to_63_operand")])
15924
15925 (define_insn "*bmi2_rorx<mode>3_1"
15926 [(set (match_operand:SWI48 0 "register_operand" "=r")
15927 (rotatert:SWI48
15928 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15929 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15930 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15931 "rorx\t{%2, %1, %0|%0, %1, %2}"
15932 [(set_attr "type" "rotatex")
15933 (set_attr "mode" "<MODE>")])
15934
15935 (define_insn "*<insn><mode>3_1"
15936 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15937 (any_rotate:SWI48
15938 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15939 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15940 (clobber (reg:CC FLAGS_REG))]
15941 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15942 {
15943 switch (get_attr_type (insn))
15944 {
15945 case TYPE_ROTATEX:
15946 return "#";
15947
15948 default:
15949 if (operands[2] == const1_rtx
15950 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15951 return "<rotate>{<imodesuffix>}\t%0";
15952 else
15953 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15954 }
15955 }
15956 [(set_attr "isa" "*,bmi2")
15957 (set_attr "type" "rotate,rotatex")
15958 (set (attr "preferred_for_size")
15959 (cond [(eq_attr "alternative" "0")
15960 (symbol_ref "true")]
15961 (symbol_ref "false")))
15962 (set (attr "length_immediate")
15963 (if_then_else
15964 (and (eq_attr "type" "rotate")
15965 (and (match_operand 2 "const1_operand")
15966 (ior (match_test "TARGET_SHIFT1")
15967 (match_test "optimize_function_for_size_p (cfun)"))))
15968 (const_string "0")
15969 (const_string "*")))
15970 (set_attr "mode" "<MODE>")])
15971
15972 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15973 (define_split
15974 [(set (match_operand:SWI48 0 "register_operand")
15975 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15976 (match_operand:QI 2 "const_int_operand")))
15977 (clobber (reg:CC FLAGS_REG))]
15978 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15979 [(set (match_dup 0)
15980 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15981 {
15982 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15983
15984 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15985 })
15986
15987 (define_split
15988 [(set (match_operand:SWI48 0 "register_operand")
15989 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15990 (match_operand:QI 2 "const_int_operand")))
15991 (clobber (reg:CC FLAGS_REG))]
15992 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15993 [(set (match_dup 0)
15994 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15995
15996 (define_insn "*bmi2_rorxsi3_1_zext"
15997 [(set (match_operand:DI 0 "register_operand" "=r")
15998 (zero_extend:DI
15999 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
16000 (match_operand:QI 2 "const_0_to_31_operand"))))]
16001 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
16002 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
16003 [(set_attr "type" "rotatex")
16004 (set_attr "mode" "SI")])
16005
16006 (define_insn "*<insn>si3_1_zext"
16007 [(set (match_operand:DI 0 "register_operand" "=r,r")
16008 (zero_extend:DI
16009 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
16010 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
16011 (clobber (reg:CC FLAGS_REG))]
16012 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
16013 {
16014 switch (get_attr_type (insn))
16015 {
16016 case TYPE_ROTATEX:
16017 return "#";
16018
16019 default:
16020 if (operands[2] == const1_rtx
16021 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16022 return "<rotate>{l}\t%k0";
16023 else
16024 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
16025 }
16026 }
16027 [(set_attr "isa" "*,bmi2")
16028 (set_attr "type" "rotate,rotatex")
16029 (set (attr "preferred_for_size")
16030 (cond [(eq_attr "alternative" "0")
16031 (symbol_ref "true")]
16032 (symbol_ref "false")))
16033 (set (attr "length_immediate")
16034 (if_then_else
16035 (and (eq_attr "type" "rotate")
16036 (and (match_operand 2 "const1_operand")
16037 (ior (match_test "TARGET_SHIFT1")
16038 (match_test "optimize_function_for_size_p (cfun)"))))
16039 (const_string "0")
16040 (const_string "*")))
16041 (set_attr "mode" "SI")])
16042
16043 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
16044 (define_split
16045 [(set (match_operand:DI 0 "register_operand")
16046 (zero_extend:DI
16047 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
16048 (match_operand:QI 2 "const_int_operand"))))
16049 (clobber (reg:CC FLAGS_REG))]
16050 "TARGET_64BIT && TARGET_BMI2 && reload_completed
16051 && !optimize_function_for_size_p (cfun)"
16052 [(set (match_dup 0)
16053 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
16054 {
16055 int bitsize = GET_MODE_BITSIZE (SImode);
16056
16057 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
16058 })
16059
16060 (define_split
16061 [(set (match_operand:DI 0 "register_operand")
16062 (zero_extend:DI
16063 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
16064 (match_operand:QI 2 "const_int_operand"))))
16065 (clobber (reg:CC FLAGS_REG))]
16066 "TARGET_64BIT && TARGET_BMI2 && reload_completed
16067 && !optimize_function_for_size_p (cfun)"
16068 [(set (match_dup 0)
16069 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
16070
16071 (define_insn "*<insn><mode>3_1"
16072 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
16073 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
16074 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
16075 (clobber (reg:CC FLAGS_REG))]
16076 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
16077 {
16078 if (operands[2] == const1_rtx
16079 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16080 return "<rotate>{<imodesuffix>}\t%0";
16081 else
16082 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16083 }
16084 [(set_attr "type" "rotate")
16085 (set (attr "length_immediate")
16086 (if_then_else
16087 (and (match_operand 2 "const1_operand")
16088 (ior (match_test "TARGET_SHIFT1")
16089 (match_test "optimize_function_for_size_p (cfun)")))
16090 (const_string "0")
16091 (const_string "*")))
16092 (set_attr "mode" "<MODE>")])
16093
16094 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16095 (define_insn_and_split "*<insn><mode>3_1_slp"
16096 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16097 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16098 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16099 (clobber (reg:CC FLAGS_REG))]
16100 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16101 {
16102 if (which_alternative)
16103 return "#";
16104
16105 if (operands[2] == const1_rtx
16106 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16107 return "<rotate>{<imodesuffix>}\t%0";
16108 else
16109 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16110 }
16111 "&& reload_completed
16112 && !(rtx_equal_p (operands[0], operands[1]))"
16113 [(set (strict_low_part (match_dup 0)) (match_dup 1))
16114 (parallel
16115 [(set (strict_low_part (match_dup 0))
16116 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
16117 (clobber (reg:CC FLAGS_REG))])]
16118 ""
16119 [(set_attr "type" "rotate")
16120 (set (attr "length_immediate")
16121 (if_then_else
16122 (and (match_operand 2 "const1_operand")
16123 (ior (match_test "TARGET_SHIFT1")
16124 (match_test "optimize_function_for_size_p (cfun)")))
16125 (const_string "0")
16126 (const_string "*")))
16127 (set_attr "mode" "<MODE>")])
16128
16129 (define_split
16130 [(set (match_operand:HI 0 "QIreg_operand")
16131 (any_rotate:HI (match_dup 0) (const_int 8)))
16132 (clobber (reg:CC FLAGS_REG))]
16133 "reload_completed
16134 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
16135 [(parallel [(set (strict_low_part (match_dup 0))
16136 (bswap:HI (match_dup 0)))
16137 (clobber (reg:CC FLAGS_REG))])])
16138
16139 ;; Rotations through carry flag
16140 (define_insn "rcrsi2"
16141 [(set (match_operand:SI 0 "register_operand" "=r")
16142 (plus:SI
16143 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
16144 (const_int 1))
16145 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
16146 (const_int 31))))
16147 (clobber (reg:CC FLAGS_REG))]
16148 ""
16149 "rcr{l}\t%0"
16150 [(set_attr "type" "ishift1")
16151 (set_attr "memory" "none")
16152 (set_attr "length_immediate" "0")
16153 (set_attr "mode" "SI")])
16154
16155 (define_insn "rcrdi2"
16156 [(set (match_operand:DI 0 "register_operand" "=r")
16157 (plus:DI
16158 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
16159 (const_int 1))
16160 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
16161 (const_int 63))))
16162 (clobber (reg:CC FLAGS_REG))]
16163 "TARGET_64BIT"
16164 "rcr{q}\t%0"
16165 [(set_attr "type" "ishift1")
16166 (set_attr "length_immediate" "0")
16167 (set_attr "mode" "DI")])
16168
16169 ;; Versions of sar and shr that set the carry flag.
16170 (define_insn "<insn><mode>3_carry"
16171 [(set (reg:CCC FLAGS_REG)
16172 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
16173 (const_int 1))
16174 (const_int 0)] UNSPEC_CC_NE))
16175 (set (match_operand:SWI48 0 "register_operand" "=r")
16176 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
16177 ""
16178 {
16179 if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16180 return "<shift>{<imodesuffix>}\t%0";
16181 return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
16182 }
16183 [(set_attr "type" "ishift1")
16184 (set (attr "length_immediate")
16185 (if_then_else
16186 (ior (match_test "TARGET_SHIFT1")
16187 (match_test "optimize_function_for_size_p (cfun)"))
16188 (const_string "0")
16189 (const_string "*")))
16190 (set_attr "mode" "<MODE>")])
16191 \f
16192 ;; Bit set / bit test instructions
16193
16194 ;; %%% bts, btr, btc
16195
16196 ;; These instructions are *slow* when applied to memory.
16197
16198 (define_code_attr btsc [(ior "bts") (xor "btc")])
16199
16200 (define_insn "*<btsc><mode>"
16201 [(set (match_operand:SWI48 0 "register_operand" "=r")
16202 (any_or:SWI48
16203 (ashift:SWI48 (const_int 1)
16204 (match_operand:QI 2 "register_operand" "r"))
16205 (match_operand:SWI48 1 "register_operand" "0")))
16206 (clobber (reg:CC FLAGS_REG))]
16207 "TARGET_USE_BT"
16208 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16209 [(set_attr "type" "alu1")
16210 (set_attr "prefix_0f" "1")
16211 (set_attr "znver1_decode" "double")
16212 (set_attr "mode" "<MODE>")])
16213
16214 ;; Avoid useless masking of count operand.
16215 (define_insn_and_split "*<btsc><mode>_mask"
16216 [(set (match_operand:SWI48 0 "register_operand")
16217 (any_or:SWI48
16218 (ashift:SWI48
16219 (const_int 1)
16220 (subreg:QI
16221 (and
16222 (match_operand 1 "int248_register_operand")
16223 (match_operand 2 "const_int_operand")) 0))
16224 (match_operand:SWI48 3 "register_operand")))
16225 (clobber (reg:CC FLAGS_REG))]
16226 "TARGET_USE_BT
16227 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16228 == GET_MODE_BITSIZE (<MODE>mode)-1
16229 && ix86_pre_reload_split ()"
16230 "#"
16231 "&& 1"
16232 [(parallel
16233 [(set (match_dup 0)
16234 (any_or:SWI48
16235 (ashift:SWI48 (const_int 1)
16236 (match_dup 1))
16237 (match_dup 3)))
16238 (clobber (reg:CC FLAGS_REG))])]
16239 {
16240 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16241 operands[1] = gen_lowpart (QImode, operands[1]);
16242 })
16243
16244 (define_insn_and_split "*<btsc><mode>_mask_1"
16245 [(set (match_operand:SWI48 0 "register_operand")
16246 (any_or:SWI48
16247 (ashift:SWI48
16248 (const_int 1)
16249 (and:QI
16250 (match_operand:QI 1 "register_operand")
16251 (match_operand:QI 2 "const_int_operand")))
16252 (match_operand:SWI48 3 "register_operand")))
16253 (clobber (reg:CC FLAGS_REG))]
16254 "TARGET_USE_BT
16255 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16256 == GET_MODE_BITSIZE (<MODE>mode)-1
16257 && ix86_pre_reload_split ()"
16258 "#"
16259 "&& 1"
16260 [(parallel
16261 [(set (match_dup 0)
16262 (any_or:SWI48
16263 (ashift:SWI48 (const_int 1)
16264 (match_dup 1))
16265 (match_dup 3)))
16266 (clobber (reg:CC FLAGS_REG))])])
16267
16268 (define_insn "*btr<mode>"
16269 [(set (match_operand:SWI48 0 "register_operand" "=r")
16270 (and:SWI48
16271 (rotate:SWI48 (const_int -2)
16272 (match_operand:QI 2 "register_operand" "r"))
16273 (match_operand:SWI48 1 "register_operand" "0")))
16274 (clobber (reg:CC FLAGS_REG))]
16275 "TARGET_USE_BT"
16276 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16277 [(set_attr "type" "alu1")
16278 (set_attr "prefix_0f" "1")
16279 (set_attr "znver1_decode" "double")
16280 (set_attr "mode" "<MODE>")])
16281
16282 ;; Avoid useless masking of count operand.
16283 (define_insn_and_split "*btr<mode>_mask"
16284 [(set (match_operand:SWI48 0 "register_operand")
16285 (and:SWI48
16286 (rotate:SWI48
16287 (const_int -2)
16288 (subreg:QI
16289 (and
16290 (match_operand 1 "int248_register_operand")
16291 (match_operand 2 "const_int_operand")) 0))
16292 (match_operand:SWI48 3 "register_operand")))
16293 (clobber (reg:CC FLAGS_REG))]
16294 "TARGET_USE_BT
16295 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16296 == GET_MODE_BITSIZE (<MODE>mode)-1
16297 && ix86_pre_reload_split ()"
16298 "#"
16299 "&& 1"
16300 [(parallel
16301 [(set (match_dup 0)
16302 (and:SWI48
16303 (rotate:SWI48 (const_int -2)
16304 (match_dup 1))
16305 (match_dup 3)))
16306 (clobber (reg:CC FLAGS_REG))])]
16307 {
16308 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16309 operands[1] = gen_lowpart (QImode, operands[1]);
16310 })
16311
16312 (define_insn_and_split "*btr<mode>_mask_1"
16313 [(set (match_operand:SWI48 0 "register_operand")
16314 (and:SWI48
16315 (rotate:SWI48
16316 (const_int -2)
16317 (and:QI
16318 (match_operand:QI 1 "register_operand")
16319 (match_operand:QI 2 "const_int_operand")))
16320 (match_operand:SWI48 3 "register_operand")))
16321 (clobber (reg:CC FLAGS_REG))]
16322 "TARGET_USE_BT
16323 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16324 == GET_MODE_BITSIZE (<MODE>mode)-1
16325 && ix86_pre_reload_split ()"
16326 "#"
16327 "&& 1"
16328 [(parallel
16329 [(set (match_dup 0)
16330 (and:SWI48
16331 (rotate:SWI48 (const_int -2)
16332 (match_dup 1))
16333 (match_dup 3)))
16334 (clobber (reg:CC FLAGS_REG))])])
16335
16336 (define_insn_and_split "*btr<mode>_1"
16337 [(set (match_operand:SWI12 0 "register_operand")
16338 (and:SWI12
16339 (subreg:SWI12
16340 (rotate:SI (const_int -2)
16341 (match_operand:QI 2 "register_operand")) 0)
16342 (match_operand:SWI12 1 "nonimmediate_operand")))
16343 (clobber (reg:CC FLAGS_REG))]
16344 "TARGET_USE_BT && ix86_pre_reload_split ()"
16345 "#"
16346 "&& 1"
16347 [(parallel
16348 [(set (match_dup 0)
16349 (and:SI (rotate:SI (const_int -2) (match_dup 2))
16350 (match_dup 1)))
16351 (clobber (reg:CC FLAGS_REG))])]
16352 {
16353 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16354 operands[1] = force_reg (<MODE>mode, operands[1]);
16355 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16356 })
16357
16358 (define_insn_and_split "*btr<mode>_2"
16359 [(set (zero_extract:HI
16360 (match_operand:SWI12 0 "nonimmediate_operand")
16361 (const_int 1)
16362 (match_operand:QI 1 "register_operand"))
16363 (const_int 0))
16364 (clobber (reg:CC FLAGS_REG))]
16365 "TARGET_USE_BT && ix86_pre_reload_split ()"
16366 "#"
16367 "&& MEM_P (operands[0])"
16368 [(set (match_dup 2) (match_dup 0))
16369 (parallel
16370 [(set (match_dup 3)
16371 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16372 (match_dup 4)))
16373 (clobber (reg:CC FLAGS_REG))])
16374 (set (match_dup 0) (match_dup 5))]
16375 {
16376 operands[2] = gen_reg_rtx (<MODE>mode);
16377 operands[5] = gen_reg_rtx (<MODE>mode);
16378 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16379 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16380 })
16381
16382 (define_split
16383 [(set (zero_extract:HI
16384 (match_operand:SWI12 0 "register_operand")
16385 (const_int 1)
16386 (match_operand:QI 1 "register_operand"))
16387 (const_int 0))
16388 (clobber (reg:CC FLAGS_REG))]
16389 "TARGET_USE_BT && ix86_pre_reload_split ()"
16390 [(parallel
16391 [(set (match_dup 0)
16392 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16393 (match_dup 2)))
16394 (clobber (reg:CC FLAGS_REG))])]
16395 {
16396 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16397 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16398 })
16399
16400 ;; These instructions are never faster than the corresponding
16401 ;; and/ior/xor operations when using immediate operand, so with
16402 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16403 ;; relevant immediates within the instruction itself, so operating
16404 ;; on bits in the high 32-bits of a register becomes easier.
16405 ;;
16406 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16407 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16408 ;; negdf respectively, so they can never be disabled entirely.
16409
16410 (define_insn "*btsq_imm"
16411 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16412 (const_int 1)
16413 (match_operand:QI 1 "const_0_to_63_operand"))
16414 (const_int 1))
16415 (clobber (reg:CC FLAGS_REG))]
16416 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16417 "bts{q}\t{%1, %0|%0, %1}"
16418 [(set_attr "type" "alu1")
16419 (set_attr "prefix_0f" "1")
16420 (set_attr "znver1_decode" "double")
16421 (set_attr "mode" "DI")])
16422
16423 (define_insn "*btrq_imm"
16424 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16425 (const_int 1)
16426 (match_operand:QI 1 "const_0_to_63_operand"))
16427 (const_int 0))
16428 (clobber (reg:CC FLAGS_REG))]
16429 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16430 "btr{q}\t{%1, %0|%0, %1}"
16431 [(set_attr "type" "alu1")
16432 (set_attr "prefix_0f" "1")
16433 (set_attr "znver1_decode" "double")
16434 (set_attr "mode" "DI")])
16435
16436 (define_insn "*btcq_imm"
16437 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16438 (const_int 1)
16439 (match_operand:QI 1 "const_0_to_63_operand"))
16440 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16441 (clobber (reg:CC FLAGS_REG))]
16442 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16443 "btc{q}\t{%1, %0|%0, %1}"
16444 [(set_attr "type" "alu1")
16445 (set_attr "prefix_0f" "1")
16446 (set_attr "znver1_decode" "double")
16447 (set_attr "mode" "DI")])
16448
16449 ;; Allow Nocona to avoid these instructions if a register is available.
16450
16451 (define_peephole2
16452 [(match_scratch:DI 2 "r")
16453 (parallel [(set (zero_extract:DI
16454 (match_operand:DI 0 "nonimmediate_operand")
16455 (const_int 1)
16456 (match_operand:QI 1 "const_0_to_63_operand"))
16457 (const_int 1))
16458 (clobber (reg:CC FLAGS_REG))])]
16459 "TARGET_64BIT && !TARGET_USE_BT"
16460 [(parallel [(set (match_dup 0)
16461 (ior:DI (match_dup 0) (match_dup 3)))
16462 (clobber (reg:CC FLAGS_REG))])]
16463 {
16464 int i = INTVAL (operands[1]);
16465
16466 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16467
16468 if (!x86_64_immediate_operand (operands[3], DImode))
16469 {
16470 emit_move_insn (operands[2], operands[3]);
16471 operands[3] = operands[2];
16472 }
16473 })
16474
16475 (define_peephole2
16476 [(match_scratch:DI 2 "r")
16477 (parallel [(set (zero_extract:DI
16478 (match_operand:DI 0 "nonimmediate_operand")
16479 (const_int 1)
16480 (match_operand:QI 1 "const_0_to_63_operand"))
16481 (const_int 0))
16482 (clobber (reg:CC FLAGS_REG))])]
16483 "TARGET_64BIT && !TARGET_USE_BT"
16484 [(parallel [(set (match_dup 0)
16485 (and:DI (match_dup 0) (match_dup 3)))
16486 (clobber (reg:CC FLAGS_REG))])]
16487 {
16488 int i = INTVAL (operands[1]);
16489
16490 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16491
16492 if (!x86_64_immediate_operand (operands[3], DImode))
16493 {
16494 emit_move_insn (operands[2], operands[3]);
16495 operands[3] = operands[2];
16496 }
16497 })
16498
16499 (define_peephole2
16500 [(match_scratch:DI 2 "r")
16501 (parallel [(set (zero_extract:DI
16502 (match_operand:DI 0 "nonimmediate_operand")
16503 (const_int 1)
16504 (match_operand:QI 1 "const_0_to_63_operand"))
16505 (not:DI (zero_extract:DI
16506 (match_dup 0) (const_int 1) (match_dup 1))))
16507 (clobber (reg:CC FLAGS_REG))])]
16508 "TARGET_64BIT && !TARGET_USE_BT"
16509 [(parallel [(set (match_dup 0)
16510 (xor:DI (match_dup 0) (match_dup 3)))
16511 (clobber (reg:CC FLAGS_REG))])]
16512 {
16513 int i = INTVAL (operands[1]);
16514
16515 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16516
16517 if (!x86_64_immediate_operand (operands[3], DImode))
16518 {
16519 emit_move_insn (operands[2], operands[3]);
16520 operands[3] = operands[2];
16521 }
16522 })
16523
16524 ;; %%% bt
16525
16526 (define_insn "*bt<mode>"
16527 [(set (reg:CCC FLAGS_REG)
16528 (compare:CCC
16529 (zero_extract:SWI48
16530 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16531 (const_int 1)
16532 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16533 (const_int 0)))]
16534 ""
16535 {
16536 switch (get_attr_mode (insn))
16537 {
16538 case MODE_SI:
16539 return "bt{l}\t{%k1, %k0|%k0, %k1}";
16540
16541 case MODE_DI:
16542 return "bt{q}\t{%q1, %0|%0, %q1}";
16543
16544 default:
16545 gcc_unreachable ();
16546 }
16547 }
16548 [(set_attr "type" "alu1")
16549 (set_attr "prefix_0f" "1")
16550 (set (attr "mode")
16551 (if_then_else
16552 (and (match_test "CONST_INT_P (operands[1])")
16553 (match_test "INTVAL (operands[1]) < 32"))
16554 (const_string "SI")
16555 (const_string "<MODE>")))])
16556
16557 (define_insn_and_split "*bt<SWI48:mode>_mask"
16558 [(set (reg:CCC FLAGS_REG)
16559 (compare:CCC
16560 (zero_extract:SWI48
16561 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16562 (const_int 1)
16563 (subreg:QI
16564 (and:SWI248
16565 (match_operand:SWI248 1 "register_operand")
16566 (match_operand 2 "const_int_operand")) 0))
16567 (const_int 0)))]
16568 "TARGET_USE_BT
16569 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16570 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16571 && ix86_pre_reload_split ()"
16572 "#"
16573 "&& 1"
16574 [(set (reg:CCC FLAGS_REG)
16575 (compare:CCC
16576 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16577 (const_int 0)))]
16578 "operands[1] = gen_lowpart (QImode, operands[1]);")
16579
16580 (define_insn_and_split "*jcc_bt<mode>"
16581 [(set (pc)
16582 (if_then_else (match_operator 0 "bt_comparison_operator"
16583 [(zero_extract:SWI48
16584 (match_operand:SWI48 1 "nonimmediate_operand")
16585 (const_int 1)
16586 (match_operand:QI 2 "nonmemory_operand"))
16587 (const_int 0)])
16588 (label_ref (match_operand 3))
16589 (pc)))
16590 (clobber (reg:CC FLAGS_REG))]
16591 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16592 && (CONST_INT_P (operands[2])
16593 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16594 && INTVAL (operands[2])
16595 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16596 : !memory_operand (operands[1], <MODE>mode))
16597 && ix86_pre_reload_split ()"
16598 "#"
16599 "&& 1"
16600 [(set (reg:CCC FLAGS_REG)
16601 (compare:CCC
16602 (zero_extract:SWI48
16603 (match_dup 1)
16604 (const_int 1)
16605 (match_dup 2))
16606 (const_int 0)))
16607 (set (pc)
16608 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16609 (label_ref (match_dup 3))
16610 (pc)))]
16611 {
16612 operands[0] = shallow_copy_rtx (operands[0]);
16613 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16614 })
16615
16616 ;; Avoid useless masking of bit offset operand.
16617 (define_insn_and_split "*jcc_bt<mode>_mask"
16618 [(set (pc)
16619 (if_then_else (match_operator 0 "bt_comparison_operator"
16620 [(zero_extract:SWI48
16621 (match_operand:SWI48 1 "register_operand")
16622 (const_int 1)
16623 (and:QI
16624 (match_operand:QI 2 "register_operand")
16625 (match_operand 3 "const_int_operand")))])
16626 (label_ref (match_operand 4))
16627 (pc)))
16628 (clobber (reg:CC FLAGS_REG))]
16629 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16630 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16631 == GET_MODE_BITSIZE (<MODE>mode)-1
16632 && ix86_pre_reload_split ()"
16633 "#"
16634 "&& 1"
16635 [(set (reg:CCC FLAGS_REG)
16636 (compare:CCC
16637 (zero_extract:SWI48
16638 (match_dup 1)
16639 (const_int 1)
16640 (match_dup 2))
16641 (const_int 0)))
16642 (set (pc)
16643 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16644 (label_ref (match_dup 4))
16645 (pc)))]
16646 {
16647 operands[0] = shallow_copy_rtx (operands[0]);
16648 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16649 })
16650
16651 ;; Avoid useless masking of bit offset operand.
16652 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16653 [(set (pc)
16654 (if_then_else (match_operator 0 "bt_comparison_operator"
16655 [(zero_extract:SWI48
16656 (match_operand:SWI48 1 "register_operand")
16657 (const_int 1)
16658 (subreg:QI
16659 (and:SWI248
16660 (match_operand:SWI248 2 "register_operand")
16661 (match_operand 3 "const_int_operand")) 0))])
16662 (label_ref (match_operand 4))
16663 (pc)))
16664 (clobber (reg:CC FLAGS_REG))]
16665 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16666 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16667 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16668 && ix86_pre_reload_split ()"
16669 "#"
16670 "&& 1"
16671 [(set (reg:CCC FLAGS_REG)
16672 (compare:CCC
16673 (zero_extract:SWI48
16674 (match_dup 1)
16675 (const_int 1)
16676 (match_dup 2))
16677 (const_int 0)))
16678 (set (pc)
16679 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16680 (label_ref (match_dup 4))
16681 (pc)))]
16682 {
16683 operands[0] = shallow_copy_rtx (operands[0]);
16684 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16685 operands[2] = gen_lowpart (QImode, operands[2]);
16686 })
16687
16688 ;; Help combine recognize bt followed by cmov
16689 (define_split
16690 [(set (match_operand:SWI248 0 "register_operand")
16691 (if_then_else:SWI248
16692 (match_operator 5 "bt_comparison_operator"
16693 [(zero_extract:SWI48
16694 (match_operand:SWI48 1 "register_operand")
16695 (const_int 1)
16696 (match_operand:QI 2 "register_operand"))
16697 (const_int 0)])
16698 (match_operand:SWI248 3 "nonimmediate_operand")
16699 (match_operand:SWI248 4 "nonimmediate_operand")))]
16700 "TARGET_USE_BT && TARGET_CMOVE
16701 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16702 && ix86_pre_reload_split ()"
16703 [(set (reg:CCC FLAGS_REG)
16704 (compare:CCC
16705 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16706 (const_int 0)))
16707 (set (match_dup 0)
16708 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16709 (match_dup 3)
16710 (match_dup 4)))]
16711 {
16712 if (GET_CODE (operands[5]) == EQ)
16713 std::swap (operands[3], operands[4]);
16714 })
16715
16716 ;; Help combine recognize bt followed by setc
16717 (define_insn_and_split "*bt<mode>_setcqi"
16718 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16719 (zero_extract:SWI48
16720 (match_operand:SWI48 1 "register_operand")
16721 (const_int 1)
16722 (match_operand:QI 2 "register_operand")))
16723 (clobber (reg:CC FLAGS_REG))]
16724 "TARGET_USE_BT && ix86_pre_reload_split ()"
16725 "#"
16726 "&& 1"
16727 [(set (reg:CCC FLAGS_REG)
16728 (compare:CCC
16729 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16730 (const_int 0)))
16731 (set (match_dup 0)
16732 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16733
16734 ;; Help combine recognize bt followed by setnc
16735 (define_insn_and_split "*bt<mode>_setncqi"
16736 [(set (match_operand:QI 0 "register_operand")
16737 (and:QI
16738 (not:QI
16739 (subreg:QI
16740 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16741 (match_operand:QI 2 "register_operand")) 0))
16742 (const_int 1)))
16743 (clobber (reg:CC FLAGS_REG))]
16744 "TARGET_USE_BT && ix86_pre_reload_split ()"
16745 "#"
16746 "&& 1"
16747 [(set (reg:CCC FLAGS_REG)
16748 (compare:CCC
16749 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16750 (const_int 0)))
16751 (set (match_dup 0)
16752 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16753
16754 (define_insn_and_split "*bt<mode>_setnc<mode>"
16755 [(set (match_operand:SWI48 0 "register_operand")
16756 (and:SWI48
16757 (not:SWI48
16758 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16759 (match_operand:QI 2 "register_operand")))
16760 (const_int 1)))
16761 (clobber (reg:CC FLAGS_REG))]
16762 "TARGET_USE_BT && ix86_pre_reload_split ()"
16763 "#"
16764 "&& 1"
16765 [(set (reg:CCC FLAGS_REG)
16766 (compare:CCC
16767 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16768 (const_int 0)))
16769 (set (match_dup 3)
16770 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16771 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16772 "operands[3] = gen_reg_rtx (QImode);")
16773
16774 ;; Help combine recognize bt followed by setnc (PR target/110588)
16775 (define_insn_and_split "*bt<mode>_setncqi_2"
16776 [(set (match_operand:QI 0 "register_operand")
16777 (eq:QI
16778 (zero_extract:SWI48
16779 (match_operand:SWI48 1 "register_operand")
16780 (const_int 1)
16781 (match_operand:QI 2 "register_operand"))
16782 (const_int 0)))
16783 (clobber (reg:CC FLAGS_REG))]
16784 "TARGET_USE_BT && ix86_pre_reload_split ()"
16785 "#"
16786 "&& 1"
16787 [(set (reg:CCC FLAGS_REG)
16788 (compare:CCC
16789 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16790 (const_int 0)))
16791 (set (match_dup 0)
16792 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16793
16794 ;; Help combine recognize bt followed by setc
16795 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16796 [(set (match_operand:SWI48 0 "register_operand")
16797 (zero_extract:SWI48
16798 (match_operand:SWI48 1 "register_operand")
16799 (const_int 1)
16800 (subreg:QI
16801 (and:SWI48
16802 (match_operand:SWI48 2 "register_operand")
16803 (match_operand 3 "const_int_operand")) 0)))
16804 (clobber (reg:CC FLAGS_REG))]
16805 "TARGET_USE_BT
16806 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16807 == GET_MODE_BITSIZE (<MODE>mode)-1
16808 && ix86_pre_reload_split ()"
16809 "#"
16810 "&& 1"
16811 [(set (reg:CCC FLAGS_REG)
16812 (compare:CCC
16813 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16814 (const_int 0)))
16815 (set (match_dup 3)
16816 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16817 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16818 {
16819 operands[2] = gen_lowpart (QImode, operands[2]);
16820 operands[3] = gen_reg_rtx (QImode);
16821 })
16822 \f
16823 ;; Store-flag instructions.
16824
16825 (define_split
16826 [(set (match_operand:QI 0 "nonimmediate_operand")
16827 (match_operator:QI 1 "add_comparison_operator"
16828 [(not:SWI (match_operand:SWI 2 "register_operand"))
16829 (match_operand:SWI 3 "nonimmediate_operand")]))]
16830 ""
16831 [(set (reg:CCC FLAGS_REG)
16832 (compare:CCC
16833 (plus:SWI (match_dup 2) (match_dup 3))
16834 (match_dup 2)))
16835 (set (match_dup 0)
16836 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16837
16838 (define_split
16839 [(set (match_operand:QI 0 "nonimmediate_operand")
16840 (match_operator:QI 1 "shr_comparison_operator"
16841 [(match_operand:DI 2 "register_operand")
16842 (match_operand 3 "const_int_operand")]))]
16843 "TARGET_64BIT
16844 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16845 [(set (reg:CCZ FLAGS_REG)
16846 (compare:CCZ
16847 (lshiftrt:DI (match_dup 2) (match_dup 4))
16848 (const_int 0)))
16849 (set (match_dup 0)
16850 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16851 {
16852 enum rtx_code new_code;
16853
16854 operands[1] = shallow_copy_rtx (operands[1]);
16855 switch (GET_CODE (operands[1]))
16856 {
16857 case GTU: new_code = NE; break;
16858 case LEU: new_code = EQ; break;
16859 default: gcc_unreachable ();
16860 }
16861 PUT_CODE (operands[1], new_code);
16862
16863 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16864 })
16865
16866 ;; For all sCOND expanders, also expand the compare or test insn that
16867 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16868
16869 (define_insn_and_split "*setcc_di_1"
16870 [(set (match_operand:DI 0 "register_operand" "=q")
16871 (match_operator:DI 1 "ix86_comparison_operator"
16872 [(reg FLAGS_REG) (const_int 0)]))]
16873 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16874 "#"
16875 "&& reload_completed"
16876 [(set (match_dup 2) (match_dup 1))
16877 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16878 {
16879 operands[1] = shallow_copy_rtx (operands[1]);
16880 PUT_MODE (operands[1], QImode);
16881 operands[2] = gen_lowpart (QImode, operands[0]);
16882 })
16883
16884 (define_insn_and_split "*setcc_<mode>_1_and"
16885 [(set (match_operand:SWI24 0 "register_operand" "=q")
16886 (match_operator:SWI24 1 "ix86_comparison_operator"
16887 [(reg FLAGS_REG) (const_int 0)]))
16888 (clobber (reg:CC FLAGS_REG))]
16889 "!TARGET_PARTIAL_REG_STALL
16890 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16891 "#"
16892 "&& reload_completed"
16893 [(set (match_dup 2) (match_dup 1))
16894 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16895 (clobber (reg:CC FLAGS_REG))])]
16896 {
16897 operands[1] = shallow_copy_rtx (operands[1]);
16898 PUT_MODE (operands[1], QImode);
16899 operands[2] = gen_lowpart (QImode, operands[0]);
16900 })
16901
16902 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16903 [(set (match_operand:SWI24 0 "register_operand" "=q")
16904 (match_operator:SWI24 1 "ix86_comparison_operator"
16905 [(reg FLAGS_REG) (const_int 0)]))]
16906 "!TARGET_PARTIAL_REG_STALL
16907 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16908 "#"
16909 "&& reload_completed"
16910 [(set (match_dup 2) (match_dup 1))
16911 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16912 {
16913 operands[1] = shallow_copy_rtx (operands[1]);
16914 PUT_MODE (operands[1], QImode);
16915 operands[2] = gen_lowpart (QImode, operands[0]);
16916 })
16917
16918 (define_insn "*setcc_qi"
16919 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16920 (match_operator:QI 1 "ix86_comparison_operator"
16921 [(reg FLAGS_REG) (const_int 0)]))]
16922 ""
16923 "set%C1\t%0"
16924 [(set_attr "type" "setcc")
16925 (set_attr "mode" "QI")])
16926
16927 (define_insn "*setcc_qi_slp"
16928 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16929 (match_operator:QI 1 "ix86_comparison_operator"
16930 [(reg FLAGS_REG) (const_int 0)]))]
16931 ""
16932 "set%C1\t%0"
16933 [(set_attr "type" "setcc")
16934 (set_attr "mode" "QI")])
16935
16936 ;; In general it is not safe to assume too much about CCmode registers,
16937 ;; so simplify-rtx stops when it sees a second one. Under certain
16938 ;; conditions this is safe on x86, so help combine not create
16939 ;;
16940 ;; seta %al
16941 ;; testb %al, %al
16942 ;; sete %al
16943
16944 (define_split
16945 [(set (match_operand:QI 0 "nonimmediate_operand")
16946 (ne:QI (match_operator 1 "ix86_comparison_operator"
16947 [(reg FLAGS_REG) (const_int 0)])
16948 (const_int 0)))]
16949 ""
16950 [(set (match_dup 0) (match_dup 1))]
16951 {
16952 operands[1] = shallow_copy_rtx (operands[1]);
16953 PUT_MODE (operands[1], QImode);
16954 })
16955
16956 (define_split
16957 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16958 (ne:QI (match_operator 1 "ix86_comparison_operator"
16959 [(reg FLAGS_REG) (const_int 0)])
16960 (const_int 0)))]
16961 ""
16962 [(set (match_dup 0) (match_dup 1))]
16963 {
16964 operands[1] = shallow_copy_rtx (operands[1]);
16965 PUT_MODE (operands[1], QImode);
16966 })
16967
16968 (define_split
16969 [(set (match_operand:QI 0 "nonimmediate_operand")
16970 (eq:QI (match_operator 1 "ix86_comparison_operator"
16971 [(reg FLAGS_REG) (const_int 0)])
16972 (const_int 0)))]
16973 ""
16974 [(set (match_dup 0) (match_dup 1))]
16975 {
16976 operands[1] = shallow_copy_rtx (operands[1]);
16977 PUT_MODE (operands[1], QImode);
16978 PUT_CODE (operands[1],
16979 ix86_reverse_condition (GET_CODE (operands[1]),
16980 GET_MODE (XEXP (operands[1], 0))));
16981
16982 /* Make sure that (a) the CCmode we have for the flags is strong
16983 enough for the reversed compare or (b) we have a valid FP compare. */
16984 if (! ix86_comparison_operator (operands[1], VOIDmode))
16985 FAIL;
16986 })
16987
16988 (define_split
16989 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16990 (eq:QI (match_operator 1 "ix86_comparison_operator"
16991 [(reg FLAGS_REG) (const_int 0)])
16992 (const_int 0)))]
16993 ""
16994 [(set (match_dup 0) (match_dup 1))]
16995 {
16996 operands[1] = shallow_copy_rtx (operands[1]);
16997 PUT_MODE (operands[1], QImode);
16998 PUT_CODE (operands[1],
16999 ix86_reverse_condition (GET_CODE (operands[1]),
17000 GET_MODE (XEXP (operands[1], 0))));
17001
17002 /* Make sure that (a) the CCmode we have for the flags is strong
17003 enough for the reversed compare or (b) we have a valid FP compare. */
17004 if (! ix86_comparison_operator (operands[1], VOIDmode))
17005 FAIL;
17006 })
17007
17008 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
17009 ;; subsequent logical operations are used to imitate conditional moves.
17010 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
17011 ;; it directly.
17012
17013 (define_insn "setcc_<mode>_sse"
17014 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17015 (match_operator:MODEF 3 "sse_comparison_operator"
17016 [(match_operand:MODEF 1 "register_operand" "0,x")
17017 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
17018 "SSE_FLOAT_MODE_P (<MODE>mode)"
17019 "@
17020 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
17021 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17022 [(set_attr "isa" "noavx,avx")
17023 (set_attr "addr" "*,gpr16")
17024 (set_attr "type" "ssecmp")
17025 (set_attr "length_immediate" "1")
17026 (set_attr "prefix" "orig,vex")
17027 (set_attr "mode" "<MODE>")])
17028
17029 (define_insn "setcc_hf_mask"
17030 [(set (match_operand:QI 0 "register_operand" "=k")
17031 (unspec:QI
17032 [(match_operand:HF 1 "register_operand" "v")
17033 (match_operand:HF 2 "nonimmediate_operand" "vm")
17034 (match_operand:SI 3 "const_0_to_31_operand")]
17035 UNSPEC_PCMP))]
17036 "TARGET_AVX512FP16"
17037 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
17038 [(set_attr "type" "ssecmp")
17039 (set_attr "prefix" "evex")
17040 (set_attr "mode" "HF")])
17041
17042 \f
17043 ;; Basic conditional jump instructions.
17044
17045 (define_split
17046 [(set (pc)
17047 (if_then_else
17048 (match_operator 1 "add_comparison_operator"
17049 [(not:SWI (match_operand:SWI 2 "register_operand"))
17050 (match_operand:SWI 3 "nonimmediate_operand")])
17051 (label_ref (match_operand 0))
17052 (pc)))]
17053 ""
17054 [(set (reg:CCC FLAGS_REG)
17055 (compare:CCC
17056 (plus:SWI (match_dup 2) (match_dup 3))
17057 (match_dup 2)))
17058 (set (pc)
17059 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
17060 (label_ref (match_operand 0))
17061 (pc)))])
17062
17063 (define_split
17064 [(set (pc)
17065 (if_then_else
17066 (match_operator 1 "shr_comparison_operator"
17067 [(match_operand:DI 2 "register_operand")
17068 (match_operand 3 "const_int_operand")])
17069 (label_ref (match_operand 0))
17070 (pc)))]
17071 "TARGET_64BIT
17072 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
17073 [(set (reg:CCZ FLAGS_REG)
17074 (compare:CCZ
17075 (lshiftrt:DI (match_dup 2) (match_dup 4))
17076 (const_int 0)))
17077 (set (pc)
17078 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
17079 (label_ref (match_operand 0))
17080 (pc)))]
17081 {
17082 enum rtx_code new_code;
17083
17084 operands[1] = shallow_copy_rtx (operands[1]);
17085 switch (GET_CODE (operands[1]))
17086 {
17087 case GTU: new_code = NE; break;
17088 case LEU: new_code = EQ; break;
17089 default: gcc_unreachable ();
17090 }
17091 PUT_CODE (operands[1], new_code);
17092
17093 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
17094 })
17095
17096 ;; We ignore the overflow flag for signed branch instructions.
17097
17098 (define_insn "*jcc"
17099 [(set (pc)
17100 (if_then_else (match_operator 1 "ix86_comparison_operator"
17101 [(reg FLAGS_REG) (const_int 0)])
17102 (label_ref (match_operand 0))
17103 (pc)))]
17104 ""
17105 "%!%+j%C1\t%l0"
17106 [(set_attr "type" "ibr")
17107 (set_attr "modrm" "0")
17108 (set (attr "length")
17109 (if_then_else
17110 (and (ge (minus (match_dup 0) (pc))
17111 (const_int -126))
17112 (lt (minus (match_dup 0) (pc))
17113 (const_int 128)))
17114 (const_int 2)
17115 (const_int 6)))])
17116
17117 ;; In general it is not safe to assume too much about CCmode registers,
17118 ;; so simplify-rtx stops when it sees a second one. Under certain
17119 ;; conditions this is safe on x86, so help combine not create
17120 ;;
17121 ;; seta %al
17122 ;; testb %al, %al
17123 ;; je Lfoo
17124
17125 (define_split
17126 [(set (pc)
17127 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
17128 [(reg FLAGS_REG) (const_int 0)])
17129 (const_int 0))
17130 (label_ref (match_operand 1))
17131 (pc)))]
17132 ""
17133 [(set (pc)
17134 (if_then_else (match_dup 0)
17135 (label_ref (match_dup 1))
17136 (pc)))]
17137 {
17138 operands[0] = shallow_copy_rtx (operands[0]);
17139 PUT_MODE (operands[0], VOIDmode);
17140 })
17141
17142 (define_split
17143 [(set (pc)
17144 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
17145 [(reg FLAGS_REG) (const_int 0)])
17146 (const_int 0))
17147 (label_ref (match_operand 1))
17148 (pc)))]
17149 ""
17150 [(set (pc)
17151 (if_then_else (match_dup 0)
17152 (label_ref (match_dup 1))
17153 (pc)))]
17154 {
17155 operands[0] = shallow_copy_rtx (operands[0]);
17156 PUT_MODE (operands[0], VOIDmode);
17157 PUT_CODE (operands[0],
17158 ix86_reverse_condition (GET_CODE (operands[0]),
17159 GET_MODE (XEXP (operands[0], 0))));
17160
17161 /* Make sure that (a) the CCmode we have for the flags is strong
17162 enough for the reversed compare or (b) we have a valid FP compare. */
17163 if (! ix86_comparison_operator (operands[0], VOIDmode))
17164 FAIL;
17165 })
17166 \f
17167 ;; Unconditional and other jump instructions
17168
17169 (define_insn "jump"
17170 [(set (pc)
17171 (label_ref (match_operand 0)))]
17172 ""
17173 "%!jmp\t%l0"
17174 [(set_attr "type" "ibr")
17175 (set_attr "modrm" "0")
17176 (set (attr "length")
17177 (if_then_else
17178 (and (ge (minus (match_dup 0) (pc))
17179 (const_int -126))
17180 (lt (minus (match_dup 0) (pc))
17181 (const_int 128)))
17182 (const_int 2)
17183 (const_int 5)))])
17184
17185 (define_expand "indirect_jump"
17186 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
17187 ""
17188 {
17189 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17190 operands[0] = convert_memory_address (word_mode, operands[0]);
17191 cfun->machine->has_local_indirect_jump = true;
17192 })
17193
17194 (define_insn "*indirect_jump"
17195 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
17196 ""
17197 "* return ix86_output_indirect_jmp (operands[0]);"
17198 [(set (attr "type")
17199 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17200 != indirect_branch_keep)")
17201 (const_string "multi")
17202 (const_string "ibr")))
17203 (set_attr "length_immediate" "0")])
17204
17205 (define_expand "tablejump"
17206 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
17207 (use (label_ref (match_operand 1)))])]
17208 ""
17209 {
17210 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
17211 relative. Convert the relative address to an absolute address. */
17212 if (flag_pic)
17213 {
17214 rtx op0, op1;
17215 enum rtx_code code;
17216
17217 /* We can't use @GOTOFF for text labels on VxWorks;
17218 see gotoff_operand. */
17219 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
17220 {
17221 code = PLUS;
17222 op0 = operands[0];
17223 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
17224 }
17225 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
17226 {
17227 code = PLUS;
17228 op0 = operands[0];
17229 op1 = pic_offset_table_rtx;
17230 }
17231 else
17232 {
17233 code = MINUS;
17234 op0 = pic_offset_table_rtx;
17235 op1 = operands[0];
17236 }
17237
17238 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17239 OPTAB_DIRECT);
17240 }
17241
17242 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17243 operands[0] = convert_memory_address (word_mode, operands[0]);
17244 cfun->machine->has_local_indirect_jump = true;
17245 })
17246
17247 (define_insn "*tablejump_1"
17248 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17249 (use (label_ref (match_operand 1)))]
17250 ""
17251 "* return ix86_output_indirect_jmp (operands[0]);"
17252 [(set (attr "type")
17253 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17254 != indirect_branch_keep)")
17255 (const_string "multi")
17256 (const_string "ibr")))
17257 (set_attr "length_immediate" "0")])
17258 \f
17259 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17260
17261 (define_peephole2
17262 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17263 (set (match_operand:QI 1 "register_operand")
17264 (match_operator:QI 2 "ix86_comparison_operator"
17265 [(reg FLAGS_REG) (const_int 0)]))
17266 (set (match_operand 3 "any_QIreg_operand")
17267 (zero_extend (match_dup 1)))]
17268 "(peep2_reg_dead_p (3, operands[1])
17269 || operands_match_p (operands[1], operands[3]))
17270 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17271 && peep2_regno_dead_p (0, FLAGS_REG)"
17272 [(set (match_dup 4) (match_dup 0))
17273 (set (strict_low_part (match_dup 5))
17274 (match_dup 2))]
17275 {
17276 operands[5] = gen_lowpart (QImode, operands[3]);
17277 ix86_expand_clear (operands[3]);
17278 })
17279
17280 (define_peephole2
17281 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17282 (match_operand 4)])
17283 (set (match_operand:QI 1 "register_operand")
17284 (match_operator:QI 2 "ix86_comparison_operator"
17285 [(reg FLAGS_REG) (const_int 0)]))
17286 (set (match_operand 3 "any_QIreg_operand")
17287 (zero_extend (match_dup 1)))]
17288 "(peep2_reg_dead_p (3, operands[1])
17289 || operands_match_p (operands[1], operands[3]))
17290 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17291 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17292 && ! reg_set_p (operands[3], operands[4])
17293 && peep2_regno_dead_p (0, FLAGS_REG)"
17294 [(parallel [(set (match_dup 5) (match_dup 0))
17295 (match_dup 4)])
17296 (set (strict_low_part (match_dup 6))
17297 (match_dup 2))]
17298 {
17299 operands[6] = gen_lowpart (QImode, operands[3]);
17300 ix86_expand_clear (operands[3]);
17301 })
17302
17303 (define_peephole2
17304 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17305 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17306 (match_operand 5)])
17307 (set (match_operand:QI 2 "register_operand")
17308 (match_operator:QI 3 "ix86_comparison_operator"
17309 [(reg FLAGS_REG) (const_int 0)]))
17310 (set (match_operand 4 "any_QIreg_operand")
17311 (zero_extend (match_dup 2)))]
17312 "(peep2_reg_dead_p (4, operands[2])
17313 || operands_match_p (operands[2], operands[4]))
17314 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17315 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17316 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17317 && ! reg_set_p (operands[4], operands[5])
17318 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17319 && peep2_regno_dead_p (0, FLAGS_REG)"
17320 [(set (match_dup 6) (match_dup 0))
17321 (parallel [(set (match_dup 7) (match_dup 1))
17322 (match_dup 5)])
17323 (set (strict_low_part (match_dup 8))
17324 (match_dup 3))]
17325 {
17326 operands[8] = gen_lowpart (QImode, operands[4]);
17327 ix86_expand_clear (operands[4]);
17328 })
17329
17330 ;; Similar, but match zero extend with andsi3.
17331
17332 (define_peephole2
17333 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17334 (set (match_operand:QI 1 "register_operand")
17335 (match_operator:QI 2 "ix86_comparison_operator"
17336 [(reg FLAGS_REG) (const_int 0)]))
17337 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17338 (and:SI (match_dup 3) (const_int 255)))
17339 (clobber (reg:CC FLAGS_REG))])]
17340 "REGNO (operands[1]) == REGNO (operands[3])
17341 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17342 && peep2_regno_dead_p (0, FLAGS_REG)"
17343 [(set (match_dup 4) (match_dup 0))
17344 (set (strict_low_part (match_dup 5))
17345 (match_dup 2))]
17346 {
17347 operands[5] = gen_lowpart (QImode, operands[3]);
17348 ix86_expand_clear (operands[3]);
17349 })
17350
17351 (define_peephole2
17352 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17353 (match_operand 4)])
17354 (set (match_operand:QI 1 "register_operand")
17355 (match_operator:QI 2 "ix86_comparison_operator"
17356 [(reg FLAGS_REG) (const_int 0)]))
17357 (parallel [(set (match_operand 3 "any_QIreg_operand")
17358 (zero_extend (match_dup 1)))
17359 (clobber (reg:CC FLAGS_REG))])]
17360 "(peep2_reg_dead_p (3, operands[1])
17361 || operands_match_p (operands[1], operands[3]))
17362 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17363 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17364 && ! reg_set_p (operands[3], operands[4])
17365 && peep2_regno_dead_p (0, FLAGS_REG)"
17366 [(parallel [(set (match_dup 5) (match_dup 0))
17367 (match_dup 4)])
17368 (set (strict_low_part (match_dup 6))
17369 (match_dup 2))]
17370 {
17371 operands[6] = gen_lowpart (QImode, operands[3]);
17372 ix86_expand_clear (operands[3]);
17373 })
17374
17375 (define_peephole2
17376 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17377 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17378 (match_operand 5)])
17379 (set (match_operand:QI 2 "register_operand")
17380 (match_operator:QI 3 "ix86_comparison_operator"
17381 [(reg FLAGS_REG) (const_int 0)]))
17382 (parallel [(set (match_operand 4 "any_QIreg_operand")
17383 (zero_extend (match_dup 2)))
17384 (clobber (reg:CC FLAGS_REG))])]
17385 "(peep2_reg_dead_p (4, operands[2])
17386 || operands_match_p (operands[2], operands[4]))
17387 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17388 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17389 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17390 && ! reg_set_p (operands[4], operands[5])
17391 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17392 && peep2_regno_dead_p (0, FLAGS_REG)"
17393 [(set (match_dup 6) (match_dup 0))
17394 (parallel [(set (match_dup 7) (match_dup 1))
17395 (match_dup 5)])
17396 (set (strict_low_part (match_dup 8))
17397 (match_dup 3))]
17398 {
17399 operands[8] = gen_lowpart (QImode, operands[4]);
17400 ix86_expand_clear (operands[4]);
17401 })
17402 \f
17403 ;; Call instructions.
17404
17405 ;; The predicates normally associated with named expanders are not properly
17406 ;; checked for calls. This is a bug in the generic code, but it isn't that
17407 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17408
17409 ;; P6 processors will jump to the address after the decrement when %esp
17410 ;; is used as a call operand, so they will execute return address as a code.
17411 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17412
17413 ;; Register constraint for call instruction.
17414 (define_mode_attr c [(SI "l") (DI "r")])
17415
17416 ;; Call subroutine returning no value.
17417
17418 (define_expand "call"
17419 [(call (match_operand:QI 0)
17420 (match_operand 1))
17421 (use (match_operand 2))]
17422 ""
17423 {
17424 ix86_expand_call (NULL, operands[0], operands[1],
17425 operands[2], NULL, false);
17426 DONE;
17427 })
17428
17429 (define_expand "sibcall"
17430 [(call (match_operand:QI 0)
17431 (match_operand 1))
17432 (use (match_operand 2))]
17433 ""
17434 {
17435 ix86_expand_call (NULL, operands[0], operands[1],
17436 operands[2], NULL, true);
17437 DONE;
17438 })
17439
17440 (define_insn "*call"
17441 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17442 (match_operand 1))]
17443 "!SIBLING_CALL_P (insn)"
17444 "* return ix86_output_call_insn (insn, operands[0]);"
17445 [(set_attr "type" "call")])
17446
17447 ;; This covers both call and sibcall since only GOT slot is allowed.
17448 (define_insn "*call_got_x32"
17449 [(call (mem:QI (zero_extend:DI
17450 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17451 (match_operand 1))]
17452 "TARGET_X32"
17453 {
17454 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17455 return ix86_output_call_insn (insn, fnaddr);
17456 }
17457 [(set_attr "type" "call")])
17458
17459 ;; Since sibcall never returns, we can only use call-clobbered register
17460 ;; as GOT base.
17461 (define_insn "*sibcall_GOT_32"
17462 [(call (mem:QI
17463 (mem:SI (plus:SI
17464 (match_operand:SI 0 "register_no_elim_operand" "U")
17465 (match_operand:SI 1 "GOT32_symbol_operand"))))
17466 (match_operand 2))]
17467 "!TARGET_MACHO
17468 && !TARGET_64BIT
17469 && !TARGET_INDIRECT_BRANCH_REGISTER
17470 && SIBLING_CALL_P (insn)"
17471 {
17472 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17473 fnaddr = gen_const_mem (SImode, fnaddr);
17474 return ix86_output_call_insn (insn, fnaddr);
17475 }
17476 [(set_attr "type" "call")])
17477
17478 (define_insn "*sibcall"
17479 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17480 (match_operand 1))]
17481 "SIBLING_CALL_P (insn)"
17482 "* return ix86_output_call_insn (insn, operands[0]);"
17483 [(set_attr "type" "call")])
17484
17485 (define_insn "*sibcall_memory"
17486 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17487 (match_operand 1))
17488 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17489 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17490 "* return ix86_output_call_insn (insn, operands[0]);"
17491 [(set_attr "type" "call")])
17492
17493 (define_peephole2
17494 [(set (match_operand:W 0 "register_operand")
17495 (match_operand:W 1 "memory_operand"))
17496 (call (mem:QI (match_dup 0))
17497 (match_operand 3))]
17498 "!TARGET_X32
17499 && !TARGET_INDIRECT_BRANCH_REGISTER
17500 && SIBLING_CALL_P (peep2_next_insn (1))
17501 && !reg_mentioned_p (operands[0],
17502 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17503 [(parallel [(call (mem:QI (match_dup 1))
17504 (match_dup 3))
17505 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17506
17507 (define_peephole2
17508 [(set (match_operand:W 0 "register_operand")
17509 (match_operand:W 1 "memory_operand"))
17510 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17511 (call (mem:QI (match_dup 0))
17512 (match_operand 3))]
17513 "!TARGET_X32
17514 && !TARGET_INDIRECT_BRANCH_REGISTER
17515 && SIBLING_CALL_P (peep2_next_insn (2))
17516 && !reg_mentioned_p (operands[0],
17517 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17518 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17519 (parallel [(call (mem:QI (match_dup 1))
17520 (match_dup 3))
17521 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17522
17523 (define_expand "call_pop"
17524 [(parallel [(call (match_operand:QI 0)
17525 (match_operand:SI 1))
17526 (set (reg:SI SP_REG)
17527 (plus:SI (reg:SI SP_REG)
17528 (match_operand:SI 3)))])]
17529 "!TARGET_64BIT"
17530 {
17531 ix86_expand_call (NULL, operands[0], operands[1],
17532 operands[2], operands[3], false);
17533 DONE;
17534 })
17535
17536 (define_insn "*call_pop"
17537 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17538 (match_operand 1))
17539 (set (reg:SI SP_REG)
17540 (plus:SI (reg:SI SP_REG)
17541 (match_operand:SI 2 "immediate_operand" "i")))]
17542 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17543 "* return ix86_output_call_insn (insn, operands[0]);"
17544 [(set_attr "type" "call")])
17545
17546 (define_insn "*sibcall_pop"
17547 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17548 (match_operand 1))
17549 (set (reg:SI SP_REG)
17550 (plus:SI (reg:SI SP_REG)
17551 (match_operand:SI 2 "immediate_operand" "i")))]
17552 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17553 "* return ix86_output_call_insn (insn, operands[0]);"
17554 [(set_attr "type" "call")])
17555
17556 (define_insn "*sibcall_pop_memory"
17557 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17558 (match_operand 1))
17559 (set (reg:SI SP_REG)
17560 (plus:SI (reg:SI SP_REG)
17561 (match_operand:SI 2 "immediate_operand" "i")))
17562 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17563 "!TARGET_64BIT"
17564 "* return ix86_output_call_insn (insn, operands[0]);"
17565 [(set_attr "type" "call")])
17566
17567 (define_peephole2
17568 [(set (match_operand:SI 0 "register_operand")
17569 (match_operand:SI 1 "memory_operand"))
17570 (parallel [(call (mem:QI (match_dup 0))
17571 (match_operand 3))
17572 (set (reg:SI SP_REG)
17573 (plus:SI (reg:SI SP_REG)
17574 (match_operand:SI 4 "immediate_operand")))])]
17575 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17576 && !reg_mentioned_p (operands[0],
17577 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17578 [(parallel [(call (mem:QI (match_dup 1))
17579 (match_dup 3))
17580 (set (reg:SI SP_REG)
17581 (plus:SI (reg:SI SP_REG)
17582 (match_dup 4)))
17583 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17584
17585 (define_peephole2
17586 [(set (match_operand:SI 0 "register_operand")
17587 (match_operand:SI 1 "memory_operand"))
17588 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17589 (parallel [(call (mem:QI (match_dup 0))
17590 (match_operand 3))
17591 (set (reg:SI SP_REG)
17592 (plus:SI (reg:SI SP_REG)
17593 (match_operand:SI 4 "immediate_operand")))])]
17594 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17595 && !reg_mentioned_p (operands[0],
17596 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17597 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17598 (parallel [(call (mem:QI (match_dup 1))
17599 (match_dup 3))
17600 (set (reg:SI SP_REG)
17601 (plus:SI (reg:SI SP_REG)
17602 (match_dup 4)))
17603 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17604
17605 ;; Combining simple memory jump instruction
17606
17607 (define_peephole2
17608 [(set (match_operand:W 0 "register_operand")
17609 (match_operand:W 1 "memory_operand"))
17610 (set (pc) (match_dup 0))]
17611 "!TARGET_X32
17612 && !TARGET_INDIRECT_BRANCH_REGISTER
17613 && peep2_reg_dead_p (2, operands[0])"
17614 [(set (pc) (match_dup 1))])
17615
17616 ;; Call subroutine, returning value in operand 0
17617
17618 (define_expand "call_value"
17619 [(set (match_operand 0)
17620 (call (match_operand:QI 1)
17621 (match_operand 2)))
17622 (use (match_operand 3))]
17623 ""
17624 {
17625 ix86_expand_call (operands[0], operands[1], operands[2],
17626 operands[3], NULL, false);
17627 DONE;
17628 })
17629
17630 (define_expand "sibcall_value"
17631 [(set (match_operand 0)
17632 (call (match_operand:QI 1)
17633 (match_operand 2)))
17634 (use (match_operand 3))]
17635 ""
17636 {
17637 ix86_expand_call (operands[0], operands[1], operands[2],
17638 operands[3], NULL, true);
17639 DONE;
17640 })
17641
17642 (define_insn "*call_value"
17643 [(set (match_operand 0)
17644 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17645 (match_operand 2)))]
17646 "!SIBLING_CALL_P (insn)"
17647 "* return ix86_output_call_insn (insn, operands[1]);"
17648 [(set_attr "type" "callv")])
17649
17650 ;; This covers both call and sibcall since only GOT slot is allowed.
17651 (define_insn "*call_value_got_x32"
17652 [(set (match_operand 0)
17653 (call (mem:QI
17654 (zero_extend:DI
17655 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17656 (match_operand 2)))]
17657 "TARGET_X32"
17658 {
17659 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17660 return ix86_output_call_insn (insn, fnaddr);
17661 }
17662 [(set_attr "type" "callv")])
17663
17664 ;; Since sibcall never returns, we can only use call-clobbered register
17665 ;; as GOT base.
17666 (define_insn "*sibcall_value_GOT_32"
17667 [(set (match_operand 0)
17668 (call (mem:QI
17669 (mem:SI (plus:SI
17670 (match_operand:SI 1 "register_no_elim_operand" "U")
17671 (match_operand:SI 2 "GOT32_symbol_operand"))))
17672 (match_operand 3)))]
17673 "!TARGET_MACHO
17674 && !TARGET_64BIT
17675 && !TARGET_INDIRECT_BRANCH_REGISTER
17676 && SIBLING_CALL_P (insn)"
17677 {
17678 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17679 fnaddr = gen_const_mem (SImode, fnaddr);
17680 return ix86_output_call_insn (insn, fnaddr);
17681 }
17682 [(set_attr "type" "callv")])
17683
17684 (define_insn "*sibcall_value"
17685 [(set (match_operand 0)
17686 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17687 (match_operand 2)))]
17688 "SIBLING_CALL_P (insn)"
17689 "* return ix86_output_call_insn (insn, operands[1]);"
17690 [(set_attr "type" "callv")])
17691
17692 (define_insn "*sibcall_value_memory"
17693 [(set (match_operand 0)
17694 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17695 (match_operand 2)))
17696 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17697 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17698 "* return ix86_output_call_insn (insn, operands[1]);"
17699 [(set_attr "type" "callv")])
17700
17701 (define_peephole2
17702 [(set (match_operand:W 0 "register_operand")
17703 (match_operand:W 1 "memory_operand"))
17704 (set (match_operand 2)
17705 (call (mem:QI (match_dup 0))
17706 (match_operand 3)))]
17707 "!TARGET_X32
17708 && !TARGET_INDIRECT_BRANCH_REGISTER
17709 && SIBLING_CALL_P (peep2_next_insn (1))
17710 && !reg_mentioned_p (operands[0],
17711 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17712 [(parallel [(set (match_dup 2)
17713 (call (mem:QI (match_dup 1))
17714 (match_dup 3)))
17715 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17716
17717 (define_peephole2
17718 [(set (match_operand:W 0 "register_operand")
17719 (match_operand:W 1 "memory_operand"))
17720 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17721 (set (match_operand 2)
17722 (call (mem:QI (match_dup 0))
17723 (match_operand 3)))]
17724 "!TARGET_X32
17725 && !TARGET_INDIRECT_BRANCH_REGISTER
17726 && SIBLING_CALL_P (peep2_next_insn (2))
17727 && !reg_mentioned_p (operands[0],
17728 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17729 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17730 (parallel [(set (match_dup 2)
17731 (call (mem:QI (match_dup 1))
17732 (match_dup 3)))
17733 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17734
17735 (define_expand "call_value_pop"
17736 [(parallel [(set (match_operand 0)
17737 (call (match_operand:QI 1)
17738 (match_operand:SI 2)))
17739 (set (reg:SI SP_REG)
17740 (plus:SI (reg:SI SP_REG)
17741 (match_operand:SI 4)))])]
17742 "!TARGET_64BIT"
17743 {
17744 ix86_expand_call (operands[0], operands[1], operands[2],
17745 operands[3], operands[4], false);
17746 DONE;
17747 })
17748
17749 (define_insn "*call_value_pop"
17750 [(set (match_operand 0)
17751 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17752 (match_operand 2)))
17753 (set (reg:SI SP_REG)
17754 (plus:SI (reg:SI SP_REG)
17755 (match_operand:SI 3 "immediate_operand" "i")))]
17756 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17757 "* return ix86_output_call_insn (insn, operands[1]);"
17758 [(set_attr "type" "callv")])
17759
17760 (define_insn "*sibcall_value_pop"
17761 [(set (match_operand 0)
17762 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17763 (match_operand 2)))
17764 (set (reg:SI SP_REG)
17765 (plus:SI (reg:SI SP_REG)
17766 (match_operand:SI 3 "immediate_operand" "i")))]
17767 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17768 "* return ix86_output_call_insn (insn, operands[1]);"
17769 [(set_attr "type" "callv")])
17770
17771 (define_insn "*sibcall_value_pop_memory"
17772 [(set (match_operand 0)
17773 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17774 (match_operand 2)))
17775 (set (reg:SI SP_REG)
17776 (plus:SI (reg:SI SP_REG)
17777 (match_operand:SI 3 "immediate_operand" "i")))
17778 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17779 "!TARGET_64BIT"
17780 "* return ix86_output_call_insn (insn, operands[1]);"
17781 [(set_attr "type" "callv")])
17782
17783 (define_peephole2
17784 [(set (match_operand:SI 0 "register_operand")
17785 (match_operand:SI 1 "memory_operand"))
17786 (parallel [(set (match_operand 2)
17787 (call (mem:QI (match_dup 0))
17788 (match_operand 3)))
17789 (set (reg:SI SP_REG)
17790 (plus:SI (reg:SI SP_REG)
17791 (match_operand:SI 4 "immediate_operand")))])]
17792 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17793 && !reg_mentioned_p (operands[0],
17794 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17795 [(parallel [(set (match_dup 2)
17796 (call (mem:QI (match_dup 1))
17797 (match_dup 3)))
17798 (set (reg:SI SP_REG)
17799 (plus:SI (reg:SI SP_REG)
17800 (match_dup 4)))
17801 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17802
17803 (define_peephole2
17804 [(set (match_operand:SI 0 "register_operand")
17805 (match_operand:SI 1 "memory_operand"))
17806 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17807 (parallel [(set (match_operand 2)
17808 (call (mem:QI (match_dup 0))
17809 (match_operand 3)))
17810 (set (reg:SI SP_REG)
17811 (plus:SI (reg:SI SP_REG)
17812 (match_operand:SI 4 "immediate_operand")))])]
17813 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17814 && !reg_mentioned_p (operands[0],
17815 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17816 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17817 (parallel [(set (match_dup 2)
17818 (call (mem:QI (match_dup 1))
17819 (match_dup 3)))
17820 (set (reg:SI SP_REG)
17821 (plus:SI (reg:SI SP_REG)
17822 (match_dup 4)))
17823 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17824
17825 ;; Call subroutine returning any type.
17826
17827 (define_expand "untyped_call"
17828 [(parallel [(call (match_operand 0)
17829 (const_int 0))
17830 (match_operand 1)
17831 (match_operand 2)])]
17832 ""
17833 {
17834 int i;
17835
17836 /* In order to give reg-stack an easier job in validating two
17837 coprocessor registers as containing a possible return value,
17838 simply pretend the untyped call returns a complex long double
17839 value.
17840
17841 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17842 and should have the default ABI. */
17843
17844 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17845 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17846 operands[0], const0_rtx,
17847 GEN_INT ((TARGET_64BIT
17848 ? (ix86_abi == SYSV_ABI
17849 ? X86_64_SSE_REGPARM_MAX
17850 : X86_64_MS_SSE_REGPARM_MAX)
17851 : X86_32_SSE_REGPARM_MAX)
17852 - 1),
17853 NULL, false);
17854
17855 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17856 {
17857 rtx set = XVECEXP (operands[2], 0, i);
17858 emit_move_insn (SET_DEST (set), SET_SRC (set));
17859 }
17860
17861 /* The optimizer does not know that the call sets the function value
17862 registers we stored in the result block. We avoid problems by
17863 claiming that all hard registers are used and clobbered at this
17864 point. */
17865 emit_insn (gen_blockage ());
17866
17867 DONE;
17868 })
17869 \f
17870 ;; Prologue and epilogue instructions
17871
17872 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17873 ;; all of memory. This blocks insns from being moved across this point.
17874
17875 (define_insn "blockage"
17876 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17877 ""
17878 ""
17879 [(set_attr "length" "0")])
17880
17881 ;; Do not schedule instructions accessing memory across this point.
17882
17883 (define_expand "memory_blockage"
17884 [(set (match_dup 0)
17885 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17886 ""
17887 {
17888 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17889 MEM_VOLATILE_P (operands[0]) = 1;
17890 })
17891
17892 (define_insn "*memory_blockage"
17893 [(set (match_operand:BLK 0)
17894 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17895 ""
17896 ""
17897 [(set_attr "length" "0")])
17898
17899 ;; As USE insns aren't meaningful after reload, this is used instead
17900 ;; to prevent deleting instructions setting registers for PIC code
17901 (define_insn "prologue_use"
17902 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17903 ""
17904 ""
17905 [(set_attr "length" "0")])
17906
17907 ;; Insn emitted into the body of a function to return from a function.
17908 ;; This is only done if the function's epilogue is known to be simple.
17909 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17910
17911 (define_expand "return"
17912 [(simple_return)]
17913 "ix86_can_use_return_insn_p ()"
17914 {
17915 if (crtl->args.pops_args)
17916 {
17917 rtx popc = GEN_INT (crtl->args.pops_args);
17918 emit_jump_insn (gen_simple_return_pop_internal (popc));
17919 DONE;
17920 }
17921 })
17922
17923 ;; We need to disable this for TARGET_SEH, as otherwise
17924 ;; shrink-wrapped prologue gets enabled too. This might exceed
17925 ;; the maximum size of prologue in unwind information.
17926 ;; Also disallow shrink-wrapping if using stack slot to pass the
17927 ;; static chain pointer - the first instruction has to be pushl %esi
17928 ;; and it can't be moved around, as we use alternate entry points
17929 ;; in that case.
17930 ;; Also disallow for ms_hook_prologue functions which have frame
17931 ;; pointer set up in function label which is correctly handled in
17932 ;; ix86_expand_{prologue|epligoue}() only.
17933
17934 (define_expand "simple_return"
17935 [(simple_return)]
17936 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17937 {
17938 if (crtl->args.pops_args)
17939 {
17940 rtx popc = GEN_INT (crtl->args.pops_args);
17941 emit_jump_insn (gen_simple_return_pop_internal (popc));
17942 DONE;
17943 }
17944 })
17945
17946 (define_insn "simple_return_internal"
17947 [(simple_return)]
17948 "reload_completed"
17949 "* return ix86_output_function_return (false);"
17950 [(set_attr "length" "1")
17951 (set_attr "atom_unit" "jeu")
17952 (set_attr "length_immediate" "0")
17953 (set_attr "modrm" "0")])
17954
17955 (define_insn "interrupt_return"
17956 [(simple_return)
17957 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17958 "reload_completed"
17959 {
17960 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17961 })
17962
17963 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17964 ;; instruction Athlon and K8 have.
17965
17966 (define_insn "simple_return_internal_long"
17967 [(simple_return)
17968 (unspec [(const_int 0)] UNSPEC_REP)]
17969 "reload_completed"
17970 "* return ix86_output_function_return (true);"
17971 [(set_attr "length" "2")
17972 (set_attr "atom_unit" "jeu")
17973 (set_attr "length_immediate" "0")
17974 (set_attr "prefix_rep" "1")
17975 (set_attr "modrm" "0")])
17976
17977 (define_insn_and_split "simple_return_pop_internal"
17978 [(simple_return)
17979 (use (match_operand:SI 0 "const_int_operand"))]
17980 "reload_completed"
17981 "ret\t%0"
17982 "&& cfun->machine->function_return_type != indirect_branch_keep"
17983 [(const_int 0)]
17984 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17985 [(set_attr "length" "3")
17986 (set_attr "atom_unit" "jeu")
17987 (set_attr "length_immediate" "2")
17988 (set_attr "modrm" "0")])
17989
17990 (define_expand "simple_return_indirect_internal"
17991 [(parallel
17992 [(simple_return)
17993 (use (match_operand 0 "register_operand"))])])
17994
17995 (define_insn "*simple_return_indirect_internal<mode>"
17996 [(simple_return)
17997 (use (match_operand:W 0 "register_operand" "r"))]
17998 "reload_completed"
17999 "* return ix86_output_indirect_function_return (operands[0]);"
18000 [(set (attr "type")
18001 (if_then_else (match_test "(cfun->machine->indirect_branch_type
18002 != indirect_branch_keep)")
18003 (const_string "multi")
18004 (const_string "ibr")))
18005 (set_attr "length_immediate" "0")])
18006
18007 (define_insn "nop"
18008 [(const_int 0)]
18009 ""
18010 "nop"
18011 [(set_attr "length" "1")
18012 (set_attr "length_immediate" "0")
18013 (set_attr "modrm" "0")])
18014
18015 ;; Generate nops. Operand 0 is the number of nops, up to 8.
18016 (define_insn "nops"
18017 [(unspec_volatile [(match_operand 0 "const_int_operand")]
18018 UNSPECV_NOPS)]
18019 "reload_completed"
18020 {
18021 int num = INTVAL (operands[0]);
18022
18023 gcc_assert (IN_RANGE (num, 1, 8));
18024
18025 while (num--)
18026 fputs ("\tnop\n", asm_out_file);
18027
18028 return "";
18029 }
18030 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
18031 (set_attr "length_immediate" "0")
18032 (set_attr "modrm" "0")])
18033
18034 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
18035 ;; branch prediction penalty for the third jump in a 16-byte
18036 ;; block on K8.
18037
18038 (define_insn "pad"
18039 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
18040 ""
18041 {
18042 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
18043 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
18044 #else
18045 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
18046 The align insn is used to avoid 3 jump instructions in the row to improve
18047 branch prediction and the benefits hardly outweigh the cost of extra 8
18048 nops on the average inserted by full alignment pseudo operation. */
18049 #endif
18050 return "";
18051 }
18052 [(set_attr "length" "16")])
18053
18054 (define_expand "prologue"
18055 [(const_int 0)]
18056 ""
18057 "ix86_expand_prologue (); DONE;")
18058
18059 (define_expand "set_got"
18060 [(parallel
18061 [(set (match_operand:SI 0 "register_operand")
18062 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
18063 (clobber (reg:CC FLAGS_REG))])]
18064 "!TARGET_64BIT"
18065 {
18066 if (flag_pic && !TARGET_VXWORKS_RTP)
18067 ix86_pc_thunk_call_expanded = true;
18068 })
18069
18070 (define_insn "*set_got"
18071 [(set (match_operand:SI 0 "register_operand" "=r")
18072 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
18073 (clobber (reg:CC FLAGS_REG))]
18074 "!TARGET_64BIT"
18075 "* return output_set_got (operands[0], NULL_RTX);"
18076 [(set_attr "type" "multi")
18077 (set_attr "length" "12")])
18078
18079 (define_expand "set_got_labelled"
18080 [(parallel
18081 [(set (match_operand:SI 0 "register_operand")
18082 (unspec:SI [(label_ref (match_operand 1))]
18083 UNSPEC_SET_GOT))
18084 (clobber (reg:CC FLAGS_REG))])]
18085 "!TARGET_64BIT"
18086 {
18087 if (flag_pic && !TARGET_VXWORKS_RTP)
18088 ix86_pc_thunk_call_expanded = true;
18089 })
18090
18091 (define_insn "*set_got_labelled"
18092 [(set (match_operand:SI 0 "register_operand" "=r")
18093 (unspec:SI [(label_ref (match_operand 1))]
18094 UNSPEC_SET_GOT))
18095 (clobber (reg:CC FLAGS_REG))]
18096 "!TARGET_64BIT"
18097 "* return output_set_got (operands[0], operands[1]);"
18098 [(set_attr "type" "multi")
18099 (set_attr "length" "12")])
18100
18101 (define_insn "set_got_rex64"
18102 [(set (match_operand:DI 0 "register_operand" "=r")
18103 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
18104 "TARGET_64BIT"
18105 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
18106 [(set_attr "type" "lea")
18107 (set_attr "length_address" "4")
18108 (set_attr "mode" "DI")])
18109
18110 (define_insn "set_rip_rex64"
18111 [(set (match_operand:DI 0 "register_operand" "=r")
18112 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
18113 "TARGET_64BIT"
18114 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
18115 [(set_attr "type" "lea")
18116 (set_attr "length_address" "4")
18117 (set_attr "mode" "DI")])
18118
18119 (define_insn "set_got_offset_rex64"
18120 [(set (match_operand:DI 0 "register_operand" "=r")
18121 (unspec:DI
18122 [(label_ref (match_operand 1))]
18123 UNSPEC_SET_GOT_OFFSET))]
18124 "TARGET_LP64"
18125 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
18126 [(set_attr "type" "imov")
18127 (set_attr "length_immediate" "0")
18128 (set_attr "length_address" "8")
18129 (set_attr "mode" "DI")])
18130
18131 (define_expand "epilogue"
18132 [(const_int 0)]
18133 ""
18134 "ix86_expand_epilogue (1); DONE;")
18135
18136 (define_expand "sibcall_epilogue"
18137 [(const_int 0)]
18138 ""
18139 "ix86_expand_epilogue (0); DONE;")
18140
18141 (define_expand "eh_return"
18142 [(use (match_operand 0 "register_operand"))]
18143 ""
18144 {
18145 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
18146
18147 /* Tricky bit: we write the address of the handler to which we will
18148 be returning into someone else's stack frame, one word below the
18149 stack address we wish to restore. */
18150 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
18151 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
18152 /* Return address is always in word_mode. */
18153 tmp = gen_rtx_MEM (word_mode, tmp);
18154 if (GET_MODE (ra) != word_mode)
18155 ra = convert_to_mode (word_mode, ra, 1);
18156 emit_move_insn (tmp, ra);
18157
18158 emit_jump_insn (gen_eh_return_internal ());
18159 emit_barrier ();
18160 DONE;
18161 })
18162
18163 (define_insn_and_split "eh_return_internal"
18164 [(eh_return)]
18165 ""
18166 "#"
18167 "epilogue_completed"
18168 [(const_int 0)]
18169 "ix86_expand_epilogue (2); DONE;")
18170
18171 (define_expand "@leave_<mode>"
18172 [(parallel
18173 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
18174 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
18175 (clobber (mem:BLK (scratch)))])]
18176 ""
18177 "operands[0] = GEN_INT (<MODE_SIZE>);")
18178
18179 (define_insn "*leave"
18180 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
18181 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
18182 (clobber (mem:BLK (scratch)))]
18183 "!TARGET_64BIT"
18184 "leave"
18185 [(set_attr "type" "leave")])
18186
18187 (define_insn "*leave_rex64"
18188 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
18189 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
18190 (clobber (mem:BLK (scratch)))]
18191 "TARGET_64BIT"
18192 "leave"
18193 [(set_attr "type" "leave")])
18194 \f
18195 ;; Handle -fsplit-stack.
18196
18197 (define_expand "split_stack_prologue"
18198 [(const_int 0)]
18199 ""
18200 {
18201 ix86_expand_split_stack_prologue ();
18202 DONE;
18203 })
18204
18205 ;; In order to support the call/return predictor, we use a return
18206 ;; instruction which the middle-end doesn't see.
18207 (define_insn "split_stack_return"
18208 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
18209 UNSPECV_SPLIT_STACK_RETURN)]
18210 ""
18211 {
18212 if (operands[0] == const0_rtx)
18213 return "ret";
18214 else
18215 return "ret\t%0";
18216 }
18217 [(set_attr "atom_unit" "jeu")
18218 (set_attr "modrm" "0")
18219 (set (attr "length")
18220 (if_then_else (match_operand:SI 0 "const0_operand")
18221 (const_int 1)
18222 (const_int 3)))
18223 (set (attr "length_immediate")
18224 (if_then_else (match_operand:SI 0 "const0_operand")
18225 (const_int 0)
18226 (const_int 2)))])
18227
18228 ;; If there are operand 0 bytes available on the stack, jump to
18229 ;; operand 1.
18230
18231 (define_expand "split_stack_space_check"
18232 [(set (pc) (if_then_else
18233 (ltu (minus (reg SP_REG)
18234 (match_operand 0 "register_operand"))
18235 (match_dup 2))
18236 (label_ref (match_operand 1))
18237 (pc)))]
18238 ""
18239 {
18240 rtx reg = gen_reg_rtx (Pmode);
18241
18242 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18243
18244 operands[2] = ix86_split_stack_guard ();
18245 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18246
18247 DONE;
18248 })
18249 \f
18250 ;; Bit manipulation instructions.
18251
18252 (define_expand "ffs<mode>2"
18253 [(set (match_dup 2) (const_int -1))
18254 (parallel [(set (match_dup 3) (match_dup 4))
18255 (set (match_operand:SWI48 0 "register_operand")
18256 (ctz:SWI48
18257 (match_operand:SWI48 1 "nonimmediate_operand")))])
18258 (set (match_dup 0) (if_then_else:SWI48
18259 (eq (match_dup 3) (const_int 0))
18260 (match_dup 2)
18261 (match_dup 0)))
18262 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18263 (clobber (reg:CC FLAGS_REG))])]
18264 ""
18265 {
18266 machine_mode flags_mode;
18267
18268 if (<MODE>mode == SImode && !TARGET_CMOVE)
18269 {
18270 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18271 DONE;
18272 }
18273
18274 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18275
18276 operands[2] = gen_reg_rtx (<MODE>mode);
18277 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18278 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18279 })
18280
18281 (define_insn_and_split "ffssi2_no_cmove"
18282 [(set (match_operand:SI 0 "register_operand" "=r")
18283 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18284 (clobber (match_scratch:SI 2 "=&q"))
18285 (clobber (reg:CC FLAGS_REG))]
18286 "!TARGET_CMOVE"
18287 "#"
18288 "&& reload_completed"
18289 [(parallel [(set (match_dup 4) (match_dup 5))
18290 (set (match_dup 0) (ctz:SI (match_dup 1)))])
18291 (set (strict_low_part (match_dup 3))
18292 (eq:QI (match_dup 4) (const_int 0)))
18293 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18294 (clobber (reg:CC FLAGS_REG))])
18295 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18296 (clobber (reg:CC FLAGS_REG))])
18297 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18298 (clobber (reg:CC FLAGS_REG))])]
18299 {
18300 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18301
18302 operands[3] = gen_lowpart (QImode, operands[2]);
18303 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18304 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18305
18306 ix86_expand_clear (operands[2]);
18307 })
18308
18309 (define_insn_and_split "*tzcnt<mode>_1"
18310 [(set (reg:CCC FLAGS_REG)
18311 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18312 (const_int 0)))
18313 (set (match_operand:SWI48 0 "register_operand" "=r")
18314 (ctz:SWI48 (match_dup 1)))]
18315 "TARGET_BMI"
18316 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18317 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18318 && optimize_function_for_speed_p (cfun)
18319 && !reg_mentioned_p (operands[0], operands[1])"
18320 [(parallel
18321 [(set (reg:CCC FLAGS_REG)
18322 (compare:CCC (match_dup 1) (const_int 0)))
18323 (set (match_dup 0)
18324 (ctz:SWI48 (match_dup 1)))
18325 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18326 "ix86_expand_clear (operands[0]);"
18327 [(set_attr "type" "alu1")
18328 (set_attr "prefix_0f" "1")
18329 (set_attr "prefix_rep" "1")
18330 (set_attr "btver2_decode" "double")
18331 (set_attr "mode" "<MODE>")])
18332
18333 ; False dependency happens when destination is only updated by tzcnt,
18334 ; lzcnt or popcnt. There is no false dependency when destination is
18335 ; also used in source.
18336 (define_insn "*tzcnt<mode>_1_falsedep"
18337 [(set (reg:CCC FLAGS_REG)
18338 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18339 (const_int 0)))
18340 (set (match_operand:SWI48 0 "register_operand" "=r")
18341 (ctz:SWI48 (match_dup 1)))
18342 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18343 UNSPEC_INSN_FALSE_DEP)]
18344 "TARGET_BMI"
18345 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18346 [(set_attr "type" "alu1")
18347 (set_attr "prefix_0f" "1")
18348 (set_attr "prefix_rep" "1")
18349 (set_attr "btver2_decode" "double")
18350 (set_attr "mode" "<MODE>")])
18351
18352 (define_insn "*bsf<mode>_1"
18353 [(set (reg:CCZ FLAGS_REG)
18354 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18355 (const_int 0)))
18356 (set (match_operand:SWI48 0 "register_operand" "=r")
18357 (ctz:SWI48 (match_dup 1)))]
18358 ""
18359 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18360 [(set_attr "type" "alu1")
18361 (set_attr "prefix_0f" "1")
18362 (set_attr "btver2_decode" "double")
18363 (set_attr "znver1_decode" "vector")
18364 (set_attr "mode" "<MODE>")])
18365
18366 (define_insn_and_split "ctz<mode>2"
18367 [(set (match_operand:SWI48 0 "register_operand" "=r")
18368 (ctz:SWI48
18369 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18370 (clobber (reg:CC FLAGS_REG))]
18371 ""
18372 {
18373 if (TARGET_BMI)
18374 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18375 else if (optimize_function_for_size_p (cfun))
18376 ;
18377 else if (TARGET_CPU_P (GENERIC))
18378 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18379 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18380
18381 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18382 }
18383 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18384 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18385 && optimize_function_for_speed_p (cfun)
18386 && !reg_mentioned_p (operands[0], operands[1])"
18387 [(parallel
18388 [(set (match_dup 0)
18389 (ctz:SWI48 (match_dup 1)))
18390 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18391 (clobber (reg:CC FLAGS_REG))])]
18392 "ix86_expand_clear (operands[0]);"
18393 [(set_attr "type" "alu1")
18394 (set_attr "prefix_0f" "1")
18395 (set (attr "prefix_rep")
18396 (if_then_else
18397 (ior (match_test "TARGET_BMI")
18398 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18399 (match_test "TARGET_CPU_P (GENERIC)")))
18400 (const_string "1")
18401 (const_string "0")))
18402 (set_attr "mode" "<MODE>")])
18403
18404 ; False dependency happens when destination is only updated by tzcnt,
18405 ; lzcnt or popcnt. There is no false dependency when destination is
18406 ; also used in source.
18407 (define_insn "*ctz<mode>2_falsedep"
18408 [(set (match_operand:SWI48 0 "register_operand" "=r")
18409 (ctz:SWI48
18410 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18411 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18412 UNSPEC_INSN_FALSE_DEP)
18413 (clobber (reg:CC FLAGS_REG))]
18414 ""
18415 {
18416 if (TARGET_BMI)
18417 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18418 else if (TARGET_CPU_P (GENERIC))
18419 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18420 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18421 else
18422 gcc_unreachable ();
18423 }
18424 [(set_attr "type" "alu1")
18425 (set_attr "prefix_0f" "1")
18426 (set_attr "prefix_rep" "1")
18427 (set_attr "mode" "<MODE>")])
18428
18429 (define_insn_and_split "*ctzsi2_zext"
18430 [(set (match_operand:DI 0 "register_operand" "=r")
18431 (and:DI
18432 (subreg:DI
18433 (ctz:SI
18434 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18435 (const_int 63)))
18436 (clobber (reg:CC FLAGS_REG))]
18437 "TARGET_BMI && TARGET_64BIT"
18438 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18439 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18440 && optimize_function_for_speed_p (cfun)
18441 && !reg_mentioned_p (operands[0], operands[1])"
18442 [(parallel
18443 [(set (match_dup 0)
18444 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18445 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18446 (clobber (reg:CC FLAGS_REG))])]
18447 "ix86_expand_clear (operands[0]);"
18448 [(set_attr "type" "alu1")
18449 (set_attr "prefix_0f" "1")
18450 (set_attr "prefix_rep" "1")
18451 (set_attr "mode" "SI")])
18452
18453 ; False dependency happens when destination is only updated by tzcnt,
18454 ; lzcnt or popcnt. There is no false dependency when destination is
18455 ; also used in source.
18456 (define_insn "*ctzsi2_zext_falsedep"
18457 [(set (match_operand:DI 0 "register_operand" "=r")
18458 (and:DI
18459 (subreg:DI
18460 (ctz:SI
18461 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18462 (const_int 63)))
18463 (unspec [(match_operand:DI 2 "register_operand" "0")]
18464 UNSPEC_INSN_FALSE_DEP)
18465 (clobber (reg:CC FLAGS_REG))]
18466 "TARGET_BMI && TARGET_64BIT"
18467 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18468 [(set_attr "type" "alu1")
18469 (set_attr "prefix_0f" "1")
18470 (set_attr "prefix_rep" "1")
18471 (set_attr "mode" "SI")])
18472
18473 (define_insn_and_split "*ctzsidi2_<s>ext"
18474 [(set (match_operand:DI 0 "register_operand" "=r")
18475 (any_extend:DI
18476 (ctz:SI
18477 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18478 (clobber (reg:CC FLAGS_REG))]
18479 "TARGET_64BIT"
18480 {
18481 if (TARGET_BMI)
18482 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18483 else if (TARGET_CPU_P (GENERIC)
18484 && !optimize_function_for_size_p (cfun))
18485 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18486 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18487 return "bsf{l}\t{%1, %k0|%k0, %1}";
18488 }
18489 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18490 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18491 && optimize_function_for_speed_p (cfun)
18492 && !reg_mentioned_p (operands[0], operands[1])"
18493 [(parallel
18494 [(set (match_dup 0)
18495 (any_extend:DI (ctz:SI (match_dup 1))))
18496 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18497 (clobber (reg:CC FLAGS_REG))])]
18498 "ix86_expand_clear (operands[0]);"
18499 [(set_attr "type" "alu1")
18500 (set_attr "prefix_0f" "1")
18501 (set (attr "prefix_rep")
18502 (if_then_else
18503 (ior (match_test "TARGET_BMI")
18504 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18505 (match_test "TARGET_CPU_P (GENERIC)")))
18506 (const_string "1")
18507 (const_string "0")))
18508 (set_attr "mode" "SI")])
18509
18510 (define_insn "*ctzsidi2_<s>ext_falsedep"
18511 [(set (match_operand:DI 0 "register_operand" "=r")
18512 (any_extend:DI
18513 (ctz:SI
18514 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18515 (unspec [(match_operand:DI 2 "register_operand" "0")]
18516 UNSPEC_INSN_FALSE_DEP)
18517 (clobber (reg:CC FLAGS_REG))]
18518 "TARGET_64BIT"
18519 {
18520 if (TARGET_BMI)
18521 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18522 else if (TARGET_CPU_P (GENERIC))
18523 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18524 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18525 else
18526 gcc_unreachable ();
18527 }
18528 [(set_attr "type" "alu1")
18529 (set_attr "prefix_0f" "1")
18530 (set_attr "prefix_rep" "1")
18531 (set_attr "mode" "SI")])
18532
18533 (define_insn "bsr_rex64"
18534 [(set (reg:CCZ FLAGS_REG)
18535 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18536 (const_int 0)))
18537 (set (match_operand:DI 0 "register_operand" "=r")
18538 (minus:DI (const_int 63)
18539 (clz:DI (match_dup 1))))]
18540 "TARGET_64BIT"
18541 "bsr{q}\t{%1, %0|%0, %1}"
18542 [(set_attr "type" "alu1")
18543 (set_attr "prefix_0f" "1")
18544 (set_attr "znver1_decode" "vector")
18545 (set_attr "mode" "DI")])
18546
18547 (define_insn "bsr_rex64_1"
18548 [(set (match_operand:DI 0 "register_operand" "=r")
18549 (minus:DI (const_int 63)
18550 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18551 (clobber (reg:CC FLAGS_REG))]
18552 "!TARGET_LZCNT && TARGET_64BIT"
18553 "bsr{q}\t{%1, %0|%0, %1}"
18554 [(set_attr "type" "alu1")
18555 (set_attr "prefix_0f" "1")
18556 (set_attr "znver1_decode" "vector")
18557 (set_attr "mode" "DI")])
18558
18559 (define_insn "bsr_rex64_1_zext"
18560 [(set (match_operand:DI 0 "register_operand" "=r")
18561 (zero_extend:DI
18562 (minus:SI (const_int 63)
18563 (subreg:SI
18564 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18565 0))))
18566 (clobber (reg:CC FLAGS_REG))]
18567 "!TARGET_LZCNT && TARGET_64BIT"
18568 "bsr{q}\t{%1, %0|%0, %1}"
18569 [(set_attr "type" "alu1")
18570 (set_attr "prefix_0f" "1")
18571 (set_attr "znver1_decode" "vector")
18572 (set_attr "mode" "DI")])
18573
18574 (define_insn "bsr"
18575 [(set (reg:CCZ FLAGS_REG)
18576 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18577 (const_int 0)))
18578 (set (match_operand:SI 0 "register_operand" "=r")
18579 (minus:SI (const_int 31)
18580 (clz:SI (match_dup 1))))]
18581 ""
18582 "bsr{l}\t{%1, %0|%0, %1}"
18583 [(set_attr "type" "alu1")
18584 (set_attr "prefix_0f" "1")
18585 (set_attr "znver1_decode" "vector")
18586 (set_attr "mode" "SI")])
18587
18588 (define_insn "bsr_1"
18589 [(set (match_operand:SI 0 "register_operand" "=r")
18590 (minus:SI (const_int 31)
18591 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18592 (clobber (reg:CC FLAGS_REG))]
18593 "!TARGET_LZCNT"
18594 "bsr{l}\t{%1, %0|%0, %1}"
18595 [(set_attr "type" "alu1")
18596 (set_attr "prefix_0f" "1")
18597 (set_attr "znver1_decode" "vector")
18598 (set_attr "mode" "SI")])
18599
18600 (define_insn "bsr_zext_1"
18601 [(set (match_operand:DI 0 "register_operand" "=r")
18602 (zero_extend:DI
18603 (minus:SI
18604 (const_int 31)
18605 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18606 (clobber (reg:CC FLAGS_REG))]
18607 "!TARGET_LZCNT && TARGET_64BIT"
18608 "bsr{l}\t{%1, %k0|%k0, %1}"
18609 [(set_attr "type" "alu1")
18610 (set_attr "prefix_0f" "1")
18611 (set_attr "znver1_decode" "vector")
18612 (set_attr "mode" "SI")])
18613
18614 ; As bsr is undefined behavior on zero and for other input
18615 ; values it is in range 0 to 63, we can optimize away sign-extends.
18616 (define_insn_and_split "*bsr_rex64_2"
18617 [(set (match_operand:DI 0 "register_operand")
18618 (xor:DI
18619 (sign_extend:DI
18620 (minus:SI
18621 (const_int 63)
18622 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18623 0)))
18624 (const_int 63)))
18625 (clobber (reg:CC FLAGS_REG))]
18626 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18627 "#"
18628 "&& 1"
18629 [(parallel [(set (reg:CCZ FLAGS_REG)
18630 (compare:CCZ (match_dup 1) (const_int 0)))
18631 (set (match_dup 2)
18632 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18633 (parallel [(set (match_dup 0)
18634 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18635 (clobber (reg:CC FLAGS_REG))])]
18636 {
18637 operands[2] = gen_reg_rtx (DImode);
18638 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18639 })
18640
18641 (define_insn_and_split "*bsr_2"
18642 [(set (match_operand:DI 0 "register_operand")
18643 (sign_extend:DI
18644 (xor:SI
18645 (minus:SI
18646 (const_int 31)
18647 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18648 (const_int 31))))
18649 (clobber (reg:CC FLAGS_REG))]
18650 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18651 "#"
18652 "&& 1"
18653 [(parallel [(set (reg:CCZ FLAGS_REG)
18654 (compare:CCZ (match_dup 1) (const_int 0)))
18655 (set (match_dup 2)
18656 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18657 (parallel [(set (match_dup 0)
18658 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18659 (clobber (reg:CC FLAGS_REG))])]
18660 "operands[2] = gen_reg_rtx (SImode);")
18661
18662 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18663 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18664 ; in [0, 63] or [0, 31] range.
18665 (define_split
18666 [(set (match_operand:SI 0 "register_operand")
18667 (minus:SI
18668 (match_operand:SI 2 "const_int_operand")
18669 (xor:SI
18670 (minus:SI (const_int 63)
18671 (subreg:SI
18672 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18673 0))
18674 (const_int 63))))]
18675 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18676 [(set (match_dup 3)
18677 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18678 (set (match_dup 0)
18679 (plus:SI (match_dup 5) (match_dup 4)))]
18680 {
18681 operands[3] = gen_reg_rtx (DImode);
18682 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18683 if (INTVAL (operands[2]) == 63)
18684 {
18685 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18686 emit_move_insn (operands[0], operands[5]);
18687 DONE;
18688 }
18689 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18690 })
18691
18692 (define_split
18693 [(set (match_operand:SI 0 "register_operand")
18694 (minus:SI
18695 (match_operand:SI 2 "const_int_operand")
18696 (xor:SI
18697 (minus:SI (const_int 31)
18698 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18699 (const_int 31))))]
18700 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18701 [(set (match_dup 3)
18702 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18703 (set (match_dup 0)
18704 (plus:SI (match_dup 3) (match_dup 4)))]
18705 {
18706 if (INTVAL (operands[2]) == 31)
18707 {
18708 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18709 DONE;
18710 }
18711 operands[3] = gen_reg_rtx (SImode);
18712 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18713 })
18714
18715 (define_split
18716 [(set (match_operand:DI 0 "register_operand")
18717 (minus:DI
18718 (match_operand:DI 2 "const_int_operand")
18719 (xor:DI
18720 (sign_extend:DI
18721 (minus:SI (const_int 63)
18722 (subreg:SI
18723 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18724 0)))
18725 (const_int 63))))]
18726 "!TARGET_LZCNT
18727 && TARGET_64BIT
18728 && ix86_pre_reload_split ()
18729 && ((unsigned HOST_WIDE_INT)
18730 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18731 == UINTVAL (operands[2]) - 63)"
18732 [(set (match_dup 3)
18733 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18734 (set (match_dup 0)
18735 (plus:DI (match_dup 3) (match_dup 4)))]
18736 {
18737 if (INTVAL (operands[2]) == 63)
18738 {
18739 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18740 DONE;
18741 }
18742 operands[3] = gen_reg_rtx (DImode);
18743 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18744 })
18745
18746 (define_split
18747 [(set (match_operand:DI 0 "register_operand")
18748 (minus:DI
18749 (match_operand:DI 2 "const_int_operand")
18750 (sign_extend:DI
18751 (xor:SI
18752 (minus:SI (const_int 31)
18753 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18754 (const_int 31)))))]
18755 "!TARGET_LZCNT
18756 && TARGET_64BIT
18757 && ix86_pre_reload_split ()
18758 && ((unsigned HOST_WIDE_INT)
18759 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18760 == UINTVAL (operands[2]) - 31)"
18761 [(set (match_dup 3)
18762 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18763 (set (match_dup 0)
18764 (plus:DI (match_dup 3) (match_dup 4)))]
18765 {
18766 if (INTVAL (operands[2]) == 31)
18767 {
18768 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18769 DONE;
18770 }
18771 operands[3] = gen_reg_rtx (DImode);
18772 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18773 })
18774
18775 (define_expand "clz<mode>2"
18776 [(parallel
18777 [(set (reg:CCZ FLAGS_REG)
18778 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18779 (const_int 0)))
18780 (set (match_dup 3) (minus:SWI48
18781 (match_dup 2)
18782 (clz:SWI48 (match_dup 1))))])
18783 (parallel
18784 [(set (match_operand:SWI48 0 "register_operand")
18785 (xor:SWI48 (match_dup 3) (match_dup 2)))
18786 (clobber (reg:CC FLAGS_REG))])]
18787 ""
18788 {
18789 if (TARGET_LZCNT)
18790 {
18791 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18792 DONE;
18793 }
18794 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18795 operands[3] = gen_reg_rtx (<MODE>mode);
18796 })
18797
18798 (define_insn_and_split "clz<mode>2_lzcnt"
18799 [(set (match_operand:SWI48 0 "register_operand" "=r")
18800 (clz:SWI48
18801 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18802 (clobber (reg:CC FLAGS_REG))]
18803 "TARGET_LZCNT"
18804 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18805 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18806 && optimize_function_for_speed_p (cfun)
18807 && !reg_mentioned_p (operands[0], operands[1])"
18808 [(parallel
18809 [(set (match_dup 0)
18810 (clz:SWI48 (match_dup 1)))
18811 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18812 (clobber (reg:CC FLAGS_REG))])]
18813 "ix86_expand_clear (operands[0]);"
18814 [(set_attr "prefix_rep" "1")
18815 (set_attr "type" "bitmanip")
18816 (set_attr "mode" "<MODE>")])
18817
18818 ; False dependency happens when destination is only updated by tzcnt,
18819 ; lzcnt or popcnt. There is no false dependency when destination is
18820 ; also used in source.
18821 (define_insn "*clz<mode>2_lzcnt_falsedep"
18822 [(set (match_operand:SWI48 0 "register_operand" "=r")
18823 (clz:SWI48
18824 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18825 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18826 UNSPEC_INSN_FALSE_DEP)
18827 (clobber (reg:CC FLAGS_REG))]
18828 "TARGET_LZCNT"
18829 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18830 [(set_attr "prefix_rep" "1")
18831 (set_attr "type" "bitmanip")
18832 (set_attr "mode" "<MODE>")])
18833
18834 (define_insn_and_split "*clzsi2_lzcnt_zext"
18835 [(set (match_operand:DI 0 "register_operand" "=r")
18836 (and:DI
18837 (subreg:DI
18838 (clz:SI
18839 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18840 (const_int 63)))
18841 (clobber (reg:CC FLAGS_REG))]
18842 "TARGET_LZCNT && TARGET_64BIT"
18843 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18844 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18845 && optimize_function_for_speed_p (cfun)
18846 && !reg_mentioned_p (operands[0], operands[1])"
18847 [(parallel
18848 [(set (match_dup 0)
18849 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18850 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18851 (clobber (reg:CC FLAGS_REG))])]
18852 "ix86_expand_clear (operands[0]);"
18853 [(set_attr "prefix_rep" "1")
18854 (set_attr "type" "bitmanip")
18855 (set_attr "mode" "SI")])
18856
18857 ; False dependency happens when destination is only updated by tzcnt,
18858 ; lzcnt or popcnt. There is no false dependency when destination is
18859 ; also used in source.
18860 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18861 [(set (match_operand:DI 0 "register_operand" "=r")
18862 (and:DI
18863 (subreg:DI
18864 (clz:SI
18865 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18866 (const_int 63)))
18867 (unspec [(match_operand:DI 2 "register_operand" "0")]
18868 UNSPEC_INSN_FALSE_DEP)
18869 (clobber (reg:CC FLAGS_REG))]
18870 "TARGET_LZCNT"
18871 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18872 [(set_attr "prefix_rep" "1")
18873 (set_attr "type" "bitmanip")
18874 (set_attr "mode" "SI")])
18875
18876 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18877 [(set (match_operand:DI 0 "register_operand" "=r")
18878 (zero_extend:DI
18879 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18880 (clobber (reg:CC FLAGS_REG))]
18881 "TARGET_LZCNT && TARGET_64BIT"
18882 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18883 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18884 && optimize_function_for_speed_p (cfun)
18885 && !reg_mentioned_p (operands[0], operands[1])"
18886 [(parallel
18887 [(set (match_dup 0)
18888 (zero_extend:DI (clz:SI (match_dup 1))))
18889 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18890 (clobber (reg:CC FLAGS_REG))])]
18891 "ix86_expand_clear (operands[0]);"
18892 [(set_attr "prefix_rep" "1")
18893 (set_attr "type" "bitmanip")
18894 (set_attr "mode" "SI")])
18895
18896 ; False dependency happens when destination is only updated by tzcnt,
18897 ; lzcnt or popcnt. There is no false dependency when destination is
18898 ; also used in source.
18899 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18900 [(set (match_operand:DI 0 "register_operand" "=r")
18901 (zero_extend:DI
18902 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18903 (unspec [(match_operand:DI 2 "register_operand" "0")]
18904 UNSPEC_INSN_FALSE_DEP)
18905 (clobber (reg:CC FLAGS_REG))]
18906 "TARGET_LZCNT"
18907 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18908 [(set_attr "prefix_rep" "1")
18909 (set_attr "type" "bitmanip")
18910 (set_attr "mode" "SI")])
18911
18912 (define_int_iterator LT_ZCNT
18913 [(UNSPEC_TZCNT "TARGET_BMI")
18914 (UNSPEC_LZCNT "TARGET_LZCNT")])
18915
18916 (define_int_attr lt_zcnt
18917 [(UNSPEC_TZCNT "tzcnt")
18918 (UNSPEC_LZCNT "lzcnt")])
18919
18920 (define_int_attr lt_zcnt_type
18921 [(UNSPEC_TZCNT "alu1")
18922 (UNSPEC_LZCNT "bitmanip")])
18923
18924 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18925 ;; provides operand size as output when source operand is zero.
18926
18927 (define_insn_and_split "<lt_zcnt>_<mode>"
18928 [(set (match_operand:SWI48 0 "register_operand" "=r")
18929 (unspec:SWI48
18930 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18931 (clobber (reg:CC FLAGS_REG))]
18932 ""
18933 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18934 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18935 && optimize_function_for_speed_p (cfun)
18936 && !reg_mentioned_p (operands[0], operands[1])"
18937 [(parallel
18938 [(set (match_dup 0)
18939 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18940 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18941 (clobber (reg:CC FLAGS_REG))])]
18942 "ix86_expand_clear (operands[0]);"
18943 [(set_attr "type" "<lt_zcnt_type>")
18944 (set_attr "prefix_0f" "1")
18945 (set_attr "prefix_rep" "1")
18946 (set_attr "mode" "<MODE>")])
18947
18948 ; False dependency happens when destination is only updated by tzcnt,
18949 ; lzcnt or popcnt. There is no false dependency when destination is
18950 ; also used in source.
18951 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18952 [(set (match_operand:SWI48 0 "register_operand" "=r")
18953 (unspec:SWI48
18954 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18955 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18956 UNSPEC_INSN_FALSE_DEP)
18957 (clobber (reg:CC FLAGS_REG))]
18958 ""
18959 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18960 [(set_attr "type" "<lt_zcnt_type>")
18961 (set_attr "prefix_0f" "1")
18962 (set_attr "prefix_rep" "1")
18963 (set_attr "mode" "<MODE>")])
18964
18965 (define_insn "<lt_zcnt>_hi"
18966 [(set (match_operand:HI 0 "register_operand" "=r")
18967 (unspec:HI
18968 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18969 (clobber (reg:CC FLAGS_REG))]
18970 ""
18971 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18972 [(set_attr "type" "<lt_zcnt_type>")
18973 (set_attr "prefix_0f" "1")
18974 (set_attr "prefix_rep" "1")
18975 (set_attr "mode" "HI")])
18976
18977 ;; BMI instructions.
18978
18979 (define_insn "bmi_bextr_<mode>"
18980 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18981 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18982 (match_operand:SWI48 2 "register_operand" "r,r")]
18983 UNSPEC_BEXTR))
18984 (clobber (reg:CC FLAGS_REG))]
18985 "TARGET_BMI"
18986 "bextr\t{%2, %1, %0|%0, %1, %2}"
18987 [(set_attr "type" "bitmanip")
18988 (set_attr "btver2_decode" "direct, double")
18989 (set_attr "mode" "<MODE>")])
18990
18991 (define_insn "*bmi_bextr_<mode>_ccz"
18992 [(set (reg:CCZ FLAGS_REG)
18993 (compare:CCZ
18994 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18995 (match_operand:SWI48 2 "register_operand" "r,r")]
18996 UNSPEC_BEXTR)
18997 (const_int 0)))
18998 (clobber (match_scratch:SWI48 0 "=r,r"))]
18999 "TARGET_BMI"
19000 "bextr\t{%2, %1, %0|%0, %1, %2}"
19001 [(set_attr "type" "bitmanip")
19002 (set_attr "btver2_decode" "direct, double")
19003 (set_attr "mode" "<MODE>")])
19004
19005 (define_insn "*bmi_blsi_<mode>"
19006 [(set (match_operand:SWI48 0 "register_operand" "=r")
19007 (and:SWI48
19008 (neg:SWI48
19009 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19010 (match_dup 1)))
19011 (clobber (reg:CC FLAGS_REG))]
19012 "TARGET_BMI"
19013 "blsi\t{%1, %0|%0, %1}"
19014 [(set_attr "type" "bitmanip")
19015 (set_attr "btver2_decode" "double")
19016 (set_attr "mode" "<MODE>")])
19017
19018 (define_insn "*bmi_blsi_<mode>_cmp"
19019 [(set (reg FLAGS_REG)
19020 (compare
19021 (and:SWI48
19022 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19023 (match_dup 1))
19024 (const_int 0)))
19025 (set (match_operand:SWI48 0 "register_operand" "=r")
19026 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
19027 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
19028 "blsi\t{%1, %0|%0, %1}"
19029 [(set_attr "type" "bitmanip")
19030 (set_attr "btver2_decode" "double")
19031 (set_attr "mode" "<MODE>")])
19032
19033 (define_insn "*bmi_blsi_<mode>_ccno"
19034 [(set (reg FLAGS_REG)
19035 (compare
19036 (and:SWI48
19037 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19038 (match_dup 1))
19039 (const_int 0)))
19040 (clobber (match_scratch:SWI48 0 "=r"))]
19041 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
19042 "blsi\t{%1, %0|%0, %1}"
19043 [(set_attr "type" "bitmanip")
19044 (set_attr "btver2_decode" "double")
19045 (set_attr "mode" "<MODE>")])
19046
19047 (define_insn "*bmi_blsmsk_<mode>"
19048 [(set (match_operand:SWI48 0 "register_operand" "=r")
19049 (xor:SWI48
19050 (plus:SWI48
19051 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19052 (const_int -1))
19053 (match_dup 1)))
19054 (clobber (reg:CC FLAGS_REG))]
19055 "TARGET_BMI"
19056 "blsmsk\t{%1, %0|%0, %1}"
19057 [(set_attr "type" "bitmanip")
19058 (set_attr "btver2_decode" "double")
19059 (set_attr "mode" "<MODE>")])
19060
19061 (define_insn "*bmi_blsr_<mode>"
19062 [(set (match_operand:SWI48 0 "register_operand" "=r")
19063 (and:SWI48
19064 (plus:SWI48
19065 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19066 (const_int -1))
19067 (match_dup 1)))
19068 (clobber (reg:CC FLAGS_REG))]
19069 "TARGET_BMI"
19070 "blsr\t{%1, %0|%0, %1}"
19071 [(set_attr "type" "bitmanip")
19072 (set_attr "btver2_decode" "double")
19073 (set_attr "mode" "<MODE>")])
19074
19075 (define_insn "*bmi_blsr_<mode>_cmp"
19076 [(set (reg:CCZ FLAGS_REG)
19077 (compare:CCZ
19078 (and:SWI48
19079 (plus:SWI48
19080 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19081 (const_int -1))
19082 (match_dup 1))
19083 (const_int 0)))
19084 (set (match_operand:SWI48 0 "register_operand" "=r")
19085 (and:SWI48
19086 (plus:SWI48
19087 (match_dup 1)
19088 (const_int -1))
19089 (match_dup 1)))]
19090 "TARGET_BMI"
19091 "blsr\t{%1, %0|%0, %1}"
19092 [(set_attr "type" "bitmanip")
19093 (set_attr "btver2_decode" "double")
19094 (set_attr "mode" "<MODE>")])
19095
19096 (define_insn "*bmi_blsr_<mode>_ccz"
19097 [(set (reg:CCZ FLAGS_REG)
19098 (compare:CCZ
19099 (and:SWI48
19100 (plus:SWI48
19101 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19102 (const_int -1))
19103 (match_dup 1))
19104 (const_int 0)))
19105 (clobber (match_scratch:SWI48 0 "=r"))]
19106 "TARGET_BMI"
19107 "blsr\t{%1, %0|%0, %1}"
19108 [(set_attr "type" "bitmanip")
19109 (set_attr "btver2_decode" "double")
19110 (set_attr "mode" "<MODE>")])
19111
19112 ;; BMI2 instructions.
19113 (define_expand "bmi2_bzhi_<mode>3"
19114 [(parallel
19115 [(set (match_operand:SWI48 0 "register_operand")
19116 (if_then_else:SWI48
19117 (ne:QI (match_operand:QI 2 "register_operand")
19118 (const_int 0))
19119 (zero_extract:SWI48
19120 (match_operand:SWI48 1 "nonimmediate_operand")
19121 (umin:QI (match_dup 2) (match_dup 3))
19122 (const_int 0))
19123 (const_int 0)))
19124 (clobber (reg:CC FLAGS_REG))])]
19125 "TARGET_BMI2"
19126 {
19127 operands[2] = gen_lowpart (QImode, operands[2]);
19128 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
19129 })
19130
19131 (define_insn "*bmi2_bzhi_<mode>3"
19132 [(set (match_operand:SWI48 0 "register_operand" "=r")
19133 (if_then_else:SWI48
19134 (ne:QI (match_operand:QI 2 "register_operand" "q")
19135 (const_int 0))
19136 (zero_extract:SWI48
19137 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19138 (umin:QI (match_dup 2)
19139 (match_operand:QI 3 "const_int_operand"))
19140 (const_int 0))
19141 (const_int 0)))
19142 (clobber (reg:CC FLAGS_REG))]
19143 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19144 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19145 [(set_attr "type" "bitmanip")
19146 (set_attr "prefix" "vex")
19147 (set_attr "mode" "<MODE>")])
19148
19149 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
19150 [(set (reg:CCZ FLAGS_REG)
19151 (compare:CCZ
19152 (if_then_else:SWI48
19153 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
19154 (zero_extract:SWI48
19155 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19156 (umin:QI (match_dup 2)
19157 (match_operand:QI 3 "const_int_operand"))
19158 (const_int 0))
19159 (const_int 0))
19160 (const_int 0)))
19161 (clobber (match_scratch:SWI48 0 "=r"))]
19162 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19163 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19164 [(set_attr "type" "bitmanip")
19165 (set_attr "prefix" "vex")
19166 (set_attr "mode" "<MODE>")])
19167
19168 (define_insn "*bmi2_bzhi_<mode>3_2"
19169 [(set (match_operand:SWI48 0 "register_operand" "=r")
19170 (and:SWI48
19171 (plus:SWI48
19172 (ashift:SWI48 (const_int 1)
19173 (match_operand:QI 2 "register_operand" "r"))
19174 (const_int -1))
19175 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19176 (clobber (reg:CC FLAGS_REG))]
19177 "TARGET_BMI2"
19178 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19179 [(set_attr "type" "bitmanip")
19180 (set_attr "prefix" "vex")
19181 (set_attr "mode" "<MODE>")])
19182
19183 (define_insn "*bmi2_bzhi_<mode>3_3"
19184 [(set (match_operand:SWI48 0 "register_operand" "=r")
19185 (and:SWI48
19186 (not:SWI48
19187 (ashift:SWI48 (const_int -1)
19188 (match_operand:QI 2 "register_operand" "r")))
19189 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19190 (clobber (reg:CC FLAGS_REG))]
19191 "TARGET_BMI2"
19192 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19193 [(set_attr "type" "bitmanip")
19194 (set_attr "prefix" "vex")
19195 (set_attr "mode" "<MODE>")])
19196
19197 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
19198 [(set (match_operand:DI 0 "register_operand" "=r")
19199 (zero_extend:DI
19200 (and:SI
19201 (plus:SI
19202 (ashift:SI (const_int 1)
19203 (match_operand:QI 2 "register_operand" "r"))
19204 (const_int -1))
19205 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19206 (clobber (reg:CC FLAGS_REG))]
19207 "TARGET_64BIT && TARGET_BMI2"
19208 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19209 [(set_attr "type" "bitmanip")
19210 (set_attr "prefix" "vex")
19211 (set_attr "mode" "DI")])
19212
19213 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
19214 [(set (match_operand:DI 0 "register_operand" "=r")
19215 (and:DI
19216 (zero_extend:DI
19217 (plus:SI
19218 (ashift:SI (const_int 1)
19219 (match_operand:QI 2 "register_operand" "r"))
19220 (const_int -1)))
19221 (match_operand:DI 1 "nonimmediate_operand" "rm")))
19222 (clobber (reg:CC FLAGS_REG))]
19223 "TARGET_64BIT && TARGET_BMI2"
19224 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19225 [(set_attr "type" "bitmanip")
19226 (set_attr "prefix" "vex")
19227 (set_attr "mode" "DI")])
19228
19229 (define_insn "bmi2_pdep_<mode>3"
19230 [(set (match_operand:SWI48 0 "register_operand" "=r")
19231 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19232 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19233 UNSPEC_PDEP))]
19234 "TARGET_BMI2"
19235 "pdep\t{%2, %1, %0|%0, %1, %2}"
19236 [(set_attr "type" "bitmanip")
19237 (set_attr "prefix" "vex")
19238 (set_attr "mode" "<MODE>")])
19239
19240 (define_insn "bmi2_pext_<mode>3"
19241 [(set (match_operand:SWI48 0 "register_operand" "=r")
19242 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19243 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19244 UNSPEC_PEXT))]
19245 "TARGET_BMI2"
19246 "pext\t{%2, %1, %0|%0, %1, %2}"
19247 [(set_attr "type" "bitmanip")
19248 (set_attr "prefix" "vex")
19249 (set_attr "mode" "<MODE>")])
19250
19251 ;; TBM instructions.
19252 (define_insn "@tbm_bextri_<mode>"
19253 [(set (match_operand:SWI48 0 "register_operand" "=r")
19254 (zero_extract:SWI48
19255 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19256 (match_operand:QI 2 "const_0_to_255_operand")
19257 (match_operand:QI 3 "const_0_to_255_operand")))
19258 (clobber (reg:CC FLAGS_REG))]
19259 "TARGET_TBM"
19260 {
19261 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19262 return "bextr\t{%2, %1, %0|%0, %1, %2}";
19263 }
19264 [(set_attr "type" "bitmanip")
19265 (set_attr "mode" "<MODE>")])
19266
19267 (define_insn "*tbm_blcfill_<mode>"
19268 [(set (match_operand:SWI48 0 "register_operand" "=r")
19269 (and:SWI48
19270 (plus:SWI48
19271 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19272 (const_int 1))
19273 (match_dup 1)))
19274 (clobber (reg:CC FLAGS_REG))]
19275 "TARGET_TBM"
19276 "blcfill\t{%1, %0|%0, %1}"
19277 [(set_attr "type" "bitmanip")
19278 (set_attr "mode" "<MODE>")])
19279
19280 (define_insn "*tbm_blci_<mode>"
19281 [(set (match_operand:SWI48 0 "register_operand" "=r")
19282 (ior:SWI48
19283 (not:SWI48
19284 (plus:SWI48
19285 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19286 (const_int 1)))
19287 (match_dup 1)))
19288 (clobber (reg:CC FLAGS_REG))]
19289 "TARGET_TBM"
19290 "blci\t{%1, %0|%0, %1}"
19291 [(set_attr "type" "bitmanip")
19292 (set_attr "mode" "<MODE>")])
19293
19294 (define_insn "*tbm_blcic_<mode>"
19295 [(set (match_operand:SWI48 0 "register_operand" "=r")
19296 (and:SWI48
19297 (plus:SWI48
19298 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19299 (const_int 1))
19300 (not:SWI48
19301 (match_dup 1))))
19302 (clobber (reg:CC FLAGS_REG))]
19303 "TARGET_TBM"
19304 "blcic\t{%1, %0|%0, %1}"
19305 [(set_attr "type" "bitmanip")
19306 (set_attr "mode" "<MODE>")])
19307
19308 (define_insn "*tbm_blcmsk_<mode>"
19309 [(set (match_operand:SWI48 0 "register_operand" "=r")
19310 (xor:SWI48
19311 (plus:SWI48
19312 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19313 (const_int 1))
19314 (match_dup 1)))
19315 (clobber (reg:CC FLAGS_REG))]
19316 "TARGET_TBM"
19317 "blcmsk\t{%1, %0|%0, %1}"
19318 [(set_attr "type" "bitmanip")
19319 (set_attr "mode" "<MODE>")])
19320
19321 (define_insn "*tbm_blcs_<mode>"
19322 [(set (match_operand:SWI48 0 "register_operand" "=r")
19323 (ior:SWI48
19324 (plus:SWI48
19325 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19326 (const_int 1))
19327 (match_dup 1)))
19328 (clobber (reg:CC FLAGS_REG))]
19329 "TARGET_TBM"
19330 "blcs\t{%1, %0|%0, %1}"
19331 [(set_attr "type" "bitmanip")
19332 (set_attr "mode" "<MODE>")])
19333
19334 (define_insn "*tbm_blsfill_<mode>"
19335 [(set (match_operand:SWI48 0 "register_operand" "=r")
19336 (ior:SWI48
19337 (plus:SWI48
19338 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19339 (const_int -1))
19340 (match_dup 1)))
19341 (clobber (reg:CC FLAGS_REG))]
19342 "TARGET_TBM"
19343 "blsfill\t{%1, %0|%0, %1}"
19344 [(set_attr "type" "bitmanip")
19345 (set_attr "mode" "<MODE>")])
19346
19347 (define_insn "*tbm_blsic_<mode>"
19348 [(set (match_operand:SWI48 0 "register_operand" "=r")
19349 (ior:SWI48
19350 (plus:SWI48
19351 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19352 (const_int -1))
19353 (not:SWI48
19354 (match_dup 1))))
19355 (clobber (reg:CC FLAGS_REG))]
19356 "TARGET_TBM"
19357 "blsic\t{%1, %0|%0, %1}"
19358 [(set_attr "type" "bitmanip")
19359 (set_attr "mode" "<MODE>")])
19360
19361 (define_insn "*tbm_t1mskc_<mode>"
19362 [(set (match_operand:SWI48 0 "register_operand" "=r")
19363 (ior:SWI48
19364 (plus:SWI48
19365 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19366 (const_int 1))
19367 (not:SWI48
19368 (match_dup 1))))
19369 (clobber (reg:CC FLAGS_REG))]
19370 "TARGET_TBM"
19371 "t1mskc\t{%1, %0|%0, %1}"
19372 [(set_attr "type" "bitmanip")
19373 (set_attr "mode" "<MODE>")])
19374
19375 (define_insn "*tbm_tzmsk_<mode>"
19376 [(set (match_operand:SWI48 0 "register_operand" "=r")
19377 (and:SWI48
19378 (plus:SWI48
19379 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19380 (const_int -1))
19381 (not:SWI48
19382 (match_dup 1))))
19383 (clobber (reg:CC FLAGS_REG))]
19384 "TARGET_TBM"
19385 "tzmsk\t{%1, %0|%0, %1}"
19386 [(set_attr "type" "bitmanip")
19387 (set_attr "mode" "<MODE>")])
19388
19389 (define_insn_and_split "popcount<mode>2"
19390 [(set (match_operand:SWI48 0 "register_operand" "=r")
19391 (popcount:SWI48
19392 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19393 (clobber (reg:CC FLAGS_REG))]
19394 "TARGET_POPCNT"
19395 {
19396 #if TARGET_MACHO
19397 return "popcnt\t{%1, %0|%0, %1}";
19398 #else
19399 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19400 #endif
19401 }
19402 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19403 && optimize_function_for_speed_p (cfun)
19404 && !reg_mentioned_p (operands[0], operands[1])"
19405 [(parallel
19406 [(set (match_dup 0)
19407 (popcount:SWI48 (match_dup 1)))
19408 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19409 (clobber (reg:CC FLAGS_REG))])]
19410 "ix86_expand_clear (operands[0]);"
19411 [(set_attr "prefix_rep" "1")
19412 (set_attr "type" "bitmanip")
19413 (set_attr "mode" "<MODE>")])
19414
19415 ; False dependency happens when destination is only updated by tzcnt,
19416 ; lzcnt or popcnt. There is no false dependency when destination is
19417 ; also used in source.
19418 (define_insn "*popcount<mode>2_falsedep"
19419 [(set (match_operand:SWI48 0 "register_operand" "=r")
19420 (popcount:SWI48
19421 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19422 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19423 UNSPEC_INSN_FALSE_DEP)
19424 (clobber (reg:CC FLAGS_REG))]
19425 "TARGET_POPCNT"
19426 {
19427 #if TARGET_MACHO
19428 return "popcnt\t{%1, %0|%0, %1}";
19429 #else
19430 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19431 #endif
19432 }
19433 [(set_attr "prefix_rep" "1")
19434 (set_attr "type" "bitmanip")
19435 (set_attr "mode" "<MODE>")])
19436
19437 (define_insn_and_split "*popcountsi2_zext"
19438 [(set (match_operand:DI 0 "register_operand" "=r")
19439 (and:DI
19440 (subreg:DI
19441 (popcount:SI
19442 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19443 (const_int 63)))
19444 (clobber (reg:CC FLAGS_REG))]
19445 "TARGET_POPCNT && TARGET_64BIT"
19446 {
19447 #if TARGET_MACHO
19448 return "popcnt\t{%1, %k0|%k0, %1}";
19449 #else
19450 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19451 #endif
19452 }
19453 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19454 && optimize_function_for_speed_p (cfun)
19455 && !reg_mentioned_p (operands[0], operands[1])"
19456 [(parallel
19457 [(set (match_dup 0)
19458 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19459 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19460 (clobber (reg:CC FLAGS_REG))])]
19461 "ix86_expand_clear (operands[0]);"
19462 [(set_attr "prefix_rep" "1")
19463 (set_attr "type" "bitmanip")
19464 (set_attr "mode" "SI")])
19465
19466 ; False dependency happens when destination is only updated by tzcnt,
19467 ; lzcnt or popcnt. There is no false dependency when destination is
19468 ; also used in source.
19469 (define_insn "*popcountsi2_zext_falsedep"
19470 [(set (match_operand:DI 0 "register_operand" "=r")
19471 (and:DI
19472 (subreg:DI
19473 (popcount:SI
19474 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19475 (const_int 63)))
19476 (unspec [(match_operand:DI 2 "register_operand" "0")]
19477 UNSPEC_INSN_FALSE_DEP)
19478 (clobber (reg:CC FLAGS_REG))]
19479 "TARGET_POPCNT && TARGET_64BIT"
19480 {
19481 #if TARGET_MACHO
19482 return "popcnt\t{%1, %k0|%k0, %1}";
19483 #else
19484 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19485 #endif
19486 }
19487 [(set_attr "prefix_rep" "1")
19488 (set_attr "type" "bitmanip")
19489 (set_attr "mode" "SI")])
19490
19491 (define_insn_and_split "*popcountsi2_zext_2"
19492 [(set (match_operand:DI 0 "register_operand" "=r")
19493 (zero_extend:DI
19494 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19495 (clobber (reg:CC FLAGS_REG))]
19496 "TARGET_POPCNT && TARGET_64BIT"
19497 {
19498 #if TARGET_MACHO
19499 return "popcnt\t{%1, %k0|%k0, %1}";
19500 #else
19501 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19502 #endif
19503 }
19504 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19505 && optimize_function_for_speed_p (cfun)
19506 && !reg_mentioned_p (operands[0], operands[1])"
19507 [(parallel
19508 [(set (match_dup 0)
19509 (zero_extend:DI (popcount:SI (match_dup 1))))
19510 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19511 (clobber (reg:CC FLAGS_REG))])]
19512 "ix86_expand_clear (operands[0]);"
19513 [(set_attr "prefix_rep" "1")
19514 (set_attr "type" "bitmanip")
19515 (set_attr "mode" "SI")])
19516
19517 ; False dependency happens when destination is only updated by tzcnt,
19518 ; lzcnt or popcnt. There is no false dependency when destination is
19519 ; also used in source.
19520 (define_insn "*popcountsi2_zext_2_falsedep"
19521 [(set (match_operand:DI 0 "register_operand" "=r")
19522 (zero_extend:DI
19523 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19524 (unspec [(match_operand:DI 2 "register_operand" "0")]
19525 UNSPEC_INSN_FALSE_DEP)
19526 (clobber (reg:CC FLAGS_REG))]
19527 "TARGET_POPCNT && TARGET_64BIT"
19528 {
19529 #if TARGET_MACHO
19530 return "popcnt\t{%1, %k0|%k0, %1}";
19531 #else
19532 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19533 #endif
19534 }
19535 [(set_attr "prefix_rep" "1")
19536 (set_attr "type" "bitmanip")
19537 (set_attr "mode" "SI")])
19538
19539 (define_insn_and_split "*popcounthi2_1"
19540 [(set (match_operand:SI 0 "register_operand")
19541 (popcount:SI
19542 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19543 (clobber (reg:CC FLAGS_REG))]
19544 "TARGET_POPCNT
19545 && ix86_pre_reload_split ()"
19546 "#"
19547 "&& 1"
19548 [(const_int 0)]
19549 {
19550 rtx tmp = gen_reg_rtx (HImode);
19551
19552 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19553 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19554 DONE;
19555 })
19556
19557 (define_insn_and_split "*popcounthi2_2"
19558 [(set (match_operand:SI 0 "register_operand")
19559 (zero_extend:SI
19560 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19561 (clobber (reg:CC FLAGS_REG))]
19562 "TARGET_POPCNT
19563 && ix86_pre_reload_split ()"
19564 "#"
19565 "&& 1"
19566 [(const_int 0)]
19567 {
19568 rtx tmp = gen_reg_rtx (HImode);
19569
19570 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19571 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19572 DONE;
19573 })
19574
19575 (define_insn "popcounthi2"
19576 [(set (match_operand:HI 0 "register_operand" "=r")
19577 (popcount:HI
19578 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19579 (clobber (reg:CC FLAGS_REG))]
19580 "TARGET_POPCNT"
19581 {
19582 #if TARGET_MACHO
19583 return "popcnt\t{%1, %0|%0, %1}";
19584 #else
19585 return "popcnt{w}\t{%1, %0|%0, %1}";
19586 #endif
19587 }
19588 [(set_attr "prefix_rep" "1")
19589 (set_attr "type" "bitmanip")
19590 (set_attr "mode" "HI")])
19591
19592 (define_expand "bswapdi2"
19593 [(set (match_operand:DI 0 "register_operand")
19594 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19595 "TARGET_64BIT"
19596 {
19597 if (!TARGET_MOVBE)
19598 operands[1] = force_reg (DImode, operands[1]);
19599 })
19600
19601 (define_expand "bswapsi2"
19602 [(set (match_operand:SI 0 "register_operand")
19603 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19604 ""
19605 {
19606 if (TARGET_MOVBE)
19607 ;
19608 else if (TARGET_BSWAP)
19609 operands[1] = force_reg (SImode, operands[1]);
19610 else
19611 {
19612 rtx x = operands[0];
19613
19614 emit_move_insn (x, operands[1]);
19615 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19616 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19617 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19618 DONE;
19619 }
19620 })
19621
19622 (define_insn "*bswap<mode>2_movbe"
19623 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19624 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19625 "TARGET_MOVBE
19626 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19627 "@
19628 bswap\t%0
19629 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19630 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19631 [(set_attr "type" "bitmanip,imov,imov")
19632 (set_attr "modrm" "0,1,1")
19633 (set_attr "prefix_0f" "*,1,1")
19634 (set_attr "prefix_extra" "*,1,1")
19635 (set_attr "mode" "<MODE>")])
19636
19637 (define_insn "*bswap<mode>2"
19638 [(set (match_operand:SWI48 0 "register_operand" "=r")
19639 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19640 "TARGET_BSWAP"
19641 "bswap\t%0"
19642 [(set_attr "type" "bitmanip")
19643 (set_attr "modrm" "0")
19644 (set_attr "mode" "<MODE>")])
19645
19646 (define_expand "bswaphi2"
19647 [(set (match_operand:HI 0 "register_operand")
19648 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19649 "TARGET_MOVBE")
19650
19651 (define_insn "*bswaphi2_movbe"
19652 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19653 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19654 "TARGET_MOVBE
19655 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19656 "@
19657 xchg{b}\t{%h0, %b0|%b0, %h0}
19658 movbe{w}\t{%1, %0|%0, %1}
19659 movbe{w}\t{%1, %0|%0, %1}"
19660 [(set_attr "type" "imov")
19661 (set_attr "modrm" "*,1,1")
19662 (set_attr "prefix_0f" "*,1,1")
19663 (set_attr "prefix_extra" "*,1,1")
19664 (set_attr "pent_pair" "np,*,*")
19665 (set_attr "athlon_decode" "vector,*,*")
19666 (set_attr "amdfam10_decode" "double,*,*")
19667 (set_attr "bdver1_decode" "double,*,*")
19668 (set_attr "mode" "QI,HI,HI")])
19669
19670 (define_peephole2
19671 [(set (match_operand:HI 0 "general_reg_operand")
19672 (bswap:HI (match_dup 0)))]
19673 "TARGET_MOVBE
19674 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19675 && peep2_regno_dead_p (0, FLAGS_REG)"
19676 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19677 (clobber (reg:CC FLAGS_REG))])])
19678
19679 (define_insn "bswaphi_lowpart"
19680 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19681 (bswap:HI (match_dup 0)))
19682 (clobber (reg:CC FLAGS_REG))]
19683 ""
19684 "@
19685 xchg{b}\t{%h0, %b0|%b0, %h0}
19686 rol{w}\t{$8, %0|%0, 8}"
19687 [(set (attr "preferred_for_size")
19688 (cond [(eq_attr "alternative" "0")
19689 (symbol_ref "true")]
19690 (symbol_ref "false")))
19691 (set (attr "preferred_for_speed")
19692 (cond [(eq_attr "alternative" "0")
19693 (symbol_ref "TARGET_USE_XCHGB")]
19694 (symbol_ref "!TARGET_USE_XCHGB")))
19695 (set_attr "length" "2,4")
19696 (set_attr "mode" "QI,HI")])
19697
19698 (define_expand "paritydi2"
19699 [(set (match_operand:DI 0 "register_operand")
19700 (parity:DI (match_operand:DI 1 "register_operand")))]
19701 "! TARGET_POPCNT"
19702 {
19703 rtx scratch = gen_reg_rtx (QImode);
19704 rtx hipart1 = gen_reg_rtx (SImode);
19705 rtx lopart1 = gen_reg_rtx (SImode);
19706 rtx xor1 = gen_reg_rtx (SImode);
19707 rtx shift2 = gen_reg_rtx (SImode);
19708 rtx hipart2 = gen_reg_rtx (HImode);
19709 rtx lopart2 = gen_reg_rtx (HImode);
19710 rtx xor2 = gen_reg_rtx (HImode);
19711
19712 if (TARGET_64BIT)
19713 {
19714 rtx shift1 = gen_reg_rtx (DImode);
19715 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19716 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19717 }
19718 else
19719 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19720
19721 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19722 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19723
19724 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19725 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19726 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19727 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19728
19729 emit_insn (gen_parityhi2_cmp (xor2));
19730
19731 ix86_expand_setcc (scratch, ORDERED,
19732 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19733
19734 if (TARGET_64BIT)
19735 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19736 else
19737 {
19738 rtx tmp = gen_reg_rtx (SImode);
19739
19740 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19741 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19742 }
19743 DONE;
19744 })
19745
19746 (define_expand "paritysi2"
19747 [(set (match_operand:SI 0 "register_operand")
19748 (parity:SI (match_operand:SI 1 "register_operand")))]
19749 "! TARGET_POPCNT"
19750 {
19751 rtx scratch = gen_reg_rtx (QImode);
19752 rtx shift = gen_reg_rtx (SImode);
19753 rtx hipart = gen_reg_rtx (HImode);
19754 rtx lopart = gen_reg_rtx (HImode);
19755 rtx tmp = gen_reg_rtx (HImode);
19756
19757 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19758 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19759 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19760 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19761
19762 emit_insn (gen_parityhi2_cmp (tmp));
19763
19764 ix86_expand_setcc (scratch, ORDERED,
19765 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19766
19767 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19768 DONE;
19769 })
19770
19771 (define_expand "parityhi2"
19772 [(set (match_operand:HI 0 "register_operand")
19773 (parity:HI (match_operand:HI 1 "register_operand")))]
19774 "! TARGET_POPCNT"
19775 {
19776 rtx scratch = gen_reg_rtx (QImode);
19777
19778 emit_insn (gen_parityhi2_cmp (operands[1]));
19779
19780 ix86_expand_setcc (scratch, ORDERED,
19781 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19782
19783 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19784 DONE;
19785 })
19786
19787 (define_expand "parityqi2"
19788 [(set (match_operand:QI 0 "register_operand")
19789 (parity:QI (match_operand:QI 1 "register_operand")))]
19790 "! TARGET_POPCNT"
19791 {
19792 emit_insn (gen_parityqi2_cmp (operands[1]));
19793
19794 ix86_expand_setcc (operands[0], ORDERED,
19795 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19796 DONE;
19797 })
19798
19799 (define_insn "parityhi2_cmp"
19800 [(set (reg:CC FLAGS_REG)
19801 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19802 UNSPEC_PARITY))
19803 (clobber (match_dup 0))]
19804 ""
19805 "xor{b}\t{%h0, %b0|%b0, %h0}"
19806 [(set_attr "length" "2")
19807 (set_attr "mode" "QI")])
19808
19809 (define_insn "parityqi2_cmp"
19810 [(set (reg:CC FLAGS_REG)
19811 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19812 UNSPEC_PARITY))]
19813 ""
19814 "test{b}\t%0, %0"
19815 [(set_attr "mode" "QI")])
19816
19817 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19818 (define_peephole2
19819 [(set (match_operand:HI 0 "register_operand")
19820 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19821 (parallel [(set (reg:CC FLAGS_REG)
19822 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19823 (clobber (match_dup 0))])]
19824 ""
19825 [(set (reg:CC FLAGS_REG)
19826 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19827
19828 ;; Eliminate QImode popcount&1 using parity flag
19829 (define_peephole2
19830 [(set (match_operand:SI 0 "register_operand")
19831 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19832 (parallel [(set (match_operand:SI 2 "register_operand")
19833 (popcount:SI (match_dup 0)))
19834 (clobber (reg:CC FLAGS_REG))])
19835 (set (reg:CCZ FLAGS_REG)
19836 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19837 (const_int 1))
19838 (const_int 0)))
19839 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19840 [(reg:CCZ FLAGS_REG)
19841 (const_int 0)])
19842 (label_ref (match_operand 5))
19843 (pc)))]
19844 "REGNO (operands[2]) == REGNO (operands[3])
19845 && peep2_reg_dead_p (3, operands[0])
19846 && peep2_reg_dead_p (3, operands[2])
19847 && peep2_regno_dead_p (4, FLAGS_REG)"
19848 [(set (reg:CC FLAGS_REG)
19849 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19850 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19851 (const_int 0)])
19852 (label_ref (match_dup 5))
19853 (pc)))]
19854 {
19855 operands[4] = shallow_copy_rtx (operands[4]);
19856 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19857 })
19858
19859 ;; Eliminate HImode popcount&1 using parity flag
19860 (define_peephole2
19861 [(match_scratch:HI 0 "Q")
19862 (parallel [(set (match_operand:HI 1 "register_operand")
19863 (popcount:HI
19864 (match_operand:HI 2 "nonimmediate_operand")))
19865 (clobber (reg:CC FLAGS_REG))])
19866 (set (match_operand 3 "register_operand")
19867 (zero_extend (match_dup 1)))
19868 (set (reg:CCZ FLAGS_REG)
19869 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19870 (const_int 1))
19871 (const_int 0)))
19872 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19873 [(reg:CCZ FLAGS_REG)
19874 (const_int 0)])
19875 (label_ref (match_operand 6))
19876 (pc)))]
19877 "REGNO (operands[3]) == REGNO (operands[4])
19878 && peep2_reg_dead_p (3, operands[1])
19879 && peep2_reg_dead_p (3, operands[3])
19880 && peep2_regno_dead_p (4, FLAGS_REG)"
19881 [(set (match_dup 0) (match_dup 2))
19882 (parallel [(set (reg:CC FLAGS_REG)
19883 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19884 (clobber (match_dup 0))])
19885 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19886 (const_int 0)])
19887 (label_ref (match_dup 6))
19888 (pc)))]
19889 {
19890 operands[5] = shallow_copy_rtx (operands[5]);
19891 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19892 })
19893
19894 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19895 (define_peephole2
19896 [(match_scratch:HI 0 "Q")
19897 (parallel [(set (match_operand:HI 1 "register_operand")
19898 (popcount:HI
19899 (match_operand:HI 2 "nonimmediate_operand")))
19900 (clobber (reg:CC FLAGS_REG))])
19901 (set (reg:CCZ FLAGS_REG)
19902 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19903 (const_int 1))
19904 (const_int 0)))
19905 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19906 [(reg:CCZ FLAGS_REG)
19907 (const_int 0)])
19908 (label_ref (match_operand 5))
19909 (pc)))]
19910 "REGNO (operands[1]) == REGNO (operands[3])
19911 && peep2_reg_dead_p (2, operands[1])
19912 && peep2_reg_dead_p (2, operands[3])
19913 && peep2_regno_dead_p (3, FLAGS_REG)"
19914 [(set (match_dup 0) (match_dup 2))
19915 (parallel [(set (reg:CC FLAGS_REG)
19916 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19917 (clobber (match_dup 0))])
19918 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19919 (const_int 0)])
19920 (label_ref (match_dup 5))
19921 (pc)))]
19922 {
19923 operands[4] = shallow_copy_rtx (operands[4]);
19924 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19925 })
19926
19927 \f
19928 ;; Thread-local storage patterns for ELF.
19929 ;;
19930 ;; Note that these code sequences must appear exactly as shown
19931 ;; in order to allow linker relaxation.
19932
19933 (define_insn "*tls_global_dynamic_32_gnu"
19934 [(set (match_operand:SI 0 "register_operand" "=a")
19935 (unspec:SI
19936 [(match_operand:SI 1 "register_operand" "Yb")
19937 (match_operand 2 "tls_symbolic_operand")
19938 (match_operand 3 "constant_call_address_operand" "Bz")
19939 (reg:SI SP_REG)]
19940 UNSPEC_TLS_GD))
19941 (clobber (match_scratch:SI 4 "=d"))
19942 (clobber (match_scratch:SI 5 "=c"))
19943 (clobber (reg:CC FLAGS_REG))]
19944 "!TARGET_64BIT && TARGET_GNU_TLS"
19945 {
19946 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19947 output_asm_insn
19948 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19949 else
19950 output_asm_insn
19951 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19952 if (TARGET_SUN_TLS)
19953 #ifdef HAVE_AS_IX86_TLSGDPLT
19954 return "call\t%a2@tlsgdplt";
19955 #else
19956 return "call\t%p3@plt";
19957 #endif
19958 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19959 return "call\t%P3";
19960 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19961 }
19962 [(set_attr "type" "multi")
19963 (set_attr "length" "12")])
19964
19965 (define_expand "tls_global_dynamic_32"
19966 [(parallel
19967 [(set (match_operand:SI 0 "register_operand")
19968 (unspec:SI [(match_operand:SI 2 "register_operand")
19969 (match_operand 1 "tls_symbolic_operand")
19970 (match_operand 3 "constant_call_address_operand")
19971 (reg:SI SP_REG)]
19972 UNSPEC_TLS_GD))
19973 (clobber (scratch:SI))
19974 (clobber (scratch:SI))
19975 (clobber (reg:CC FLAGS_REG))])]
19976 ""
19977 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19978
19979 (define_insn "*tls_global_dynamic_64_<mode>"
19980 [(set (match_operand:P 0 "register_operand" "=a")
19981 (call:P
19982 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19983 (match_operand 3)))
19984 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19985 (reg:P SP_REG)]
19986 UNSPEC_TLS_GD)]
19987 "TARGET_64BIT"
19988 {
19989 if (!TARGET_X32)
19990 /* The .loc directive has effect for 'the immediately following assembly
19991 instruction'. So for a sequence:
19992 .loc f l
19993 .byte x
19994 insn1
19995 the 'immediately following assembly instruction' is insn1.
19996 We want to emit an insn prefix here, but if we use .byte (as shown in
19997 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19998 inside the insn sequence, rather than to the start. After relaxation
19999 of the sequence by the linker, the .loc might point inside an insn.
20000 Use data16 prefix instead, which doesn't have this problem. */
20001 fputs ("\tdata16", asm_out_file);
20002 output_asm_insn
20003 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
20004 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20005 fputs (ASM_SHORT "0x6666\n", asm_out_file);
20006 else
20007 fputs (ASM_BYTE "0x66\n", asm_out_file);
20008 fputs ("\trex64\n", asm_out_file);
20009 if (TARGET_SUN_TLS)
20010 return "call\t%p2@plt";
20011 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20012 return "call\t%P2";
20013 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
20014 }
20015 [(set_attr "type" "multi")
20016 (set (attr "length")
20017 (symbol_ref "TARGET_X32 ? 15 : 16"))])
20018
20019 (define_insn "*tls_global_dynamic_64_largepic"
20020 [(set (match_operand:DI 0 "register_operand" "=a")
20021 (call:DI
20022 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
20023 (match_operand:DI 3 "immediate_operand" "i")))
20024 (match_operand 4)))
20025 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
20026 (reg:DI SP_REG)]
20027 UNSPEC_TLS_GD)]
20028 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20029 && GET_CODE (operands[3]) == CONST
20030 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
20031 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
20032 {
20033 output_asm_insn
20034 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
20035 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
20036 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
20037 return "call\t{*%%rax|rax}";
20038 }
20039 [(set_attr "type" "multi")
20040 (set_attr "length" "22")])
20041
20042 (define_expand "@tls_global_dynamic_64_<mode>"
20043 [(parallel
20044 [(set (match_operand:P 0 "register_operand")
20045 (call:P
20046 (mem:QI (match_operand 2))
20047 (const_int 0)))
20048 (unspec:P [(match_operand 1 "tls_symbolic_operand")
20049 (reg:P SP_REG)]
20050 UNSPEC_TLS_GD)])]
20051 "TARGET_64BIT"
20052 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20053
20054 (define_insn "*tls_local_dynamic_base_32_gnu"
20055 [(set (match_operand:SI 0 "register_operand" "=a")
20056 (unspec:SI
20057 [(match_operand:SI 1 "register_operand" "Yb")
20058 (match_operand 2 "constant_call_address_operand" "Bz")
20059 (reg:SI SP_REG)]
20060 UNSPEC_TLS_LD_BASE))
20061 (clobber (match_scratch:SI 3 "=d"))
20062 (clobber (match_scratch:SI 4 "=c"))
20063 (clobber (reg:CC FLAGS_REG))]
20064 "!TARGET_64BIT && TARGET_GNU_TLS"
20065 {
20066 output_asm_insn
20067 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
20068 if (TARGET_SUN_TLS)
20069 {
20070 if (HAVE_AS_IX86_TLSLDMPLT)
20071 return "call\t%&@tlsldmplt";
20072 else
20073 return "call\t%p2@plt";
20074 }
20075 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20076 return "call\t%P2";
20077 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
20078 }
20079 [(set_attr "type" "multi")
20080 (set_attr "length" "11")])
20081
20082 (define_expand "tls_local_dynamic_base_32"
20083 [(parallel
20084 [(set (match_operand:SI 0 "register_operand")
20085 (unspec:SI
20086 [(match_operand:SI 1 "register_operand")
20087 (match_operand 2 "constant_call_address_operand")
20088 (reg:SI SP_REG)]
20089 UNSPEC_TLS_LD_BASE))
20090 (clobber (scratch:SI))
20091 (clobber (scratch:SI))
20092 (clobber (reg:CC FLAGS_REG))])]
20093 ""
20094 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20095
20096 (define_insn "*tls_local_dynamic_base_64_<mode>"
20097 [(set (match_operand:P 0 "register_operand" "=a")
20098 (call:P
20099 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
20100 (match_operand 2)))
20101 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
20102 "TARGET_64BIT"
20103 {
20104 output_asm_insn
20105 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20106 if (TARGET_SUN_TLS)
20107 return "call\t%p1@plt";
20108 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20109 return "call\t%P1";
20110 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
20111 }
20112 [(set_attr "type" "multi")
20113 (set_attr "length" "12")])
20114
20115 (define_insn "*tls_local_dynamic_base_64_largepic"
20116 [(set (match_operand:DI 0 "register_operand" "=a")
20117 (call:DI
20118 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
20119 (match_operand:DI 2 "immediate_operand" "i")))
20120 (match_operand 3)))
20121 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
20122 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20123 && GET_CODE (operands[2]) == CONST
20124 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
20125 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
20126 {
20127 output_asm_insn
20128 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20129 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
20130 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
20131 return "call\t{*%%rax|rax}";
20132 }
20133 [(set_attr "type" "multi")
20134 (set_attr "length" "22")])
20135
20136 (define_expand "@tls_local_dynamic_base_64_<mode>"
20137 [(parallel
20138 [(set (match_operand:P 0 "register_operand")
20139 (call:P
20140 (mem:QI (match_operand 1))
20141 (const_int 0)))
20142 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
20143 "TARGET_64BIT"
20144 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20145
20146 ;; Local dynamic of a single variable is a lose. Show combine how
20147 ;; to convert that back to global dynamic.
20148
20149 (define_insn_and_split "*tls_local_dynamic_32_once"
20150 [(set (match_operand:SI 0 "register_operand" "=a")
20151 (plus:SI
20152 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
20153 (match_operand 2 "constant_call_address_operand" "Bz")
20154 (reg:SI SP_REG)]
20155 UNSPEC_TLS_LD_BASE)
20156 (const:SI (unspec:SI
20157 [(match_operand 3 "tls_symbolic_operand")]
20158 UNSPEC_DTPOFF))))
20159 (clobber (match_scratch:SI 4 "=d"))
20160 (clobber (match_scratch:SI 5 "=c"))
20161 (clobber (reg:CC FLAGS_REG))]
20162 ""
20163 "#"
20164 ""
20165 [(parallel
20166 [(set (match_dup 0)
20167 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
20168 (reg:SI SP_REG)]
20169 UNSPEC_TLS_GD))
20170 (clobber (match_dup 4))
20171 (clobber (match_dup 5))
20172 (clobber (reg:CC FLAGS_REG))])])
20173
20174 ;; Load and add the thread base pointer from %<tp_seg>:0.
20175 (define_expand "get_thread_pointer<mode>"
20176 [(set (match_operand:PTR 0 "register_operand")
20177 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20178 ""
20179 {
20180 /* targetm is not visible in the scope of the condition. */
20181 if (!targetm.have_tls)
20182 error ("%<__builtin_thread_pointer%> is not supported on this target");
20183 })
20184
20185 (define_insn_and_split "*load_tp_<mode>"
20186 [(set (match_operand:PTR 0 "register_operand" "=r")
20187 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20188 ""
20189 "#"
20190 ""
20191 [(set (match_dup 0)
20192 (match_dup 1))]
20193 {
20194 addr_space_t as = DEFAULT_TLS_SEG_REG;
20195
20196 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
20197 set_mem_addr_space (operands[1], as);
20198 })
20199
20200 (define_insn_and_split "*load_tp_x32_zext"
20201 [(set (match_operand:DI 0 "register_operand" "=r")
20202 (zero_extend:DI
20203 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
20204 "TARGET_X32"
20205 "#"
20206 "&& 1"
20207 [(set (match_dup 0)
20208 (zero_extend:DI (match_dup 1)))]
20209 {
20210 addr_space_t as = DEFAULT_TLS_SEG_REG;
20211
20212 operands[1] = gen_const_mem (SImode, const0_rtx);
20213 set_mem_addr_space (operands[1], as);
20214 })
20215
20216 (define_insn_and_split "*add_tp_<mode>"
20217 [(set (match_operand:PTR 0 "register_operand" "=r")
20218 (plus:PTR
20219 (unspec:PTR [(const_int 0)] UNSPEC_TP)
20220 (match_operand:PTR 1 "register_operand" "0")))
20221 (clobber (reg:CC FLAGS_REG))]
20222 ""
20223 "#"
20224 ""
20225 [(parallel
20226 [(set (match_dup 0)
20227 (plus:PTR (match_dup 1) (match_dup 2)))
20228 (clobber (reg:CC FLAGS_REG))])]
20229 {
20230 addr_space_t as = DEFAULT_TLS_SEG_REG;
20231
20232 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
20233 set_mem_addr_space (operands[2], as);
20234 })
20235
20236 (define_insn_and_split "*add_tp_x32_zext"
20237 [(set (match_operand:DI 0 "register_operand" "=r")
20238 (zero_extend:DI
20239 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20240 (match_operand:SI 1 "register_operand" "0"))))
20241 (clobber (reg:CC FLAGS_REG))]
20242 "TARGET_X32"
20243 "#"
20244 "&& 1"
20245 [(parallel
20246 [(set (match_dup 0)
20247 (zero_extend:DI
20248 (plus:SI (match_dup 1) (match_dup 2))))
20249 (clobber (reg:CC FLAGS_REG))])]
20250 {
20251 addr_space_t as = DEFAULT_TLS_SEG_REG;
20252
20253 operands[2] = gen_const_mem (SImode, const0_rtx);
20254 set_mem_addr_space (operands[2], as);
20255 })
20256
20257 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20258 ;; %rax as destination of the initial executable code sequence.
20259 (define_insn "tls_initial_exec_64_sun"
20260 [(set (match_operand:DI 0 "register_operand" "=a")
20261 (unspec:DI
20262 [(match_operand 1 "tls_symbolic_operand")]
20263 UNSPEC_TLS_IE_SUN))
20264 (clobber (reg:CC FLAGS_REG))]
20265 "TARGET_64BIT && TARGET_SUN_TLS"
20266 {
20267 output_asm_insn
20268 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20269 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20270 }
20271 [(set_attr "type" "multi")])
20272
20273 ;; GNU2 TLS patterns can be split.
20274
20275 (define_expand "tls_dynamic_gnu2_32"
20276 [(set (match_dup 3)
20277 (plus:SI (match_operand:SI 2 "register_operand")
20278 (const:SI
20279 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20280 UNSPEC_TLSDESC))))
20281 (parallel
20282 [(set (match_operand:SI 0 "register_operand")
20283 (unspec:SI [(match_dup 1) (match_dup 3)
20284 (match_dup 2) (reg:SI SP_REG)]
20285 UNSPEC_TLSDESC))
20286 (clobber (reg:CC FLAGS_REG))])]
20287 "!TARGET_64BIT && TARGET_GNU2_TLS"
20288 {
20289 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20290 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20291 })
20292
20293 (define_insn "*tls_dynamic_gnu2_lea_32"
20294 [(set (match_operand:SI 0 "register_operand" "=r")
20295 (plus:SI (match_operand:SI 1 "register_operand" "b")
20296 (const:SI
20297 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20298 UNSPEC_TLSDESC))))]
20299 "!TARGET_64BIT && TARGET_GNU2_TLS"
20300 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20301 [(set_attr "type" "lea")
20302 (set_attr "mode" "SI")
20303 (set_attr "length" "6")
20304 (set_attr "length_address" "4")])
20305
20306 (define_insn "*tls_dynamic_gnu2_call_32"
20307 [(set (match_operand:SI 0 "register_operand" "=a")
20308 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20309 (match_operand:SI 2 "register_operand" "0")
20310 ;; we have to make sure %ebx still points to the GOT
20311 (match_operand:SI 3 "register_operand" "b")
20312 (reg:SI SP_REG)]
20313 UNSPEC_TLSDESC))
20314 (clobber (reg:CC FLAGS_REG))]
20315 "!TARGET_64BIT && TARGET_GNU2_TLS"
20316 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20317 [(set_attr "type" "call")
20318 (set_attr "length" "2")
20319 (set_attr "length_address" "0")])
20320
20321 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20322 [(set (match_operand:SI 0 "register_operand" "=&a")
20323 (plus:SI
20324 (unspec:SI [(match_operand 3 "tls_modbase_operand")
20325 (match_operand:SI 4)
20326 (match_operand:SI 2 "register_operand" "b")
20327 (reg:SI SP_REG)]
20328 UNSPEC_TLSDESC)
20329 (const:SI (unspec:SI
20330 [(match_operand 1 "tls_symbolic_operand")]
20331 UNSPEC_DTPOFF))))
20332 (clobber (reg:CC FLAGS_REG))]
20333 "!TARGET_64BIT && TARGET_GNU2_TLS"
20334 "#"
20335 "&& 1"
20336 [(set (match_dup 0) (match_dup 5))]
20337 {
20338 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20339 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20340 })
20341
20342 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20343 [(set (match_dup 2)
20344 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20345 UNSPEC_TLSDESC))
20346 (parallel
20347 [(set (match_operand:PTR 0 "register_operand")
20348 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20349 UNSPEC_TLSDESC))
20350 (clobber (reg:CC FLAGS_REG))])]
20351 "TARGET_64BIT && TARGET_GNU2_TLS"
20352 {
20353 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20354 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20355 })
20356
20357 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20358 [(set (match_operand:PTR 0 "register_operand" "=r")
20359 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20360 UNSPEC_TLSDESC))]
20361 "TARGET_64BIT && TARGET_GNU2_TLS"
20362 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20363 [(set_attr "type" "lea")
20364 (set_attr "mode" "<MODE>")
20365 (set_attr "length" "7")
20366 (set_attr "length_address" "4")])
20367
20368 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20369 [(set (match_operand:PTR 0 "register_operand" "=a")
20370 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20371 (match_operand:PTR 2 "register_operand" "0")
20372 (reg:PTR SP_REG)]
20373 UNSPEC_TLSDESC))
20374 (clobber (reg:CC FLAGS_REG))]
20375 "TARGET_64BIT && TARGET_GNU2_TLS"
20376 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20377 [(set_attr "type" "call")
20378 (set_attr "length" "2")
20379 (set_attr "length_address" "0")])
20380
20381 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20382 [(set (match_operand:PTR 0 "register_operand" "=&a")
20383 (plus:PTR
20384 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20385 (match_operand:PTR 3)
20386 (reg:PTR SP_REG)]
20387 UNSPEC_TLSDESC)
20388 (const:PTR (unspec:PTR
20389 [(match_operand 1 "tls_symbolic_operand")]
20390 UNSPEC_DTPOFF))))
20391 (clobber (reg:CC FLAGS_REG))]
20392 "TARGET_64BIT && TARGET_GNU2_TLS"
20393 "#"
20394 "&& 1"
20395 [(set (match_dup 0) (match_dup 4))]
20396 {
20397 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20398 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20399 })
20400
20401 (define_split
20402 [(match_operand 0 "tls_address_pattern")]
20403 "TARGET_TLS_DIRECT_SEG_REFS"
20404 [(match_dup 0)]
20405 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20406
20407 \f
20408 ;; These patterns match the binary 387 instructions for addM3, subM3,
20409 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20410 ;; SFmode. The first is the normal insn, the second the same insn but
20411 ;; with one operand a conversion, and the third the same insn but with
20412 ;; the other operand a conversion. The conversion may be SFmode or
20413 ;; SImode if the target mode DFmode, but only SImode if the target mode
20414 ;; is SFmode.
20415
20416 ;; Gcc is slightly more smart about handling normal two address instructions
20417 ;; so use special patterns for add and mull.
20418
20419 (define_insn "*fop_xf_comm_i387"
20420 [(set (match_operand:XF 0 "register_operand" "=f")
20421 (match_operator:XF 3 "binary_fp_operator"
20422 [(match_operand:XF 1 "register_operand" "%0")
20423 (match_operand:XF 2 "register_operand" "f")]))]
20424 "TARGET_80387
20425 && COMMUTATIVE_ARITH_P (operands[3])"
20426 "* return output_387_binary_op (insn, operands);"
20427 [(set (attr "type")
20428 (if_then_else (match_operand:XF 3 "mult_operator")
20429 (const_string "fmul")
20430 (const_string "fop")))
20431 (set_attr "mode" "XF")])
20432
20433 (define_insn "*fop_<mode>_comm"
20434 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20435 (match_operator:MODEF 3 "binary_fp_operator"
20436 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20437 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20438 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20439 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20440 && COMMUTATIVE_ARITH_P (operands[3])
20441 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20442 "* return output_387_binary_op (insn, operands);"
20443 [(set (attr "type")
20444 (if_then_else (eq_attr "alternative" "1,2")
20445 (if_then_else (match_operand:MODEF 3 "mult_operator")
20446 (const_string "ssemul")
20447 (const_string "sseadd"))
20448 (if_then_else (match_operand:MODEF 3 "mult_operator")
20449 (const_string "fmul")
20450 (const_string "fop"))))
20451 (set_attr "isa" "*,noavx,avx")
20452 (set_attr "prefix" "orig,orig,vex")
20453 (set_attr "mode" "<MODE>")
20454 (set (attr "enabled")
20455 (if_then_else
20456 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20457 (if_then_else
20458 (eq_attr "alternative" "0")
20459 (symbol_ref "TARGET_MIX_SSE_I387
20460 && X87_ENABLE_ARITH (<MODE>mode)")
20461 (const_string "*"))
20462 (if_then_else
20463 (eq_attr "alternative" "0")
20464 (symbol_ref "true")
20465 (symbol_ref "false"))))])
20466
20467 (define_insn "*<insn>hf"
20468 [(set (match_operand:HF 0 "register_operand" "=v")
20469 (plusminusmultdiv:HF
20470 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20471 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20472 "TARGET_AVX512FP16
20473 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20474 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20475 [(set_attr "prefix" "evex")
20476 (set_attr "mode" "HF")])
20477
20478 (define_insn "*rcpsf2_sse"
20479 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20480 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20481 UNSPEC_RCP))]
20482 "TARGET_SSE && TARGET_SSE_MATH"
20483 "@
20484 %vrcpss\t{%d1, %0|%0, %d1}
20485 %vrcpss\t{%d1, %0|%0, %d1}
20486 rcpss\t{%1, %d0|%d0, %1}
20487 vrcpss\t{%1, %d0|%d0, %1}"
20488 [(set_attr "isa" "*,*,noavx,avx")
20489 (set_attr "addr" "*,*,*,gpr16")
20490 (set_attr "type" "sse")
20491 (set_attr "atom_sse_attr" "rcp")
20492 (set_attr "btver2_sse_attr" "rcp")
20493 (set_attr "prefix" "maybe_vex")
20494 (set_attr "mode" "SF")
20495 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20496 (set (attr "preferred_for_speed")
20497 (cond [(match_test "TARGET_AVX")
20498 (symbol_ref "true")
20499 (eq_attr "alternative" "1,2,3")
20500 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20501 ]
20502 (symbol_ref "true")))])
20503
20504 (define_insn "rcphf2"
20505 [(set (match_operand:HF 0 "register_operand" "=v,v")
20506 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20507 UNSPEC_RCP))]
20508 "TARGET_AVX512FP16"
20509 "@
20510 vrcpsh\t{%d1, %0|%0, %d1}
20511 vrcpsh\t{%1, %d0|%d0, %1}"
20512 [(set_attr "type" "sse")
20513 (set_attr "prefix" "evex")
20514 (set_attr "mode" "HF")
20515 (set_attr "avx_partial_xmm_update" "false,true")])
20516
20517 (define_insn "*fop_xf_1_i387"
20518 [(set (match_operand:XF 0 "register_operand" "=f,f")
20519 (match_operator:XF 3 "binary_fp_operator"
20520 [(match_operand:XF 1 "register_operand" "0,f")
20521 (match_operand:XF 2 "register_operand" "f,0")]))]
20522 "TARGET_80387
20523 && !COMMUTATIVE_ARITH_P (operands[3])"
20524 "* return output_387_binary_op (insn, operands);"
20525 [(set (attr "type")
20526 (if_then_else (match_operand:XF 3 "div_operator")
20527 (const_string "fdiv")
20528 (const_string "fop")))
20529 (set_attr "mode" "XF")])
20530
20531 (define_insn "*fop_<mode>_1"
20532 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20533 (match_operator:MODEF 3 "binary_fp_operator"
20534 [(match_operand:MODEF 1
20535 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20536 (match_operand:MODEF 2
20537 "nonimmediate_operand" "fm,0,xm,vm")]))]
20538 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20539 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20540 && !COMMUTATIVE_ARITH_P (operands[3])
20541 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20542 "* return output_387_binary_op (insn, operands);"
20543 [(set (attr "type")
20544 (if_then_else (eq_attr "alternative" "2,3")
20545 (if_then_else (match_operand:MODEF 3 "div_operator")
20546 (const_string "ssediv")
20547 (const_string "sseadd"))
20548 (if_then_else (match_operand:MODEF 3 "div_operator")
20549 (const_string "fdiv")
20550 (const_string "fop"))))
20551 (set_attr "isa" "*,*,noavx,avx")
20552 (set_attr "prefix" "orig,orig,orig,vex")
20553 (set_attr "mode" "<MODE>")
20554 (set (attr "enabled")
20555 (if_then_else
20556 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20557 (if_then_else
20558 (eq_attr "alternative" "0,1")
20559 (symbol_ref "TARGET_MIX_SSE_I387
20560 && X87_ENABLE_ARITH (<MODE>mode)")
20561 (const_string "*"))
20562 (if_then_else
20563 (eq_attr "alternative" "0,1")
20564 (symbol_ref "true")
20565 (symbol_ref "false"))))])
20566
20567 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20568 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20569 (match_operator:X87MODEF 3 "binary_fp_operator"
20570 [(float:X87MODEF
20571 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20572 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20573 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20574 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20575 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20576 || optimize_function_for_size_p (cfun))"
20577 "* return output_387_binary_op (insn, operands);"
20578 [(set (attr "type")
20579 (cond [(match_operand:X87MODEF 3 "mult_operator")
20580 (const_string "fmul")
20581 (match_operand:X87MODEF 3 "div_operator")
20582 (const_string "fdiv")
20583 ]
20584 (const_string "fop")))
20585 (set_attr "fp_int_src" "true")
20586 (set_attr "mode" "<SWI24:MODE>")])
20587
20588 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20589 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20590 (match_operator:X87MODEF 3 "binary_fp_operator"
20591 [(match_operand:X87MODEF 1 "register_operand" "0")
20592 (float:X87MODEF
20593 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20594 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20595 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20596 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20597 || optimize_function_for_size_p (cfun))"
20598 "* return output_387_binary_op (insn, operands);"
20599 [(set (attr "type")
20600 (cond [(match_operand:X87MODEF 3 "mult_operator")
20601 (const_string "fmul")
20602 (match_operand:X87MODEF 3 "div_operator")
20603 (const_string "fdiv")
20604 ]
20605 (const_string "fop")))
20606 (set_attr "fp_int_src" "true")
20607 (set_attr "mode" "<SWI24:MODE>")])
20608
20609 (define_insn "*fop_xf_4_i387"
20610 [(set (match_operand:XF 0 "register_operand" "=f,f")
20611 (match_operator:XF 3 "binary_fp_operator"
20612 [(float_extend:XF
20613 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20614 (match_operand:XF 2 "register_operand" "0,f")]))]
20615 "TARGET_80387"
20616 "* return output_387_binary_op (insn, operands);"
20617 [(set (attr "type")
20618 (cond [(match_operand:XF 3 "mult_operator")
20619 (const_string "fmul")
20620 (match_operand:XF 3 "div_operator")
20621 (const_string "fdiv")
20622 ]
20623 (const_string "fop")))
20624 (set_attr "mode" "<MODE>")])
20625
20626 (define_insn "*fop_df_4_i387"
20627 [(set (match_operand:DF 0 "register_operand" "=f,f")
20628 (match_operator:DF 3 "binary_fp_operator"
20629 [(float_extend:DF
20630 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20631 (match_operand:DF 2 "register_operand" "0,f")]))]
20632 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20633 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20634 "* return output_387_binary_op (insn, operands);"
20635 [(set (attr "type")
20636 (cond [(match_operand:DF 3 "mult_operator")
20637 (const_string "fmul")
20638 (match_operand:DF 3 "div_operator")
20639 (const_string "fdiv")
20640 ]
20641 (const_string "fop")))
20642 (set_attr "mode" "SF")])
20643
20644 (define_insn "*fop_xf_5_i387"
20645 [(set (match_operand:XF 0 "register_operand" "=f,f")
20646 (match_operator:XF 3 "binary_fp_operator"
20647 [(match_operand:XF 1 "register_operand" "0,f")
20648 (float_extend:XF
20649 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20650 "TARGET_80387"
20651 "* return output_387_binary_op (insn, operands);"
20652 [(set (attr "type")
20653 (cond [(match_operand:XF 3 "mult_operator")
20654 (const_string "fmul")
20655 (match_operand:XF 3 "div_operator")
20656 (const_string "fdiv")
20657 ]
20658 (const_string "fop")))
20659 (set_attr "mode" "<MODE>")])
20660
20661 (define_insn "*fop_df_5_i387"
20662 [(set (match_operand:DF 0 "register_operand" "=f,f")
20663 (match_operator:DF 3 "binary_fp_operator"
20664 [(match_operand:DF 1 "register_operand" "0,f")
20665 (float_extend:DF
20666 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20667 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20668 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20669 "* return output_387_binary_op (insn, operands);"
20670 [(set (attr "type")
20671 (cond [(match_operand:DF 3 "mult_operator")
20672 (const_string "fmul")
20673 (match_operand:DF 3 "div_operator")
20674 (const_string "fdiv")
20675 ]
20676 (const_string "fop")))
20677 (set_attr "mode" "SF")])
20678
20679 (define_insn "*fop_xf_6_i387"
20680 [(set (match_operand:XF 0 "register_operand" "=f,f")
20681 (match_operator:XF 3 "binary_fp_operator"
20682 [(float_extend:XF
20683 (match_operand:MODEF 1 "register_operand" "0,f"))
20684 (float_extend:XF
20685 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20686 "TARGET_80387"
20687 "* return output_387_binary_op (insn, operands);"
20688 [(set (attr "type")
20689 (cond [(match_operand:XF 3 "mult_operator")
20690 (const_string "fmul")
20691 (match_operand:XF 3 "div_operator")
20692 (const_string "fdiv")
20693 ]
20694 (const_string "fop")))
20695 (set_attr "mode" "<MODE>")])
20696
20697 (define_insn "*fop_df_6_i387"
20698 [(set (match_operand:DF 0 "register_operand" "=f,f")
20699 (match_operator:DF 3 "binary_fp_operator"
20700 [(float_extend:DF
20701 (match_operand:SF 1 "register_operand" "0,f"))
20702 (float_extend:DF
20703 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20704 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20705 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20706 "* return output_387_binary_op (insn, operands);"
20707 [(set (attr "type")
20708 (cond [(match_operand:DF 3 "mult_operator")
20709 (const_string "fmul")
20710 (match_operand:DF 3 "div_operator")
20711 (const_string "fdiv")
20712 ]
20713 (const_string "fop")))
20714 (set_attr "mode" "SF")])
20715 \f
20716 ;; FPU special functions.
20717
20718 ;; This pattern implements a no-op XFmode truncation for
20719 ;; all fancy i386 XFmode math functions.
20720
20721 (define_insn "truncxf<mode>2_i387_noop_unspec"
20722 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20723 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20724 UNSPEC_TRUNC_NOOP))]
20725 "TARGET_USE_FANCY_MATH_387"
20726 "* return output_387_reg_move (insn, operands);"
20727 [(set_attr "type" "fmov")
20728 (set_attr "mode" "<MODE>")])
20729
20730 (define_insn "sqrtxf2"
20731 [(set (match_operand:XF 0 "register_operand" "=f")
20732 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20733 "TARGET_USE_FANCY_MATH_387"
20734 "fsqrt"
20735 [(set_attr "type" "fpspc")
20736 (set_attr "mode" "XF")
20737 (set_attr "athlon_decode" "direct")
20738 (set_attr "amdfam10_decode" "direct")
20739 (set_attr "bdver1_decode" "direct")])
20740
20741 (define_insn "*rsqrtsf2_sse"
20742 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20743 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20744 UNSPEC_RSQRT))]
20745 "TARGET_SSE && TARGET_SSE_MATH"
20746 "@
20747 %vrsqrtss\t{%d1, %0|%0, %d1}
20748 %vrsqrtss\t{%d1, %0|%0, %d1}
20749 rsqrtss\t{%1, %d0|%d0, %1}
20750 vrsqrtss\t{%1, %d0|%d0, %1}"
20751 [(set_attr "isa" "*,*,noavx,avx")
20752 (set_attr "addr" "*,*,*,gpr16")
20753 (set_attr "type" "sse")
20754 (set_attr "atom_sse_attr" "rcp")
20755 (set_attr "btver2_sse_attr" "rcp")
20756 (set_attr "prefix" "maybe_vex")
20757 (set_attr "mode" "SF")
20758 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20759 (set (attr "preferred_for_speed")
20760 (cond [(match_test "TARGET_AVX")
20761 (symbol_ref "true")
20762 (eq_attr "alternative" "1,2,3")
20763 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20764 ]
20765 (symbol_ref "true")))])
20766
20767 (define_expand "rsqrtsf2"
20768 [(set (match_operand:SF 0 "register_operand")
20769 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20770 UNSPEC_RSQRT))]
20771 "TARGET_SSE && TARGET_SSE_MATH"
20772 {
20773 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20774 DONE;
20775 })
20776
20777 (define_insn "rsqrthf2"
20778 [(set (match_operand:HF 0 "register_operand" "=v,v")
20779 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20780 UNSPEC_RSQRT))]
20781 "TARGET_AVX512FP16"
20782 "@
20783 vrsqrtsh\t{%d1, %0|%0, %d1}
20784 vrsqrtsh\t{%1, %d0|%d0, %1}"
20785 [(set_attr "type" "sse")
20786 (set_attr "prefix" "evex")
20787 (set_attr "avx_partial_xmm_update" "false,true")
20788 (set_attr "mode" "HF")])
20789
20790 (define_insn "sqrthf2"
20791 [(set (match_operand:HF 0 "register_operand" "=v,v")
20792 (sqrt:HF
20793 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20794 "TARGET_AVX512FP16"
20795 "@
20796 vsqrtsh\t{%d1, %0|%0, %d1}
20797 vsqrtsh\t{%1, %d0|%d0, %1}"
20798 [(set_attr "type" "sse")
20799 (set_attr "prefix" "evex")
20800 (set_attr "avx_partial_xmm_update" "false,true")
20801 (set_attr "mode" "HF")])
20802
20803 (define_insn "*sqrt<mode>2_sse"
20804 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20805 (sqrt:MODEF
20806 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20807 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20808 "@
20809 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20810 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20811 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20812 [(set_attr "type" "sse")
20813 (set_attr "atom_sse_attr" "sqrt")
20814 (set_attr "btver2_sse_attr" "sqrt")
20815 (set_attr "prefix" "maybe_vex")
20816 (set_attr "avx_partial_xmm_update" "false,false,true")
20817 (set_attr "mode" "<MODE>")
20818 (set (attr "preferred_for_speed")
20819 (cond [(match_test "TARGET_AVX")
20820 (symbol_ref "true")
20821 (eq_attr "alternative" "1,2")
20822 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20823 ]
20824 (symbol_ref "true")))])
20825
20826 (define_expand "sqrt<mode>2"
20827 [(set (match_operand:MODEF 0 "register_operand")
20828 (sqrt:MODEF
20829 (match_operand:MODEF 1 "nonimmediate_operand")))]
20830 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20831 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20832 {
20833 if (<MODE>mode == SFmode
20834 && TARGET_SSE && TARGET_SSE_MATH
20835 && TARGET_RECIP_SQRT
20836 && !optimize_function_for_size_p (cfun)
20837 && flag_finite_math_only && !flag_trapping_math
20838 && flag_unsafe_math_optimizations)
20839 {
20840 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20841 DONE;
20842 }
20843
20844 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20845 {
20846 rtx op0 = gen_reg_rtx (XFmode);
20847 rtx op1 = gen_reg_rtx (XFmode);
20848
20849 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20850 emit_insn (gen_sqrtxf2 (op0, op1));
20851 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20852 DONE;
20853 }
20854 })
20855
20856 (define_expand "hypot<mode>3"
20857 [(use (match_operand:MODEF 0 "register_operand"))
20858 (use (match_operand:MODEF 1 "general_operand"))
20859 (use (match_operand:MODEF 2 "general_operand"))]
20860 "TARGET_USE_FANCY_MATH_387
20861 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20862 || TARGET_MIX_SSE_I387)
20863 && flag_finite_math_only
20864 && flag_unsafe_math_optimizations"
20865 {
20866 rtx op0 = gen_reg_rtx (XFmode);
20867 rtx op1 = gen_reg_rtx (XFmode);
20868 rtx op2 = gen_reg_rtx (XFmode);
20869
20870 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20871 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20872
20873 emit_insn (gen_mulxf3 (op1, op1, op1));
20874 emit_insn (gen_mulxf3 (op2, op2, op2));
20875 emit_insn (gen_addxf3 (op0, op2, op1));
20876 emit_insn (gen_sqrtxf2 (op0, op0));
20877
20878 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20879 DONE;
20880 })
20881
20882 (define_insn "x86_fnstsw_1"
20883 [(set (match_operand:HI 0 "register_operand" "=a")
20884 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20885 "TARGET_80387"
20886 "fnstsw\t%0"
20887 [(set_attr "length" "2")
20888 (set_attr "mode" "SI")
20889 (set_attr "unit" "i387")])
20890
20891 (define_insn "fpremxf4_i387"
20892 [(set (match_operand:XF 0 "register_operand" "=f")
20893 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20894 (match_operand:XF 3 "register_operand" "1")]
20895 UNSPEC_FPREM_F))
20896 (set (match_operand:XF 1 "register_operand" "=f")
20897 (unspec:XF [(match_dup 2) (match_dup 3)]
20898 UNSPEC_FPREM_U))
20899 (set (reg:CCFP FPSR_REG)
20900 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20901 UNSPEC_C2_FLAG))]
20902 "TARGET_USE_FANCY_MATH_387"
20903 "fprem"
20904 [(set_attr "type" "fpspc")
20905 (set_attr "znver1_decode" "vector")
20906 (set_attr "mode" "XF")])
20907
20908 (define_expand "fmodxf3"
20909 [(use (match_operand:XF 0 "register_operand"))
20910 (use (match_operand:XF 1 "general_operand"))
20911 (use (match_operand:XF 2 "general_operand"))]
20912 "TARGET_USE_FANCY_MATH_387"
20913 {
20914 rtx_code_label *label = gen_label_rtx ();
20915
20916 rtx op1 = gen_reg_rtx (XFmode);
20917 rtx op2 = gen_reg_rtx (XFmode);
20918
20919 emit_move_insn (op2, operands[2]);
20920 emit_move_insn (op1, operands[1]);
20921
20922 emit_label (label);
20923 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20924 ix86_emit_fp_unordered_jump (label);
20925 LABEL_NUSES (label) = 1;
20926
20927 emit_move_insn (operands[0], op1);
20928 DONE;
20929 })
20930
20931 (define_expand "fmod<mode>3"
20932 [(use (match_operand:MODEF 0 "register_operand"))
20933 (use (match_operand:MODEF 1 "general_operand"))
20934 (use (match_operand:MODEF 2 "general_operand"))]
20935 "TARGET_USE_FANCY_MATH_387"
20936 {
20937 rtx (*gen_truncxf) (rtx, rtx);
20938
20939 rtx_code_label *label = gen_label_rtx ();
20940
20941 rtx op1 = gen_reg_rtx (XFmode);
20942 rtx op2 = gen_reg_rtx (XFmode);
20943
20944 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20945 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20946
20947 emit_label (label);
20948 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20949 ix86_emit_fp_unordered_jump (label);
20950 LABEL_NUSES (label) = 1;
20951
20952 /* Truncate the result properly for strict SSE math. */
20953 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20954 && !TARGET_MIX_SSE_I387)
20955 gen_truncxf = gen_truncxf<mode>2;
20956 else
20957 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20958
20959 emit_insn (gen_truncxf (operands[0], op1));
20960 DONE;
20961 })
20962
20963 (define_insn "fprem1xf4_i387"
20964 [(set (match_operand:XF 0 "register_operand" "=f")
20965 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20966 (match_operand:XF 3 "register_operand" "1")]
20967 UNSPEC_FPREM1_F))
20968 (set (match_operand:XF 1 "register_operand" "=f")
20969 (unspec:XF [(match_dup 2) (match_dup 3)]
20970 UNSPEC_FPREM1_U))
20971 (set (reg:CCFP FPSR_REG)
20972 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20973 UNSPEC_C2_FLAG))]
20974 "TARGET_USE_FANCY_MATH_387"
20975 "fprem1"
20976 [(set_attr "type" "fpspc")
20977 (set_attr "znver1_decode" "vector")
20978 (set_attr "mode" "XF")])
20979
20980 (define_expand "remainderxf3"
20981 [(use (match_operand:XF 0 "register_operand"))
20982 (use (match_operand:XF 1 "general_operand"))
20983 (use (match_operand:XF 2 "general_operand"))]
20984 "TARGET_USE_FANCY_MATH_387"
20985 {
20986 rtx_code_label *label = gen_label_rtx ();
20987
20988 rtx op1 = gen_reg_rtx (XFmode);
20989 rtx op2 = gen_reg_rtx (XFmode);
20990
20991 emit_move_insn (op2, operands[2]);
20992 emit_move_insn (op1, operands[1]);
20993
20994 emit_label (label);
20995 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20996 ix86_emit_fp_unordered_jump (label);
20997 LABEL_NUSES (label) = 1;
20998
20999 emit_move_insn (operands[0], op1);
21000 DONE;
21001 })
21002
21003 (define_expand "remainder<mode>3"
21004 [(use (match_operand:MODEF 0 "register_operand"))
21005 (use (match_operand:MODEF 1 "general_operand"))
21006 (use (match_operand:MODEF 2 "general_operand"))]
21007 "TARGET_USE_FANCY_MATH_387"
21008 {
21009 rtx (*gen_truncxf) (rtx, rtx);
21010
21011 rtx_code_label *label = gen_label_rtx ();
21012
21013 rtx op1 = gen_reg_rtx (XFmode);
21014 rtx op2 = gen_reg_rtx (XFmode);
21015
21016 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21017 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21018
21019 emit_label (label);
21020
21021 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
21022 ix86_emit_fp_unordered_jump (label);
21023 LABEL_NUSES (label) = 1;
21024
21025 /* Truncate the result properly for strict SSE math. */
21026 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21027 && !TARGET_MIX_SSE_I387)
21028 gen_truncxf = gen_truncxf<mode>2;
21029 else
21030 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
21031
21032 emit_insn (gen_truncxf (operands[0], op1));
21033 DONE;
21034 })
21035
21036 (define_int_iterator SINCOS
21037 [UNSPEC_SIN
21038 UNSPEC_COS])
21039
21040 (define_int_attr sincos
21041 [(UNSPEC_SIN "sin")
21042 (UNSPEC_COS "cos")])
21043
21044 (define_insn "<sincos>xf2"
21045 [(set (match_operand:XF 0 "register_operand" "=f")
21046 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21047 SINCOS))]
21048 "TARGET_USE_FANCY_MATH_387
21049 && flag_unsafe_math_optimizations"
21050 "f<sincos>"
21051 [(set_attr "type" "fpspc")
21052 (set_attr "znver1_decode" "vector")
21053 (set_attr "mode" "XF")])
21054
21055 (define_expand "<sincos><mode>2"
21056 [(set (match_operand:MODEF 0 "register_operand")
21057 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
21058 SINCOS))]
21059 "TARGET_USE_FANCY_MATH_387
21060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21061 || TARGET_MIX_SSE_I387)
21062 && flag_unsafe_math_optimizations"
21063 {
21064 rtx op0 = gen_reg_rtx (XFmode);
21065 rtx op1 = gen_reg_rtx (XFmode);
21066
21067 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21068 emit_insn (gen_<sincos>xf2 (op0, op1));
21069 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21070 DONE;
21071 })
21072
21073 (define_insn "sincosxf3"
21074 [(set (match_operand:XF 0 "register_operand" "=f")
21075 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21076 UNSPEC_SINCOS_COS))
21077 (set (match_operand:XF 1 "register_operand" "=f")
21078 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
21079 "TARGET_USE_FANCY_MATH_387
21080 && flag_unsafe_math_optimizations"
21081 "fsincos"
21082 [(set_attr "type" "fpspc")
21083 (set_attr "znver1_decode" "vector")
21084 (set_attr "mode" "XF")])
21085
21086 (define_expand "sincos<mode>3"
21087 [(use (match_operand:MODEF 0 "register_operand"))
21088 (use (match_operand:MODEF 1 "register_operand"))
21089 (use (match_operand:MODEF 2 "general_operand"))]
21090 "TARGET_USE_FANCY_MATH_387
21091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21092 || TARGET_MIX_SSE_I387)
21093 && flag_unsafe_math_optimizations"
21094 {
21095 rtx op0 = gen_reg_rtx (XFmode);
21096 rtx op1 = gen_reg_rtx (XFmode);
21097 rtx op2 = gen_reg_rtx (XFmode);
21098
21099 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21100 emit_insn (gen_sincosxf3 (op0, op1, op2));
21101 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21102 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
21103 DONE;
21104 })
21105
21106 (define_insn "fptanxf4_i387"
21107 [(set (match_operand:SF 0 "register_operand" "=f")
21108 (match_operand:SF 3 "const1_operand"))
21109 (set (match_operand:XF 1 "register_operand" "=f")
21110 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21111 UNSPEC_TAN))]
21112 "TARGET_USE_FANCY_MATH_387
21113 && flag_unsafe_math_optimizations"
21114 "fptan"
21115 [(set_attr "type" "fpspc")
21116 (set_attr "znver1_decode" "vector")
21117 (set_attr "mode" "XF")])
21118
21119 (define_expand "tanxf2"
21120 [(use (match_operand:XF 0 "register_operand"))
21121 (use (match_operand:XF 1 "register_operand"))]
21122 "TARGET_USE_FANCY_MATH_387
21123 && flag_unsafe_math_optimizations"
21124 {
21125 rtx one = gen_reg_rtx (SFmode);
21126 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
21127 CONST1_RTX (SFmode)));
21128 DONE;
21129 })
21130
21131 (define_expand "tan<mode>2"
21132 [(use (match_operand:MODEF 0 "register_operand"))
21133 (use (match_operand:MODEF 1 "general_operand"))]
21134 "TARGET_USE_FANCY_MATH_387
21135 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21136 || TARGET_MIX_SSE_I387)
21137 && flag_unsafe_math_optimizations"
21138 {
21139 rtx op0 = gen_reg_rtx (XFmode);
21140 rtx op1 = gen_reg_rtx (XFmode);
21141
21142 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21143 emit_insn (gen_tanxf2 (op0, op1));
21144 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21145 DONE;
21146 })
21147
21148 (define_insn "atan2xf3"
21149 [(set (match_operand:XF 0 "register_operand" "=f")
21150 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21151 (match_operand:XF 1 "register_operand" "f")]
21152 UNSPEC_FPATAN))
21153 (clobber (match_scratch:XF 3 "=1"))]
21154 "TARGET_USE_FANCY_MATH_387
21155 && flag_unsafe_math_optimizations"
21156 "fpatan"
21157 [(set_attr "type" "fpspc")
21158 (set_attr "znver1_decode" "vector")
21159 (set_attr "mode" "XF")])
21160
21161 (define_expand "atan2<mode>3"
21162 [(use (match_operand:MODEF 0 "register_operand"))
21163 (use (match_operand:MODEF 1 "general_operand"))
21164 (use (match_operand:MODEF 2 "general_operand"))]
21165 "TARGET_USE_FANCY_MATH_387
21166 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21167 || TARGET_MIX_SSE_I387)
21168 && flag_unsafe_math_optimizations"
21169 {
21170 rtx op0 = gen_reg_rtx (XFmode);
21171 rtx op1 = gen_reg_rtx (XFmode);
21172 rtx op2 = gen_reg_rtx (XFmode);
21173
21174 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21175 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21176
21177 emit_insn (gen_atan2xf3 (op0, op1, op2));
21178 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21179 DONE;
21180 })
21181
21182 (define_expand "atanxf2"
21183 [(parallel [(set (match_operand:XF 0 "register_operand")
21184 (unspec:XF [(match_dup 2)
21185 (match_operand:XF 1 "register_operand")]
21186 UNSPEC_FPATAN))
21187 (clobber (scratch:XF))])]
21188 "TARGET_USE_FANCY_MATH_387
21189 && flag_unsafe_math_optimizations"
21190 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21191
21192 (define_expand "atan<mode>2"
21193 [(use (match_operand:MODEF 0 "register_operand"))
21194 (use (match_operand:MODEF 1 "general_operand"))]
21195 "TARGET_USE_FANCY_MATH_387
21196 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21197 || TARGET_MIX_SSE_I387)
21198 && flag_unsafe_math_optimizations"
21199 {
21200 rtx op0 = gen_reg_rtx (XFmode);
21201 rtx op1 = gen_reg_rtx (XFmode);
21202
21203 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21204 emit_insn (gen_atanxf2 (op0, op1));
21205 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21206 DONE;
21207 })
21208
21209 (define_expand "asinxf2"
21210 [(set (match_dup 2)
21211 (mult:XF (match_operand:XF 1 "register_operand")
21212 (match_dup 1)))
21213 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21214 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21215 (parallel [(set (match_operand:XF 0 "register_operand")
21216 (unspec:XF [(match_dup 5) (match_dup 1)]
21217 UNSPEC_FPATAN))
21218 (clobber (scratch:XF))])]
21219 "TARGET_USE_FANCY_MATH_387
21220 && flag_unsafe_math_optimizations"
21221 {
21222 int i;
21223
21224 for (i = 2; i < 6; i++)
21225 operands[i] = gen_reg_rtx (XFmode);
21226
21227 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21228 })
21229
21230 (define_expand "asin<mode>2"
21231 [(use (match_operand:MODEF 0 "register_operand"))
21232 (use (match_operand:MODEF 1 "general_operand"))]
21233 "TARGET_USE_FANCY_MATH_387
21234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21235 || TARGET_MIX_SSE_I387)
21236 && flag_unsafe_math_optimizations"
21237 {
21238 rtx op0 = gen_reg_rtx (XFmode);
21239 rtx op1 = gen_reg_rtx (XFmode);
21240
21241 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21242 emit_insn (gen_asinxf2 (op0, op1));
21243 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21244 DONE;
21245 })
21246
21247 (define_expand "acosxf2"
21248 [(set (match_dup 2)
21249 (mult:XF (match_operand:XF 1 "register_operand")
21250 (match_dup 1)))
21251 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21252 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21253 (parallel [(set (match_operand:XF 0 "register_operand")
21254 (unspec:XF [(match_dup 1) (match_dup 5)]
21255 UNSPEC_FPATAN))
21256 (clobber (scratch:XF))])]
21257 "TARGET_USE_FANCY_MATH_387
21258 && flag_unsafe_math_optimizations"
21259 {
21260 int i;
21261
21262 for (i = 2; i < 6; i++)
21263 operands[i] = gen_reg_rtx (XFmode);
21264
21265 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21266 })
21267
21268 (define_expand "acos<mode>2"
21269 [(use (match_operand:MODEF 0 "register_operand"))
21270 (use (match_operand:MODEF 1 "general_operand"))]
21271 "TARGET_USE_FANCY_MATH_387
21272 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21273 || TARGET_MIX_SSE_I387)
21274 && flag_unsafe_math_optimizations"
21275 {
21276 rtx op0 = gen_reg_rtx (XFmode);
21277 rtx op1 = gen_reg_rtx (XFmode);
21278
21279 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21280 emit_insn (gen_acosxf2 (op0, op1));
21281 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21282 DONE;
21283 })
21284
21285 (define_expand "sinhxf2"
21286 [(use (match_operand:XF 0 "register_operand"))
21287 (use (match_operand:XF 1 "register_operand"))]
21288 "TARGET_USE_FANCY_MATH_387
21289 && flag_finite_math_only
21290 && flag_unsafe_math_optimizations"
21291 {
21292 ix86_emit_i387_sinh (operands[0], operands[1]);
21293 DONE;
21294 })
21295
21296 (define_expand "sinh<mode>2"
21297 [(use (match_operand:MODEF 0 "register_operand"))
21298 (use (match_operand:MODEF 1 "general_operand"))]
21299 "TARGET_USE_FANCY_MATH_387
21300 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21301 || TARGET_MIX_SSE_I387)
21302 && flag_finite_math_only
21303 && flag_unsafe_math_optimizations"
21304 {
21305 rtx op0 = gen_reg_rtx (XFmode);
21306 rtx op1 = gen_reg_rtx (XFmode);
21307
21308 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21309 emit_insn (gen_sinhxf2 (op0, op1));
21310 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21311 DONE;
21312 })
21313
21314 (define_expand "coshxf2"
21315 [(use (match_operand:XF 0 "register_operand"))
21316 (use (match_operand:XF 1 "register_operand"))]
21317 "TARGET_USE_FANCY_MATH_387
21318 && flag_unsafe_math_optimizations"
21319 {
21320 ix86_emit_i387_cosh (operands[0], operands[1]);
21321 DONE;
21322 })
21323
21324 (define_expand "cosh<mode>2"
21325 [(use (match_operand:MODEF 0 "register_operand"))
21326 (use (match_operand:MODEF 1 "general_operand"))]
21327 "TARGET_USE_FANCY_MATH_387
21328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21329 || TARGET_MIX_SSE_I387)
21330 && flag_unsafe_math_optimizations"
21331 {
21332 rtx op0 = gen_reg_rtx (XFmode);
21333 rtx op1 = gen_reg_rtx (XFmode);
21334
21335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21336 emit_insn (gen_coshxf2 (op0, op1));
21337 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21338 DONE;
21339 })
21340
21341 (define_expand "tanhxf2"
21342 [(use (match_operand:XF 0 "register_operand"))
21343 (use (match_operand:XF 1 "register_operand"))]
21344 "TARGET_USE_FANCY_MATH_387
21345 && flag_unsafe_math_optimizations"
21346 {
21347 ix86_emit_i387_tanh (operands[0], operands[1]);
21348 DONE;
21349 })
21350
21351 (define_expand "tanh<mode>2"
21352 [(use (match_operand:MODEF 0 "register_operand"))
21353 (use (match_operand:MODEF 1 "general_operand"))]
21354 "TARGET_USE_FANCY_MATH_387
21355 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21356 || TARGET_MIX_SSE_I387)
21357 && flag_unsafe_math_optimizations"
21358 {
21359 rtx op0 = gen_reg_rtx (XFmode);
21360 rtx op1 = gen_reg_rtx (XFmode);
21361
21362 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21363 emit_insn (gen_tanhxf2 (op0, op1));
21364 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21365 DONE;
21366 })
21367
21368 (define_expand "asinhxf2"
21369 [(use (match_operand:XF 0 "register_operand"))
21370 (use (match_operand:XF 1 "register_operand"))]
21371 "TARGET_USE_FANCY_MATH_387
21372 && flag_finite_math_only
21373 && flag_unsafe_math_optimizations"
21374 {
21375 ix86_emit_i387_asinh (operands[0], operands[1]);
21376 DONE;
21377 })
21378
21379 (define_expand "asinh<mode>2"
21380 [(use (match_operand:MODEF 0 "register_operand"))
21381 (use (match_operand:MODEF 1 "general_operand"))]
21382 "TARGET_USE_FANCY_MATH_387
21383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21384 || TARGET_MIX_SSE_I387)
21385 && flag_finite_math_only
21386 && flag_unsafe_math_optimizations"
21387 {
21388 rtx op0 = gen_reg_rtx (XFmode);
21389 rtx op1 = gen_reg_rtx (XFmode);
21390
21391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21392 emit_insn (gen_asinhxf2 (op0, op1));
21393 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21394 DONE;
21395 })
21396
21397 (define_expand "acoshxf2"
21398 [(use (match_operand:XF 0 "register_operand"))
21399 (use (match_operand:XF 1 "register_operand"))]
21400 "TARGET_USE_FANCY_MATH_387
21401 && flag_unsafe_math_optimizations"
21402 {
21403 ix86_emit_i387_acosh (operands[0], operands[1]);
21404 DONE;
21405 })
21406
21407 (define_expand "acosh<mode>2"
21408 [(use (match_operand:MODEF 0 "register_operand"))
21409 (use (match_operand:MODEF 1 "general_operand"))]
21410 "TARGET_USE_FANCY_MATH_387
21411 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21412 || TARGET_MIX_SSE_I387)
21413 && flag_unsafe_math_optimizations"
21414 {
21415 rtx op0 = gen_reg_rtx (XFmode);
21416 rtx op1 = gen_reg_rtx (XFmode);
21417
21418 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21419 emit_insn (gen_acoshxf2 (op0, op1));
21420 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21421 DONE;
21422 })
21423
21424 (define_expand "atanhxf2"
21425 [(use (match_operand:XF 0 "register_operand"))
21426 (use (match_operand:XF 1 "register_operand"))]
21427 "TARGET_USE_FANCY_MATH_387
21428 && flag_unsafe_math_optimizations"
21429 {
21430 ix86_emit_i387_atanh (operands[0], operands[1]);
21431 DONE;
21432 })
21433
21434 (define_expand "atanh<mode>2"
21435 [(use (match_operand:MODEF 0 "register_operand"))
21436 (use (match_operand:MODEF 1 "general_operand"))]
21437 "TARGET_USE_FANCY_MATH_387
21438 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21439 || TARGET_MIX_SSE_I387)
21440 && flag_unsafe_math_optimizations"
21441 {
21442 rtx op0 = gen_reg_rtx (XFmode);
21443 rtx op1 = gen_reg_rtx (XFmode);
21444
21445 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21446 emit_insn (gen_atanhxf2 (op0, op1));
21447 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21448 DONE;
21449 })
21450
21451 (define_insn "fyl2xxf3_i387"
21452 [(set (match_operand:XF 0 "register_operand" "=f")
21453 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21454 (match_operand:XF 2 "register_operand" "f")]
21455 UNSPEC_FYL2X))
21456 (clobber (match_scratch:XF 3 "=2"))]
21457 "TARGET_USE_FANCY_MATH_387
21458 && flag_unsafe_math_optimizations"
21459 "fyl2x"
21460 [(set_attr "type" "fpspc")
21461 (set_attr "znver1_decode" "vector")
21462 (set_attr "mode" "XF")])
21463
21464 (define_expand "logxf2"
21465 [(parallel [(set (match_operand:XF 0 "register_operand")
21466 (unspec:XF [(match_operand:XF 1 "register_operand")
21467 (match_dup 2)] UNSPEC_FYL2X))
21468 (clobber (scratch:XF))])]
21469 "TARGET_USE_FANCY_MATH_387
21470 && flag_unsafe_math_optimizations"
21471 {
21472 operands[2]
21473 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21474 })
21475
21476 (define_expand "log<mode>2"
21477 [(use (match_operand:MODEF 0 "register_operand"))
21478 (use (match_operand:MODEF 1 "general_operand"))]
21479 "TARGET_USE_FANCY_MATH_387
21480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21481 || TARGET_MIX_SSE_I387)
21482 && flag_unsafe_math_optimizations"
21483 {
21484 rtx op0 = gen_reg_rtx (XFmode);
21485 rtx op1 = gen_reg_rtx (XFmode);
21486
21487 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21488 emit_insn (gen_logxf2 (op0, op1));
21489 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21490 DONE;
21491 })
21492
21493 (define_expand "log10xf2"
21494 [(parallel [(set (match_operand:XF 0 "register_operand")
21495 (unspec:XF [(match_operand:XF 1 "register_operand")
21496 (match_dup 2)] UNSPEC_FYL2X))
21497 (clobber (scratch:XF))])]
21498 "TARGET_USE_FANCY_MATH_387
21499 && flag_unsafe_math_optimizations"
21500 {
21501 operands[2]
21502 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21503 })
21504
21505 (define_expand "log10<mode>2"
21506 [(use (match_operand:MODEF 0 "register_operand"))
21507 (use (match_operand:MODEF 1 "general_operand"))]
21508 "TARGET_USE_FANCY_MATH_387
21509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21510 || TARGET_MIX_SSE_I387)
21511 && flag_unsafe_math_optimizations"
21512 {
21513 rtx op0 = gen_reg_rtx (XFmode);
21514 rtx op1 = gen_reg_rtx (XFmode);
21515
21516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21517 emit_insn (gen_log10xf2 (op0, op1));
21518 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21519 DONE;
21520 })
21521
21522 (define_expand "log2xf2"
21523 [(parallel [(set (match_operand:XF 0 "register_operand")
21524 (unspec:XF [(match_operand:XF 1 "register_operand")
21525 (match_dup 2)] UNSPEC_FYL2X))
21526 (clobber (scratch:XF))])]
21527 "TARGET_USE_FANCY_MATH_387
21528 && flag_unsafe_math_optimizations"
21529 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21530
21531 (define_expand "log2<mode>2"
21532 [(use (match_operand:MODEF 0 "register_operand"))
21533 (use (match_operand:MODEF 1 "general_operand"))]
21534 "TARGET_USE_FANCY_MATH_387
21535 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21536 || TARGET_MIX_SSE_I387)
21537 && flag_unsafe_math_optimizations"
21538 {
21539 rtx op0 = gen_reg_rtx (XFmode);
21540 rtx op1 = gen_reg_rtx (XFmode);
21541
21542 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21543 emit_insn (gen_log2xf2 (op0, op1));
21544 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21545 DONE;
21546 })
21547
21548 (define_insn "fyl2xp1xf3_i387"
21549 [(set (match_operand:XF 0 "register_operand" "=f")
21550 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21551 (match_operand:XF 2 "register_operand" "f")]
21552 UNSPEC_FYL2XP1))
21553 (clobber (match_scratch:XF 3 "=2"))]
21554 "TARGET_USE_FANCY_MATH_387
21555 && flag_unsafe_math_optimizations"
21556 "fyl2xp1"
21557 [(set_attr "type" "fpspc")
21558 (set_attr "znver1_decode" "vector")
21559 (set_attr "mode" "XF")])
21560
21561 (define_expand "log1pxf2"
21562 [(use (match_operand:XF 0 "register_operand"))
21563 (use (match_operand:XF 1 "register_operand"))]
21564 "TARGET_USE_FANCY_MATH_387
21565 && flag_unsafe_math_optimizations"
21566 {
21567 ix86_emit_i387_log1p (operands[0], operands[1]);
21568 DONE;
21569 })
21570
21571 (define_expand "log1p<mode>2"
21572 [(use (match_operand:MODEF 0 "register_operand"))
21573 (use (match_operand:MODEF 1 "general_operand"))]
21574 "TARGET_USE_FANCY_MATH_387
21575 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21576 || TARGET_MIX_SSE_I387)
21577 && flag_unsafe_math_optimizations"
21578 {
21579 rtx op0 = gen_reg_rtx (XFmode);
21580 rtx op1 = gen_reg_rtx (XFmode);
21581
21582 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21583 emit_insn (gen_log1pxf2 (op0, op1));
21584 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21585 DONE;
21586 })
21587
21588 (define_insn "fxtractxf3_i387"
21589 [(set (match_operand:XF 0 "register_operand" "=f")
21590 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21591 UNSPEC_XTRACT_FRACT))
21592 (set (match_operand:XF 1 "register_operand" "=f")
21593 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21594 "TARGET_USE_FANCY_MATH_387
21595 && flag_unsafe_math_optimizations"
21596 "fxtract"
21597 [(set_attr "type" "fpspc")
21598 (set_attr "znver1_decode" "vector")
21599 (set_attr "mode" "XF")])
21600
21601 (define_expand "logbxf2"
21602 [(parallel [(set (match_dup 2)
21603 (unspec:XF [(match_operand:XF 1 "register_operand")]
21604 UNSPEC_XTRACT_FRACT))
21605 (set (match_operand:XF 0 "register_operand")
21606 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21607 "TARGET_USE_FANCY_MATH_387
21608 && flag_unsafe_math_optimizations"
21609 "operands[2] = gen_reg_rtx (XFmode);")
21610
21611 (define_expand "logb<mode>2"
21612 [(use (match_operand:MODEF 0 "register_operand"))
21613 (use (match_operand:MODEF 1 "general_operand"))]
21614 "TARGET_USE_FANCY_MATH_387
21615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21616 || TARGET_MIX_SSE_I387)
21617 && flag_unsafe_math_optimizations"
21618 {
21619 rtx op0 = gen_reg_rtx (XFmode);
21620 rtx op1 = gen_reg_rtx (XFmode);
21621
21622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21623 emit_insn (gen_logbxf2 (op0, op1));
21624 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21625 DONE;
21626 })
21627
21628 (define_expand "ilogbxf2"
21629 [(use (match_operand:SI 0 "register_operand"))
21630 (use (match_operand:XF 1 "register_operand"))]
21631 "TARGET_USE_FANCY_MATH_387
21632 && flag_unsafe_math_optimizations"
21633 {
21634 rtx op0, op1;
21635
21636 if (optimize_insn_for_size_p ())
21637 FAIL;
21638
21639 op0 = gen_reg_rtx (XFmode);
21640 op1 = gen_reg_rtx (XFmode);
21641
21642 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21643 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21644 DONE;
21645 })
21646
21647 (define_expand "ilogb<mode>2"
21648 [(use (match_operand:SI 0 "register_operand"))
21649 (use (match_operand:MODEF 1 "general_operand"))]
21650 "TARGET_USE_FANCY_MATH_387
21651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21652 || TARGET_MIX_SSE_I387)
21653 && flag_unsafe_math_optimizations"
21654 {
21655 rtx op0, op1, op2;
21656
21657 if (optimize_insn_for_size_p ())
21658 FAIL;
21659
21660 op0 = gen_reg_rtx (XFmode);
21661 op1 = gen_reg_rtx (XFmode);
21662 op2 = gen_reg_rtx (XFmode);
21663
21664 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21665 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21666 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21667 DONE;
21668 })
21669
21670 (define_insn "*f2xm1xf2_i387"
21671 [(set (match_operand:XF 0 "register_operand" "=f")
21672 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21673 UNSPEC_F2XM1))]
21674 "TARGET_USE_FANCY_MATH_387
21675 && flag_unsafe_math_optimizations"
21676 "f2xm1"
21677 [(set_attr "type" "fpspc")
21678 (set_attr "znver1_decode" "vector")
21679 (set_attr "mode" "XF")])
21680
21681 (define_insn "fscalexf4_i387"
21682 [(set (match_operand:XF 0 "register_operand" "=f")
21683 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21684 (match_operand:XF 3 "register_operand" "1")]
21685 UNSPEC_FSCALE_FRACT))
21686 (set (match_operand:XF 1 "register_operand" "=f")
21687 (unspec:XF [(match_dup 2) (match_dup 3)]
21688 UNSPEC_FSCALE_EXP))]
21689 "TARGET_USE_FANCY_MATH_387
21690 && flag_unsafe_math_optimizations"
21691 "fscale"
21692 [(set_attr "type" "fpspc")
21693 (set_attr "znver1_decode" "vector")
21694 (set_attr "mode" "XF")])
21695
21696 (define_expand "expNcorexf3"
21697 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21698 (match_operand:XF 2 "register_operand")))
21699 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21700 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21701 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21702 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21703 (parallel [(set (match_operand:XF 0 "register_operand")
21704 (unspec:XF [(match_dup 8) (match_dup 4)]
21705 UNSPEC_FSCALE_FRACT))
21706 (set (match_dup 9)
21707 (unspec:XF [(match_dup 8) (match_dup 4)]
21708 UNSPEC_FSCALE_EXP))])]
21709 "TARGET_USE_FANCY_MATH_387
21710 && flag_unsafe_math_optimizations"
21711 {
21712 int i;
21713
21714 for (i = 3; i < 10; i++)
21715 operands[i] = gen_reg_rtx (XFmode);
21716
21717 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21718 })
21719
21720 (define_expand "expxf2"
21721 [(use (match_operand:XF 0 "register_operand"))
21722 (use (match_operand:XF 1 "register_operand"))]
21723 "TARGET_USE_FANCY_MATH_387
21724 && flag_unsafe_math_optimizations"
21725 {
21726 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21727
21728 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21729 DONE;
21730 })
21731
21732 (define_expand "exp<mode>2"
21733 [(use (match_operand:MODEF 0 "register_operand"))
21734 (use (match_operand:MODEF 1 "general_operand"))]
21735 "TARGET_USE_FANCY_MATH_387
21736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21737 || TARGET_MIX_SSE_I387)
21738 && flag_unsafe_math_optimizations"
21739 {
21740 rtx op0 = gen_reg_rtx (XFmode);
21741 rtx op1 = gen_reg_rtx (XFmode);
21742
21743 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21744 emit_insn (gen_expxf2 (op0, op1));
21745 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21746 DONE;
21747 })
21748
21749 (define_expand "exp10xf2"
21750 [(use (match_operand:XF 0 "register_operand"))
21751 (use (match_operand:XF 1 "register_operand"))]
21752 "TARGET_USE_FANCY_MATH_387
21753 && flag_unsafe_math_optimizations"
21754 {
21755 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21756
21757 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21758 DONE;
21759 })
21760
21761 (define_expand "exp10<mode>2"
21762 [(use (match_operand:MODEF 0 "register_operand"))
21763 (use (match_operand:MODEF 1 "general_operand"))]
21764 "TARGET_USE_FANCY_MATH_387
21765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21766 || TARGET_MIX_SSE_I387)
21767 && flag_unsafe_math_optimizations"
21768 {
21769 rtx op0 = gen_reg_rtx (XFmode);
21770 rtx op1 = gen_reg_rtx (XFmode);
21771
21772 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21773 emit_insn (gen_exp10xf2 (op0, op1));
21774 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21775 DONE;
21776 })
21777
21778 (define_expand "exp2xf2"
21779 [(use (match_operand:XF 0 "register_operand"))
21780 (use (match_operand:XF 1 "register_operand"))]
21781 "TARGET_USE_FANCY_MATH_387
21782 && flag_unsafe_math_optimizations"
21783 {
21784 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21785
21786 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21787 DONE;
21788 })
21789
21790 (define_expand "exp2<mode>2"
21791 [(use (match_operand:MODEF 0 "register_operand"))
21792 (use (match_operand:MODEF 1 "general_operand"))]
21793 "TARGET_USE_FANCY_MATH_387
21794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21795 || TARGET_MIX_SSE_I387)
21796 && flag_unsafe_math_optimizations"
21797 {
21798 rtx op0 = gen_reg_rtx (XFmode);
21799 rtx op1 = gen_reg_rtx (XFmode);
21800
21801 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21802 emit_insn (gen_exp2xf2 (op0, op1));
21803 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21804 DONE;
21805 })
21806
21807 (define_expand "expm1xf2"
21808 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21809 (match_dup 2)))
21810 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21811 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21812 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21813 (parallel [(set (match_dup 7)
21814 (unspec:XF [(match_dup 6) (match_dup 4)]
21815 UNSPEC_FSCALE_FRACT))
21816 (set (match_dup 8)
21817 (unspec:XF [(match_dup 6) (match_dup 4)]
21818 UNSPEC_FSCALE_EXP))])
21819 (parallel [(set (match_dup 10)
21820 (unspec:XF [(match_dup 9) (match_dup 8)]
21821 UNSPEC_FSCALE_FRACT))
21822 (set (match_dup 11)
21823 (unspec:XF [(match_dup 9) (match_dup 8)]
21824 UNSPEC_FSCALE_EXP))])
21825 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21826 (set (match_operand:XF 0 "register_operand")
21827 (plus:XF (match_dup 12) (match_dup 7)))]
21828 "TARGET_USE_FANCY_MATH_387
21829 && flag_unsafe_math_optimizations"
21830 {
21831 int i;
21832
21833 for (i = 2; i < 13; i++)
21834 operands[i] = gen_reg_rtx (XFmode);
21835
21836 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21837 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21838 })
21839
21840 (define_expand "expm1<mode>2"
21841 [(use (match_operand:MODEF 0 "register_operand"))
21842 (use (match_operand:MODEF 1 "general_operand"))]
21843 "TARGET_USE_FANCY_MATH_387
21844 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21845 || TARGET_MIX_SSE_I387)
21846 && flag_unsafe_math_optimizations"
21847 {
21848 rtx op0 = gen_reg_rtx (XFmode);
21849 rtx op1 = gen_reg_rtx (XFmode);
21850
21851 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21852 emit_insn (gen_expm1xf2 (op0, op1));
21853 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21854 DONE;
21855 })
21856
21857 (define_insn "avx512f_scalef<mode>2"
21858 [(set (match_operand:MODEF 0 "register_operand" "=v")
21859 (unspec:MODEF
21860 [(match_operand:MODEF 1 "register_operand" "v")
21861 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21862 UNSPEC_SCALEF))]
21863 "TARGET_AVX512F"
21864 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21865 [(set_attr "prefix" "evex")
21866 (set_attr "mode" "<MODE>")])
21867
21868 (define_expand "ldexpxf3"
21869 [(match_operand:XF 0 "register_operand")
21870 (match_operand:XF 1 "register_operand")
21871 (match_operand:SI 2 "register_operand")]
21872 "TARGET_USE_FANCY_MATH_387
21873 && flag_unsafe_math_optimizations"
21874 {
21875 rtx tmp1 = gen_reg_rtx (XFmode);
21876 rtx tmp2 = gen_reg_rtx (XFmode);
21877
21878 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21879 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21880 operands[1], tmp1));
21881 DONE;
21882 })
21883
21884 (define_expand "ldexp<mode>3"
21885 [(use (match_operand:MODEF 0 "register_operand"))
21886 (use (match_operand:MODEF 1 "general_operand"))
21887 (use (match_operand:SI 2 "register_operand"))]
21888 "((TARGET_USE_FANCY_MATH_387
21889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21890 || TARGET_MIX_SSE_I387))
21891 || (TARGET_AVX512F && TARGET_SSE_MATH))
21892 && flag_unsafe_math_optimizations"
21893 {
21894 /* Prefer avx512f version. */
21895 if (TARGET_AVX512F && TARGET_SSE_MATH)
21896 {
21897 rtx op2 = gen_reg_rtx (<MODE>mode);
21898 operands[1] = force_reg (<MODE>mode, operands[1]);
21899
21900 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21901 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21902 }
21903 else
21904 {
21905 rtx op0 = gen_reg_rtx (XFmode);
21906 rtx op1 = gen_reg_rtx (XFmode);
21907
21908 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21909 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21910 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21911 }
21912 DONE;
21913 })
21914
21915 (define_expand "scalbxf3"
21916 [(parallel [(set (match_operand:XF 0 " register_operand")
21917 (unspec:XF [(match_operand:XF 1 "register_operand")
21918 (match_operand:XF 2 "register_operand")]
21919 UNSPEC_FSCALE_FRACT))
21920 (set (match_dup 3)
21921 (unspec:XF [(match_dup 1) (match_dup 2)]
21922 UNSPEC_FSCALE_EXP))])]
21923 "TARGET_USE_FANCY_MATH_387
21924 && flag_unsafe_math_optimizations"
21925 "operands[3] = gen_reg_rtx (XFmode);")
21926
21927 (define_expand "scalb<mode>3"
21928 [(use (match_operand:MODEF 0 "register_operand"))
21929 (use (match_operand:MODEF 1 "general_operand"))
21930 (use (match_operand:MODEF 2 "general_operand"))]
21931 "TARGET_USE_FANCY_MATH_387
21932 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21933 || TARGET_MIX_SSE_I387)
21934 && flag_unsafe_math_optimizations"
21935 {
21936 rtx op0 = gen_reg_rtx (XFmode);
21937 rtx op1 = gen_reg_rtx (XFmode);
21938 rtx op2 = gen_reg_rtx (XFmode);
21939
21940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21941 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21942 emit_insn (gen_scalbxf3 (op0, op1, op2));
21943 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21944 DONE;
21945 })
21946
21947 (define_expand "significandxf2"
21948 [(parallel [(set (match_operand:XF 0 "register_operand")
21949 (unspec:XF [(match_operand:XF 1 "register_operand")]
21950 UNSPEC_XTRACT_FRACT))
21951 (set (match_dup 2)
21952 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21953 "TARGET_USE_FANCY_MATH_387
21954 && flag_unsafe_math_optimizations"
21955 "operands[2] = gen_reg_rtx (XFmode);")
21956
21957 (define_expand "significand<mode>2"
21958 [(use (match_operand:MODEF 0 "register_operand"))
21959 (use (match_operand:MODEF 1 "general_operand"))]
21960 "TARGET_USE_FANCY_MATH_387
21961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21962 || TARGET_MIX_SSE_I387)
21963 && flag_unsafe_math_optimizations"
21964 {
21965 rtx op0 = gen_reg_rtx (XFmode);
21966 rtx op1 = gen_reg_rtx (XFmode);
21967
21968 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21969 emit_insn (gen_significandxf2 (op0, op1));
21970 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21971 DONE;
21972 })
21973 \f
21974
21975 (define_insn "sse4_1_round<mode>2"
21976 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21977 (unspec:MODEFH
21978 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
21979 (match_operand:SI 2 "const_0_to_15_operand")]
21980 UNSPEC_ROUND))]
21981 "TARGET_SSE4_1"
21982 "@
21983 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21984 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21985 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21986 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21987 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21988 [(set_attr "type" "ssecvt")
21989 (set_attr "prefix_extra" "1,1,1,*,*")
21990 (set_attr "length_immediate" "1")
21991 (set_attr "addr" "*,*,gpr16,*,*")
21992 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21993 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21994 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21995 (set_attr "mode" "<MODE>")
21996 (set (attr "preferred_for_speed")
21997 (cond [(match_test "TARGET_AVX")
21998 (symbol_ref "true")
21999 (eq_attr "alternative" "1,2")
22000 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
22001 ]
22002 (symbol_ref "true")))])
22003
22004 (define_insn "rintxf2"
22005 [(set (match_operand:XF 0 "register_operand" "=f")
22006 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22007 UNSPEC_FRNDINT))]
22008 "TARGET_USE_FANCY_MATH_387"
22009 "frndint"
22010 [(set_attr "type" "fpspc")
22011 (set_attr "znver1_decode" "vector")
22012 (set_attr "mode" "XF")])
22013
22014 (define_expand "rinthf2"
22015 [(match_operand:HF 0 "register_operand")
22016 (match_operand:HF 1 "nonimmediate_operand")]
22017 "TARGET_AVX512FP16"
22018 {
22019 emit_insn (gen_sse4_1_roundhf2 (operands[0],
22020 operands[1],
22021 GEN_INT (ROUND_MXCSR)));
22022 DONE;
22023 })
22024
22025 (define_expand "rint<mode>2"
22026 [(use (match_operand:MODEF 0 "register_operand"))
22027 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
22028 "TARGET_USE_FANCY_MATH_387
22029 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
22030 {
22031 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22032 {
22033 if (TARGET_SSE4_1)
22034 emit_insn (gen_sse4_1_round<mode>2
22035 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
22036 else
22037 ix86_expand_rint (operands[0], operands[1]);
22038 }
22039 else
22040 {
22041 rtx op0 = gen_reg_rtx (XFmode);
22042 rtx op1 = gen_reg_rtx (XFmode);
22043
22044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22045 emit_insn (gen_rintxf2 (op0, op1));
22046 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22047 }
22048 DONE;
22049 })
22050
22051 (define_expand "nearbyintxf2"
22052 [(set (match_operand:XF 0 "register_operand")
22053 (unspec:XF [(match_operand:XF 1 "register_operand")]
22054 UNSPEC_FRNDINT))]
22055 "TARGET_USE_FANCY_MATH_387
22056 && !flag_trapping_math")
22057
22058 (define_expand "nearbyinthf2"
22059 [(match_operand:HF 0 "register_operand")
22060 (match_operand:HF 1 "nonimmediate_operand")]
22061 "TARGET_AVX512FP16"
22062 {
22063 emit_insn (gen_sse4_1_roundhf2 (operands[0],
22064 operands[1],
22065 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
22066 DONE;
22067 })
22068
22069 (define_expand "nearbyint<mode>2"
22070 [(use (match_operand:MODEF 0 "register_operand"))
22071 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
22072 "(TARGET_USE_FANCY_MATH_387
22073 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22074 || TARGET_MIX_SSE_I387)
22075 && !flag_trapping_math)
22076 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
22077 {
22078 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
22079 emit_insn (gen_sse4_1_round<mode>2
22080 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
22081 | ROUND_NO_EXC)));
22082 else
22083 {
22084 rtx op0 = gen_reg_rtx (XFmode);
22085 rtx op1 = gen_reg_rtx (XFmode);
22086
22087 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22088 emit_insn (gen_nearbyintxf2 (op0, op1));
22089 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22090 }
22091 DONE;
22092 })
22093
22094 (define_expand "roundhf2"
22095 [(match_operand:HF 0 "register_operand")
22096 (match_operand:HF 1 "register_operand")]
22097 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22098 {
22099 ix86_expand_round_sse4 (operands[0], operands[1]);
22100 DONE;
22101 })
22102
22103 (define_expand "round<mode>2"
22104 [(match_operand:X87MODEF 0 "register_operand")
22105 (match_operand:X87MODEF 1 "nonimmediate_operand")]
22106 "(TARGET_USE_FANCY_MATH_387
22107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22108 || TARGET_MIX_SSE_I387)
22109 && flag_unsafe_math_optimizations
22110 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22111 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22112 && !flag_trapping_math && !flag_rounding_math)"
22113 {
22114 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22115 && !flag_trapping_math && !flag_rounding_math)
22116 {
22117 if (TARGET_SSE4_1)
22118 {
22119 operands[1] = force_reg (<MODE>mode, operands[1]);
22120 ix86_expand_round_sse4 (operands[0], operands[1]);
22121 }
22122 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22123 ix86_expand_round (operands[0], operands[1]);
22124 else
22125 ix86_expand_rounddf_32 (operands[0], operands[1]);
22126 }
22127 else
22128 {
22129 operands[1] = force_reg (<MODE>mode, operands[1]);
22130 ix86_emit_i387_round (operands[0], operands[1]);
22131 }
22132 DONE;
22133 })
22134
22135 (define_insn "lrintxfdi2"
22136 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22137 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22138 UNSPEC_FIST))
22139 (clobber (match_scratch:XF 2 "=&f"))]
22140 "TARGET_USE_FANCY_MATH_387"
22141 "* return output_fix_trunc (insn, operands, false);"
22142 [(set_attr "type" "fpspc")
22143 (set_attr "mode" "DI")])
22144
22145 (define_insn "lrintxf<mode>2"
22146 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22147 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22148 UNSPEC_FIST))]
22149 "TARGET_USE_FANCY_MATH_387"
22150 "* return output_fix_trunc (insn, operands, false);"
22151 [(set_attr "type" "fpspc")
22152 (set_attr "mode" "<MODE>")])
22153
22154 (define_expand "lroundhf<mode>2"
22155 [(set (match_operand:SWI248 0 "register_operand")
22156 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
22157 UNSPEC_FIX_NOTRUNC))]
22158 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22159 {
22160 ix86_expand_lround (operands[0], operands[1]);
22161 DONE;
22162 })
22163
22164 (define_expand "lrinthf<mode>2"
22165 [(set (match_operand:SWI48 0 "register_operand")
22166 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
22167 UNSPEC_FIX_NOTRUNC))]
22168 "TARGET_AVX512FP16")
22169
22170 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
22171 [(set (match_operand:SWI48 0 "register_operand")
22172 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
22173 UNSPEC_FIX_NOTRUNC))]
22174 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
22175
22176 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
22177 [(match_operand:SWI248x 0 "nonimmediate_operand")
22178 (match_operand:X87MODEF 1 "register_operand")]
22179 "(TARGET_USE_FANCY_MATH_387
22180 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
22181 || TARGET_MIX_SSE_I387)
22182 && flag_unsafe_math_optimizations)
22183 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22184 && <SWI248x:MODE>mode != HImode
22185 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22186 && !flag_trapping_math && !flag_rounding_math)"
22187 {
22188 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22189 && <SWI248x:MODE>mode != HImode
22190 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22191 && !flag_trapping_math && !flag_rounding_math)
22192 ix86_expand_lround (operands[0], operands[1]);
22193 else
22194 ix86_emit_i387_round (operands[0], operands[1]);
22195 DONE;
22196 })
22197
22198 (define_int_iterator FRNDINT_ROUNDING
22199 [UNSPEC_FRNDINT_ROUNDEVEN
22200 UNSPEC_FRNDINT_FLOOR
22201 UNSPEC_FRNDINT_CEIL
22202 UNSPEC_FRNDINT_TRUNC])
22203
22204 (define_int_iterator FIST_ROUNDING
22205 [UNSPEC_FIST_FLOOR
22206 UNSPEC_FIST_CEIL])
22207
22208 ;; Base name for define_insn
22209 (define_int_attr rounding_insn
22210 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22211 (UNSPEC_FRNDINT_FLOOR "floor")
22212 (UNSPEC_FRNDINT_CEIL "ceil")
22213 (UNSPEC_FRNDINT_TRUNC "btrunc")
22214 (UNSPEC_FIST_FLOOR "floor")
22215 (UNSPEC_FIST_CEIL "ceil")])
22216
22217 (define_int_attr rounding
22218 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22219 (UNSPEC_FRNDINT_FLOOR "floor")
22220 (UNSPEC_FRNDINT_CEIL "ceil")
22221 (UNSPEC_FRNDINT_TRUNC "trunc")
22222 (UNSPEC_FIST_FLOOR "floor")
22223 (UNSPEC_FIST_CEIL "ceil")])
22224
22225 (define_int_attr ROUNDING
22226 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
22227 (UNSPEC_FRNDINT_FLOOR "FLOOR")
22228 (UNSPEC_FRNDINT_CEIL "CEIL")
22229 (UNSPEC_FRNDINT_TRUNC "TRUNC")
22230 (UNSPEC_FIST_FLOOR "FLOOR")
22231 (UNSPEC_FIST_CEIL "CEIL")])
22232
22233 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22234 (define_insn_and_split "frndintxf2_<rounding>"
22235 [(set (match_operand:XF 0 "register_operand")
22236 (unspec:XF [(match_operand:XF 1 "register_operand")]
22237 FRNDINT_ROUNDING))
22238 (clobber (reg:CC FLAGS_REG))]
22239 "TARGET_USE_FANCY_MATH_387
22240 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22241 && ix86_pre_reload_split ()"
22242 "#"
22243 "&& 1"
22244 [(const_int 0)]
22245 {
22246 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22247
22248 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22249 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22250
22251 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22252 operands[2], operands[3]));
22253 DONE;
22254 }
22255 [(set_attr "type" "frndint")
22256 (set_attr "i387_cw" "<rounding>")
22257 (set_attr "mode" "XF")])
22258
22259 (define_insn "frndintxf2_<rounding>_i387"
22260 [(set (match_operand:XF 0 "register_operand" "=f")
22261 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22262 FRNDINT_ROUNDING))
22263 (use (match_operand:HI 2 "memory_operand" "m"))
22264 (use (match_operand:HI 3 "memory_operand" "m"))]
22265 "TARGET_USE_FANCY_MATH_387
22266 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22267 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22268 [(set_attr "type" "frndint")
22269 (set_attr "i387_cw" "<rounding>")
22270 (set_attr "mode" "XF")])
22271
22272 (define_expand "<rounding_insn>xf2"
22273 [(parallel [(set (match_operand:XF 0 "register_operand")
22274 (unspec:XF [(match_operand:XF 1 "register_operand")]
22275 FRNDINT_ROUNDING))
22276 (clobber (reg:CC FLAGS_REG))])]
22277 "TARGET_USE_FANCY_MATH_387
22278 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22279
22280 (define_expand "<rounding_insn>hf2"
22281 [(parallel [(set (match_operand:HF 0 "register_operand")
22282 (unspec:HF [(match_operand:HF 1 "register_operand")]
22283 FRNDINT_ROUNDING))
22284 (clobber (reg:CC FLAGS_REG))])]
22285 "TARGET_AVX512FP16"
22286 {
22287 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22288 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22289 DONE;
22290 })
22291
22292 (define_expand "<rounding_insn><mode>2"
22293 [(parallel [(set (match_operand:MODEF 0 "register_operand")
22294 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22295 FRNDINT_ROUNDING))
22296 (clobber (reg:CC FLAGS_REG))])]
22297 "(TARGET_USE_FANCY_MATH_387
22298 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22299 || TARGET_MIX_SSE_I387)
22300 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22301 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22302 && (TARGET_SSE4_1
22303 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22304 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22305 {
22306 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22307 && (TARGET_SSE4_1
22308 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22309 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22310 {
22311 if (TARGET_SSE4_1)
22312 emit_insn (gen_sse4_1_round<mode>2
22313 (operands[0], operands[1],
22314 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22315 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22316 {
22317 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22318 ix86_expand_floorceil (operands[0], operands[1], true);
22319 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22320 ix86_expand_floorceil (operands[0], operands[1], false);
22321 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22322 ix86_expand_trunc (operands[0], operands[1]);
22323 else
22324 gcc_unreachable ();
22325 }
22326 else
22327 {
22328 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22329 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22330 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22331 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22332 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22333 ix86_expand_truncdf_32 (operands[0], operands[1]);
22334 else
22335 gcc_unreachable ();
22336 }
22337 }
22338 else
22339 {
22340 rtx op0 = gen_reg_rtx (XFmode);
22341 rtx op1 = gen_reg_rtx (XFmode);
22342
22343 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22344 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22345 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22346 }
22347 DONE;
22348 })
22349
22350 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22351 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22352 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22353 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22354 FIST_ROUNDING))
22355 (clobber (reg:CC FLAGS_REG))]
22356 "TARGET_USE_FANCY_MATH_387
22357 && flag_unsafe_math_optimizations
22358 && ix86_pre_reload_split ()"
22359 "#"
22360 "&& 1"
22361 [(const_int 0)]
22362 {
22363 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22364
22365 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22366 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22367
22368 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22369 operands[2], operands[3]));
22370 DONE;
22371 }
22372 [(set_attr "type" "fistp")
22373 (set_attr "i387_cw" "<rounding>")
22374 (set_attr "mode" "<MODE>")])
22375
22376 (define_insn "fistdi2_<rounding>"
22377 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22378 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22379 FIST_ROUNDING))
22380 (use (match_operand:HI 2 "memory_operand" "m"))
22381 (use (match_operand:HI 3 "memory_operand" "m"))
22382 (clobber (match_scratch:XF 4 "=&f"))]
22383 "TARGET_USE_FANCY_MATH_387
22384 && flag_unsafe_math_optimizations"
22385 "* return output_fix_trunc (insn, operands, false);"
22386 [(set_attr "type" "fistp")
22387 (set_attr "i387_cw" "<rounding>")
22388 (set_attr "mode" "DI")])
22389
22390 (define_insn "fist<mode>2_<rounding>"
22391 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22392 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22393 FIST_ROUNDING))
22394 (use (match_operand:HI 2 "memory_operand" "m"))
22395 (use (match_operand:HI 3 "memory_operand" "m"))]
22396 "TARGET_USE_FANCY_MATH_387
22397 && flag_unsafe_math_optimizations"
22398 "* return output_fix_trunc (insn, operands, false);"
22399 [(set_attr "type" "fistp")
22400 (set_attr "i387_cw" "<rounding>")
22401 (set_attr "mode" "<MODE>")])
22402
22403 (define_expand "l<rounding_insn>xf<mode>2"
22404 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22405 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22406 FIST_ROUNDING))
22407 (clobber (reg:CC FLAGS_REG))])]
22408 "TARGET_USE_FANCY_MATH_387
22409 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22410 && flag_unsafe_math_optimizations")
22411
22412 (define_expand "l<rounding_insn>hf<mode>2"
22413 [(set (match_operand:SWI48 0 "nonimmediate_operand")
22414 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22415 FIST_ROUNDING))]
22416 "TARGET_AVX512FP16"
22417 {
22418 rtx tmp = gen_reg_rtx (HFmode);
22419 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22420 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22421 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22422 DONE;
22423 })
22424
22425 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22426 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22427 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22428 FIST_ROUNDING))
22429 (clobber (reg:CC FLAGS_REG))])]
22430 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22431 && (TARGET_SSE4_1 || !flag_trapping_math)"
22432 {
22433 if (TARGET_SSE4_1)
22434 {
22435 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22436
22437 emit_insn (gen_sse4_1_round<MODEF:mode>2
22438 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22439 | ROUND_NO_EXC)));
22440 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22441 (operands[0], tmp));
22442 }
22443 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22444 ix86_expand_lfloorceil (operands[0], operands[1], true);
22445 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22446 ix86_expand_lfloorceil (operands[0], operands[1], false);
22447 else
22448 gcc_unreachable ();
22449
22450 DONE;
22451 })
22452
22453 (define_insn "fxam<mode>2_i387"
22454 [(set (match_operand:HI 0 "register_operand" "=a")
22455 (unspec:HI
22456 [(match_operand:X87MODEF 1 "register_operand" "f")]
22457 UNSPEC_FXAM))]
22458 "TARGET_USE_FANCY_MATH_387"
22459 "fxam\n\tfnstsw\t%0"
22460 [(set_attr "type" "multi")
22461 (set_attr "length" "4")
22462 (set_attr "unit" "i387")
22463 (set_attr "mode" "<MODE>")])
22464
22465 (define_expand "signbittf2"
22466 [(use (match_operand:SI 0 "register_operand"))
22467 (use (match_operand:TF 1 "register_operand"))]
22468 "TARGET_SSE"
22469 {
22470 if (TARGET_SSE4_1)
22471 {
22472 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22473 rtx scratch = gen_reg_rtx (QImode);
22474
22475 emit_insn (gen_ptesttf2 (operands[1], mask));
22476 ix86_expand_setcc (scratch, NE,
22477 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22478
22479 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22480 }
22481 else
22482 {
22483 emit_insn (gen_sse_movmskps (operands[0],
22484 gen_lowpart (V4SFmode, operands[1])));
22485 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22486 }
22487 DONE;
22488 })
22489
22490 (define_expand "signbitxf2"
22491 [(use (match_operand:SI 0 "register_operand"))
22492 (use (match_operand:XF 1 "register_operand"))]
22493 "TARGET_USE_FANCY_MATH_387"
22494 {
22495 rtx scratch = gen_reg_rtx (HImode);
22496
22497 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22498 emit_insn (gen_andsi3 (operands[0],
22499 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22500 DONE;
22501 })
22502
22503 (define_insn "movmsk_df"
22504 [(set (match_operand:SI 0 "register_operand" "=r,jr")
22505 (unspec:SI
22506 [(match_operand:DF 1 "register_operand" "x,x")]
22507 UNSPEC_MOVMSK))]
22508 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22509 "%vmovmskpd\t{%1, %0|%0, %1}"
22510 [(set_attr "isa" "noavx,avx")
22511 (set_attr "type" "ssemov")
22512 (set_attr "prefix" "maybe_evex")
22513 (set_attr "mode" "DF")])
22514
22515 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22516 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22517 (define_expand "signbitdf2"
22518 [(use (match_operand:SI 0 "register_operand"))
22519 (use (match_operand:DF 1 "register_operand"))]
22520 "TARGET_USE_FANCY_MATH_387
22521 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22522 {
22523 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22524 {
22525 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22526 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22527 }
22528 else
22529 {
22530 rtx scratch = gen_reg_rtx (HImode);
22531
22532 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22533 emit_insn (gen_andsi3 (operands[0],
22534 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22535 }
22536 DONE;
22537 })
22538
22539 (define_expand "signbitsf2"
22540 [(use (match_operand:SI 0 "register_operand"))
22541 (use (match_operand:SF 1 "register_operand"))]
22542 "TARGET_USE_FANCY_MATH_387
22543 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22544 {
22545 rtx scratch = gen_reg_rtx (HImode);
22546
22547 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22548 emit_insn (gen_andsi3 (operands[0],
22549 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22550 DONE;
22551 })
22552 \f
22553 ;; Block operation instructions
22554
22555 (define_insn "cld"
22556 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22557 ""
22558 "cld"
22559 [(set_attr "length" "1")
22560 (set_attr "length_immediate" "0")
22561 (set_attr "modrm" "0")])
22562
22563 (define_expand "cpymem<mode>"
22564 [(use (match_operand:BLK 0 "memory_operand"))
22565 (use (match_operand:BLK 1 "memory_operand"))
22566 (use (match_operand:SWI48 2 "nonmemory_operand"))
22567 (use (match_operand:SWI48 3 "const_int_operand"))
22568 (use (match_operand:SI 4 "const_int_operand"))
22569 (use (match_operand:SI 5 "const_int_operand"))
22570 (use (match_operand:SI 6 ""))
22571 (use (match_operand:SI 7 ""))
22572 (use (match_operand:SI 8 ""))]
22573 ""
22574 {
22575 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22576 operands[2], NULL, operands[3],
22577 operands[4], operands[5],
22578 operands[6], operands[7],
22579 operands[8], false))
22580 DONE;
22581 else
22582 FAIL;
22583 })
22584
22585 ;; Most CPUs don't like single string operations
22586 ;; Handle this case here to simplify previous expander.
22587
22588 (define_expand "strmov"
22589 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22590 (set (match_operand 1 "memory_operand") (match_dup 4))
22591 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22592 (clobber (reg:CC FLAGS_REG))])
22593 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22594 (clobber (reg:CC FLAGS_REG))])]
22595 ""
22596 {
22597 /* Can't use this for non-default address spaces. */
22598 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22599 FAIL;
22600
22601 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22602
22603 /* If .md ever supports :P for Pmode, these can be directly
22604 in the pattern above. */
22605 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22606 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22607
22608 /* Can't use this if the user has appropriated esi or edi. */
22609 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22610 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22611 {
22612 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22613 operands[2], operands[3],
22614 operands[5], operands[6]));
22615 DONE;
22616 }
22617
22618 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22619 })
22620
22621 (define_expand "strmov_singleop"
22622 [(parallel [(set (match_operand 1 "memory_operand")
22623 (match_operand 3 "memory_operand"))
22624 (set (match_operand 0 "register_operand")
22625 (match_operand 4))
22626 (set (match_operand 2 "register_operand")
22627 (match_operand 5))])]
22628 ""
22629 {
22630 if (TARGET_CLD)
22631 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22632 })
22633
22634 (define_insn "*strmovdi_rex_1"
22635 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22636 (mem:DI (match_operand:P 3 "register_operand" "1")))
22637 (set (match_operand:P 0 "register_operand" "=D")
22638 (plus:P (match_dup 2)
22639 (const_int 8)))
22640 (set (match_operand:P 1 "register_operand" "=S")
22641 (plus:P (match_dup 3)
22642 (const_int 8)))]
22643 "TARGET_64BIT
22644 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22645 && ix86_check_no_addr_space (insn)"
22646 "%^movsq"
22647 [(set_attr "type" "str")
22648 (set_attr "memory" "both")
22649 (set_attr "mode" "DI")])
22650
22651 (define_insn "*strmovsi_1"
22652 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22653 (mem:SI (match_operand:P 3 "register_operand" "1")))
22654 (set (match_operand:P 0 "register_operand" "=D")
22655 (plus:P (match_dup 2)
22656 (const_int 4)))
22657 (set (match_operand:P 1 "register_operand" "=S")
22658 (plus:P (match_dup 3)
22659 (const_int 4)))]
22660 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22661 && ix86_check_no_addr_space (insn)"
22662 "%^movs{l|d}"
22663 [(set_attr "type" "str")
22664 (set_attr "memory" "both")
22665 (set_attr "mode" "SI")])
22666
22667 (define_insn "*strmovhi_1"
22668 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22669 (mem:HI (match_operand:P 3 "register_operand" "1")))
22670 (set (match_operand:P 0 "register_operand" "=D")
22671 (plus:P (match_dup 2)
22672 (const_int 2)))
22673 (set (match_operand:P 1 "register_operand" "=S")
22674 (plus:P (match_dup 3)
22675 (const_int 2)))]
22676 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22677 && ix86_check_no_addr_space (insn)"
22678 "%^movsw"
22679 [(set_attr "type" "str")
22680 (set_attr "memory" "both")
22681 (set_attr "mode" "HI")])
22682
22683 (define_insn "*strmovqi_1"
22684 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22685 (mem:QI (match_operand:P 3 "register_operand" "1")))
22686 (set (match_operand:P 0 "register_operand" "=D")
22687 (plus:P (match_dup 2)
22688 (const_int 1)))
22689 (set (match_operand:P 1 "register_operand" "=S")
22690 (plus:P (match_dup 3)
22691 (const_int 1)))]
22692 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22693 && ix86_check_no_addr_space (insn)"
22694 "%^movsb"
22695 [(set_attr "type" "str")
22696 (set_attr "memory" "both")
22697 (set (attr "prefix_rex")
22698 (if_then_else
22699 (match_test "<P:MODE>mode == DImode")
22700 (const_string "0")
22701 (const_string "*")))
22702 (set_attr "mode" "QI")])
22703
22704 (define_expand "rep_mov"
22705 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22706 (set (match_operand 0 "register_operand")
22707 (match_operand 5))
22708 (set (match_operand 2 "register_operand")
22709 (match_operand 6))
22710 (set (match_operand 1 "memory_operand")
22711 (match_operand 3 "memory_operand"))
22712 (use (match_dup 4))])]
22713 ""
22714 {
22715 if (TARGET_CLD)
22716 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22717 })
22718
22719 (define_insn "*rep_movdi_rex64"
22720 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22721 (set (match_operand:P 0 "register_operand" "=D")
22722 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22723 (const_int 3))
22724 (match_operand:P 3 "register_operand" "0")))
22725 (set (match_operand:P 1 "register_operand" "=S")
22726 (plus:P (ashift:P (match_dup 5) (const_int 3))
22727 (match_operand:P 4 "register_operand" "1")))
22728 (set (mem:BLK (match_dup 3))
22729 (mem:BLK (match_dup 4)))
22730 (use (match_dup 5))]
22731 "TARGET_64BIT
22732 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22733 && ix86_check_no_addr_space (insn)"
22734 "%^rep{%;} movsq"
22735 [(set_attr "type" "str")
22736 (set_attr "prefix_rep" "1")
22737 (set_attr "memory" "both")
22738 (set_attr "mode" "DI")])
22739
22740 (define_insn "*rep_movsi"
22741 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22742 (set (match_operand:P 0 "register_operand" "=D")
22743 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22744 (const_int 2))
22745 (match_operand:P 3 "register_operand" "0")))
22746 (set (match_operand:P 1 "register_operand" "=S")
22747 (plus:P (ashift:P (match_dup 5) (const_int 2))
22748 (match_operand:P 4 "register_operand" "1")))
22749 (set (mem:BLK (match_dup 3))
22750 (mem:BLK (match_dup 4)))
22751 (use (match_dup 5))]
22752 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22753 && ix86_check_no_addr_space (insn)"
22754 "%^rep{%;} movs{l|d}"
22755 [(set_attr "type" "str")
22756 (set_attr "prefix_rep" "1")
22757 (set_attr "memory" "both")
22758 (set_attr "mode" "SI")])
22759
22760 (define_insn "*rep_movqi"
22761 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22762 (set (match_operand:P 0 "register_operand" "=D")
22763 (plus:P (match_operand:P 3 "register_operand" "0")
22764 (match_operand:P 5 "register_operand" "2")))
22765 (set (match_operand:P 1 "register_operand" "=S")
22766 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22767 (set (mem:BLK (match_dup 3))
22768 (mem:BLK (match_dup 4)))
22769 (use (match_dup 5))]
22770 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22771 && ix86_check_no_addr_space (insn)"
22772 "%^rep{%;} movsb"
22773 [(set_attr "type" "str")
22774 (set_attr "prefix_rep" "1")
22775 (set_attr "memory" "both")
22776 (set_attr "mode" "QI")])
22777
22778 (define_expand "setmem<mode>"
22779 [(use (match_operand:BLK 0 "memory_operand"))
22780 (use (match_operand:SWI48 1 "nonmemory_operand"))
22781 (use (match_operand:QI 2 "nonmemory_operand"))
22782 (use (match_operand 3 "const_int_operand"))
22783 (use (match_operand:SI 4 "const_int_operand"))
22784 (use (match_operand:SI 5 "const_int_operand"))
22785 (use (match_operand:SI 6 ""))
22786 (use (match_operand:SI 7 ""))
22787 (use (match_operand:SI 8 ""))]
22788 ""
22789 {
22790 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22791 operands[1], operands[2],
22792 operands[3], operands[4],
22793 operands[5], operands[6],
22794 operands[7], operands[8], true))
22795 DONE;
22796 else
22797 FAIL;
22798 })
22799
22800 ;; Most CPUs don't like single string operations
22801 ;; Handle this case here to simplify previous expander.
22802
22803 (define_expand "strset"
22804 [(set (match_operand 1 "memory_operand")
22805 (match_operand 2 "register_operand"))
22806 (parallel [(set (match_operand 0 "register_operand")
22807 (match_dup 3))
22808 (clobber (reg:CC FLAGS_REG))])]
22809 ""
22810 {
22811 /* Can't use this for non-default address spaces. */
22812 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22813 FAIL;
22814
22815 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22816 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22817
22818 /* If .md ever supports :P for Pmode, this can be directly
22819 in the pattern above. */
22820 operands[3] = plus_constant (Pmode, operands[0],
22821 GET_MODE_SIZE (GET_MODE (operands[2])));
22822
22823 /* Can't use this if the user has appropriated eax or edi. */
22824 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22825 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22826 {
22827 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22828 operands[3]));
22829 DONE;
22830 }
22831 })
22832
22833 (define_expand "strset_singleop"
22834 [(parallel [(set (match_operand 1 "memory_operand")
22835 (match_operand 2 "register_operand"))
22836 (set (match_operand 0 "register_operand")
22837 (match_operand 3))
22838 (unspec [(const_int 0)] UNSPEC_STOS)])]
22839 ""
22840 {
22841 if (TARGET_CLD)
22842 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22843 })
22844
22845 (define_insn "*strsetdi_rex_1"
22846 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22847 (match_operand:DI 2 "register_operand" "a"))
22848 (set (match_operand:P 0 "register_operand" "=D")
22849 (plus:P (match_dup 1)
22850 (const_int 8)))
22851 (unspec [(const_int 0)] UNSPEC_STOS)]
22852 "TARGET_64BIT
22853 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22854 && ix86_check_no_addr_space (insn)"
22855 "%^stosq"
22856 [(set_attr "type" "str")
22857 (set_attr "memory" "store")
22858 (set_attr "mode" "DI")])
22859
22860 (define_insn "*strsetsi_1"
22861 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22862 (match_operand:SI 2 "register_operand" "a"))
22863 (set (match_operand:P 0 "register_operand" "=D")
22864 (plus:P (match_dup 1)
22865 (const_int 4)))
22866 (unspec [(const_int 0)] UNSPEC_STOS)]
22867 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22868 && ix86_check_no_addr_space (insn)"
22869 "%^stos{l|d}"
22870 [(set_attr "type" "str")
22871 (set_attr "memory" "store")
22872 (set_attr "mode" "SI")])
22873
22874 (define_insn "*strsethi_1"
22875 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22876 (match_operand:HI 2 "register_operand" "a"))
22877 (set (match_operand:P 0 "register_operand" "=D")
22878 (plus:P (match_dup 1)
22879 (const_int 2)))
22880 (unspec [(const_int 0)] UNSPEC_STOS)]
22881 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22882 && ix86_check_no_addr_space (insn)"
22883 "%^stosw"
22884 [(set_attr "type" "str")
22885 (set_attr "memory" "store")
22886 (set_attr "mode" "HI")])
22887
22888 (define_insn "*strsetqi_1"
22889 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22890 (match_operand:QI 2 "register_operand" "a"))
22891 (set (match_operand:P 0 "register_operand" "=D")
22892 (plus:P (match_dup 1)
22893 (const_int 1)))
22894 (unspec [(const_int 0)] UNSPEC_STOS)]
22895 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22896 && ix86_check_no_addr_space (insn)"
22897 "%^stosb"
22898 [(set_attr "type" "str")
22899 (set_attr "memory" "store")
22900 (set (attr "prefix_rex")
22901 (if_then_else
22902 (match_test "<P:MODE>mode == DImode")
22903 (const_string "0")
22904 (const_string "*")))
22905 (set_attr "mode" "QI")])
22906
22907 (define_expand "rep_stos"
22908 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22909 (set (match_operand 0 "register_operand")
22910 (match_operand 4))
22911 (set (match_operand 2 "memory_operand") (const_int 0))
22912 (use (match_operand 3 "register_operand"))
22913 (use (match_dup 1))])]
22914 ""
22915 {
22916 if (TARGET_CLD)
22917 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22918 })
22919
22920 (define_insn "*rep_stosdi_rex64"
22921 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22922 (set (match_operand:P 0 "register_operand" "=D")
22923 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22924 (const_int 3))
22925 (match_operand:P 3 "register_operand" "0")))
22926 (set (mem:BLK (match_dup 3))
22927 (const_int 0))
22928 (use (match_operand:DI 2 "register_operand" "a"))
22929 (use (match_dup 4))]
22930 "TARGET_64BIT
22931 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22932 && ix86_check_no_addr_space (insn)"
22933 "%^rep{%;} stosq"
22934 [(set_attr "type" "str")
22935 (set_attr "prefix_rep" "1")
22936 (set_attr "memory" "store")
22937 (set_attr "mode" "DI")])
22938
22939 (define_insn "*rep_stossi"
22940 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22941 (set (match_operand:P 0 "register_operand" "=D")
22942 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22943 (const_int 2))
22944 (match_operand:P 3 "register_operand" "0")))
22945 (set (mem:BLK (match_dup 3))
22946 (const_int 0))
22947 (use (match_operand:SI 2 "register_operand" "a"))
22948 (use (match_dup 4))]
22949 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22950 && ix86_check_no_addr_space (insn)"
22951 "%^rep{%;} stos{l|d}"
22952 [(set_attr "type" "str")
22953 (set_attr "prefix_rep" "1")
22954 (set_attr "memory" "store")
22955 (set_attr "mode" "SI")])
22956
22957 (define_insn "*rep_stosqi"
22958 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22959 (set (match_operand:P 0 "register_operand" "=D")
22960 (plus:P (match_operand:P 3 "register_operand" "0")
22961 (match_operand:P 4 "register_operand" "1")))
22962 (set (mem:BLK (match_dup 3))
22963 (const_int 0))
22964 (use (match_operand:QI 2 "register_operand" "a"))
22965 (use (match_dup 4))]
22966 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22967 && ix86_check_no_addr_space (insn)"
22968 "%^rep{%;} stosb"
22969 [(set_attr "type" "str")
22970 (set_attr "prefix_rep" "1")
22971 (set_attr "memory" "store")
22972 (set (attr "prefix_rex")
22973 (if_then_else
22974 (match_test "<P:MODE>mode == DImode")
22975 (const_string "0")
22976 (const_string "*")))
22977 (set_attr "mode" "QI")])
22978
22979 (define_expand "cmpmemsi"
22980 [(set (match_operand:SI 0 "register_operand" "")
22981 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22982 (match_operand:BLK 2 "memory_operand" "") ) )
22983 (use (match_operand 3 "general_operand"))
22984 (use (match_operand 4 "immediate_operand"))]
22985 ""
22986 {
22987 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22988 operands[2], operands[3],
22989 operands[4], false))
22990 DONE;
22991 else
22992 FAIL;
22993 })
22994
22995 (define_expand "cmpstrnsi"
22996 [(set (match_operand:SI 0 "register_operand")
22997 (compare:SI (match_operand:BLK 1 "general_operand")
22998 (match_operand:BLK 2 "general_operand")))
22999 (use (match_operand 3 "general_operand"))
23000 (use (match_operand 4 "immediate_operand"))]
23001 ""
23002 {
23003 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
23004 operands[2], operands[3],
23005 operands[4], true))
23006 DONE;
23007 else
23008 FAIL;
23009 })
23010
23011 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
23012
23013 (define_expand "cmpintqi"
23014 [(set (match_dup 1)
23015 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23016 (set (match_dup 2)
23017 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23018 (parallel [(set (match_operand:QI 0 "register_operand")
23019 (minus:QI (match_dup 1)
23020 (match_dup 2)))
23021 (clobber (reg:CC FLAGS_REG))])]
23022 ""
23023 {
23024 operands[1] = gen_reg_rtx (QImode);
23025 operands[2] = gen_reg_rtx (QImode);
23026 })
23027
23028 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
23029 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
23030
23031 (define_expand "cmpstrnqi_nz_1"
23032 [(parallel [(set (reg:CC FLAGS_REG)
23033 (compare:CC (match_operand 4 "memory_operand")
23034 (match_operand 5 "memory_operand")))
23035 (use (match_operand 2 "register_operand"))
23036 (use (match_operand:SI 3 "immediate_operand"))
23037 (clobber (match_operand 0 "register_operand"))
23038 (clobber (match_operand 1 "register_operand"))
23039 (clobber (match_dup 2))])]
23040 ""
23041 {
23042 if (TARGET_CLD)
23043 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23044 })
23045
23046 (define_insn "*cmpstrnqi_nz_1"
23047 [(set (reg:CC FLAGS_REG)
23048 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23049 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
23050 (use (match_operand:P 6 "register_operand" "2"))
23051 (use (match_operand:SI 3 "immediate_operand" "i"))
23052 (clobber (match_operand:P 0 "register_operand" "=S"))
23053 (clobber (match_operand:P 1 "register_operand" "=D"))
23054 (clobber (match_operand:P 2 "register_operand" "=c"))]
23055 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23056 && ix86_check_no_addr_space (insn)"
23057 "%^repz{%;} cmpsb"
23058 [(set_attr "type" "str")
23059 (set_attr "mode" "QI")
23060 (set (attr "prefix_rex")
23061 (if_then_else
23062 (match_test "<P:MODE>mode == DImode")
23063 (const_string "0")
23064 (const_string "*")))
23065 (set_attr "prefix_rep" "1")])
23066
23067 ;; The same, but the count is not known to not be zero.
23068
23069 (define_expand "cmpstrnqi_1"
23070 [(parallel [(set (reg:CC FLAGS_REG)
23071 (if_then_else:CC (ne (match_operand 2 "register_operand")
23072 (const_int 0))
23073 (compare:CC (match_operand 4 "memory_operand")
23074 (match_operand 5 "memory_operand"))
23075 (const_int 0)))
23076 (use (match_operand:SI 3 "immediate_operand"))
23077 (use (reg:CC FLAGS_REG))
23078 (clobber (match_operand 0 "register_operand"))
23079 (clobber (match_operand 1 "register_operand"))
23080 (clobber (match_dup 2))])]
23081 ""
23082 {
23083 if (TARGET_CLD)
23084 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23085 })
23086
23087 (define_insn "*cmpstrnqi_1"
23088 [(set (reg:CC FLAGS_REG)
23089 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
23090 (const_int 0))
23091 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23092 (mem:BLK (match_operand:P 5 "register_operand" "1")))
23093 (const_int 0)))
23094 (use (match_operand:SI 3 "immediate_operand" "i"))
23095 (use (reg:CC FLAGS_REG))
23096 (clobber (match_operand:P 0 "register_operand" "=S"))
23097 (clobber (match_operand:P 1 "register_operand" "=D"))
23098 (clobber (match_operand:P 2 "register_operand" "=c"))]
23099 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23100 && ix86_check_no_addr_space (insn)"
23101 "%^repz{%;} cmpsb"
23102 [(set_attr "type" "str")
23103 (set_attr "mode" "QI")
23104 (set (attr "prefix_rex")
23105 (if_then_else
23106 (match_test "<P:MODE>mode == DImode")
23107 (const_string "0")
23108 (const_string "*")))
23109 (set_attr "prefix_rep" "1")])
23110
23111 (define_expand "strlen<mode>"
23112 [(set (match_operand:P 0 "register_operand")
23113 (unspec:P [(match_operand:BLK 1 "general_operand")
23114 (match_operand:QI 2 "immediate_operand")
23115 (match_operand 3 "immediate_operand")]
23116 UNSPEC_SCAS))]
23117 ""
23118 {
23119 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
23120 DONE;
23121 else
23122 FAIL;
23123 })
23124
23125 (define_expand "strlenqi_1"
23126 [(parallel [(set (match_operand 0 "register_operand")
23127 (match_operand 2))
23128 (clobber (match_operand 1 "register_operand"))
23129 (clobber (reg:CC FLAGS_REG))])]
23130 ""
23131 {
23132 if (TARGET_CLD)
23133 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23134 })
23135
23136 (define_insn "*strlenqi_1"
23137 [(set (match_operand:P 0 "register_operand" "=&c")
23138 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
23139 (match_operand:QI 2 "register_operand" "a")
23140 (match_operand:P 3 "immediate_operand" "i")
23141 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
23142 (clobber (match_operand:P 1 "register_operand" "=D"))
23143 (clobber (reg:CC FLAGS_REG))]
23144 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23145 && ix86_check_no_addr_space (insn)"
23146 "%^repnz{%;} scasb"
23147 [(set_attr "type" "str")
23148 (set_attr "mode" "QI")
23149 (set (attr "prefix_rex")
23150 (if_then_else
23151 (match_test "<P:MODE>mode == DImode")
23152 (const_string "0")
23153 (const_string "*")))
23154 (set_attr "prefix_rep" "1")])
23155
23156 ;; Peephole optimizations to clean up after cmpstrn*. This should be
23157 ;; handled in combine, but it is not currently up to the task.
23158 ;; When used for their truth value, the cmpstrn* expanders generate
23159 ;; code like this:
23160 ;;
23161 ;; repz cmpsb
23162 ;; seta %al
23163 ;; setb %dl
23164 ;; cmpb %al, %dl
23165 ;; jcc label
23166 ;;
23167 ;; The intermediate three instructions are unnecessary.
23168
23169 ;; This one handles cmpstrn*_nz_1...
23170 (define_peephole2
23171 [(parallel[
23172 (set (reg:CC FLAGS_REG)
23173 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23174 (mem:BLK (match_operand 5 "register_operand"))))
23175 (use (match_operand 6 "register_operand"))
23176 (use (match_operand:SI 3 "immediate_operand"))
23177 (clobber (match_operand 0 "register_operand"))
23178 (clobber (match_operand 1 "register_operand"))
23179 (clobber (match_operand 2 "register_operand"))])
23180 (set (match_operand:QI 7 "register_operand")
23181 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23182 (set (match_operand:QI 8 "register_operand")
23183 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23184 (set (reg FLAGS_REG)
23185 (compare (match_dup 7) (match_dup 8)))
23186 ]
23187 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23188 [(parallel[
23189 (set (reg:CC FLAGS_REG)
23190 (compare:CC (mem:BLK (match_dup 4))
23191 (mem:BLK (match_dup 5))))
23192 (use (match_dup 6))
23193 (use (match_dup 3))
23194 (clobber (match_dup 0))
23195 (clobber (match_dup 1))
23196 (clobber (match_dup 2))])])
23197
23198 ;; ...and this one handles cmpstrn*_1.
23199 (define_peephole2
23200 [(parallel[
23201 (set (reg:CC FLAGS_REG)
23202 (if_then_else:CC (ne (match_operand 6 "register_operand")
23203 (const_int 0))
23204 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23205 (mem:BLK (match_operand 5 "register_operand")))
23206 (const_int 0)))
23207 (use (match_operand:SI 3 "immediate_operand"))
23208 (use (reg:CC FLAGS_REG))
23209 (clobber (match_operand 0 "register_operand"))
23210 (clobber (match_operand 1 "register_operand"))
23211 (clobber (match_operand 2 "register_operand"))])
23212 (set (match_operand:QI 7 "register_operand")
23213 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23214 (set (match_operand:QI 8 "register_operand")
23215 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23216 (set (reg FLAGS_REG)
23217 (compare (match_dup 7) (match_dup 8)))
23218 ]
23219 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23220 [(parallel[
23221 (set (reg:CC FLAGS_REG)
23222 (if_then_else:CC (ne (match_dup 6)
23223 (const_int 0))
23224 (compare:CC (mem:BLK (match_dup 4))
23225 (mem:BLK (match_dup 5)))
23226 (const_int 0)))
23227 (use (match_dup 3))
23228 (use (reg:CC FLAGS_REG))
23229 (clobber (match_dup 0))
23230 (clobber (match_dup 1))
23231 (clobber (match_dup 2))])])
23232 \f
23233 ;; Conditional move instructions.
23234
23235 (define_expand "mov<mode>cc"
23236 [(set (match_operand:SWIM 0 "register_operand")
23237 (if_then_else:SWIM (match_operand 1 "comparison_operator")
23238 (match_operand:SWIM 2 "<general_operand>")
23239 (match_operand:SWIM 3 "<general_operand>")))]
23240 ""
23241 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23242
23243 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23244 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23245 ;; So just document what we're doing explicitly.
23246
23247 (define_expand "x86_mov<mode>cc_0_m1"
23248 [(parallel
23249 [(set (match_operand:SWI48 0 "register_operand")
23250 (if_then_else:SWI48
23251 (match_operator:SWI48 2 "ix86_carry_flag_operator"
23252 [(match_operand 1 "flags_reg_operand")
23253 (const_int 0)])
23254 (const_int -1)
23255 (const_int 0)))
23256 (clobber (reg:CC FLAGS_REG))])])
23257
23258 (define_insn "*x86_mov<mode>cc_0_m1"
23259 [(set (match_operand:SWI48 0 "register_operand" "=r")
23260 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23261 [(reg FLAGS_REG) (const_int 0)])
23262 (const_int -1)
23263 (const_int 0)))
23264 (clobber (reg:CC FLAGS_REG))]
23265 ""
23266 "sbb{<imodesuffix>}\t%0, %0"
23267 [(set_attr "type" "alu1")
23268 (set_attr "use_carry" "1")
23269 (set_attr "pent_pair" "pu")
23270 (set_attr "mode" "<MODE>")
23271 (set_attr "length_immediate" "0")])
23272
23273 (define_insn "*x86_mov<mode>cc_0_m1_se"
23274 [(set (match_operand:SWI48 0 "register_operand" "=r")
23275 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23276 [(reg FLAGS_REG) (const_int 0)])
23277 (const_int 1)
23278 (const_int 0)))
23279 (clobber (reg:CC FLAGS_REG))]
23280 ""
23281 "sbb{<imodesuffix>}\t%0, %0"
23282 [(set_attr "type" "alu1")
23283 (set_attr "use_carry" "1")
23284 (set_attr "pent_pair" "pu")
23285 (set_attr "mode" "<MODE>")
23286 (set_attr "length_immediate" "0")])
23287
23288 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23289 [(set (match_operand:SWI 0 "register_operand" "=<r>")
23290 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23291 [(reg FLAGS_REG) (const_int 0)])))
23292 (clobber (reg:CC FLAGS_REG))]
23293 ""
23294 "sbb{<imodesuffix>}\t%0, %0"
23295 [(set_attr "type" "alu1")
23296 (set_attr "use_carry" "1")
23297 (set_attr "pent_pair" "pu")
23298 (set_attr "mode" "<MODE>")
23299 (set_attr "length_immediate" "0")])
23300
23301 (define_expand "x86_mov<mode>cc_0_m1_neg"
23302 [(parallel
23303 [(set (match_operand:SWI48 0 "register_operand")
23304 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23305 (clobber (reg:CC FLAGS_REG))])])
23306
23307 (define_split
23308 [(set (match_operand:SWI48 0 "register_operand")
23309 (neg:SWI48
23310 (leu:SWI48
23311 (match_operand 1 "int_nonimmediate_operand")
23312 (match_operand 2 "const_int_operand"))))]
23313 "x86_64_immediate_operand (operands[2], VOIDmode)
23314 && INTVAL (operands[2]) != -1
23315 && INTVAL (operands[2]) != 2147483647"
23316 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23317 (set (match_dup 0)
23318 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23319 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23320
23321 (define_split
23322 [(set (match_operand:SWI 0 "register_operand")
23323 (neg:SWI
23324 (eq:SWI
23325 (match_operand 1 "int_nonimmediate_operand")
23326 (const_int 0))))]
23327 ""
23328 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23329 (set (match_dup 0)
23330 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23331
23332 (define_split
23333 [(set (match_operand:SWI 0 "register_operand")
23334 (neg:SWI
23335 (ne:SWI
23336 (match_operand 1 "int_nonimmediate_operand")
23337 (const_int 0))))]
23338 ""
23339 [(set (reg:CCC FLAGS_REG)
23340 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23341 (set (match_dup 0)
23342 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23343
23344 (define_insn "*mov<mode>cc_noc"
23345 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23346 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23347 [(reg FLAGS_REG) (const_int 0)])
23348 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23349 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23350 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23351 "@
23352 cmov%O2%C1\t{%2, %0|%0, %2}
23353 cmov%O2%c1\t{%3, %0|%0, %3}"
23354 [(set_attr "type" "icmov")
23355 (set_attr "mode" "<MODE>")])
23356
23357 (define_insn "*movsicc_noc_zext"
23358 [(set (match_operand:DI 0 "register_operand" "=r,r")
23359 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23360 [(reg FLAGS_REG) (const_int 0)])
23361 (zero_extend:DI
23362 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23363 (zero_extend:DI
23364 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23365 "TARGET_64BIT
23366 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23367 "@
23368 cmov%O2%C1\t{%2, %k0|%k0, %2}
23369 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23370 [(set_attr "type" "icmov")
23371 (set_attr "mode" "SI")])
23372
23373 (define_insn "*movsicc_noc_zext_1"
23374 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23375 (zero_extend:DI
23376 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23377 [(reg FLAGS_REG) (const_int 0)])
23378 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23379 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23380 "TARGET_64BIT
23381 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23382 "@
23383 cmov%O2%C1\t{%2, %k0|%k0, %2}
23384 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23385 [(set_attr "type" "icmov")
23386 (set_attr "mode" "SI")])
23387
23388
23389 ;; Don't do conditional moves with memory inputs. This splitter helps
23390 ;; register starved x86_32 by forcing inputs into registers before reload.
23391 (define_split
23392 [(set (match_operand:SWI248 0 "register_operand")
23393 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23394 [(reg FLAGS_REG) (const_int 0)])
23395 (match_operand:SWI248 2 "nonimmediate_operand")
23396 (match_operand:SWI248 3 "nonimmediate_operand")))]
23397 "!TARGET_64BIT && TARGET_CMOVE
23398 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23399 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23400 && can_create_pseudo_p ()
23401 && optimize_insn_for_speed_p ()"
23402 [(set (match_dup 0)
23403 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23404 {
23405 operands[2] = force_reg (<MODE>mode, operands[2]);
23406 operands[3] = force_reg (<MODE>mode, operands[3]);
23407 })
23408
23409 (define_insn "*movqicc_noc"
23410 [(set (match_operand:QI 0 "register_operand" "=r,r")
23411 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23412 [(reg FLAGS_REG) (const_int 0)])
23413 (match_operand:QI 2 "register_operand" "r,0")
23414 (match_operand:QI 3 "register_operand" "0,r")))]
23415 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23416 "#"
23417 [(set_attr "type" "icmov")
23418 (set_attr "mode" "QI")])
23419
23420 (define_split
23421 [(set (match_operand:SWI12 0 "register_operand")
23422 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23423 [(reg FLAGS_REG) (const_int 0)])
23424 (match_operand:SWI12 2 "register_operand")
23425 (match_operand:SWI12 3 "register_operand")))]
23426 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23427 && reload_completed"
23428 [(set (match_dup 0)
23429 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23430 {
23431 operands[0] = gen_lowpart (SImode, operands[0]);
23432 operands[2] = gen_lowpart (SImode, operands[2]);
23433 operands[3] = gen_lowpart (SImode, operands[3]);
23434 })
23435
23436 ;; Don't do conditional moves with memory inputs
23437 (define_peephole2
23438 [(match_scratch:SWI248 4 "r")
23439 (set (match_operand:SWI248 0 "register_operand")
23440 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23441 [(reg FLAGS_REG) (const_int 0)])
23442 (match_operand:SWI248 2 "nonimmediate_operand")
23443 (match_operand:SWI248 3 "nonimmediate_operand")))]
23444 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23445 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23446 && optimize_insn_for_speed_p ()"
23447 [(set (match_dup 4) (match_dup 5))
23448 (set (match_dup 0)
23449 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23450 {
23451 if (MEM_P (operands[2]))
23452 {
23453 operands[5] = operands[2];
23454 operands[2] = operands[4];
23455 }
23456 else if (MEM_P (operands[3]))
23457 {
23458 operands[5] = operands[3];
23459 operands[3] = operands[4];
23460 }
23461 else
23462 gcc_unreachable ();
23463 })
23464
23465 (define_peephole2
23466 [(match_scratch:SI 4 "r")
23467 (set (match_operand:DI 0 "register_operand")
23468 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23469 [(reg FLAGS_REG) (const_int 0)])
23470 (zero_extend:DI
23471 (match_operand:SI 2 "nonimmediate_operand"))
23472 (zero_extend:DI
23473 (match_operand:SI 3 "nonimmediate_operand"))))]
23474 "TARGET_64BIT
23475 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23476 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23477 && optimize_insn_for_speed_p ()"
23478 [(set (match_dup 4) (match_dup 5))
23479 (set (match_dup 0)
23480 (if_then_else:DI (match_dup 1)
23481 (zero_extend:DI (match_dup 2))
23482 (zero_extend:DI (match_dup 3))))]
23483 {
23484 if (MEM_P (operands[2]))
23485 {
23486 operands[5] = operands[2];
23487 operands[2] = operands[4];
23488 }
23489 else if (MEM_P (operands[3]))
23490 {
23491 operands[5] = operands[3];
23492 operands[3] = operands[4];
23493 }
23494 else
23495 gcc_unreachable ();
23496 })
23497
23498 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23499 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23500 (define_peephole2
23501 [(set (match_operand:SWI248 0 "general_reg_operand")
23502 (match_operand:SWI248 1 "general_reg_operand"))
23503 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23504 (set (match_dup 0) (match_operand:SWI248 6))])
23505 (set (match_operand:SWI248 2 "general_reg_operand")
23506 (match_operand:SWI248 3 "general_gr_operand"))
23507 (set (match_dup 0)
23508 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23509 [(reg FLAGS_REG) (const_int 0)])
23510 (match_dup 0)
23511 (match_dup 2)))]
23512 "TARGET_CMOVE
23513 && REGNO (operands[2]) != REGNO (operands[0])
23514 && REGNO (operands[2]) != REGNO (operands[1])
23515 && peep2_reg_dead_p (1, operands[1])
23516 && peep2_reg_dead_p (4, operands[2])
23517 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23518 [(parallel [(set (match_dup 7) (match_dup 8))
23519 (set (match_dup 1) (match_dup 9))])
23520 (set (match_dup 0) (match_dup 3))
23521 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23522 (match_dup 1)
23523 (match_dup 0)))]
23524 {
23525 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23526 operands[8]
23527 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23528 operands[9]
23529 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23530 })
23531
23532 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23533 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23534 (define_peephole2
23535 [(set (match_operand:SWI248 2 "general_reg_operand")
23536 (match_operand:SWI248 3 "general_gr_operand"))
23537 (set (match_operand:SWI248 0 "general_reg_operand")
23538 (match_operand:SWI248 1 "general_reg_operand"))
23539 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23540 (set (match_dup 0) (match_operand:SWI248 6))])
23541 (set (match_dup 0)
23542 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23543 [(reg FLAGS_REG) (const_int 0)])
23544 (match_dup 0)
23545 (match_dup 2)))]
23546 "TARGET_CMOVE
23547 && REGNO (operands[2]) != REGNO (operands[0])
23548 && REGNO (operands[2]) != REGNO (operands[1])
23549 && peep2_reg_dead_p (2, operands[1])
23550 && peep2_reg_dead_p (4, operands[2])
23551 && !reg_overlap_mentioned_p (operands[0], operands[3])
23552 && !reg_mentioned_p (operands[2], operands[6])"
23553 [(parallel [(set (match_dup 7) (match_dup 8))
23554 (set (match_dup 1) (match_dup 9))])
23555 (set (match_dup 0) (match_dup 3))
23556 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23557 (match_dup 1)
23558 (match_dup 0)))]
23559 {
23560 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23561 operands[8]
23562 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23563 operands[9]
23564 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23565 })
23566
23567 (define_insn "movhf_mask"
23568 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23569 (unspec:HF
23570 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23571 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23572 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23573 UNSPEC_MOVCC_MASK))]
23574 "TARGET_AVX512FP16"
23575 "@
23576 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23577 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23578 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23579 [(set_attr "type" "ssemov")
23580 (set_attr "prefix" "evex")
23581 (set_attr "mode" "HF")])
23582
23583 (define_expand "movhfcc"
23584 [(set (match_operand:HF 0 "register_operand")
23585 (if_then_else:HF
23586 (match_operand 1 "comparison_operator")
23587 (match_operand:HF 2 "register_operand")
23588 (match_operand:HF 3 "register_operand")))]
23589 "TARGET_AVX512FP16"
23590 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23591
23592 (define_expand "mov<mode>cc"
23593 [(set (match_operand:X87MODEF 0 "register_operand")
23594 (if_then_else:X87MODEF
23595 (match_operand 1 "comparison_operator")
23596 (match_operand:X87MODEF 2 "register_operand")
23597 (match_operand:X87MODEF 3 "register_operand")))]
23598 "(TARGET_80387 && TARGET_CMOVE)
23599 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23600 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23601
23602 (define_insn "*movxfcc_1"
23603 [(set (match_operand:XF 0 "register_operand" "=f,f")
23604 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23605 [(reg FLAGS_REG) (const_int 0)])
23606 (match_operand:XF 2 "register_operand" "f,0")
23607 (match_operand:XF 3 "register_operand" "0,f")))]
23608 "TARGET_80387 && TARGET_CMOVE"
23609 "@
23610 fcmov%F1\t{%2, %0|%0, %2}
23611 fcmov%f1\t{%3, %0|%0, %3}"
23612 [(set_attr "type" "fcmov")
23613 (set_attr "mode" "XF")])
23614
23615 (define_insn "*movdfcc_1"
23616 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23617 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23618 [(reg FLAGS_REG) (const_int 0)])
23619 (match_operand:DF 2 "nonimmediate_operand"
23620 "f ,0,rm,0 ,rm,0")
23621 (match_operand:DF 3 "nonimmediate_operand"
23622 "0 ,f,0 ,rm,0, rm")))]
23623 "TARGET_80387 && TARGET_CMOVE
23624 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23625 "@
23626 fcmov%F1\t{%2, %0|%0, %2}
23627 fcmov%f1\t{%3, %0|%0, %3}
23628 #
23629 #
23630 cmov%O2%C1\t{%2, %0|%0, %2}
23631 cmov%O2%c1\t{%3, %0|%0, %3}"
23632 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23633 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23634 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23635
23636 (define_split
23637 [(set (match_operand:DF 0 "general_reg_operand")
23638 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23639 [(reg FLAGS_REG) (const_int 0)])
23640 (match_operand:DF 2 "nonimmediate_operand")
23641 (match_operand:DF 3 "nonimmediate_operand")))]
23642 "!TARGET_64BIT && reload_completed"
23643 [(set (match_dup 2)
23644 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23645 (set (match_dup 3)
23646 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23647 {
23648 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23649 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23650 })
23651
23652 (define_insn "*movsfcc_1_387"
23653 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23654 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23655 [(reg FLAGS_REG) (const_int 0)])
23656 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23657 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23658 "TARGET_80387 && TARGET_CMOVE
23659 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23660 "@
23661 fcmov%F1\t{%2, %0|%0, %2}
23662 fcmov%f1\t{%3, %0|%0, %3}
23663 cmov%O2%C1\t{%2, %0|%0, %2}
23664 cmov%O2%c1\t{%3, %0|%0, %3}"
23665 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23666 (set_attr "mode" "SF,SF,SI,SI")])
23667
23668 ;; Don't do conditional moves with memory inputs. This splitter helps
23669 ;; register starved x86_32 by forcing inputs into registers before reload.
23670 (define_split
23671 [(set (match_operand:MODEF 0 "register_operand")
23672 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23673 [(reg FLAGS_REG) (const_int 0)])
23674 (match_operand:MODEF 2 "nonimmediate_operand")
23675 (match_operand:MODEF 3 "nonimmediate_operand")))]
23676 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23677 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23678 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23679 && can_create_pseudo_p ()
23680 && optimize_insn_for_speed_p ()"
23681 [(set (match_dup 0)
23682 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23683 {
23684 operands[2] = force_reg (<MODE>mode, operands[2]);
23685 operands[3] = force_reg (<MODE>mode, operands[3]);
23686 })
23687
23688 ;; Don't do conditional moves with memory inputs
23689 (define_peephole2
23690 [(match_scratch:MODEF 4 "r")
23691 (set (match_operand:MODEF 0 "general_reg_operand")
23692 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23693 [(reg FLAGS_REG) (const_int 0)])
23694 (match_operand:MODEF 2 "nonimmediate_operand")
23695 (match_operand:MODEF 3 "nonimmediate_operand")))]
23696 "(<MODE>mode != DFmode || TARGET_64BIT)
23697 && TARGET_80387 && TARGET_CMOVE
23698 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23699 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23700 && optimize_insn_for_speed_p ()"
23701 [(set (match_dup 4) (match_dup 5))
23702 (set (match_dup 0)
23703 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23704 {
23705 if (MEM_P (operands[2]))
23706 {
23707 operands[5] = operands[2];
23708 operands[2] = operands[4];
23709 }
23710 else if (MEM_P (operands[3]))
23711 {
23712 operands[5] = operands[3];
23713 operands[3] = operands[4];
23714 }
23715 else
23716 gcc_unreachable ();
23717 })
23718
23719 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23720 ;; the scalar versions to have only XMM registers as operands.
23721
23722 ;; XOP conditional move
23723 (define_insn "*xop_pcmov_<mode>"
23724 [(set (match_operand:MODEF 0 "register_operand" "=x")
23725 (if_then_else:MODEF
23726 (match_operand:MODEF 1 "register_operand" "x")
23727 (match_operand:MODEF 2 "register_operand" "x")
23728 (match_operand:MODEF 3 "register_operand" "x")))]
23729 "TARGET_XOP"
23730 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23731 [(set_attr "type" "sse4arg")
23732 (set_attr "mode" "TI")])
23733
23734 ;; These versions of the min/max patterns are intentionally ignorant of
23735 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23736 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23737 ;; are undefined in this condition, we're certain this is correct.
23738
23739 (define_insn "<code><mode>3"
23740 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23741 (smaxmin:MODEF
23742 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23743 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23744 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23745 "@
23746 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23747 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23748 [(set_attr "isa" "noavx,avx")
23749 (set_attr "prefix" "orig,vex")
23750 (set_attr "type" "sseadd")
23751 (set_attr "mode" "<MODE>")])
23752
23753 (define_insn "<code>hf3"
23754 [(set (match_operand:HF 0 "register_operand" "=v")
23755 (smaxmin:HF
23756 (match_operand:HF 1 "nonimmediate_operand" "%v")
23757 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23758 "TARGET_AVX512FP16"
23759 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23760 [(set_attr "prefix" "evex")
23761 (set_attr "type" "sseadd")
23762 (set_attr "mode" "HF")])
23763
23764 ;; These versions of the min/max patterns implement exactly the operations
23765 ;; min = (op1 < op2 ? op1 : op2)
23766 ;; max = (!(op1 < op2) ? op1 : op2)
23767 ;; Their operands are not commutative, and thus they may be used in the
23768 ;; presence of -0.0 and NaN.
23769
23770 (define_insn "*ieee_s<ieee_maxmin>hf3"
23771 [(set (match_operand:HF 0 "register_operand" "=v")
23772 (unspec:HF
23773 [(match_operand:HF 1 "register_operand" "v")
23774 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23775 IEEE_MAXMIN))]
23776 "TARGET_AVX512FP16"
23777 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23778 [(set_attr "prefix" "evex")
23779 (set_attr "type" "sseadd")
23780 (set_attr "mode" "HF")])
23781
23782 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23783 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23784 (unspec:MODEF
23785 [(match_operand:MODEF 1 "register_operand" "0,v")
23786 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23787 IEEE_MAXMIN))]
23788 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23789 "@
23790 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23791 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23792 [(set_attr "isa" "noavx,avx")
23793 (set_attr "prefix" "orig,maybe_evex")
23794 (set_attr "type" "sseadd")
23795 (set_attr "mode" "<MODE>")])
23796
23797 ;; Operands order in min/max instruction matters for signed zero and NANs.
23798 (define_insn_and_split "*ieee_max<mode>3_1"
23799 [(set (match_operand:MODEF 0 "register_operand")
23800 (unspec:MODEF
23801 [(match_operand:MODEF 1 "register_operand")
23802 (match_operand:MODEF 2 "register_operand")
23803 (lt:MODEF
23804 (match_operand:MODEF 3 "register_operand")
23805 (match_operand:MODEF 4 "register_operand"))]
23806 UNSPEC_BLENDV))]
23807 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23808 && (rtx_equal_p (operands[1], operands[3])
23809 && rtx_equal_p (operands[2], operands[4]))
23810 && ix86_pre_reload_split ()"
23811 "#"
23812 "&& 1"
23813 [(set (match_dup 0)
23814 (unspec:MODEF
23815 [(match_dup 2)
23816 (match_dup 1)]
23817 UNSPEC_IEEE_MAX))])
23818
23819 (define_insn_and_split "*ieee_min<mode>3_1"
23820 [(set (match_operand:MODEF 0 "register_operand")
23821 (unspec:MODEF
23822 [(match_operand:MODEF 1 "register_operand")
23823 (match_operand:MODEF 2 "register_operand")
23824 (lt:MODEF
23825 (match_operand:MODEF 3 "register_operand")
23826 (match_operand:MODEF 4 "register_operand"))]
23827 UNSPEC_BLENDV))]
23828 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23829 && (rtx_equal_p (operands[1], operands[4])
23830 && rtx_equal_p (operands[2], operands[3]))
23831 && ix86_pre_reload_split ()"
23832 "#"
23833 "&& 1"
23834 [(set (match_dup 0)
23835 (unspec:MODEF
23836 [(match_dup 2)
23837 (match_dup 1)]
23838 UNSPEC_IEEE_MIN))])
23839
23840 ;; Make two stack loads independent:
23841 ;; fld aa fld aa
23842 ;; fld %st(0) -> fld bb
23843 ;; fmul bb fmul %st(1), %st
23844 ;;
23845 ;; Actually we only match the last two instructions for simplicity.
23846
23847 (define_peephole2
23848 [(set (match_operand 0 "fp_register_operand")
23849 (match_operand 1 "fp_register_operand"))
23850 (set (match_dup 0)
23851 (match_operator 2 "binary_fp_operator"
23852 [(match_dup 0)
23853 (match_operand 3 "memory_operand")]))]
23854 "REGNO (operands[0]) != REGNO (operands[1])"
23855 [(set (match_dup 0) (match_dup 3))
23856 (set (match_dup 0)
23857 (match_op_dup 2
23858 [(match_dup 5) (match_dup 4)]))]
23859 {
23860 operands[4] = operands[0];
23861 operands[5] = operands[1];
23862
23863 /* The % modifier is not operational anymore in peephole2's, so we have to
23864 swap the operands manually in the case of addition and multiplication. */
23865 if (COMMUTATIVE_ARITH_P (operands[2]))
23866 std::swap (operands[4], operands[5]);
23867 })
23868
23869 (define_peephole2
23870 [(set (match_operand 0 "fp_register_operand")
23871 (match_operand 1 "fp_register_operand"))
23872 (set (match_dup 0)
23873 (match_operator 2 "binary_fp_operator"
23874 [(match_operand 3 "memory_operand")
23875 (match_dup 0)]))]
23876 "REGNO (operands[0]) != REGNO (operands[1])"
23877 [(set (match_dup 0) (match_dup 3))
23878 (set (match_dup 0)
23879 (match_op_dup 2
23880 [(match_dup 4) (match_dup 5)]))]
23881 {
23882 operands[4] = operands[0];
23883 operands[5] = operands[1];
23884
23885 /* The % modifier is not operational anymore in peephole2's, so we have to
23886 swap the operands manually in the case of addition and multiplication. */
23887 if (COMMUTATIVE_ARITH_P (operands[2]))
23888 std::swap (operands[4], operands[5]);
23889 })
23890
23891 ;; Conditional addition patterns
23892 (define_expand "add<mode>cc"
23893 [(match_operand:SWI 0 "register_operand")
23894 (match_operand 1 "ordered_comparison_operator")
23895 (match_operand:SWI 2 "register_operand")
23896 (match_operand:SWI 3 "const_int_operand")]
23897 ""
23898 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23899
23900 ;; min/max patterns
23901
23902 (define_code_attr maxmin_rel
23903 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23904
23905 (define_expand "<code><mode>3"
23906 [(parallel
23907 [(set (match_operand:SDWIM 0 "register_operand")
23908 (maxmin:SDWIM
23909 (match_operand:SDWIM 1 "register_operand")
23910 (match_operand:SDWIM 2 "general_operand")))
23911 (clobber (reg:CC FLAGS_REG))])]
23912 "TARGET_CMOVE
23913 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23914
23915 (define_insn_and_split "*<code><dwi>3_doubleword"
23916 [(set (match_operand:<DWI> 0 "register_operand")
23917 (maxmin:<DWI>
23918 (match_operand:<DWI> 1 "register_operand")
23919 (match_operand:<DWI> 2 "general_operand")))
23920 (clobber (reg:CC FLAGS_REG))]
23921 "TARGET_CMOVE
23922 && ix86_pre_reload_split ()"
23923 "#"
23924 "&& 1"
23925 [(set (match_dup 0)
23926 (if_then_else:DWIH (match_dup 6)
23927 (match_dup 1)
23928 (match_dup 2)))
23929 (set (match_dup 3)
23930 (if_then_else:DWIH (match_dup 6)
23931 (match_dup 4)
23932 (match_dup 5)))]
23933 {
23934 operands[2] = force_reg (<DWI>mode, operands[2]);
23935
23936 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23937
23938 rtx cmplo[2] = { operands[1], operands[2] };
23939 rtx cmphi[2] = { operands[4], operands[5] };
23940
23941 enum rtx_code code = <maxmin_rel>;
23942
23943 switch (code)
23944 {
23945 case LE: case LEU:
23946 std::swap (cmplo[0], cmplo[1]);
23947 std::swap (cmphi[0], cmphi[1]);
23948 code = swap_condition (code);
23949 /* FALLTHRU */
23950
23951 case GE: case GEU:
23952 {
23953 bool uns = (code == GEU);
23954 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23955 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23956
23957 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23958
23959 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23960 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23961
23962 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23963 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23964
23965 break;
23966 }
23967
23968 default:
23969 gcc_unreachable ();
23970 }
23971 })
23972
23973 (define_insn_and_split "*<code><mode>3_1"
23974 [(set (match_operand:SWI 0 "register_operand")
23975 (maxmin:SWI
23976 (match_operand:SWI 1 "register_operand")
23977 (match_operand:SWI 2 "general_operand")))
23978 (clobber (reg:CC FLAGS_REG))]
23979 "TARGET_CMOVE
23980 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23981 && ix86_pre_reload_split ()"
23982 "#"
23983 "&& 1"
23984 [(set (match_dup 0)
23985 (if_then_else:SWI (match_dup 3)
23986 (match_dup 1)
23987 (match_dup 2)))]
23988 {
23989 machine_mode mode = <MODE>mode;
23990 rtx cmp_op = operands[2];
23991
23992 operands[2] = force_reg (mode, cmp_op);
23993
23994 enum rtx_code code = <maxmin_rel>;
23995
23996 if (cmp_op == const1_rtx)
23997 {
23998 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23999 Convert umax (x, 1) into (x != 0 ? x : 1).
24000 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
24001 cmp_op = const0_rtx;
24002 if (code == GE)
24003 code = GT;
24004 else if (code == GEU)
24005 code = NE;
24006 }
24007 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
24008 else if (cmp_op == constm1_rtx && code == LE)
24009 {
24010 cmp_op = const0_rtx;
24011 code = LT;
24012 }
24013 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
24014 else if (cmp_op == constm1_rtx && code == GE)
24015 cmp_op = const0_rtx;
24016 else if (cmp_op != const0_rtx)
24017 cmp_op = operands[2];
24018
24019 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
24020 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
24021
24022 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
24023 emit_insn (gen_rtx_SET (flags, tmp));
24024
24025 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
24026 })
24027
24028 ;; Avoid clearing a register between a flags setting comparison and its use,
24029 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
24030 (define_peephole2
24031 [(set (reg FLAGS_REG) (match_operand 0))
24032 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
24033 "peep2_regno_dead_p (0, FLAGS_REG)
24034 && !reg_overlap_mentioned_p (operands[1], operands[0])"
24035 [(set (match_dup 2) (match_dup 0))]
24036 {
24037 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
24038 ix86_expand_clear (operands[1]);
24039 })
24040
24041 ;; When optimizing for size, zeroing memory should use a register.
24042 (define_peephole2
24043 [(match_scratch:SWI48 0 "r")
24044 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24045 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24046 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24047 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24048 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24049 [(const_int 0)]
24050 {
24051 ix86_expand_clear (operands[0]);
24052 emit_move_insn (operands[1], operands[0]);
24053 emit_move_insn (operands[2], operands[0]);
24054 emit_move_insn (operands[3], operands[0]);
24055 ix86_last_zero_store_uid
24056 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24057 DONE;
24058 })
24059
24060 (define_peephole2
24061 [(match_scratch:SWI48 0 "r")
24062 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24063 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24064 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24065 [(const_int 0)]
24066 {
24067 ix86_expand_clear (operands[0]);
24068 emit_move_insn (operands[1], operands[0]);
24069 ix86_last_zero_store_uid
24070 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24071 DONE;
24072 })
24073
24074 (define_peephole2
24075 [(match_scratch:SWI48 0 "r")
24076 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24077 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24078 [(const_int 0)]
24079 {
24080 ix86_expand_clear (operands[0]);
24081 ix86_last_zero_store_uid
24082 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24083 DONE;
24084 })
24085
24086 (define_peephole2
24087 [(set (match_operand:SWI48 5 "memory_operand")
24088 (match_operand:SWI48 0 "general_reg_operand"))
24089 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24090 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24091 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24092 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24093 "optimize_insn_for_size_p ()
24094 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24095 [(const_int 0)]
24096 {
24097 emit_move_insn (operands[5], operands[0]);
24098 emit_move_insn (operands[1], operands[0]);
24099 emit_move_insn (operands[2], operands[0]);
24100 emit_move_insn (operands[3], operands[0]);
24101 ix86_last_zero_store_uid
24102 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24103 DONE;
24104 })
24105
24106 (define_peephole2
24107 [(set (match_operand:SWI48 3 "memory_operand")
24108 (match_operand:SWI48 0 "general_reg_operand"))
24109 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24110 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24111 "optimize_insn_for_size_p ()
24112 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24113 [(const_int 0)]
24114 {
24115 emit_move_insn (operands[3], operands[0]);
24116 emit_move_insn (operands[1], operands[0]);
24117 ix86_last_zero_store_uid
24118 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24119 DONE;
24120 })
24121
24122 (define_peephole2
24123 [(set (match_operand:SWI48 2 "memory_operand")
24124 (match_operand:SWI48 0 "general_reg_operand"))
24125 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24126 "optimize_insn_for_size_p ()
24127 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24128 [(const_int 0)]
24129 {
24130 emit_move_insn (operands[2], operands[0]);
24131 ix86_last_zero_store_uid
24132 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24133 DONE;
24134 })
24135
24136 ;; Reload dislikes loading constants directly into class_likely_spilled
24137 ;; hard registers. Try to tidy things up here.
24138 (define_peephole2
24139 [(set (match_operand:SWI 0 "general_reg_operand")
24140 (match_operand:SWI 1 "x86_64_general_operand"))
24141 (set (match_operand:SWI 2 "general_reg_operand")
24142 (match_dup 0))]
24143 "peep2_reg_dead_p (2, operands[0])"
24144 [(set (match_dup 2) (match_dup 1))])
24145 \f
24146 ;; Misc patterns (?)
24147
24148 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
24149 ;; Otherwise there will be nothing to keep
24150 ;;
24151 ;; [(set (reg ebp) (reg esp))]
24152 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
24153 ;; (clobber (eflags)]
24154 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
24155 ;;
24156 ;; in proper program order.
24157
24158 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
24159 [(set (match_operand:P 0 "register_operand" "=r,r")
24160 (plus:P (match_operand:P 1 "register_operand" "0,r")
24161 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
24162 (clobber (reg:CC FLAGS_REG))
24163 (clobber (mem:BLK (scratch)))]
24164 ""
24165 {
24166 switch (get_attr_type (insn))
24167 {
24168 case TYPE_IMOV:
24169 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
24170
24171 case TYPE_ALU:
24172 gcc_assert (rtx_equal_p (operands[0], operands[1]));
24173 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
24174 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
24175
24176 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
24177
24178 default:
24179 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
24180 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
24181 }
24182 }
24183 [(set (attr "type")
24184 (cond [(and (eq_attr "alternative" "0")
24185 (not (match_test "TARGET_OPT_AGU")))
24186 (const_string "alu")
24187 (match_operand:<MODE> 2 "const0_operand")
24188 (const_string "imov")
24189 ]
24190 (const_string "lea")))
24191 (set (attr "length_immediate")
24192 (cond [(eq_attr "type" "imov")
24193 (const_string "0")
24194 (and (eq_attr "type" "alu")
24195 (match_operand 2 "const128_operand"))
24196 (const_string "1")
24197 ]
24198 (const_string "*")))
24199 (set_attr "mode" "<MODE>")])
24200
24201 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
24202 [(set (match_operand:P 0 "register_operand" "=r")
24203 (minus:P (match_operand:P 1 "register_operand" "0")
24204 (match_operand:P 2 "register_operand" "r")))
24205 (clobber (reg:CC FLAGS_REG))
24206 (clobber (mem:BLK (scratch)))]
24207 ""
24208 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
24209 [(set_attr "type" "alu")
24210 (set_attr "mode" "<MODE>")])
24211
24212 (define_insn "@allocate_stack_worker_probe_<mode>"
24213 [(set (match_operand:P 0 "register_operand" "=a")
24214 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24215 UNSPECV_STACK_PROBE))
24216 (clobber (reg:CC FLAGS_REG))]
24217 "ix86_target_stack_probe ()"
24218 "call\t___chkstk_ms"
24219 [(set_attr "type" "multi")
24220 (set_attr "length" "5")])
24221
24222 (define_expand "allocate_stack"
24223 [(match_operand 0 "register_operand")
24224 (match_operand 1 "general_operand")]
24225 "ix86_target_stack_probe ()"
24226 {
24227 rtx x;
24228
24229 #ifndef CHECK_STACK_LIMIT
24230 #define CHECK_STACK_LIMIT 0
24231 #endif
24232
24233 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
24234 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24235 x = operands[1];
24236 else
24237 {
24238 x = copy_to_mode_reg (Pmode, operands[1]);
24239
24240 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24241 }
24242
24243 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24244 stack_pointer_rtx, 0, OPTAB_DIRECT);
24245
24246 if (x != stack_pointer_rtx)
24247 emit_move_insn (stack_pointer_rtx, x);
24248
24249 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24250 DONE;
24251 })
24252
24253 (define_expand "probe_stack"
24254 [(match_operand 0 "memory_operand")]
24255 ""
24256 {
24257 emit_insn (gen_probe_stack_1
24258 (word_mode, operands[0], const0_rtx));
24259 DONE;
24260 })
24261
24262 ;; Use OR for stack probes, this is shorter.
24263 (define_insn "@probe_stack_1_<mode>"
24264 [(set (match_operand:W 0 "memory_operand" "=m")
24265 (unspec:W [(match_operand:W 1 "const0_operand")]
24266 UNSPEC_PROBE_STACK))
24267 (clobber (reg:CC FLAGS_REG))]
24268 ""
24269 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24270 [(set_attr "type" "alu1")
24271 (set_attr "mode" "<MODE>")
24272 (set_attr "length_immediate" "1")])
24273
24274 (define_insn "@adjust_stack_and_probe_<mode>"
24275 [(set (match_operand:P 0 "register_operand" "=r")
24276 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24277 UNSPECV_PROBE_STACK_RANGE))
24278 (set (reg:P SP_REG)
24279 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24280 (clobber (reg:CC FLAGS_REG))
24281 (clobber (mem:BLK (scratch)))]
24282 ""
24283 "* return output_adjust_stack_and_probe (operands[0]);"
24284 [(set_attr "type" "multi")])
24285
24286 (define_insn "@probe_stack_range_<mode>"
24287 [(set (match_operand:P 0 "register_operand" "=r")
24288 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24289 (match_operand:P 2 "const_int_operand")]
24290 UNSPECV_PROBE_STACK_RANGE))
24291 (clobber (reg:CC FLAGS_REG))]
24292 ""
24293 "* return output_probe_stack_range (operands[0], operands[2]);"
24294 [(set_attr "type" "multi")])
24295
24296 (define_expand "builtin_setjmp_receiver"
24297 [(label_ref (match_operand 0))]
24298 "!TARGET_64BIT && flag_pic"
24299 {
24300 #if TARGET_MACHO
24301 if (TARGET_MACHO)
24302 {
24303 rtx xops[3];
24304 rtx_code_label *label_rtx = gen_label_rtx ();
24305 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24306 xops[0] = xops[1] = pic_offset_table_rtx;
24307 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24308 ix86_expand_binary_operator (MINUS, SImode, xops);
24309 }
24310 else
24311 #endif
24312 emit_insn (gen_set_got (pic_offset_table_rtx));
24313 DONE;
24314 })
24315
24316 (define_expand "save_stack_nonlocal"
24317 [(set (match_operand 0 "memory_operand")
24318 (match_operand 1 "register_operand"))]
24319 ""
24320 {
24321 rtx stack_slot;
24322
24323 if (flag_cf_protection & CF_RETURN)
24324 {
24325 /* Copy shadow stack pointer to the first slot
24326 and stack pointer to the second slot. */
24327 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24328 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24329
24330 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24331 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24332 emit_move_insn (ssp_slot, reg_ssp);
24333 }
24334 else
24335 stack_slot = adjust_address (operands[0], Pmode, 0);
24336 emit_move_insn (stack_slot, operands[1]);
24337 DONE;
24338 })
24339
24340 (define_expand "restore_stack_nonlocal"
24341 [(set (match_operand 0 "register_operand" "")
24342 (match_operand 1 "memory_operand" ""))]
24343 ""
24344 {
24345 rtx stack_slot;
24346
24347 if (flag_cf_protection & CF_RETURN)
24348 {
24349 /* Restore shadow stack pointer from the first slot
24350 and stack pointer from the second slot. */
24351 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24352 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24353
24354 /* Get the current shadow stack pointer. The code below will check if
24355 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
24356 is a NOP. */
24357 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24358 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24359
24360 /* Compare through subtraction the saved and the current ssp
24361 to decide if ssp has to be adjusted. */
24362 reg_ssp = expand_simple_binop (word_mode, MINUS,
24363 reg_ssp, ssp_slot,
24364 reg_ssp, 1, OPTAB_DIRECT);
24365
24366 /* Compare and jump over adjustment code. */
24367 rtx noadj_label = gen_label_rtx ();
24368 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24369 word_mode, 1, noadj_label);
24370
24371 /* Compute the number of frames to adjust. */
24372 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24373 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24374 NULL_RTX, 1);
24375
24376 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24377 GEN_INT (exact_log2 (UNITS_PER_WORD)),
24378 reg_adj, 1, OPTAB_DIRECT);
24379
24380 /* Check if number of frames <= 255 so no loop is needed. */
24381 rtx inc_label = gen_label_rtx ();
24382 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24383 ptr_mode, 1, inc_label);
24384
24385 /* Adjust the ssp in a loop. */
24386 rtx loop_label = gen_label_rtx ();
24387 emit_label (loop_label);
24388 LABEL_NUSES (loop_label) = 1;
24389
24390 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24391 emit_insn (gen_incssp (word_mode, reg_255));
24392
24393 reg_adj = expand_simple_binop (ptr_mode, MINUS,
24394 reg_adj, GEN_INT (255),
24395 reg_adj, 1, OPTAB_DIRECT);
24396
24397 /* Compare and jump to the loop label. */
24398 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24399 ptr_mode, 1, loop_label);
24400
24401 emit_label (inc_label);
24402 LABEL_NUSES (inc_label) = 1;
24403
24404 emit_insn (gen_incssp (word_mode, reg_ssp));
24405
24406 emit_label (noadj_label);
24407 LABEL_NUSES (noadj_label) = 1;
24408 }
24409 else
24410 stack_slot = adjust_address (operands[1], Pmode, 0);
24411 emit_move_insn (operands[0], stack_slot);
24412 DONE;
24413 })
24414
24415 (define_expand "stack_protect_set"
24416 [(match_operand 0 "memory_operand")
24417 (match_operand 1 "memory_operand")]
24418 ""
24419 {
24420 rtx scratch = gen_reg_rtx (word_mode);
24421
24422 emit_insn (gen_stack_protect_set_1
24423 (ptr_mode, word_mode, operands[0], operands[1], scratch));
24424 DONE;
24425 })
24426
24427 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
24428 [(set (match_operand:PTR 0 "memory_operand" "=m")
24429 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
24430 UNSPEC_SP_SET))
24431 (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
24432 (clobber (reg:CC FLAGS_REG))]
24433 ""
24434 {
24435 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
24436 operands);
24437 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
24438 operands);
24439 if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24440 return "xor{l}\t%k2, %k2";
24441 else
24442 return "mov{l}\t{$0, %k2|%k2, 0}";
24443 }
24444 [(set_attr "type" "multi")])
24445
24446 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
24447 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
24448 ;; the xor{l} above. We don't split this, so that scheduling or
24449 ;; anything else doesn't separate the *stack_protect_set* pattern from
24450 ;; the set of the register that overwrites the register with a new value.
24451
24452 (define_peephole2
24453 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24454 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24455 UNSPEC_SP_SET))
24456 (set (match_operand 2 "general_reg_operand") (const_int 0))
24457 (clobber (reg:CC FLAGS_REG))])
24458 (set (match_operand 3 "general_reg_operand")
24459 (match_operand 4 "const0_operand"))]
24460 "GET_MODE (operands[2]) == word_mode
24461 && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
24462 && peep2_reg_dead_p (0, operands[3])
24463 && peep2_reg_dead_p (1, operands[2])"
24464 [(parallel [(set (match_dup 0)
24465 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24466 (set (match_dup 3) (const_int 0))
24467 (clobber (reg:CC FLAGS_REG))])]
24468 "operands[3] = gen_lowpart (word_mode, operands[3]);")
24469
24470 (define_insn "*stack_protect_set_2_<mode>_si"
24471 [(set (match_operand:PTR 0 "memory_operand" "=m")
24472 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24473 UNSPEC_SP_SET))
24474 (set (match_operand:SI 1 "register_operand" "=&r")
24475 (match_operand:SI 2 "general_operand" "g"))]
24476 "reload_completed"
24477 {
24478 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24479 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24480 if (pic_32bit_operand (operands[2], SImode)
24481 || ix86_use_lea_for_mov (insn, operands + 1))
24482 return "lea{l}\t{%E2, %1|%1, %E2}";
24483 else
24484 return "mov{l}\t{%2, %1|%1, %2}";
24485 }
24486 [(set_attr "type" "multi")
24487 (set_attr "length" "24")])
24488
24489 (define_insn "*stack_protect_set_2_<mode>_di"
24490 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
24491 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
24492 UNSPEC_SP_SET))
24493 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
24494 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
24495 "TARGET_64BIT && reload_completed"
24496 {
24497 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24498 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24499 if (pic_32bit_operand (operands[2], DImode))
24500 return "lea{q}\t{%E2, %1|%1, %E2}";
24501 else if (which_alternative == 0)
24502 return "mov{l}\t{%k2, %k1|%k1, %k2}";
24503 else if (which_alternative == 2)
24504 return "movabs{q}\t{%2, %1|%1, %2}";
24505 else if (ix86_use_lea_for_mov (insn, operands + 1))
24506 return "lea{q}\t{%E2, %1|%1, %E2}";
24507 else
24508 return "mov{q}\t{%2, %1|%1, %2}";
24509 }
24510 [(set_attr "type" "multi")
24511 (set_attr "length" "24")])
24512
24513 (define_peephole2
24514 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24515 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24516 UNSPEC_SP_SET))
24517 (set (match_operand 2 "general_reg_operand") (const_int 0))
24518 (clobber (reg:CC FLAGS_REG))])
24519 (set (match_operand:SWI48 3 "general_reg_operand")
24520 (match_operand:SWI48 4 "general_gr_operand"))]
24521 "GET_MODE (operands[2]) == word_mode
24522 && peep2_reg_dead_p (0, operands[3])
24523 && peep2_reg_dead_p (1, operands[2])"
24524 [(parallel [(set (match_dup 0)
24525 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24526 (set (match_dup 3) (match_dup 4))])])
24527
24528 (define_peephole2
24529 [(set (match_operand:SWI48 3 "general_reg_operand")
24530 (match_operand:SWI48 4 "general_gr_operand"))
24531 (parallel [(set (match_operand:PTR 0 "memory_operand")
24532 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24533 UNSPEC_SP_SET))
24534 (set (match_operand 2 "general_reg_operand") (const_int 0))
24535 (clobber (reg:CC FLAGS_REG))])]
24536 "GET_MODE (operands[2]) == word_mode
24537 && peep2_reg_dead_p (0, operands[3])
24538 && peep2_reg_dead_p (2, operands[2])
24539 && !reg_mentioned_p (operands[3], operands[0])
24540 && !reg_mentioned_p (operands[3], operands[1])"
24541 [(parallel [(set (match_dup 0)
24542 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24543 (set (match_dup 3) (match_dup 4))])])
24544
24545 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
24546 [(set (match_operand:PTR 0 "memory_operand" "=m")
24547 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24548 UNSPEC_SP_SET))
24549 (set (match_operand:SWI48 1 "register_operand" "=&r")
24550 (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
24551 ""
24552 {
24553 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
24554 operands);
24555 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
24556 operands);
24557 if (SImode_address_operand (operands[2], VOIDmode))
24558 {
24559 gcc_assert (TARGET_64BIT);
24560 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24561 }
24562 else
24563 return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
24564 }
24565 [(set_attr "type" "multi")
24566 (set_attr "length" "24")])
24567
24568 (define_peephole2
24569 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24570 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24571 UNSPEC_SP_SET))
24572 (set (match_operand 2 "general_reg_operand") (const_int 0))
24573 (clobber (reg:CC FLAGS_REG))])
24574 (set (match_operand:SWI48 3 "general_reg_operand")
24575 (match_operand:SWI48 4 "address_no_seg_operand"))]
24576 "GET_MODE (operands[2]) == word_mode
24577 && peep2_reg_dead_p (0, operands[3])
24578 && peep2_reg_dead_p (1, operands[2])"
24579 [(parallel [(set (match_dup 0)
24580 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24581 (set (match_dup 3) (match_dup 4))])])
24582
24583 (define_insn "*stack_protect_set_4z_<mode>_di"
24584 [(set (match_operand:PTR 0 "memory_operand" "=m")
24585 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24586 UNSPEC_SP_SET))
24587 (set (match_operand:DI 1 "register_operand" "=&r")
24588 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24589 "TARGET_64BIT && reload_completed"
24590 {
24591 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24592 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24593 if (ix86_use_lea_for_mov (insn, operands + 1))
24594 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24595 else
24596 return "mov{l}\t{%2, %k1|%k1, %2}";
24597 }
24598 [(set_attr "type" "multi")
24599 (set_attr "length" "24")])
24600
24601 (define_insn "*stack_protect_set_4s_<mode>_di"
24602 [(set (match_operand:PTR 0 "memory_operand" "=m")
24603 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24604 UNSPEC_SP_SET))
24605 (set (match_operand:DI 1 "register_operand" "=&r")
24606 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24607 "TARGET_64BIT && reload_completed"
24608 {
24609 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24610 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24611 return "movs{lq|x}\t{%2, %1|%1, %2}";
24612 }
24613 [(set_attr "type" "multi")
24614 (set_attr "length" "24")])
24615
24616 (define_peephole2
24617 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24618 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24619 UNSPEC_SP_SET))
24620 (set (match_operand 2 "general_reg_operand") (const_int 0))
24621 (clobber (reg:CC FLAGS_REG))])
24622 (set (match_operand:DI 3 "general_reg_operand")
24623 (any_extend:DI
24624 (match_operand:SI 4 "nonimmediate_gr_operand")))]
24625 "TARGET_64BIT
24626 && GET_MODE (operands[2]) == word_mode
24627 && peep2_reg_dead_p (0, operands[3])
24628 && peep2_reg_dead_p (1, operands[2])"
24629 [(parallel [(set (match_dup 0)
24630 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24631 (set (match_dup 3)
24632 (any_extend:DI (match_dup 4)))])])
24633
24634 (define_expand "stack_protect_test"
24635 [(match_operand 0 "memory_operand")
24636 (match_operand 1 "memory_operand")
24637 (match_operand 2)]
24638 ""
24639 {
24640 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
24641
24642 emit_insn (gen_stack_protect_test_1
24643 (ptr_mode, flags, operands[0], operands[1]));
24644
24645 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
24646 flags, const0_rtx, operands[2]));
24647 DONE;
24648 })
24649
24650 (define_insn "@stack_protect_test_1_<mode>"
24651 [(set (match_operand:CCZ 0 "flags_reg_operand")
24652 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
24653 (match_operand:PTR 2 "memory_operand" "m")]
24654 UNSPEC_SP_TEST))
24655 (clobber (match_scratch:PTR 3 "=&r"))]
24656 ""
24657 {
24658 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
24659 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
24660 }
24661 [(set_attr "type" "multi")])
24662
24663 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24664 ;; Do not split instructions with mask registers.
24665 (define_split
24666 [(set (match_operand 0 "general_reg_operand")
24667 (match_operator 3 "promotable_binary_operator"
24668 [(match_operand 1 "general_reg_operand")
24669 (match_operand 2 "aligned_operand")]))
24670 (clobber (reg:CC FLAGS_REG))]
24671 "! TARGET_PARTIAL_REG_STALL && reload_completed
24672 && ((GET_MODE (operands[0]) == HImode
24673 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24674 /* ??? next two lines just !satisfies_constraint_K (...) */
24675 || !CONST_INT_P (operands[2])
24676 || satisfies_constraint_K (operands[2])))
24677 || (GET_MODE (operands[0]) == QImode
24678 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24679 [(parallel [(set (match_dup 0)
24680 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24681 (clobber (reg:CC FLAGS_REG))])]
24682 {
24683 operands[0] = gen_lowpart (SImode, operands[0]);
24684 operands[1] = gen_lowpart (SImode, operands[1]);
24685 if (GET_CODE (operands[3]) != ASHIFT)
24686 operands[2] = gen_lowpart (SImode, operands[2]);
24687 operands[3] = shallow_copy_rtx (operands[3]);
24688 PUT_MODE (operands[3], SImode);
24689 })
24690
24691 ; Promote the QImode tests, as i386 has encoding of the AND
24692 ; instruction with 32-bit sign-extended immediate and thus the
24693 ; instruction size is unchanged, except in the %eax case for
24694 ; which it is increased by one byte, hence the ! optimize_size.
24695 (define_split
24696 [(set (match_operand 0 "flags_reg_operand")
24697 (match_operator 2 "compare_operator"
24698 [(and (match_operand 3 "aligned_operand")
24699 (match_operand 4 "const_int_operand"))
24700 (const_int 0)]))
24701 (set (match_operand 1 "register_operand")
24702 (and (match_dup 3) (match_dup 4)))]
24703 "! TARGET_PARTIAL_REG_STALL && reload_completed
24704 && optimize_insn_for_speed_p ()
24705 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24706 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24707 /* Ensure that the operand will remain sign-extended immediate. */
24708 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24709 [(parallel [(set (match_dup 0)
24710 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24711 (const_int 0)]))
24712 (set (match_dup 1)
24713 (and:SI (match_dup 3) (match_dup 4)))])]
24714 {
24715 operands[4]
24716 = gen_int_mode (INTVAL (operands[4])
24717 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24718 operands[1] = gen_lowpart (SImode, operands[1]);
24719 operands[3] = gen_lowpart (SImode, operands[3]);
24720 })
24721
24722 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24723 ; the TEST instruction with 32-bit sign-extended immediate and thus
24724 ; the instruction size would at least double, which is not what we
24725 ; want even with ! optimize_size.
24726 (define_split
24727 [(set (match_operand 0 "flags_reg_operand")
24728 (match_operator 1 "compare_operator"
24729 [(and (match_operand:HI 2 "aligned_operand")
24730 (match_operand:HI 3 "const_int_operand"))
24731 (const_int 0)]))]
24732 "! TARGET_PARTIAL_REG_STALL && reload_completed
24733 && ! TARGET_FAST_PREFIX
24734 && optimize_insn_for_speed_p ()
24735 /* Ensure that the operand will remain sign-extended immediate. */
24736 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24737 [(set (match_dup 0)
24738 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24739 (const_int 0)]))]
24740 {
24741 operands[3]
24742 = gen_int_mode (INTVAL (operands[3])
24743 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24744 operands[2] = gen_lowpart (SImode, operands[2]);
24745 })
24746
24747 (define_split
24748 [(set (match_operand 0 "register_operand")
24749 (neg (match_operand 1 "register_operand")))
24750 (clobber (reg:CC FLAGS_REG))]
24751 "! TARGET_PARTIAL_REG_STALL && reload_completed
24752 && (GET_MODE (operands[0]) == HImode
24753 || (GET_MODE (operands[0]) == QImode
24754 && (TARGET_PROMOTE_QImode
24755 || optimize_insn_for_size_p ())))"
24756 [(parallel [(set (match_dup 0)
24757 (neg:SI (match_dup 1)))
24758 (clobber (reg:CC FLAGS_REG))])]
24759 {
24760 operands[0] = gen_lowpart (SImode, operands[0]);
24761 operands[1] = gen_lowpart (SImode, operands[1]);
24762 })
24763
24764 ;; Do not split instructions with mask regs.
24765 (define_split
24766 [(set (match_operand 0 "general_reg_operand")
24767 (not (match_operand 1 "general_reg_operand")))]
24768 "! TARGET_PARTIAL_REG_STALL && reload_completed
24769 && (GET_MODE (operands[0]) == HImode
24770 || (GET_MODE (operands[0]) == QImode
24771 && (TARGET_PROMOTE_QImode
24772 || optimize_insn_for_size_p ())))"
24773 [(set (match_dup 0)
24774 (not:SI (match_dup 1)))]
24775 {
24776 operands[0] = gen_lowpart (SImode, operands[0]);
24777 operands[1] = gen_lowpart (SImode, operands[1]);
24778 })
24779 \f
24780 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24781 ;; transform a complex memory operation into two memory to register operations.
24782
24783 ;; Don't push memory operands
24784 (define_peephole2
24785 [(set (match_operand:SWI 0 "push_operand")
24786 (match_operand:SWI 1 "memory_operand"))
24787 (match_scratch:SWI 2 "<r>")]
24788 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24789 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24790 [(set (match_dup 2) (match_dup 1))
24791 (set (match_dup 0) (match_dup 2))])
24792
24793 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24794 ;; SImode pushes.
24795 (define_peephole2
24796 [(set (match_operand:SF 0 "push_operand")
24797 (match_operand:SF 1 "memory_operand"))
24798 (match_scratch:SF 2 "r")]
24799 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24800 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24801 [(set (match_dup 2) (match_dup 1))
24802 (set (match_dup 0) (match_dup 2))])
24803
24804 ;; Don't move an immediate directly to memory when the instruction
24805 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24806 (define_peephole2
24807 [(match_scratch:SWI124 1 "<r>")
24808 (set (match_operand:SWI124 0 "memory_operand")
24809 (const_int 0))]
24810 "optimize_insn_for_speed_p ()
24811 && ((<MODE>mode == HImode
24812 && TARGET_LCP_STALL)
24813 || (!TARGET_USE_MOV0
24814 && TARGET_SPLIT_LONG_MOVES
24815 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24816 && peep2_regno_dead_p (0, FLAGS_REG)"
24817 [(parallel [(set (match_dup 2) (const_int 0))
24818 (clobber (reg:CC FLAGS_REG))])
24819 (set (match_dup 0) (match_dup 1))]
24820 "operands[2] = gen_lowpart (SImode, operands[1]);")
24821
24822 (define_peephole2
24823 [(match_scratch:SWI124 2 "<r>")
24824 (set (match_operand:SWI124 0 "memory_operand")
24825 (match_operand:SWI124 1 "immediate_operand"))]
24826 "optimize_insn_for_speed_p ()
24827 && ((<MODE>mode == HImode
24828 && TARGET_LCP_STALL)
24829 || (TARGET_SPLIT_LONG_MOVES
24830 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24831 [(set (match_dup 2) (match_dup 1))
24832 (set (match_dup 0) (match_dup 2))])
24833
24834 ;; Don't compare memory with zero, load and use a test instead.
24835 (define_peephole2
24836 [(set (match_operand 0 "flags_reg_operand")
24837 (match_operator 1 "compare_operator"
24838 [(match_operand:SI 2 "memory_operand")
24839 (const_int 0)]))
24840 (match_scratch:SI 3 "r")]
24841 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24842 [(set (match_dup 3) (match_dup 2))
24843 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24844
24845 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24846 ;; Don't split NOTs with a displacement operand, because resulting XOR
24847 ;; will not be pairable anyway.
24848 ;;
24849 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24850 ;; represented using a modRM byte. The XOR replacement is long decoded,
24851 ;; so this split helps here as well.
24852 ;;
24853 ;; Note: Can't do this as a regular split because we can't get proper
24854 ;; lifetime information then.
24855
24856 (define_peephole2
24857 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24858 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24859 "optimize_insn_for_speed_p ()
24860 && ((TARGET_NOT_UNPAIRABLE
24861 && (!MEM_P (operands[0])
24862 || !memory_displacement_operand (operands[0], <MODE>mode)))
24863 || (TARGET_NOT_VECTORMODE
24864 && long_memory_operand (operands[0], <MODE>mode)))
24865 && peep2_regno_dead_p (0, FLAGS_REG)"
24866 [(parallel [(set (match_dup 0)
24867 (xor:SWI124 (match_dup 1) (const_int -1)))
24868 (clobber (reg:CC FLAGS_REG))])])
24869
24870 ;; Non pairable "test imm, reg" instructions can be translated to
24871 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24872 ;; byte opcode instead of two, have a short form for byte operands),
24873 ;; so do it for other CPUs as well. Given that the value was dead,
24874 ;; this should not create any new dependencies. Pass on the sub-word
24875 ;; versions if we're concerned about partial register stalls.
24876
24877 (define_peephole2
24878 [(set (match_operand 0 "flags_reg_operand")
24879 (match_operator 1 "compare_operator"
24880 [(and:SI (match_operand:SI 2 "register_operand")
24881 (match_operand:SI 3 "immediate_operand"))
24882 (const_int 0)]))]
24883 "ix86_match_ccmode (insn, CCNOmode)
24884 && (REGNO (operands[2]) != AX_REG
24885 || satisfies_constraint_K (operands[3]))
24886 && peep2_reg_dead_p (1, operands[2])"
24887 [(parallel
24888 [(set (match_dup 0)
24889 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24890 (const_int 0)]))
24891 (set (match_dup 2)
24892 (and:SI (match_dup 2) (match_dup 3)))])])
24893
24894 ;; We don't need to handle HImode case, because it will be promoted to SImode
24895 ;; on ! TARGET_PARTIAL_REG_STALL
24896
24897 (define_peephole2
24898 [(set (match_operand 0 "flags_reg_operand")
24899 (match_operator 1 "compare_operator"
24900 [(and:QI (match_operand:QI 2 "register_operand")
24901 (match_operand:QI 3 "immediate_operand"))
24902 (const_int 0)]))]
24903 "! TARGET_PARTIAL_REG_STALL
24904 && ix86_match_ccmode (insn, CCNOmode)
24905 && REGNO (operands[2]) != AX_REG
24906 && peep2_reg_dead_p (1, operands[2])"
24907 [(parallel
24908 [(set (match_dup 0)
24909 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24910 (const_int 0)]))
24911 (set (match_dup 2)
24912 (and:QI (match_dup 2) (match_dup 3)))])])
24913
24914 (define_peephole2
24915 [(set (match_operand 0 "flags_reg_operand")
24916 (match_operator 1 "compare_operator"
24917 [(and:QI
24918 (subreg:QI
24919 (match_operator:SWI248 4 "extract_operator"
24920 [(match_operand 2 "int248_register_operand")
24921 (const_int 8)
24922 (const_int 8)]) 0)
24923 (match_operand 3 "const_int_operand"))
24924 (const_int 0)]))]
24925 "! TARGET_PARTIAL_REG_STALL
24926 && ix86_match_ccmode (insn, CCNOmode)
24927 && REGNO (operands[2]) != AX_REG
24928 && peep2_reg_dead_p (1, operands[2])"
24929 [(parallel
24930 [(set (match_dup 0)
24931 (match_op_dup 1
24932 [(and:QI
24933 (subreg:QI
24934 (match_op_dup 4 [(match_dup 2)
24935 (const_int 8)
24936 (const_int 8)]) 0)
24937 (match_dup 3))
24938 (const_int 0)]))
24939 (set (zero_extract:SWI248 (match_dup 2)
24940 (const_int 8)
24941 (const_int 8))
24942 (subreg:SWI248
24943 (and:QI
24944 (subreg:QI
24945 (match_op_dup 4 [(match_dup 2)
24946 (const_int 8)
24947 (const_int 8)]) 0)
24948 (match_dup 3)) 0))])])
24949
24950 ;; Don't do logical operations with memory inputs.
24951 (define_peephole2
24952 [(match_scratch:SWI 2 "<r>")
24953 (parallel [(set (match_operand:SWI 0 "register_operand")
24954 (match_operator:SWI 3 "arith_or_logical_operator"
24955 [(match_dup 0)
24956 (match_operand:SWI 1 "memory_operand")]))
24957 (clobber (reg:CC FLAGS_REG))])]
24958 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24959 [(set (match_dup 2) (match_dup 1))
24960 (parallel [(set (match_dup 0)
24961 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24962 (clobber (reg:CC FLAGS_REG))])])
24963
24964 (define_peephole2
24965 [(match_scratch:SWI 2 "<r>")
24966 (parallel [(set (match_operand:SWI 0 "register_operand")
24967 (match_operator:SWI 3 "arith_or_logical_operator"
24968 [(match_operand:SWI 1 "memory_operand")
24969 (match_dup 0)]))
24970 (clobber (reg:CC FLAGS_REG))])]
24971 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24972 [(set (match_dup 2) (match_dup 1))
24973 (parallel [(set (match_dup 0)
24974 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24975 (clobber (reg:CC FLAGS_REG))])])
24976
24977 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24978 ;; the memory address refers to the destination of the load!
24979
24980 (define_peephole2
24981 [(set (match_operand:SWI 0 "general_reg_operand")
24982 (match_operand:SWI 1 "general_reg_operand"))
24983 (parallel [(set (match_dup 0)
24984 (match_operator:SWI 3 "commutative_operator"
24985 [(match_dup 0)
24986 (match_operand:SWI 2 "memory_operand")]))
24987 (clobber (reg:CC FLAGS_REG))])]
24988 "REGNO (operands[0]) != REGNO (operands[1])
24989 && (<MODE>mode != QImode
24990 || any_QIreg_operand (operands[1], QImode))"
24991 [(set (match_dup 0) (match_dup 4))
24992 (parallel [(set (match_dup 0)
24993 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24994 (clobber (reg:CC FLAGS_REG))])]
24995 {
24996 operands[4]
24997 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24998 })
24999
25000 (define_peephole2
25001 [(set (match_operand 0 "mmx_reg_operand")
25002 (match_operand 1 "mmx_reg_operand"))
25003 (set (match_dup 0)
25004 (match_operator 3 "commutative_operator"
25005 [(match_dup 0)
25006 (match_operand 2 "memory_operand")]))]
25007 "REGNO (operands[0]) != REGNO (operands[1])"
25008 [(set (match_dup 0) (match_dup 2))
25009 (set (match_dup 0)
25010 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
25011
25012 (define_peephole2
25013 [(set (match_operand 0 "sse_reg_operand")
25014 (match_operand 1 "sse_reg_operand"))
25015 (set (match_dup 0)
25016 (match_operator 3 "commutative_operator"
25017 [(match_dup 0)
25018 (match_operand 2 "memory_operand")]))]
25019 "REGNO (operands[0]) != REGNO (operands[1])
25020 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
25021 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
25022 instructions require AVX512BW and AVX512VL, but with the original
25023 instructions it might require just AVX512VL.
25024 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
25025 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
25026 || TARGET_AVX512BW
25027 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
25028 || logic_operator (operands[3], VOIDmode))"
25029 [(set (match_dup 0) (match_dup 2))
25030 (set (match_dup 0)
25031 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
25032
25033 ; Don't do logical operations with memory outputs
25034 ;
25035 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
25036 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
25037 ; the same decoder scheduling characteristics as the original.
25038
25039 (define_peephole2
25040 [(match_scratch:SWI 2 "<r>")
25041 (parallel [(set (match_operand:SWI 0 "memory_operand")
25042 (match_operator:SWI 3 "arith_or_logical_operator"
25043 [(match_dup 0)
25044 (match_operand:SWI 1 "<nonmemory_operand>")]))
25045 (clobber (reg:CC FLAGS_REG))])]
25046 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
25047 [(set (match_dup 2) (match_dup 0))
25048 (parallel [(set (match_dup 2)
25049 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
25050 (clobber (reg:CC FLAGS_REG))])
25051 (set (match_dup 0) (match_dup 2))])
25052
25053 (define_peephole2
25054 [(match_scratch:SWI 2 "<r>")
25055 (parallel [(set (match_operand:SWI 0 "memory_operand")
25056 (match_operator:SWI 3 "arith_or_logical_operator"
25057 [(match_operand:SWI 1 "<nonmemory_operand>")
25058 (match_dup 0)]))
25059 (clobber (reg:CC FLAGS_REG))])]
25060 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
25061 [(set (match_dup 2) (match_dup 0))
25062 (parallel [(set (match_dup 2)
25063 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
25064 (clobber (reg:CC FLAGS_REG))])
25065 (set (match_dup 0) (match_dup 2))])
25066
25067 ;; Attempt to use arith or logical operations with memory outputs with
25068 ;; setting of flags.
25069 (define_peephole2
25070 [(set (match_operand:SWI 0 "register_operand")
25071 (match_operand:SWI 1 "memory_operand"))
25072 (parallel [(set (match_dup 0)
25073 (match_operator:SWI 3 "plusminuslogic_operator"
25074 [(match_dup 0)
25075 (match_operand:SWI 2 "<nonmemory_operand>")]))
25076 (clobber (reg:CC FLAGS_REG))])
25077 (set (match_dup 1) (match_dup 0))
25078 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25079 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25080 && peep2_reg_dead_p (4, operands[0])
25081 && !reg_overlap_mentioned_p (operands[0], operands[1])
25082 && !reg_overlap_mentioned_p (operands[0], operands[2])
25083 && (<MODE>mode != QImode
25084 || immediate_operand (operands[2], QImode)
25085 || any_QIreg_operand (operands[2], QImode))
25086 && ix86_match_ccmode (peep2_next_insn (3),
25087 (GET_CODE (operands[3]) == PLUS
25088 || GET_CODE (operands[3]) == MINUS)
25089 ? CCGOCmode : CCNOmode)"
25090 [(parallel [(set (match_dup 4) (match_dup 6))
25091 (set (match_dup 1) (match_dup 5))])]
25092 {
25093 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
25094 operands[5]
25095 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25096 copy_rtx (operands[1]),
25097 operands[2]);
25098 operands[6]
25099 = gen_rtx_COMPARE (GET_MODE (operands[4]),
25100 copy_rtx (operands[5]),
25101 const0_rtx);
25102 })
25103
25104 ;; Likewise for cmpelim optimized pattern.
25105 (define_peephole2
25106 [(set (match_operand:SWI 0 "register_operand")
25107 (match_operand:SWI 1 "memory_operand"))
25108 (parallel [(set (reg FLAGS_REG)
25109 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25110 [(match_dup 0)
25111 (match_operand:SWI 2 "<nonmemory_operand>")])
25112 (const_int 0)))
25113 (set (match_dup 0) (match_dup 3))])
25114 (set (match_dup 1) (match_dup 0))]
25115 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25116 && peep2_reg_dead_p (3, operands[0])
25117 && !reg_overlap_mentioned_p (operands[0], operands[1])
25118 && !reg_overlap_mentioned_p (operands[0], operands[2])
25119 && ix86_match_ccmode (peep2_next_insn (1),
25120 (GET_CODE (operands[3]) == PLUS
25121 || GET_CODE (operands[3]) == MINUS)
25122 ? CCGOCmode : CCNOmode)"
25123 [(parallel [(set (match_dup 4) (match_dup 6))
25124 (set (match_dup 1) (match_dup 5))])]
25125 {
25126 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25127 operands[5]
25128 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25129 copy_rtx (operands[1]), operands[2]);
25130 operands[6]
25131 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
25132 const0_rtx);
25133 })
25134
25135 ;; Likewise for instances where we have a lea pattern.
25136 (define_peephole2
25137 [(set (match_operand:SWI 0 "register_operand")
25138 (match_operand:SWI 1 "memory_operand"))
25139 (set (match_operand:<LEAMODE> 3 "register_operand")
25140 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
25141 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
25142 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
25143 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25144 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25145 && REGNO (operands[4]) == REGNO (operands[0])
25146 && REGNO (operands[5]) == REGNO (operands[3])
25147 && peep2_reg_dead_p (4, operands[3])
25148 && ((REGNO (operands[0]) == REGNO (operands[3]))
25149 || peep2_reg_dead_p (2, operands[0]))
25150 && !reg_overlap_mentioned_p (operands[0], operands[1])
25151 && !reg_overlap_mentioned_p (operands[3], operands[1])
25152 && !reg_overlap_mentioned_p (operands[0], operands[2])
25153 && (<MODE>mode != QImode
25154 || immediate_operand (operands[2], QImode)
25155 || any_QIreg_operand (operands[2], QImode))
25156 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
25157 [(parallel [(set (match_dup 6) (match_dup 8))
25158 (set (match_dup 1) (match_dup 7))])]
25159 {
25160 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
25161 operands[7]
25162 = gen_rtx_PLUS (<MODE>mode,
25163 copy_rtx (operands[1]),
25164 gen_lowpart (<MODE>mode, operands[2]));
25165 operands[8]
25166 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25167 copy_rtx (operands[7]),
25168 const0_rtx);
25169 })
25170
25171 (define_peephole2
25172 [(parallel [(set (match_operand:SWI 0 "register_operand")
25173 (match_operator:SWI 2 "plusminuslogic_operator"
25174 [(match_dup 0)
25175 (match_operand:SWI 1 "memory_operand")]))
25176 (clobber (reg:CC FLAGS_REG))])
25177 (set (match_dup 1) (match_dup 0))
25178 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25179 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25180 && COMMUTATIVE_ARITH_P (operands[2])
25181 && peep2_reg_dead_p (3, operands[0])
25182 && !reg_overlap_mentioned_p (operands[0], operands[1])
25183 && ix86_match_ccmode (peep2_next_insn (2),
25184 GET_CODE (operands[2]) == PLUS
25185 ? CCGOCmode : CCNOmode)"
25186 [(parallel [(set (match_dup 3) (match_dup 5))
25187 (set (match_dup 1) (match_dup 4))])]
25188 {
25189 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
25190 operands[4]
25191 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25192 copy_rtx (operands[1]),
25193 operands[0]);
25194 operands[5]
25195 = gen_rtx_COMPARE (GET_MODE (operands[3]),
25196 copy_rtx (operands[4]),
25197 const0_rtx);
25198 })
25199
25200 ;; Likewise for cmpelim optimized pattern.
25201 (define_peephole2
25202 [(parallel [(set (reg FLAGS_REG)
25203 (compare (match_operator:SWI 2 "plusminuslogic_operator"
25204 [(match_operand:SWI 0 "register_operand")
25205 (match_operand:SWI 1 "memory_operand")])
25206 (const_int 0)))
25207 (set (match_dup 0) (match_dup 2))])
25208 (set (match_dup 1) (match_dup 0))]
25209 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25210 && COMMUTATIVE_ARITH_P (operands[2])
25211 && peep2_reg_dead_p (2, operands[0])
25212 && !reg_overlap_mentioned_p (operands[0], operands[1])
25213 && ix86_match_ccmode (peep2_next_insn (0),
25214 GET_CODE (operands[2]) == PLUS
25215 ? CCGOCmode : CCNOmode)"
25216 [(parallel [(set (match_dup 3) (match_dup 5))
25217 (set (match_dup 1) (match_dup 4))])]
25218 {
25219 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
25220 operands[4]
25221 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25222 copy_rtx (operands[1]), operands[0]);
25223 operands[5]
25224 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
25225 const0_rtx);
25226 })
25227
25228 (define_peephole2
25229 [(set (match_operand:SWI12 0 "register_operand")
25230 (match_operand:SWI12 1 "memory_operand"))
25231 (parallel [(set (match_operand:SI 4 "register_operand")
25232 (match_operator:SI 3 "plusminuslogic_operator"
25233 [(match_dup 4)
25234 (match_operand:SI 2 "nonmemory_operand")]))
25235 (clobber (reg:CC FLAGS_REG))])
25236 (set (match_dup 1) (match_dup 0))
25237 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25238 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25239 && REGNO (operands[0]) == REGNO (operands[4])
25240 && peep2_reg_dead_p (4, operands[0])
25241 && (<MODE>mode != QImode
25242 || immediate_operand (operands[2], SImode)
25243 || any_QIreg_operand (operands[2], SImode))
25244 && !reg_overlap_mentioned_p (operands[0], operands[1])
25245 && !reg_overlap_mentioned_p (operands[0], operands[2])
25246 && ix86_match_ccmode (peep2_next_insn (3),
25247 (GET_CODE (operands[3]) == PLUS
25248 || GET_CODE (operands[3]) == MINUS)
25249 ? CCGOCmode : CCNOmode)"
25250 [(parallel [(set (match_dup 5) (match_dup 7))
25251 (set (match_dup 1) (match_dup 6))])]
25252 {
25253 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
25254 operands[6]
25255 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25256 copy_rtx (operands[1]),
25257 gen_lowpart (<MODE>mode, operands[2]));
25258 operands[7]
25259 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25260 copy_rtx (operands[6]),
25261 const0_rtx);
25262 })
25263
25264 ;; peephole2 comes before regcprop, so deal also with a case that
25265 ;; would be cleaned up by regcprop.
25266 (define_peephole2
25267 [(set (match_operand:SWI 0 "register_operand")
25268 (match_operand:SWI 1 "memory_operand"))
25269 (parallel [(set (match_dup 0)
25270 (match_operator:SWI 3 "plusminuslogic_operator"
25271 [(match_dup 0)
25272 (match_operand:SWI 2 "<nonmemory_operand>")]))
25273 (clobber (reg:CC FLAGS_REG))])
25274 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25275 (set (match_dup 1) (match_dup 4))
25276 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
25277 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25278 && peep2_reg_dead_p (3, operands[0])
25279 && peep2_reg_dead_p (5, operands[4])
25280 && !reg_overlap_mentioned_p (operands[0], operands[1])
25281 && !reg_overlap_mentioned_p (operands[0], operands[2])
25282 && !reg_overlap_mentioned_p (operands[4], operands[1])
25283 && (<MODE>mode != QImode
25284 || immediate_operand (operands[2], QImode)
25285 || any_QIreg_operand (operands[2], QImode))
25286 && ix86_match_ccmode (peep2_next_insn (4),
25287 (GET_CODE (operands[3]) == PLUS
25288 || GET_CODE (operands[3]) == MINUS)
25289 ? CCGOCmode : CCNOmode)"
25290 [(parallel [(set (match_dup 5) (match_dup 7))
25291 (set (match_dup 1) (match_dup 6))])]
25292 {
25293 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
25294 operands[6]
25295 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25296 copy_rtx (operands[1]),
25297 operands[2]);
25298 operands[7]
25299 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25300 copy_rtx (operands[6]),
25301 const0_rtx);
25302 })
25303
25304 (define_peephole2
25305 [(set (match_operand:SWI12 0 "register_operand")
25306 (match_operand:SWI12 1 "memory_operand"))
25307 (parallel [(set (match_operand:SI 4 "register_operand")
25308 (match_operator:SI 3 "plusminuslogic_operator"
25309 [(match_dup 4)
25310 (match_operand:SI 2 "nonmemory_operand")]))
25311 (clobber (reg:CC FLAGS_REG))])
25312 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
25313 (set (match_dup 1) (match_dup 5))
25314 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25315 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25316 && REGNO (operands[0]) == REGNO (operands[4])
25317 && peep2_reg_dead_p (3, operands[0])
25318 && peep2_reg_dead_p (5, operands[5])
25319 && (<MODE>mode != QImode
25320 || immediate_operand (operands[2], SImode)
25321 || any_QIreg_operand (operands[2], SImode))
25322 && !reg_overlap_mentioned_p (operands[0], operands[1])
25323 && !reg_overlap_mentioned_p (operands[0], operands[2])
25324 && !reg_overlap_mentioned_p (operands[5], operands[1])
25325 && ix86_match_ccmode (peep2_next_insn (4),
25326 (GET_CODE (operands[3]) == PLUS
25327 || GET_CODE (operands[3]) == MINUS)
25328 ? CCGOCmode : CCNOmode)"
25329 [(parallel [(set (match_dup 6) (match_dup 8))
25330 (set (match_dup 1) (match_dup 7))])]
25331 {
25332 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
25333 operands[7]
25334 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25335 copy_rtx (operands[1]),
25336 gen_lowpart (<MODE>mode, operands[2]));
25337 operands[8]
25338 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25339 copy_rtx (operands[7]),
25340 const0_rtx);
25341 })
25342
25343 ;; Likewise for cmpelim optimized pattern.
25344 (define_peephole2
25345 [(set (match_operand:SWI 0 "register_operand")
25346 (match_operand:SWI 1 "memory_operand"))
25347 (parallel [(set (reg FLAGS_REG)
25348 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25349 [(match_dup 0)
25350 (match_operand:SWI 2 "<nonmemory_operand>")])
25351 (const_int 0)))
25352 (set (match_dup 0) (match_dup 3))])
25353 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25354 (set (match_dup 1) (match_dup 4))]
25355 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25356 && peep2_reg_dead_p (3, operands[0])
25357 && peep2_reg_dead_p (4, operands[4])
25358 && !reg_overlap_mentioned_p (operands[0], operands[1])
25359 && !reg_overlap_mentioned_p (operands[0], operands[2])
25360 && !reg_overlap_mentioned_p (operands[4], operands[1])
25361 && ix86_match_ccmode (peep2_next_insn (1),
25362 (GET_CODE (operands[3]) == PLUS
25363 || GET_CODE (operands[3]) == MINUS)
25364 ? CCGOCmode : CCNOmode)"
25365 [(parallel [(set (match_dup 5) (match_dup 7))
25366 (set (match_dup 1) (match_dup 6))])]
25367 {
25368 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25369 operands[6]
25370 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25371 copy_rtx (operands[1]), operands[2]);
25372 operands[7]
25373 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
25374 const0_rtx);
25375 })
25376
25377 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25378 ;; into x = z; x ^= y; x != z
25379 (define_peephole2
25380 [(set (match_operand:SWI 0 "register_operand")
25381 (match_operand:SWI 1 "memory_operand"))
25382 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25383 (parallel [(set (match_operand:SWI 4 "register_operand")
25384 (xor:SWI (match_dup 4)
25385 (match_operand:SWI 2 "<nonmemory_operand>")))
25386 (clobber (reg:CC FLAGS_REG))])
25387 (set (match_dup 1) (match_dup 4))
25388 (set (reg:CCZ FLAGS_REG)
25389 (compare:CCZ (match_operand:SWI 5 "register_operand")
25390 (match_operand:SWI 6 "<nonmemory_operand>")))]
25391 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25392 && (REGNO (operands[4]) == REGNO (operands[0])
25393 || REGNO (operands[4]) == REGNO (operands[3]))
25394 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25395 ? 3 : 0], operands[5])
25396 ? rtx_equal_p (operands[2], operands[6])
25397 : rtx_equal_p (operands[2], operands[5])
25398 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25399 ? 3 : 0], operands[6]))
25400 && peep2_reg_dead_p (4, operands[4])
25401 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25402 ? 3 : 0])
25403 && !reg_overlap_mentioned_p (operands[0], operands[1])
25404 && !reg_overlap_mentioned_p (operands[0], operands[2])
25405 && !reg_overlap_mentioned_p (operands[3], operands[0])
25406 && !reg_overlap_mentioned_p (operands[3], operands[1])
25407 && !reg_overlap_mentioned_p (operands[3], operands[2])
25408 && (<MODE>mode != QImode
25409 || immediate_operand (operands[2], QImode)
25410 || any_QIreg_operand (operands[2], QImode))"
25411 [(parallel [(set (match_dup 7) (match_dup 9))
25412 (set (match_dup 1) (match_dup 8))])]
25413 {
25414 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25415 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25416 operands[2]);
25417 operands[9]
25418 = gen_rtx_COMPARE (GET_MODE (operands[7]),
25419 copy_rtx (operands[8]),
25420 const0_rtx);
25421 })
25422
25423 (define_peephole2
25424 [(set (match_operand:SWI12 0 "register_operand")
25425 (match_operand:SWI12 1 "memory_operand"))
25426 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25427 (parallel [(set (match_operand:SI 4 "register_operand")
25428 (xor:SI (match_dup 4)
25429 (match_operand:SI 2 "<nonmemory_operand>")))
25430 (clobber (reg:CC FLAGS_REG))])
25431 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25432 (set (reg:CCZ FLAGS_REG)
25433 (compare:CCZ (match_operand:SWI12 6 "register_operand")
25434 (match_operand:SWI12 7 "<nonmemory_operand>")))]
25435 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25436 && (REGNO (operands[5]) == REGNO (operands[0])
25437 || REGNO (operands[5]) == REGNO (operands[3]))
25438 && REGNO (operands[5]) == REGNO (operands[4])
25439 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25440 ? 3 : 0], operands[6])
25441 ? (REG_P (operands[2])
25442 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25443 : rtx_equal_p (operands[2], operands[7]))
25444 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25445 ? 3 : 0], operands[7])
25446 && REG_P (operands[2])
25447 && REGNO (operands[2]) == REGNO (operands[6])))
25448 && peep2_reg_dead_p (4, operands[5])
25449 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25450 ? 3 : 0])
25451 && !reg_overlap_mentioned_p (operands[0], operands[1])
25452 && !reg_overlap_mentioned_p (operands[0], operands[2])
25453 && !reg_overlap_mentioned_p (operands[3], operands[0])
25454 && !reg_overlap_mentioned_p (operands[3], operands[1])
25455 && !reg_overlap_mentioned_p (operands[3], operands[2])
25456 && (<MODE>mode != QImode
25457 || immediate_operand (operands[2], SImode)
25458 || any_QIreg_operand (operands[2], SImode))"
25459 [(parallel [(set (match_dup 8) (match_dup 10))
25460 (set (match_dup 1) (match_dup 9))])]
25461 {
25462 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25463 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25464 gen_lowpart (<MODE>mode, operands[2]));
25465 operands[10]
25466 = gen_rtx_COMPARE (GET_MODE (operands[8]),
25467 copy_rtx (operands[9]),
25468 const0_rtx);
25469 })
25470
25471 ;; Attempt to optimize away memory stores of values the memory already
25472 ;; has. See PR79593.
25473 (define_peephole2
25474 [(set (match_operand 0 "register_operand")
25475 (match_operand 1 "memory_operand"))
25476 (set (match_operand 2 "memory_operand") (match_dup 0))]
25477 "!MEM_VOLATILE_P (operands[1])
25478 && !MEM_VOLATILE_P (operands[2])
25479 && rtx_equal_p (operands[1], operands[2])
25480 && !reg_overlap_mentioned_p (operands[0], operands[2])"
25481 [(set (match_dup 0) (match_dup 1))])
25482
25483 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25484 (define_peephole2
25485 [(set (match_operand 0 "general_reg_operand")
25486 (match_operand 1 "const0_operand"))]
25487 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25488 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25489 && peep2_regno_dead_p (0, FLAGS_REG)"
25490 [(parallel [(set (match_dup 0) (const_int 0))
25491 (clobber (reg:CC FLAGS_REG))])]
25492 "operands[0] = gen_lowpart (word_mode, operands[0]);")
25493
25494 (define_peephole2
25495 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25496 (const_int 0))]
25497 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25498 && peep2_regno_dead_p (0, FLAGS_REG)"
25499 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25500 (clobber (reg:CC FLAGS_REG))])])
25501
25502 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25503 (define_peephole2
25504 [(set (match_operand:SWI248 0 "general_reg_operand")
25505 (const_int -1))]
25506 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25507 && peep2_regno_dead_p (0, FLAGS_REG)"
25508 [(parallel [(set (match_dup 0) (const_int -1))
25509 (clobber (reg:CC FLAGS_REG))])]
25510 {
25511 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25512 operands[0] = gen_lowpart (SImode, operands[0]);
25513 })
25514
25515 ;; Attempt to convert simple lea to add/shift.
25516 ;; These can be created by move expanders.
25517 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25518 ;; relevant lea instructions were already split.
25519
25520 (define_peephole2
25521 [(set (match_operand:SWI48 0 "register_operand")
25522 (plus:SWI48 (match_dup 0)
25523 (match_operand:SWI48 1 "<nonmemory_operand>")))]
25524 "!TARGET_OPT_AGU
25525 && peep2_regno_dead_p (0, FLAGS_REG)"
25526 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25527 (clobber (reg:CC FLAGS_REG))])])
25528
25529 (define_peephole2
25530 [(set (match_operand:SWI48 0 "register_operand")
25531 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25532 (match_dup 0)))]
25533 "!TARGET_OPT_AGU
25534 && peep2_regno_dead_p (0, FLAGS_REG)"
25535 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25536 (clobber (reg:CC FLAGS_REG))])])
25537
25538 (define_peephole2
25539 [(set (match_operand:DI 0 "register_operand")
25540 (zero_extend:DI
25541 (plus:SI (match_operand:SI 1 "register_operand")
25542 (match_operand:SI 2 "nonmemory_operand"))))]
25543 "TARGET_64BIT && !TARGET_OPT_AGU
25544 && REGNO (operands[0]) == REGNO (operands[1])
25545 && peep2_regno_dead_p (0, FLAGS_REG)"
25546 [(parallel [(set (match_dup 0)
25547 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25548 (clobber (reg:CC FLAGS_REG))])])
25549
25550 (define_peephole2
25551 [(set (match_operand:DI 0 "register_operand")
25552 (zero_extend:DI
25553 (plus:SI (match_operand:SI 1 "nonmemory_operand")
25554 (match_operand:SI 2 "register_operand"))))]
25555 "TARGET_64BIT && !TARGET_OPT_AGU
25556 && REGNO (operands[0]) == REGNO (operands[2])
25557 && peep2_regno_dead_p (0, FLAGS_REG)"
25558 [(parallel [(set (match_dup 0)
25559 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25560 (clobber (reg:CC FLAGS_REG))])])
25561
25562 (define_peephole2
25563 [(set (match_operand:SWI48 0 "register_operand")
25564 (mult:SWI48 (match_dup 0)
25565 (match_operand:SWI48 1 "const_int_operand")))]
25566 "pow2p_hwi (INTVAL (operands[1]))
25567 && peep2_regno_dead_p (0, FLAGS_REG)"
25568 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25569 (clobber (reg:CC FLAGS_REG))])]
25570 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25571
25572 (define_peephole2
25573 [(set (match_operand:DI 0 "register_operand")
25574 (zero_extend:DI
25575 (mult:SI (match_operand:SI 1 "register_operand")
25576 (match_operand:SI 2 "const_int_operand"))))]
25577 "TARGET_64BIT
25578 && pow2p_hwi (INTVAL (operands[2]))
25579 && REGNO (operands[0]) == REGNO (operands[1])
25580 && peep2_regno_dead_p (0, FLAGS_REG)"
25581 [(parallel [(set (match_dup 0)
25582 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25583 (clobber (reg:CC FLAGS_REG))])]
25584 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25585
25586 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
25587 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25588 ;; On many CPUs it is also faster, since special hardware to avoid esp
25589 ;; dependencies is present.
25590
25591 ;; While some of these conversions may be done using splitters, we use
25592 ;; peepholes in order to allow combine_stack_adjustments pass to see
25593 ;; nonobfuscated RTL.
25594
25595 ;; Convert prologue esp subtractions to push.
25596 ;; We need register to push. In order to keep verify_flow_info happy we have
25597 ;; two choices
25598 ;; - use scratch and clobber it in order to avoid dependencies
25599 ;; - use already live register
25600 ;; We can't use the second way right now, since there is no reliable way how to
25601 ;; verify that given register is live. First choice will also most likely in
25602 ;; fewer dependencies. On the place of esp adjustments it is very likely that
25603 ;; call clobbered registers are dead. We may want to use base pointer as an
25604 ;; alternative when no register is available later.
25605
25606 (define_peephole2
25607 [(match_scratch:W 1 "r")
25608 (parallel [(set (reg:P SP_REG)
25609 (plus:P (reg:P SP_REG)
25610 (match_operand:P 0 "const_int_operand")))
25611 (clobber (reg:CC FLAGS_REG))
25612 (clobber (mem:BLK (scratch)))])]
25613 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25614 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25615 && !ix86_red_zone_used"
25616 [(clobber (match_dup 1))
25617 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25618 (clobber (mem:BLK (scratch)))])])
25619
25620 (define_peephole2
25621 [(match_scratch:W 1 "r")
25622 (parallel [(set (reg:P SP_REG)
25623 (plus:P (reg:P SP_REG)
25624 (match_operand:P 0 "const_int_operand")))
25625 (clobber (reg:CC FLAGS_REG))
25626 (clobber (mem:BLK (scratch)))])]
25627 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25628 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25629 && !ix86_red_zone_used"
25630 [(clobber (match_dup 1))
25631 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25632 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25633 (clobber (mem:BLK (scratch)))])])
25634
25635 ;; Convert esp subtractions to push.
25636 (define_peephole2
25637 [(match_scratch:W 1 "r")
25638 (parallel [(set (reg:P SP_REG)
25639 (plus:P (reg:P SP_REG)
25640 (match_operand:P 0 "const_int_operand")))
25641 (clobber (reg:CC FLAGS_REG))])]
25642 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25643 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25644 && !ix86_red_zone_used"
25645 [(clobber (match_dup 1))
25646 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25647
25648 (define_peephole2
25649 [(match_scratch:W 1 "r")
25650 (parallel [(set (reg:P SP_REG)
25651 (plus:P (reg:P SP_REG)
25652 (match_operand:P 0 "const_int_operand")))
25653 (clobber (reg:CC FLAGS_REG))])]
25654 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25655 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25656 && !ix86_red_zone_used"
25657 [(clobber (match_dup 1))
25658 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25659 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25660
25661 ;; Convert epilogue deallocator to pop.
25662 (define_peephole2
25663 [(match_scratch:W 1 "r")
25664 (parallel [(set (reg:P SP_REG)
25665 (plus:P (reg:P SP_REG)
25666 (match_operand:P 0 "const_int_operand")))
25667 (clobber (reg:CC FLAGS_REG))
25668 (clobber (mem:BLK (scratch)))])]
25669 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25670 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25671 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25672 (clobber (mem:BLK (scratch)))])])
25673
25674 ;; Two pops case is tricky, since pop causes dependency
25675 ;; on destination register. We use two registers if available.
25676 (define_peephole2
25677 [(match_scratch:W 1 "r")
25678 (match_scratch:W 2 "r")
25679 (parallel [(set (reg:P SP_REG)
25680 (plus:P (reg:P SP_REG)
25681 (match_operand:P 0 "const_int_operand")))
25682 (clobber (reg:CC FLAGS_REG))
25683 (clobber (mem:BLK (scratch)))])]
25684 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25685 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25686 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25687 (clobber (mem:BLK (scratch)))])
25688 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25689
25690 (define_peephole2
25691 [(match_scratch:W 1 "r")
25692 (parallel [(set (reg:P SP_REG)
25693 (plus:P (reg:P SP_REG)
25694 (match_operand:P 0 "const_int_operand")))
25695 (clobber (reg:CC FLAGS_REG))
25696 (clobber (mem:BLK (scratch)))])]
25697 "optimize_insn_for_size_p ()
25698 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25699 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25700 (clobber (mem:BLK (scratch)))])
25701 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25702
25703 ;; Convert esp additions to pop.
25704 (define_peephole2
25705 [(match_scratch:W 1 "r")
25706 (parallel [(set (reg:P SP_REG)
25707 (plus:P (reg:P SP_REG)
25708 (match_operand:P 0 "const_int_operand")))
25709 (clobber (reg:CC FLAGS_REG))])]
25710 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25711 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25712
25713 ;; Two pops case is tricky, since pop causes dependency
25714 ;; on destination register. We use two registers if available.
25715 (define_peephole2
25716 [(match_scratch:W 1 "r")
25717 (match_scratch:W 2 "r")
25718 (parallel [(set (reg:P SP_REG)
25719 (plus:P (reg:P SP_REG)
25720 (match_operand:P 0 "const_int_operand")))
25721 (clobber (reg:CC FLAGS_REG))])]
25722 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25723 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25724 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25725
25726 (define_peephole2
25727 [(match_scratch:W 1 "r")
25728 (parallel [(set (reg:P SP_REG)
25729 (plus:P (reg:P SP_REG)
25730 (match_operand:P 0 "const_int_operand")))
25731 (clobber (reg:CC FLAGS_REG))])]
25732 "optimize_insn_for_size_p ()
25733 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25734 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25735 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25736 \f
25737 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25738 ;; required and register dies. Similarly for 128 to -128.
25739 (define_peephole2
25740 [(set (match_operand 0 "flags_reg_operand")
25741 (match_operator 1 "compare_operator"
25742 [(match_operand 2 "register_operand")
25743 (match_operand 3 "const_int_operand")]))]
25744 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25745 && incdec_operand (operands[3], GET_MODE (operands[3])))
25746 || (!TARGET_FUSE_CMP_AND_BRANCH
25747 && INTVAL (operands[3]) == 128))
25748 && ix86_match_ccmode (insn, CCGCmode)
25749 && peep2_reg_dead_p (1, operands[2])"
25750 [(parallel [(set (match_dup 0)
25751 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25752 (clobber (match_dup 2))])])
25753 \f
25754 ;; Convert imul by three, five and nine into lea
25755 (define_peephole2
25756 [(parallel
25757 [(set (match_operand:SWI48 0 "register_operand")
25758 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25759 (match_operand:SWI48 2 "const359_operand")))
25760 (clobber (reg:CC FLAGS_REG))])]
25761 "!TARGET_PARTIAL_REG_STALL
25762 || <MODE>mode == SImode
25763 || optimize_function_for_size_p (cfun)"
25764 [(set (match_dup 0)
25765 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25766 (match_dup 1)))]
25767 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25768
25769 (define_peephole2
25770 [(parallel
25771 [(set (match_operand:SWI48 0 "register_operand")
25772 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25773 (match_operand:SWI48 2 "const359_operand")))
25774 (clobber (reg:CC FLAGS_REG))])]
25775 "optimize_insn_for_speed_p ()
25776 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25777 [(set (match_dup 0) (match_dup 1))
25778 (set (match_dup 0)
25779 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25780 (match_dup 0)))]
25781 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25782
25783 ;; imul $32bit_imm, mem, reg is vector decoded, while
25784 ;; imul $32bit_imm, reg, reg is direct decoded.
25785 (define_peephole2
25786 [(match_scratch:SWI48 3 "r")
25787 (parallel [(set (match_operand:SWI48 0 "register_operand")
25788 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25789 (match_operand:SWI48 2 "immediate_operand")))
25790 (clobber (reg:CC FLAGS_REG))])]
25791 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25792 && !satisfies_constraint_K (operands[2])"
25793 [(set (match_dup 3) (match_dup 1))
25794 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25795 (clobber (reg:CC FLAGS_REG))])])
25796
25797 (define_peephole2
25798 [(match_scratch:SI 3 "r")
25799 (parallel [(set (match_operand:DI 0 "register_operand")
25800 (zero_extend:DI
25801 (mult:SI (match_operand:SI 1 "memory_operand")
25802 (match_operand:SI 2 "immediate_operand"))))
25803 (clobber (reg:CC FLAGS_REG))])]
25804 "TARGET_64BIT
25805 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25806 && !satisfies_constraint_K (operands[2])"
25807 [(set (match_dup 3) (match_dup 1))
25808 (parallel [(set (match_dup 0)
25809 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25810 (clobber (reg:CC FLAGS_REG))])])
25811
25812 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25813 ;; Convert it into imul reg, reg
25814 ;; It would be better to force assembler to encode instruction using long
25815 ;; immediate, but there is apparently no way to do so.
25816 (define_peephole2
25817 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25818 (mult:SWI248
25819 (match_operand:SWI248 1 "nonimmediate_operand")
25820 (match_operand:SWI248 2 "const_int_operand")))
25821 (clobber (reg:CC FLAGS_REG))])
25822 (match_scratch:SWI248 3 "r")]
25823 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25824 && satisfies_constraint_K (operands[2])"
25825 [(set (match_dup 3) (match_dup 2))
25826 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25827 (clobber (reg:CC FLAGS_REG))])]
25828 {
25829 if (!rtx_equal_p (operands[0], operands[1]))
25830 emit_move_insn (operands[0], operands[1]);
25831 })
25832
25833 ;; After splitting up read-modify operations, array accesses with memory
25834 ;; operands might end up in form:
25835 ;; sall $2, %eax
25836 ;; movl 4(%esp), %edx
25837 ;; addl %edx, %eax
25838 ;; instead of pre-splitting:
25839 ;; sall $2, %eax
25840 ;; addl 4(%esp), %eax
25841 ;; Turn it into:
25842 ;; movl 4(%esp), %edx
25843 ;; leal (%edx,%eax,4), %eax
25844
25845 (define_peephole2
25846 [(match_scratch:W 5 "r")
25847 (parallel [(set (match_operand 0 "register_operand")
25848 (ashift (match_operand 1 "register_operand")
25849 (match_operand 2 "const_int_operand")))
25850 (clobber (reg:CC FLAGS_REG))])
25851 (parallel [(set (match_operand 3 "register_operand")
25852 (plus (match_dup 0)
25853 (match_operand 4 "x86_64_general_operand")))
25854 (clobber (reg:CC FLAGS_REG))])]
25855 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25856 /* Validate MODE for lea. */
25857 && ((!TARGET_PARTIAL_REG_STALL
25858 && (GET_MODE (operands[0]) == QImode
25859 || GET_MODE (operands[0]) == HImode))
25860 || GET_MODE (operands[0]) == SImode
25861 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25862 && (rtx_equal_p (operands[0], operands[3])
25863 || peep2_reg_dead_p (2, operands[0]))
25864 /* We reorder load and the shift. */
25865 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25866 [(set (match_dup 5) (match_dup 4))
25867 (set (match_dup 0) (match_dup 1))]
25868 {
25869 machine_mode op1mode = GET_MODE (operands[1]);
25870 machine_mode mode = op1mode == DImode ? DImode : SImode;
25871 int scale = 1 << INTVAL (operands[2]);
25872 rtx index = gen_lowpart (word_mode, operands[1]);
25873 rtx base = gen_lowpart (word_mode, operands[5]);
25874 rtx dest = gen_lowpart (mode, operands[3]);
25875
25876 operands[1] = gen_rtx_PLUS (word_mode, base,
25877 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25878 if (mode != word_mode)
25879 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25880
25881 operands[5] = base;
25882 if (op1mode != word_mode)
25883 operands[5] = gen_lowpart (op1mode, operands[5]);
25884
25885 operands[0] = dest;
25886 })
25887 \f
25888 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25889 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25890 ;; caught for use by garbage collectors and the like. Using an insn that
25891 ;; maps to SIGILL makes it more likely the program will rightfully die.
25892 ;; Keeping with tradition, "6" is in honor of #UD.
25893 (define_insn "trap"
25894 [(trap_if (const_int 1) (const_int 6))]
25895 ""
25896 {
25897 #ifdef HAVE_AS_IX86_UD2
25898 return "ud2";
25899 #else
25900 return ASM_SHORT "0x0b0f";
25901 #endif
25902 }
25903 [(set_attr "length" "2")])
25904
25905 (define_insn "ud2"
25906 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25907 ""
25908 {
25909 #ifdef HAVE_AS_IX86_UD2
25910 return "ud2";
25911 #else
25912 return ASM_SHORT "0x0b0f";
25913 #endif
25914 }
25915 [(set_attr "length" "2")])
25916
25917 (define_expand "prefetch"
25918 [(prefetch (match_operand 0 "address_operand")
25919 (match_operand:SI 1 "const_int_operand")
25920 (match_operand:SI 2 "const_int_operand"))]
25921 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25922 {
25923 bool write = operands[1] != const0_rtx;
25924 int locality = INTVAL (operands[2]);
25925
25926 gcc_assert (IN_RANGE (locality, 0, 3));
25927
25928 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25929 supported by SSE counterpart (non-SSE2 athlon machines) or the
25930 SSE prefetch is not available (K6 machines). Otherwise use SSE
25931 prefetch as it allows specifying of locality. */
25932
25933 if (write)
25934 {
25935 if (TARGET_PREFETCHWT1)
25936 operands[2] = GEN_INT (MAX (locality, 2));
25937 else if (TARGET_PRFCHW)
25938 operands[2] = GEN_INT (3);
25939 else if (TARGET_3DNOW && !TARGET_SSE2)
25940 operands[2] = GEN_INT (3);
25941 else if (TARGET_PREFETCH_SSE)
25942 operands[1] = const0_rtx;
25943 else
25944 {
25945 gcc_assert (TARGET_3DNOW);
25946 operands[2] = GEN_INT (3);
25947 }
25948 }
25949 else
25950 {
25951 if (TARGET_PREFETCH_SSE)
25952 ;
25953 else
25954 {
25955 gcc_assert (TARGET_3DNOW);
25956 operands[2] = GEN_INT (3);
25957 }
25958 }
25959 })
25960
25961 (define_insn "*prefetch_sse"
25962 [(prefetch (match_operand 0 "address_operand" "p")
25963 (const_int 0)
25964 (match_operand:SI 1 "const_int_operand"))]
25965 "TARGET_PREFETCH_SSE"
25966 {
25967 static const char * const patterns[4] = {
25968 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25969 };
25970
25971 int locality = INTVAL (operands[1]);
25972 gcc_assert (IN_RANGE (locality, 0, 3));
25973
25974 return patterns[locality];
25975 }
25976 [(set_attr "type" "sse")
25977 (set_attr "atom_sse_attr" "prefetch")
25978 (set (attr "length_address")
25979 (symbol_ref "memory_address_length (operands[0], false)"))
25980 (set_attr "memory" "none")])
25981
25982 (define_insn "*prefetch_3dnow"
25983 [(prefetch (match_operand 0 "address_operand" "p")
25984 (match_operand:SI 1 "const_int_operand")
25985 (const_int 3))]
25986 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25987 {
25988 if (operands[1] == const0_rtx)
25989 return "prefetch\t%a0";
25990 else
25991 return "prefetchw\t%a0";
25992 }
25993 [(set_attr "type" "mmx")
25994 (set (attr "length_address")
25995 (symbol_ref "memory_address_length (operands[0], false)"))
25996 (set_attr "memory" "none")])
25997
25998 (define_insn "*prefetch_prefetchwt1"
25999 [(prefetch (match_operand 0 "address_operand" "p")
26000 (const_int 1)
26001 (const_int 2))]
26002 "TARGET_PREFETCHWT1"
26003 "prefetchwt1\t%a0";
26004 [(set_attr "type" "sse")
26005 (set (attr "length_address")
26006 (symbol_ref "memory_address_length (operands[0], false)"))
26007 (set_attr "memory" "none")])
26008
26009 (define_insn "prefetchi"
26010 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
26011 (match_operand:SI 1 "const_int_operand")]
26012 UNSPECV_PREFETCHI)]
26013 "TARGET_PREFETCHI && TARGET_64BIT"
26014 {
26015 static const char * const patterns[2] = {
26016 "prefetchit1\t%0", "prefetchit0\t%0"
26017 };
26018
26019 int locality = INTVAL (operands[1]);
26020 gcc_assert (IN_RANGE (locality, 2, 3));
26021
26022 return patterns[locality - 2];
26023 }
26024 [(set_attr "type" "sse")
26025 (set (attr "length_address")
26026 (symbol_ref "memory_address_length (operands[0], false)"))
26027 (set_attr "memory" "none")])
26028
26029 (define_insn "sse4_2_crc32<mode>"
26030 [(set (match_operand:SI 0 "register_operand" "=r")
26031 (unspec:SI
26032 [(match_operand:SI 1 "register_operand" "0")
26033 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
26034 UNSPEC_CRC32))]
26035 "TARGET_CRC32"
26036 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
26037 [(set_attr "type" "sselog1")
26038 (set_attr "prefix_rep" "1")
26039 (set_attr "prefix_extra" "1")
26040 (set (attr "prefix_data16")
26041 (if_then_else (match_operand:HI 2)
26042 (const_string "1")
26043 (const_string "*")))
26044 (set (attr "prefix_rex")
26045 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
26046 (const_string "1")
26047 (const_string "*")))
26048 (set_attr "mode" "SI")])
26049
26050 (define_insn "sse4_2_crc32di"
26051 [(set (match_operand:DI 0 "register_operand" "=r")
26052 (zero_extend:DI
26053 (unspec:SI
26054 [(match_operand:SI 1 "register_operand" "0")
26055 (match_operand:DI 2 "nonimmediate_operand" "rm")]
26056 UNSPEC_CRC32)))]
26057 "TARGET_64BIT && TARGET_CRC32"
26058 "crc32{q}\t{%2, %0|%0, %2}"
26059 [(set_attr "type" "sselog1")
26060 (set_attr "prefix_rep" "1")
26061 (set_attr "prefix_extra" "1")
26062 (set_attr "mode" "DI")])
26063
26064 (define_insn "rdpmc"
26065 [(set (match_operand:DI 0 "register_operand" "=A")
26066 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26067 UNSPECV_RDPMC))]
26068 "!TARGET_64BIT"
26069 "rdpmc"
26070 [(set_attr "type" "other")
26071 (set_attr "length" "2")])
26072
26073 (define_insn "rdpmc_rex64"
26074 [(set (match_operand:DI 0 "register_operand" "=a")
26075 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26076 UNSPECV_RDPMC))
26077 (set (match_operand:DI 1 "register_operand" "=d")
26078 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
26079 "TARGET_64BIT"
26080 "rdpmc"
26081 [(set_attr "type" "other")
26082 (set_attr "length" "2")])
26083
26084 (define_insn "rdtsc"
26085 [(set (match_operand:DI 0 "register_operand" "=A")
26086 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26087 "!TARGET_64BIT"
26088 "rdtsc"
26089 [(set_attr "type" "other")
26090 (set_attr "length" "2")])
26091
26092 (define_insn "rdtsc_rex64"
26093 [(set (match_operand:DI 0 "register_operand" "=a")
26094 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
26095 (set (match_operand:DI 1 "register_operand" "=d")
26096 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26097 "TARGET_64BIT"
26098 "rdtsc"
26099 [(set_attr "type" "other")
26100 (set_attr "length" "2")])
26101
26102 (define_insn "rdtscp"
26103 [(set (match_operand:DI 0 "register_operand" "=A")
26104 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26105 (set (match_operand:SI 1 "register_operand" "=c")
26106 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26107 "!TARGET_64BIT"
26108 "rdtscp"
26109 [(set_attr "type" "other")
26110 (set_attr "length" "3")])
26111
26112 (define_insn "rdtscp_rex64"
26113 [(set (match_operand:DI 0 "register_operand" "=a")
26114 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26115 (set (match_operand:DI 1 "register_operand" "=d")
26116 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26117 (set (match_operand:SI 2 "register_operand" "=c")
26118 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26119 "TARGET_64BIT"
26120 "rdtscp"
26121 [(set_attr "type" "other")
26122 (set_attr "length" "3")])
26123
26124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26125 ;;
26126 ;; FXSR, XSAVE and XSAVEOPT instructions
26127 ;;
26128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26129
26130 (define_insn "fxsave"
26131 [(set (match_operand:BLK 0 "memory_operand" "=m")
26132 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
26133 "TARGET_FXSR"
26134 "fxsave\t%0"
26135 [(set_attr "type" "other")
26136 (set_attr "memory" "store")
26137 (set (attr "length")
26138 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26139
26140 (define_insn "fxsave64"
26141 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26142 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
26143 "TARGET_64BIT && TARGET_FXSR"
26144 "fxsave64\t%0"
26145 [(set_attr "type" "other")
26146 (set_attr "addr" "gpr16")
26147 (set_attr "memory" "store")
26148 (set (attr "length")
26149 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26150
26151 (define_insn "fxrstor"
26152 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26153 UNSPECV_FXRSTOR)]
26154 "TARGET_FXSR"
26155 "fxrstor\t%0"
26156 [(set_attr "type" "other")
26157 (set_attr "memory" "load")
26158 (set (attr "length")
26159 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26160
26161 (define_insn "fxrstor64"
26162 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
26163 UNSPECV_FXRSTOR64)]
26164 "TARGET_64BIT && TARGET_FXSR"
26165 "fxrstor64\t%0"
26166 [(set_attr "type" "other")
26167 (set_attr "addr" "gpr16")
26168 (set_attr "memory" "load")
26169 (set (attr "length")
26170 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26171
26172 (define_int_iterator ANY_XSAVE
26173 [UNSPECV_XSAVE
26174 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
26175 (UNSPECV_XSAVEC "TARGET_XSAVEC")
26176 (UNSPECV_XSAVES "TARGET_XSAVES")])
26177
26178 (define_int_iterator ANY_XSAVE64
26179 [UNSPECV_XSAVE64
26180 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
26181 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
26182 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
26183
26184 (define_int_attr xsave
26185 [(UNSPECV_XSAVE "xsave")
26186 (UNSPECV_XSAVE64 "xsave64")
26187 (UNSPECV_XSAVEOPT "xsaveopt")
26188 (UNSPECV_XSAVEOPT64 "xsaveopt64")
26189 (UNSPECV_XSAVEC "xsavec")
26190 (UNSPECV_XSAVEC64 "xsavec64")
26191 (UNSPECV_XSAVES "xsaves")
26192 (UNSPECV_XSAVES64 "xsaves64")])
26193
26194 (define_int_iterator ANY_XRSTOR
26195 [UNSPECV_XRSTOR
26196 (UNSPECV_XRSTORS "TARGET_XSAVES")])
26197
26198 (define_int_iterator ANY_XRSTOR64
26199 [UNSPECV_XRSTOR64
26200 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
26201
26202 (define_int_attr xrstor
26203 [(UNSPECV_XRSTOR "xrstor")
26204 (UNSPECV_XRSTOR64 "xrstor")
26205 (UNSPECV_XRSTORS "xrstors")
26206 (UNSPECV_XRSTORS64 "xrstors")])
26207
26208 (define_insn "<xsave>"
26209 [(set (match_operand:BLK 0 "memory_operand" "=m")
26210 (unspec_volatile:BLK
26211 [(match_operand:DI 1 "register_operand" "A")]
26212 ANY_XSAVE))]
26213 "!TARGET_64BIT && TARGET_XSAVE"
26214 "<xsave>\t%0"
26215 [(set_attr "type" "other")
26216 (set_attr "memory" "store")
26217 (set (attr "length")
26218 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26219
26220 (define_insn "<xsave>_rex64"
26221 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26222 (unspec_volatile:BLK
26223 [(match_operand:SI 1 "register_operand" "a")
26224 (match_operand:SI 2 "register_operand" "d")]
26225 ANY_XSAVE))]
26226 "TARGET_64BIT && TARGET_XSAVE"
26227 "<xsave>\t%0"
26228 [(set_attr "type" "other")
26229 (set_attr "memory" "store")
26230 (set_attr "addr" "gpr16")
26231 (set (attr "length")
26232 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26233
26234 (define_insn "<xsave>"
26235 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26236 (unspec_volatile:BLK
26237 [(match_operand:SI 1 "register_operand" "a")
26238 (match_operand:SI 2 "register_operand" "d")]
26239 ANY_XSAVE64))]
26240 "TARGET_64BIT && TARGET_XSAVE"
26241 "<xsave>\t%0"
26242 [(set_attr "type" "other")
26243 (set_attr "memory" "store")
26244 (set_attr "addr" "gpr16")
26245 (set (attr "length")
26246 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26247
26248 (define_insn "<xrstor>"
26249 [(unspec_volatile:BLK
26250 [(match_operand:BLK 0 "memory_operand" "m")
26251 (match_operand:DI 1 "register_operand" "A")]
26252 ANY_XRSTOR)]
26253 "!TARGET_64BIT && TARGET_XSAVE"
26254 "<xrstor>\t%0"
26255 [(set_attr "type" "other")
26256 (set_attr "memory" "load")
26257 (set (attr "length")
26258 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26259
26260 (define_insn "<xrstor>_rex64"
26261 [(unspec_volatile:BLK
26262 [(match_operand:BLK 0 "memory_operand" "jm")
26263 (match_operand:SI 1 "register_operand" "a")
26264 (match_operand:SI 2 "register_operand" "d")]
26265 ANY_XRSTOR)]
26266 "TARGET_64BIT && TARGET_XSAVE"
26267 "<xrstor>\t%0"
26268 [(set_attr "type" "other")
26269 (set_attr "memory" "load")
26270 (set_attr "addr" "gpr16")
26271 (set (attr "length")
26272 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26273
26274 (define_insn "<xrstor>64"
26275 [(unspec_volatile:BLK
26276 [(match_operand:BLK 0 "memory_operand" "jm")
26277 (match_operand:SI 1 "register_operand" "a")
26278 (match_operand:SI 2 "register_operand" "d")]
26279 ANY_XRSTOR64)]
26280 "TARGET_64BIT && TARGET_XSAVE"
26281 "<xrstor>64\t%0"
26282 [(set_attr "type" "other")
26283 (set_attr "memory" "load")
26284 (set_attr "addr" "gpr16")
26285 (set (attr "length")
26286 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26287
26288 (define_insn "xsetbv"
26289 [(unspec_volatile:SI
26290 [(match_operand:SI 0 "register_operand" "c")
26291 (match_operand:DI 1 "register_operand" "A")]
26292 UNSPECV_XSETBV)]
26293 "!TARGET_64BIT && TARGET_XSAVE"
26294 "xsetbv"
26295 [(set_attr "type" "other")])
26296
26297 (define_insn "xsetbv_rex64"
26298 [(unspec_volatile:SI
26299 [(match_operand:SI 0 "register_operand" "c")
26300 (match_operand:SI 1 "register_operand" "a")
26301 (match_operand:SI 2 "register_operand" "d")]
26302 UNSPECV_XSETBV)]
26303 "TARGET_64BIT && TARGET_XSAVE"
26304 "xsetbv"
26305 [(set_attr "type" "other")])
26306
26307 (define_insn "xgetbv"
26308 [(set (match_operand:DI 0 "register_operand" "=A")
26309 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26310 UNSPECV_XGETBV))]
26311 "!TARGET_64BIT && TARGET_XSAVE"
26312 "xgetbv"
26313 [(set_attr "type" "other")])
26314
26315 (define_insn "xgetbv_rex64"
26316 [(set (match_operand:DI 0 "register_operand" "=a")
26317 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26318 UNSPECV_XGETBV))
26319 (set (match_operand:DI 1 "register_operand" "=d")
26320 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
26321 "TARGET_64BIT && TARGET_XSAVE"
26322 "xgetbv"
26323 [(set_attr "type" "other")])
26324
26325 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26326 ;;
26327 ;; Floating-point instructions for atomic compound assignments
26328 ;;
26329 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26330
26331 ; Clobber all floating-point registers on environment save and restore
26332 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
26333 (define_insn "fnstenv"
26334 [(set (match_operand:BLK 0 "memory_operand" "=m")
26335 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
26336 (clobber (reg:XF ST0_REG))
26337 (clobber (reg:XF ST1_REG))
26338 (clobber (reg:XF ST2_REG))
26339 (clobber (reg:XF ST3_REG))
26340 (clobber (reg:XF ST4_REG))
26341 (clobber (reg:XF ST5_REG))
26342 (clobber (reg:XF ST6_REG))
26343 (clobber (reg:XF ST7_REG))]
26344 "TARGET_80387"
26345 "fnstenv\t%0"
26346 [(set_attr "type" "other")
26347 (set_attr "memory" "store")
26348 (set (attr "length")
26349 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26350
26351 (define_insn "fldenv"
26352 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26353 UNSPECV_FLDENV)
26354 (clobber (reg:XF ST0_REG))
26355 (clobber (reg:XF ST1_REG))
26356 (clobber (reg:XF ST2_REG))
26357 (clobber (reg:XF ST3_REG))
26358 (clobber (reg:XF ST4_REG))
26359 (clobber (reg:XF ST5_REG))
26360 (clobber (reg:XF ST6_REG))
26361 (clobber (reg:XF ST7_REG))]
26362 "TARGET_80387"
26363 "fldenv\t%0"
26364 [(set_attr "type" "other")
26365 (set_attr "memory" "load")
26366 (set (attr "length")
26367 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26368
26369 (define_insn "fnstsw"
26370 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26371 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26372 "TARGET_80387"
26373 "fnstsw\t%0"
26374 [(set_attr "type" "other,other")
26375 (set_attr "memory" "none,store")
26376 (set (attr "length")
26377 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26378
26379 (define_insn "fnclex"
26380 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26381 "TARGET_80387"
26382 "fnclex"
26383 [(set_attr "type" "other")
26384 (set_attr "memory" "none")
26385 (set_attr "length" "2")])
26386
26387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26388 ;;
26389 ;; LWP instructions
26390 ;;
26391 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26392
26393 (define_insn "@lwp_llwpcb<mode>"
26394 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26395 UNSPECV_LLWP_INTRINSIC)]
26396 "TARGET_LWP"
26397 "llwpcb\t%0"
26398 [(set_attr "type" "lwp")
26399 (set_attr "mode" "<MODE>")
26400 (set_attr "length" "5")])
26401
26402 (define_insn "@lwp_slwpcb<mode>"
26403 [(set (match_operand:P 0 "register_operand" "=r")
26404 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26405 "TARGET_LWP"
26406 "slwpcb\t%0"
26407 [(set_attr "type" "lwp")
26408 (set_attr "mode" "<MODE>")
26409 (set_attr "length" "5")])
26410
26411 (define_insn "@lwp_lwpval<mode>"
26412 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26413 (match_operand:SI 1 "nonimmediate_operand" "rm")
26414 (match_operand:SI 2 "const_int_operand")]
26415 UNSPECV_LWPVAL_INTRINSIC)]
26416 "TARGET_LWP"
26417 "lwpval\t{%2, %1, %0|%0, %1, %2}"
26418 [(set_attr "type" "lwp")
26419 (set_attr "mode" "<MODE>")
26420 (set (attr "length")
26421 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26422
26423 (define_insn "@lwp_lwpins<mode>"
26424 [(set (reg:CCC FLAGS_REG)
26425 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26426 (match_operand:SI 1 "nonimmediate_operand" "rm")
26427 (match_operand:SI 2 "const_int_operand")]
26428 UNSPECV_LWPINS_INTRINSIC))]
26429 "TARGET_LWP"
26430 "lwpins\t{%2, %1, %0|%0, %1, %2}"
26431 [(set_attr "type" "lwp")
26432 (set_attr "mode" "<MODE>")
26433 (set (attr "length")
26434 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26435
26436 (define_int_iterator RDFSGSBASE
26437 [UNSPECV_RDFSBASE
26438 UNSPECV_RDGSBASE])
26439
26440 (define_int_iterator WRFSGSBASE
26441 [UNSPECV_WRFSBASE
26442 UNSPECV_WRGSBASE])
26443
26444 (define_int_attr fsgs
26445 [(UNSPECV_RDFSBASE "fs")
26446 (UNSPECV_RDGSBASE "gs")
26447 (UNSPECV_WRFSBASE "fs")
26448 (UNSPECV_WRGSBASE "gs")])
26449
26450 (define_insn "rd<fsgs>base<mode>"
26451 [(set (match_operand:SWI48 0 "register_operand" "=r")
26452 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26453 "TARGET_64BIT && TARGET_FSGSBASE"
26454 "rd<fsgs>base\t%0"
26455 [(set_attr "type" "other")
26456 (set_attr "prefix_0f" "1")
26457 (set_attr "prefix_rep" "1")])
26458
26459 (define_insn "wr<fsgs>base<mode>"
26460 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26461 WRFSGSBASE)]
26462 "TARGET_64BIT && TARGET_FSGSBASE"
26463 "wr<fsgs>base\t%0"
26464 [(set_attr "type" "other")
26465 (set_attr "prefix_0f" "1")
26466 (set_attr "prefix_rep" "1")])
26467
26468 (define_insn "ptwrite<mode>"
26469 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26470 UNSPECV_PTWRITE)]
26471 "TARGET_PTWRITE"
26472 "ptwrite\t%0"
26473 [(set_attr "type" "other")
26474 (set_attr "prefix_0f" "1")
26475 (set_attr "prefix_rep" "1")])
26476
26477 (define_insn "@rdrand<mode>"
26478 [(set (match_operand:SWI248 0 "register_operand" "=r")
26479 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26480 (set (reg:CCC FLAGS_REG)
26481 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26482 "TARGET_RDRND"
26483 "rdrand\t%0"
26484 [(set_attr "type" "other")
26485 (set_attr "prefix_0f" "1")])
26486
26487 (define_insn "@rdseed<mode>"
26488 [(set (match_operand:SWI248 0 "register_operand" "=r")
26489 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26490 (set (reg:CCC FLAGS_REG)
26491 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26492 "TARGET_RDSEED"
26493 "rdseed\t%0"
26494 [(set_attr "type" "other")
26495 (set_attr "prefix_0f" "1")])
26496
26497 (define_expand "pause"
26498 [(set (match_dup 0)
26499 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26500 ""
26501 {
26502 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26503 MEM_VOLATILE_P (operands[0]) = 1;
26504 })
26505
26506 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26507 ;; They have the same encoding.
26508 (define_insn "*pause"
26509 [(set (match_operand:BLK 0)
26510 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26511 ""
26512 "rep%; nop"
26513 [(set_attr "length" "2")
26514 (set_attr "memory" "unknown")])
26515
26516 ;; CET instructions
26517 (define_insn "@rdssp<mode>"
26518 [(set (match_operand:SWI48 0 "register_operand" "=r")
26519 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26520 UNSPECV_NOP_RDSSP))]
26521 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26522 "rdssp<mskmodesuffix>\t%0"
26523 [(set_attr "length" "6")
26524 (set_attr "type" "other")])
26525
26526 (define_insn "@incssp<mode>"
26527 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26528 UNSPECV_INCSSP)]
26529 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26530 "incssp<mskmodesuffix>\t%0"
26531 [(set_attr "length" "4")
26532 (set_attr "type" "other")])
26533
26534 (define_insn "saveprevssp"
26535 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26536 "TARGET_SHSTK"
26537 "saveprevssp"
26538 [(set_attr "length" "5")
26539 (set_attr "type" "other")])
26540
26541 (define_insn "rstorssp"
26542 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26543 UNSPECV_RSTORSSP)]
26544 "TARGET_SHSTK"
26545 "rstorssp\t%0"
26546 [(set_attr "length" "5")
26547 (set_attr "type" "other")])
26548
26549 (define_insn "@wrss<mode>"
26550 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26551 (match_operand:SWI48 1 "memory_operand" "m")]
26552 UNSPECV_WRSS)]
26553 "TARGET_SHSTK"
26554 "wrss<mskmodesuffix>\t%0, %1"
26555 [(set_attr "length" "3")
26556 (set_attr "type" "other")])
26557
26558 (define_insn "@wruss<mode>"
26559 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26560 (match_operand:SWI48 1 "memory_operand" "m")]
26561 UNSPECV_WRUSS)]
26562 "TARGET_SHSTK"
26563 "wruss<mskmodesuffix>\t%0, %1"
26564 [(set_attr "length" "4")
26565 (set_attr "type" "other")])
26566
26567 (define_insn "setssbsy"
26568 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26569 "TARGET_SHSTK"
26570 "setssbsy"
26571 [(set_attr "length" "4")
26572 (set_attr "type" "other")])
26573
26574 (define_insn "clrssbsy"
26575 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26576 UNSPECV_CLRSSBSY)]
26577 "TARGET_SHSTK"
26578 "clrssbsy\t%0"
26579 [(set_attr "length" "4")
26580 (set_attr "type" "other")])
26581
26582 (define_insn "nop_endbr"
26583 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26584 "(flag_cf_protection & CF_BRANCH)"
26585 {
26586 return TARGET_64BIT ? "endbr64" : "endbr32";
26587 }
26588 [(set_attr "length" "4")
26589 (set_attr "length_immediate" "0")
26590 (set_attr "modrm" "0")])
26591
26592 ;; For RTM support
26593 (define_expand "xbegin"
26594 [(set (match_operand:SI 0 "register_operand")
26595 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26596 "TARGET_RTM"
26597 {
26598 rtx_code_label *label = gen_label_rtx ();
26599
26600 /* xbegin is emitted as jump_insn, so reload won't be able
26601 to reload its operand. Force the value into AX hard register. */
26602 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26603 emit_move_insn (ax_reg, constm1_rtx);
26604
26605 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26606
26607 emit_label (label);
26608 LABEL_NUSES (label) = 1;
26609
26610 emit_move_insn (operands[0], ax_reg);
26611
26612 DONE;
26613 })
26614
26615 (define_insn "xbegin_1"
26616 [(set (pc)
26617 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26618 (const_int 0))
26619 (label_ref (match_operand 1))
26620 (pc)))
26621 (set (match_operand:SI 0 "register_operand" "+a")
26622 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26623 "TARGET_RTM"
26624 "xbegin\t%l1"
26625 [(set_attr "type" "other")
26626 (set_attr "length" "6")])
26627
26628 (define_insn "xend"
26629 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26630 "TARGET_RTM"
26631 "xend"
26632 [(set_attr "type" "other")
26633 (set_attr "length" "3")])
26634
26635 (define_insn "xabort"
26636 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26637 UNSPECV_XABORT)]
26638 "TARGET_RTM"
26639 "xabort\t%0"
26640 [(set_attr "type" "other")
26641 (set_attr "length" "3")])
26642
26643 (define_expand "xtest"
26644 [(set (match_operand:QI 0 "register_operand")
26645 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26646 "TARGET_RTM"
26647 {
26648 emit_insn (gen_xtest_1 ());
26649
26650 ix86_expand_setcc (operands[0], NE,
26651 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26652 DONE;
26653 })
26654
26655 (define_insn "xtest_1"
26656 [(set (reg:CCZ FLAGS_REG)
26657 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26658 "TARGET_RTM"
26659 "xtest"
26660 [(set_attr "type" "other")
26661 (set_attr "length" "3")])
26662
26663 (define_insn "clwb"
26664 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26665 UNSPECV_CLWB)]
26666 "TARGET_CLWB"
26667 "clwb\t%a0"
26668 [(set_attr "type" "sse")
26669 (set_attr "atom_sse_attr" "fence")
26670 (set_attr "memory" "unknown")])
26671
26672 (define_insn "clflushopt"
26673 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26674 UNSPECV_CLFLUSHOPT)]
26675 "TARGET_CLFLUSHOPT"
26676 "clflushopt\t%a0"
26677 [(set_attr "type" "sse")
26678 (set_attr "atom_sse_attr" "fence")
26679 (set_attr "memory" "unknown")])
26680
26681 ;; MONITORX and MWAITX
26682 (define_insn "mwaitx"
26683 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26684 (match_operand:SI 1 "register_operand" "a")
26685 (match_operand:SI 2 "register_operand" "b")]
26686 UNSPECV_MWAITX)]
26687 "TARGET_MWAITX"
26688 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26689 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26690 ;; we only need to set up 32bit registers.
26691 "mwaitx"
26692 [(set_attr "length" "3")])
26693
26694 (define_insn "@monitorx_<mode>"
26695 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26696 (match_operand:SI 1 "register_operand" "c")
26697 (match_operand:SI 2 "register_operand" "d")]
26698 UNSPECV_MONITORX)]
26699 "TARGET_MWAITX"
26700 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26701 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26702 ;; zero extended to 64bit, we only need to set up 32bit registers.
26703 "%^monitorx"
26704 [(set (attr "length")
26705 (symbol_ref ("(Pmode != word_mode) + 3")))])
26706
26707 ;; CLZERO
26708 (define_insn "@clzero_<mode>"
26709 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26710 UNSPECV_CLZERO)]
26711 "TARGET_CLZERO"
26712 "clzero"
26713 [(set_attr "length" "3")
26714 (set_attr "memory" "unknown")])
26715
26716 ;; RDPKRU and WRPKRU
26717
26718 (define_expand "rdpkru"
26719 [(parallel
26720 [(set (match_operand:SI 0 "register_operand")
26721 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26722 (set (match_dup 2) (const_int 0))])]
26723 "TARGET_PKU"
26724 {
26725 operands[1] = force_reg (SImode, const0_rtx);
26726 operands[2] = gen_reg_rtx (SImode);
26727 })
26728
26729 (define_insn "*rdpkru"
26730 [(set (match_operand:SI 0 "register_operand" "=a")
26731 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26732 UNSPECV_PKU))
26733 (set (match_operand:SI 1 "register_operand" "=d")
26734 (const_int 0))]
26735 "TARGET_PKU"
26736 "rdpkru"
26737 [(set_attr "type" "other")])
26738
26739 (define_expand "wrpkru"
26740 [(unspec_volatile:SI
26741 [(match_operand:SI 0 "register_operand")
26742 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26743 "TARGET_PKU"
26744 {
26745 operands[1] = force_reg (SImode, const0_rtx);
26746 operands[2] = force_reg (SImode, const0_rtx);
26747 })
26748
26749 (define_insn "*wrpkru"
26750 [(unspec_volatile:SI
26751 [(match_operand:SI 0 "register_operand" "a")
26752 (match_operand:SI 1 "register_operand" "d")
26753 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26754 "TARGET_PKU"
26755 "wrpkru"
26756 [(set_attr "type" "other")])
26757
26758 (define_insn "rdpid"
26759 [(set (match_operand:SI 0 "register_operand" "=r")
26760 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26761 "!TARGET_64BIT && TARGET_RDPID"
26762 "rdpid\t%0"
26763 [(set_attr "type" "other")])
26764
26765 (define_insn "rdpid_rex64"
26766 [(set (match_operand:DI 0 "register_operand" "=r")
26767 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26768 "TARGET_64BIT && TARGET_RDPID"
26769 "rdpid\t%0"
26770 [(set_attr "type" "other")])
26771
26772 ;; Intirinsics for > i486
26773
26774 (define_insn "wbinvd"
26775 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26776 ""
26777 "wbinvd"
26778 [(set_attr "type" "other")])
26779
26780 (define_insn "wbnoinvd"
26781 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26782 "TARGET_WBNOINVD"
26783 "wbnoinvd"
26784 [(set_attr "type" "other")])
26785
26786 ;; MOVDIRI and MOVDIR64B
26787
26788 (define_insn "movdiri<mode>"
26789 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26790 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26791 UNSPEC_MOVDIRI))]
26792 "TARGET_MOVDIRI"
26793 "movdiri\t{%1, %0|%0, %1}"
26794 [(set_attr "type" "other")])
26795
26796 (define_insn "@movdir64b_<mode>"
26797 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26798 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26799 UNSPEC_MOVDIR64B))]
26800 "TARGET_MOVDIR64B"
26801 "movdir64b\t{%1, %0|%0, %1}"
26802 [(set_attr "type" "other")])
26803
26804 ;; TSXLDTRK
26805 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26806 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26807 (UNSPECV_XRESLDTRK "xresldtrk")])
26808 (define_insn "<tsxldtrk>"
26809 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26810 "TARGET_TSXLDTRK"
26811 "<tsxldtrk>"
26812 [(set_attr "type" "other")
26813 (set_attr "length" "4")])
26814
26815 ;; ENQCMD and ENQCMDS
26816
26817 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26818 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26819
26820 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26821 [(set (reg:CCZ FLAGS_REG)
26822 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26823 (match_operand:XI 1 "memory_operand" "m")]
26824 ENQCMD))]
26825 "TARGET_ENQCMD"
26826 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26827 [(set_attr "type" "other")])
26828
26829 ;; UINTR
26830 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26831 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26832
26833 (define_insn "<uintr>"
26834 [(unspec_volatile [(const_int 0)] UINTR)]
26835 "TARGET_UINTR && TARGET_64BIT"
26836 "<uintr>"
26837 [(set_attr "type" "other")
26838 (set_attr "length" "4")])
26839
26840 (define_insn "testui"
26841 [(set (reg:CCC FLAGS_REG)
26842 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26843 "TARGET_UINTR && TARGET_64BIT"
26844 "testui"
26845 [(set_attr "type" "other")
26846 (set_attr "length" "4")])
26847
26848 (define_insn "senduipi"
26849 [(unspec_volatile
26850 [(match_operand:DI 0 "register_operand" "r")]
26851 UNSPECV_SENDUIPI)]
26852 "TARGET_UINTR && TARGET_64BIT"
26853 "senduipi\t%0"
26854 [(set_attr "type" "other")
26855 (set_attr "length" "4")])
26856
26857 ;; WAITPKG
26858
26859 (define_insn "umwait"
26860 [(set (reg:CCC FLAGS_REG)
26861 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26862 (match_operand:DI 1 "register_operand" "A")]
26863 UNSPECV_UMWAIT))]
26864 "!TARGET_64BIT && TARGET_WAITPKG"
26865 "umwait\t%0"
26866 [(set_attr "length" "3")])
26867
26868 (define_insn "umwait_rex64"
26869 [(set (reg:CCC FLAGS_REG)
26870 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26871 (match_operand:SI 1 "register_operand" "a")
26872 (match_operand:SI 2 "register_operand" "d")]
26873 UNSPECV_UMWAIT))]
26874 "TARGET_64BIT && TARGET_WAITPKG"
26875 "umwait\t%0"
26876 [(set_attr "length" "3")])
26877
26878 (define_insn "@umonitor_<mode>"
26879 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26880 UNSPECV_UMONITOR)]
26881 "TARGET_WAITPKG"
26882 "umonitor\t%0"
26883 [(set (attr "length")
26884 (symbol_ref ("(Pmode != word_mode) + 3")))])
26885
26886 (define_insn "tpause"
26887 [(set (reg:CCC FLAGS_REG)
26888 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26889 (match_operand:DI 1 "register_operand" "A")]
26890 UNSPECV_TPAUSE))]
26891 "!TARGET_64BIT && TARGET_WAITPKG"
26892 "tpause\t%0"
26893 [(set_attr "length" "3")])
26894
26895 (define_insn "tpause_rex64"
26896 [(set (reg:CCC FLAGS_REG)
26897 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26898 (match_operand:SI 1 "register_operand" "a")
26899 (match_operand:SI 2 "register_operand" "d")]
26900 UNSPECV_TPAUSE))]
26901 "TARGET_64BIT && TARGET_WAITPKG"
26902 "tpause\t%0"
26903 [(set_attr "length" "3")])
26904
26905 (define_insn "cldemote"
26906 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26907 UNSPECV_CLDEMOTE)]
26908 "TARGET_CLDEMOTE"
26909 "cldemote\t%a0"
26910 [(set_attr "type" "other")
26911 (set_attr "memory" "unknown")])
26912
26913 (define_insn "speculation_barrier"
26914 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26915 ""
26916 "lfence"
26917 [(set_attr "type" "other")
26918 (set_attr "length" "3")])
26919
26920 (define_insn "serialize"
26921 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26922 "TARGET_SERIALIZE"
26923 "serialize"
26924 [(set_attr "type" "other")
26925 (set_attr "length" "3")])
26926
26927 (define_insn "patchable_area"
26928 [(unspec_volatile [(match_operand 0 "const_int_operand")
26929 (match_operand 1 "const_int_operand")]
26930 UNSPECV_PATCHABLE_AREA)]
26931 ""
26932 {
26933 ix86_output_patchable_area (INTVAL (operands[0]),
26934 INTVAL (operands[1]) != 0);
26935 return "";
26936 }
26937 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26938 (set_attr "length_immediate" "0")
26939 (set_attr "modrm" "0")])
26940
26941 (define_insn "hreset"
26942 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26943 UNSPECV_HRESET)]
26944 "TARGET_HRESET"
26945 "hreset\t{$0|0}"
26946 [(set_attr "type" "other")
26947 (set_attr "length" "4")])
26948
26949 ;; Spaceship optimization
26950 (define_expand "spaceship<mode>3"
26951 [(match_operand:SI 0 "register_operand")
26952 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26953 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26954 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26955 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26956 {
26957 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26958 DONE;
26959 })
26960
26961 (define_expand "spaceshipxf3"
26962 [(match_operand:SI 0 "register_operand")
26963 (match_operand:XF 1 "nonmemory_operand")
26964 (match_operand:XF 2 "nonmemory_operand")]
26965 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26966 {
26967 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26968 DONE;
26969 })
26970
26971 ;; Defined because the generic expand_builtin_issignaling for XFmode
26972 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26973 ;; signaling.
26974 (define_expand "issignalingxf2"
26975 [(match_operand:SI 0 "register_operand")
26976 (match_operand:XF 1 "general_operand")]
26977 ""
26978 {
26979 rtx temp = operands[1];
26980 if (!MEM_P (temp))
26981 {
26982 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26983 emit_move_insn (mem, temp);
26984 temp = mem;
26985 }
26986 rtx ex = adjust_address (temp, HImode, 8);
26987 rtx hi = adjust_address (temp, SImode, 4);
26988 rtx lo = adjust_address (temp, SImode, 0);
26989 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26990 rtx mask = GEN_INT (0x7fff);
26991 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26992 /* Expand to:
26993 ((ex & mask) && (int) hi >= 0)
26994 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26995 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26996 lo = expand_binop (SImode, ior_optab, lo, nlo,
26997 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26998 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26999 temp = expand_binop (SImode, xor_optab, hi, bit,
27000 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27001 temp = expand_binop (SImode, ior_optab, temp, lo,
27002 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27003 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
27004 SImode, 1, 1);
27005 ex = expand_binop (HImode, and_optab, ex, mask,
27006 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27007 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
27008 ex, const0_rtx, SImode, 1, 1);
27009 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
27010 ex, mask, HImode, 1, 1);
27011 temp = expand_binop (SImode, and_optab, temp, ex,
27012 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27013 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
27014 hi, const0_rtx, SImode, 0, 1);
27015 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
27016 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27017 temp = expand_binop (SImode, ior_optab, temp, temp2,
27018 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27019 emit_move_insn (operands[0], temp);
27020 DONE;
27021 })
27022
27023 (define_insn "urdmsr"
27024 [(set (match_operand:DI 0 "register_operand" "=r")
27025 (unspec_volatile:DI
27026 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
27027 UNSPECV_URDMSR))]
27028 "TARGET_USER_MSR && TARGET_64BIT"
27029 "urdmsr\t{%1, %0|%0, %1}"
27030 [(set_attr "prefix" "vex")
27031 (set_attr "type" "other")])
27032
27033 (define_insn "uwrmsr"
27034 [(unspec_volatile
27035 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
27036 (match_operand:DI 1 "register_operand" "r")]
27037 UNSPECV_UWRMSR)]
27038 "TARGET_USER_MSR && TARGET_64BIT"
27039 "uwrmsr\t{%1, %0|%0, %1}"
27040 [(set_attr "prefix" "vex")
27041 (set_attr "type" "other")])
27042
27043 (include "mmx.md")
27044 (include "sse.md")
27045 (include "sync.md")