]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
i386: Improve stack protector patterns and peephole2s
[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
119 ;; For SSE/MMX support:
120 UNSPEC_FIX_NOTRUNC
121 UNSPEC_MASKMOV
122 UNSPEC_MOVCC_MASK
123 UNSPEC_MOVMSK
124 UNSPEC_INSERTPS
125 UNSPEC_BLENDV
126 UNSPEC_PSHUFB
127 UNSPEC_XOP_PERMUTE
128 UNSPEC_RCP
129 UNSPEC_RSQRT
130 UNSPEC_PSADBW
131
132 ;; Different from generic us_truncate RTX
133 ;; as it does unsigned saturation of signed source.
134 UNSPEC_US_TRUNCATE
135
136 ;; For AVX/AVX512F support
137 UNSPEC_SCALEF
138 UNSPEC_PCMP
139 UNSPEC_CVTBFSF
140
141 ;; Generic math support
142 UNSPEC_IEEE_MIN ; not commutative
143 UNSPEC_IEEE_MAX ; not commutative
144
145 ;; x87 Floating point
146 UNSPEC_SIN
147 UNSPEC_COS
148 UNSPEC_FPATAN
149 UNSPEC_FYL2X
150 UNSPEC_FYL2XP1
151 UNSPEC_FRNDINT
152 UNSPEC_FIST
153 UNSPEC_F2XM1
154 UNSPEC_TAN
155 UNSPEC_FXAM
156
157 ;; x87 Rounding
158 UNSPEC_FRNDINT_ROUNDEVEN
159 UNSPEC_FRNDINT_FLOOR
160 UNSPEC_FRNDINT_CEIL
161 UNSPEC_FRNDINT_TRUNC
162 UNSPEC_FIST_FLOOR
163 UNSPEC_FIST_CEIL
164
165 ;; x87 Double output FP
166 UNSPEC_SINCOS_COS
167 UNSPEC_SINCOS_SIN
168 UNSPEC_XTRACT_FRACT
169 UNSPEC_XTRACT_EXP
170 UNSPEC_FSCALE_FRACT
171 UNSPEC_FSCALE_EXP
172 UNSPEC_FPREM_F
173 UNSPEC_FPREM_U
174 UNSPEC_FPREM1_F
175 UNSPEC_FPREM1_U
176
177 UNSPEC_C2_FLAG
178 UNSPEC_FXAM_MEM
179
180 ;; SSP patterns
181 UNSPEC_SP_SET
182 UNSPEC_SP_TEST
183
184 ;; For ROUND support
185 UNSPEC_ROUND
186
187 ;; For CRC32 support
188 UNSPEC_CRC32
189
190 ;; For LZCNT suppoprt
191 UNSPEC_LZCNT
192
193 ;; For BMI support
194 UNSPEC_TZCNT
195 UNSPEC_BEXTR
196
197 ;; For BMI2 support
198 UNSPEC_PDEP
199 UNSPEC_PEXT
200
201 ;; IRET support
202 UNSPEC_INTERRUPT_RETURN
203
204 ;; For MOVDIRI and MOVDIR64B support
205 UNSPEC_MOVDIRI
206 UNSPEC_MOVDIR64B
207
208 ;; For insn_callee_abi:
209 UNSPEC_CALLEE_ABI
210
211 ;; For PUSH2/POP2 support
212 UNSPEC_APXPUSH2
213 UNSPEC_APXPOP2_LOW
214 UNSPEC_APXPOP2_HIGH
215 ])
216
217 (define_c_enum "unspecv" [
218 UNSPECV_UD2
219 UNSPECV_BLOCKAGE
220 UNSPECV_STACK_PROBE
221 UNSPECV_PROBE_STACK_RANGE
222 UNSPECV_ALIGN
223 UNSPECV_PROLOGUE_USE
224 UNSPECV_SPLIT_STACK_RETURN
225 UNSPECV_CLD
226 UNSPECV_NOPS
227 UNSPECV_RDTSC
228 UNSPECV_RDTSCP
229 UNSPECV_RDPMC
230 UNSPECV_LLWP_INTRINSIC
231 UNSPECV_SLWP_INTRINSIC
232 UNSPECV_LWPVAL_INTRINSIC
233 UNSPECV_LWPINS_INTRINSIC
234 UNSPECV_RDFSBASE
235 UNSPECV_RDGSBASE
236 UNSPECV_WRFSBASE
237 UNSPECV_WRGSBASE
238 UNSPECV_FXSAVE
239 UNSPECV_FXRSTOR
240 UNSPECV_FXSAVE64
241 UNSPECV_FXRSTOR64
242 UNSPECV_XSAVE
243 UNSPECV_XRSTOR
244 UNSPECV_XSAVE64
245 UNSPECV_XRSTOR64
246 UNSPECV_XSAVEOPT
247 UNSPECV_XSAVEOPT64
248 UNSPECV_XSAVES
249 UNSPECV_XRSTORS
250 UNSPECV_XSAVES64
251 UNSPECV_XRSTORS64
252 UNSPECV_XSAVEC
253 UNSPECV_XSAVEC64
254 UNSPECV_XGETBV
255 UNSPECV_XSETBV
256 UNSPECV_WBINVD
257 UNSPECV_WBNOINVD
258
259 ;; For atomic compound assignments.
260 UNSPECV_FNSTENV
261 UNSPECV_FLDENV
262 UNSPECV_FNSTSW
263 UNSPECV_FNCLEX
264
265 ;; For RDRAND support
266 UNSPECV_RDRAND
267
268 ;; For RDSEED support
269 UNSPECV_RDSEED
270
271 ;; For RTM support
272 UNSPECV_XBEGIN
273 UNSPECV_XEND
274 UNSPECV_XABORT
275 UNSPECV_XTEST
276
277 UNSPECV_NLGR
278
279 ;; For CLWB support
280 UNSPECV_CLWB
281
282 ;; For CLFLUSHOPT support
283 UNSPECV_CLFLUSHOPT
284
285 ;; For MONITORX and MWAITX support
286 UNSPECV_MONITORX
287 UNSPECV_MWAITX
288
289 ;; For CLZERO support
290 UNSPECV_CLZERO
291
292 ;; For RDPKRU and WRPKRU support
293 UNSPECV_PKU
294
295 ;; For RDPID support
296 UNSPECV_RDPID
297
298 ;; For CET support
299 UNSPECV_NOP_ENDBR
300 UNSPECV_NOP_RDSSP
301 UNSPECV_INCSSP
302 UNSPECV_SAVEPREVSSP
303 UNSPECV_RSTORSSP
304 UNSPECV_WRSS
305 UNSPECV_WRUSS
306 UNSPECV_SETSSBSY
307 UNSPECV_CLRSSBSY
308
309 ;; For TSXLDTRK support
310 UNSPECV_XSUSLDTRK
311 UNSPECV_XRESLDTRK
312
313 ;; For WAITPKG support
314 UNSPECV_UMWAIT
315 UNSPECV_UMONITOR
316 UNSPECV_TPAUSE
317
318 ;; For UINTR support
319 UNSPECV_CLUI
320 UNSPECV_STUI
321 UNSPECV_TESTUI
322 UNSPECV_SENDUIPI
323
324 ;; For CLDEMOTE support
325 UNSPECV_CLDEMOTE
326
327 ;; For Speculation Barrier support
328 UNSPECV_SPECULATION_BARRIER
329
330 UNSPECV_PTWRITE
331
332 ;; For ENQCMD and ENQCMDS support
333 UNSPECV_ENQCMD
334 UNSPECV_ENQCMDS
335
336 ;; For SERIALIZE support
337 UNSPECV_SERIALIZE
338
339 ;; For patchable area support
340 UNSPECV_PATCHABLE_AREA
341
342 ;; For HRESET support
343 UNSPECV_HRESET
344
345 ;; For PREFETCHI support
346 UNSPECV_PREFETCHI
347
348 ;; For USER_MSR support
349 UNSPECV_URDMSR
350 UNSPECV_UWRMSR
351 ])
352
353 ;; Constants to represent rounding modes in the ROUND instruction
354 (define_constants
355 [(ROUND_ROUNDEVEN 0x0)
356 (ROUND_FLOOR 0x1)
357 (ROUND_CEIL 0x2)
358 (ROUND_TRUNC 0x3)
359 (ROUND_MXCSR 0x4)
360 (ROUND_NO_EXC 0x8)
361 ])
362
363 ;; Constants to represent AVX512F embeded rounding
364 (define_constants
365 [(ROUND_NEAREST_INT 0)
366 (ROUND_NEG_INF 1)
367 (ROUND_POS_INF 2)
368 (ROUND_ZERO 3)
369 (NO_ROUND 4)
370 (ROUND_SAE 8)
371 ])
372
373 ;; Constants to represent pcomtrue/pcomfalse variants
374 (define_constants
375 [(PCOM_FALSE 0)
376 (PCOM_TRUE 1)
377 (COM_FALSE_S 2)
378 (COM_FALSE_P 3)
379 (COM_TRUE_S 4)
380 (COM_TRUE_P 5)
381 ])
382
383 ;; Constants used in the XOP pperm instruction
384 (define_constants
385 [(PPERM_SRC 0x00) /* copy source */
386 (PPERM_INVERT 0x20) /* invert source */
387 (PPERM_REVERSE 0x40) /* bit reverse source */
388 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
389 (PPERM_ZERO 0x80) /* all 0's */
390 (PPERM_ONES 0xa0) /* all 1's */
391 (PPERM_SIGN 0xc0) /* propagate sign bit */
392 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
393 (PPERM_SRC1 0x00) /* use first source byte */
394 (PPERM_SRC2 0x10) /* use second source byte */
395 ])
396
397 ;; Registers by name.
398 (define_constants
399 [(AX_REG 0)
400 (DX_REG 1)
401 (CX_REG 2)
402 (BX_REG 3)
403 (SI_REG 4)
404 (DI_REG 5)
405 (BP_REG 6)
406 (SP_REG 7)
407 (ST0_REG 8)
408 (ST1_REG 9)
409 (ST2_REG 10)
410 (ST3_REG 11)
411 (ST4_REG 12)
412 (ST5_REG 13)
413 (ST6_REG 14)
414 (ST7_REG 15)
415 (ARGP_REG 16)
416 (FLAGS_REG 17)
417 (FPSR_REG 18)
418 (FRAME_REG 19)
419 (XMM0_REG 20)
420 (XMM1_REG 21)
421 (XMM2_REG 22)
422 (XMM3_REG 23)
423 (XMM4_REG 24)
424 (XMM5_REG 25)
425 (XMM6_REG 26)
426 (XMM7_REG 27)
427 (MM0_REG 28)
428 (MM1_REG 29)
429 (MM2_REG 30)
430 (MM3_REG 31)
431 (MM4_REG 32)
432 (MM5_REG 33)
433 (MM6_REG 34)
434 (MM7_REG 35)
435 (R8_REG 36)
436 (R9_REG 37)
437 (R10_REG 38)
438 (R11_REG 39)
439 (R12_REG 40)
440 (R13_REG 41)
441 (R14_REG 42)
442 (R15_REG 43)
443 (XMM8_REG 44)
444 (XMM9_REG 45)
445 (XMM10_REG 46)
446 (XMM11_REG 47)
447 (XMM12_REG 48)
448 (XMM13_REG 49)
449 (XMM14_REG 50)
450 (XMM15_REG 51)
451 (XMM16_REG 52)
452 (XMM17_REG 53)
453 (XMM18_REG 54)
454 (XMM19_REG 55)
455 (XMM20_REG 56)
456 (XMM21_REG 57)
457 (XMM22_REG 58)
458 (XMM23_REG 59)
459 (XMM24_REG 60)
460 (XMM25_REG 61)
461 (XMM26_REG 62)
462 (XMM27_REG 63)
463 (XMM28_REG 64)
464 (XMM29_REG 65)
465 (XMM30_REG 66)
466 (XMM31_REG 67)
467 (MASK0_REG 68)
468 (MASK1_REG 69)
469 (MASK2_REG 70)
470 (MASK3_REG 71)
471 (MASK4_REG 72)
472 (MASK5_REG 73)
473 (MASK6_REG 74)
474 (MASK7_REG 75)
475 (R16_REG 76)
476 (R17_REG 77)
477 (R18_REG 78)
478 (R19_REG 79)
479 (R20_REG 80)
480 (R21_REG 81)
481 (R22_REG 82)
482 (R23_REG 83)
483 (R24_REG 84)
484 (R25_REG 85)
485 (R26_REG 86)
486 (R27_REG 87)
487 (R28_REG 88)
488 (R29_REG 89)
489 (R30_REG 90)
490 (R31_REG 91)
491 (FIRST_PSEUDO_REG 92)
492 ])
493
494 ;; Insn callee abi index.
495 (define_constants
496 [(ABI_DEFAULT 0)
497 (ABI_VZEROUPPER 1)
498 (ABI_UNKNOWN 2)])
499
500 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
501 ;; from i386.cc.
502
503 ;; In C guard expressions, put expressions which may be compile-time
504 ;; constants first. This allows for better optimization. For
505 ;; example, write "TARGET_64BIT && reload_completed", not
506 ;; "reload_completed && TARGET_64BIT".
507
508 \f
509 ;; Processor type.
510 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
511 atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
512 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
513 (const (symbol_ref "ix86_schedule")))
514
515 ;; A basic instruction type. Refinements due to arguments to be
516 ;; provided in other attributes.
517 (define_attr "type"
518 "other,multi,
519 alu,alu1,negnot,imov,imovx,lea,
520 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
521 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
522 push,pop,call,callv,leave,
523 str,bitmanip,
524 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
525 fxch,fistp,fisttp,frndint,
526 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
527 ssemul,sseimul,ssediv,sselog,sselog1,
528 sseishft,sseishft1,ssecmp,ssecomi,
529 ssecvt,ssecvt1,sseicvt,sseins,
530 sseshuf,sseshuf1,ssemuladd,sse4arg,
531 lwp,mskmov,msklog,
532 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
533 (const_string "other"))
534
535 ;; Main data type used by the insn
536 (define_attr "mode"
537 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
538 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
539 (const_string "unknown"))
540
541 ;; The CPU unit operations uses.
542 (define_attr "unit" "integer,i387,sse,mmx,unknown"
543 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
544 fxch,fistp,fisttp,frndint")
545 (const_string "i387")
546 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
547 ssemul,sseimul,ssediv,sselog,sselog1,
548 sseishft,sseishft1,ssecmp,ssecomi,
549 ssecvt,ssecvt1,sseicvt,sseins,
550 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
551 (const_string "sse")
552 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
553 (const_string "mmx")
554 (eq_attr "type" "other")
555 (const_string "unknown")]
556 (const_string "integer")))
557
558 ;; Used to control the "enabled" attribute on a per-instruction basis.
559 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
560 x64_avx,x64_avx512bw,x64_avx512dq,aes,
561 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
562 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
563 noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
564 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
565 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
566 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
567 (const_string "base"))
568
569 ;; The (bounding maximum) length of an instruction immediate.
570 (define_attr "length_immediate" ""
571 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
572 bitmanip,imulx,msklog,mskmov")
573 (const_int 0)
574 (ior (eq_attr "type" "sse4arg")
575 (eq_attr "isa" "fma4"))
576 (const_int 1)
577 (eq_attr "unit" "i387,sse,mmx")
578 (const_int 0)
579 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
580 rotate,rotatex,rotate1,imul,icmp,push,pop")
581 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
582 (eq_attr "type" "imov,test")
583 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
584 (eq_attr "type" "call")
585 (if_then_else (match_operand 0 "constant_call_address_operand")
586 (const_int 4)
587 (const_int 0))
588 (eq_attr "type" "callv")
589 (if_then_else (match_operand 1 "constant_call_address_operand")
590 (const_int 4)
591 (const_int 0))
592 ;; We don't know the size before shorten_branches. Expect
593 ;; the instruction to fit for better scheduling.
594 (eq_attr "type" "ibr")
595 (const_int 1)
596 ]
597 (symbol_ref "/* Update immediate_length and other attributes! */
598 gcc_unreachable (),1")))
599
600 ;; The (bounding maximum) length of an instruction address.
601 (define_attr "length_address" ""
602 (cond [(eq_attr "type" "str,other,multi,fxch")
603 (const_int 0)
604 (and (eq_attr "type" "call")
605 (match_operand 0 "constant_call_address_operand"))
606 (const_int 0)
607 (and (eq_attr "type" "callv")
608 (match_operand 1 "constant_call_address_operand"))
609 (const_int 0)
610 ]
611 (symbol_ref "ix86_attr_length_address_default (insn)")))
612
613 ;; Set when length prefix is used.
614 (define_attr "prefix_data16" ""
615 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
616 (const_int 0)
617 (eq_attr "mode" "HI")
618 (const_int 1)
619 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
620 (const_int 1)
621 ]
622 (const_int 0)))
623
624 ;; Set when string REP prefix is used.
625 (define_attr "prefix_rep" ""
626 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
627 (const_int 0)
628 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
629 (const_int 1)
630 ]
631 (const_int 0)))
632
633 ;; Set when 0f opcode prefix is used.
634 (define_attr "prefix_0f" ""
635 (if_then_else
636 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
637 (eq_attr "unit" "sse,mmx"))
638 (const_int 1)
639 (const_int 0)))
640
641 ;; Set when REX opcode prefix is used.
642 (define_attr "prefix_rex" ""
643 (cond [(not (match_test "TARGET_64BIT"))
644 (const_int 0)
645 (and (eq_attr "mode" "DI")
646 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
647 (eq_attr "unit" "!mmx")))
648 (const_int 1)
649 (and (eq_attr "mode" "QI")
650 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
651 (const_int 1)
652 (match_test "x86_extended_reg_mentioned_p (insn)")
653 (const_int 1)
654 (and (eq_attr "type" "imovx")
655 (match_operand:QI 1 "ext_QIreg_operand"))
656 (const_int 1)
657 ]
658 (const_int 0)))
659
660 ;; There are also additional prefixes in 3DNOW, SSSE3.
661 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
662 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
663 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
664 (define_attr "prefix_extra" ""
665 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
666 (const_int 1)
667 ]
668 (const_int 0)))
669
670 ;; Prefix used: original, VEX or maybe VEX.
671 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
672 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
673 (const_string "vex")
674 (eq_attr "mode" "XI,V16SF,V8DF")
675 (const_string "evex")
676 (eq_attr "type" "ssemuladd")
677 (if_then_else (eq_attr "isa" "fma4")
678 (const_string "vex")
679 (const_string "maybe_evex"))
680 (eq_attr "type" "sse4arg")
681 (const_string "vex")
682 ]
683 (const_string "orig")))
684
685 ;; VEX W bit is used.
686 (define_attr "prefix_vex_w" "" (const_int 0))
687
688 ;; The length of VEX prefix
689 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
690 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
691 ;; still prefix_0f 1, with prefix_extra 1.
692 (define_attr "length_vex" ""
693 (if_then_else (and (eq_attr "prefix_0f" "1")
694 (eq_attr "prefix_extra" "0"))
695 (if_then_else (eq_attr "prefix_vex_w" "1")
696 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
697 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
698 (if_then_else (eq_attr "prefix_vex_w" "1")
699 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
700 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
701
702 ;; 4-bytes evex prefix and 1 byte opcode.
703 (define_attr "length_evex" "" (const_int 5))
704
705 ;; Set when modrm byte is used.
706 (define_attr "modrm" ""
707 (cond [(eq_attr "type" "str,leave")
708 (const_int 0)
709 (eq_attr "unit" "i387")
710 (const_int 0)
711 (and (eq_attr "type" "incdec")
712 (and (not (match_test "TARGET_64BIT"))
713 (ior (match_operand:SI 1 "register_operand")
714 (match_operand:HI 1 "register_operand"))))
715 (const_int 0)
716 (and (eq_attr "type" "push")
717 (not (match_operand 1 "memory_operand")))
718 (const_int 0)
719 (and (eq_attr "type" "pop")
720 (not (match_operand 0 "memory_operand")))
721 (const_int 0)
722 (and (eq_attr "type" "imov")
723 (and (not (eq_attr "mode" "DI"))
724 (ior (and (match_operand 0 "register_operand")
725 (match_operand 1 "immediate_operand"))
726 (ior (and (match_operand 0 "ax_reg_operand")
727 (match_operand 1 "memory_displacement_only_operand"))
728 (and (match_operand 0 "memory_displacement_only_operand")
729 (match_operand 1 "ax_reg_operand"))))))
730 (const_int 0)
731 (and (eq_attr "type" "call")
732 (match_operand 0 "constant_call_address_operand"))
733 (const_int 0)
734 (and (eq_attr "type" "callv")
735 (match_operand 1 "constant_call_address_operand"))
736 (const_int 0)
737 (and (eq_attr "type" "alu,alu1,icmp,test")
738 (match_operand 0 "ax_reg_operand"))
739 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
740 ]
741 (const_int 1)))
742
743 ;; The (bounding maximum) length of an instruction in bytes.
744 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
745 ;; Later we may want to split them and compute proper length as for
746 ;; other insns.
747 (define_attr "length" ""
748 (cond [(eq_attr "type" "other,multi,fistp,frndint")
749 (const_int 16)
750 (eq_attr "type" "fcmp")
751 (const_int 4)
752 (eq_attr "unit" "i387")
753 (plus (const_int 2)
754 (plus (attr "prefix_data16")
755 (attr "length_address")))
756 (ior (eq_attr "prefix" "evex")
757 (and (ior (eq_attr "prefix" "maybe_evex")
758 (eq_attr "prefix" "maybe_vex"))
759 (match_test "TARGET_AVX512F")))
760 (plus (attr "length_evex")
761 (plus (attr "length_immediate")
762 (plus (attr "modrm")
763 (attr "length_address"))))
764 (ior (eq_attr "prefix" "vex")
765 (and (ior (eq_attr "prefix" "maybe_vex")
766 (eq_attr "prefix" "maybe_evex"))
767 (match_test "TARGET_AVX")))
768 (plus (attr "length_vex")
769 (plus (attr "length_immediate")
770 (plus (attr "modrm")
771 (attr "length_address"))))]
772 (plus (plus (attr "modrm")
773 (plus (attr "prefix_0f")
774 (plus (attr "prefix_rex")
775 (plus (attr "prefix_extra")
776 (const_int 1)))))
777 (plus (attr "prefix_rep")
778 (plus (attr "prefix_data16")
779 (plus (attr "length_immediate")
780 (attr "length_address")))))))
781
782 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
783 ;; `store' if there is a simple memory reference therein, or `unknown'
784 ;; if the instruction is complex.
785
786 (define_attr "memory" "none,load,store,both,unknown"
787 (cond [(eq_attr "type" "other,multi,str,lwp")
788 (const_string "unknown")
789 (eq_attr "type" "lea,fcmov,fpspc")
790 (const_string "none")
791 (eq_attr "type" "fistp,leave")
792 (const_string "both")
793 (eq_attr "type" "frndint")
794 (const_string "load")
795 (eq_attr "type" "push")
796 (if_then_else (match_operand 1 "memory_operand")
797 (const_string "both")
798 (const_string "store"))
799 (eq_attr "type" "pop")
800 (if_then_else (match_operand 0 "memory_operand")
801 (const_string "both")
802 (const_string "load"))
803 (eq_attr "type" "setcc")
804 (if_then_else (match_operand 0 "memory_operand")
805 (const_string "store")
806 (const_string "none"))
807 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
808 (if_then_else (ior (match_operand 0 "memory_operand")
809 (match_operand 1 "memory_operand"))
810 (const_string "load")
811 (const_string "none"))
812 (eq_attr "type" "ibr")
813 (if_then_else (match_operand 0 "memory_operand")
814 (const_string "load")
815 (const_string "none"))
816 (eq_attr "type" "call")
817 (if_then_else (match_operand 0 "constant_call_address_operand")
818 (const_string "none")
819 (const_string "load"))
820 (eq_attr "type" "callv")
821 (if_then_else (match_operand 1 "constant_call_address_operand")
822 (const_string "none")
823 (const_string "load"))
824 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
825 (match_operand 1 "memory_operand"))
826 (const_string "both")
827 (and (match_operand 0 "memory_operand")
828 (match_operand 1 "memory_operand"))
829 (const_string "both")
830 (match_operand 0 "memory_operand")
831 (const_string "store")
832 (match_operand 1 "memory_operand")
833 (const_string "load")
834 (and (eq_attr "type"
835 "!alu1,negnot,ishift1,rotate1,
836 imov,imovx,icmp,test,bitmanip,
837 fmov,fcmp,fsgn,
838 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
839 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
840 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
841 (match_operand 2 "memory_operand"))
842 (const_string "load")
843 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
844 (match_operand 3 "memory_operand"))
845 (const_string "load")
846 ]
847 (const_string "none")))
848
849 ;; Indicates if an instruction has both an immediate and a displacement.
850
851 (define_attr "imm_disp" "false,true,unknown"
852 (cond [(eq_attr "type" "other,multi")
853 (const_string "unknown")
854 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
855 (and (match_operand 0 "memory_displacement_operand")
856 (match_operand 1 "immediate_operand")))
857 (const_string "true")
858 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
859 (and (match_operand 0 "memory_displacement_operand")
860 (match_operand 2 "immediate_operand")))
861 (const_string "true")
862 ]
863 (const_string "false")))
864
865 ;; Indicates if an FP operation has an integer source.
866
867 (define_attr "fp_int_src" "false,true"
868 (const_string "false"))
869
870 ;; Defines rounding mode of an FP operation.
871
872 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
873 (const_string "any"))
874
875 ;; Define attribute to indicate AVX insns with partial XMM register update.
876 (define_attr "avx_partial_xmm_update" "false,true"
877 (const_string "false"))
878
879 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
880 (define_attr "use_carry" "0,1" (const_string "0"))
881
882 ;; Define attribute to indicate unaligned ssemov insns
883 (define_attr "movu" "0,1" (const_string "0"))
884
885 ;; Define attribute to indicate gpr32 insns.
886 (define_attr "gpr32" "0, 1" (const_string "1"))
887
888 ;; Define instruction set of MMX instructions
889 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
890 (const_string "base"))
891
892 (define_attr "enabled" ""
893 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
894 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
895 (eq_attr "isa" "x64_sse2")
896 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
897 (eq_attr "isa" "x64_sse4")
898 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
899 (eq_attr "isa" "x64_sse4_noavx")
900 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
901 (eq_attr "isa" "x64_avx")
902 (symbol_ref "TARGET_64BIT && TARGET_AVX")
903 (eq_attr "isa" "x64_avx512bw")
904 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
905 (eq_attr "isa" "x64_avx512dq")
906 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
907 (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
908 (eq_attr "isa" "sse_noavx")
909 (symbol_ref "TARGET_SSE && !TARGET_AVX")
910 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
911 (eq_attr "isa" "sse2_noavx")
912 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
913 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
914 (eq_attr "isa" "sse3_noavx")
915 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
916 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
917 (eq_attr "isa" "sse4_noavx")
918 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
919 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
920 (eq_attr "isa" "avx_noavx512f")
921 (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
922 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
923 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
924 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
925 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
926 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
927 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
928 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
929 (eq_attr "isa" "fma_or_avx512vl")
930 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
931 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
932 (eq_attr "isa" "avx512f_512")
933 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
934 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
935 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
936 (eq_attr "isa" "avx512bw_512")
937 (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
938 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
939 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
940 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
941 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
942 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
943 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
944 (eq_attr "isa" "avx512vnnivl")
945 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
946 (eq_attr "isa" "avx512fp16")
947 (symbol_ref "TARGET_AVX512FP16")
948 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
949 (eq_attr "isa" "avx512ifmavl")
950 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
951 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
952 (eq_attr "isa" "avx512bf16vl")
953 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
954 (eq_attr "isa" "vpclmulqdqvl")
955 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
956
957 (eq_attr "mmx_isa" "native")
958 (symbol_ref "!TARGET_MMX_WITH_SSE")
959 (eq_attr "mmx_isa" "sse")
960 (symbol_ref "TARGET_MMX_WITH_SSE")
961 (eq_attr "mmx_isa" "sse_noavx")
962 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
963 (eq_attr "mmx_isa" "avx")
964 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
965 ]
966 (const_int 1)))
967
968 (define_attr "preferred_for_size" "" (const_int 1))
969 (define_attr "preferred_for_speed" "" (const_int 1))
970
971 ;; Describe a user's asm statement.
972 (define_asm_attributes
973 [(set_attr "length" "128")
974 (set_attr "type" "multi")])
975
976 (define_code_iterator plusminus [plus minus])
977 (define_code_iterator plusminusmult [plus minus mult])
978 (define_code_iterator plusminusmultdiv [plus minus mult div])
979
980 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
981
982 ;; Base name for insn mnemonic.
983 (define_code_attr plusminus_mnemonic
984 [(plus "add") (ss_plus "adds") (us_plus "addus")
985 (minus "sub") (ss_minus "subs") (us_minus "subus")])
986
987 (define_code_iterator multdiv [mult div])
988
989 (define_code_attr multdiv_mnemonic
990 [(mult "mul") (div "div")])
991
992 ;; Mark commutative operators as such in constraints.
993 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
994 (minus "") (ss_minus "") (us_minus "")
995 (mult "%") (div "")])
996
997 ;; Mapping of max and min
998 (define_code_iterator maxmin [smax smin umax umin])
999
1000 ;; Mapping of signed max and min
1001 (define_code_iterator smaxmin [smax smin])
1002
1003 ;; Mapping of unsigned max and min
1004 (define_code_iterator umaxmin [umax umin])
1005
1006 ;; Base name for integer and FP insn mnemonic
1007 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1008 (umax "maxu") (umin "minu")])
1009 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1010
1011 (define_int_iterator IEEE_MAXMIN
1012 [UNSPEC_IEEE_MAX
1013 UNSPEC_IEEE_MIN])
1014
1015 (define_int_attr ieee_maxmin
1016 [(UNSPEC_IEEE_MAX "max")
1017 (UNSPEC_IEEE_MIN "min")])
1018
1019 ;; Mapping of logic operators
1020 (define_code_iterator any_logic [and ior xor])
1021 (define_code_iterator any_or [ior xor])
1022 (define_code_iterator fpint_logic [and xor])
1023
1024 ;; Base name for insn mnemonic.
1025 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1026
1027 ;; Mapping of logic-shift operators
1028 (define_code_iterator any_lshift [ashift lshiftrt])
1029
1030 ;; Mapping of shift-right operators
1031 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1032
1033 ;; Mapping of all shift operators
1034 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1035
1036 ;; Base name for insn mnemonic.
1037 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
1038 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1039
1040 ;; Mapping of rotate operators
1041 (define_code_iterator any_rotate [rotate rotatert])
1042
1043 ;; Base name for insn mnemonic.
1044 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1045
1046 ;; Mapping of abs neg operators
1047 (define_code_iterator absneg [abs neg])
1048
1049 ;; Mapping of abs neg operators to logic operation
1050 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1051
1052 ;; Base name for x87 insn mnemonic.
1053 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1054
1055 ;; Mapping of extend operators
1056 (define_code_iterator any_extend [sign_extend zero_extend])
1057
1058 ;; Mapping of highpart multiply operators
1059 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1060
1061 ;; Prefix for insn menmonic.
1062 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1063 (smul_highpart "i") (umul_highpart "")
1064 (div "i") (udiv "")])
1065 ;; Prefix for define_insn
1066 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1067 (smul_highpart "s") (umul_highpart "u")])
1068 (define_code_attr u [(sign_extend "") (zero_extend "u")
1069 (div "") (udiv "u")])
1070 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1071 (div "false") (udiv "true")])
1072
1073 ;; Used in signed and unsigned truncations.
1074 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1075 ;; Instruction suffix for truncations.
1076 (define_code_attr trunsuffix
1077 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1078
1079 ;; Instruction suffix for SSE sign and zero extensions.
1080 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1081
1082 ;; Used in signed and unsigned fix.
1083 (define_code_iterator any_fix [fix unsigned_fix])
1084 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1085 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1086 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1087
1088 ;; Used in signed and unsigned float.
1089 (define_code_iterator any_float [float unsigned_float])
1090 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1091 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1092 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1093
1094 ;; Base name for expression
1095 (define_code_attr insn
1096 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1097 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1098 (sign_extend "extend") (zero_extend "zero_extend")
1099 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1100 (rotate "rotl") (rotatert "rotr")
1101 (mult "mul") (div "div")])
1102
1103 ;; All integer modes.
1104 (define_mode_iterator SWI1248x [QI HI SI DI])
1105
1106 ;; All integer modes without QImode.
1107 (define_mode_iterator SWI248x [HI SI DI])
1108
1109 ;; All integer modes without QImode and HImode.
1110 (define_mode_iterator SWI48x [SI DI])
1111
1112 ;; All integer modes without SImode and DImode.
1113 (define_mode_iterator SWI12 [QI HI])
1114
1115 ;; All integer modes without DImode.
1116 (define_mode_iterator SWI124 [QI HI SI])
1117
1118 ;; All integer modes without QImode and DImode.
1119 (define_mode_iterator SWI24 [HI SI])
1120
1121 ;; Single word integer modes.
1122 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1123
1124 ;; Single word integer modes without QImode.
1125 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1126
1127 ;; Single word integer modes without QImode and HImode.
1128 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1129
1130 ;; All math-dependant single and double word integer modes.
1131 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1132 (HI "TARGET_HIMODE_MATH")
1133 SI DI (TI "TARGET_64BIT")])
1134
1135 ;; Math-dependant single word integer modes.
1136 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1137 (HI "TARGET_HIMODE_MATH")
1138 SI (DI "TARGET_64BIT")])
1139
1140 ;; Math-dependant integer modes without DImode.
1141 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1142 (HI "TARGET_HIMODE_MATH")
1143 SI])
1144
1145 ;; Math-dependant integer modes with DImode.
1146 (define_mode_iterator SWIM1248x
1147 [(QI "TARGET_QIMODE_MATH")
1148 (HI "TARGET_HIMODE_MATH")
1149 SI DI])
1150
1151 ;; Math-dependant single word integer modes without QImode.
1152 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1153 SI (DI "TARGET_64BIT")])
1154
1155 ;; Double word integer modes.
1156 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1157 (TI "TARGET_64BIT")])
1158
1159 ;; SWI and DWI together.
1160 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1161
1162 ;; SWI48 and DWI together.
1163 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1164
1165 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1166 ;; compile time constant, it is faster to use <MODE_SIZE> than
1167 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1168 ;; command line options just use GET_MODE_SIZE macro.
1169 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1170 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1171 (XF "GET_MODE_SIZE (XFmode)")
1172 (V16QI "16") (V32QI "32") (V64QI "64")
1173 (V8HI "16") (V16HI "32") (V32HI "64")
1174 (V4SI "16") (V8SI "32") (V16SI "64")
1175 (V2DI "16") (V4DI "32") (V8DI "64")
1176 (V1TI "16") (V2TI "32") (V4TI "64")
1177 (V2DF "16") (V4DF "32") (V8DF "64")
1178 (V4SF "16") (V8SF "32") (V16SF "64")
1179 (V8HF "16") (V16HF "32") (V32HF "64")
1180 (V4HF "8") (V2HF "4")
1181 (V8BF "16") (V16BF "32") (V32BF "64")
1182 (V4BF "8") (V2BF "4")])
1183
1184 ;; Double word integer modes as mode attribute.
1185 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1186 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1187
1188 ;; Half sized integer modes.
1189 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1190 (define_mode_attr half [(TI "di") (DI "si")])
1191
1192 ;; LEA mode corresponding to an integer mode
1193 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1194
1195 ;; Half mode for double word integer modes.
1196 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1197 (DI "TARGET_64BIT")])
1198
1199 ;; Instruction suffix for integer modes.
1200 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1201
1202 ;; Instruction suffix for masks.
1203 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1204
1205 ;; Pointer size prefix for integer modes (Intel asm dialect)
1206 (define_mode_attr iptrsize [(QI "BYTE")
1207 (HI "WORD")
1208 (SI "DWORD")
1209 (DI "QWORD")])
1210
1211 ;; Register class for integer modes.
1212 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1213
1214 ;; Immediate operand constraint for integer modes.
1215 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1216
1217 ;; General operand constraint for word modes.
1218 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1219
1220 ;; Memory operand constraint for word modes.
1221 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1222
1223 ;; Immediate operand constraint for double integer modes.
1224 (define_mode_attr di [(SI "nF") (DI "Wd")])
1225
1226 ;; Immediate operand constraint for shifts.
1227 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1228 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1229
1230 ;; Print register name in the specified mode.
1231 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1232
1233 ;; General operand predicate for integer modes.
1234 (define_mode_attr general_operand
1235 [(QI "general_operand")
1236 (HI "general_operand")
1237 (SI "x86_64_general_operand")
1238 (DI "x86_64_general_operand")
1239 (TI "x86_64_general_operand")])
1240
1241 ;; General operand predicate for integer modes, where for TImode
1242 ;; we need both words of the operand to be general operands.
1243 (define_mode_attr general_hilo_operand
1244 [(QI "general_operand")
1245 (HI "general_operand")
1246 (SI "x86_64_general_operand")
1247 (DI "x86_64_general_operand")
1248 (TI "x86_64_hilo_general_operand")])
1249
1250 ;; General sign extend operand predicate for integer modes,
1251 ;; which disallows VOIDmode operands and thus it is suitable
1252 ;; for use inside sign_extend.
1253 (define_mode_attr general_sext_operand
1254 [(QI "sext_operand")
1255 (HI "sext_operand")
1256 (SI "x86_64_sext_operand")
1257 (DI "x86_64_sext_operand")])
1258
1259 ;; General sign/zero extend operand predicate for integer modes.
1260 (define_mode_attr general_szext_operand
1261 [(QI "general_operand")
1262 (HI "general_operand")
1263 (SI "x86_64_szext_general_operand")
1264 (DI "x86_64_szext_general_operand")
1265 (TI "x86_64_hilo_general_operand")])
1266
1267 (define_mode_attr nonmemory_szext_operand
1268 [(QI "nonmemory_operand")
1269 (HI "nonmemory_operand")
1270 (SI "x86_64_szext_nonmemory_operand")
1271 (DI "x86_64_szext_nonmemory_operand")])
1272
1273 ;; Immediate operand predicate for integer modes.
1274 (define_mode_attr immediate_operand
1275 [(QI "immediate_operand")
1276 (HI "immediate_operand")
1277 (SI "x86_64_immediate_operand")
1278 (DI "x86_64_immediate_operand")])
1279
1280 ;; Nonmemory operand predicate for integer modes.
1281 (define_mode_attr nonmemory_operand
1282 [(QI "nonmemory_operand")
1283 (HI "nonmemory_operand")
1284 (SI "x86_64_nonmemory_operand")
1285 (DI "x86_64_nonmemory_operand")])
1286
1287 ;; Operand predicate for shifts.
1288 (define_mode_attr shift_operand
1289 [(QI "nonimmediate_operand")
1290 (HI "nonimmediate_operand")
1291 (SI "nonimmediate_operand")
1292 (DI "shiftdi_operand")
1293 (TI "register_operand")])
1294
1295 ;; Operand predicate for shift argument.
1296 (define_mode_attr shift_immediate_operand
1297 [(QI "const_1_to_31_operand")
1298 (HI "const_1_to_31_operand")
1299 (SI "const_1_to_31_operand")
1300 (DI "const_1_to_63_operand")])
1301
1302 ;; Input operand predicate for arithmetic left shifts.
1303 (define_mode_attr ashl_input_operand
1304 [(QI "nonimmediate_operand")
1305 (HI "nonimmediate_operand")
1306 (SI "nonimmediate_operand")
1307 (DI "ashldi_input_operand")
1308 (TI "reg_or_pm1_operand")])
1309
1310 ;; SSE and x87 SFmode and DFmode floating point modes
1311 (define_mode_iterator MODEF [SF DF])
1312
1313 ;; SSE floating point modes
1314 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1315
1316 ;; All x87 floating point modes
1317 (define_mode_iterator X87MODEF [SF DF XF])
1318
1319 ;; All x87 floating point modes plus HFmode
1320 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1321
1322 ;; All SSE floating point modes
1323 (define_mode_iterator SSEMODEF [HF SF DF TF])
1324 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1325
1326 ;; SSE instruction suffix for various modes
1327 (define_mode_attr ssemodesuffix
1328 [(HF "sh") (SF "ss") (DF "sd")
1329 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1330 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1331 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1332 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1333 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1334 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1335
1336 ;; SSE vector suffix for floating point modes
1337 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1338
1339 ;; SSE vector mode corresponding to a scalar mode
1340 (define_mode_attr ssevecmode
1341 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1342 (define_mode_attr ssevecmodelower
1343 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1344
1345 ;; AVX512F vector mode corresponding to a scalar mode
1346 (define_mode_attr avx512fvecmode
1347 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1348
1349 ;; Instruction suffix for REX 64bit operators.
1350 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1351 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1352
1353 ;; This mode iterator allows :P to be used for patterns that operate on
1354 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1355 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1356
1357 ;; This mode iterator allows :W to be used for patterns that operate on
1358 ;; word_mode sized quantities.
1359 (define_mode_iterator W
1360 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1361
1362 ;; This mode iterator allows :PTR to be used for patterns that operate on
1363 ;; ptr_mode sized quantities.
1364 (define_mode_iterator PTR
1365 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1366 \f
1367 ;; Scheduling descriptions
1368
1369 (include "pentium.md")
1370 (include "ppro.md")
1371 (include "k6.md")
1372 (include "athlon.md")
1373 (include "bdver1.md")
1374 (include "bdver3.md")
1375 (include "btver2.md")
1376 (include "znver.md")
1377 (include "znver4.md")
1378 (include "geode.md")
1379 (include "atom.md")
1380 (include "slm.md")
1381 (include "glm.md")
1382 (include "core2.md")
1383 (include "haswell.md")
1384 (include "lujiazui.md")
1385 (include "yongfeng.md")
1386
1387 \f
1388 ;; Operand and operator predicates and constraints
1389
1390 (include "predicates.md")
1391 (include "constraints.md")
1392
1393 \f
1394 ;; Compare and branch/compare and store instructions.
1395
1396 (define_expand "cbranch<mode>4"
1397 [(set (reg:CC FLAGS_REG)
1398 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1399 (match_operand:SWIM1248x 2 "<general_operand>")))
1400 (set (pc) (if_then_else
1401 (match_operator 0 "ordered_comparison_operator"
1402 [(reg:CC FLAGS_REG) (const_int 0)])
1403 (label_ref (match_operand 3))
1404 (pc)))]
1405 ""
1406 {
1407 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1408 operands[1] = force_reg (<MODE>mode, operands[1]);
1409 ix86_expand_branch (GET_CODE (operands[0]),
1410 operands[1], operands[2], operands[3]);
1411 DONE;
1412 })
1413
1414 (define_expand "cbranchti4"
1415 [(set (reg:CC FLAGS_REG)
1416 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1417 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1418 (set (pc) (if_then_else
1419 (match_operator 0 "ix86_timode_comparison_operator"
1420 [(reg:CC FLAGS_REG) (const_int 0)])
1421 (label_ref (match_operand 3))
1422 (pc)))]
1423 "TARGET_64BIT || TARGET_SSE4_1"
1424 {
1425 ix86_expand_branch (GET_CODE (operands[0]),
1426 operands[1], operands[2], operands[3]);
1427 DONE;
1428 })
1429
1430 (define_expand "cbranchoi4"
1431 [(set (reg:CC FLAGS_REG)
1432 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1433 (match_operand:OI 2 "nonimmediate_operand")))
1434 (set (pc) (if_then_else
1435 (match_operator 0 "bt_comparison_operator"
1436 [(reg:CC FLAGS_REG) (const_int 0)])
1437 (label_ref (match_operand 3))
1438 (pc)))]
1439 "TARGET_AVX"
1440 {
1441 ix86_expand_branch (GET_CODE (operands[0]),
1442 operands[1], operands[2], operands[3]);
1443 DONE;
1444 })
1445
1446 (define_expand "cbranchxi4"
1447 [(set (reg:CC FLAGS_REG)
1448 (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1449 (match_operand:XI 2 "nonimmediate_operand")))
1450 (set (pc) (if_then_else
1451 (match_operator 0 "bt_comparison_operator"
1452 [(reg:CC FLAGS_REG) (const_int 0)])
1453 (label_ref (match_operand 3))
1454 (pc)))]
1455 "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1456 {
1457 ix86_expand_branch (GET_CODE (operands[0]),
1458 operands[1], operands[2], operands[3]);
1459 DONE;
1460 })
1461
1462 (define_expand "cstore<mode>4"
1463 [(set (reg:CC FLAGS_REG)
1464 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1465 (match_operand:SDWIM 3 "<general_operand>")))
1466 (set (match_operand:QI 0 "register_operand")
1467 (match_operator 1 "ordered_comparison_operator"
1468 [(reg:CC FLAGS_REG) (const_int 0)]))]
1469 ""
1470 {
1471 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1472 {
1473 if (GET_CODE (operands[1]) != EQ
1474 && GET_CODE (operands[1]) != NE)
1475 FAIL;
1476 }
1477 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1478 operands[2] = force_reg (<MODE>mode, operands[2]);
1479 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1480 operands[2], operands[3]);
1481 DONE;
1482 })
1483
1484 (define_expand "@cmp<mode>_1"
1485 [(set (reg:CC FLAGS_REG)
1486 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1487 (match_operand:SWI48 1 "<general_operand>")))])
1488
1489 (define_mode_iterator SWI1248_AVX512BWDQ_64
1490 [(QI "TARGET_AVX512DQ") HI
1491 (SI "TARGET_AVX512BW")
1492 (DI "TARGET_AVX512BW && TARGET_EVEX512 && TARGET_64BIT")])
1493
1494 (define_insn "*cmp<mode>_ccz_1"
1495 [(set (reg FLAGS_REG)
1496 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1497 "nonimmediate_operand" "<r>,?m<r>,$k")
1498 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1499 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1500 "@
1501 test{<imodesuffix>}\t%0, %0
1502 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1503 kortest<mskmodesuffix>\t%0, %0"
1504 [(set_attr "type" "test,icmp,msklog")
1505 (set_attr "length_immediate" "0,1,*")
1506 (set_attr "prefix" "*,*,vex")
1507 (set_attr "mode" "<MODE>")])
1508
1509 (define_insn "*cmp<mode>_ccno_1"
1510 [(set (reg FLAGS_REG)
1511 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1512 (match_operand:SWI 1 "const0_operand")))]
1513 "ix86_match_ccmode (insn, CCNOmode)"
1514 "@
1515 test{<imodesuffix>}\t%0, %0
1516 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1517 [(set_attr "type" "test,icmp")
1518 (set_attr "length_immediate" "0,1")
1519 (set_attr "mode" "<MODE>")])
1520
1521 (define_insn "*cmp<mode>_1"
1522 [(set (reg FLAGS_REG)
1523 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1524 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1525 "ix86_match_ccmode (insn, CCmode)"
1526 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1527 [(set_attr "type" "icmp")
1528 (set_attr "mode" "<MODE>")])
1529
1530 (define_insn "*cmp<mode>_minus_1"
1531 [(set (reg FLAGS_REG)
1532 (compare
1533 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1534 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1535 (const_int 0)))]
1536 "ix86_match_ccmode (insn, CCGOCmode)"
1537 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1538 [(set_attr "type" "icmp")
1539 (set_attr "mode" "<MODE>")])
1540
1541 (define_insn "*cmpqi_ext<mode>_1_mem_rex64"
1542 [(set (reg FLAGS_REG)
1543 (compare
1544 (match_operand:QI 0 "norex_memory_operand" "Bn")
1545 (subreg:QI
1546 (match_operator:SWI248 2 "extract_operator"
1547 [(match_operand 1 "int248_register_operand" "Q")
1548 (const_int 8)
1549 (const_int 8)]) 0)))]
1550 "TARGET_64BIT && reload_completed
1551 && ix86_match_ccmode (insn, CCmode)"
1552 "cmp{b}\t{%h1, %0|%0, %h1}"
1553 [(set_attr "type" "icmp")
1554 (set_attr "mode" "QI")])
1555
1556 (define_insn "*cmpqi_ext<mode>_1"
1557 [(set (reg FLAGS_REG)
1558 (compare
1559 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1560 (subreg:QI
1561 (match_operator:SWI248 2 "extract_operator"
1562 [(match_operand 1 "int248_register_operand" "Q,Q")
1563 (const_int 8)
1564 (const_int 8)]) 0)))]
1565 "ix86_match_ccmode (insn, CCmode)"
1566 "cmp{b}\t{%h1, %0|%0, %h1}"
1567 [(set_attr "isa" "*,nox64")
1568 (set_attr "type" "icmp")
1569 (set_attr "mode" "QI")])
1570
1571 (define_peephole2
1572 [(set (match_operand:QI 0 "register_operand")
1573 (match_operand:QI 1 "norex_memory_operand"))
1574 (set (match_operand 3 "flags_reg_operand")
1575 (match_operator 4 "compare_operator"
1576 [(match_dup 0)
1577 (subreg:QI
1578 (match_operator:SWI248 5 "extract_operator"
1579 [(match_operand 2 "int248_register_operand")
1580 (const_int 8)
1581 (const_int 8)]) 0)]))]
1582 "TARGET_64BIT
1583 && peep2_reg_dead_p (2, operands[0])"
1584 [(set (match_dup 3)
1585 (match_op_dup 4
1586 [(match_dup 1)
1587 (subreg:QI
1588 (match_op_dup 5
1589 [(match_dup 2)
1590 (const_int 8)
1591 (const_int 8)]) 0)]))])
1592
1593 (define_insn "*cmpqi_ext<mode>_2"
1594 [(set (reg FLAGS_REG)
1595 (compare
1596 (subreg:QI
1597 (match_operator:SWI248 2 "extract_operator"
1598 [(match_operand 0 "int248_register_operand" "Q")
1599 (const_int 8)
1600 (const_int 8)]) 0)
1601 (match_operand:QI 1 "const0_operand")))]
1602 "ix86_match_ccmode (insn, CCNOmode)"
1603 "test{b}\t%h0, %h0"
1604 [(set_attr "type" "test")
1605 (set_attr "length_immediate" "0")
1606 (set_attr "mode" "QI")])
1607
1608 (define_expand "cmpqi_ext_3"
1609 [(set (reg:CC FLAGS_REG)
1610 (compare:CC
1611 (subreg:QI
1612 (zero_extract:HI
1613 (match_operand:HI 0 "register_operand")
1614 (const_int 8)
1615 (const_int 8)) 0)
1616 (match_operand:QI 1 "const_int_operand")))])
1617
1618 (define_insn "*cmpqi_ext<mode>_3_mem_rex64"
1619 [(set (reg FLAGS_REG)
1620 (compare
1621 (subreg:QI
1622 (match_operator:SWI248 2 "extract_operator"
1623 [(match_operand 0 "int248_register_operand" "Q")
1624 (const_int 8)
1625 (const_int 8)]) 0)
1626 (match_operand:QI 1 "norex_memory_operand" "Bn")))]
1627 "TARGET_64BIT && reload_completed
1628 && ix86_match_ccmode (insn, CCmode)"
1629 "cmp{b}\t{%1, %h0|%h0, %1}"
1630 [(set_attr "type" "icmp")
1631 (set_attr "mode" "QI")])
1632
1633 (define_insn "*cmpqi_ext<mode>_3"
1634 [(set (reg FLAGS_REG)
1635 (compare
1636 (subreg:QI
1637 (match_operator:SWI248 2 "extract_operator"
1638 [(match_operand 0 "int248_register_operand" "Q,Q")
1639 (const_int 8)
1640 (const_int 8)]) 0)
1641 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1642 "ix86_match_ccmode (insn, CCmode)"
1643 "cmp{b}\t{%1, %h0|%h0, %1}"
1644 [(set_attr "isa" "*,nox64")
1645 (set_attr "type" "icmp")
1646 (set_attr "mode" "QI")])
1647
1648 (define_peephole2
1649 [(set (match_operand:QI 0 "register_operand")
1650 (match_operand:QI 1 "norex_memory_operand"))
1651 (set (match_operand 3 "flags_reg_operand")
1652 (match_operator 4 "compare_operator"
1653 [(subreg:QI
1654 (match_operator:SWI248 5 "extract_operator"
1655 [(match_operand 2 "int248_register_operand")
1656 (const_int 8)
1657 (const_int 8)]) 0)
1658 (match_dup 0)]))]
1659 "TARGET_64BIT
1660 && peep2_reg_dead_p (2, operands[0])"
1661 [(set (match_dup 3)
1662 (match_op_dup 4
1663 [(subreg:QI
1664 (match_op_dup 5
1665 [(match_dup 2)
1666 (const_int 8)
1667 (const_int 8)]) 0)
1668 (match_dup 1)]))])
1669
1670 (define_insn "*cmpqi_ext<mode>_4"
1671 [(set (reg FLAGS_REG)
1672 (compare
1673 (subreg:QI
1674 (match_operator:SWI248 2 "extract_operator"
1675 [(match_operand 0 "int248_register_operand" "Q")
1676 (const_int 8)
1677 (const_int 8)]) 0)
1678 (subreg:QI
1679 (match_operator:SWI248 3 "extract_operator"
1680 [(match_operand 1 "int248_register_operand" "Q")
1681 (const_int 8)
1682 (const_int 8)]) 0)))]
1683 "ix86_match_ccmode (insn, CCmode)"
1684 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1685 [(set_attr "type" "icmp")
1686 (set_attr "mode" "QI")])
1687
1688 (define_insn_and_split "*cmp<dwi>_doubleword"
1689 [(set (reg:CCZ FLAGS_REG)
1690 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1691 (match_operand:<DWI> 1 "general_operand")))]
1692 "ix86_pre_reload_split ()"
1693 "#"
1694 "&& 1"
1695 [(parallel [(set (reg:CCZ FLAGS_REG)
1696 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1697 (const_int 0)))
1698 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1699 {
1700 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1701 /* Placing the SUBREG pieces in pseudos helps reload. */
1702 for (int i = 0; i < 4; i++)
1703 if (SUBREG_P (operands[i]))
1704 operands[i] = force_reg (<MODE>mode, operands[i]);
1705
1706 operands[4] = gen_reg_rtx (<MODE>mode);
1707
1708 /* Special case comparisons against -1. */
1709 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1710 {
1711 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1712 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1713 DONE;
1714 }
1715
1716 if (operands[1] == const0_rtx)
1717 emit_move_insn (operands[4], operands[0]);
1718 else if (operands[0] == const0_rtx)
1719 emit_move_insn (operands[4], operands[1]);
1720 else if (operands[1] == constm1_rtx)
1721 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1722 else if (operands[0] == constm1_rtx)
1723 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1724 else
1725 {
1726 if (CONST_SCALAR_INT_P (operands[1])
1727 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1728 operands[1] = force_reg (<MODE>mode, operands[1]);
1729 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1730 }
1731
1732 if (operands[3] == const0_rtx)
1733 operands[5] = operands[2];
1734 else if (operands[2] == const0_rtx)
1735 operands[5] = operands[3];
1736 else
1737 {
1738 operands[5] = gen_reg_rtx (<MODE>mode);
1739 if (operands[3] == constm1_rtx)
1740 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1741 else if (operands[2] == constm1_rtx)
1742 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1743 else
1744 {
1745 if (CONST_SCALAR_INT_P (operands[3])
1746 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1747 operands[3] = force_reg (<MODE>mode, operands[3]);
1748 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1749 }
1750 }
1751 })
1752
1753 ;; These implement float point compares.
1754 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1755 ;; which would allow mix and match FP modes on the compares. Which is what
1756 ;; the old patterns did, but with many more of them.
1757
1758 (define_expand "cbranchxf4"
1759 [(set (reg:CC FLAGS_REG)
1760 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1761 (match_operand:XF 2 "nonmemory_operand")))
1762 (set (pc) (if_then_else
1763 (match_operator 0 "ix86_fp_comparison_operator"
1764 [(reg:CC FLAGS_REG)
1765 (const_int 0)])
1766 (label_ref (match_operand 3))
1767 (pc)))]
1768 "TARGET_80387"
1769 {
1770 ix86_expand_branch (GET_CODE (operands[0]),
1771 operands[1], operands[2], operands[3]);
1772 DONE;
1773 })
1774
1775 (define_expand "cstorexf4"
1776 [(set (reg:CC FLAGS_REG)
1777 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1778 (match_operand:XF 3 "nonmemory_operand")))
1779 (set (match_operand:QI 0 "register_operand")
1780 (match_operator 1 "ix86_fp_comparison_operator"
1781 [(reg:CC FLAGS_REG)
1782 (const_int 0)]))]
1783 "TARGET_80387"
1784 {
1785 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1786 operands[2], operands[3]);
1787 DONE;
1788 })
1789
1790 (define_expand "cbranchhf4"
1791 [(set (reg:CC FLAGS_REG)
1792 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1793 (match_operand:HF 2 "cmp_fp_expander_operand")))
1794 (set (pc) (if_then_else
1795 (match_operator 0 "ix86_fp_comparison_operator"
1796 [(reg:CC FLAGS_REG)
1797 (const_int 0)])
1798 (label_ref (match_operand 3))
1799 (pc)))]
1800 "TARGET_AVX512FP16"
1801 {
1802 ix86_expand_branch (GET_CODE (operands[0]),
1803 operands[1], operands[2], operands[3]);
1804 DONE;
1805 })
1806
1807 (define_expand "cbranch<mode>4"
1808 [(set (reg:CC FLAGS_REG)
1809 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1810 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1811 (set (pc) (if_then_else
1812 (match_operator 0 "ix86_fp_comparison_operator"
1813 [(reg:CC FLAGS_REG)
1814 (const_int 0)])
1815 (label_ref (match_operand 3))
1816 (pc)))]
1817 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1818 {
1819 ix86_expand_branch (GET_CODE (operands[0]),
1820 operands[1], operands[2], operands[3]);
1821 DONE;
1822 })
1823
1824 (define_expand "cbranchbf4"
1825 [(set (reg:CC FLAGS_REG)
1826 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1827 (match_operand:BF 2 "cmp_fp_expander_operand")))
1828 (set (pc) (if_then_else
1829 (match_operator 0 "comparison_operator"
1830 [(reg:CC FLAGS_REG)
1831 (const_int 0)])
1832 (label_ref (match_operand 3))
1833 (pc)))]
1834 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1835 {
1836 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1837 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1838 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1839 SFmode, NULL_RTX, NULL,
1840 as_a <rtx_code_label *> (operands[3]),
1841 /* Unfortunately this isn't propagated. */
1842 profile_probability::even ());
1843 DONE;
1844 })
1845
1846 (define_expand "cstorehf4"
1847 [(set (reg:CC FLAGS_REG)
1848 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1849 (match_operand:HF 3 "cmp_fp_expander_operand")))
1850 (set (match_operand:QI 0 "register_operand")
1851 (match_operator 1 "ix86_fp_comparison_operator"
1852 [(reg:CC FLAGS_REG)
1853 (const_int 0)]))]
1854 "TARGET_AVX512FP16"
1855 {
1856 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1857 operands[2], operands[3]);
1858 DONE;
1859 })
1860
1861 (define_expand "cstorebf4"
1862 [(set (reg:CC FLAGS_REG)
1863 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1864 (match_operand:BF 3 "cmp_fp_expander_operand")))
1865 (set (match_operand:QI 0 "register_operand")
1866 (match_operator 1 "comparison_operator"
1867 [(reg:CC FLAGS_REG)
1868 (const_int 0)]))]
1869 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1870 {
1871 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1872 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1873 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1874 op1, op2, SFmode, 0, 1);
1875 if (!rtx_equal_p (res, operands[0]))
1876 emit_move_insn (operands[0], res);
1877 DONE;
1878 })
1879
1880 (define_expand "cstore<mode>4"
1881 [(set (reg:CC FLAGS_REG)
1882 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1883 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1884 (set (match_operand:QI 0 "register_operand")
1885 (match_operator 1 "ix86_fp_comparison_operator"
1886 [(reg:CC FLAGS_REG)
1887 (const_int 0)]))]
1888 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1889 {
1890 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1891 operands[2], operands[3]);
1892 DONE;
1893 })
1894
1895 (define_expand "cbranchcc4"
1896 [(set (pc) (if_then_else
1897 (match_operator 0 "comparison_operator"
1898 [(match_operand 1 "flags_reg_operand")
1899 (match_operand 2 "const0_operand")])
1900 (label_ref (match_operand 3))
1901 (pc)))]
1902 ""
1903 {
1904 ix86_expand_branch (GET_CODE (operands[0]),
1905 operands[1], operands[2], operands[3]);
1906 DONE;
1907 })
1908
1909 (define_expand "cstorecc4"
1910 [(set (match_operand:QI 0 "register_operand")
1911 (match_operator 1 "comparison_operator"
1912 [(match_operand 2 "flags_reg_operand")
1913 (match_operand 3 "const0_operand")]))]
1914 ""
1915 {
1916 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1917 operands[2], operands[3]);
1918 DONE;
1919 })
1920
1921 ;; FP compares, step 1:
1922 ;; Set the FP condition codes and move fpsr to ax.
1923
1924 ;; We may not use "#" to split and emit these
1925 ;; due to reg-stack pops killing fpsr.
1926
1927 (define_insn "*cmpxf_i387"
1928 [(set (match_operand:HI 0 "register_operand" "=a")
1929 (unspec:HI
1930 [(compare:CCFP
1931 (match_operand:XF 1 "register_operand" "f")
1932 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1933 UNSPEC_FNSTSW))]
1934 "TARGET_80387"
1935 "* return output_fp_compare (insn, operands, false, false);"
1936 [(set_attr "type" "multi")
1937 (set_attr "unit" "i387")
1938 (set_attr "mode" "XF")])
1939
1940 (define_insn "*cmp<mode>_i387"
1941 [(set (match_operand:HI 0 "register_operand" "=a")
1942 (unspec:HI
1943 [(compare:CCFP
1944 (match_operand:MODEF 1 "register_operand" "f")
1945 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1946 UNSPEC_FNSTSW))]
1947 "TARGET_80387"
1948 "* return output_fp_compare (insn, operands, false, false);"
1949 [(set_attr "type" "multi")
1950 (set_attr "unit" "i387")
1951 (set_attr "mode" "<MODE>")])
1952
1953 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1954 [(set (match_operand:HI 0 "register_operand" "=a")
1955 (unspec:HI
1956 [(compare:CCFP
1957 (match_operand:X87MODEF 1 "register_operand" "f")
1958 (float:X87MODEF
1959 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1960 UNSPEC_FNSTSW))]
1961 "TARGET_80387
1962 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1963 || optimize_function_for_size_p (cfun))"
1964 "* return output_fp_compare (insn, operands, false, false);"
1965 [(set_attr "type" "multi")
1966 (set_attr "unit" "i387")
1967 (set_attr "fp_int_src" "true")
1968 (set_attr "mode" "<SWI24:MODE>")])
1969
1970 (define_insn "*cmpu<mode>_i387"
1971 [(set (match_operand:HI 0 "register_operand" "=a")
1972 (unspec:HI
1973 [(unspec:CCFP
1974 [(compare:CCFP
1975 (match_operand:X87MODEF 1 "register_operand" "f")
1976 (match_operand:X87MODEF 2 "register_operand" "f"))]
1977 UNSPEC_NOTRAP)]
1978 UNSPEC_FNSTSW))]
1979 "TARGET_80387"
1980 "* return output_fp_compare (insn, operands, false, true);"
1981 [(set_attr "type" "multi")
1982 (set_attr "unit" "i387")
1983 (set_attr "mode" "<MODE>")])
1984
1985 ;; FP compares, step 2:
1986 ;; Get ax into flags, general case.
1987
1988 (define_insn "x86_sahf_1"
1989 [(set (reg:CC FLAGS_REG)
1990 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1991 UNSPEC_SAHF))]
1992 "TARGET_SAHF"
1993 {
1994 #ifndef HAVE_AS_IX86_SAHF
1995 if (TARGET_64BIT)
1996 return ASM_BYTE "0x9e";
1997 else
1998 #endif
1999 return "sahf";
2000 }
2001 [(set_attr "length" "1")
2002 (set_attr "athlon_decode" "vector")
2003 (set_attr "amdfam10_decode" "direct")
2004 (set_attr "bdver1_decode" "direct")
2005 (set_attr "mode" "SI")])
2006
2007 ;; Pentium Pro can do both steps in one go.
2008 ;; (these instructions set flags directly)
2009
2010 (define_subst_attr "unord" "unord_subst" "" "u")
2011 (define_subst_attr "unordered" "unord_subst" "false" "true")
2012
2013 (define_subst "unord_subst"
2014 [(set (match_operand:CCFP 0)
2015 (match_operand:CCFP 1))]
2016 ""
2017 [(set (match_dup 0)
2018 (unspec:CCFP
2019 [(match_dup 1)]
2020 UNSPEC_NOTRAP))])
2021
2022 (define_insn "*cmpi<unord>xf_i387"
2023 [(set (reg:CCFP FLAGS_REG)
2024 (compare:CCFP
2025 (match_operand:XF 0 "register_operand" "f")
2026 (match_operand:XF 1 "register_operand" "f")))]
2027 "TARGET_80387 && TARGET_CMOVE"
2028 "* return output_fp_compare (insn, operands, true, <unordered>);"
2029 [(set_attr "type" "fcmp")
2030 (set_attr "mode" "XF")
2031 (set_attr "athlon_decode" "vector")
2032 (set_attr "amdfam10_decode" "direct")
2033 (set_attr "bdver1_decode" "double")
2034 (set_attr "znver1_decode" "double")])
2035
2036 (define_insn "*cmpi<unord><MODEF:mode>"
2037 [(set (reg:CCFP FLAGS_REG)
2038 (compare:CCFP
2039 (match_operand:MODEF 0 "register_operand" "f,v")
2040 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
2041 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
2042 || (TARGET_80387 && TARGET_CMOVE)"
2043 "@
2044 * return output_fp_compare (insn, operands, true, <unordered>);
2045 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
2046 [(set_attr "type" "fcmp,ssecomi")
2047 (set_attr "prefix" "orig,maybe_vex")
2048 (set_attr "mode" "<MODEF:MODE>")
2049 (set_attr "prefix_rep" "*,0")
2050 (set (attr "prefix_data16")
2051 (cond [(eq_attr "alternative" "0")
2052 (const_string "*")
2053 (eq_attr "mode" "DF")
2054 (const_string "1")
2055 ]
2056 (const_string "0")))
2057 (set_attr "athlon_decode" "vector")
2058 (set_attr "amdfam10_decode" "direct")
2059 (set_attr "bdver1_decode" "double")
2060 (set_attr "znver1_decode" "double")
2061 (set (attr "enabled")
2062 (if_then_else
2063 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
2064 (if_then_else
2065 (eq_attr "alternative" "0")
2066 (symbol_ref "TARGET_MIX_SSE_I387")
2067 (symbol_ref "true"))
2068 (if_then_else
2069 (eq_attr "alternative" "0")
2070 (symbol_ref "true")
2071 (symbol_ref "false"))))])
2072
2073 (define_insn "*cmpi<unord>hf"
2074 [(set (reg:CCFP FLAGS_REG)
2075 (compare:CCFP
2076 (match_operand:HF 0 "register_operand" "v")
2077 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2078 "TARGET_AVX512FP16"
2079 "v<unord>comish\t{%1, %0|%0, %1}"
2080 [(set_attr "type" "ssecomi")
2081 (set_attr "prefix" "evex")
2082 (set_attr "mode" "HF")])
2083
2084 ;; Set carry flag.
2085 (define_insn "x86_stc"
2086 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2087 ""
2088 "stc"
2089 [(set_attr "length" "1")
2090 (set_attr "length_immediate" "0")
2091 (set_attr "modrm" "0")])
2092
2093 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2094 (define_peephole2
2095 [(match_scratch:QI 0 "r")
2096 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2097 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2098 [(set (match_dup 0) (const_int 1))
2099 (parallel
2100 [(set (reg:CCC FLAGS_REG)
2101 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2102 (match_dup 0)))
2103 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2104
2105 ;; Complement carry flag.
2106 (define_insn "*x86_cmc"
2107 [(set (reg:CCC FLAGS_REG)
2108 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2109 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2110 ""
2111 "cmc"
2112 [(set_attr "length" "1")
2113 (set_attr "length_immediate" "0")
2114 (set_attr "use_carry" "1")
2115 (set_attr "modrm" "0")])
2116
2117 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2118 (define_peephole2
2119 [(match_scratch:QI 0 "r")
2120 (set (reg:CCC FLAGS_REG)
2121 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2122 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2123 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2124 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2125 (parallel
2126 [(set (reg:CCC FLAGS_REG)
2127 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2128 (match_dup 0)))
2129 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2130 \f
2131 ;; Push/pop instructions.
2132
2133 (define_insn_and_split "*pushv1ti2"
2134 [(set (match_operand:V1TI 0 "push_operand" "=<")
2135 (match_operand:V1TI 1 "register_operand" "v"))]
2136 "TARGET_64BIT && TARGET_STV"
2137 "#"
2138 "&& reload_completed"
2139 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2140 (set (match_dup 0) (match_dup 1))]
2141 {
2142 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2143 /* Preserve memory attributes. */
2144 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2145 }
2146 [(set_attr "type" "multi")
2147 (set_attr "mode" "TI")])
2148
2149 (define_insn "*push<mode>2"
2150 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2151 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2152 ""
2153 "#"
2154 [(set_attr "type" "multi")
2155 (set_attr "mode" "<MODE>")])
2156
2157 (define_split
2158 [(set (match_operand:DWI 0 "push_operand")
2159 (match_operand:DWI 1 "general_gr_operand"))]
2160 "reload_completed"
2161 [(const_int 0)]
2162 "ix86_split_long_move (operands); DONE;")
2163
2164 (define_insn "*pushdi2_rex64"
2165 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2166 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2167 "TARGET_64BIT"
2168 "@
2169 push{q}\t%1
2170 #
2171 #"
2172 [(set_attr "type" "push,multi,multi")
2173 (set_attr "mode" "DI")])
2174
2175 ;; Convert impossible pushes of immediate to existing instructions.
2176 ;; First try to get scratch register and go through it. In case this
2177 ;; fails, push sign extended lower part first and then overwrite
2178 ;; upper part by 32bit move.
2179
2180 (define_peephole2
2181 [(match_scratch:DI 2 "r")
2182 (set (match_operand:DI 0 "push_operand")
2183 (match_operand:DI 1 "immediate_operand"))]
2184 "TARGET_64BIT
2185 && !symbolic_operand (operands[1], DImode)
2186 && !x86_64_immediate_operand (operands[1], DImode)"
2187 [(set (match_dup 2) (match_dup 1))
2188 (set (match_dup 0) (match_dup 2))])
2189
2190 (define_split
2191 [(set (match_operand:DI 0 "push_operand")
2192 (match_operand:DI 1 "immediate_operand"))]
2193 "TARGET_64BIT && epilogue_completed
2194 && !symbolic_operand (operands[1], DImode)
2195 && !x86_64_immediate_operand (operands[1], DImode)"
2196 [(set (match_dup 0) (match_dup 1))
2197 (set (match_dup 2) (match_dup 3))]
2198 {
2199 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2200
2201 operands[1] = gen_lowpart (DImode, operands[2]);
2202 operands[2] = gen_rtx_MEM (SImode,
2203 plus_constant (Pmode, stack_pointer_rtx, 4));
2204 })
2205
2206 ;; For TARGET_64BIT we always round up to 8 bytes.
2207 (define_insn "*pushsi2_rex64"
2208 [(set (match_operand:SI 0 "push_operand" "=X,X")
2209 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2210 "TARGET_64BIT"
2211 "@
2212 push{q}\t%q1
2213 #"
2214 [(set_attr "type" "push,multi")
2215 (set_attr "mode" "DI")])
2216
2217 (define_insn "*pushsi2"
2218 [(set (match_operand:SI 0 "push_operand" "=<,<")
2219 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2220 "!TARGET_64BIT"
2221 "@
2222 push{l}\t%1
2223 #"
2224 [(set_attr "type" "push,multi")
2225 (set_attr "mode" "SI")])
2226
2227 (define_split
2228 [(set (match_operand:SWI48DWI 0 "push_operand")
2229 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2230 "TARGET_SSE && reload_completed"
2231 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2232 (set (match_dup 0) (match_dup 1))]
2233 {
2234 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2235 /* Preserve memory attributes. */
2236 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2237 })
2238
2239 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2240 ;; "push a byte/word". But actually we use push{l,q}, which has
2241 ;; the effect of rounding the amount pushed up to a word.
2242
2243 (define_insn "*push<mode>2"
2244 [(set (match_operand:SWI12 0 "push_operand" "=X")
2245 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2246 ""
2247 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2248 [(set_attr "type" "push")
2249 (set (attr "mode")
2250 (if_then_else (match_test "TARGET_64BIT")
2251 (const_string "DI")
2252 (const_string "SI")))])
2253
2254 (define_insn "*push<mode>2_prologue"
2255 [(set (match_operand:W 0 "push_operand" "=<")
2256 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2257 (clobber (mem:BLK (scratch)))]
2258 ""
2259 "push{<imodesuffix>}\t%1"
2260 [(set_attr "type" "push")
2261 (set_attr "mode" "<MODE>")])
2262
2263 (define_insn "*pop<mode>1"
2264 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2265 (match_operand:W 1 "pop_operand" ">"))]
2266 ""
2267 "pop{<imodesuffix>}\t%0"
2268 [(set_attr "type" "pop")
2269 (set_attr "mode" "<MODE>")])
2270
2271 (define_insn "*pop<mode>1_epilogue"
2272 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2273 (match_operand:W 1 "pop_operand" ">"))
2274 (clobber (mem:BLK (scratch)))]
2275 ""
2276 "pop{<imodesuffix>}\t%0"
2277 [(set_attr "type" "pop")
2278 (set_attr "mode" "<MODE>")])
2279
2280 (define_insn "*pushfl<mode>2"
2281 [(set (match_operand:W 0 "push_operand" "=<")
2282 (match_operand:W 1 "flags_reg_operand"))]
2283 ""
2284 "pushf{<imodesuffix>}"
2285 [(set_attr "type" "push")
2286 (set_attr "mode" "<MODE>")])
2287
2288 (define_insn "*popfl<mode>1"
2289 [(set (match_operand:W 0 "flags_reg_operand")
2290 (match_operand:W 1 "pop_operand" ">"))]
2291 ""
2292 "popf{<imodesuffix>}"
2293 [(set_attr "type" "pop")
2294 (set_attr "mode" "<MODE>")])
2295
2296 \f
2297 ;; Reload patterns to support multi-word load/store
2298 ;; with non-offsetable address.
2299 (define_expand "reload_noff_store"
2300 [(parallel [(match_operand 0 "memory_operand" "=m")
2301 (match_operand 1 "register_operand" "r")
2302 (match_operand:DI 2 "register_operand" "=&r")])]
2303 "TARGET_64BIT"
2304 {
2305 rtx mem = operands[0];
2306 rtx addr = XEXP (mem, 0);
2307
2308 emit_move_insn (operands[2], addr);
2309 mem = replace_equiv_address_nv (mem, operands[2]);
2310
2311 emit_insn (gen_rtx_SET (mem, operands[1]));
2312 DONE;
2313 })
2314
2315 (define_expand "reload_noff_load"
2316 [(parallel [(match_operand 0 "register_operand" "=r")
2317 (match_operand 1 "memory_operand" "m")
2318 (match_operand:DI 2 "register_operand" "=r")])]
2319 "TARGET_64BIT"
2320 {
2321 rtx mem = operands[1];
2322 rtx addr = XEXP (mem, 0);
2323
2324 emit_move_insn (operands[2], addr);
2325 mem = replace_equiv_address_nv (mem, operands[2]);
2326
2327 emit_insn (gen_rtx_SET (operands[0], mem));
2328 DONE;
2329 })
2330
2331 ;; Move instructions.
2332
2333 (define_expand "movxi"
2334 [(set (match_operand:XI 0 "nonimmediate_operand")
2335 (match_operand:XI 1 "general_operand"))]
2336 "TARGET_AVX512F && TARGET_EVEX512"
2337 "ix86_expand_vector_move (XImode, operands); DONE;")
2338
2339 (define_expand "movoi"
2340 [(set (match_operand:OI 0 "nonimmediate_operand")
2341 (match_operand:OI 1 "general_operand"))]
2342 "TARGET_AVX"
2343 "ix86_expand_vector_move (OImode, operands); DONE;")
2344
2345 (define_expand "movti"
2346 [(set (match_operand:TI 0 "nonimmediate_operand")
2347 (match_operand:TI 1 "general_operand"))]
2348 "TARGET_64BIT || TARGET_SSE"
2349 {
2350 if (TARGET_64BIT)
2351 ix86_expand_move (TImode, operands);
2352 else
2353 ix86_expand_vector_move (TImode, operands);
2354 DONE;
2355 })
2356
2357 ;; This expands to what emit_move_complex would generate if we didn't
2358 ;; have a movti pattern. Having this avoids problems with reload on
2359 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2360 ;; to have around all the time.
2361 (define_expand "movcdi"
2362 [(set (match_operand:CDI 0 "nonimmediate_operand")
2363 (match_operand:CDI 1 "general_operand"))]
2364 ""
2365 {
2366 if (push_operand (operands[0], CDImode))
2367 emit_move_complex_push (CDImode, operands[0], operands[1]);
2368 else
2369 emit_move_complex_parts (operands[0], operands[1]);
2370 DONE;
2371 })
2372
2373 (define_expand "mov<mode>"
2374 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2375 (match_operand:SWI1248x 1 "general_operand"))]
2376 ""
2377 "ix86_expand_move (<MODE>mode, operands); DONE;")
2378
2379 (define_insn "*mov<mode>_xor"
2380 [(set (match_operand:SWI48 0 "register_operand" "=r")
2381 (match_operand:SWI48 1 "const0_operand"))
2382 (clobber (reg:CC FLAGS_REG))]
2383 "reload_completed"
2384 "xor{l}\t%k0, %k0"
2385 [(set_attr "type" "alu1")
2386 (set_attr "mode" "SI")
2387 (set_attr "length_immediate" "0")])
2388
2389 (define_insn "*mov<mode>_and"
2390 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2391 (match_operand:SWI248 1 "const0_operand"))
2392 (clobber (reg:CC FLAGS_REG))]
2393 "reload_completed"
2394 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2395 [(set_attr "type" "alu1")
2396 (set_attr "mode" "<MODE>")
2397 (set_attr "length_immediate" "1")])
2398
2399 (define_insn "*mov<mode>_or"
2400 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2401 (match_operand:SWI248 1 "constm1_operand"))
2402 (clobber (reg:CC FLAGS_REG))]
2403 "reload_completed"
2404 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2405 [(set_attr "type" "alu1")
2406 (set_attr "mode" "<MODE>")
2407 (set_attr "length_immediate" "1")])
2408
2409 (define_insn "*movxi_internal_avx512f"
2410 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2411 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2412 "TARGET_AVX512F && TARGET_EVEX512
2413 && (register_operand (operands[0], XImode)
2414 || register_operand (operands[1], XImode))"
2415 {
2416 switch (get_attr_type (insn))
2417 {
2418 case TYPE_SSELOG1:
2419 return standard_sse_constant_opcode (insn, operands);
2420
2421 case TYPE_SSEMOV:
2422 return ix86_output_ssemov (insn, operands);
2423
2424 default:
2425 gcc_unreachable ();
2426 }
2427 }
2428 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2429 (set_attr "prefix" "evex")
2430 (set_attr "mode" "XI")])
2431
2432 (define_insn "*movoi_internal_avx"
2433 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2434 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2435 "TARGET_AVX
2436 && (register_operand (operands[0], OImode)
2437 || register_operand (operands[1], OImode))"
2438 {
2439 switch (get_attr_type (insn))
2440 {
2441 case TYPE_SSELOG1:
2442 return standard_sse_constant_opcode (insn, operands);
2443
2444 case TYPE_SSEMOV:
2445 return ix86_output_ssemov (insn, operands);
2446
2447 default:
2448 gcc_unreachable ();
2449 }
2450 }
2451 [(set_attr "isa" "*,avx2,*,*")
2452 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2453 (set_attr "prefix" "vex")
2454 (set_attr "mode" "OI")])
2455
2456 (define_insn "*movti_internal"
2457 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2458 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2459 "(TARGET_64BIT
2460 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2461 || (TARGET_SSE
2462 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2463 && (register_operand (operands[0], TImode)
2464 || register_operand (operands[1], TImode)))"
2465 {
2466 switch (get_attr_type (insn))
2467 {
2468 case TYPE_MULTI:
2469 return "#";
2470
2471 case TYPE_SSELOG1:
2472 return standard_sse_constant_opcode (insn, operands);
2473
2474 case TYPE_SSEMOV:
2475 return ix86_output_ssemov (insn, operands);
2476
2477 default:
2478 gcc_unreachable ();
2479 }
2480 }
2481 [(set (attr "isa")
2482 (cond [(eq_attr "alternative" "0,1,6,7")
2483 (const_string "x64")
2484 (eq_attr "alternative" "3")
2485 (const_string "sse2")
2486 ]
2487 (const_string "*")))
2488 (set (attr "type")
2489 (cond [(eq_attr "alternative" "0,1,6,7")
2490 (const_string "multi")
2491 (eq_attr "alternative" "2,3")
2492 (const_string "sselog1")
2493 ]
2494 (const_string "ssemov")))
2495 (set (attr "prefix")
2496 (if_then_else (eq_attr "type" "sselog1,ssemov")
2497 (const_string "maybe_vex")
2498 (const_string "orig")))
2499 (set (attr "mode")
2500 (cond [(eq_attr "alternative" "0,1")
2501 (const_string "DI")
2502 (match_test "TARGET_AVX")
2503 (const_string "TI")
2504 (ior (not (match_test "TARGET_SSE2"))
2505 (match_test "optimize_function_for_size_p (cfun)"))
2506 (const_string "V4SF")
2507 (and (eq_attr "alternative" "5")
2508 (match_test "TARGET_SSE_TYPELESS_STORES"))
2509 (const_string "V4SF")
2510 ]
2511 (const_string "TI")))
2512 (set (attr "preferred_for_speed")
2513 (cond [(eq_attr "alternative" "6")
2514 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2515 (eq_attr "alternative" "7")
2516 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2517 ]
2518 (symbol_ref "true")))])
2519
2520 (define_split
2521 [(set (match_operand:TI 0 "sse_reg_operand")
2522 (match_operand:TI 1 "general_reg_operand"))]
2523 "TARGET_64BIT && TARGET_SSE4_1
2524 && reload_completed"
2525 [(set (match_dup 2)
2526 (vec_merge:V2DI
2527 (vec_duplicate:V2DI (match_dup 3))
2528 (match_dup 2)
2529 (const_int 2)))]
2530 {
2531 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2532 operands[3] = gen_highpart (DImode, operands[1]);
2533
2534 emit_move_insn (gen_lowpart (DImode, operands[0]),
2535 gen_lowpart (DImode, operands[1]));
2536 })
2537
2538 (define_insn "*movdi_internal"
2539 [(set (match_operand:DI 0 "nonimmediate_operand"
2540 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?r ,?*Yd,?r,?v,?*y,?*x,*k,*k ,*r,*m,*k")
2541 (match_operand:DI 1 "general_operand"
2542 "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,v,*Yd,r ,?v,r ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2543 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2544 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2545 {
2546 switch (get_attr_type (insn))
2547 {
2548 case TYPE_MSKMOV:
2549 return "kmovq\t{%1, %0|%0, %1}";
2550
2551 case TYPE_MSKLOG:
2552 if (operands[1] == const0_rtx)
2553 return "kxorq\t%0, %0, %0";
2554 else if (operands[1] == constm1_rtx)
2555 return "kxnorq\t%0, %0, %0";
2556 gcc_unreachable ();
2557
2558 case TYPE_MULTI:
2559 return "#";
2560
2561 case TYPE_MMX:
2562 return "pxor\t%0, %0";
2563
2564 case TYPE_MMXMOV:
2565 /* Handle broken assemblers that require movd instead of movq. */
2566 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2567 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2568 return "movd\t{%1, %0|%0, %1}";
2569 return "movq\t{%1, %0|%0, %1}";
2570
2571 case TYPE_SSELOG1:
2572 return standard_sse_constant_opcode (insn, operands);
2573
2574 case TYPE_SSEMOV:
2575 return ix86_output_ssemov (insn, operands);
2576
2577 case TYPE_SSECVT:
2578 if (SSE_REG_P (operands[0]))
2579 return "movq2dq\t{%1, %0|%0, %1}";
2580 else
2581 return "movdq2q\t{%1, %0|%0, %1}";
2582
2583 case TYPE_LEA:
2584 return "lea{q}\t{%E1, %0|%0, %E1}";
2585
2586 case TYPE_IMOV:
2587 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2588 if (get_attr_mode (insn) == MODE_SI)
2589 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2590 else if (which_alternative == 4)
2591 return "movabs{q}\t{%1, %0|%0, %1}";
2592 else if (ix86_use_lea_for_mov (insn, operands))
2593 return "lea{q}\t{%E1, %0|%0, %E1}";
2594 else
2595 return "mov{q}\t{%1, %0|%0, %1}";
2596
2597 default:
2598 gcc_unreachable ();
2599 }
2600 }
2601 [(set (attr "isa")
2602 (cond [(eq_attr "alternative" "0,1,17,18")
2603 (const_string "nox64")
2604 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2605 (const_string "x64")
2606 (eq_attr "alternative" "19,20")
2607 (const_string "x64_sse2")
2608 (eq_attr "alternative" "21,22")
2609 (const_string "sse2")
2610 ]
2611 (const_string "*")))
2612 (set (attr "type")
2613 (cond [(eq_attr "alternative" "0,1,17,18")
2614 (const_string "multi")
2615 (eq_attr "alternative" "6")
2616 (const_string "mmx")
2617 (eq_attr "alternative" "7,8,9,10,11")
2618 (const_string "mmxmov")
2619 (eq_attr "alternative" "12")
2620 (const_string "sselog1")
2621 (eq_attr "alternative" "13,14,15,16,19,20")
2622 (const_string "ssemov")
2623 (eq_attr "alternative" "21,22")
2624 (const_string "ssecvt")
2625 (eq_attr "alternative" "23,24,25,26")
2626 (const_string "mskmov")
2627 (eq_attr "alternative" "27")
2628 (const_string "msklog")
2629 (and (match_operand 0 "register_operand")
2630 (match_operand 1 "pic_32bit_operand"))
2631 (const_string "lea")
2632 ]
2633 (const_string "imov")))
2634 (set (attr "modrm")
2635 (if_then_else
2636 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2637 (const_string "0")
2638 (const_string "*")))
2639 (set (attr "length_immediate")
2640 (if_then_else
2641 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2642 (const_string "8")
2643 (const_string "*")))
2644 (set (attr "prefix_rex")
2645 (if_then_else
2646 (eq_attr "alternative" "10,11,19,20")
2647 (const_string "1")
2648 (const_string "*")))
2649 (set (attr "prefix")
2650 (if_then_else (eq_attr "type" "sselog1,ssemov")
2651 (const_string "maybe_vex")
2652 (const_string "orig")))
2653 (set (attr "prefix_data16")
2654 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2655 (const_string "1")
2656 (const_string "*")))
2657 (set (attr "mode")
2658 (cond [(eq_attr "alternative" "2")
2659 (const_string "SI")
2660 (eq_attr "alternative" "12")
2661 (cond [(match_test "TARGET_AVX")
2662 (const_string "TI")
2663 (ior (not (match_test "TARGET_SSE2"))
2664 (match_test "optimize_function_for_size_p (cfun)"))
2665 (const_string "V4SF")
2666 ]
2667 (const_string "TI"))
2668 (eq_attr "alternative" "13")
2669 (cond [(match_test "TARGET_AVX512VL")
2670 (const_string "TI")
2671 (match_test "TARGET_AVX512F")
2672 (const_string "DF")
2673 (match_test "TARGET_AVX")
2674 (const_string "TI")
2675 (ior (not (match_test "TARGET_SSE2"))
2676 (match_test "optimize_function_for_size_p (cfun)"))
2677 (const_string "V4SF")
2678 ]
2679 (const_string "TI"))
2680
2681 (and (eq_attr "alternative" "14,15,16")
2682 (not (match_test "TARGET_SSE2")))
2683 (const_string "V2SF")
2684 ]
2685 (const_string "DI")))
2686 (set (attr "preferred_for_speed")
2687 (cond [(eq_attr "alternative" "10,17,19")
2688 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2689 (eq_attr "alternative" "11,18,20")
2690 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2691 ]
2692 (symbol_ref "true")))
2693 (set (attr "enabled")
2694 (cond [(eq_attr "alternative" "15")
2695 (if_then_else
2696 (match_test "TARGET_STV && TARGET_SSE2")
2697 (symbol_ref "false")
2698 (const_string "*"))
2699 (eq_attr "alternative" "16")
2700 (if_then_else
2701 (match_test "TARGET_STV && TARGET_SSE2")
2702 (symbol_ref "true")
2703 (symbol_ref "false"))
2704 ]
2705 (const_string "*")))])
2706
2707 (define_split
2708 [(set (match_operand:<DWI> 0 "general_reg_operand")
2709 (match_operand:<DWI> 1 "sse_reg_operand"))]
2710 "TARGET_SSE4_1
2711 && reload_completed"
2712 [(set (match_dup 2)
2713 (vec_select:DWIH
2714 (match_dup 3)
2715 (parallel [(const_int 1)])))]
2716 {
2717 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2718 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2719
2720 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2721 gen_lowpart (<MODE>mode, operands[1]));
2722 })
2723
2724 (define_split
2725 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2726 (match_operand:DWI 1 "general_gr_operand"))]
2727 "reload_completed"
2728 [(const_int 0)]
2729 "ix86_split_long_move (operands); DONE;")
2730
2731 (define_split
2732 [(set (match_operand:DI 0 "sse_reg_operand")
2733 (match_operand:DI 1 "general_reg_operand"))]
2734 "!TARGET_64BIT && TARGET_SSE4_1
2735 && reload_completed"
2736 [(set (match_dup 2)
2737 (vec_merge:V4SI
2738 (vec_duplicate:V4SI (match_dup 3))
2739 (match_dup 2)
2740 (const_int 2)))]
2741 {
2742 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2743 operands[3] = gen_highpart (SImode, operands[1]);
2744
2745 emit_move_insn (gen_lowpart (SImode, operands[0]),
2746 gen_lowpart (SImode, operands[1]));
2747 })
2748
2749 ;; movabsq $0x0012345678000000, %rax is longer
2750 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2751 (define_peephole2
2752 [(set (match_operand:DI 0 "register_operand")
2753 (match_operand:DI 1 "const_int_operand"))]
2754 "TARGET_64BIT
2755 && optimize_insn_for_size_p ()
2756 && LEGACY_INT_REG_P (operands[0])
2757 && !x86_64_immediate_operand (operands[1], DImode)
2758 && !x86_64_zext_immediate_operand (operands[1], DImode)
2759 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2760 & ~(HOST_WIDE_INT) 0xffffffff)
2761 && peep2_regno_dead_p (0, FLAGS_REG)"
2762 [(set (match_dup 0) (match_dup 1))
2763 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2764 (clobber (reg:CC FLAGS_REG))])]
2765 {
2766 int shift = ctz_hwi (UINTVAL (operands[1]));
2767 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2768 operands[2] = gen_int_mode (shift, QImode);
2769 })
2770
2771 (define_insn "*movsi_internal"
2772 [(set (match_operand:SI 0 "nonimmediate_operand"
2773 "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2774 (match_operand:SI 1 "general_operand"
2775 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2776 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2777 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2778 {
2779 switch (get_attr_type (insn))
2780 {
2781 case TYPE_SSELOG1:
2782 return standard_sse_constant_opcode (insn, operands);
2783
2784 case TYPE_MSKMOV:
2785 return "kmovd\t{%1, %0|%0, %1}";
2786
2787 case TYPE_MSKLOG:
2788 if (operands[1] == const0_rtx)
2789 return "kxord\t%0, %0, %0";
2790 else if (operands[1] == constm1_rtx)
2791 return "kxnord\t%0, %0, %0";
2792 gcc_unreachable ();
2793
2794 case TYPE_SSEMOV:
2795 return ix86_output_ssemov (insn, operands);
2796
2797 case TYPE_MMX:
2798 return "pxor\t%0, %0";
2799
2800 case TYPE_MMXMOV:
2801 switch (get_attr_mode (insn))
2802 {
2803 case MODE_DI:
2804 return "movq\t{%1, %0|%0, %1}";
2805 case MODE_SI:
2806 return "movd\t{%1, %0|%0, %1}";
2807
2808 default:
2809 gcc_unreachable ();
2810 }
2811
2812 case TYPE_LEA:
2813 return "lea{l}\t{%E1, %0|%0, %E1}";
2814
2815 case TYPE_IMOV:
2816 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2817 if (ix86_use_lea_for_mov (insn, operands))
2818 return "lea{l}\t{%E1, %0|%0, %E1}";
2819 else
2820 return "mov{l}\t{%1, %0|%0, %1}";
2821
2822 default:
2823 gcc_unreachable ();
2824 }
2825 }
2826 [(set (attr "isa")
2827 (cond [(eq_attr "alternative" "12,13")
2828 (const_string "sse2")
2829 ]
2830 (const_string "*")))
2831 (set (attr "type")
2832 (cond [(eq_attr "alternative" "2")
2833 (const_string "mmx")
2834 (eq_attr "alternative" "3,4,5,6,7")
2835 (const_string "mmxmov")
2836 (eq_attr "alternative" "8")
2837 (const_string "sselog1")
2838 (eq_attr "alternative" "9,10,11,12,13")
2839 (const_string "ssemov")
2840 (eq_attr "alternative" "14,15,16")
2841 (const_string "mskmov")
2842 (eq_attr "alternative" "17")
2843 (const_string "msklog")
2844 (and (match_operand 0 "register_operand")
2845 (match_operand 1 "pic_32bit_operand"))
2846 (const_string "lea")
2847 ]
2848 (const_string "imov")))
2849 (set (attr "prefix")
2850 (if_then_else (eq_attr "type" "sselog1,ssemov")
2851 (const_string "maybe_vex")
2852 (const_string "orig")))
2853 (set (attr "prefix_data16")
2854 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2855 (const_string "1")
2856 (const_string "*")))
2857 (set (attr "mode")
2858 (cond [(eq_attr "alternative" "2,3")
2859 (const_string "DI")
2860 (eq_attr "alternative" "8")
2861 (cond [(match_test "TARGET_AVX")
2862 (const_string "TI")
2863 (ior (not (match_test "TARGET_SSE2"))
2864 (match_test "optimize_function_for_size_p (cfun)"))
2865 (const_string "V4SF")
2866 ]
2867 (const_string "TI"))
2868 (eq_attr "alternative" "9")
2869 (cond [(match_test "TARGET_AVX512VL")
2870 (const_string "TI")
2871 (match_test "TARGET_AVX512F")
2872 (const_string "SF")
2873 (match_test "TARGET_AVX")
2874 (const_string "TI")
2875 (ior (not (match_test "TARGET_SSE2"))
2876 (match_test "optimize_function_for_size_p (cfun)"))
2877 (const_string "V4SF")
2878 ]
2879 (const_string "TI"))
2880
2881 (and (eq_attr "alternative" "10,11")
2882 (not (match_test "TARGET_SSE2")))
2883 (const_string "SF")
2884 ]
2885 (const_string "SI")))
2886 (set (attr "preferred_for_speed")
2887 (cond [(eq_attr "alternative" "6,12")
2888 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2889 (eq_attr "alternative" "7,13")
2890 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2891 ]
2892 (symbol_ref "true")))])
2893
2894 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2895 (define_peephole2
2896 [(set (match_operand:SWI248 0 "general_reg_operand")
2897 (match_operand:SWI248 1 "const_int_operand"))]
2898 "optimize_insn_for_size_p () && optimize_size > 1
2899 && operands[1] != const0_rtx
2900 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2901 && !ix86_red_zone_used
2902 && REGNO (operands[0]) != SP_REG"
2903 [(set (match_dup 2) (match_dup 1))
2904 (set (match_dup 0) (match_dup 3))]
2905 {
2906 if (GET_MODE (operands[0]) != word_mode)
2907 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2908
2909 operands[2] = gen_rtx_MEM (word_mode,
2910 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2911 operands[3] = gen_rtx_MEM (word_mode,
2912 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2913 })
2914
2915 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2916 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2917 (define_peephole2
2918 [(set (match_operand:SWI248 0 "memory_operand")
2919 (match_operand:SWI248 1 "const_int_operand"))]
2920 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2921 && optimize_insn_for_size_p () && optimize_size > 1
2922 && peep2_regno_dead_p (0, FLAGS_REG)"
2923 [(parallel [(set (match_dup 0) (match_dup 1))
2924 (clobber (reg:CC FLAGS_REG))])])
2925
2926 (define_insn "*movhi_internal"
2927 [(set (match_operand:HI 0 "nonimmediate_operand"
2928 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2929 (match_operand:HI 1 "general_operand"
2930 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*x,*v"))]
2931 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2932 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2933 {
2934 switch (get_attr_type (insn))
2935 {
2936 case TYPE_IMOVX:
2937 /* movzwl is faster than movw on p2 due to partial word stalls,
2938 though not as fast as an aligned movl. */
2939 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2940
2941 case TYPE_MSKMOV:
2942 switch (which_alternative)
2943 {
2944 case 4:
2945 return "kmovw\t{%k1, %0|%0, %k1}";
2946 case 6:
2947 return "kmovw\t{%1, %k0|%k0, %1}";
2948 case 5:
2949 case 7:
2950 return "kmovw\t{%1, %0|%0, %1}";
2951 default:
2952 gcc_unreachable ();
2953 }
2954
2955 case TYPE_SSEMOV:
2956 return ix86_output_ssemov (insn, operands);
2957
2958 case TYPE_SSELOG1:
2959 if (satisfies_constraint_C (operands[1]))
2960 return standard_sse_constant_opcode (insn, operands);
2961
2962 if (SSE_REG_P (operands[0]))
2963 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2964 else
2965 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2966
2967 case TYPE_MSKLOG:
2968 if (operands[1] == const0_rtx)
2969 return "kxorw\t%0, %0, %0";
2970 else if (operands[1] == constm1_rtx)
2971 return "kxnorw\t%0, %0, %0";
2972 gcc_unreachable ();
2973
2974 default:
2975 if (get_attr_mode (insn) == MODE_SI)
2976 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2977 else
2978 return "mov{w}\t{%1, %0|%0, %1}";
2979 }
2980 }
2981 [(set (attr "isa")
2982 (cond [(eq_attr "alternative" "9,10,11,12,13")
2983 (const_string "sse2")
2984 (eq_attr "alternative" "14")
2985 (const_string "sse4_noavx")
2986 (eq_attr "alternative" "15")
2987 (const_string "avx")
2988 ]
2989 (const_string "*")))
2990 (set (attr "gpr32")
2991 (if_then_else (eq_attr "alternative" "14")
2992 (const_string "0")
2993 (const_string "1")))
2994 (set (attr "type")
2995 (cond [(eq_attr "alternative" "4,5,6,7")
2996 (const_string "mskmov")
2997 (eq_attr "alternative" "8")
2998 (const_string "msklog")
2999 (eq_attr "alternative" "13,14,15")
3000 (if_then_else (match_test "TARGET_AVX512FP16")
3001 (const_string "ssemov")
3002 (const_string "sselog1"))
3003 (eq_attr "alternative" "11")
3004 (const_string "sselog1")
3005 (eq_attr "alternative" "9,10,12")
3006 (const_string "ssemov")
3007 (match_test "optimize_function_for_size_p (cfun)")
3008 (const_string "imov")
3009 (and (eq_attr "alternative" "0")
3010 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3011 (not (match_test "TARGET_HIMODE_MATH"))))
3012 (const_string "imov")
3013 (and (eq_attr "alternative" "1,2")
3014 (match_operand:HI 1 "aligned_operand"))
3015 (const_string "imov")
3016 (and (match_test "TARGET_MOVX")
3017 (eq_attr "alternative" "0,2"))
3018 (const_string "imovx")
3019 ]
3020 (const_string "imov")))
3021 (set (attr "prefix")
3022 (cond [(eq_attr "alternative" "4,5,6,7,8")
3023 (const_string "vex")
3024 (eq_attr "alternative" "9,10,11,12,13,14,15")
3025 (const_string "maybe_evex")
3026 ]
3027 (const_string "orig")))
3028 (set (attr "mode")
3029 (cond [(eq_attr "alternative" "9,10")
3030 (if_then_else (match_test "TARGET_AVX512FP16")
3031 (const_string "HI")
3032 (const_string "SI"))
3033 (eq_attr "alternative" "13,14,15")
3034 (if_then_else (match_test "TARGET_AVX512FP16")
3035 (const_string "HI")
3036 (const_string "TI"))
3037 (eq_attr "alternative" "11")
3038 (cond [(match_test "TARGET_AVX")
3039 (const_string "TI")
3040 (ior (not (match_test "TARGET_SSE2"))
3041 (match_test "optimize_function_for_size_p (cfun)"))
3042 (const_string "V4SF")
3043 ]
3044 (const_string "TI"))
3045 (eq_attr "alternative" "12")
3046 (cond [(match_test "TARGET_AVX512VL")
3047 (const_string "TI")
3048 (match_test "TARGET_AVX512FP16")
3049 (const_string "HF")
3050 (match_test "TARGET_AVX512F")
3051 (const_string "SF")
3052 (match_test "TARGET_AVX")
3053 (const_string "TI")
3054 (ior (not (match_test "TARGET_SSE2"))
3055 (match_test "optimize_function_for_size_p (cfun)"))
3056 (const_string "V4SF")
3057 ]
3058 (const_string "TI"))
3059 (eq_attr "type" "imovx")
3060 (const_string "SI")
3061 (and (eq_attr "alternative" "1,2")
3062 (match_operand:HI 1 "aligned_operand"))
3063 (const_string "SI")
3064 (and (eq_attr "alternative" "0")
3065 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3066 (not (match_test "TARGET_HIMODE_MATH"))))
3067 (const_string "SI")
3068 ]
3069 (const_string "HI")))
3070 (set (attr "preferred_for_speed")
3071 (cond [(eq_attr "alternative" "9")
3072 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3073 (eq_attr "alternative" "10")
3074 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3075 ]
3076 (symbol_ref "true")))])
3077
3078 ;; Situation is quite tricky about when to choose full sized (SImode) move
3079 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
3080 ;; partial register dependency machines (such as AMD Athlon), where QImode
3081 ;; moves issue extra dependency and for partial register stalls machines
3082 ;; that don't use QImode patterns (and QImode move cause stall on the next
3083 ;; instruction).
3084 ;;
3085 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3086 ;; register stall machines with, where we use QImode instructions, since
3087 ;; partial register stall can be caused there. Then we use movzx.
3088
3089 (define_insn "*movqi_internal"
3090 [(set (match_operand:QI 0 "nonimmediate_operand"
3091 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3092 (match_operand:QI 1 "general_operand"
3093 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3094 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3095 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3096
3097 {
3098 char buf[128];
3099 const char *ops;
3100 const char *suffix;
3101
3102 switch (get_attr_type (insn))
3103 {
3104 case TYPE_IMOVX:
3105 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3106 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3107
3108 case TYPE_MSKMOV:
3109 switch (which_alternative)
3110 {
3111 case 9:
3112 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3113 break;
3114 case 11:
3115 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3116 break;
3117 case 12:
3118 case 13:
3119 gcc_assert (TARGET_AVX512DQ);
3120 /* FALLTHRU */
3121 case 10:
3122 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3123 break;
3124 default:
3125 gcc_unreachable ();
3126 }
3127
3128 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3129
3130 snprintf (buf, sizeof (buf), ops, suffix);
3131 output_asm_insn (buf, operands);
3132 return "";
3133
3134 case TYPE_MSKLOG:
3135 if (operands[1] == const0_rtx)
3136 {
3137 if (get_attr_mode (insn) == MODE_HI)
3138 return "kxorw\t%0, %0, %0";
3139 else
3140 return "kxorb\t%0, %0, %0";
3141 }
3142 else if (operands[1] == constm1_rtx)
3143 {
3144 gcc_assert (TARGET_AVX512DQ);
3145 return "kxnorb\t%0, %0, %0";
3146 }
3147 gcc_unreachable ();
3148
3149 default:
3150 if (get_attr_mode (insn) == MODE_SI)
3151 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3152 else
3153 return "mov{b}\t{%1, %0|%0, %1}";
3154 }
3155 }
3156 [(set (attr "isa")
3157 (cond [(eq_attr "alternative" "1,2")
3158 (const_string "x64")
3159 (eq_attr "alternative" "12,13,15")
3160 (const_string "avx512dq")
3161 ]
3162 (const_string "*")))
3163 (set (attr "type")
3164 (cond [(eq_attr "alternative" "9,10,11,12,13")
3165 (const_string "mskmov")
3166 (eq_attr "alternative" "14,15")
3167 (const_string "msklog")
3168 (and (eq_attr "alternative" "7")
3169 (not (match_operand:QI 1 "aligned_operand")))
3170 (const_string "imovx")
3171 (match_test "optimize_function_for_size_p (cfun)")
3172 (const_string "imov")
3173 (and (eq_attr "alternative" "5")
3174 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3175 (not (match_test "TARGET_QIMODE_MATH"))))
3176 (const_string "imov")
3177 (eq_attr "alternative" "5,7")
3178 (const_string "imovx")
3179 (and (match_test "TARGET_MOVX")
3180 (eq_attr "alternative" "4"))
3181 (const_string "imovx")
3182 ]
3183 (const_string "imov")))
3184 (set (attr "prefix")
3185 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3186 (const_string "vex")
3187 (const_string "orig")))
3188 (set (attr "mode")
3189 (cond [(eq_attr "alternative" "5,6,7")
3190 (const_string "SI")
3191 (eq_attr "alternative" "8")
3192 (const_string "QI")
3193 (and (eq_attr "alternative" "9,10,11,14")
3194 (not (match_test "TARGET_AVX512DQ")))
3195 (const_string "HI")
3196 (eq_attr "type" "imovx")
3197 (const_string "SI")
3198 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3199 ;; ones.
3200 (and (eq_attr "type" "imov")
3201 (and (eq_attr "alternative" "3")
3202 (match_test "optimize_function_for_size_p (cfun)")))
3203 (const_string "QI")
3204 ;; For -Os, movl where one or both operands are NON_Q_REGS
3205 ;; and both are LEGACY_REGS is shorter than movb.
3206 ;; Otherwise movb and movl sizes are the same, so decide purely
3207 ;; based on speed factors.
3208 (and (eq_attr "type" "imov")
3209 (and (eq_attr "alternative" "1")
3210 (match_test "optimize_function_for_size_p (cfun)")))
3211 (const_string "SI")
3212 (and (eq_attr "type" "imov")
3213 (and (eq_attr "alternative" "0,1,2,3")
3214 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3215 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3216 (const_string "SI")
3217 ;; Avoid partial register stalls when not using QImode arithmetic
3218 (and (eq_attr "type" "imov")
3219 (and (eq_attr "alternative" "0,1,2,3")
3220 (and (match_test "TARGET_PARTIAL_REG_STALL")
3221 (not (match_test "TARGET_QIMODE_MATH")))))
3222 (const_string "SI")
3223 ]
3224 (const_string "QI")))])
3225
3226 /* Reload dislikes loading 0/-1 directly into mask registers.
3227 Try to tidy things up here. */
3228 (define_peephole2
3229 [(set (match_operand:SWI 0 "general_reg_operand")
3230 (match_operand:SWI 1 "immediate_operand"))
3231 (set (match_operand:SWI 2 "mask_reg_operand")
3232 (match_dup 0))]
3233 "peep2_reg_dead_p (2, operands[0])
3234 && (const0_operand (operands[1], <MODE>mode)
3235 || (constm1_operand (operands[1], <MODE>mode)
3236 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3237 [(set (match_dup 2) (match_dup 1))])
3238
3239 ;; Stores and loads of ax to arbitrary constant address.
3240 ;; We fake an second form of instruction to force reload to load address
3241 ;; into register when rax is not available
3242 (define_insn "*movabs<mode>_1"
3243 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3244 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3245 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3246 {
3247 /* Recover the full memory rtx. */
3248 operands[0] = SET_DEST (PATTERN (insn));
3249 switch (which_alternative)
3250 {
3251 case 0:
3252 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3253 case 1:
3254 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3255 default:
3256 gcc_unreachable ();
3257 }
3258 }
3259 [(set_attr "type" "imov")
3260 (set_attr "modrm" "0,*")
3261 (set_attr "length_address" "8,0")
3262 (set_attr "length_immediate" "0,*")
3263 (set_attr "memory" "store")
3264 (set_attr "mode" "<MODE>")])
3265
3266 (define_insn "*movabs<mode>_2"
3267 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3268 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3269 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3270 {
3271 /* Recover the full memory rtx. */
3272 operands[1] = SET_SRC (PATTERN (insn));
3273 switch (which_alternative)
3274 {
3275 case 0:
3276 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3277 case 1:
3278 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3279 default:
3280 gcc_unreachable ();
3281 }
3282 }
3283 [(set_attr "type" "imov")
3284 (set_attr "modrm" "0,*")
3285 (set_attr "length_address" "8,0")
3286 (set_attr "length_immediate" "0")
3287 (set_attr "memory" "load")
3288 (set_attr "mode" "<MODE>")])
3289
3290 (define_insn "swap<mode>"
3291 [(set (match_operand:SWI48 0 "register_operand" "+r")
3292 (match_operand:SWI48 1 "register_operand" "+r"))
3293 (set (match_dup 1)
3294 (match_dup 0))]
3295 ""
3296 "xchg{<imodesuffix>}\t%1, %0"
3297 [(set_attr "type" "imov")
3298 (set_attr "mode" "<MODE>")
3299 (set_attr "pent_pair" "np")
3300 (set_attr "athlon_decode" "vector")
3301 (set_attr "amdfam10_decode" "double")
3302 (set_attr "bdver1_decode" "double")])
3303
3304 (define_insn "*swap<mode>"
3305 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3306 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3307 (set (match_dup 1)
3308 (match_dup 0))]
3309 ""
3310 "@
3311 xchg{<imodesuffix>}\t%1, %0
3312 xchg{l}\t%k1, %k0"
3313 [(set_attr "type" "imov")
3314 (set_attr "mode" "<MODE>,SI")
3315 (set (attr "preferred_for_size")
3316 (cond [(eq_attr "alternative" "0")
3317 (symbol_ref "false")]
3318 (symbol_ref "true")))
3319 ;; Potential partial reg stall on alternative 1.
3320 (set (attr "preferred_for_speed")
3321 (cond [(eq_attr "alternative" "1")
3322 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3323 (symbol_ref "true")))
3324 (set_attr "pent_pair" "np")
3325 (set_attr "athlon_decode" "vector")
3326 (set_attr "amdfam10_decode" "double")
3327 (set_attr "bdver1_decode" "double")])
3328
3329 (define_peephole2
3330 [(set (match_operand:SWI 0 "general_reg_operand")
3331 (match_operand:SWI 1 "general_reg_operand"))
3332 (set (match_dup 1)
3333 (match_operand:SWI 2 "general_reg_operand"))
3334 (set (match_dup 2) (match_dup 0))]
3335 "peep2_reg_dead_p (3, operands[0])
3336 && optimize_insn_for_size_p ()"
3337 [(parallel [(set (match_dup 1) (match_dup 2))
3338 (set (match_dup 2) (match_dup 1))])])
3339
3340 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3341 (define_peephole2
3342 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3343 (match_operand:SWI 1 "general_reg_operand"))
3344 (set (match_dup 1) (match_dup 0))])]
3345 "((REGNO (operands[0]) != AX_REG
3346 && REGNO (operands[1]) != AX_REG)
3347 || optimize_size < 2
3348 || !optimize_insn_for_size_p ())
3349 && peep2_reg_dead_p (1, operands[0])"
3350 [(set (match_dup 1) (match_dup 0))])
3351
3352 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3353 (define_peephole2
3354 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3355 (match_operand:SWI 1 "general_reg_operand"))
3356 (set (match_dup 1) (match_dup 0))])]
3357 "((REGNO (operands[0]) != AX_REG
3358 && REGNO (operands[1]) != AX_REG)
3359 || optimize_size < 2
3360 || !optimize_insn_for_size_p ())
3361 && peep2_reg_dead_p (1, operands[1])"
3362 [(set (match_dup 0) (match_dup 1))])
3363
3364 ;; Convert moves to/from AX_REG into xchg with -Oz.
3365 (define_peephole2
3366 [(set (match_operand:SWI48 0 "general_reg_operand")
3367 (match_operand:SWI48 1 "general_reg_operand"))]
3368 "optimize_size > 1
3369 && ((REGNO (operands[0]) == AX_REG)
3370 != (REGNO (operands[1]) == AX_REG))
3371 && optimize_insn_for_size_p ()
3372 && peep2_reg_dead_p (1, operands[1])"
3373 [(parallel [(set (match_dup 0) (match_dup 1))
3374 (set (match_dup 1) (match_dup 0))])])
3375
3376 (define_expand "movstrict<mode>"
3377 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3378 (match_operand:SWI12 1 "general_operand"))]
3379 ""
3380 {
3381 gcc_assert (SUBREG_P (operands[0]));
3382 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3383 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3384 FAIL;
3385 })
3386
3387 (define_insn "*movstrict<mode>_1"
3388 [(set (strict_low_part
3389 (match_operand:SWI12 0 "register_operand" "+<r>"))
3390 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3391 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3392 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3393 [(set_attr "type" "imov")
3394 (set_attr "mode" "<MODE>")])
3395
3396 (define_insn "*movstrict<mode>_xor"
3397 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3398 (match_operand:SWI12 1 "const0_operand"))
3399 (clobber (reg:CC FLAGS_REG))]
3400 "reload_completed"
3401 "xor{<imodesuffix>}\t%0, %0"
3402 [(set_attr "type" "alu1")
3403 (set_attr "mode" "<MODE>")
3404 (set_attr "length_immediate" "0")])
3405
3406 (define_expand "extv<mode>"
3407 [(set (match_operand:SWI24 0 "register_operand")
3408 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3409 (match_operand:QI 2 "const_int_operand")
3410 (match_operand:QI 3 "const_int_operand")))]
3411 ""
3412 {
3413 /* Handle extractions from %ah et al. */
3414 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3415 FAIL;
3416
3417 unsigned int regno = reg_or_subregno (operands[1]);
3418
3419 /* Be careful to expand only with registers having upper parts. */
3420 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3421 operands[1] = copy_to_reg (operands[1]);
3422 })
3423
3424 (define_insn "*extv<mode>"
3425 [(set (match_operand:SWI24 0 "register_operand" "=R")
3426 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3427 (const_int 8)
3428 (const_int 8)))]
3429 ""
3430 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3431 [(set_attr "type" "imovx")
3432 (set_attr "mode" "SI")])
3433
3434 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3435 (define_insn_and_split "*extv<mode>_1_0"
3436 [(set (match_operand:SWI48 0 "register_operand" "=r")
3437 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3438 (const_int 1)
3439 (const_int 0)))
3440 (clobber (reg:CC FLAGS_REG))]
3441 ""
3442 "#"
3443 ""
3444 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3445 (clobber (reg:CC FLAGS_REG))])
3446 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3447 (clobber (reg:CC FLAGS_REG))])])
3448
3449 (define_expand "extzv<mode>"
3450 [(set (match_operand:SWI248 0 "register_operand")
3451 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3452 (match_operand:QI 2 "const_int_operand")
3453 (match_operand:QI 3 "const_int_operand")))]
3454 ""
3455 {
3456 if (ix86_expand_pextr (operands))
3457 DONE;
3458
3459 /* Handle extractions from %ah et al. */
3460 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3461 FAIL;
3462
3463 unsigned int regno = reg_or_subregno (operands[1]);
3464
3465 /* Be careful to expand only with registers having upper parts. */
3466 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3467 operands[1] = copy_to_reg (operands[1]);
3468 })
3469
3470 (define_insn "*extzv<mode>"
3471 [(set (match_operand:SWI248 0 "register_operand" "=R")
3472 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3473 (const_int 8)
3474 (const_int 8)))]
3475 ""
3476 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3477 [(set_attr "type" "imovx")
3478 (set_attr "mode" "SI")])
3479
3480 (define_insn "*extzvqi_mem_rex64"
3481 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
3482 (subreg:QI
3483 (match_operator:SWI248 2 "extract_operator"
3484 [(match_operand 1 "int248_register_operand" "Q")
3485 (const_int 8)
3486 (const_int 8)]) 0))]
3487 "TARGET_64BIT && reload_completed"
3488 "mov{b}\t{%h1, %0|%0, %h1}"
3489 [(set_attr "type" "imov")
3490 (set_attr "mode" "QI")])
3491
3492 (define_insn "*extzvqi"
3493 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
3494 (subreg:QI
3495 (match_operator:SWI248 2 "extract_operator"
3496 [(match_operand 1 "int248_register_operand" "Q,Q,Q")
3497 (const_int 8)
3498 (const_int 8)]) 0))]
3499 ""
3500 {
3501 switch (get_attr_type (insn))
3502 {
3503 case TYPE_IMOVX:
3504 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3505 default:
3506 return "mov{b}\t{%h1, %0|%0, %h1}";
3507 }
3508 }
3509 [(set_attr "isa" "*,*,nox64")
3510 (set (attr "type")
3511 (if_then_else (and (match_operand:QI 0 "register_operand")
3512 (ior (not (match_operand:QI 0 "QIreg_operand"))
3513 (match_test "TARGET_MOVX")))
3514 (const_string "imovx")
3515 (const_string "imov")))
3516 (set (attr "mode")
3517 (if_then_else (eq_attr "type" "imovx")
3518 (const_string "SI")
3519 (const_string "QI")))])
3520
3521 (define_peephole2
3522 [(set (match_operand:QI 0 "register_operand")
3523 (subreg:QI
3524 (match_operator:SWI248 3 "extract_operator"
3525 [(match_operand 1 "int248_register_operand")
3526 (const_int 8)
3527 (const_int 8)]) 0))
3528 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3529 "TARGET_64BIT
3530 && peep2_reg_dead_p (2, operands[0])"
3531 [(set (match_dup 2)
3532 (subreg:QI
3533 (match_op_dup 3
3534 [(match_dup 1)
3535 (const_int 8)
3536 (const_int 8)]) 0))])
3537
3538 (define_expand "insv<mode>"
3539 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3540 (match_operand:QI 1 "const_int_operand")
3541 (match_operand:QI 2 "const_int_operand"))
3542 (match_operand:SWI248 3 "register_operand"))]
3543 ""
3544 {
3545 rtx dst;
3546
3547 if (ix86_expand_pinsr (operands))
3548 DONE;
3549
3550 /* Handle insertions to %ah et al. */
3551 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3552 FAIL;
3553
3554 unsigned int regno = reg_or_subregno (operands[0]);
3555
3556 /* Be careful to expand only with registers having upper parts. */
3557 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3558 dst = copy_to_reg (operands[0]);
3559 else
3560 dst = operands[0];
3561
3562 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3563
3564 /* Fix up the destination if needed. */
3565 if (dst != operands[0])
3566 emit_move_insn (operands[0], dst);
3567
3568 DONE;
3569 })
3570
3571 (define_insn "*insvqi_1_mem_rex64"
3572 [(set (zero_extract:SWI248
3573 (match_operand 0 "int248_register_operand" "+Q")
3574 (const_int 8)
3575 (const_int 8))
3576 (subreg:SWI248
3577 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3578 "TARGET_64BIT && reload_completed"
3579 "mov{b}\t{%1, %h0|%h0, %1}"
3580 [(set_attr "type" "imov")
3581 (set_attr "mode" "QI")])
3582
3583 (define_insn "@insv<mode>_1"
3584 [(set (zero_extract:SWI248
3585 (match_operand 0 "int248_register_operand" "+Q,Q")
3586 (const_int 8)
3587 (const_int 8))
3588 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3589 ""
3590 {
3591 if (CONST_INT_P (operands[1]))
3592 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3593 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3594 }
3595 [(set_attr "isa" "*,nox64")
3596 (set_attr "type" "imov")
3597 (set_attr "mode" "QI")])
3598
3599 (define_insn "*insvqi_1"
3600 [(set (zero_extract:SWI248
3601 (match_operand 0 "int248_register_operand" "+Q,Q")
3602 (const_int 8)
3603 (const_int 8))
3604 (subreg:SWI248
3605 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3606 ""
3607 "mov{b}\t{%1, %h0|%h0, %1}"
3608 [(set_attr "isa" "*,nox64")
3609 (set_attr "type" "imov")
3610 (set_attr "mode" "QI")])
3611
3612 (define_peephole2
3613 [(set (match_operand:QI 0 "register_operand")
3614 (match_operand:QI 1 "norex_memory_operand"))
3615 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3616 (const_int 8)
3617 (const_int 8))
3618 (subreg:SWI248 (match_dup 0) 0))]
3619 "TARGET_64BIT
3620 && peep2_reg_dead_p (2, operands[0])"
3621 [(set (zero_extract:SWI248 (match_dup 2)
3622 (const_int 8)
3623 (const_int 8))
3624 (subreg:SWI248 (match_dup 1) 0))])
3625
3626 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3627 (define_peephole2
3628 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3629 (const_int 0))
3630 (clobber (reg:CC FLAGS_REG))])
3631 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3632 (const_int 8)
3633 (const_int 8))
3634 (const_int 0))]
3635 "REGNO (operands[0]) == REGNO (operands[1])"
3636 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3637 (const_int 0))
3638 (clobber (reg:CC FLAGS_REG))])])
3639
3640 ;; Combine movl followed by movb.
3641 (define_peephole2
3642 [(set (match_operand:SWI48 0 "general_reg_operand")
3643 (match_operand:SWI48 1 "const_int_operand"))
3644 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3645 (const_int 8)
3646 (const_int 8))
3647 (match_operand:SWI248 3 "const_int_operand"))]
3648 "REGNO (operands[0]) == REGNO (operands[2])"
3649 [(set (match_operand:SWI48 0 "general_reg_operand")
3650 (match_dup 4))]
3651 {
3652 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3653 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3654 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3655 })
3656
3657 (define_insn "*insvqi_2"
3658 [(set (zero_extract:SWI248
3659 (match_operand 0 "int248_register_operand" "+Q")
3660 (const_int 8)
3661 (const_int 8))
3662 (match_operator:SWI248 2 "extract_operator"
3663 [(match_operand 1 "int248_register_operand" "Q")
3664 (const_int 8)
3665 (const_int 8)]))]
3666 ""
3667 "mov{b}\t{%h1, %h0|%h0, %h1}"
3668 [(set_attr "type" "imov")
3669 (set_attr "mode" "QI")])
3670
3671 (define_insn "*insvqi_3"
3672 [(set (zero_extract:SWI248
3673 (match_operand 0 "int248_register_operand" "+Q")
3674 (const_int 8)
3675 (const_int 8))
3676 (any_shiftrt:SWI248
3677 (match_operand:SWI248 1 "register_operand" "Q")
3678 (const_int 8)))]
3679 ""
3680 "mov{b}\t{%h1, %h0|%h0, %h1}"
3681 [(set_attr "type" "imov")
3682 (set_attr "mode" "QI")])
3683
3684 (define_code_iterator any_or_plus [plus ior xor])
3685
3686 (define_insn_and_split "*insvti_highpart_1"
3687 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3688 (any_or_plus:TI
3689 (and:TI
3690 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3691 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3692 (ashift:TI
3693 (zero_extend:TI
3694 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3695 (const_int 64))))]
3696 "TARGET_64BIT
3697 && CONST_WIDE_INT_P (operands[3])
3698 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3699 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3700 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3701 "#"
3702 "&& reload_completed"
3703 [(const_int 0)]
3704 {
3705 operands[4] = gen_lowpart (DImode, operands[1]);
3706 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3707 DONE;
3708 })
3709
3710 (define_insn_and_split "*insvti_lowpart_1"
3711 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3712 (any_or_plus:TI
3713 (and:TI
3714 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3715 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3716 (zero_extend:TI
3717 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3718 "TARGET_64BIT
3719 && CONST_WIDE_INT_P (operands[3])
3720 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3721 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3722 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3723 "#"
3724 "&& reload_completed"
3725 [(const_int 0)]
3726 {
3727 operands[4] = gen_highpart (DImode, operands[1]);
3728 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3729 DONE;
3730 })
3731
3732 (define_insn_and_split "*insvdi_lowpart_1"
3733 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3734 (any_or_plus:DI
3735 (and:DI
3736 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3737 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3738 (zero_extend:DI
3739 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3740 "!TARGET_64BIT
3741 && CONST_INT_P (operands[3])
3742 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3743 "#"
3744 "&& reload_completed"
3745 [(const_int 0)]
3746 {
3747 operands[4] = gen_highpart (SImode, operands[1]);
3748 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3749 DONE;
3750 })
3751 \f
3752 ;; Floating point push instructions.
3753
3754 (define_insn "*pushtf"
3755 [(set (match_operand:TF 0 "push_operand" "=<,<")
3756 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3757 "TARGET_64BIT || TARGET_SSE"
3758 {
3759 /* This insn should be already split before reg-stack. */
3760 return "#";
3761 }
3762 [(set_attr "isa" "*,x64")
3763 (set_attr "type" "multi")
3764 (set_attr "unit" "sse,*")
3765 (set_attr "mode" "TF,DI")])
3766
3767 ;; %%% Kill this when call knows how to work this out.
3768 (define_split
3769 [(set (match_operand:TF 0 "push_operand")
3770 (match_operand:TF 1 "sse_reg_operand"))]
3771 "TARGET_SSE && reload_completed"
3772 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3773 (set (match_dup 0) (match_dup 1))]
3774 {
3775 /* Preserve memory attributes. */
3776 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3777 })
3778
3779 (define_insn "*pushxf"
3780 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3781 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3782 ""
3783 {
3784 /* This insn should be already split before reg-stack. */
3785 return "#";
3786 }
3787 [(set_attr "isa" "*,*,*,nox64,x64")
3788 (set_attr "type" "multi")
3789 (set_attr "unit" "i387,*,*,*,*")
3790 (set (attr "mode")
3791 (cond [(eq_attr "alternative" "1,2,3,4")
3792 (if_then_else (match_test "TARGET_64BIT")
3793 (const_string "DI")
3794 (const_string "SI"))
3795 ]
3796 (const_string "XF")))
3797 (set (attr "preferred_for_size")
3798 (cond [(eq_attr "alternative" "1")
3799 (symbol_ref "false")]
3800 (symbol_ref "true")))])
3801
3802 ;; %%% Kill this when call knows how to work this out.
3803 (define_split
3804 [(set (match_operand:XF 0 "push_operand")
3805 (match_operand:XF 1 "fp_register_operand"))]
3806 "reload_completed"
3807 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3808 (set (match_dup 0) (match_dup 1))]
3809 {
3810 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3811 /* Preserve memory attributes. */
3812 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3813 })
3814
3815 (define_insn "*pushdf"
3816 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3817 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3818 ""
3819 {
3820 /* This insn should be already split before reg-stack. */
3821 return "#";
3822 }
3823 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3824 (set_attr "type" "multi")
3825 (set_attr "unit" "i387,*,*,*,*,sse")
3826 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3827 (set (attr "preferred_for_size")
3828 (cond [(eq_attr "alternative" "1")
3829 (symbol_ref "false")]
3830 (symbol_ref "true")))
3831 (set (attr "preferred_for_speed")
3832 (cond [(eq_attr "alternative" "1")
3833 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3834 (symbol_ref "true")))])
3835
3836 ;; %%% Kill this when call knows how to work this out.
3837 (define_split
3838 [(set (match_operand:DF 0 "push_operand")
3839 (match_operand:DF 1 "any_fp_register_operand"))]
3840 "reload_completed"
3841 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3842 (set (match_dup 0) (match_dup 1))]
3843 {
3844 /* Preserve memory attributes. */
3845 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3846 })
3847
3848 (define_mode_iterator HFBF [HF BF])
3849
3850 (define_insn "*push<mode>_rex64"
3851 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3852 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3853 "TARGET_64BIT"
3854 {
3855 /* Anything else should be already split before reg-stack. */
3856 gcc_assert (which_alternative == 0);
3857 return "push{q}\t%q1";
3858 }
3859 [(set_attr "isa" "*,sse4")
3860 (set_attr "type" "push,multi")
3861 (set_attr "mode" "DI,TI")])
3862
3863 (define_insn "*push<mode>"
3864 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3865 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3866 "!TARGET_64BIT"
3867 {
3868 /* Anything else should be already split before reg-stack. */
3869 gcc_assert (which_alternative == 0);
3870 return "push{l}\t%k1";
3871 }
3872 [(set_attr "isa" "*,sse4")
3873 (set_attr "type" "push,multi")
3874 (set_attr "mode" "SI,TI")])
3875
3876 (define_insn "push2_di"
3877 [(set (match_operand:TI 0 "push_operand" "=<")
3878 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3879 (match_operand:DI 2 "register_operand" "r")]
3880 UNSPEC_APXPUSH2))]
3881 "TARGET_APX_PUSH2POP2"
3882 "push2\t%1, %2"
3883 [(set_attr "mode" "TI")
3884 (set_attr "type" "multi")
3885 (set_attr "prefix" "evex")])
3886
3887 (define_insn "pop2_di"
3888 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3889 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3890 UNSPEC_APXPOP2_LOW))
3891 (set (match_operand:DI 2 "register_operand" "=r")
3892 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3893 "TARGET_APX_PUSH2POP2"
3894 "pop2\t%0, %2"
3895 [(set_attr "mode" "TI")
3896 (set_attr "prefix" "evex")])
3897
3898 (define_insn "*pushsf_rex64"
3899 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3900 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3901 "TARGET_64BIT"
3902 {
3903 /* Anything else should be already split before reg-stack. */
3904 if (which_alternative != 1)
3905 return "#";
3906 return "push{q}\t%q1";
3907 }
3908 [(set_attr "type" "multi,push,multi")
3909 (set_attr "unit" "i387,*,*")
3910 (set_attr "mode" "SF,DI,SF")])
3911
3912 (define_insn "*pushsf"
3913 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3914 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3915 "!TARGET_64BIT"
3916 {
3917 /* Anything else should be already split before reg-stack. */
3918 if (which_alternative != 1)
3919 return "#";
3920 return "push{l}\t%1";
3921 }
3922 [(set_attr "type" "multi,push,multi")
3923 (set_attr "unit" "i387,*,*")
3924 (set_attr "mode" "SF,SI,SF")])
3925
3926 (define_mode_iterator MODESH [SF HF BF])
3927 ;; %%% Kill this when call knows how to work this out.
3928 (define_split
3929 [(set (match_operand:MODESH 0 "push_operand")
3930 (match_operand:MODESH 1 "any_fp_register_operand"))]
3931 "reload_completed"
3932 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3933 (set (match_dup 0) (match_dup 1))]
3934 {
3935 rtx op = XEXP (operands[0], 0);
3936 if (GET_CODE (op) == PRE_DEC)
3937 {
3938 gcc_assert (!TARGET_64BIT);
3939 op = GEN_INT (-4);
3940 }
3941 else
3942 {
3943 op = XEXP (XEXP (op, 1), 1);
3944 gcc_assert (CONST_INT_P (op));
3945 }
3946 operands[2] = op;
3947 /* Preserve memory attributes. */
3948 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3949 })
3950
3951 (define_split
3952 [(set (match_operand:SF 0 "push_operand")
3953 (match_operand:SF 1 "memory_operand"))]
3954 "reload_completed
3955 && find_constant_src (insn)"
3956 [(set (match_dup 0) (match_dup 2))]
3957 "operands[2] = find_constant_src (curr_insn);")
3958
3959 (define_split
3960 [(set (match_operand 0 "push_operand")
3961 (match_operand 1 "general_gr_operand"))]
3962 "reload_completed
3963 && (GET_MODE (operands[0]) == TFmode
3964 || GET_MODE (operands[0]) == XFmode
3965 || GET_MODE (operands[0]) == DFmode)"
3966 [(const_int 0)]
3967 "ix86_split_long_move (operands); DONE;")
3968 \f
3969 ;; Floating point move instructions.
3970
3971 (define_expand "movtf"
3972 [(set (match_operand:TF 0 "nonimmediate_operand")
3973 (match_operand:TF 1 "nonimmediate_operand"))]
3974 "TARGET_64BIT || TARGET_SSE"
3975 "ix86_expand_move (TFmode, operands); DONE;")
3976
3977 (define_expand "mov<mode>"
3978 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3979 (match_operand:X87MODEFH 1 "general_operand"))]
3980 ""
3981 "ix86_expand_move (<MODE>mode, operands); DONE;")
3982
3983 (define_insn "*movtf_internal"
3984 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3985 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3986 "(TARGET_64BIT || TARGET_SSE)
3987 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3988 && (lra_in_progress || reload_completed
3989 || !CONST_DOUBLE_P (operands[1])
3990 || (standard_sse_constant_p (operands[1], TFmode) == 1
3991 && !memory_operand (operands[0], TFmode))
3992 || (!TARGET_MEMORY_MISMATCH_STALL
3993 && memory_operand (operands[0], TFmode)))"
3994 {
3995 switch (get_attr_type (insn))
3996 {
3997 case TYPE_SSELOG1:
3998 return standard_sse_constant_opcode (insn, operands);
3999
4000 case TYPE_SSEMOV:
4001 return ix86_output_ssemov (insn, operands);
4002
4003 case TYPE_MULTI:
4004 return "#";
4005
4006 default:
4007 gcc_unreachable ();
4008 }
4009 }
4010 [(set_attr "isa" "*,*,*,x64,x64")
4011 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
4012 (set (attr "prefix")
4013 (if_then_else (eq_attr "type" "sselog1,ssemov")
4014 (const_string "maybe_vex")
4015 (const_string "orig")))
4016 (set (attr "mode")
4017 (cond [(eq_attr "alternative" "3,4")
4018 (const_string "DI")
4019 (match_test "TARGET_AVX")
4020 (const_string "TI")
4021 (ior (not (match_test "TARGET_SSE2"))
4022 (match_test "optimize_function_for_size_p (cfun)"))
4023 (const_string "V4SF")
4024 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4025 (const_string "V4SF")
4026 (and (eq_attr "alternative" "2")
4027 (match_test "TARGET_SSE_TYPELESS_STORES"))
4028 (const_string "V4SF")
4029 ]
4030 (const_string "TI")))])
4031
4032 (define_split
4033 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
4034 (match_operand:TF 1 "general_gr_operand"))]
4035 "reload_completed"
4036 [(const_int 0)]
4037 "ix86_split_long_move (operands); DONE;")
4038
4039 ;; Possible store forwarding (partial memory) stall
4040 ;; in alternatives 4, 6, 7 and 8.
4041 (define_insn "*movxf_internal"
4042 [(set (match_operand:XF 0 "nonimmediate_operand"
4043 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
4044 (match_operand:XF 1 "general_operand"
4045 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
4046 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4047 && (lra_in_progress || reload_completed
4048 || !CONST_DOUBLE_P (operands[1])
4049 || ((optimize_function_for_size_p (cfun)
4050 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4051 && standard_80387_constant_p (operands[1]) > 0
4052 && !memory_operand (operands[0], XFmode))
4053 || (!TARGET_MEMORY_MISMATCH_STALL
4054 && memory_operand (operands[0], XFmode))
4055 || !TARGET_HARD_XF_REGS)"
4056 {
4057 switch (get_attr_type (insn))
4058 {
4059 case TYPE_FMOV:
4060 if (which_alternative == 2)
4061 return standard_80387_constant_opcode (operands[1]);
4062 return output_387_reg_move (insn, operands);
4063
4064 case TYPE_MULTI:
4065 return "#";
4066
4067 default:
4068 gcc_unreachable ();
4069 }
4070 }
4071 [(set (attr "isa")
4072 (cond [(eq_attr "alternative" "7,10")
4073 (const_string "nox64")
4074 (eq_attr "alternative" "8,11")
4075 (const_string "x64")
4076 ]
4077 (const_string "*")))
4078 (set (attr "type")
4079 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4080 (const_string "multi")
4081 ]
4082 (const_string "fmov")))
4083 (set (attr "mode")
4084 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
4085 (if_then_else (match_test "TARGET_64BIT")
4086 (const_string "DI")
4087 (const_string "SI"))
4088 ]
4089 (const_string "XF")))
4090 (set (attr "preferred_for_size")
4091 (cond [(eq_attr "alternative" "3,4")
4092 (symbol_ref "false")]
4093 (symbol_ref "true")))
4094 (set (attr "enabled")
4095 (cond [(eq_attr "alternative" "9,10,11")
4096 (if_then_else
4097 (match_test "TARGET_HARD_XF_REGS")
4098 (symbol_ref "false")
4099 (const_string "*"))
4100 (not (match_test "TARGET_HARD_XF_REGS"))
4101 (symbol_ref "false")
4102 ]
4103 (const_string "*")))])
4104
4105 (define_split
4106 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
4107 (match_operand:XF 1 "general_gr_operand"))]
4108 "reload_completed"
4109 [(const_int 0)]
4110 "ix86_split_long_move (operands); DONE;")
4111
4112 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
4113 (define_insn "*movdf_internal"
4114 [(set (match_operand:DF 0 "nonimmediate_operand"
4115 "=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")
4116 (match_operand:DF 1 "general_operand"
4117 "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"))]
4118 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4119 && (lra_in_progress || reload_completed
4120 || !CONST_DOUBLE_P (operands[1])
4121 || ((optimize_function_for_size_p (cfun)
4122 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4123 && IS_STACK_MODE (DFmode)
4124 && standard_80387_constant_p (operands[1]) > 0
4125 && !memory_operand (operands[0], DFmode))
4126 || (TARGET_SSE2 && TARGET_SSE_MATH
4127 && standard_sse_constant_p (operands[1], DFmode) == 1
4128 && !memory_operand (operands[0], DFmode))
4129 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4130 && memory_operand (operands[0], DFmode))
4131 || !TARGET_HARD_DF_REGS)"
4132 {
4133 switch (get_attr_type (insn))
4134 {
4135 case TYPE_FMOV:
4136 if (which_alternative == 2)
4137 return standard_80387_constant_opcode (operands[1]);
4138 return output_387_reg_move (insn, operands);
4139
4140 case TYPE_MULTI:
4141 return "#";
4142
4143 case TYPE_IMOV:
4144 if (get_attr_mode (insn) == MODE_SI)
4145 return "mov{l}\t{%1, %k0|%k0, %1}";
4146 else if (which_alternative == 11)
4147 return "movabs{q}\t{%1, %0|%0, %1}";
4148 else
4149 return "mov{q}\t{%1, %0|%0, %1}";
4150
4151 case TYPE_SSELOG1:
4152 return standard_sse_constant_opcode (insn, operands);
4153
4154 case TYPE_SSEMOV:
4155 return ix86_output_ssemov (insn, operands);
4156
4157 default:
4158 gcc_unreachable ();
4159 }
4160 }
4161 [(set (attr "isa")
4162 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4163 (const_string "nox64")
4164 (eq_attr "alternative" "8,9,10,11,24,25")
4165 (const_string "x64")
4166 (eq_attr "alternative" "12,13,14,15")
4167 (const_string "sse2")
4168 (eq_attr "alternative" "20,21")
4169 (const_string "x64_sse2")
4170 ]
4171 (const_string "*")))
4172 (set (attr "type")
4173 (cond [(eq_attr "alternative" "0,1,2")
4174 (const_string "fmov")
4175 (eq_attr "alternative" "3,4,5,6,7,22,23")
4176 (const_string "multi")
4177 (eq_attr "alternative" "8,9,10,11,24,25")
4178 (const_string "imov")
4179 (eq_attr "alternative" "12,16")
4180 (const_string "sselog1")
4181 ]
4182 (const_string "ssemov")))
4183 (set (attr "modrm")
4184 (if_then_else (eq_attr "alternative" "11")
4185 (const_string "0")
4186 (const_string "*")))
4187 (set (attr "length_immediate")
4188 (if_then_else (eq_attr "alternative" "11")
4189 (const_string "8")
4190 (const_string "*")))
4191 (set (attr "prefix")
4192 (if_then_else (eq_attr "type" "sselog1,ssemov")
4193 (const_string "maybe_vex")
4194 (const_string "orig")))
4195 (set (attr "prefix_data16")
4196 (if_then_else
4197 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4198 (eq_attr "mode" "V1DF"))
4199 (const_string "1")
4200 (const_string "*")))
4201 (set (attr "mode")
4202 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4203 (const_string "SI")
4204 (eq_attr "alternative" "8,9,11,20,21,24,25")
4205 (const_string "DI")
4206
4207 /* xorps is one byte shorter for non-AVX targets. */
4208 (eq_attr "alternative" "12,16")
4209 (cond [(match_test "TARGET_AVX")
4210 (const_string "V2DF")
4211 (ior (not (match_test "TARGET_SSE2"))
4212 (match_test "optimize_function_for_size_p (cfun)"))
4213 (const_string "V4SF")
4214 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4215 (const_string "TI")
4216 ]
4217 (const_string "V2DF"))
4218
4219 /* For architectures resolving dependencies on
4220 whole SSE registers use movapd to break dependency
4221 chains, otherwise use short move to avoid extra work. */
4222
4223 /* movaps is one byte shorter for non-AVX targets. */
4224 (eq_attr "alternative" "13,17")
4225 (cond [(match_test "TARGET_AVX512VL")
4226 (const_string "V2DF")
4227 (match_test "TARGET_AVX512F")
4228 (const_string "DF")
4229 (match_test "TARGET_AVX")
4230 (const_string "V2DF")
4231 (ior (not (match_test "TARGET_SSE2"))
4232 (match_test "optimize_function_for_size_p (cfun)"))
4233 (const_string "V4SF")
4234 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4235 (const_string "V4SF")
4236 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4237 (const_string "V2DF")
4238 ]
4239 (const_string "DF"))
4240
4241 /* For architectures resolving dependencies on register
4242 parts we may avoid extra work to zero out upper part
4243 of register. */
4244 (eq_attr "alternative" "14,18")
4245 (cond [(not (match_test "TARGET_SSE2"))
4246 (const_string "V2SF")
4247 (match_test "TARGET_AVX")
4248 (const_string "DF")
4249 (match_test "TARGET_SSE_SPLIT_REGS")
4250 (const_string "V1DF")
4251 ]
4252 (const_string "DF"))
4253
4254 (and (eq_attr "alternative" "15,19")
4255 (not (match_test "TARGET_SSE2")))
4256 (const_string "V2SF")
4257 ]
4258 (const_string "DF")))
4259 (set (attr "preferred_for_size")
4260 (cond [(eq_attr "alternative" "3,4")
4261 (symbol_ref "false")]
4262 (symbol_ref "true")))
4263 (set (attr "preferred_for_speed")
4264 (cond [(eq_attr "alternative" "3,4")
4265 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4266 (eq_attr "alternative" "20")
4267 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4268 (eq_attr "alternative" "21")
4269 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4270 ]
4271 (symbol_ref "true")))
4272 (set (attr "enabled")
4273 (cond [(eq_attr "alternative" "22,23,24,25")
4274 (if_then_else
4275 (match_test "TARGET_HARD_DF_REGS")
4276 (symbol_ref "false")
4277 (const_string "*"))
4278 (not (match_test "TARGET_HARD_DF_REGS"))
4279 (symbol_ref "false")
4280 ]
4281 (const_string "*")))])
4282
4283 (define_split
4284 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4285 (match_operand:DF 1 "general_gr_operand"))]
4286 "!TARGET_64BIT && reload_completed"
4287 [(const_int 0)]
4288 "ix86_split_long_move (operands); DONE;")
4289
4290 (define_insn "*movsf_internal"
4291 [(set (match_operand:SF 0 "nonimmediate_operand"
4292 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4293 (match_operand:SF 1 "general_operand"
4294 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4295 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4296 && (lra_in_progress || reload_completed
4297 || !CONST_DOUBLE_P (operands[1])
4298 || ((optimize_function_for_size_p (cfun)
4299 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4300 && IS_STACK_MODE (SFmode)
4301 && standard_80387_constant_p (operands[1]) > 0)
4302 || (TARGET_SSE && TARGET_SSE_MATH
4303 && standard_sse_constant_p (operands[1], SFmode) == 1)
4304 || memory_operand (operands[0], SFmode)
4305 || !TARGET_HARD_SF_REGS)"
4306 {
4307 switch (get_attr_type (insn))
4308 {
4309 case TYPE_FMOV:
4310 if (which_alternative == 2)
4311 return standard_80387_constant_opcode (operands[1]);
4312 return output_387_reg_move (insn, operands);
4313
4314 case TYPE_IMOV:
4315 return "mov{l}\t{%1, %0|%0, %1}";
4316
4317 case TYPE_SSELOG1:
4318 return standard_sse_constant_opcode (insn, operands);
4319
4320 case TYPE_SSEMOV:
4321 return ix86_output_ssemov (insn, operands);
4322
4323 case TYPE_MMXMOV:
4324 switch (get_attr_mode (insn))
4325 {
4326 case MODE_DI:
4327 return "movq\t{%1, %0|%0, %1}";
4328 case MODE_SI:
4329 return "movd\t{%1, %0|%0, %1}";
4330
4331 default:
4332 gcc_unreachable ();
4333 }
4334
4335 default:
4336 gcc_unreachable ();
4337 }
4338 }
4339 [(set (attr "isa")
4340 (cond [(eq_attr "alternative" "9,10")
4341 (const_string "sse2")
4342 ]
4343 (const_string "*")))
4344 (set (attr "type")
4345 (cond [(eq_attr "alternative" "0,1,2")
4346 (const_string "fmov")
4347 (eq_attr "alternative" "3,4,16,17")
4348 (const_string "imov")
4349 (eq_attr "alternative" "5")
4350 (const_string "sselog1")
4351 (eq_attr "alternative" "11,12,13,14,15")
4352 (const_string "mmxmov")
4353 ]
4354 (const_string "ssemov")))
4355 (set (attr "prefix")
4356 (if_then_else (eq_attr "type" "sselog1,ssemov")
4357 (const_string "maybe_vex")
4358 (const_string "orig")))
4359 (set (attr "prefix_data16")
4360 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4361 (const_string "1")
4362 (const_string "*")))
4363 (set (attr "mode")
4364 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4365 (const_string "SI")
4366 (eq_attr "alternative" "11")
4367 (const_string "DI")
4368 (eq_attr "alternative" "5")
4369 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4370 (not (match_test "TARGET_PREFER_AVX256")))
4371 (const_string "V16SF")
4372 (match_test "TARGET_AVX")
4373 (const_string "V4SF")
4374 (ior (not (match_test "TARGET_SSE2"))
4375 (match_test "optimize_function_for_size_p (cfun)"))
4376 (const_string "V4SF")
4377 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4378 (const_string "TI")
4379 ]
4380 (const_string "V4SF"))
4381
4382 /* For architectures resolving dependencies on
4383 whole SSE registers use APS move to break dependency
4384 chains, otherwise use short move to avoid extra work.
4385
4386 Do the same for architectures resolving dependencies on
4387 the parts. While in DF mode it is better to always handle
4388 just register parts, the SF mode is different due to lack
4389 of instructions to load just part of the register. It is
4390 better to maintain the whole registers in single format
4391 to avoid problems on using packed logical operations. */
4392 (eq_attr "alternative" "6")
4393 (cond [(match_test "TARGET_AVX512VL")
4394 (const_string "V4SF")
4395 (match_test "TARGET_AVX512F")
4396 (const_string "SF")
4397 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4398 (match_test "TARGET_SSE_SPLIT_REGS"))
4399 (const_string "V4SF")
4400 ]
4401 (const_string "SF"))
4402 ]
4403 (const_string "SF")))
4404 (set (attr "preferred_for_speed")
4405 (cond [(eq_attr "alternative" "9,14")
4406 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4407 (eq_attr "alternative" "10,15")
4408 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4409 ]
4410 (symbol_ref "true")))
4411 (set (attr "enabled")
4412 (cond [(eq_attr "alternative" "16,17")
4413 (if_then_else
4414 (match_test "TARGET_HARD_SF_REGS")
4415 (symbol_ref "false")
4416 (const_string "*"))
4417 (not (match_test "TARGET_HARD_SF_REGS"))
4418 (symbol_ref "false")
4419 ]
4420 (const_string "*")))])
4421
4422 (define_mode_attr hfbfconstf
4423 [(HF "F") (BF "")])
4424
4425 (define_insn "*mov<mode>_internal"
4426 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4427 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4428 (match_operand:HFBF 1 "general_operand"
4429 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4430 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4431 && (lra_in_progress
4432 || reload_completed
4433 || !CONST_DOUBLE_P (operands[1])
4434 || (TARGET_SSE2
4435 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4436 || memory_operand (operands[0], <MODE>mode))"
4437 {
4438 switch (get_attr_type (insn))
4439 {
4440 case TYPE_IMOVX:
4441 /* movzwl is faster than movw on p2 due to partial word stalls,
4442 though not as fast as an aligned movl. */
4443 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4444
4445 case TYPE_SSEMOV:
4446 return ix86_output_ssemov (insn, operands);
4447
4448 case TYPE_SSELOG1:
4449 if (satisfies_constraint_C (operands[1]))
4450 return standard_sse_constant_opcode (insn, operands);
4451
4452 if (SSE_REG_P (operands[0]))
4453 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4454 else
4455 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4456
4457 default:
4458 if (get_attr_mode (insn) == MODE_SI)
4459 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4460 else
4461 return "mov{w}\t{%1, %0|%0, %1}";
4462 }
4463 }
4464 [(set (attr "isa")
4465 (cond [(eq_attr "alternative" "4,5,6,9,10")
4466 (const_string "sse2")
4467 (eq_attr "alternative" "7")
4468 (const_string "sse4_noavx")
4469 (eq_attr "alternative" "8")
4470 (const_string "avx")
4471 ]
4472 (const_string "*")))
4473 (set (attr "gpr32")
4474 (if_then_else (eq_attr "alternative" "8")
4475 (const_string "0")
4476 (const_string "1")))
4477 (set (attr "type")
4478 (cond [(eq_attr "alternative" "4")
4479 (const_string "sselog1")
4480 (eq_attr "alternative" "5,6,9")
4481 (const_string "ssemov")
4482 (eq_attr "alternative" "7,8,10")
4483 (if_then_else
4484 (match_test ("TARGET_AVX512FP16"))
4485 (const_string "ssemov")
4486 (const_string "sselog1"))
4487 (match_test "optimize_function_for_size_p (cfun)")
4488 (const_string "imov")
4489 (and (eq_attr "alternative" "0")
4490 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4491 (not (match_test "TARGET_HIMODE_MATH"))))
4492 (const_string "imov")
4493 (and (eq_attr "alternative" "1,2")
4494 (match_operand:HI 1 "aligned_operand"))
4495 (const_string "imov")
4496 (and (match_test "TARGET_MOVX")
4497 (eq_attr "alternative" "0,2"))
4498 (const_string "imovx")
4499 ]
4500 (const_string "imov")))
4501 (set (attr "prefix")
4502 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4503 (const_string "maybe_vex")
4504 ]
4505 (const_string "orig")))
4506 (set (attr "mode")
4507 (cond [(eq_attr "alternative" "4")
4508 (const_string "V4SF")
4509 (eq_attr "alternative" "6,9")
4510 (if_then_else
4511 (match_test "TARGET_AVX512FP16")
4512 (const_string "HI")
4513 (const_string "SI"))
4514 (eq_attr "alternative" "7,8,10")
4515 (if_then_else
4516 (match_test "TARGET_AVX512FP16")
4517 (const_string "HI")
4518 (const_string "TI"))
4519 (eq_attr "alternative" "5")
4520 (cond [(match_test "TARGET_AVX512VL")
4521 (const_string "V4SF")
4522 (match_test "TARGET_AVX512FP16")
4523 (const_string "HF")
4524 (match_test "TARGET_AVX512F")
4525 (const_string "SF")
4526 (match_test "TARGET_AVX")
4527 (const_string "V4SF")
4528 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4529 (match_test "TARGET_SSE_SPLIT_REGS"))
4530 (const_string "V4SF")
4531 ]
4532 (const_string "SF"))
4533 (eq_attr "type" "imovx")
4534 (const_string "SI")
4535 (and (eq_attr "alternative" "1,2")
4536 (match_operand:HI 1 "aligned_operand"))
4537 (const_string "SI")
4538 (and (eq_attr "alternative" "0")
4539 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4540 (not (match_test "TARGET_HIMODE_MATH"))))
4541 (const_string "SI")
4542 ]
4543 (const_string "HI")))
4544 (set (attr "enabled")
4545 (cond [(and (match_test "<MODE>mode == BFmode")
4546 (eq_attr "alternative" "1"))
4547 (symbol_ref "false")
4548 ]
4549 (const_string "*")))])
4550
4551 (define_split
4552 [(set (match_operand 0 "any_fp_register_operand")
4553 (match_operand 1 "memory_operand"))]
4554 "reload_completed
4555 && (GET_MODE (operands[0]) == TFmode
4556 || GET_MODE (operands[0]) == XFmode
4557 || GET_MODE (operands[0]) == DFmode
4558 || GET_MODE (operands[0]) == SFmode)
4559 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4560 [(set (match_dup 0) (match_dup 2))]
4561 "operands[2] = find_constant_src (curr_insn);")
4562
4563 (define_split
4564 [(set (match_operand 0 "any_fp_register_operand")
4565 (float_extend (match_operand 1 "memory_operand")))]
4566 "reload_completed
4567 && (GET_MODE (operands[0]) == TFmode
4568 || GET_MODE (operands[0]) == XFmode
4569 || GET_MODE (operands[0]) == DFmode)
4570 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4571 [(set (match_dup 0) (match_dup 2))]
4572 "operands[2] = find_constant_src (curr_insn);")
4573
4574 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4575 (define_split
4576 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4577 (match_operand:X87MODEF 1 "immediate_operand"))]
4578 "reload_completed
4579 && (standard_80387_constant_p (operands[1]) == 8
4580 || standard_80387_constant_p (operands[1]) == 9)"
4581 [(set (match_dup 0)(match_dup 1))
4582 (set (match_dup 0)
4583 (neg:X87MODEF (match_dup 0)))]
4584 {
4585 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4586 operands[1] = CONST0_RTX (<MODE>mode);
4587 else
4588 operands[1] = CONST1_RTX (<MODE>mode);
4589 })
4590
4591 (define_insn "*swapxf"
4592 [(set (match_operand:XF 0 "register_operand" "+f")
4593 (match_operand:XF 1 "register_operand" "+f"))
4594 (set (match_dup 1)
4595 (match_dup 0))]
4596 "TARGET_80387"
4597 {
4598 if (STACK_TOP_P (operands[0]))
4599 return "fxch\t%1";
4600 else
4601 return "fxch\t%0";
4602 }
4603 [(set_attr "type" "fxch")
4604 (set_attr "mode" "XF")])
4605 \f
4606
4607 ;; Zero extension instructions
4608
4609 (define_insn_and_split "zero_extendditi2"
4610 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4611 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4612 "TARGET_64BIT"
4613 "#"
4614 "&& reload_completed"
4615 [(set (match_dup 3) (match_dup 1))
4616 (set (match_dup 4) (const_int 0))]
4617 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4618
4619 (define_expand "zero_extendsidi2"
4620 [(set (match_operand:DI 0 "nonimmediate_operand")
4621 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4622
4623 (define_insn "*zero_extendsidi2"
4624 [(set (match_operand:DI 0 "nonimmediate_operand"
4625 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4626 (zero_extend:DI
4627 (match_operand:SI 1 "x86_64_zext_operand"
4628 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4629 ""
4630 {
4631 switch (get_attr_type (insn))
4632 {
4633 case TYPE_IMOVX:
4634 if (ix86_use_lea_for_mov (insn, operands))
4635 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4636 else
4637 return "mov{l}\t{%1, %k0|%k0, %1}";
4638
4639 case TYPE_MULTI:
4640 return "#";
4641
4642 case TYPE_MMXMOV:
4643 return "movd\t{%1, %0|%0, %1}";
4644
4645 case TYPE_SSEMOV:
4646 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4647 {
4648 if (EXT_REX_SSE_REG_P (operands[0])
4649 || EXT_REX_SSE_REG_P (operands[1]))
4650 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4651 else
4652 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4653 }
4654
4655 if (GENERAL_REG_P (operands[0]))
4656 return "%vmovd\t{%1, %k0|%k0, %1}";
4657
4658 return "%vmovd\t{%1, %0|%0, %1}";
4659
4660 case TYPE_MSKMOV:
4661 return "kmovd\t{%1, %k0|%k0, %1}";
4662
4663 default:
4664 gcc_unreachable ();
4665 }
4666 }
4667 [(set (attr "isa")
4668 (cond [(eq_attr "alternative" "0,1,2")
4669 (const_string "nox64")
4670 (eq_attr "alternative" "3")
4671 (const_string "x64")
4672 (eq_attr "alternative" "7,8,9")
4673 (const_string "sse2")
4674 (eq_attr "alternative" "10")
4675 (const_string "sse4")
4676 (eq_attr "alternative" "11")
4677 (const_string "avx512f")
4678 (eq_attr "alternative" "12")
4679 (const_string "x64_avx512bw")
4680 (eq_attr "alternative" "13")
4681 (const_string "avx512bw_512")
4682 ]
4683 (const_string "*")))
4684 (set (attr "mmx_isa")
4685 (if_then_else (eq_attr "alternative" "5,6")
4686 (const_string "native")
4687 (const_string "*")))
4688 (set (attr "type")
4689 (cond [(eq_attr "alternative" "0,1,2,4")
4690 (const_string "multi")
4691 (eq_attr "alternative" "5,6")
4692 (const_string "mmxmov")
4693 (eq_attr "alternative" "7")
4694 (if_then_else (match_test "TARGET_64BIT")
4695 (const_string "ssemov")
4696 (const_string "multi"))
4697 (eq_attr "alternative" "8,9,10,11")
4698 (const_string "ssemov")
4699 (eq_attr "alternative" "12,13")
4700 (const_string "mskmov")
4701 ]
4702 (const_string "imovx")))
4703 (set (attr "prefix_extra")
4704 (if_then_else (eq_attr "alternative" "10,11")
4705 (const_string "1")
4706 (const_string "*")))
4707 (set (attr "prefix")
4708 (if_then_else (eq_attr "type" "ssemov")
4709 (const_string "maybe_vex")
4710 (const_string "orig")))
4711 (set (attr "prefix_0f")
4712 (if_then_else (eq_attr "type" "imovx")
4713 (const_string "0")
4714 (const_string "*")))
4715 (set (attr "mode")
4716 (cond [(eq_attr "alternative" "5,6")
4717 (const_string "DI")
4718 (and (eq_attr "alternative" "7")
4719 (match_test "TARGET_64BIT"))
4720 (const_string "TI")
4721 (eq_attr "alternative" "8,10,11")
4722 (const_string "TI")
4723 ]
4724 (const_string "SI")))
4725 (set (attr "preferred_for_speed")
4726 (cond [(eq_attr "alternative" "7")
4727 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4728 (eq_attr "alternative" "5,8")
4729 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4730 ]
4731 (symbol_ref "true")))])
4732
4733 (define_split
4734 [(set (match_operand:DI 0 "memory_operand")
4735 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4736 "reload_completed"
4737 [(set (match_dup 4) (const_int 0))]
4738 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4739
4740 (define_split
4741 [(set (match_operand:DI 0 "general_reg_operand")
4742 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4743 "!TARGET_64BIT && reload_completed
4744 && REGNO (operands[0]) == REGNO (operands[1])"
4745 [(set (match_dup 4) (const_int 0))]
4746 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4747
4748 (define_split
4749 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4750 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4751 "!TARGET_64BIT && reload_completed
4752 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4753 [(set (match_dup 3) (match_dup 1))
4754 (set (match_dup 4) (const_int 0))]
4755 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4756
4757 (define_mode_attr kmov_isa
4758 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4759
4760 (define_insn "zero_extend<mode>di2"
4761 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4762 (zero_extend:DI
4763 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4764 "TARGET_64BIT"
4765 "@
4766 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4767 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4768 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4769 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4770 (set_attr "type" "imovx,mskmov,mskmov")
4771 (set_attr "mode" "SI,<MODE>,<MODE>")])
4772
4773 (define_expand "zero_extend<mode>si2"
4774 [(set (match_operand:SI 0 "register_operand")
4775 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4776 ""
4777 {
4778 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4779 {
4780 operands[1] = force_reg (<MODE>mode, operands[1]);
4781 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4782 DONE;
4783 }
4784 })
4785
4786 (define_insn_and_split "zero_extend<mode>si2_and"
4787 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4788 (zero_extend:SI
4789 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4792 "#"
4793 "&& reload_completed"
4794 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4795 (clobber (reg:CC FLAGS_REG))])]
4796 {
4797 if (!REG_P (operands[1])
4798 || REGNO (operands[0]) != REGNO (operands[1]))
4799 {
4800 ix86_expand_clear (operands[0]);
4801
4802 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4803 emit_insn (gen_rtx_SET
4804 (gen_rtx_STRICT_LOW_PART
4805 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4806 operands[1]));
4807 DONE;
4808 }
4809
4810 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4811 }
4812 [(set_attr "type" "alu1")
4813 (set_attr "mode" "SI")])
4814
4815 (define_insn "*zero_extend<mode>si2"
4816 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4817 (zero_extend:SI
4818 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4819 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4820 "@
4821 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4822 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4823 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4824 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4825 (set_attr "type" "imovx,mskmov,mskmov")
4826 (set_attr "mode" "SI,<MODE>,<MODE>")])
4827
4828 (define_expand "zero_extendqihi2"
4829 [(set (match_operand:HI 0 "register_operand")
4830 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4831 ""
4832 {
4833 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4834 {
4835 operands[1] = force_reg (QImode, operands[1]);
4836 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4837 DONE;
4838 }
4839 })
4840
4841 (define_insn_and_split "zero_extendqihi2_and"
4842 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4843 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4844 (clobber (reg:CC FLAGS_REG))]
4845 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4846 "#"
4847 "&& reload_completed"
4848 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4849 (clobber (reg:CC FLAGS_REG))])]
4850 {
4851 if (!REG_P (operands[1])
4852 || REGNO (operands[0]) != REGNO (operands[1]))
4853 {
4854 ix86_expand_clear (operands[0]);
4855
4856 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4857 emit_insn (gen_rtx_SET
4858 (gen_rtx_STRICT_LOW_PART
4859 (VOIDmode, gen_lowpart (QImode, operands[0])),
4860 operands[1]));
4861 DONE;
4862 }
4863
4864 operands[0] = gen_lowpart (SImode, operands[0]);
4865 }
4866 [(set_attr "type" "alu1")
4867 (set_attr "mode" "SI")])
4868
4869 ; zero extend to SImode to avoid partial register stalls
4870 (define_insn "*zero_extendqihi2"
4871 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4872 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4873 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4874 "@
4875 movz{bl|x}\t{%1, %k0|%k0, %1}
4876 kmovb\t{%1, %k0|%k0, %1}
4877 kmovb\t{%1, %0|%0, %1}"
4878 [(set_attr "isa" "*,avx512dq,avx512dq")
4879 (set_attr "type" "imovx,mskmov,mskmov")
4880 (set_attr "mode" "SI,QI,QI")])
4881
4882 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4883 (define_peephole2
4884 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4885 (const_int 0))
4886 (clobber (reg:CC FLAGS_REG))])
4887 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4888 (match_operand:SWI12 2 "nonimmediate_operand"))]
4889 "REGNO (operands[0]) == REGNO (operands[1])
4890 && (<SWI48:MODE>mode != SImode
4891 || !TARGET_ZERO_EXTEND_WITH_AND
4892 || !optimize_function_for_speed_p (cfun))"
4893 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4894
4895 ;; Likewise, but preserving FLAGS_REG.
4896 (define_peephole2
4897 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4898 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4899 (match_operand:SWI12 2 "nonimmediate_operand"))]
4900 "REGNO (operands[0]) == REGNO (operands[1])
4901 && (<SWI48:MODE>mode != SImode
4902 || !TARGET_ZERO_EXTEND_WITH_AND
4903 || !optimize_function_for_speed_p (cfun))"
4904 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4905 \f
4906 ;; Sign extension instructions
4907
4908 (define_expand "extendsidi2"
4909 [(set (match_operand:DI 0 "register_operand")
4910 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4911 ""
4912 {
4913 if (!TARGET_64BIT)
4914 {
4915 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4916 DONE;
4917 }
4918 })
4919
4920 (define_insn "*extendsidi2_rex64"
4921 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4922 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4923 "TARGET_64BIT"
4924 "@
4925 {cltq|cdqe}
4926 movs{lq|x}\t{%1, %0|%0, %1}"
4927 [(set_attr "type" "imovx")
4928 (set_attr "mode" "DI")
4929 (set_attr "prefix_0f" "0")
4930 (set_attr "modrm" "0,1")])
4931
4932 (define_insn "extendsidi2_1"
4933 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4934 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4935 (clobber (reg:CC FLAGS_REG))
4936 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4937 "!TARGET_64BIT"
4938 "#")
4939
4940 (define_insn "extendditi2"
4941 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4942 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4943 (clobber (reg:CC FLAGS_REG))
4944 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4945 "TARGET_64BIT"
4946 "#")
4947
4948 ;; Split the memory case. If the source register doesn't die, it will stay
4949 ;; this way, if it does die, following peephole2s take care of it.
4950 (define_split
4951 [(set (match_operand:<DWI> 0 "memory_operand")
4952 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4953 (clobber (reg:CC FLAGS_REG))
4954 (clobber (match_operand:DWIH 2 "register_operand"))]
4955 "reload_completed"
4956 [(const_int 0)]
4957 {
4958 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4959
4960 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4961
4962 emit_move_insn (operands[3], operands[1]);
4963
4964 /* Generate a cltd if possible and doing so it profitable. */
4965 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4966 && REGNO (operands[1]) == AX_REG
4967 && REGNO (operands[2]) == DX_REG)
4968 {
4969 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4970 }
4971 else
4972 {
4973 emit_move_insn (operands[2], operands[1]);
4974 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4975 }
4976 emit_move_insn (operands[4], operands[2]);
4977 DONE;
4978 })
4979
4980 ;; Peepholes for the case where the source register does die, after
4981 ;; being split with the above splitter.
4982 (define_peephole2
4983 [(set (match_operand:DWIH 0 "memory_operand")
4984 (match_operand:DWIH 1 "general_reg_operand"))
4985 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4986 (parallel [(set (match_dup 2)
4987 (ashiftrt:DWIH (match_dup 2)
4988 (match_operand 4 "const_int_operand")))
4989 (clobber (reg:CC FLAGS_REG))])
4990 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4991 "REGNO (operands[1]) != REGNO (operands[2])
4992 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4993 && peep2_reg_dead_p (2, operands[1])
4994 && peep2_reg_dead_p (4, operands[2])
4995 && !reg_mentioned_p (operands[2], operands[3])"
4996 [(set (match_dup 0) (match_dup 1))
4997 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4998 (clobber (reg:CC FLAGS_REG))])
4999 (set (match_dup 3) (match_dup 1))])
5000
5001 (define_peephole2
5002 [(set (match_operand:DWIH 0 "memory_operand")
5003 (match_operand:DWIH 1 "general_reg_operand"))
5004 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
5005 (ashiftrt:DWIH (match_dup 1)
5006 (match_operand 4 "const_int_operand")))
5007 (clobber (reg:CC FLAGS_REG))])
5008 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
5009 "/* cltd is shorter than sarl $31, %eax */
5010 !optimize_function_for_size_p (cfun)
5011 && REGNO (operands[1]) == AX_REG
5012 && REGNO (operands[2]) == DX_REG
5013 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
5014 && peep2_reg_dead_p (2, operands[1])
5015 && peep2_reg_dead_p (3, operands[2])
5016 && !reg_mentioned_p (operands[2], operands[3])"
5017 [(set (match_dup 0) (match_dup 1))
5018 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
5019 (clobber (reg:CC FLAGS_REG))])
5020 (set (match_dup 3) (match_dup 1))])
5021
5022 ;; Extend to register case. Optimize case where source and destination
5023 ;; registers match and cases where we can use cltd.
5024 (define_split
5025 [(set (match_operand:<DWI> 0 "register_operand")
5026 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
5027 (clobber (reg:CC FLAGS_REG))
5028 (clobber (match_scratch:DWIH 2))]
5029 "reload_completed"
5030 [(const_int 0)]
5031 {
5032 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
5033
5034 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
5035
5036 if (REGNO (operands[3]) != REGNO (operands[1]))
5037 emit_move_insn (operands[3], operands[1]);
5038
5039 rtx src = operands[1];
5040 if (REGNO (operands[3]) == AX_REG)
5041 src = operands[3];
5042
5043 /* Generate a cltd if possible and doing so it profitable. */
5044 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
5045 && REGNO (src) == AX_REG
5046 && REGNO (operands[4]) == DX_REG)
5047 {
5048 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
5049 DONE;
5050 }
5051
5052 if (REGNO (operands[4]) != REGNO (operands[1]))
5053 emit_move_insn (operands[4], operands[1]);
5054
5055 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
5056 DONE;
5057 })
5058
5059 (define_insn "extend<mode>di2"
5060 [(set (match_operand:DI 0 "register_operand" "=r")
5061 (sign_extend:DI
5062 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
5063 "TARGET_64BIT"
5064 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
5065 [(set_attr "type" "imovx")
5066 (set_attr "mode" "DI")])
5067
5068 (define_insn "extendhisi2"
5069 [(set (match_operand:SI 0 "register_operand" "=*a,r")
5070 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
5071 ""
5072 {
5073 switch (get_attr_prefix_0f (insn))
5074 {
5075 case 0:
5076 return "{cwtl|cwde}";
5077 default:
5078 return "movs{wl|x}\t{%1, %0|%0, %1}";
5079 }
5080 }
5081 [(set_attr "type" "imovx")
5082 (set_attr "mode" "SI")
5083 (set (attr "prefix_0f")
5084 ;; movsx is short decodable while cwtl is vector decoded.
5085 (if_then_else (and (eq_attr "cpu" "!k6")
5086 (eq_attr "alternative" "0"))
5087 (const_string "0")
5088 (const_string "1")))
5089 (set (attr "znver1_decode")
5090 (if_then_else (eq_attr "prefix_0f" "0")
5091 (const_string "double")
5092 (const_string "direct")))
5093 (set (attr "modrm")
5094 (if_then_else (eq_attr "prefix_0f" "0")
5095 (const_string "0")
5096 (const_string "1")))])
5097
5098 (define_insn "*extendhisi2_zext"
5099 [(set (match_operand:DI 0 "register_operand" "=*a,r")
5100 (zero_extend:DI
5101 (sign_extend:SI
5102 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
5103 "TARGET_64BIT"
5104 {
5105 switch (get_attr_prefix_0f (insn))
5106 {
5107 case 0:
5108 return "{cwtl|cwde}";
5109 default:
5110 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
5111 }
5112 }
5113 [(set_attr "type" "imovx")
5114 (set_attr "mode" "SI")
5115 (set (attr "prefix_0f")
5116 ;; movsx is short decodable while cwtl is vector decoded.
5117 (if_then_else (and (eq_attr "cpu" "!k6")
5118 (eq_attr "alternative" "0"))
5119 (const_string "0")
5120 (const_string "1")))
5121 (set (attr "modrm")
5122 (if_then_else (eq_attr "prefix_0f" "0")
5123 (const_string "0")
5124 (const_string "1")))])
5125
5126 (define_insn "extendqisi2"
5127 [(set (match_operand:SI 0 "register_operand" "=r")
5128 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5129 ""
5130 "movs{bl|x}\t{%1, %0|%0, %1}"
5131 [(set_attr "type" "imovx")
5132 (set_attr "mode" "SI")])
5133
5134 (define_insn "*extendqisi2_zext"
5135 [(set (match_operand:DI 0 "register_operand" "=r")
5136 (zero_extend:DI
5137 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5138 "TARGET_64BIT"
5139 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5140 [(set_attr "type" "imovx")
5141 (set_attr "mode" "SI")])
5142
5143 (define_insn "extendqihi2"
5144 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5145 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5146 ""
5147 {
5148 switch (get_attr_prefix_0f (insn))
5149 {
5150 case 0:
5151 return "{cbtw|cbw}";
5152 default:
5153 return "movs{bw|x}\t{%1, %0|%0, %1}";
5154 }
5155 }
5156 [(set_attr "type" "imovx")
5157 (set_attr "mode" "HI")
5158 (set (attr "prefix_0f")
5159 ;; movsx is short decodable while cwtl is vector decoded.
5160 (if_then_else (and (eq_attr "cpu" "!k6")
5161 (eq_attr "alternative" "0"))
5162 (const_string "0")
5163 (const_string "1")))
5164 (set (attr "modrm")
5165 (if_then_else (eq_attr "prefix_0f" "0")
5166 (const_string "0")
5167 (const_string "1")))])
5168
5169 (define_insn "*extendqi<SWI24:mode>_ext_1"
5170 [(set (match_operand:SWI24 0 "register_operand" "=R")
5171 (sign_extend:SWI24
5172 (subreg:QI
5173 (match_operator:SWI248 2 "extract_operator"
5174 [(match_operand 1 "int248_register_operand" "Q")
5175 (const_int 8)
5176 (const_int 8)]) 0)))]
5177 ""
5178 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5179 [(set_attr "type" "imovx")
5180 (set_attr "mode" "<SWI24:MODE>")])
5181 \f
5182 ;; Conversions between float and double.
5183
5184 ;; These are all no-ops in the model used for the 80387.
5185 ;; So just emit moves.
5186
5187 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5188 (define_split
5189 [(set (match_operand:DF 0 "push_operand")
5190 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5191 "reload_completed"
5192 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5193 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5194
5195 (define_split
5196 [(set (match_operand:XF 0 "push_operand")
5197 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5198 "reload_completed"
5199 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5200 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5201 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5202
5203 (define_expand "extendsfdf2"
5204 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5205 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5206 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5207 {
5208 /* ??? Needed for compress_float_constant since all fp constants
5209 are TARGET_LEGITIMATE_CONSTANT_P. */
5210 if (CONST_DOUBLE_P (operands[1]))
5211 {
5212 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5213 && standard_80387_constant_p (operands[1]) > 0)
5214 {
5215 operands[1] = simplify_const_unary_operation
5216 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5217 emit_move_insn_1 (operands[0], operands[1]);
5218 DONE;
5219 }
5220 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5221 }
5222 })
5223
5224 (define_insn "*extendsfdf2"
5225 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5226 (float_extend:DF
5227 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5228 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5229 {
5230 switch (which_alternative)
5231 {
5232 case 0:
5233 case 1:
5234 return output_387_reg_move (insn, operands);
5235
5236 case 2:
5237 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5238 case 3:
5239 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5240
5241 default:
5242 gcc_unreachable ();
5243 }
5244 }
5245 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5246 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5247 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5248 (set_attr "mode" "SF,XF,DF,DF")
5249 (set (attr "enabled")
5250 (if_then_else
5251 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5252 (if_then_else
5253 (eq_attr "alternative" "0,1")
5254 (symbol_ref "TARGET_MIX_SSE_I387")
5255 (symbol_ref "true"))
5256 (if_then_else
5257 (eq_attr "alternative" "0,1")
5258 (symbol_ref "true")
5259 (symbol_ref "false"))))])
5260
5261 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5262 cvtss2sd:
5263 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5264 cvtps2pd xmm2,xmm1
5265 We do the conversion post reload to avoid producing of 128bit spills
5266 that might lead to ICE on 32bit target. The sequence unlikely combine
5267 anyway. */
5268 (define_split
5269 [(set (match_operand:DF 0 "sse_reg_operand")
5270 (float_extend:DF
5271 (match_operand:SF 1 "nonimmediate_operand")))]
5272 "TARGET_USE_VECTOR_FP_CONVERTS
5273 && optimize_insn_for_speed_p ()
5274 && reload_completed
5275 && (!EXT_REX_SSE_REG_P (operands[0])
5276 || TARGET_AVX512VL || TARGET_EVEX512)"
5277 [(set (match_dup 2)
5278 (float_extend:V2DF
5279 (vec_select:V2SF
5280 (match_dup 3)
5281 (parallel [(const_int 0) (const_int 1)]))))]
5282 {
5283 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5284 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5285 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5286 Try to avoid move when unpacking can be done in source. */
5287 if (REG_P (operands[1]))
5288 {
5289 /* If it is unsafe to overwrite upper half of source, we need
5290 to move to destination and unpack there. */
5291 if (REGNO (operands[0]) != REGNO (operands[1])
5292 || (EXT_REX_SSE_REG_P (operands[1])
5293 && !TARGET_AVX512VL))
5294 {
5295 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5296 emit_move_insn (tmp, operands[1]);
5297 }
5298 else
5299 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5300 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5301 =v, v, then vbroadcastss will be only needed for AVX512F without
5302 AVX512VL. */
5303 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5304 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5305 operands[3]));
5306 else
5307 {
5308 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5309 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5310 }
5311 }
5312 else
5313 emit_insn (gen_vec_setv4sf_0 (operands[3],
5314 CONST0_RTX (V4SFmode), operands[1]));
5315 })
5316
5317 ;; It's more profitable to split and then extend in the same register.
5318 (define_peephole2
5319 [(set (match_operand:DF 0 "sse_reg_operand")
5320 (float_extend:DF
5321 (match_operand:SF 1 "memory_operand")))]
5322 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5323 && optimize_insn_for_speed_p ()"
5324 [(set (match_dup 2) (match_dup 1))
5325 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5326 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5327
5328 ;; Break partial SSE register dependency stall. This splitter should split
5329 ;; late in the pass sequence (after register rename pass), so allocated
5330 ;; registers won't change anymore
5331
5332 (define_split
5333 [(set (match_operand:DF 0 "sse_reg_operand")
5334 (float_extend:DF
5335 (match_operand:SF 1 "nonimmediate_operand")))]
5336 "!TARGET_AVX
5337 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5338 && epilogue_completed
5339 && optimize_function_for_speed_p (cfun)
5340 && (!REG_P (operands[1])
5341 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5342 && (!EXT_REX_SSE_REG_P (operands[0])
5343 || TARGET_AVX512VL)"
5344 [(set (match_dup 0)
5345 (vec_merge:V2DF
5346 (vec_duplicate:V2DF
5347 (float_extend:DF
5348 (match_dup 1)))
5349 (match_dup 0)
5350 (const_int 1)))]
5351 {
5352 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5353 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5354 })
5355
5356 (define_expand "extendhfsf2"
5357 [(set (match_operand:SF 0 "register_operand")
5358 (float_extend:SF
5359 (match_operand:HF 1 "nonimmediate_operand")))]
5360 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5361 {
5362 if (!TARGET_AVX512FP16)
5363 {
5364 rtx res = gen_reg_rtx (V4SFmode);
5365 rtx tmp = gen_reg_rtx (V8HFmode);
5366 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5367
5368 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5369 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5370 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5371 DONE;
5372 }
5373 })
5374
5375 (define_expand "extendhfdf2"
5376 [(set (match_operand:DF 0 "register_operand")
5377 (float_extend:DF
5378 (match_operand:HF 1 "nonimmediate_operand")))]
5379 "TARGET_AVX512FP16")
5380
5381 (define_insn "*extendhf<mode>2"
5382 [(set (match_operand:MODEF 0 "register_operand" "=v")
5383 (float_extend:MODEF
5384 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5385 "TARGET_AVX512FP16"
5386 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5387 [(set_attr "type" "ssecvt")
5388 (set_attr "prefix" "evex")
5389 (set_attr "mode" "<MODE>")])
5390
5391 (define_expand "extendbfsf2"
5392 [(set (match_operand:SF 0 "register_operand")
5393 (unspec:SF
5394 [(match_operand:BF 1 "register_operand")]
5395 UNSPEC_CVTBFSF))]
5396 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5397
5398 ;; Don't use float_extend since psrlld doesn't raise
5399 ;; exceptions and turn a sNaN into a qNaN.
5400 (define_insn "extendbfsf2_1"
5401 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5402 (unspec:SF
5403 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5404 UNSPEC_CVTBFSF))]
5405 "TARGET_SSE2"
5406 "@
5407 pslld\t{$16, %0|%0, 16}
5408 vpslld\t{$16, %1, %0|%0, %1, 16}
5409 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5410 [(set_attr "isa" "noavx,avx,*")
5411 (set_attr "type" "sseishft1")
5412 (set_attr "length_immediate" "1")
5413 (set_attr "prefix_data16" "1,*,*")
5414 (set_attr "prefix" "orig,maybe_evex,evex")
5415 (set_attr "mode" "TI,TI,XI")
5416 (set_attr "memory" "none")
5417 (set (attr "enabled")
5418 (if_then_else (eq_attr "alternative" "2")
5419 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5420 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5421 (const_string "*")))])
5422
5423 (define_expand "extend<mode>xf2"
5424 [(set (match_operand:XF 0 "nonimmediate_operand")
5425 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5426 "TARGET_80387"
5427 {
5428 /* ??? Needed for compress_float_constant since all fp constants
5429 are TARGET_LEGITIMATE_CONSTANT_P. */
5430 if (CONST_DOUBLE_P (operands[1]))
5431 {
5432 if (standard_80387_constant_p (operands[1]) > 0)
5433 {
5434 operands[1] = simplify_const_unary_operation
5435 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5436 emit_move_insn_1 (operands[0], operands[1]);
5437 DONE;
5438 }
5439 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5440 }
5441 })
5442
5443 (define_insn "*extend<mode>xf2_i387"
5444 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5445 (float_extend:XF
5446 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5447 "TARGET_80387"
5448 "* return output_387_reg_move (insn, operands);"
5449 [(set_attr "type" "fmov")
5450 (set_attr "mode" "<MODE>,XF")])
5451
5452 ;; %%% This seems like bad news.
5453 ;; This cannot output into an f-reg because there is no way to be sure
5454 ;; of truncating in that case. Otherwise this is just like a simple move
5455 ;; insn. So we pretend we can output to a reg in order to get better
5456 ;; register preferencing, but we really use a stack slot.
5457
5458 ;; Conversion from DFmode to SFmode.
5459
5460 (define_insn "truncdfsf2"
5461 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5462 (float_truncate:SF
5463 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5464 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5465 {
5466 switch (which_alternative)
5467 {
5468 case 0:
5469 case 1:
5470 return output_387_reg_move (insn, operands);
5471
5472 case 2:
5473 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5474 case 3:
5475 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5476
5477 default:
5478 gcc_unreachable ();
5479 }
5480 }
5481 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5482 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5483 (set_attr "mode" "SF")
5484 (set (attr "enabled")
5485 (if_then_else
5486 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5487 (cond [(eq_attr "alternative" "0")
5488 (symbol_ref "TARGET_MIX_SSE_I387")
5489 (eq_attr "alternative" "1")
5490 (symbol_ref "TARGET_MIX_SSE_I387
5491 && flag_unsafe_math_optimizations")
5492 ]
5493 (symbol_ref "true"))
5494 (cond [(eq_attr "alternative" "0")
5495 (symbol_ref "true")
5496 (eq_attr "alternative" "1")
5497 (symbol_ref "flag_unsafe_math_optimizations")
5498 ]
5499 (symbol_ref "false"))))])
5500
5501 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5502 cvtsd2ss:
5503 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5504 cvtpd2ps xmm2,xmm1
5505 We do the conversion post reload to avoid producing of 128bit spills
5506 that might lead to ICE on 32bit target. The sequence unlikely combine
5507 anyway. */
5508 (define_split
5509 [(set (match_operand:SF 0 "sse_reg_operand")
5510 (float_truncate:SF
5511 (match_operand:DF 1 "nonimmediate_operand")))]
5512 "TARGET_USE_VECTOR_FP_CONVERTS
5513 && optimize_insn_for_speed_p ()
5514 && reload_completed
5515 && (!EXT_REX_SSE_REG_P (operands[0])
5516 || TARGET_AVX512VL)"
5517 [(set (match_dup 2)
5518 (vec_concat:V4SF
5519 (float_truncate:V2SF
5520 (match_dup 4))
5521 (match_dup 3)))]
5522 {
5523 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5524 operands[3] = CONST0_RTX (V2SFmode);
5525 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5526 /* Use movsd for loading from memory, unpcklpd for registers.
5527 Try to avoid move when unpacking can be done in source, or SSE3
5528 movddup is available. */
5529 if (REG_P (operands[1]))
5530 {
5531 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5532 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5533 {
5534 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5535 emit_move_insn (tmp, operands[1]);
5536 operands[1] = tmp;
5537 }
5538 else if (!TARGET_SSE3)
5539 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5540 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5541 }
5542 else
5543 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5544 CONST0_RTX (DFmode)));
5545 })
5546
5547 ;; It's more profitable to split and then truncate in the same register.
5548 (define_peephole2
5549 [(set (match_operand:SF 0 "sse_reg_operand")
5550 (float_truncate:SF
5551 (match_operand:DF 1 "memory_operand")))]
5552 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5553 && optimize_insn_for_speed_p ()"
5554 [(set (match_dup 2) (match_dup 1))
5555 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5556 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5557
5558 ;; Break partial SSE register dependency stall. This splitter should split
5559 ;; late in the pass sequence (after register rename pass), so allocated
5560 ;; registers won't change anymore
5561
5562 (define_split
5563 [(set (match_operand:SF 0 "sse_reg_operand")
5564 (float_truncate:SF
5565 (match_operand:DF 1 "nonimmediate_operand")))]
5566 "!TARGET_AVX
5567 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5568 && epilogue_completed
5569 && optimize_function_for_speed_p (cfun)
5570 && (!REG_P (operands[1])
5571 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5572 && (!EXT_REX_SSE_REG_P (operands[0])
5573 || TARGET_AVX512VL)"
5574 [(set (match_dup 0)
5575 (vec_merge:V4SF
5576 (vec_duplicate:V4SF
5577 (float_truncate:SF
5578 (match_dup 1)))
5579 (match_dup 0)
5580 (const_int 1)))]
5581 {
5582 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5583 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5584 })
5585
5586 ;; Conversion from XFmode to {SF,DF}mode
5587
5588 (define_insn "truncxf<mode>2"
5589 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5590 (float_truncate:MODEF
5591 (match_operand:XF 1 "register_operand" "f,f")))]
5592 "TARGET_80387"
5593 "* return output_387_reg_move (insn, operands);"
5594 [(set_attr "type" "fmov")
5595 (set_attr "mode" "<MODE>")
5596 (set (attr "enabled")
5597 (cond [(eq_attr "alternative" "1")
5598 (symbol_ref "flag_unsafe_math_optimizations")
5599 ]
5600 (symbol_ref "true")))])
5601
5602 ;; Conversion from {SF,DF}mode to HFmode.
5603
5604 (define_expand "truncsfhf2"
5605 [(set (match_operand:HF 0 "register_operand")
5606 (float_truncate:HF
5607 (match_operand:SF 1 "nonimmediate_operand")))]
5608 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5609 {
5610 if (!TARGET_AVX512FP16)
5611 {
5612 rtx res = gen_reg_rtx (V8HFmode);
5613 rtx tmp = gen_reg_rtx (V4SFmode);
5614 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5615
5616 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5617 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5618 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5619 DONE;
5620 }
5621 })
5622
5623 (define_expand "truncdfhf2"
5624 [(set (match_operand:HF 0 "register_operand")
5625 (float_truncate:HF
5626 (match_operand:DF 1 "nonimmediate_operand")))]
5627 "TARGET_AVX512FP16")
5628
5629 (define_insn "*trunc<mode>hf2"
5630 [(set (match_operand:HF 0 "register_operand" "=v")
5631 (float_truncate:HF
5632 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5633 "TARGET_AVX512FP16"
5634 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5635 [(set_attr "type" "ssecvt")
5636 (set_attr "prefix" "evex")
5637 (set_attr "mode" "HF")])
5638
5639 (define_insn "truncsfbf2"
5640 [(set (match_operand:BF 0 "register_operand" "=x, v")
5641 (float_truncate:BF
5642 (match_operand:SF 1 "register_operand" "x,v")))]
5643 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5644 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5645 "@
5646 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5647 vcvtneps2bf16\t{%1, %0|%0, %1}"
5648 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5649 (set_attr "prefix" "vex,evex")])
5650
5651 ;; Signed conversion to DImode.
5652
5653 (define_expand "fix_truncxfdi2"
5654 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5655 (fix:DI (match_operand:XF 1 "register_operand")))
5656 (clobber (reg:CC FLAGS_REG))])]
5657 "TARGET_80387"
5658 {
5659 if (TARGET_FISTTP)
5660 {
5661 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5662 DONE;
5663 }
5664 })
5665
5666 (define_expand "fix_trunc<mode>di2"
5667 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5668 (fix:DI (match_operand:MODEF 1 "register_operand")))
5669 (clobber (reg:CC FLAGS_REG))])]
5670 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5671 {
5672 if (TARGET_FISTTP
5673 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5674 {
5675 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5676 DONE;
5677 }
5678 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5679 {
5680 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5681 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5682 if (out != operands[0])
5683 emit_move_insn (operands[0], out);
5684 DONE;
5685 }
5686 })
5687
5688 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5689 [(set (match_operand:SWI48 0 "register_operand" "=r")
5690 (any_fix:SWI48
5691 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5692 "TARGET_AVX512FP16"
5693 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5694 [(set_attr "type" "sseicvt")
5695 (set_attr "prefix" "evex")
5696 (set_attr "mode" "<MODE>")])
5697
5698 ;; Signed conversion to SImode.
5699
5700 (define_expand "fix_truncxfsi2"
5701 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5702 (fix:SI (match_operand:XF 1 "register_operand")))
5703 (clobber (reg:CC FLAGS_REG))])]
5704 "TARGET_80387"
5705 {
5706 if (TARGET_FISTTP)
5707 {
5708 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5709 DONE;
5710 }
5711 })
5712
5713 (define_expand "fix_trunc<mode>si2"
5714 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5715 (fix:SI (match_operand:MODEF 1 "register_operand")))
5716 (clobber (reg:CC FLAGS_REG))])]
5717 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5718 {
5719 if (TARGET_FISTTP
5720 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5721 {
5722 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5723 DONE;
5724 }
5725 if (SSE_FLOAT_MODE_P (<MODE>mode))
5726 {
5727 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5728 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5729 if (out != operands[0])
5730 emit_move_insn (operands[0], out);
5731 DONE;
5732 }
5733 })
5734
5735 ;; Signed conversion to HImode.
5736
5737 (define_expand "fix_trunc<mode>hi2"
5738 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5739 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5740 (clobber (reg:CC FLAGS_REG))])]
5741 "TARGET_80387
5742 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5743 {
5744 if (TARGET_FISTTP)
5745 {
5746 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5747 DONE;
5748 }
5749 })
5750
5751 ;; Unsigned conversion to DImode
5752
5753 (define_insn "fixuns_trunc<mode>di2"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5755 (unsigned_fix:DI
5756 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5757 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5758 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5759 [(set_attr "type" "sseicvt")
5760 (set_attr "prefix" "evex")
5761 (set_attr "mode" "DI")])
5762
5763 ;; Unsigned conversion to SImode.
5764
5765 (define_expand "fixuns_trunc<mode>si2"
5766 [(parallel
5767 [(set (match_operand:SI 0 "register_operand")
5768 (unsigned_fix:SI
5769 (match_operand:MODEF 1 "nonimmediate_operand")))
5770 (use (match_dup 2))
5771 (clobber (scratch:<ssevecmode>))
5772 (clobber (scratch:<ssevecmode>))])]
5773 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5774 {
5775 machine_mode mode = <MODE>mode;
5776 machine_mode vecmode = <ssevecmode>mode;
5777 REAL_VALUE_TYPE TWO31r;
5778 rtx two31;
5779
5780 if (TARGET_AVX512F)
5781 {
5782 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5783 DONE;
5784 }
5785
5786 if (optimize_insn_for_size_p ())
5787 FAIL;
5788
5789 real_ldexp (&TWO31r, &dconst1, 31);
5790 two31 = const_double_from_real_value (TWO31r, mode);
5791 two31 = ix86_build_const_vector (vecmode, true, two31);
5792 operands[2] = force_reg (vecmode, two31);
5793 })
5794
5795 (define_insn "fixuns_trunc<mode>si2_avx512f"
5796 [(set (match_operand:SI 0 "register_operand" "=r")
5797 (unsigned_fix:SI
5798 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5799 "TARGET_AVX512F && TARGET_SSE_MATH"
5800 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5801 [(set_attr "type" "sseicvt")
5802 (set_attr "prefix" "evex")
5803 (set_attr "mode" "SI")])
5804
5805 (define_insn "*fixuns_trunchfsi2zext"
5806 [(set (match_operand:DI 0 "register_operand" "=r")
5807 (zero_extend:DI
5808 (unsigned_fix:SI
5809 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5810 "TARGET_64BIT && TARGET_AVX512FP16"
5811 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5812 [(set_attr "type" "sseicvt")
5813 (set_attr "prefix" "evex")
5814 (set_attr "mode" "SI")])
5815
5816 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5817 [(set (match_operand:DI 0 "register_operand" "=r")
5818 (zero_extend:DI
5819 (unsigned_fix:SI
5820 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5821 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5822 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5823 [(set_attr "type" "sseicvt")
5824 (set_attr "prefix" "evex")
5825 (set_attr "mode" "SI")])
5826
5827 (define_insn_and_split "*fixuns_trunc<mode>_1"
5828 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5829 (unsigned_fix:SI
5830 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5831 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5832 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5833 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5834 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5835 && optimize_function_for_speed_p (cfun)"
5836 "#"
5837 "&& reload_completed"
5838 [(const_int 0)]
5839 {
5840 ix86_split_convert_uns_si_sse (operands);
5841 DONE;
5842 })
5843
5844 ;; Unsigned conversion to HImode.
5845 ;; Without these patterns, we'll try the unsigned SI conversion which
5846 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5847
5848 (define_expand "fixuns_trunchfhi2"
5849 [(set (match_dup 2)
5850 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5851 (set (match_operand:HI 0 "nonimmediate_operand")
5852 (subreg:HI (match_dup 2) 0))]
5853 "TARGET_AVX512FP16"
5854 "operands[2] = gen_reg_rtx (SImode);")
5855
5856 (define_expand "fixuns_trunc<mode>hi2"
5857 [(set (match_dup 2)
5858 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5859 (set (match_operand:HI 0 "nonimmediate_operand")
5860 (subreg:HI (match_dup 2) 0))]
5861 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5862 "operands[2] = gen_reg_rtx (SImode);")
5863
5864 ;; When SSE is available, it is always faster to use it!
5865 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5866 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5867 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5868 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5869 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5870 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5871 [(set_attr "type" "sseicvt")
5872 (set_attr "prefix" "maybe_vex")
5873 (set (attr "prefix_rex")
5874 (if_then_else
5875 (match_test "<SWI48:MODE>mode == DImode")
5876 (const_string "1")
5877 (const_string "*")))
5878 (set_attr "mode" "<MODEF:MODE>")
5879 (set_attr "athlon_decode" "double,vector")
5880 (set_attr "amdfam10_decode" "double,double")
5881 (set_attr "bdver1_decode" "double,double")])
5882
5883 ;; Avoid vector decoded forms of the instruction.
5884 (define_peephole2
5885 [(match_scratch:MODEF 2 "x")
5886 (set (match_operand:SWI48 0 "register_operand")
5887 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5888 "TARGET_AVOID_VECTOR_DECODE
5889 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5890 && optimize_insn_for_speed_p ()"
5891 [(set (match_dup 2) (match_dup 1))
5892 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5893
5894 (define_insn "fix_trunc<mode>_i387_fisttp"
5895 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5896 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5897 (clobber (match_scratch:XF 2 "=&f"))]
5898 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5899 && TARGET_FISTTP
5900 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5901 && (TARGET_64BIT || <MODE>mode != DImode))
5902 && TARGET_SSE_MATH)"
5903 "* return output_fix_trunc (insn, operands, true);"
5904 [(set_attr "type" "fisttp")
5905 (set_attr "mode" "<MODE>")])
5906
5907 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5908 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5909 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5910 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5911 ;; function in i386.cc.
5912 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5913 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5914 (fix:SWI248x (match_operand 1 "register_operand")))
5915 (clobber (reg:CC FLAGS_REG))]
5916 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5917 && !TARGET_FISTTP
5918 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5919 && (TARGET_64BIT || <MODE>mode != DImode))
5920 && ix86_pre_reload_split ()"
5921 "#"
5922 "&& 1"
5923 [(const_int 0)]
5924 {
5925 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5926
5927 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5928 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5929
5930 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5931 operands[2], operands[3]));
5932 DONE;
5933 }
5934 [(set_attr "type" "fistp")
5935 (set_attr "i387_cw" "trunc")
5936 (set_attr "mode" "<MODE>")])
5937
5938 (define_insn "fix_truncdi_i387"
5939 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5940 (fix:DI (match_operand 1 "register_operand" "f")))
5941 (use (match_operand:HI 2 "memory_operand" "m"))
5942 (use (match_operand:HI 3 "memory_operand" "m"))
5943 (clobber (match_scratch:XF 4 "=&f"))]
5944 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5945 && !TARGET_FISTTP
5946 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5947 "* return output_fix_trunc (insn, operands, false);"
5948 [(set_attr "type" "fistp")
5949 (set_attr "i387_cw" "trunc")
5950 (set_attr "mode" "DI")])
5951
5952 (define_insn "fix_trunc<mode>_i387"
5953 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5954 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5955 (use (match_operand:HI 2 "memory_operand" "m"))
5956 (use (match_operand:HI 3 "memory_operand" "m"))]
5957 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5958 && !TARGET_FISTTP
5959 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5960 "* return output_fix_trunc (insn, operands, false);"
5961 [(set_attr "type" "fistp")
5962 (set_attr "i387_cw" "trunc")
5963 (set_attr "mode" "<MODE>")])
5964
5965 (define_insn "x86_fnstcw_1"
5966 [(set (match_operand:HI 0 "memory_operand" "=m")
5967 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5968 "TARGET_80387"
5969 "fnstcw\t%0"
5970 [(set (attr "length")
5971 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5972 (set_attr "mode" "HI")
5973 (set_attr "unit" "i387")
5974 (set_attr "bdver1_decode" "vector")])
5975 \f
5976 ;; Conversion between fixed point and floating point.
5977
5978 ;; Even though we only accept memory inputs, the backend _really_
5979 ;; wants to be able to do this between registers. Thankfully, LRA
5980 ;; will fix this up for us during register allocation.
5981
5982 (define_insn "floathi<mode>2"
5983 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5984 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5985 "TARGET_80387
5986 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5987 || TARGET_MIX_SSE_I387)"
5988 "fild%Z1\t%1"
5989 [(set_attr "type" "fmov")
5990 (set_attr "mode" "<MODE>")
5991 (set_attr "znver1_decode" "double")
5992 (set_attr "fp_int_src" "true")])
5993
5994 (define_insn "float<SWI48x:mode>xf2"
5995 [(set (match_operand:XF 0 "register_operand" "=f")
5996 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5997 "TARGET_80387"
5998 "fild%Z1\t%1"
5999 [(set_attr "type" "fmov")
6000 (set_attr "mode" "XF")
6001 (set_attr "znver1_decode" "double")
6002 (set_attr "fp_int_src" "true")])
6003
6004 (define_expand "float<SWI48x:mode><MODEF:mode>2"
6005 [(set (match_operand:MODEF 0 "register_operand")
6006 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
6007 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
6008 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
6009 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
6010
6011 (define_insn "*float<SWI48:mode><MODEF:mode>2"
6012 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
6013 (float:MODEF
6014 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
6015 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
6016 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
6017 "@
6018 fild%Z1\t%1
6019 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
6020 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
6021 [(set_attr "type" "fmov,sseicvt,sseicvt")
6022 (set_attr "avx_partial_xmm_update" "false,true,true")
6023 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
6024 (set_attr "mode" "<MODEF:MODE>")
6025 (set (attr "prefix_rex")
6026 (if_then_else
6027 (and (eq_attr "prefix" "maybe_vex")
6028 (match_test "<SWI48:MODE>mode == DImode"))
6029 (const_string "1")
6030 (const_string "*")))
6031 (set_attr "unit" "i387,*,*")
6032 (set_attr "athlon_decode" "*,double,direct")
6033 (set_attr "amdfam10_decode" "*,vector,double")
6034 (set_attr "bdver1_decode" "*,double,direct")
6035 (set_attr "znver1_decode" "double,*,*")
6036 (set_attr "fp_int_src" "true")
6037 (set (attr "enabled")
6038 (if_then_else
6039 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
6040 (if_then_else
6041 (eq_attr "alternative" "0")
6042 (symbol_ref "TARGET_MIX_SSE_I387
6043 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
6044 <SWI48:MODE>mode)")
6045 (symbol_ref "true"))
6046 (if_then_else
6047 (eq_attr "alternative" "0")
6048 (symbol_ref "true")
6049 (symbol_ref "false"))))
6050 (set (attr "preferred_for_speed")
6051 (cond [(eq_attr "alternative" "1")
6052 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
6053 (symbol_ref "true")))])
6054
6055 (define_insn "float<floatunssuffix><mode>hf2"
6056 [(set (match_operand:HF 0 "register_operand" "=v")
6057 (any_float:HF
6058 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6059 "TARGET_AVX512FP16"
6060 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
6061 [(set_attr "type" "sseicvt")
6062 (set_attr "prefix" "evex")
6063 (set_attr "mode" "HF")])
6064
6065 (define_insn "*floatdi<MODEF:mode>2_i387"
6066 [(set (match_operand:MODEF 0 "register_operand" "=f")
6067 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
6068 "!TARGET_64BIT
6069 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
6070 "fild%Z1\t%1"
6071 [(set_attr "type" "fmov")
6072 (set_attr "mode" "<MODEF:MODE>")
6073 (set_attr "znver1_decode" "double")
6074 (set_attr "fp_int_src" "true")])
6075
6076 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
6077 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
6078 ;; alternative in sse2_loadld.
6079 (define_split
6080 [(set (match_operand:MODEF 0 "sse_reg_operand")
6081 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
6082 "TARGET_SSE2
6083 && TARGET_USE_VECTOR_CONVERTS
6084 && optimize_function_for_speed_p (cfun)
6085 && reload_completed
6086 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
6087 && (!EXT_REX_SSE_REG_P (operands[0])
6088 || TARGET_AVX512VL)"
6089 [(const_int 0)]
6090 {
6091 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
6092 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
6093
6094 emit_insn (gen_sse2_loadld (operands[4],
6095 CONST0_RTX (V4SImode), operands[1]));
6096
6097 if (<ssevecmode>mode == V4SFmode)
6098 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
6099 else
6100 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
6101 DONE;
6102 })
6103
6104 ;; Avoid store forwarding (partial memory) stall penalty
6105 ;; by passing DImode value through XMM registers. */
6106
6107 (define_split
6108 [(set (match_operand:X87MODEF 0 "register_operand")
6109 (float:X87MODEF
6110 (match_operand:DI 1 "register_operand")))]
6111 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6112 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6113 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
6114 && can_create_pseudo_p ()"
6115 [(const_int 0)]
6116 {
6117 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
6118 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
6119 DONE;
6120 })
6121
6122 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6123 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6124 (float:X87MODEF
6125 (match_operand:DI 1 "register_operand" "r,r")))
6126 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6127 (clobber (match_scratch:V4SI 3 "=x,x"))
6128 (clobber (match_scratch:V4SI 4 "=X,x"))]
6129 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6130 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6131 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6132 "#"
6133 "&& reload_completed"
6134 [(set (match_dup 2) (match_dup 3))
6135 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6136 {
6137 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6138 Assemble the 64-bit DImode value in an xmm register. */
6139 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6140 gen_lowpart (SImode, operands[1])));
6141 if (TARGET_SSE4_1)
6142 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6143 gen_highpart (SImode, operands[1]),
6144 GEN_INT (2)));
6145 else
6146 {
6147 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6148 gen_highpart (SImode, operands[1])));
6149 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6150 operands[4]));
6151 }
6152 operands[3] = gen_lowpart (DImode, operands[3]);
6153 }
6154 [(set_attr "isa" "sse4,*")
6155 (set_attr "type" "multi")
6156 (set_attr "mode" "<X87MODEF:MODE>")
6157 (set_attr "unit" "i387")
6158 (set_attr "fp_int_src" "true")])
6159
6160 ;; Break partial SSE register dependency stall. This splitter should split
6161 ;; late in the pass sequence (after register rename pass), so allocated
6162 ;; registers won't change anymore
6163
6164 (define_split
6165 [(set (match_operand:MODEF 0 "sse_reg_operand")
6166 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6167 "!TARGET_AVX
6168 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6169 && epilogue_completed
6170 && optimize_function_for_speed_p (cfun)
6171 && (!EXT_REX_SSE_REG_P (operands[0])
6172 || TARGET_AVX512VL)"
6173 [(set (match_dup 0)
6174 (vec_merge:<MODEF:ssevecmode>
6175 (vec_duplicate:<MODEF:ssevecmode>
6176 (float:MODEF
6177 (match_dup 1)))
6178 (match_dup 0)
6179 (const_int 1)))]
6180 {
6181 const machine_mode vmode = <MODEF:ssevecmode>mode;
6182
6183 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6184 emit_move_insn (operands[0], CONST0_RTX (vmode));
6185 })
6186
6187 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6188 [(set (match_operand:MODEF 0 "register_operand")
6189 (unsigned_float:MODEF
6190 (match_operand:SWI12 1 "nonimmediate_operand")))]
6191 "!TARGET_64BIT
6192 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6193 {
6194 operands[1] = convert_to_mode (SImode, operands[1], 1);
6195 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6196 DONE;
6197 })
6198
6199 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6200 [(set (match_operand:MODEF 0 "register_operand" "=v")
6201 (unsigned_float:MODEF
6202 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6203 "TARGET_AVX512F && TARGET_SSE_MATH"
6204 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6205 [(set_attr "type" "sseicvt")
6206 (set_attr "avx_partial_xmm_update" "true")
6207 (set_attr "prefix" "evex")
6208 (set_attr "mode" "<MODEF:MODE>")])
6209
6210 ;; Avoid store forwarding (partial memory) stall penalty by extending
6211 ;; SImode value to DImode through XMM register instead of pushing two
6212 ;; SImode values to stack. Also note that fild loads from memory only.
6213
6214 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6215 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6216 (unsigned_float:X87MODEF
6217 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6218 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6219 (clobber (match_scratch:DI 3 "=x"))]
6220 "!TARGET_64BIT
6221 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6222 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6223 "#"
6224 "&& reload_completed"
6225 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6226 (set (match_dup 2) (match_dup 3))
6227 (set (match_dup 0)
6228 (float:X87MODEF (match_dup 2)))]
6229 ""
6230 [(set_attr "type" "multi")
6231 (set_attr "mode" "<MODE>")])
6232
6233 (define_expand "floatunssi<mode>2"
6234 [(set (match_operand:X87MODEF 0 "register_operand")
6235 (unsigned_float:X87MODEF
6236 (match_operand:SI 1 "nonimmediate_operand")))]
6237 "(!TARGET_64BIT
6238 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6239 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6240 || ((!TARGET_64BIT || TARGET_AVX512F)
6241 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6242 {
6243 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6244 {
6245 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6246 (operands[0], operands[1],
6247 assign_386_stack_local (DImode, SLOT_TEMP)));
6248 DONE;
6249 }
6250 if (!TARGET_AVX512F)
6251 {
6252 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6253 DONE;
6254 }
6255 })
6256
6257 (define_expand "floatunsdisf2"
6258 [(set (match_operand:SF 0 "register_operand")
6259 (unsigned_float:SF
6260 (match_operand:DI 1 "nonimmediate_operand")))]
6261 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6262 {
6263 if (!TARGET_AVX512F)
6264 {
6265 x86_emit_floatuns (operands);
6266 DONE;
6267 }
6268 })
6269
6270 (define_expand "floatunsdidf2"
6271 [(set (match_operand:DF 0 "register_operand")
6272 (unsigned_float:DF
6273 (match_operand:DI 1 "nonimmediate_operand")))]
6274 "((TARGET_64BIT && TARGET_AVX512F)
6275 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6276 && TARGET_SSE2 && TARGET_SSE_MATH"
6277 {
6278 if (!TARGET_64BIT)
6279 {
6280 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6281 DONE;
6282 }
6283 if (!TARGET_AVX512F)
6284 {
6285 x86_emit_floatuns (operands);
6286 DONE;
6287 }
6288 })
6289 \f
6290 ;; Load effective address instructions
6291
6292 (define_insn "*lea<mode>"
6293 [(set (match_operand:SWI48 0 "register_operand" "=r")
6294 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6295 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6296 {
6297 if (SImode_address_operand (operands[1], VOIDmode))
6298 {
6299 gcc_assert (TARGET_64BIT);
6300 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6301 }
6302 else
6303 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6304 }
6305 [(set_attr "type" "lea")
6306 (set (attr "mode")
6307 (if_then_else
6308 (match_operand 1 "SImode_address_operand")
6309 (const_string "SI")
6310 (const_string "<MODE>")))])
6311
6312 (define_peephole2
6313 [(set (match_operand:SWI48 0 "register_operand")
6314 (match_operand:SWI48 1 "address_no_seg_operand"))]
6315 "ix86_hardreg_mov_ok (operands[0], operands[1])
6316 && peep2_regno_dead_p (0, FLAGS_REG)
6317 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6318 [(const_int 0)]
6319 {
6320 machine_mode mode = <MODE>mode;
6321
6322 /* Emit all operations in SImode for zero-extended addresses. */
6323 if (SImode_address_operand (operands[1], VOIDmode))
6324 mode = SImode;
6325
6326 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6327
6328 /* Zero-extend return register to DImode for zero-extended addresses. */
6329 if (mode != <MODE>mode)
6330 emit_insn (gen_zero_extendsidi2 (operands[0],
6331 gen_lowpart (mode, operands[0])));
6332
6333 DONE;
6334 })
6335
6336 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6337 ;; peephole2 optimized back into a lea. Split that into the shift during
6338 ;; the following split pass.
6339 (define_split
6340 [(set (match_operand:SWI48 0 "general_reg_operand")
6341 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6342 (clobber (reg:CC FLAGS_REG))]
6343 "reload_completed"
6344 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6345 (clobber (reg:CC FLAGS_REG))])]
6346 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6347 \f
6348 ;; Add instructions
6349
6350 (define_expand "add<mode>3"
6351 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6352 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6353 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6354 ""
6355 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6356
6357 (define_insn_and_split "*add<dwi>3_doubleword"
6358 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6359 (plus:<DWI>
6360 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6361 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6362 (clobber (reg:CC FLAGS_REG))]
6363 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6364 "#"
6365 "&& reload_completed"
6366 [(parallel [(set (reg:CCC FLAGS_REG)
6367 (compare:CCC
6368 (plus:DWIH (match_dup 1) (match_dup 2))
6369 (match_dup 1)))
6370 (set (match_dup 0)
6371 (plus:DWIH (match_dup 1) (match_dup 2)))])
6372 (parallel [(set (match_dup 3)
6373 (plus:DWIH
6374 (plus:DWIH
6375 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6376 (match_dup 4))
6377 (match_dup 5)))
6378 (clobber (reg:CC FLAGS_REG))])]
6379 {
6380 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6381 if (operands[2] == const0_rtx)
6382 {
6383 if (operands[5] != const0_rtx)
6384 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6385 else if (!rtx_equal_p (operands[3], operands[4]))
6386 emit_move_insn (operands[3], operands[4]);
6387 else
6388 emit_note (NOTE_INSN_DELETED);
6389 DONE;
6390 }
6391 })
6392
6393 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6394 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6395 (plus:<DWI>
6396 (zero_extend:<DWI>
6397 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6398 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6399 (clobber (reg:CC FLAGS_REG))]
6400 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6401 "#"
6402 "&& reload_completed"
6403 [(parallel [(set (reg:CCC FLAGS_REG)
6404 (compare:CCC
6405 (plus:DWIH (match_dup 1) (match_dup 2))
6406 (match_dup 1)))
6407 (set (match_dup 0)
6408 (plus:DWIH (match_dup 1) (match_dup 2)))])
6409 (parallel [(set (match_dup 3)
6410 (plus:DWIH
6411 (plus:DWIH
6412 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6413 (match_dup 4))
6414 (const_int 0)))
6415 (clobber (reg:CC FLAGS_REG))])]
6416 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6417
6418 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6419 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6420 (plus:<DWI>
6421 (any_or_plus:<DWI>
6422 (ashift:<DWI>
6423 (zero_extend:<DWI>
6424 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6425 (match_operand:QI 3 "const_int_operand"))
6426 (zero_extend:<DWI>
6427 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6428 (match_operand:<DWI> 1 "register_operand" "0")))
6429 (clobber (reg:CC FLAGS_REG))]
6430 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6431 "#"
6432 "&& reload_completed"
6433 [(parallel [(set (reg:CCC FLAGS_REG)
6434 (compare:CCC
6435 (plus:DWIH (match_dup 1) (match_dup 4))
6436 (match_dup 1)))
6437 (set (match_dup 0)
6438 (plus:DWIH (match_dup 1) (match_dup 4)))])
6439 (parallel [(set (match_dup 5)
6440 (plus:DWIH
6441 (plus:DWIH
6442 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6443 (match_dup 6))
6444 (match_dup 2)))
6445 (clobber (reg:CC FLAGS_REG))])]
6446 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6447
6448 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6449 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6450 (plus:<DWI>
6451 (any_or_plus:<DWI>
6452 (ashift:<DWI>
6453 (zero_extend:<DWI>
6454 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6455 (match_operand:QI 3 "const_int_operand"))
6456 (zero_extend:<DWI>
6457 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6458 (zero_extend:<DWI>
6459 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6460 (clobber (reg:CC FLAGS_REG))]
6461 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6462 "#"
6463 "&& reload_completed"
6464 [(set (match_dup 0) (match_dup 4))
6465 (set (match_dup 5) (match_dup 2))
6466 (parallel [(set (reg:CCC FLAGS_REG)
6467 (compare:CCC
6468 (plus:DWIH (match_dup 0) (match_dup 1))
6469 (match_dup 0)))
6470 (set (match_dup 0)
6471 (plus:DWIH (match_dup 0) (match_dup 1)))])
6472 (parallel [(set (match_dup 5)
6473 (plus:DWIH
6474 (plus:DWIH
6475 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6476 (match_dup 5))
6477 (const_int 0)))
6478 (clobber (reg:CC FLAGS_REG))])]
6479 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6480
6481 (define_insn "*add<mode>_1"
6482 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6483 (plus:SWI48
6484 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6485 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6486 (clobber (reg:CC FLAGS_REG))]
6487 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6488 {
6489 switch (get_attr_type (insn))
6490 {
6491 case TYPE_LEA:
6492 return "#";
6493
6494 case TYPE_INCDEC:
6495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6496 if (operands[2] == const1_rtx)
6497 return "inc{<imodesuffix>}\t%0";
6498 else
6499 {
6500 gcc_assert (operands[2] == constm1_rtx);
6501 return "dec{<imodesuffix>}\t%0";
6502 }
6503
6504 default:
6505 /* For most processors, ADD is faster than LEA. This alternative
6506 was added to use ADD as much as possible. */
6507 if (which_alternative == 2)
6508 std::swap (operands[1], operands[2]);
6509
6510 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6511 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6512 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6513
6514 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6515 }
6516 }
6517 [(set (attr "type")
6518 (cond [(eq_attr "alternative" "3")
6519 (const_string "lea")
6520 (match_operand:SWI48 2 "incdec_operand")
6521 (const_string "incdec")
6522 ]
6523 (const_string "alu")))
6524 (set (attr "length_immediate")
6525 (if_then_else
6526 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6527 (const_string "1")
6528 (const_string "*")))
6529 (set_attr "mode" "<MODE>")])
6530
6531 ;; It may seem that nonimmediate operand is proper one for operand 1.
6532 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6533 ;; we take care in ix86_binary_operator_ok to not allow two memory
6534 ;; operands so proper swapping will be done in reload. This allow
6535 ;; patterns constructed from addsi_1 to match.
6536
6537 (define_insn "addsi_1_zext"
6538 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6539 (zero_extend:DI
6540 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6541 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6542 (clobber (reg:CC FLAGS_REG))]
6543 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6544 {
6545 switch (get_attr_type (insn))
6546 {
6547 case TYPE_LEA:
6548 return "#";
6549
6550 case TYPE_INCDEC:
6551 if (operands[2] == const1_rtx)
6552 return "inc{l}\t%k0";
6553 else
6554 {
6555 gcc_assert (operands[2] == constm1_rtx);
6556 return "dec{l}\t%k0";
6557 }
6558
6559 default:
6560 /* For most processors, ADD is faster than LEA. This alternative
6561 was added to use ADD as much as possible. */
6562 if (which_alternative == 1)
6563 std::swap (operands[1], operands[2]);
6564
6565 if (x86_maybe_negate_const_int (&operands[2], SImode))
6566 return "sub{l}\t{%2, %k0|%k0, %2}";
6567
6568 return "add{l}\t{%2, %k0|%k0, %2}";
6569 }
6570 }
6571 [(set (attr "type")
6572 (cond [(eq_attr "alternative" "2")
6573 (const_string "lea")
6574 (match_operand:SI 2 "incdec_operand")
6575 (const_string "incdec")
6576 ]
6577 (const_string "alu")))
6578 (set (attr "length_immediate")
6579 (if_then_else
6580 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6581 (const_string "1")
6582 (const_string "*")))
6583 (set_attr "mode" "SI")])
6584
6585 (define_insn "*addhi_1"
6586 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6587 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6588 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6589 (clobber (reg:CC FLAGS_REG))]
6590 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6591 {
6592 switch (get_attr_type (insn))
6593 {
6594 case TYPE_LEA:
6595 return "#";
6596
6597 case TYPE_INCDEC:
6598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6599 if (operands[2] == const1_rtx)
6600 return "inc{w}\t%0";
6601 else
6602 {
6603 gcc_assert (operands[2] == constm1_rtx);
6604 return "dec{w}\t%0";
6605 }
6606
6607 default:
6608 /* For most processors, ADD is faster than LEA. This alternative
6609 was added to use ADD as much as possible. */
6610 if (which_alternative == 2)
6611 std::swap (operands[1], operands[2]);
6612
6613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614 if (x86_maybe_negate_const_int (&operands[2], HImode))
6615 return "sub{w}\t{%2, %0|%0, %2}";
6616
6617 return "add{w}\t{%2, %0|%0, %2}";
6618 }
6619 }
6620 [(set (attr "type")
6621 (cond [(eq_attr "alternative" "3")
6622 (const_string "lea")
6623 (match_operand:HI 2 "incdec_operand")
6624 (const_string "incdec")
6625 ]
6626 (const_string "alu")))
6627 (set (attr "length_immediate")
6628 (if_then_else
6629 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6630 (const_string "1")
6631 (const_string "*")))
6632 (set_attr "mode" "HI,HI,HI,SI")])
6633
6634 (define_insn "*addqi_1"
6635 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6636 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6637 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6638 (clobber (reg:CC FLAGS_REG))]
6639 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6640 {
6641 bool widen = (get_attr_mode (insn) != MODE_QI);
6642
6643 switch (get_attr_type (insn))
6644 {
6645 case TYPE_LEA:
6646 return "#";
6647
6648 case TYPE_INCDEC:
6649 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6650 if (operands[2] == const1_rtx)
6651 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6652 else
6653 {
6654 gcc_assert (operands[2] == constm1_rtx);
6655 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6656 }
6657
6658 default:
6659 /* For most processors, ADD is faster than LEA. These alternatives
6660 were added to use ADD as much as possible. */
6661 if (which_alternative == 2 || which_alternative == 4)
6662 std::swap (operands[1], operands[2]);
6663
6664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6665 if (x86_maybe_negate_const_int (&operands[2], QImode))
6666 {
6667 if (widen)
6668 return "sub{l}\t{%2, %k0|%k0, %2}";
6669 else
6670 return "sub{b}\t{%2, %0|%0, %2}";
6671 }
6672 if (widen)
6673 return "add{l}\t{%k2, %k0|%k0, %k2}";
6674 else
6675 return "add{b}\t{%2, %0|%0, %2}";
6676 }
6677 }
6678 [(set (attr "type")
6679 (cond [(eq_attr "alternative" "5")
6680 (const_string "lea")
6681 (match_operand:QI 2 "incdec_operand")
6682 (const_string "incdec")
6683 ]
6684 (const_string "alu")))
6685 (set (attr "length_immediate")
6686 (if_then_else
6687 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6688 (const_string "1")
6689 (const_string "*")))
6690 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6691 ;; Potential partial reg stall on alternatives 3 and 4.
6692 (set (attr "preferred_for_speed")
6693 (cond [(eq_attr "alternative" "3,4")
6694 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6695 (symbol_ref "true")))])
6696
6697 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6698 (define_insn_and_split "*add<mode>_1_slp"
6699 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6700 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6701 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6702 (clobber (reg:CC FLAGS_REG))]
6703 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6704 {
6705 if (which_alternative)
6706 return "#";
6707
6708 switch (get_attr_type (insn))
6709 {
6710 case TYPE_INCDEC:
6711 if (operands[2] == const1_rtx)
6712 return "inc{<imodesuffix>}\t%0";
6713 else
6714 {
6715 gcc_assert (operands[2] == constm1_rtx);
6716 return "dec{<imodesuffix>}\t%0";
6717 }
6718
6719 default:
6720 if (x86_maybe_negate_const_int (&operands[2], QImode))
6721 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6722
6723 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6724 }
6725 }
6726 "&& reload_completed"
6727 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6728 (parallel
6729 [(set (strict_low_part (match_dup 0))
6730 (plus:SWI12 (match_dup 0) (match_dup 2)))
6731 (clobber (reg:CC FLAGS_REG))])]
6732 ""
6733 [(set (attr "type")
6734 (if_then_else (match_operand:QI 2 "incdec_operand")
6735 (const_string "incdec")
6736 (const_string "alu")))
6737 (set_attr "mode" "<MODE>")])
6738
6739 ;; Split non destructive adds if we cannot use lea.
6740 (define_split
6741 [(set (match_operand:SWI48 0 "register_operand")
6742 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6743 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6744 (clobber (reg:CC FLAGS_REG))]
6745 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6746 [(set (match_dup 0) (match_dup 1))
6747 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6748 (clobber (reg:CC FLAGS_REG))])])
6749
6750 ;; Split non destructive adds if we cannot use lea.
6751 (define_split
6752 [(set (match_operand:DI 0 "register_operand")
6753 (zero_extend:DI
6754 (plus:SI (match_operand:SI 1 "register_operand")
6755 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6756 (clobber (reg:CC FLAGS_REG))]
6757 "TARGET_64BIT
6758 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6759 [(set (match_dup 3) (match_dup 1))
6760 (parallel [(set (match_dup 0)
6761 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6762 (clobber (reg:CC FLAGS_REG))])]
6763 "operands[3] = gen_lowpart (SImode, operands[0]);")
6764
6765 ;; Convert add to the lea pattern to avoid flags dependency.
6766 (define_split
6767 [(set (match_operand:SWI 0 "register_operand")
6768 (plus:SWI (match_operand:SWI 1 "register_operand")
6769 (match_operand:SWI 2 "<nonmemory_operand>")))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6772 [(set (match_dup 0)
6773 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6774 {
6775 if (<MODE>mode != <LEAMODE>mode)
6776 {
6777 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6778 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6779 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6780 }
6781 })
6782
6783 ;; Convert add to the lea pattern to avoid flags dependency.
6784 (define_split
6785 [(set (match_operand:DI 0 "register_operand")
6786 (zero_extend:DI
6787 (plus:SI (match_operand:SI 1 "register_operand")
6788 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6789 (clobber (reg:CC FLAGS_REG))]
6790 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6791 [(set (match_dup 0)
6792 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6793
6794 (define_insn "*add<mode>_2"
6795 [(set (reg FLAGS_REG)
6796 (compare
6797 (plus:SWI
6798 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6799 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6800 (const_int 0)))
6801 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6802 (plus:SWI (match_dup 1) (match_dup 2)))]
6803 "ix86_match_ccmode (insn, CCGOCmode)
6804 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6805 {
6806 switch (get_attr_type (insn))
6807 {
6808 case TYPE_INCDEC:
6809 if (operands[2] == const1_rtx)
6810 return "inc{<imodesuffix>}\t%0";
6811 else
6812 {
6813 gcc_assert (operands[2] == constm1_rtx);
6814 return "dec{<imodesuffix>}\t%0";
6815 }
6816
6817 default:
6818 if (which_alternative == 2)
6819 std::swap (operands[1], operands[2]);
6820
6821 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6822 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6823 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6824
6825 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6826 }
6827 }
6828 [(set (attr "type")
6829 (if_then_else (match_operand:SWI 2 "incdec_operand")
6830 (const_string "incdec")
6831 (const_string "alu")))
6832 (set (attr "length_immediate")
6833 (if_then_else
6834 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6835 (const_string "1")
6836 (const_string "*")))
6837 (set_attr "mode" "<MODE>")])
6838
6839 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6840 (define_insn "*addsi_2_zext"
6841 [(set (reg FLAGS_REG)
6842 (compare
6843 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6844 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6845 (const_int 0)))
6846 (set (match_operand:DI 0 "register_operand" "=r,r")
6847 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6848 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6849 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6850 {
6851 switch (get_attr_type (insn))
6852 {
6853 case TYPE_INCDEC:
6854 if (operands[2] == const1_rtx)
6855 return "inc{l}\t%k0";
6856 else
6857 {
6858 gcc_assert (operands[2] == constm1_rtx);
6859 return "dec{l}\t%k0";
6860 }
6861
6862 default:
6863 if (which_alternative == 1)
6864 std::swap (operands[1], operands[2]);
6865
6866 if (x86_maybe_negate_const_int (&operands[2], SImode))
6867 return "sub{l}\t{%2, %k0|%k0, %2}";
6868
6869 return "add{l}\t{%2, %k0|%k0, %2}";
6870 }
6871 }
6872 [(set (attr "type")
6873 (if_then_else (match_operand:SI 2 "incdec_operand")
6874 (const_string "incdec")
6875 (const_string "alu")))
6876 (set (attr "length_immediate")
6877 (if_then_else
6878 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6879 (const_string "1")
6880 (const_string "*")))
6881 (set_attr "mode" "SI")])
6882
6883 (define_insn "*add<mode>_3"
6884 [(set (reg FLAGS_REG)
6885 (compare
6886 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6887 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6888 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6889 "ix86_match_ccmode (insn, CCZmode)
6890 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6891 {
6892 switch (get_attr_type (insn))
6893 {
6894 case TYPE_INCDEC:
6895 if (operands[2] == const1_rtx)
6896 return "inc{<imodesuffix>}\t%0";
6897 else
6898 {
6899 gcc_assert (operands[2] == constm1_rtx);
6900 return "dec{<imodesuffix>}\t%0";
6901 }
6902
6903 default:
6904 if (which_alternative == 1)
6905 std::swap (operands[1], operands[2]);
6906
6907 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6908 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6909 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6910
6911 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6912 }
6913 }
6914 [(set (attr "type")
6915 (if_then_else (match_operand:SWI 2 "incdec_operand")
6916 (const_string "incdec")
6917 (const_string "alu")))
6918 (set (attr "length_immediate")
6919 (if_then_else
6920 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6921 (const_string "1")
6922 (const_string "*")))
6923 (set_attr "mode" "<MODE>")])
6924
6925 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6926 (define_insn "*addsi_3_zext"
6927 [(set (reg FLAGS_REG)
6928 (compare
6929 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6930 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6931 (set (match_operand:DI 0 "register_operand" "=r,r")
6932 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6933 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6934 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6935 {
6936 switch (get_attr_type (insn))
6937 {
6938 case TYPE_INCDEC:
6939 if (operands[2] == const1_rtx)
6940 return "inc{l}\t%k0";
6941 else
6942 {
6943 gcc_assert (operands[2] == constm1_rtx);
6944 return "dec{l}\t%k0";
6945 }
6946
6947 default:
6948 if (which_alternative == 1)
6949 std::swap (operands[1], operands[2]);
6950
6951 if (x86_maybe_negate_const_int (&operands[2], SImode))
6952 return "sub{l}\t{%2, %k0|%k0, %2}";
6953
6954 return "add{l}\t{%2, %k0|%k0, %2}";
6955 }
6956 }
6957 [(set (attr "type")
6958 (if_then_else (match_operand:SI 2 "incdec_operand")
6959 (const_string "incdec")
6960 (const_string "alu")))
6961 (set (attr "length_immediate")
6962 (if_then_else
6963 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6964 (const_string "1")
6965 (const_string "*")))
6966 (set_attr "mode" "SI")])
6967
6968 ; For comparisons against 1, -1 and 128, we may generate better code
6969 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6970 ; is matched then. We can't accept general immediate, because for
6971 ; case of overflows, the result is messed up.
6972 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6973 ; only for comparisons not depending on it.
6974
6975 (define_insn "*adddi_4"
6976 [(set (reg FLAGS_REG)
6977 (compare
6978 (match_operand:DI 1 "nonimmediate_operand" "0")
6979 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6980 (clobber (match_scratch:DI 0 "=r"))]
6981 "TARGET_64BIT
6982 && ix86_match_ccmode (insn, CCGCmode)"
6983 {
6984 switch (get_attr_type (insn))
6985 {
6986 case TYPE_INCDEC:
6987 if (operands[2] == constm1_rtx)
6988 return "inc{q}\t%0";
6989 else
6990 {
6991 gcc_assert (operands[2] == const1_rtx);
6992 return "dec{q}\t%0";
6993 }
6994
6995 default:
6996 if (x86_maybe_negate_const_int (&operands[2], DImode))
6997 return "add{q}\t{%2, %0|%0, %2}";
6998
6999 return "sub{q}\t{%2, %0|%0, %2}";
7000 }
7001 }
7002 [(set (attr "type")
7003 (if_then_else (match_operand:DI 2 "incdec_operand")
7004 (const_string "incdec")
7005 (const_string "alu")))
7006 (set (attr "length_immediate")
7007 (if_then_else
7008 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7009 (const_string "1")
7010 (const_string "*")))
7011 (set_attr "mode" "DI")])
7012
7013 ; For comparisons against 1, -1 and 128, we may generate better code
7014 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7015 ; is matched then. We can't accept general immediate, because for
7016 ; case of overflows, the result is messed up.
7017 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7018 ; only for comparisons not depending on it.
7019
7020 (define_insn "*add<mode>_4"
7021 [(set (reg FLAGS_REG)
7022 (compare
7023 (match_operand:SWI124 1 "nonimmediate_operand" "0")
7024 (match_operand:SWI124 2 "const_int_operand")))
7025 (clobber (match_scratch:SWI124 0 "=<r>"))]
7026 "ix86_match_ccmode (insn, CCGCmode)"
7027 {
7028 switch (get_attr_type (insn))
7029 {
7030 case TYPE_INCDEC:
7031 if (operands[2] == constm1_rtx)
7032 return "inc{<imodesuffix>}\t%0";
7033 else
7034 {
7035 gcc_assert (operands[2] == const1_rtx);
7036 return "dec{<imodesuffix>}\t%0";
7037 }
7038
7039 default:
7040 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7041 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7042
7043 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7044 }
7045 }
7046 [(set (attr "type")
7047 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
7048 (const_string "incdec")
7049 (const_string "alu")))
7050 (set (attr "length_immediate")
7051 (if_then_else
7052 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7053 (const_string "1")
7054 (const_string "*")))
7055 (set_attr "mode" "<MODE>")])
7056
7057 (define_insn "*add<mode>_5"
7058 [(set (reg FLAGS_REG)
7059 (compare
7060 (plus:SWI
7061 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
7062 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
7063 (const_int 0)))
7064 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
7065 "ix86_match_ccmode (insn, CCGOCmode)
7066 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7067 {
7068 switch (get_attr_type (insn))
7069 {
7070 case TYPE_INCDEC:
7071 if (operands[2] == const1_rtx)
7072 return "inc{<imodesuffix>}\t%0";
7073 else
7074 {
7075 gcc_assert (operands[2] == constm1_rtx);
7076 return "dec{<imodesuffix>}\t%0";
7077 }
7078
7079 default:
7080 if (which_alternative == 1)
7081 std::swap (operands[1], operands[2]);
7082
7083 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7084 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7085 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7086
7087 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7088 }
7089 }
7090 [(set (attr "type")
7091 (if_then_else (match_operand:SWI 2 "incdec_operand")
7092 (const_string "incdec")
7093 (const_string "alu")))
7094 (set (attr "length_immediate")
7095 (if_then_else
7096 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7097 (const_string "1")
7098 (const_string "*")))
7099 (set_attr "mode" "<MODE>")])
7100
7101 (define_insn "*addqi_ext<mode>_0"
7102 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7103 (plus:QI
7104 (subreg:QI
7105 (match_operator:SWI248 3 "extract_operator"
7106 [(match_operand 2 "int248_register_operand" "Q,Q")
7107 (const_int 8)
7108 (const_int 8)]) 0)
7109 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
7110 (clobber (reg:CC FLAGS_REG))]
7111 ""
7112 "add{b}\t{%h2, %0|%0, %h2}"
7113 [(set_attr "isa" "*,nox64")
7114 (set_attr "type" "alu")
7115 (set_attr "mode" "QI")])
7116
7117 (define_expand "addqi_ext_1"
7118 [(parallel
7119 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7120 (const_int 8)
7121 (const_int 8))
7122 (subreg:HI
7123 (plus:QI
7124 (subreg:QI
7125 (zero_extract:HI (match_operand:HI 1 "register_operand")
7126 (const_int 8)
7127 (const_int 8)) 0)
7128 (match_operand:QI 2 "const_int_operand")) 0))
7129 (clobber (reg:CC FLAGS_REG))])])
7130
7131 (define_insn "*addqi_ext<mode>_1"
7132 [(set (zero_extract:SWI248
7133 (match_operand 0 "int248_register_operand" "+Q,Q")
7134 (const_int 8)
7135 (const_int 8))
7136 (subreg:SWI248
7137 (plus:QI
7138 (subreg:QI
7139 (match_operator:SWI248 3 "extract_operator"
7140 [(match_operand 1 "int248_register_operand" "0,0")
7141 (const_int 8)
7142 (const_int 8)]) 0)
7143 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7146 rtx_equal_p (operands[0], operands[1])"
7147 {
7148 switch (get_attr_type (insn))
7149 {
7150 case TYPE_INCDEC:
7151 if (operands[2] == const1_rtx)
7152 return "inc{b}\t%h0";
7153 else
7154 {
7155 gcc_assert (operands[2] == constm1_rtx);
7156 return "dec{b}\t%h0";
7157 }
7158
7159 default:
7160 return "add{b}\t{%2, %h0|%h0, %2}";
7161 }
7162 }
7163 [(set_attr "isa" "*,nox64")
7164 (set (attr "type")
7165 (if_then_else (match_operand:QI 2 "incdec_operand")
7166 (const_string "incdec")
7167 (const_string "alu")))
7168 (set_attr "mode" "QI")])
7169
7170 (define_insn "*addqi_ext<mode>_2"
7171 [(set (zero_extract:SWI248
7172 (match_operand 0 "int248_register_operand" "+Q")
7173 (const_int 8)
7174 (const_int 8))
7175 (subreg:SWI248
7176 (plus:QI
7177 (subreg:QI
7178 (match_operator:SWI248 3 "extract_operator"
7179 [(match_operand 1 "int248_register_operand" "%0")
7180 (const_int 8)
7181 (const_int 8)]) 0)
7182 (subreg:QI
7183 (match_operator:SWI248 4 "extract_operator"
7184 [(match_operand 2 "int248_register_operand" "Q")
7185 (const_int 8)
7186 (const_int 8)]) 0)) 0))
7187 (clobber (reg:CC FLAGS_REG))]
7188 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7189 rtx_equal_p (operands[0], operands[1])
7190 || rtx_equal_p (operands[0], operands[2])"
7191 "add{b}\t{%h2, %h0|%h0, %h2}"
7192 [(set_attr "type" "alu")
7193 (set_attr "mode" "QI")])
7194
7195 ;; Like DWI, but use POImode instead of OImode.
7196 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7197
7198 ;; Add with jump on overflow.
7199 (define_expand "addv<mode>4"
7200 [(parallel [(set (reg:CCO FLAGS_REG)
7201 (eq:CCO
7202 (plus:<DPWI>
7203 (sign_extend:<DPWI>
7204 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7205 (match_dup 4))
7206 (sign_extend:<DPWI>
7207 (plus:SWIDWI (match_dup 1)
7208 (match_operand:SWIDWI 2
7209 "<general_hilo_operand>")))))
7210 (set (match_operand:SWIDWI 0 "register_operand")
7211 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7212 (set (pc) (if_then_else
7213 (eq (reg:CCO FLAGS_REG) (const_int 0))
7214 (label_ref (match_operand 3))
7215 (pc)))]
7216 ""
7217 {
7218 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7219 if (CONST_SCALAR_INT_P (operands[2]))
7220 operands[4] = operands[2];
7221 else
7222 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7223 })
7224
7225 (define_insn "*addv<mode>4"
7226 [(set (reg:CCO FLAGS_REG)
7227 (eq:CCO (plus:<DWI>
7228 (sign_extend:<DWI>
7229 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7230 (sign_extend:<DWI>
7231 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7232 (sign_extend:<DWI>
7233 (plus:SWI (match_dup 1) (match_dup 2)))))
7234 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7235 (plus:SWI (match_dup 1) (match_dup 2)))]
7236 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7237 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7238 [(set_attr "type" "alu")
7239 (set_attr "mode" "<MODE>")])
7240
7241 (define_insn "addv<mode>4_1"
7242 [(set (reg:CCO FLAGS_REG)
7243 (eq:CCO (plus:<DWI>
7244 (sign_extend:<DWI>
7245 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7246 (match_operand:<DWI> 3 "const_int_operand"))
7247 (sign_extend:<DWI>
7248 (plus:SWI
7249 (match_dup 1)
7250 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7251 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7252 (plus:SWI (match_dup 1) (match_dup 2)))]
7253 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7254 && CONST_INT_P (operands[2])
7255 && INTVAL (operands[2]) == INTVAL (operands[3])"
7256 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7257 [(set_attr "type" "alu")
7258 (set_attr "mode" "<MODE>")
7259 (set (attr "length_immediate")
7260 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7261 (const_string "1")
7262 (match_test "<MODE_SIZE> == 8")
7263 (const_string "4")]
7264 (const_string "<MODE_SIZE>")))])
7265
7266 ;; Quad word integer modes as mode attribute.
7267 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7268
7269 (define_insn_and_split "*addv<dwi>4_doubleword"
7270 [(set (reg:CCO FLAGS_REG)
7271 (eq:CCO
7272 (plus:<QPWI>
7273 (sign_extend:<QPWI>
7274 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7275 (sign_extend:<QPWI>
7276 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7277 (sign_extend:<QPWI>
7278 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7279 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7280 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7281 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7282 "#"
7283 "&& reload_completed"
7284 [(parallel [(set (reg:CCC FLAGS_REG)
7285 (compare:CCC
7286 (plus:DWIH (match_dup 1) (match_dup 2))
7287 (match_dup 1)))
7288 (set (match_dup 0)
7289 (plus:DWIH (match_dup 1) (match_dup 2)))])
7290 (parallel [(set (reg:CCO FLAGS_REG)
7291 (eq:CCO
7292 (plus:<DWI>
7293 (plus:<DWI>
7294 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7295 (sign_extend:<DWI> (match_dup 4)))
7296 (sign_extend:<DWI> (match_dup 5)))
7297 (sign_extend:<DWI>
7298 (plus:DWIH
7299 (plus:DWIH
7300 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7301 (match_dup 4))
7302 (match_dup 5)))))
7303 (set (match_dup 3)
7304 (plus:DWIH
7305 (plus:DWIH
7306 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7307 (match_dup 4))
7308 (match_dup 5)))])]
7309 {
7310 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7311 })
7312
7313 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7314 [(set (reg:CCO FLAGS_REG)
7315 (eq:CCO
7316 (plus:<QPWI>
7317 (sign_extend:<QPWI>
7318 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7319 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7320 (sign_extend:<QPWI>
7321 (plus:<DWI>
7322 (match_dup 1)
7323 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7324 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7325 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7326 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7327 && CONST_SCALAR_INT_P (operands[2])
7328 && rtx_equal_p (operands[2], operands[3])"
7329 "#"
7330 "&& reload_completed"
7331 [(parallel [(set (reg:CCC FLAGS_REG)
7332 (compare:CCC
7333 (plus:DWIH (match_dup 1) (match_dup 2))
7334 (match_dup 1)))
7335 (set (match_dup 0)
7336 (plus:DWIH (match_dup 1) (match_dup 2)))])
7337 (parallel [(set (reg:CCO FLAGS_REG)
7338 (eq:CCO
7339 (plus:<DWI>
7340 (plus:<DWI>
7341 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7342 (sign_extend:<DWI> (match_dup 4)))
7343 (match_dup 5))
7344 (sign_extend:<DWI>
7345 (plus:DWIH
7346 (plus:DWIH
7347 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7348 (match_dup 4))
7349 (match_dup 5)))))
7350 (set (match_dup 3)
7351 (plus:DWIH
7352 (plus:DWIH
7353 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7354 (match_dup 4))
7355 (match_dup 5)))])]
7356 {
7357 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7358 if (operands[2] == const0_rtx)
7359 {
7360 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7361 operands[5]));
7362 DONE;
7363 }
7364 })
7365
7366 (define_insn "*addv<mode>4_overflow_1"
7367 [(set (reg:CCO FLAGS_REG)
7368 (eq:CCO
7369 (plus:<DWI>
7370 (plus:<DWI>
7371 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7372 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7373 (sign_extend:<DWI>
7374 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7375 (sign_extend:<DWI>
7376 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7377 (sign_extend:<DWI>
7378 (plus:SWI
7379 (plus:SWI
7380 (match_operator:SWI 5 "ix86_carry_flag_operator"
7381 [(match_dup 3) (const_int 0)])
7382 (match_dup 1))
7383 (match_dup 2)))))
7384 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7385 (plus:SWI
7386 (plus:SWI
7387 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7388 (match_dup 1))
7389 (match_dup 2)))]
7390 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7391 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7392 [(set_attr "type" "alu")
7393 (set_attr "mode" "<MODE>")])
7394
7395 (define_insn "*addv<mode>4_overflow_2"
7396 [(set (reg:CCO FLAGS_REG)
7397 (eq:CCO
7398 (plus:<DWI>
7399 (plus:<DWI>
7400 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7401 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7402 (sign_extend:<DWI>
7403 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7404 (match_operand:<DWI> 6 "const_int_operand" "n"))
7405 (sign_extend:<DWI>
7406 (plus:SWI
7407 (plus:SWI
7408 (match_operator:SWI 5 "ix86_carry_flag_operator"
7409 [(match_dup 3) (const_int 0)])
7410 (match_dup 1))
7411 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7412 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7413 (plus:SWI
7414 (plus:SWI
7415 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7416 (match_dup 1))
7417 (match_dup 2)))]
7418 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7419 && CONST_INT_P (operands[2])
7420 && INTVAL (operands[2]) == INTVAL (operands[6])"
7421 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7422 [(set_attr "type" "alu")
7423 (set_attr "mode" "<MODE>")
7424 (set (attr "length_immediate")
7425 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7426 (const_string "1")
7427 (const_string "4")))])
7428
7429 (define_expand "uaddv<mode>4"
7430 [(parallel [(set (reg:CCC FLAGS_REG)
7431 (compare:CCC
7432 (plus:SWIDWI
7433 (match_operand:SWIDWI 1 "nonimmediate_operand")
7434 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7435 (match_dup 1)))
7436 (set (match_operand:SWIDWI 0 "register_operand")
7437 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7438 (set (pc) (if_then_else
7439 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7440 (label_ref (match_operand 3))
7441 (pc)))]
7442 ""
7443 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7444
7445 ;; The lea patterns for modes less than 32 bits need to be matched by
7446 ;; several insns converted to real lea by splitters.
7447
7448 (define_insn_and_split "*lea<mode>_general_1"
7449 [(set (match_operand:SWI12 0 "register_operand" "=r")
7450 (plus:SWI12
7451 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7452 (match_operand:SWI12 2 "register_operand" "r"))
7453 (match_operand:SWI12 3 "immediate_operand" "i")))]
7454 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7455 "#"
7456 "&& reload_completed"
7457 [(set (match_dup 0)
7458 (plus:SI
7459 (plus:SI (match_dup 1) (match_dup 2))
7460 (match_dup 3)))]
7461 {
7462 operands[0] = gen_lowpart (SImode, operands[0]);
7463 operands[1] = gen_lowpart (SImode, operands[1]);
7464 operands[2] = gen_lowpart (SImode, operands[2]);
7465 operands[3] = gen_lowpart (SImode, operands[3]);
7466 }
7467 [(set_attr "type" "lea")
7468 (set_attr "mode" "SI")])
7469
7470 (define_insn_and_split "*lea<mode>_general_2"
7471 [(set (match_operand:SWI12 0 "register_operand" "=r")
7472 (plus:SWI12
7473 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7474 (match_operand 2 "const248_operand" "n"))
7475 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7476 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7477 "#"
7478 "&& reload_completed"
7479 [(set (match_dup 0)
7480 (plus:SI
7481 (mult:SI (match_dup 1) (match_dup 2))
7482 (match_dup 3)))]
7483 {
7484 operands[0] = gen_lowpart (SImode, operands[0]);
7485 operands[1] = gen_lowpart (SImode, operands[1]);
7486 operands[3] = gen_lowpart (SImode, operands[3]);
7487 }
7488 [(set_attr "type" "lea")
7489 (set_attr "mode" "SI")])
7490
7491 (define_insn_and_split "*lea<mode>_general_2b"
7492 [(set (match_operand:SWI12 0 "register_operand" "=r")
7493 (plus:SWI12
7494 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7495 (match_operand 2 "const123_operand" "n"))
7496 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7497 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7498 "#"
7499 "&& reload_completed"
7500 [(set (match_dup 0)
7501 (plus:SI
7502 (ashift:SI (match_dup 1) (match_dup 2))
7503 (match_dup 3)))]
7504 {
7505 operands[0] = gen_lowpart (SImode, operands[0]);
7506 operands[1] = gen_lowpart (SImode, operands[1]);
7507 operands[3] = gen_lowpart (SImode, operands[3]);
7508 }
7509 [(set_attr "type" "lea")
7510 (set_attr "mode" "SI")])
7511
7512 (define_insn_and_split "*lea<mode>_general_3"
7513 [(set (match_operand:SWI12 0 "register_operand" "=r")
7514 (plus:SWI12
7515 (plus:SWI12
7516 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7517 (match_operand 2 "const248_operand" "n"))
7518 (match_operand:SWI12 3 "register_operand" "r"))
7519 (match_operand:SWI12 4 "immediate_operand" "i")))]
7520 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7521 "#"
7522 "&& reload_completed"
7523 [(set (match_dup 0)
7524 (plus:SI
7525 (plus:SI
7526 (mult:SI (match_dup 1) (match_dup 2))
7527 (match_dup 3))
7528 (match_dup 4)))]
7529 {
7530 operands[0] = gen_lowpart (SImode, operands[0]);
7531 operands[1] = gen_lowpart (SImode, operands[1]);
7532 operands[3] = gen_lowpart (SImode, operands[3]);
7533 operands[4] = gen_lowpart (SImode, operands[4]);
7534 }
7535 [(set_attr "type" "lea")
7536 (set_attr "mode" "SI")])
7537
7538 (define_insn_and_split "*lea<mode>_general_3b"
7539 [(set (match_operand:SWI12 0 "register_operand" "=r")
7540 (plus:SWI12
7541 (plus:SWI12
7542 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7543 (match_operand 2 "const123_operand" "n"))
7544 (match_operand:SWI12 3 "register_operand" "r"))
7545 (match_operand:SWI12 4 "immediate_operand" "i")))]
7546 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7547 "#"
7548 "&& reload_completed"
7549 [(set (match_dup 0)
7550 (plus:SI
7551 (plus:SI
7552 (ashift:SI (match_dup 1) (match_dup 2))
7553 (match_dup 3))
7554 (match_dup 4)))]
7555 {
7556 operands[0] = gen_lowpart (SImode, operands[0]);
7557 operands[1] = gen_lowpart (SImode, operands[1]);
7558 operands[3] = gen_lowpart (SImode, operands[3]);
7559 operands[4] = gen_lowpart (SImode, operands[4]);
7560 }
7561 [(set_attr "type" "lea")
7562 (set_attr "mode" "SI")])
7563
7564 (define_insn_and_split "*lea<mode>_general_4"
7565 [(set (match_operand:SWI12 0 "register_operand" "=r")
7566 (any_or:SWI12
7567 (ashift:SWI12
7568 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7569 (match_operand 2 "const_0_to_3_operand"))
7570 (match_operand 3 "const_int_operand")))]
7571 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7572 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7573 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7574 "#"
7575 "&& reload_completed"
7576 [(set (match_dup 0)
7577 (plus:SI
7578 (mult:SI (match_dup 1) (match_dup 2))
7579 (match_dup 3)))]
7580 {
7581 operands[0] = gen_lowpart (SImode, operands[0]);
7582 operands[1] = gen_lowpart (SImode, operands[1]);
7583 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7584 }
7585 [(set_attr "type" "lea")
7586 (set_attr "mode" "SI")])
7587
7588 (define_insn_and_split "*lea<mode>_general_4"
7589 [(set (match_operand:SWI48 0 "register_operand" "=r")
7590 (any_or:SWI48
7591 (ashift:SWI48
7592 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7593 (match_operand 2 "const_0_to_3_operand"))
7594 (match_operand 3 "const_int_operand")))]
7595 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7596 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7597 "#"
7598 "&& reload_completed"
7599 [(set (match_dup 0)
7600 (plus:SWI48
7601 (mult:SWI48 (match_dup 1) (match_dup 2))
7602 (match_dup 3)))]
7603 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7604 [(set_attr "type" "lea")
7605 (set_attr "mode" "<MODE>")])
7606 \f
7607 ;; Subtract instructions
7608
7609 (define_expand "sub<mode>3"
7610 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7611 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7612 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7613 ""
7614 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7615
7616 (define_insn_and_split "*sub<dwi>3_doubleword"
7617 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7618 (minus:<DWI>
7619 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7620 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7621 (clobber (reg:CC FLAGS_REG))]
7622 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7623 "#"
7624 "&& reload_completed"
7625 [(parallel [(set (reg:CC FLAGS_REG)
7626 (compare:CC (match_dup 1) (match_dup 2)))
7627 (set (match_dup 0)
7628 (minus:DWIH (match_dup 1) (match_dup 2)))])
7629 (parallel [(set (match_dup 3)
7630 (minus:DWIH
7631 (minus:DWIH
7632 (match_dup 4)
7633 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7634 (match_dup 5)))
7635 (clobber (reg:CC FLAGS_REG))])]
7636 {
7637 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7638 if (operands[2] == const0_rtx)
7639 {
7640 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7641 DONE;
7642 }
7643 })
7644
7645 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7646 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7647 (minus:<DWI>
7648 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7649 (zero_extend:<DWI>
7650 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7651 (clobber (reg:CC FLAGS_REG))]
7652 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7653 "#"
7654 "&& reload_completed"
7655 [(parallel [(set (reg:CC FLAGS_REG)
7656 (compare:CC (match_dup 1) (match_dup 2)))
7657 (set (match_dup 0)
7658 (minus:DWIH (match_dup 1) (match_dup 2)))])
7659 (parallel [(set (match_dup 3)
7660 (minus:DWIH
7661 (minus:DWIH
7662 (match_dup 4)
7663 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7664 (const_int 0)))
7665 (clobber (reg:CC FLAGS_REG))])]
7666 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7667
7668 (define_insn "*sub<mode>_1"
7669 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7670 (minus:SWI
7671 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7672 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7673 (clobber (reg:CC FLAGS_REG))]
7674 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7675 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7676 [(set_attr "type" "alu")
7677 (set_attr "mode" "<MODE>")])
7678
7679 (define_insn "*subsi_1_zext"
7680 [(set (match_operand:DI 0 "register_operand" "=r")
7681 (zero_extend:DI
7682 (minus:SI (match_operand:SI 1 "register_operand" "0")
7683 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7684 (clobber (reg:CC FLAGS_REG))]
7685 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7686 "sub{l}\t{%2, %k0|%k0, %2}"
7687 [(set_attr "type" "alu")
7688 (set_attr "mode" "SI")])
7689
7690 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7691 (define_insn_and_split "*sub<mode>_1_slp"
7692 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7693 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7694 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7695 (clobber (reg:CC FLAGS_REG))]
7696 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7697 "@
7698 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7699 #"
7700 "&& reload_completed"
7701 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7702 (parallel
7703 [(set (strict_low_part (match_dup 0))
7704 (minus:SWI12 (match_dup 0) (match_dup 2)))
7705 (clobber (reg:CC FLAGS_REG))])]
7706 ""
7707 [(set_attr "type" "alu")
7708 (set_attr "mode" "<MODE>")])
7709
7710 (define_insn "*sub<mode>_2"
7711 [(set (reg FLAGS_REG)
7712 (compare
7713 (minus:SWI
7714 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7715 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7716 (const_int 0)))
7717 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7718 (minus:SWI (match_dup 1) (match_dup 2)))]
7719 "ix86_match_ccmode (insn, CCGOCmode)
7720 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7721 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7722 [(set_attr "type" "alu")
7723 (set_attr "mode" "<MODE>")])
7724
7725 (define_insn "*subsi_2_zext"
7726 [(set (reg FLAGS_REG)
7727 (compare
7728 (minus:SI (match_operand:SI 1 "register_operand" "0")
7729 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7730 (const_int 0)))
7731 (set (match_operand:DI 0 "register_operand" "=r")
7732 (zero_extend:DI
7733 (minus:SI (match_dup 1)
7734 (match_dup 2))))]
7735 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7736 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7737 "sub{l}\t{%2, %k0|%k0, %2}"
7738 [(set_attr "type" "alu")
7739 (set_attr "mode" "SI")])
7740
7741 (define_insn "*subqi_ext<mode>_0"
7742 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7743 (minus:QI
7744 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
7745 (subreg:QI
7746 (match_operator:SWI248 3 "extract_operator"
7747 [(match_operand 2 "int248_register_operand" "Q,Q")
7748 (const_int 8)
7749 (const_int 8)]) 0)))
7750 (clobber (reg:CC FLAGS_REG))]
7751 ""
7752 "sub{b}\t{%h2, %0|%0, %h2}"
7753 [(set_attr "isa" "*,nox64")
7754 (set_attr "type" "alu")
7755 (set_attr "mode" "QI")])
7756
7757 (define_insn "*subqi_ext<mode>_2"
7758 [(set (zero_extract:SWI248
7759 (match_operand 0 "int248_register_operand" "+Q")
7760 (const_int 8)
7761 (const_int 8))
7762 (subreg:SWI248
7763 (minus:QI
7764 (subreg:QI
7765 (match_operator:SWI248 3 "extract_operator"
7766 [(match_operand 1 "int248_register_operand" "0")
7767 (const_int 8)
7768 (const_int 8)]) 0)
7769 (subreg:QI
7770 (match_operator:SWI248 4 "extract_operator"
7771 [(match_operand 2 "int248_register_operand" "Q")
7772 (const_int 8)
7773 (const_int 8)]) 0)) 0))
7774 (clobber (reg:CC FLAGS_REG))]
7775 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7776 rtx_equal_p (operands[0], operands[1])"
7777 "sub{b}\t{%h2, %h0|%h0, %h2}"
7778 [(set_attr "type" "alu")
7779 (set_attr "mode" "QI")])
7780
7781 ;; Subtract with jump on overflow.
7782 (define_expand "subv<mode>4"
7783 [(parallel [(set (reg:CCO FLAGS_REG)
7784 (eq:CCO
7785 (minus:<DPWI>
7786 (sign_extend:<DPWI>
7787 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7788 (match_dup 4))
7789 (sign_extend:<DPWI>
7790 (minus:SWIDWI (match_dup 1)
7791 (match_operand:SWIDWI 2
7792 "<general_hilo_operand>")))))
7793 (set (match_operand:SWIDWI 0 "register_operand")
7794 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7795 (set (pc) (if_then_else
7796 (eq (reg:CCO FLAGS_REG) (const_int 0))
7797 (label_ref (match_operand 3))
7798 (pc)))]
7799 ""
7800 {
7801 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7802 if (CONST_SCALAR_INT_P (operands[2]))
7803 operands[4] = operands[2];
7804 else
7805 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7806 })
7807
7808 (define_insn "*subv<mode>4"
7809 [(set (reg:CCO FLAGS_REG)
7810 (eq:CCO (minus:<DWI>
7811 (sign_extend:<DWI>
7812 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7813 (sign_extend:<DWI>
7814 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7815 (sign_extend:<DWI>
7816 (minus:SWI (match_dup 1) (match_dup 2)))))
7817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7818 (minus:SWI (match_dup 1) (match_dup 2)))]
7819 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7820 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7821 [(set_attr "type" "alu")
7822 (set_attr "mode" "<MODE>")])
7823
7824 (define_insn "subv<mode>4_1"
7825 [(set (reg:CCO FLAGS_REG)
7826 (eq:CCO (minus:<DWI>
7827 (sign_extend:<DWI>
7828 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7829 (match_operand:<DWI> 3 "const_int_operand"))
7830 (sign_extend:<DWI>
7831 (minus:SWI
7832 (match_dup 1)
7833 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7834 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7835 (minus:SWI (match_dup 1) (match_dup 2)))]
7836 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7837 && CONST_INT_P (operands[2])
7838 && INTVAL (operands[2]) == INTVAL (operands[3])"
7839 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7840 [(set_attr "type" "alu")
7841 (set_attr "mode" "<MODE>")
7842 (set (attr "length_immediate")
7843 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7844 (const_string "1")
7845 (match_test "<MODE_SIZE> == 8")
7846 (const_string "4")]
7847 (const_string "<MODE_SIZE>")))])
7848
7849 (define_insn_and_split "*subv<dwi>4_doubleword"
7850 [(set (reg:CCO FLAGS_REG)
7851 (eq:CCO
7852 (minus:<QPWI>
7853 (sign_extend:<QPWI>
7854 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7855 (sign_extend:<QPWI>
7856 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7857 (sign_extend:<QPWI>
7858 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7859 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7860 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7861 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7862 "#"
7863 "&& reload_completed"
7864 [(parallel [(set (reg:CC FLAGS_REG)
7865 (compare:CC (match_dup 1) (match_dup 2)))
7866 (set (match_dup 0)
7867 (minus:DWIH (match_dup 1) (match_dup 2)))])
7868 (parallel [(set (reg:CCO FLAGS_REG)
7869 (eq:CCO
7870 (minus:<DWI>
7871 (minus:<DWI>
7872 (sign_extend:<DWI> (match_dup 4))
7873 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7874 (sign_extend:<DWI> (match_dup 5)))
7875 (sign_extend:<DWI>
7876 (minus:DWIH
7877 (minus:DWIH
7878 (match_dup 4)
7879 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7880 (match_dup 5)))))
7881 (set (match_dup 3)
7882 (minus:DWIH
7883 (minus:DWIH
7884 (match_dup 4)
7885 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7886 (match_dup 5)))])]
7887 {
7888 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7889 })
7890
7891 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7892 [(set (reg:CCO FLAGS_REG)
7893 (eq:CCO
7894 (minus:<QPWI>
7895 (sign_extend:<QPWI>
7896 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7897 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7898 (sign_extend:<QPWI>
7899 (minus:<DWI>
7900 (match_dup 1)
7901 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7902 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7903 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7904 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7905 && CONST_SCALAR_INT_P (operands[2])
7906 && rtx_equal_p (operands[2], operands[3])"
7907 "#"
7908 "&& reload_completed"
7909 [(parallel [(set (reg:CC FLAGS_REG)
7910 (compare:CC (match_dup 1) (match_dup 2)))
7911 (set (match_dup 0)
7912 (minus:DWIH (match_dup 1) (match_dup 2)))])
7913 (parallel [(set (reg:CCO FLAGS_REG)
7914 (eq:CCO
7915 (minus:<DWI>
7916 (minus:<DWI>
7917 (sign_extend:<DWI> (match_dup 4))
7918 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7919 (match_dup 5))
7920 (sign_extend:<DWI>
7921 (minus:DWIH
7922 (minus:DWIH
7923 (match_dup 4)
7924 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7925 (match_dup 5)))))
7926 (set (match_dup 3)
7927 (minus:DWIH
7928 (minus:DWIH
7929 (match_dup 4)
7930 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7931 (match_dup 5)))])]
7932 {
7933 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7934 if (operands[2] == const0_rtx)
7935 {
7936 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7937 operands[5]));
7938 DONE;
7939 }
7940 })
7941
7942 (define_insn "*subv<mode>4_overflow_1"
7943 [(set (reg:CCO FLAGS_REG)
7944 (eq:CCO
7945 (minus:<DWI>
7946 (minus:<DWI>
7947 (sign_extend:<DWI>
7948 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7949 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7950 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7951 (sign_extend:<DWI>
7952 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7953 (sign_extend:<DWI>
7954 (minus:SWI
7955 (minus:SWI
7956 (match_dup 1)
7957 (match_operator:SWI 5 "ix86_carry_flag_operator"
7958 [(match_dup 3) (const_int 0)]))
7959 (match_dup 2)))))
7960 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7961 (minus:SWI
7962 (minus:SWI
7963 (match_dup 1)
7964 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7965 (match_dup 2)))]
7966 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7967 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7968 [(set_attr "type" "alu")
7969 (set_attr "mode" "<MODE>")])
7970
7971 (define_insn "*subv<mode>4_overflow_2"
7972 [(set (reg:CCO FLAGS_REG)
7973 (eq:CCO
7974 (minus:<DWI>
7975 (minus:<DWI>
7976 (sign_extend:<DWI>
7977 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7978 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7979 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7980 (match_operand:<DWI> 6 "const_int_operand" "n"))
7981 (sign_extend:<DWI>
7982 (minus:SWI
7983 (minus:SWI
7984 (match_dup 1)
7985 (match_operator:SWI 5 "ix86_carry_flag_operator"
7986 [(match_dup 3) (const_int 0)]))
7987 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7988 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7989 (minus:SWI
7990 (minus:SWI
7991 (match_dup 1)
7992 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7993 (match_dup 2)))]
7994 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7995 && CONST_INT_P (operands[2])
7996 && INTVAL (operands[2]) == INTVAL (operands[6])"
7997 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7998 [(set_attr "type" "alu")
7999 (set_attr "mode" "<MODE>")
8000 (set (attr "length_immediate")
8001 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8002 (const_string "1")
8003 (const_string "4")))])
8004
8005 (define_expand "usubv<mode>4"
8006 [(parallel [(set (reg:CC FLAGS_REG)
8007 (compare:CC
8008 (match_operand:SWI 1 "nonimmediate_operand")
8009 (match_operand:SWI 2 "<general_operand>")))
8010 (set (match_operand:SWI 0 "register_operand")
8011 (minus:SWI (match_dup 1) (match_dup 2)))])
8012 (set (pc) (if_then_else
8013 (ltu (reg:CC FLAGS_REG) (const_int 0))
8014 (label_ref (match_operand 3))
8015 (pc)))]
8016 ""
8017 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
8018
8019 (define_insn "*sub<mode>_3"
8020 [(set (reg FLAGS_REG)
8021 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8022 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8023 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8024 (minus:SWI (match_dup 1) (match_dup 2)))]
8025 "ix86_match_ccmode (insn, CCmode)
8026 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8027 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
8028 [(set_attr "type" "alu")
8029 (set_attr "mode" "<MODE>")])
8030
8031 (define_peephole2
8032 [(parallel
8033 [(set (reg:CC FLAGS_REG)
8034 (compare:CC (match_operand:SWI 0 "general_reg_operand")
8035 (match_operand:SWI 1 "general_gr_operand")))
8036 (set (match_dup 0)
8037 (minus:SWI (match_dup 0) (match_dup 1)))])]
8038 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8039 [(set (reg:CC FLAGS_REG)
8040 (compare:CC (match_dup 0) (match_dup 1)))])
8041
8042 (define_peephole2
8043 [(set (match_operand:SWI 0 "general_reg_operand")
8044 (match_operand:SWI 1 "memory_operand"))
8045 (parallel [(set (reg:CC FLAGS_REG)
8046 (compare:CC (match_dup 0)
8047 (match_operand:SWI 2 "memory_operand")))
8048 (set (match_dup 0)
8049 (minus:SWI (match_dup 0) (match_dup 2)))])
8050 (set (match_dup 1) (match_dup 0))]
8051 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8052 && peep2_reg_dead_p (3, operands[0])
8053 && !reg_overlap_mentioned_p (operands[0], operands[1])
8054 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8055 [(set (match_dup 0) (match_dup 2))
8056 (parallel [(set (reg:CC FLAGS_REG)
8057 (compare:CC (match_dup 1) (match_dup 0)))
8058 (set (match_dup 1)
8059 (minus:SWI (match_dup 1) (match_dup 0)))])])
8060
8061 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8062 ;; subl $1, %eax; jnc .Lxx;
8063 (define_peephole2
8064 [(parallel
8065 [(set (match_operand:SWI 0 "general_reg_operand")
8066 (plus:SWI (match_dup 0) (const_int -1)))
8067 (clobber (reg FLAGS_REG))])
8068 (set (reg:CCZ FLAGS_REG)
8069 (compare:CCZ (match_dup 0) (const_int -1)))
8070 (set (pc)
8071 (if_then_else (match_operator 1 "bt_comparison_operator"
8072 [(reg:CCZ FLAGS_REG) (const_int 0)])
8073 (match_operand 2)
8074 (pc)))]
8075 "peep2_regno_dead_p (3, FLAGS_REG)"
8076 [(parallel
8077 [(set (reg:CC FLAGS_REG)
8078 (compare:CC (match_dup 0) (const_int 1)))
8079 (set (match_dup 0)
8080 (minus:SWI (match_dup 0) (const_int 1)))])
8081 (set (pc)
8082 (if_then_else (match_dup 3)
8083 (match_dup 2)
8084 (pc)))]
8085 {
8086 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8087 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8088 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8089 })
8090
8091 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8092 (define_insn_and_split "*dec_cmov<mode>"
8093 [(set (match_operand:SWI248 0 "register_operand" "=r")
8094 (if_then_else:SWI248
8095 (match_operator 1 "bt_comparison_operator"
8096 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8097 (plus:SWI248 (match_dup 2) (const_int -1))
8098 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8099 (clobber (reg:CC FLAGS_REG))]
8100 "TARGET_CMOVE"
8101 "#"
8102 "&& reload_completed"
8103 [(parallel [(set (reg:CC FLAGS_REG)
8104 (compare:CC (match_dup 2) (const_int 1)))
8105 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8106 (set (match_dup 0)
8107 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8108 {
8109 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8110 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8111 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8112 })
8113
8114 (define_insn "*subsi_3_zext"
8115 [(set (reg FLAGS_REG)
8116 (compare (match_operand:SI 1 "register_operand" "0")
8117 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
8118 (set (match_operand:DI 0 "register_operand" "=r")
8119 (zero_extend:DI
8120 (minus:SI (match_dup 1)
8121 (match_dup 2))))]
8122 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8123 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8124 "sub{l}\t{%2, %1|%1, %2}"
8125 [(set_attr "type" "alu")
8126 (set_attr "mode" "SI")])
8127 \f
8128 ;; Add with carry and subtract with borrow
8129
8130 (define_insn "@add<mode>3_carry"
8131 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8132 (plus:SWI
8133 (plus:SWI
8134 (match_operator:SWI 4 "ix86_carry_flag_operator"
8135 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8136 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8137 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8138 (clobber (reg:CC FLAGS_REG))]
8139 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8140 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8141 [(set_attr "type" "alu")
8142 (set_attr "use_carry" "1")
8143 (set_attr "pent_pair" "pu")
8144 (set_attr "mode" "<MODE>")])
8145
8146 (define_peephole2
8147 [(set (match_operand:SWI 0 "general_reg_operand")
8148 (match_operand:SWI 1 "memory_operand"))
8149 (parallel [(set (match_dup 0)
8150 (plus:SWI
8151 (plus:SWI
8152 (match_operator:SWI 4 "ix86_carry_flag_operator"
8153 [(match_operand 3 "flags_reg_operand")
8154 (const_int 0)])
8155 (match_dup 0))
8156 (match_operand:SWI 2 "memory_operand")))
8157 (clobber (reg:CC FLAGS_REG))])
8158 (set (match_dup 1) (match_dup 0))]
8159 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8160 && peep2_reg_dead_p (3, operands[0])
8161 && !reg_overlap_mentioned_p (operands[0], operands[1])
8162 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8163 [(set (match_dup 0) (match_dup 2))
8164 (parallel [(set (match_dup 1)
8165 (plus:SWI (plus:SWI (match_op_dup 4
8166 [(match_dup 3) (const_int 0)])
8167 (match_dup 1))
8168 (match_dup 0)))
8169 (clobber (reg:CC FLAGS_REG))])])
8170
8171 (define_peephole2
8172 [(set (match_operand:SWI 0 "general_reg_operand")
8173 (match_operand:SWI 1 "memory_operand"))
8174 (parallel [(set (match_dup 0)
8175 (plus:SWI
8176 (plus:SWI
8177 (match_operator:SWI 4 "ix86_carry_flag_operator"
8178 [(match_operand 3 "flags_reg_operand")
8179 (const_int 0)])
8180 (match_dup 0))
8181 (match_operand:SWI 2 "memory_operand")))
8182 (clobber (reg:CC FLAGS_REG))])
8183 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8184 (set (match_dup 1) (match_dup 5))]
8185 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8186 && peep2_reg_dead_p (3, operands[0])
8187 && peep2_reg_dead_p (4, operands[5])
8188 && !reg_overlap_mentioned_p (operands[0], operands[1])
8189 && !reg_overlap_mentioned_p (operands[0], operands[2])
8190 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8191 [(set (match_dup 0) (match_dup 2))
8192 (parallel [(set (match_dup 1)
8193 (plus:SWI (plus:SWI (match_op_dup 4
8194 [(match_dup 3) (const_int 0)])
8195 (match_dup 1))
8196 (match_dup 0)))
8197 (clobber (reg:CC FLAGS_REG))])])
8198
8199 (define_insn "*add<mode>3_carry_0"
8200 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8201 (plus:SWI
8202 (match_operator:SWI 2 "ix86_carry_flag_operator"
8203 [(reg FLAGS_REG) (const_int 0)])
8204 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8207 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8208 [(set_attr "type" "alu")
8209 (set_attr "use_carry" "1")
8210 (set_attr "pent_pair" "pu")
8211 (set_attr "mode" "<MODE>")])
8212
8213 (define_insn "*add<mode>3_carry_0r"
8214 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8215 (plus:SWI
8216 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8217 [(reg FLAGS_REG) (const_int 0)])
8218 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8219 (clobber (reg:CC FLAGS_REG))]
8220 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8221 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8222 [(set_attr "type" "alu")
8223 (set_attr "use_carry" "1")
8224 (set_attr "pent_pair" "pu")
8225 (set_attr "mode" "<MODE>")])
8226
8227 (define_insn "*addsi3_carry_zext"
8228 [(set (match_operand:DI 0 "register_operand" "=r")
8229 (zero_extend:DI
8230 (plus:SI
8231 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8232 [(reg FLAGS_REG) (const_int 0)])
8233 (match_operand:SI 1 "register_operand" "%0"))
8234 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8235 (clobber (reg:CC FLAGS_REG))]
8236 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8237 "adc{l}\t{%2, %k0|%k0, %2}"
8238 [(set_attr "type" "alu")
8239 (set_attr "use_carry" "1")
8240 (set_attr "pent_pair" "pu")
8241 (set_attr "mode" "SI")])
8242
8243 (define_insn "*addsi3_carry_zext_0"
8244 [(set (match_operand:DI 0 "register_operand" "=r")
8245 (zero_extend:DI
8246 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8247 [(reg FLAGS_REG) (const_int 0)])
8248 (match_operand:SI 1 "register_operand" "0"))))
8249 (clobber (reg:CC FLAGS_REG))]
8250 "TARGET_64BIT"
8251 "adc{l}\t{$0, %k0|%k0, 0}"
8252 [(set_attr "type" "alu")
8253 (set_attr "use_carry" "1")
8254 (set_attr "pent_pair" "pu")
8255 (set_attr "mode" "SI")])
8256
8257 (define_insn "*addsi3_carry_zext_0r"
8258 [(set (match_operand:DI 0 "register_operand" "=r")
8259 (zero_extend:DI
8260 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8261 [(reg FLAGS_REG) (const_int 0)])
8262 (match_operand:SI 1 "register_operand" "0"))))
8263 (clobber (reg:CC FLAGS_REG))]
8264 "TARGET_64BIT"
8265 "sbb{l}\t{$-1, %k0|%k0, -1}"
8266 [(set_attr "type" "alu")
8267 (set_attr "use_carry" "1")
8268 (set_attr "pent_pair" "pu")
8269 (set_attr "mode" "SI")])
8270
8271 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8272
8273 (define_insn "addcarry<mode>"
8274 [(set (reg:CCC FLAGS_REG)
8275 (compare:CCC
8276 (zero_extend:<DWI>
8277 (plus:SWI48
8278 (plus:SWI48
8279 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8280 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8281 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8282 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8283 (plus:<DWI>
8284 (zero_extend:<DWI> (match_dup 2))
8285 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8286 [(match_dup 3) (const_int 0)]))))
8287 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8288 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8289 [(match_dup 3) (const_int 0)])
8290 (match_dup 1))
8291 (match_dup 2)))]
8292 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8293 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8294 [(set_attr "type" "alu")
8295 (set_attr "use_carry" "1")
8296 (set_attr "pent_pair" "pu")
8297 (set_attr "mode" "<MODE>")])
8298
8299 (define_peephole2
8300 [(parallel [(set (reg:CCC FLAGS_REG)
8301 (compare:CCC
8302 (zero_extend:<DWI>
8303 (plus:SWI48
8304 (plus:SWI48
8305 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8306 [(match_operand 2 "flags_reg_operand")
8307 (const_int 0)])
8308 (match_operand:SWI48 0 "general_reg_operand"))
8309 (match_operand:SWI48 1 "memory_operand")))
8310 (plus:<DWI>
8311 (zero_extend:<DWI> (match_dup 1))
8312 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8313 [(match_dup 2) (const_int 0)]))))
8314 (set (match_dup 0)
8315 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8316 [(match_dup 2) (const_int 0)])
8317 (match_dup 0))
8318 (match_dup 1)))])
8319 (set (match_dup 1) (match_dup 0))]
8320 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8321 && peep2_reg_dead_p (2, operands[0])
8322 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8323 [(parallel [(set (reg:CCC FLAGS_REG)
8324 (compare:CCC
8325 (zero_extend:<DWI>
8326 (plus:SWI48
8327 (plus:SWI48
8328 (match_op_dup 4
8329 [(match_dup 2) (const_int 0)])
8330 (match_dup 1))
8331 (match_dup 0)))
8332 (plus:<DWI>
8333 (zero_extend:<DWI> (match_dup 0))
8334 (match_op_dup 3
8335 [(match_dup 2) (const_int 0)]))))
8336 (set (match_dup 1)
8337 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8338 [(match_dup 2) (const_int 0)])
8339 (match_dup 1))
8340 (match_dup 0)))])])
8341
8342 (define_peephole2
8343 [(set (match_operand:SWI48 0 "general_reg_operand")
8344 (match_operand:SWI48 1 "memory_operand"))
8345 (parallel [(set (reg:CCC FLAGS_REG)
8346 (compare:CCC
8347 (zero_extend:<DWI>
8348 (plus:SWI48
8349 (plus:SWI48
8350 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8351 [(match_operand 3 "flags_reg_operand")
8352 (const_int 0)])
8353 (match_dup 0))
8354 (match_operand:SWI48 2 "memory_operand")))
8355 (plus:<DWI>
8356 (zero_extend:<DWI> (match_dup 2))
8357 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8358 [(match_dup 3) (const_int 0)]))))
8359 (set (match_dup 0)
8360 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8361 [(match_dup 3) (const_int 0)])
8362 (match_dup 0))
8363 (match_dup 2)))])
8364 (set (match_dup 1) (match_dup 0))]
8365 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8366 && peep2_reg_dead_p (3, operands[0])
8367 && !reg_overlap_mentioned_p (operands[0], operands[1])
8368 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8369 [(set (match_dup 0) (match_dup 2))
8370 (parallel [(set (reg:CCC FLAGS_REG)
8371 (compare:CCC
8372 (zero_extend:<DWI>
8373 (plus:SWI48
8374 (plus:SWI48
8375 (match_op_dup 5
8376 [(match_dup 3) (const_int 0)])
8377 (match_dup 1))
8378 (match_dup 0)))
8379 (plus:<DWI>
8380 (zero_extend:<DWI> (match_dup 0))
8381 (match_op_dup 4
8382 [(match_dup 3) (const_int 0)]))))
8383 (set (match_dup 1)
8384 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8385 [(match_dup 3) (const_int 0)])
8386 (match_dup 1))
8387 (match_dup 0)))])])
8388
8389 (define_peephole2
8390 [(parallel [(set (reg:CCC FLAGS_REG)
8391 (compare:CCC
8392 (zero_extend:<DWI>
8393 (plus:SWI48
8394 (plus:SWI48
8395 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8396 [(match_operand 2 "flags_reg_operand")
8397 (const_int 0)])
8398 (match_operand:SWI48 0 "general_reg_operand"))
8399 (match_operand:SWI48 1 "memory_operand")))
8400 (plus:<DWI>
8401 (zero_extend:<DWI> (match_dup 1))
8402 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8403 [(match_dup 2) (const_int 0)]))))
8404 (set (match_dup 0)
8405 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8406 [(match_dup 2) (const_int 0)])
8407 (match_dup 0))
8408 (match_dup 1)))])
8409 (set (match_operand:QI 5 "general_reg_operand")
8410 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8411 (set (match_operand:SWI48 6 "general_reg_operand")
8412 (zero_extend:SWI48 (match_dup 5)))
8413 (set (match_dup 1) (match_dup 0))]
8414 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8415 && peep2_reg_dead_p (4, operands[0])
8416 && !reg_overlap_mentioned_p (operands[0], operands[1])
8417 && !reg_overlap_mentioned_p (operands[0], operands[5])
8418 && !reg_overlap_mentioned_p (operands[5], operands[1])
8419 && !reg_overlap_mentioned_p (operands[0], operands[6])
8420 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8421 [(parallel [(set (reg:CCC FLAGS_REG)
8422 (compare:CCC
8423 (zero_extend:<DWI>
8424 (plus:SWI48
8425 (plus:SWI48
8426 (match_op_dup 4
8427 [(match_dup 2) (const_int 0)])
8428 (match_dup 1))
8429 (match_dup 0)))
8430 (plus:<DWI>
8431 (zero_extend:<DWI> (match_dup 0))
8432 (match_op_dup 3
8433 [(match_dup 2) (const_int 0)]))))
8434 (set (match_dup 1)
8435 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8436 [(match_dup 2) (const_int 0)])
8437 (match_dup 1))
8438 (match_dup 0)))])
8439 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8440 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8441
8442 (define_expand "addcarry<mode>_0"
8443 [(parallel
8444 [(set (reg:CCC FLAGS_REG)
8445 (compare:CCC
8446 (plus:SWI48
8447 (match_operand:SWI48 1 "nonimmediate_operand")
8448 (match_operand:SWI48 2 "x86_64_general_operand"))
8449 (match_dup 1)))
8450 (set (match_operand:SWI48 0 "nonimmediate_operand")
8451 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8452 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8453
8454 (define_insn "*addcarry<mode>_1"
8455 [(set (reg:CCC FLAGS_REG)
8456 (compare:CCC
8457 (zero_extend:<DWI>
8458 (plus:SWI48
8459 (plus:SWI48
8460 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8461 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8462 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8463 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8464 (plus:<DWI>
8465 (match_operand:<DWI> 6 "const_scalar_int_operand")
8466 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8467 [(match_dup 3) (const_int 0)]))))
8468 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8469 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8470 [(match_dup 3) (const_int 0)])
8471 (match_dup 1))
8472 (match_dup 2)))]
8473 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8474 && CONST_INT_P (operands[2])
8475 /* Check that operands[6] is operands[2] zero extended from
8476 <MODE>mode to <DWI>mode. */
8477 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8478 ? (CONST_INT_P (operands[6])
8479 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8480 & GET_MODE_MASK (<MODE>mode)))
8481 : (CONST_WIDE_INT_P (operands[6])
8482 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8483 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8484 == UINTVAL (operands[2]))
8485 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8486 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8487 [(set_attr "type" "alu")
8488 (set_attr "use_carry" "1")
8489 (set_attr "pent_pair" "pu")
8490 (set_attr "mode" "<MODE>")
8491 (set (attr "length_immediate")
8492 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8493 (const_string "1")
8494 (const_string "4")))])
8495
8496 (define_insn "@sub<mode>3_carry"
8497 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8498 (minus:SWI
8499 (minus:SWI
8500 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8501 (match_operator:SWI 4 "ix86_carry_flag_operator"
8502 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8503 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8504 (clobber (reg:CC FLAGS_REG))]
8505 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8506 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8507 [(set_attr "type" "alu")
8508 (set_attr "use_carry" "1")
8509 (set_attr "pent_pair" "pu")
8510 (set_attr "mode" "<MODE>")])
8511
8512 (define_peephole2
8513 [(set (match_operand:SWI 0 "general_reg_operand")
8514 (match_operand:SWI 1 "memory_operand"))
8515 (parallel [(set (match_dup 0)
8516 (minus:SWI
8517 (minus:SWI
8518 (match_dup 0)
8519 (match_operator:SWI 4 "ix86_carry_flag_operator"
8520 [(match_operand 3 "flags_reg_operand")
8521 (const_int 0)]))
8522 (match_operand:SWI 2 "memory_operand")))
8523 (clobber (reg:CC FLAGS_REG))])
8524 (set (match_dup 1) (match_dup 0))]
8525 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8526 && peep2_reg_dead_p (3, operands[0])
8527 && !reg_overlap_mentioned_p (operands[0], operands[1])
8528 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8529 [(set (match_dup 0) (match_dup 2))
8530 (parallel [(set (match_dup 1)
8531 (minus:SWI (minus:SWI (match_dup 1)
8532 (match_op_dup 4
8533 [(match_dup 3) (const_int 0)]))
8534 (match_dup 0)))
8535 (clobber (reg:CC FLAGS_REG))])])
8536
8537 (define_peephole2
8538 [(set (match_operand:SWI 0 "general_reg_operand")
8539 (match_operand:SWI 1 "memory_operand"))
8540 (parallel [(set (match_dup 0)
8541 (minus:SWI
8542 (minus:SWI
8543 (match_dup 0)
8544 (match_operator:SWI 4 "ix86_carry_flag_operator"
8545 [(match_operand 3 "flags_reg_operand")
8546 (const_int 0)]))
8547 (match_operand:SWI 2 "memory_operand")))
8548 (clobber (reg:CC FLAGS_REG))])
8549 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8550 (set (match_dup 1) (match_dup 5))]
8551 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8552 && peep2_reg_dead_p (3, operands[0])
8553 && peep2_reg_dead_p (4, operands[5])
8554 && !reg_overlap_mentioned_p (operands[0], operands[1])
8555 && !reg_overlap_mentioned_p (operands[0], operands[2])
8556 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8557 [(set (match_dup 0) (match_dup 2))
8558 (parallel [(set (match_dup 1)
8559 (minus:SWI (minus:SWI (match_dup 1)
8560 (match_op_dup 4
8561 [(match_dup 3) (const_int 0)]))
8562 (match_dup 0)))
8563 (clobber (reg:CC FLAGS_REG))])])
8564
8565 (define_insn "*sub<mode>3_carry_0"
8566 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8567 (minus:SWI
8568 (match_operand:SWI 1 "nonimmediate_operand" "0")
8569 (match_operator:SWI 2 "ix86_carry_flag_operator"
8570 [(reg FLAGS_REG) (const_int 0)])))
8571 (clobber (reg:CC FLAGS_REG))]
8572 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8573 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8574 [(set_attr "type" "alu")
8575 (set_attr "use_carry" "1")
8576 (set_attr "pent_pair" "pu")
8577 (set_attr "mode" "<MODE>")])
8578
8579 (define_insn "*sub<mode>3_carry_0r"
8580 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8581 (minus:SWI
8582 (match_operand:SWI 1 "nonimmediate_operand" "0")
8583 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8584 [(reg FLAGS_REG) (const_int 0)])))
8585 (clobber (reg:CC FLAGS_REG))]
8586 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8587 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8588 [(set_attr "type" "alu")
8589 (set_attr "use_carry" "1")
8590 (set_attr "pent_pair" "pu")
8591 (set_attr "mode" "<MODE>")])
8592
8593 (define_insn "*subsi3_carry_zext"
8594 [(set (match_operand:DI 0 "register_operand" "=r")
8595 (zero_extend:DI
8596 (minus:SI
8597 (minus:SI
8598 (match_operand:SI 1 "register_operand" "0")
8599 (match_operator:SI 3 "ix86_carry_flag_operator"
8600 [(reg FLAGS_REG) (const_int 0)]))
8601 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8604 "sbb{l}\t{%2, %k0|%k0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "use_carry" "1")
8607 (set_attr "pent_pair" "pu")
8608 (set_attr "mode" "SI")])
8609
8610 (define_insn "*subsi3_carry_zext_0"
8611 [(set (match_operand:DI 0 "register_operand" "=r")
8612 (zero_extend:DI
8613 (minus:SI
8614 (match_operand:SI 1 "register_operand" "0")
8615 (match_operator:SI 2 "ix86_carry_flag_operator"
8616 [(reg FLAGS_REG) (const_int 0)]))))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "TARGET_64BIT"
8619 "sbb{l}\t{$0, %k0|%k0, 0}"
8620 [(set_attr "type" "alu")
8621 (set_attr "use_carry" "1")
8622 (set_attr "pent_pair" "pu")
8623 (set_attr "mode" "SI")])
8624
8625 (define_insn "*subsi3_carry_zext_0r"
8626 [(set (match_operand:DI 0 "register_operand" "=r")
8627 (zero_extend:DI
8628 (minus:SI
8629 (match_operand:SI 1 "register_operand" "0")
8630 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8631 [(reg FLAGS_REG) (const_int 0)]))))
8632 (clobber (reg:CC FLAGS_REG))]
8633 "TARGET_64BIT"
8634 "adc{l}\t{$-1, %k0|%k0, -1}"
8635 [(set_attr "type" "alu")
8636 (set_attr "use_carry" "1")
8637 (set_attr "pent_pair" "pu")
8638 (set_attr "mode" "SI")])
8639
8640 (define_insn "@sub<mode>3_carry_ccc"
8641 [(set (reg:CCC FLAGS_REG)
8642 (compare:CCC
8643 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8644 (plus:<DWI>
8645 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8646 (zero_extend:<DWI>
8647 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8648 (clobber (match_scratch:DWIH 0 "=r"))]
8649 ""
8650 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8651 [(set_attr "type" "alu")
8652 (set_attr "mode" "<MODE>")])
8653
8654 (define_insn "*sub<mode>3_carry_ccc_1"
8655 [(set (reg:CCC FLAGS_REG)
8656 (compare:CCC
8657 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8658 (plus:<DWI>
8659 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8660 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8661 (clobber (match_scratch:DWIH 0 "=r"))]
8662 ""
8663 {
8664 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8665 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8666 }
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "<MODE>")])
8669
8670 ;; The sign flag is set from the
8671 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8672 ;; result, the overflow flag likewise, but the overflow flag is also
8673 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8674 (define_insn "@sub<mode>3_carry_ccgz"
8675 [(set (reg:CCGZ FLAGS_REG)
8676 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8677 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8678 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8679 UNSPEC_SBB))
8680 (clobber (match_scratch:DWIH 0 "=r"))]
8681 ""
8682 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "<MODE>")])
8685
8686 (define_insn "subborrow<mode>"
8687 [(set (reg:CCC FLAGS_REG)
8688 (compare:CCC
8689 (zero_extend:<DWI>
8690 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8691 (plus:<DWI>
8692 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8693 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8694 (zero_extend:<DWI>
8695 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8696 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8697 (minus:SWI48 (minus:SWI48
8698 (match_dup 1)
8699 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8700 [(match_dup 3) (const_int 0)]))
8701 (match_dup 2)))]
8702 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8703 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "use_carry" "1")
8706 (set_attr "pent_pair" "pu")
8707 (set_attr "mode" "<MODE>")])
8708
8709 (define_peephole2
8710 [(set (match_operand:SWI48 0 "general_reg_operand")
8711 (match_operand:SWI48 1 "memory_operand"))
8712 (parallel [(set (reg:CCC FLAGS_REG)
8713 (compare:CCC
8714 (zero_extend:<DWI> (match_dup 0))
8715 (plus:<DWI>
8716 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8717 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8718 (zero_extend:<DWI>
8719 (match_operand:SWI48 2 "memory_operand")))))
8720 (set (match_dup 0)
8721 (minus:SWI48
8722 (minus:SWI48
8723 (match_dup 0)
8724 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8725 [(match_dup 3) (const_int 0)]))
8726 (match_dup 2)))])
8727 (set (match_dup 1) (match_dup 0))]
8728 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8729 && peep2_reg_dead_p (3, operands[0])
8730 && !reg_overlap_mentioned_p (operands[0], operands[1])
8731 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8732 [(set (match_dup 0) (match_dup 2))
8733 (parallel [(set (reg:CCC FLAGS_REG)
8734 (compare:CCC
8735 (zero_extend:<DWI> (match_dup 1))
8736 (plus:<DWI> (match_op_dup 4
8737 [(match_dup 3) (const_int 0)])
8738 (zero_extend:<DWI> (match_dup 0)))))
8739 (set (match_dup 1)
8740 (minus:SWI48 (minus:SWI48 (match_dup 1)
8741 (match_op_dup 5
8742 [(match_dup 3) (const_int 0)]))
8743 (match_dup 0)))])])
8744
8745 (define_peephole2
8746 [(set (match_operand:SWI48 6 "general_reg_operand")
8747 (match_operand:SWI48 7 "memory_operand"))
8748 (set (match_operand:SWI48 8 "general_reg_operand")
8749 (match_operand:SWI48 9 "memory_operand"))
8750 (parallel [(set (reg:CCC FLAGS_REG)
8751 (compare:CCC
8752 (zero_extend:<DWI>
8753 (match_operand:SWI48 0 "general_reg_operand"))
8754 (plus:<DWI>
8755 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8756 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8757 (zero_extend:<DWI>
8758 (match_operand:SWI48 2 "general_reg_operand")))))
8759 (set (match_dup 0)
8760 (minus:SWI48
8761 (minus:SWI48
8762 (match_dup 0)
8763 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8764 [(match_dup 3) (const_int 0)]))
8765 (match_dup 2)))])
8766 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8767 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8768 && peep2_reg_dead_p (4, operands[0])
8769 && peep2_reg_dead_p (3, operands[2])
8770 && !reg_overlap_mentioned_p (operands[0], operands[1])
8771 && !reg_overlap_mentioned_p (operands[2], operands[1])
8772 && !reg_overlap_mentioned_p (operands[6], operands[9])
8773 && (rtx_equal_p (operands[6], operands[0])
8774 ? (rtx_equal_p (operands[7], operands[1])
8775 && rtx_equal_p (operands[8], operands[2]))
8776 : (rtx_equal_p (operands[8], operands[0])
8777 && rtx_equal_p (operands[9], operands[1])
8778 && rtx_equal_p (operands[6], operands[2])))"
8779 [(set (match_dup 0) (match_dup 9))
8780 (parallel [(set (reg:CCC FLAGS_REG)
8781 (compare:CCC
8782 (zero_extend:<DWI> (match_dup 1))
8783 (plus:<DWI> (match_op_dup 4
8784 [(match_dup 3) (const_int 0)])
8785 (zero_extend:<DWI> (match_dup 0)))))
8786 (set (match_dup 1)
8787 (minus:SWI48 (minus:SWI48 (match_dup 1)
8788 (match_op_dup 5
8789 [(match_dup 3) (const_int 0)]))
8790 (match_dup 0)))])]
8791 {
8792 if (!rtx_equal_p (operands[6], operands[0]))
8793 operands[9] = operands[7];
8794 })
8795
8796 (define_peephole2
8797 [(set (match_operand:SWI48 6 "general_reg_operand")
8798 (match_operand:SWI48 7 "memory_operand"))
8799 (set (match_operand:SWI48 8 "general_reg_operand")
8800 (match_operand:SWI48 9 "memory_operand"))
8801 (parallel [(set (reg:CCC FLAGS_REG)
8802 (compare:CCC
8803 (zero_extend:<DWI>
8804 (match_operand:SWI48 0 "general_reg_operand"))
8805 (plus:<DWI>
8806 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8807 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8808 (zero_extend:<DWI>
8809 (match_operand:SWI48 2 "general_reg_operand")))))
8810 (set (match_dup 0)
8811 (minus:SWI48
8812 (minus:SWI48
8813 (match_dup 0)
8814 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8815 [(match_dup 3) (const_int 0)]))
8816 (match_dup 2)))])
8817 (set (match_operand:QI 10 "general_reg_operand")
8818 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8819 (set (match_operand:SWI48 11 "general_reg_operand")
8820 (zero_extend:SWI48 (match_dup 10)))
8821 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8822 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8823 && peep2_reg_dead_p (6, operands[0])
8824 && peep2_reg_dead_p (3, operands[2])
8825 && !reg_overlap_mentioned_p (operands[0], operands[1])
8826 && !reg_overlap_mentioned_p (operands[2], operands[1])
8827 && !reg_overlap_mentioned_p (operands[6], operands[9])
8828 && !reg_overlap_mentioned_p (operands[0], operands[10])
8829 && !reg_overlap_mentioned_p (operands[10], operands[1])
8830 && !reg_overlap_mentioned_p (operands[0], operands[11])
8831 && !reg_overlap_mentioned_p (operands[11], operands[1])
8832 && (rtx_equal_p (operands[6], operands[0])
8833 ? (rtx_equal_p (operands[7], operands[1])
8834 && rtx_equal_p (operands[8], operands[2]))
8835 : (rtx_equal_p (operands[8], operands[0])
8836 && rtx_equal_p (operands[9], operands[1])
8837 && rtx_equal_p (operands[6], operands[2])))"
8838 [(set (match_dup 0) (match_dup 9))
8839 (parallel [(set (reg:CCC FLAGS_REG)
8840 (compare:CCC
8841 (zero_extend:<DWI> (match_dup 1))
8842 (plus:<DWI> (match_op_dup 4
8843 [(match_dup 3) (const_int 0)])
8844 (zero_extend:<DWI> (match_dup 0)))))
8845 (set (match_dup 1)
8846 (minus:SWI48 (minus:SWI48 (match_dup 1)
8847 (match_op_dup 5
8848 [(match_dup 3) (const_int 0)]))
8849 (match_dup 0)))])
8850 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8851 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8852 {
8853 if (!rtx_equal_p (operands[6], operands[0]))
8854 operands[9] = operands[7];
8855 })
8856
8857 (define_expand "subborrow<mode>_0"
8858 [(parallel
8859 [(set (reg:CC FLAGS_REG)
8860 (compare:CC
8861 (match_operand:SWI48 1 "nonimmediate_operand")
8862 (match_operand:SWI48 2 "<general_operand>")))
8863 (set (match_operand:SWI48 0 "register_operand")
8864 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8865 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8866
8867 (define_expand "uaddc<mode>5"
8868 [(match_operand:SWI48 0 "register_operand")
8869 (match_operand:SWI48 1 "register_operand")
8870 (match_operand:SWI48 2 "register_operand")
8871 (match_operand:SWI48 3 "register_operand")
8872 (match_operand:SWI48 4 "nonmemory_operand")]
8873 ""
8874 {
8875 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8876 if (operands[4] == const0_rtx)
8877 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8878 else
8879 {
8880 ix86_expand_carry (operands[4]);
8881 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8882 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8883 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8884 cf, pat, pat2));
8885 }
8886 rtx cc = gen_reg_rtx (QImode);
8887 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8888 emit_insn (gen_rtx_SET (cc, pat));
8889 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8890 DONE;
8891 })
8892
8893 (define_expand "usubc<mode>5"
8894 [(match_operand:SWI48 0 "register_operand")
8895 (match_operand:SWI48 1 "register_operand")
8896 (match_operand:SWI48 2 "register_operand")
8897 (match_operand:SWI48 3 "register_operand")
8898 (match_operand:SWI48 4 "nonmemory_operand")]
8899 ""
8900 {
8901 rtx cf, pat, pat2;
8902 if (operands[4] == const0_rtx)
8903 {
8904 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8905 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8906 operands[3]));
8907 }
8908 else
8909 {
8910 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8911 ix86_expand_carry (operands[4]);
8912 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8913 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8914 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8915 cf, pat, pat2));
8916 }
8917 rtx cc = gen_reg_rtx (QImode);
8918 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8919 emit_insn (gen_rtx_SET (cc, pat));
8920 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8921 DONE;
8922 })
8923
8924 (define_mode_iterator CC_CCC [CC CCC])
8925
8926 ;; Pre-reload splitter to optimize
8927 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8928 ;; operand and no intervening flags modifications into nothing.
8929 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8930 [(set (reg:CCC FLAGS_REG)
8931 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8932 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8933 "ix86_pre_reload_split ()"
8934 "#"
8935 "&& 1"
8936 [(const_int 0)]
8937 "emit_note (NOTE_INSN_DELETED); DONE;")
8938
8939 ;; Set the carry flag from the carry flag.
8940 (define_insn_and_split "*setccc"
8941 [(set (reg:CCC FLAGS_REG)
8942 (reg:CCC FLAGS_REG))]
8943 "ix86_pre_reload_split ()"
8944 "#"
8945 "&& 1"
8946 [(const_int 0)]
8947 "emit_note (NOTE_INSN_DELETED); DONE;")
8948
8949 ;; Set the carry flag from the carry flag.
8950 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8951 [(set (reg:CCC FLAGS_REG)
8952 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8953 "ix86_pre_reload_split ()"
8954 "#"
8955 "&& 1"
8956 [(const_int 0)]
8957 "emit_note (NOTE_INSN_DELETED); DONE;")
8958
8959 ;; Set the carry flag from the carry flag.
8960 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8961 [(set (reg:CCC FLAGS_REG)
8962 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8963 (const_int 0)] UNSPEC_CC_NE))]
8964 "ix86_pre_reload_split ()"
8965 "#"
8966 "&& 1"
8967 [(const_int 0)]
8968 "emit_note (NOTE_INSN_DELETED); DONE;")
8969 \f
8970 ;; Overflow setting add instructions
8971
8972 (define_expand "addqi3_cconly_overflow"
8973 [(parallel
8974 [(set (reg:CCC FLAGS_REG)
8975 (compare:CCC
8976 (plus:QI
8977 (match_operand:QI 0 "nonimmediate_operand")
8978 (match_operand:QI 1 "general_operand"))
8979 (match_dup 0)))
8980 (clobber (scratch:QI))])]
8981 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8982
8983 (define_insn "*add<mode>3_cconly_overflow_1"
8984 [(set (reg:CCC FLAGS_REG)
8985 (compare:CCC
8986 (plus:SWI
8987 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8988 (match_operand:SWI 2 "<general_operand>" "<g>"))
8989 (match_dup 1)))
8990 (clobber (match_scratch:SWI 0 "=<r>"))]
8991 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8992 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "<MODE>")])
8995
8996 (define_insn "@add<mode>3_cc_overflow_1"
8997 [(set (reg:CCC FLAGS_REG)
8998 (compare:CCC
8999 (plus:SWI
9000 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9001 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9002 (match_dup 1)))
9003 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9004 (plus:SWI (match_dup 1) (match_dup 2)))]
9005 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9006 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "<MODE>")])
9009
9010 (define_peephole2
9011 [(parallel [(set (reg:CCC FLAGS_REG)
9012 (compare:CCC
9013 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9014 (match_operand:SWI 1 "memory_operand"))
9015 (match_dup 0)))
9016 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9017 (set (match_dup 1) (match_dup 0))]
9018 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9019 && peep2_reg_dead_p (2, operands[0])
9020 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9021 [(parallel [(set (reg:CCC FLAGS_REG)
9022 (compare:CCC
9023 (plus:SWI (match_dup 1) (match_dup 0))
9024 (match_dup 1)))
9025 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9026
9027 (define_peephole2
9028 [(set (match_operand:SWI 0 "general_reg_operand")
9029 (match_operand:SWI 1 "memory_operand"))
9030 (parallel [(set (reg:CCC FLAGS_REG)
9031 (compare:CCC
9032 (plus:SWI (match_dup 0)
9033 (match_operand:SWI 2 "memory_operand"))
9034 (match_dup 0)))
9035 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9036 (set (match_dup 1) (match_dup 0))]
9037 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9038 && peep2_reg_dead_p (3, operands[0])
9039 && !reg_overlap_mentioned_p (operands[0], operands[1])
9040 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9041 [(set (match_dup 0) (match_dup 2))
9042 (parallel [(set (reg:CCC FLAGS_REG)
9043 (compare:CCC
9044 (plus:SWI (match_dup 1) (match_dup 0))
9045 (match_dup 1)))
9046 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9047
9048 (define_insn "*addsi3_zext_cc_overflow_1"
9049 [(set (reg:CCC FLAGS_REG)
9050 (compare:CCC
9051 (plus:SI
9052 (match_operand:SI 1 "nonimmediate_operand" "%0")
9053 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9054 (match_dup 1)))
9055 (set (match_operand:DI 0 "register_operand" "=r")
9056 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9057 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9058 "add{l}\t{%2, %k0|%k0, %2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "SI")])
9061
9062 (define_insn "*add<mode>3_cconly_overflow_2"
9063 [(set (reg:CCC FLAGS_REG)
9064 (compare:CCC
9065 (plus:SWI
9066 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9067 (match_operand:SWI 2 "<general_operand>" "<g>"))
9068 (match_dup 2)))
9069 (clobber (match_scratch:SWI 0 "=<r>"))]
9070 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9071 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "mode" "<MODE>")])
9074
9075 (define_insn "*add<mode>3_cc_overflow_2"
9076 [(set (reg:CCC FLAGS_REG)
9077 (compare:CCC
9078 (plus:SWI
9079 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9080 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9081 (match_dup 2)))
9082 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9083 (plus:SWI (match_dup 1) (match_dup 2)))]
9084 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9085 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "mode" "<MODE>")])
9088
9089 (define_insn "*addsi3_zext_cc_overflow_2"
9090 [(set (reg:CCC FLAGS_REG)
9091 (compare:CCC
9092 (plus:SI
9093 (match_operand:SI 1 "nonimmediate_operand" "%0")
9094 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9095 (match_dup 2)))
9096 (set (match_operand:DI 0 "register_operand" "=r")
9097 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9098 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9099 "add{l}\t{%2, %k0|%k0, %2}"
9100 [(set_attr "type" "alu")
9101 (set_attr "mode" "SI")])
9102
9103 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9104 [(set (reg:CCC FLAGS_REG)
9105 (compare:CCC
9106 (plus:<DWI>
9107 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
9108 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
9109 (match_dup 1)))
9110 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
9111 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9112 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
9113 "#"
9114 "&& reload_completed"
9115 [(parallel [(set (reg:CCC FLAGS_REG)
9116 (compare:CCC
9117 (plus:DWIH (match_dup 1) (match_dup 2))
9118 (match_dup 1)))
9119 (set (match_dup 0)
9120 (plus:DWIH (match_dup 1) (match_dup 2)))])
9121 (parallel [(set (reg:CCC FLAGS_REG)
9122 (compare:CCC
9123 (zero_extend:<DWI>
9124 (plus:DWIH
9125 (plus:DWIH
9126 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9127 (match_dup 4))
9128 (match_dup 5)))
9129 (plus:<DWI>
9130 (match_dup 6)
9131 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9132 (set (match_dup 3)
9133 (plus:DWIH
9134 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9135 (match_dup 4))
9136 (match_dup 5)))])]
9137 {
9138 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9139 if (operands[2] == const0_rtx)
9140 {
9141 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9142 DONE;
9143 }
9144 if (CONST_INT_P (operands[5]))
9145 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9146 operands[5], <MODE>mode);
9147 else
9148 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9149 })
9150
9151 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9152 ;; test, where the latter is preferrable if we have some carry consuming
9153 ;; instruction.
9154 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9155 ;; + (1 - CF).
9156 (define_insn_and_split "*add<mode>3_eq"
9157 [(set (match_operand:SWI 0 "nonimmediate_operand")
9158 (plus:SWI
9159 (plus:SWI
9160 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9161 (match_operand:SWI 1 "nonimmediate_operand"))
9162 (match_operand:SWI 2 "<general_operand>")))
9163 (clobber (reg:CC FLAGS_REG))]
9164 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9165 && ix86_pre_reload_split ()"
9166 "#"
9167 "&& 1"
9168 [(set (reg:CC FLAGS_REG)
9169 (compare:CC (match_dup 3) (const_int 1)))
9170 (parallel [(set (match_dup 0)
9171 (plus:SWI
9172 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9173 (match_dup 1))
9174 (match_dup 2)))
9175 (clobber (reg:CC FLAGS_REG))])])
9176
9177 (define_insn_and_split "*add<mode>3_ne"
9178 [(set (match_operand:SWI 0 "nonimmediate_operand")
9179 (plus:SWI
9180 (plus:SWI
9181 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9182 (match_operand:SWI 1 "nonimmediate_operand"))
9183 (match_operand:SWI 2 "<immediate_operand>")))
9184 (clobber (reg:CC FLAGS_REG))]
9185 "CONST_INT_P (operands[2])
9186 && (<MODE>mode != DImode
9187 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9188 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9189 && ix86_pre_reload_split ()"
9190 "#"
9191 "&& 1"
9192 [(set (reg:CC FLAGS_REG)
9193 (compare:CC (match_dup 3) (const_int 1)))
9194 (parallel [(set (match_dup 0)
9195 (minus:SWI
9196 (minus:SWI (match_dup 1)
9197 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9198 (match_dup 2)))
9199 (clobber (reg:CC FLAGS_REG))])]
9200 {
9201 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9202 <MODE>mode == DImode ? SImode : <MODE>mode);
9203 })
9204
9205 (define_insn_and_split "*add<mode>3_eq_0"
9206 [(set (match_operand:SWI 0 "nonimmediate_operand")
9207 (plus:SWI
9208 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9209 (match_operand:SWI 1 "<general_operand>")))
9210 (clobber (reg:CC FLAGS_REG))]
9211 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9212 && ix86_pre_reload_split ()"
9213 "#"
9214 "&& 1"
9215 [(set (reg:CC FLAGS_REG)
9216 (compare:CC (match_dup 2) (const_int 1)))
9217 (parallel [(set (match_dup 0)
9218 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9219 (match_dup 1)))
9220 (clobber (reg:CC FLAGS_REG))])]
9221 {
9222 if (!nonimmediate_operand (operands[1], <MODE>mode))
9223 operands[1] = force_reg (<MODE>mode, operands[1]);
9224 })
9225
9226 (define_insn_and_split "*add<mode>3_ne_0"
9227 [(set (match_operand:SWI 0 "nonimmediate_operand")
9228 (plus:SWI
9229 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9230 (match_operand:SWI 1 "<general_operand>")))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9233 && ix86_pre_reload_split ()"
9234 "#"
9235 "&& 1"
9236 [(set (reg:CC FLAGS_REG)
9237 (compare:CC (match_dup 2) (const_int 1)))
9238 (parallel [(set (match_dup 0)
9239 (minus:SWI (minus:SWI
9240 (match_dup 1)
9241 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9242 (const_int -1)))
9243 (clobber (reg:CC FLAGS_REG))])]
9244 {
9245 if (!nonimmediate_operand (operands[1], <MODE>mode))
9246 operands[1] = force_reg (<MODE>mode, operands[1]);
9247 })
9248
9249 (define_insn_and_split "*sub<mode>3_eq"
9250 [(set (match_operand:SWI 0 "nonimmediate_operand")
9251 (minus:SWI
9252 (minus:SWI
9253 (match_operand:SWI 1 "nonimmediate_operand")
9254 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9255 (const_int 0)))
9256 (match_operand:SWI 2 "<general_operand>")))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9259 && ix86_pre_reload_split ()"
9260 "#"
9261 "&& 1"
9262 [(set (reg:CC FLAGS_REG)
9263 (compare:CC (match_dup 3) (const_int 1)))
9264 (parallel [(set (match_dup 0)
9265 (minus:SWI
9266 (minus:SWI (match_dup 1)
9267 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9268 (match_dup 2)))
9269 (clobber (reg:CC FLAGS_REG))])])
9270
9271 (define_insn_and_split "*sub<mode>3_ne"
9272 [(set (match_operand:SWI 0 "nonimmediate_operand")
9273 (plus:SWI
9274 (minus:SWI
9275 (match_operand:SWI 1 "nonimmediate_operand")
9276 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9277 (const_int 0)))
9278 (match_operand:SWI 2 "<immediate_operand>")))
9279 (clobber (reg:CC FLAGS_REG))]
9280 "CONST_INT_P (operands[2])
9281 && (<MODE>mode != DImode
9282 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9283 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9284 && ix86_pre_reload_split ()"
9285 "#"
9286 "&& 1"
9287 [(set (reg:CC FLAGS_REG)
9288 (compare:CC (match_dup 3) (const_int 1)))
9289 (parallel [(set (match_dup 0)
9290 (plus:SWI
9291 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9292 (match_dup 1))
9293 (match_dup 2)))
9294 (clobber (reg:CC FLAGS_REG))])]
9295 {
9296 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9297 <MODE>mode == DImode ? SImode : <MODE>mode);
9298 })
9299
9300 (define_insn_and_split "*sub<mode>3_eq_1"
9301 [(set (match_operand:SWI 0 "nonimmediate_operand")
9302 (plus:SWI
9303 (minus:SWI
9304 (match_operand:SWI 1 "nonimmediate_operand")
9305 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9306 (const_int 0)))
9307 (match_operand:SWI 2 "<immediate_operand>")))
9308 (clobber (reg:CC FLAGS_REG))]
9309 "CONST_INT_P (operands[2])
9310 && (<MODE>mode != DImode
9311 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9312 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9313 && ix86_pre_reload_split ()"
9314 "#"
9315 "&& 1"
9316 [(set (reg:CC FLAGS_REG)
9317 (compare:CC (match_dup 3) (const_int 1)))
9318 (parallel [(set (match_dup 0)
9319 (minus:SWI
9320 (minus:SWI (match_dup 1)
9321 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9322 (match_dup 2)))
9323 (clobber (reg:CC FLAGS_REG))])]
9324 {
9325 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9326 <MODE>mode == DImode ? SImode : <MODE>mode);
9327 })
9328
9329 (define_insn_and_split "*sub<mode>3_eq_0"
9330 [(set (match_operand:SWI 0 "nonimmediate_operand")
9331 (minus:SWI
9332 (match_operand:SWI 1 "<general_operand>")
9333 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9334 (clobber (reg:CC FLAGS_REG))]
9335 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9336 && ix86_pre_reload_split ()"
9337 "#"
9338 "&& 1"
9339 [(set (reg:CC FLAGS_REG)
9340 (compare:CC (match_dup 2) (const_int 1)))
9341 (parallel [(set (match_dup 0)
9342 (minus:SWI (match_dup 1)
9343 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9344 (clobber (reg:CC FLAGS_REG))])]
9345 {
9346 if (!nonimmediate_operand (operands[1], <MODE>mode))
9347 operands[1] = force_reg (<MODE>mode, operands[1]);
9348 })
9349
9350 (define_insn_and_split "*sub<mode>3_ne_0"
9351 [(set (match_operand:SWI 0 "nonimmediate_operand")
9352 (minus:SWI
9353 (match_operand:SWI 1 "<general_operand>")
9354 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9355 (clobber (reg:CC FLAGS_REG))]
9356 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9357 && ix86_pre_reload_split ()"
9358 "#"
9359 "&& 1"
9360 [(set (reg:CC FLAGS_REG)
9361 (compare:CC (match_dup 2) (const_int 1)))
9362 (parallel [(set (match_dup 0)
9363 (plus:SWI (plus:SWI
9364 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9365 (match_dup 1))
9366 (const_int -1)))
9367 (clobber (reg:CC FLAGS_REG))])]
9368 {
9369 if (!nonimmediate_operand (operands[1], <MODE>mode))
9370 operands[1] = force_reg (<MODE>mode, operands[1]);
9371 })
9372
9373 ;; The patterns that match these are at the end of this file.
9374
9375 (define_expand "<insn>xf3"
9376 [(set (match_operand:XF 0 "register_operand")
9377 (plusminus:XF
9378 (match_operand:XF 1 "register_operand")
9379 (match_operand:XF 2 "register_operand")))]
9380 "TARGET_80387")
9381
9382 (define_expand "<insn>hf3"
9383 [(set (match_operand:HF 0 "register_operand")
9384 (plusminus:HF
9385 (match_operand:HF 1 "register_operand")
9386 (match_operand:HF 2 "nonimmediate_operand")))]
9387 "TARGET_AVX512FP16")
9388
9389 (define_expand "<insn><mode>3"
9390 [(set (match_operand:MODEF 0 "register_operand")
9391 (plusminus:MODEF
9392 (match_operand:MODEF 1 "register_operand")
9393 (match_operand:MODEF 2 "nonimmediate_operand")))]
9394 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9395 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9396 \f
9397 ;; Multiply instructions
9398
9399 (define_expand "mul<mode>3"
9400 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9401 (mult:SWIM248
9402 (match_operand:SWIM248 1 "register_operand")
9403 (match_operand:SWIM248 2 "<general_operand>")))
9404 (clobber (reg:CC FLAGS_REG))])])
9405
9406 (define_expand "mulqi3"
9407 [(parallel [(set (match_operand:QI 0 "register_operand")
9408 (mult:QI
9409 (match_operand:QI 1 "register_operand")
9410 (match_operand:QI 2 "nonimmediate_operand")))
9411 (clobber (reg:CC FLAGS_REG))])]
9412 "TARGET_QIMODE_MATH")
9413
9414 ;; On AMDFAM10
9415 ;; IMUL reg32/64, reg32/64, imm8 Direct
9416 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9417 ;; IMUL reg32/64, reg32/64, imm32 Direct
9418 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9419 ;; IMUL reg32/64, reg32/64 Direct
9420 ;; IMUL reg32/64, mem32/64 Direct
9421 ;;
9422 ;; On BDVER1, all above IMULs use DirectPath
9423 ;;
9424 ;; On AMDFAM10
9425 ;; IMUL reg16, reg16, imm8 VectorPath
9426 ;; IMUL reg16, mem16, imm8 VectorPath
9427 ;; IMUL reg16, reg16, imm16 VectorPath
9428 ;; IMUL reg16, mem16, imm16 VectorPath
9429 ;; IMUL reg16, reg16 Direct
9430 ;; IMUL reg16, mem16 Direct
9431 ;;
9432 ;; On BDVER1, all HI MULs use DoublePath
9433
9434 (define_insn "*mul<mode>3_1"
9435 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9436 (mult:SWIM248
9437 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9438 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9439 (clobber (reg:CC FLAGS_REG))]
9440 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9441 "@
9442 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9443 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9444 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9445 [(set_attr "type" "imul")
9446 (set_attr "prefix_0f" "0,0,1")
9447 (set (attr "athlon_decode")
9448 (cond [(eq_attr "cpu" "athlon")
9449 (const_string "vector")
9450 (eq_attr "alternative" "1")
9451 (const_string "vector")
9452 (and (eq_attr "alternative" "2")
9453 (ior (match_test "<MODE>mode == HImode")
9454 (match_operand 1 "memory_operand")))
9455 (const_string "vector")]
9456 (const_string "direct")))
9457 (set (attr "amdfam10_decode")
9458 (cond [(and (eq_attr "alternative" "0,1")
9459 (ior (match_test "<MODE>mode == HImode")
9460 (match_operand 1 "memory_operand")))
9461 (const_string "vector")]
9462 (const_string "direct")))
9463 (set (attr "bdver1_decode")
9464 (if_then_else
9465 (match_test "<MODE>mode == HImode")
9466 (const_string "double")
9467 (const_string "direct")))
9468 (set_attr "mode" "<MODE>")])
9469
9470 (define_insn "*mulsi3_1_zext"
9471 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9472 (zero_extend:DI
9473 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9474 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "TARGET_64BIT
9477 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9478 "@
9479 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9480 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9481 imul{l}\t{%2, %k0|%k0, %2}"
9482 [(set_attr "type" "imul")
9483 (set_attr "prefix_0f" "0,0,1")
9484 (set (attr "athlon_decode")
9485 (cond [(eq_attr "cpu" "athlon")
9486 (const_string "vector")
9487 (eq_attr "alternative" "1")
9488 (const_string "vector")
9489 (and (eq_attr "alternative" "2")
9490 (match_operand 1 "memory_operand"))
9491 (const_string "vector")]
9492 (const_string "direct")))
9493 (set (attr "amdfam10_decode")
9494 (cond [(and (eq_attr "alternative" "0,1")
9495 (match_operand 1 "memory_operand"))
9496 (const_string "vector")]
9497 (const_string "direct")))
9498 (set_attr "bdver1_decode" "direct")
9499 (set_attr "mode" "SI")])
9500
9501 ;;On AMDFAM10 and BDVER1
9502 ;; MUL reg8 Direct
9503 ;; MUL mem8 Direct
9504
9505 (define_insn "*mulqi3_1"
9506 [(set (match_operand:QI 0 "register_operand" "=a")
9507 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9508 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "TARGET_QIMODE_MATH
9511 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9512 "mul{b}\t%2"
9513 [(set_attr "type" "imul")
9514 (set_attr "length_immediate" "0")
9515 (set (attr "athlon_decode")
9516 (if_then_else (eq_attr "cpu" "athlon")
9517 (const_string "vector")
9518 (const_string "direct")))
9519 (set_attr "amdfam10_decode" "direct")
9520 (set_attr "bdver1_decode" "direct")
9521 (set_attr "mode" "QI")])
9522
9523 ;; Multiply with jump on overflow.
9524 (define_expand "mulv<mode>4"
9525 [(parallel [(set (reg:CCO FLAGS_REG)
9526 (eq:CCO (mult:<DWI>
9527 (sign_extend:<DWI>
9528 (match_operand:SWI248 1 "register_operand"))
9529 (match_dup 4))
9530 (sign_extend:<DWI>
9531 (mult:SWI248 (match_dup 1)
9532 (match_operand:SWI248 2
9533 "<general_operand>")))))
9534 (set (match_operand:SWI248 0 "register_operand")
9535 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9536 (set (pc) (if_then_else
9537 (eq (reg:CCO FLAGS_REG) (const_int 0))
9538 (label_ref (match_operand 3))
9539 (pc)))]
9540 ""
9541 {
9542 if (CONST_INT_P (operands[2]))
9543 operands[4] = operands[2];
9544 else
9545 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9546 })
9547
9548 (define_insn "*mulv<mode>4"
9549 [(set (reg:CCO FLAGS_REG)
9550 (eq:CCO (mult:<DWI>
9551 (sign_extend:<DWI>
9552 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9553 (sign_extend:<DWI>
9554 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9555 (sign_extend:<DWI>
9556 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9557 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9558 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9559 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9560 "@
9561 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9562 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9563 [(set_attr "type" "imul")
9564 (set_attr "prefix_0f" "0,1")
9565 (set (attr "athlon_decode")
9566 (cond [(eq_attr "cpu" "athlon")
9567 (const_string "vector")
9568 (eq_attr "alternative" "0")
9569 (const_string "vector")
9570 (and (eq_attr "alternative" "1")
9571 (match_operand 1 "memory_operand"))
9572 (const_string "vector")]
9573 (const_string "direct")))
9574 (set (attr "amdfam10_decode")
9575 (cond [(and (eq_attr "alternative" "1")
9576 (match_operand 1 "memory_operand"))
9577 (const_string "vector")]
9578 (const_string "direct")))
9579 (set_attr "bdver1_decode" "direct")
9580 (set_attr "mode" "<MODE>")])
9581
9582 (define_insn "*mulvhi4"
9583 [(set (reg:CCO FLAGS_REG)
9584 (eq:CCO (mult:SI
9585 (sign_extend:SI
9586 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9587 (sign_extend:SI
9588 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9589 (sign_extend:SI
9590 (mult:HI (match_dup 1) (match_dup 2)))))
9591 (set (match_operand:HI 0 "register_operand" "=r")
9592 (mult:HI (match_dup 1) (match_dup 2)))]
9593 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9594 "imul{w}\t{%2, %0|%0, %2}"
9595 [(set_attr "type" "imul")
9596 (set_attr "prefix_0f" "1")
9597 (set_attr "athlon_decode" "vector")
9598 (set_attr "amdfam10_decode" "direct")
9599 (set_attr "bdver1_decode" "double")
9600 (set_attr "mode" "HI")])
9601
9602 (define_insn "*mulv<mode>4_1"
9603 [(set (reg:CCO FLAGS_REG)
9604 (eq:CCO (mult:<DWI>
9605 (sign_extend:<DWI>
9606 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9607 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9608 (sign_extend:<DWI>
9609 (mult:SWI248 (match_dup 1)
9610 (match_operand:SWI248 2
9611 "<immediate_operand>" "K,<i>")))))
9612 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9613 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9614 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9615 && CONST_INT_P (operands[2])
9616 && INTVAL (operands[2]) == INTVAL (operands[3])"
9617 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9618 [(set_attr "type" "imul")
9619 (set (attr "prefix_0f")
9620 (if_then_else
9621 (match_test "<MODE>mode == HImode")
9622 (const_string "0")
9623 (const_string "*")))
9624 (set (attr "athlon_decode")
9625 (cond [(eq_attr "cpu" "athlon")
9626 (const_string "vector")
9627 (eq_attr "alternative" "1")
9628 (const_string "vector")]
9629 (const_string "direct")))
9630 (set (attr "amdfam10_decode")
9631 (cond [(ior (match_test "<MODE>mode == HImode")
9632 (match_operand 1 "memory_operand"))
9633 (const_string "vector")]
9634 (const_string "direct")))
9635 (set (attr "bdver1_decode")
9636 (if_then_else
9637 (match_test "<MODE>mode == HImode")
9638 (const_string "double")
9639 (const_string "direct")))
9640 (set_attr "mode" "<MODE>")
9641 (set (attr "length_immediate")
9642 (cond [(eq_attr "alternative" "0")
9643 (const_string "1")
9644 (match_test "<MODE_SIZE> == 8")
9645 (const_string "4")]
9646 (const_string "<MODE_SIZE>")))])
9647
9648 (define_expand "umulv<mode>4"
9649 [(parallel [(set (reg:CCO FLAGS_REG)
9650 (eq:CCO (mult:<DWI>
9651 (zero_extend:<DWI>
9652 (match_operand:SWI248 1
9653 "nonimmediate_operand"))
9654 (zero_extend:<DWI>
9655 (match_operand:SWI248 2
9656 "nonimmediate_operand")))
9657 (zero_extend:<DWI>
9658 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9659 (set (match_operand:SWI248 0 "register_operand")
9660 (mult:SWI248 (match_dup 1) (match_dup 2)))
9661 (clobber (scratch:SWI248))])
9662 (set (pc) (if_then_else
9663 (eq (reg:CCO FLAGS_REG) (const_int 0))
9664 (label_ref (match_operand 3))
9665 (pc)))]
9666 ""
9667 {
9668 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9669 operands[1] = force_reg (<MODE>mode, operands[1]);
9670 })
9671
9672 (define_insn "*umulv<mode>4"
9673 [(set (reg:CCO FLAGS_REG)
9674 (eq:CCO (mult:<DWI>
9675 (zero_extend:<DWI>
9676 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9677 (zero_extend:<DWI>
9678 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9679 (zero_extend:<DWI>
9680 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9681 (set (match_operand:SWI248 0 "register_operand" "=a")
9682 (mult:SWI248 (match_dup 1) (match_dup 2)))
9683 (clobber (match_scratch:SWI248 3 "=d"))]
9684 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9685 "mul{<imodesuffix>}\t%2"
9686 [(set_attr "type" "imul")
9687 (set_attr "length_immediate" "0")
9688 (set (attr "athlon_decode")
9689 (if_then_else (eq_attr "cpu" "athlon")
9690 (const_string "vector")
9691 (const_string "double")))
9692 (set_attr "amdfam10_decode" "double")
9693 (set_attr "bdver1_decode" "direct")
9694 (set_attr "mode" "<MODE>")])
9695
9696 (define_expand "<u>mulvqi4"
9697 [(parallel [(set (reg:CCO FLAGS_REG)
9698 (eq:CCO (mult:HI
9699 (any_extend:HI
9700 (match_operand:QI 1 "nonimmediate_operand"))
9701 (any_extend:HI
9702 (match_operand:QI 2 "nonimmediate_operand")))
9703 (any_extend:HI
9704 (mult:QI (match_dup 1) (match_dup 2)))))
9705 (set (match_operand:QI 0 "register_operand")
9706 (mult:QI (match_dup 1) (match_dup 2)))])
9707 (set (pc) (if_then_else
9708 (eq (reg:CCO FLAGS_REG) (const_int 0))
9709 (label_ref (match_operand 3))
9710 (pc)))]
9711 "TARGET_QIMODE_MATH"
9712 {
9713 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9714 operands[1] = force_reg (QImode, operands[1]);
9715 })
9716
9717 (define_insn "*<u>mulvqi4"
9718 [(set (reg:CCO FLAGS_REG)
9719 (eq:CCO (mult:HI
9720 (any_extend:HI
9721 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9722 (any_extend:HI
9723 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9724 (any_extend:HI
9725 (mult:QI (match_dup 1) (match_dup 2)))))
9726 (set (match_operand:QI 0 "register_operand" "=a")
9727 (mult:QI (match_dup 1) (match_dup 2)))]
9728 "TARGET_QIMODE_MATH
9729 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9730 "<sgnprefix>mul{b}\t%2"
9731 [(set_attr "type" "imul")
9732 (set_attr "length_immediate" "0")
9733 (set (attr "athlon_decode")
9734 (if_then_else (eq_attr "cpu" "athlon")
9735 (const_string "vector")
9736 (const_string "direct")))
9737 (set_attr "amdfam10_decode" "direct")
9738 (set_attr "bdver1_decode" "direct")
9739 (set_attr "mode" "QI")])
9740
9741 (define_expand "<u>mul<mode><dwi>3"
9742 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9743 (mult:<DWI>
9744 (any_extend:<DWI>
9745 (match_operand:DWIH 1 "register_operand"))
9746 (any_extend:<DWI>
9747 (match_operand:DWIH 2 "nonimmediate_operand"))))
9748 (clobber (reg:CC FLAGS_REG))])])
9749
9750 (define_expand "<u>mulqihi3"
9751 [(parallel [(set (match_operand:HI 0 "register_operand")
9752 (mult:HI
9753 (any_extend:HI
9754 (match_operand:QI 1 "register_operand"))
9755 (any_extend:HI
9756 (match_operand:QI 2 "nonimmediate_operand"))))
9757 (clobber (reg:CC FLAGS_REG))])]
9758 "TARGET_QIMODE_MATH")
9759
9760 (define_insn "*bmi2_umul<mode><dwi>3_1"
9761 [(set (match_operand:DWIH 0 "register_operand" "=r")
9762 (mult:DWIH
9763 (match_operand:DWIH 2 "register_operand" "%d")
9764 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9765 (set (match_operand:DWIH 1 "register_operand" "=r")
9766 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9767 "TARGET_BMI2
9768 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9769 "mulx\t{%3, %0, %1|%1, %0, %3}"
9770 [(set_attr "type" "imulx")
9771 (set_attr "prefix" "vex")
9772 (set_attr "mode" "<MODE>")])
9773
9774 (define_insn "*umul<mode><dwi>3_1"
9775 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9776 (mult:<DWI>
9777 (zero_extend:<DWI>
9778 (match_operand:DWIH 1 "register_operand" "%d,a"))
9779 (zero_extend:<DWI>
9780 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9781 (clobber (reg:CC FLAGS_REG))]
9782 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9783 "@
9784 #
9785 mul{<imodesuffix>}\t%2"
9786 [(set_attr "isa" "bmi2,*")
9787 (set_attr "type" "imulx,imul")
9788 (set_attr "length_immediate" "*,0")
9789 (set (attr "athlon_decode")
9790 (cond [(eq_attr "alternative" "1")
9791 (if_then_else (eq_attr "cpu" "athlon")
9792 (const_string "vector")
9793 (const_string "double"))]
9794 (const_string "*")))
9795 (set_attr "amdfam10_decode" "*,double")
9796 (set_attr "bdver1_decode" "*,direct")
9797 (set_attr "prefix" "vex,orig")
9798 (set_attr "mode" "<MODE>")])
9799
9800 ;; Convert mul to the mulx pattern to avoid flags dependency.
9801 (define_split
9802 [(set (match_operand:<DWI> 0 "register_operand")
9803 (mult:<DWI>
9804 (zero_extend:<DWI>
9805 (match_operand:DWIH 1 "register_operand"))
9806 (zero_extend:<DWI>
9807 (match_operand:DWIH 2 "nonimmediate_operand"))))
9808 (clobber (reg:CC FLAGS_REG))]
9809 "TARGET_BMI2 && reload_completed
9810 && REGNO (operands[1]) == DX_REG"
9811 [(parallel [(set (match_dup 3)
9812 (mult:DWIH (match_dup 1) (match_dup 2)))
9813 (set (match_dup 4)
9814 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9815 {
9816 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9817
9818 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9819 })
9820
9821 (define_insn "*mul<mode><dwi>3_1"
9822 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9823 (mult:<DWI>
9824 (sign_extend:<DWI>
9825 (match_operand:DWIH 1 "register_operand" "%a"))
9826 (sign_extend:<DWI>
9827 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9830 "imul{<imodesuffix>}\t%2"
9831 [(set_attr "type" "imul")
9832 (set_attr "length_immediate" "0")
9833 (set (attr "athlon_decode")
9834 (if_then_else (eq_attr "cpu" "athlon")
9835 (const_string "vector")
9836 (const_string "double")))
9837 (set_attr "amdfam10_decode" "double")
9838 (set_attr "bdver1_decode" "direct")
9839 (set_attr "mode" "<MODE>")])
9840
9841 (define_insn "*<u>mulqihi3_1"
9842 [(set (match_operand:HI 0 "register_operand" "=a")
9843 (mult:HI
9844 (any_extend:HI
9845 (match_operand:QI 1 "register_operand" "%0"))
9846 (any_extend:HI
9847 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9848 (clobber (reg:CC FLAGS_REG))]
9849 "TARGET_QIMODE_MATH
9850 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9851 "<sgnprefix>mul{b}\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 "direct")))
9858 (set_attr "amdfam10_decode" "direct")
9859 (set_attr "bdver1_decode" "direct")
9860 (set_attr "mode" "QI")])
9861
9862 ;; Widening multiplication peephole2s to tweak register allocation.
9863 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
9864 (define_peephole2
9865 [(set (match_operand:DWIH 0 "general_reg_operand")
9866 (match_operand:DWIH 1 "immediate_operand"))
9867 (set (match_operand:DWIH 2 "general_reg_operand")
9868 (match_operand:DWIH 3 "general_reg_operand"))
9869 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9870 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9871 (zero_extend:<DWI> (match_dup 0))))
9872 (clobber (reg:CC FLAGS_REG))])]
9873 "REGNO (operands[3]) != AX_REG
9874 && REGNO (operands[0]) != REGNO (operands[2])
9875 && REGNO (operands[0]) != REGNO (operands[3])
9876 && (REGNO (operands[0]) == REGNO (operands[4])
9877 || REGNO (operands[0]) == DX_REG
9878 || peep2_reg_dead_p (3, operands[0]))"
9879 [(set (match_dup 2) (match_dup 1))
9880 (parallel [(set (match_dup 4)
9881 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9882 (zero_extend:<DWI> (match_dup 3))))
9883 (clobber (reg:CC FLAGS_REG))])])
9884
9885 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
9886 (define_peephole2
9887 [(set (match_operand:DWIH 0 "general_reg_operand")
9888 (match_operand:DWIH 1 "immediate_operand"))
9889 (set (match_operand:DWIH 2 "general_reg_operand")
9890 (match_operand:DWIH 3 "general_reg_operand"))
9891 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9892 (mult:DWIH (match_dup 2) (match_dup 0)))
9893 (set (match_operand:DWIH 5 "general_reg_operand")
9894 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9895 "REGNO (operands[3]) != DX_REG
9896 && REGNO (operands[0]) != REGNO (operands[2])
9897 && REGNO (operands[0]) != REGNO (operands[3])
9898 && (REGNO (operands[0]) == REGNO (operands[4])
9899 || REGNO (operands[0]) == REGNO (operands[5])
9900 || peep2_reg_dead_p (3, operands[0]))"
9901 [(set (match_dup 2) (match_dup 1))
9902 (parallel [(set (match_dup 4)
9903 (mult:DWIH (match_dup 2) (match_dup 3)))
9904 (set (match_dup 5)
9905 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
9906
9907 ;; Highpart multiplication patterns
9908 (define_insn "<s>mul<mode>3_highpart"
9909 [(set (match_operand:DWIH 0 "register_operand" "=d")
9910 (any_mul_highpart:DWIH
9911 (match_operand:DWIH 1 "register_operand" "%a")
9912 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9913 (clobber (match_scratch:DWIH 3 "=1"))
9914 (clobber (reg:CC FLAGS_REG))]
9915 ""
9916 "<sgnprefix>mul{<imodesuffix>}\t%2"
9917 [(set_attr "type" "imul")
9918 (set_attr "length_immediate" "0")
9919 (set (attr "athlon_decode")
9920 (if_then_else (eq_attr "cpu" "athlon")
9921 (const_string "vector")
9922 (const_string "double")))
9923 (set_attr "amdfam10_decode" "double")
9924 (set_attr "bdver1_decode" "direct")
9925 (set_attr "mode" "<MODE>")])
9926
9927 (define_insn "*<s>mulsi3_highpart_zext"
9928 [(set (match_operand:DI 0 "register_operand" "=d")
9929 (zero_extend:DI
9930 (any_mul_highpart:SI
9931 (match_operand:SI 1 "register_operand" "%a")
9932 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9933 (clobber (match_scratch:SI 3 "=1"))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "TARGET_64BIT"
9936 "<sgnprefix>mul{l}\t%2"
9937 [(set_attr "type" "imul")
9938 (set_attr "length_immediate" "0")
9939 (set (attr "athlon_decode")
9940 (if_then_else (eq_attr "cpu" "athlon")
9941 (const_string "vector")
9942 (const_string "double")))
9943 (set_attr "amdfam10_decode" "double")
9944 (set_attr "bdver1_decode" "direct")
9945 (set_attr "mode" "SI")])
9946
9947 (define_insn "*<s>muldi3_highpart_1"
9948 [(set (match_operand:DI 0 "register_operand" "=d")
9949 (truncate:DI
9950 (lshiftrt:TI
9951 (mult:TI
9952 (any_extend:TI
9953 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9954 (any_extend:TI
9955 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9956 (const_int 64))))
9957 (clobber (match_scratch:DI 3 "=1"))
9958 (clobber (reg:CC FLAGS_REG))]
9959 "TARGET_64BIT
9960 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9961 "<sgnprefix>mul{q}\t%2"
9962 [(set_attr "type" "imul")
9963 (set_attr "length_immediate" "0")
9964 (set (attr "athlon_decode")
9965 (if_then_else (eq_attr "cpu" "athlon")
9966 (const_string "vector")
9967 (const_string "double")))
9968 (set_attr "amdfam10_decode" "double")
9969 (set_attr "bdver1_decode" "direct")
9970 (set_attr "mode" "DI")])
9971
9972 (define_insn "*<s>mulsi3_highpart_zext"
9973 [(set (match_operand:DI 0 "register_operand" "=d")
9974 (zero_extend:DI (truncate:SI
9975 (lshiftrt:DI
9976 (mult:DI (any_extend:DI
9977 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9978 (any_extend:DI
9979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9980 (const_int 32)))))
9981 (clobber (match_scratch:SI 3 "=1"))
9982 (clobber (reg:CC FLAGS_REG))]
9983 "TARGET_64BIT
9984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9985 "<sgnprefix>mul{l}\t%2"
9986 [(set_attr "type" "imul")
9987 (set_attr "length_immediate" "0")
9988 (set (attr "athlon_decode")
9989 (if_then_else (eq_attr "cpu" "athlon")
9990 (const_string "vector")
9991 (const_string "double")))
9992 (set_attr "amdfam10_decode" "double")
9993 (set_attr "bdver1_decode" "direct")
9994 (set_attr "mode" "SI")])
9995
9996 (define_insn "*<s>mulsi3_highpart_1"
9997 [(set (match_operand:SI 0 "register_operand" "=d")
9998 (truncate:SI
9999 (lshiftrt:DI
10000 (mult:DI
10001 (any_extend:DI
10002 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10003 (any_extend:DI
10004 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10005 (const_int 32))))
10006 (clobber (match_scratch:SI 3 "=1"))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10009 "<sgnprefix>mul{l}\t%2"
10010 [(set_attr "type" "imul")
10011 (set_attr "length_immediate" "0")
10012 (set (attr "athlon_decode")
10013 (if_then_else (eq_attr "cpu" "athlon")
10014 (const_string "vector")
10015 (const_string "double")))
10016 (set_attr "amdfam10_decode" "double")
10017 (set_attr "bdver1_decode" "direct")
10018 (set_attr "mode" "SI")])
10019
10020 ;; Highpart multiplication peephole2s to tweak register allocation.
10021 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
10022 (define_peephole2
10023 [(set (match_operand:SWI48 0 "general_reg_operand")
10024 (match_operand:SWI48 1 "immediate_operand"))
10025 (set (match_operand:SWI48 2 "general_reg_operand")
10026 (match_operand:SWI48 3 "general_reg_operand"))
10027 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
10028 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
10029 (clobber (match_dup 2))
10030 (clobber (reg:CC FLAGS_REG))])]
10031 "REGNO (operands[3]) != AX_REG
10032 && REGNO (operands[0]) != REGNO (operands[2])
10033 && REGNO (operands[0]) != REGNO (operands[3])
10034 && (REGNO (operands[0]) == REGNO (operands[4])
10035 || peep2_reg_dead_p (3, operands[0]))"
10036 [(set (match_dup 2) (match_dup 1))
10037 (parallel [(set (match_dup 4)
10038 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10039 (clobber (match_dup 2))
10040 (clobber (reg:CC FLAGS_REG))])])
10041
10042 (define_peephole2
10043 [(set (match_operand:SI 0 "general_reg_operand")
10044 (match_operand:SI 1 "immediate_operand"))
10045 (set (match_operand:SI 2 "general_reg_operand")
10046 (match_operand:SI 3 "general_reg_operand"))
10047 (parallel [(set (match_operand:DI 4 "general_reg_operand")
10048 (zero_extend:DI
10049 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10050 (clobber (match_dup 2))
10051 (clobber (reg:CC FLAGS_REG))])]
10052 "TARGET_64BIT
10053 && REGNO (operands[3]) != AX_REG
10054 && REGNO (operands[0]) != REGNO (operands[2])
10055 && REGNO (operands[2]) != REGNO (operands[3])
10056 && REGNO (operands[0]) != REGNO (operands[3])
10057 && (REGNO (operands[0]) == REGNO (operands[4])
10058 || peep2_reg_dead_p (3, operands[0]))"
10059 [(set (match_dup 2) (match_dup 1))
10060 (parallel [(set (match_dup 4)
10061 (zero_extend:DI
10062 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10063 (clobber (match_dup 2))
10064 (clobber (reg:CC FLAGS_REG))])])
10065
10066 ;; The patterns that match these are at the end of this file.
10067
10068 (define_expand "mulxf3"
10069 [(set (match_operand:XF 0 "register_operand")
10070 (mult:XF (match_operand:XF 1 "register_operand")
10071 (match_operand:XF 2 "register_operand")))]
10072 "TARGET_80387")
10073
10074 (define_expand "mulhf3"
10075 [(set (match_operand:HF 0 "register_operand")
10076 (mult:HF (match_operand:HF 1 "register_operand")
10077 (match_operand:HF 2 "nonimmediate_operand")))]
10078 "TARGET_AVX512FP16")
10079
10080 (define_expand "mul<mode>3"
10081 [(set (match_operand:MODEF 0 "register_operand")
10082 (mult:MODEF (match_operand:MODEF 1 "register_operand")
10083 (match_operand:MODEF 2 "nonimmediate_operand")))]
10084 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10085 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10086 \f
10087 ;; Divide instructions
10088
10089 ;; The patterns that match these are at the end of this file.
10090
10091 (define_expand "divxf3"
10092 [(set (match_operand:XF 0 "register_operand")
10093 (div:XF (match_operand:XF 1 "register_operand")
10094 (match_operand:XF 2 "register_operand")))]
10095 "TARGET_80387")
10096
10097 /* There is no more precision loss than Newton-Rhapson approximation
10098 when using HFmode rcp/rsqrt, so do the transformation directly under
10099 TARGET_RECIP_DIV and fast-math. */
10100 (define_expand "divhf3"
10101 [(set (match_operand:HF 0 "register_operand")
10102 (div:HF (match_operand:HF 1 "register_operand")
10103 (match_operand:HF 2 "nonimmediate_operand")))]
10104 "TARGET_AVX512FP16"
10105 {
10106 if (TARGET_RECIP_DIV
10107 && optimize_insn_for_speed_p ()
10108 && flag_finite_math_only && !flag_trapping_math
10109 && flag_unsafe_math_optimizations)
10110 {
10111 rtx op = gen_reg_rtx (HFmode);
10112 operands[2] = force_reg (HFmode, operands[2]);
10113 emit_insn (gen_rcphf2 (op, operands[2]));
10114 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10115 DONE;
10116 }
10117 })
10118
10119 (define_expand "div<mode>3"
10120 [(set (match_operand:MODEF 0 "register_operand")
10121 (div:MODEF (match_operand:MODEF 1 "register_operand")
10122 (match_operand:MODEF 2 "nonimmediate_operand")))]
10123 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10124 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10125 {
10126 if (<MODE>mode == SFmode
10127 && TARGET_SSE && TARGET_SSE_MATH
10128 && TARGET_RECIP_DIV
10129 && optimize_insn_for_speed_p ()
10130 && flag_finite_math_only && !flag_trapping_math
10131 && flag_unsafe_math_optimizations)
10132 {
10133 ix86_emit_swdivsf (operands[0], operands[1],
10134 operands[2], SFmode);
10135 DONE;
10136 }
10137 })
10138 \f
10139 ;; Divmod instructions.
10140
10141 (define_code_iterator any_div [div udiv])
10142 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10143
10144 (define_expand "<u>divmod<mode>4"
10145 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10146 (any_div:SWIM248
10147 (match_operand:SWIM248 1 "register_operand")
10148 (match_operand:SWIM248 2 "nonimmediate_operand")))
10149 (set (match_operand:SWIM248 3 "register_operand")
10150 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10151 (clobber (reg:CC FLAGS_REG))])])
10152
10153 ;; Split with 8bit unsigned divide:
10154 ;; if (dividend an divisor are in [0-255])
10155 ;; use 8bit unsigned integer divide
10156 ;; else
10157 ;; use original integer divide
10158 (define_split
10159 [(set (match_operand:SWI48 0 "register_operand")
10160 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10161 (match_operand:SWI48 3 "nonimmediate_operand")))
10162 (set (match_operand:SWI48 1 "register_operand")
10163 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10164 (clobber (reg:CC FLAGS_REG))]
10165 "TARGET_USE_8BIT_IDIV
10166 && TARGET_QIMODE_MATH
10167 && can_create_pseudo_p ()
10168 && !optimize_insn_for_size_p ()"
10169 [(const_int 0)]
10170 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10171
10172 (define_split
10173 [(set (match_operand:DI 0 "register_operand")
10174 (zero_extend:DI
10175 (any_div:SI (match_operand:SI 2 "register_operand")
10176 (match_operand:SI 3 "nonimmediate_operand"))))
10177 (set (match_operand:SI 1 "register_operand")
10178 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10179 (clobber (reg:CC FLAGS_REG))]
10180 "TARGET_64BIT
10181 && TARGET_USE_8BIT_IDIV
10182 && TARGET_QIMODE_MATH
10183 && can_create_pseudo_p ()
10184 && !optimize_insn_for_size_p ()"
10185 [(const_int 0)]
10186 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10187
10188 (define_split
10189 [(set (match_operand:DI 1 "register_operand")
10190 (zero_extend:DI
10191 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10192 (match_operand:SI 3 "nonimmediate_operand"))))
10193 (set (match_operand:SI 0 "register_operand")
10194 (any_div:SI (match_dup 2) (match_dup 3)))
10195 (clobber (reg:CC FLAGS_REG))]
10196 "TARGET_64BIT
10197 && TARGET_USE_8BIT_IDIV
10198 && TARGET_QIMODE_MATH
10199 && can_create_pseudo_p ()
10200 && !optimize_insn_for_size_p ()"
10201 [(const_int 0)]
10202 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10203
10204 (define_insn_and_split "divmod<mode>4_1"
10205 [(set (match_operand:SWI48 0 "register_operand" "=a")
10206 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10207 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10208 (set (match_operand:SWI48 1 "register_operand" "=&d")
10209 (mod:SWI48 (match_dup 2) (match_dup 3)))
10210 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10211 (clobber (reg:CC FLAGS_REG))]
10212 ""
10213 "#"
10214 "reload_completed"
10215 [(parallel [(set (match_dup 1)
10216 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10217 (clobber (reg:CC FLAGS_REG))])
10218 (parallel [(set (match_dup 0)
10219 (div:SWI48 (match_dup 2) (match_dup 3)))
10220 (set (match_dup 1)
10221 (mod:SWI48 (match_dup 2) (match_dup 3)))
10222 (use (match_dup 1))
10223 (clobber (reg:CC FLAGS_REG))])]
10224 {
10225 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10226
10227 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10228 operands[4] = operands[2];
10229 else
10230 {
10231 /* Avoid use of cltd in favor of a mov+shift. */
10232 emit_move_insn (operands[1], operands[2]);
10233 operands[4] = operands[1];
10234 }
10235 }
10236 [(set_attr "type" "multi")
10237 (set_attr "mode" "<MODE>")])
10238
10239 (define_insn_and_split "udivmod<mode>4_1"
10240 [(set (match_operand:SWI48 0 "register_operand" "=a")
10241 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10242 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10243 (set (match_operand:SWI48 1 "register_operand" "=&d")
10244 (umod:SWI48 (match_dup 2) (match_dup 3)))
10245 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10246 (clobber (reg:CC FLAGS_REG))]
10247 ""
10248 "#"
10249 "reload_completed"
10250 [(set (match_dup 1) (const_int 0))
10251 (parallel [(set (match_dup 0)
10252 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10253 (set (match_dup 1)
10254 (umod:SWI48 (match_dup 2) (match_dup 3)))
10255 (use (match_dup 1))
10256 (clobber (reg:CC FLAGS_REG))])]
10257 ""
10258 [(set_attr "type" "multi")
10259 (set_attr "mode" "<MODE>")])
10260
10261 (define_insn_and_split "divmodsi4_zext_1"
10262 [(set (match_operand:DI 0 "register_operand" "=a")
10263 (zero_extend:DI
10264 (div:SI (match_operand:SI 2 "register_operand" "0")
10265 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10266 (set (match_operand:SI 1 "register_operand" "=&d")
10267 (mod:SI (match_dup 2) (match_dup 3)))
10268 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10269 (clobber (reg:CC FLAGS_REG))]
10270 "TARGET_64BIT"
10271 "#"
10272 "&& reload_completed"
10273 [(parallel [(set (match_dup 1)
10274 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10275 (clobber (reg:CC FLAGS_REG))])
10276 (parallel [(set (match_dup 0)
10277 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10278 (set (match_dup 1)
10279 (mod:SI (match_dup 2) (match_dup 3)))
10280 (use (match_dup 1))
10281 (clobber (reg:CC FLAGS_REG))])]
10282 {
10283 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10284
10285 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10286 operands[4] = operands[2];
10287 else
10288 {
10289 /* Avoid use of cltd in favor of a mov+shift. */
10290 emit_move_insn (operands[1], operands[2]);
10291 operands[4] = operands[1];
10292 }
10293 }
10294 [(set_attr "type" "multi")
10295 (set_attr "mode" "SI")])
10296
10297 (define_insn_and_split "udivmodsi4_zext_1"
10298 [(set (match_operand:DI 0 "register_operand" "=a")
10299 (zero_extend:DI
10300 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10301 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10302 (set (match_operand:SI 1 "register_operand" "=&d")
10303 (umod:SI (match_dup 2) (match_dup 3)))
10304 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10305 (clobber (reg:CC FLAGS_REG))]
10306 "TARGET_64BIT"
10307 "#"
10308 "&& reload_completed"
10309 [(set (match_dup 1) (const_int 0))
10310 (parallel [(set (match_dup 0)
10311 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10312 (set (match_dup 1)
10313 (umod:SI (match_dup 2) (match_dup 3)))
10314 (use (match_dup 1))
10315 (clobber (reg:CC FLAGS_REG))])]
10316 ""
10317 [(set_attr "type" "multi")
10318 (set_attr "mode" "SI")])
10319
10320 (define_insn_and_split "divmodsi4_zext_2"
10321 [(set (match_operand:DI 1 "register_operand" "=&d")
10322 (zero_extend:DI
10323 (mod:SI (match_operand:SI 2 "register_operand" "0")
10324 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10325 (set (match_operand:SI 0 "register_operand" "=a")
10326 (div:SI (match_dup 2) (match_dup 3)))
10327 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10328 (clobber (reg:CC FLAGS_REG))]
10329 "TARGET_64BIT"
10330 "#"
10331 "&& reload_completed"
10332 [(parallel [(set (match_dup 6)
10333 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10334 (clobber (reg:CC FLAGS_REG))])
10335 (parallel [(set (match_dup 1)
10336 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10337 (set (match_dup 0)
10338 (div:SI (match_dup 2) (match_dup 3)))
10339 (use (match_dup 6))
10340 (clobber (reg:CC FLAGS_REG))])]
10341 {
10342 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10343 operands[6] = gen_lowpart (SImode, operands[1]);
10344
10345 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10346 operands[4] = operands[2];
10347 else
10348 {
10349 /* Avoid use of cltd in favor of a mov+shift. */
10350 emit_move_insn (operands[6], operands[2]);
10351 operands[4] = operands[6];
10352 }
10353 }
10354 [(set_attr "type" "multi")
10355 (set_attr "mode" "SI")])
10356
10357 (define_insn_and_split "udivmodsi4_zext_2"
10358 [(set (match_operand:DI 1 "register_operand" "=&d")
10359 (zero_extend:DI
10360 (umod:SI (match_operand:SI 2 "register_operand" "0")
10361 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10362 (set (match_operand:SI 0 "register_operand" "=a")
10363 (udiv:SI (match_dup 2) (match_dup 3)))
10364 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT"
10367 "#"
10368 "&& reload_completed"
10369 [(set (match_dup 4) (const_int 0))
10370 (parallel [(set (match_dup 1)
10371 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10372 (set (match_dup 0)
10373 (udiv:SI (match_dup 2) (match_dup 3)))
10374 (use (match_dup 4))
10375 (clobber (reg:CC FLAGS_REG))])]
10376 "operands[4] = gen_lowpart (SImode, operands[1]);"
10377 [(set_attr "type" "multi")
10378 (set_attr "mode" "SI")])
10379
10380 (define_insn_and_split "*divmod<mode>4"
10381 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10382 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10383 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10384 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10385 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10386 (clobber (reg:CC FLAGS_REG))]
10387 ""
10388 "#"
10389 "reload_completed"
10390 [(parallel [(set (match_dup 1)
10391 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10392 (clobber (reg:CC FLAGS_REG))])
10393 (parallel [(set (match_dup 0)
10394 (div:SWIM248 (match_dup 2) (match_dup 3)))
10395 (set (match_dup 1)
10396 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10397 (use (match_dup 1))
10398 (clobber (reg:CC FLAGS_REG))])]
10399 {
10400 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10401
10402 if (<MODE>mode != HImode
10403 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10404 operands[4] = operands[2];
10405 else
10406 {
10407 /* Avoid use of cltd in favor of a mov+shift. */
10408 emit_move_insn (operands[1], operands[2]);
10409 operands[4] = operands[1];
10410 }
10411 }
10412 [(set_attr "type" "multi")
10413 (set_attr "mode" "<MODE>")])
10414
10415 (define_insn_and_split "*udivmod<mode>4"
10416 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10417 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10418 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10419 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10420 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10421 (clobber (reg:CC FLAGS_REG))]
10422 ""
10423 "#"
10424 "reload_completed"
10425 [(set (match_dup 1) (const_int 0))
10426 (parallel [(set (match_dup 0)
10427 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10428 (set (match_dup 1)
10429 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10430 (use (match_dup 1))
10431 (clobber (reg:CC FLAGS_REG))])]
10432 ""
10433 [(set_attr "type" "multi")
10434 (set_attr "mode" "<MODE>")])
10435
10436 ;; Optimize division or modulo by constant power of 2, if the constant
10437 ;; materializes only after expansion.
10438 (define_insn_and_split "*udivmod<mode>4_pow2"
10439 [(set (match_operand:SWI48 0 "register_operand" "=r")
10440 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10441 (match_operand:SWI48 3 "const_int_operand")))
10442 (set (match_operand:SWI48 1 "register_operand" "=r")
10443 (umod:SWI48 (match_dup 2) (match_dup 3)))
10444 (clobber (reg:CC FLAGS_REG))]
10445 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10446 "#"
10447 "&& reload_completed"
10448 [(set (match_dup 1) (match_dup 2))
10449 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10450 (clobber (reg:CC FLAGS_REG))])
10451 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10452 (clobber (reg:CC FLAGS_REG))])]
10453 {
10454 int v = exact_log2 (UINTVAL (operands[3]));
10455 operands[4] = GEN_INT (v);
10456 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10457 }
10458 [(set_attr "type" "multi")
10459 (set_attr "mode" "<MODE>")])
10460
10461 (define_insn_and_split "*divmodsi4_zext_1"
10462 [(set (match_operand:DI 0 "register_operand" "=a")
10463 (zero_extend:DI
10464 (div:SI (match_operand:SI 2 "register_operand" "0")
10465 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10466 (set (match_operand:SI 1 "register_operand" "=&d")
10467 (mod:SI (match_dup 2) (match_dup 3)))
10468 (clobber (reg:CC FLAGS_REG))]
10469 "TARGET_64BIT"
10470 "#"
10471 "&& reload_completed"
10472 [(parallel [(set (match_dup 1)
10473 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10474 (clobber (reg:CC FLAGS_REG))])
10475 (parallel [(set (match_dup 0)
10476 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10477 (set (match_dup 1)
10478 (mod:SI (match_dup 2) (match_dup 3)))
10479 (use (match_dup 1))
10480 (clobber (reg:CC FLAGS_REG))])]
10481 {
10482 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10483
10484 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10485 operands[4] = operands[2];
10486 else
10487 {
10488 /* Avoid use of cltd in favor of a mov+shift. */
10489 emit_move_insn (operands[1], operands[2]);
10490 operands[4] = operands[1];
10491 }
10492 }
10493 [(set_attr "type" "multi")
10494 (set_attr "mode" "SI")])
10495
10496 (define_insn_and_split "*udivmodsi4_zext_1"
10497 [(set (match_operand:DI 0 "register_operand" "=a")
10498 (zero_extend:DI
10499 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10500 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10501 (set (match_operand:SI 1 "register_operand" "=&d")
10502 (umod:SI (match_dup 2) (match_dup 3)))
10503 (clobber (reg:CC FLAGS_REG))]
10504 "TARGET_64BIT"
10505 "#"
10506 "&& reload_completed"
10507 [(set (match_dup 1) (const_int 0))
10508 (parallel [(set (match_dup 0)
10509 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10510 (set (match_dup 1)
10511 (umod:SI (match_dup 2) (match_dup 3)))
10512 (use (match_dup 1))
10513 (clobber (reg:CC FLAGS_REG))])]
10514 ""
10515 [(set_attr "type" "multi")
10516 (set_attr "mode" "SI")])
10517
10518 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10519 [(set (match_operand:DI 0 "register_operand" "=r")
10520 (zero_extend:DI
10521 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10522 (match_operand:SI 3 "const_int_operand"))))
10523 (set (match_operand:SI 1 "register_operand" "=r")
10524 (umod:SI (match_dup 2) (match_dup 3)))
10525 (clobber (reg:CC FLAGS_REG))]
10526 "TARGET_64BIT
10527 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10528 "#"
10529 "&& reload_completed"
10530 [(set (match_dup 1) (match_dup 2))
10531 (parallel [(set (match_dup 0)
10532 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10533 (clobber (reg:CC FLAGS_REG))])
10534 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10535 (clobber (reg:CC FLAGS_REG))])]
10536 {
10537 int v = exact_log2 (UINTVAL (operands[3]));
10538 operands[4] = GEN_INT (v);
10539 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10540 }
10541 [(set_attr "type" "multi")
10542 (set_attr "mode" "SI")])
10543
10544 (define_insn_and_split "*divmodsi4_zext_2"
10545 [(set (match_operand:DI 1 "register_operand" "=&d")
10546 (zero_extend:DI
10547 (mod:SI (match_operand:SI 2 "register_operand" "0")
10548 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10549 (set (match_operand:SI 0 "register_operand" "=a")
10550 (div:SI (match_dup 2) (match_dup 3)))
10551 (clobber (reg:CC FLAGS_REG))]
10552 "TARGET_64BIT"
10553 "#"
10554 "&& reload_completed"
10555 [(parallel [(set (match_dup 6)
10556 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10557 (clobber (reg:CC FLAGS_REG))])
10558 (parallel [(set (match_dup 1)
10559 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10560 (set (match_dup 0)
10561 (div:SI (match_dup 2) (match_dup 3)))
10562 (use (match_dup 6))
10563 (clobber (reg:CC FLAGS_REG))])]
10564 {
10565 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10566 operands[6] = gen_lowpart (SImode, operands[1]);
10567
10568 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10569 operands[4] = operands[2];
10570 else
10571 {
10572 /* Avoid use of cltd in favor of a mov+shift. */
10573 emit_move_insn (operands[6], operands[2]);
10574 operands[4] = operands[6];
10575 }
10576 }
10577 [(set_attr "type" "multi")
10578 (set_attr "mode" "SI")])
10579
10580 (define_insn_and_split "*udivmodsi4_zext_2"
10581 [(set (match_operand:DI 1 "register_operand" "=&d")
10582 (zero_extend:DI
10583 (umod:SI (match_operand:SI 2 "register_operand" "0")
10584 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10585 (set (match_operand:SI 0 "register_operand" "=a")
10586 (udiv:SI (match_dup 2) (match_dup 3)))
10587 (clobber (reg:CC FLAGS_REG))]
10588 "TARGET_64BIT"
10589 "#"
10590 "&& reload_completed"
10591 [(set (match_dup 4) (const_int 0))
10592 (parallel [(set (match_dup 1)
10593 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10594 (set (match_dup 0)
10595 (udiv:SI (match_dup 2) (match_dup 3)))
10596 (use (match_dup 4))
10597 (clobber (reg:CC FLAGS_REG))])]
10598 "operands[4] = gen_lowpart (SImode, operands[1]);"
10599 [(set_attr "type" "multi")
10600 (set_attr "mode" "SI")])
10601
10602 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10603 [(set (match_operand:DI 1 "register_operand" "=r")
10604 (zero_extend:DI
10605 (umod:SI (match_operand:SI 2 "register_operand" "0")
10606 (match_operand:SI 3 "const_int_operand"))))
10607 (set (match_operand:SI 0 "register_operand" "=r")
10608 (udiv:SI (match_dup 2) (match_dup 3)))
10609 (clobber (reg:CC FLAGS_REG))]
10610 "TARGET_64BIT
10611 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10612 "#"
10613 "&& reload_completed"
10614 [(set (match_dup 1) (match_dup 2))
10615 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10616 (clobber (reg:CC FLAGS_REG))])
10617 (parallel [(set (match_dup 1)
10618 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10619 (clobber (reg:CC FLAGS_REG))])]
10620 {
10621 int v = exact_log2 (UINTVAL (operands[3]));
10622 operands[4] = GEN_INT (v);
10623 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10624 }
10625 [(set_attr "type" "multi")
10626 (set_attr "mode" "SI")])
10627
10628 (define_insn "*<u>divmod<mode>4_noext"
10629 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10630 (any_div:SWIM248
10631 (match_operand:SWIM248 2 "register_operand" "0")
10632 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10633 (set (match_operand:SWIM248 1 "register_operand" "=d")
10634 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10635 (use (match_operand:SWIM248 4 "register_operand" "1"))
10636 (clobber (reg:CC FLAGS_REG))]
10637 ""
10638 "<sgnprefix>div{<imodesuffix>}\t%3"
10639 [(set_attr "type" "idiv")
10640 (set_attr "mode" "<MODE>")])
10641
10642 (define_insn "*<u>divmodsi4_noext_zext_1"
10643 [(set (match_operand:DI 0 "register_operand" "=a")
10644 (zero_extend:DI
10645 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10646 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10647 (set (match_operand:SI 1 "register_operand" "=d")
10648 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10649 (use (match_operand:SI 4 "register_operand" "1"))
10650 (clobber (reg:CC FLAGS_REG))]
10651 "TARGET_64BIT"
10652 "<sgnprefix>div{l}\t%3"
10653 [(set_attr "type" "idiv")
10654 (set_attr "mode" "SI")])
10655
10656 (define_insn "*<u>divmodsi4_noext_zext_2"
10657 [(set (match_operand:DI 1 "register_operand" "=d")
10658 (zero_extend:DI
10659 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10660 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10661 (set (match_operand:SI 0 "register_operand" "=a")
10662 (any_div:SI (match_dup 2) (match_dup 3)))
10663 (use (match_operand:SI 4 "register_operand" "1"))
10664 (clobber (reg:CC FLAGS_REG))]
10665 "TARGET_64BIT"
10666 "<sgnprefix>div{l}\t%3"
10667 [(set_attr "type" "idiv")
10668 (set_attr "mode" "SI")])
10669
10670 ;; Avoid sign-extension (using cdq) for constant numerators.
10671 (define_insn_and_split "*divmodsi4_const"
10672 [(set (match_operand:SI 0 "register_operand" "=&a")
10673 (div:SI (match_operand:SI 2 "const_int_operand")
10674 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10675 (set (match_operand:SI 1 "register_operand" "=&d")
10676 (mod:SI (match_dup 2) (match_dup 3)))
10677 (clobber (reg:CC FLAGS_REG))]
10678 "!optimize_function_for_size_p (cfun)"
10679 "#"
10680 "&& reload_completed"
10681 [(set (match_dup 0) (match_dup 2))
10682 (set (match_dup 1) (match_dup 4))
10683 (parallel [(set (match_dup 0)
10684 (div:SI (match_dup 0) (match_dup 3)))
10685 (set (match_dup 1)
10686 (mod:SI (match_dup 0) (match_dup 3)))
10687 (use (match_dup 1))
10688 (clobber (reg:CC FLAGS_REG))])]
10689 {
10690 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10691 }
10692 [(set_attr "type" "multi")
10693 (set_attr "mode" "SI")])
10694
10695 (define_expand "divmodqi4"
10696 [(parallel [(set (match_operand:QI 0 "register_operand")
10697 (div:QI
10698 (match_operand:QI 1 "register_operand")
10699 (match_operand:QI 2 "nonimmediate_operand")))
10700 (set (match_operand:QI 3 "register_operand")
10701 (mod:QI (match_dup 1) (match_dup 2)))
10702 (clobber (reg:CC FLAGS_REG))])]
10703 "TARGET_QIMODE_MATH"
10704 {
10705 rtx div, mod;
10706 rtx tmp0, tmp1;
10707
10708 tmp0 = gen_reg_rtx (HImode);
10709 tmp1 = gen_reg_rtx (HImode);
10710
10711 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10712 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10713 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10714
10715 /* Extract remainder from AH. */
10716 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10717 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10718 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10719
10720 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10721 set_unique_reg_note (insn, REG_EQUAL, mod);
10722
10723 /* Extract quotient from AL. */
10724 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10725
10726 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10727 set_unique_reg_note (insn, REG_EQUAL, div);
10728
10729 DONE;
10730 })
10731
10732 (define_expand "udivmodqi4"
10733 [(parallel [(set (match_operand:QI 0 "register_operand")
10734 (udiv:QI
10735 (match_operand:QI 1 "register_operand")
10736 (match_operand:QI 2 "nonimmediate_operand")))
10737 (set (match_operand:QI 3 "register_operand")
10738 (umod:QI (match_dup 1) (match_dup 2)))
10739 (clobber (reg:CC FLAGS_REG))])]
10740 "TARGET_QIMODE_MATH"
10741 {
10742 rtx div, mod;
10743 rtx tmp0, tmp1;
10744
10745 tmp0 = gen_reg_rtx (HImode);
10746 tmp1 = gen_reg_rtx (HImode);
10747
10748 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10749 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10750 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10751
10752 /* Extract remainder from AH. */
10753 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10754 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10755 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10756
10757 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10758 set_unique_reg_note (insn, REG_EQUAL, mod);
10759
10760 /* Extract quotient from AL. */
10761 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10762
10763 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10764 set_unique_reg_note (insn, REG_EQUAL, div);
10765
10766 DONE;
10767 })
10768
10769 ;; Divide AX by r/m8, with result stored in
10770 ;; AL <- Quotient
10771 ;; AH <- Remainder
10772 ;; Change div/mod to HImode and extend the second argument to HImode
10773 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10774 ;; combine may fail.
10775 (define_insn "<u>divmodhiqi3"
10776 [(set (match_operand:HI 0 "register_operand" "=a")
10777 (ior:HI
10778 (ashift:HI
10779 (zero_extend:HI
10780 (truncate:QI
10781 (mod:HI (match_operand:HI 1 "register_operand" "0")
10782 (any_extend:HI
10783 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10784 (const_int 8))
10785 (zero_extend:HI
10786 (truncate:QI
10787 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10788 (clobber (reg:CC FLAGS_REG))]
10789 "TARGET_QIMODE_MATH"
10790 "<sgnprefix>div{b}\t%2"
10791 [(set_attr "type" "idiv")
10792 (set_attr "mode" "QI")])
10793
10794 ;; We cannot use div/idiv for double division, because it causes
10795 ;; "division by zero" on the overflow and that's not what we expect
10796 ;; from truncate. Because true (non truncating) double division is
10797 ;; never generated, we can't create this insn anyway.
10798 ;
10799 ;(define_insn ""
10800 ; [(set (match_operand:SI 0 "register_operand" "=a")
10801 ; (truncate:SI
10802 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10803 ; (zero_extend:DI
10804 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10805 ; (set (match_operand:SI 3 "register_operand" "=d")
10806 ; (truncate:SI
10807 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10808 ; (clobber (reg:CC FLAGS_REG))]
10809 ; ""
10810 ; "div{l}\t{%2, %0|%0, %2}"
10811 ; [(set_attr "type" "idiv")])
10812 \f
10813 ;;- Logical AND instructions
10814
10815 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10816 ;; Note that this excludes ah.
10817
10818 (define_expand "@test<mode>_ccno_1"
10819 [(set (reg:CCNO FLAGS_REG)
10820 (compare:CCNO
10821 (and:SWI48
10822 (match_operand:SWI48 0 "nonimmediate_operand")
10823 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10824 (const_int 0)))])
10825
10826 (define_expand "testqi_ccz_1"
10827 [(set (reg:CCZ FLAGS_REG)
10828 (compare:CCZ
10829 (and:QI
10830 (match_operand:QI 0 "nonimmediate_operand")
10831 (match_operand:QI 1 "nonmemory_operand"))
10832 (const_int 0)))])
10833
10834 (define_insn "*testdi_1"
10835 [(set (reg FLAGS_REG)
10836 (compare
10837 (and:DI
10838 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10839 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10840 (const_int 0)))]
10841 "TARGET_64BIT
10842 && ix86_match_ccmode
10843 (insn,
10844 /* If we are going to emit testl instead of testq, and the operands[1]
10845 constant might have the SImode sign bit set, make sure the sign
10846 flag isn't tested, because the instruction will set the sign flag
10847 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10848 conservatively assume it might have bit 31 set. */
10849 (satisfies_constraint_Z (operands[1])
10850 && (!CONST_INT_P (operands[1])
10851 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10852 ? CCZmode : CCNOmode)"
10853 "@
10854 test{l}\t{%k1, %k0|%k0, %k1}
10855 test{q}\t{%1, %0|%0, %1}"
10856 [(set_attr "type" "test")
10857 (set_attr "mode" "SI,DI")])
10858
10859 (define_insn "*testqi_1_maybe_si"
10860 [(set (reg FLAGS_REG)
10861 (compare
10862 (and:QI
10863 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10864 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10865 (const_int 0)))]
10866 "ix86_match_ccmode (insn,
10867 CONST_INT_P (operands[1])
10868 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10869 {
10870 if (get_attr_mode (insn) == MODE_SI)
10871 {
10872 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10873 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10874 return "test{l}\t{%1, %k0|%k0, %1}";
10875 }
10876 return "test{b}\t{%1, %0|%0, %1}";
10877 }
10878 [(set_attr "type" "test")
10879 (set (attr "mode")
10880 (cond [(eq_attr "alternative" "2")
10881 (const_string "SI")
10882 (and (match_test "optimize_insn_for_size_p ()")
10883 (and (match_operand 0 "ext_QIreg_operand")
10884 (match_operand 1 "const_0_to_127_operand")))
10885 (const_string "SI")
10886 ]
10887 (const_string "QI")))
10888 (set_attr "pent_pair" "uv,np,np")])
10889
10890 (define_insn "*test<mode>_1"
10891 [(set (reg FLAGS_REG)
10892 (compare
10893 (and:SWI124
10894 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10895 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10896 (const_int 0)))]
10897 "ix86_match_ccmode (insn, CCNOmode)"
10898 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10899 [(set_attr "type" "test")
10900 (set_attr "mode" "<MODE>")
10901 (set_attr "pent_pair" "uv,uv,np")])
10902
10903 (define_expand "testqi_ext_1_ccno"
10904 [(set (reg:CCNO FLAGS_REG)
10905 (compare:CCNO
10906 (and:QI
10907 (subreg:QI
10908 (zero_extract:HI
10909 (match_operand:HI 0 "register_operand")
10910 (const_int 8)
10911 (const_int 8)) 0)
10912 (match_operand:QI 1 "const_int_operand"))
10913 (const_int 0)))])
10914
10915 (define_insn "*testqi_ext<mode>_1"
10916 [(set (reg FLAGS_REG)
10917 (compare
10918 (and:QI
10919 (subreg:QI
10920 (match_operator:SWI248 2 "extract_operator"
10921 [(match_operand 0 "int248_register_operand" "Q,Q")
10922 (const_int 8)
10923 (const_int 8)]) 0)
10924 (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
10925 (const_int 0)))]
10926 "ix86_match_ccmode (insn, CCNOmode)"
10927 "test{b}\t{%1, %h0|%h0, %1}"
10928 [(set_attr "isa" "*,nox64")
10929 (set_attr "type" "test")
10930 (set_attr "mode" "QI")])
10931
10932 (define_insn "*testqi_ext<mode>_2"
10933 [(set (reg FLAGS_REG)
10934 (compare
10935 (and:QI
10936 (subreg:QI
10937 (match_operator:SWI248 2 "extract_operator"
10938 [(match_operand 0 "int248_register_operand" "Q")
10939 (const_int 8)
10940 (const_int 8)]) 0)
10941 (subreg:QI
10942 (match_operator:SWI248 3 "extract_operator"
10943 [(match_operand 1 "int248_register_operand" "Q")
10944 (const_int 8)
10945 (const_int 8)]) 0))
10946 (const_int 0)))]
10947 "ix86_match_ccmode (insn, CCNOmode)"
10948 "test{b}\t{%h1, %h0|%h0, %h1}"
10949 [(set_attr "type" "test")
10950 (set_attr "mode" "QI")])
10951
10952 ;; Provide a *testti instruction that STV can implement using ptest.
10953 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10954 (define_insn_and_split "*testti_doubleword"
10955 [(set (reg:CCZ FLAGS_REG)
10956 (compare:CCZ
10957 (and:TI (match_operand:TI 0 "register_operand")
10958 (match_operand:TI 1 "general_operand"))
10959 (const_int 0)))]
10960 "TARGET_64BIT
10961 && ix86_pre_reload_split ()"
10962 "#"
10963 "&& 1"
10964 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10965 (clobber (reg:CC FLAGS_REG))])
10966 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10967 {
10968 operands[2] = gen_reg_rtx (TImode);
10969 if (!x86_64_hilo_general_operand (operands[1], TImode))
10970 operands[1] = force_reg (TImode, operands[1]);
10971 })
10972
10973 ;; Combine likes to form bit extractions for some tests. Humor it.
10974 (define_insn_and_split "*testqi_ext_3"
10975 [(set (match_operand 0 "flags_reg_operand")
10976 (match_operator 1 "compare_operator"
10977 [(zero_extract:SWI248
10978 (match_operand 2 "int_nonimmediate_operand" "rm")
10979 (match_operand:QI 3 "const_int_operand")
10980 (match_operand:QI 4 "const_int_operand"))
10981 (const_int 0)]))]
10982 "/* Ensure that resulting mask is zero or sign extended operand. */
10983 INTVAL (operands[4]) >= 0
10984 && ((INTVAL (operands[3]) > 0
10985 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10986 || (<MODE>mode == DImode
10987 && INTVAL (operands[3]) > 32
10988 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10989 && ix86_match_ccmode (insn,
10990 /* If zero_extract mode precision is the same
10991 as len, the SF of the zero_extract
10992 comparison will be the most significant
10993 extracted bit, but this could be matched
10994 after splitting only for pos 0 len all bits
10995 trivial extractions. Require CCZmode. */
10996 (GET_MODE_PRECISION (<MODE>mode)
10997 == INTVAL (operands[3]))
10998 /* Otherwise, require CCZmode if we'd use a mask
10999 with the most significant bit set and can't
11000 widen it to wider mode. *testdi_1 also
11001 requires CCZmode if the mask has bit
11002 31 set and all bits above it clear. */
11003 || (INTVAL (operands[3]) + INTVAL (operands[4])
11004 >= 32)
11005 /* We can't widen also if val is not a REG. */
11006 || (INTVAL (operands[3]) + INTVAL (operands[4])
11007 == GET_MODE_PRECISION (GET_MODE (operands[2]))
11008 && !register_operand (operands[2],
11009 GET_MODE (operands[2])))
11010 /* And we shouldn't widen if
11011 TARGET_PARTIAL_REG_STALL. */
11012 || (TARGET_PARTIAL_REG_STALL
11013 && (INTVAL (operands[3]) + INTVAL (operands[4])
11014 >= (paradoxical_subreg_p (operands[2])
11015 && (GET_MODE_CLASS
11016 (GET_MODE (SUBREG_REG (operands[2])))
11017 == MODE_INT)
11018 ? GET_MODE_PRECISION
11019 (GET_MODE (SUBREG_REG (operands[2])))
11020 : GET_MODE_PRECISION
11021 (GET_MODE (operands[2])))))
11022 ? CCZmode : CCNOmode)"
11023 "#"
11024 "&& 1"
11025 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11026 {
11027 rtx val = operands[2];
11028 HOST_WIDE_INT len = INTVAL (operands[3]);
11029 HOST_WIDE_INT pos = INTVAL (operands[4]);
11030 machine_mode mode = GET_MODE (val);
11031
11032 if (SUBREG_P (val))
11033 {
11034 machine_mode submode = GET_MODE (SUBREG_REG (val));
11035
11036 /* Narrow paradoxical subregs to prevent partial register stalls. */
11037 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
11038 && GET_MODE_CLASS (submode) == MODE_INT
11039 && (GET_MODE (operands[0]) == CCZmode
11040 || pos + len < GET_MODE_PRECISION (submode)
11041 || REG_P (SUBREG_REG (val))))
11042 {
11043 val = SUBREG_REG (val);
11044 mode = submode;
11045 }
11046 }
11047
11048 /* Small HImode tests can be converted to QImode. */
11049 if (pos + len <= 8
11050 && register_operand (val, HImode))
11051 {
11052 rtx nval = gen_lowpart (QImode, val);
11053 if (!MEM_P (nval)
11054 || GET_MODE (operands[0]) == CCZmode
11055 || pos + len < 8)
11056 {
11057 val = nval;
11058 mode = QImode;
11059 }
11060 }
11061
11062 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11063
11064 /* If the mask is going to have the sign bit set in the mode
11065 we want to do the comparison in and user isn't interested just
11066 in the zero flag, then we must widen the target mode. */
11067 if (pos + len == GET_MODE_PRECISION (mode)
11068 && GET_MODE (operands[0]) != CCZmode)
11069 {
11070 gcc_assert (pos + len < 32 && !MEM_P (val));
11071 mode = SImode;
11072 val = gen_lowpart (mode, val);
11073 }
11074
11075 wide_int mask
11076 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11077
11078 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11079 })
11080
11081 ;; Split and;cmp (as optimized by combine) into not;test
11082 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11083 (define_insn_and_split "*test<mode>_not"
11084 [(set (reg:CCZ FLAGS_REG)
11085 (compare:CCZ
11086 (and:SWI
11087 (not:SWI (match_operand:SWI 0 "register_operand"))
11088 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11089 (const_int 0)))]
11090 "ix86_pre_reload_split ()
11091 && (!TARGET_BMI || !REG_P (operands[1]))"
11092 "#"
11093 "&& 1"
11094 [(set (match_dup 2) (not:SWI (match_dup 0)))
11095 (set (reg:CCZ FLAGS_REG)
11096 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11097 (const_int 0)))]
11098 "operands[2] = gen_reg_rtx (<MODE>mode);")
11099
11100 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11101 (define_insn_and_split "*test<mode>_not_doubleword"
11102 [(set (reg:CCZ FLAGS_REG)
11103 (compare:CCZ
11104 (and:DWI
11105 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11106 (match_operand:DWI 1 "nonimmediate_operand"))
11107 (const_int 0)))]
11108 "ix86_pre_reload_split ()"
11109 "#"
11110 "&& 1"
11111 [(parallel
11112 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11113 (clobber (reg:CC FLAGS_REG))])
11114 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11115 {
11116 operands[0] = force_reg (<MODE>mode, operands[0]);
11117 operands[2] = gen_reg_rtx (<MODE>mode);
11118 })
11119
11120 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11121 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11122 ;; this is relatively important trick.
11123 ;; Do the conversion only post-reload to avoid limiting of the register class
11124 ;; to QI regs.
11125 (define_split
11126 [(set (match_operand 0 "flags_reg_operand")
11127 (match_operator 1 "compare_operator"
11128 [(and (match_operand 2 "QIreg_operand")
11129 (match_operand 3 "const_int_operand"))
11130 (const_int 0)]))]
11131 "reload_completed
11132 && GET_MODE (operands[2]) != QImode
11133 && ((ix86_match_ccmode (insn, CCZmode)
11134 && !(INTVAL (operands[3]) & ~(255 << 8)))
11135 || (ix86_match_ccmode (insn, CCNOmode)
11136 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11137 [(set (match_dup 0)
11138 (match_op_dup 1
11139 [(and:QI
11140 (subreg:QI
11141 (zero_extract:HI (match_dup 2)
11142 (const_int 8)
11143 (const_int 8)) 0)
11144 (match_dup 3))
11145 (const_int 0)]))]
11146 {
11147 operands[2] = gen_lowpart (HImode, operands[2]);
11148 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11149 })
11150
11151 (define_split
11152 [(set (match_operand 0 "flags_reg_operand")
11153 (match_operator 1 "compare_operator"
11154 [(and (match_operand 2 "nonimmediate_operand")
11155 (match_operand 3 "const_int_operand"))
11156 (const_int 0)]))]
11157 "reload_completed
11158 && GET_MODE (operands[2]) != QImode
11159 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11160 && ((ix86_match_ccmode (insn, CCZmode)
11161 && !(INTVAL (operands[3]) & ~255))
11162 || (ix86_match_ccmode (insn, CCNOmode)
11163 && !(INTVAL (operands[3]) & ~127)))"
11164 [(set (match_dup 0)
11165 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11166 (const_int 0)]))]
11167 {
11168 operands[2] = gen_lowpart (QImode, operands[2]);
11169 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11170 })
11171
11172 ;; Narrow test instructions with immediate operands that test
11173 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11174 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11175 ;; targets where reading (possibly unaligned) part of memory
11176 ;; location after a large write to the same address causes
11177 ;; store-to-load forwarding stall.
11178 (define_peephole2
11179 [(set (reg:CCZ FLAGS_REG)
11180 (compare:CCZ
11181 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11182 (match_operand 1 "const_int_operand"))
11183 (const_int 0)))]
11184 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11185 [(set (reg:CCZ FLAGS_REG)
11186 (compare:CCZ (match_dup 2) (const_int 0)))]
11187 {
11188 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11189 int first_nonzero_byte, bitsize;
11190 rtx new_addr, new_const;
11191 machine_mode new_mode;
11192
11193 if (ival == 0)
11194 FAIL;
11195
11196 /* Clear bits outside mode width. */
11197 ival &= GET_MODE_MASK (<MODE>mode);
11198
11199 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11200
11201 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11202
11203 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11204
11205 if (bitsize <= GET_MODE_BITSIZE (QImode))
11206 new_mode = QImode;
11207 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11208 new_mode = HImode;
11209 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11210 new_mode = SImode;
11211 else
11212 new_mode = DImode;
11213
11214 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11215 FAIL;
11216
11217 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11218 new_const = gen_int_mode (ival, new_mode);
11219
11220 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11221 })
11222
11223 ;; %%% This used to optimize known byte-wide and operations to memory,
11224 ;; and sometimes to QImode registers. If this is considered useful,
11225 ;; it should be done with splitters.
11226
11227 (define_expand "and<mode>3"
11228 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11229 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11230 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11231 ""
11232 {
11233 machine_mode mode = <MODE>mode;
11234
11235 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11236 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11237 operands[2] = force_reg (<MODE>mode, operands[2]);
11238
11239 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11240 && const_int_operand (operands[2], <MODE>mode)
11241 && register_operand (operands[0], <MODE>mode)
11242 && !(TARGET_ZERO_EXTEND_WITH_AND
11243 && optimize_function_for_speed_p (cfun)))
11244 {
11245 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11246
11247 if (ival == GET_MODE_MASK (SImode))
11248 mode = SImode;
11249 else if (ival == GET_MODE_MASK (HImode))
11250 mode = HImode;
11251 else if (ival == GET_MODE_MASK (QImode))
11252 mode = QImode;
11253 }
11254
11255 if (mode != <MODE>mode)
11256 emit_insn (gen_extend_insn
11257 (operands[0], gen_lowpart (mode, operands[1]),
11258 <MODE>mode, mode, 1));
11259 else
11260 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11261
11262 DONE;
11263 })
11264
11265 (define_insn_and_split "*and<dwi>3_doubleword"
11266 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11267 (and:<DWI>
11268 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11269 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11270 (clobber (reg:CC FLAGS_REG))]
11271 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11272 "#"
11273 "&& reload_completed"
11274 [(const_int:DWIH 0)]
11275 {
11276 bool emit_insn_deleted_note_p = false;
11277
11278 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11279
11280 if (operands[2] == const0_rtx)
11281 emit_move_insn (operands[0], const0_rtx);
11282 else if (operands[2] == constm1_rtx)
11283 emit_insn_deleted_note_p = true;
11284 else
11285 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11286
11287 if (operands[5] == const0_rtx)
11288 emit_move_insn (operands[3], const0_rtx);
11289 else if (operands[5] == constm1_rtx)
11290 {
11291 if (emit_insn_deleted_note_p)
11292 emit_note (NOTE_INSN_DELETED);
11293 }
11294 else
11295 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11296
11297 DONE;
11298 })
11299
11300 (define_insn "*anddi_1"
11301 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11302 (and:DI
11303 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11304 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11305 (clobber (reg:CC FLAGS_REG))]
11306 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11307 "@
11308 and{l}\t{%k2, %k0|%k0, %k2}
11309 and{q}\t{%2, %0|%0, %2}
11310 and{q}\t{%2, %0|%0, %2}
11311 #
11312 #"
11313 [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11314 (set_attr "type" "alu,alu,alu,imovx,msklog")
11315 (set_attr "length_immediate" "*,*,*,0,*")
11316 (set (attr "prefix_rex")
11317 (if_then_else
11318 (and (eq_attr "type" "imovx")
11319 (and (match_test "INTVAL (operands[2]) == 0xff")
11320 (match_operand 1 "ext_QIreg_operand")))
11321 (const_string "1")
11322 (const_string "*")))
11323 (set_attr "mode" "SI,DI,DI,SI,DI")])
11324
11325 (define_insn_and_split "*anddi_1_btr"
11326 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11327 (and:DI
11328 (match_operand:DI 1 "nonimmediate_operand" "%0")
11329 (match_operand:DI 2 "const_int_operand" "n")))
11330 (clobber (reg:CC FLAGS_REG))]
11331 "TARGET_64BIT && TARGET_USE_BT
11332 && ix86_binary_operator_ok (AND, DImode, operands)
11333 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11334 "#"
11335 "&& reload_completed"
11336 [(parallel [(set (zero_extract:DI (match_dup 0)
11337 (const_int 1)
11338 (match_dup 3))
11339 (const_int 0))
11340 (clobber (reg:CC FLAGS_REG))])]
11341 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11342 [(set_attr "type" "alu1")
11343 (set_attr "prefix_0f" "1")
11344 (set_attr "znver1_decode" "double")
11345 (set_attr "mode" "DI")])
11346
11347 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11348 (define_split
11349 [(set (match_operand:DI 0 "register_operand")
11350 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11351 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11352 (clobber (reg:CC FLAGS_REG))]
11353 "TARGET_64BIT"
11354 [(parallel [(set (match_dup 0)
11355 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11356 (clobber (reg:CC FLAGS_REG))])]
11357 {
11358 if (GET_CODE (operands[2]) == SYMBOL_REF
11359 || GET_CODE (operands[2]) == LABEL_REF)
11360 {
11361 operands[2] = shallow_copy_rtx (operands[2]);
11362 PUT_MODE (operands[2], SImode);
11363 }
11364 else if (GET_CODE (operands[2]) == CONST)
11365 {
11366 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11367 operands[2] = copy_rtx (operands[2]);
11368 PUT_MODE (operands[2], SImode);
11369 PUT_MODE (XEXP (operands[2], 0), SImode);
11370 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11371 }
11372 else
11373 operands[2] = gen_lowpart (SImode, operands[2]);
11374 })
11375
11376 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11377 (define_insn "*andsi_1_zext"
11378 [(set (match_operand:DI 0 "register_operand" "=r")
11379 (zero_extend:DI
11380 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11381 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11382 (clobber (reg:CC FLAGS_REG))]
11383 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11384 "and{l}\t{%2, %k0|%k0, %2}"
11385 [(set_attr "type" "alu")
11386 (set_attr "mode" "SI")])
11387
11388 (define_insn "*and<mode>_1"
11389 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11390 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11391 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11392 (clobber (reg:CC FLAGS_REG))]
11393 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11394 "@
11395 and{<imodesuffix>}\t{%2, %0|%0, %2}
11396 and{<imodesuffix>}\t{%2, %0|%0, %2}
11397 #
11398 #"
11399 [(set (attr "isa")
11400 (cond [(eq_attr "alternative" "3")
11401 (if_then_else (eq_attr "mode" "SI")
11402 (const_string "avx512bw")
11403 (const_string "avx512f"))
11404 ]
11405 (const_string "*")))
11406 (set_attr "type" "alu,alu,imovx,msklog")
11407 (set_attr "length_immediate" "*,*,0,*")
11408 (set (attr "prefix_rex")
11409 (if_then_else
11410 (and (eq_attr "type" "imovx")
11411 (and (match_test "INTVAL (operands[2]) == 0xff")
11412 (match_operand 1 "ext_QIreg_operand")))
11413 (const_string "1")
11414 (const_string "*")))
11415 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11416
11417 (define_insn "*andqi_1"
11418 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11419 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11420 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11421 (clobber (reg:CC FLAGS_REG))]
11422 "ix86_binary_operator_ok (AND, QImode, operands)"
11423 "@
11424 and{b}\t{%2, %0|%0, %2}
11425 and{b}\t{%2, %0|%0, %2}
11426 and{l}\t{%k2, %k0|%k0, %k2}
11427 #"
11428 [(set_attr "type" "alu,alu,alu,msklog")
11429 (set (attr "mode")
11430 (cond [(eq_attr "alternative" "2")
11431 (const_string "SI")
11432 (and (eq_attr "alternative" "3")
11433 (match_test "!TARGET_AVX512DQ"))
11434 (const_string "HI")
11435 ]
11436 (const_string "QI")))
11437 ;; Potential partial reg stall on alternative 2.
11438 (set (attr "preferred_for_speed")
11439 (cond [(eq_attr "alternative" "2")
11440 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11441 (symbol_ref "true")))])
11442
11443 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11444 (define_insn_and_split "*and<mode>_1_slp"
11445 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11446 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11447 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11448 (clobber (reg:CC FLAGS_REG))]
11449 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11450 "@
11451 and{<imodesuffix>}\t{%2, %0|%0, %2}
11452 #"
11453 "&& reload_completed"
11454 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11455 (parallel
11456 [(set (strict_low_part (match_dup 0))
11457 (and:SWI12 (match_dup 0) (match_dup 2)))
11458 (clobber (reg:CC FLAGS_REG))])]
11459 ""
11460 [(set_attr "type" "alu")
11461 (set_attr "mode" "<MODE>")])
11462
11463 (define_split
11464 [(set (match_operand:SWI248 0 "register_operand")
11465 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11466 (match_operand:SWI248 2 "const_int_operand")))
11467 (clobber (reg:CC FLAGS_REG))]
11468 "reload_completed
11469 && (!REG_P (operands[1])
11470 || REGNO (operands[0]) != REGNO (operands[1]))"
11471 [(const_int 0)]
11472 {
11473 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11474 machine_mode mode;
11475
11476 if (ival == GET_MODE_MASK (SImode))
11477 mode = SImode;
11478 else if (ival == GET_MODE_MASK (HImode))
11479 mode = HImode;
11480 else if (ival == GET_MODE_MASK (QImode))
11481 mode = QImode;
11482 else
11483 gcc_unreachable ();
11484
11485 /* Zero extend to SImode to avoid partial register stalls. */
11486 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11487 operands[0] = gen_lowpart (SImode, operands[0]);
11488
11489 emit_insn (gen_extend_insn
11490 (operands[0], gen_lowpart (mode, operands[1]),
11491 GET_MODE (operands[0]), mode, 1));
11492 DONE;
11493 })
11494
11495 (define_split
11496 [(set (match_operand:SWI48 0 "register_operand")
11497 (and:SWI48 (match_dup 0)
11498 (const_int -65536)))
11499 (clobber (reg:CC FLAGS_REG))]
11500 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11501 || optimize_function_for_size_p (cfun)"
11502 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11503 "operands[1] = gen_lowpart (HImode, operands[0]);")
11504
11505 (define_split
11506 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11507 (and:SWI248 (match_dup 0)
11508 (const_int -256)))
11509 (clobber (reg:CC FLAGS_REG))]
11510 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11511 && reload_completed"
11512 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11513 "operands[1] = gen_lowpart (QImode, operands[0]);")
11514
11515 (define_split
11516 [(set (match_operand:SWI248 0 "QIreg_operand")
11517 (and:SWI248 (match_dup 0)
11518 (const_int -65281)))
11519 (clobber (reg:CC FLAGS_REG))]
11520 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11521 && reload_completed"
11522 [(parallel
11523 [(set (zero_extract:HI (match_dup 0)
11524 (const_int 8)
11525 (const_int 8))
11526 (subreg:HI
11527 (xor:QI
11528 (subreg:QI
11529 (zero_extract:HI (match_dup 0)
11530 (const_int 8)
11531 (const_int 8)) 0)
11532 (subreg:QI
11533 (zero_extract:HI (match_dup 0)
11534 (const_int 8)
11535 (const_int 8)) 0)) 0))
11536 (clobber (reg:CC FLAGS_REG))])]
11537 "operands[0] = gen_lowpart (HImode, operands[0]);")
11538
11539 (define_insn "*anddi_2"
11540 [(set (reg FLAGS_REG)
11541 (compare
11542 (and:DI
11543 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11544 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11545 (const_int 0)))
11546 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11547 (and:DI (match_dup 1) (match_dup 2)))]
11548 "TARGET_64BIT
11549 && ix86_match_ccmode
11550 (insn,
11551 /* If we are going to emit andl instead of andq, and the operands[2]
11552 constant might have the SImode sign bit set, make sure the sign
11553 flag isn't tested, because the instruction will set the sign flag
11554 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11555 conservatively assume it might have bit 31 set. */
11556 (satisfies_constraint_Z (operands[2])
11557 && (!CONST_INT_P (operands[2])
11558 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11559 ? CCZmode : CCNOmode)
11560 && ix86_binary_operator_ok (AND, DImode, operands)"
11561 "@
11562 and{l}\t{%k2, %k0|%k0, %k2}
11563 and{q}\t{%2, %0|%0, %2}
11564 and{q}\t{%2, %0|%0, %2}"
11565 [(set_attr "type" "alu")
11566 (set_attr "mode" "SI,DI,DI")])
11567
11568 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11569 (define_insn "*andsi_2_zext"
11570 [(set (reg FLAGS_REG)
11571 (compare (and:SI
11572 (match_operand:SI 1 "nonimmediate_operand" "%0")
11573 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11574 (const_int 0)))
11575 (set (match_operand:DI 0 "register_operand" "=r")
11576 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11577 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11578 && ix86_binary_operator_ok (AND, SImode, operands)"
11579 "and{l}\t{%2, %k0|%k0, %2}"
11580 [(set_attr "type" "alu")
11581 (set_attr "mode" "SI")])
11582
11583 (define_insn "*andqi_2_maybe_si"
11584 [(set (reg FLAGS_REG)
11585 (compare (and:QI
11586 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11587 (match_operand:QI 2 "general_operand" "qn,m,n"))
11588 (const_int 0)))
11589 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11590 (and:QI (match_dup 1) (match_dup 2)))]
11591 "ix86_binary_operator_ok (AND, QImode, operands)
11592 && ix86_match_ccmode (insn,
11593 CONST_INT_P (operands[2])
11594 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11595 {
11596 if (get_attr_mode (insn) == MODE_SI)
11597 {
11598 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11599 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11600 return "and{l}\t{%2, %k0|%k0, %2}";
11601 }
11602 return "and{b}\t{%2, %0|%0, %2}";
11603 }
11604 [(set_attr "type" "alu")
11605 (set (attr "mode")
11606 (cond [(eq_attr "alternative" "2")
11607 (const_string "SI")
11608 (and (match_test "optimize_insn_for_size_p ()")
11609 (and (match_operand 0 "ext_QIreg_operand")
11610 (match_operand 2 "const_0_to_127_operand")))
11611 (const_string "SI")
11612 ]
11613 (const_string "QI")))
11614 ;; Potential partial reg stall on alternative 2.
11615 (set (attr "preferred_for_speed")
11616 (cond [(eq_attr "alternative" "2")
11617 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11618 (symbol_ref "true")))])
11619
11620 (define_insn "*and<mode>_2"
11621 [(set (reg FLAGS_REG)
11622 (compare (and:SWI124
11623 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11624 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11625 (const_int 0)))
11626 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11627 (and:SWI124 (match_dup 1) (match_dup 2)))]
11628 "ix86_match_ccmode (insn, CCNOmode)
11629 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11630 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11631 [(set_attr "type" "alu")
11632 (set_attr "mode" "<MODE>")])
11633
11634 (define_insn "*andqi_ext<mode>_0"
11635 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
11636 (and:QI
11637 (subreg:QI
11638 (match_operator:SWI248 3 "extract_operator"
11639 [(match_operand 2 "int248_register_operand" "Q,Q")
11640 (const_int 8)
11641 (const_int 8)]) 0)
11642 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
11643 (clobber (reg:CC FLAGS_REG))]
11644 ""
11645 "and{b}\t{%h2, %0|%0, %h2}"
11646 [(set_attr "isa" "*,nox64")
11647 (set_attr "type" "alu")
11648 (set_attr "mode" "QI")])
11649
11650 (define_expand "andqi_ext_1"
11651 [(parallel
11652 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11653 (const_int 8)
11654 (const_int 8))
11655 (subreg:HI
11656 (and:QI
11657 (subreg:QI
11658 (zero_extract:HI (match_operand:HI 1 "register_operand")
11659 (const_int 8)
11660 (const_int 8)) 0)
11661 (match_operand:QI 2 "const_int_operand")) 0))
11662 (clobber (reg:CC FLAGS_REG))])])
11663
11664 (define_insn "*andqi_ext<mode>_1"
11665 [(set (zero_extract:SWI248
11666 (match_operand 0 "int248_register_operand" "+Q,Q")
11667 (const_int 8)
11668 (const_int 8))
11669 (subreg:SWI248
11670 (and:QI
11671 (subreg:QI
11672 (match_operator:SWI248 3 "extract_operator"
11673 [(match_operand 1 "int248_register_operand" "0,0")
11674 (const_int 8)
11675 (const_int 8)]) 0)
11676 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
11677 (clobber (reg:CC FLAGS_REG))]
11678 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11679 rtx_equal_p (operands[0], operands[1])"
11680 "and{b}\t{%2, %h0|%h0, %2}"
11681 [(set_attr "isa" "*,nox64")
11682 (set_attr "type" "alu")
11683 (set_attr "mode" "QI")])
11684
11685 ;; Generated by peephole translating test to and. This shows up
11686 ;; often in fp comparisons.
11687 (define_insn "*andqi_ext<mode>_1_cc"
11688 [(set (reg FLAGS_REG)
11689 (compare
11690 (and:QI
11691 (subreg:QI
11692 (match_operator:SWI248 3 "extract_operator"
11693 [(match_operand 1 "int248_register_operand" "0,0")
11694 (const_int 8)
11695 (const_int 8)]) 0)
11696 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
11697 (const_int 0)))
11698 (set (zero_extract:SWI248
11699 (match_operand 0 "int248_register_operand" "+Q,Q")
11700 (const_int 8)
11701 (const_int 8))
11702 (subreg:SWI248
11703 (and:QI
11704 (subreg:QI
11705 (match_op_dup 3
11706 [(match_dup 1)
11707 (const_int 8)
11708 (const_int 8)]) 0)
11709 (match_dup 2)) 0))]
11710 "ix86_match_ccmode (insn, CCNOmode)
11711 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11712 && rtx_equal_p (operands[0], operands[1])"
11713 "and{b}\t{%2, %h0|%h0, %2}"
11714 [(set_attr "isa" "*,nox64")
11715 (set_attr "type" "alu")
11716 (set_attr "mode" "QI")])
11717
11718 (define_insn "*andqi_ext<mode>_2"
11719 [(set (zero_extract:SWI248
11720 (match_operand 0 "int248_register_operand" "+Q")
11721 (const_int 8)
11722 (const_int 8))
11723 (subreg:SWI248
11724 (and:QI
11725 (subreg:QI
11726 (match_operator:SWI248 3 "extract_operator"
11727 [(match_operand 1 "int248_register_operand" "%0")
11728 (const_int 8)
11729 (const_int 8)]) 0)
11730 (subreg:QI
11731 (match_operator:SWI248 4 "extract_operator"
11732 [(match_operand 2 "int248_register_operand" "Q")
11733 (const_int 8)
11734 (const_int 8)]) 0)) 0))
11735 (clobber (reg:CC FLAGS_REG))]
11736 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11737 rtx_equal_p (operands[0], operands[1])
11738 || rtx_equal_p (operands[0], operands[2])"
11739 "and{b}\t{%h2, %h0|%h0, %h2}"
11740 [(set_attr "type" "alu")
11741 (set_attr "mode" "QI")])
11742
11743 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11744
11745 ;; Convert wide AND instructions with immediate operand to shorter QImode
11746 ;; equivalents when possible.
11747 ;; Don't do the splitting with memory operands, since it introduces risk
11748 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11749 ;; for size, but that can (should?) be handled by generic code instead.
11750 (define_split
11751 [(set (match_operand:SWI248 0 "QIreg_operand")
11752 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11753 (match_operand:SWI248 2 "const_int_operand")))
11754 (clobber (reg:CC FLAGS_REG))]
11755 "reload_completed
11756 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11757 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11758 [(parallel
11759 [(set (zero_extract:HI (match_dup 0)
11760 (const_int 8)
11761 (const_int 8))
11762 (subreg:HI
11763 (and:QI
11764 (subreg:QI
11765 (zero_extract:HI (match_dup 1)
11766 (const_int 8)
11767 (const_int 8)) 0)
11768 (match_dup 2)) 0))
11769 (clobber (reg:CC FLAGS_REG))])]
11770 {
11771 operands[0] = gen_lowpart (HImode, operands[0]);
11772 operands[1] = gen_lowpart (HImode, operands[1]);
11773 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11774 })
11775
11776 ;; Since AND can be encoded with sign extended immediate, this is only
11777 ;; profitable when 7th bit is not set.
11778 (define_split
11779 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11780 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11781 (match_operand:SWI248 2 "const_int_operand")))
11782 (clobber (reg:CC FLAGS_REG))]
11783 "reload_completed
11784 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11785 && !(~INTVAL (operands[2]) & ~255)
11786 && !(INTVAL (operands[2]) & 128)"
11787 [(parallel [(set (strict_low_part (match_dup 0))
11788 (and:QI (match_dup 1)
11789 (match_dup 2)))
11790 (clobber (reg:CC FLAGS_REG))])]
11791 {
11792 operands[0] = gen_lowpart (QImode, operands[0]);
11793 operands[1] = gen_lowpart (QImode, operands[1]);
11794 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11795 })
11796
11797 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11798 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11799 (and:<DWI>
11800 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11801 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11802 (clobber (reg:CC FLAGS_REG))]
11803 "TARGET_BMI"
11804 "#"
11805 "&& reload_completed"
11806 [(parallel [(set (match_dup 0)
11807 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11808 (clobber (reg:CC FLAGS_REG))])
11809 (parallel [(set (match_dup 3)
11810 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11811 (clobber (reg:CC FLAGS_REG))])]
11812 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11813
11814 (define_insn_and_split "*andn<mode>3_doubleword"
11815 [(set (match_operand:DWI 0 "register_operand")
11816 (and:DWI
11817 (not:DWI (match_operand:DWI 1 "register_operand"))
11818 (match_operand:DWI 2 "nonimmediate_operand")))
11819 (clobber (reg:CC FLAGS_REG))]
11820 "!TARGET_BMI
11821 && ix86_pre_reload_split ()"
11822 "#"
11823 "&& 1"
11824 [(set (match_dup 3) (not:DWI (match_dup 1)))
11825 (parallel [(set (match_dup 0)
11826 (and:DWI (match_dup 3) (match_dup 2)))
11827 (clobber (reg:CC FLAGS_REG))])]
11828 "operands[3] = gen_reg_rtx (<MODE>mode);")
11829
11830 (define_insn "*andn<mode>_1"
11831 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11832 (and:SWI48
11833 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11834 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11835 (clobber (reg:CC FLAGS_REG))]
11836 "TARGET_BMI
11837 || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
11838 "@
11839 andn\t{%2, %1, %0|%0, %1, %2}
11840 andn\t{%2, %1, %0|%0, %1, %2}
11841 #"
11842 [(set_attr "isa" "bmi,bmi,<kmov_isa>")
11843 (set_attr "type" "bitmanip,bitmanip,msklog")
11844 (set_attr "btver2_decode" "direct, double,*")
11845 (set_attr "mode" "<MODE>")])
11846
11847 (define_insn "*andn<mode>_1"
11848 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11849 (and:SWI12
11850 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11851 (match_operand:SWI12 2 "register_operand" "r,k")))
11852 (clobber (reg:CC FLAGS_REG))]
11853 "TARGET_BMI || TARGET_AVX512BW"
11854 "@
11855 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11856 #"
11857 [(set_attr "isa" "bmi,avx512f")
11858 (set_attr "type" "bitmanip,msklog")
11859 (set_attr "btver2_decode" "direct,*")
11860 (set (attr "mode")
11861 (cond [(eq_attr "alternative" "0")
11862 (const_string "SI")
11863 (and (eq_attr "alternative" "1")
11864 (match_test "!TARGET_AVX512DQ"))
11865 (const_string "HI")
11866 ]
11867 (const_string "<MODE>")))])
11868
11869 (define_insn "*andn_<mode>_ccno"
11870 [(set (reg FLAGS_REG)
11871 (compare
11872 (and:SWI48
11873 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11874 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11875 (const_int 0)))
11876 (clobber (match_scratch:SWI48 0 "=r,r"))]
11877 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11878 "andn\t{%2, %1, %0|%0, %1, %2}"
11879 [(set_attr "type" "bitmanip")
11880 (set_attr "btver2_decode" "direct, double")
11881 (set_attr "mode" "<MODE>")])
11882
11883 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11884 (define_split
11885 [(set (match_operand:SI 0 "register_operand")
11886 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11887 (match_operand:SI 2 "nonimmediate_operand")))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "reload_completed
11890 && optimize_insn_for_size_p () && optimize_size > 1
11891 && REGNO (operands[0]) == REGNO (operands[1])
11892 && LEGACY_INT_REG_P (operands[0])
11893 && !REX_INT_REG_P (operands[2])
11894 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11895 [(set (match_dup 0) (not:SI (match_dup 1)))
11896 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11897 (clobber (reg:CC FLAGS_REG))])])
11898
11899 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11900 (define_split
11901 [(set (match_operand 0 "flags_reg_operand")
11902 (match_operator 1 "compare_operator"
11903 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11904 (match_operand:SI 3 "nonimmediate_operand"))
11905 (const_int 0)]))
11906 (clobber (match_dup 2))]
11907 "reload_completed
11908 && optimize_insn_for_size_p () && optimize_size > 1
11909 && LEGACY_INT_REG_P (operands[2])
11910 && !REX_INT_REG_P (operands[3])
11911 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11912 [(set (match_dup 2) (not:SI (match_dup 2)))
11913 (set (match_dup 0) (match_op_dup 1
11914 [(and:SI (match_dup 3) (match_dup 2))
11915 (const_int 0)]))])
11916
11917 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11918 (define_split
11919 [(set (match_operand:SWI48 0 "register_operand")
11920 (xor:SWI48
11921 (xor:SWI48
11922 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11923 (match_operand:SWI48 2 "nonimmediate_operand"))
11924 (match_dup 1))
11925 (match_operand:SWI48 3 "nonimmediate_operand")))
11926 (clobber (reg:CC FLAGS_REG))]
11927 "TARGET_BMI"
11928 [(parallel
11929 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11930 (clobber (reg:CC FLAGS_REG))])
11931 (parallel
11932 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11933 (clobber (reg:CC FLAGS_REG))])]
11934 "operands[4] = gen_reg_rtx (<MODE>mode);")
11935
11936 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11937 (define_split
11938 [(set (match_operand:SWI48 0 "register_operand")
11939 (xor:SWI48
11940 (xor:SWI48
11941 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11942 (match_operand:SWI48 2 "register_operand"))
11943 (match_dup 2))
11944 (match_operand:SWI48 3 "nonimmediate_operand")))
11945 (clobber (reg:CC FLAGS_REG))]
11946 "TARGET_BMI"
11947 [(parallel
11948 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11949 (clobber (reg:CC FLAGS_REG))])
11950 (parallel
11951 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11952 (clobber (reg:CC FLAGS_REG))])]
11953 "operands[4] = gen_reg_rtx (<MODE>mode);")
11954
11955 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11956 (define_split
11957 [(set (match_operand:SWI48 0 "register_operand")
11958 (xor:SWI48
11959 (xor:SWI48
11960 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11961 (match_operand:SWI48 2 "nonimmediate_operand"))
11962 (match_operand:SWI48 3 "nonimmediate_operand"))
11963 (match_dup 1)))
11964 (clobber (reg:CC FLAGS_REG))]
11965 "TARGET_BMI"
11966 [(parallel
11967 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11968 (clobber (reg:CC FLAGS_REG))])
11969 (parallel
11970 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11971 (clobber (reg:CC FLAGS_REG))])]
11972 "operands[4] = gen_reg_rtx (<MODE>mode);")
11973
11974 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11975 (define_split
11976 [(set (match_operand:SWI48 0 "register_operand")
11977 (xor:SWI48
11978 (xor:SWI48
11979 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11980 (match_operand:SWI48 2 "register_operand"))
11981 (match_operand:SWI48 3 "nonimmediate_operand"))
11982 (match_dup 2)))
11983 (clobber (reg:CC FLAGS_REG))]
11984 "TARGET_BMI"
11985 [(parallel
11986 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11987 (clobber (reg:CC FLAGS_REG))])
11988 (parallel
11989 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11990 (clobber (reg:CC FLAGS_REG))])]
11991 "operands[4] = gen_reg_rtx (<MODE>mode);")
11992 \f
11993 ;; Logical inclusive and exclusive OR instructions
11994
11995 ;; %%% This used to optimize known byte-wide and operations to memory.
11996 ;; If this is considered useful, it should be done with splitters.
11997
11998 (define_expand "<code><mode>3"
11999 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12000 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12001 (match_operand:SDWIM 2 "<general_operand>")))]
12002 ""
12003 {
12004 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12005 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12006 operands[2] = force_reg (<MODE>mode, operands[2]);
12007
12008 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
12009 DONE;
12010 })
12011
12012 (define_insn_and_split "*<code><dwi>3_doubleword"
12013 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12014 (any_or:<DWI>
12015 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
12016 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
12017 (clobber (reg:CC FLAGS_REG))]
12018 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
12019 "#"
12020 "&& reload_completed"
12021 [(const_int:DWIH 0)]
12022 {
12023 /* This insn may disappear completely when operands[2] == const0_rtx
12024 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
12025 bool emit_insn_deleted_note_p = false;
12026
12027 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12028
12029 if (operands[2] == const0_rtx)
12030 emit_insn_deleted_note_p = true;
12031 else if (operands[2] == constm1_rtx)
12032 {
12033 if (<CODE> == IOR)
12034 emit_move_insn (operands[0], constm1_rtx);
12035 else
12036 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
12037 }
12038 else
12039 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
12040
12041 if (operands[5] == const0_rtx)
12042 {
12043 if (emit_insn_deleted_note_p)
12044 emit_note (NOTE_INSN_DELETED);
12045 }
12046 else if (operands[5] == constm1_rtx)
12047 {
12048 if (<CODE> == IOR)
12049 emit_move_insn (operands[3], constm1_rtx);
12050 else
12051 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
12052 }
12053 else
12054 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
12055
12056 DONE;
12057 })
12058
12059 (define_insn "*<code><mode>_1"
12060 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12061 (any_or:SWI248
12062 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12063 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
12064 (clobber (reg:CC FLAGS_REG))]
12065 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12066 "@
12067 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12068 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12069 #"
12070 [(set_attr "isa" "*,*,<kmov_isa>")
12071 (set_attr "type" "alu, alu, msklog")
12072 (set_attr "mode" "<MODE>")])
12073
12074 (define_insn_and_split "*notxor<mode>_1"
12075 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12076 (not:SWI248
12077 (xor:SWI248
12078 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12079 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
12080 (clobber (reg:CC FLAGS_REG))]
12081 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
12082 "#"
12083 "&& reload_completed"
12084 [(parallel
12085 [(set (match_dup 0)
12086 (xor:SWI248 (match_dup 1) (match_dup 2)))
12087 (clobber (reg:CC FLAGS_REG))])
12088 (set (match_dup 0)
12089 (not:SWI248 (match_dup 0)))]
12090 {
12091 if (MASK_REG_P (operands[0]))
12092 {
12093 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12094 DONE;
12095 }
12096 }
12097 [(set_attr "isa" "*,*,<kmov_isa>")
12098 (set_attr "type" "alu, alu, msklog")
12099 (set_attr "mode" "<MODE>")])
12100
12101 (define_insn_and_split "*iordi_1_bts"
12102 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12103 (ior:DI
12104 (match_operand:DI 1 "nonimmediate_operand" "%0")
12105 (match_operand:DI 2 "const_int_operand" "n")))
12106 (clobber (reg:CC FLAGS_REG))]
12107 "TARGET_64BIT && TARGET_USE_BT
12108 && ix86_binary_operator_ok (IOR, DImode, operands)
12109 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12110 "#"
12111 "&& reload_completed"
12112 [(parallel [(set (zero_extract:DI (match_dup 0)
12113 (const_int 1)
12114 (match_dup 3))
12115 (const_int 1))
12116 (clobber (reg:CC FLAGS_REG))])]
12117 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12118 [(set_attr "type" "alu1")
12119 (set_attr "prefix_0f" "1")
12120 (set_attr "znver1_decode" "double")
12121 (set_attr "mode" "DI")])
12122
12123 (define_insn_and_split "*xordi_1_btc"
12124 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12125 (xor:DI
12126 (match_operand:DI 1 "nonimmediate_operand" "%0")
12127 (match_operand:DI 2 "const_int_operand" "n")))
12128 (clobber (reg:CC FLAGS_REG))]
12129 "TARGET_64BIT && TARGET_USE_BT
12130 && ix86_binary_operator_ok (XOR, DImode, operands)
12131 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12132 "#"
12133 "&& reload_completed"
12134 [(parallel [(set (zero_extract:DI (match_dup 0)
12135 (const_int 1)
12136 (match_dup 3))
12137 (not:DI (zero_extract:DI (match_dup 0)
12138 (const_int 1)
12139 (match_dup 3))))
12140 (clobber (reg:CC FLAGS_REG))])]
12141 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12142 [(set_attr "type" "alu1")
12143 (set_attr "prefix_0f" "1")
12144 (set_attr "znver1_decode" "double")
12145 (set_attr "mode" "DI")])
12146
12147 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12148 (define_insn_and_split "*xor2andn"
12149 [(set (match_operand:SWI248 0 "register_operand")
12150 (xor:SWI248
12151 (and:SWI248
12152 (xor:SWI248
12153 (match_operand:SWI248 1 "nonimmediate_operand")
12154 (match_operand:SWI248 2 "nonimmediate_operand"))
12155 (match_operand:SWI248 3 "nonimmediate_operand"))
12156 (match_dup 1)))
12157 (clobber (reg:CC FLAGS_REG))]
12158 "TARGET_BMI && ix86_pre_reload_split ()"
12159 "#"
12160 "&& 1"
12161 [(parallel [(set (match_dup 4)
12162 (and:SWI248
12163 (not:SWI248
12164 (match_dup 3))
12165 (match_dup 1)))
12166 (clobber (reg:CC FLAGS_REG))])
12167 (parallel [(set (match_dup 5)
12168 (and:SWI248
12169 (match_dup 3)
12170 (match_dup 2)))
12171 (clobber (reg:CC FLAGS_REG))])
12172 (parallel [(set (match_dup 0)
12173 (ior:SWI248
12174 (match_dup 4)
12175 (match_dup 5)))
12176 (clobber (reg:CC FLAGS_REG))])]
12177 {
12178 operands[1] = force_reg (<MODE>mode, operands[1]);
12179 operands[3] = force_reg (<MODE>mode, operands[3]);
12180 operands[4] = gen_reg_rtx (<MODE>mode);
12181 operands[5] = gen_reg_rtx (<MODE>mode);
12182 })
12183
12184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12185 (define_insn "*<code>si_1_zext"
12186 [(set (match_operand:DI 0 "register_operand" "=r")
12187 (zero_extend:DI
12188 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12189 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12190 (clobber (reg:CC FLAGS_REG))]
12191 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12192 "<logic>{l}\t{%2, %k0|%k0, %2}"
12193 [(set_attr "type" "alu")
12194 (set_attr "mode" "SI")])
12195
12196 (define_insn "*<code>si_1_zext_imm"
12197 [(set (match_operand:DI 0 "register_operand" "=r")
12198 (any_or:DI
12199 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12200 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12201 (clobber (reg:CC FLAGS_REG))]
12202 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12203 "<logic>{l}\t{%2, %k0|%k0, %2}"
12204 [(set_attr "type" "alu")
12205 (set_attr "mode" "SI")])
12206
12207 (define_insn "*<code>qi_1"
12208 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12209 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12210 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12211 (clobber (reg:CC FLAGS_REG))]
12212 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12213 "@
12214 <logic>{b}\t{%2, %0|%0, %2}
12215 <logic>{b}\t{%2, %0|%0, %2}
12216 <logic>{l}\t{%k2, %k0|%k0, %k2}
12217 #"
12218 [(set_attr "isa" "*,*,*,avx512f")
12219 (set_attr "type" "alu,alu,alu,msklog")
12220 (set (attr "mode")
12221 (cond [(eq_attr "alternative" "2")
12222 (const_string "SI")
12223 (and (eq_attr "alternative" "3")
12224 (match_test "!TARGET_AVX512DQ"))
12225 (const_string "HI")
12226 ]
12227 (const_string "QI")))
12228 ;; Potential partial reg stall on alternative 2.
12229 (set (attr "preferred_for_speed")
12230 (cond [(eq_attr "alternative" "2")
12231 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12232 (symbol_ref "true")))])
12233
12234 (define_insn_and_split "*notxorqi_1"
12235 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12236 (not:QI
12237 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12238 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12239 (clobber (reg:CC FLAGS_REG))]
12240 "ix86_binary_operator_ok (XOR, QImode, operands)"
12241 "#"
12242 "&& reload_completed"
12243 [(parallel
12244 [(set (match_dup 0)
12245 (xor:QI (match_dup 1) (match_dup 2)))
12246 (clobber (reg:CC FLAGS_REG))])
12247 (set (match_dup 0)
12248 (not:QI (match_dup 0)))]
12249 {
12250 if (mask_reg_operand (operands[0], QImode))
12251 {
12252 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12253 DONE;
12254 }
12255 }
12256 [(set_attr "isa" "*,*,*,avx512f")
12257 (set_attr "type" "alu,alu,alu,msklog")
12258 (set (attr "mode")
12259 (cond [(eq_attr "alternative" "2")
12260 (const_string "SI")
12261 (and (eq_attr "alternative" "3")
12262 (match_test "!TARGET_AVX512DQ"))
12263 (const_string "HI")
12264 ]
12265 (const_string "QI")))
12266 ;; Potential partial reg stall on alternative 2.
12267 (set (attr "preferred_for_speed")
12268 (cond [(eq_attr "alternative" "2")
12269 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12270 (symbol_ref "true")))])
12271
12272 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12273 (define_insn_and_split "*<code><mode>_1_slp"
12274 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12275 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12276 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12277 (clobber (reg:CC FLAGS_REG))]
12278 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12279 "@
12280 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12281 #"
12282 "&& reload_completed"
12283 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12284 (parallel
12285 [(set (strict_low_part (match_dup 0))
12286 (any_or:SWI12 (match_dup 0) (match_dup 2)))
12287 (clobber (reg:CC FLAGS_REG))])]
12288 ""
12289 [(set_attr "type" "alu")
12290 (set_attr "mode" "<MODE>")])
12291
12292 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12293 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12294 ;; This eliminates sign extension after logic operation.
12295
12296 (define_split
12297 [(set (match_operand:SWI248 0 "register_operand")
12298 (sign_extend:SWI248
12299 (any_logic:QI (match_operand:QI 1 "memory_operand")
12300 (match_operand:QI 2 "const_int_operand"))))]
12301 ""
12302 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12303 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12304 "operands[3] = gen_reg_rtx (<MODE>mode);")
12305
12306 (define_split
12307 [(set (match_operand:SWI48 0 "register_operand")
12308 (sign_extend:SWI48
12309 (any_logic:HI (match_operand:HI 1 "memory_operand")
12310 (match_operand:HI 2 "const_int_operand"))))]
12311 ""
12312 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12313 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12314 "operands[3] = gen_reg_rtx (<MODE>mode);")
12315
12316 (define_split
12317 [(set (match_operand:DI 0 "register_operand")
12318 (sign_extend:DI
12319 (any_logic:SI (match_operand:SI 1 "memory_operand")
12320 (match_operand:SI 2 "const_int_operand"))))]
12321 "TARGET_64BIT"
12322 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12323 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12324 "operands[3] = gen_reg_rtx (DImode);")
12325
12326 (define_insn "*<code><mode>_2"
12327 [(set (reg FLAGS_REG)
12328 (compare (any_or:SWI
12329 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12330 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12331 (const_int 0)))
12332 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12333 (any_or:SWI (match_dup 1) (match_dup 2)))]
12334 "ix86_match_ccmode (insn, CCNOmode)
12335 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12336 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12337 [(set_attr "type" "alu")
12338 (set_attr "mode" "<MODE>")])
12339
12340 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12341 ;; ??? Special case for immediate operand is missing - it is tricky.
12342 (define_insn "*<code>si_2_zext"
12343 [(set (reg FLAGS_REG)
12344 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12345 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12346 (const_int 0)))
12347 (set (match_operand:DI 0 "register_operand" "=r")
12348 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12349 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12350 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12351 "<logic>{l}\t{%2, %k0|%k0, %2}"
12352 [(set_attr "type" "alu")
12353 (set_attr "mode" "SI")])
12354
12355 (define_insn "*<code>si_2_zext_imm"
12356 [(set (reg FLAGS_REG)
12357 (compare (any_or:SI
12358 (match_operand:SI 1 "nonimmediate_operand" "%0")
12359 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12360 (const_int 0)))
12361 (set (match_operand:DI 0 "register_operand" "=r")
12362 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12363 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12364 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12365 "<logic>{l}\t{%2, %k0|%k0, %2}"
12366 [(set_attr "type" "alu")
12367 (set_attr "mode" "SI")])
12368
12369 (define_insn "*<code><mode>_3"
12370 [(set (reg FLAGS_REG)
12371 (compare (any_or:SWI
12372 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12373 (match_operand:SWI 2 "<general_operand>" "<g>"))
12374 (const_int 0)))
12375 (clobber (match_scratch:SWI 0 "=<r>"))]
12376 "ix86_match_ccmode (insn, CCNOmode)
12377 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12378 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12379 [(set_attr "type" "alu")
12380 (set_attr "mode" "<MODE>")])
12381
12382 (define_insn "*<code>qi_ext<mode>_0"
12383 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
12384 (any_or:QI
12385 (subreg:QI
12386 (match_operator:SWI248 3 "extract_operator"
12387 [(match_operand 2 "int248_register_operand" "Q,Q")
12388 (const_int 8)
12389 (const_int 8)]) 0)
12390 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
12391 (clobber (reg:CC FLAGS_REG))]
12392 ""
12393 "<logic>{b}\t{%h2, %0|%0, %h2}"
12394 [(set_attr "isa" "*,nox64")
12395 (set_attr "type" "alu")
12396 (set_attr "mode" "QI")])
12397
12398 (define_insn "*<code>qi_ext<mode>_1"
12399 [(set (zero_extract:SWI248
12400 (match_operand 0 "int248_register_operand" "+Q,Q")
12401 (const_int 8)
12402 (const_int 8))
12403 (subreg:SWI248
12404 (any_or:QI
12405 (subreg:QI
12406 (match_operator:SWI248 3 "extract_operator"
12407 [(match_operand 1 "int248_register_operand" "0,0")
12408 (const_int 8)
12409 (const_int 8)]) 0)
12410 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12413 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12414 && rtx_equal_p (operands[0], operands[1])"
12415 "<logic>{b}\t{%2, %h0|%h0, %2}"
12416 [(set_attr "isa" "*,nox64")
12417 (set_attr "type" "alu")
12418 (set_attr "mode" "QI")])
12419
12420 (define_insn "*<code>qi_ext<mode>_2"
12421 [(set (zero_extract:SWI248
12422 (match_operand 0 "int248_register_operand" "+Q")
12423 (const_int 8)
12424 (const_int 8))
12425 (subreg:SWI248
12426 (any_or:QI
12427 (subreg:QI
12428 (match_operator:SWI248 3 "extract_operator"
12429 [(match_operand 1 "int248_register_operand" "%0")
12430 (const_int 8)
12431 (const_int 8)]) 0)
12432 (subreg:QI
12433 (match_operator:SWI248 4 "extract_operator"
12434 [(match_operand 2 "int248_register_operand" "Q")
12435 (const_int 8)
12436 (const_int 8)]) 0)) 0))
12437 (clobber (reg:CC FLAGS_REG))]
12438 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12439 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12440 && (rtx_equal_p (operands[0], operands[1])
12441 || rtx_equal_p (operands[0], operands[2]))"
12442 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12443 [(set_attr "type" "alu")
12444 (set_attr "mode" "QI")])
12445
12446 (define_insn "*<code>qi_ext<mode>_3"
12447 [(set (zero_extract:SWI248
12448 (match_operand 0 "int248_register_operand" "+Q")
12449 (const_int 8)
12450 (const_int 8))
12451 (zero_extract:SWI248
12452 (any_logic:SWI248
12453 (match_operand 1 "int248_register_operand" "%0")
12454 (match_operand 2 "int248_register_operand" "Q"))
12455 (const_int 8)
12456 (const_int 8)))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12459 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12460 && (rtx_equal_p (operands[0], operands[1])
12461 || rtx_equal_p (operands[0], operands[2]))"
12462 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12463 [(set_attr "type" "alu")
12464 (set_attr "mode" "QI")])
12465
12466 ;; Convert wide OR instructions with immediate operand to shorter QImode
12467 ;; equivalents when possible.
12468 ;; Don't do the splitting with memory operands, since it introduces risk
12469 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12470 ;; for size, but that can (should?) be handled by generic code instead.
12471 (define_split
12472 [(set (match_operand:SWI248 0 "QIreg_operand")
12473 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12474 (match_operand:SWI248 2 "const_int_operand")))
12475 (clobber (reg:CC FLAGS_REG))]
12476 "reload_completed
12477 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12478 && !(INTVAL (operands[2]) & ~(255 << 8))"
12479 [(parallel
12480 [(set (zero_extract:HI (match_dup 0)
12481 (const_int 8)
12482 (const_int 8))
12483 (subreg:HI
12484 (any_or:QI
12485 (subreg:QI
12486 (zero_extract:HI (match_dup 1)
12487 (const_int 8)
12488 (const_int 8)) 0)
12489 (match_dup 2)) 0))
12490 (clobber (reg:CC FLAGS_REG))])]
12491 {
12492 /* Handle the case where INTVAL (operands[2]) == 0. */
12493 if (operands[2] == const0_rtx)
12494 {
12495 if (!rtx_equal_p (operands[0], operands[1]))
12496 emit_move_insn (operands[0], operands[1]);
12497 else
12498 emit_note (NOTE_INSN_DELETED);
12499 DONE;
12500 }
12501 operands[0] = gen_lowpart (HImode, operands[0]);
12502 operands[1] = gen_lowpart (HImode, operands[1]);
12503 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12504 })
12505
12506 ;; Since OR can be encoded with sign extended immediate, this is only
12507 ;; profitable when 7th bit is set.
12508 (define_split
12509 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12510 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12511 (match_operand:SWI248 2 "const_int_operand")))
12512 (clobber (reg:CC FLAGS_REG))]
12513 "reload_completed
12514 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12515 && !(INTVAL (operands[2]) & ~255)
12516 && (INTVAL (operands[2]) & 128)"
12517 [(parallel [(set (strict_low_part (match_dup 0))
12518 (any_or:QI (match_dup 1)
12519 (match_dup 2)))
12520 (clobber (reg:CC FLAGS_REG))])]
12521 {
12522 operands[0] = gen_lowpart (QImode, operands[0]);
12523 operands[1] = gen_lowpart (QImode, operands[1]);
12524 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12525 })
12526
12527 (define_expand "xorqi_ext_1_cc"
12528 [(parallel
12529 [(set (reg:CCNO FLAGS_REG)
12530 (compare:CCNO
12531 (xor:QI
12532 (subreg:QI
12533 (zero_extract:HI (match_operand:HI 1 "register_operand")
12534 (const_int 8)
12535 (const_int 8)) 0)
12536 (match_operand:QI 2 "const_int_operand"))
12537 (const_int 0)))
12538 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12539 (const_int 8)
12540 (const_int 8))
12541 (subreg:HI
12542 (xor:QI
12543 (subreg:QI
12544 (zero_extract:HI (match_dup 1)
12545 (const_int 8)
12546 (const_int 8)) 0)
12547 (match_dup 2)) 0))])])
12548
12549 (define_insn "*xorqi_ext<mode>_1_cc"
12550 [(set (reg FLAGS_REG)
12551 (compare
12552 (xor:QI
12553 (subreg:QI
12554 (match_operator:SWI248 3 "extract_operator"
12555 [(match_operand 1 "int248_register_operand" "0,0")
12556 (const_int 8)
12557 (const_int 8)]) 0)
12558 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
12559 (const_int 0)))
12560 (set (zero_extract:SWI248
12561 (match_operand 0 "int248_register_operand" "+Q,Q")
12562 (const_int 8)
12563 (const_int 8))
12564 (subreg:SWI248
12565 (xor:QI
12566 (subreg:QI
12567 (match_op_dup 3
12568 [(match_dup 1)
12569 (const_int 8)
12570 (const_int 8)]) 0)
12571 (match_dup 2)) 0))]
12572 "ix86_match_ccmode (insn, CCNOmode)
12573 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12574 && rtx_equal_p (operands[0], operands[1])"
12575 "xor{b}\t{%2, %h0|%h0, %2}"
12576 [(set_attr "isa" "*,nox64")
12577 (set_attr "type" "alu")
12578 (set_attr "mode" "QI")])
12579
12580 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12581 (define_peephole2
12582 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12583 (const_int 0))
12584 (clobber (reg:CC FLAGS_REG))])
12585 (parallel [(set (match_dup 0)
12586 (any_or_plus:SWI (match_dup 0)
12587 (match_operand:SWI 1 "<general_operand>")))
12588 (clobber (reg:CC FLAGS_REG))])]
12589 "!reg_mentioned_p (operands[0], operands[1])"
12590 [(set (match_dup 0) (match_dup 1))])
12591
12592 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
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) (match_dup 0)))
12599 (clobber (reg:CC FLAGS_REG))])]
12600 ""
12601 [(parallel [(set (match_dup 0) (const_int 0))
12602 (clobber (reg:CC FLAGS_REG))])])
12603
12604 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12605 (define_insn_and_split "*concat<mode><dwi>3_1"
12606 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12607 (any_or_plus:<DWI>
12608 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12609 (match_operand:QI 2 "const_int_operand"))
12610 (zero_extend:<DWI>
12611 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12612 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12613 "#"
12614 "&& reload_completed"
12615 [(const_int 0)]
12616 {
12617 split_double_concat (<DWI>mode, operands[0], operands[3],
12618 gen_lowpart (<MODE>mode, operands[1]));
12619 DONE;
12620 })
12621
12622 (define_insn_and_split "*concat<mode><dwi>3_2"
12623 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12624 (any_or_plus:<DWI>
12625 (zero_extend:<DWI>
12626 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12627 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12628 (match_operand:QI 3 "const_int_operand"))))]
12629 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12630 "#"
12631 "&& reload_completed"
12632 [(const_int 0)]
12633 {
12634 split_double_concat (<DWI>mode, operands[0], operands[1],
12635 gen_lowpart (<MODE>mode, operands[2]));
12636 DONE;
12637 })
12638
12639 (define_insn_and_split "*concat<mode><dwi>3_3"
12640 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12641 (any_or_plus:<DWI>
12642 (ashift:<DWI>
12643 (zero_extend:<DWI>
12644 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12645 (match_operand:QI 2 "const_int_operand"))
12646 (zero_extend:<DWI>
12647 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12648 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12649 "#"
12650 "&& reload_completed"
12651 [(const_int 0)]
12652 {
12653 if (SSE_REG_P (operands[0]))
12654 {
12655 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12656 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12657 }
12658 else
12659 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12660 DONE;
12661 }
12662 [(set_attr "isa" "*,*,*,x64,x64")])
12663
12664 (define_insn_and_split "*concat<mode><dwi>3_4"
12665 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12666 (any_or_plus:<DWI>
12667 (zero_extend:<DWI>
12668 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12669 (ashift:<DWI>
12670 (zero_extend:<DWI>
12671 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12672 (match_operand:QI 3 "const_int_operand"))))]
12673 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12674 "#"
12675 "&& reload_completed"
12676 [(const_int 0)]
12677 {
12678 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12679 DONE;
12680 }
12681 [(set_attr "isa" "*,*,*,x64")])
12682
12683 (define_insn_and_split "*concat<half><mode>3_5"
12684 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12685 (any_or_plus:DWI
12686 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12687 (match_operand:QI 2 "const_int_operand"))
12688 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12689 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12690 && (<MODE>mode == DImode
12691 ? CONST_INT_P (operands[3])
12692 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12693 : CONST_INT_P (operands[3])
12694 ? INTVAL (operands[3]) >= 0
12695 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12696 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12697 && !(CONST_INT_P (operands[3])
12698 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12699 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12700 0)),
12701 VOIDmode))"
12702 "#"
12703 "&& reload_completed"
12704 [(const_int 0)]
12705 {
12706 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12707 split_double_concat (<MODE>mode, operands[0], op3,
12708 gen_lowpart (<HALF>mode, operands[1]));
12709 DONE;
12710 }
12711 [(set_attr "isa" "*,nox64,x64")])
12712
12713 (define_insn_and_split "*concat<mode><dwi>3_6"
12714 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12715 (any_or_plus:<DWI>
12716 (ashift:<DWI>
12717 (zero_extend:<DWI>
12718 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12719 (match_operand:QI 2 "const_int_operand"))
12720 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12721 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12722 && (<DWI>mode == DImode
12723 ? CONST_INT_P (operands[3])
12724 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12725 : CONST_INT_P (operands[3])
12726 ? INTVAL (operands[3]) >= 0
12727 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12728 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12729 && !(CONST_INT_P (operands[3])
12730 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12731 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12732 0)),
12733 VOIDmode))"
12734 "#"
12735 "&& reload_completed"
12736 [(const_int 0)]
12737 {
12738 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12739 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12740 DONE;
12741 }
12742 [(set_attr "isa" "*,nox64,x64,*")])
12743
12744 (define_insn_and_split "*concat<mode><dwi>3_7"
12745 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12746 (any_or_plus:<DWI>
12747 (zero_extend:<DWI>
12748 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12749 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12750 "<DWI>mode == DImode
12751 ? CONST_INT_P (operands[2])
12752 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12753 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12754 : CONST_WIDE_INT_P (operands[2])
12755 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12756 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12757 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12758 1)),
12759 VOIDmode)"
12760 "#"
12761 "&& reload_completed"
12762 [(const_int 0)]
12763 {
12764 rtx op2;
12765 if (<DWI>mode == DImode)
12766 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12767 else
12768 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12769 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12770 DONE;
12771 }
12772 [(set_attr "isa" "*,nox64,x64,*")])
12773 \f
12774 ;; Negation instructions
12775
12776 (define_expand "neg<mode>2"
12777 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12778 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12779 ""
12780 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12781
12782 (define_insn_and_split "*neg<dwi>2_doubleword"
12783 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12784 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12785 (clobber (reg:CC FLAGS_REG))]
12786 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12787 "#"
12788 "&& reload_completed"
12789 [(parallel
12790 [(set (reg:CCC FLAGS_REG)
12791 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12792 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12793 (parallel
12794 [(set (match_dup 2)
12795 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12796 (match_dup 3))
12797 (const_int 0)))
12798 (clobber (reg:CC FLAGS_REG))])
12799 (parallel
12800 [(set (match_dup 2)
12801 (neg:DWIH (match_dup 2)))
12802 (clobber (reg:CC FLAGS_REG))])]
12803 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12804
12805 ;; Convert:
12806 ;; mov %esi, %edx
12807 ;; negl %eax
12808 ;; adcl $0, %edx
12809 ;; negl %edx
12810 ;; to:
12811 ;; xorl %edx, %edx
12812 ;; negl %eax
12813 ;; sbbl %esi, %edx
12814
12815 (define_peephole2
12816 [(set (match_operand:SWI48 0 "general_reg_operand")
12817 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12818 (parallel
12819 [(set (reg:CCC FLAGS_REG)
12820 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12821 (const_int 0)] UNSPEC_CC_NE))
12822 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12823 (parallel
12824 [(set (match_dup 0)
12825 (plus:SWI48 (plus:SWI48
12826 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12827 (match_dup 0))
12828 (const_int 0)))
12829 (clobber (reg:CC FLAGS_REG))])
12830 (parallel
12831 [(set (match_dup 0)
12832 (neg:SWI48 (match_dup 0)))
12833 (clobber (reg:CC FLAGS_REG))])]
12834 "REGNO (operands[0]) != REGNO (operands[2])
12835 && !reg_mentioned_p (operands[0], operands[1])
12836 && !reg_mentioned_p (operands[2], operands[1])"
12837 [(parallel
12838 [(set (reg:CCC FLAGS_REG)
12839 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12840 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12841 (parallel
12842 [(set (match_dup 0)
12843 (minus:SWI48 (minus:SWI48
12844 (match_dup 0)
12845 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12846 (match_dup 1)))
12847 (clobber (reg:CC FLAGS_REG))])]
12848 "ix86_expand_clear (operands[0]);")
12849
12850 ;; Convert:
12851 ;; xorl %edx, %edx
12852 ;; negl %eax
12853 ;; adcl $0, %edx
12854 ;; negl %edx
12855 ;; to:
12856 ;; negl %eax
12857 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12858
12859 (define_peephole2
12860 [(parallel
12861 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12862 (clobber (reg:CC FLAGS_REG))])
12863 (parallel
12864 [(set (reg:CCC FLAGS_REG)
12865 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12866 (const_int 0)] UNSPEC_CC_NE))
12867 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12868 (parallel
12869 [(set (match_dup 0)
12870 (plus:SWI48 (plus:SWI48
12871 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12872 (match_dup 0))
12873 (const_int 0)))
12874 (clobber (reg:CC FLAGS_REG))])
12875 (parallel
12876 [(set (match_dup 0)
12877 (neg:SWI48 (match_dup 0)))
12878 (clobber (reg:CC FLAGS_REG))])]
12879 "REGNO (operands[0]) != REGNO (operands[1])"
12880 [(parallel
12881 [(set (reg:CCC FLAGS_REG)
12882 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12883 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12884 (parallel
12885 [(set (match_dup 0)
12886 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12887 (const_int -1)
12888 (const_int 0)))
12889 (clobber (reg:CC FLAGS_REG))])])
12890
12891 (define_insn "*neg<mode>_1"
12892 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12893 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12896 "neg{<imodesuffix>}\t%0"
12897 [(set_attr "type" "negnot")
12898 (set_attr "mode" "<MODE>")])
12899
12900 (define_insn "*negsi_1_zext"
12901 [(set (match_operand:DI 0 "register_operand" "=r")
12902 (zero_extend:DI
12903 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12904 (clobber (reg:CC FLAGS_REG))]
12905 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12906 "neg{l}\t%k0"
12907 [(set_attr "type" "negnot")
12908 (set_attr "mode" "SI")])
12909
12910 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12911 (define_insn_and_split "*neg<mode>_1_slp"
12912 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12913 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12914 (clobber (reg:CC FLAGS_REG))]
12915 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12916 "@
12917 neg{<imodesuffix>}\t%0
12918 #"
12919 "&& reload_completed"
12920 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12921 (parallel
12922 [(set (strict_low_part (match_dup 0))
12923 (neg:SWI12 (match_dup 0)))
12924 (clobber (reg:CC FLAGS_REG))])]
12925 ""
12926 [(set_attr "type" "negnot")
12927 (set_attr "mode" "<MODE>")])
12928
12929 (define_insn "*neg<mode>_2"
12930 [(set (reg FLAGS_REG)
12931 (compare
12932 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12933 (const_int 0)))
12934 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12935 (neg:SWI (match_dup 1)))]
12936 "ix86_match_ccmode (insn, CCGOCmode)
12937 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12938 "neg{<imodesuffix>}\t%0"
12939 [(set_attr "type" "negnot")
12940 (set_attr "mode" "<MODE>")])
12941
12942 (define_insn "*negsi_2_zext"
12943 [(set (reg FLAGS_REG)
12944 (compare
12945 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12946 (const_int 0)))
12947 (set (match_operand:DI 0 "register_operand" "=r")
12948 (zero_extend:DI
12949 (neg:SI (match_dup 1))))]
12950 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12951 && ix86_unary_operator_ok (NEG, SImode, operands)"
12952 "neg{l}\t%k0"
12953 [(set_attr "type" "negnot")
12954 (set_attr "mode" "SI")])
12955
12956 (define_insn "*neg<mode>_ccc_1"
12957 [(set (reg:CCC FLAGS_REG)
12958 (unspec:CCC
12959 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12960 (const_int 0)] UNSPEC_CC_NE))
12961 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12962 (neg:SWI (match_dup 1)))]
12963 ""
12964 "neg{<imodesuffix>}\t%0"
12965 [(set_attr "type" "negnot")
12966 (set_attr "mode" "<MODE>")])
12967
12968 (define_insn "*neg<mode>_ccc_2"
12969 [(set (reg:CCC FLAGS_REG)
12970 (unspec:CCC
12971 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12972 (const_int 0)] UNSPEC_CC_NE))
12973 (clobber (match_scratch:SWI 0 "=<r>"))]
12974 ""
12975 "neg{<imodesuffix>}\t%0"
12976 [(set_attr "type" "negnot")
12977 (set_attr "mode" "<MODE>")])
12978
12979 (define_expand "x86_neg<mode>_ccc"
12980 [(parallel
12981 [(set (reg:CCC FLAGS_REG)
12982 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12983 (const_int 0)] UNSPEC_CC_NE))
12984 (set (match_operand:SWI48 0 "register_operand")
12985 (neg:SWI48 (match_dup 1)))])])
12986
12987 (define_insn "*negqi_ext<mode>_2"
12988 [(set (zero_extract:SWI248
12989 (match_operand 0 "int248_register_operand" "+Q")
12990 (const_int 8)
12991 (const_int 8))
12992 (subreg:SWI248
12993 (neg:QI
12994 (subreg:QI
12995 (match_operator:SWI248 2 "extract_operator"
12996 [(match_operand 1 "int248_register_operand" "0")
12997 (const_int 8)
12998 (const_int 8)]) 0)) 0))
12999 (clobber (reg:CC FLAGS_REG))]
13000 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
13001 rtx_equal_p (operands[0], operands[1])"
13002 "neg{b}\t%h0"
13003 [(set_attr "type" "negnot")
13004 (set_attr "mode" "QI")])
13005
13006 ;; Negate with jump on overflow.
13007 (define_expand "negv<mode>3"
13008 [(parallel [(set (reg:CCO FLAGS_REG)
13009 (unspec:CCO
13010 [(match_operand:SWI 1 "register_operand")
13011 (match_dup 3)] UNSPEC_CC_NE))
13012 (set (match_operand:SWI 0 "register_operand")
13013 (neg:SWI (match_dup 1)))])
13014 (set (pc) (if_then_else
13015 (eq (reg:CCO FLAGS_REG) (const_int 0))
13016 (label_ref (match_operand 2))
13017 (pc)))]
13018 ""
13019 {
13020 operands[3]
13021 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
13022 <MODE>mode);
13023 })
13024
13025 (define_insn "*negv<mode>3"
13026 [(set (reg:CCO FLAGS_REG)
13027 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
13028 (match_operand:SWI 2 "const_int_operand")]
13029 UNSPEC_CC_NE))
13030 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13031 (neg:SWI (match_dup 1)))]
13032 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
13033 && mode_signbit_p (<MODE>mode, operands[2])"
13034 "neg{<imodesuffix>}\t%0"
13035 [(set_attr "type" "negnot")
13036 (set_attr "mode" "<MODE>")])
13037
13038 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
13039 (define_peephole2
13040 [(set (match_operand:SWI 0 "general_reg_operand")
13041 (match_operand:SWI 1 "general_reg_operand"))
13042 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
13043 (clobber (reg:CC FLAGS_REG))])
13044 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
13045 ""
13046 [(set (match_dup 0) (match_dup 1))
13047 (parallel [(set (reg:CCZ FLAGS_REG)
13048 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
13049 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
13050
13051 ;; Special expand pattern to handle integer mode abs
13052
13053 (define_expand "abs<mode>2"
13054 [(parallel
13055 [(set (match_operand:SDWIM 0 "register_operand")
13056 (abs:SDWIM
13057 (match_operand:SDWIM 1 "general_operand")))
13058 (clobber (reg:CC FLAGS_REG))])]
13059 "TARGET_CMOVE
13060 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13061 {
13062 if (TARGET_EXPAND_ABS)
13063 {
13064 machine_mode mode = <MODE>mode;
13065 operands[1] = force_reg (mode, operands[1]);
13066
13067 /* Generate rtx abs using:
13068 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13069
13070 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13071 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13072 shift_amount, NULL_RTX,
13073 0, OPTAB_DIRECT);
13074 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13075 operands[0], 0, OPTAB_DIRECT);
13076 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13077 operands[0], 0, OPTAB_DIRECT);
13078 if (!rtx_equal_p (minus_dst, operands[0]))
13079 emit_move_insn (operands[0], minus_dst);
13080 DONE;
13081 }
13082 })
13083
13084 (define_insn_and_split "*abs<dwi>2_doubleword"
13085 [(set (match_operand:<DWI> 0 "register_operand")
13086 (abs:<DWI>
13087 (match_operand:<DWI> 1 "general_operand")))
13088 (clobber (reg:CC FLAGS_REG))]
13089 "TARGET_CMOVE
13090 && ix86_pre_reload_split ()"
13091 "#"
13092 "&& 1"
13093 [(parallel
13094 [(set (reg:CCC FLAGS_REG)
13095 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13096 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13097 (parallel
13098 [(set (match_dup 5)
13099 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13100 (match_dup 4))
13101 (const_int 0)))
13102 (clobber (reg:CC FLAGS_REG))])
13103 (parallel
13104 [(set (reg:CCGOC FLAGS_REG)
13105 (compare:CCGOC
13106 (neg:DWIH (match_dup 5))
13107 (const_int 0)))
13108 (set (match_dup 5)
13109 (neg:DWIH (match_dup 5)))])
13110 (set (match_dup 0)
13111 (if_then_else:DWIH
13112 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13113 (match_dup 2)
13114 (match_dup 1)))
13115 (set (match_dup 3)
13116 (if_then_else:DWIH
13117 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13118 (match_dup 5)
13119 (match_dup 4)))]
13120 {
13121 operands[1] = force_reg (<DWI>mode, operands[1]);
13122 operands[2] = gen_reg_rtx (<DWI>mode);
13123
13124 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13125 })
13126
13127 (define_insn_and_split "*nabs<dwi>2_doubleword"
13128 [(set (match_operand:<DWI> 0 "register_operand")
13129 (neg:<DWI>
13130 (abs:<DWI>
13131 (match_operand:<DWI> 1 "general_operand"))))
13132 (clobber (reg:CC FLAGS_REG))]
13133 "TARGET_CMOVE
13134 && ix86_pre_reload_split ()"
13135 "#"
13136 "&& 1"
13137 [(parallel
13138 [(set (reg:CCC FLAGS_REG)
13139 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13140 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13141 (parallel
13142 [(set (match_dup 5)
13143 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13144 (match_dup 4))
13145 (const_int 0)))
13146 (clobber (reg:CC FLAGS_REG))])
13147 (parallel
13148 [(set (reg:CCGOC FLAGS_REG)
13149 (compare:CCGOC
13150 (neg:DWIH (match_dup 5))
13151 (const_int 0)))
13152 (set (match_dup 5)
13153 (neg:DWIH (match_dup 5)))])
13154 (set (match_dup 0)
13155 (if_then_else:DWIH
13156 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13157 (match_dup 2)
13158 (match_dup 1)))
13159 (set (match_dup 3)
13160 (if_then_else:DWIH
13161 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13162 (match_dup 5)
13163 (match_dup 4)))]
13164 {
13165 operands[1] = force_reg (<DWI>mode, operands[1]);
13166 operands[2] = gen_reg_rtx (<DWI>mode);
13167
13168 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13169 })
13170
13171 (define_insn_and_split "*abs<mode>2_1"
13172 [(set (match_operand:SWI 0 "register_operand")
13173 (abs:SWI
13174 (match_operand:SWI 1 "general_operand")))
13175 (clobber (reg:CC FLAGS_REG))]
13176 "TARGET_CMOVE
13177 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13178 && ix86_pre_reload_split ()"
13179 "#"
13180 "&& 1"
13181 [(parallel
13182 [(set (reg:CCGOC FLAGS_REG)
13183 (compare:CCGOC
13184 (neg:SWI (match_dup 1))
13185 (const_int 0)))
13186 (set (match_dup 2)
13187 (neg:SWI (match_dup 1)))])
13188 (set (match_dup 0)
13189 (if_then_else:SWI
13190 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13191 (match_dup 2)
13192 (match_dup 1)))]
13193 {
13194 operands[1] = force_reg (<MODE>mode, operands[1]);
13195 operands[2] = gen_reg_rtx (<MODE>mode);
13196 })
13197
13198 (define_insn_and_split "*nabs<mode>2_1"
13199 [(set (match_operand:SWI 0 "register_operand")
13200 (neg:SWI
13201 (abs:SWI
13202 (match_operand:SWI 1 "general_operand"))))
13203 (clobber (reg:CC FLAGS_REG))]
13204 "TARGET_CMOVE
13205 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13206 && ix86_pre_reload_split ()"
13207 "#"
13208 "&& 1"
13209 [(parallel
13210 [(set (reg:CCGOC FLAGS_REG)
13211 (compare:CCGOC
13212 (neg:SWI (match_dup 1))
13213 (const_int 0)))
13214 (set (match_dup 2)
13215 (neg:SWI (match_dup 1)))])
13216 (set (match_dup 0)
13217 (if_then_else:SWI
13218 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13219 (match_dup 2)
13220 (match_dup 1)))]
13221 {
13222 operands[1] = force_reg (<MODE>mode, operands[1]);
13223 operands[2] = gen_reg_rtx (<MODE>mode);
13224 })
13225
13226 (define_expand "<code>tf2"
13227 [(set (match_operand:TF 0 "register_operand")
13228 (absneg:TF (match_operand:TF 1 "register_operand")))]
13229 "TARGET_SSE"
13230 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13231
13232 (define_insn_and_split "*<code>tf2_1"
13233 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13234 (absneg:TF
13235 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13236 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13237 "TARGET_SSE"
13238 "#"
13239 "&& reload_completed"
13240 [(set (match_dup 0)
13241 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13242 {
13243 if (TARGET_AVX)
13244 {
13245 if (MEM_P (operands[1]))
13246 std::swap (operands[1], operands[2]);
13247 }
13248 else
13249 {
13250 if (operands_match_p (operands[0], operands[2]))
13251 std::swap (operands[1], operands[2]);
13252 }
13253 }
13254 [(set_attr "isa" "noavx,noavx,avx,avx")])
13255
13256 (define_insn_and_split "*nabstf2_1"
13257 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13258 (neg:TF
13259 (abs:TF
13260 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13261 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13262 "TARGET_SSE"
13263 "#"
13264 "&& reload_completed"
13265 [(set (match_dup 0)
13266 (ior:TF (match_dup 1) (match_dup 2)))]
13267 {
13268 if (TARGET_AVX)
13269 {
13270 if (MEM_P (operands[1]))
13271 std::swap (operands[1], operands[2]);
13272 }
13273 else
13274 {
13275 if (operands_match_p (operands[0], operands[2]))
13276 std::swap (operands[1], operands[2]);
13277 }
13278 }
13279 [(set_attr "isa" "noavx,noavx,avx,avx")])
13280
13281 (define_expand "<code>hf2"
13282 [(set (match_operand:HF 0 "register_operand")
13283 (absneg:HF (match_operand:HF 1 "register_operand")))]
13284 "TARGET_AVX512FP16"
13285 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13286
13287 (define_expand "<code><mode>2"
13288 [(set (match_operand:X87MODEF 0 "register_operand")
13289 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13290 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13291 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13292
13293 ;; Changing of sign for FP values is doable using integer unit too.
13294 (define_insn "*<code><mode>2_i387_1"
13295 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13296 (absneg:X87MODEF
13297 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13298 (clobber (reg:CC FLAGS_REG))]
13299 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13300 "#")
13301
13302 (define_split
13303 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13304 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13305 (clobber (reg:CC FLAGS_REG))]
13306 "TARGET_80387 && reload_completed"
13307 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13308
13309 (define_split
13310 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13311 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13312 (clobber (reg:CC FLAGS_REG))]
13313 "TARGET_80387 && reload_completed"
13314 [(const_int 0)]
13315 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13316
13317 (define_insn_and_split "*<code>hf2_1"
13318 [(set (match_operand:HF 0 "register_operand" "=Yv")
13319 (absneg:HF
13320 (match_operand:HF 1 "register_operand" "Yv")))
13321 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13322 (clobber (reg:CC FLAGS_REG))]
13323 "TARGET_AVX512FP16"
13324 "#"
13325 "&& reload_completed"
13326 [(set (match_dup 0)
13327 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13328 {
13329 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13330 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13331 })
13332
13333 (define_insn "*<code><mode>2_1"
13334 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13335 (absneg:MODEF
13336 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13337 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13338 (clobber (reg:CC FLAGS_REG))]
13339 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13340 "#"
13341 [(set_attr "isa" "noavx,noavx,avx,*,*")
13342 (set (attr "enabled")
13343 (if_then_else
13344 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13345 (if_then_else
13346 (eq_attr "alternative" "3,4")
13347 (symbol_ref "TARGET_MIX_SSE_I387")
13348 (const_string "*"))
13349 (if_then_else
13350 (eq_attr "alternative" "3,4")
13351 (symbol_ref "true")
13352 (symbol_ref "false"))))])
13353
13354 (define_split
13355 [(set (match_operand:MODEF 0 "sse_reg_operand")
13356 (absneg:MODEF
13357 (match_operand:MODEF 1 "sse_reg_operand")))
13358 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13359 (clobber (reg:CC FLAGS_REG))]
13360 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13361 && reload_completed"
13362 [(set (match_dup 0)
13363 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13364 {
13365 machine_mode mode = <MODE>mode;
13366 machine_mode vmode = <ssevecmodef>mode;
13367
13368 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13369 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13370
13371 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13372 std::swap (operands[1], operands[2]);
13373 })
13374
13375 (define_split
13376 [(set (match_operand:MODEF 0 "fp_register_operand")
13377 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13378 (use (match_operand 2))
13379 (clobber (reg:CC FLAGS_REG))]
13380 "TARGET_80387 && reload_completed"
13381 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13382
13383 (define_split
13384 [(set (match_operand:MODEF 0 "general_reg_operand")
13385 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13386 (use (match_operand 2))
13387 (clobber (reg:CC FLAGS_REG))]
13388 "TARGET_80387 && reload_completed"
13389 [(const_int 0)]
13390 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13391
13392 (define_insn_and_split "*nabs<mode>2_1"
13393 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13394 (neg:MODEF
13395 (abs:MODEF
13396 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13397 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13398 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13399 "#"
13400 "&& reload_completed"
13401 [(set (match_dup 0)
13402 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13403 {
13404 machine_mode mode = <MODE>mode;
13405 machine_mode vmode = <ssevecmodef>mode;
13406
13407 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13408 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13409
13410 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13411 std::swap (operands[1], operands[2]);
13412 }
13413 [(set_attr "isa" "noavx,noavx,avx")])
13414
13415 ;; Conditionalize these after reload. If they match before reload, we
13416 ;; lose the clobber and ability to use integer instructions.
13417
13418 (define_insn "*<code><mode>2_i387"
13419 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13420 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13421 "TARGET_80387 && reload_completed"
13422 "<absneg_mnemonic>"
13423 [(set_attr "type" "fsgn")
13424 (set_attr "mode" "<MODE>")])
13425
13426 ;; Copysign instructions
13427
13428 (define_expand "copysign<mode>3"
13429 [(match_operand:SSEMODEF 0 "register_operand")
13430 (match_operand:SSEMODEF 1 "nonmemory_operand")
13431 (match_operand:SSEMODEF 2 "register_operand")]
13432 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13433 || (TARGET_SSE && (<MODE>mode == TFmode))
13434 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13435 "ix86_expand_copysign (operands); DONE;")
13436
13437 (define_expand "xorsign<mode>3"
13438 [(match_operand:MODEFH 0 "register_operand")
13439 (match_operand:MODEFH 1 "register_operand")
13440 (match_operand:MODEFH 2 "register_operand")]
13441 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13442 || <MODE>mode == HFmode"
13443 {
13444 if (rtx_equal_p (operands[1], operands[2]))
13445 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13446 else
13447 ix86_expand_xorsign (operands);
13448 DONE;
13449 })
13450 \f
13451 ;; One complement instructions
13452
13453 (define_expand "one_cmpl<mode>2"
13454 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13455 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13456 ""
13457 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13458
13459 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13460 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13461 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13462 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13463 "#"
13464 "&& reload_completed"
13465 [(set (match_dup 0)
13466 (not:DWIH (match_dup 1)))
13467 (set (match_dup 2)
13468 (not:DWIH (match_dup 3)))]
13469 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13470
13471 (define_insn "*one_cmpl<mode>2_1"
13472 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13473 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13474 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13475 "@
13476 not{<imodesuffix>}\t%0
13477 #"
13478 [(set_attr "isa" "*,<kmov_isa>")
13479 (set_attr "type" "negnot,msklog")
13480 (set_attr "mode" "<MODE>")])
13481
13482 (define_insn "*one_cmplsi2_1_zext"
13483 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13484 (zero_extend:DI
13485 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13486 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13487 "@
13488 not{l}\t%k0
13489 #"
13490 [(set_attr "isa" "x64,avx512bw_512")
13491 (set_attr "type" "negnot,msklog")
13492 (set_attr "mode" "SI,SI")])
13493
13494 (define_insn "*one_cmplqi2_1"
13495 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13496 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13497 "ix86_unary_operator_ok (NOT, QImode, operands)"
13498 "@
13499 not{b}\t%0
13500 not{l}\t%k0
13501 #"
13502 [(set_attr "isa" "*,*,avx512f")
13503 (set_attr "type" "negnot,negnot,msklog")
13504 (set (attr "mode")
13505 (cond [(eq_attr "alternative" "1")
13506 (const_string "SI")
13507 (and (eq_attr "alternative" "2")
13508 (match_test "!TARGET_AVX512DQ"))
13509 (const_string "HI")
13510 ]
13511 (const_string "QI")))
13512 ;; Potential partial reg stall on alternative 1.
13513 (set (attr "preferred_for_speed")
13514 (cond [(eq_attr "alternative" "1")
13515 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13516 (symbol_ref "true")))])
13517
13518 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13519 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13520 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13521 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13522 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13523 "@
13524 not{<imodesuffix>}\t%0
13525 #"
13526 "&& reload_completed"
13527 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13528 (set (strict_low_part (match_dup 0))
13529 (not:SWI12 (match_dup 0)))]
13530 ""
13531 [(set_attr "type" "negnot")
13532 (set_attr "mode" "<MODE>")])
13533
13534 (define_insn "*one_cmpl<mode>2_2"
13535 [(set (reg FLAGS_REG)
13536 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13537 (const_int 0)))
13538 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13539 (not:SWI (match_dup 1)))]
13540 "ix86_match_ccmode (insn, CCNOmode)
13541 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13542 "#"
13543 [(set_attr "type" "alu1")
13544 (set_attr "mode" "<MODE>")])
13545
13546 (define_split
13547 [(set (match_operand 0 "flags_reg_operand")
13548 (match_operator 2 "compare_operator"
13549 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13550 (const_int 0)]))
13551 (set (match_operand:SWI 1 "nonimmediate_operand")
13552 (not:SWI (match_dup 3)))]
13553 "ix86_match_ccmode (insn, CCNOmode)"
13554 [(parallel [(set (match_dup 0)
13555 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13556 (const_int 0)]))
13557 (set (match_dup 1)
13558 (xor:SWI (match_dup 3) (const_int -1)))])])
13559
13560 (define_insn "*one_cmplsi2_2_zext"
13561 [(set (reg FLAGS_REG)
13562 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13563 (const_int 0)))
13564 (set (match_operand:DI 0 "register_operand" "=r")
13565 (zero_extend:DI (not:SI (match_dup 1))))]
13566 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13567 && ix86_unary_operator_ok (NOT, SImode, operands)"
13568 "#"
13569 [(set_attr "type" "alu1")
13570 (set_attr "mode" "SI")])
13571
13572 (define_split
13573 [(set (match_operand 0 "flags_reg_operand")
13574 (match_operator 2 "compare_operator"
13575 [(not:SI (match_operand:SI 3 "register_operand"))
13576 (const_int 0)]))
13577 (set (match_operand:DI 1 "register_operand")
13578 (zero_extend:DI (not:SI (match_dup 3))))]
13579 "ix86_match_ccmode (insn, CCNOmode)"
13580 [(parallel [(set (match_dup 0)
13581 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13582 (const_int 0)]))
13583 (set (match_dup 1)
13584 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13585 \f
13586 ;; Shift instructions
13587
13588 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13589 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13590 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13591 ;; from the assembler input.
13592 ;;
13593 ;; This instruction shifts the target reg/mem as usual, but instead of
13594 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13595 ;; is a left shift double, bits are taken from the high order bits of
13596 ;; reg, else if the insn is a shift right double, bits are taken from the
13597 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13598 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13599 ;;
13600 ;; Since sh[lr]d does not change the `reg' operand, that is done
13601 ;; separately, making all shifts emit pairs of shift double and normal
13602 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13603 ;; support a 63 bit shift, each shift where the count is in a reg expands
13604 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13605 ;;
13606 ;; If the shift count is a constant, we need never emit more than one
13607 ;; shift pair, instead using moves and sign extension for counts greater
13608 ;; than 31.
13609
13610 (define_expand "ashl<mode>3"
13611 [(set (match_operand:SDWIM 0 "<shift_operand>")
13612 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13613 (match_operand:QI 2 "nonmemory_operand")))]
13614 ""
13615 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13616
13617 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13618 [(set (match_operand:<DWI> 0 "register_operand")
13619 (ashift:<DWI>
13620 (match_operand:<DWI> 1 "register_operand")
13621 (subreg:QI
13622 (and
13623 (match_operand 2 "int248_register_operand" "c")
13624 (match_operand 3 "const_int_operand")) 0)))
13625 (clobber (reg:CC FLAGS_REG))]
13626 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13627 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13628 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13629 && ix86_pre_reload_split ()"
13630 "#"
13631 "&& 1"
13632 [(parallel
13633 [(set (match_dup 6)
13634 (ior:DWIH (ashift:DWIH (match_dup 6)
13635 (and:QI (match_dup 2) (match_dup 8)))
13636 (subreg:DWIH
13637 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13638 (minus:QI (match_dup 9)
13639 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13640 (clobber (reg:CC FLAGS_REG))])
13641 (parallel
13642 [(set (match_dup 4)
13643 (ashift:DWIH (match_dup 5) (match_dup 2)))
13644 (clobber (reg:CC FLAGS_REG))])]
13645 {
13646 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13647 {
13648 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13649 operands[2] = gen_lowpart (QImode, operands[2]);
13650 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13651 operands[2]));
13652 DONE;
13653 }
13654
13655 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13656
13657 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13658 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13659
13660 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13661 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13662 {
13663 rtx xops[3];
13664 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13665 xops[1] = operands[2];
13666 xops[2] = GEN_INT (INTVAL (operands[3])
13667 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13668 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13669 operands[2] = xops[0];
13670 }
13671
13672 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13673 operands[2] = gen_lowpart (QImode, operands[2]);
13674
13675 if (!rtx_equal_p (operands[6], operands[7]))
13676 emit_move_insn (operands[6], operands[7]);
13677 })
13678
13679 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13680 [(set (match_operand:<DWI> 0 "register_operand")
13681 (ashift:<DWI>
13682 (match_operand:<DWI> 1 "register_operand")
13683 (and:QI
13684 (match_operand:QI 2 "register_operand" "c")
13685 (match_operand:QI 3 "const_int_operand"))))
13686 (clobber (reg:CC FLAGS_REG))]
13687 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13688 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13689 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13690 && ix86_pre_reload_split ()"
13691 "#"
13692 "&& 1"
13693 [(parallel
13694 [(set (match_dup 6)
13695 (ior:DWIH (ashift:DWIH (match_dup 6)
13696 (and:QI (match_dup 2) (match_dup 8)))
13697 (subreg:DWIH
13698 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13699 (minus:QI (match_dup 9)
13700 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13701 (clobber (reg:CC FLAGS_REG))])
13702 (parallel
13703 [(set (match_dup 4)
13704 (ashift:DWIH (match_dup 5) (match_dup 2)))
13705 (clobber (reg:CC FLAGS_REG))])]
13706 {
13707 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13708 {
13709 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13710 operands[2]));
13711 DONE;
13712 }
13713
13714 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13715
13716 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13717 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13718
13719 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13720 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13721 {
13722 rtx tem = gen_reg_rtx (QImode);
13723 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13724 operands[2] = tem;
13725 }
13726
13727 if (!rtx_equal_p (operands[6], operands[7]))
13728 emit_move_insn (operands[6], operands[7]);
13729 })
13730
13731 (define_insn "ashl<mode>3_doubleword"
13732 [(set (match_operand:DWI 0 "register_operand" "=&r")
13733 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13734 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13735 (clobber (reg:CC FLAGS_REG))]
13736 ""
13737 "#"
13738 [(set_attr "type" "multi")])
13739
13740 (define_split
13741 [(set (match_operand:DWI 0 "register_operand")
13742 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13743 (match_operand:QI 2 "nonmemory_operand")))
13744 (clobber (reg:CC FLAGS_REG))]
13745 "epilogue_completed"
13746 [(const_int 0)]
13747 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13748
13749 ;; By default we don't ask for a scratch register, because when DWImode
13750 ;; values are manipulated, registers are already at a premium. But if
13751 ;; we have one handy, we won't turn it away.
13752
13753 (define_peephole2
13754 [(match_scratch:DWIH 3 "r")
13755 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13756 (ashift:<DWI>
13757 (match_operand:<DWI> 1 "nonmemory_operand")
13758 (match_operand:QI 2 "nonmemory_operand")))
13759 (clobber (reg:CC FLAGS_REG))])
13760 (match_dup 3)]
13761 "TARGET_CMOVE"
13762 [(const_int 0)]
13763 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13764
13765 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13766 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13767 (ashift:<DWI>
13768 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13769 (match_operand:QI 2 "const_int_operand")))
13770 (clobber (reg:CC FLAGS_REG))]
13771 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13772 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13773 "#"
13774 "&& reload_completed"
13775 [(const_int 0)]
13776 {
13777 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13778 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13779 if (!rtx_equal_p (operands[3], operands[1]))
13780 emit_move_insn (operands[3], operands[1]);
13781 if (bits > 0)
13782 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13783 ix86_expand_clear (operands[0]);
13784 DONE;
13785 })
13786
13787 (define_insn "x86_64_shld"
13788 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13789 (ior:DI (ashift:DI (match_dup 0)
13790 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13791 (const_int 63)))
13792 (subreg:DI
13793 (lshiftrt:TI
13794 (zero_extend:TI
13795 (match_operand:DI 1 "register_operand" "r"))
13796 (minus:QI (const_int 64)
13797 (and:QI (match_dup 2) (const_int 63)))) 0)))
13798 (clobber (reg:CC FLAGS_REG))]
13799 "TARGET_64BIT"
13800 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13801 [(set_attr "type" "ishift")
13802 (set_attr "prefix_0f" "1")
13803 (set_attr "mode" "DI")
13804 (set_attr "athlon_decode" "vector")
13805 (set_attr "amdfam10_decode" "vector")
13806 (set_attr "bdver1_decode" "vector")])
13807
13808 (define_insn "x86_64_shld_1"
13809 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13810 (ior:DI (ashift:DI (match_dup 0)
13811 (match_operand:QI 2 "const_0_to_63_operand"))
13812 (subreg:DI
13813 (lshiftrt:TI
13814 (zero_extend:TI
13815 (match_operand:DI 1 "register_operand" "r"))
13816 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13817 (clobber (reg:CC FLAGS_REG))]
13818 "TARGET_64BIT
13819 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13820 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13821 [(set_attr "type" "ishift")
13822 (set_attr "prefix_0f" "1")
13823 (set_attr "mode" "DI")
13824 (set_attr "length_immediate" "1")
13825 (set_attr "athlon_decode" "vector")
13826 (set_attr "amdfam10_decode" "vector")
13827 (set_attr "bdver1_decode" "vector")])
13828
13829 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13830 [(set (match_operand:DI 0 "nonimmediate_operand")
13831 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13832 (match_operand:QI 2 "const_0_to_63_operand"))
13833 (lshiftrt:DI
13834 (match_operand:DI 1 "nonimmediate_operand")
13835 (match_operand:QI 3 "const_0_to_63_operand"))))
13836 (clobber (reg:CC FLAGS_REG))]
13837 "TARGET_64BIT
13838 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13839 && ix86_pre_reload_split ()"
13840 "#"
13841 "&& 1"
13842 [(const_int 0)]
13843 {
13844 if (rtx_equal_p (operands[4], operands[0]))
13845 {
13846 operands[1] = force_reg (DImode, operands[1]);
13847 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13848 }
13849 else if (rtx_equal_p (operands[1], operands[0]))
13850 {
13851 operands[4] = force_reg (DImode, operands[4]);
13852 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13853 }
13854 else
13855 {
13856 operands[1] = force_reg (DImode, operands[1]);
13857 rtx tmp = gen_reg_rtx (DImode);
13858 emit_move_insn (tmp, operands[4]);
13859 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13860 emit_move_insn (operands[0], tmp);
13861 }
13862 DONE;
13863 })
13864
13865 (define_insn_and_split "*x86_64_shld_2"
13866 [(set (match_operand:DI 0 "nonimmediate_operand")
13867 (ior:DI (ashift:DI (match_dup 0)
13868 (match_operand:QI 2 "nonmemory_operand"))
13869 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13870 (minus:QI (const_int 64) (match_dup 2)))))
13871 (clobber (reg:CC FLAGS_REG))]
13872 "TARGET_64BIT && ix86_pre_reload_split ()"
13873 "#"
13874 "&& 1"
13875 [(parallel [(set (match_dup 0)
13876 (ior:DI (ashift:DI (match_dup 0)
13877 (and:QI (match_dup 2) (const_int 63)))
13878 (subreg:DI
13879 (lshiftrt:TI
13880 (zero_extend:TI (match_dup 1))
13881 (minus:QI (const_int 64)
13882 (and:QI (match_dup 2)
13883 (const_int 63)))) 0)))
13884 (clobber (reg:CC FLAGS_REG))])])
13885
13886 (define_insn "x86_shld"
13887 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13888 (ior:SI (ashift:SI (match_dup 0)
13889 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13890 (const_int 31)))
13891 (subreg:SI
13892 (lshiftrt:DI
13893 (zero_extend:DI
13894 (match_operand:SI 1 "register_operand" "r"))
13895 (minus:QI (const_int 32)
13896 (and:QI (match_dup 2) (const_int 31)))) 0)))
13897 (clobber (reg:CC FLAGS_REG))]
13898 ""
13899 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13900 [(set_attr "type" "ishift")
13901 (set_attr "prefix_0f" "1")
13902 (set_attr "mode" "SI")
13903 (set_attr "pent_pair" "np")
13904 (set_attr "athlon_decode" "vector")
13905 (set_attr "amdfam10_decode" "vector")
13906 (set_attr "bdver1_decode" "vector")])
13907
13908 (define_insn "x86_shld_1"
13909 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13910 (ior:SI (ashift:SI (match_dup 0)
13911 (match_operand:QI 2 "const_0_to_31_operand"))
13912 (subreg:SI
13913 (lshiftrt:DI
13914 (zero_extend:DI
13915 (match_operand:SI 1 "register_operand" "r"))
13916 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13917 (clobber (reg:CC FLAGS_REG))]
13918 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13919 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13920 [(set_attr "type" "ishift")
13921 (set_attr "prefix_0f" "1")
13922 (set_attr "length_immediate" "1")
13923 (set_attr "mode" "SI")
13924 (set_attr "pent_pair" "np")
13925 (set_attr "athlon_decode" "vector")
13926 (set_attr "amdfam10_decode" "vector")
13927 (set_attr "bdver1_decode" "vector")])
13928
13929 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13930 [(set (match_operand:SI 0 "nonimmediate_operand")
13931 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13932 (match_operand:QI 2 "const_0_to_31_operand"))
13933 (lshiftrt:SI
13934 (match_operand:SI 1 "nonimmediate_operand")
13935 (match_operand:QI 3 "const_0_to_31_operand"))))
13936 (clobber (reg:CC FLAGS_REG))]
13937 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13938 && ix86_pre_reload_split ()"
13939 "#"
13940 "&& 1"
13941 [(const_int 0)]
13942 {
13943 if (rtx_equal_p (operands[4], operands[0]))
13944 {
13945 operands[1] = force_reg (SImode, operands[1]);
13946 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13947 }
13948 else if (rtx_equal_p (operands[1], operands[0]))
13949 {
13950 operands[4] = force_reg (SImode, operands[4]);
13951 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13952 }
13953 else
13954 {
13955 operands[1] = force_reg (SImode, operands[1]);
13956 rtx tmp = gen_reg_rtx (SImode);
13957 emit_move_insn (tmp, operands[4]);
13958 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13959 emit_move_insn (operands[0], tmp);
13960 }
13961 DONE;
13962 })
13963
13964 (define_insn_and_split "*x86_shld_2"
13965 [(set (match_operand:SI 0 "nonimmediate_operand")
13966 (ior:SI (ashift:SI (match_dup 0)
13967 (match_operand:QI 2 "nonmemory_operand"))
13968 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13969 (minus:QI (const_int 32) (match_dup 2)))))
13970 (clobber (reg:CC FLAGS_REG))]
13971 "TARGET_64BIT && ix86_pre_reload_split ()"
13972 "#"
13973 "&& 1"
13974 [(parallel [(set (match_dup 0)
13975 (ior:SI (ashift:SI (match_dup 0)
13976 (and:QI (match_dup 2) (const_int 31)))
13977 (subreg:SI
13978 (lshiftrt:DI
13979 (zero_extend:DI (match_dup 1))
13980 (minus:QI (const_int 32)
13981 (and:QI (match_dup 2)
13982 (const_int 31)))) 0)))
13983 (clobber (reg:CC FLAGS_REG))])])
13984
13985 (define_expand "@x86_shift<mode>_adj_1"
13986 [(set (reg:CCZ FLAGS_REG)
13987 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13988 (match_dup 4))
13989 (const_int 0)))
13990 (set (match_operand:SWI48 0 "register_operand")
13991 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13992 (match_operand:SWI48 1 "register_operand")
13993 (match_dup 0)))
13994 (set (match_dup 1)
13995 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13996 (match_operand:SWI48 3 "register_operand")
13997 (match_dup 1)))]
13998 "TARGET_CMOVE"
13999 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
14000
14001 (define_expand "@x86_shift<mode>_adj_2"
14002 [(use (match_operand:SWI48 0 "register_operand"))
14003 (use (match_operand:SWI48 1 "register_operand"))
14004 (use (match_operand:QI 2 "register_operand"))]
14005 ""
14006 {
14007 rtx_code_label *label = gen_label_rtx ();
14008 rtx tmp;
14009
14010 emit_insn (gen_testqi_ccz_1 (operands[2],
14011 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14012
14013 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14014 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14015 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14016 gen_rtx_LABEL_REF (VOIDmode, label),
14017 pc_rtx);
14018 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14019 JUMP_LABEL (tmp) = label;
14020
14021 emit_move_insn (operands[0], operands[1]);
14022 ix86_expand_clear (operands[1]);
14023
14024 emit_label (label);
14025 LABEL_NUSES (label) = 1;
14026
14027 DONE;
14028 })
14029
14030 ;; Avoid useless masking of count operand.
14031 (define_insn_and_split "*ashl<mode>3_mask"
14032 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14033 (ashift:SWI48
14034 (match_operand:SWI48 1 "nonimmediate_operand")
14035 (subreg:QI
14036 (and
14037 (match_operand 2 "int248_register_operand" "c,r")
14038 (match_operand 3 "const_int_operand")) 0)))
14039 (clobber (reg:CC FLAGS_REG))]
14040 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14041 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14042 == GET_MODE_BITSIZE (<MODE>mode)-1
14043 && ix86_pre_reload_split ()"
14044 "#"
14045 "&& 1"
14046 [(parallel
14047 [(set (match_dup 0)
14048 (ashift:SWI48 (match_dup 1)
14049 (match_dup 2)))
14050 (clobber (reg:CC FLAGS_REG))])]
14051 {
14052 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14053 operands[2] = gen_lowpart (QImode, operands[2]);
14054 }
14055 [(set_attr "isa" "*,bmi2")])
14056
14057 (define_insn_and_split "*ashl<mode>3_mask_1"
14058 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14059 (ashift:SWI48
14060 (match_operand:SWI48 1 "nonimmediate_operand")
14061 (and:QI
14062 (match_operand:QI 2 "register_operand" "c,r")
14063 (match_operand:QI 3 "const_int_operand"))))
14064 (clobber (reg:CC FLAGS_REG))]
14065 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14066 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14067 == GET_MODE_BITSIZE (<MODE>mode)-1
14068 && ix86_pre_reload_split ()"
14069 "#"
14070 "&& 1"
14071 [(parallel
14072 [(set (match_dup 0)
14073 (ashift:SWI48 (match_dup 1)
14074 (match_dup 2)))
14075 (clobber (reg:CC FLAGS_REG))])]
14076 ""
14077 [(set_attr "isa" "*,bmi2")])
14078
14079 (define_insn "*bmi2_ashl<mode>3_1"
14080 [(set (match_operand:SWI48 0 "register_operand" "=r")
14081 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14082 (match_operand:SWI48 2 "register_operand" "r")))]
14083 "TARGET_BMI2"
14084 "shlx\t{%2, %1, %0|%0, %1, %2}"
14085 [(set_attr "type" "ishiftx")
14086 (set_attr "mode" "<MODE>")])
14087
14088 (define_insn "*ashl<mode>3_1"
14089 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
14090 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
14091 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
14092 (clobber (reg:CC FLAGS_REG))]
14093 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14094 {
14095 switch (get_attr_type (insn))
14096 {
14097 case TYPE_LEA:
14098 case TYPE_ISHIFTX:
14099 case TYPE_MSKLOG:
14100 return "#";
14101
14102 case TYPE_ALU:
14103 gcc_assert (operands[2] == const1_rtx);
14104 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14105 return "add{<imodesuffix>}\t%0, %0";
14106
14107 default:
14108 if (operands[2] == const1_rtx
14109 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14110 return "sal{<imodesuffix>}\t%0";
14111 else
14112 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14113 }
14114 }
14115 [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14116 (set (attr "type")
14117 (cond [(eq_attr "alternative" "1")
14118 (const_string "lea")
14119 (eq_attr "alternative" "2")
14120 (const_string "ishiftx")
14121 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14122 (match_operand 0 "register_operand"))
14123 (match_operand 2 "const1_operand"))
14124 (const_string "alu")
14125 (eq_attr "alternative" "3")
14126 (const_string "msklog")
14127 ]
14128 (const_string "ishift")))
14129 (set (attr "length_immediate")
14130 (if_then_else
14131 (ior (eq_attr "type" "alu")
14132 (and (eq_attr "type" "ishift")
14133 (and (match_operand 2 "const1_operand")
14134 (ior (match_test "TARGET_SHIFT1")
14135 (match_test "optimize_function_for_size_p (cfun)")))))
14136 (const_string "0")
14137 (const_string "*")))
14138 (set_attr "mode" "<MODE>")])
14139
14140 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14141 (define_split
14142 [(set (match_operand:SWI48 0 "register_operand")
14143 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14144 (match_operand:QI 2 "register_operand")))
14145 (clobber (reg:CC FLAGS_REG))]
14146 "TARGET_BMI2 && reload_completed"
14147 [(set (match_dup 0)
14148 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14149 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14150
14151 (define_insn "*bmi2_ashlsi3_1_zext"
14152 [(set (match_operand:DI 0 "register_operand" "=r")
14153 (zero_extend:DI
14154 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14155 (match_operand:SI 2 "register_operand" "r"))))]
14156 "TARGET_64BIT && TARGET_BMI2"
14157 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14158 [(set_attr "type" "ishiftx")
14159 (set_attr "mode" "SI")])
14160
14161 (define_insn "*ashlsi3_1_zext"
14162 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14163 (zero_extend:DI
14164 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14165 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14166 (clobber (reg:CC FLAGS_REG))]
14167 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14168 {
14169 switch (get_attr_type (insn))
14170 {
14171 case TYPE_LEA:
14172 case TYPE_ISHIFTX:
14173 return "#";
14174
14175 case TYPE_ALU:
14176 gcc_assert (operands[2] == const1_rtx);
14177 return "add{l}\t%k0, %k0";
14178
14179 default:
14180 if (operands[2] == const1_rtx
14181 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14182 return "sal{l}\t%k0";
14183 else
14184 return "sal{l}\t{%2, %k0|%k0, %2}";
14185 }
14186 }
14187 [(set_attr "isa" "*,*,bmi2")
14188 (set (attr "type")
14189 (cond [(eq_attr "alternative" "1")
14190 (const_string "lea")
14191 (eq_attr "alternative" "2")
14192 (const_string "ishiftx")
14193 (and (match_test "TARGET_DOUBLE_WITH_ADD")
14194 (match_operand 2 "const1_operand"))
14195 (const_string "alu")
14196 ]
14197 (const_string "ishift")))
14198 (set (attr "length_immediate")
14199 (if_then_else
14200 (ior (eq_attr "type" "alu")
14201 (and (eq_attr "type" "ishift")
14202 (and (match_operand 2 "const1_operand")
14203 (ior (match_test "TARGET_SHIFT1")
14204 (match_test "optimize_function_for_size_p (cfun)")))))
14205 (const_string "0")
14206 (const_string "*")))
14207 (set_attr "mode" "SI")])
14208
14209 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14210 (define_split
14211 [(set (match_operand:DI 0 "register_operand")
14212 (zero_extend:DI
14213 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14214 (match_operand:QI 2 "register_operand"))))
14215 (clobber (reg:CC FLAGS_REG))]
14216 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14217 [(set (match_dup 0)
14218 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14219 "operands[2] = gen_lowpart (SImode, operands[2]);")
14220
14221 (define_insn "*ashlhi3_1"
14222 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14223 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14224 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14225 (clobber (reg:CC FLAGS_REG))]
14226 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14227 {
14228 switch (get_attr_type (insn))
14229 {
14230 case TYPE_LEA:
14231 case TYPE_MSKLOG:
14232 return "#";
14233
14234 case TYPE_ALU:
14235 gcc_assert (operands[2] == const1_rtx);
14236 return "add{w}\t%0, %0";
14237
14238 default:
14239 if (operands[2] == const1_rtx
14240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14241 return "sal{w}\t%0";
14242 else
14243 return "sal{w}\t{%2, %0|%0, %2}";
14244 }
14245 }
14246 [(set_attr "isa" "*,*,avx512f")
14247 (set (attr "type")
14248 (cond [(eq_attr "alternative" "1")
14249 (const_string "lea")
14250 (eq_attr "alternative" "2")
14251 (const_string "msklog")
14252 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14253 (match_operand 0 "register_operand"))
14254 (match_operand 2 "const1_operand"))
14255 (const_string "alu")
14256 ]
14257 (const_string "ishift")))
14258 (set (attr "length_immediate")
14259 (if_then_else
14260 (ior (eq_attr "type" "alu")
14261 (and (eq_attr "type" "ishift")
14262 (and (match_operand 2 "const1_operand")
14263 (ior (match_test "TARGET_SHIFT1")
14264 (match_test "optimize_function_for_size_p (cfun)")))))
14265 (const_string "0")
14266 (const_string "*")))
14267 (set_attr "mode" "HI,SI,HI")])
14268
14269 (define_insn "*ashlqi3_1"
14270 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14271 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14272 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14273 (clobber (reg:CC FLAGS_REG))]
14274 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14275 {
14276 switch (get_attr_type (insn))
14277 {
14278 case TYPE_LEA:
14279 case TYPE_MSKLOG:
14280 return "#";
14281
14282 case TYPE_ALU:
14283 gcc_assert (operands[2] == const1_rtx);
14284 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14285 return "add{l}\t%k0, %k0";
14286 else
14287 return "add{b}\t%0, %0";
14288
14289 default:
14290 if (operands[2] == const1_rtx
14291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14292 {
14293 if (get_attr_mode (insn) == MODE_SI)
14294 return "sal{l}\t%k0";
14295 else
14296 return "sal{b}\t%0";
14297 }
14298 else
14299 {
14300 if (get_attr_mode (insn) == MODE_SI)
14301 return "sal{l}\t{%2, %k0|%k0, %2}";
14302 else
14303 return "sal{b}\t{%2, %0|%0, %2}";
14304 }
14305 }
14306 }
14307 [(set_attr "isa" "*,*,*,avx512dq")
14308 (set (attr "type")
14309 (cond [(eq_attr "alternative" "2")
14310 (const_string "lea")
14311 (eq_attr "alternative" "3")
14312 (const_string "msklog")
14313 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14314 (match_operand 0 "register_operand"))
14315 (match_operand 2 "const1_operand"))
14316 (const_string "alu")
14317 ]
14318 (const_string "ishift")))
14319 (set (attr "length_immediate")
14320 (if_then_else
14321 (ior (eq_attr "type" "alu")
14322 (and (eq_attr "type" "ishift")
14323 (and (match_operand 2 "const1_operand")
14324 (ior (match_test "TARGET_SHIFT1")
14325 (match_test "optimize_function_for_size_p (cfun)")))))
14326 (const_string "0")
14327 (const_string "*")))
14328 (set_attr "mode" "QI,SI,SI,QI")
14329 ;; Potential partial reg stall on alternative 1.
14330 (set (attr "preferred_for_speed")
14331 (cond [(eq_attr "alternative" "1")
14332 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14333 (symbol_ref "true")))])
14334
14335 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14336 (define_insn_and_split "*ashl<mode>3_1_slp"
14337 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14338 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14339 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14340 (clobber (reg:CC FLAGS_REG))]
14341 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14342 {
14343 if (which_alternative)
14344 return "#";
14345
14346 switch (get_attr_type (insn))
14347 {
14348 case TYPE_ALU:
14349 gcc_assert (operands[2] == const1_rtx);
14350 return "add{<imodesuffix>}\t%0, %0";
14351
14352 default:
14353 if (operands[2] == const1_rtx
14354 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14355 return "sal{<imodesuffix>}\t%0";
14356 else
14357 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14358 }
14359 }
14360 "&& reload_completed"
14361 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14362 (parallel
14363 [(set (strict_low_part (match_dup 0))
14364 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14365 (clobber (reg:CC FLAGS_REG))])]
14366 ""
14367 [(set (attr "type")
14368 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14369 (match_operand 2 "const1_operand"))
14370 (const_string "alu")
14371 ]
14372 (const_string "ishift")))
14373 (set (attr "length_immediate")
14374 (if_then_else
14375 (ior (eq_attr "type" "alu")
14376 (and (eq_attr "type" "ishift")
14377 (and (match_operand 2 "const1_operand")
14378 (ior (match_test "TARGET_SHIFT1")
14379 (match_test "optimize_function_for_size_p (cfun)")))))
14380 (const_string "0")
14381 (const_string "*")))
14382 (set_attr "mode" "<MODE>")])
14383
14384 ;; Convert ashift to the lea pattern to avoid flags dependency.
14385 (define_split
14386 [(set (match_operand:SWI 0 "general_reg_operand")
14387 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14388 (match_operand 2 "const_0_to_3_operand")))
14389 (clobber (reg:CC FLAGS_REG))]
14390 "reload_completed
14391 && REGNO (operands[0]) != REGNO (operands[1])"
14392 [(set (match_dup 0)
14393 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14394 {
14395 if (<MODE>mode != <LEAMODE>mode)
14396 {
14397 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14398 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14399 }
14400 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14401 })
14402
14403 ;; Convert ashift to the lea pattern to avoid flags dependency.
14404 (define_split
14405 [(set (match_operand:DI 0 "general_reg_operand")
14406 (zero_extend:DI
14407 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14408 (match_operand 2 "const_0_to_3_operand"))))
14409 (clobber (reg:CC FLAGS_REG))]
14410 "TARGET_64BIT && reload_completed
14411 && REGNO (operands[0]) != REGNO (operands[1])"
14412 [(set (match_dup 0)
14413 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14414 {
14415 operands[1] = gen_lowpart (SImode, operands[1]);
14416 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14417 })
14418
14419 ;; This pattern can't accept a variable shift count, since shifts by
14420 ;; zero don't affect the flags. We assume that shifts by constant
14421 ;; zero are optimized away.
14422 (define_insn "*ashl<mode>3_cmp"
14423 [(set (reg FLAGS_REG)
14424 (compare
14425 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14426 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14427 (const_int 0)))
14428 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14429 (ashift:SWI (match_dup 1) (match_dup 2)))]
14430 "(optimize_function_for_size_p (cfun)
14431 || !TARGET_PARTIAL_FLAG_REG_STALL
14432 || (operands[2] == const1_rtx
14433 && (TARGET_SHIFT1
14434 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14435 && ix86_match_ccmode (insn, CCGOCmode)
14436 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14437 {
14438 switch (get_attr_type (insn))
14439 {
14440 case TYPE_ALU:
14441 gcc_assert (operands[2] == const1_rtx);
14442 return "add{<imodesuffix>}\t%0, %0";
14443
14444 default:
14445 if (operands[2] == const1_rtx
14446 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14447 return "sal{<imodesuffix>}\t%0";
14448 else
14449 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14450 }
14451 }
14452 [(set (attr "type")
14453 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14454 (match_operand 0 "register_operand"))
14455 (match_operand 2 "const1_operand"))
14456 (const_string "alu")
14457 ]
14458 (const_string "ishift")))
14459 (set (attr "length_immediate")
14460 (if_then_else
14461 (ior (eq_attr "type" "alu")
14462 (and (eq_attr "type" "ishift")
14463 (and (match_operand 2 "const1_operand")
14464 (ior (match_test "TARGET_SHIFT1")
14465 (match_test "optimize_function_for_size_p (cfun)")))))
14466 (const_string "0")
14467 (const_string "*")))
14468 (set_attr "mode" "<MODE>")])
14469
14470 (define_insn "*ashlsi3_cmp_zext"
14471 [(set (reg FLAGS_REG)
14472 (compare
14473 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14474 (match_operand:QI 2 "const_1_to_31_operand"))
14475 (const_int 0)))
14476 (set (match_operand:DI 0 "register_operand" "=r")
14477 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14478 "TARGET_64BIT
14479 && (optimize_function_for_size_p (cfun)
14480 || !TARGET_PARTIAL_FLAG_REG_STALL
14481 || (operands[2] == const1_rtx
14482 && (TARGET_SHIFT1
14483 || TARGET_DOUBLE_WITH_ADD)))
14484 && ix86_match_ccmode (insn, CCGOCmode)
14485 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14486 {
14487 switch (get_attr_type (insn))
14488 {
14489 case TYPE_ALU:
14490 gcc_assert (operands[2] == const1_rtx);
14491 return "add{l}\t%k0, %k0";
14492
14493 default:
14494 if (operands[2] == const1_rtx
14495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14496 return "sal{l}\t%k0";
14497 else
14498 return "sal{l}\t{%2, %k0|%k0, %2}";
14499 }
14500 }
14501 [(set (attr "type")
14502 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14503 (match_operand 2 "const1_operand"))
14504 (const_string "alu")
14505 ]
14506 (const_string "ishift")))
14507 (set (attr "length_immediate")
14508 (if_then_else
14509 (ior (eq_attr "type" "alu")
14510 (and (eq_attr "type" "ishift")
14511 (and (match_operand 2 "const1_operand")
14512 (ior (match_test "TARGET_SHIFT1")
14513 (match_test "optimize_function_for_size_p (cfun)")))))
14514 (const_string "0")
14515 (const_string "*")))
14516 (set_attr "mode" "SI")])
14517
14518 (define_insn "*ashl<mode>3_cconly"
14519 [(set (reg FLAGS_REG)
14520 (compare
14521 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14522 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14523 (const_int 0)))
14524 (clobber (match_scratch:SWI 0 "=<r>"))]
14525 "(optimize_function_for_size_p (cfun)
14526 || !TARGET_PARTIAL_FLAG_REG_STALL
14527 || (operands[2] == const1_rtx
14528 && (TARGET_SHIFT1
14529 || TARGET_DOUBLE_WITH_ADD)))
14530 && ix86_match_ccmode (insn, CCGOCmode)"
14531 {
14532 switch (get_attr_type (insn))
14533 {
14534 case TYPE_ALU:
14535 gcc_assert (operands[2] == const1_rtx);
14536 return "add{<imodesuffix>}\t%0, %0";
14537
14538 default:
14539 if (operands[2] == const1_rtx
14540 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14541 return "sal{<imodesuffix>}\t%0";
14542 else
14543 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14544 }
14545 }
14546 [(set (attr "type")
14547 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14548 (match_operand 0 "register_operand"))
14549 (match_operand 2 "const1_operand"))
14550 (const_string "alu")
14551 ]
14552 (const_string "ishift")))
14553 (set (attr "length_immediate")
14554 (if_then_else
14555 (ior (eq_attr "type" "alu")
14556 (and (eq_attr "type" "ishift")
14557 (and (match_operand 2 "const1_operand")
14558 (ior (match_test "TARGET_SHIFT1")
14559 (match_test "optimize_function_for_size_p (cfun)")))))
14560 (const_string "0")
14561 (const_string "*")))
14562 (set_attr "mode" "<MODE>")])
14563
14564 (define_insn "*ashlqi_ext<mode>_2"
14565 [(set (zero_extract:SWI248
14566 (match_operand 0 "int248_register_operand" "+Q")
14567 (const_int 8)
14568 (const_int 8))
14569 (subreg:SWI248
14570 (ashift:QI
14571 (subreg:QI
14572 (match_operator:SWI248 3 "extract_operator"
14573 [(match_operand 1 "int248_register_operand" "0")
14574 (const_int 8)
14575 (const_int 8)]) 0)
14576 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14577 (clobber (reg:CC FLAGS_REG))]
14578 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14579 rtx_equal_p (operands[0], operands[1])"
14580 {
14581 switch (get_attr_type (insn))
14582 {
14583 case TYPE_ALU:
14584 gcc_assert (operands[2] == const1_rtx);
14585 return "add{b}\t%h0, %h0";
14586
14587 default:
14588 if (operands[2] == const1_rtx
14589 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14590 return "sal{b}\t%h0";
14591 else
14592 return "sal{b}\t{%2, %h0|%h0, %2}";
14593 }
14594 }
14595 [(set (attr "type")
14596 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14597 (match_operand 2 "const1_operand"))
14598 (const_string "alu")
14599 ]
14600 (const_string "ishift")))
14601 (set (attr "length_immediate")
14602 (if_then_else
14603 (ior (eq_attr "type" "alu")
14604 (and (eq_attr "type" "ishift")
14605 (and (match_operand 2 "const1_operand")
14606 (ior (match_test "TARGET_SHIFT1")
14607 (match_test "optimize_function_for_size_p (cfun)")))))
14608 (const_string "0")
14609 (const_string "*")))
14610 (set_attr "mode" "QI")])
14611
14612 ;; See comment above `ashl<mode>3' about how this works.
14613
14614 (define_expand "<insn><mode>3"
14615 [(set (match_operand:SDWIM 0 "<shift_operand>")
14616 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14617 (match_operand:QI 2 "nonmemory_operand")))]
14618 ""
14619 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14620
14621 ;; Avoid useless masking of count operand.
14622 (define_insn_and_split "*<insn><mode>3_mask"
14623 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14624 (any_shiftrt:SWI48
14625 (match_operand:SWI48 1 "nonimmediate_operand")
14626 (subreg:QI
14627 (and
14628 (match_operand 2 "int248_register_operand" "c,r")
14629 (match_operand 3 "const_int_operand")) 0)))
14630 (clobber (reg:CC FLAGS_REG))]
14631 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14632 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14633 == GET_MODE_BITSIZE (<MODE>mode)-1
14634 && ix86_pre_reload_split ()"
14635 "#"
14636 "&& 1"
14637 [(parallel
14638 [(set (match_dup 0)
14639 (any_shiftrt:SWI48 (match_dup 1)
14640 (match_dup 2)))
14641 (clobber (reg:CC FLAGS_REG))])]
14642 {
14643 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14644 operands[2] = gen_lowpart (QImode, operands[2]);
14645 }
14646 [(set_attr "isa" "*,bmi2")])
14647
14648 (define_insn_and_split "*<insn><mode>3_mask_1"
14649 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14650 (any_shiftrt:SWI48
14651 (match_operand:SWI48 1 "nonimmediate_operand")
14652 (and:QI
14653 (match_operand:QI 2 "register_operand" "c,r")
14654 (match_operand:QI 3 "const_int_operand"))))
14655 (clobber (reg:CC FLAGS_REG))]
14656 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14657 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14658 == GET_MODE_BITSIZE (<MODE>mode)-1
14659 && ix86_pre_reload_split ()"
14660 "#"
14661 "&& 1"
14662 [(parallel
14663 [(set (match_dup 0)
14664 (any_shiftrt:SWI48 (match_dup 1)
14665 (match_dup 2)))
14666 (clobber (reg:CC FLAGS_REG))])]
14667 ""
14668 [(set_attr "isa" "*,bmi2")])
14669
14670 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14671 [(set (match_operand:<DWI> 0 "register_operand")
14672 (any_shiftrt:<DWI>
14673 (match_operand:<DWI> 1 "register_operand")
14674 (subreg:QI
14675 (and
14676 (match_operand 2 "int248_register_operand" "c")
14677 (match_operand 3 "const_int_operand")) 0)))
14678 (clobber (reg:CC FLAGS_REG))]
14679 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14680 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14681 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14682 && ix86_pre_reload_split ()"
14683 "#"
14684 "&& 1"
14685 [(parallel
14686 [(set (match_dup 4)
14687 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14688 (and:QI (match_dup 2) (match_dup 8)))
14689 (subreg:DWIH
14690 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14691 (minus:QI (match_dup 9)
14692 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14693 (clobber (reg:CC FLAGS_REG))])
14694 (parallel
14695 [(set (match_dup 6)
14696 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14697 (clobber (reg:CC FLAGS_REG))])]
14698 {
14699 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14700 {
14701 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14702 operands[2] = gen_lowpart (QImode, operands[2]);
14703 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14704 operands[2]));
14705 DONE;
14706 }
14707
14708 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14709
14710 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14711 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14712
14713 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14714 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14715 {
14716 rtx xops[3];
14717 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14718 xops[1] = operands[2];
14719 xops[2] = GEN_INT (INTVAL (operands[3])
14720 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14721 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14722 operands[2] = xops[0];
14723 }
14724
14725 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14726 operands[2] = gen_lowpart (QImode, operands[2]);
14727
14728 if (!rtx_equal_p (operands[4], operands[5]))
14729 emit_move_insn (operands[4], operands[5]);
14730 })
14731
14732 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14733 [(set (match_operand:<DWI> 0 "register_operand")
14734 (any_shiftrt:<DWI>
14735 (match_operand:<DWI> 1 "register_operand")
14736 (and:QI
14737 (match_operand:QI 2 "register_operand" "c")
14738 (match_operand:QI 3 "const_int_operand"))))
14739 (clobber (reg:CC FLAGS_REG))]
14740 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14741 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14742 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14743 && ix86_pre_reload_split ()"
14744 "#"
14745 "&& 1"
14746 [(parallel
14747 [(set (match_dup 4)
14748 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14749 (and:QI (match_dup 2) (match_dup 8)))
14750 (subreg:DWIH
14751 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14752 (minus:QI (match_dup 9)
14753 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14754 (clobber (reg:CC FLAGS_REG))])
14755 (parallel
14756 [(set (match_dup 6)
14757 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14758 (clobber (reg:CC FLAGS_REG))])]
14759 {
14760 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14761 {
14762 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14763 operands[2]));
14764 DONE;
14765 }
14766
14767 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14768
14769 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14770 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14771
14772 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14773 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14774 {
14775 rtx tem = gen_reg_rtx (QImode);
14776 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14777 operands[2] = tem;
14778 }
14779
14780 if (!rtx_equal_p (operands[4], operands[5]))
14781 emit_move_insn (operands[4], operands[5]);
14782 })
14783
14784 (define_insn_and_split "<insn><mode>3_doubleword"
14785 [(set (match_operand:DWI 0 "register_operand" "=&r")
14786 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14787 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14788 (clobber (reg:CC FLAGS_REG))]
14789 ""
14790 "#"
14791 "epilogue_completed"
14792 [(const_int 0)]
14793 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14794 [(set_attr "type" "multi")])
14795
14796 ;; By default we don't ask for a scratch register, because when DWImode
14797 ;; values are manipulated, registers are already at a premium. But if
14798 ;; we have one handy, we won't turn it away.
14799
14800 (define_peephole2
14801 [(match_scratch:DWIH 3 "r")
14802 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14803 (any_shiftrt:<DWI>
14804 (match_operand:<DWI> 1 "register_operand")
14805 (match_operand:QI 2 "nonmemory_operand")))
14806 (clobber (reg:CC FLAGS_REG))])
14807 (match_dup 3)]
14808 "TARGET_CMOVE"
14809 [(const_int 0)]
14810 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14811
14812 (define_insn "x86_64_shrd"
14813 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14814 (ior:DI (lshiftrt:DI (match_dup 0)
14815 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14816 (const_int 63)))
14817 (subreg:DI
14818 (ashift:TI
14819 (zero_extend:TI
14820 (match_operand:DI 1 "register_operand" "r"))
14821 (minus:QI (const_int 64)
14822 (and:QI (match_dup 2) (const_int 63)))) 0)))
14823 (clobber (reg:CC FLAGS_REG))]
14824 "TARGET_64BIT"
14825 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14826 [(set_attr "type" "ishift")
14827 (set_attr "prefix_0f" "1")
14828 (set_attr "mode" "DI")
14829 (set_attr "athlon_decode" "vector")
14830 (set_attr "amdfam10_decode" "vector")
14831 (set_attr "bdver1_decode" "vector")])
14832
14833 (define_insn "x86_64_shrd_1"
14834 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14835 (ior:DI (lshiftrt:DI (match_dup 0)
14836 (match_operand:QI 2 "const_0_to_63_operand"))
14837 (subreg:DI
14838 (ashift:TI
14839 (zero_extend:TI
14840 (match_operand:DI 1 "register_operand" "r"))
14841 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14842 (clobber (reg:CC FLAGS_REG))]
14843 "TARGET_64BIT
14844 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14845 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14846 [(set_attr "type" "ishift")
14847 (set_attr "prefix_0f" "1")
14848 (set_attr "length_immediate" "1")
14849 (set_attr "mode" "DI")
14850 (set_attr "athlon_decode" "vector")
14851 (set_attr "amdfam10_decode" "vector")
14852 (set_attr "bdver1_decode" "vector")])
14853
14854 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14855 [(set (match_operand:DI 0 "nonimmediate_operand")
14856 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14857 (match_operand:QI 2 "const_0_to_63_operand"))
14858 (ashift:DI
14859 (match_operand:DI 1 "nonimmediate_operand")
14860 (match_operand:QI 3 "const_0_to_63_operand"))))
14861 (clobber (reg:CC FLAGS_REG))]
14862 "TARGET_64BIT
14863 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14864 && ix86_pre_reload_split ()"
14865 "#"
14866 "&& 1"
14867 [(const_int 0)]
14868 {
14869 if (rtx_equal_p (operands[4], operands[0]))
14870 {
14871 operands[1] = force_reg (DImode, operands[1]);
14872 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14873 }
14874 else if (rtx_equal_p (operands[1], operands[0]))
14875 {
14876 operands[4] = force_reg (DImode, operands[4]);
14877 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14878 }
14879 else
14880 {
14881 operands[1] = force_reg (DImode, operands[1]);
14882 rtx tmp = gen_reg_rtx (DImode);
14883 emit_move_insn (tmp, operands[4]);
14884 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14885 emit_move_insn (operands[0], tmp);
14886 }
14887 DONE;
14888 })
14889
14890 (define_insn_and_split "*x86_64_shrd_2"
14891 [(set (match_operand:DI 0 "nonimmediate_operand")
14892 (ior:DI (lshiftrt:DI (match_dup 0)
14893 (match_operand:QI 2 "nonmemory_operand"))
14894 (ashift:DI (match_operand:DI 1 "register_operand")
14895 (minus:QI (const_int 64) (match_dup 2)))))
14896 (clobber (reg:CC FLAGS_REG))]
14897 "TARGET_64BIT && ix86_pre_reload_split ()"
14898 "#"
14899 "&& 1"
14900 [(parallel [(set (match_dup 0)
14901 (ior:DI (lshiftrt:DI (match_dup 0)
14902 (and:QI (match_dup 2) (const_int 63)))
14903 (subreg:DI
14904 (ashift:TI
14905 (zero_extend:TI (match_dup 1))
14906 (minus:QI (const_int 64)
14907 (and:QI (match_dup 2)
14908 (const_int 63)))) 0)))
14909 (clobber (reg:CC FLAGS_REG))])])
14910
14911 (define_insn "x86_shrd"
14912 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14913 (ior:SI (lshiftrt:SI (match_dup 0)
14914 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14915 (const_int 31)))
14916 (subreg:SI
14917 (ashift:DI
14918 (zero_extend:DI
14919 (match_operand:SI 1 "register_operand" "r"))
14920 (minus:QI (const_int 32)
14921 (and:QI (match_dup 2) (const_int 31)))) 0)))
14922 (clobber (reg:CC FLAGS_REG))]
14923 ""
14924 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14925 [(set_attr "type" "ishift")
14926 (set_attr "prefix_0f" "1")
14927 (set_attr "mode" "SI")
14928 (set_attr "pent_pair" "np")
14929 (set_attr "athlon_decode" "vector")
14930 (set_attr "amdfam10_decode" "vector")
14931 (set_attr "bdver1_decode" "vector")])
14932
14933 (define_insn "x86_shrd_1"
14934 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14935 (ior:SI (lshiftrt:SI (match_dup 0)
14936 (match_operand:QI 2 "const_0_to_31_operand"))
14937 (subreg:SI
14938 (ashift:DI
14939 (zero_extend:DI
14940 (match_operand:SI 1 "register_operand" "r"))
14941 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14942 (clobber (reg:CC FLAGS_REG))]
14943 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14944 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14945 [(set_attr "type" "ishift")
14946 (set_attr "prefix_0f" "1")
14947 (set_attr "length_immediate" "1")
14948 (set_attr "mode" "SI")
14949 (set_attr "pent_pair" "np")
14950 (set_attr "athlon_decode" "vector")
14951 (set_attr "amdfam10_decode" "vector")
14952 (set_attr "bdver1_decode" "vector")])
14953
14954 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14955 [(set (match_operand:SI 0 "nonimmediate_operand")
14956 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14957 (match_operand:QI 2 "const_0_to_31_operand"))
14958 (ashift:SI
14959 (match_operand:SI 1 "nonimmediate_operand")
14960 (match_operand:QI 3 "const_0_to_31_operand"))))
14961 (clobber (reg:CC FLAGS_REG))]
14962 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14963 && ix86_pre_reload_split ()"
14964 "#"
14965 "&& 1"
14966 [(const_int 0)]
14967 {
14968 if (rtx_equal_p (operands[4], operands[0]))
14969 {
14970 operands[1] = force_reg (SImode, operands[1]);
14971 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14972 }
14973 else if (rtx_equal_p (operands[1], operands[0]))
14974 {
14975 operands[4] = force_reg (SImode, operands[4]);
14976 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14977 }
14978 else
14979 {
14980 operands[1] = force_reg (SImode, operands[1]);
14981 rtx tmp = gen_reg_rtx (SImode);
14982 emit_move_insn (tmp, operands[4]);
14983 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14984 emit_move_insn (operands[0], tmp);
14985 }
14986 DONE;
14987 })
14988
14989 (define_insn_and_split "*x86_shrd_2"
14990 [(set (match_operand:SI 0 "nonimmediate_operand")
14991 (ior:SI (lshiftrt:SI (match_dup 0)
14992 (match_operand:QI 2 "nonmemory_operand"))
14993 (ashift:SI (match_operand:SI 1 "register_operand")
14994 (minus:QI (const_int 32) (match_dup 2)))))
14995 (clobber (reg:CC FLAGS_REG))]
14996 "TARGET_64BIT && ix86_pre_reload_split ()"
14997 "#"
14998 "&& 1"
14999 [(parallel [(set (match_dup 0)
15000 (ior:SI (lshiftrt:SI (match_dup 0)
15001 (and:QI (match_dup 2) (const_int 31)))
15002 (subreg:SI
15003 (ashift:DI
15004 (zero_extend:DI (match_dup 1))
15005 (minus:QI (const_int 32)
15006 (and:QI (match_dup 2)
15007 (const_int 31)))) 0)))
15008 (clobber (reg:CC FLAGS_REG))])])
15009
15010 ;; Base name for insn mnemonic.
15011 (define_mode_attr cvt_mnemonic
15012 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
15013
15014 (define_insn "ashr<mode>3_cvt"
15015 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
15016 (ashiftrt:SWI48
15017 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
15018 (match_operand:QI 2 "const_int_operand")))
15019 (clobber (reg:CC FLAGS_REG))]
15020 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
15021 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15022 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15023 "@
15024 <cvt_mnemonic>
15025 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
15026 [(set_attr "type" "imovx,ishift")
15027 (set_attr "prefix_0f" "0,*")
15028 (set_attr "length_immediate" "0,*")
15029 (set_attr "modrm" "0,1")
15030 (set_attr "mode" "<MODE>")])
15031
15032 (define_insn "*ashrsi3_cvt_zext"
15033 [(set (match_operand:DI 0 "register_operand" "=*d,r")
15034 (zero_extend:DI
15035 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
15036 (match_operand:QI 2 "const_int_operand"))))
15037 (clobber (reg:CC FLAGS_REG))]
15038 "TARGET_64BIT && INTVAL (operands[2]) == 31
15039 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15040 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
15041 "@
15042 {cltd|cdq}
15043 sar{l}\t{%2, %k0|%k0, %2}"
15044 [(set_attr "type" "imovx,ishift")
15045 (set_attr "prefix_0f" "0,*")
15046 (set_attr "length_immediate" "0,*")
15047 (set_attr "modrm" "0,1")
15048 (set_attr "mode" "SI")])
15049
15050 (define_expand "@x86_shift<mode>_adj_3"
15051 [(use (match_operand:SWI48 0 "register_operand"))
15052 (use (match_operand:SWI48 1 "register_operand"))
15053 (use (match_operand:QI 2 "register_operand"))]
15054 ""
15055 {
15056 rtx_code_label *label = gen_label_rtx ();
15057 rtx tmp;
15058
15059 emit_insn (gen_testqi_ccz_1 (operands[2],
15060 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15061
15062 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15063 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15064 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15065 gen_rtx_LABEL_REF (VOIDmode, label),
15066 pc_rtx);
15067 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15068 JUMP_LABEL (tmp) = label;
15069
15070 emit_move_insn (operands[0], operands[1]);
15071 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
15072 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
15073 emit_label (label);
15074 LABEL_NUSES (label) = 1;
15075
15076 DONE;
15077 })
15078
15079 (define_insn "*bmi2_<insn><mode>3_1"
15080 [(set (match_operand:SWI48 0 "register_operand" "=r")
15081 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15082 (match_operand:SWI48 2 "register_operand" "r")))]
15083 "TARGET_BMI2"
15084 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
15085 [(set_attr "type" "ishiftx")
15086 (set_attr "mode" "<MODE>")])
15087
15088 (define_insn "*ashr<mode>3_1"
15089 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15090 (ashiftrt:SWI48
15091 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15092 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
15093 (clobber (reg:CC FLAGS_REG))]
15094 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15095 {
15096 switch (get_attr_type (insn))
15097 {
15098 case TYPE_ISHIFTX:
15099 return "#";
15100
15101 default:
15102 if (operands[2] == const1_rtx
15103 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15104 return "sar{<imodesuffix>}\t%0";
15105 else
15106 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15107 }
15108 }
15109 [(set_attr "isa" "*,bmi2")
15110 (set_attr "type" "ishift,ishiftx")
15111 (set (attr "length_immediate")
15112 (if_then_else
15113 (and (match_operand 2 "const1_operand")
15114 (ior (match_test "TARGET_SHIFT1")
15115 (match_test "optimize_function_for_size_p (cfun)")))
15116 (const_string "0")
15117 (const_string "*")))
15118 (set_attr "mode" "<MODE>")])
15119
15120 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15121 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15122 (define_insn_and_split "*highpartdisi2"
15123 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15124 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15125 (const_int 32)))
15126 (clobber (reg:CC FLAGS_REG))]
15127 "TARGET_64BIT"
15128 "#"
15129 "&& reload_completed"
15130 [(parallel
15131 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15132 (clobber (reg:CC FLAGS_REG))])]
15133 {
15134 if (SSE_REG_P (operands[0]))
15135 {
15136 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15137 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15138 const1_rtx, const1_rtx,
15139 GEN_INT (5), GEN_INT (5)));
15140 DONE;
15141 }
15142 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15143 })
15144
15145 (define_insn "*lshr<mode>3_1"
15146 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15147 (lshiftrt:SWI48
15148 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15149 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15150 (clobber (reg:CC FLAGS_REG))]
15151 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15152 {
15153 switch (get_attr_type (insn))
15154 {
15155 case TYPE_ISHIFTX:
15156 case TYPE_MSKLOG:
15157 return "#";
15158
15159 default:
15160 if (operands[2] == const1_rtx
15161 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15162 return "shr{<imodesuffix>}\t%0";
15163 else
15164 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15165 }
15166 }
15167 [(set_attr "isa" "*,bmi2,<kmov_isa>")
15168 (set_attr "type" "ishift,ishiftx,msklog")
15169 (set (attr "length_immediate")
15170 (if_then_else
15171 (and (and (match_operand 2 "const1_operand")
15172 (eq_attr "alternative" "0"))
15173 (ior (match_test "TARGET_SHIFT1")
15174 (match_test "optimize_function_for_size_p (cfun)")))
15175 (const_string "0")
15176 (const_string "*")))
15177 (set_attr "mode" "<MODE>")])
15178
15179 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15180 (define_split
15181 [(set (match_operand:SWI48 0 "register_operand")
15182 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15183 (match_operand:QI 2 "register_operand")))
15184 (clobber (reg:CC FLAGS_REG))]
15185 "TARGET_BMI2 && reload_completed"
15186 [(set (match_dup 0)
15187 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15188 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15189
15190 (define_insn "*bmi2_<insn>si3_1_zext"
15191 [(set (match_operand:DI 0 "register_operand" "=r")
15192 (zero_extend:DI
15193 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15194 (match_operand:SI 2 "register_operand" "r"))))]
15195 "TARGET_64BIT && TARGET_BMI2"
15196 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15197 [(set_attr "type" "ishiftx")
15198 (set_attr "mode" "SI")])
15199
15200 (define_insn "*<insn>si3_1_zext"
15201 [(set (match_operand:DI 0 "register_operand" "=r,r")
15202 (zero_extend:DI
15203 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15204 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15205 (clobber (reg:CC FLAGS_REG))]
15206 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15207 {
15208 switch (get_attr_type (insn))
15209 {
15210 case TYPE_ISHIFTX:
15211 return "#";
15212
15213 default:
15214 if (operands[2] == const1_rtx
15215 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15216 return "<shift>{l}\t%k0";
15217 else
15218 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15219 }
15220 }
15221 [(set_attr "isa" "*,bmi2")
15222 (set_attr "type" "ishift,ishiftx")
15223 (set (attr "length_immediate")
15224 (if_then_else
15225 (and (match_operand 2 "const1_operand")
15226 (ior (match_test "TARGET_SHIFT1")
15227 (match_test "optimize_function_for_size_p (cfun)")))
15228 (const_string "0")
15229 (const_string "*")))
15230 (set_attr "mode" "SI")])
15231
15232 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15233 (define_split
15234 [(set (match_operand:DI 0 "register_operand")
15235 (zero_extend:DI
15236 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15237 (match_operand:QI 2 "register_operand"))))
15238 (clobber (reg:CC FLAGS_REG))]
15239 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15240 [(set (match_dup 0)
15241 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15242 "operands[2] = gen_lowpart (SImode, operands[2]);")
15243
15244 (define_insn "*ashr<mode>3_1"
15245 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15246 (ashiftrt:SWI12
15247 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15248 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15249 (clobber (reg:CC FLAGS_REG))]
15250 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15251 {
15252 if (operands[2] == const1_rtx
15253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15254 return "sar{<imodesuffix>}\t%0";
15255 else
15256 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15257 }
15258 [(set_attr "type" "ishift")
15259 (set (attr "length_immediate")
15260 (if_then_else
15261 (and (match_operand 2 "const1_operand")
15262 (ior (match_test "TARGET_SHIFT1")
15263 (match_test "optimize_function_for_size_p (cfun)")))
15264 (const_string "0")
15265 (const_string "*")))
15266 (set_attr "mode" "<MODE>")])
15267
15268 (define_insn "*lshrqi3_1"
15269 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15270 (lshiftrt:QI
15271 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15272 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15273 (clobber (reg:CC FLAGS_REG))]
15274 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15275 {
15276 switch (get_attr_type (insn))
15277 {
15278 case TYPE_ISHIFT:
15279 if (operands[2] == const1_rtx
15280 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15281 return "shr{b}\t%0";
15282 else
15283 return "shr{b}\t{%2, %0|%0, %2}";
15284 case TYPE_MSKLOG:
15285 return "#";
15286 default:
15287 gcc_unreachable ();
15288 }
15289 }
15290 [(set_attr "isa" "*,avx512dq")
15291 (set_attr "type" "ishift,msklog")
15292 (set (attr "length_immediate")
15293 (if_then_else
15294 (and (and (match_operand 2 "const1_operand")
15295 (eq_attr "alternative" "0"))
15296 (ior (match_test "TARGET_SHIFT1")
15297 (match_test "optimize_function_for_size_p (cfun)")))
15298 (const_string "0")
15299 (const_string "*")))
15300 (set_attr "mode" "QI")])
15301
15302 (define_insn "*lshrhi3_1"
15303 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15304 (lshiftrt:HI
15305 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15306 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15307 (clobber (reg:CC FLAGS_REG))]
15308 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15309 {
15310 switch (get_attr_type (insn))
15311 {
15312 case TYPE_ISHIFT:
15313 if (operands[2] == const1_rtx
15314 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15315 return "shr{w}\t%0";
15316 else
15317 return "shr{w}\t{%2, %0|%0, %2}";
15318 case TYPE_MSKLOG:
15319 return "#";
15320 default:
15321 gcc_unreachable ();
15322 }
15323 }
15324 [(set_attr "isa" "*, avx512f")
15325 (set_attr "type" "ishift,msklog")
15326 (set (attr "length_immediate")
15327 (if_then_else
15328 (and (and (match_operand 2 "const1_operand")
15329 (eq_attr "alternative" "0"))
15330 (ior (match_test "TARGET_SHIFT1")
15331 (match_test "optimize_function_for_size_p (cfun)")))
15332 (const_string "0")
15333 (const_string "*")))
15334 (set_attr "mode" "HI")])
15335
15336 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15337 (define_insn_and_split "*<insn><mode>3_1_slp"
15338 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15339 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15340 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15341 (clobber (reg:CC FLAGS_REG))]
15342 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15343 {
15344 if (which_alternative)
15345 return "#";
15346
15347 if (operands[2] == const1_rtx
15348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15349 return "<shift>{<imodesuffix>}\t%0";
15350 else
15351 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15352 }
15353 "&& reload_completed"
15354 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15355 (parallel
15356 [(set (strict_low_part (match_dup 0))
15357 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15358 (clobber (reg:CC FLAGS_REG))])]
15359 ""
15360 [(set_attr "type" "ishift")
15361 (set (attr "length_immediate")
15362 (if_then_else
15363 (and (match_operand 2 "const1_operand")
15364 (ior (match_test "TARGET_SHIFT1")
15365 (match_test "optimize_function_for_size_p (cfun)")))
15366 (const_string "0")
15367 (const_string "*")))
15368 (set_attr "mode" "<MODE>")])
15369
15370 ;; This pattern can't accept a variable shift count, since shifts by
15371 ;; zero don't affect the flags. We assume that shifts by constant
15372 ;; zero are optimized away.
15373 (define_insn "*<insn><mode>3_cmp"
15374 [(set (reg FLAGS_REG)
15375 (compare
15376 (any_shiftrt:SWI
15377 (match_operand:SWI 1 "nonimmediate_operand" "0")
15378 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15379 (const_int 0)))
15380 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15381 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15382 "(optimize_function_for_size_p (cfun)
15383 || !TARGET_PARTIAL_FLAG_REG_STALL
15384 || (operands[2] == const1_rtx
15385 && TARGET_SHIFT1))
15386 && ix86_match_ccmode (insn, CCGOCmode)
15387 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15388 {
15389 if (operands[2] == const1_rtx
15390 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15391 return "<shift>{<imodesuffix>}\t%0";
15392 else
15393 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15394 }
15395 [(set_attr "type" "ishift")
15396 (set (attr "length_immediate")
15397 (if_then_else
15398 (and (match_operand 2 "const1_operand")
15399 (ior (match_test "TARGET_SHIFT1")
15400 (match_test "optimize_function_for_size_p (cfun)")))
15401 (const_string "0")
15402 (const_string "*")))
15403 (set_attr "mode" "<MODE>")])
15404
15405 (define_insn "*<insn>si3_cmp_zext"
15406 [(set (reg FLAGS_REG)
15407 (compare
15408 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15409 (match_operand:QI 2 "const_1_to_31_operand"))
15410 (const_int 0)))
15411 (set (match_operand:DI 0 "register_operand" "=r")
15412 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15413 "TARGET_64BIT
15414 && (optimize_function_for_size_p (cfun)
15415 || !TARGET_PARTIAL_FLAG_REG_STALL
15416 || (operands[2] == const1_rtx
15417 && TARGET_SHIFT1))
15418 && ix86_match_ccmode (insn, CCGOCmode)
15419 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15420 {
15421 if (operands[2] == const1_rtx
15422 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15423 return "<shift>{l}\t%k0";
15424 else
15425 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15426 }
15427 [(set_attr "type" "ishift")
15428 (set (attr "length_immediate")
15429 (if_then_else
15430 (and (match_operand 2 "const1_operand")
15431 (ior (match_test "TARGET_SHIFT1")
15432 (match_test "optimize_function_for_size_p (cfun)")))
15433 (const_string "0")
15434 (const_string "*")))
15435 (set_attr "mode" "SI")])
15436
15437 (define_insn "*<insn><mode>3_cconly"
15438 [(set (reg FLAGS_REG)
15439 (compare
15440 (any_shiftrt:SWI
15441 (match_operand:SWI 1 "register_operand" "0")
15442 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15443 (const_int 0)))
15444 (clobber (match_scratch:SWI 0 "=<r>"))]
15445 "(optimize_function_for_size_p (cfun)
15446 || !TARGET_PARTIAL_FLAG_REG_STALL
15447 || (operands[2] == const1_rtx
15448 && TARGET_SHIFT1))
15449 && ix86_match_ccmode (insn, CCGOCmode)"
15450 {
15451 if (operands[2] == const1_rtx
15452 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15453 return "<shift>{<imodesuffix>}\t%0";
15454 else
15455 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15456 }
15457 [(set_attr "type" "ishift")
15458 (set (attr "length_immediate")
15459 (if_then_else
15460 (and (match_operand 2 "const1_operand")
15461 (ior (match_test "TARGET_SHIFT1")
15462 (match_test "optimize_function_for_size_p (cfun)")))
15463 (const_string "0")
15464 (const_string "*")))
15465 (set_attr "mode" "<MODE>")])
15466
15467 (define_insn "*<insn>qi_ext<mode>_2"
15468 [(set (zero_extract:SWI248
15469 (match_operand 0 "int248_register_operand" "+Q")
15470 (const_int 8)
15471 (const_int 8))
15472 (subreg:SWI248
15473 (any_shiftrt:QI
15474 (subreg:QI
15475 (match_operator:SWI248 3 "extract_operator"
15476 [(match_operand 1 "int248_register_operand" "0")
15477 (const_int 8)
15478 (const_int 8)]) 0)
15479 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15480 (clobber (reg:CC FLAGS_REG))]
15481 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15482 rtx_equal_p (operands[0], operands[1])"
15483 {
15484 if (operands[2] == const1_rtx
15485 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15486 return "<shift>{b}\t%h0";
15487 else
15488 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15489 }
15490 [(set_attr "type" "ishift")
15491 (set (attr "length_immediate")
15492 (if_then_else
15493 (and (match_operand 2 "const1_operand")
15494 (ior (match_test "TARGET_SHIFT1")
15495 (match_test "optimize_function_for_size_p (cfun)")))
15496 (const_string "0")
15497 (const_string "*")))
15498 (set_attr "mode" "QI")])
15499
15500 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15501 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15502 (ashiftrt:<DWI>
15503 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15504 (match_operand:QI 2 "const_int_operand"))
15505 (match_operand:QI 3 "const_int_operand")))
15506 (clobber (reg:CC FLAGS_REG))]
15507 "INTVAL (operands[2]) == INTVAL (operands[3])
15508 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15509 "#"
15510 "&& reload_completed"
15511 [(parallel [(set (match_dup 4)
15512 (ashift:DWIH (match_dup 4) (match_dup 2)))
15513 (clobber (reg:CC FLAGS_REG))])
15514 (parallel [(set (match_dup 4)
15515 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15516 (clobber (reg:CC FLAGS_REG))])]
15517 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15518
15519 (define_insn_and_split "*extendv2di2_highpart_stv"
15520 [(set (match_operand:V2DI 0 "register_operand" "=v")
15521 (ashiftrt:V2DI
15522 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15523 (match_operand:QI 2 "const_int_operand"))
15524 (match_operand:QI 3 "const_int_operand")))]
15525 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15526 && INTVAL (operands[2]) == INTVAL (operands[3])
15527 && UINTVAL (operands[2]) < 32"
15528 "#"
15529 "&& reload_completed"
15530 [(set (match_dup 0)
15531 (ashift:V2DI (match_dup 1) (match_dup 2)))
15532 (set (match_dup 0)
15533 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15534 \f
15535 ;; Rotate instructions
15536
15537 (define_expand "<insn>ti3"
15538 [(set (match_operand:TI 0 "register_operand")
15539 (any_rotate:TI (match_operand:TI 1 "register_operand")
15540 (match_operand:QI 2 "nonmemory_operand")))]
15541 "TARGET_64BIT"
15542 {
15543 if (const_1_to_63_operand (operands[2], VOIDmode))
15544 emit_insn (gen_ix86_<insn>ti3_doubleword
15545 (operands[0], operands[1], operands[2]));
15546 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15547 {
15548 operands[1] = force_reg (TImode, operands[1]);
15549 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15550 }
15551 else
15552 {
15553 rtx amount = force_reg (QImode, operands[2]);
15554 rtx src_lo = gen_lowpart (DImode, operands[1]);
15555 rtx src_hi = gen_highpart (DImode, operands[1]);
15556 rtx tmp_lo = gen_reg_rtx (DImode);
15557 rtx tmp_hi = gen_reg_rtx (DImode);
15558 emit_move_insn (tmp_lo, src_lo);
15559 emit_move_insn (tmp_hi, src_hi);
15560 rtx (*shiftd) (rtx, rtx, rtx)
15561 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15562 emit_insn (shiftd (tmp_lo, src_hi, amount));
15563 emit_insn (shiftd (tmp_hi, src_lo, amount));
15564 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15565 rtx dst_hi = gen_highpart (DImode, operands[0]);
15566 emit_move_insn (dst_lo, tmp_lo);
15567 emit_move_insn (dst_hi, tmp_hi);
15568 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15569 }
15570 DONE;
15571 })
15572
15573 (define_expand "<insn>di3"
15574 [(set (match_operand:DI 0 "shiftdi_operand")
15575 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15576 (match_operand:QI 2 "nonmemory_operand")))]
15577 ""
15578 {
15579 if (TARGET_64BIT)
15580 ix86_expand_binary_operator (<CODE>, DImode, operands);
15581 else if (const_1_to_31_operand (operands[2], VOIDmode))
15582 emit_insn (gen_ix86_<insn>di3_doubleword
15583 (operands[0], operands[1], operands[2]));
15584 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15585 {
15586 operands[1] = force_reg (DImode, operands[1]);
15587 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15588 }
15589 else
15590 FAIL;
15591
15592 DONE;
15593 })
15594
15595 (define_expand "<insn><mode>3"
15596 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15597 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15598 (match_operand:QI 2 "nonmemory_operand")))]
15599 ""
15600 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15601
15602 ;; Avoid useless masking of count operand.
15603 (define_insn_and_split "*<insn><mode>3_mask"
15604 [(set (match_operand:SWI 0 "nonimmediate_operand")
15605 (any_rotate:SWI
15606 (match_operand:SWI 1 "nonimmediate_operand")
15607 (subreg:QI
15608 (and
15609 (match_operand 2 "int248_register_operand" "c")
15610 (match_operand 3 "const_int_operand")) 0)))
15611 (clobber (reg:CC FLAGS_REG))]
15612 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15613 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15614 == GET_MODE_BITSIZE (<MODE>mode)-1
15615 && ix86_pre_reload_split ()"
15616 "#"
15617 "&& 1"
15618 [(parallel
15619 [(set (match_dup 0)
15620 (any_rotate:SWI (match_dup 1)
15621 (match_dup 2)))
15622 (clobber (reg:CC FLAGS_REG))])]
15623 {
15624 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15625 operands[2] = gen_lowpart (QImode, operands[2]);
15626 })
15627
15628 (define_split
15629 [(set (match_operand:SWI 0 "register_operand")
15630 (any_rotate:SWI
15631 (match_operand:SWI 1 "const_int_operand")
15632 (subreg:QI
15633 (and
15634 (match_operand 2 "int248_register_operand")
15635 (match_operand 3 "const_int_operand")) 0)))]
15636 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15637 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15638 [(set (match_dup 4) (match_dup 1))
15639 (set (match_dup 0)
15640 (any_rotate:SWI (match_dup 4)
15641 (subreg:QI (match_dup 2) 0)))]
15642 "operands[4] = gen_reg_rtx (<MODE>mode);")
15643
15644 (define_insn_and_split "*<insn><mode>3_mask_1"
15645 [(set (match_operand:SWI 0 "nonimmediate_operand")
15646 (any_rotate:SWI
15647 (match_operand:SWI 1 "nonimmediate_operand")
15648 (and:QI
15649 (match_operand:QI 2 "register_operand" "c")
15650 (match_operand:QI 3 "const_int_operand"))))
15651 (clobber (reg:CC FLAGS_REG))]
15652 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15653 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15654 == GET_MODE_BITSIZE (<MODE>mode)-1
15655 && ix86_pre_reload_split ()"
15656 "#"
15657 "&& 1"
15658 [(parallel
15659 [(set (match_dup 0)
15660 (any_rotate:SWI (match_dup 1)
15661 (match_dup 2)))
15662 (clobber (reg:CC FLAGS_REG))])])
15663
15664 (define_split
15665 [(set (match_operand:SWI 0 "register_operand")
15666 (any_rotate:SWI
15667 (match_operand:SWI 1 "const_int_operand")
15668 (and:QI
15669 (match_operand:QI 2 "register_operand")
15670 (match_operand:QI 3 "const_int_operand"))))]
15671 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15672 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15673 [(set (match_dup 4) (match_dup 1))
15674 (set (match_dup 0)
15675 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15676 "operands[4] = gen_reg_rtx (<MODE>mode);")
15677
15678 ;; Implement rotation using two double-precision
15679 ;; shift instructions and a scratch register.
15680
15681 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15682 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15683 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15684 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15685 (clobber (reg:CC FLAGS_REG))
15686 (clobber (match_scratch:DWIH 3 "=&r"))]
15687 ""
15688 "#"
15689 "reload_completed"
15690 [(set (match_dup 3) (match_dup 4))
15691 (parallel
15692 [(set (match_dup 4)
15693 (ior:DWIH (ashift:DWIH (match_dup 4)
15694 (and:QI (match_dup 2) (match_dup 6)))
15695 (subreg:DWIH
15696 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15697 (minus:QI (match_dup 7)
15698 (and:QI (match_dup 2)
15699 (match_dup 6)))) 0)))
15700 (clobber (reg:CC FLAGS_REG))])
15701 (parallel
15702 [(set (match_dup 5)
15703 (ior:DWIH (ashift:DWIH (match_dup 5)
15704 (and:QI (match_dup 2) (match_dup 6)))
15705 (subreg:DWIH
15706 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15707 (minus:QI (match_dup 7)
15708 (and:QI (match_dup 2)
15709 (match_dup 6)))) 0)))
15710 (clobber (reg:CC FLAGS_REG))])]
15711 {
15712 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15713 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15714
15715 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15716 })
15717
15718 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15719 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15720 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15721 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15722 (clobber (reg:CC FLAGS_REG))
15723 (clobber (match_scratch:DWIH 3 "=&r"))]
15724 ""
15725 "#"
15726 "reload_completed"
15727 [(set (match_dup 3) (match_dup 4))
15728 (parallel
15729 [(set (match_dup 4)
15730 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15731 (and:QI (match_dup 2) (match_dup 6)))
15732 (subreg:DWIH
15733 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15734 (minus:QI (match_dup 7)
15735 (and:QI (match_dup 2)
15736 (match_dup 6)))) 0)))
15737 (clobber (reg:CC FLAGS_REG))])
15738 (parallel
15739 [(set (match_dup 5)
15740 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15741 (and:QI (match_dup 2) (match_dup 6)))
15742 (subreg:DWIH
15743 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15744 (minus:QI (match_dup 7)
15745 (and:QI (match_dup 2)
15746 (match_dup 6)))) 0)))
15747 (clobber (reg:CC FLAGS_REG))])]
15748 {
15749 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15750 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15751
15752 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15753 })
15754
15755 (define_insn_and_split "<insn>32di2_doubleword"
15756 [(set (match_operand:DI 0 "register_operand" "=r,r")
15757 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
15758 (const_int 32)))]
15759 "!TARGET_64BIT"
15760 "#"
15761 "&& reload_completed"
15762 [(set (match_dup 0) (match_dup 3))
15763 (set (match_dup 2) (match_dup 1))]
15764 {
15765 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15766 if (rtx_equal_p (operands[0], operands[1]))
15767 {
15768 emit_insn (gen_swapsi (operands[0], operands[2]));
15769 DONE;
15770 }
15771 })
15772
15773 (define_insn_and_split "<insn>64ti2_doubleword"
15774 [(set (match_operand:TI 0 "register_operand" "=r,r")
15775 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
15776 (const_int 64)))]
15777 "TARGET_64BIT"
15778 "#"
15779 "&& reload_completed"
15780 [(set (match_dup 0) (match_dup 3))
15781 (set (match_dup 2) (match_dup 1))]
15782 {
15783 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15784 if (rtx_equal_p (operands[0], operands[1]))
15785 {
15786 emit_insn (gen_swapdi (operands[0], operands[2]));
15787 DONE;
15788 }
15789 })
15790
15791 (define_mode_attr rorx_immediate_operand
15792 [(SI "const_0_to_31_operand")
15793 (DI "const_0_to_63_operand")])
15794
15795 (define_insn "*bmi2_rorx<mode>3_1"
15796 [(set (match_operand:SWI48 0 "register_operand" "=r")
15797 (rotatert:SWI48
15798 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15799 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15800 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15801 "rorx\t{%2, %1, %0|%0, %1, %2}"
15802 [(set_attr "type" "rotatex")
15803 (set_attr "mode" "<MODE>")])
15804
15805 (define_insn "*<insn><mode>3_1"
15806 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15807 (any_rotate:SWI48
15808 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15809 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15810 (clobber (reg:CC FLAGS_REG))]
15811 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15812 {
15813 switch (get_attr_type (insn))
15814 {
15815 case TYPE_ROTATEX:
15816 return "#";
15817
15818 default:
15819 if (operands[2] == const1_rtx
15820 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15821 return "<rotate>{<imodesuffix>}\t%0";
15822 else
15823 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15824 }
15825 }
15826 [(set_attr "isa" "*,bmi2")
15827 (set_attr "type" "rotate,rotatex")
15828 (set (attr "preferred_for_size")
15829 (cond [(eq_attr "alternative" "0")
15830 (symbol_ref "true")]
15831 (symbol_ref "false")))
15832 (set (attr "length_immediate")
15833 (if_then_else
15834 (and (eq_attr "type" "rotate")
15835 (and (match_operand 2 "const1_operand")
15836 (ior (match_test "TARGET_SHIFT1")
15837 (match_test "optimize_function_for_size_p (cfun)"))))
15838 (const_string "0")
15839 (const_string "*")))
15840 (set_attr "mode" "<MODE>")])
15841
15842 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15843 (define_split
15844 [(set (match_operand:SWI48 0 "register_operand")
15845 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15846 (match_operand:QI 2 "const_int_operand")))
15847 (clobber (reg:CC FLAGS_REG))]
15848 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15849 [(set (match_dup 0)
15850 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15851 {
15852 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15853
15854 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15855 })
15856
15857 (define_split
15858 [(set (match_operand:SWI48 0 "register_operand")
15859 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15860 (match_operand:QI 2 "const_int_operand")))
15861 (clobber (reg:CC FLAGS_REG))]
15862 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15863 [(set (match_dup 0)
15864 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15865
15866 (define_insn "*bmi2_rorxsi3_1_zext"
15867 [(set (match_operand:DI 0 "register_operand" "=r")
15868 (zero_extend:DI
15869 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15870 (match_operand:QI 2 "const_0_to_31_operand"))))]
15871 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15872 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15873 [(set_attr "type" "rotatex")
15874 (set_attr "mode" "SI")])
15875
15876 (define_insn "*<insn>si3_1_zext"
15877 [(set (match_operand:DI 0 "register_operand" "=r,r")
15878 (zero_extend:DI
15879 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15880 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15881 (clobber (reg:CC FLAGS_REG))]
15882 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15883 {
15884 switch (get_attr_type (insn))
15885 {
15886 case TYPE_ROTATEX:
15887 return "#";
15888
15889 default:
15890 if (operands[2] == const1_rtx
15891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15892 return "<rotate>{l}\t%k0";
15893 else
15894 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15895 }
15896 }
15897 [(set_attr "isa" "*,bmi2")
15898 (set_attr "type" "rotate,rotatex")
15899 (set (attr "preferred_for_size")
15900 (cond [(eq_attr "alternative" "0")
15901 (symbol_ref "true")]
15902 (symbol_ref "false")))
15903 (set (attr "length_immediate")
15904 (if_then_else
15905 (and (eq_attr "type" "rotate")
15906 (and (match_operand 2 "const1_operand")
15907 (ior (match_test "TARGET_SHIFT1")
15908 (match_test "optimize_function_for_size_p (cfun)"))))
15909 (const_string "0")
15910 (const_string "*")))
15911 (set_attr "mode" "SI")])
15912
15913 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15914 (define_split
15915 [(set (match_operand:DI 0 "register_operand")
15916 (zero_extend:DI
15917 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15918 (match_operand:QI 2 "const_int_operand"))))
15919 (clobber (reg:CC FLAGS_REG))]
15920 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15921 && !optimize_function_for_size_p (cfun)"
15922 [(set (match_dup 0)
15923 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15924 {
15925 int bitsize = GET_MODE_BITSIZE (SImode);
15926
15927 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15928 })
15929
15930 (define_split
15931 [(set (match_operand:DI 0 "register_operand")
15932 (zero_extend:DI
15933 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15934 (match_operand:QI 2 "const_int_operand"))))
15935 (clobber (reg:CC FLAGS_REG))]
15936 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15937 && !optimize_function_for_size_p (cfun)"
15938 [(set (match_dup 0)
15939 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15940
15941 (define_insn "*<insn><mode>3_1"
15942 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15943 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15944 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15945 (clobber (reg:CC FLAGS_REG))]
15946 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15947 {
15948 if (operands[2] == const1_rtx
15949 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15950 return "<rotate>{<imodesuffix>}\t%0";
15951 else
15952 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15953 }
15954 [(set_attr "type" "rotate")
15955 (set (attr "length_immediate")
15956 (if_then_else
15957 (and (match_operand 2 "const1_operand")
15958 (ior (match_test "TARGET_SHIFT1")
15959 (match_test "optimize_function_for_size_p (cfun)")))
15960 (const_string "0")
15961 (const_string "*")))
15962 (set_attr "mode" "<MODE>")])
15963
15964 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15965 (define_insn_and_split "*<insn><mode>3_1_slp"
15966 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15967 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15968 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15969 (clobber (reg:CC FLAGS_REG))]
15970 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15971 {
15972 if (which_alternative)
15973 return "#";
15974
15975 if (operands[2] == const1_rtx
15976 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15977 return "<rotate>{<imodesuffix>}\t%0";
15978 else
15979 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15980 }
15981 "&& reload_completed"
15982 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15983 (parallel
15984 [(set (strict_low_part (match_dup 0))
15985 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15986 (clobber (reg:CC FLAGS_REG))])]
15987 ""
15988 [(set_attr "type" "rotate")
15989 (set (attr "length_immediate")
15990 (if_then_else
15991 (and (match_operand 2 "const1_operand")
15992 (ior (match_test "TARGET_SHIFT1")
15993 (match_test "optimize_function_for_size_p (cfun)")))
15994 (const_string "0")
15995 (const_string "*")))
15996 (set_attr "mode" "<MODE>")])
15997
15998 (define_split
15999 [(set (match_operand:HI 0 "QIreg_operand")
16000 (any_rotate:HI (match_dup 0) (const_int 8)))
16001 (clobber (reg:CC FLAGS_REG))]
16002 "reload_completed
16003 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
16004 [(parallel [(set (strict_low_part (match_dup 0))
16005 (bswap:HI (match_dup 0)))
16006 (clobber (reg:CC FLAGS_REG))])])
16007
16008 ;; Rotations through carry flag
16009 (define_insn "rcrsi2"
16010 [(set (match_operand:SI 0 "register_operand" "=r")
16011 (plus:SI
16012 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
16013 (const_int 1))
16014 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
16015 (const_int 31))))
16016 (clobber (reg:CC FLAGS_REG))]
16017 ""
16018 "rcr{l}\t%0"
16019 [(set_attr "type" "ishift1")
16020 (set_attr "memory" "none")
16021 (set_attr "length_immediate" "0")
16022 (set_attr "mode" "SI")])
16023
16024 (define_insn "rcrdi2"
16025 [(set (match_operand:DI 0 "register_operand" "=r")
16026 (plus:DI
16027 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
16028 (const_int 1))
16029 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
16030 (const_int 63))))
16031 (clobber (reg:CC FLAGS_REG))]
16032 "TARGET_64BIT"
16033 "rcr{q}\t%0"
16034 [(set_attr "type" "ishift1")
16035 (set_attr "length_immediate" "0")
16036 (set_attr "mode" "DI")])
16037
16038 ;; Versions of sar and shr that set the carry flag.
16039 (define_insn "<insn><mode>3_carry"
16040 [(set (reg:CCC FLAGS_REG)
16041 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
16042 (const_int 1))
16043 (const_int 0)] UNSPEC_CC_NE))
16044 (set (match_operand:SWI48 0 "register_operand" "=r")
16045 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
16046 ""
16047 {
16048 if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16049 return "<shift>{<imodesuffix>}\t%0";
16050 return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
16051 }
16052 [(set_attr "type" "ishift1")
16053 (set (attr "length_immediate")
16054 (if_then_else
16055 (ior (match_test "TARGET_SHIFT1")
16056 (match_test "optimize_function_for_size_p (cfun)"))
16057 (const_string "0")
16058 (const_string "*")))
16059 (set_attr "mode" "<MODE>")])
16060 \f
16061 ;; Bit set / bit test instructions
16062
16063 ;; %%% bts, btr, btc
16064
16065 ;; These instructions are *slow* when applied to memory.
16066
16067 (define_code_attr btsc [(ior "bts") (xor "btc")])
16068
16069 (define_insn "*<btsc><mode>"
16070 [(set (match_operand:SWI48 0 "register_operand" "=r")
16071 (any_or:SWI48
16072 (ashift:SWI48 (const_int 1)
16073 (match_operand:QI 2 "register_operand" "r"))
16074 (match_operand:SWI48 1 "register_operand" "0")))
16075 (clobber (reg:CC FLAGS_REG))]
16076 "TARGET_USE_BT"
16077 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16078 [(set_attr "type" "alu1")
16079 (set_attr "prefix_0f" "1")
16080 (set_attr "znver1_decode" "double")
16081 (set_attr "mode" "<MODE>")])
16082
16083 ;; Avoid useless masking of count operand.
16084 (define_insn_and_split "*<btsc><mode>_mask"
16085 [(set (match_operand:SWI48 0 "register_operand")
16086 (any_or:SWI48
16087 (ashift:SWI48
16088 (const_int 1)
16089 (subreg:QI
16090 (and
16091 (match_operand 1 "int248_register_operand")
16092 (match_operand 2 "const_int_operand")) 0))
16093 (match_operand:SWI48 3 "register_operand")))
16094 (clobber (reg:CC FLAGS_REG))]
16095 "TARGET_USE_BT
16096 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16097 == GET_MODE_BITSIZE (<MODE>mode)-1
16098 && ix86_pre_reload_split ()"
16099 "#"
16100 "&& 1"
16101 [(parallel
16102 [(set (match_dup 0)
16103 (any_or:SWI48
16104 (ashift:SWI48 (const_int 1)
16105 (match_dup 1))
16106 (match_dup 3)))
16107 (clobber (reg:CC FLAGS_REG))])]
16108 {
16109 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16110 operands[1] = gen_lowpart (QImode, operands[1]);
16111 })
16112
16113 (define_insn_and_split "*<btsc><mode>_mask_1"
16114 [(set (match_operand:SWI48 0 "register_operand")
16115 (any_or:SWI48
16116 (ashift:SWI48
16117 (const_int 1)
16118 (and:QI
16119 (match_operand:QI 1 "register_operand")
16120 (match_operand:QI 2 "const_int_operand")))
16121 (match_operand:SWI48 3 "register_operand")))
16122 (clobber (reg:CC FLAGS_REG))]
16123 "TARGET_USE_BT
16124 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16125 == GET_MODE_BITSIZE (<MODE>mode)-1
16126 && ix86_pre_reload_split ()"
16127 "#"
16128 "&& 1"
16129 [(parallel
16130 [(set (match_dup 0)
16131 (any_or:SWI48
16132 (ashift:SWI48 (const_int 1)
16133 (match_dup 1))
16134 (match_dup 3)))
16135 (clobber (reg:CC FLAGS_REG))])])
16136
16137 (define_insn "*btr<mode>"
16138 [(set (match_operand:SWI48 0 "register_operand" "=r")
16139 (and:SWI48
16140 (rotate:SWI48 (const_int -2)
16141 (match_operand:QI 2 "register_operand" "r"))
16142 (match_operand:SWI48 1 "register_operand" "0")))
16143 (clobber (reg:CC FLAGS_REG))]
16144 "TARGET_USE_BT"
16145 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16146 [(set_attr "type" "alu1")
16147 (set_attr "prefix_0f" "1")
16148 (set_attr "znver1_decode" "double")
16149 (set_attr "mode" "<MODE>")])
16150
16151 ;; Avoid useless masking of count operand.
16152 (define_insn_and_split "*btr<mode>_mask"
16153 [(set (match_operand:SWI48 0 "register_operand")
16154 (and:SWI48
16155 (rotate:SWI48
16156 (const_int -2)
16157 (subreg:QI
16158 (and
16159 (match_operand 1 "int248_register_operand")
16160 (match_operand 2 "const_int_operand")) 0))
16161 (match_operand:SWI48 3 "register_operand")))
16162 (clobber (reg:CC FLAGS_REG))]
16163 "TARGET_USE_BT
16164 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16165 == GET_MODE_BITSIZE (<MODE>mode)-1
16166 && ix86_pre_reload_split ()"
16167 "#"
16168 "&& 1"
16169 [(parallel
16170 [(set (match_dup 0)
16171 (and:SWI48
16172 (rotate:SWI48 (const_int -2)
16173 (match_dup 1))
16174 (match_dup 3)))
16175 (clobber (reg:CC FLAGS_REG))])]
16176 {
16177 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16178 operands[1] = gen_lowpart (QImode, operands[1]);
16179 })
16180
16181 (define_insn_and_split "*btr<mode>_mask_1"
16182 [(set (match_operand:SWI48 0 "register_operand")
16183 (and:SWI48
16184 (rotate:SWI48
16185 (const_int -2)
16186 (and:QI
16187 (match_operand:QI 1 "register_operand")
16188 (match_operand:QI 2 "const_int_operand")))
16189 (match_operand:SWI48 3 "register_operand")))
16190 (clobber (reg:CC FLAGS_REG))]
16191 "TARGET_USE_BT
16192 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16193 == GET_MODE_BITSIZE (<MODE>mode)-1
16194 && ix86_pre_reload_split ()"
16195 "#"
16196 "&& 1"
16197 [(parallel
16198 [(set (match_dup 0)
16199 (and:SWI48
16200 (rotate:SWI48 (const_int -2)
16201 (match_dup 1))
16202 (match_dup 3)))
16203 (clobber (reg:CC FLAGS_REG))])])
16204
16205 (define_insn_and_split "*btr<mode>_1"
16206 [(set (match_operand:SWI12 0 "register_operand")
16207 (and:SWI12
16208 (subreg:SWI12
16209 (rotate:SI (const_int -2)
16210 (match_operand:QI 2 "register_operand")) 0)
16211 (match_operand:SWI12 1 "nonimmediate_operand")))
16212 (clobber (reg:CC FLAGS_REG))]
16213 "TARGET_USE_BT && ix86_pre_reload_split ()"
16214 "#"
16215 "&& 1"
16216 [(parallel
16217 [(set (match_dup 0)
16218 (and:SI (rotate:SI (const_int -2) (match_dup 2))
16219 (match_dup 1)))
16220 (clobber (reg:CC FLAGS_REG))])]
16221 {
16222 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16223 operands[1] = force_reg (<MODE>mode, operands[1]);
16224 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16225 })
16226
16227 (define_insn_and_split "*btr<mode>_2"
16228 [(set (zero_extract:HI
16229 (match_operand:SWI12 0 "nonimmediate_operand")
16230 (const_int 1)
16231 (match_operand:QI 1 "register_operand"))
16232 (const_int 0))
16233 (clobber (reg:CC FLAGS_REG))]
16234 "TARGET_USE_BT && ix86_pre_reload_split ()"
16235 "#"
16236 "&& MEM_P (operands[0])"
16237 [(set (match_dup 2) (match_dup 0))
16238 (parallel
16239 [(set (match_dup 3)
16240 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16241 (match_dup 4)))
16242 (clobber (reg:CC FLAGS_REG))])
16243 (set (match_dup 0) (match_dup 5))]
16244 {
16245 operands[2] = gen_reg_rtx (<MODE>mode);
16246 operands[5] = gen_reg_rtx (<MODE>mode);
16247 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16248 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16249 })
16250
16251 (define_split
16252 [(set (zero_extract:HI
16253 (match_operand:SWI12 0 "register_operand")
16254 (const_int 1)
16255 (match_operand:QI 1 "register_operand"))
16256 (const_int 0))
16257 (clobber (reg:CC FLAGS_REG))]
16258 "TARGET_USE_BT && ix86_pre_reload_split ()"
16259 [(parallel
16260 [(set (match_dup 0)
16261 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16262 (match_dup 2)))
16263 (clobber (reg:CC FLAGS_REG))])]
16264 {
16265 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16266 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16267 })
16268
16269 ;; These instructions are never faster than the corresponding
16270 ;; and/ior/xor operations when using immediate operand, so with
16271 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16272 ;; relevant immediates within the instruction itself, so operating
16273 ;; on bits in the high 32-bits of a register becomes easier.
16274 ;;
16275 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16276 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16277 ;; negdf respectively, so they can never be disabled entirely.
16278
16279 (define_insn "*btsq_imm"
16280 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16281 (const_int 1)
16282 (match_operand:QI 1 "const_0_to_63_operand"))
16283 (const_int 1))
16284 (clobber (reg:CC FLAGS_REG))]
16285 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16286 "bts{q}\t{%1, %0|%0, %1}"
16287 [(set_attr "type" "alu1")
16288 (set_attr "prefix_0f" "1")
16289 (set_attr "znver1_decode" "double")
16290 (set_attr "mode" "DI")])
16291
16292 (define_insn "*btrq_imm"
16293 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16294 (const_int 1)
16295 (match_operand:QI 1 "const_0_to_63_operand"))
16296 (const_int 0))
16297 (clobber (reg:CC FLAGS_REG))]
16298 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16299 "btr{q}\t{%1, %0|%0, %1}"
16300 [(set_attr "type" "alu1")
16301 (set_attr "prefix_0f" "1")
16302 (set_attr "znver1_decode" "double")
16303 (set_attr "mode" "DI")])
16304
16305 (define_insn "*btcq_imm"
16306 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16307 (const_int 1)
16308 (match_operand:QI 1 "const_0_to_63_operand"))
16309 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16310 (clobber (reg:CC FLAGS_REG))]
16311 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16312 "btc{q}\t{%1, %0|%0, %1}"
16313 [(set_attr "type" "alu1")
16314 (set_attr "prefix_0f" "1")
16315 (set_attr "znver1_decode" "double")
16316 (set_attr "mode" "DI")])
16317
16318 ;; Allow Nocona to avoid these instructions if a register is available.
16319
16320 (define_peephole2
16321 [(match_scratch:DI 2 "r")
16322 (parallel [(set (zero_extract:DI
16323 (match_operand:DI 0 "nonimmediate_operand")
16324 (const_int 1)
16325 (match_operand:QI 1 "const_0_to_63_operand"))
16326 (const_int 1))
16327 (clobber (reg:CC FLAGS_REG))])]
16328 "TARGET_64BIT && !TARGET_USE_BT"
16329 [(parallel [(set (match_dup 0)
16330 (ior:DI (match_dup 0) (match_dup 3)))
16331 (clobber (reg:CC FLAGS_REG))])]
16332 {
16333 int i = INTVAL (operands[1]);
16334
16335 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16336
16337 if (!x86_64_immediate_operand (operands[3], DImode))
16338 {
16339 emit_move_insn (operands[2], operands[3]);
16340 operands[3] = operands[2];
16341 }
16342 })
16343
16344 (define_peephole2
16345 [(match_scratch:DI 2 "r")
16346 (parallel [(set (zero_extract:DI
16347 (match_operand:DI 0 "nonimmediate_operand")
16348 (const_int 1)
16349 (match_operand:QI 1 "const_0_to_63_operand"))
16350 (const_int 0))
16351 (clobber (reg:CC FLAGS_REG))])]
16352 "TARGET_64BIT && !TARGET_USE_BT"
16353 [(parallel [(set (match_dup 0)
16354 (and:DI (match_dup 0) (match_dup 3)))
16355 (clobber (reg:CC FLAGS_REG))])]
16356 {
16357 int i = INTVAL (operands[1]);
16358
16359 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16360
16361 if (!x86_64_immediate_operand (operands[3], DImode))
16362 {
16363 emit_move_insn (operands[2], operands[3]);
16364 operands[3] = operands[2];
16365 }
16366 })
16367
16368 (define_peephole2
16369 [(match_scratch:DI 2 "r")
16370 (parallel [(set (zero_extract:DI
16371 (match_operand:DI 0 "nonimmediate_operand")
16372 (const_int 1)
16373 (match_operand:QI 1 "const_0_to_63_operand"))
16374 (not:DI (zero_extract:DI
16375 (match_dup 0) (const_int 1) (match_dup 1))))
16376 (clobber (reg:CC FLAGS_REG))])]
16377 "TARGET_64BIT && !TARGET_USE_BT"
16378 [(parallel [(set (match_dup 0)
16379 (xor:DI (match_dup 0) (match_dup 3)))
16380 (clobber (reg:CC FLAGS_REG))])]
16381 {
16382 int i = INTVAL (operands[1]);
16383
16384 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16385
16386 if (!x86_64_immediate_operand (operands[3], DImode))
16387 {
16388 emit_move_insn (operands[2], operands[3]);
16389 operands[3] = operands[2];
16390 }
16391 })
16392
16393 ;; %%% bt
16394
16395 (define_insn "*bt<mode>"
16396 [(set (reg:CCC FLAGS_REG)
16397 (compare:CCC
16398 (zero_extract:SWI48
16399 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16400 (const_int 1)
16401 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16402 (const_int 0)))]
16403 ""
16404 {
16405 switch (get_attr_mode (insn))
16406 {
16407 case MODE_SI:
16408 return "bt{l}\t{%k1, %k0|%k0, %k1}";
16409
16410 case MODE_DI:
16411 return "bt{q}\t{%q1, %0|%0, %q1}";
16412
16413 default:
16414 gcc_unreachable ();
16415 }
16416 }
16417 [(set_attr "type" "alu1")
16418 (set_attr "prefix_0f" "1")
16419 (set (attr "mode")
16420 (if_then_else
16421 (and (match_test "CONST_INT_P (operands[1])")
16422 (match_test "INTVAL (operands[1]) < 32"))
16423 (const_string "SI")
16424 (const_string "<MODE>")))])
16425
16426 (define_insn_and_split "*bt<SWI48:mode>_mask"
16427 [(set (reg:CCC FLAGS_REG)
16428 (compare:CCC
16429 (zero_extract:SWI48
16430 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16431 (const_int 1)
16432 (subreg:QI
16433 (and:SWI248
16434 (match_operand:SWI248 1 "register_operand")
16435 (match_operand 2 "const_int_operand")) 0))
16436 (const_int 0)))]
16437 "TARGET_USE_BT
16438 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16439 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16440 && ix86_pre_reload_split ()"
16441 "#"
16442 "&& 1"
16443 [(set (reg:CCC FLAGS_REG)
16444 (compare:CCC
16445 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16446 (const_int 0)))]
16447 "operands[1] = gen_lowpart (QImode, operands[1]);")
16448
16449 (define_insn_and_split "*jcc_bt<mode>"
16450 [(set (pc)
16451 (if_then_else (match_operator 0 "bt_comparison_operator"
16452 [(zero_extract:SWI48
16453 (match_operand:SWI48 1 "nonimmediate_operand")
16454 (const_int 1)
16455 (match_operand:QI 2 "nonmemory_operand"))
16456 (const_int 0)])
16457 (label_ref (match_operand 3))
16458 (pc)))
16459 (clobber (reg:CC FLAGS_REG))]
16460 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16461 && (CONST_INT_P (operands[2])
16462 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16463 && INTVAL (operands[2])
16464 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16465 : !memory_operand (operands[1], <MODE>mode))
16466 && ix86_pre_reload_split ()"
16467 "#"
16468 "&& 1"
16469 [(set (reg:CCC FLAGS_REG)
16470 (compare:CCC
16471 (zero_extract:SWI48
16472 (match_dup 1)
16473 (const_int 1)
16474 (match_dup 2))
16475 (const_int 0)))
16476 (set (pc)
16477 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16478 (label_ref (match_dup 3))
16479 (pc)))]
16480 {
16481 operands[0] = shallow_copy_rtx (operands[0]);
16482 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16483 })
16484
16485 ;; Avoid useless masking of bit offset operand.
16486 (define_insn_and_split "*jcc_bt<mode>_mask"
16487 [(set (pc)
16488 (if_then_else (match_operator 0 "bt_comparison_operator"
16489 [(zero_extract:SWI48
16490 (match_operand:SWI48 1 "register_operand")
16491 (const_int 1)
16492 (and:QI
16493 (match_operand:QI 2 "register_operand")
16494 (match_operand 3 "const_int_operand")))])
16495 (label_ref (match_operand 4))
16496 (pc)))
16497 (clobber (reg:CC FLAGS_REG))]
16498 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16499 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16500 == GET_MODE_BITSIZE (<MODE>mode)-1
16501 && ix86_pre_reload_split ()"
16502 "#"
16503 "&& 1"
16504 [(set (reg:CCC FLAGS_REG)
16505 (compare:CCC
16506 (zero_extract:SWI48
16507 (match_dup 1)
16508 (const_int 1)
16509 (match_dup 2))
16510 (const_int 0)))
16511 (set (pc)
16512 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16513 (label_ref (match_dup 4))
16514 (pc)))]
16515 {
16516 operands[0] = shallow_copy_rtx (operands[0]);
16517 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16518 })
16519
16520 ;; Avoid useless masking of bit offset operand.
16521 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16522 [(set (pc)
16523 (if_then_else (match_operator 0 "bt_comparison_operator"
16524 [(zero_extract:SWI48
16525 (match_operand:SWI48 1 "register_operand")
16526 (const_int 1)
16527 (subreg:QI
16528 (and:SWI248
16529 (match_operand:SWI248 2 "register_operand")
16530 (match_operand 3 "const_int_operand")) 0))])
16531 (label_ref (match_operand 4))
16532 (pc)))
16533 (clobber (reg:CC FLAGS_REG))]
16534 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16535 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16536 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16537 && ix86_pre_reload_split ()"
16538 "#"
16539 "&& 1"
16540 [(set (reg:CCC FLAGS_REG)
16541 (compare:CCC
16542 (zero_extract:SWI48
16543 (match_dup 1)
16544 (const_int 1)
16545 (match_dup 2))
16546 (const_int 0)))
16547 (set (pc)
16548 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16549 (label_ref (match_dup 4))
16550 (pc)))]
16551 {
16552 operands[0] = shallow_copy_rtx (operands[0]);
16553 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16554 operands[2] = gen_lowpart (QImode, operands[2]);
16555 })
16556
16557 ;; Help combine recognize bt followed by cmov
16558 (define_split
16559 [(set (match_operand:SWI248 0 "register_operand")
16560 (if_then_else:SWI248
16561 (match_operator 5 "bt_comparison_operator"
16562 [(zero_extract:SWI48
16563 (match_operand:SWI48 1 "register_operand")
16564 (const_int 1)
16565 (match_operand:QI 2 "register_operand"))
16566 (const_int 0)])
16567 (match_operand:SWI248 3 "nonimmediate_operand")
16568 (match_operand:SWI248 4 "nonimmediate_operand")))]
16569 "TARGET_USE_BT && TARGET_CMOVE
16570 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16571 && ix86_pre_reload_split ()"
16572 [(set (reg:CCC FLAGS_REG)
16573 (compare:CCC
16574 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16575 (const_int 0)))
16576 (set (match_dup 0)
16577 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16578 (match_dup 3)
16579 (match_dup 4)))]
16580 {
16581 if (GET_CODE (operands[5]) == EQ)
16582 std::swap (operands[3], operands[4]);
16583 })
16584
16585 ;; Help combine recognize bt followed by setc
16586 (define_insn_and_split "*bt<mode>_setcqi"
16587 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16588 (zero_extract:SWI48
16589 (match_operand:SWI48 1 "register_operand")
16590 (const_int 1)
16591 (match_operand:QI 2 "register_operand")))
16592 (clobber (reg:CC FLAGS_REG))]
16593 "TARGET_USE_BT && ix86_pre_reload_split ()"
16594 "#"
16595 "&& 1"
16596 [(set (reg:CCC FLAGS_REG)
16597 (compare:CCC
16598 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16599 (const_int 0)))
16600 (set (match_dup 0)
16601 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16602
16603 ;; Help combine recognize bt followed by setnc
16604 (define_insn_and_split "*bt<mode>_setncqi"
16605 [(set (match_operand:QI 0 "register_operand")
16606 (and:QI
16607 (not:QI
16608 (subreg:QI
16609 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16610 (match_operand:QI 2 "register_operand")) 0))
16611 (const_int 1)))
16612 (clobber (reg:CC FLAGS_REG))]
16613 "TARGET_USE_BT && ix86_pre_reload_split ()"
16614 "#"
16615 "&& 1"
16616 [(set (reg:CCC FLAGS_REG)
16617 (compare:CCC
16618 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16619 (const_int 0)))
16620 (set (match_dup 0)
16621 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16622
16623 (define_insn_and_split "*bt<mode>_setnc<mode>"
16624 [(set (match_operand:SWI48 0 "register_operand")
16625 (and:SWI48
16626 (not:SWI48
16627 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16628 (match_operand:QI 2 "register_operand")))
16629 (const_int 1)))
16630 (clobber (reg:CC FLAGS_REG))]
16631 "TARGET_USE_BT && ix86_pre_reload_split ()"
16632 "#"
16633 "&& 1"
16634 [(set (reg:CCC FLAGS_REG)
16635 (compare:CCC
16636 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16637 (const_int 0)))
16638 (set (match_dup 3)
16639 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16640 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16641 "operands[3] = gen_reg_rtx (QImode);")
16642
16643 ;; Help combine recognize bt followed by setnc (PR target/110588)
16644 (define_insn_and_split "*bt<mode>_setncqi_2"
16645 [(set (match_operand:QI 0 "register_operand")
16646 (eq:QI
16647 (zero_extract:SWI48
16648 (match_operand:SWI48 1 "register_operand")
16649 (const_int 1)
16650 (match_operand:QI 2 "register_operand"))
16651 (const_int 0)))
16652 (clobber (reg:CC FLAGS_REG))]
16653 "TARGET_USE_BT && ix86_pre_reload_split ()"
16654 "#"
16655 "&& 1"
16656 [(set (reg:CCC FLAGS_REG)
16657 (compare:CCC
16658 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16659 (const_int 0)))
16660 (set (match_dup 0)
16661 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16662
16663 ;; Help combine recognize bt followed by setc
16664 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16665 [(set (match_operand:SWI48 0 "register_operand")
16666 (zero_extract:SWI48
16667 (match_operand:SWI48 1 "register_operand")
16668 (const_int 1)
16669 (subreg:QI
16670 (and:SWI48
16671 (match_operand:SWI48 2 "register_operand")
16672 (match_operand 3 "const_int_operand")) 0)))
16673 (clobber (reg:CC FLAGS_REG))]
16674 "TARGET_USE_BT
16675 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16676 == GET_MODE_BITSIZE (<MODE>mode)-1
16677 && ix86_pre_reload_split ()"
16678 "#"
16679 "&& 1"
16680 [(set (reg:CCC FLAGS_REG)
16681 (compare:CCC
16682 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16683 (const_int 0)))
16684 (set (match_dup 3)
16685 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16686 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16687 {
16688 operands[2] = gen_lowpart (QImode, operands[2]);
16689 operands[3] = gen_reg_rtx (QImode);
16690 })
16691 \f
16692 ;; Store-flag instructions.
16693
16694 (define_split
16695 [(set (match_operand:QI 0 "nonimmediate_operand")
16696 (match_operator:QI 1 "add_comparison_operator"
16697 [(not:SWI (match_operand:SWI 2 "register_operand"))
16698 (match_operand:SWI 3 "nonimmediate_operand")]))]
16699 ""
16700 [(set (reg:CCC FLAGS_REG)
16701 (compare:CCC
16702 (plus:SWI (match_dup 2) (match_dup 3))
16703 (match_dup 2)))
16704 (set (match_dup 0)
16705 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16706
16707 (define_split
16708 [(set (match_operand:QI 0 "nonimmediate_operand")
16709 (match_operator:QI 1 "shr_comparison_operator"
16710 [(match_operand:DI 2 "register_operand")
16711 (match_operand 3 "const_int_operand")]))]
16712 "TARGET_64BIT
16713 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16714 [(set (reg:CCZ FLAGS_REG)
16715 (compare:CCZ
16716 (lshiftrt:DI (match_dup 2) (match_dup 4))
16717 (const_int 0)))
16718 (set (match_dup 0)
16719 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16720 {
16721 enum rtx_code new_code;
16722
16723 operands[1] = shallow_copy_rtx (operands[1]);
16724 switch (GET_CODE (operands[1]))
16725 {
16726 case GTU: new_code = NE; break;
16727 case LEU: new_code = EQ; break;
16728 default: gcc_unreachable ();
16729 }
16730 PUT_CODE (operands[1], new_code);
16731
16732 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16733 })
16734
16735 ;; For all sCOND expanders, also expand the compare or test insn that
16736 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16737
16738 (define_insn_and_split "*setcc_di_1"
16739 [(set (match_operand:DI 0 "register_operand" "=q")
16740 (match_operator:DI 1 "ix86_comparison_operator"
16741 [(reg FLAGS_REG) (const_int 0)]))]
16742 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16743 "#"
16744 "&& reload_completed"
16745 [(set (match_dup 2) (match_dup 1))
16746 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16747 {
16748 operands[1] = shallow_copy_rtx (operands[1]);
16749 PUT_MODE (operands[1], QImode);
16750 operands[2] = gen_lowpart (QImode, operands[0]);
16751 })
16752
16753 (define_insn_and_split "*setcc_<mode>_1_and"
16754 [(set (match_operand:SWI24 0 "register_operand" "=q")
16755 (match_operator:SWI24 1 "ix86_comparison_operator"
16756 [(reg FLAGS_REG) (const_int 0)]))
16757 (clobber (reg:CC FLAGS_REG))]
16758 "!TARGET_PARTIAL_REG_STALL
16759 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16760 "#"
16761 "&& reload_completed"
16762 [(set (match_dup 2) (match_dup 1))
16763 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16764 (clobber (reg:CC FLAGS_REG))])]
16765 {
16766 operands[1] = shallow_copy_rtx (operands[1]);
16767 PUT_MODE (operands[1], QImode);
16768 operands[2] = gen_lowpart (QImode, operands[0]);
16769 })
16770
16771 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16772 [(set (match_operand:SWI24 0 "register_operand" "=q")
16773 (match_operator:SWI24 1 "ix86_comparison_operator"
16774 [(reg FLAGS_REG) (const_int 0)]))]
16775 "!TARGET_PARTIAL_REG_STALL
16776 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16777 "#"
16778 "&& reload_completed"
16779 [(set (match_dup 2) (match_dup 1))
16780 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16781 {
16782 operands[1] = shallow_copy_rtx (operands[1]);
16783 PUT_MODE (operands[1], QImode);
16784 operands[2] = gen_lowpart (QImode, operands[0]);
16785 })
16786
16787 (define_insn "*setcc_qi"
16788 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16789 (match_operator:QI 1 "ix86_comparison_operator"
16790 [(reg FLAGS_REG) (const_int 0)]))]
16791 ""
16792 "set%C1\t%0"
16793 [(set_attr "type" "setcc")
16794 (set_attr "mode" "QI")])
16795
16796 (define_insn "*setcc_qi_slp"
16797 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16798 (match_operator:QI 1 "ix86_comparison_operator"
16799 [(reg FLAGS_REG) (const_int 0)]))]
16800 ""
16801 "set%C1\t%0"
16802 [(set_attr "type" "setcc")
16803 (set_attr "mode" "QI")])
16804
16805 ;; In general it is not safe to assume too much about CCmode registers,
16806 ;; so simplify-rtx stops when it sees a second one. Under certain
16807 ;; conditions this is safe on x86, so help combine not create
16808 ;;
16809 ;; seta %al
16810 ;; testb %al, %al
16811 ;; sete %al
16812
16813 (define_split
16814 [(set (match_operand:QI 0 "nonimmediate_operand")
16815 (ne:QI (match_operator 1 "ix86_comparison_operator"
16816 [(reg FLAGS_REG) (const_int 0)])
16817 (const_int 0)))]
16818 ""
16819 [(set (match_dup 0) (match_dup 1))]
16820 {
16821 operands[1] = shallow_copy_rtx (operands[1]);
16822 PUT_MODE (operands[1], QImode);
16823 })
16824
16825 (define_split
16826 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16827 (ne:QI (match_operator 1 "ix86_comparison_operator"
16828 [(reg FLAGS_REG) (const_int 0)])
16829 (const_int 0)))]
16830 ""
16831 [(set (match_dup 0) (match_dup 1))]
16832 {
16833 operands[1] = shallow_copy_rtx (operands[1]);
16834 PUT_MODE (operands[1], QImode);
16835 })
16836
16837 (define_split
16838 [(set (match_operand:QI 0 "nonimmediate_operand")
16839 (eq:QI (match_operator 1 "ix86_comparison_operator"
16840 [(reg FLAGS_REG) (const_int 0)])
16841 (const_int 0)))]
16842 ""
16843 [(set (match_dup 0) (match_dup 1))]
16844 {
16845 operands[1] = shallow_copy_rtx (operands[1]);
16846 PUT_MODE (operands[1], QImode);
16847 PUT_CODE (operands[1],
16848 ix86_reverse_condition (GET_CODE (operands[1]),
16849 GET_MODE (XEXP (operands[1], 0))));
16850
16851 /* Make sure that (a) the CCmode we have for the flags is strong
16852 enough for the reversed compare or (b) we have a valid FP compare. */
16853 if (! ix86_comparison_operator (operands[1], VOIDmode))
16854 FAIL;
16855 })
16856
16857 (define_split
16858 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16859 (eq:QI (match_operator 1 "ix86_comparison_operator"
16860 [(reg FLAGS_REG) (const_int 0)])
16861 (const_int 0)))]
16862 ""
16863 [(set (match_dup 0) (match_dup 1))]
16864 {
16865 operands[1] = shallow_copy_rtx (operands[1]);
16866 PUT_MODE (operands[1], QImode);
16867 PUT_CODE (operands[1],
16868 ix86_reverse_condition (GET_CODE (operands[1]),
16869 GET_MODE (XEXP (operands[1], 0))));
16870
16871 /* Make sure that (a) the CCmode we have for the flags is strong
16872 enough for the reversed compare or (b) we have a valid FP compare. */
16873 if (! ix86_comparison_operator (operands[1], VOIDmode))
16874 FAIL;
16875 })
16876
16877 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16878 ;; subsequent logical operations are used to imitate conditional moves.
16879 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16880 ;; it directly.
16881
16882 (define_insn "setcc_<mode>_sse"
16883 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16884 (match_operator:MODEF 3 "sse_comparison_operator"
16885 [(match_operand:MODEF 1 "register_operand" "0,x")
16886 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
16887 "SSE_FLOAT_MODE_P (<MODE>mode)"
16888 "@
16889 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16890 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16891 [(set_attr "isa" "noavx,avx")
16892 (set_attr "gpr32" "1,0")
16893 (set_attr "type" "ssecmp")
16894 (set_attr "length_immediate" "1")
16895 (set_attr "prefix" "orig,vex")
16896 (set_attr "mode" "<MODE>")])
16897
16898 (define_insn "setcc_hf_mask"
16899 [(set (match_operand:QI 0 "register_operand" "=k")
16900 (unspec:QI
16901 [(match_operand:HF 1 "register_operand" "v")
16902 (match_operand:HF 2 "nonimmediate_operand" "vm")
16903 (match_operand:SI 3 "const_0_to_31_operand")]
16904 UNSPEC_PCMP))]
16905 "TARGET_AVX512FP16"
16906 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16907 [(set_attr "type" "ssecmp")
16908 (set_attr "prefix" "evex")
16909 (set_attr "mode" "HF")])
16910
16911 \f
16912 ;; Basic conditional jump instructions.
16913
16914 (define_split
16915 [(set (pc)
16916 (if_then_else
16917 (match_operator 1 "add_comparison_operator"
16918 [(not:SWI (match_operand:SWI 2 "register_operand"))
16919 (match_operand:SWI 3 "nonimmediate_operand")])
16920 (label_ref (match_operand 0))
16921 (pc)))]
16922 ""
16923 [(set (reg:CCC FLAGS_REG)
16924 (compare:CCC
16925 (plus:SWI (match_dup 2) (match_dup 3))
16926 (match_dup 2)))
16927 (set (pc)
16928 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16929 (label_ref (match_operand 0))
16930 (pc)))])
16931
16932 (define_split
16933 [(set (pc)
16934 (if_then_else
16935 (match_operator 1 "shr_comparison_operator"
16936 [(match_operand:DI 2 "register_operand")
16937 (match_operand 3 "const_int_operand")])
16938 (label_ref (match_operand 0))
16939 (pc)))]
16940 "TARGET_64BIT
16941 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16942 [(set (reg:CCZ FLAGS_REG)
16943 (compare:CCZ
16944 (lshiftrt:DI (match_dup 2) (match_dup 4))
16945 (const_int 0)))
16946 (set (pc)
16947 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16948 (label_ref (match_operand 0))
16949 (pc)))]
16950 {
16951 enum rtx_code new_code;
16952
16953 operands[1] = shallow_copy_rtx (operands[1]);
16954 switch (GET_CODE (operands[1]))
16955 {
16956 case GTU: new_code = NE; break;
16957 case LEU: new_code = EQ; break;
16958 default: gcc_unreachable ();
16959 }
16960 PUT_CODE (operands[1], new_code);
16961
16962 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16963 })
16964
16965 ;; We ignore the overflow flag for signed branch instructions.
16966
16967 (define_insn "*jcc"
16968 [(set (pc)
16969 (if_then_else (match_operator 1 "ix86_comparison_operator"
16970 [(reg FLAGS_REG) (const_int 0)])
16971 (label_ref (match_operand 0))
16972 (pc)))]
16973 ""
16974 "%!%+j%C1\t%l0"
16975 [(set_attr "type" "ibr")
16976 (set_attr "modrm" "0")
16977 (set (attr "length")
16978 (if_then_else
16979 (and (ge (minus (match_dup 0) (pc))
16980 (const_int -126))
16981 (lt (minus (match_dup 0) (pc))
16982 (const_int 128)))
16983 (const_int 2)
16984 (const_int 6)))])
16985
16986 ;; In general it is not safe to assume too much about CCmode registers,
16987 ;; so simplify-rtx stops when it sees a second one. Under certain
16988 ;; conditions this is safe on x86, so help combine not create
16989 ;;
16990 ;; seta %al
16991 ;; testb %al, %al
16992 ;; je Lfoo
16993
16994 (define_split
16995 [(set (pc)
16996 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16997 [(reg FLAGS_REG) (const_int 0)])
16998 (const_int 0))
16999 (label_ref (match_operand 1))
17000 (pc)))]
17001 ""
17002 [(set (pc)
17003 (if_then_else (match_dup 0)
17004 (label_ref (match_dup 1))
17005 (pc)))]
17006 {
17007 operands[0] = shallow_copy_rtx (operands[0]);
17008 PUT_MODE (operands[0], VOIDmode);
17009 })
17010
17011 (define_split
17012 [(set (pc)
17013 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
17014 [(reg FLAGS_REG) (const_int 0)])
17015 (const_int 0))
17016 (label_ref (match_operand 1))
17017 (pc)))]
17018 ""
17019 [(set (pc)
17020 (if_then_else (match_dup 0)
17021 (label_ref (match_dup 1))
17022 (pc)))]
17023 {
17024 operands[0] = shallow_copy_rtx (operands[0]);
17025 PUT_MODE (operands[0], VOIDmode);
17026 PUT_CODE (operands[0],
17027 ix86_reverse_condition (GET_CODE (operands[0]),
17028 GET_MODE (XEXP (operands[0], 0))));
17029
17030 /* Make sure that (a) the CCmode we have for the flags is strong
17031 enough for the reversed compare or (b) we have a valid FP compare. */
17032 if (! ix86_comparison_operator (operands[0], VOIDmode))
17033 FAIL;
17034 })
17035 \f
17036 ;; Unconditional and other jump instructions
17037
17038 (define_insn "jump"
17039 [(set (pc)
17040 (label_ref (match_operand 0)))]
17041 ""
17042 "%!jmp\t%l0"
17043 [(set_attr "type" "ibr")
17044 (set_attr "modrm" "0")
17045 (set (attr "length")
17046 (if_then_else
17047 (and (ge (minus (match_dup 0) (pc))
17048 (const_int -126))
17049 (lt (minus (match_dup 0) (pc))
17050 (const_int 128)))
17051 (const_int 2)
17052 (const_int 5)))])
17053
17054 (define_expand "indirect_jump"
17055 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
17056 ""
17057 {
17058 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17059 operands[0] = convert_memory_address (word_mode, operands[0]);
17060 cfun->machine->has_local_indirect_jump = true;
17061 })
17062
17063 (define_insn "*indirect_jump"
17064 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
17065 ""
17066 "* return ix86_output_indirect_jmp (operands[0]);"
17067 [(set (attr "type")
17068 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17069 != indirect_branch_keep)")
17070 (const_string "multi")
17071 (const_string "ibr")))
17072 (set_attr "length_immediate" "0")])
17073
17074 (define_expand "tablejump"
17075 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
17076 (use (label_ref (match_operand 1)))])]
17077 ""
17078 {
17079 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
17080 relative. Convert the relative address to an absolute address. */
17081 if (flag_pic)
17082 {
17083 rtx op0, op1;
17084 enum rtx_code code;
17085
17086 /* We can't use @GOTOFF for text labels on VxWorks;
17087 see gotoff_operand. */
17088 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
17089 {
17090 code = PLUS;
17091 op0 = operands[0];
17092 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
17093 }
17094 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
17095 {
17096 code = PLUS;
17097 op0 = operands[0];
17098 op1 = pic_offset_table_rtx;
17099 }
17100 else
17101 {
17102 code = MINUS;
17103 op0 = pic_offset_table_rtx;
17104 op1 = operands[0];
17105 }
17106
17107 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17108 OPTAB_DIRECT);
17109 }
17110
17111 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17112 operands[0] = convert_memory_address (word_mode, operands[0]);
17113 cfun->machine->has_local_indirect_jump = true;
17114 })
17115
17116 (define_insn "*tablejump_1"
17117 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17118 (use (label_ref (match_operand 1)))]
17119 ""
17120 "* return ix86_output_indirect_jmp (operands[0]);"
17121 [(set (attr "type")
17122 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17123 != indirect_branch_keep)")
17124 (const_string "multi")
17125 (const_string "ibr")))
17126 (set_attr "length_immediate" "0")])
17127 \f
17128 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17129
17130 (define_peephole2
17131 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17132 (set (match_operand:QI 1 "register_operand")
17133 (match_operator:QI 2 "ix86_comparison_operator"
17134 [(reg FLAGS_REG) (const_int 0)]))
17135 (set (match_operand 3 "any_QIreg_operand")
17136 (zero_extend (match_dup 1)))]
17137 "(peep2_reg_dead_p (3, operands[1])
17138 || operands_match_p (operands[1], operands[3]))
17139 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17140 && peep2_regno_dead_p (0, FLAGS_REG)"
17141 [(set (match_dup 4) (match_dup 0))
17142 (set (strict_low_part (match_dup 5))
17143 (match_dup 2))]
17144 {
17145 operands[5] = gen_lowpart (QImode, operands[3]);
17146 ix86_expand_clear (operands[3]);
17147 })
17148
17149 (define_peephole2
17150 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17151 (match_operand 4)])
17152 (set (match_operand:QI 1 "register_operand")
17153 (match_operator:QI 2 "ix86_comparison_operator"
17154 [(reg FLAGS_REG) (const_int 0)]))
17155 (set (match_operand 3 "any_QIreg_operand")
17156 (zero_extend (match_dup 1)))]
17157 "(peep2_reg_dead_p (3, operands[1])
17158 || operands_match_p (operands[1], operands[3]))
17159 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17160 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17161 && ! reg_set_p (operands[3], operands[4])
17162 && peep2_regno_dead_p (0, FLAGS_REG)"
17163 [(parallel [(set (match_dup 5) (match_dup 0))
17164 (match_dup 4)])
17165 (set (strict_low_part (match_dup 6))
17166 (match_dup 2))]
17167 {
17168 operands[6] = gen_lowpart (QImode, operands[3]);
17169 ix86_expand_clear (operands[3]);
17170 })
17171
17172 (define_peephole2
17173 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17174 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17175 (match_operand 5)])
17176 (set (match_operand:QI 2 "register_operand")
17177 (match_operator:QI 3 "ix86_comparison_operator"
17178 [(reg FLAGS_REG) (const_int 0)]))
17179 (set (match_operand 4 "any_QIreg_operand")
17180 (zero_extend (match_dup 2)))]
17181 "(peep2_reg_dead_p (4, operands[2])
17182 || operands_match_p (operands[2], operands[4]))
17183 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17184 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17185 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17186 && ! reg_set_p (operands[4], operands[5])
17187 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17188 && peep2_regno_dead_p (0, FLAGS_REG)"
17189 [(set (match_dup 6) (match_dup 0))
17190 (parallel [(set (match_dup 7) (match_dup 1))
17191 (match_dup 5)])
17192 (set (strict_low_part (match_dup 8))
17193 (match_dup 3))]
17194 {
17195 operands[8] = gen_lowpart (QImode, operands[4]);
17196 ix86_expand_clear (operands[4]);
17197 })
17198
17199 ;; Similar, but match zero extend with andsi3.
17200
17201 (define_peephole2
17202 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17203 (set (match_operand:QI 1 "register_operand")
17204 (match_operator:QI 2 "ix86_comparison_operator"
17205 [(reg FLAGS_REG) (const_int 0)]))
17206 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17207 (and:SI (match_dup 3) (const_int 255)))
17208 (clobber (reg:CC FLAGS_REG))])]
17209 "REGNO (operands[1]) == REGNO (operands[3])
17210 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17211 && peep2_regno_dead_p (0, FLAGS_REG)"
17212 [(set (match_dup 4) (match_dup 0))
17213 (set (strict_low_part (match_dup 5))
17214 (match_dup 2))]
17215 {
17216 operands[5] = gen_lowpart (QImode, operands[3]);
17217 ix86_expand_clear (operands[3]);
17218 })
17219
17220 (define_peephole2
17221 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17222 (match_operand 4)])
17223 (set (match_operand:QI 1 "register_operand")
17224 (match_operator:QI 2 "ix86_comparison_operator"
17225 [(reg FLAGS_REG) (const_int 0)]))
17226 (parallel [(set (match_operand 3 "any_QIreg_operand")
17227 (zero_extend (match_dup 1)))
17228 (clobber (reg:CC FLAGS_REG))])]
17229 "(peep2_reg_dead_p (3, operands[1])
17230 || operands_match_p (operands[1], operands[3]))
17231 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17232 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17233 && ! reg_set_p (operands[3], operands[4])
17234 && peep2_regno_dead_p (0, FLAGS_REG)"
17235 [(parallel [(set (match_dup 5) (match_dup 0))
17236 (match_dup 4)])
17237 (set (strict_low_part (match_dup 6))
17238 (match_dup 2))]
17239 {
17240 operands[6] = gen_lowpart (QImode, operands[3]);
17241 ix86_expand_clear (operands[3]);
17242 })
17243
17244 (define_peephole2
17245 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17246 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17247 (match_operand 5)])
17248 (set (match_operand:QI 2 "register_operand")
17249 (match_operator:QI 3 "ix86_comparison_operator"
17250 [(reg FLAGS_REG) (const_int 0)]))
17251 (parallel [(set (match_operand 4 "any_QIreg_operand")
17252 (zero_extend (match_dup 2)))
17253 (clobber (reg:CC FLAGS_REG))])]
17254 "(peep2_reg_dead_p (4, operands[2])
17255 || operands_match_p (operands[2], operands[4]))
17256 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17257 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17258 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17259 && ! reg_set_p (operands[4], operands[5])
17260 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17261 && peep2_regno_dead_p (0, FLAGS_REG)"
17262 [(set (match_dup 6) (match_dup 0))
17263 (parallel [(set (match_dup 7) (match_dup 1))
17264 (match_dup 5)])
17265 (set (strict_low_part (match_dup 8))
17266 (match_dup 3))]
17267 {
17268 operands[8] = gen_lowpart (QImode, operands[4]);
17269 ix86_expand_clear (operands[4]);
17270 })
17271 \f
17272 ;; Call instructions.
17273
17274 ;; The predicates normally associated with named expanders are not properly
17275 ;; checked for calls. This is a bug in the generic code, but it isn't that
17276 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17277
17278 ;; P6 processors will jump to the address after the decrement when %esp
17279 ;; is used as a call operand, so they will execute return address as a code.
17280 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17281
17282 ;; Register constraint for call instruction.
17283 (define_mode_attr c [(SI "l") (DI "r")])
17284
17285 ;; Call subroutine returning no value.
17286
17287 (define_expand "call"
17288 [(call (match_operand:QI 0)
17289 (match_operand 1))
17290 (use (match_operand 2))]
17291 ""
17292 {
17293 ix86_expand_call (NULL, operands[0], operands[1],
17294 operands[2], NULL, false);
17295 DONE;
17296 })
17297
17298 (define_expand "sibcall"
17299 [(call (match_operand:QI 0)
17300 (match_operand 1))
17301 (use (match_operand 2))]
17302 ""
17303 {
17304 ix86_expand_call (NULL, operands[0], operands[1],
17305 operands[2], NULL, true);
17306 DONE;
17307 })
17308
17309 (define_insn "*call"
17310 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17311 (match_operand 1))]
17312 "!SIBLING_CALL_P (insn)"
17313 "* return ix86_output_call_insn (insn, operands[0]);"
17314 [(set_attr "type" "call")])
17315
17316 ;; This covers both call and sibcall since only GOT slot is allowed.
17317 (define_insn "*call_got_x32"
17318 [(call (mem:QI (zero_extend:DI
17319 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17320 (match_operand 1))]
17321 "TARGET_X32"
17322 {
17323 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17324 return ix86_output_call_insn (insn, fnaddr);
17325 }
17326 [(set_attr "type" "call")])
17327
17328 ;; Since sibcall never returns, we can only use call-clobbered register
17329 ;; as GOT base.
17330 (define_insn "*sibcall_GOT_32"
17331 [(call (mem:QI
17332 (mem:SI (plus:SI
17333 (match_operand:SI 0 "register_no_elim_operand" "U")
17334 (match_operand:SI 1 "GOT32_symbol_operand"))))
17335 (match_operand 2))]
17336 "!TARGET_MACHO
17337 && !TARGET_64BIT
17338 && !TARGET_INDIRECT_BRANCH_REGISTER
17339 && SIBLING_CALL_P (insn)"
17340 {
17341 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17342 fnaddr = gen_const_mem (SImode, fnaddr);
17343 return ix86_output_call_insn (insn, fnaddr);
17344 }
17345 [(set_attr "type" "call")])
17346
17347 (define_insn "*sibcall"
17348 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17349 (match_operand 1))]
17350 "SIBLING_CALL_P (insn)"
17351 "* return ix86_output_call_insn (insn, operands[0]);"
17352 [(set_attr "type" "call")])
17353
17354 (define_insn "*sibcall_memory"
17355 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17356 (match_operand 1))
17357 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17358 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17359 "* return ix86_output_call_insn (insn, operands[0]);"
17360 [(set_attr "type" "call")])
17361
17362 (define_peephole2
17363 [(set (match_operand:W 0 "register_operand")
17364 (match_operand:W 1 "memory_operand"))
17365 (call (mem:QI (match_dup 0))
17366 (match_operand 3))]
17367 "!TARGET_X32
17368 && !TARGET_INDIRECT_BRANCH_REGISTER
17369 && SIBLING_CALL_P (peep2_next_insn (1))
17370 && !reg_mentioned_p (operands[0],
17371 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17372 [(parallel [(call (mem:QI (match_dup 1))
17373 (match_dup 3))
17374 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17375
17376 (define_peephole2
17377 [(set (match_operand:W 0 "register_operand")
17378 (match_operand:W 1 "memory_operand"))
17379 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17380 (call (mem:QI (match_dup 0))
17381 (match_operand 3))]
17382 "!TARGET_X32
17383 && !TARGET_INDIRECT_BRANCH_REGISTER
17384 && SIBLING_CALL_P (peep2_next_insn (2))
17385 && !reg_mentioned_p (operands[0],
17386 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17387 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17388 (parallel [(call (mem:QI (match_dup 1))
17389 (match_dup 3))
17390 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17391
17392 (define_expand "call_pop"
17393 [(parallel [(call (match_operand:QI 0)
17394 (match_operand:SI 1))
17395 (set (reg:SI SP_REG)
17396 (plus:SI (reg:SI SP_REG)
17397 (match_operand:SI 3)))])]
17398 "!TARGET_64BIT"
17399 {
17400 ix86_expand_call (NULL, operands[0], operands[1],
17401 operands[2], operands[3], false);
17402 DONE;
17403 })
17404
17405 (define_insn "*call_pop"
17406 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17407 (match_operand 1))
17408 (set (reg:SI SP_REG)
17409 (plus:SI (reg:SI SP_REG)
17410 (match_operand:SI 2 "immediate_operand" "i")))]
17411 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17412 "* return ix86_output_call_insn (insn, operands[0]);"
17413 [(set_attr "type" "call")])
17414
17415 (define_insn "*sibcall_pop"
17416 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17417 (match_operand 1))
17418 (set (reg:SI SP_REG)
17419 (plus:SI (reg:SI SP_REG)
17420 (match_operand:SI 2 "immediate_operand" "i")))]
17421 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17422 "* return ix86_output_call_insn (insn, operands[0]);"
17423 [(set_attr "type" "call")])
17424
17425 (define_insn "*sibcall_pop_memory"
17426 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17427 (match_operand 1))
17428 (set (reg:SI SP_REG)
17429 (plus:SI (reg:SI SP_REG)
17430 (match_operand:SI 2 "immediate_operand" "i")))
17431 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17432 "!TARGET_64BIT"
17433 "* return ix86_output_call_insn (insn, operands[0]);"
17434 [(set_attr "type" "call")])
17435
17436 (define_peephole2
17437 [(set (match_operand:SI 0 "register_operand")
17438 (match_operand:SI 1 "memory_operand"))
17439 (parallel [(call (mem:QI (match_dup 0))
17440 (match_operand 3))
17441 (set (reg:SI SP_REG)
17442 (plus:SI (reg:SI SP_REG)
17443 (match_operand:SI 4 "immediate_operand")))])]
17444 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17445 && !reg_mentioned_p (operands[0],
17446 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17447 [(parallel [(call (mem:QI (match_dup 1))
17448 (match_dup 3))
17449 (set (reg:SI SP_REG)
17450 (plus:SI (reg:SI SP_REG)
17451 (match_dup 4)))
17452 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17453
17454 (define_peephole2
17455 [(set (match_operand:SI 0 "register_operand")
17456 (match_operand:SI 1 "memory_operand"))
17457 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17458 (parallel [(call (mem:QI (match_dup 0))
17459 (match_operand 3))
17460 (set (reg:SI SP_REG)
17461 (plus:SI (reg:SI SP_REG)
17462 (match_operand:SI 4 "immediate_operand")))])]
17463 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17464 && !reg_mentioned_p (operands[0],
17465 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17466 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17467 (parallel [(call (mem:QI (match_dup 1))
17468 (match_dup 3))
17469 (set (reg:SI SP_REG)
17470 (plus:SI (reg:SI SP_REG)
17471 (match_dup 4)))
17472 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17473
17474 ;; Combining simple memory jump instruction
17475
17476 (define_peephole2
17477 [(set (match_operand:W 0 "register_operand")
17478 (match_operand:W 1 "memory_operand"))
17479 (set (pc) (match_dup 0))]
17480 "!TARGET_X32
17481 && !TARGET_INDIRECT_BRANCH_REGISTER
17482 && peep2_reg_dead_p (2, operands[0])"
17483 [(set (pc) (match_dup 1))])
17484
17485 ;; Call subroutine, returning value in operand 0
17486
17487 (define_expand "call_value"
17488 [(set (match_operand 0)
17489 (call (match_operand:QI 1)
17490 (match_operand 2)))
17491 (use (match_operand 3))]
17492 ""
17493 {
17494 ix86_expand_call (operands[0], operands[1], operands[2],
17495 operands[3], NULL, false);
17496 DONE;
17497 })
17498
17499 (define_expand "sibcall_value"
17500 [(set (match_operand 0)
17501 (call (match_operand:QI 1)
17502 (match_operand 2)))
17503 (use (match_operand 3))]
17504 ""
17505 {
17506 ix86_expand_call (operands[0], operands[1], operands[2],
17507 operands[3], NULL, true);
17508 DONE;
17509 })
17510
17511 (define_insn "*call_value"
17512 [(set (match_operand 0)
17513 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17514 (match_operand 2)))]
17515 "!SIBLING_CALL_P (insn)"
17516 "* return ix86_output_call_insn (insn, operands[1]);"
17517 [(set_attr "type" "callv")])
17518
17519 ;; This covers both call and sibcall since only GOT slot is allowed.
17520 (define_insn "*call_value_got_x32"
17521 [(set (match_operand 0)
17522 (call (mem:QI
17523 (zero_extend:DI
17524 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17525 (match_operand 2)))]
17526 "TARGET_X32"
17527 {
17528 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17529 return ix86_output_call_insn (insn, fnaddr);
17530 }
17531 [(set_attr "type" "callv")])
17532
17533 ;; Since sibcall never returns, we can only use call-clobbered register
17534 ;; as GOT base.
17535 (define_insn "*sibcall_value_GOT_32"
17536 [(set (match_operand 0)
17537 (call (mem:QI
17538 (mem:SI (plus:SI
17539 (match_operand:SI 1 "register_no_elim_operand" "U")
17540 (match_operand:SI 2 "GOT32_symbol_operand"))))
17541 (match_operand 3)))]
17542 "!TARGET_MACHO
17543 && !TARGET_64BIT
17544 && !TARGET_INDIRECT_BRANCH_REGISTER
17545 && SIBLING_CALL_P (insn)"
17546 {
17547 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17548 fnaddr = gen_const_mem (SImode, fnaddr);
17549 return ix86_output_call_insn (insn, fnaddr);
17550 }
17551 [(set_attr "type" "callv")])
17552
17553 (define_insn "*sibcall_value"
17554 [(set (match_operand 0)
17555 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17556 (match_operand 2)))]
17557 "SIBLING_CALL_P (insn)"
17558 "* return ix86_output_call_insn (insn, operands[1]);"
17559 [(set_attr "type" "callv")])
17560
17561 (define_insn "*sibcall_value_memory"
17562 [(set (match_operand 0)
17563 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17564 (match_operand 2)))
17565 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17566 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17567 "* return ix86_output_call_insn (insn, operands[1]);"
17568 [(set_attr "type" "callv")])
17569
17570 (define_peephole2
17571 [(set (match_operand:W 0 "register_operand")
17572 (match_operand:W 1 "memory_operand"))
17573 (set (match_operand 2)
17574 (call (mem:QI (match_dup 0))
17575 (match_operand 3)))]
17576 "!TARGET_X32
17577 && !TARGET_INDIRECT_BRANCH_REGISTER
17578 && SIBLING_CALL_P (peep2_next_insn (1))
17579 && !reg_mentioned_p (operands[0],
17580 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17581 [(parallel [(set (match_dup 2)
17582 (call (mem:QI (match_dup 1))
17583 (match_dup 3)))
17584 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17585
17586 (define_peephole2
17587 [(set (match_operand:W 0 "register_operand")
17588 (match_operand:W 1 "memory_operand"))
17589 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17590 (set (match_operand 2)
17591 (call (mem:QI (match_dup 0))
17592 (match_operand 3)))]
17593 "!TARGET_X32
17594 && !TARGET_INDIRECT_BRANCH_REGISTER
17595 && SIBLING_CALL_P (peep2_next_insn (2))
17596 && !reg_mentioned_p (operands[0],
17597 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17598 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17599 (parallel [(set (match_dup 2)
17600 (call (mem:QI (match_dup 1))
17601 (match_dup 3)))
17602 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17603
17604 (define_expand "call_value_pop"
17605 [(parallel [(set (match_operand 0)
17606 (call (match_operand:QI 1)
17607 (match_operand:SI 2)))
17608 (set (reg:SI SP_REG)
17609 (plus:SI (reg:SI SP_REG)
17610 (match_operand:SI 4)))])]
17611 "!TARGET_64BIT"
17612 {
17613 ix86_expand_call (operands[0], operands[1], operands[2],
17614 operands[3], operands[4], false);
17615 DONE;
17616 })
17617
17618 (define_insn "*call_value_pop"
17619 [(set (match_operand 0)
17620 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17621 (match_operand 2)))
17622 (set (reg:SI SP_REG)
17623 (plus:SI (reg:SI SP_REG)
17624 (match_operand:SI 3 "immediate_operand" "i")))]
17625 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17626 "* return ix86_output_call_insn (insn, operands[1]);"
17627 [(set_attr "type" "callv")])
17628
17629 (define_insn "*sibcall_value_pop"
17630 [(set (match_operand 0)
17631 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17632 (match_operand 2)))
17633 (set (reg:SI SP_REG)
17634 (plus:SI (reg:SI SP_REG)
17635 (match_operand:SI 3 "immediate_operand" "i")))]
17636 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17637 "* return ix86_output_call_insn (insn, operands[1]);"
17638 [(set_attr "type" "callv")])
17639
17640 (define_insn "*sibcall_value_pop_memory"
17641 [(set (match_operand 0)
17642 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17643 (match_operand 2)))
17644 (set (reg:SI SP_REG)
17645 (plus:SI (reg:SI SP_REG)
17646 (match_operand:SI 3 "immediate_operand" "i")))
17647 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17648 "!TARGET_64BIT"
17649 "* return ix86_output_call_insn (insn, operands[1]);"
17650 [(set_attr "type" "callv")])
17651
17652 (define_peephole2
17653 [(set (match_operand:SI 0 "register_operand")
17654 (match_operand:SI 1 "memory_operand"))
17655 (parallel [(set (match_operand 2)
17656 (call (mem:QI (match_dup 0))
17657 (match_operand 3)))
17658 (set (reg:SI SP_REG)
17659 (plus:SI (reg:SI SP_REG)
17660 (match_operand:SI 4 "immediate_operand")))])]
17661 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17662 && !reg_mentioned_p (operands[0],
17663 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17664 [(parallel [(set (match_dup 2)
17665 (call (mem:QI (match_dup 1))
17666 (match_dup 3)))
17667 (set (reg:SI SP_REG)
17668 (plus:SI (reg:SI SP_REG)
17669 (match_dup 4)))
17670 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17671
17672 (define_peephole2
17673 [(set (match_operand:SI 0 "register_operand")
17674 (match_operand:SI 1 "memory_operand"))
17675 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17676 (parallel [(set (match_operand 2)
17677 (call (mem:QI (match_dup 0))
17678 (match_operand 3)))
17679 (set (reg:SI SP_REG)
17680 (plus:SI (reg:SI SP_REG)
17681 (match_operand:SI 4 "immediate_operand")))])]
17682 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17683 && !reg_mentioned_p (operands[0],
17684 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17685 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17686 (parallel [(set (match_dup 2)
17687 (call (mem:QI (match_dup 1))
17688 (match_dup 3)))
17689 (set (reg:SI SP_REG)
17690 (plus:SI (reg:SI SP_REG)
17691 (match_dup 4)))
17692 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17693
17694 ;; Call subroutine returning any type.
17695
17696 (define_expand "untyped_call"
17697 [(parallel [(call (match_operand 0)
17698 (const_int 0))
17699 (match_operand 1)
17700 (match_operand 2)])]
17701 ""
17702 {
17703 int i;
17704
17705 /* In order to give reg-stack an easier job in validating two
17706 coprocessor registers as containing a possible return value,
17707 simply pretend the untyped call returns a complex long double
17708 value.
17709
17710 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17711 and should have the default ABI. */
17712
17713 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17714 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17715 operands[0], const0_rtx,
17716 GEN_INT ((TARGET_64BIT
17717 ? (ix86_abi == SYSV_ABI
17718 ? X86_64_SSE_REGPARM_MAX
17719 : X86_64_MS_SSE_REGPARM_MAX)
17720 : X86_32_SSE_REGPARM_MAX)
17721 - 1),
17722 NULL, false);
17723
17724 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17725 {
17726 rtx set = XVECEXP (operands[2], 0, i);
17727 emit_move_insn (SET_DEST (set), SET_SRC (set));
17728 }
17729
17730 /* The optimizer does not know that the call sets the function value
17731 registers we stored in the result block. We avoid problems by
17732 claiming that all hard registers are used and clobbered at this
17733 point. */
17734 emit_insn (gen_blockage ());
17735
17736 DONE;
17737 })
17738 \f
17739 ;; Prologue and epilogue instructions
17740
17741 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17742 ;; all of memory. This blocks insns from being moved across this point.
17743
17744 (define_insn "blockage"
17745 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17746 ""
17747 ""
17748 [(set_attr "length" "0")])
17749
17750 ;; Do not schedule instructions accessing memory across this point.
17751
17752 (define_expand "memory_blockage"
17753 [(set (match_dup 0)
17754 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17755 ""
17756 {
17757 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17758 MEM_VOLATILE_P (operands[0]) = 1;
17759 })
17760
17761 (define_insn "*memory_blockage"
17762 [(set (match_operand:BLK 0)
17763 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17764 ""
17765 ""
17766 [(set_attr "length" "0")])
17767
17768 ;; As USE insns aren't meaningful after reload, this is used instead
17769 ;; to prevent deleting instructions setting registers for PIC code
17770 (define_insn "prologue_use"
17771 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17772 ""
17773 ""
17774 [(set_attr "length" "0")])
17775
17776 ;; Insn emitted into the body of a function to return from a function.
17777 ;; This is only done if the function's epilogue is known to be simple.
17778 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17779
17780 (define_expand "return"
17781 [(simple_return)]
17782 "ix86_can_use_return_insn_p ()"
17783 {
17784 if (crtl->args.pops_args)
17785 {
17786 rtx popc = GEN_INT (crtl->args.pops_args);
17787 emit_jump_insn (gen_simple_return_pop_internal (popc));
17788 DONE;
17789 }
17790 })
17791
17792 ;; We need to disable this for TARGET_SEH, as otherwise
17793 ;; shrink-wrapped prologue gets enabled too. This might exceed
17794 ;; the maximum size of prologue in unwind information.
17795 ;; Also disallow shrink-wrapping if using stack slot to pass the
17796 ;; static chain pointer - the first instruction has to be pushl %esi
17797 ;; and it can't be moved around, as we use alternate entry points
17798 ;; in that case.
17799 ;; Also disallow for ms_hook_prologue functions which have frame
17800 ;; pointer set up in function label which is correctly handled in
17801 ;; ix86_expand_{prologue|epligoue}() only.
17802
17803 (define_expand "simple_return"
17804 [(simple_return)]
17805 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17806 {
17807 if (crtl->args.pops_args)
17808 {
17809 rtx popc = GEN_INT (crtl->args.pops_args);
17810 emit_jump_insn (gen_simple_return_pop_internal (popc));
17811 DONE;
17812 }
17813 })
17814
17815 (define_insn "simple_return_internal"
17816 [(simple_return)]
17817 "reload_completed"
17818 "* return ix86_output_function_return (false);"
17819 [(set_attr "length" "1")
17820 (set_attr "atom_unit" "jeu")
17821 (set_attr "length_immediate" "0")
17822 (set_attr "modrm" "0")])
17823
17824 (define_insn "interrupt_return"
17825 [(simple_return)
17826 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17827 "reload_completed"
17828 {
17829 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17830 })
17831
17832 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17833 ;; instruction Athlon and K8 have.
17834
17835 (define_insn "simple_return_internal_long"
17836 [(simple_return)
17837 (unspec [(const_int 0)] UNSPEC_REP)]
17838 "reload_completed"
17839 "* return ix86_output_function_return (true);"
17840 [(set_attr "length" "2")
17841 (set_attr "atom_unit" "jeu")
17842 (set_attr "length_immediate" "0")
17843 (set_attr "prefix_rep" "1")
17844 (set_attr "modrm" "0")])
17845
17846 (define_insn_and_split "simple_return_pop_internal"
17847 [(simple_return)
17848 (use (match_operand:SI 0 "const_int_operand"))]
17849 "reload_completed"
17850 "ret\t%0"
17851 "&& cfun->machine->function_return_type != indirect_branch_keep"
17852 [(const_int 0)]
17853 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17854 [(set_attr "length" "3")
17855 (set_attr "atom_unit" "jeu")
17856 (set_attr "length_immediate" "2")
17857 (set_attr "modrm" "0")])
17858
17859 (define_expand "simple_return_indirect_internal"
17860 [(parallel
17861 [(simple_return)
17862 (use (match_operand 0 "register_operand"))])])
17863
17864 (define_insn "*simple_return_indirect_internal<mode>"
17865 [(simple_return)
17866 (use (match_operand:W 0 "register_operand" "r"))]
17867 "reload_completed"
17868 "* return ix86_output_indirect_function_return (operands[0]);"
17869 [(set (attr "type")
17870 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17871 != indirect_branch_keep)")
17872 (const_string "multi")
17873 (const_string "ibr")))
17874 (set_attr "length_immediate" "0")])
17875
17876 (define_insn "nop"
17877 [(const_int 0)]
17878 ""
17879 "nop"
17880 [(set_attr "length" "1")
17881 (set_attr "length_immediate" "0")
17882 (set_attr "modrm" "0")])
17883
17884 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17885 (define_insn "nops"
17886 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17887 UNSPECV_NOPS)]
17888 "reload_completed"
17889 {
17890 int num = INTVAL (operands[0]);
17891
17892 gcc_assert (IN_RANGE (num, 1, 8));
17893
17894 while (num--)
17895 fputs ("\tnop\n", asm_out_file);
17896
17897 return "";
17898 }
17899 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17900 (set_attr "length_immediate" "0")
17901 (set_attr "modrm" "0")])
17902
17903 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17904 ;; branch prediction penalty for the third jump in a 16-byte
17905 ;; block on K8.
17906
17907 (define_insn "pad"
17908 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17909 ""
17910 {
17911 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17912 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17913 #else
17914 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17915 The align insn is used to avoid 3 jump instructions in the row to improve
17916 branch prediction and the benefits hardly outweigh the cost of extra 8
17917 nops on the average inserted by full alignment pseudo operation. */
17918 #endif
17919 return "";
17920 }
17921 [(set_attr "length" "16")])
17922
17923 (define_expand "prologue"
17924 [(const_int 0)]
17925 ""
17926 "ix86_expand_prologue (); DONE;")
17927
17928 (define_expand "set_got"
17929 [(parallel
17930 [(set (match_operand:SI 0 "register_operand")
17931 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17932 (clobber (reg:CC FLAGS_REG))])]
17933 "!TARGET_64BIT"
17934 {
17935 if (flag_pic && !TARGET_VXWORKS_RTP)
17936 ix86_pc_thunk_call_expanded = true;
17937 })
17938
17939 (define_insn "*set_got"
17940 [(set (match_operand:SI 0 "register_operand" "=r")
17941 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17942 (clobber (reg:CC FLAGS_REG))]
17943 "!TARGET_64BIT"
17944 "* return output_set_got (operands[0], NULL_RTX);"
17945 [(set_attr "type" "multi")
17946 (set_attr "length" "12")])
17947
17948 (define_expand "set_got_labelled"
17949 [(parallel
17950 [(set (match_operand:SI 0 "register_operand")
17951 (unspec:SI [(label_ref (match_operand 1))]
17952 UNSPEC_SET_GOT))
17953 (clobber (reg:CC FLAGS_REG))])]
17954 "!TARGET_64BIT"
17955 {
17956 if (flag_pic && !TARGET_VXWORKS_RTP)
17957 ix86_pc_thunk_call_expanded = true;
17958 })
17959
17960 (define_insn "*set_got_labelled"
17961 [(set (match_operand:SI 0 "register_operand" "=r")
17962 (unspec:SI [(label_ref (match_operand 1))]
17963 UNSPEC_SET_GOT))
17964 (clobber (reg:CC FLAGS_REG))]
17965 "!TARGET_64BIT"
17966 "* return output_set_got (operands[0], operands[1]);"
17967 [(set_attr "type" "multi")
17968 (set_attr "length" "12")])
17969
17970 (define_insn "set_got_rex64"
17971 [(set (match_operand:DI 0 "register_operand" "=r")
17972 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17973 "TARGET_64BIT"
17974 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17975 [(set_attr "type" "lea")
17976 (set_attr "length_address" "4")
17977 (set_attr "mode" "DI")])
17978
17979 (define_insn "set_rip_rex64"
17980 [(set (match_operand:DI 0 "register_operand" "=r")
17981 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17982 "TARGET_64BIT"
17983 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17984 [(set_attr "type" "lea")
17985 (set_attr "length_address" "4")
17986 (set_attr "mode" "DI")])
17987
17988 (define_insn "set_got_offset_rex64"
17989 [(set (match_operand:DI 0 "register_operand" "=r")
17990 (unspec:DI
17991 [(label_ref (match_operand 1))]
17992 UNSPEC_SET_GOT_OFFSET))]
17993 "TARGET_LP64"
17994 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17995 [(set_attr "type" "imov")
17996 (set_attr "length_immediate" "0")
17997 (set_attr "length_address" "8")
17998 (set_attr "mode" "DI")])
17999
18000 (define_expand "epilogue"
18001 [(const_int 0)]
18002 ""
18003 "ix86_expand_epilogue (1); DONE;")
18004
18005 (define_expand "sibcall_epilogue"
18006 [(const_int 0)]
18007 ""
18008 "ix86_expand_epilogue (0); DONE;")
18009
18010 (define_expand "eh_return"
18011 [(use (match_operand 0 "register_operand"))]
18012 ""
18013 {
18014 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
18015
18016 /* Tricky bit: we write the address of the handler to which we will
18017 be returning into someone else's stack frame, one word below the
18018 stack address we wish to restore. */
18019 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
18020 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
18021 /* Return address is always in word_mode. */
18022 tmp = gen_rtx_MEM (word_mode, tmp);
18023 if (GET_MODE (ra) != word_mode)
18024 ra = convert_to_mode (word_mode, ra, 1);
18025 emit_move_insn (tmp, ra);
18026
18027 emit_jump_insn (gen_eh_return_internal ());
18028 emit_barrier ();
18029 DONE;
18030 })
18031
18032 (define_insn_and_split "eh_return_internal"
18033 [(eh_return)]
18034 ""
18035 "#"
18036 "epilogue_completed"
18037 [(const_int 0)]
18038 "ix86_expand_epilogue (2); DONE;")
18039
18040 (define_expand "@leave_<mode>"
18041 [(parallel
18042 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
18043 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
18044 (clobber (mem:BLK (scratch)))])]
18045 ""
18046 "operands[0] = GEN_INT (<MODE_SIZE>);")
18047
18048 (define_insn "*leave"
18049 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
18050 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
18051 (clobber (mem:BLK (scratch)))]
18052 "!TARGET_64BIT"
18053 "leave"
18054 [(set_attr "type" "leave")])
18055
18056 (define_insn "*leave_rex64"
18057 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
18058 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
18059 (clobber (mem:BLK (scratch)))]
18060 "TARGET_64BIT"
18061 "leave"
18062 [(set_attr "type" "leave")])
18063 \f
18064 ;; Handle -fsplit-stack.
18065
18066 (define_expand "split_stack_prologue"
18067 [(const_int 0)]
18068 ""
18069 {
18070 ix86_expand_split_stack_prologue ();
18071 DONE;
18072 })
18073
18074 ;; In order to support the call/return predictor, we use a return
18075 ;; instruction which the middle-end doesn't see.
18076 (define_insn "split_stack_return"
18077 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
18078 UNSPECV_SPLIT_STACK_RETURN)]
18079 ""
18080 {
18081 if (operands[0] == const0_rtx)
18082 return "ret";
18083 else
18084 return "ret\t%0";
18085 }
18086 [(set_attr "atom_unit" "jeu")
18087 (set_attr "modrm" "0")
18088 (set (attr "length")
18089 (if_then_else (match_operand:SI 0 "const0_operand")
18090 (const_int 1)
18091 (const_int 3)))
18092 (set (attr "length_immediate")
18093 (if_then_else (match_operand:SI 0 "const0_operand")
18094 (const_int 0)
18095 (const_int 2)))])
18096
18097 ;; If there are operand 0 bytes available on the stack, jump to
18098 ;; operand 1.
18099
18100 (define_expand "split_stack_space_check"
18101 [(set (pc) (if_then_else
18102 (ltu (minus (reg SP_REG)
18103 (match_operand 0 "register_operand"))
18104 (match_dup 2))
18105 (label_ref (match_operand 1))
18106 (pc)))]
18107 ""
18108 {
18109 rtx reg = gen_reg_rtx (Pmode);
18110
18111 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18112
18113 operands[2] = ix86_split_stack_guard ();
18114 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18115
18116 DONE;
18117 })
18118 \f
18119 ;; Bit manipulation instructions.
18120
18121 (define_expand "ffs<mode>2"
18122 [(set (match_dup 2) (const_int -1))
18123 (parallel [(set (match_dup 3) (match_dup 4))
18124 (set (match_operand:SWI48 0 "register_operand")
18125 (ctz:SWI48
18126 (match_operand:SWI48 1 "nonimmediate_operand")))])
18127 (set (match_dup 0) (if_then_else:SWI48
18128 (eq (match_dup 3) (const_int 0))
18129 (match_dup 2)
18130 (match_dup 0)))
18131 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18132 (clobber (reg:CC FLAGS_REG))])]
18133 ""
18134 {
18135 machine_mode flags_mode;
18136
18137 if (<MODE>mode == SImode && !TARGET_CMOVE)
18138 {
18139 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18140 DONE;
18141 }
18142
18143 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18144
18145 operands[2] = gen_reg_rtx (<MODE>mode);
18146 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18147 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18148 })
18149
18150 (define_insn_and_split "ffssi2_no_cmove"
18151 [(set (match_operand:SI 0 "register_operand" "=r")
18152 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18153 (clobber (match_scratch:SI 2 "=&q"))
18154 (clobber (reg:CC FLAGS_REG))]
18155 "!TARGET_CMOVE"
18156 "#"
18157 "&& reload_completed"
18158 [(parallel [(set (match_dup 4) (match_dup 5))
18159 (set (match_dup 0) (ctz:SI (match_dup 1)))])
18160 (set (strict_low_part (match_dup 3))
18161 (eq:QI (match_dup 4) (const_int 0)))
18162 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18163 (clobber (reg:CC FLAGS_REG))])
18164 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18165 (clobber (reg:CC FLAGS_REG))])
18166 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18167 (clobber (reg:CC FLAGS_REG))])]
18168 {
18169 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18170
18171 operands[3] = gen_lowpart (QImode, operands[2]);
18172 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18173 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18174
18175 ix86_expand_clear (operands[2]);
18176 })
18177
18178 (define_insn_and_split "*tzcnt<mode>_1"
18179 [(set (reg:CCC FLAGS_REG)
18180 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18181 (const_int 0)))
18182 (set (match_operand:SWI48 0 "register_operand" "=r")
18183 (ctz:SWI48 (match_dup 1)))]
18184 "TARGET_BMI"
18185 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18186 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18187 && optimize_function_for_speed_p (cfun)
18188 && !reg_mentioned_p (operands[0], operands[1])"
18189 [(parallel
18190 [(set (reg:CCC FLAGS_REG)
18191 (compare:CCC (match_dup 1) (const_int 0)))
18192 (set (match_dup 0)
18193 (ctz:SWI48 (match_dup 1)))
18194 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18195 "ix86_expand_clear (operands[0]);"
18196 [(set_attr "type" "alu1")
18197 (set_attr "prefix_0f" "1")
18198 (set_attr "prefix_rep" "1")
18199 (set_attr "btver2_decode" "double")
18200 (set_attr "mode" "<MODE>")])
18201
18202 ; False dependency happens when destination is only updated by tzcnt,
18203 ; lzcnt or popcnt. There is no false dependency when destination is
18204 ; also used in source.
18205 (define_insn "*tzcnt<mode>_1_falsedep"
18206 [(set (reg:CCC FLAGS_REG)
18207 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18208 (const_int 0)))
18209 (set (match_operand:SWI48 0 "register_operand" "=r")
18210 (ctz:SWI48 (match_dup 1)))
18211 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18212 UNSPEC_INSN_FALSE_DEP)]
18213 "TARGET_BMI"
18214 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18215 [(set_attr "type" "alu1")
18216 (set_attr "prefix_0f" "1")
18217 (set_attr "prefix_rep" "1")
18218 (set_attr "btver2_decode" "double")
18219 (set_attr "mode" "<MODE>")])
18220
18221 (define_insn "*bsf<mode>_1"
18222 [(set (reg:CCZ FLAGS_REG)
18223 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18224 (const_int 0)))
18225 (set (match_operand:SWI48 0 "register_operand" "=r")
18226 (ctz:SWI48 (match_dup 1)))]
18227 ""
18228 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18229 [(set_attr "type" "alu1")
18230 (set_attr "prefix_0f" "1")
18231 (set_attr "btver2_decode" "double")
18232 (set_attr "znver1_decode" "vector")
18233 (set_attr "mode" "<MODE>")])
18234
18235 (define_insn_and_split "ctz<mode>2"
18236 [(set (match_operand:SWI48 0 "register_operand" "=r")
18237 (ctz:SWI48
18238 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18239 (clobber (reg:CC FLAGS_REG))]
18240 ""
18241 {
18242 if (TARGET_BMI)
18243 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18244 else if (optimize_function_for_size_p (cfun))
18245 ;
18246 else if (TARGET_CPU_P (GENERIC))
18247 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18248 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18249
18250 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18251 }
18252 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18253 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18254 && optimize_function_for_speed_p (cfun)
18255 && !reg_mentioned_p (operands[0], operands[1])"
18256 [(parallel
18257 [(set (match_dup 0)
18258 (ctz:SWI48 (match_dup 1)))
18259 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18260 (clobber (reg:CC FLAGS_REG))])]
18261 "ix86_expand_clear (operands[0]);"
18262 [(set_attr "type" "alu1")
18263 (set_attr "prefix_0f" "1")
18264 (set (attr "prefix_rep")
18265 (if_then_else
18266 (ior (match_test "TARGET_BMI")
18267 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18268 (match_test "TARGET_CPU_P (GENERIC)")))
18269 (const_string "1")
18270 (const_string "0")))
18271 (set_attr "mode" "<MODE>")])
18272
18273 ; False dependency happens when destination is only updated by tzcnt,
18274 ; lzcnt or popcnt. There is no false dependency when destination is
18275 ; also used in source.
18276 (define_insn "*ctz<mode>2_falsedep"
18277 [(set (match_operand:SWI48 0 "register_operand" "=r")
18278 (ctz:SWI48
18279 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18280 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18281 UNSPEC_INSN_FALSE_DEP)
18282 (clobber (reg:CC FLAGS_REG))]
18283 ""
18284 {
18285 if (TARGET_BMI)
18286 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18287 else if (TARGET_CPU_P (GENERIC))
18288 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18289 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18290 else
18291 gcc_unreachable ();
18292 }
18293 [(set_attr "type" "alu1")
18294 (set_attr "prefix_0f" "1")
18295 (set_attr "prefix_rep" "1")
18296 (set_attr "mode" "<MODE>")])
18297
18298 (define_insn_and_split "*ctzsi2_zext"
18299 [(set (match_operand:DI 0 "register_operand" "=r")
18300 (and:DI
18301 (subreg:DI
18302 (ctz:SI
18303 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18304 (const_int 63)))
18305 (clobber (reg:CC FLAGS_REG))]
18306 "TARGET_BMI && TARGET_64BIT"
18307 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18308 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18309 && optimize_function_for_speed_p (cfun)
18310 && !reg_mentioned_p (operands[0], operands[1])"
18311 [(parallel
18312 [(set (match_dup 0)
18313 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18314 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18315 (clobber (reg:CC FLAGS_REG))])]
18316 "ix86_expand_clear (operands[0]);"
18317 [(set_attr "type" "alu1")
18318 (set_attr "prefix_0f" "1")
18319 (set_attr "prefix_rep" "1")
18320 (set_attr "mode" "SI")])
18321
18322 ; False dependency happens when destination is only updated by tzcnt,
18323 ; lzcnt or popcnt. There is no false dependency when destination is
18324 ; also used in source.
18325 (define_insn "*ctzsi2_zext_falsedep"
18326 [(set (match_operand:DI 0 "register_operand" "=r")
18327 (and:DI
18328 (subreg:DI
18329 (ctz:SI
18330 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18331 (const_int 63)))
18332 (unspec [(match_operand:DI 2 "register_operand" "0")]
18333 UNSPEC_INSN_FALSE_DEP)
18334 (clobber (reg:CC FLAGS_REG))]
18335 "TARGET_BMI && TARGET_64BIT"
18336 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18337 [(set_attr "type" "alu1")
18338 (set_attr "prefix_0f" "1")
18339 (set_attr "prefix_rep" "1")
18340 (set_attr "mode" "SI")])
18341
18342 (define_insn_and_split "*ctzsidi2_<s>ext"
18343 [(set (match_operand:DI 0 "register_operand" "=r")
18344 (any_extend:DI
18345 (ctz:SI
18346 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18347 (clobber (reg:CC FLAGS_REG))]
18348 "TARGET_64BIT"
18349 {
18350 if (TARGET_BMI)
18351 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18352 else if (TARGET_CPU_P (GENERIC)
18353 && !optimize_function_for_size_p (cfun))
18354 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18355 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18356 return "bsf{l}\t{%1, %k0|%k0, %1}";
18357 }
18358 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18359 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18360 && optimize_function_for_speed_p (cfun)
18361 && !reg_mentioned_p (operands[0], operands[1])"
18362 [(parallel
18363 [(set (match_dup 0)
18364 (any_extend:DI (ctz:SI (match_dup 1))))
18365 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18366 (clobber (reg:CC FLAGS_REG))])]
18367 "ix86_expand_clear (operands[0]);"
18368 [(set_attr "type" "alu1")
18369 (set_attr "prefix_0f" "1")
18370 (set (attr "prefix_rep")
18371 (if_then_else
18372 (ior (match_test "TARGET_BMI")
18373 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18374 (match_test "TARGET_CPU_P (GENERIC)")))
18375 (const_string "1")
18376 (const_string "0")))
18377 (set_attr "mode" "SI")])
18378
18379 (define_insn "*ctzsidi2_<s>ext_falsedep"
18380 [(set (match_operand:DI 0 "register_operand" "=r")
18381 (any_extend:DI
18382 (ctz:SI
18383 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18384 (unspec [(match_operand:DI 2 "register_operand" "0")]
18385 UNSPEC_INSN_FALSE_DEP)
18386 (clobber (reg:CC FLAGS_REG))]
18387 "TARGET_64BIT"
18388 {
18389 if (TARGET_BMI)
18390 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18391 else if (TARGET_CPU_P (GENERIC))
18392 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18393 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18394 else
18395 gcc_unreachable ();
18396 }
18397 [(set_attr "type" "alu1")
18398 (set_attr "prefix_0f" "1")
18399 (set_attr "prefix_rep" "1")
18400 (set_attr "mode" "SI")])
18401
18402 (define_insn "bsr_rex64"
18403 [(set (reg:CCZ FLAGS_REG)
18404 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18405 (const_int 0)))
18406 (set (match_operand:DI 0 "register_operand" "=r")
18407 (minus:DI (const_int 63)
18408 (clz:DI (match_dup 1))))]
18409 "TARGET_64BIT"
18410 "bsr{q}\t{%1, %0|%0, %1}"
18411 [(set_attr "type" "alu1")
18412 (set_attr "prefix_0f" "1")
18413 (set_attr "znver1_decode" "vector")
18414 (set_attr "mode" "DI")])
18415
18416 (define_insn "bsr_rex64_1"
18417 [(set (match_operand:DI 0 "register_operand" "=r")
18418 (minus:DI (const_int 63)
18419 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18420 (clobber (reg:CC FLAGS_REG))]
18421 "!TARGET_LZCNT && TARGET_64BIT"
18422 "bsr{q}\t{%1, %0|%0, %1}"
18423 [(set_attr "type" "alu1")
18424 (set_attr "prefix_0f" "1")
18425 (set_attr "znver1_decode" "vector")
18426 (set_attr "mode" "DI")])
18427
18428 (define_insn "bsr_rex64_1_zext"
18429 [(set (match_operand:DI 0 "register_operand" "=r")
18430 (zero_extend:DI
18431 (minus:SI (const_int 63)
18432 (subreg:SI
18433 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18434 0))))
18435 (clobber (reg:CC FLAGS_REG))]
18436 "!TARGET_LZCNT && TARGET_64BIT"
18437 "bsr{q}\t{%1, %0|%0, %1}"
18438 [(set_attr "type" "alu1")
18439 (set_attr "prefix_0f" "1")
18440 (set_attr "znver1_decode" "vector")
18441 (set_attr "mode" "DI")])
18442
18443 (define_insn "bsr"
18444 [(set (reg:CCZ FLAGS_REG)
18445 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18446 (const_int 0)))
18447 (set (match_operand:SI 0 "register_operand" "=r")
18448 (minus:SI (const_int 31)
18449 (clz:SI (match_dup 1))))]
18450 ""
18451 "bsr{l}\t{%1, %0|%0, %1}"
18452 [(set_attr "type" "alu1")
18453 (set_attr "prefix_0f" "1")
18454 (set_attr "znver1_decode" "vector")
18455 (set_attr "mode" "SI")])
18456
18457 (define_insn "bsr_1"
18458 [(set (match_operand:SI 0 "register_operand" "=r")
18459 (minus:SI (const_int 31)
18460 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18461 (clobber (reg:CC FLAGS_REG))]
18462 "!TARGET_LZCNT"
18463 "bsr{l}\t{%1, %0|%0, %1}"
18464 [(set_attr "type" "alu1")
18465 (set_attr "prefix_0f" "1")
18466 (set_attr "znver1_decode" "vector")
18467 (set_attr "mode" "SI")])
18468
18469 (define_insn "bsr_zext_1"
18470 [(set (match_operand:DI 0 "register_operand" "=r")
18471 (zero_extend:DI
18472 (minus:SI
18473 (const_int 31)
18474 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18475 (clobber (reg:CC FLAGS_REG))]
18476 "!TARGET_LZCNT && TARGET_64BIT"
18477 "bsr{l}\t{%1, %k0|%k0, %1}"
18478 [(set_attr "type" "alu1")
18479 (set_attr "prefix_0f" "1")
18480 (set_attr "znver1_decode" "vector")
18481 (set_attr "mode" "SI")])
18482
18483 ; As bsr is undefined behavior on zero and for other input
18484 ; values it is in range 0 to 63, we can optimize away sign-extends.
18485 (define_insn_and_split "*bsr_rex64_2"
18486 [(set (match_operand:DI 0 "register_operand")
18487 (xor:DI
18488 (sign_extend:DI
18489 (minus:SI
18490 (const_int 63)
18491 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18492 0)))
18493 (const_int 63)))
18494 (clobber (reg:CC FLAGS_REG))]
18495 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18496 "#"
18497 "&& 1"
18498 [(parallel [(set (reg:CCZ FLAGS_REG)
18499 (compare:CCZ (match_dup 1) (const_int 0)))
18500 (set (match_dup 2)
18501 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18502 (parallel [(set (match_dup 0)
18503 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18504 (clobber (reg:CC FLAGS_REG))])]
18505 {
18506 operands[2] = gen_reg_rtx (DImode);
18507 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18508 })
18509
18510 (define_insn_and_split "*bsr_2"
18511 [(set (match_operand:DI 0 "register_operand")
18512 (sign_extend:DI
18513 (xor:SI
18514 (minus:SI
18515 (const_int 31)
18516 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18517 (const_int 31))))
18518 (clobber (reg:CC FLAGS_REG))]
18519 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18520 "#"
18521 "&& 1"
18522 [(parallel [(set (reg:CCZ FLAGS_REG)
18523 (compare:CCZ (match_dup 1) (const_int 0)))
18524 (set (match_dup 2)
18525 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18526 (parallel [(set (match_dup 0)
18527 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18528 (clobber (reg:CC FLAGS_REG))])]
18529 "operands[2] = gen_reg_rtx (SImode);")
18530
18531 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18532 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18533 ; in [0, 63] or [0, 31] range.
18534 (define_split
18535 [(set (match_operand:SI 0 "register_operand")
18536 (minus:SI
18537 (match_operand:SI 2 "const_int_operand")
18538 (xor:SI
18539 (minus:SI (const_int 63)
18540 (subreg:SI
18541 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18542 0))
18543 (const_int 63))))]
18544 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18545 [(set (match_dup 3)
18546 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18547 (set (match_dup 0)
18548 (plus:SI (match_dup 5) (match_dup 4)))]
18549 {
18550 operands[3] = gen_reg_rtx (DImode);
18551 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18552 if (INTVAL (operands[2]) == 63)
18553 {
18554 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18555 emit_move_insn (operands[0], operands[5]);
18556 DONE;
18557 }
18558 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18559 })
18560
18561 (define_split
18562 [(set (match_operand:SI 0 "register_operand")
18563 (minus:SI
18564 (match_operand:SI 2 "const_int_operand")
18565 (xor:SI
18566 (minus:SI (const_int 31)
18567 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18568 (const_int 31))))]
18569 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18570 [(set (match_dup 3)
18571 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18572 (set (match_dup 0)
18573 (plus:SI (match_dup 3) (match_dup 4)))]
18574 {
18575 if (INTVAL (operands[2]) == 31)
18576 {
18577 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18578 DONE;
18579 }
18580 operands[3] = gen_reg_rtx (SImode);
18581 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18582 })
18583
18584 (define_split
18585 [(set (match_operand:DI 0 "register_operand")
18586 (minus:DI
18587 (match_operand:DI 2 "const_int_operand")
18588 (xor:DI
18589 (sign_extend:DI
18590 (minus:SI (const_int 63)
18591 (subreg:SI
18592 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18593 0)))
18594 (const_int 63))))]
18595 "!TARGET_LZCNT
18596 && TARGET_64BIT
18597 && ix86_pre_reload_split ()
18598 && ((unsigned HOST_WIDE_INT)
18599 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18600 == UINTVAL (operands[2]) - 63)"
18601 [(set (match_dup 3)
18602 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18603 (set (match_dup 0)
18604 (plus:DI (match_dup 3) (match_dup 4)))]
18605 {
18606 if (INTVAL (operands[2]) == 63)
18607 {
18608 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18609 DONE;
18610 }
18611 operands[3] = gen_reg_rtx (DImode);
18612 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18613 })
18614
18615 (define_split
18616 [(set (match_operand:DI 0 "register_operand")
18617 (minus:DI
18618 (match_operand:DI 2 "const_int_operand")
18619 (sign_extend:DI
18620 (xor:SI
18621 (minus:SI (const_int 31)
18622 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18623 (const_int 31)))))]
18624 "!TARGET_LZCNT
18625 && TARGET_64BIT
18626 && ix86_pre_reload_split ()
18627 && ((unsigned HOST_WIDE_INT)
18628 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18629 == UINTVAL (operands[2]) - 31)"
18630 [(set (match_dup 3)
18631 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18632 (set (match_dup 0)
18633 (plus:DI (match_dup 3) (match_dup 4)))]
18634 {
18635 if (INTVAL (operands[2]) == 31)
18636 {
18637 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18638 DONE;
18639 }
18640 operands[3] = gen_reg_rtx (DImode);
18641 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18642 })
18643
18644 (define_expand "clz<mode>2"
18645 [(parallel
18646 [(set (reg:CCZ FLAGS_REG)
18647 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18648 (const_int 0)))
18649 (set (match_dup 3) (minus:SWI48
18650 (match_dup 2)
18651 (clz:SWI48 (match_dup 1))))])
18652 (parallel
18653 [(set (match_operand:SWI48 0 "register_operand")
18654 (xor:SWI48 (match_dup 3) (match_dup 2)))
18655 (clobber (reg:CC FLAGS_REG))])]
18656 ""
18657 {
18658 if (TARGET_LZCNT)
18659 {
18660 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18661 DONE;
18662 }
18663 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18664 operands[3] = gen_reg_rtx (<MODE>mode);
18665 })
18666
18667 (define_insn_and_split "clz<mode>2_lzcnt"
18668 [(set (match_operand:SWI48 0 "register_operand" "=r")
18669 (clz:SWI48
18670 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18671 (clobber (reg:CC FLAGS_REG))]
18672 "TARGET_LZCNT"
18673 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18674 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18675 && optimize_function_for_speed_p (cfun)
18676 && !reg_mentioned_p (operands[0], operands[1])"
18677 [(parallel
18678 [(set (match_dup 0)
18679 (clz:SWI48 (match_dup 1)))
18680 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18681 (clobber (reg:CC FLAGS_REG))])]
18682 "ix86_expand_clear (operands[0]);"
18683 [(set_attr "prefix_rep" "1")
18684 (set_attr "type" "bitmanip")
18685 (set_attr "mode" "<MODE>")])
18686
18687 ; False dependency happens when destination is only updated by tzcnt,
18688 ; lzcnt or popcnt. There is no false dependency when destination is
18689 ; also used in source.
18690 (define_insn "*clz<mode>2_lzcnt_falsedep"
18691 [(set (match_operand:SWI48 0 "register_operand" "=r")
18692 (clz:SWI48
18693 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18694 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18695 UNSPEC_INSN_FALSE_DEP)
18696 (clobber (reg:CC FLAGS_REG))]
18697 "TARGET_LZCNT"
18698 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18699 [(set_attr "prefix_rep" "1")
18700 (set_attr "type" "bitmanip")
18701 (set_attr "mode" "<MODE>")])
18702
18703 (define_insn_and_split "*clzsi2_lzcnt_zext"
18704 [(set (match_operand:DI 0 "register_operand" "=r")
18705 (and:DI
18706 (subreg:DI
18707 (clz:SI
18708 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18709 (const_int 63)))
18710 (clobber (reg:CC FLAGS_REG))]
18711 "TARGET_LZCNT && TARGET_64BIT"
18712 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18713 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18714 && optimize_function_for_speed_p (cfun)
18715 && !reg_mentioned_p (operands[0], operands[1])"
18716 [(parallel
18717 [(set (match_dup 0)
18718 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18719 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18720 (clobber (reg:CC FLAGS_REG))])]
18721 "ix86_expand_clear (operands[0]);"
18722 [(set_attr "prefix_rep" "1")
18723 (set_attr "type" "bitmanip")
18724 (set_attr "mode" "SI")])
18725
18726 ; False dependency happens when destination is only updated by tzcnt,
18727 ; lzcnt or popcnt. There is no false dependency when destination is
18728 ; also used in source.
18729 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18730 [(set (match_operand:DI 0 "register_operand" "=r")
18731 (and:DI
18732 (subreg:DI
18733 (clz:SI
18734 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18735 (const_int 63)))
18736 (unspec [(match_operand:DI 2 "register_operand" "0")]
18737 UNSPEC_INSN_FALSE_DEP)
18738 (clobber (reg:CC FLAGS_REG))]
18739 "TARGET_LZCNT"
18740 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18741 [(set_attr "prefix_rep" "1")
18742 (set_attr "type" "bitmanip")
18743 (set_attr "mode" "SI")])
18744
18745 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18746 [(set (match_operand:DI 0 "register_operand" "=r")
18747 (zero_extend:DI
18748 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18749 (clobber (reg:CC FLAGS_REG))]
18750 "TARGET_LZCNT && TARGET_64BIT"
18751 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18752 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18753 && optimize_function_for_speed_p (cfun)
18754 && !reg_mentioned_p (operands[0], operands[1])"
18755 [(parallel
18756 [(set (match_dup 0)
18757 (zero_extend:DI (clz:SI (match_dup 1))))
18758 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18759 (clobber (reg:CC FLAGS_REG))])]
18760 "ix86_expand_clear (operands[0]);"
18761 [(set_attr "prefix_rep" "1")
18762 (set_attr "type" "bitmanip")
18763 (set_attr "mode" "SI")])
18764
18765 ; False dependency happens when destination is only updated by tzcnt,
18766 ; lzcnt or popcnt. There is no false dependency when destination is
18767 ; also used in source.
18768 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18769 [(set (match_operand:DI 0 "register_operand" "=r")
18770 (zero_extend:DI
18771 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18772 (unspec [(match_operand:DI 2 "register_operand" "0")]
18773 UNSPEC_INSN_FALSE_DEP)
18774 (clobber (reg:CC FLAGS_REG))]
18775 "TARGET_LZCNT"
18776 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18777 [(set_attr "prefix_rep" "1")
18778 (set_attr "type" "bitmanip")
18779 (set_attr "mode" "SI")])
18780
18781 (define_int_iterator LT_ZCNT
18782 [(UNSPEC_TZCNT "TARGET_BMI")
18783 (UNSPEC_LZCNT "TARGET_LZCNT")])
18784
18785 (define_int_attr lt_zcnt
18786 [(UNSPEC_TZCNT "tzcnt")
18787 (UNSPEC_LZCNT "lzcnt")])
18788
18789 (define_int_attr lt_zcnt_type
18790 [(UNSPEC_TZCNT "alu1")
18791 (UNSPEC_LZCNT "bitmanip")])
18792
18793 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18794 ;; provides operand size as output when source operand is zero.
18795
18796 (define_insn_and_split "<lt_zcnt>_<mode>"
18797 [(set (match_operand:SWI48 0 "register_operand" "=r")
18798 (unspec:SWI48
18799 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18800 (clobber (reg:CC FLAGS_REG))]
18801 ""
18802 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18803 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18804 && optimize_function_for_speed_p (cfun)
18805 && !reg_mentioned_p (operands[0], operands[1])"
18806 [(parallel
18807 [(set (match_dup 0)
18808 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18809 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18810 (clobber (reg:CC FLAGS_REG))])]
18811 "ix86_expand_clear (operands[0]);"
18812 [(set_attr "type" "<lt_zcnt_type>")
18813 (set_attr "prefix_0f" "1")
18814 (set_attr "prefix_rep" "1")
18815 (set_attr "mode" "<MODE>")])
18816
18817 ; False dependency happens when destination is only updated by tzcnt,
18818 ; lzcnt or popcnt. There is no false dependency when destination is
18819 ; also used in source.
18820 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18821 [(set (match_operand:SWI48 0 "register_operand" "=r")
18822 (unspec:SWI48
18823 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18824 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18825 UNSPEC_INSN_FALSE_DEP)
18826 (clobber (reg:CC FLAGS_REG))]
18827 ""
18828 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18829 [(set_attr "type" "<lt_zcnt_type>")
18830 (set_attr "prefix_0f" "1")
18831 (set_attr "prefix_rep" "1")
18832 (set_attr "mode" "<MODE>")])
18833
18834 (define_insn "<lt_zcnt>_hi"
18835 [(set (match_operand:HI 0 "register_operand" "=r")
18836 (unspec:HI
18837 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18838 (clobber (reg:CC FLAGS_REG))]
18839 ""
18840 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18841 [(set_attr "type" "<lt_zcnt_type>")
18842 (set_attr "prefix_0f" "1")
18843 (set_attr "prefix_rep" "1")
18844 (set_attr "mode" "HI")])
18845
18846 ;; BMI instructions.
18847
18848 (define_insn "bmi_bextr_<mode>"
18849 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18850 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18851 (match_operand:SWI48 2 "register_operand" "r,r")]
18852 UNSPEC_BEXTR))
18853 (clobber (reg:CC FLAGS_REG))]
18854 "TARGET_BMI"
18855 "bextr\t{%2, %1, %0|%0, %1, %2}"
18856 [(set_attr "type" "bitmanip")
18857 (set_attr "btver2_decode" "direct, double")
18858 (set_attr "mode" "<MODE>")])
18859
18860 (define_insn "*bmi_bextr_<mode>_ccz"
18861 [(set (reg:CCZ FLAGS_REG)
18862 (compare:CCZ
18863 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18864 (match_operand:SWI48 2 "register_operand" "r,r")]
18865 UNSPEC_BEXTR)
18866 (const_int 0)))
18867 (clobber (match_scratch:SWI48 0 "=r,r"))]
18868 "TARGET_BMI"
18869 "bextr\t{%2, %1, %0|%0, %1, %2}"
18870 [(set_attr "type" "bitmanip")
18871 (set_attr "btver2_decode" "direct, double")
18872 (set_attr "mode" "<MODE>")])
18873
18874 (define_insn "*bmi_blsi_<mode>"
18875 [(set (match_operand:SWI48 0 "register_operand" "=r")
18876 (and:SWI48
18877 (neg:SWI48
18878 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18879 (match_dup 1)))
18880 (clobber (reg:CC FLAGS_REG))]
18881 "TARGET_BMI"
18882 "blsi\t{%1, %0|%0, %1}"
18883 [(set_attr "type" "bitmanip")
18884 (set_attr "btver2_decode" "double")
18885 (set_attr "mode" "<MODE>")])
18886
18887 (define_insn "*bmi_blsi_<mode>_cmp"
18888 [(set (reg FLAGS_REG)
18889 (compare
18890 (and:SWI48
18891 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18892 (match_dup 1))
18893 (const_int 0)))
18894 (set (match_operand:SWI48 0 "register_operand" "=r")
18895 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18896 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18897 "blsi\t{%1, %0|%0, %1}"
18898 [(set_attr "type" "bitmanip")
18899 (set_attr "btver2_decode" "double")
18900 (set_attr "mode" "<MODE>")])
18901
18902 (define_insn "*bmi_blsi_<mode>_ccno"
18903 [(set (reg FLAGS_REG)
18904 (compare
18905 (and:SWI48
18906 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18907 (match_dup 1))
18908 (const_int 0)))
18909 (clobber (match_scratch:SWI48 0 "=r"))]
18910 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18911 "blsi\t{%1, %0|%0, %1}"
18912 [(set_attr "type" "bitmanip")
18913 (set_attr "btver2_decode" "double")
18914 (set_attr "mode" "<MODE>")])
18915
18916 (define_insn "*bmi_blsmsk_<mode>"
18917 [(set (match_operand:SWI48 0 "register_operand" "=r")
18918 (xor:SWI48
18919 (plus:SWI48
18920 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18921 (const_int -1))
18922 (match_dup 1)))
18923 (clobber (reg:CC FLAGS_REG))]
18924 "TARGET_BMI"
18925 "blsmsk\t{%1, %0|%0, %1}"
18926 [(set_attr "type" "bitmanip")
18927 (set_attr "btver2_decode" "double")
18928 (set_attr "mode" "<MODE>")])
18929
18930 (define_insn "*bmi_blsr_<mode>"
18931 [(set (match_operand:SWI48 0 "register_operand" "=r")
18932 (and:SWI48
18933 (plus:SWI48
18934 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18935 (const_int -1))
18936 (match_dup 1)))
18937 (clobber (reg:CC FLAGS_REG))]
18938 "TARGET_BMI"
18939 "blsr\t{%1, %0|%0, %1}"
18940 [(set_attr "type" "bitmanip")
18941 (set_attr "btver2_decode" "double")
18942 (set_attr "mode" "<MODE>")])
18943
18944 (define_insn "*bmi_blsr_<mode>_cmp"
18945 [(set (reg:CCZ FLAGS_REG)
18946 (compare:CCZ
18947 (and:SWI48
18948 (plus:SWI48
18949 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18950 (const_int -1))
18951 (match_dup 1))
18952 (const_int 0)))
18953 (set (match_operand:SWI48 0 "register_operand" "=r")
18954 (and:SWI48
18955 (plus:SWI48
18956 (match_dup 1)
18957 (const_int -1))
18958 (match_dup 1)))]
18959 "TARGET_BMI"
18960 "blsr\t{%1, %0|%0, %1}"
18961 [(set_attr "type" "bitmanip")
18962 (set_attr "btver2_decode" "double")
18963 (set_attr "mode" "<MODE>")])
18964
18965 (define_insn "*bmi_blsr_<mode>_ccz"
18966 [(set (reg:CCZ FLAGS_REG)
18967 (compare:CCZ
18968 (and:SWI48
18969 (plus:SWI48
18970 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18971 (const_int -1))
18972 (match_dup 1))
18973 (const_int 0)))
18974 (clobber (match_scratch:SWI48 0 "=r"))]
18975 "TARGET_BMI"
18976 "blsr\t{%1, %0|%0, %1}"
18977 [(set_attr "type" "bitmanip")
18978 (set_attr "btver2_decode" "double")
18979 (set_attr "mode" "<MODE>")])
18980
18981 ;; BMI2 instructions.
18982 (define_expand "bmi2_bzhi_<mode>3"
18983 [(parallel
18984 [(set (match_operand:SWI48 0 "register_operand")
18985 (if_then_else:SWI48
18986 (ne:QI (match_operand:QI 2 "register_operand")
18987 (const_int 0))
18988 (zero_extract:SWI48
18989 (match_operand:SWI48 1 "nonimmediate_operand")
18990 (umin:QI (match_dup 2) (match_dup 3))
18991 (const_int 0))
18992 (const_int 0)))
18993 (clobber (reg:CC FLAGS_REG))])]
18994 "TARGET_BMI2"
18995 {
18996 operands[2] = gen_lowpart (QImode, operands[2]);
18997 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
18998 })
18999
19000 (define_insn "*bmi2_bzhi_<mode>3"
19001 [(set (match_operand:SWI48 0 "register_operand" "=r")
19002 (if_then_else:SWI48
19003 (ne:QI (match_operand:QI 2 "register_operand" "q")
19004 (const_int 0))
19005 (zero_extract:SWI48
19006 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19007 (umin:QI (match_dup 2)
19008 (match_operand:QI 3 "const_int_operand"))
19009 (const_int 0))
19010 (const_int 0)))
19011 (clobber (reg:CC FLAGS_REG))]
19012 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19013 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19014 [(set_attr "type" "bitmanip")
19015 (set_attr "prefix" "vex")
19016 (set_attr "mode" "<MODE>")])
19017
19018 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
19019 [(set (reg:CCZ FLAGS_REG)
19020 (compare:CCZ
19021 (if_then_else:SWI48
19022 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
19023 (zero_extract:SWI48
19024 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19025 (umin:QI (match_dup 2)
19026 (match_operand:QI 3 "const_int_operand"))
19027 (const_int 0))
19028 (const_int 0))
19029 (const_int 0)))
19030 (clobber (match_scratch:SWI48 0 "=r"))]
19031 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19032 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19033 [(set_attr "type" "bitmanip")
19034 (set_attr "prefix" "vex")
19035 (set_attr "mode" "<MODE>")])
19036
19037 (define_insn "*bmi2_bzhi_<mode>3_2"
19038 [(set (match_operand:SWI48 0 "register_operand" "=r")
19039 (and:SWI48
19040 (plus:SWI48
19041 (ashift:SWI48 (const_int 1)
19042 (match_operand:QI 2 "register_operand" "r"))
19043 (const_int -1))
19044 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19045 (clobber (reg:CC FLAGS_REG))]
19046 "TARGET_BMI2"
19047 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19048 [(set_attr "type" "bitmanip")
19049 (set_attr "prefix" "vex")
19050 (set_attr "mode" "<MODE>")])
19051
19052 (define_insn "*bmi2_bzhi_<mode>3_3"
19053 [(set (match_operand:SWI48 0 "register_operand" "=r")
19054 (and:SWI48
19055 (not:SWI48
19056 (ashift:SWI48 (const_int -1)
19057 (match_operand:QI 2 "register_operand" "r")))
19058 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19059 (clobber (reg:CC FLAGS_REG))]
19060 "TARGET_BMI2"
19061 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19062 [(set_attr "type" "bitmanip")
19063 (set_attr "prefix" "vex")
19064 (set_attr "mode" "<MODE>")])
19065
19066 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
19067 [(set (match_operand:DI 0 "register_operand" "=r")
19068 (zero_extend:DI
19069 (and:SI
19070 (plus:SI
19071 (ashift:SI (const_int 1)
19072 (match_operand:QI 2 "register_operand" "r"))
19073 (const_int -1))
19074 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19075 (clobber (reg:CC FLAGS_REG))]
19076 "TARGET_64BIT && TARGET_BMI2"
19077 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19078 [(set_attr "type" "bitmanip")
19079 (set_attr "prefix" "vex")
19080 (set_attr "mode" "DI")])
19081
19082 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
19083 [(set (match_operand:DI 0 "register_operand" "=r")
19084 (and:DI
19085 (zero_extend:DI
19086 (plus:SI
19087 (ashift:SI (const_int 1)
19088 (match_operand:QI 2 "register_operand" "r"))
19089 (const_int -1)))
19090 (match_operand:DI 1 "nonimmediate_operand" "rm")))
19091 (clobber (reg:CC FLAGS_REG))]
19092 "TARGET_64BIT && TARGET_BMI2"
19093 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19094 [(set_attr "type" "bitmanip")
19095 (set_attr "prefix" "vex")
19096 (set_attr "mode" "DI")])
19097
19098 (define_insn "bmi2_pdep_<mode>3"
19099 [(set (match_operand:SWI48 0 "register_operand" "=r")
19100 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19101 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19102 UNSPEC_PDEP))]
19103 "TARGET_BMI2"
19104 "pdep\t{%2, %1, %0|%0, %1, %2}"
19105 [(set_attr "type" "bitmanip")
19106 (set_attr "prefix" "vex")
19107 (set_attr "mode" "<MODE>")])
19108
19109 (define_insn "bmi2_pext_<mode>3"
19110 [(set (match_operand:SWI48 0 "register_operand" "=r")
19111 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19112 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19113 UNSPEC_PEXT))]
19114 "TARGET_BMI2"
19115 "pext\t{%2, %1, %0|%0, %1, %2}"
19116 [(set_attr "type" "bitmanip")
19117 (set_attr "prefix" "vex")
19118 (set_attr "mode" "<MODE>")])
19119
19120 ;; TBM instructions.
19121 (define_insn "@tbm_bextri_<mode>"
19122 [(set (match_operand:SWI48 0 "register_operand" "=r")
19123 (zero_extract:SWI48
19124 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19125 (match_operand:QI 2 "const_0_to_255_operand")
19126 (match_operand:QI 3 "const_0_to_255_operand")))
19127 (clobber (reg:CC FLAGS_REG))]
19128 "TARGET_TBM"
19129 {
19130 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19131 return "bextr\t{%2, %1, %0|%0, %1, %2}";
19132 }
19133 [(set_attr "type" "bitmanip")
19134 (set_attr "mode" "<MODE>")])
19135
19136 (define_insn "*tbm_blcfill_<mode>"
19137 [(set (match_operand:SWI48 0 "register_operand" "=r")
19138 (and:SWI48
19139 (plus:SWI48
19140 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19141 (const_int 1))
19142 (match_dup 1)))
19143 (clobber (reg:CC FLAGS_REG))]
19144 "TARGET_TBM"
19145 "blcfill\t{%1, %0|%0, %1}"
19146 [(set_attr "type" "bitmanip")
19147 (set_attr "mode" "<MODE>")])
19148
19149 (define_insn "*tbm_blci_<mode>"
19150 [(set (match_operand:SWI48 0 "register_operand" "=r")
19151 (ior:SWI48
19152 (not:SWI48
19153 (plus:SWI48
19154 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19155 (const_int 1)))
19156 (match_dup 1)))
19157 (clobber (reg:CC FLAGS_REG))]
19158 "TARGET_TBM"
19159 "blci\t{%1, %0|%0, %1}"
19160 [(set_attr "type" "bitmanip")
19161 (set_attr "mode" "<MODE>")])
19162
19163 (define_insn "*tbm_blcic_<mode>"
19164 [(set (match_operand:SWI48 0 "register_operand" "=r")
19165 (and:SWI48
19166 (plus:SWI48
19167 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19168 (const_int 1))
19169 (not:SWI48
19170 (match_dup 1))))
19171 (clobber (reg:CC FLAGS_REG))]
19172 "TARGET_TBM"
19173 "blcic\t{%1, %0|%0, %1}"
19174 [(set_attr "type" "bitmanip")
19175 (set_attr "mode" "<MODE>")])
19176
19177 (define_insn "*tbm_blcmsk_<mode>"
19178 [(set (match_operand:SWI48 0 "register_operand" "=r")
19179 (xor:SWI48
19180 (plus:SWI48
19181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19182 (const_int 1))
19183 (match_dup 1)))
19184 (clobber (reg:CC FLAGS_REG))]
19185 "TARGET_TBM"
19186 "blcmsk\t{%1, %0|%0, %1}"
19187 [(set_attr "type" "bitmanip")
19188 (set_attr "mode" "<MODE>")])
19189
19190 (define_insn "*tbm_blcs_<mode>"
19191 [(set (match_operand:SWI48 0 "register_operand" "=r")
19192 (ior:SWI48
19193 (plus:SWI48
19194 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19195 (const_int 1))
19196 (match_dup 1)))
19197 (clobber (reg:CC FLAGS_REG))]
19198 "TARGET_TBM"
19199 "blcs\t{%1, %0|%0, %1}"
19200 [(set_attr "type" "bitmanip")
19201 (set_attr "mode" "<MODE>")])
19202
19203 (define_insn "*tbm_blsfill_<mode>"
19204 [(set (match_operand:SWI48 0 "register_operand" "=r")
19205 (ior:SWI48
19206 (plus:SWI48
19207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19208 (const_int -1))
19209 (match_dup 1)))
19210 (clobber (reg:CC FLAGS_REG))]
19211 "TARGET_TBM"
19212 "blsfill\t{%1, %0|%0, %1}"
19213 [(set_attr "type" "bitmanip")
19214 (set_attr "mode" "<MODE>")])
19215
19216 (define_insn "*tbm_blsic_<mode>"
19217 [(set (match_operand:SWI48 0 "register_operand" "=r")
19218 (ior:SWI48
19219 (plus:SWI48
19220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19221 (const_int -1))
19222 (not:SWI48
19223 (match_dup 1))))
19224 (clobber (reg:CC FLAGS_REG))]
19225 "TARGET_TBM"
19226 "blsic\t{%1, %0|%0, %1}"
19227 [(set_attr "type" "bitmanip")
19228 (set_attr "mode" "<MODE>")])
19229
19230 (define_insn "*tbm_t1mskc_<mode>"
19231 [(set (match_operand:SWI48 0 "register_operand" "=r")
19232 (ior:SWI48
19233 (plus:SWI48
19234 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19235 (const_int 1))
19236 (not:SWI48
19237 (match_dup 1))))
19238 (clobber (reg:CC FLAGS_REG))]
19239 "TARGET_TBM"
19240 "t1mskc\t{%1, %0|%0, %1}"
19241 [(set_attr "type" "bitmanip")
19242 (set_attr "mode" "<MODE>")])
19243
19244 (define_insn "*tbm_tzmsk_<mode>"
19245 [(set (match_operand:SWI48 0 "register_operand" "=r")
19246 (and:SWI48
19247 (plus:SWI48
19248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19249 (const_int -1))
19250 (not:SWI48
19251 (match_dup 1))))
19252 (clobber (reg:CC FLAGS_REG))]
19253 "TARGET_TBM"
19254 "tzmsk\t{%1, %0|%0, %1}"
19255 [(set_attr "type" "bitmanip")
19256 (set_attr "mode" "<MODE>")])
19257
19258 (define_insn_and_split "popcount<mode>2"
19259 [(set (match_operand:SWI48 0 "register_operand" "=r")
19260 (popcount:SWI48
19261 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19262 (clobber (reg:CC FLAGS_REG))]
19263 "TARGET_POPCNT"
19264 {
19265 #if TARGET_MACHO
19266 return "popcnt\t{%1, %0|%0, %1}";
19267 #else
19268 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19269 #endif
19270 }
19271 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19272 && optimize_function_for_speed_p (cfun)
19273 && !reg_mentioned_p (operands[0], operands[1])"
19274 [(parallel
19275 [(set (match_dup 0)
19276 (popcount:SWI48 (match_dup 1)))
19277 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19278 (clobber (reg:CC FLAGS_REG))])]
19279 "ix86_expand_clear (operands[0]);"
19280 [(set_attr "prefix_rep" "1")
19281 (set_attr "type" "bitmanip")
19282 (set_attr "mode" "<MODE>")])
19283
19284 ; False dependency happens when destination is only updated by tzcnt,
19285 ; lzcnt or popcnt. There is no false dependency when destination is
19286 ; also used in source.
19287 (define_insn "*popcount<mode>2_falsedep"
19288 [(set (match_operand:SWI48 0 "register_operand" "=r")
19289 (popcount:SWI48
19290 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19291 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19292 UNSPEC_INSN_FALSE_DEP)
19293 (clobber (reg:CC FLAGS_REG))]
19294 "TARGET_POPCNT"
19295 {
19296 #if TARGET_MACHO
19297 return "popcnt\t{%1, %0|%0, %1}";
19298 #else
19299 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19300 #endif
19301 }
19302 [(set_attr "prefix_rep" "1")
19303 (set_attr "type" "bitmanip")
19304 (set_attr "mode" "<MODE>")])
19305
19306 (define_insn_and_split "*popcountsi2_zext"
19307 [(set (match_operand:DI 0 "register_operand" "=r")
19308 (and:DI
19309 (subreg:DI
19310 (popcount:SI
19311 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19312 (const_int 63)))
19313 (clobber (reg:CC FLAGS_REG))]
19314 "TARGET_POPCNT && TARGET_64BIT"
19315 {
19316 #if TARGET_MACHO
19317 return "popcnt\t{%1, %k0|%k0, %1}";
19318 #else
19319 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19320 #endif
19321 }
19322 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19323 && optimize_function_for_speed_p (cfun)
19324 && !reg_mentioned_p (operands[0], operands[1])"
19325 [(parallel
19326 [(set (match_dup 0)
19327 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19328 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19329 (clobber (reg:CC FLAGS_REG))])]
19330 "ix86_expand_clear (operands[0]);"
19331 [(set_attr "prefix_rep" "1")
19332 (set_attr "type" "bitmanip")
19333 (set_attr "mode" "SI")])
19334
19335 ; False dependency happens when destination is only updated by tzcnt,
19336 ; lzcnt or popcnt. There is no false dependency when destination is
19337 ; also used in source.
19338 (define_insn "*popcountsi2_zext_falsedep"
19339 [(set (match_operand:DI 0 "register_operand" "=r")
19340 (and:DI
19341 (subreg:DI
19342 (popcount:SI
19343 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19344 (const_int 63)))
19345 (unspec [(match_operand:DI 2 "register_operand" "0")]
19346 UNSPEC_INSN_FALSE_DEP)
19347 (clobber (reg:CC FLAGS_REG))]
19348 "TARGET_POPCNT && TARGET_64BIT"
19349 {
19350 #if TARGET_MACHO
19351 return "popcnt\t{%1, %k0|%k0, %1}";
19352 #else
19353 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19354 #endif
19355 }
19356 [(set_attr "prefix_rep" "1")
19357 (set_attr "type" "bitmanip")
19358 (set_attr "mode" "SI")])
19359
19360 (define_insn_and_split "*popcountsi2_zext_2"
19361 [(set (match_operand:DI 0 "register_operand" "=r")
19362 (zero_extend:DI
19363 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19364 (clobber (reg:CC FLAGS_REG))]
19365 "TARGET_POPCNT && TARGET_64BIT"
19366 {
19367 #if TARGET_MACHO
19368 return "popcnt\t{%1, %k0|%k0, %1}";
19369 #else
19370 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19371 #endif
19372 }
19373 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19374 && optimize_function_for_speed_p (cfun)
19375 && !reg_mentioned_p (operands[0], operands[1])"
19376 [(parallel
19377 [(set (match_dup 0)
19378 (zero_extend:DI (popcount:SI (match_dup 1))))
19379 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19380 (clobber (reg:CC FLAGS_REG))])]
19381 "ix86_expand_clear (operands[0]);"
19382 [(set_attr "prefix_rep" "1")
19383 (set_attr "type" "bitmanip")
19384 (set_attr "mode" "SI")])
19385
19386 ; False dependency happens when destination is only updated by tzcnt,
19387 ; lzcnt or popcnt. There is no false dependency when destination is
19388 ; also used in source.
19389 (define_insn "*popcountsi2_zext_2_falsedep"
19390 [(set (match_operand:DI 0 "register_operand" "=r")
19391 (zero_extend:DI
19392 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19393 (unspec [(match_operand:DI 2 "register_operand" "0")]
19394 UNSPEC_INSN_FALSE_DEP)
19395 (clobber (reg:CC FLAGS_REG))]
19396 "TARGET_POPCNT && TARGET_64BIT"
19397 {
19398 #if TARGET_MACHO
19399 return "popcnt\t{%1, %k0|%k0, %1}";
19400 #else
19401 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19402 #endif
19403 }
19404 [(set_attr "prefix_rep" "1")
19405 (set_attr "type" "bitmanip")
19406 (set_attr "mode" "SI")])
19407
19408 (define_insn_and_split "*popcounthi2_1"
19409 [(set (match_operand:SI 0 "register_operand")
19410 (popcount:SI
19411 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19412 (clobber (reg:CC FLAGS_REG))]
19413 "TARGET_POPCNT
19414 && ix86_pre_reload_split ()"
19415 "#"
19416 "&& 1"
19417 [(const_int 0)]
19418 {
19419 rtx tmp = gen_reg_rtx (HImode);
19420
19421 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19422 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19423 DONE;
19424 })
19425
19426 (define_insn_and_split "*popcounthi2_2"
19427 [(set (match_operand:SI 0 "register_operand")
19428 (zero_extend:SI
19429 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19430 (clobber (reg:CC FLAGS_REG))]
19431 "TARGET_POPCNT
19432 && ix86_pre_reload_split ()"
19433 "#"
19434 "&& 1"
19435 [(const_int 0)]
19436 {
19437 rtx tmp = gen_reg_rtx (HImode);
19438
19439 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19440 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19441 DONE;
19442 })
19443
19444 (define_insn "popcounthi2"
19445 [(set (match_operand:HI 0 "register_operand" "=r")
19446 (popcount:HI
19447 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19448 (clobber (reg:CC FLAGS_REG))]
19449 "TARGET_POPCNT"
19450 {
19451 #if TARGET_MACHO
19452 return "popcnt\t{%1, %0|%0, %1}";
19453 #else
19454 return "popcnt{w}\t{%1, %0|%0, %1}";
19455 #endif
19456 }
19457 [(set_attr "prefix_rep" "1")
19458 (set_attr "type" "bitmanip")
19459 (set_attr "mode" "HI")])
19460
19461 (define_expand "bswapdi2"
19462 [(set (match_operand:DI 0 "register_operand")
19463 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19464 "TARGET_64BIT"
19465 {
19466 if (!TARGET_MOVBE)
19467 operands[1] = force_reg (DImode, operands[1]);
19468 })
19469
19470 (define_expand "bswapsi2"
19471 [(set (match_operand:SI 0 "register_operand")
19472 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19473 ""
19474 {
19475 if (TARGET_MOVBE)
19476 ;
19477 else if (TARGET_BSWAP)
19478 operands[1] = force_reg (SImode, operands[1]);
19479 else
19480 {
19481 rtx x = operands[0];
19482
19483 emit_move_insn (x, operands[1]);
19484 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19485 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19486 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19487 DONE;
19488 }
19489 })
19490
19491 (define_insn "*bswap<mode>2_movbe"
19492 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19493 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19494 "TARGET_MOVBE
19495 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19496 "@
19497 bswap\t%0
19498 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19499 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19500 [(set_attr "type" "bitmanip,imov,imov")
19501 (set_attr "modrm" "0,1,1")
19502 (set_attr "prefix_0f" "*,1,1")
19503 (set_attr "prefix_extra" "*,1,1")
19504 (set_attr "mode" "<MODE>")])
19505
19506 (define_insn "*bswap<mode>2"
19507 [(set (match_operand:SWI48 0 "register_operand" "=r")
19508 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19509 "TARGET_BSWAP"
19510 "bswap\t%0"
19511 [(set_attr "type" "bitmanip")
19512 (set_attr "modrm" "0")
19513 (set_attr "mode" "<MODE>")])
19514
19515 (define_expand "bswaphi2"
19516 [(set (match_operand:HI 0 "register_operand")
19517 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19518 "TARGET_MOVBE")
19519
19520 (define_insn "*bswaphi2_movbe"
19521 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19522 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19523 "TARGET_MOVBE
19524 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19525 "@
19526 xchg{b}\t{%h0, %b0|%b0, %h0}
19527 movbe{w}\t{%1, %0|%0, %1}
19528 movbe{w}\t{%1, %0|%0, %1}"
19529 [(set_attr "type" "imov")
19530 (set_attr "modrm" "*,1,1")
19531 (set_attr "prefix_0f" "*,1,1")
19532 (set_attr "prefix_extra" "*,1,1")
19533 (set_attr "pent_pair" "np,*,*")
19534 (set_attr "athlon_decode" "vector,*,*")
19535 (set_attr "amdfam10_decode" "double,*,*")
19536 (set_attr "bdver1_decode" "double,*,*")
19537 (set_attr "mode" "QI,HI,HI")])
19538
19539 (define_peephole2
19540 [(set (match_operand:HI 0 "general_reg_operand")
19541 (bswap:HI (match_dup 0)))]
19542 "TARGET_MOVBE
19543 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19544 && peep2_regno_dead_p (0, FLAGS_REG)"
19545 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19546 (clobber (reg:CC FLAGS_REG))])])
19547
19548 (define_insn "bswaphi_lowpart"
19549 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19550 (bswap:HI (match_dup 0)))
19551 (clobber (reg:CC FLAGS_REG))]
19552 ""
19553 "@
19554 xchg{b}\t{%h0, %b0|%b0, %h0}
19555 rol{w}\t{$8, %0|%0, 8}"
19556 [(set (attr "preferred_for_size")
19557 (cond [(eq_attr "alternative" "0")
19558 (symbol_ref "true")]
19559 (symbol_ref "false")))
19560 (set (attr "preferred_for_speed")
19561 (cond [(eq_attr "alternative" "0")
19562 (symbol_ref "TARGET_USE_XCHGB")]
19563 (symbol_ref "!TARGET_USE_XCHGB")))
19564 (set_attr "length" "2,4")
19565 (set_attr "mode" "QI,HI")])
19566
19567 (define_expand "paritydi2"
19568 [(set (match_operand:DI 0 "register_operand")
19569 (parity:DI (match_operand:DI 1 "register_operand")))]
19570 "! TARGET_POPCNT"
19571 {
19572 rtx scratch = gen_reg_rtx (QImode);
19573 rtx hipart1 = gen_reg_rtx (SImode);
19574 rtx lopart1 = gen_reg_rtx (SImode);
19575 rtx xor1 = gen_reg_rtx (SImode);
19576 rtx shift2 = gen_reg_rtx (SImode);
19577 rtx hipart2 = gen_reg_rtx (HImode);
19578 rtx lopart2 = gen_reg_rtx (HImode);
19579 rtx xor2 = gen_reg_rtx (HImode);
19580
19581 if (TARGET_64BIT)
19582 {
19583 rtx shift1 = gen_reg_rtx (DImode);
19584 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19585 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19586 }
19587 else
19588 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19589
19590 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19591 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19592
19593 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19594 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19595 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19596 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19597
19598 emit_insn (gen_parityhi2_cmp (xor2));
19599
19600 ix86_expand_setcc (scratch, ORDERED,
19601 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19602
19603 if (TARGET_64BIT)
19604 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19605 else
19606 {
19607 rtx tmp = gen_reg_rtx (SImode);
19608
19609 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19610 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19611 }
19612 DONE;
19613 })
19614
19615 (define_expand "paritysi2"
19616 [(set (match_operand:SI 0 "register_operand")
19617 (parity:SI (match_operand:SI 1 "register_operand")))]
19618 "! TARGET_POPCNT"
19619 {
19620 rtx scratch = gen_reg_rtx (QImode);
19621 rtx shift = gen_reg_rtx (SImode);
19622 rtx hipart = gen_reg_rtx (HImode);
19623 rtx lopart = gen_reg_rtx (HImode);
19624 rtx tmp = gen_reg_rtx (HImode);
19625
19626 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19627 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19628 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19629 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19630
19631 emit_insn (gen_parityhi2_cmp (tmp));
19632
19633 ix86_expand_setcc (scratch, ORDERED,
19634 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19635
19636 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19637 DONE;
19638 })
19639
19640 (define_expand "parityhi2"
19641 [(set (match_operand:HI 0 "register_operand")
19642 (parity:HI (match_operand:HI 1 "register_operand")))]
19643 "! TARGET_POPCNT"
19644 {
19645 rtx scratch = gen_reg_rtx (QImode);
19646
19647 emit_insn (gen_parityhi2_cmp (operands[1]));
19648
19649 ix86_expand_setcc (scratch, ORDERED,
19650 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19651
19652 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19653 DONE;
19654 })
19655
19656 (define_expand "parityqi2"
19657 [(set (match_operand:QI 0 "register_operand")
19658 (parity:QI (match_operand:QI 1 "register_operand")))]
19659 "! TARGET_POPCNT"
19660 {
19661 emit_insn (gen_parityqi2_cmp (operands[1]));
19662
19663 ix86_expand_setcc (operands[0], ORDERED,
19664 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19665 DONE;
19666 })
19667
19668 (define_insn "parityhi2_cmp"
19669 [(set (reg:CC FLAGS_REG)
19670 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19671 UNSPEC_PARITY))
19672 (clobber (match_dup 0))]
19673 ""
19674 "xor{b}\t{%h0, %b0|%b0, %h0}"
19675 [(set_attr "length" "2")
19676 (set_attr "mode" "QI")])
19677
19678 (define_insn "parityqi2_cmp"
19679 [(set (reg:CC FLAGS_REG)
19680 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19681 UNSPEC_PARITY))]
19682 ""
19683 "test{b}\t%0, %0"
19684 [(set_attr "mode" "QI")])
19685
19686 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19687 (define_peephole2
19688 [(set (match_operand:HI 0 "register_operand")
19689 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19690 (parallel [(set (reg:CC FLAGS_REG)
19691 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19692 (clobber (match_dup 0))])]
19693 ""
19694 [(set (reg:CC FLAGS_REG)
19695 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19696
19697 ;; Eliminate QImode popcount&1 using parity flag
19698 (define_peephole2
19699 [(set (match_operand:SI 0 "register_operand")
19700 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19701 (parallel [(set (match_operand:SI 2 "register_operand")
19702 (popcount:SI (match_dup 0)))
19703 (clobber (reg:CC FLAGS_REG))])
19704 (set (reg:CCZ FLAGS_REG)
19705 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19706 (const_int 1))
19707 (const_int 0)))
19708 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19709 [(reg:CCZ FLAGS_REG)
19710 (const_int 0)])
19711 (label_ref (match_operand 5))
19712 (pc)))]
19713 "REGNO (operands[2]) == REGNO (operands[3])
19714 && peep2_reg_dead_p (3, operands[0])
19715 && peep2_reg_dead_p (3, operands[2])
19716 && peep2_regno_dead_p (4, FLAGS_REG)"
19717 [(set (reg:CC FLAGS_REG)
19718 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19719 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19720 (const_int 0)])
19721 (label_ref (match_dup 5))
19722 (pc)))]
19723 {
19724 operands[4] = shallow_copy_rtx (operands[4]);
19725 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19726 })
19727
19728 ;; Eliminate HImode popcount&1 using parity flag
19729 (define_peephole2
19730 [(match_scratch:HI 0 "Q")
19731 (parallel [(set (match_operand:HI 1 "register_operand")
19732 (popcount:HI
19733 (match_operand:HI 2 "nonimmediate_operand")))
19734 (clobber (reg:CC FLAGS_REG))])
19735 (set (match_operand 3 "register_operand")
19736 (zero_extend (match_dup 1)))
19737 (set (reg:CCZ FLAGS_REG)
19738 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19739 (const_int 1))
19740 (const_int 0)))
19741 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19742 [(reg:CCZ FLAGS_REG)
19743 (const_int 0)])
19744 (label_ref (match_operand 6))
19745 (pc)))]
19746 "REGNO (operands[3]) == REGNO (operands[4])
19747 && peep2_reg_dead_p (3, operands[1])
19748 && peep2_reg_dead_p (3, operands[3])
19749 && peep2_regno_dead_p (4, FLAGS_REG)"
19750 [(set (match_dup 0) (match_dup 2))
19751 (parallel [(set (reg:CC FLAGS_REG)
19752 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19753 (clobber (match_dup 0))])
19754 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19755 (const_int 0)])
19756 (label_ref (match_dup 6))
19757 (pc)))]
19758 {
19759 operands[5] = shallow_copy_rtx (operands[5]);
19760 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19761 })
19762
19763 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19764 (define_peephole2
19765 [(match_scratch:HI 0 "Q")
19766 (parallel [(set (match_operand:HI 1 "register_operand")
19767 (popcount:HI
19768 (match_operand:HI 2 "nonimmediate_operand")))
19769 (clobber (reg:CC FLAGS_REG))])
19770 (set (reg:CCZ FLAGS_REG)
19771 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19772 (const_int 1))
19773 (const_int 0)))
19774 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19775 [(reg:CCZ FLAGS_REG)
19776 (const_int 0)])
19777 (label_ref (match_operand 5))
19778 (pc)))]
19779 "REGNO (operands[1]) == REGNO (operands[3])
19780 && peep2_reg_dead_p (2, operands[1])
19781 && peep2_reg_dead_p (2, operands[3])
19782 && peep2_regno_dead_p (3, FLAGS_REG)"
19783 [(set (match_dup 0) (match_dup 2))
19784 (parallel [(set (reg:CC FLAGS_REG)
19785 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19786 (clobber (match_dup 0))])
19787 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19788 (const_int 0)])
19789 (label_ref (match_dup 5))
19790 (pc)))]
19791 {
19792 operands[4] = shallow_copy_rtx (operands[4]);
19793 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19794 })
19795
19796 \f
19797 ;; Thread-local storage patterns for ELF.
19798 ;;
19799 ;; Note that these code sequences must appear exactly as shown
19800 ;; in order to allow linker relaxation.
19801
19802 (define_insn "*tls_global_dynamic_32_gnu"
19803 [(set (match_operand:SI 0 "register_operand" "=a")
19804 (unspec:SI
19805 [(match_operand:SI 1 "register_operand" "Yb")
19806 (match_operand 2 "tls_symbolic_operand")
19807 (match_operand 3 "constant_call_address_operand" "Bz")
19808 (reg:SI SP_REG)]
19809 UNSPEC_TLS_GD))
19810 (clobber (match_scratch:SI 4 "=d"))
19811 (clobber (match_scratch:SI 5 "=c"))
19812 (clobber (reg:CC FLAGS_REG))]
19813 "!TARGET_64BIT && TARGET_GNU_TLS"
19814 {
19815 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19816 output_asm_insn
19817 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19818 else
19819 output_asm_insn
19820 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19821 if (TARGET_SUN_TLS)
19822 #ifdef HAVE_AS_IX86_TLSGDPLT
19823 return "call\t%a2@tlsgdplt";
19824 #else
19825 return "call\t%p3@plt";
19826 #endif
19827 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19828 return "call\t%P3";
19829 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19830 }
19831 [(set_attr "type" "multi")
19832 (set_attr "length" "12")])
19833
19834 (define_expand "tls_global_dynamic_32"
19835 [(parallel
19836 [(set (match_operand:SI 0 "register_operand")
19837 (unspec:SI [(match_operand:SI 2 "register_operand")
19838 (match_operand 1 "tls_symbolic_operand")
19839 (match_operand 3 "constant_call_address_operand")
19840 (reg:SI SP_REG)]
19841 UNSPEC_TLS_GD))
19842 (clobber (scratch:SI))
19843 (clobber (scratch:SI))
19844 (clobber (reg:CC FLAGS_REG))])]
19845 ""
19846 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19847
19848 (define_insn "*tls_global_dynamic_64_<mode>"
19849 [(set (match_operand:P 0 "register_operand" "=a")
19850 (call:P
19851 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19852 (match_operand 3)))
19853 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19854 (reg:P SP_REG)]
19855 UNSPEC_TLS_GD)]
19856 "TARGET_64BIT"
19857 {
19858 if (!TARGET_X32)
19859 /* The .loc directive has effect for 'the immediately following assembly
19860 instruction'. So for a sequence:
19861 .loc f l
19862 .byte x
19863 insn1
19864 the 'immediately following assembly instruction' is insn1.
19865 We want to emit an insn prefix here, but if we use .byte (as shown in
19866 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19867 inside the insn sequence, rather than to the start. After relaxation
19868 of the sequence by the linker, the .loc might point inside an insn.
19869 Use data16 prefix instead, which doesn't have this problem. */
19870 fputs ("\tdata16", asm_out_file);
19871 output_asm_insn
19872 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19873 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19874 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19875 else
19876 fputs (ASM_BYTE "0x66\n", asm_out_file);
19877 fputs ("\trex64\n", asm_out_file);
19878 if (TARGET_SUN_TLS)
19879 return "call\t%p2@plt";
19880 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19881 return "call\t%P2";
19882 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19883 }
19884 [(set_attr "type" "multi")
19885 (set (attr "length")
19886 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19887
19888 (define_insn "*tls_global_dynamic_64_largepic"
19889 [(set (match_operand:DI 0 "register_operand" "=a")
19890 (call:DI
19891 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19892 (match_operand:DI 3 "immediate_operand" "i")))
19893 (match_operand 4)))
19894 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19895 (reg:DI SP_REG)]
19896 UNSPEC_TLS_GD)]
19897 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19898 && GET_CODE (operands[3]) == CONST
19899 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19900 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19901 {
19902 output_asm_insn
19903 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19904 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19905 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19906 return "call\t{*%%rax|rax}";
19907 }
19908 [(set_attr "type" "multi")
19909 (set_attr "length" "22")])
19910
19911 (define_expand "@tls_global_dynamic_64_<mode>"
19912 [(parallel
19913 [(set (match_operand:P 0 "register_operand")
19914 (call:P
19915 (mem:QI (match_operand 2))
19916 (const_int 0)))
19917 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19918 (reg:P SP_REG)]
19919 UNSPEC_TLS_GD)])]
19920 "TARGET_64BIT"
19921 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19922
19923 (define_insn "*tls_local_dynamic_base_32_gnu"
19924 [(set (match_operand:SI 0 "register_operand" "=a")
19925 (unspec:SI
19926 [(match_operand:SI 1 "register_operand" "Yb")
19927 (match_operand 2 "constant_call_address_operand" "Bz")
19928 (reg:SI SP_REG)]
19929 UNSPEC_TLS_LD_BASE))
19930 (clobber (match_scratch:SI 3 "=d"))
19931 (clobber (match_scratch:SI 4 "=c"))
19932 (clobber (reg:CC FLAGS_REG))]
19933 "!TARGET_64BIT && TARGET_GNU_TLS"
19934 {
19935 output_asm_insn
19936 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19937 if (TARGET_SUN_TLS)
19938 {
19939 if (HAVE_AS_IX86_TLSLDMPLT)
19940 return "call\t%&@tlsldmplt";
19941 else
19942 return "call\t%p2@plt";
19943 }
19944 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19945 return "call\t%P2";
19946 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19947 }
19948 [(set_attr "type" "multi")
19949 (set_attr "length" "11")])
19950
19951 (define_expand "tls_local_dynamic_base_32"
19952 [(parallel
19953 [(set (match_operand:SI 0 "register_operand")
19954 (unspec:SI
19955 [(match_operand:SI 1 "register_operand")
19956 (match_operand 2 "constant_call_address_operand")
19957 (reg:SI SP_REG)]
19958 UNSPEC_TLS_LD_BASE))
19959 (clobber (scratch:SI))
19960 (clobber (scratch:SI))
19961 (clobber (reg:CC FLAGS_REG))])]
19962 ""
19963 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19964
19965 (define_insn "*tls_local_dynamic_base_64_<mode>"
19966 [(set (match_operand:P 0 "register_operand" "=a")
19967 (call:P
19968 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19969 (match_operand 2)))
19970 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19971 "TARGET_64BIT"
19972 {
19973 output_asm_insn
19974 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19975 if (TARGET_SUN_TLS)
19976 return "call\t%p1@plt";
19977 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19978 return "call\t%P1";
19979 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19980 }
19981 [(set_attr "type" "multi")
19982 (set_attr "length" "12")])
19983
19984 (define_insn "*tls_local_dynamic_base_64_largepic"
19985 [(set (match_operand:DI 0 "register_operand" "=a")
19986 (call:DI
19987 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19988 (match_operand:DI 2 "immediate_operand" "i")))
19989 (match_operand 3)))
19990 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19991 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19992 && GET_CODE (operands[2]) == CONST
19993 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19994 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19995 {
19996 output_asm_insn
19997 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19998 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19999 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
20000 return "call\t{*%%rax|rax}";
20001 }
20002 [(set_attr "type" "multi")
20003 (set_attr "length" "22")])
20004
20005 (define_expand "@tls_local_dynamic_base_64_<mode>"
20006 [(parallel
20007 [(set (match_operand:P 0 "register_operand")
20008 (call:P
20009 (mem:QI (match_operand 1))
20010 (const_int 0)))
20011 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
20012 "TARGET_64BIT"
20013 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20014
20015 ;; Local dynamic of a single variable is a lose. Show combine how
20016 ;; to convert that back to global dynamic.
20017
20018 (define_insn_and_split "*tls_local_dynamic_32_once"
20019 [(set (match_operand:SI 0 "register_operand" "=a")
20020 (plus:SI
20021 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
20022 (match_operand 2 "constant_call_address_operand" "Bz")
20023 (reg:SI SP_REG)]
20024 UNSPEC_TLS_LD_BASE)
20025 (const:SI (unspec:SI
20026 [(match_operand 3 "tls_symbolic_operand")]
20027 UNSPEC_DTPOFF))))
20028 (clobber (match_scratch:SI 4 "=d"))
20029 (clobber (match_scratch:SI 5 "=c"))
20030 (clobber (reg:CC FLAGS_REG))]
20031 ""
20032 "#"
20033 ""
20034 [(parallel
20035 [(set (match_dup 0)
20036 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
20037 (reg:SI SP_REG)]
20038 UNSPEC_TLS_GD))
20039 (clobber (match_dup 4))
20040 (clobber (match_dup 5))
20041 (clobber (reg:CC FLAGS_REG))])])
20042
20043 ;; Load and add the thread base pointer from %<tp_seg>:0.
20044 (define_expand "get_thread_pointer<mode>"
20045 [(set (match_operand:PTR 0 "register_operand")
20046 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20047 ""
20048 {
20049 /* targetm is not visible in the scope of the condition. */
20050 if (!targetm.have_tls)
20051 error ("%<__builtin_thread_pointer%> is not supported on this target");
20052 })
20053
20054 (define_insn_and_split "*load_tp_<mode>"
20055 [(set (match_operand:PTR 0 "register_operand" "=r")
20056 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20057 ""
20058 "#"
20059 ""
20060 [(set (match_dup 0)
20061 (match_dup 1))]
20062 {
20063 addr_space_t as = DEFAULT_TLS_SEG_REG;
20064
20065 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
20066 set_mem_addr_space (operands[1], as);
20067 })
20068
20069 (define_insn_and_split "*load_tp_x32_zext"
20070 [(set (match_operand:DI 0 "register_operand" "=r")
20071 (zero_extend:DI
20072 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
20073 "TARGET_X32"
20074 "#"
20075 "&& 1"
20076 [(set (match_dup 0)
20077 (zero_extend:DI (match_dup 1)))]
20078 {
20079 addr_space_t as = DEFAULT_TLS_SEG_REG;
20080
20081 operands[1] = gen_const_mem (SImode, const0_rtx);
20082 set_mem_addr_space (operands[1], as);
20083 })
20084
20085 (define_insn_and_split "*add_tp_<mode>"
20086 [(set (match_operand:PTR 0 "register_operand" "=r")
20087 (plus:PTR
20088 (unspec:PTR [(const_int 0)] UNSPEC_TP)
20089 (match_operand:PTR 1 "register_operand" "0")))
20090 (clobber (reg:CC FLAGS_REG))]
20091 ""
20092 "#"
20093 ""
20094 [(parallel
20095 [(set (match_dup 0)
20096 (plus:PTR (match_dup 1) (match_dup 2)))
20097 (clobber (reg:CC FLAGS_REG))])]
20098 {
20099 addr_space_t as = DEFAULT_TLS_SEG_REG;
20100
20101 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
20102 set_mem_addr_space (operands[2], as);
20103 })
20104
20105 (define_insn_and_split "*add_tp_x32_zext"
20106 [(set (match_operand:DI 0 "register_operand" "=r")
20107 (zero_extend:DI
20108 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20109 (match_operand:SI 1 "register_operand" "0"))))
20110 (clobber (reg:CC FLAGS_REG))]
20111 "TARGET_X32"
20112 "#"
20113 "&& 1"
20114 [(parallel
20115 [(set (match_dup 0)
20116 (zero_extend:DI
20117 (plus:SI (match_dup 1) (match_dup 2))))
20118 (clobber (reg:CC FLAGS_REG))])]
20119 {
20120 addr_space_t as = DEFAULT_TLS_SEG_REG;
20121
20122 operands[2] = gen_const_mem (SImode, const0_rtx);
20123 set_mem_addr_space (operands[2], as);
20124 })
20125
20126 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20127 ;; %rax as destination of the initial executable code sequence.
20128 (define_insn "tls_initial_exec_64_sun"
20129 [(set (match_operand:DI 0 "register_operand" "=a")
20130 (unspec:DI
20131 [(match_operand 1 "tls_symbolic_operand")]
20132 UNSPEC_TLS_IE_SUN))
20133 (clobber (reg:CC FLAGS_REG))]
20134 "TARGET_64BIT && TARGET_SUN_TLS"
20135 {
20136 output_asm_insn
20137 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20138 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20139 }
20140 [(set_attr "type" "multi")])
20141
20142 ;; GNU2 TLS patterns can be split.
20143
20144 (define_expand "tls_dynamic_gnu2_32"
20145 [(set (match_dup 3)
20146 (plus:SI (match_operand:SI 2 "register_operand")
20147 (const:SI
20148 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20149 UNSPEC_TLSDESC))))
20150 (parallel
20151 [(set (match_operand:SI 0 "register_operand")
20152 (unspec:SI [(match_dup 1) (match_dup 3)
20153 (match_dup 2) (reg:SI SP_REG)]
20154 UNSPEC_TLSDESC))
20155 (clobber (reg:CC FLAGS_REG))])]
20156 "!TARGET_64BIT && TARGET_GNU2_TLS"
20157 {
20158 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20159 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20160 })
20161
20162 (define_insn "*tls_dynamic_gnu2_lea_32"
20163 [(set (match_operand:SI 0 "register_operand" "=r")
20164 (plus:SI (match_operand:SI 1 "register_operand" "b")
20165 (const:SI
20166 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20167 UNSPEC_TLSDESC))))]
20168 "!TARGET_64BIT && TARGET_GNU2_TLS"
20169 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20170 [(set_attr "type" "lea")
20171 (set_attr "mode" "SI")
20172 (set_attr "length" "6")
20173 (set_attr "length_address" "4")])
20174
20175 (define_insn "*tls_dynamic_gnu2_call_32"
20176 [(set (match_operand:SI 0 "register_operand" "=a")
20177 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20178 (match_operand:SI 2 "register_operand" "0")
20179 ;; we have to make sure %ebx still points to the GOT
20180 (match_operand:SI 3 "register_operand" "b")
20181 (reg:SI SP_REG)]
20182 UNSPEC_TLSDESC))
20183 (clobber (reg:CC FLAGS_REG))]
20184 "!TARGET_64BIT && TARGET_GNU2_TLS"
20185 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20186 [(set_attr "type" "call")
20187 (set_attr "length" "2")
20188 (set_attr "length_address" "0")])
20189
20190 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20191 [(set (match_operand:SI 0 "register_operand" "=&a")
20192 (plus:SI
20193 (unspec:SI [(match_operand 3 "tls_modbase_operand")
20194 (match_operand:SI 4)
20195 (match_operand:SI 2 "register_operand" "b")
20196 (reg:SI SP_REG)]
20197 UNSPEC_TLSDESC)
20198 (const:SI (unspec:SI
20199 [(match_operand 1 "tls_symbolic_operand")]
20200 UNSPEC_DTPOFF))))
20201 (clobber (reg:CC FLAGS_REG))]
20202 "!TARGET_64BIT && TARGET_GNU2_TLS"
20203 "#"
20204 "&& 1"
20205 [(set (match_dup 0) (match_dup 5))]
20206 {
20207 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20208 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20209 })
20210
20211 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20212 [(set (match_dup 2)
20213 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20214 UNSPEC_TLSDESC))
20215 (parallel
20216 [(set (match_operand:PTR 0 "register_operand")
20217 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20218 UNSPEC_TLSDESC))
20219 (clobber (reg:CC FLAGS_REG))])]
20220 "TARGET_64BIT && TARGET_GNU2_TLS"
20221 {
20222 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20223 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20224 })
20225
20226 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20227 [(set (match_operand:PTR 0 "register_operand" "=r")
20228 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20229 UNSPEC_TLSDESC))]
20230 "TARGET_64BIT && TARGET_GNU2_TLS"
20231 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20232 [(set_attr "type" "lea")
20233 (set_attr "mode" "<MODE>")
20234 (set_attr "length" "7")
20235 (set_attr "length_address" "4")])
20236
20237 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20238 [(set (match_operand:PTR 0 "register_operand" "=a")
20239 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20240 (match_operand:PTR 2 "register_operand" "0")
20241 (reg:PTR SP_REG)]
20242 UNSPEC_TLSDESC))
20243 (clobber (reg:CC FLAGS_REG))]
20244 "TARGET_64BIT && TARGET_GNU2_TLS"
20245 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20246 [(set_attr "type" "call")
20247 (set_attr "length" "2")
20248 (set_attr "length_address" "0")])
20249
20250 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20251 [(set (match_operand:PTR 0 "register_operand" "=&a")
20252 (plus:PTR
20253 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20254 (match_operand:PTR 3)
20255 (reg:PTR SP_REG)]
20256 UNSPEC_TLSDESC)
20257 (const:PTR (unspec:PTR
20258 [(match_operand 1 "tls_symbolic_operand")]
20259 UNSPEC_DTPOFF))))
20260 (clobber (reg:CC FLAGS_REG))]
20261 "TARGET_64BIT && TARGET_GNU2_TLS"
20262 "#"
20263 "&& 1"
20264 [(set (match_dup 0) (match_dup 4))]
20265 {
20266 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20267 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20268 })
20269
20270 (define_split
20271 [(match_operand 0 "tls_address_pattern")]
20272 "TARGET_TLS_DIRECT_SEG_REFS"
20273 [(match_dup 0)]
20274 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20275
20276 \f
20277 ;; These patterns match the binary 387 instructions for addM3, subM3,
20278 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20279 ;; SFmode. The first is the normal insn, the second the same insn but
20280 ;; with one operand a conversion, and the third the same insn but with
20281 ;; the other operand a conversion. The conversion may be SFmode or
20282 ;; SImode if the target mode DFmode, but only SImode if the target mode
20283 ;; is SFmode.
20284
20285 ;; Gcc is slightly more smart about handling normal two address instructions
20286 ;; so use special patterns for add and mull.
20287
20288 (define_insn "*fop_xf_comm_i387"
20289 [(set (match_operand:XF 0 "register_operand" "=f")
20290 (match_operator:XF 3 "binary_fp_operator"
20291 [(match_operand:XF 1 "register_operand" "%0")
20292 (match_operand:XF 2 "register_operand" "f")]))]
20293 "TARGET_80387
20294 && COMMUTATIVE_ARITH_P (operands[3])"
20295 "* return output_387_binary_op (insn, operands);"
20296 [(set (attr "type")
20297 (if_then_else (match_operand:XF 3 "mult_operator")
20298 (const_string "fmul")
20299 (const_string "fop")))
20300 (set_attr "mode" "XF")])
20301
20302 (define_insn "*fop_<mode>_comm"
20303 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20304 (match_operator:MODEF 3 "binary_fp_operator"
20305 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20306 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20307 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20308 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20309 && COMMUTATIVE_ARITH_P (operands[3])
20310 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20311 "* return output_387_binary_op (insn, operands);"
20312 [(set (attr "type")
20313 (if_then_else (eq_attr "alternative" "1,2")
20314 (if_then_else (match_operand:MODEF 3 "mult_operator")
20315 (const_string "ssemul")
20316 (const_string "sseadd"))
20317 (if_then_else (match_operand:MODEF 3 "mult_operator")
20318 (const_string "fmul")
20319 (const_string "fop"))))
20320 (set_attr "isa" "*,noavx,avx")
20321 (set_attr "prefix" "orig,orig,vex")
20322 (set_attr "mode" "<MODE>")
20323 (set (attr "enabled")
20324 (if_then_else
20325 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20326 (if_then_else
20327 (eq_attr "alternative" "0")
20328 (symbol_ref "TARGET_MIX_SSE_I387
20329 && X87_ENABLE_ARITH (<MODE>mode)")
20330 (const_string "*"))
20331 (if_then_else
20332 (eq_attr "alternative" "0")
20333 (symbol_ref "true")
20334 (symbol_ref "false"))))])
20335
20336 (define_insn "*<insn>hf"
20337 [(set (match_operand:HF 0 "register_operand" "=v")
20338 (plusminusmultdiv:HF
20339 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20340 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20341 "TARGET_AVX512FP16
20342 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20343 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20344 [(set_attr "prefix" "evex")
20345 (set_attr "mode" "HF")])
20346
20347 (define_insn "*rcpsf2_sse"
20348 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20349 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20350 UNSPEC_RCP))]
20351 "TARGET_SSE && TARGET_SSE_MATH"
20352 "@
20353 %vrcpss\t{%d1, %0|%0, %d1}
20354 %vrcpss\t{%d1, %0|%0, %d1}
20355 rcpss\t{%1, %d0|%d0, %1}
20356 vrcpss\t{%1, %d0|%d0, %1}"
20357 [(set_attr "isa" "*,*,noavx,avx")
20358 (set_attr "gpr32" "1,1,1,0")
20359 (set_attr "type" "sse")
20360 (set_attr "atom_sse_attr" "rcp")
20361 (set_attr "btver2_sse_attr" "rcp")
20362 (set_attr "prefix" "maybe_vex")
20363 (set_attr "mode" "SF")
20364 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20365 (set (attr "preferred_for_speed")
20366 (cond [(match_test "TARGET_AVX")
20367 (symbol_ref "true")
20368 (eq_attr "alternative" "1,2,3")
20369 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20370 ]
20371 (symbol_ref "true")))])
20372
20373 (define_insn "rcphf2"
20374 [(set (match_operand:HF 0 "register_operand" "=v,v")
20375 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20376 UNSPEC_RCP))]
20377 "TARGET_AVX512FP16"
20378 "@
20379 vrcpsh\t{%d1, %0|%0, %d1}
20380 vrcpsh\t{%1, %d0|%d0, %1}"
20381 [(set_attr "type" "sse")
20382 (set_attr "prefix" "evex")
20383 (set_attr "mode" "HF")
20384 (set_attr "avx_partial_xmm_update" "false,true")])
20385
20386 (define_insn "*fop_xf_1_i387"
20387 [(set (match_operand:XF 0 "register_operand" "=f,f")
20388 (match_operator:XF 3 "binary_fp_operator"
20389 [(match_operand:XF 1 "register_operand" "0,f")
20390 (match_operand:XF 2 "register_operand" "f,0")]))]
20391 "TARGET_80387
20392 && !COMMUTATIVE_ARITH_P (operands[3])"
20393 "* return output_387_binary_op (insn, operands);"
20394 [(set (attr "type")
20395 (if_then_else (match_operand:XF 3 "div_operator")
20396 (const_string "fdiv")
20397 (const_string "fop")))
20398 (set_attr "mode" "XF")])
20399
20400 (define_insn "*fop_<mode>_1"
20401 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20402 (match_operator:MODEF 3 "binary_fp_operator"
20403 [(match_operand:MODEF 1
20404 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20405 (match_operand:MODEF 2
20406 "nonimmediate_operand" "fm,0,xm,vm")]))]
20407 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20408 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20409 && !COMMUTATIVE_ARITH_P (operands[3])
20410 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20411 "* return output_387_binary_op (insn, operands);"
20412 [(set (attr "type")
20413 (if_then_else (eq_attr "alternative" "2,3")
20414 (if_then_else (match_operand:MODEF 3 "div_operator")
20415 (const_string "ssediv")
20416 (const_string "sseadd"))
20417 (if_then_else (match_operand:MODEF 3 "div_operator")
20418 (const_string "fdiv")
20419 (const_string "fop"))))
20420 (set_attr "isa" "*,*,noavx,avx")
20421 (set_attr "prefix" "orig,orig,orig,vex")
20422 (set_attr "mode" "<MODE>")
20423 (set (attr "enabled")
20424 (if_then_else
20425 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20426 (if_then_else
20427 (eq_attr "alternative" "0,1")
20428 (symbol_ref "TARGET_MIX_SSE_I387
20429 && X87_ENABLE_ARITH (<MODE>mode)")
20430 (const_string "*"))
20431 (if_then_else
20432 (eq_attr "alternative" "0,1")
20433 (symbol_ref "true")
20434 (symbol_ref "false"))))])
20435
20436 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20437 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20438 (match_operator:X87MODEF 3 "binary_fp_operator"
20439 [(float:X87MODEF
20440 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20441 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20442 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20443 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20444 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20445 || optimize_function_for_size_p (cfun))"
20446 "* return output_387_binary_op (insn, operands);"
20447 [(set (attr "type")
20448 (cond [(match_operand:X87MODEF 3 "mult_operator")
20449 (const_string "fmul")
20450 (match_operand:X87MODEF 3 "div_operator")
20451 (const_string "fdiv")
20452 ]
20453 (const_string "fop")))
20454 (set_attr "fp_int_src" "true")
20455 (set_attr "mode" "<SWI24:MODE>")])
20456
20457 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20458 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20459 (match_operator:X87MODEF 3 "binary_fp_operator"
20460 [(match_operand:X87MODEF 1 "register_operand" "0")
20461 (float:X87MODEF
20462 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20463 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20464 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20465 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20466 || optimize_function_for_size_p (cfun))"
20467 "* return output_387_binary_op (insn, operands);"
20468 [(set (attr "type")
20469 (cond [(match_operand:X87MODEF 3 "mult_operator")
20470 (const_string "fmul")
20471 (match_operand:X87MODEF 3 "div_operator")
20472 (const_string "fdiv")
20473 ]
20474 (const_string "fop")))
20475 (set_attr "fp_int_src" "true")
20476 (set_attr "mode" "<SWI24:MODE>")])
20477
20478 (define_insn "*fop_xf_4_i387"
20479 [(set (match_operand:XF 0 "register_operand" "=f,f")
20480 (match_operator:XF 3 "binary_fp_operator"
20481 [(float_extend:XF
20482 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20483 (match_operand:XF 2 "register_operand" "0,f")]))]
20484 "TARGET_80387"
20485 "* return output_387_binary_op (insn, operands);"
20486 [(set (attr "type")
20487 (cond [(match_operand:XF 3 "mult_operator")
20488 (const_string "fmul")
20489 (match_operand:XF 3 "div_operator")
20490 (const_string "fdiv")
20491 ]
20492 (const_string "fop")))
20493 (set_attr "mode" "<MODE>")])
20494
20495 (define_insn "*fop_df_4_i387"
20496 [(set (match_operand:DF 0 "register_operand" "=f,f")
20497 (match_operator:DF 3 "binary_fp_operator"
20498 [(float_extend:DF
20499 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20500 (match_operand:DF 2 "register_operand" "0,f")]))]
20501 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20502 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20503 "* return output_387_binary_op (insn, operands);"
20504 [(set (attr "type")
20505 (cond [(match_operand:DF 3 "mult_operator")
20506 (const_string "fmul")
20507 (match_operand:DF 3 "div_operator")
20508 (const_string "fdiv")
20509 ]
20510 (const_string "fop")))
20511 (set_attr "mode" "SF")])
20512
20513 (define_insn "*fop_xf_5_i387"
20514 [(set (match_operand:XF 0 "register_operand" "=f,f")
20515 (match_operator:XF 3 "binary_fp_operator"
20516 [(match_operand:XF 1 "register_operand" "0,f")
20517 (float_extend:XF
20518 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20519 "TARGET_80387"
20520 "* return output_387_binary_op (insn, operands);"
20521 [(set (attr "type")
20522 (cond [(match_operand:XF 3 "mult_operator")
20523 (const_string "fmul")
20524 (match_operand:XF 3 "div_operator")
20525 (const_string "fdiv")
20526 ]
20527 (const_string "fop")))
20528 (set_attr "mode" "<MODE>")])
20529
20530 (define_insn "*fop_df_5_i387"
20531 [(set (match_operand:DF 0 "register_operand" "=f,f")
20532 (match_operator:DF 3 "binary_fp_operator"
20533 [(match_operand:DF 1 "register_operand" "0,f")
20534 (float_extend:DF
20535 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20536 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20537 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20538 "* return output_387_binary_op (insn, operands);"
20539 [(set (attr "type")
20540 (cond [(match_operand:DF 3 "mult_operator")
20541 (const_string "fmul")
20542 (match_operand:DF 3 "div_operator")
20543 (const_string "fdiv")
20544 ]
20545 (const_string "fop")))
20546 (set_attr "mode" "SF")])
20547
20548 (define_insn "*fop_xf_6_i387"
20549 [(set (match_operand:XF 0 "register_operand" "=f,f")
20550 (match_operator:XF 3 "binary_fp_operator"
20551 [(float_extend:XF
20552 (match_operand:MODEF 1 "register_operand" "0,f"))
20553 (float_extend:XF
20554 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20555 "TARGET_80387"
20556 "* return output_387_binary_op (insn, operands);"
20557 [(set (attr "type")
20558 (cond [(match_operand:XF 3 "mult_operator")
20559 (const_string "fmul")
20560 (match_operand:XF 3 "div_operator")
20561 (const_string "fdiv")
20562 ]
20563 (const_string "fop")))
20564 (set_attr "mode" "<MODE>")])
20565
20566 (define_insn "*fop_df_6_i387"
20567 [(set (match_operand:DF 0 "register_operand" "=f,f")
20568 (match_operator:DF 3 "binary_fp_operator"
20569 [(float_extend:DF
20570 (match_operand:SF 1 "register_operand" "0,f"))
20571 (float_extend:DF
20572 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20573 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20574 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20575 "* return output_387_binary_op (insn, operands);"
20576 [(set (attr "type")
20577 (cond [(match_operand:DF 3 "mult_operator")
20578 (const_string "fmul")
20579 (match_operand:DF 3 "div_operator")
20580 (const_string "fdiv")
20581 ]
20582 (const_string "fop")))
20583 (set_attr "mode" "SF")])
20584 \f
20585 ;; FPU special functions.
20586
20587 ;; This pattern implements a no-op XFmode truncation for
20588 ;; all fancy i386 XFmode math functions.
20589
20590 (define_insn "truncxf<mode>2_i387_noop_unspec"
20591 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20592 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20593 UNSPEC_TRUNC_NOOP))]
20594 "TARGET_USE_FANCY_MATH_387"
20595 "* return output_387_reg_move (insn, operands);"
20596 [(set_attr "type" "fmov")
20597 (set_attr "mode" "<MODE>")])
20598
20599 (define_insn "sqrtxf2"
20600 [(set (match_operand:XF 0 "register_operand" "=f")
20601 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20602 "TARGET_USE_FANCY_MATH_387"
20603 "fsqrt"
20604 [(set_attr "type" "fpspc")
20605 (set_attr "mode" "XF")
20606 (set_attr "athlon_decode" "direct")
20607 (set_attr "amdfam10_decode" "direct")
20608 (set_attr "bdver1_decode" "direct")])
20609
20610 (define_insn "*rsqrtsf2_sse"
20611 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20612 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20613 UNSPEC_RSQRT))]
20614 "TARGET_SSE && TARGET_SSE_MATH"
20615 "@
20616 %vrsqrtss\t{%d1, %0|%0, %d1}
20617 %vrsqrtss\t{%d1, %0|%0, %d1}
20618 rsqrtss\t{%1, %d0|%d0, %1}
20619 vrsqrtss\t{%1, %d0|%d0, %1}"
20620 [(set_attr "isa" "*,*,noavx,avx")
20621 (set_attr "gpr32" "1,1,1,0")
20622 (set_attr "type" "sse")
20623 (set_attr "atom_sse_attr" "rcp")
20624 (set_attr "btver2_sse_attr" "rcp")
20625 (set_attr "prefix" "maybe_vex")
20626 (set_attr "mode" "SF")
20627 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20628 (set (attr "preferred_for_speed")
20629 (cond [(match_test "TARGET_AVX")
20630 (symbol_ref "true")
20631 (eq_attr "alternative" "1,2,3")
20632 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20633 ]
20634 (symbol_ref "true")))])
20635
20636 (define_expand "rsqrtsf2"
20637 [(set (match_operand:SF 0 "register_operand")
20638 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20639 UNSPEC_RSQRT))]
20640 "TARGET_SSE && TARGET_SSE_MATH"
20641 {
20642 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20643 DONE;
20644 })
20645
20646 (define_insn "rsqrthf2"
20647 [(set (match_operand:HF 0 "register_operand" "=v,v")
20648 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20649 UNSPEC_RSQRT))]
20650 "TARGET_AVX512FP16"
20651 "@
20652 vrsqrtsh\t{%d1, %0|%0, %d1}
20653 vrsqrtsh\t{%1, %d0|%d0, %1}"
20654 [(set_attr "type" "sse")
20655 (set_attr "prefix" "evex")
20656 (set_attr "avx_partial_xmm_update" "false,true")
20657 (set_attr "mode" "HF")])
20658
20659 (define_insn "sqrthf2"
20660 [(set (match_operand:HF 0 "register_operand" "=v,v")
20661 (sqrt:HF
20662 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20663 "TARGET_AVX512FP16"
20664 "@
20665 vsqrtsh\t{%d1, %0|%0, %d1}
20666 vsqrtsh\t{%1, %d0|%d0, %1}"
20667 [(set_attr "type" "sse")
20668 (set_attr "prefix" "evex")
20669 (set_attr "avx_partial_xmm_update" "false,true")
20670 (set_attr "mode" "HF")])
20671
20672 (define_insn "*sqrt<mode>2_sse"
20673 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20674 (sqrt:MODEF
20675 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20676 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20677 "@
20678 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20679 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20680 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20681 [(set_attr "type" "sse")
20682 (set_attr "atom_sse_attr" "sqrt")
20683 (set_attr "btver2_sse_attr" "sqrt")
20684 (set_attr "prefix" "maybe_vex")
20685 (set_attr "avx_partial_xmm_update" "false,false,true")
20686 (set_attr "mode" "<MODE>")
20687 (set (attr "preferred_for_speed")
20688 (cond [(match_test "TARGET_AVX")
20689 (symbol_ref "true")
20690 (eq_attr "alternative" "1,2")
20691 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20692 ]
20693 (symbol_ref "true")))])
20694
20695 (define_expand "sqrt<mode>2"
20696 [(set (match_operand:MODEF 0 "register_operand")
20697 (sqrt:MODEF
20698 (match_operand:MODEF 1 "nonimmediate_operand")))]
20699 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20700 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20701 {
20702 if (<MODE>mode == SFmode
20703 && TARGET_SSE && TARGET_SSE_MATH
20704 && TARGET_RECIP_SQRT
20705 && !optimize_function_for_size_p (cfun)
20706 && flag_finite_math_only && !flag_trapping_math
20707 && flag_unsafe_math_optimizations)
20708 {
20709 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20710 DONE;
20711 }
20712
20713 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20714 {
20715 rtx op0 = gen_reg_rtx (XFmode);
20716 rtx op1 = gen_reg_rtx (XFmode);
20717
20718 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20719 emit_insn (gen_sqrtxf2 (op0, op1));
20720 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20721 DONE;
20722 }
20723 })
20724
20725 (define_expand "hypot<mode>3"
20726 [(use (match_operand:MODEF 0 "register_operand"))
20727 (use (match_operand:MODEF 1 "general_operand"))
20728 (use (match_operand:MODEF 2 "general_operand"))]
20729 "TARGET_USE_FANCY_MATH_387
20730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20731 || TARGET_MIX_SSE_I387)
20732 && flag_finite_math_only
20733 && flag_unsafe_math_optimizations"
20734 {
20735 rtx op0 = gen_reg_rtx (XFmode);
20736 rtx op1 = gen_reg_rtx (XFmode);
20737 rtx op2 = gen_reg_rtx (XFmode);
20738
20739 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20740 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20741
20742 emit_insn (gen_mulxf3 (op1, op1, op1));
20743 emit_insn (gen_mulxf3 (op2, op2, op2));
20744 emit_insn (gen_addxf3 (op0, op2, op1));
20745 emit_insn (gen_sqrtxf2 (op0, op0));
20746
20747 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20748 DONE;
20749 })
20750
20751 (define_insn "x86_fnstsw_1"
20752 [(set (match_operand:HI 0 "register_operand" "=a")
20753 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20754 "TARGET_80387"
20755 "fnstsw\t%0"
20756 [(set_attr "length" "2")
20757 (set_attr "mode" "SI")
20758 (set_attr "unit" "i387")])
20759
20760 (define_insn "fpremxf4_i387"
20761 [(set (match_operand:XF 0 "register_operand" "=f")
20762 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20763 (match_operand:XF 3 "register_operand" "1")]
20764 UNSPEC_FPREM_F))
20765 (set (match_operand:XF 1 "register_operand" "=f")
20766 (unspec:XF [(match_dup 2) (match_dup 3)]
20767 UNSPEC_FPREM_U))
20768 (set (reg:CCFP FPSR_REG)
20769 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20770 UNSPEC_C2_FLAG))]
20771 "TARGET_USE_FANCY_MATH_387"
20772 "fprem"
20773 [(set_attr "type" "fpspc")
20774 (set_attr "znver1_decode" "vector")
20775 (set_attr "mode" "XF")])
20776
20777 (define_expand "fmodxf3"
20778 [(use (match_operand:XF 0 "register_operand"))
20779 (use (match_operand:XF 1 "general_operand"))
20780 (use (match_operand:XF 2 "general_operand"))]
20781 "TARGET_USE_FANCY_MATH_387"
20782 {
20783 rtx_code_label *label = gen_label_rtx ();
20784
20785 rtx op1 = gen_reg_rtx (XFmode);
20786 rtx op2 = gen_reg_rtx (XFmode);
20787
20788 emit_move_insn (op2, operands[2]);
20789 emit_move_insn (op1, operands[1]);
20790
20791 emit_label (label);
20792 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20793 ix86_emit_fp_unordered_jump (label);
20794 LABEL_NUSES (label) = 1;
20795
20796 emit_move_insn (operands[0], op1);
20797 DONE;
20798 })
20799
20800 (define_expand "fmod<mode>3"
20801 [(use (match_operand:MODEF 0 "register_operand"))
20802 (use (match_operand:MODEF 1 "general_operand"))
20803 (use (match_operand:MODEF 2 "general_operand"))]
20804 "TARGET_USE_FANCY_MATH_387"
20805 {
20806 rtx (*gen_truncxf) (rtx, rtx);
20807
20808 rtx_code_label *label = gen_label_rtx ();
20809
20810 rtx op1 = gen_reg_rtx (XFmode);
20811 rtx op2 = gen_reg_rtx (XFmode);
20812
20813 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20814 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20815
20816 emit_label (label);
20817 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20818 ix86_emit_fp_unordered_jump (label);
20819 LABEL_NUSES (label) = 1;
20820
20821 /* Truncate the result properly for strict SSE math. */
20822 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20823 && !TARGET_MIX_SSE_I387)
20824 gen_truncxf = gen_truncxf<mode>2;
20825 else
20826 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20827
20828 emit_insn (gen_truncxf (operands[0], op1));
20829 DONE;
20830 })
20831
20832 (define_insn "fprem1xf4_i387"
20833 [(set (match_operand:XF 0 "register_operand" "=f")
20834 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20835 (match_operand:XF 3 "register_operand" "1")]
20836 UNSPEC_FPREM1_F))
20837 (set (match_operand:XF 1 "register_operand" "=f")
20838 (unspec:XF [(match_dup 2) (match_dup 3)]
20839 UNSPEC_FPREM1_U))
20840 (set (reg:CCFP FPSR_REG)
20841 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20842 UNSPEC_C2_FLAG))]
20843 "TARGET_USE_FANCY_MATH_387"
20844 "fprem1"
20845 [(set_attr "type" "fpspc")
20846 (set_attr "znver1_decode" "vector")
20847 (set_attr "mode" "XF")])
20848
20849 (define_expand "remainderxf3"
20850 [(use (match_operand:XF 0 "register_operand"))
20851 (use (match_operand:XF 1 "general_operand"))
20852 (use (match_operand:XF 2 "general_operand"))]
20853 "TARGET_USE_FANCY_MATH_387"
20854 {
20855 rtx_code_label *label = gen_label_rtx ();
20856
20857 rtx op1 = gen_reg_rtx (XFmode);
20858 rtx op2 = gen_reg_rtx (XFmode);
20859
20860 emit_move_insn (op2, operands[2]);
20861 emit_move_insn (op1, operands[1]);
20862
20863 emit_label (label);
20864 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20865 ix86_emit_fp_unordered_jump (label);
20866 LABEL_NUSES (label) = 1;
20867
20868 emit_move_insn (operands[0], op1);
20869 DONE;
20870 })
20871
20872 (define_expand "remainder<mode>3"
20873 [(use (match_operand:MODEF 0 "register_operand"))
20874 (use (match_operand:MODEF 1 "general_operand"))
20875 (use (match_operand:MODEF 2 "general_operand"))]
20876 "TARGET_USE_FANCY_MATH_387"
20877 {
20878 rtx (*gen_truncxf) (rtx, rtx);
20879
20880 rtx_code_label *label = gen_label_rtx ();
20881
20882 rtx op1 = gen_reg_rtx (XFmode);
20883 rtx op2 = gen_reg_rtx (XFmode);
20884
20885 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20886 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20887
20888 emit_label (label);
20889
20890 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20891 ix86_emit_fp_unordered_jump (label);
20892 LABEL_NUSES (label) = 1;
20893
20894 /* Truncate the result properly for strict SSE math. */
20895 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20896 && !TARGET_MIX_SSE_I387)
20897 gen_truncxf = gen_truncxf<mode>2;
20898 else
20899 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20900
20901 emit_insn (gen_truncxf (operands[0], op1));
20902 DONE;
20903 })
20904
20905 (define_int_iterator SINCOS
20906 [UNSPEC_SIN
20907 UNSPEC_COS])
20908
20909 (define_int_attr sincos
20910 [(UNSPEC_SIN "sin")
20911 (UNSPEC_COS "cos")])
20912
20913 (define_insn "<sincos>xf2"
20914 [(set (match_operand:XF 0 "register_operand" "=f")
20915 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20916 SINCOS))]
20917 "TARGET_USE_FANCY_MATH_387
20918 && flag_unsafe_math_optimizations"
20919 "f<sincos>"
20920 [(set_attr "type" "fpspc")
20921 (set_attr "znver1_decode" "vector")
20922 (set_attr "mode" "XF")])
20923
20924 (define_expand "<sincos><mode>2"
20925 [(set (match_operand:MODEF 0 "register_operand")
20926 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20927 SINCOS))]
20928 "TARGET_USE_FANCY_MATH_387
20929 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20930 || TARGET_MIX_SSE_I387)
20931 && flag_unsafe_math_optimizations"
20932 {
20933 rtx op0 = gen_reg_rtx (XFmode);
20934 rtx op1 = gen_reg_rtx (XFmode);
20935
20936 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20937 emit_insn (gen_<sincos>xf2 (op0, op1));
20938 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20939 DONE;
20940 })
20941
20942 (define_insn "sincosxf3"
20943 [(set (match_operand:XF 0 "register_operand" "=f")
20944 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20945 UNSPEC_SINCOS_COS))
20946 (set (match_operand:XF 1 "register_operand" "=f")
20947 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20948 "TARGET_USE_FANCY_MATH_387
20949 && flag_unsafe_math_optimizations"
20950 "fsincos"
20951 [(set_attr "type" "fpspc")
20952 (set_attr "znver1_decode" "vector")
20953 (set_attr "mode" "XF")])
20954
20955 (define_expand "sincos<mode>3"
20956 [(use (match_operand:MODEF 0 "register_operand"))
20957 (use (match_operand:MODEF 1 "register_operand"))
20958 (use (match_operand:MODEF 2 "general_operand"))]
20959 "TARGET_USE_FANCY_MATH_387
20960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20961 || TARGET_MIX_SSE_I387)
20962 && flag_unsafe_math_optimizations"
20963 {
20964 rtx op0 = gen_reg_rtx (XFmode);
20965 rtx op1 = gen_reg_rtx (XFmode);
20966 rtx op2 = gen_reg_rtx (XFmode);
20967
20968 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20969 emit_insn (gen_sincosxf3 (op0, op1, op2));
20970 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20971 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20972 DONE;
20973 })
20974
20975 (define_insn "fptanxf4_i387"
20976 [(set (match_operand:SF 0 "register_operand" "=f")
20977 (match_operand:SF 3 "const1_operand"))
20978 (set (match_operand:XF 1 "register_operand" "=f")
20979 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20980 UNSPEC_TAN))]
20981 "TARGET_USE_FANCY_MATH_387
20982 && flag_unsafe_math_optimizations"
20983 "fptan"
20984 [(set_attr "type" "fpspc")
20985 (set_attr "znver1_decode" "vector")
20986 (set_attr "mode" "XF")])
20987
20988 (define_expand "tanxf2"
20989 [(use (match_operand:XF 0 "register_operand"))
20990 (use (match_operand:XF 1 "register_operand"))]
20991 "TARGET_USE_FANCY_MATH_387
20992 && flag_unsafe_math_optimizations"
20993 {
20994 rtx one = gen_reg_rtx (SFmode);
20995 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20996 CONST1_RTX (SFmode)));
20997 DONE;
20998 })
20999
21000 (define_expand "tan<mode>2"
21001 [(use (match_operand:MODEF 0 "register_operand"))
21002 (use (match_operand:MODEF 1 "general_operand"))]
21003 "TARGET_USE_FANCY_MATH_387
21004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21005 || TARGET_MIX_SSE_I387)
21006 && flag_unsafe_math_optimizations"
21007 {
21008 rtx op0 = gen_reg_rtx (XFmode);
21009 rtx op1 = gen_reg_rtx (XFmode);
21010
21011 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21012 emit_insn (gen_tanxf2 (op0, op1));
21013 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21014 DONE;
21015 })
21016
21017 (define_insn "atan2xf3"
21018 [(set (match_operand:XF 0 "register_operand" "=f")
21019 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21020 (match_operand:XF 1 "register_operand" "f")]
21021 UNSPEC_FPATAN))
21022 (clobber (match_scratch:XF 3 "=1"))]
21023 "TARGET_USE_FANCY_MATH_387
21024 && flag_unsafe_math_optimizations"
21025 "fpatan"
21026 [(set_attr "type" "fpspc")
21027 (set_attr "znver1_decode" "vector")
21028 (set_attr "mode" "XF")])
21029
21030 (define_expand "atan2<mode>3"
21031 [(use (match_operand:MODEF 0 "register_operand"))
21032 (use (match_operand:MODEF 1 "general_operand"))
21033 (use (match_operand:MODEF 2 "general_operand"))]
21034 "TARGET_USE_FANCY_MATH_387
21035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21036 || TARGET_MIX_SSE_I387)
21037 && flag_unsafe_math_optimizations"
21038 {
21039 rtx op0 = gen_reg_rtx (XFmode);
21040 rtx op1 = gen_reg_rtx (XFmode);
21041 rtx op2 = gen_reg_rtx (XFmode);
21042
21043 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21045
21046 emit_insn (gen_atan2xf3 (op0, op1, op2));
21047 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21048 DONE;
21049 })
21050
21051 (define_expand "atanxf2"
21052 [(parallel [(set (match_operand:XF 0 "register_operand")
21053 (unspec:XF [(match_dup 2)
21054 (match_operand:XF 1 "register_operand")]
21055 UNSPEC_FPATAN))
21056 (clobber (scratch:XF))])]
21057 "TARGET_USE_FANCY_MATH_387
21058 && flag_unsafe_math_optimizations"
21059 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21060
21061 (define_expand "atan<mode>2"
21062 [(use (match_operand:MODEF 0 "register_operand"))
21063 (use (match_operand:MODEF 1 "general_operand"))]
21064 "TARGET_USE_FANCY_MATH_387
21065 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21066 || TARGET_MIX_SSE_I387)
21067 && flag_unsafe_math_optimizations"
21068 {
21069 rtx op0 = gen_reg_rtx (XFmode);
21070 rtx op1 = gen_reg_rtx (XFmode);
21071
21072 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21073 emit_insn (gen_atanxf2 (op0, op1));
21074 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21075 DONE;
21076 })
21077
21078 (define_expand "asinxf2"
21079 [(set (match_dup 2)
21080 (mult:XF (match_operand:XF 1 "register_operand")
21081 (match_dup 1)))
21082 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21083 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21084 (parallel [(set (match_operand:XF 0 "register_operand")
21085 (unspec:XF [(match_dup 5) (match_dup 1)]
21086 UNSPEC_FPATAN))
21087 (clobber (scratch:XF))])]
21088 "TARGET_USE_FANCY_MATH_387
21089 && flag_unsafe_math_optimizations"
21090 {
21091 int i;
21092
21093 for (i = 2; i < 6; i++)
21094 operands[i] = gen_reg_rtx (XFmode);
21095
21096 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21097 })
21098
21099 (define_expand "asin<mode>2"
21100 [(use (match_operand:MODEF 0 "register_operand"))
21101 (use (match_operand:MODEF 1 "general_operand"))]
21102 "TARGET_USE_FANCY_MATH_387
21103 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21104 || TARGET_MIX_SSE_I387)
21105 && flag_unsafe_math_optimizations"
21106 {
21107 rtx op0 = gen_reg_rtx (XFmode);
21108 rtx op1 = gen_reg_rtx (XFmode);
21109
21110 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21111 emit_insn (gen_asinxf2 (op0, op1));
21112 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21113 DONE;
21114 })
21115
21116 (define_expand "acosxf2"
21117 [(set (match_dup 2)
21118 (mult:XF (match_operand:XF 1 "register_operand")
21119 (match_dup 1)))
21120 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21121 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21122 (parallel [(set (match_operand:XF 0 "register_operand")
21123 (unspec:XF [(match_dup 1) (match_dup 5)]
21124 UNSPEC_FPATAN))
21125 (clobber (scratch:XF))])]
21126 "TARGET_USE_FANCY_MATH_387
21127 && flag_unsafe_math_optimizations"
21128 {
21129 int i;
21130
21131 for (i = 2; i < 6; i++)
21132 operands[i] = gen_reg_rtx (XFmode);
21133
21134 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21135 })
21136
21137 (define_expand "acos<mode>2"
21138 [(use (match_operand:MODEF 0 "register_operand"))
21139 (use (match_operand:MODEF 1 "general_operand"))]
21140 "TARGET_USE_FANCY_MATH_387
21141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21142 || TARGET_MIX_SSE_I387)
21143 && flag_unsafe_math_optimizations"
21144 {
21145 rtx op0 = gen_reg_rtx (XFmode);
21146 rtx op1 = gen_reg_rtx (XFmode);
21147
21148 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21149 emit_insn (gen_acosxf2 (op0, op1));
21150 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21151 DONE;
21152 })
21153
21154 (define_expand "sinhxf2"
21155 [(use (match_operand:XF 0 "register_operand"))
21156 (use (match_operand:XF 1 "register_operand"))]
21157 "TARGET_USE_FANCY_MATH_387
21158 && flag_finite_math_only
21159 && flag_unsafe_math_optimizations"
21160 {
21161 ix86_emit_i387_sinh (operands[0], operands[1]);
21162 DONE;
21163 })
21164
21165 (define_expand "sinh<mode>2"
21166 [(use (match_operand:MODEF 0 "register_operand"))
21167 (use (match_operand:MODEF 1 "general_operand"))]
21168 "TARGET_USE_FANCY_MATH_387
21169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21170 || TARGET_MIX_SSE_I387)
21171 && flag_finite_math_only
21172 && flag_unsafe_math_optimizations"
21173 {
21174 rtx op0 = gen_reg_rtx (XFmode);
21175 rtx op1 = gen_reg_rtx (XFmode);
21176
21177 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21178 emit_insn (gen_sinhxf2 (op0, op1));
21179 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21180 DONE;
21181 })
21182
21183 (define_expand "coshxf2"
21184 [(use (match_operand:XF 0 "register_operand"))
21185 (use (match_operand:XF 1 "register_operand"))]
21186 "TARGET_USE_FANCY_MATH_387
21187 && flag_unsafe_math_optimizations"
21188 {
21189 ix86_emit_i387_cosh (operands[0], operands[1]);
21190 DONE;
21191 })
21192
21193 (define_expand "cosh<mode>2"
21194 [(use (match_operand:MODEF 0 "register_operand"))
21195 (use (match_operand:MODEF 1 "general_operand"))]
21196 "TARGET_USE_FANCY_MATH_387
21197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21198 || TARGET_MIX_SSE_I387)
21199 && flag_unsafe_math_optimizations"
21200 {
21201 rtx op0 = gen_reg_rtx (XFmode);
21202 rtx op1 = gen_reg_rtx (XFmode);
21203
21204 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21205 emit_insn (gen_coshxf2 (op0, op1));
21206 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21207 DONE;
21208 })
21209
21210 (define_expand "tanhxf2"
21211 [(use (match_operand:XF 0 "register_operand"))
21212 (use (match_operand:XF 1 "register_operand"))]
21213 "TARGET_USE_FANCY_MATH_387
21214 && flag_unsafe_math_optimizations"
21215 {
21216 ix86_emit_i387_tanh (operands[0], operands[1]);
21217 DONE;
21218 })
21219
21220 (define_expand "tanh<mode>2"
21221 [(use (match_operand:MODEF 0 "register_operand"))
21222 (use (match_operand:MODEF 1 "general_operand"))]
21223 "TARGET_USE_FANCY_MATH_387
21224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21225 || TARGET_MIX_SSE_I387)
21226 && flag_unsafe_math_optimizations"
21227 {
21228 rtx op0 = gen_reg_rtx (XFmode);
21229 rtx op1 = gen_reg_rtx (XFmode);
21230
21231 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21232 emit_insn (gen_tanhxf2 (op0, op1));
21233 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21234 DONE;
21235 })
21236
21237 (define_expand "asinhxf2"
21238 [(use (match_operand:XF 0 "register_operand"))
21239 (use (match_operand:XF 1 "register_operand"))]
21240 "TARGET_USE_FANCY_MATH_387
21241 && flag_finite_math_only
21242 && flag_unsafe_math_optimizations"
21243 {
21244 ix86_emit_i387_asinh (operands[0], operands[1]);
21245 DONE;
21246 })
21247
21248 (define_expand "asinh<mode>2"
21249 [(use (match_operand:MODEF 0 "register_operand"))
21250 (use (match_operand:MODEF 1 "general_operand"))]
21251 "TARGET_USE_FANCY_MATH_387
21252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21253 || TARGET_MIX_SSE_I387)
21254 && flag_finite_math_only
21255 && flag_unsafe_math_optimizations"
21256 {
21257 rtx op0 = gen_reg_rtx (XFmode);
21258 rtx op1 = gen_reg_rtx (XFmode);
21259
21260 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21261 emit_insn (gen_asinhxf2 (op0, op1));
21262 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21263 DONE;
21264 })
21265
21266 (define_expand "acoshxf2"
21267 [(use (match_operand:XF 0 "register_operand"))
21268 (use (match_operand:XF 1 "register_operand"))]
21269 "TARGET_USE_FANCY_MATH_387
21270 && flag_unsafe_math_optimizations"
21271 {
21272 ix86_emit_i387_acosh (operands[0], operands[1]);
21273 DONE;
21274 })
21275
21276 (define_expand "acosh<mode>2"
21277 [(use (match_operand:MODEF 0 "register_operand"))
21278 (use (match_operand:MODEF 1 "general_operand"))]
21279 "TARGET_USE_FANCY_MATH_387
21280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21281 || TARGET_MIX_SSE_I387)
21282 && flag_unsafe_math_optimizations"
21283 {
21284 rtx op0 = gen_reg_rtx (XFmode);
21285 rtx op1 = gen_reg_rtx (XFmode);
21286
21287 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21288 emit_insn (gen_acoshxf2 (op0, op1));
21289 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21290 DONE;
21291 })
21292
21293 (define_expand "atanhxf2"
21294 [(use (match_operand:XF 0 "register_operand"))
21295 (use (match_operand:XF 1 "register_operand"))]
21296 "TARGET_USE_FANCY_MATH_387
21297 && flag_unsafe_math_optimizations"
21298 {
21299 ix86_emit_i387_atanh (operands[0], operands[1]);
21300 DONE;
21301 })
21302
21303 (define_expand "atanh<mode>2"
21304 [(use (match_operand:MODEF 0 "register_operand"))
21305 (use (match_operand:MODEF 1 "general_operand"))]
21306 "TARGET_USE_FANCY_MATH_387
21307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21308 || TARGET_MIX_SSE_I387)
21309 && flag_unsafe_math_optimizations"
21310 {
21311 rtx op0 = gen_reg_rtx (XFmode);
21312 rtx op1 = gen_reg_rtx (XFmode);
21313
21314 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21315 emit_insn (gen_atanhxf2 (op0, op1));
21316 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21317 DONE;
21318 })
21319
21320 (define_insn "fyl2xxf3_i387"
21321 [(set (match_operand:XF 0 "register_operand" "=f")
21322 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21323 (match_operand:XF 2 "register_operand" "f")]
21324 UNSPEC_FYL2X))
21325 (clobber (match_scratch:XF 3 "=2"))]
21326 "TARGET_USE_FANCY_MATH_387
21327 && flag_unsafe_math_optimizations"
21328 "fyl2x"
21329 [(set_attr "type" "fpspc")
21330 (set_attr "znver1_decode" "vector")
21331 (set_attr "mode" "XF")])
21332
21333 (define_expand "logxf2"
21334 [(parallel [(set (match_operand:XF 0 "register_operand")
21335 (unspec:XF [(match_operand:XF 1 "register_operand")
21336 (match_dup 2)] UNSPEC_FYL2X))
21337 (clobber (scratch:XF))])]
21338 "TARGET_USE_FANCY_MATH_387
21339 && flag_unsafe_math_optimizations"
21340 {
21341 operands[2]
21342 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21343 })
21344
21345 (define_expand "log<mode>2"
21346 [(use (match_operand:MODEF 0 "register_operand"))
21347 (use (match_operand:MODEF 1 "general_operand"))]
21348 "TARGET_USE_FANCY_MATH_387
21349 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21350 || TARGET_MIX_SSE_I387)
21351 && flag_unsafe_math_optimizations"
21352 {
21353 rtx op0 = gen_reg_rtx (XFmode);
21354 rtx op1 = gen_reg_rtx (XFmode);
21355
21356 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21357 emit_insn (gen_logxf2 (op0, op1));
21358 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21359 DONE;
21360 })
21361
21362 (define_expand "log10xf2"
21363 [(parallel [(set (match_operand:XF 0 "register_operand")
21364 (unspec:XF [(match_operand:XF 1 "register_operand")
21365 (match_dup 2)] UNSPEC_FYL2X))
21366 (clobber (scratch:XF))])]
21367 "TARGET_USE_FANCY_MATH_387
21368 && flag_unsafe_math_optimizations"
21369 {
21370 operands[2]
21371 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21372 })
21373
21374 (define_expand "log10<mode>2"
21375 [(use (match_operand:MODEF 0 "register_operand"))
21376 (use (match_operand:MODEF 1 "general_operand"))]
21377 "TARGET_USE_FANCY_MATH_387
21378 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21379 || TARGET_MIX_SSE_I387)
21380 && flag_unsafe_math_optimizations"
21381 {
21382 rtx op0 = gen_reg_rtx (XFmode);
21383 rtx op1 = gen_reg_rtx (XFmode);
21384
21385 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21386 emit_insn (gen_log10xf2 (op0, op1));
21387 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21388 DONE;
21389 })
21390
21391 (define_expand "log2xf2"
21392 [(parallel [(set (match_operand:XF 0 "register_operand")
21393 (unspec:XF [(match_operand:XF 1 "register_operand")
21394 (match_dup 2)] UNSPEC_FYL2X))
21395 (clobber (scratch:XF))])]
21396 "TARGET_USE_FANCY_MATH_387
21397 && flag_unsafe_math_optimizations"
21398 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21399
21400 (define_expand "log2<mode>2"
21401 [(use (match_operand:MODEF 0 "register_operand"))
21402 (use (match_operand:MODEF 1 "general_operand"))]
21403 "TARGET_USE_FANCY_MATH_387
21404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21405 || TARGET_MIX_SSE_I387)
21406 && flag_unsafe_math_optimizations"
21407 {
21408 rtx op0 = gen_reg_rtx (XFmode);
21409 rtx op1 = gen_reg_rtx (XFmode);
21410
21411 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21412 emit_insn (gen_log2xf2 (op0, op1));
21413 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21414 DONE;
21415 })
21416
21417 (define_insn "fyl2xp1xf3_i387"
21418 [(set (match_operand:XF 0 "register_operand" "=f")
21419 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21420 (match_operand:XF 2 "register_operand" "f")]
21421 UNSPEC_FYL2XP1))
21422 (clobber (match_scratch:XF 3 "=2"))]
21423 "TARGET_USE_FANCY_MATH_387
21424 && flag_unsafe_math_optimizations"
21425 "fyl2xp1"
21426 [(set_attr "type" "fpspc")
21427 (set_attr "znver1_decode" "vector")
21428 (set_attr "mode" "XF")])
21429
21430 (define_expand "log1pxf2"
21431 [(use (match_operand:XF 0 "register_operand"))
21432 (use (match_operand:XF 1 "register_operand"))]
21433 "TARGET_USE_FANCY_MATH_387
21434 && flag_unsafe_math_optimizations"
21435 {
21436 ix86_emit_i387_log1p (operands[0], operands[1]);
21437 DONE;
21438 })
21439
21440 (define_expand "log1p<mode>2"
21441 [(use (match_operand:MODEF 0 "register_operand"))
21442 (use (match_operand:MODEF 1 "general_operand"))]
21443 "TARGET_USE_FANCY_MATH_387
21444 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21445 || TARGET_MIX_SSE_I387)
21446 && flag_unsafe_math_optimizations"
21447 {
21448 rtx op0 = gen_reg_rtx (XFmode);
21449 rtx op1 = gen_reg_rtx (XFmode);
21450
21451 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21452 emit_insn (gen_log1pxf2 (op0, op1));
21453 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21454 DONE;
21455 })
21456
21457 (define_insn "fxtractxf3_i387"
21458 [(set (match_operand:XF 0 "register_operand" "=f")
21459 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21460 UNSPEC_XTRACT_FRACT))
21461 (set (match_operand:XF 1 "register_operand" "=f")
21462 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21463 "TARGET_USE_FANCY_MATH_387
21464 && flag_unsafe_math_optimizations"
21465 "fxtract"
21466 [(set_attr "type" "fpspc")
21467 (set_attr "znver1_decode" "vector")
21468 (set_attr "mode" "XF")])
21469
21470 (define_expand "logbxf2"
21471 [(parallel [(set (match_dup 2)
21472 (unspec:XF [(match_operand:XF 1 "register_operand")]
21473 UNSPEC_XTRACT_FRACT))
21474 (set (match_operand:XF 0 "register_operand")
21475 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21476 "TARGET_USE_FANCY_MATH_387
21477 && flag_unsafe_math_optimizations"
21478 "operands[2] = gen_reg_rtx (XFmode);")
21479
21480 (define_expand "logb<mode>2"
21481 [(use (match_operand:MODEF 0 "register_operand"))
21482 (use (match_operand:MODEF 1 "general_operand"))]
21483 "TARGET_USE_FANCY_MATH_387
21484 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21485 || TARGET_MIX_SSE_I387)
21486 && flag_unsafe_math_optimizations"
21487 {
21488 rtx op0 = gen_reg_rtx (XFmode);
21489 rtx op1 = gen_reg_rtx (XFmode);
21490
21491 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21492 emit_insn (gen_logbxf2 (op0, op1));
21493 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21494 DONE;
21495 })
21496
21497 (define_expand "ilogbxf2"
21498 [(use (match_operand:SI 0 "register_operand"))
21499 (use (match_operand:XF 1 "register_operand"))]
21500 "TARGET_USE_FANCY_MATH_387
21501 && flag_unsafe_math_optimizations"
21502 {
21503 rtx op0, op1;
21504
21505 if (optimize_insn_for_size_p ())
21506 FAIL;
21507
21508 op0 = gen_reg_rtx (XFmode);
21509 op1 = gen_reg_rtx (XFmode);
21510
21511 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21512 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21513 DONE;
21514 })
21515
21516 (define_expand "ilogb<mode>2"
21517 [(use (match_operand:SI 0 "register_operand"))
21518 (use (match_operand:MODEF 1 "general_operand"))]
21519 "TARGET_USE_FANCY_MATH_387
21520 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21521 || TARGET_MIX_SSE_I387)
21522 && flag_unsafe_math_optimizations"
21523 {
21524 rtx op0, op1, op2;
21525
21526 if (optimize_insn_for_size_p ())
21527 FAIL;
21528
21529 op0 = gen_reg_rtx (XFmode);
21530 op1 = gen_reg_rtx (XFmode);
21531 op2 = gen_reg_rtx (XFmode);
21532
21533 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21534 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21535 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21536 DONE;
21537 })
21538
21539 (define_insn "*f2xm1xf2_i387"
21540 [(set (match_operand:XF 0 "register_operand" "=f")
21541 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21542 UNSPEC_F2XM1))]
21543 "TARGET_USE_FANCY_MATH_387
21544 && flag_unsafe_math_optimizations"
21545 "f2xm1"
21546 [(set_attr "type" "fpspc")
21547 (set_attr "znver1_decode" "vector")
21548 (set_attr "mode" "XF")])
21549
21550 (define_insn "fscalexf4_i387"
21551 [(set (match_operand:XF 0 "register_operand" "=f")
21552 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21553 (match_operand:XF 3 "register_operand" "1")]
21554 UNSPEC_FSCALE_FRACT))
21555 (set (match_operand:XF 1 "register_operand" "=f")
21556 (unspec:XF [(match_dup 2) (match_dup 3)]
21557 UNSPEC_FSCALE_EXP))]
21558 "TARGET_USE_FANCY_MATH_387
21559 && flag_unsafe_math_optimizations"
21560 "fscale"
21561 [(set_attr "type" "fpspc")
21562 (set_attr "znver1_decode" "vector")
21563 (set_attr "mode" "XF")])
21564
21565 (define_expand "expNcorexf3"
21566 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21567 (match_operand:XF 2 "register_operand")))
21568 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21569 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21570 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21571 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21572 (parallel [(set (match_operand:XF 0 "register_operand")
21573 (unspec:XF [(match_dup 8) (match_dup 4)]
21574 UNSPEC_FSCALE_FRACT))
21575 (set (match_dup 9)
21576 (unspec:XF [(match_dup 8) (match_dup 4)]
21577 UNSPEC_FSCALE_EXP))])]
21578 "TARGET_USE_FANCY_MATH_387
21579 && flag_unsafe_math_optimizations"
21580 {
21581 int i;
21582
21583 for (i = 3; i < 10; i++)
21584 operands[i] = gen_reg_rtx (XFmode);
21585
21586 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21587 })
21588
21589 (define_expand "expxf2"
21590 [(use (match_operand:XF 0 "register_operand"))
21591 (use (match_operand:XF 1 "register_operand"))]
21592 "TARGET_USE_FANCY_MATH_387
21593 && flag_unsafe_math_optimizations"
21594 {
21595 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21596
21597 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21598 DONE;
21599 })
21600
21601 (define_expand "exp<mode>2"
21602 [(use (match_operand:MODEF 0 "register_operand"))
21603 (use (match_operand:MODEF 1 "general_operand"))]
21604 "TARGET_USE_FANCY_MATH_387
21605 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21606 || TARGET_MIX_SSE_I387)
21607 && flag_unsafe_math_optimizations"
21608 {
21609 rtx op0 = gen_reg_rtx (XFmode);
21610 rtx op1 = gen_reg_rtx (XFmode);
21611
21612 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21613 emit_insn (gen_expxf2 (op0, op1));
21614 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21615 DONE;
21616 })
21617
21618 (define_expand "exp10xf2"
21619 [(use (match_operand:XF 0 "register_operand"))
21620 (use (match_operand:XF 1 "register_operand"))]
21621 "TARGET_USE_FANCY_MATH_387
21622 && flag_unsafe_math_optimizations"
21623 {
21624 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21625
21626 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21627 DONE;
21628 })
21629
21630 (define_expand "exp10<mode>2"
21631 [(use (match_operand:MODEF 0 "register_operand"))
21632 (use (match_operand:MODEF 1 "general_operand"))]
21633 "TARGET_USE_FANCY_MATH_387
21634 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21635 || TARGET_MIX_SSE_I387)
21636 && flag_unsafe_math_optimizations"
21637 {
21638 rtx op0 = gen_reg_rtx (XFmode);
21639 rtx op1 = gen_reg_rtx (XFmode);
21640
21641 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21642 emit_insn (gen_exp10xf2 (op0, op1));
21643 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21644 DONE;
21645 })
21646
21647 (define_expand "exp2xf2"
21648 [(use (match_operand:XF 0 "register_operand"))
21649 (use (match_operand:XF 1 "register_operand"))]
21650 "TARGET_USE_FANCY_MATH_387
21651 && flag_unsafe_math_optimizations"
21652 {
21653 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21654
21655 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21656 DONE;
21657 })
21658
21659 (define_expand "exp2<mode>2"
21660 [(use (match_operand:MODEF 0 "register_operand"))
21661 (use (match_operand:MODEF 1 "general_operand"))]
21662 "TARGET_USE_FANCY_MATH_387
21663 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21664 || TARGET_MIX_SSE_I387)
21665 && flag_unsafe_math_optimizations"
21666 {
21667 rtx op0 = gen_reg_rtx (XFmode);
21668 rtx op1 = gen_reg_rtx (XFmode);
21669
21670 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21671 emit_insn (gen_exp2xf2 (op0, op1));
21672 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21673 DONE;
21674 })
21675
21676 (define_expand "expm1xf2"
21677 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21678 (match_dup 2)))
21679 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21680 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21681 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21682 (parallel [(set (match_dup 7)
21683 (unspec:XF [(match_dup 6) (match_dup 4)]
21684 UNSPEC_FSCALE_FRACT))
21685 (set (match_dup 8)
21686 (unspec:XF [(match_dup 6) (match_dup 4)]
21687 UNSPEC_FSCALE_EXP))])
21688 (parallel [(set (match_dup 10)
21689 (unspec:XF [(match_dup 9) (match_dup 8)]
21690 UNSPEC_FSCALE_FRACT))
21691 (set (match_dup 11)
21692 (unspec:XF [(match_dup 9) (match_dup 8)]
21693 UNSPEC_FSCALE_EXP))])
21694 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21695 (set (match_operand:XF 0 "register_operand")
21696 (plus:XF (match_dup 12) (match_dup 7)))]
21697 "TARGET_USE_FANCY_MATH_387
21698 && flag_unsafe_math_optimizations"
21699 {
21700 int i;
21701
21702 for (i = 2; i < 13; i++)
21703 operands[i] = gen_reg_rtx (XFmode);
21704
21705 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21706 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21707 })
21708
21709 (define_expand "expm1<mode>2"
21710 [(use (match_operand:MODEF 0 "register_operand"))
21711 (use (match_operand:MODEF 1 "general_operand"))]
21712 "TARGET_USE_FANCY_MATH_387
21713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21714 || TARGET_MIX_SSE_I387)
21715 && flag_unsafe_math_optimizations"
21716 {
21717 rtx op0 = gen_reg_rtx (XFmode);
21718 rtx op1 = gen_reg_rtx (XFmode);
21719
21720 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21721 emit_insn (gen_expm1xf2 (op0, op1));
21722 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21723 DONE;
21724 })
21725
21726 (define_insn "avx512f_scalef<mode>2"
21727 [(set (match_operand:MODEF 0 "register_operand" "=v")
21728 (unspec:MODEF
21729 [(match_operand:MODEF 1 "register_operand" "v")
21730 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21731 UNSPEC_SCALEF))]
21732 "TARGET_AVX512F"
21733 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21734 [(set_attr "prefix" "evex")
21735 (set_attr "mode" "<MODE>")])
21736
21737 (define_expand "ldexpxf3"
21738 [(match_operand:XF 0 "register_operand")
21739 (match_operand:XF 1 "register_operand")
21740 (match_operand:SI 2 "register_operand")]
21741 "TARGET_USE_FANCY_MATH_387
21742 && flag_unsafe_math_optimizations"
21743 {
21744 rtx tmp1 = gen_reg_rtx (XFmode);
21745 rtx tmp2 = gen_reg_rtx (XFmode);
21746
21747 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21748 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21749 operands[1], tmp1));
21750 DONE;
21751 })
21752
21753 (define_expand "ldexp<mode>3"
21754 [(use (match_operand:MODEF 0 "register_operand"))
21755 (use (match_operand:MODEF 1 "general_operand"))
21756 (use (match_operand:SI 2 "register_operand"))]
21757 "((TARGET_USE_FANCY_MATH_387
21758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21759 || TARGET_MIX_SSE_I387))
21760 || (TARGET_AVX512F && TARGET_SSE_MATH))
21761 && flag_unsafe_math_optimizations"
21762 {
21763 /* Prefer avx512f version. */
21764 if (TARGET_AVX512F && TARGET_SSE_MATH)
21765 {
21766 rtx op2 = gen_reg_rtx (<MODE>mode);
21767 operands[1] = force_reg (<MODE>mode, operands[1]);
21768
21769 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21770 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21771 }
21772 else
21773 {
21774 rtx op0 = gen_reg_rtx (XFmode);
21775 rtx op1 = gen_reg_rtx (XFmode);
21776
21777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21778 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21779 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21780 }
21781 DONE;
21782 })
21783
21784 (define_expand "scalbxf3"
21785 [(parallel [(set (match_operand:XF 0 " register_operand")
21786 (unspec:XF [(match_operand:XF 1 "register_operand")
21787 (match_operand:XF 2 "register_operand")]
21788 UNSPEC_FSCALE_FRACT))
21789 (set (match_dup 3)
21790 (unspec:XF [(match_dup 1) (match_dup 2)]
21791 UNSPEC_FSCALE_EXP))])]
21792 "TARGET_USE_FANCY_MATH_387
21793 && flag_unsafe_math_optimizations"
21794 "operands[3] = gen_reg_rtx (XFmode);")
21795
21796 (define_expand "scalb<mode>3"
21797 [(use (match_operand:MODEF 0 "register_operand"))
21798 (use (match_operand:MODEF 1 "general_operand"))
21799 (use (match_operand:MODEF 2 "general_operand"))]
21800 "TARGET_USE_FANCY_MATH_387
21801 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21802 || TARGET_MIX_SSE_I387)
21803 && flag_unsafe_math_optimizations"
21804 {
21805 rtx op0 = gen_reg_rtx (XFmode);
21806 rtx op1 = gen_reg_rtx (XFmode);
21807 rtx op2 = gen_reg_rtx (XFmode);
21808
21809 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21810 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21811 emit_insn (gen_scalbxf3 (op0, op1, op2));
21812 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21813 DONE;
21814 })
21815
21816 (define_expand "significandxf2"
21817 [(parallel [(set (match_operand:XF 0 "register_operand")
21818 (unspec:XF [(match_operand:XF 1 "register_operand")]
21819 UNSPEC_XTRACT_FRACT))
21820 (set (match_dup 2)
21821 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21822 "TARGET_USE_FANCY_MATH_387
21823 && flag_unsafe_math_optimizations"
21824 "operands[2] = gen_reg_rtx (XFmode);")
21825
21826 (define_expand "significand<mode>2"
21827 [(use (match_operand:MODEF 0 "register_operand"))
21828 (use (match_operand:MODEF 1 "general_operand"))]
21829 "TARGET_USE_FANCY_MATH_387
21830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21831 || TARGET_MIX_SSE_I387)
21832 && flag_unsafe_math_optimizations"
21833 {
21834 rtx op0 = gen_reg_rtx (XFmode);
21835 rtx op1 = gen_reg_rtx (XFmode);
21836
21837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21838 emit_insn (gen_significandxf2 (op0, op1));
21839 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21840 DONE;
21841 })
21842 \f
21843
21844 (define_insn "sse4_1_round<mode>2"
21845 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21846 (unspec:MODEFH
21847 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
21848 (match_operand:SI 2 "const_0_to_15_operand")]
21849 UNSPEC_ROUND))]
21850 "TARGET_SSE4_1"
21851 "@
21852 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21853 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21854 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21855 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21856 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21857 [(set_attr "type" "ssecvt")
21858 (set_attr "prefix_extra" "1,1,1,*,*")
21859 (set_attr "length_immediate" "1")
21860 (set_attr "gpr32" "1,1,0,1,1")
21861 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21862 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21863 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21864 (set_attr "mode" "<MODE>")
21865 (set (attr "preferred_for_speed")
21866 (cond [(match_test "TARGET_AVX")
21867 (symbol_ref "true")
21868 (eq_attr "alternative" "1,2")
21869 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21870 ]
21871 (symbol_ref "true")))])
21872
21873 (define_insn "rintxf2"
21874 [(set (match_operand:XF 0 "register_operand" "=f")
21875 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21876 UNSPEC_FRNDINT))]
21877 "TARGET_USE_FANCY_MATH_387"
21878 "frndint"
21879 [(set_attr "type" "fpspc")
21880 (set_attr "znver1_decode" "vector")
21881 (set_attr "mode" "XF")])
21882
21883 (define_expand "rinthf2"
21884 [(match_operand:HF 0 "register_operand")
21885 (match_operand:HF 1 "nonimmediate_operand")]
21886 "TARGET_AVX512FP16"
21887 {
21888 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21889 operands[1],
21890 GEN_INT (ROUND_MXCSR)));
21891 DONE;
21892 })
21893
21894 (define_expand "rint<mode>2"
21895 [(use (match_operand:MODEF 0 "register_operand"))
21896 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21897 "TARGET_USE_FANCY_MATH_387
21898 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21899 {
21900 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21901 {
21902 if (TARGET_SSE4_1)
21903 emit_insn (gen_sse4_1_round<mode>2
21904 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21905 else
21906 ix86_expand_rint (operands[0], operands[1]);
21907 }
21908 else
21909 {
21910 rtx op0 = gen_reg_rtx (XFmode);
21911 rtx op1 = gen_reg_rtx (XFmode);
21912
21913 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21914 emit_insn (gen_rintxf2 (op0, op1));
21915 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21916 }
21917 DONE;
21918 })
21919
21920 (define_expand "nearbyintxf2"
21921 [(set (match_operand:XF 0 "register_operand")
21922 (unspec:XF [(match_operand:XF 1 "register_operand")]
21923 UNSPEC_FRNDINT))]
21924 "TARGET_USE_FANCY_MATH_387
21925 && !flag_trapping_math")
21926
21927 (define_expand "nearbyinthf2"
21928 [(match_operand:HF 0 "register_operand")
21929 (match_operand:HF 1 "nonimmediate_operand")]
21930 "TARGET_AVX512FP16"
21931 {
21932 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21933 operands[1],
21934 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21935 DONE;
21936 })
21937
21938 (define_expand "nearbyint<mode>2"
21939 [(use (match_operand:MODEF 0 "register_operand"))
21940 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21941 "(TARGET_USE_FANCY_MATH_387
21942 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21943 || TARGET_MIX_SSE_I387)
21944 && !flag_trapping_math)
21945 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21946 {
21947 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21948 emit_insn (gen_sse4_1_round<mode>2
21949 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21950 | ROUND_NO_EXC)));
21951 else
21952 {
21953 rtx op0 = gen_reg_rtx (XFmode);
21954 rtx op1 = gen_reg_rtx (XFmode);
21955
21956 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21957 emit_insn (gen_nearbyintxf2 (op0, op1));
21958 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21959 }
21960 DONE;
21961 })
21962
21963 (define_expand "roundhf2"
21964 [(match_operand:HF 0 "register_operand")
21965 (match_operand:HF 1 "register_operand")]
21966 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
21967 {
21968 ix86_expand_round_sse4 (operands[0], operands[1]);
21969 DONE;
21970 })
21971
21972 (define_expand "round<mode>2"
21973 [(match_operand:X87MODEF 0 "register_operand")
21974 (match_operand:X87MODEF 1 "nonimmediate_operand")]
21975 "(TARGET_USE_FANCY_MATH_387
21976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21977 || TARGET_MIX_SSE_I387)
21978 && flag_unsafe_math_optimizations
21979 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21980 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21981 && !flag_trapping_math && !flag_rounding_math)"
21982 {
21983 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21984 && !flag_trapping_math && !flag_rounding_math)
21985 {
21986 if (TARGET_SSE4_1)
21987 {
21988 operands[1] = force_reg (<MODE>mode, operands[1]);
21989 ix86_expand_round_sse4 (operands[0], operands[1]);
21990 }
21991 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21992 ix86_expand_round (operands[0], operands[1]);
21993 else
21994 ix86_expand_rounddf_32 (operands[0], operands[1]);
21995 }
21996 else
21997 {
21998 operands[1] = force_reg (<MODE>mode, operands[1]);
21999 ix86_emit_i387_round (operands[0], operands[1]);
22000 }
22001 DONE;
22002 })
22003
22004 (define_insn "lrintxfdi2"
22005 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22006 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22007 UNSPEC_FIST))
22008 (clobber (match_scratch:XF 2 "=&f"))]
22009 "TARGET_USE_FANCY_MATH_387"
22010 "* return output_fix_trunc (insn, operands, false);"
22011 [(set_attr "type" "fpspc")
22012 (set_attr "mode" "DI")])
22013
22014 (define_insn "lrintxf<mode>2"
22015 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22016 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22017 UNSPEC_FIST))]
22018 "TARGET_USE_FANCY_MATH_387"
22019 "* return output_fix_trunc (insn, operands, false);"
22020 [(set_attr "type" "fpspc")
22021 (set_attr "mode" "<MODE>")])
22022
22023 (define_expand "lroundhf<mode>2"
22024 [(set (match_operand:SWI248 0 "register_operand")
22025 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
22026 UNSPEC_FIX_NOTRUNC))]
22027 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22028 {
22029 ix86_expand_lround (operands[0], operands[1]);
22030 DONE;
22031 })
22032
22033 (define_expand "lrinthf<mode>2"
22034 [(set (match_operand:SWI48 0 "register_operand")
22035 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
22036 UNSPEC_FIX_NOTRUNC))]
22037 "TARGET_AVX512FP16")
22038
22039 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
22040 [(set (match_operand:SWI48 0 "register_operand")
22041 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
22042 UNSPEC_FIX_NOTRUNC))]
22043 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
22044
22045 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
22046 [(match_operand:SWI248x 0 "nonimmediate_operand")
22047 (match_operand:X87MODEF 1 "register_operand")]
22048 "(TARGET_USE_FANCY_MATH_387
22049 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
22050 || TARGET_MIX_SSE_I387)
22051 && flag_unsafe_math_optimizations)
22052 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22053 && <SWI248x:MODE>mode != HImode
22054 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22055 && !flag_trapping_math && !flag_rounding_math)"
22056 {
22057 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22058 && <SWI248x:MODE>mode != HImode
22059 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22060 && !flag_trapping_math && !flag_rounding_math)
22061 ix86_expand_lround (operands[0], operands[1]);
22062 else
22063 ix86_emit_i387_round (operands[0], operands[1]);
22064 DONE;
22065 })
22066
22067 (define_int_iterator FRNDINT_ROUNDING
22068 [UNSPEC_FRNDINT_ROUNDEVEN
22069 UNSPEC_FRNDINT_FLOOR
22070 UNSPEC_FRNDINT_CEIL
22071 UNSPEC_FRNDINT_TRUNC])
22072
22073 (define_int_iterator FIST_ROUNDING
22074 [UNSPEC_FIST_FLOOR
22075 UNSPEC_FIST_CEIL])
22076
22077 ;; Base name for define_insn
22078 (define_int_attr rounding_insn
22079 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22080 (UNSPEC_FRNDINT_FLOOR "floor")
22081 (UNSPEC_FRNDINT_CEIL "ceil")
22082 (UNSPEC_FRNDINT_TRUNC "btrunc")
22083 (UNSPEC_FIST_FLOOR "floor")
22084 (UNSPEC_FIST_CEIL "ceil")])
22085
22086 (define_int_attr rounding
22087 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22088 (UNSPEC_FRNDINT_FLOOR "floor")
22089 (UNSPEC_FRNDINT_CEIL "ceil")
22090 (UNSPEC_FRNDINT_TRUNC "trunc")
22091 (UNSPEC_FIST_FLOOR "floor")
22092 (UNSPEC_FIST_CEIL "ceil")])
22093
22094 (define_int_attr ROUNDING
22095 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
22096 (UNSPEC_FRNDINT_FLOOR "FLOOR")
22097 (UNSPEC_FRNDINT_CEIL "CEIL")
22098 (UNSPEC_FRNDINT_TRUNC "TRUNC")
22099 (UNSPEC_FIST_FLOOR "FLOOR")
22100 (UNSPEC_FIST_CEIL "CEIL")])
22101
22102 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22103 (define_insn_and_split "frndintxf2_<rounding>"
22104 [(set (match_operand:XF 0 "register_operand")
22105 (unspec:XF [(match_operand:XF 1 "register_operand")]
22106 FRNDINT_ROUNDING))
22107 (clobber (reg:CC FLAGS_REG))]
22108 "TARGET_USE_FANCY_MATH_387
22109 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22110 && ix86_pre_reload_split ()"
22111 "#"
22112 "&& 1"
22113 [(const_int 0)]
22114 {
22115 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22116
22117 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22118 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22119
22120 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22121 operands[2], operands[3]));
22122 DONE;
22123 }
22124 [(set_attr "type" "frndint")
22125 (set_attr "i387_cw" "<rounding>")
22126 (set_attr "mode" "XF")])
22127
22128 (define_insn "frndintxf2_<rounding>_i387"
22129 [(set (match_operand:XF 0 "register_operand" "=f")
22130 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22131 FRNDINT_ROUNDING))
22132 (use (match_operand:HI 2 "memory_operand" "m"))
22133 (use (match_operand:HI 3 "memory_operand" "m"))]
22134 "TARGET_USE_FANCY_MATH_387
22135 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22136 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22137 [(set_attr "type" "frndint")
22138 (set_attr "i387_cw" "<rounding>")
22139 (set_attr "mode" "XF")])
22140
22141 (define_expand "<rounding_insn>xf2"
22142 [(parallel [(set (match_operand:XF 0 "register_operand")
22143 (unspec:XF [(match_operand:XF 1 "register_operand")]
22144 FRNDINT_ROUNDING))
22145 (clobber (reg:CC FLAGS_REG))])]
22146 "TARGET_USE_FANCY_MATH_387
22147 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22148
22149 (define_expand "<rounding_insn>hf2"
22150 [(parallel [(set (match_operand:HF 0 "register_operand")
22151 (unspec:HF [(match_operand:HF 1 "register_operand")]
22152 FRNDINT_ROUNDING))
22153 (clobber (reg:CC FLAGS_REG))])]
22154 "TARGET_AVX512FP16"
22155 {
22156 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22157 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22158 DONE;
22159 })
22160
22161 (define_expand "<rounding_insn><mode>2"
22162 [(parallel [(set (match_operand:MODEF 0 "register_operand")
22163 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22164 FRNDINT_ROUNDING))
22165 (clobber (reg:CC FLAGS_REG))])]
22166 "(TARGET_USE_FANCY_MATH_387
22167 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22168 || TARGET_MIX_SSE_I387)
22169 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22170 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22171 && (TARGET_SSE4_1
22172 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22173 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22174 {
22175 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22176 && (TARGET_SSE4_1
22177 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22178 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22179 {
22180 if (TARGET_SSE4_1)
22181 emit_insn (gen_sse4_1_round<mode>2
22182 (operands[0], operands[1],
22183 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22184 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22185 {
22186 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22187 ix86_expand_floorceil (operands[0], operands[1], true);
22188 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22189 ix86_expand_floorceil (operands[0], operands[1], false);
22190 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22191 ix86_expand_trunc (operands[0], operands[1]);
22192 else
22193 gcc_unreachable ();
22194 }
22195 else
22196 {
22197 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22198 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22199 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22200 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22201 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22202 ix86_expand_truncdf_32 (operands[0], operands[1]);
22203 else
22204 gcc_unreachable ();
22205 }
22206 }
22207 else
22208 {
22209 rtx op0 = gen_reg_rtx (XFmode);
22210 rtx op1 = gen_reg_rtx (XFmode);
22211
22212 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22213 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22214 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22215 }
22216 DONE;
22217 })
22218
22219 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22220 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22221 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22222 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22223 FIST_ROUNDING))
22224 (clobber (reg:CC FLAGS_REG))]
22225 "TARGET_USE_FANCY_MATH_387
22226 && flag_unsafe_math_optimizations
22227 && ix86_pre_reload_split ()"
22228 "#"
22229 "&& 1"
22230 [(const_int 0)]
22231 {
22232 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22233
22234 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22235 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22236
22237 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22238 operands[2], operands[3]));
22239 DONE;
22240 }
22241 [(set_attr "type" "fistp")
22242 (set_attr "i387_cw" "<rounding>")
22243 (set_attr "mode" "<MODE>")])
22244
22245 (define_insn "fistdi2_<rounding>"
22246 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22247 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22248 FIST_ROUNDING))
22249 (use (match_operand:HI 2 "memory_operand" "m"))
22250 (use (match_operand:HI 3 "memory_operand" "m"))
22251 (clobber (match_scratch:XF 4 "=&f"))]
22252 "TARGET_USE_FANCY_MATH_387
22253 && flag_unsafe_math_optimizations"
22254 "* return output_fix_trunc (insn, operands, false);"
22255 [(set_attr "type" "fistp")
22256 (set_attr "i387_cw" "<rounding>")
22257 (set_attr "mode" "DI")])
22258
22259 (define_insn "fist<mode>2_<rounding>"
22260 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22261 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22262 FIST_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_unsafe_math_optimizations"
22267 "* return output_fix_trunc (insn, operands, false);"
22268 [(set_attr "type" "fistp")
22269 (set_attr "i387_cw" "<rounding>")
22270 (set_attr "mode" "<MODE>")])
22271
22272 (define_expand "l<rounding_insn>xf<mode>2"
22273 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22274 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22275 FIST_ROUNDING))
22276 (clobber (reg:CC FLAGS_REG))])]
22277 "TARGET_USE_FANCY_MATH_387
22278 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22279 && flag_unsafe_math_optimizations")
22280
22281 (define_expand "l<rounding_insn>hf<mode>2"
22282 [(set (match_operand:SWI48 0 "nonimmediate_operand")
22283 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22284 FIST_ROUNDING))]
22285 "TARGET_AVX512FP16"
22286 {
22287 rtx tmp = gen_reg_rtx (HFmode);
22288 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22289 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22290 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22291 DONE;
22292 })
22293
22294 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22295 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22296 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22297 FIST_ROUNDING))
22298 (clobber (reg:CC FLAGS_REG))])]
22299 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22300 && (TARGET_SSE4_1 || !flag_trapping_math)"
22301 {
22302 if (TARGET_SSE4_1)
22303 {
22304 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22305
22306 emit_insn (gen_sse4_1_round<MODEF:mode>2
22307 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22308 | ROUND_NO_EXC)));
22309 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22310 (operands[0], tmp));
22311 }
22312 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22313 ix86_expand_lfloorceil (operands[0], operands[1], true);
22314 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22315 ix86_expand_lfloorceil (operands[0], operands[1], false);
22316 else
22317 gcc_unreachable ();
22318
22319 DONE;
22320 })
22321
22322 (define_insn "fxam<mode>2_i387"
22323 [(set (match_operand:HI 0 "register_operand" "=a")
22324 (unspec:HI
22325 [(match_operand:X87MODEF 1 "register_operand" "f")]
22326 UNSPEC_FXAM))]
22327 "TARGET_USE_FANCY_MATH_387"
22328 "fxam\n\tfnstsw\t%0"
22329 [(set_attr "type" "multi")
22330 (set_attr "length" "4")
22331 (set_attr "unit" "i387")
22332 (set_attr "mode" "<MODE>")])
22333
22334 (define_expand "signbittf2"
22335 [(use (match_operand:SI 0 "register_operand"))
22336 (use (match_operand:TF 1 "register_operand"))]
22337 "TARGET_SSE"
22338 {
22339 if (TARGET_SSE4_1)
22340 {
22341 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22342 rtx scratch = gen_reg_rtx (QImode);
22343
22344 emit_insn (gen_ptesttf2 (operands[1], mask));
22345 ix86_expand_setcc (scratch, NE,
22346 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22347
22348 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22349 }
22350 else
22351 {
22352 emit_insn (gen_sse_movmskps (operands[0],
22353 gen_lowpart (V4SFmode, operands[1])));
22354 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22355 }
22356 DONE;
22357 })
22358
22359 (define_expand "signbitxf2"
22360 [(use (match_operand:SI 0 "register_operand"))
22361 (use (match_operand:XF 1 "register_operand"))]
22362 "TARGET_USE_FANCY_MATH_387"
22363 {
22364 rtx scratch = gen_reg_rtx (HImode);
22365
22366 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22367 emit_insn (gen_andsi3 (operands[0],
22368 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22369 DONE;
22370 })
22371
22372 (define_insn "movmsk_df"
22373 [(set (match_operand:SI 0 "register_operand" "=r,jr")
22374 (unspec:SI
22375 [(match_operand:DF 1 "register_operand" "x,x")]
22376 UNSPEC_MOVMSK))]
22377 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22378 "%vmovmskpd\t{%1, %0|%0, %1}"
22379 [(set_attr "isa" "noavx,avx")
22380 (set_attr "type" "ssemov")
22381 (set_attr "prefix" "maybe_evex")
22382 (set_attr "mode" "DF")])
22383
22384 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22385 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22386 (define_expand "signbitdf2"
22387 [(use (match_operand:SI 0 "register_operand"))
22388 (use (match_operand:DF 1 "register_operand"))]
22389 "TARGET_USE_FANCY_MATH_387
22390 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22391 {
22392 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22393 {
22394 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22395 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22396 }
22397 else
22398 {
22399 rtx scratch = gen_reg_rtx (HImode);
22400
22401 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22402 emit_insn (gen_andsi3 (operands[0],
22403 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22404 }
22405 DONE;
22406 })
22407
22408 (define_expand "signbitsf2"
22409 [(use (match_operand:SI 0 "register_operand"))
22410 (use (match_operand:SF 1 "register_operand"))]
22411 "TARGET_USE_FANCY_MATH_387
22412 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22413 {
22414 rtx scratch = gen_reg_rtx (HImode);
22415
22416 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22417 emit_insn (gen_andsi3 (operands[0],
22418 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22419 DONE;
22420 })
22421 \f
22422 ;; Block operation instructions
22423
22424 (define_insn "cld"
22425 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22426 ""
22427 "cld"
22428 [(set_attr "length" "1")
22429 (set_attr "length_immediate" "0")
22430 (set_attr "modrm" "0")])
22431
22432 (define_expand "cpymem<mode>"
22433 [(use (match_operand:BLK 0 "memory_operand"))
22434 (use (match_operand:BLK 1 "memory_operand"))
22435 (use (match_operand:SWI48 2 "nonmemory_operand"))
22436 (use (match_operand:SWI48 3 "const_int_operand"))
22437 (use (match_operand:SI 4 "const_int_operand"))
22438 (use (match_operand:SI 5 "const_int_operand"))
22439 (use (match_operand:SI 6 ""))
22440 (use (match_operand:SI 7 ""))
22441 (use (match_operand:SI 8 ""))]
22442 ""
22443 {
22444 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22445 operands[2], NULL, operands[3],
22446 operands[4], operands[5],
22447 operands[6], operands[7],
22448 operands[8], false))
22449 DONE;
22450 else
22451 FAIL;
22452 })
22453
22454 ;; Most CPUs don't like single string operations
22455 ;; Handle this case here to simplify previous expander.
22456
22457 (define_expand "strmov"
22458 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22459 (set (match_operand 1 "memory_operand") (match_dup 4))
22460 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22461 (clobber (reg:CC FLAGS_REG))])
22462 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22463 (clobber (reg:CC FLAGS_REG))])]
22464 ""
22465 {
22466 /* Can't use this for non-default address spaces. */
22467 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22468 FAIL;
22469
22470 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22471
22472 /* If .md ever supports :P for Pmode, these can be directly
22473 in the pattern above. */
22474 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22475 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22476
22477 /* Can't use this if the user has appropriated esi or edi. */
22478 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22479 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22480 {
22481 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22482 operands[2], operands[3],
22483 operands[5], operands[6]));
22484 DONE;
22485 }
22486
22487 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22488 })
22489
22490 (define_expand "strmov_singleop"
22491 [(parallel [(set (match_operand 1 "memory_operand")
22492 (match_operand 3 "memory_operand"))
22493 (set (match_operand 0 "register_operand")
22494 (match_operand 4))
22495 (set (match_operand 2 "register_operand")
22496 (match_operand 5))])]
22497 ""
22498 {
22499 if (TARGET_CLD)
22500 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22501 })
22502
22503 (define_insn "*strmovdi_rex_1"
22504 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22505 (mem:DI (match_operand:P 3 "register_operand" "1")))
22506 (set (match_operand:P 0 "register_operand" "=D")
22507 (plus:P (match_dup 2)
22508 (const_int 8)))
22509 (set (match_operand:P 1 "register_operand" "=S")
22510 (plus:P (match_dup 3)
22511 (const_int 8)))]
22512 "TARGET_64BIT
22513 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22514 && ix86_check_no_addr_space (insn)"
22515 "%^movsq"
22516 [(set_attr "type" "str")
22517 (set_attr "memory" "both")
22518 (set_attr "mode" "DI")])
22519
22520 (define_insn "*strmovsi_1"
22521 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22522 (mem:SI (match_operand:P 3 "register_operand" "1")))
22523 (set (match_operand:P 0 "register_operand" "=D")
22524 (plus:P (match_dup 2)
22525 (const_int 4)))
22526 (set (match_operand:P 1 "register_operand" "=S")
22527 (plus:P (match_dup 3)
22528 (const_int 4)))]
22529 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22530 && ix86_check_no_addr_space (insn)"
22531 "%^movs{l|d}"
22532 [(set_attr "type" "str")
22533 (set_attr "memory" "both")
22534 (set_attr "mode" "SI")])
22535
22536 (define_insn "*strmovhi_1"
22537 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22538 (mem:HI (match_operand:P 3 "register_operand" "1")))
22539 (set (match_operand:P 0 "register_operand" "=D")
22540 (plus:P (match_dup 2)
22541 (const_int 2)))
22542 (set (match_operand:P 1 "register_operand" "=S")
22543 (plus:P (match_dup 3)
22544 (const_int 2)))]
22545 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22546 && ix86_check_no_addr_space (insn)"
22547 "%^movsw"
22548 [(set_attr "type" "str")
22549 (set_attr "memory" "both")
22550 (set_attr "mode" "HI")])
22551
22552 (define_insn "*strmovqi_1"
22553 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22554 (mem:QI (match_operand:P 3 "register_operand" "1")))
22555 (set (match_operand:P 0 "register_operand" "=D")
22556 (plus:P (match_dup 2)
22557 (const_int 1)))
22558 (set (match_operand:P 1 "register_operand" "=S")
22559 (plus:P (match_dup 3)
22560 (const_int 1)))]
22561 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22562 && ix86_check_no_addr_space (insn)"
22563 "%^movsb"
22564 [(set_attr "type" "str")
22565 (set_attr "memory" "both")
22566 (set (attr "prefix_rex")
22567 (if_then_else
22568 (match_test "<P:MODE>mode == DImode")
22569 (const_string "0")
22570 (const_string "*")))
22571 (set_attr "mode" "QI")])
22572
22573 (define_expand "rep_mov"
22574 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22575 (set (match_operand 0 "register_operand")
22576 (match_operand 5))
22577 (set (match_operand 2 "register_operand")
22578 (match_operand 6))
22579 (set (match_operand 1 "memory_operand")
22580 (match_operand 3 "memory_operand"))
22581 (use (match_dup 4))])]
22582 ""
22583 {
22584 if (TARGET_CLD)
22585 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22586 })
22587
22588 (define_insn "*rep_movdi_rex64"
22589 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22590 (set (match_operand:P 0 "register_operand" "=D")
22591 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22592 (const_int 3))
22593 (match_operand:P 3 "register_operand" "0")))
22594 (set (match_operand:P 1 "register_operand" "=S")
22595 (plus:P (ashift:P (match_dup 5) (const_int 3))
22596 (match_operand:P 4 "register_operand" "1")))
22597 (set (mem:BLK (match_dup 3))
22598 (mem:BLK (match_dup 4)))
22599 (use (match_dup 5))]
22600 "TARGET_64BIT
22601 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22602 && ix86_check_no_addr_space (insn)"
22603 "%^rep{%;} movsq"
22604 [(set_attr "type" "str")
22605 (set_attr "prefix_rep" "1")
22606 (set_attr "memory" "both")
22607 (set_attr "mode" "DI")])
22608
22609 (define_insn "*rep_movsi"
22610 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22611 (set (match_operand:P 0 "register_operand" "=D")
22612 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22613 (const_int 2))
22614 (match_operand:P 3 "register_operand" "0")))
22615 (set (match_operand:P 1 "register_operand" "=S")
22616 (plus:P (ashift:P (match_dup 5) (const_int 2))
22617 (match_operand:P 4 "register_operand" "1")))
22618 (set (mem:BLK (match_dup 3))
22619 (mem:BLK (match_dup 4)))
22620 (use (match_dup 5))]
22621 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22622 && ix86_check_no_addr_space (insn)"
22623 "%^rep{%;} movs{l|d}"
22624 [(set_attr "type" "str")
22625 (set_attr "prefix_rep" "1")
22626 (set_attr "memory" "both")
22627 (set_attr "mode" "SI")])
22628
22629 (define_insn "*rep_movqi"
22630 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22631 (set (match_operand:P 0 "register_operand" "=D")
22632 (plus:P (match_operand:P 3 "register_operand" "0")
22633 (match_operand:P 5 "register_operand" "2")))
22634 (set (match_operand:P 1 "register_operand" "=S")
22635 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22636 (set (mem:BLK (match_dup 3))
22637 (mem:BLK (match_dup 4)))
22638 (use (match_dup 5))]
22639 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22640 && ix86_check_no_addr_space (insn)"
22641 "%^rep{%;} movsb"
22642 [(set_attr "type" "str")
22643 (set_attr "prefix_rep" "1")
22644 (set_attr "memory" "both")
22645 (set_attr "mode" "QI")])
22646
22647 (define_expand "setmem<mode>"
22648 [(use (match_operand:BLK 0 "memory_operand"))
22649 (use (match_operand:SWI48 1 "nonmemory_operand"))
22650 (use (match_operand:QI 2 "nonmemory_operand"))
22651 (use (match_operand 3 "const_int_operand"))
22652 (use (match_operand:SI 4 "const_int_operand"))
22653 (use (match_operand:SI 5 "const_int_operand"))
22654 (use (match_operand:SI 6 ""))
22655 (use (match_operand:SI 7 ""))
22656 (use (match_operand:SI 8 ""))]
22657 ""
22658 {
22659 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22660 operands[1], operands[2],
22661 operands[3], operands[4],
22662 operands[5], operands[6],
22663 operands[7], operands[8], true))
22664 DONE;
22665 else
22666 FAIL;
22667 })
22668
22669 ;; Most CPUs don't like single string operations
22670 ;; Handle this case here to simplify previous expander.
22671
22672 (define_expand "strset"
22673 [(set (match_operand 1 "memory_operand")
22674 (match_operand 2 "register_operand"))
22675 (parallel [(set (match_operand 0 "register_operand")
22676 (match_dup 3))
22677 (clobber (reg:CC FLAGS_REG))])]
22678 ""
22679 {
22680 /* Can't use this for non-default address spaces. */
22681 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22682 FAIL;
22683
22684 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22685 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22686
22687 /* If .md ever supports :P for Pmode, this can be directly
22688 in the pattern above. */
22689 operands[3] = plus_constant (Pmode, operands[0],
22690 GET_MODE_SIZE (GET_MODE (operands[2])));
22691
22692 /* Can't use this if the user has appropriated eax or edi. */
22693 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22694 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22695 {
22696 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22697 operands[3]));
22698 DONE;
22699 }
22700 })
22701
22702 (define_expand "strset_singleop"
22703 [(parallel [(set (match_operand 1 "memory_operand")
22704 (match_operand 2 "register_operand"))
22705 (set (match_operand 0 "register_operand")
22706 (match_operand 3))
22707 (unspec [(const_int 0)] UNSPEC_STOS)])]
22708 ""
22709 {
22710 if (TARGET_CLD)
22711 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22712 })
22713
22714 (define_insn "*strsetdi_rex_1"
22715 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22716 (match_operand:DI 2 "register_operand" "a"))
22717 (set (match_operand:P 0 "register_operand" "=D")
22718 (plus:P (match_dup 1)
22719 (const_int 8)))
22720 (unspec [(const_int 0)] UNSPEC_STOS)]
22721 "TARGET_64BIT
22722 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22723 && ix86_check_no_addr_space (insn)"
22724 "%^stosq"
22725 [(set_attr "type" "str")
22726 (set_attr "memory" "store")
22727 (set_attr "mode" "DI")])
22728
22729 (define_insn "*strsetsi_1"
22730 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22731 (match_operand:SI 2 "register_operand" "a"))
22732 (set (match_operand:P 0 "register_operand" "=D")
22733 (plus:P (match_dup 1)
22734 (const_int 4)))
22735 (unspec [(const_int 0)] UNSPEC_STOS)]
22736 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22737 && ix86_check_no_addr_space (insn)"
22738 "%^stos{l|d}"
22739 [(set_attr "type" "str")
22740 (set_attr "memory" "store")
22741 (set_attr "mode" "SI")])
22742
22743 (define_insn "*strsethi_1"
22744 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22745 (match_operand:HI 2 "register_operand" "a"))
22746 (set (match_operand:P 0 "register_operand" "=D")
22747 (plus:P (match_dup 1)
22748 (const_int 2)))
22749 (unspec [(const_int 0)] UNSPEC_STOS)]
22750 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22751 && ix86_check_no_addr_space (insn)"
22752 "%^stosw"
22753 [(set_attr "type" "str")
22754 (set_attr "memory" "store")
22755 (set_attr "mode" "HI")])
22756
22757 (define_insn "*strsetqi_1"
22758 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22759 (match_operand:QI 2 "register_operand" "a"))
22760 (set (match_operand:P 0 "register_operand" "=D")
22761 (plus:P (match_dup 1)
22762 (const_int 1)))
22763 (unspec [(const_int 0)] UNSPEC_STOS)]
22764 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22765 && ix86_check_no_addr_space (insn)"
22766 "%^stosb"
22767 [(set_attr "type" "str")
22768 (set_attr "memory" "store")
22769 (set (attr "prefix_rex")
22770 (if_then_else
22771 (match_test "<P:MODE>mode == DImode")
22772 (const_string "0")
22773 (const_string "*")))
22774 (set_attr "mode" "QI")])
22775
22776 (define_expand "rep_stos"
22777 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22778 (set (match_operand 0 "register_operand")
22779 (match_operand 4))
22780 (set (match_operand 2 "memory_operand") (const_int 0))
22781 (use (match_operand 3 "register_operand"))
22782 (use (match_dup 1))])]
22783 ""
22784 {
22785 if (TARGET_CLD)
22786 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22787 })
22788
22789 (define_insn "*rep_stosdi_rex64"
22790 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22791 (set (match_operand:P 0 "register_operand" "=D")
22792 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22793 (const_int 3))
22794 (match_operand:P 3 "register_operand" "0")))
22795 (set (mem:BLK (match_dup 3))
22796 (const_int 0))
22797 (use (match_operand:DI 2 "register_operand" "a"))
22798 (use (match_dup 4))]
22799 "TARGET_64BIT
22800 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22801 && ix86_check_no_addr_space (insn)"
22802 "%^rep{%;} stosq"
22803 [(set_attr "type" "str")
22804 (set_attr "prefix_rep" "1")
22805 (set_attr "memory" "store")
22806 (set_attr "mode" "DI")])
22807
22808 (define_insn "*rep_stossi"
22809 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22810 (set (match_operand:P 0 "register_operand" "=D")
22811 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22812 (const_int 2))
22813 (match_operand:P 3 "register_operand" "0")))
22814 (set (mem:BLK (match_dup 3))
22815 (const_int 0))
22816 (use (match_operand:SI 2 "register_operand" "a"))
22817 (use (match_dup 4))]
22818 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22819 && ix86_check_no_addr_space (insn)"
22820 "%^rep{%;} stos{l|d}"
22821 [(set_attr "type" "str")
22822 (set_attr "prefix_rep" "1")
22823 (set_attr "memory" "store")
22824 (set_attr "mode" "SI")])
22825
22826 (define_insn "*rep_stosqi"
22827 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22828 (set (match_operand:P 0 "register_operand" "=D")
22829 (plus:P (match_operand:P 3 "register_operand" "0")
22830 (match_operand:P 4 "register_operand" "1")))
22831 (set (mem:BLK (match_dup 3))
22832 (const_int 0))
22833 (use (match_operand:QI 2 "register_operand" "a"))
22834 (use (match_dup 4))]
22835 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22836 && ix86_check_no_addr_space (insn)"
22837 "%^rep{%;} stosb"
22838 [(set_attr "type" "str")
22839 (set_attr "prefix_rep" "1")
22840 (set_attr "memory" "store")
22841 (set (attr "prefix_rex")
22842 (if_then_else
22843 (match_test "<P:MODE>mode == DImode")
22844 (const_string "0")
22845 (const_string "*")))
22846 (set_attr "mode" "QI")])
22847
22848 (define_expand "cmpmemsi"
22849 [(set (match_operand:SI 0 "register_operand" "")
22850 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22851 (match_operand:BLK 2 "memory_operand" "") ) )
22852 (use (match_operand 3 "general_operand"))
22853 (use (match_operand 4 "immediate_operand"))]
22854 ""
22855 {
22856 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22857 operands[2], operands[3],
22858 operands[4], false))
22859 DONE;
22860 else
22861 FAIL;
22862 })
22863
22864 (define_expand "cmpstrnsi"
22865 [(set (match_operand:SI 0 "register_operand")
22866 (compare:SI (match_operand:BLK 1 "general_operand")
22867 (match_operand:BLK 2 "general_operand")))
22868 (use (match_operand 3 "general_operand"))
22869 (use (match_operand 4 "immediate_operand"))]
22870 ""
22871 {
22872 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22873 operands[2], operands[3],
22874 operands[4], true))
22875 DONE;
22876 else
22877 FAIL;
22878 })
22879
22880 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22881
22882 (define_expand "cmpintqi"
22883 [(set (match_dup 1)
22884 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22885 (set (match_dup 2)
22886 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22887 (parallel [(set (match_operand:QI 0 "register_operand")
22888 (minus:QI (match_dup 1)
22889 (match_dup 2)))
22890 (clobber (reg:CC FLAGS_REG))])]
22891 ""
22892 {
22893 operands[1] = gen_reg_rtx (QImode);
22894 operands[2] = gen_reg_rtx (QImode);
22895 })
22896
22897 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22898 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22899
22900 (define_expand "cmpstrnqi_nz_1"
22901 [(parallel [(set (reg:CC FLAGS_REG)
22902 (compare:CC (match_operand 4 "memory_operand")
22903 (match_operand 5 "memory_operand")))
22904 (use (match_operand 2 "register_operand"))
22905 (use (match_operand:SI 3 "immediate_operand"))
22906 (clobber (match_operand 0 "register_operand"))
22907 (clobber (match_operand 1 "register_operand"))
22908 (clobber (match_dup 2))])]
22909 ""
22910 {
22911 if (TARGET_CLD)
22912 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22913 })
22914
22915 (define_insn "*cmpstrnqi_nz_1"
22916 [(set (reg:CC FLAGS_REG)
22917 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22918 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22919 (use (match_operand:P 6 "register_operand" "2"))
22920 (use (match_operand:SI 3 "immediate_operand" "i"))
22921 (clobber (match_operand:P 0 "register_operand" "=S"))
22922 (clobber (match_operand:P 1 "register_operand" "=D"))
22923 (clobber (match_operand:P 2 "register_operand" "=c"))]
22924 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22925 && ix86_check_no_addr_space (insn)"
22926 "%^repz{%;} cmpsb"
22927 [(set_attr "type" "str")
22928 (set_attr "mode" "QI")
22929 (set (attr "prefix_rex")
22930 (if_then_else
22931 (match_test "<P:MODE>mode == DImode")
22932 (const_string "0")
22933 (const_string "*")))
22934 (set_attr "prefix_rep" "1")])
22935
22936 ;; The same, but the count is not known to not be zero.
22937
22938 (define_expand "cmpstrnqi_1"
22939 [(parallel [(set (reg:CC FLAGS_REG)
22940 (if_then_else:CC (ne (match_operand 2 "register_operand")
22941 (const_int 0))
22942 (compare:CC (match_operand 4 "memory_operand")
22943 (match_operand 5 "memory_operand"))
22944 (const_int 0)))
22945 (use (match_operand:SI 3 "immediate_operand"))
22946 (use (reg:CC FLAGS_REG))
22947 (clobber (match_operand 0 "register_operand"))
22948 (clobber (match_operand 1 "register_operand"))
22949 (clobber (match_dup 2))])]
22950 ""
22951 {
22952 if (TARGET_CLD)
22953 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22954 })
22955
22956 (define_insn "*cmpstrnqi_1"
22957 [(set (reg:CC FLAGS_REG)
22958 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22959 (const_int 0))
22960 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22961 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22962 (const_int 0)))
22963 (use (match_operand:SI 3 "immediate_operand" "i"))
22964 (use (reg:CC FLAGS_REG))
22965 (clobber (match_operand:P 0 "register_operand" "=S"))
22966 (clobber (match_operand:P 1 "register_operand" "=D"))
22967 (clobber (match_operand:P 2 "register_operand" "=c"))]
22968 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22969 && ix86_check_no_addr_space (insn)"
22970 "%^repz{%;} cmpsb"
22971 [(set_attr "type" "str")
22972 (set_attr "mode" "QI")
22973 (set (attr "prefix_rex")
22974 (if_then_else
22975 (match_test "<P:MODE>mode == DImode")
22976 (const_string "0")
22977 (const_string "*")))
22978 (set_attr "prefix_rep" "1")])
22979
22980 (define_expand "strlen<mode>"
22981 [(set (match_operand:P 0 "register_operand")
22982 (unspec:P [(match_operand:BLK 1 "general_operand")
22983 (match_operand:QI 2 "immediate_operand")
22984 (match_operand 3 "immediate_operand")]
22985 UNSPEC_SCAS))]
22986 ""
22987 {
22988 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22989 DONE;
22990 else
22991 FAIL;
22992 })
22993
22994 (define_expand "strlenqi_1"
22995 [(parallel [(set (match_operand 0 "register_operand")
22996 (match_operand 2))
22997 (clobber (match_operand 1 "register_operand"))
22998 (clobber (reg:CC FLAGS_REG))])]
22999 ""
23000 {
23001 if (TARGET_CLD)
23002 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23003 })
23004
23005 (define_insn "*strlenqi_1"
23006 [(set (match_operand:P 0 "register_operand" "=&c")
23007 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
23008 (match_operand:QI 2 "register_operand" "a")
23009 (match_operand:P 3 "immediate_operand" "i")
23010 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
23011 (clobber (match_operand:P 1 "register_operand" "=D"))
23012 (clobber (reg:CC FLAGS_REG))]
23013 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23014 && ix86_check_no_addr_space (insn)"
23015 "%^repnz{%;} scasb"
23016 [(set_attr "type" "str")
23017 (set_attr "mode" "QI")
23018 (set (attr "prefix_rex")
23019 (if_then_else
23020 (match_test "<P:MODE>mode == DImode")
23021 (const_string "0")
23022 (const_string "*")))
23023 (set_attr "prefix_rep" "1")])
23024
23025 ;; Peephole optimizations to clean up after cmpstrn*. This should be
23026 ;; handled in combine, but it is not currently up to the task.
23027 ;; When used for their truth value, the cmpstrn* expanders generate
23028 ;; code like this:
23029 ;;
23030 ;; repz cmpsb
23031 ;; seta %al
23032 ;; setb %dl
23033 ;; cmpb %al, %dl
23034 ;; jcc label
23035 ;;
23036 ;; The intermediate three instructions are unnecessary.
23037
23038 ;; This one handles cmpstrn*_nz_1...
23039 (define_peephole2
23040 [(parallel[
23041 (set (reg:CC FLAGS_REG)
23042 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23043 (mem:BLK (match_operand 5 "register_operand"))))
23044 (use (match_operand 6 "register_operand"))
23045 (use (match_operand:SI 3 "immediate_operand"))
23046 (clobber (match_operand 0 "register_operand"))
23047 (clobber (match_operand 1 "register_operand"))
23048 (clobber (match_operand 2 "register_operand"))])
23049 (set (match_operand:QI 7 "register_operand")
23050 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23051 (set (match_operand:QI 8 "register_operand")
23052 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23053 (set (reg FLAGS_REG)
23054 (compare (match_dup 7) (match_dup 8)))
23055 ]
23056 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23057 [(parallel[
23058 (set (reg:CC FLAGS_REG)
23059 (compare:CC (mem:BLK (match_dup 4))
23060 (mem:BLK (match_dup 5))))
23061 (use (match_dup 6))
23062 (use (match_dup 3))
23063 (clobber (match_dup 0))
23064 (clobber (match_dup 1))
23065 (clobber (match_dup 2))])])
23066
23067 ;; ...and this one handles cmpstrn*_1.
23068 (define_peephole2
23069 [(parallel[
23070 (set (reg:CC FLAGS_REG)
23071 (if_then_else:CC (ne (match_operand 6 "register_operand")
23072 (const_int 0))
23073 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23074 (mem:BLK (match_operand 5 "register_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_operand 2 "register_operand"))])
23081 (set (match_operand:QI 7 "register_operand")
23082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23083 (set (match_operand:QI 8 "register_operand")
23084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23085 (set (reg FLAGS_REG)
23086 (compare (match_dup 7) (match_dup 8)))
23087 ]
23088 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23089 [(parallel[
23090 (set (reg:CC FLAGS_REG)
23091 (if_then_else:CC (ne (match_dup 6)
23092 (const_int 0))
23093 (compare:CC (mem:BLK (match_dup 4))
23094 (mem:BLK (match_dup 5)))
23095 (const_int 0)))
23096 (use (match_dup 3))
23097 (use (reg:CC FLAGS_REG))
23098 (clobber (match_dup 0))
23099 (clobber (match_dup 1))
23100 (clobber (match_dup 2))])])
23101 \f
23102 ;; Conditional move instructions.
23103
23104 (define_expand "mov<mode>cc"
23105 [(set (match_operand:SWIM 0 "register_operand")
23106 (if_then_else:SWIM (match_operand 1 "comparison_operator")
23107 (match_operand:SWIM 2 "<general_operand>")
23108 (match_operand:SWIM 3 "<general_operand>")))]
23109 ""
23110 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23111
23112 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23113 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23114 ;; So just document what we're doing explicitly.
23115
23116 (define_expand "x86_mov<mode>cc_0_m1"
23117 [(parallel
23118 [(set (match_operand:SWI48 0 "register_operand")
23119 (if_then_else:SWI48
23120 (match_operator:SWI48 2 "ix86_carry_flag_operator"
23121 [(match_operand 1 "flags_reg_operand")
23122 (const_int 0)])
23123 (const_int -1)
23124 (const_int 0)))
23125 (clobber (reg:CC FLAGS_REG))])])
23126
23127 (define_insn "*x86_mov<mode>cc_0_m1"
23128 [(set (match_operand:SWI48 0 "register_operand" "=r")
23129 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23130 [(reg FLAGS_REG) (const_int 0)])
23131 (const_int -1)
23132 (const_int 0)))
23133 (clobber (reg:CC FLAGS_REG))]
23134 ""
23135 "sbb{<imodesuffix>}\t%0, %0"
23136 [(set_attr "type" "alu1")
23137 (set_attr "use_carry" "1")
23138 (set_attr "pent_pair" "pu")
23139 (set_attr "mode" "<MODE>")
23140 (set_attr "length_immediate" "0")])
23141
23142 (define_insn "*x86_mov<mode>cc_0_m1_se"
23143 [(set (match_operand:SWI48 0 "register_operand" "=r")
23144 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23145 [(reg FLAGS_REG) (const_int 0)])
23146 (const_int 1)
23147 (const_int 0)))
23148 (clobber (reg:CC FLAGS_REG))]
23149 ""
23150 "sbb{<imodesuffix>}\t%0, %0"
23151 [(set_attr "type" "alu1")
23152 (set_attr "use_carry" "1")
23153 (set_attr "pent_pair" "pu")
23154 (set_attr "mode" "<MODE>")
23155 (set_attr "length_immediate" "0")])
23156
23157 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23158 [(set (match_operand:SWI 0 "register_operand" "=<r>")
23159 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23160 [(reg FLAGS_REG) (const_int 0)])))
23161 (clobber (reg:CC FLAGS_REG))]
23162 ""
23163 "sbb{<imodesuffix>}\t%0, %0"
23164 [(set_attr "type" "alu1")
23165 (set_attr "use_carry" "1")
23166 (set_attr "pent_pair" "pu")
23167 (set_attr "mode" "<MODE>")
23168 (set_attr "length_immediate" "0")])
23169
23170 (define_expand "x86_mov<mode>cc_0_m1_neg"
23171 [(parallel
23172 [(set (match_operand:SWI48 0 "register_operand")
23173 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23174 (clobber (reg:CC FLAGS_REG))])])
23175
23176 (define_split
23177 [(set (match_operand:SWI48 0 "register_operand")
23178 (neg:SWI48
23179 (leu:SWI48
23180 (match_operand 1 "int_nonimmediate_operand")
23181 (match_operand 2 "const_int_operand"))))]
23182 "x86_64_immediate_operand (operands[2], VOIDmode)
23183 && INTVAL (operands[2]) != -1
23184 && INTVAL (operands[2]) != 2147483647"
23185 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23186 (set (match_dup 0)
23187 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23188 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23189
23190 (define_split
23191 [(set (match_operand:SWI 0 "register_operand")
23192 (neg:SWI
23193 (eq:SWI
23194 (match_operand 1 "int_nonimmediate_operand")
23195 (const_int 0))))]
23196 ""
23197 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23198 (set (match_dup 0)
23199 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23200
23201 (define_split
23202 [(set (match_operand:SWI 0 "register_operand")
23203 (neg:SWI
23204 (ne:SWI
23205 (match_operand 1 "int_nonimmediate_operand")
23206 (const_int 0))))]
23207 ""
23208 [(set (reg:CCC FLAGS_REG)
23209 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23210 (set (match_dup 0)
23211 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23212
23213 (define_insn "*mov<mode>cc_noc"
23214 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23215 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23216 [(reg FLAGS_REG) (const_int 0)])
23217 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23218 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23219 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23220 "@
23221 cmov%O2%C1\t{%2, %0|%0, %2}
23222 cmov%O2%c1\t{%3, %0|%0, %3}"
23223 [(set_attr "type" "icmov")
23224 (set_attr "mode" "<MODE>")])
23225
23226 (define_insn "*movsicc_noc_zext"
23227 [(set (match_operand:DI 0 "register_operand" "=r,r")
23228 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23229 [(reg FLAGS_REG) (const_int 0)])
23230 (zero_extend:DI
23231 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23232 (zero_extend:DI
23233 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23234 "TARGET_64BIT
23235 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23236 "@
23237 cmov%O2%C1\t{%2, %k0|%k0, %2}
23238 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23239 [(set_attr "type" "icmov")
23240 (set_attr "mode" "SI")])
23241
23242 (define_insn "*movsicc_noc_zext_1"
23243 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23244 (zero_extend:DI
23245 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23246 [(reg FLAGS_REG) (const_int 0)])
23247 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23248 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23249 "TARGET_64BIT
23250 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23251 "@
23252 cmov%O2%C1\t{%2, %k0|%k0, %2}
23253 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23254 [(set_attr "type" "icmov")
23255 (set_attr "mode" "SI")])
23256
23257
23258 ;; Don't do conditional moves with memory inputs. This splitter helps
23259 ;; register starved x86_32 by forcing inputs into registers before reload.
23260 (define_split
23261 [(set (match_operand:SWI248 0 "register_operand")
23262 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23263 [(reg FLAGS_REG) (const_int 0)])
23264 (match_operand:SWI248 2 "nonimmediate_operand")
23265 (match_operand:SWI248 3 "nonimmediate_operand")))]
23266 "!TARGET_64BIT && TARGET_CMOVE
23267 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23268 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23269 && can_create_pseudo_p ()
23270 && optimize_insn_for_speed_p ()"
23271 [(set (match_dup 0)
23272 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23273 {
23274 operands[2] = force_reg (<MODE>mode, operands[2]);
23275 operands[3] = force_reg (<MODE>mode, operands[3]);
23276 })
23277
23278 (define_insn "*movqicc_noc"
23279 [(set (match_operand:QI 0 "register_operand" "=r,r")
23280 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23281 [(reg FLAGS_REG) (const_int 0)])
23282 (match_operand:QI 2 "register_operand" "r,0")
23283 (match_operand:QI 3 "register_operand" "0,r")))]
23284 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23285 "#"
23286 [(set_attr "type" "icmov")
23287 (set_attr "mode" "QI")])
23288
23289 (define_split
23290 [(set (match_operand:SWI12 0 "register_operand")
23291 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23292 [(reg FLAGS_REG) (const_int 0)])
23293 (match_operand:SWI12 2 "register_operand")
23294 (match_operand:SWI12 3 "register_operand")))]
23295 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23296 && reload_completed"
23297 [(set (match_dup 0)
23298 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23299 {
23300 operands[0] = gen_lowpart (SImode, operands[0]);
23301 operands[2] = gen_lowpart (SImode, operands[2]);
23302 operands[3] = gen_lowpart (SImode, operands[3]);
23303 })
23304
23305 ;; Don't do conditional moves with memory inputs
23306 (define_peephole2
23307 [(match_scratch:SWI248 4 "r")
23308 (set (match_operand:SWI248 0 "register_operand")
23309 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23310 [(reg FLAGS_REG) (const_int 0)])
23311 (match_operand:SWI248 2 "nonimmediate_operand")
23312 (match_operand:SWI248 3 "nonimmediate_operand")))]
23313 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23314 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23315 && optimize_insn_for_speed_p ()"
23316 [(set (match_dup 4) (match_dup 5))
23317 (set (match_dup 0)
23318 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23319 {
23320 if (MEM_P (operands[2]))
23321 {
23322 operands[5] = operands[2];
23323 operands[2] = operands[4];
23324 }
23325 else if (MEM_P (operands[3]))
23326 {
23327 operands[5] = operands[3];
23328 operands[3] = operands[4];
23329 }
23330 else
23331 gcc_unreachable ();
23332 })
23333
23334 (define_peephole2
23335 [(match_scratch:SI 4 "r")
23336 (set (match_operand:DI 0 "register_operand")
23337 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23338 [(reg FLAGS_REG) (const_int 0)])
23339 (zero_extend:DI
23340 (match_operand:SI 2 "nonimmediate_operand"))
23341 (zero_extend:DI
23342 (match_operand:SI 3 "nonimmediate_operand"))))]
23343 "TARGET_64BIT
23344 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23345 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23346 && optimize_insn_for_speed_p ()"
23347 [(set (match_dup 4) (match_dup 5))
23348 (set (match_dup 0)
23349 (if_then_else:DI (match_dup 1)
23350 (zero_extend:DI (match_dup 2))
23351 (zero_extend:DI (match_dup 3))))]
23352 {
23353 if (MEM_P (operands[2]))
23354 {
23355 operands[5] = operands[2];
23356 operands[2] = operands[4];
23357 }
23358 else if (MEM_P (operands[3]))
23359 {
23360 operands[5] = operands[3];
23361 operands[3] = operands[4];
23362 }
23363 else
23364 gcc_unreachable ();
23365 })
23366
23367 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23368 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23369 (define_peephole2
23370 [(set (match_operand:SWI248 0 "general_reg_operand")
23371 (match_operand:SWI248 1 "general_reg_operand"))
23372 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23373 (set (match_dup 0) (match_operand:SWI248 6))])
23374 (set (match_operand:SWI248 2 "general_reg_operand")
23375 (match_operand:SWI248 3 "general_gr_operand"))
23376 (set (match_dup 0)
23377 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23378 [(reg FLAGS_REG) (const_int 0)])
23379 (match_dup 0)
23380 (match_dup 2)))]
23381 "TARGET_CMOVE
23382 && REGNO (operands[2]) != REGNO (operands[0])
23383 && REGNO (operands[2]) != REGNO (operands[1])
23384 && peep2_reg_dead_p (1, operands[1])
23385 && peep2_reg_dead_p (4, operands[2])
23386 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23387 [(parallel [(set (match_dup 7) (match_dup 8))
23388 (set (match_dup 1) (match_dup 9))])
23389 (set (match_dup 0) (match_dup 3))
23390 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23391 (match_dup 1)
23392 (match_dup 0)))]
23393 {
23394 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23395 operands[8]
23396 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23397 operands[9]
23398 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23399 })
23400
23401 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23402 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23403 (define_peephole2
23404 [(set (match_operand:SWI248 2 "general_reg_operand")
23405 (match_operand:SWI248 3 "general_gr_operand"))
23406 (set (match_operand:SWI248 0 "general_reg_operand")
23407 (match_operand:SWI248 1 "general_reg_operand"))
23408 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23409 (set (match_dup 0) (match_operand:SWI248 6))])
23410 (set (match_dup 0)
23411 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23412 [(reg FLAGS_REG) (const_int 0)])
23413 (match_dup 0)
23414 (match_dup 2)))]
23415 "TARGET_CMOVE
23416 && REGNO (operands[2]) != REGNO (operands[0])
23417 && REGNO (operands[2]) != REGNO (operands[1])
23418 && peep2_reg_dead_p (2, operands[1])
23419 && peep2_reg_dead_p (4, operands[2])
23420 && !reg_overlap_mentioned_p (operands[0], operands[3])
23421 && !reg_mentioned_p (operands[2], operands[6])"
23422 [(parallel [(set (match_dup 7) (match_dup 8))
23423 (set (match_dup 1) (match_dup 9))])
23424 (set (match_dup 0) (match_dup 3))
23425 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23426 (match_dup 1)
23427 (match_dup 0)))]
23428 {
23429 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23430 operands[8]
23431 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23432 operands[9]
23433 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23434 })
23435
23436 (define_insn "movhf_mask"
23437 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23438 (unspec:HF
23439 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23440 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23441 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23442 UNSPEC_MOVCC_MASK))]
23443 "TARGET_AVX512FP16"
23444 "@
23445 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23446 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23447 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23448 [(set_attr "type" "ssemov")
23449 (set_attr "prefix" "evex")
23450 (set_attr "mode" "HF")])
23451
23452 (define_expand "movhfcc"
23453 [(set (match_operand:HF 0 "register_operand")
23454 (if_then_else:HF
23455 (match_operand 1 "comparison_operator")
23456 (match_operand:HF 2 "register_operand")
23457 (match_operand:HF 3 "register_operand")))]
23458 "TARGET_AVX512FP16"
23459 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23460
23461 (define_expand "mov<mode>cc"
23462 [(set (match_operand:X87MODEF 0 "register_operand")
23463 (if_then_else:X87MODEF
23464 (match_operand 1 "comparison_operator")
23465 (match_operand:X87MODEF 2 "register_operand")
23466 (match_operand:X87MODEF 3 "register_operand")))]
23467 "(TARGET_80387 && TARGET_CMOVE)
23468 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23469 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23470
23471 (define_insn "*movxfcc_1"
23472 [(set (match_operand:XF 0 "register_operand" "=f,f")
23473 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23474 [(reg FLAGS_REG) (const_int 0)])
23475 (match_operand:XF 2 "register_operand" "f,0")
23476 (match_operand:XF 3 "register_operand" "0,f")))]
23477 "TARGET_80387 && TARGET_CMOVE"
23478 "@
23479 fcmov%F1\t{%2, %0|%0, %2}
23480 fcmov%f1\t{%3, %0|%0, %3}"
23481 [(set_attr "type" "fcmov")
23482 (set_attr "mode" "XF")])
23483
23484 (define_insn "*movdfcc_1"
23485 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23486 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23487 [(reg FLAGS_REG) (const_int 0)])
23488 (match_operand:DF 2 "nonimmediate_operand"
23489 "f ,0,rm,0 ,rm,0")
23490 (match_operand:DF 3 "nonimmediate_operand"
23491 "0 ,f,0 ,rm,0, rm")))]
23492 "TARGET_80387 && TARGET_CMOVE
23493 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23494 "@
23495 fcmov%F1\t{%2, %0|%0, %2}
23496 fcmov%f1\t{%3, %0|%0, %3}
23497 #
23498 #
23499 cmov%O2%C1\t{%2, %0|%0, %2}
23500 cmov%O2%c1\t{%3, %0|%0, %3}"
23501 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23502 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23503 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23504
23505 (define_split
23506 [(set (match_operand:DF 0 "general_reg_operand")
23507 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23508 [(reg FLAGS_REG) (const_int 0)])
23509 (match_operand:DF 2 "nonimmediate_operand")
23510 (match_operand:DF 3 "nonimmediate_operand")))]
23511 "!TARGET_64BIT && reload_completed"
23512 [(set (match_dup 2)
23513 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23514 (set (match_dup 3)
23515 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23516 {
23517 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23518 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23519 })
23520
23521 (define_insn "*movsfcc_1_387"
23522 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23523 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23524 [(reg FLAGS_REG) (const_int 0)])
23525 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23526 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23527 "TARGET_80387 && TARGET_CMOVE
23528 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23529 "@
23530 fcmov%F1\t{%2, %0|%0, %2}
23531 fcmov%f1\t{%3, %0|%0, %3}
23532 cmov%O2%C1\t{%2, %0|%0, %2}
23533 cmov%O2%c1\t{%3, %0|%0, %3}"
23534 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23535 (set_attr "mode" "SF,SF,SI,SI")])
23536
23537 ;; Don't do conditional moves with memory inputs. This splitter helps
23538 ;; register starved x86_32 by forcing inputs into registers before reload.
23539 (define_split
23540 [(set (match_operand:MODEF 0 "register_operand")
23541 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23542 [(reg FLAGS_REG) (const_int 0)])
23543 (match_operand:MODEF 2 "nonimmediate_operand")
23544 (match_operand:MODEF 3 "nonimmediate_operand")))]
23545 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23546 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23547 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23548 && can_create_pseudo_p ()
23549 && optimize_insn_for_speed_p ()"
23550 [(set (match_dup 0)
23551 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23552 {
23553 operands[2] = force_reg (<MODE>mode, operands[2]);
23554 operands[3] = force_reg (<MODE>mode, operands[3]);
23555 })
23556
23557 ;; Don't do conditional moves with memory inputs
23558 (define_peephole2
23559 [(match_scratch:MODEF 4 "r")
23560 (set (match_operand:MODEF 0 "general_reg_operand")
23561 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23562 [(reg FLAGS_REG) (const_int 0)])
23563 (match_operand:MODEF 2 "nonimmediate_operand")
23564 (match_operand:MODEF 3 "nonimmediate_operand")))]
23565 "(<MODE>mode != DFmode || TARGET_64BIT)
23566 && TARGET_80387 && TARGET_CMOVE
23567 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23568 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23569 && optimize_insn_for_speed_p ()"
23570 [(set (match_dup 4) (match_dup 5))
23571 (set (match_dup 0)
23572 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23573 {
23574 if (MEM_P (operands[2]))
23575 {
23576 operands[5] = operands[2];
23577 operands[2] = operands[4];
23578 }
23579 else if (MEM_P (operands[3]))
23580 {
23581 operands[5] = operands[3];
23582 operands[3] = operands[4];
23583 }
23584 else
23585 gcc_unreachable ();
23586 })
23587
23588 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23589 ;; the scalar versions to have only XMM registers as operands.
23590
23591 ;; XOP conditional move
23592 (define_insn "*xop_pcmov_<mode>"
23593 [(set (match_operand:MODEF 0 "register_operand" "=x")
23594 (if_then_else:MODEF
23595 (match_operand:MODEF 1 "register_operand" "x")
23596 (match_operand:MODEF 2 "register_operand" "x")
23597 (match_operand:MODEF 3 "register_operand" "x")))]
23598 "TARGET_XOP"
23599 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23600 [(set_attr "type" "sse4arg")
23601 (set_attr "mode" "TI")])
23602
23603 ;; These versions of the min/max patterns are intentionally ignorant of
23604 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23605 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23606 ;; are undefined in this condition, we're certain this is correct.
23607
23608 (define_insn "<code><mode>3"
23609 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23610 (smaxmin:MODEF
23611 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23612 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23613 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23614 "@
23615 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23616 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23617 [(set_attr "isa" "noavx,avx")
23618 (set_attr "prefix" "orig,vex")
23619 (set_attr "type" "sseadd")
23620 (set_attr "mode" "<MODE>")])
23621
23622 (define_insn "<code>hf3"
23623 [(set (match_operand:HF 0 "register_operand" "=v")
23624 (smaxmin:HF
23625 (match_operand:HF 1 "nonimmediate_operand" "%v")
23626 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23627 "TARGET_AVX512FP16"
23628 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23629 [(set_attr "prefix" "evex")
23630 (set_attr "type" "sseadd")
23631 (set_attr "mode" "HF")])
23632
23633 ;; These versions of the min/max patterns implement exactly the operations
23634 ;; min = (op1 < op2 ? op1 : op2)
23635 ;; max = (!(op1 < op2) ? op1 : op2)
23636 ;; Their operands are not commutative, and thus they may be used in the
23637 ;; presence of -0.0 and NaN.
23638
23639 (define_insn "*ieee_s<ieee_maxmin>hf3"
23640 [(set (match_operand:HF 0 "register_operand" "=v")
23641 (unspec:HF
23642 [(match_operand:HF 1 "register_operand" "v")
23643 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23644 IEEE_MAXMIN))]
23645 "TARGET_AVX512FP16"
23646 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23647 [(set_attr "prefix" "evex")
23648 (set_attr "type" "sseadd")
23649 (set_attr "mode" "HF")])
23650
23651 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23652 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23653 (unspec:MODEF
23654 [(match_operand:MODEF 1 "register_operand" "0,v")
23655 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23656 IEEE_MAXMIN))]
23657 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23658 "@
23659 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23660 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23661 [(set_attr "isa" "noavx,avx")
23662 (set_attr "prefix" "orig,maybe_evex")
23663 (set_attr "type" "sseadd")
23664 (set_attr "mode" "<MODE>")])
23665
23666 ;; Operands order in min/max instruction matters for signed zero and NANs.
23667 (define_insn_and_split "*ieee_max<mode>3_1"
23668 [(set (match_operand:MODEF 0 "register_operand")
23669 (unspec:MODEF
23670 [(match_operand:MODEF 1 "register_operand")
23671 (match_operand:MODEF 2 "register_operand")
23672 (lt:MODEF
23673 (match_operand:MODEF 3 "register_operand")
23674 (match_operand:MODEF 4 "register_operand"))]
23675 UNSPEC_BLENDV))]
23676 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23677 && (rtx_equal_p (operands[1], operands[3])
23678 && rtx_equal_p (operands[2], operands[4]))
23679 && ix86_pre_reload_split ()"
23680 "#"
23681 "&& 1"
23682 [(set (match_dup 0)
23683 (unspec:MODEF
23684 [(match_dup 2)
23685 (match_dup 1)]
23686 UNSPEC_IEEE_MAX))])
23687
23688 (define_insn_and_split "*ieee_min<mode>3_1"
23689 [(set (match_operand:MODEF 0 "register_operand")
23690 (unspec:MODEF
23691 [(match_operand:MODEF 1 "register_operand")
23692 (match_operand:MODEF 2 "register_operand")
23693 (lt:MODEF
23694 (match_operand:MODEF 3 "register_operand")
23695 (match_operand:MODEF 4 "register_operand"))]
23696 UNSPEC_BLENDV))]
23697 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23698 && (rtx_equal_p (operands[1], operands[4])
23699 && rtx_equal_p (operands[2], operands[3]))
23700 && ix86_pre_reload_split ()"
23701 "#"
23702 "&& 1"
23703 [(set (match_dup 0)
23704 (unspec:MODEF
23705 [(match_dup 2)
23706 (match_dup 1)]
23707 UNSPEC_IEEE_MIN))])
23708
23709 ;; Make two stack loads independent:
23710 ;; fld aa fld aa
23711 ;; fld %st(0) -> fld bb
23712 ;; fmul bb fmul %st(1), %st
23713 ;;
23714 ;; Actually we only match the last two instructions for simplicity.
23715
23716 (define_peephole2
23717 [(set (match_operand 0 "fp_register_operand")
23718 (match_operand 1 "fp_register_operand"))
23719 (set (match_dup 0)
23720 (match_operator 2 "binary_fp_operator"
23721 [(match_dup 0)
23722 (match_operand 3 "memory_operand")]))]
23723 "REGNO (operands[0]) != REGNO (operands[1])"
23724 [(set (match_dup 0) (match_dup 3))
23725 (set (match_dup 0)
23726 (match_op_dup 2
23727 [(match_dup 5) (match_dup 4)]))]
23728 {
23729 operands[4] = operands[0];
23730 operands[5] = operands[1];
23731
23732 /* The % modifier is not operational anymore in peephole2's, so we have to
23733 swap the operands manually in the case of addition and multiplication. */
23734 if (COMMUTATIVE_ARITH_P (operands[2]))
23735 std::swap (operands[4], operands[5]);
23736 })
23737
23738 (define_peephole2
23739 [(set (match_operand 0 "fp_register_operand")
23740 (match_operand 1 "fp_register_operand"))
23741 (set (match_dup 0)
23742 (match_operator 2 "binary_fp_operator"
23743 [(match_operand 3 "memory_operand")
23744 (match_dup 0)]))]
23745 "REGNO (operands[0]) != REGNO (operands[1])"
23746 [(set (match_dup 0) (match_dup 3))
23747 (set (match_dup 0)
23748 (match_op_dup 2
23749 [(match_dup 4) (match_dup 5)]))]
23750 {
23751 operands[4] = operands[0];
23752 operands[5] = operands[1];
23753
23754 /* The % modifier is not operational anymore in peephole2's, so we have to
23755 swap the operands manually in the case of addition and multiplication. */
23756 if (COMMUTATIVE_ARITH_P (operands[2]))
23757 std::swap (operands[4], operands[5]);
23758 })
23759
23760 ;; Conditional addition patterns
23761 (define_expand "add<mode>cc"
23762 [(match_operand:SWI 0 "register_operand")
23763 (match_operand 1 "ordered_comparison_operator")
23764 (match_operand:SWI 2 "register_operand")
23765 (match_operand:SWI 3 "const_int_operand")]
23766 ""
23767 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23768
23769 ;; min/max patterns
23770
23771 (define_code_attr maxmin_rel
23772 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23773
23774 (define_expand "<code><mode>3"
23775 [(parallel
23776 [(set (match_operand:SDWIM 0 "register_operand")
23777 (maxmin:SDWIM
23778 (match_operand:SDWIM 1 "register_operand")
23779 (match_operand:SDWIM 2 "general_operand")))
23780 (clobber (reg:CC FLAGS_REG))])]
23781 "TARGET_CMOVE
23782 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23783
23784 (define_insn_and_split "*<code><dwi>3_doubleword"
23785 [(set (match_operand:<DWI> 0 "register_operand")
23786 (maxmin:<DWI>
23787 (match_operand:<DWI> 1 "register_operand")
23788 (match_operand:<DWI> 2 "general_operand")))
23789 (clobber (reg:CC FLAGS_REG))]
23790 "TARGET_CMOVE
23791 && ix86_pre_reload_split ()"
23792 "#"
23793 "&& 1"
23794 [(set (match_dup 0)
23795 (if_then_else:DWIH (match_dup 6)
23796 (match_dup 1)
23797 (match_dup 2)))
23798 (set (match_dup 3)
23799 (if_then_else:DWIH (match_dup 6)
23800 (match_dup 4)
23801 (match_dup 5)))]
23802 {
23803 operands[2] = force_reg (<DWI>mode, operands[2]);
23804
23805 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23806
23807 rtx cmplo[2] = { operands[1], operands[2] };
23808 rtx cmphi[2] = { operands[4], operands[5] };
23809
23810 enum rtx_code code = <maxmin_rel>;
23811
23812 switch (code)
23813 {
23814 case LE: case LEU:
23815 std::swap (cmplo[0], cmplo[1]);
23816 std::swap (cmphi[0], cmphi[1]);
23817 code = swap_condition (code);
23818 /* FALLTHRU */
23819
23820 case GE: case GEU:
23821 {
23822 bool uns = (code == GEU);
23823 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23824 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23825
23826 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23827
23828 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23829 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23830
23831 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23832 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23833
23834 break;
23835 }
23836
23837 default:
23838 gcc_unreachable ();
23839 }
23840 })
23841
23842 (define_insn_and_split "*<code><mode>3_1"
23843 [(set (match_operand:SWI 0 "register_operand")
23844 (maxmin:SWI
23845 (match_operand:SWI 1 "register_operand")
23846 (match_operand:SWI 2 "general_operand")))
23847 (clobber (reg:CC FLAGS_REG))]
23848 "TARGET_CMOVE
23849 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23850 && ix86_pre_reload_split ()"
23851 "#"
23852 "&& 1"
23853 [(set (match_dup 0)
23854 (if_then_else:SWI (match_dup 3)
23855 (match_dup 1)
23856 (match_dup 2)))]
23857 {
23858 machine_mode mode = <MODE>mode;
23859 rtx cmp_op = operands[2];
23860
23861 operands[2] = force_reg (mode, cmp_op);
23862
23863 enum rtx_code code = <maxmin_rel>;
23864
23865 if (cmp_op == const1_rtx)
23866 {
23867 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23868 Convert umax (x, 1) into (x != 0 ? x : 1).
23869 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23870 cmp_op = const0_rtx;
23871 if (code == GE)
23872 code = GT;
23873 else if (code == GEU)
23874 code = NE;
23875 }
23876 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23877 else if (cmp_op == constm1_rtx && code == LE)
23878 {
23879 cmp_op = const0_rtx;
23880 code = LT;
23881 }
23882 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23883 else if (cmp_op == constm1_rtx && code == GE)
23884 cmp_op = const0_rtx;
23885 else if (cmp_op != const0_rtx)
23886 cmp_op = operands[2];
23887
23888 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23889 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23890
23891 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23892 emit_insn (gen_rtx_SET (flags, tmp));
23893
23894 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23895 })
23896
23897 ;; Avoid clearing a register between a flags setting comparison and its use,
23898 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23899 (define_peephole2
23900 [(set (reg FLAGS_REG) (match_operand 0))
23901 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23902 "peep2_regno_dead_p (0, FLAGS_REG)
23903 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23904 [(set (match_dup 2) (match_dup 0))]
23905 {
23906 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23907 ix86_expand_clear (operands[1]);
23908 })
23909
23910 ;; When optimizing for size, zeroing memory should use a register.
23911 (define_peephole2
23912 [(match_scratch:SWI48 0 "r")
23913 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23914 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23915 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23916 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23917 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23918 [(const_int 0)]
23919 {
23920 ix86_expand_clear (operands[0]);
23921 emit_move_insn (operands[1], operands[0]);
23922 emit_move_insn (operands[2], operands[0]);
23923 emit_move_insn (operands[3], operands[0]);
23924 ix86_last_zero_store_uid
23925 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23926 DONE;
23927 })
23928
23929 (define_peephole2
23930 [(match_scratch:SWI48 0 "r")
23931 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23932 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23933 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23934 [(const_int 0)]
23935 {
23936 ix86_expand_clear (operands[0]);
23937 emit_move_insn (operands[1], operands[0]);
23938 ix86_last_zero_store_uid
23939 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23940 DONE;
23941 })
23942
23943 (define_peephole2
23944 [(match_scratch:SWI48 0 "r")
23945 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23946 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23947 [(const_int 0)]
23948 {
23949 ix86_expand_clear (operands[0]);
23950 ix86_last_zero_store_uid
23951 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23952 DONE;
23953 })
23954
23955 (define_peephole2
23956 [(set (match_operand:SWI48 5 "memory_operand")
23957 (match_operand:SWI48 0 "general_reg_operand"))
23958 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23959 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23960 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23961 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23962 "optimize_insn_for_size_p ()
23963 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23964 [(const_int 0)]
23965 {
23966 emit_move_insn (operands[5], operands[0]);
23967 emit_move_insn (operands[1], operands[0]);
23968 emit_move_insn (operands[2], operands[0]);
23969 emit_move_insn (operands[3], operands[0]);
23970 ix86_last_zero_store_uid
23971 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23972 DONE;
23973 })
23974
23975 (define_peephole2
23976 [(set (match_operand:SWI48 3 "memory_operand")
23977 (match_operand:SWI48 0 "general_reg_operand"))
23978 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23979 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23980 "optimize_insn_for_size_p ()
23981 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23982 [(const_int 0)]
23983 {
23984 emit_move_insn (operands[3], operands[0]);
23985 emit_move_insn (operands[1], operands[0]);
23986 ix86_last_zero_store_uid
23987 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23988 DONE;
23989 })
23990
23991 (define_peephole2
23992 [(set (match_operand:SWI48 2 "memory_operand")
23993 (match_operand:SWI48 0 "general_reg_operand"))
23994 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23995 "optimize_insn_for_size_p ()
23996 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23997 [(const_int 0)]
23998 {
23999 emit_move_insn (operands[2], operands[0]);
24000 ix86_last_zero_store_uid
24001 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24002 DONE;
24003 })
24004
24005 ;; Reload dislikes loading constants directly into class_likely_spilled
24006 ;; hard registers. Try to tidy things up here.
24007 (define_peephole2
24008 [(set (match_operand:SWI 0 "general_reg_operand")
24009 (match_operand:SWI 1 "x86_64_general_operand"))
24010 (set (match_operand:SWI 2 "general_reg_operand")
24011 (match_dup 0))]
24012 "peep2_reg_dead_p (2, operands[0])"
24013 [(set (match_dup 2) (match_dup 1))])
24014 \f
24015 ;; Misc patterns (?)
24016
24017 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
24018 ;; Otherwise there will be nothing to keep
24019 ;;
24020 ;; [(set (reg ebp) (reg esp))]
24021 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
24022 ;; (clobber (eflags)]
24023 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
24024 ;;
24025 ;; in proper program order.
24026
24027 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
24028 [(set (match_operand:P 0 "register_operand" "=r,r")
24029 (plus:P (match_operand:P 1 "register_operand" "0,r")
24030 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
24031 (clobber (reg:CC FLAGS_REG))
24032 (clobber (mem:BLK (scratch)))]
24033 ""
24034 {
24035 switch (get_attr_type (insn))
24036 {
24037 case TYPE_IMOV:
24038 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
24039
24040 case TYPE_ALU:
24041 gcc_assert (rtx_equal_p (operands[0], operands[1]));
24042 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
24043 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
24044
24045 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
24046
24047 default:
24048 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
24049 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
24050 }
24051 }
24052 [(set (attr "type")
24053 (cond [(and (eq_attr "alternative" "0")
24054 (not (match_test "TARGET_OPT_AGU")))
24055 (const_string "alu")
24056 (match_operand:<MODE> 2 "const0_operand")
24057 (const_string "imov")
24058 ]
24059 (const_string "lea")))
24060 (set (attr "length_immediate")
24061 (cond [(eq_attr "type" "imov")
24062 (const_string "0")
24063 (and (eq_attr "type" "alu")
24064 (match_operand 2 "const128_operand"))
24065 (const_string "1")
24066 ]
24067 (const_string "*")))
24068 (set_attr "mode" "<MODE>")])
24069
24070 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
24071 [(set (match_operand:P 0 "register_operand" "=r")
24072 (minus:P (match_operand:P 1 "register_operand" "0")
24073 (match_operand:P 2 "register_operand" "r")))
24074 (clobber (reg:CC FLAGS_REG))
24075 (clobber (mem:BLK (scratch)))]
24076 ""
24077 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
24078 [(set_attr "type" "alu")
24079 (set_attr "mode" "<MODE>")])
24080
24081 (define_insn "@allocate_stack_worker_probe_<mode>"
24082 [(set (match_operand:P 0 "register_operand" "=a")
24083 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24084 UNSPECV_STACK_PROBE))
24085 (clobber (reg:CC FLAGS_REG))]
24086 "ix86_target_stack_probe ()"
24087 "call\t___chkstk_ms"
24088 [(set_attr "type" "multi")
24089 (set_attr "length" "5")])
24090
24091 (define_expand "allocate_stack"
24092 [(match_operand 0 "register_operand")
24093 (match_operand 1 "general_operand")]
24094 "ix86_target_stack_probe ()"
24095 {
24096 rtx x;
24097
24098 #ifndef CHECK_STACK_LIMIT
24099 #define CHECK_STACK_LIMIT 0
24100 #endif
24101
24102 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
24103 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24104 x = operands[1];
24105 else
24106 {
24107 x = copy_to_mode_reg (Pmode, operands[1]);
24108
24109 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24110 }
24111
24112 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24113 stack_pointer_rtx, 0, OPTAB_DIRECT);
24114
24115 if (x != stack_pointer_rtx)
24116 emit_move_insn (stack_pointer_rtx, x);
24117
24118 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24119 DONE;
24120 })
24121
24122 (define_expand "probe_stack"
24123 [(match_operand 0 "memory_operand")]
24124 ""
24125 {
24126 emit_insn (gen_probe_stack_1
24127 (word_mode, operands[0], const0_rtx));
24128 DONE;
24129 })
24130
24131 ;; Use OR for stack probes, this is shorter.
24132 (define_insn "@probe_stack_1_<mode>"
24133 [(set (match_operand:W 0 "memory_operand" "=m")
24134 (unspec:W [(match_operand:W 1 "const0_operand")]
24135 UNSPEC_PROBE_STACK))
24136 (clobber (reg:CC FLAGS_REG))]
24137 ""
24138 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24139 [(set_attr "type" "alu1")
24140 (set_attr "mode" "<MODE>")
24141 (set_attr "length_immediate" "1")])
24142
24143 (define_insn "@adjust_stack_and_probe_<mode>"
24144 [(set (match_operand:P 0 "register_operand" "=r")
24145 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24146 UNSPECV_PROBE_STACK_RANGE))
24147 (set (reg:P SP_REG)
24148 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24149 (clobber (reg:CC FLAGS_REG))
24150 (clobber (mem:BLK (scratch)))]
24151 ""
24152 "* return output_adjust_stack_and_probe (operands[0]);"
24153 [(set_attr "type" "multi")])
24154
24155 (define_insn "@probe_stack_range_<mode>"
24156 [(set (match_operand:P 0 "register_operand" "=r")
24157 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24158 (match_operand:P 2 "const_int_operand")]
24159 UNSPECV_PROBE_STACK_RANGE))
24160 (clobber (reg:CC FLAGS_REG))]
24161 ""
24162 "* return output_probe_stack_range (operands[0], operands[2]);"
24163 [(set_attr "type" "multi")])
24164
24165 (define_expand "builtin_setjmp_receiver"
24166 [(label_ref (match_operand 0))]
24167 "!TARGET_64BIT && flag_pic"
24168 {
24169 #if TARGET_MACHO
24170 if (TARGET_MACHO)
24171 {
24172 rtx xops[3];
24173 rtx_code_label *label_rtx = gen_label_rtx ();
24174 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24175 xops[0] = xops[1] = pic_offset_table_rtx;
24176 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24177 ix86_expand_binary_operator (MINUS, SImode, xops);
24178 }
24179 else
24180 #endif
24181 emit_insn (gen_set_got (pic_offset_table_rtx));
24182 DONE;
24183 })
24184
24185 (define_expand "save_stack_nonlocal"
24186 [(set (match_operand 0 "memory_operand")
24187 (match_operand 1 "register_operand"))]
24188 ""
24189 {
24190 rtx stack_slot;
24191
24192 if (flag_cf_protection & CF_RETURN)
24193 {
24194 /* Copy shadow stack pointer to the first slot
24195 and stack pointer to the second slot. */
24196 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24197 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24198
24199 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24200 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24201 emit_move_insn (ssp_slot, reg_ssp);
24202 }
24203 else
24204 stack_slot = adjust_address (operands[0], Pmode, 0);
24205 emit_move_insn (stack_slot, operands[1]);
24206 DONE;
24207 })
24208
24209 (define_expand "restore_stack_nonlocal"
24210 [(set (match_operand 0 "register_operand" "")
24211 (match_operand 1 "memory_operand" ""))]
24212 ""
24213 {
24214 rtx stack_slot;
24215
24216 if (flag_cf_protection & CF_RETURN)
24217 {
24218 /* Restore shadow stack pointer from the first slot
24219 and stack pointer from the second slot. */
24220 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24221 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24222
24223 /* Get the current shadow stack pointer. The code below will check if
24224 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
24225 is a NOP. */
24226 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24227 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24228
24229 /* Compare through subtraction the saved and the current ssp
24230 to decide if ssp has to be adjusted. */
24231 reg_ssp = expand_simple_binop (word_mode, MINUS,
24232 reg_ssp, ssp_slot,
24233 reg_ssp, 1, OPTAB_DIRECT);
24234
24235 /* Compare and jump over adjustment code. */
24236 rtx noadj_label = gen_label_rtx ();
24237 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24238 word_mode, 1, noadj_label);
24239
24240 /* Compute the number of frames to adjust. */
24241 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24242 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24243 NULL_RTX, 1);
24244
24245 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24246 GEN_INT (exact_log2 (UNITS_PER_WORD)),
24247 reg_adj, 1, OPTAB_DIRECT);
24248
24249 /* Check if number of frames <= 255 so no loop is needed. */
24250 rtx inc_label = gen_label_rtx ();
24251 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24252 ptr_mode, 1, inc_label);
24253
24254 /* Adjust the ssp in a loop. */
24255 rtx loop_label = gen_label_rtx ();
24256 emit_label (loop_label);
24257 LABEL_NUSES (loop_label) = 1;
24258
24259 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24260 emit_insn (gen_incssp (word_mode, reg_255));
24261
24262 reg_adj = expand_simple_binop (ptr_mode, MINUS,
24263 reg_adj, GEN_INT (255),
24264 reg_adj, 1, OPTAB_DIRECT);
24265
24266 /* Compare and jump to the loop label. */
24267 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24268 ptr_mode, 1, loop_label);
24269
24270 emit_label (inc_label);
24271 LABEL_NUSES (inc_label) = 1;
24272
24273 emit_insn (gen_incssp (word_mode, reg_ssp));
24274
24275 emit_label (noadj_label);
24276 LABEL_NUSES (noadj_label) = 1;
24277 }
24278 else
24279 stack_slot = adjust_address (operands[1], Pmode, 0);
24280 emit_move_insn (operands[0], stack_slot);
24281 DONE;
24282 })
24283
24284
24285 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24286 ;; Do not split instructions with mask registers.
24287 (define_split
24288 [(set (match_operand 0 "general_reg_operand")
24289 (match_operator 3 "promotable_binary_operator"
24290 [(match_operand 1 "general_reg_operand")
24291 (match_operand 2 "aligned_operand")]))
24292 (clobber (reg:CC FLAGS_REG))]
24293 "! TARGET_PARTIAL_REG_STALL && reload_completed
24294 && ((GET_MODE (operands[0]) == HImode
24295 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24296 /* ??? next two lines just !satisfies_constraint_K (...) */
24297 || !CONST_INT_P (operands[2])
24298 || satisfies_constraint_K (operands[2])))
24299 || (GET_MODE (operands[0]) == QImode
24300 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24301 [(parallel [(set (match_dup 0)
24302 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24303 (clobber (reg:CC FLAGS_REG))])]
24304 {
24305 operands[0] = gen_lowpart (SImode, operands[0]);
24306 operands[1] = gen_lowpart (SImode, operands[1]);
24307 if (GET_CODE (operands[3]) != ASHIFT)
24308 operands[2] = gen_lowpart (SImode, operands[2]);
24309 operands[3] = shallow_copy_rtx (operands[3]);
24310 PUT_MODE (operands[3], SImode);
24311 })
24312
24313 ; Promote the QImode tests, as i386 has encoding of the AND
24314 ; instruction with 32-bit sign-extended immediate and thus the
24315 ; instruction size is unchanged, except in the %eax case for
24316 ; which it is increased by one byte, hence the ! optimize_size.
24317 (define_split
24318 [(set (match_operand 0 "flags_reg_operand")
24319 (match_operator 2 "compare_operator"
24320 [(and (match_operand 3 "aligned_operand")
24321 (match_operand 4 "const_int_operand"))
24322 (const_int 0)]))
24323 (set (match_operand 1 "register_operand")
24324 (and (match_dup 3) (match_dup 4)))]
24325 "! TARGET_PARTIAL_REG_STALL && reload_completed
24326 && optimize_insn_for_speed_p ()
24327 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24328 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24329 /* Ensure that the operand will remain sign-extended immediate. */
24330 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24331 [(parallel [(set (match_dup 0)
24332 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24333 (const_int 0)]))
24334 (set (match_dup 1)
24335 (and:SI (match_dup 3) (match_dup 4)))])]
24336 {
24337 operands[4]
24338 = gen_int_mode (INTVAL (operands[4])
24339 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24340 operands[1] = gen_lowpart (SImode, operands[1]);
24341 operands[3] = gen_lowpart (SImode, operands[3]);
24342 })
24343
24344 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24345 ; the TEST instruction with 32-bit sign-extended immediate and thus
24346 ; the instruction size would at least double, which is not what we
24347 ; want even with ! optimize_size.
24348 (define_split
24349 [(set (match_operand 0 "flags_reg_operand")
24350 (match_operator 1 "compare_operator"
24351 [(and (match_operand:HI 2 "aligned_operand")
24352 (match_operand:HI 3 "const_int_operand"))
24353 (const_int 0)]))]
24354 "! TARGET_PARTIAL_REG_STALL && reload_completed
24355 && ! TARGET_FAST_PREFIX
24356 && optimize_insn_for_speed_p ()
24357 /* Ensure that the operand will remain sign-extended immediate. */
24358 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24359 [(set (match_dup 0)
24360 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24361 (const_int 0)]))]
24362 {
24363 operands[3]
24364 = gen_int_mode (INTVAL (operands[3])
24365 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24366 operands[2] = gen_lowpart (SImode, operands[2]);
24367 })
24368
24369 (define_split
24370 [(set (match_operand 0 "register_operand")
24371 (neg (match_operand 1 "register_operand")))
24372 (clobber (reg:CC FLAGS_REG))]
24373 "! TARGET_PARTIAL_REG_STALL && reload_completed
24374 && (GET_MODE (operands[0]) == HImode
24375 || (GET_MODE (operands[0]) == QImode
24376 && (TARGET_PROMOTE_QImode
24377 || optimize_insn_for_size_p ())))"
24378 [(parallel [(set (match_dup 0)
24379 (neg:SI (match_dup 1)))
24380 (clobber (reg:CC FLAGS_REG))])]
24381 {
24382 operands[0] = gen_lowpart (SImode, operands[0]);
24383 operands[1] = gen_lowpart (SImode, operands[1]);
24384 })
24385
24386 ;; Do not split instructions with mask regs.
24387 (define_split
24388 [(set (match_operand 0 "general_reg_operand")
24389 (not (match_operand 1 "general_reg_operand")))]
24390 "! TARGET_PARTIAL_REG_STALL && reload_completed
24391 && (GET_MODE (operands[0]) == HImode
24392 || (GET_MODE (operands[0]) == QImode
24393 && (TARGET_PROMOTE_QImode
24394 || optimize_insn_for_size_p ())))"
24395 [(set (match_dup 0)
24396 (not:SI (match_dup 1)))]
24397 {
24398 operands[0] = gen_lowpart (SImode, operands[0]);
24399 operands[1] = gen_lowpart (SImode, operands[1]);
24400 })
24401 \f
24402 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24403 ;; transform a complex memory operation into two memory to register operations.
24404
24405 ;; Don't push memory operands
24406 (define_peephole2
24407 [(set (match_operand:SWI 0 "push_operand")
24408 (match_operand:SWI 1 "memory_operand"))
24409 (match_scratch:SWI 2 "<r>")]
24410 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24411 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24412 [(set (match_dup 2) (match_dup 1))
24413 (set (match_dup 0) (match_dup 2))])
24414
24415 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24416 ;; SImode pushes.
24417 (define_peephole2
24418 [(set (match_operand:SF 0 "push_operand")
24419 (match_operand:SF 1 "memory_operand"))
24420 (match_scratch:SF 2 "r")]
24421 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24422 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24423 [(set (match_dup 2) (match_dup 1))
24424 (set (match_dup 0) (match_dup 2))])
24425
24426 ;; Don't move an immediate directly to memory when the instruction
24427 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24428 (define_peephole2
24429 [(match_scratch:SWI124 1 "<r>")
24430 (set (match_operand:SWI124 0 "memory_operand")
24431 (const_int 0))]
24432 "optimize_insn_for_speed_p ()
24433 && ((<MODE>mode == HImode
24434 && TARGET_LCP_STALL)
24435 || (!TARGET_USE_MOV0
24436 && TARGET_SPLIT_LONG_MOVES
24437 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24438 && peep2_regno_dead_p (0, FLAGS_REG)"
24439 [(parallel [(set (match_dup 2) (const_int 0))
24440 (clobber (reg:CC FLAGS_REG))])
24441 (set (match_dup 0) (match_dup 1))]
24442 "operands[2] = gen_lowpart (SImode, operands[1]);")
24443
24444 (define_peephole2
24445 [(match_scratch:SWI124 2 "<r>")
24446 (set (match_operand:SWI124 0 "memory_operand")
24447 (match_operand:SWI124 1 "immediate_operand"))]
24448 "optimize_insn_for_speed_p ()
24449 && ((<MODE>mode == HImode
24450 && TARGET_LCP_STALL)
24451 || (TARGET_SPLIT_LONG_MOVES
24452 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24453 [(set (match_dup 2) (match_dup 1))
24454 (set (match_dup 0) (match_dup 2))])
24455
24456 ;; Don't compare memory with zero, load and use a test instead.
24457 (define_peephole2
24458 [(set (match_operand 0 "flags_reg_operand")
24459 (match_operator 1 "compare_operator"
24460 [(match_operand:SI 2 "memory_operand")
24461 (const_int 0)]))
24462 (match_scratch:SI 3 "r")]
24463 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24464 [(set (match_dup 3) (match_dup 2))
24465 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24466
24467 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24468 ;; Don't split NOTs with a displacement operand, because resulting XOR
24469 ;; will not be pairable anyway.
24470 ;;
24471 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24472 ;; represented using a modRM byte. The XOR replacement is long decoded,
24473 ;; so this split helps here as well.
24474 ;;
24475 ;; Note: Can't do this as a regular split because we can't get proper
24476 ;; lifetime information then.
24477
24478 (define_peephole2
24479 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24480 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24481 "optimize_insn_for_speed_p ()
24482 && ((TARGET_NOT_UNPAIRABLE
24483 && (!MEM_P (operands[0])
24484 || !memory_displacement_operand (operands[0], <MODE>mode)))
24485 || (TARGET_NOT_VECTORMODE
24486 && long_memory_operand (operands[0], <MODE>mode)))
24487 && peep2_regno_dead_p (0, FLAGS_REG)"
24488 [(parallel [(set (match_dup 0)
24489 (xor:SWI124 (match_dup 1) (const_int -1)))
24490 (clobber (reg:CC FLAGS_REG))])])
24491
24492 ;; Non pairable "test imm, reg" instructions can be translated to
24493 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24494 ;; byte opcode instead of two, have a short form for byte operands),
24495 ;; so do it for other CPUs as well. Given that the value was dead,
24496 ;; this should not create any new dependencies. Pass on the sub-word
24497 ;; versions if we're concerned about partial register stalls.
24498
24499 (define_peephole2
24500 [(set (match_operand 0 "flags_reg_operand")
24501 (match_operator 1 "compare_operator"
24502 [(and:SI (match_operand:SI 2 "register_operand")
24503 (match_operand:SI 3 "immediate_operand"))
24504 (const_int 0)]))]
24505 "ix86_match_ccmode (insn, CCNOmode)
24506 && (REGNO (operands[2]) != AX_REG
24507 || satisfies_constraint_K (operands[3]))
24508 && peep2_reg_dead_p (1, operands[2])"
24509 [(parallel
24510 [(set (match_dup 0)
24511 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24512 (const_int 0)]))
24513 (set (match_dup 2)
24514 (and:SI (match_dup 2) (match_dup 3)))])])
24515
24516 ;; We don't need to handle HImode case, because it will be promoted to SImode
24517 ;; on ! TARGET_PARTIAL_REG_STALL
24518
24519 (define_peephole2
24520 [(set (match_operand 0 "flags_reg_operand")
24521 (match_operator 1 "compare_operator"
24522 [(and:QI (match_operand:QI 2 "register_operand")
24523 (match_operand:QI 3 "immediate_operand"))
24524 (const_int 0)]))]
24525 "! TARGET_PARTIAL_REG_STALL
24526 && ix86_match_ccmode (insn, CCNOmode)
24527 && REGNO (operands[2]) != AX_REG
24528 && peep2_reg_dead_p (1, operands[2])"
24529 [(parallel
24530 [(set (match_dup 0)
24531 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24532 (const_int 0)]))
24533 (set (match_dup 2)
24534 (and:QI (match_dup 2) (match_dup 3)))])])
24535
24536 (define_peephole2
24537 [(set (match_operand 0 "flags_reg_operand")
24538 (match_operator 1 "compare_operator"
24539 [(and:QI
24540 (subreg:QI
24541 (match_operator:SWI248 4 "extract_operator"
24542 [(match_operand 2 "int248_register_operand")
24543 (const_int 8)
24544 (const_int 8)]) 0)
24545 (match_operand 3 "const_int_operand"))
24546 (const_int 0)]))]
24547 "! TARGET_PARTIAL_REG_STALL
24548 && ix86_match_ccmode (insn, CCNOmode)
24549 && REGNO (operands[2]) != AX_REG
24550 && peep2_reg_dead_p (1, operands[2])"
24551 [(parallel
24552 [(set (match_dup 0)
24553 (match_op_dup 1
24554 [(and:QI
24555 (subreg:QI
24556 (match_op_dup 4 [(match_dup 2)
24557 (const_int 8)
24558 (const_int 8)]) 0)
24559 (match_dup 3))
24560 (const_int 0)]))
24561 (set (zero_extract:SWI248 (match_dup 2)
24562 (const_int 8)
24563 (const_int 8))
24564 (subreg:SWI248
24565 (and:QI
24566 (subreg:QI
24567 (match_op_dup 4 [(match_dup 2)
24568 (const_int 8)
24569 (const_int 8)]) 0)
24570 (match_dup 3)) 0))])])
24571
24572 ;; Don't do logical operations with memory inputs.
24573 (define_peephole2
24574 [(match_scratch:SWI 2 "<r>")
24575 (parallel [(set (match_operand:SWI 0 "register_operand")
24576 (match_operator:SWI 3 "arith_or_logical_operator"
24577 [(match_dup 0)
24578 (match_operand:SWI 1 "memory_operand")]))
24579 (clobber (reg:CC FLAGS_REG))])]
24580 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24581 [(set (match_dup 2) (match_dup 1))
24582 (parallel [(set (match_dup 0)
24583 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24584 (clobber (reg:CC FLAGS_REG))])])
24585
24586 (define_peephole2
24587 [(match_scratch:SWI 2 "<r>")
24588 (parallel [(set (match_operand:SWI 0 "register_operand")
24589 (match_operator:SWI 3 "arith_or_logical_operator"
24590 [(match_operand:SWI 1 "memory_operand")
24591 (match_dup 0)]))
24592 (clobber (reg:CC FLAGS_REG))])]
24593 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24594 [(set (match_dup 2) (match_dup 1))
24595 (parallel [(set (match_dup 0)
24596 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24597 (clobber (reg:CC FLAGS_REG))])])
24598
24599 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24600 ;; the memory address refers to the destination of the load!
24601
24602 (define_peephole2
24603 [(set (match_operand:SWI 0 "general_reg_operand")
24604 (match_operand:SWI 1 "general_reg_operand"))
24605 (parallel [(set (match_dup 0)
24606 (match_operator:SWI 3 "commutative_operator"
24607 [(match_dup 0)
24608 (match_operand:SWI 2 "memory_operand")]))
24609 (clobber (reg:CC FLAGS_REG))])]
24610 "REGNO (operands[0]) != REGNO (operands[1])
24611 && (<MODE>mode != QImode
24612 || any_QIreg_operand (operands[1], QImode))"
24613 [(set (match_dup 0) (match_dup 4))
24614 (parallel [(set (match_dup 0)
24615 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24616 (clobber (reg:CC FLAGS_REG))])]
24617 {
24618 operands[4]
24619 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24620 })
24621
24622 (define_peephole2
24623 [(set (match_operand 0 "mmx_reg_operand")
24624 (match_operand 1 "mmx_reg_operand"))
24625 (set (match_dup 0)
24626 (match_operator 3 "commutative_operator"
24627 [(match_dup 0)
24628 (match_operand 2 "memory_operand")]))]
24629 "REGNO (operands[0]) != REGNO (operands[1])"
24630 [(set (match_dup 0) (match_dup 2))
24631 (set (match_dup 0)
24632 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24633
24634 (define_peephole2
24635 [(set (match_operand 0 "sse_reg_operand")
24636 (match_operand 1 "sse_reg_operand"))
24637 (set (match_dup 0)
24638 (match_operator 3 "commutative_operator"
24639 [(match_dup 0)
24640 (match_operand 2 "memory_operand")]))]
24641 "REGNO (operands[0]) != REGNO (operands[1])
24642 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24643 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24644 instructions require AVX512BW and AVX512VL, but with the original
24645 instructions it might require just AVX512VL.
24646 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24647 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24648 || TARGET_AVX512BW
24649 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24650 || logic_operator (operands[3], VOIDmode))"
24651 [(set (match_dup 0) (match_dup 2))
24652 (set (match_dup 0)
24653 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24654
24655 ; Don't do logical operations with memory outputs
24656 ;
24657 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24658 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24659 ; the same decoder scheduling characteristics as the original.
24660
24661 (define_peephole2
24662 [(match_scratch:SWI 2 "<r>")
24663 (parallel [(set (match_operand:SWI 0 "memory_operand")
24664 (match_operator:SWI 3 "arith_or_logical_operator"
24665 [(match_dup 0)
24666 (match_operand:SWI 1 "<nonmemory_operand>")]))
24667 (clobber (reg:CC FLAGS_REG))])]
24668 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24669 [(set (match_dup 2) (match_dup 0))
24670 (parallel [(set (match_dup 2)
24671 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24672 (clobber (reg:CC FLAGS_REG))])
24673 (set (match_dup 0) (match_dup 2))])
24674
24675 (define_peephole2
24676 [(match_scratch:SWI 2 "<r>")
24677 (parallel [(set (match_operand:SWI 0 "memory_operand")
24678 (match_operator:SWI 3 "arith_or_logical_operator"
24679 [(match_operand:SWI 1 "<nonmemory_operand>")
24680 (match_dup 0)]))
24681 (clobber (reg:CC FLAGS_REG))])]
24682 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24683 [(set (match_dup 2) (match_dup 0))
24684 (parallel [(set (match_dup 2)
24685 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24686 (clobber (reg:CC FLAGS_REG))])
24687 (set (match_dup 0) (match_dup 2))])
24688
24689 ;; Attempt to use arith or logical operations with memory outputs with
24690 ;; setting of flags.
24691 (define_peephole2
24692 [(set (match_operand:SWI 0 "register_operand")
24693 (match_operand:SWI 1 "memory_operand"))
24694 (parallel [(set (match_dup 0)
24695 (match_operator:SWI 3 "plusminuslogic_operator"
24696 [(match_dup 0)
24697 (match_operand:SWI 2 "<nonmemory_operand>")]))
24698 (clobber (reg:CC FLAGS_REG))])
24699 (set (match_dup 1) (match_dup 0))
24700 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24701 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24702 && peep2_reg_dead_p (4, operands[0])
24703 && !reg_overlap_mentioned_p (operands[0], operands[1])
24704 && !reg_overlap_mentioned_p (operands[0], operands[2])
24705 && (<MODE>mode != QImode
24706 || immediate_operand (operands[2], QImode)
24707 || any_QIreg_operand (operands[2], QImode))
24708 && ix86_match_ccmode (peep2_next_insn (3),
24709 (GET_CODE (operands[3]) == PLUS
24710 || GET_CODE (operands[3]) == MINUS)
24711 ? CCGOCmode : CCNOmode)"
24712 [(parallel [(set (match_dup 4) (match_dup 6))
24713 (set (match_dup 1) (match_dup 5))])]
24714 {
24715 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24716 operands[5]
24717 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24718 copy_rtx (operands[1]),
24719 operands[2]);
24720 operands[6]
24721 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24722 copy_rtx (operands[5]),
24723 const0_rtx);
24724 })
24725
24726 ;; Likewise for cmpelim optimized pattern.
24727 (define_peephole2
24728 [(set (match_operand:SWI 0 "register_operand")
24729 (match_operand:SWI 1 "memory_operand"))
24730 (parallel [(set (reg FLAGS_REG)
24731 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24732 [(match_dup 0)
24733 (match_operand:SWI 2 "<nonmemory_operand>")])
24734 (const_int 0)))
24735 (set (match_dup 0) (match_dup 3))])
24736 (set (match_dup 1) (match_dup 0))]
24737 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24738 && peep2_reg_dead_p (3, operands[0])
24739 && !reg_overlap_mentioned_p (operands[0], operands[1])
24740 && !reg_overlap_mentioned_p (operands[0], operands[2])
24741 && ix86_match_ccmode (peep2_next_insn (1),
24742 (GET_CODE (operands[3]) == PLUS
24743 || GET_CODE (operands[3]) == MINUS)
24744 ? CCGOCmode : CCNOmode)"
24745 [(parallel [(set (match_dup 4) (match_dup 6))
24746 (set (match_dup 1) (match_dup 5))])]
24747 {
24748 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24749 operands[5]
24750 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24751 copy_rtx (operands[1]), operands[2]);
24752 operands[6]
24753 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24754 const0_rtx);
24755 })
24756
24757 ;; Likewise for instances where we have a lea pattern.
24758 (define_peephole2
24759 [(set (match_operand:SWI 0 "register_operand")
24760 (match_operand:SWI 1 "memory_operand"))
24761 (set (match_operand:<LEAMODE> 3 "register_operand")
24762 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24763 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24764 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24765 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24766 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24767 && REGNO (operands[4]) == REGNO (operands[0])
24768 && REGNO (operands[5]) == REGNO (operands[3])
24769 && peep2_reg_dead_p (4, operands[3])
24770 && ((REGNO (operands[0]) == REGNO (operands[3]))
24771 || peep2_reg_dead_p (2, operands[0]))
24772 && !reg_overlap_mentioned_p (operands[0], operands[1])
24773 && !reg_overlap_mentioned_p (operands[3], operands[1])
24774 && !reg_overlap_mentioned_p (operands[0], operands[2])
24775 && (<MODE>mode != QImode
24776 || immediate_operand (operands[2], QImode)
24777 || any_QIreg_operand (operands[2], QImode))
24778 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24779 [(parallel [(set (match_dup 6) (match_dup 8))
24780 (set (match_dup 1) (match_dup 7))])]
24781 {
24782 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24783 operands[7]
24784 = gen_rtx_PLUS (<MODE>mode,
24785 copy_rtx (operands[1]),
24786 gen_lowpart (<MODE>mode, operands[2]));
24787 operands[8]
24788 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24789 copy_rtx (operands[7]),
24790 const0_rtx);
24791 })
24792
24793 (define_peephole2
24794 [(parallel [(set (match_operand:SWI 0 "register_operand")
24795 (match_operator:SWI 2 "plusminuslogic_operator"
24796 [(match_dup 0)
24797 (match_operand:SWI 1 "memory_operand")]))
24798 (clobber (reg:CC FLAGS_REG))])
24799 (set (match_dup 1) (match_dup 0))
24800 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24801 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24802 && COMMUTATIVE_ARITH_P (operands[2])
24803 && peep2_reg_dead_p (3, operands[0])
24804 && !reg_overlap_mentioned_p (operands[0], operands[1])
24805 && ix86_match_ccmode (peep2_next_insn (2),
24806 GET_CODE (operands[2]) == PLUS
24807 ? CCGOCmode : CCNOmode)"
24808 [(parallel [(set (match_dup 3) (match_dup 5))
24809 (set (match_dup 1) (match_dup 4))])]
24810 {
24811 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24812 operands[4]
24813 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24814 copy_rtx (operands[1]),
24815 operands[0]);
24816 operands[5]
24817 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24818 copy_rtx (operands[4]),
24819 const0_rtx);
24820 })
24821
24822 ;; Likewise for cmpelim optimized pattern.
24823 (define_peephole2
24824 [(parallel [(set (reg FLAGS_REG)
24825 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24826 [(match_operand:SWI 0 "register_operand")
24827 (match_operand:SWI 1 "memory_operand")])
24828 (const_int 0)))
24829 (set (match_dup 0) (match_dup 2))])
24830 (set (match_dup 1) (match_dup 0))]
24831 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24832 && COMMUTATIVE_ARITH_P (operands[2])
24833 && peep2_reg_dead_p (2, operands[0])
24834 && !reg_overlap_mentioned_p (operands[0], operands[1])
24835 && ix86_match_ccmode (peep2_next_insn (0),
24836 GET_CODE (operands[2]) == PLUS
24837 ? CCGOCmode : CCNOmode)"
24838 [(parallel [(set (match_dup 3) (match_dup 5))
24839 (set (match_dup 1) (match_dup 4))])]
24840 {
24841 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24842 operands[4]
24843 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24844 copy_rtx (operands[1]), operands[0]);
24845 operands[5]
24846 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24847 const0_rtx);
24848 })
24849
24850 (define_peephole2
24851 [(set (match_operand:SWI12 0 "register_operand")
24852 (match_operand:SWI12 1 "memory_operand"))
24853 (parallel [(set (match_operand:SI 4 "register_operand")
24854 (match_operator:SI 3 "plusminuslogic_operator"
24855 [(match_dup 4)
24856 (match_operand:SI 2 "nonmemory_operand")]))
24857 (clobber (reg:CC FLAGS_REG))])
24858 (set (match_dup 1) (match_dup 0))
24859 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24860 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24861 && REGNO (operands[0]) == REGNO (operands[4])
24862 && peep2_reg_dead_p (4, operands[0])
24863 && (<MODE>mode != QImode
24864 || immediate_operand (operands[2], SImode)
24865 || any_QIreg_operand (operands[2], SImode))
24866 && !reg_overlap_mentioned_p (operands[0], operands[1])
24867 && !reg_overlap_mentioned_p (operands[0], operands[2])
24868 && ix86_match_ccmode (peep2_next_insn (3),
24869 (GET_CODE (operands[3]) == PLUS
24870 || GET_CODE (operands[3]) == MINUS)
24871 ? CCGOCmode : CCNOmode)"
24872 [(parallel [(set (match_dup 5) (match_dup 7))
24873 (set (match_dup 1) (match_dup 6))])]
24874 {
24875 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24876 operands[6]
24877 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24878 copy_rtx (operands[1]),
24879 gen_lowpart (<MODE>mode, operands[2]));
24880 operands[7]
24881 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24882 copy_rtx (operands[6]),
24883 const0_rtx);
24884 })
24885
24886 ;; peephole2 comes before regcprop, so deal also with a case that
24887 ;; would be cleaned up by regcprop.
24888 (define_peephole2
24889 [(set (match_operand:SWI 0 "register_operand")
24890 (match_operand:SWI 1 "memory_operand"))
24891 (parallel [(set (match_dup 0)
24892 (match_operator:SWI 3 "plusminuslogic_operator"
24893 [(match_dup 0)
24894 (match_operand:SWI 2 "<nonmemory_operand>")]))
24895 (clobber (reg:CC FLAGS_REG))])
24896 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24897 (set (match_dup 1) (match_dup 4))
24898 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24899 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24900 && peep2_reg_dead_p (3, operands[0])
24901 && peep2_reg_dead_p (5, operands[4])
24902 && !reg_overlap_mentioned_p (operands[0], operands[1])
24903 && !reg_overlap_mentioned_p (operands[0], operands[2])
24904 && !reg_overlap_mentioned_p (operands[4], operands[1])
24905 && (<MODE>mode != QImode
24906 || immediate_operand (operands[2], QImode)
24907 || any_QIreg_operand (operands[2], QImode))
24908 && ix86_match_ccmode (peep2_next_insn (4),
24909 (GET_CODE (operands[3]) == PLUS
24910 || GET_CODE (operands[3]) == MINUS)
24911 ? CCGOCmode : CCNOmode)"
24912 [(parallel [(set (match_dup 5) (match_dup 7))
24913 (set (match_dup 1) (match_dup 6))])]
24914 {
24915 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24916 operands[6]
24917 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24918 copy_rtx (operands[1]),
24919 operands[2]);
24920 operands[7]
24921 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24922 copy_rtx (operands[6]),
24923 const0_rtx);
24924 })
24925
24926 (define_peephole2
24927 [(set (match_operand:SWI12 0 "register_operand")
24928 (match_operand:SWI12 1 "memory_operand"))
24929 (parallel [(set (match_operand:SI 4 "register_operand")
24930 (match_operator:SI 3 "plusminuslogic_operator"
24931 [(match_dup 4)
24932 (match_operand:SI 2 "nonmemory_operand")]))
24933 (clobber (reg:CC FLAGS_REG))])
24934 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24935 (set (match_dup 1) (match_dup 5))
24936 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24937 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24938 && REGNO (operands[0]) == REGNO (operands[4])
24939 && peep2_reg_dead_p (3, operands[0])
24940 && peep2_reg_dead_p (5, operands[5])
24941 && (<MODE>mode != QImode
24942 || immediate_operand (operands[2], SImode)
24943 || any_QIreg_operand (operands[2], SImode))
24944 && !reg_overlap_mentioned_p (operands[0], operands[1])
24945 && !reg_overlap_mentioned_p (operands[0], operands[2])
24946 && !reg_overlap_mentioned_p (operands[5], operands[1])
24947 && ix86_match_ccmode (peep2_next_insn (4),
24948 (GET_CODE (operands[3]) == PLUS
24949 || GET_CODE (operands[3]) == MINUS)
24950 ? CCGOCmode : CCNOmode)"
24951 [(parallel [(set (match_dup 6) (match_dup 8))
24952 (set (match_dup 1) (match_dup 7))])]
24953 {
24954 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24955 operands[7]
24956 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24957 copy_rtx (operands[1]),
24958 gen_lowpart (<MODE>mode, operands[2]));
24959 operands[8]
24960 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24961 copy_rtx (operands[7]),
24962 const0_rtx);
24963 })
24964
24965 ;; Likewise for cmpelim optimized pattern.
24966 (define_peephole2
24967 [(set (match_operand:SWI 0 "register_operand")
24968 (match_operand:SWI 1 "memory_operand"))
24969 (parallel [(set (reg FLAGS_REG)
24970 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24971 [(match_dup 0)
24972 (match_operand:SWI 2 "<nonmemory_operand>")])
24973 (const_int 0)))
24974 (set (match_dup 0) (match_dup 3))])
24975 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24976 (set (match_dup 1) (match_dup 4))]
24977 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24978 && peep2_reg_dead_p (3, operands[0])
24979 && peep2_reg_dead_p (4, operands[4])
24980 && !reg_overlap_mentioned_p (operands[0], operands[1])
24981 && !reg_overlap_mentioned_p (operands[0], operands[2])
24982 && !reg_overlap_mentioned_p (operands[4], operands[1])
24983 && ix86_match_ccmode (peep2_next_insn (1),
24984 (GET_CODE (operands[3]) == PLUS
24985 || GET_CODE (operands[3]) == MINUS)
24986 ? CCGOCmode : CCNOmode)"
24987 [(parallel [(set (match_dup 5) (match_dup 7))
24988 (set (match_dup 1) (match_dup 6))])]
24989 {
24990 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24991 operands[6]
24992 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24993 copy_rtx (operands[1]), operands[2]);
24994 operands[7]
24995 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
24996 const0_rtx);
24997 })
24998
24999 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25000 ;; into x = z; x ^= y; x != z
25001 (define_peephole2
25002 [(set (match_operand:SWI 0 "register_operand")
25003 (match_operand:SWI 1 "memory_operand"))
25004 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25005 (parallel [(set (match_operand:SWI 4 "register_operand")
25006 (xor:SWI (match_dup 4)
25007 (match_operand:SWI 2 "<nonmemory_operand>")))
25008 (clobber (reg:CC FLAGS_REG))])
25009 (set (match_dup 1) (match_dup 4))
25010 (set (reg:CCZ FLAGS_REG)
25011 (compare:CCZ (match_operand:SWI 5 "register_operand")
25012 (match_operand:SWI 6 "<nonmemory_operand>")))]
25013 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25014 && (REGNO (operands[4]) == REGNO (operands[0])
25015 || REGNO (operands[4]) == REGNO (operands[3]))
25016 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25017 ? 3 : 0], operands[5])
25018 ? rtx_equal_p (operands[2], operands[6])
25019 : rtx_equal_p (operands[2], operands[5])
25020 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25021 ? 3 : 0], operands[6]))
25022 && peep2_reg_dead_p (4, operands[4])
25023 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25024 ? 3 : 0])
25025 && !reg_overlap_mentioned_p (operands[0], operands[1])
25026 && !reg_overlap_mentioned_p (operands[0], operands[2])
25027 && !reg_overlap_mentioned_p (operands[3], operands[0])
25028 && !reg_overlap_mentioned_p (operands[3], operands[1])
25029 && !reg_overlap_mentioned_p (operands[3], operands[2])
25030 && (<MODE>mode != QImode
25031 || immediate_operand (operands[2], QImode)
25032 || any_QIreg_operand (operands[2], QImode))"
25033 [(parallel [(set (match_dup 7) (match_dup 9))
25034 (set (match_dup 1) (match_dup 8))])]
25035 {
25036 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25037 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25038 operands[2]);
25039 operands[9]
25040 = gen_rtx_COMPARE (GET_MODE (operands[7]),
25041 copy_rtx (operands[8]),
25042 const0_rtx);
25043 })
25044
25045 (define_peephole2
25046 [(set (match_operand:SWI12 0 "register_operand")
25047 (match_operand:SWI12 1 "memory_operand"))
25048 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25049 (parallel [(set (match_operand:SI 4 "register_operand")
25050 (xor:SI (match_dup 4)
25051 (match_operand:SI 2 "<nonmemory_operand>")))
25052 (clobber (reg:CC FLAGS_REG))])
25053 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25054 (set (reg:CCZ FLAGS_REG)
25055 (compare:CCZ (match_operand:SWI12 6 "register_operand")
25056 (match_operand:SWI12 7 "<nonmemory_operand>")))]
25057 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25058 && (REGNO (operands[5]) == REGNO (operands[0])
25059 || REGNO (operands[5]) == REGNO (operands[3]))
25060 && REGNO (operands[5]) == REGNO (operands[4])
25061 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25062 ? 3 : 0], operands[6])
25063 ? (REG_P (operands[2])
25064 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25065 : rtx_equal_p (operands[2], operands[7]))
25066 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25067 ? 3 : 0], operands[7])
25068 && REG_P (operands[2])
25069 && REGNO (operands[2]) == REGNO (operands[6])))
25070 && peep2_reg_dead_p (4, operands[5])
25071 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25072 ? 3 : 0])
25073 && !reg_overlap_mentioned_p (operands[0], operands[1])
25074 && !reg_overlap_mentioned_p (operands[0], operands[2])
25075 && !reg_overlap_mentioned_p (operands[3], operands[0])
25076 && !reg_overlap_mentioned_p (operands[3], operands[1])
25077 && !reg_overlap_mentioned_p (operands[3], operands[2])
25078 && (<MODE>mode != QImode
25079 || immediate_operand (operands[2], SImode)
25080 || any_QIreg_operand (operands[2], SImode))"
25081 [(parallel [(set (match_dup 8) (match_dup 10))
25082 (set (match_dup 1) (match_dup 9))])]
25083 {
25084 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25085 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25086 gen_lowpart (<MODE>mode, operands[2]));
25087 operands[10]
25088 = gen_rtx_COMPARE (GET_MODE (operands[8]),
25089 copy_rtx (operands[9]),
25090 const0_rtx);
25091 })
25092
25093 ;; Attempt to optimize away memory stores of values the memory already
25094 ;; has. See PR79593.
25095 (define_peephole2
25096 [(set (match_operand 0 "register_operand")
25097 (match_operand 1 "memory_operand"))
25098 (set (match_operand 2 "memory_operand") (match_dup 0))]
25099 "!MEM_VOLATILE_P (operands[1])
25100 && !MEM_VOLATILE_P (operands[2])
25101 && rtx_equal_p (operands[1], operands[2])
25102 && !reg_overlap_mentioned_p (operands[0], operands[2])"
25103 [(set (match_dup 0) (match_dup 1))])
25104
25105 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25106 (define_peephole2
25107 [(set (match_operand 0 "general_reg_operand")
25108 (match_operand 1 "const0_operand"))]
25109 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25110 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25111 && peep2_regno_dead_p (0, FLAGS_REG)"
25112 [(parallel [(set (match_dup 0) (const_int 0))
25113 (clobber (reg:CC FLAGS_REG))])]
25114 "operands[0] = gen_lowpart (word_mode, operands[0]);")
25115
25116 (define_peephole2
25117 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25118 (const_int 0))]
25119 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25120 && peep2_regno_dead_p (0, FLAGS_REG)"
25121 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25122 (clobber (reg:CC FLAGS_REG))])])
25123
25124 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25125 (define_peephole2
25126 [(set (match_operand:SWI248 0 "general_reg_operand")
25127 (const_int -1))]
25128 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25129 && peep2_regno_dead_p (0, FLAGS_REG)"
25130 [(parallel [(set (match_dup 0) (const_int -1))
25131 (clobber (reg:CC FLAGS_REG))])]
25132 {
25133 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25134 operands[0] = gen_lowpart (SImode, operands[0]);
25135 })
25136
25137 ;; Attempt to convert simple lea to add/shift.
25138 ;; These can be created by move expanders.
25139 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25140 ;; relevant lea instructions were already split.
25141
25142 (define_peephole2
25143 [(set (match_operand:SWI48 0 "register_operand")
25144 (plus:SWI48 (match_dup 0)
25145 (match_operand:SWI48 1 "<nonmemory_operand>")))]
25146 "!TARGET_OPT_AGU
25147 && peep2_regno_dead_p (0, FLAGS_REG)"
25148 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25149 (clobber (reg:CC FLAGS_REG))])])
25150
25151 (define_peephole2
25152 [(set (match_operand:SWI48 0 "register_operand")
25153 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25154 (match_dup 0)))]
25155 "!TARGET_OPT_AGU
25156 && peep2_regno_dead_p (0, FLAGS_REG)"
25157 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25158 (clobber (reg:CC FLAGS_REG))])])
25159
25160 (define_peephole2
25161 [(set (match_operand:DI 0 "register_operand")
25162 (zero_extend:DI
25163 (plus:SI (match_operand:SI 1 "register_operand")
25164 (match_operand:SI 2 "nonmemory_operand"))))]
25165 "TARGET_64BIT && !TARGET_OPT_AGU
25166 && REGNO (operands[0]) == REGNO (operands[1])
25167 && peep2_regno_dead_p (0, FLAGS_REG)"
25168 [(parallel [(set (match_dup 0)
25169 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25170 (clobber (reg:CC FLAGS_REG))])])
25171
25172 (define_peephole2
25173 [(set (match_operand:DI 0 "register_operand")
25174 (zero_extend:DI
25175 (plus:SI (match_operand:SI 1 "nonmemory_operand")
25176 (match_operand:SI 2 "register_operand"))))]
25177 "TARGET_64BIT && !TARGET_OPT_AGU
25178 && REGNO (operands[0]) == REGNO (operands[2])
25179 && peep2_regno_dead_p (0, FLAGS_REG)"
25180 [(parallel [(set (match_dup 0)
25181 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25182 (clobber (reg:CC FLAGS_REG))])])
25183
25184 (define_peephole2
25185 [(set (match_operand:SWI48 0 "register_operand")
25186 (mult:SWI48 (match_dup 0)
25187 (match_operand:SWI48 1 "const_int_operand")))]
25188 "pow2p_hwi (INTVAL (operands[1]))
25189 && peep2_regno_dead_p (0, FLAGS_REG)"
25190 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25191 (clobber (reg:CC FLAGS_REG))])]
25192 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25193
25194 (define_peephole2
25195 [(set (match_operand:DI 0 "register_operand")
25196 (zero_extend:DI
25197 (mult:SI (match_operand:SI 1 "register_operand")
25198 (match_operand:SI 2 "const_int_operand"))))]
25199 "TARGET_64BIT
25200 && pow2p_hwi (INTVAL (operands[2]))
25201 && REGNO (operands[0]) == REGNO (operands[1])
25202 && peep2_regno_dead_p (0, FLAGS_REG)"
25203 [(parallel [(set (match_dup 0)
25204 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25205 (clobber (reg:CC FLAGS_REG))])]
25206 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25207
25208 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
25209 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25210 ;; On many CPUs it is also faster, since special hardware to avoid esp
25211 ;; dependencies is present.
25212
25213 ;; While some of these conversions may be done using splitters, we use
25214 ;; peepholes in order to allow combine_stack_adjustments pass to see
25215 ;; nonobfuscated RTL.
25216
25217 ;; Convert prologue esp subtractions to push.
25218 ;; We need register to push. In order to keep verify_flow_info happy we have
25219 ;; two choices
25220 ;; - use scratch and clobber it in order to avoid dependencies
25221 ;; - use already live register
25222 ;; We can't use the second way right now, since there is no reliable way how to
25223 ;; verify that given register is live. First choice will also most likely in
25224 ;; fewer dependencies. On the place of esp adjustments it is very likely that
25225 ;; call clobbered registers are dead. We may want to use base pointer as an
25226 ;; alternative when no register is available later.
25227
25228 (define_peephole2
25229 [(match_scratch:W 1 "r")
25230 (parallel [(set (reg:P SP_REG)
25231 (plus:P (reg:P SP_REG)
25232 (match_operand:P 0 "const_int_operand")))
25233 (clobber (reg:CC FLAGS_REG))
25234 (clobber (mem:BLK (scratch)))])]
25235 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25236 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25237 && !ix86_red_zone_used"
25238 [(clobber (match_dup 1))
25239 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25240 (clobber (mem:BLK (scratch)))])])
25241
25242 (define_peephole2
25243 [(match_scratch:W 1 "r")
25244 (parallel [(set (reg:P SP_REG)
25245 (plus:P (reg:P SP_REG)
25246 (match_operand:P 0 "const_int_operand")))
25247 (clobber (reg:CC FLAGS_REG))
25248 (clobber (mem:BLK (scratch)))])]
25249 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25250 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25251 && !ix86_red_zone_used"
25252 [(clobber (match_dup 1))
25253 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25254 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25255 (clobber (mem:BLK (scratch)))])])
25256
25257 ;; Convert esp subtractions to push.
25258 (define_peephole2
25259 [(match_scratch:W 1 "r")
25260 (parallel [(set (reg:P SP_REG)
25261 (plus:P (reg:P SP_REG)
25262 (match_operand:P 0 "const_int_operand")))
25263 (clobber (reg:CC FLAGS_REG))])]
25264 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25265 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25266 && !ix86_red_zone_used"
25267 [(clobber (match_dup 1))
25268 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25269
25270 (define_peephole2
25271 [(match_scratch:W 1 "r")
25272 (parallel [(set (reg:P SP_REG)
25273 (plus:P (reg:P SP_REG)
25274 (match_operand:P 0 "const_int_operand")))
25275 (clobber (reg:CC FLAGS_REG))])]
25276 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25277 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25278 && !ix86_red_zone_used"
25279 [(clobber (match_dup 1))
25280 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25281 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25282
25283 ;; Convert epilogue deallocator to pop.
25284 (define_peephole2
25285 [(match_scratch:W 1 "r")
25286 (parallel [(set (reg:P SP_REG)
25287 (plus:P (reg:P SP_REG)
25288 (match_operand:P 0 "const_int_operand")))
25289 (clobber (reg:CC FLAGS_REG))
25290 (clobber (mem:BLK (scratch)))])]
25291 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25292 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25293 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25294 (clobber (mem:BLK (scratch)))])])
25295
25296 ;; Two pops case is tricky, since pop causes dependency
25297 ;; on destination register. We use two registers if available.
25298 (define_peephole2
25299 [(match_scratch:W 1 "r")
25300 (match_scratch:W 2 "r")
25301 (parallel [(set (reg:P SP_REG)
25302 (plus:P (reg:P SP_REG)
25303 (match_operand:P 0 "const_int_operand")))
25304 (clobber (reg:CC FLAGS_REG))
25305 (clobber (mem:BLK (scratch)))])]
25306 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25307 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25308 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25309 (clobber (mem:BLK (scratch)))])
25310 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25311
25312 (define_peephole2
25313 [(match_scratch:W 1 "r")
25314 (parallel [(set (reg:P SP_REG)
25315 (plus:P (reg:P SP_REG)
25316 (match_operand:P 0 "const_int_operand")))
25317 (clobber (reg:CC FLAGS_REG))
25318 (clobber (mem:BLK (scratch)))])]
25319 "optimize_insn_for_size_p ()
25320 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25321 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25322 (clobber (mem:BLK (scratch)))])
25323 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25324
25325 ;; Convert esp additions to pop.
25326 (define_peephole2
25327 [(match_scratch:W 1 "r")
25328 (parallel [(set (reg:P SP_REG)
25329 (plus:P (reg:P SP_REG)
25330 (match_operand:P 0 "const_int_operand")))
25331 (clobber (reg:CC FLAGS_REG))])]
25332 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25333 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25334
25335 ;; Two pops case is tricky, since pop causes dependency
25336 ;; on destination register. We use two registers if available.
25337 (define_peephole2
25338 [(match_scratch:W 1 "r")
25339 (match_scratch:W 2 "r")
25340 (parallel [(set (reg:P SP_REG)
25341 (plus:P (reg:P SP_REG)
25342 (match_operand:P 0 "const_int_operand")))
25343 (clobber (reg:CC FLAGS_REG))])]
25344 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25345 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25346 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25347
25348 (define_peephole2
25349 [(match_scratch:W 1 "r")
25350 (parallel [(set (reg:P SP_REG)
25351 (plus:P (reg:P SP_REG)
25352 (match_operand:P 0 "const_int_operand")))
25353 (clobber (reg:CC FLAGS_REG))])]
25354 "optimize_insn_for_size_p ()
25355 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25356 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25357 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25358 \f
25359 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25360 ;; required and register dies. Similarly for 128 to -128.
25361 (define_peephole2
25362 [(set (match_operand 0 "flags_reg_operand")
25363 (match_operator 1 "compare_operator"
25364 [(match_operand 2 "register_operand")
25365 (match_operand 3 "const_int_operand")]))]
25366 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25367 && incdec_operand (operands[3], GET_MODE (operands[3])))
25368 || (!TARGET_FUSE_CMP_AND_BRANCH
25369 && INTVAL (operands[3]) == 128))
25370 && ix86_match_ccmode (insn, CCGCmode)
25371 && peep2_reg_dead_p (1, operands[2])"
25372 [(parallel [(set (match_dup 0)
25373 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25374 (clobber (match_dup 2))])])
25375 \f
25376 ;; Convert imul by three, five and nine into lea
25377 (define_peephole2
25378 [(parallel
25379 [(set (match_operand:SWI48 0 "register_operand")
25380 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25381 (match_operand:SWI48 2 "const359_operand")))
25382 (clobber (reg:CC FLAGS_REG))])]
25383 "!TARGET_PARTIAL_REG_STALL
25384 || <MODE>mode == SImode
25385 || optimize_function_for_size_p (cfun)"
25386 [(set (match_dup 0)
25387 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25388 (match_dup 1)))]
25389 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25390
25391 (define_peephole2
25392 [(parallel
25393 [(set (match_operand:SWI48 0 "register_operand")
25394 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25395 (match_operand:SWI48 2 "const359_operand")))
25396 (clobber (reg:CC FLAGS_REG))])]
25397 "optimize_insn_for_speed_p ()
25398 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25399 [(set (match_dup 0) (match_dup 1))
25400 (set (match_dup 0)
25401 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25402 (match_dup 0)))]
25403 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25404
25405 ;; imul $32bit_imm, mem, reg is vector decoded, while
25406 ;; imul $32bit_imm, reg, reg is direct decoded.
25407 (define_peephole2
25408 [(match_scratch:SWI48 3 "r")
25409 (parallel [(set (match_operand:SWI48 0 "register_operand")
25410 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25411 (match_operand:SWI48 2 "immediate_operand")))
25412 (clobber (reg:CC FLAGS_REG))])]
25413 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25414 && !satisfies_constraint_K (operands[2])"
25415 [(set (match_dup 3) (match_dup 1))
25416 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25417 (clobber (reg:CC FLAGS_REG))])])
25418
25419 (define_peephole2
25420 [(match_scratch:SI 3 "r")
25421 (parallel [(set (match_operand:DI 0 "register_operand")
25422 (zero_extend:DI
25423 (mult:SI (match_operand:SI 1 "memory_operand")
25424 (match_operand:SI 2 "immediate_operand"))))
25425 (clobber (reg:CC FLAGS_REG))])]
25426 "TARGET_64BIT
25427 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25428 && !satisfies_constraint_K (operands[2])"
25429 [(set (match_dup 3) (match_dup 1))
25430 (parallel [(set (match_dup 0)
25431 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25432 (clobber (reg:CC FLAGS_REG))])])
25433
25434 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25435 ;; Convert it into imul reg, reg
25436 ;; It would be better to force assembler to encode instruction using long
25437 ;; immediate, but there is apparently no way to do so.
25438 (define_peephole2
25439 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25440 (mult:SWI248
25441 (match_operand:SWI248 1 "nonimmediate_operand")
25442 (match_operand:SWI248 2 "const_int_operand")))
25443 (clobber (reg:CC FLAGS_REG))])
25444 (match_scratch:SWI248 3 "r")]
25445 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25446 && satisfies_constraint_K (operands[2])"
25447 [(set (match_dup 3) (match_dup 2))
25448 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25449 (clobber (reg:CC FLAGS_REG))])]
25450 {
25451 if (!rtx_equal_p (operands[0], operands[1]))
25452 emit_move_insn (operands[0], operands[1]);
25453 })
25454
25455 ;; After splitting up read-modify operations, array accesses with memory
25456 ;; operands might end up in form:
25457 ;; sall $2, %eax
25458 ;; movl 4(%esp), %edx
25459 ;; addl %edx, %eax
25460 ;; instead of pre-splitting:
25461 ;; sall $2, %eax
25462 ;; addl 4(%esp), %eax
25463 ;; Turn it into:
25464 ;; movl 4(%esp), %edx
25465 ;; leal (%edx,%eax,4), %eax
25466
25467 (define_peephole2
25468 [(match_scratch:W 5 "r")
25469 (parallel [(set (match_operand 0 "register_operand")
25470 (ashift (match_operand 1 "register_operand")
25471 (match_operand 2 "const_int_operand")))
25472 (clobber (reg:CC FLAGS_REG))])
25473 (parallel [(set (match_operand 3 "register_operand")
25474 (plus (match_dup 0)
25475 (match_operand 4 "x86_64_general_operand")))
25476 (clobber (reg:CC FLAGS_REG))])]
25477 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25478 /* Validate MODE for lea. */
25479 && ((!TARGET_PARTIAL_REG_STALL
25480 && (GET_MODE (operands[0]) == QImode
25481 || GET_MODE (operands[0]) == HImode))
25482 || GET_MODE (operands[0]) == SImode
25483 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25484 && (rtx_equal_p (operands[0], operands[3])
25485 || peep2_reg_dead_p (2, operands[0]))
25486 /* We reorder load and the shift. */
25487 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25488 [(set (match_dup 5) (match_dup 4))
25489 (set (match_dup 0) (match_dup 1))]
25490 {
25491 machine_mode op1mode = GET_MODE (operands[1]);
25492 machine_mode mode = op1mode == DImode ? DImode : SImode;
25493 int scale = 1 << INTVAL (operands[2]);
25494 rtx index = gen_lowpart (word_mode, operands[1]);
25495 rtx base = gen_lowpart (word_mode, operands[5]);
25496 rtx dest = gen_lowpart (mode, operands[3]);
25497
25498 operands[1] = gen_rtx_PLUS (word_mode, base,
25499 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25500 if (mode != word_mode)
25501 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25502
25503 operands[5] = base;
25504 if (op1mode != word_mode)
25505 operands[5] = gen_lowpart (op1mode, operands[5]);
25506
25507 operands[0] = dest;
25508 })
25509 \f
25510 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25511 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25512 ;; caught for use by garbage collectors and the like. Using an insn that
25513 ;; maps to SIGILL makes it more likely the program will rightfully die.
25514 ;; Keeping with tradition, "6" is in honor of #UD.
25515 (define_insn "trap"
25516 [(trap_if (const_int 1) (const_int 6))]
25517 ""
25518 {
25519 #ifdef HAVE_AS_IX86_UD2
25520 return "ud2";
25521 #else
25522 return ASM_SHORT "0x0b0f";
25523 #endif
25524 }
25525 [(set_attr "length" "2")])
25526
25527 (define_insn "ud2"
25528 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25529 ""
25530 {
25531 #ifdef HAVE_AS_IX86_UD2
25532 return "ud2";
25533 #else
25534 return ASM_SHORT "0x0b0f";
25535 #endif
25536 }
25537 [(set_attr "length" "2")])
25538
25539 (define_expand "prefetch"
25540 [(prefetch (match_operand 0 "address_operand")
25541 (match_operand:SI 1 "const_int_operand")
25542 (match_operand:SI 2 "const_int_operand"))]
25543 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25544 {
25545 bool write = operands[1] != const0_rtx;
25546 int locality = INTVAL (operands[2]);
25547
25548 gcc_assert (IN_RANGE (locality, 0, 3));
25549
25550 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25551 supported by SSE counterpart (non-SSE2 athlon machines) or the
25552 SSE prefetch is not available (K6 machines). Otherwise use SSE
25553 prefetch as it allows specifying of locality. */
25554
25555 if (write)
25556 {
25557 if (TARGET_PREFETCHWT1)
25558 operands[2] = GEN_INT (MAX (locality, 2));
25559 else if (TARGET_PRFCHW)
25560 operands[2] = GEN_INT (3);
25561 else if (TARGET_3DNOW && !TARGET_SSE2)
25562 operands[2] = GEN_INT (3);
25563 else if (TARGET_PREFETCH_SSE)
25564 operands[1] = const0_rtx;
25565 else
25566 {
25567 gcc_assert (TARGET_3DNOW);
25568 operands[2] = GEN_INT (3);
25569 }
25570 }
25571 else
25572 {
25573 if (TARGET_PREFETCH_SSE)
25574 ;
25575 else
25576 {
25577 gcc_assert (TARGET_3DNOW);
25578 operands[2] = GEN_INT (3);
25579 }
25580 }
25581 })
25582
25583 (define_insn "*prefetch_sse"
25584 [(prefetch (match_operand 0 "address_operand" "p")
25585 (const_int 0)
25586 (match_operand:SI 1 "const_int_operand"))]
25587 "TARGET_PREFETCH_SSE"
25588 {
25589 static const char * const patterns[4] = {
25590 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25591 };
25592
25593 int locality = INTVAL (operands[1]);
25594 gcc_assert (IN_RANGE (locality, 0, 3));
25595
25596 return patterns[locality];
25597 }
25598 [(set_attr "type" "sse")
25599 (set_attr "atom_sse_attr" "prefetch")
25600 (set (attr "length_address")
25601 (symbol_ref "memory_address_length (operands[0], false)"))
25602 (set_attr "memory" "none")])
25603
25604 (define_insn "*prefetch_3dnow"
25605 [(prefetch (match_operand 0 "address_operand" "p")
25606 (match_operand:SI 1 "const_int_operand")
25607 (const_int 3))]
25608 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25609 {
25610 if (operands[1] == const0_rtx)
25611 return "prefetch\t%a0";
25612 else
25613 return "prefetchw\t%a0";
25614 }
25615 [(set_attr "type" "mmx")
25616 (set (attr "length_address")
25617 (symbol_ref "memory_address_length (operands[0], false)"))
25618 (set_attr "memory" "none")])
25619
25620 (define_insn "*prefetch_prefetchwt1"
25621 [(prefetch (match_operand 0 "address_operand" "p")
25622 (const_int 1)
25623 (const_int 2))]
25624 "TARGET_PREFETCHWT1"
25625 "prefetchwt1\t%a0";
25626 [(set_attr "type" "sse")
25627 (set (attr "length_address")
25628 (symbol_ref "memory_address_length (operands[0], false)"))
25629 (set_attr "memory" "none")])
25630
25631 (define_insn "prefetchi"
25632 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25633 (match_operand:SI 1 "const_int_operand")]
25634 UNSPECV_PREFETCHI)]
25635 "TARGET_PREFETCHI && TARGET_64BIT"
25636 {
25637 static const char * const patterns[2] = {
25638 "prefetchit1\t%0", "prefetchit0\t%0"
25639 };
25640
25641 int locality = INTVAL (operands[1]);
25642 gcc_assert (IN_RANGE (locality, 2, 3));
25643
25644 return patterns[locality - 2];
25645 }
25646 [(set_attr "type" "sse")
25647 (set (attr "length_address")
25648 (symbol_ref "memory_address_length (operands[0], false)"))
25649 (set_attr "memory" "none")])
25650
25651 (define_expand "stack_protect_set"
25652 [(match_operand 0 "memory_operand")
25653 (match_operand 1 "memory_operand")]
25654 ""
25655 {
25656 rtx scratch = gen_reg_rtx (word_mode);
25657
25658 emit_insn (gen_stack_protect_set_1
25659 (ptr_mode, word_mode, operands[0], operands[1], scratch));
25660 DONE;
25661 })
25662
25663 (define_insn "@stack_protect_set_1_<PTR:mode>_<SWI48:mode>"
25664 [(set (match_operand:PTR 0 "memory_operand" "=m")
25665 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25666 UNSPEC_SP_SET))
25667 (set (match_operand:SWI48 2 "register_operand" "=&r") (const_int 0))
25668 (clobber (reg:CC FLAGS_REG))]
25669 ""
25670 {
25671 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
25672 operands);
25673 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
25674 operands);
25675 return "xor{l}\t%k2, %k2";
25676 }
25677 [(set_attr "type" "multi")])
25678
25679 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25680 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
25681 ;; the xor{l} above. We don't split this, so that scheduling or
25682 ;; anything else doesn't separate the *stack_protect_set* pattern from
25683 ;; the set of the register that overwrites the register with a new value.
25684
25685 (define_peephole2
25686 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25687 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25688 UNSPEC_SP_SET))
25689 (set (match_operand:W 2 "general_reg_operand") (const_int 0))
25690 (clobber (reg:CC FLAGS_REG))])
25691 (parallel [(set (match_operand:SWI48 3 "general_reg_operand")
25692 (match_operand:SWI48 4 "const0_operand"))
25693 (clobber (reg:CC FLAGS_REG))])]
25694 "peep2_reg_dead_p (0, operands[3])
25695 && peep2_reg_dead_p (1, operands[2])"
25696 [(parallel [(set (match_dup 0)
25697 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25698 (set (match_dup 3) (const_int 0))
25699 (clobber (reg:CC FLAGS_REG))])])
25700
25701 (define_insn "*stack_protect_set_2_<mode>_si"
25702 [(set (match_operand:PTR 0 "memory_operand" "=m")
25703 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25704 UNSPEC_SP_SET))
25705 (set (match_operand:SI 1 "register_operand" "=&r")
25706 (match_operand:SI 2 "general_operand" "g"))]
25707 "reload_completed"
25708 {
25709 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25710 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25711 if (pic_32bit_operand (operands[2], SImode)
25712 || ix86_use_lea_for_mov (insn, operands + 1))
25713 return "lea{l}\t{%E2, %1|%1, %E2}";
25714 else
25715 return "mov{l}\t{%2, %1|%1, %2}";
25716 }
25717 [(set_attr "type" "multi")
25718 (set_attr "length" "24")])
25719
25720 (define_insn "*stack_protect_set_2_<mode>_di"
25721 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
25722 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
25723 UNSPEC_SP_SET))
25724 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
25725 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
25726 "TARGET_64BIT && reload_completed"
25727 {
25728 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25729 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25730 if (pic_32bit_operand (operands[2], DImode))
25731 return "lea{q}\t{%E2, %1|%1, %E2}";
25732 else if (which_alternative == 0)
25733 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25734 else if (which_alternative == 2)
25735 return "movabs{q}\t{%2, %1|%1, %2}";
25736 else if (ix86_use_lea_for_mov (insn, operands + 1))
25737 return "lea{q}\t{%E2, %1|%1, %E2}";
25738 else
25739 return "mov{q}\t{%2, %1|%1, %2}";
25740 }
25741 [(set_attr "type" "multi")
25742 (set_attr "length" "24")])
25743
25744 (define_peephole2
25745 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25746 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25747 UNSPEC_SP_SET))
25748 (set (match_operand:W 2 "general_reg_operand") (const_int 0))
25749 (clobber (reg:CC FLAGS_REG))])
25750 (set (match_operand:SWI48 3 "general_reg_operand")
25751 (match_operand:SWI48 4 "general_operand"))]
25752 "peep2_reg_dead_p (0, operands[3])
25753 && peep2_reg_dead_p (1, operands[2])"
25754 [(parallel [(set (match_dup 0)
25755 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25756 (set (match_dup 3) (match_dup 4))])])
25757
25758 (define_expand "stack_protect_test"
25759 [(match_operand 0 "memory_operand")
25760 (match_operand 1 "memory_operand")
25761 (match_operand 2)]
25762 ""
25763 {
25764 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25765
25766 emit_insn (gen_stack_protect_test_1
25767 (ptr_mode, flags, operands[0], operands[1]));
25768
25769 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25770 flags, const0_rtx, operands[2]));
25771 DONE;
25772 })
25773
25774 (define_insn "@stack_protect_test_1_<mode>"
25775 [(set (match_operand:CCZ 0 "flags_reg_operand")
25776 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25777 (match_operand:PTR 2 "memory_operand" "m")]
25778 UNSPEC_SP_TEST))
25779 (clobber (match_scratch:PTR 3 "=&r"))]
25780 ""
25781 {
25782 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25783 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25784 }
25785 [(set_attr "type" "multi")])
25786
25787 (define_insn "sse4_2_crc32<mode>"
25788 [(set (match_operand:SI 0 "register_operand" "=r")
25789 (unspec:SI
25790 [(match_operand:SI 1 "register_operand" "0")
25791 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25792 UNSPEC_CRC32))]
25793 "TARGET_CRC32"
25794 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25795 [(set_attr "type" "sselog1")
25796 (set_attr "prefix_rep" "1")
25797 (set_attr "prefix_extra" "1")
25798 (set (attr "prefix_data16")
25799 (if_then_else (match_operand:HI 2)
25800 (const_string "1")
25801 (const_string "*")))
25802 (set (attr "prefix_rex")
25803 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25804 (const_string "1")
25805 (const_string "*")))
25806 (set_attr "mode" "SI")])
25807
25808 (define_insn "sse4_2_crc32di"
25809 [(set (match_operand:DI 0 "register_operand" "=r")
25810 (zero_extend:DI
25811 (unspec:SI
25812 [(match_operand:SI 1 "register_operand" "0")
25813 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25814 UNSPEC_CRC32)))]
25815 "TARGET_64BIT && TARGET_CRC32"
25816 "crc32{q}\t{%2, %0|%0, %2}"
25817 [(set_attr "type" "sselog1")
25818 (set_attr "prefix_rep" "1")
25819 (set_attr "prefix_extra" "1")
25820 (set_attr "mode" "DI")])
25821
25822 (define_insn "rdpmc"
25823 [(set (match_operand:DI 0 "register_operand" "=A")
25824 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25825 UNSPECV_RDPMC))]
25826 "!TARGET_64BIT"
25827 "rdpmc"
25828 [(set_attr "type" "other")
25829 (set_attr "length" "2")])
25830
25831 (define_insn "rdpmc_rex64"
25832 [(set (match_operand:DI 0 "register_operand" "=a")
25833 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25834 UNSPECV_RDPMC))
25835 (set (match_operand:DI 1 "register_operand" "=d")
25836 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25837 "TARGET_64BIT"
25838 "rdpmc"
25839 [(set_attr "type" "other")
25840 (set_attr "length" "2")])
25841
25842 (define_insn "rdtsc"
25843 [(set (match_operand:DI 0 "register_operand" "=A")
25844 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25845 "!TARGET_64BIT"
25846 "rdtsc"
25847 [(set_attr "type" "other")
25848 (set_attr "length" "2")])
25849
25850 (define_insn "rdtsc_rex64"
25851 [(set (match_operand:DI 0 "register_operand" "=a")
25852 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25853 (set (match_operand:DI 1 "register_operand" "=d")
25854 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25855 "TARGET_64BIT"
25856 "rdtsc"
25857 [(set_attr "type" "other")
25858 (set_attr "length" "2")])
25859
25860 (define_insn "rdtscp"
25861 [(set (match_operand:DI 0 "register_operand" "=A")
25862 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25863 (set (match_operand:SI 1 "register_operand" "=c")
25864 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25865 "!TARGET_64BIT"
25866 "rdtscp"
25867 [(set_attr "type" "other")
25868 (set_attr "length" "3")])
25869
25870 (define_insn "rdtscp_rex64"
25871 [(set (match_operand:DI 0 "register_operand" "=a")
25872 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25873 (set (match_operand:DI 1 "register_operand" "=d")
25874 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25875 (set (match_operand:SI 2 "register_operand" "=c")
25876 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25877 "TARGET_64BIT"
25878 "rdtscp"
25879 [(set_attr "type" "other")
25880 (set_attr "length" "3")])
25881
25882 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25883 ;;
25884 ;; FXSR, XSAVE and XSAVEOPT instructions
25885 ;;
25886 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25887
25888 (define_insn "fxsave"
25889 [(set (match_operand:BLK 0 "memory_operand" "=m")
25890 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25891 "TARGET_FXSR"
25892 "fxsave\t%0"
25893 [(set_attr "type" "other")
25894 (set_attr "memory" "store")
25895 (set (attr "length")
25896 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25897
25898 (define_insn "fxsave64"
25899 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25900 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25901 "TARGET_64BIT && TARGET_FXSR"
25902 "fxsave64\t%0"
25903 [(set_attr "type" "other")
25904 (set_attr "gpr32" "0")
25905 (set_attr "memory" "store")
25906 (set (attr "length")
25907 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25908
25909 (define_insn "fxrstor"
25910 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25911 UNSPECV_FXRSTOR)]
25912 "TARGET_FXSR"
25913 "fxrstor\t%0"
25914 [(set_attr "type" "other")
25915 (set_attr "memory" "load")
25916 (set (attr "length")
25917 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25918
25919 (define_insn "fxrstor64"
25920 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
25921 UNSPECV_FXRSTOR64)]
25922 "TARGET_64BIT && TARGET_FXSR"
25923 "fxrstor64\t%0"
25924 [(set_attr "type" "other")
25925 (set_attr "gpr32" "0")
25926 (set_attr "memory" "load")
25927 (set (attr "length")
25928 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25929
25930 (define_int_iterator ANY_XSAVE
25931 [UNSPECV_XSAVE
25932 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25933 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25934 (UNSPECV_XSAVES "TARGET_XSAVES")])
25935
25936 (define_int_iterator ANY_XSAVE64
25937 [UNSPECV_XSAVE64
25938 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25939 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25940 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25941
25942 (define_int_attr xsave
25943 [(UNSPECV_XSAVE "xsave")
25944 (UNSPECV_XSAVE64 "xsave64")
25945 (UNSPECV_XSAVEOPT "xsaveopt")
25946 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25947 (UNSPECV_XSAVEC "xsavec")
25948 (UNSPECV_XSAVEC64 "xsavec64")
25949 (UNSPECV_XSAVES "xsaves")
25950 (UNSPECV_XSAVES64 "xsaves64")])
25951
25952 (define_int_iterator ANY_XRSTOR
25953 [UNSPECV_XRSTOR
25954 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25955
25956 (define_int_iterator ANY_XRSTOR64
25957 [UNSPECV_XRSTOR64
25958 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25959
25960 (define_int_attr xrstor
25961 [(UNSPECV_XRSTOR "xrstor")
25962 (UNSPECV_XRSTOR64 "xrstor")
25963 (UNSPECV_XRSTORS "xrstors")
25964 (UNSPECV_XRSTORS64 "xrstors")])
25965
25966 (define_insn "<xsave>"
25967 [(set (match_operand:BLK 0 "memory_operand" "=m")
25968 (unspec_volatile:BLK
25969 [(match_operand:DI 1 "register_operand" "A")]
25970 ANY_XSAVE))]
25971 "!TARGET_64BIT && TARGET_XSAVE"
25972 "<xsave>\t%0"
25973 [(set_attr "type" "other")
25974 (set_attr "memory" "store")
25975 (set (attr "length")
25976 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25977
25978 (define_insn "<xsave>_rex64"
25979 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25980 (unspec_volatile:BLK
25981 [(match_operand:SI 1 "register_operand" "a")
25982 (match_operand:SI 2 "register_operand" "d")]
25983 ANY_XSAVE))]
25984 "TARGET_64BIT && TARGET_XSAVE"
25985 "<xsave>\t%0"
25986 [(set_attr "type" "other")
25987 (set_attr "memory" "store")
25988 (set_attr "gpr32" "0")
25989 (set (attr "length")
25990 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25991
25992 (define_insn "<xsave>"
25993 [(set (match_operand:BLK 0 "memory_operand" "=jm")
25994 (unspec_volatile:BLK
25995 [(match_operand:SI 1 "register_operand" "a")
25996 (match_operand:SI 2 "register_operand" "d")]
25997 ANY_XSAVE64))]
25998 "TARGET_64BIT && TARGET_XSAVE"
25999 "<xsave>\t%0"
26000 [(set_attr "type" "other")
26001 (set_attr "memory" "store")
26002 (set_attr "gpr32" "0")
26003 (set (attr "length")
26004 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26005
26006 (define_insn "<xrstor>"
26007 [(unspec_volatile:BLK
26008 [(match_operand:BLK 0 "memory_operand" "m")
26009 (match_operand:DI 1 "register_operand" "A")]
26010 ANY_XRSTOR)]
26011 "!TARGET_64BIT && TARGET_XSAVE"
26012 "<xrstor>\t%0"
26013 [(set_attr "type" "other")
26014 (set_attr "memory" "load")
26015 (set (attr "length")
26016 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26017
26018 (define_insn "<xrstor>_rex64"
26019 [(unspec_volatile:BLK
26020 [(match_operand:BLK 0 "memory_operand" "jm")
26021 (match_operand:SI 1 "register_operand" "a")
26022 (match_operand:SI 2 "register_operand" "d")]
26023 ANY_XRSTOR)]
26024 "TARGET_64BIT && TARGET_XSAVE"
26025 "<xrstor>\t%0"
26026 [(set_attr "type" "other")
26027 (set_attr "memory" "load")
26028 (set_attr "gpr32" "0")
26029 (set (attr "length")
26030 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26031
26032 (define_insn "<xrstor>64"
26033 [(unspec_volatile:BLK
26034 [(match_operand:BLK 0 "memory_operand" "jm")
26035 (match_operand:SI 1 "register_operand" "a")
26036 (match_operand:SI 2 "register_operand" "d")]
26037 ANY_XRSTOR64)]
26038 "TARGET_64BIT && TARGET_XSAVE"
26039 "<xrstor>64\t%0"
26040 [(set_attr "type" "other")
26041 (set_attr "memory" "load")
26042 (set_attr "gpr32" "0")
26043 (set (attr "length")
26044 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26045
26046 (define_insn "xsetbv"
26047 [(unspec_volatile:SI
26048 [(match_operand:SI 0 "register_operand" "c")
26049 (match_operand:DI 1 "register_operand" "A")]
26050 UNSPECV_XSETBV)]
26051 "!TARGET_64BIT && TARGET_XSAVE"
26052 "xsetbv"
26053 [(set_attr "type" "other")])
26054
26055 (define_insn "xsetbv_rex64"
26056 [(unspec_volatile:SI
26057 [(match_operand:SI 0 "register_operand" "c")
26058 (match_operand:SI 1 "register_operand" "a")
26059 (match_operand:SI 2 "register_operand" "d")]
26060 UNSPECV_XSETBV)]
26061 "TARGET_64BIT && TARGET_XSAVE"
26062 "xsetbv"
26063 [(set_attr "type" "other")])
26064
26065 (define_insn "xgetbv"
26066 [(set (match_operand:DI 0 "register_operand" "=A")
26067 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26068 UNSPECV_XGETBV))]
26069 "!TARGET_64BIT && TARGET_XSAVE"
26070 "xgetbv"
26071 [(set_attr "type" "other")])
26072
26073 (define_insn "xgetbv_rex64"
26074 [(set (match_operand:DI 0 "register_operand" "=a")
26075 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26076 UNSPECV_XGETBV))
26077 (set (match_operand:DI 1 "register_operand" "=d")
26078 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
26079 "TARGET_64BIT && TARGET_XSAVE"
26080 "xgetbv"
26081 [(set_attr "type" "other")])
26082
26083 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26084 ;;
26085 ;; Floating-point instructions for atomic compound assignments
26086 ;;
26087 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26088
26089 ; Clobber all floating-point registers on environment save and restore
26090 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
26091 (define_insn "fnstenv"
26092 [(set (match_operand:BLK 0 "memory_operand" "=m")
26093 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
26094 (clobber (reg:XF ST0_REG))
26095 (clobber (reg:XF ST1_REG))
26096 (clobber (reg:XF ST2_REG))
26097 (clobber (reg:XF ST3_REG))
26098 (clobber (reg:XF ST4_REG))
26099 (clobber (reg:XF ST5_REG))
26100 (clobber (reg:XF ST6_REG))
26101 (clobber (reg:XF ST7_REG))]
26102 "TARGET_80387"
26103 "fnstenv\t%0"
26104 [(set_attr "type" "other")
26105 (set_attr "memory" "store")
26106 (set (attr "length")
26107 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26108
26109 (define_insn "fldenv"
26110 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26111 UNSPECV_FLDENV)
26112 (clobber (reg:XF ST0_REG))
26113 (clobber (reg:XF ST1_REG))
26114 (clobber (reg:XF ST2_REG))
26115 (clobber (reg:XF ST3_REG))
26116 (clobber (reg:XF ST4_REG))
26117 (clobber (reg:XF ST5_REG))
26118 (clobber (reg:XF ST6_REG))
26119 (clobber (reg:XF ST7_REG))]
26120 "TARGET_80387"
26121 "fldenv\t%0"
26122 [(set_attr "type" "other")
26123 (set_attr "memory" "load")
26124 (set (attr "length")
26125 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26126
26127 (define_insn "fnstsw"
26128 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26129 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26130 "TARGET_80387"
26131 "fnstsw\t%0"
26132 [(set_attr "type" "other,other")
26133 (set_attr "memory" "none,store")
26134 (set (attr "length")
26135 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26136
26137 (define_insn "fnclex"
26138 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26139 "TARGET_80387"
26140 "fnclex"
26141 [(set_attr "type" "other")
26142 (set_attr "memory" "none")
26143 (set_attr "length" "2")])
26144
26145 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26146 ;;
26147 ;; LWP instructions
26148 ;;
26149 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26150
26151 (define_insn "@lwp_llwpcb<mode>"
26152 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26153 UNSPECV_LLWP_INTRINSIC)]
26154 "TARGET_LWP"
26155 "llwpcb\t%0"
26156 [(set_attr "type" "lwp")
26157 (set_attr "mode" "<MODE>")
26158 (set_attr "length" "5")])
26159
26160 (define_insn "@lwp_slwpcb<mode>"
26161 [(set (match_operand:P 0 "register_operand" "=r")
26162 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26163 "TARGET_LWP"
26164 "slwpcb\t%0"
26165 [(set_attr "type" "lwp")
26166 (set_attr "mode" "<MODE>")
26167 (set_attr "length" "5")])
26168
26169 (define_insn "@lwp_lwpval<mode>"
26170 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26171 (match_operand:SI 1 "nonimmediate_operand" "rm")
26172 (match_operand:SI 2 "const_int_operand")]
26173 UNSPECV_LWPVAL_INTRINSIC)]
26174 "TARGET_LWP"
26175 "lwpval\t{%2, %1, %0|%0, %1, %2}"
26176 [(set_attr "type" "lwp")
26177 (set_attr "mode" "<MODE>")
26178 (set (attr "length")
26179 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26180
26181 (define_insn "@lwp_lwpins<mode>"
26182 [(set (reg:CCC FLAGS_REG)
26183 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26184 (match_operand:SI 1 "nonimmediate_operand" "rm")
26185 (match_operand:SI 2 "const_int_operand")]
26186 UNSPECV_LWPINS_INTRINSIC))]
26187 "TARGET_LWP"
26188 "lwpins\t{%2, %1, %0|%0, %1, %2}"
26189 [(set_attr "type" "lwp")
26190 (set_attr "mode" "<MODE>")
26191 (set (attr "length")
26192 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26193
26194 (define_int_iterator RDFSGSBASE
26195 [UNSPECV_RDFSBASE
26196 UNSPECV_RDGSBASE])
26197
26198 (define_int_iterator WRFSGSBASE
26199 [UNSPECV_WRFSBASE
26200 UNSPECV_WRGSBASE])
26201
26202 (define_int_attr fsgs
26203 [(UNSPECV_RDFSBASE "fs")
26204 (UNSPECV_RDGSBASE "gs")
26205 (UNSPECV_WRFSBASE "fs")
26206 (UNSPECV_WRGSBASE "gs")])
26207
26208 (define_insn "rd<fsgs>base<mode>"
26209 [(set (match_operand:SWI48 0 "register_operand" "=r")
26210 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26211 "TARGET_64BIT && TARGET_FSGSBASE"
26212 "rd<fsgs>base\t%0"
26213 [(set_attr "type" "other")
26214 (set_attr "prefix_0f" "1")
26215 (set_attr "prefix_rep" "1")])
26216
26217 (define_insn "wr<fsgs>base<mode>"
26218 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26219 WRFSGSBASE)]
26220 "TARGET_64BIT && TARGET_FSGSBASE"
26221 "wr<fsgs>base\t%0"
26222 [(set_attr "type" "other")
26223 (set_attr "prefix_0f" "1")
26224 (set_attr "prefix_rep" "1")])
26225
26226 (define_insn "ptwrite<mode>"
26227 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26228 UNSPECV_PTWRITE)]
26229 "TARGET_PTWRITE"
26230 "ptwrite\t%0"
26231 [(set_attr "type" "other")
26232 (set_attr "prefix_0f" "1")
26233 (set_attr "prefix_rep" "1")])
26234
26235 (define_insn "@rdrand<mode>"
26236 [(set (match_operand:SWI248 0 "register_operand" "=r")
26237 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26238 (set (reg:CCC FLAGS_REG)
26239 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26240 "TARGET_RDRND"
26241 "rdrand\t%0"
26242 [(set_attr "type" "other")
26243 (set_attr "prefix_0f" "1")])
26244
26245 (define_insn "@rdseed<mode>"
26246 [(set (match_operand:SWI248 0 "register_operand" "=r")
26247 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26248 (set (reg:CCC FLAGS_REG)
26249 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26250 "TARGET_RDSEED"
26251 "rdseed\t%0"
26252 [(set_attr "type" "other")
26253 (set_attr "prefix_0f" "1")])
26254
26255 (define_expand "pause"
26256 [(set (match_dup 0)
26257 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26258 ""
26259 {
26260 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26261 MEM_VOLATILE_P (operands[0]) = 1;
26262 })
26263
26264 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26265 ;; They have the same encoding.
26266 (define_insn "*pause"
26267 [(set (match_operand:BLK 0)
26268 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26269 ""
26270 "rep%; nop"
26271 [(set_attr "length" "2")
26272 (set_attr "memory" "unknown")])
26273
26274 ;; CET instructions
26275 (define_insn "@rdssp<mode>"
26276 [(set (match_operand:SWI48 0 "register_operand" "=r")
26277 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26278 UNSPECV_NOP_RDSSP))]
26279 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26280 "rdssp<mskmodesuffix>\t%0"
26281 [(set_attr "length" "6")
26282 (set_attr "type" "other")])
26283
26284 (define_insn "@incssp<mode>"
26285 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26286 UNSPECV_INCSSP)]
26287 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26288 "incssp<mskmodesuffix>\t%0"
26289 [(set_attr "length" "4")
26290 (set_attr "type" "other")])
26291
26292 (define_insn "saveprevssp"
26293 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26294 "TARGET_SHSTK"
26295 "saveprevssp"
26296 [(set_attr "length" "5")
26297 (set_attr "type" "other")])
26298
26299 (define_insn "rstorssp"
26300 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26301 UNSPECV_RSTORSSP)]
26302 "TARGET_SHSTK"
26303 "rstorssp\t%0"
26304 [(set_attr "length" "5")
26305 (set_attr "type" "other")])
26306
26307 (define_insn "@wrss<mode>"
26308 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26309 (match_operand:SWI48 1 "memory_operand" "m")]
26310 UNSPECV_WRSS)]
26311 "TARGET_SHSTK"
26312 "wrss<mskmodesuffix>\t%0, %1"
26313 [(set_attr "length" "3")
26314 (set_attr "type" "other")])
26315
26316 (define_insn "@wruss<mode>"
26317 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26318 (match_operand:SWI48 1 "memory_operand" "m")]
26319 UNSPECV_WRUSS)]
26320 "TARGET_SHSTK"
26321 "wruss<mskmodesuffix>\t%0, %1"
26322 [(set_attr "length" "4")
26323 (set_attr "type" "other")])
26324
26325 (define_insn "setssbsy"
26326 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26327 "TARGET_SHSTK"
26328 "setssbsy"
26329 [(set_attr "length" "4")
26330 (set_attr "type" "other")])
26331
26332 (define_insn "clrssbsy"
26333 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26334 UNSPECV_CLRSSBSY)]
26335 "TARGET_SHSTK"
26336 "clrssbsy\t%0"
26337 [(set_attr "length" "4")
26338 (set_attr "type" "other")])
26339
26340 (define_insn "nop_endbr"
26341 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26342 "(flag_cf_protection & CF_BRANCH)"
26343 {
26344 return TARGET_64BIT ? "endbr64" : "endbr32";
26345 }
26346 [(set_attr "length" "4")
26347 (set_attr "length_immediate" "0")
26348 (set_attr "modrm" "0")])
26349
26350 ;; For RTM support
26351 (define_expand "xbegin"
26352 [(set (match_operand:SI 0 "register_operand")
26353 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26354 "TARGET_RTM"
26355 {
26356 rtx_code_label *label = gen_label_rtx ();
26357
26358 /* xbegin is emitted as jump_insn, so reload won't be able
26359 to reload its operand. Force the value into AX hard register. */
26360 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26361 emit_move_insn (ax_reg, constm1_rtx);
26362
26363 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26364
26365 emit_label (label);
26366 LABEL_NUSES (label) = 1;
26367
26368 emit_move_insn (operands[0], ax_reg);
26369
26370 DONE;
26371 })
26372
26373 (define_insn "xbegin_1"
26374 [(set (pc)
26375 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26376 (const_int 0))
26377 (label_ref (match_operand 1))
26378 (pc)))
26379 (set (match_operand:SI 0 "register_operand" "+a")
26380 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26381 "TARGET_RTM"
26382 "xbegin\t%l1"
26383 [(set_attr "type" "other")
26384 (set_attr "length" "6")])
26385
26386 (define_insn "xend"
26387 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26388 "TARGET_RTM"
26389 "xend"
26390 [(set_attr "type" "other")
26391 (set_attr "length" "3")])
26392
26393 (define_insn "xabort"
26394 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26395 UNSPECV_XABORT)]
26396 "TARGET_RTM"
26397 "xabort\t%0"
26398 [(set_attr "type" "other")
26399 (set_attr "length" "3")])
26400
26401 (define_expand "xtest"
26402 [(set (match_operand:QI 0 "register_operand")
26403 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26404 "TARGET_RTM"
26405 {
26406 emit_insn (gen_xtest_1 ());
26407
26408 ix86_expand_setcc (operands[0], NE,
26409 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26410 DONE;
26411 })
26412
26413 (define_insn "xtest_1"
26414 [(set (reg:CCZ FLAGS_REG)
26415 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26416 "TARGET_RTM"
26417 "xtest"
26418 [(set_attr "type" "other")
26419 (set_attr "length" "3")])
26420
26421 (define_insn "clwb"
26422 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26423 UNSPECV_CLWB)]
26424 "TARGET_CLWB"
26425 "clwb\t%a0"
26426 [(set_attr "type" "sse")
26427 (set_attr "atom_sse_attr" "fence")
26428 (set_attr "memory" "unknown")])
26429
26430 (define_insn "clflushopt"
26431 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26432 UNSPECV_CLFLUSHOPT)]
26433 "TARGET_CLFLUSHOPT"
26434 "clflushopt\t%a0"
26435 [(set_attr "type" "sse")
26436 (set_attr "atom_sse_attr" "fence")
26437 (set_attr "memory" "unknown")])
26438
26439 ;; MONITORX and MWAITX
26440 (define_insn "mwaitx"
26441 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26442 (match_operand:SI 1 "register_operand" "a")
26443 (match_operand:SI 2 "register_operand" "b")]
26444 UNSPECV_MWAITX)]
26445 "TARGET_MWAITX"
26446 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26447 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26448 ;; we only need to set up 32bit registers.
26449 "mwaitx"
26450 [(set_attr "length" "3")])
26451
26452 (define_insn "@monitorx_<mode>"
26453 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26454 (match_operand:SI 1 "register_operand" "c")
26455 (match_operand:SI 2 "register_operand" "d")]
26456 UNSPECV_MONITORX)]
26457 "TARGET_MWAITX"
26458 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26459 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26460 ;; zero extended to 64bit, we only need to set up 32bit registers.
26461 "%^monitorx"
26462 [(set (attr "length")
26463 (symbol_ref ("(Pmode != word_mode) + 3")))])
26464
26465 ;; CLZERO
26466 (define_insn "@clzero_<mode>"
26467 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26468 UNSPECV_CLZERO)]
26469 "TARGET_CLZERO"
26470 "clzero"
26471 [(set_attr "length" "3")
26472 (set_attr "memory" "unknown")])
26473
26474 ;; RDPKRU and WRPKRU
26475
26476 (define_expand "rdpkru"
26477 [(parallel
26478 [(set (match_operand:SI 0 "register_operand")
26479 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26480 (set (match_dup 2) (const_int 0))])]
26481 "TARGET_PKU"
26482 {
26483 operands[1] = force_reg (SImode, const0_rtx);
26484 operands[2] = gen_reg_rtx (SImode);
26485 })
26486
26487 (define_insn "*rdpkru"
26488 [(set (match_operand:SI 0 "register_operand" "=a")
26489 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26490 UNSPECV_PKU))
26491 (set (match_operand:SI 1 "register_operand" "=d")
26492 (const_int 0))]
26493 "TARGET_PKU"
26494 "rdpkru"
26495 [(set_attr "type" "other")])
26496
26497 (define_expand "wrpkru"
26498 [(unspec_volatile:SI
26499 [(match_operand:SI 0 "register_operand")
26500 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26501 "TARGET_PKU"
26502 {
26503 operands[1] = force_reg (SImode, const0_rtx);
26504 operands[2] = force_reg (SImode, const0_rtx);
26505 })
26506
26507 (define_insn "*wrpkru"
26508 [(unspec_volatile:SI
26509 [(match_operand:SI 0 "register_operand" "a")
26510 (match_operand:SI 1 "register_operand" "d")
26511 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26512 "TARGET_PKU"
26513 "wrpkru"
26514 [(set_attr "type" "other")])
26515
26516 (define_insn "rdpid"
26517 [(set (match_operand:SI 0 "register_operand" "=r")
26518 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26519 "!TARGET_64BIT && TARGET_RDPID"
26520 "rdpid\t%0"
26521 [(set_attr "type" "other")])
26522
26523 (define_insn "rdpid_rex64"
26524 [(set (match_operand:DI 0 "register_operand" "=r")
26525 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26526 "TARGET_64BIT && TARGET_RDPID"
26527 "rdpid\t%0"
26528 [(set_attr "type" "other")])
26529
26530 ;; Intirinsics for > i486
26531
26532 (define_insn "wbinvd"
26533 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26534 ""
26535 "wbinvd"
26536 [(set_attr "type" "other")])
26537
26538 (define_insn "wbnoinvd"
26539 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26540 "TARGET_WBNOINVD"
26541 "wbnoinvd"
26542 [(set_attr "type" "other")])
26543
26544 ;; MOVDIRI and MOVDIR64B
26545
26546 (define_insn "movdiri<mode>"
26547 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26548 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26549 UNSPEC_MOVDIRI))]
26550 "TARGET_MOVDIRI"
26551 "movdiri\t{%1, %0|%0, %1}"
26552 [(set_attr "type" "other")])
26553
26554 (define_insn "@movdir64b_<mode>"
26555 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26556 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26557 UNSPEC_MOVDIR64B))]
26558 "TARGET_MOVDIR64B"
26559 "movdir64b\t{%1, %0|%0, %1}"
26560 [(set_attr "type" "other")])
26561
26562 ;; TSXLDTRK
26563 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26564 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26565 (UNSPECV_XRESLDTRK "xresldtrk")])
26566 (define_insn "<tsxldtrk>"
26567 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26568 "TARGET_TSXLDTRK"
26569 "<tsxldtrk>"
26570 [(set_attr "type" "other")
26571 (set_attr "length" "4")])
26572
26573 ;; ENQCMD and ENQCMDS
26574
26575 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26576 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26577
26578 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26579 [(set (reg:CCZ FLAGS_REG)
26580 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26581 (match_operand:XI 1 "memory_operand" "m")]
26582 ENQCMD))]
26583 "TARGET_ENQCMD"
26584 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26585 [(set_attr "type" "other")])
26586
26587 ;; UINTR
26588 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26589 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26590
26591 (define_insn "<uintr>"
26592 [(unspec_volatile [(const_int 0)] UINTR)]
26593 "TARGET_UINTR && TARGET_64BIT"
26594 "<uintr>"
26595 [(set_attr "type" "other")
26596 (set_attr "length" "4")])
26597
26598 (define_insn "testui"
26599 [(set (reg:CCC FLAGS_REG)
26600 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26601 "TARGET_UINTR && TARGET_64BIT"
26602 "testui"
26603 [(set_attr "type" "other")
26604 (set_attr "length" "4")])
26605
26606 (define_insn "senduipi"
26607 [(unspec_volatile
26608 [(match_operand:DI 0 "register_operand" "r")]
26609 UNSPECV_SENDUIPI)]
26610 "TARGET_UINTR && TARGET_64BIT"
26611 "senduipi\t%0"
26612 [(set_attr "type" "other")
26613 (set_attr "length" "4")])
26614
26615 ;; WAITPKG
26616
26617 (define_insn "umwait"
26618 [(set (reg:CCC FLAGS_REG)
26619 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26620 (match_operand:DI 1 "register_operand" "A")]
26621 UNSPECV_UMWAIT))]
26622 "!TARGET_64BIT && TARGET_WAITPKG"
26623 "umwait\t%0"
26624 [(set_attr "length" "3")])
26625
26626 (define_insn "umwait_rex64"
26627 [(set (reg:CCC FLAGS_REG)
26628 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26629 (match_operand:SI 1 "register_operand" "a")
26630 (match_operand:SI 2 "register_operand" "d")]
26631 UNSPECV_UMWAIT))]
26632 "TARGET_64BIT && TARGET_WAITPKG"
26633 "umwait\t%0"
26634 [(set_attr "length" "3")])
26635
26636 (define_insn "@umonitor_<mode>"
26637 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26638 UNSPECV_UMONITOR)]
26639 "TARGET_WAITPKG"
26640 "umonitor\t%0"
26641 [(set (attr "length")
26642 (symbol_ref ("(Pmode != word_mode) + 3")))])
26643
26644 (define_insn "tpause"
26645 [(set (reg:CCC FLAGS_REG)
26646 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26647 (match_operand:DI 1 "register_operand" "A")]
26648 UNSPECV_TPAUSE))]
26649 "!TARGET_64BIT && TARGET_WAITPKG"
26650 "tpause\t%0"
26651 [(set_attr "length" "3")])
26652
26653 (define_insn "tpause_rex64"
26654 [(set (reg:CCC FLAGS_REG)
26655 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26656 (match_operand:SI 1 "register_operand" "a")
26657 (match_operand:SI 2 "register_operand" "d")]
26658 UNSPECV_TPAUSE))]
26659 "TARGET_64BIT && TARGET_WAITPKG"
26660 "tpause\t%0"
26661 [(set_attr "length" "3")])
26662
26663 (define_insn "cldemote"
26664 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26665 UNSPECV_CLDEMOTE)]
26666 "TARGET_CLDEMOTE"
26667 "cldemote\t%a0"
26668 [(set_attr "type" "other")
26669 (set_attr "memory" "unknown")])
26670
26671 (define_insn "speculation_barrier"
26672 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26673 ""
26674 "lfence"
26675 [(set_attr "type" "other")
26676 (set_attr "length" "3")])
26677
26678 (define_insn "serialize"
26679 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26680 "TARGET_SERIALIZE"
26681 "serialize"
26682 [(set_attr "type" "other")
26683 (set_attr "length" "3")])
26684
26685 (define_insn "patchable_area"
26686 [(unspec_volatile [(match_operand 0 "const_int_operand")
26687 (match_operand 1 "const_int_operand")]
26688 UNSPECV_PATCHABLE_AREA)]
26689 ""
26690 {
26691 ix86_output_patchable_area (INTVAL (operands[0]),
26692 INTVAL (operands[1]) != 0);
26693 return "";
26694 }
26695 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26696 (set_attr "length_immediate" "0")
26697 (set_attr "modrm" "0")])
26698
26699 (define_insn "hreset"
26700 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26701 UNSPECV_HRESET)]
26702 "TARGET_HRESET"
26703 "hreset\t{$0|0}"
26704 [(set_attr "type" "other")
26705 (set_attr "length" "4")])
26706
26707 ;; Spaceship optimization
26708 (define_expand "spaceship<mode>3"
26709 [(match_operand:SI 0 "register_operand")
26710 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26711 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26712 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26713 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26714 {
26715 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26716 DONE;
26717 })
26718
26719 (define_expand "spaceshipxf3"
26720 [(match_operand:SI 0 "register_operand")
26721 (match_operand:XF 1 "nonmemory_operand")
26722 (match_operand:XF 2 "nonmemory_operand")]
26723 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26724 {
26725 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26726 DONE;
26727 })
26728
26729 ;; Defined because the generic expand_builtin_issignaling for XFmode
26730 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26731 ;; signaling.
26732 (define_expand "issignalingxf2"
26733 [(match_operand:SI 0 "register_operand")
26734 (match_operand:XF 1 "general_operand")]
26735 ""
26736 {
26737 rtx temp = operands[1];
26738 if (!MEM_P (temp))
26739 {
26740 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26741 emit_move_insn (mem, temp);
26742 temp = mem;
26743 }
26744 rtx ex = adjust_address (temp, HImode, 8);
26745 rtx hi = adjust_address (temp, SImode, 4);
26746 rtx lo = adjust_address (temp, SImode, 0);
26747 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26748 rtx mask = GEN_INT (0x7fff);
26749 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26750 /* Expand to:
26751 ((ex & mask) && (int) hi >= 0)
26752 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26753 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26754 lo = expand_binop (SImode, ior_optab, lo, nlo,
26755 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26756 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26757 temp = expand_binop (SImode, xor_optab, hi, bit,
26758 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26759 temp = expand_binop (SImode, ior_optab, temp, lo,
26760 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26761 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26762 SImode, 1, 1);
26763 ex = expand_binop (HImode, and_optab, ex, mask,
26764 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26765 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26766 ex, const0_rtx, SImode, 1, 1);
26767 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26768 ex, mask, HImode, 1, 1);
26769 temp = expand_binop (SImode, and_optab, temp, ex,
26770 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26771 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26772 hi, const0_rtx, SImode, 0, 1);
26773 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26774 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26775 temp = expand_binop (SImode, ior_optab, temp, temp2,
26776 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26777 emit_move_insn (operands[0], temp);
26778 DONE;
26779 })
26780
26781 (define_insn "urdmsr"
26782 [(set (match_operand:DI 0 "register_operand" "=r")
26783 (unspec_volatile:DI
26784 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
26785 UNSPECV_URDMSR))]
26786 "TARGET_USER_MSR && TARGET_64BIT"
26787 "urdmsr\t{%1, %0|%0, %1}"
26788 [(set_attr "prefix" "vex")
26789 (set_attr "type" "other")])
26790
26791 (define_insn "uwrmsr"
26792 [(unspec_volatile
26793 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
26794 (match_operand:DI 1 "register_operand" "r")]
26795 UNSPECV_UWRMSR)]
26796 "TARGET_USER_MSR && TARGET_64BIT"
26797 "uwrmsr\t{%1, %0|%0, %1}"
26798 [(set_attr "prefix" "vex")
26799 (set_attr "type" "other")])
26800
26801 (include "mmx.md")
26802 (include "sse.md")
26803 (include "sync.md")