]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
f5407ab305491f1eba355f06f6898e2af05902e6
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2023 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
21 ;;
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24 ;;
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;; otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;; delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81 UNSPEC_SIZEOF
82
83 ;; Prologue support
84 UNSPEC_STACK_ALLOC
85 UNSPEC_SET_GOT
86 UNSPEC_SET_RIP
87 UNSPEC_SET_GOT_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
89 UNSPEC_PROBE_STACK
90
91 ;; TLS support
92 UNSPEC_TP
93 UNSPEC_TLS_GD
94 UNSPEC_TLS_LD_BASE
95 UNSPEC_TLSDESC
96 UNSPEC_TLS_IE_SUN
97
98 ;; Other random patterns
99 UNSPEC_SCAS
100 UNSPEC_FNSTSW
101 UNSPEC_SAHF
102 UNSPEC_NOTRAP
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_REP
106 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_TRUNC_NOOP
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_PAUSE
110 UNSPEC_LEA_ADDR
111 UNSPEC_XBEGIN_ABORT
112 UNSPEC_STOS
113 UNSPEC_PEEPSIB
114 UNSPEC_INSN_FALSE_DEP
115 UNSPEC_SBB
116 UNSPEC_CC_NE
117 UNSPEC_STC
118 UNSPEC_PUSHFL
119 UNSPEC_POPFL
120
121 ;; For SSE/MMX support:
122 UNSPEC_FIX_NOTRUNC
123 UNSPEC_MASKMOV
124 UNSPEC_MOVCC_MASK
125 UNSPEC_MOVMSK
126 UNSPEC_INSERTPS
127 UNSPEC_BLENDV
128 UNSPEC_PSHUFB
129 UNSPEC_XOP_PERMUTE
130 UNSPEC_RCP
131 UNSPEC_RSQRT
132 UNSPEC_PSADBW
133
134 ;; Different from generic us_truncate RTX
135 ;; as it does unsigned saturation of signed source.
136 UNSPEC_US_TRUNCATE
137
138 ;; For AVX/AVX512F support
139 UNSPEC_SCALEF
140 UNSPEC_PCMP
141 UNSPEC_CVTBFSF
142
143 ;; Generic math support
144 UNSPEC_IEEE_MIN ; not commutative
145 UNSPEC_IEEE_MAX ; not commutative
146
147 ;; x87 Floating point
148 UNSPEC_SIN
149 UNSPEC_COS
150 UNSPEC_FPATAN
151 UNSPEC_FYL2X
152 UNSPEC_FYL2XP1
153 UNSPEC_FRNDINT
154 UNSPEC_FIST
155 UNSPEC_F2XM1
156 UNSPEC_TAN
157 UNSPEC_FXAM
158
159 ;; x87 Rounding
160 UNSPEC_FRNDINT_ROUNDEVEN
161 UNSPEC_FRNDINT_FLOOR
162 UNSPEC_FRNDINT_CEIL
163 UNSPEC_FRNDINT_TRUNC
164 UNSPEC_FIST_FLOOR
165 UNSPEC_FIST_CEIL
166
167 ;; x87 Double output FP
168 UNSPEC_SINCOS_COS
169 UNSPEC_SINCOS_SIN
170 UNSPEC_XTRACT_FRACT
171 UNSPEC_XTRACT_EXP
172 UNSPEC_FSCALE_FRACT
173 UNSPEC_FSCALE_EXP
174 UNSPEC_FPREM_F
175 UNSPEC_FPREM_U
176 UNSPEC_FPREM1_F
177 UNSPEC_FPREM1_U
178
179 UNSPEC_C2_FLAG
180 UNSPEC_FXAM_MEM
181
182 ;; SSP patterns
183 UNSPEC_SP_SET
184 UNSPEC_SP_TEST
185
186 ;; For ROUND support
187 UNSPEC_ROUND
188
189 ;; For CRC32 support
190 UNSPEC_CRC32
191
192 ;; For LZCNT suppoprt
193 UNSPEC_LZCNT
194
195 ;; For BMI support
196 UNSPEC_TZCNT
197 UNSPEC_BEXTR
198
199 ;; For BMI2 support
200 UNSPEC_PDEP
201 UNSPEC_PEXT
202
203 ;; IRET support
204 UNSPEC_INTERRUPT_RETURN
205
206 ;; For MOVDIRI and MOVDIR64B support
207 UNSPEC_MOVDIRI
208 UNSPEC_MOVDIR64B
209
210 ;; For insn_callee_abi:
211 UNSPEC_CALLEE_ABI
212
213 ;; For PUSH2/POP2 support
214 UNSPEC_APXPUSH2
215 UNSPEC_APXPOP2_LOW
216 UNSPEC_APXPOP2_HIGH
217 ])
218
219 (define_c_enum "unspecv" [
220 UNSPECV_UD2
221 UNSPECV_BLOCKAGE
222 UNSPECV_STACK_PROBE
223 UNSPECV_PROBE_STACK_RANGE
224 UNSPECV_ALIGN
225 UNSPECV_PROLOGUE_USE
226 UNSPECV_SPLIT_STACK_RETURN
227 UNSPECV_CLD
228 UNSPECV_NOPS
229 UNSPECV_RDTSC
230 UNSPECV_RDTSCP
231 UNSPECV_RDPMC
232 UNSPECV_LLWP_INTRINSIC
233 UNSPECV_SLWP_INTRINSIC
234 UNSPECV_LWPVAL_INTRINSIC
235 UNSPECV_LWPINS_INTRINSIC
236 UNSPECV_RDFSBASE
237 UNSPECV_RDGSBASE
238 UNSPECV_WRFSBASE
239 UNSPECV_WRGSBASE
240 UNSPECV_FXSAVE
241 UNSPECV_FXRSTOR
242 UNSPECV_FXSAVE64
243 UNSPECV_FXRSTOR64
244 UNSPECV_XSAVE
245 UNSPECV_XRSTOR
246 UNSPECV_XSAVE64
247 UNSPECV_XRSTOR64
248 UNSPECV_XSAVEOPT
249 UNSPECV_XSAVEOPT64
250 UNSPECV_XSAVES
251 UNSPECV_XRSTORS
252 UNSPECV_XSAVES64
253 UNSPECV_XRSTORS64
254 UNSPECV_XSAVEC
255 UNSPECV_XSAVEC64
256 UNSPECV_XGETBV
257 UNSPECV_XSETBV
258 UNSPECV_WBINVD
259 UNSPECV_WBNOINVD
260
261 ;; For atomic compound assignments.
262 UNSPECV_FNSTENV
263 UNSPECV_FLDENV
264 UNSPECV_FNSTSW
265 UNSPECV_FNCLEX
266
267 ;; For RDRAND support
268 UNSPECV_RDRAND
269
270 ;; For RDSEED support
271 UNSPECV_RDSEED
272
273 ;; For RTM support
274 UNSPECV_XBEGIN
275 UNSPECV_XEND
276 UNSPECV_XABORT
277 UNSPECV_XTEST
278
279 UNSPECV_NLGR
280
281 ;; For CLWB support
282 UNSPECV_CLWB
283
284 ;; For CLFLUSHOPT support
285 UNSPECV_CLFLUSHOPT
286
287 ;; For MONITORX and MWAITX support
288 UNSPECV_MONITORX
289 UNSPECV_MWAITX
290
291 ;; For CLZERO support
292 UNSPECV_CLZERO
293
294 ;; For RDPKRU and WRPKRU support
295 UNSPECV_PKU
296
297 ;; For RDPID support
298 UNSPECV_RDPID
299
300 ;; For CET support
301 UNSPECV_NOP_ENDBR
302 UNSPECV_NOP_RDSSP
303 UNSPECV_INCSSP
304 UNSPECV_SAVEPREVSSP
305 UNSPECV_RSTORSSP
306 UNSPECV_WRSS
307 UNSPECV_WRUSS
308 UNSPECV_SETSSBSY
309 UNSPECV_CLRSSBSY
310
311 ;; For TSXLDTRK support
312 UNSPECV_XSUSLDTRK
313 UNSPECV_XRESLDTRK
314
315 ;; For WAITPKG support
316 UNSPECV_UMWAIT
317 UNSPECV_UMONITOR
318 UNSPECV_TPAUSE
319
320 ;; For UINTR support
321 UNSPECV_CLUI
322 UNSPECV_STUI
323 UNSPECV_TESTUI
324 UNSPECV_SENDUIPI
325
326 ;; For CLDEMOTE support
327 UNSPECV_CLDEMOTE
328
329 ;; For Speculation Barrier support
330 UNSPECV_SPECULATION_BARRIER
331
332 UNSPECV_PTWRITE
333
334 ;; For ENQCMD and ENQCMDS support
335 UNSPECV_ENQCMD
336 UNSPECV_ENQCMDS
337
338 ;; For SERIALIZE support
339 UNSPECV_SERIALIZE
340
341 ;; For patchable area support
342 UNSPECV_PATCHABLE_AREA
343
344 ;; For HRESET support
345 UNSPECV_HRESET
346
347 ;; For PREFETCHI support
348 UNSPECV_PREFETCHI
349
350 ;; For USER_MSR support
351 UNSPECV_URDMSR
352 UNSPECV_UWRMSR
353 ])
354
355 ;; Constants to represent rounding modes in the ROUND instruction
356 (define_constants
357 [(ROUND_ROUNDEVEN 0x0)
358 (ROUND_FLOOR 0x1)
359 (ROUND_CEIL 0x2)
360 (ROUND_TRUNC 0x3)
361 (ROUND_MXCSR 0x4)
362 (ROUND_NO_EXC 0x8)
363 ])
364
365 ;; Constants to represent AVX512F embeded rounding
366 (define_constants
367 [(ROUND_NEAREST_INT 0)
368 (ROUND_NEG_INF 1)
369 (ROUND_POS_INF 2)
370 (ROUND_ZERO 3)
371 (NO_ROUND 4)
372 (ROUND_SAE 8)
373 ])
374
375 ;; Constants to represent pcomtrue/pcomfalse variants
376 (define_constants
377 [(PCOM_FALSE 0)
378 (PCOM_TRUE 1)
379 (COM_FALSE_S 2)
380 (COM_FALSE_P 3)
381 (COM_TRUE_S 4)
382 (COM_TRUE_P 5)
383 ])
384
385 ;; Constants used in the XOP pperm instruction
386 (define_constants
387 [(PPERM_SRC 0x00) /* copy source */
388 (PPERM_INVERT 0x20) /* invert source */
389 (PPERM_REVERSE 0x40) /* bit reverse source */
390 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
391 (PPERM_ZERO 0x80) /* all 0's */
392 (PPERM_ONES 0xa0) /* all 1's */
393 (PPERM_SIGN 0xc0) /* propagate sign bit */
394 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
395 (PPERM_SRC1 0x00) /* use first source byte */
396 (PPERM_SRC2 0x10) /* use second source byte */
397 ])
398
399 ;; Registers by name.
400 (define_constants
401 [(AX_REG 0)
402 (DX_REG 1)
403 (CX_REG 2)
404 (BX_REG 3)
405 (SI_REG 4)
406 (DI_REG 5)
407 (BP_REG 6)
408 (SP_REG 7)
409 (ST0_REG 8)
410 (ST1_REG 9)
411 (ST2_REG 10)
412 (ST3_REG 11)
413 (ST4_REG 12)
414 (ST5_REG 13)
415 (ST6_REG 14)
416 (ST7_REG 15)
417 (ARGP_REG 16)
418 (FLAGS_REG 17)
419 (FPSR_REG 18)
420 (FRAME_REG 19)
421 (XMM0_REG 20)
422 (XMM1_REG 21)
423 (XMM2_REG 22)
424 (XMM3_REG 23)
425 (XMM4_REG 24)
426 (XMM5_REG 25)
427 (XMM6_REG 26)
428 (XMM7_REG 27)
429 (MM0_REG 28)
430 (MM1_REG 29)
431 (MM2_REG 30)
432 (MM3_REG 31)
433 (MM4_REG 32)
434 (MM5_REG 33)
435 (MM6_REG 34)
436 (MM7_REG 35)
437 (R8_REG 36)
438 (R9_REG 37)
439 (R10_REG 38)
440 (R11_REG 39)
441 (R12_REG 40)
442 (R13_REG 41)
443 (R14_REG 42)
444 (R15_REG 43)
445 (XMM8_REG 44)
446 (XMM9_REG 45)
447 (XMM10_REG 46)
448 (XMM11_REG 47)
449 (XMM12_REG 48)
450 (XMM13_REG 49)
451 (XMM14_REG 50)
452 (XMM15_REG 51)
453 (XMM16_REG 52)
454 (XMM17_REG 53)
455 (XMM18_REG 54)
456 (XMM19_REG 55)
457 (XMM20_REG 56)
458 (XMM21_REG 57)
459 (XMM22_REG 58)
460 (XMM23_REG 59)
461 (XMM24_REG 60)
462 (XMM25_REG 61)
463 (XMM26_REG 62)
464 (XMM27_REG 63)
465 (XMM28_REG 64)
466 (XMM29_REG 65)
467 (XMM30_REG 66)
468 (XMM31_REG 67)
469 (MASK0_REG 68)
470 (MASK1_REG 69)
471 (MASK2_REG 70)
472 (MASK3_REG 71)
473 (MASK4_REG 72)
474 (MASK5_REG 73)
475 (MASK6_REG 74)
476 (MASK7_REG 75)
477 (R16_REG 76)
478 (R17_REG 77)
479 (R18_REG 78)
480 (R19_REG 79)
481 (R20_REG 80)
482 (R21_REG 81)
483 (R22_REG 82)
484 (R23_REG 83)
485 (R24_REG 84)
486 (R25_REG 85)
487 (R26_REG 86)
488 (R27_REG 87)
489 (R28_REG 88)
490 (R29_REG 89)
491 (R30_REG 90)
492 (R31_REG 91)
493 (FIRST_PSEUDO_REG 92)
494 ])
495
496 ;; Insn callee abi index.
497 (define_constants
498 [(ABI_DEFAULT 0)
499 (ABI_VZEROUPPER 1)
500 (ABI_UNKNOWN 2)])
501
502 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
503 ;; from i386.cc.
504
505 ;; In C guard expressions, put expressions which may be compile-time
506 ;; constants first. This allows for better optimization. For
507 ;; example, write "TARGET_64BIT && reload_completed", not
508 ;; "reload_completed && TARGET_64BIT".
509
510 \f
511 ;; Processor type.
512 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
513 atom,slm,glm,haswell,generic,lujiazui,yongfeng,amdfam10,bdver1,
514 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
515 (const (symbol_ref "ix86_schedule")))
516
517 ;; A basic instruction type. Refinements due to arguments to be
518 ;; provided in other attributes.
519 (define_attr "type"
520 "other,multi,
521 alu,alu1,negnot,imov,imovx,lea,
522 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
523 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
524 push,pop,call,callv,leave,
525 str,bitmanip,
526 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
527 fxch,fistp,fisttp,frndint,
528 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
529 ssemul,sseimul,ssediv,sselog,sselog1,
530 sseishft,sseishft1,ssecmp,ssecomi,
531 ssecvt,ssecvt1,sseicvt,sseins,
532 sseshuf,sseshuf1,ssemuladd,sse4arg,
533 lwp,mskmov,msklog,
534 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
535 (const_string "other"))
536
537 ;; Main data type used by the insn
538 (define_attr "mode"
539 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
540 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
541 (const_string "unknown"))
542
543 ;; The CPU unit operations uses.
544 (define_attr "unit" "integer,i387,sse,mmx,unknown"
545 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
546 fxch,fistp,fisttp,frndint")
547 (const_string "i387")
548 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
549 ssemul,sseimul,ssediv,sselog,sselog1,
550 sseishft,sseishft1,ssecmp,ssecomi,
551 ssecvt,ssecvt1,sseicvt,sseins,
552 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
553 (const_string "sse")
554 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
555 (const_string "mmx")
556 (eq_attr "type" "other")
557 (const_string "unknown")]
558 (const_string "integer")))
559
560 ;; Used to control the "enabled" attribute on a per-instruction basis.
561 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
562 x64_avx,x64_avx512bw,x64_avx512dq,aes,
563 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
564 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,avx512f_512,
565 noavx512f,avx512bw,avx512bw_512,noavx512bw,avx512dq,
566 noavx512dq,fma_or_avx512vl,avx512vl,noavx512vl,avxvnni,
567 avx512vnnivl,avx512fp16,avxifma,avx512ifmavl,avxneconvert,
568 avx512bf16vl,vpclmulqdqvl,avx_noavx512f,avx_noavx512vl"
569 (const_string "base"))
570
571 ;; The (bounding maximum) length of an instruction immediate.
572 (define_attr "length_immediate" ""
573 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
574 bitmanip,imulx,msklog,mskmov")
575 (const_int 0)
576 (ior (eq_attr "type" "sse4arg")
577 (eq_attr "isa" "fma4"))
578 (const_int 1)
579 (eq_attr "unit" "i387,sse,mmx")
580 (const_int 0)
581 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
582 rotate,rotatex,rotate1,imul,icmp,push,pop")
583 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
584 (eq_attr "type" "imov,test")
585 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
586 (eq_attr "type" "call")
587 (if_then_else (match_operand 0 "constant_call_address_operand")
588 (const_int 4)
589 (const_int 0))
590 (eq_attr "type" "callv")
591 (if_then_else (match_operand 1 "constant_call_address_operand")
592 (const_int 4)
593 (const_int 0))
594 ;; We don't know the size before shorten_branches. Expect
595 ;; the instruction to fit for better scheduling.
596 (eq_attr "type" "ibr")
597 (const_int 1)
598 ]
599 (symbol_ref "/* Update immediate_length and other attributes! */
600 gcc_unreachable (),1")))
601
602 ;; The (bounding maximum) length of an instruction address.
603 (define_attr "length_address" ""
604 (cond [(eq_attr "type" "str,other,multi,fxch")
605 (const_int 0)
606 (and (eq_attr "type" "call")
607 (match_operand 0 "constant_call_address_operand"))
608 (const_int 0)
609 (and (eq_attr "type" "callv")
610 (match_operand 1 "constant_call_address_operand"))
611 (const_int 0)
612 ]
613 (symbol_ref "ix86_attr_length_address_default (insn)")))
614
615 ;; Set when length prefix is used.
616 (define_attr "prefix_data16" ""
617 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
618 (const_int 0)
619 (eq_attr "mode" "HI")
620 (const_int 1)
621 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
622 (const_int 1)
623 ]
624 (const_int 0)))
625
626 ;; Set when string REP prefix is used.
627 (define_attr "prefix_rep" ""
628 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
629 (const_int 0)
630 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
631 (const_int 1)
632 ]
633 (const_int 0)))
634
635 ;; Set when 0f opcode prefix is used.
636 (define_attr "prefix_0f" ""
637 (if_then_else
638 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
639 (eq_attr "unit" "sse,mmx"))
640 (const_int 1)
641 (const_int 0)))
642
643 ;; Set when REX opcode prefix is used.
644 (define_attr "prefix_rex" ""
645 (cond [(not (match_test "TARGET_64BIT"))
646 (const_int 0)
647 (and (eq_attr "mode" "DI")
648 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
649 (eq_attr "unit" "!mmx")))
650 (const_int 1)
651 (and (eq_attr "mode" "QI")
652 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
653 (const_int 1)
654 (match_test "x86_extended_reg_mentioned_p (insn)")
655 (const_int 1)
656 (and (eq_attr "type" "imovx")
657 (match_operand:QI 1 "ext_QIreg_operand"))
658 (const_int 1)
659 ]
660 (const_int 0)))
661
662 ;; There are also additional prefixes in 3DNOW, SSSE3.
663 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
664 ;; While generally inapplicable to VEX/XOP/EVEX encodings, "length_vex" uses
665 ;; the attribute evaluating to zero to know that VEX2 encoding may be usable.
666 (define_attr "prefix_extra" ""
667 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
668 (const_int 1)
669 ]
670 (const_int 0)))
671
672 ;; Prefix used: original, VEX or maybe VEX.
673 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
674 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
675 (const_string "vex")
676 (eq_attr "mode" "XI,V16SF,V8DF")
677 (const_string "evex")
678 (eq_attr "type" "ssemuladd")
679 (if_then_else (eq_attr "isa" "fma4")
680 (const_string "vex")
681 (const_string "maybe_evex"))
682 (eq_attr "type" "sse4arg")
683 (const_string "vex")
684 ]
685 (const_string "orig")))
686
687 ;; VEX W bit is used.
688 (define_attr "prefix_vex_w" "" (const_int 0))
689
690 ;; The length of VEX prefix
691 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
692 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
693 ;; still prefix_0f 1, with prefix_extra 1.
694 (define_attr "length_vex" ""
695 (if_then_else (and (eq_attr "prefix_0f" "1")
696 (eq_attr "prefix_extra" "0"))
697 (if_then_else (eq_attr "prefix_vex_w" "1")
698 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
699 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
700 (if_then_else (eq_attr "prefix_vex_w" "1")
701 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
702 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
703
704 ;; 4-bytes evex prefix and 1 byte opcode.
705 (define_attr "length_evex" "" (const_int 5))
706
707 ;; Set when modrm byte is used.
708 (define_attr "modrm" ""
709 (cond [(eq_attr "type" "str,leave")
710 (const_int 0)
711 (eq_attr "unit" "i387")
712 (const_int 0)
713 (and (eq_attr "type" "incdec")
714 (and (not (match_test "TARGET_64BIT"))
715 (ior (match_operand:SI 1 "register_operand")
716 (match_operand:HI 1 "register_operand"))))
717 (const_int 0)
718 (and (eq_attr "type" "push")
719 (not (match_operand 1 "memory_operand")))
720 (const_int 0)
721 (and (eq_attr "type" "pop")
722 (not (match_operand 0 "memory_operand")))
723 (const_int 0)
724 (and (eq_attr "type" "imov")
725 (and (not (eq_attr "mode" "DI"))
726 (ior (and (match_operand 0 "register_operand")
727 (match_operand 1 "immediate_operand"))
728 (ior (and (match_operand 0 "ax_reg_operand")
729 (match_operand 1 "memory_displacement_only_operand"))
730 (and (match_operand 0 "memory_displacement_only_operand")
731 (match_operand 1 "ax_reg_operand"))))))
732 (const_int 0)
733 (and (eq_attr "type" "call")
734 (match_operand 0 "constant_call_address_operand"))
735 (const_int 0)
736 (and (eq_attr "type" "callv")
737 (match_operand 1 "constant_call_address_operand"))
738 (const_int 0)
739 (and (eq_attr "type" "alu,alu1,icmp,test")
740 (match_operand 0 "ax_reg_operand"))
741 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
742 ]
743 (const_int 1)))
744
745 ;; The (bounding maximum) length of an instruction in bytes.
746 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
747 ;; Later we may want to split them and compute proper length as for
748 ;; other insns.
749 (define_attr "length" ""
750 (cond [(eq_attr "type" "other,multi,fistp,frndint")
751 (const_int 16)
752 (eq_attr "type" "fcmp")
753 (const_int 4)
754 (eq_attr "unit" "i387")
755 (plus (const_int 2)
756 (plus (attr "prefix_data16")
757 (attr "length_address")))
758 (ior (eq_attr "prefix" "evex")
759 (and (ior (eq_attr "prefix" "maybe_evex")
760 (eq_attr "prefix" "maybe_vex"))
761 (match_test "TARGET_AVX512F")))
762 (plus (attr "length_evex")
763 (plus (attr "length_immediate")
764 (plus (attr "modrm")
765 (attr "length_address"))))
766 (ior (eq_attr "prefix" "vex")
767 (and (ior (eq_attr "prefix" "maybe_vex")
768 (eq_attr "prefix" "maybe_evex"))
769 (match_test "TARGET_AVX")))
770 (plus (attr "length_vex")
771 (plus (attr "length_immediate")
772 (plus (attr "modrm")
773 (attr "length_address"))))]
774 (plus (plus (attr "modrm")
775 (plus (attr "prefix_0f")
776 (plus (attr "prefix_rex")
777 (plus (attr "prefix_extra")
778 (const_int 1)))))
779 (plus (attr "prefix_rep")
780 (plus (attr "prefix_data16")
781 (plus (attr "length_immediate")
782 (attr "length_address")))))))
783
784 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
785 ;; `store' if there is a simple memory reference therein, or `unknown'
786 ;; if the instruction is complex.
787
788 (define_attr "memory" "none,load,store,both,unknown"
789 (cond [(eq_attr "type" "other,multi,str,lwp")
790 (const_string "unknown")
791 (eq_attr "type" "lea,fcmov,fpspc")
792 (const_string "none")
793 (eq_attr "type" "fistp,leave")
794 (const_string "both")
795 (eq_attr "type" "frndint")
796 (const_string "load")
797 (eq_attr "type" "push")
798 (if_then_else (match_operand 1 "memory_operand")
799 (const_string "both")
800 (const_string "store"))
801 (eq_attr "type" "pop")
802 (if_then_else (match_operand 0 "memory_operand")
803 (const_string "both")
804 (const_string "load"))
805 (eq_attr "type" "setcc")
806 (if_then_else (match_operand 0 "memory_operand")
807 (const_string "store")
808 (const_string "none"))
809 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
810 (if_then_else (ior (match_operand 0 "memory_operand")
811 (match_operand 1 "memory_operand"))
812 (const_string "load")
813 (const_string "none"))
814 (eq_attr "type" "ibr")
815 (if_then_else (match_operand 0 "memory_operand")
816 (const_string "load")
817 (const_string "none"))
818 (eq_attr "type" "call")
819 (if_then_else (match_operand 0 "constant_call_address_operand")
820 (const_string "none")
821 (const_string "load"))
822 (eq_attr "type" "callv")
823 (if_then_else (match_operand 1 "constant_call_address_operand")
824 (const_string "none")
825 (const_string "load"))
826 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
827 (match_operand 1 "memory_operand"))
828 (const_string "both")
829 (and (match_operand 0 "memory_operand")
830 (match_operand 1 "memory_operand"))
831 (const_string "both")
832 (match_operand 0 "memory_operand")
833 (const_string "store")
834 (match_operand 1 "memory_operand")
835 (const_string "load")
836 (and (eq_attr "type"
837 "!alu1,negnot,ishift1,rotate1,
838 imov,imovx,icmp,test,bitmanip,
839 fmov,fcmp,fsgn,
840 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
841 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
842 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
843 (match_operand 2 "memory_operand"))
844 (const_string "load")
845 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
846 (match_operand 3 "memory_operand"))
847 (const_string "load")
848 ]
849 (const_string "none")))
850
851 ;; Indicates if an instruction has both an immediate and a displacement.
852
853 (define_attr "imm_disp" "false,true,unknown"
854 (cond [(eq_attr "type" "other,multi")
855 (const_string "unknown")
856 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
857 (and (match_operand 0 "memory_displacement_operand")
858 (match_operand 1 "immediate_operand")))
859 (const_string "true")
860 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
861 (and (match_operand 0 "memory_displacement_operand")
862 (match_operand 2 "immediate_operand")))
863 (const_string "true")
864 ]
865 (const_string "false")))
866
867 ;; Indicates if an FP operation has an integer source.
868
869 (define_attr "fp_int_src" "false,true"
870 (const_string "false"))
871
872 ;; Defines rounding mode of an FP operation.
873
874 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
875 (const_string "any"))
876
877 ;; Define attribute to indicate AVX insns with partial XMM register update.
878 (define_attr "avx_partial_xmm_update" "false,true"
879 (const_string "false"))
880
881 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
882 (define_attr "use_carry" "0,1" (const_string "0"))
883
884 ;; Define attribute to indicate unaligned ssemov insns
885 (define_attr "movu" "0,1" (const_string "0"))
886
887 ;; Define attribute to limit memory address register set.
888 (define_attr "addr" "gpr8,gpr16,gpr32" (const_string "gpr32"))
889
890 ;; Define instruction set of MMX instructions
891 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
892 (const_string "base"))
893
894 (define_attr "enabled" ""
895 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
896 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
897 (eq_attr "isa" "x64_sse2")
898 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
899 (eq_attr "isa" "x64_sse4")
900 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
901 (eq_attr "isa" "x64_sse4_noavx")
902 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
903 (eq_attr "isa" "x64_avx")
904 (symbol_ref "TARGET_64BIT && TARGET_AVX")
905 (eq_attr "isa" "x64_avx512bw")
906 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
907 (eq_attr "isa" "x64_avx512dq")
908 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
909 (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
910 (eq_attr "isa" "sse_noavx")
911 (symbol_ref "TARGET_SSE && !TARGET_AVX")
912 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
913 (eq_attr "isa" "sse2_noavx")
914 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
915 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
916 (eq_attr "isa" "sse3_noavx")
917 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
918 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
919 (eq_attr "isa" "sse4_noavx")
920 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
921 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
922 (eq_attr "isa" "avx_noavx512f")
923 (symbol_ref "TARGET_AVX && !TARGET_AVX512F")
924 (eq_attr "isa" "avx_noavx512vl")
925 (symbol_ref "TARGET_AVX && !TARGET_AVX512VL")
926 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
927 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
928 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
929 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
930 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
931 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
932 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
933 (eq_attr "isa" "fma_or_avx512vl")
934 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
935 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
936 (eq_attr "isa" "avx512f_512")
937 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512")
938 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
939 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
940 (eq_attr "isa" "avx512bw_512")
941 (symbol_ref "TARGET_AVX512BW && TARGET_EVEX512")
942 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
943 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
944 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
945 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
946 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
947 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
948 (eq_attr "isa" "avx512vnnivl")
949 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
950 (eq_attr "isa" "avx512fp16")
951 (symbol_ref "TARGET_AVX512FP16")
952 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
953 (eq_attr "isa" "avx512ifmavl")
954 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
955 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
956 (eq_attr "isa" "avx512bf16vl")
957 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
958 (eq_attr "isa" "vpclmulqdqvl")
959 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
960
961 (eq_attr "mmx_isa" "native")
962 (symbol_ref "!TARGET_MMX_WITH_SSE")
963 (eq_attr "mmx_isa" "sse")
964 (symbol_ref "TARGET_MMX_WITH_SSE")
965 (eq_attr "mmx_isa" "sse_noavx")
966 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
967 (eq_attr "mmx_isa" "avx")
968 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
969 ]
970 (const_int 1)))
971
972 (define_attr "preferred_for_size" "" (const_int 1))
973 (define_attr "preferred_for_speed" "" (const_int 1))
974
975 ;; Describe a user's asm statement.
976 (define_asm_attributes
977 [(set_attr "length" "128")
978 (set_attr "type" "multi")])
979
980 (define_code_iterator plusminus [plus minus])
981 (define_code_iterator plusminusmult [plus minus mult])
982 (define_code_iterator plusminusmultdiv [plus minus mult div])
983
984 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
985
986 ;; Base name for insn mnemonic.
987 (define_code_attr plusminus_mnemonic
988 [(plus "add") (ss_plus "adds") (us_plus "addus")
989 (minus "sub") (ss_minus "subs") (us_minus "subus")])
990
991 (define_code_iterator multdiv [mult div])
992
993 (define_code_attr multdiv_mnemonic
994 [(mult "mul") (div "div")])
995
996 ;; Mark commutative operators as such in constraints.
997 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
998 (minus "") (ss_minus "") (us_minus "")
999 (mult "%") (div "")])
1000
1001 ;; Mapping of max and min
1002 (define_code_iterator maxmin [smax smin umax umin])
1003
1004 ;; Mapping of signed max and min
1005 (define_code_iterator smaxmin [smax smin])
1006
1007 ;; Mapping of unsigned max and min
1008 (define_code_iterator umaxmin [umax umin])
1009
1010 ;; Base name for integer and FP insn mnemonic
1011 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
1012 (umax "maxu") (umin "minu")])
1013 (define_code_attr maxmin_float [(smax "max") (smin "min")])
1014
1015 (define_int_iterator IEEE_MAXMIN
1016 [UNSPEC_IEEE_MAX
1017 UNSPEC_IEEE_MIN])
1018
1019 (define_int_attr ieee_maxmin
1020 [(UNSPEC_IEEE_MAX "max")
1021 (UNSPEC_IEEE_MIN "min")])
1022
1023 ;; Mapping of logic operators
1024 (define_code_iterator any_logic [and ior xor])
1025 (define_code_iterator any_or [ior xor])
1026 (define_code_iterator fpint_logic [and xor])
1027
1028 ;; Base name for insn mnemonic.
1029 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
1030
1031 ;; Mapping of logic-shift operators
1032 (define_code_iterator any_lshift [ashift lshiftrt])
1033
1034 ;; Mapping of shift-right operators
1035 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
1036
1037 ;; Mapping of all shift operators
1038 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
1039
1040 ;; Base name for insn mnemonic.
1041 (define_code_attr shift [(ashift "sal") (lshiftrt "shr") (ashiftrt "sar")])
1042 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
1043
1044 ;; Mapping of rotate operators
1045 (define_code_iterator any_rotate [rotate rotatert])
1046
1047 ;; Base name for insn mnemonic.
1048 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1049
1050 ;; Mapping of abs neg operators
1051 (define_code_iterator absneg [abs neg])
1052
1053 ;; Mapping of abs neg operators to logic operation
1054 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1055
1056 ;; Base name for x87 insn mnemonic.
1057 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1058
1059 ;; Mapping of extend operators
1060 (define_code_iterator any_extend [sign_extend zero_extend])
1061
1062 ;; Mapping of highpart multiply operators
1063 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1064
1065 ;; Prefix for insn menmonic.
1066 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1067 (smul_highpart "i") (umul_highpart "")
1068 (div "i") (udiv "")])
1069 ;; Prefix for define_insn
1070 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1071 (smul_highpart "s") (umul_highpart "u")])
1072 (define_code_attr u [(sign_extend "") (zero_extend "u")
1073 (div "") (udiv "u")])
1074 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1075 (div "false") (udiv "true")])
1076
1077 ;; Used in signed and unsigned truncations.
1078 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1079 ;; Instruction suffix for truncations.
1080 (define_code_attr trunsuffix
1081 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1082
1083 ;; Instruction suffix for SSE sign and zero extensions.
1084 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1085
1086 ;; Used in signed and unsigned fix.
1087 (define_code_iterator any_fix [fix unsigned_fix])
1088 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1089 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1090 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1091
1092 ;; Used in signed and unsigned float.
1093 (define_code_iterator any_float [float unsigned_float])
1094 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1095 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1096 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1097
1098 ;; Base name for expression
1099 (define_code_attr insn
1100 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1101 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1102 (sign_extend "extend") (zero_extend "zero_extend")
1103 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1104 (rotate "rotl") (rotatert "rotr")
1105 (mult "mul") (div "div")])
1106
1107 ;; All integer modes.
1108 (define_mode_iterator SWI1248x [QI HI SI DI])
1109
1110 ;; All integer modes without QImode.
1111 (define_mode_iterator SWI248x [HI SI DI])
1112
1113 ;; All integer modes without QImode and HImode.
1114 (define_mode_iterator SWI48x [SI DI])
1115
1116 ;; All integer modes without SImode and DImode.
1117 (define_mode_iterator SWI12 [QI HI])
1118
1119 ;; All integer modes without DImode.
1120 (define_mode_iterator SWI124 [QI HI SI])
1121
1122 ;; All integer modes without QImode and DImode.
1123 (define_mode_iterator SWI24 [HI SI])
1124
1125 ;; Single word integer modes.
1126 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1127
1128 ;; Single word integer modes without QImode.
1129 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1130
1131 ;; Single word integer modes without QImode and HImode.
1132 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1133
1134 ;; All math-dependant single and double word integer modes.
1135 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1136 (HI "TARGET_HIMODE_MATH")
1137 SI DI (TI "TARGET_64BIT")])
1138
1139 ;; Math-dependant single word integer modes.
1140 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1141 (HI "TARGET_HIMODE_MATH")
1142 SI (DI "TARGET_64BIT")])
1143
1144 ;; Math-dependant integer modes without DImode.
1145 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1146 (HI "TARGET_HIMODE_MATH")
1147 SI])
1148
1149 ;; Math-dependant integer modes with DImode.
1150 (define_mode_iterator SWIM1248x
1151 [(QI "TARGET_QIMODE_MATH")
1152 (HI "TARGET_HIMODE_MATH")
1153 SI DI])
1154
1155 ;; Math-dependant single word integer modes without QImode.
1156 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1157 SI (DI "TARGET_64BIT")])
1158
1159 ;; Double word integer modes.
1160 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1161 (TI "TARGET_64BIT")])
1162
1163 ;; SWI and DWI together.
1164 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1165
1166 ;; SWI48 and DWI together.
1167 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1168
1169 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1170 ;; compile time constant, it is faster to use <MODE_SIZE> than
1171 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1172 ;; command line options just use GET_MODE_SIZE macro.
1173 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1174 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1175 (XF "GET_MODE_SIZE (XFmode)")
1176 (V16QI "16") (V32QI "32") (V64QI "64")
1177 (V8HI "16") (V16HI "32") (V32HI "64")
1178 (V4SI "16") (V8SI "32") (V16SI "64")
1179 (V2DI "16") (V4DI "32") (V8DI "64")
1180 (V1TI "16") (V2TI "32") (V4TI "64")
1181 (V2DF "16") (V4DF "32") (V8DF "64")
1182 (V4SF "16") (V8SF "32") (V16SF "64")
1183 (V8HF "16") (V16HF "32") (V32HF "64")
1184 (V4HF "8") (V2HF "4")
1185 (V8BF "16") (V16BF "32") (V32BF "64")
1186 (V4BF "8") (V2BF "4")])
1187
1188 ;; Double word integer modes as mode attribute.
1189 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1190 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1191
1192 ;; Half sized integer modes.
1193 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1194 (define_mode_attr half [(TI "di") (DI "si")])
1195
1196 ;; LEA mode corresponding to an integer mode
1197 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1198
1199 ;; Half mode for double word integer modes.
1200 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1201 (DI "TARGET_64BIT")])
1202
1203 ;; Instruction suffix for integer modes.
1204 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1205
1206 ;; Instruction suffix for masks.
1207 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1208
1209 ;; Pointer size prefix for integer modes (Intel asm dialect)
1210 (define_mode_attr iptrsize [(QI "BYTE")
1211 (HI "WORD")
1212 (SI "DWORD")
1213 (DI "QWORD")])
1214
1215 ;; Register class for integer modes.
1216 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1217
1218 ;; Immediate operand constraint for integer modes.
1219 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1220
1221 ;; General operand constraint for word modes.
1222 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1223
1224 ;; Memory operand constraint for word modes.
1225 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1226
1227 ;; Immediate operand constraint for double integer modes.
1228 (define_mode_attr di [(SI "nF") (DI "Wd")])
1229
1230 ;; Immediate operand constraint for shifts.
1231 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1232 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1233
1234 ;; Print register name in the specified mode.
1235 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1236
1237 ;; General operand predicate for integer modes.
1238 (define_mode_attr general_operand
1239 [(QI "general_operand")
1240 (HI "general_operand")
1241 (SI "x86_64_general_operand")
1242 (DI "x86_64_general_operand")
1243 (TI "x86_64_general_operand")])
1244
1245 ;; General operand predicate for integer modes, where for TImode
1246 ;; we need both words of the operand to be general operands.
1247 (define_mode_attr general_hilo_operand
1248 [(QI "general_operand")
1249 (HI "general_operand")
1250 (SI "x86_64_general_operand")
1251 (DI "x86_64_general_operand")
1252 (TI "x86_64_hilo_general_operand")])
1253
1254 ;; General sign extend operand predicate for integer modes,
1255 ;; which disallows VOIDmode operands and thus it is suitable
1256 ;; for use inside sign_extend.
1257 (define_mode_attr general_sext_operand
1258 [(QI "sext_operand")
1259 (HI "sext_operand")
1260 (SI "x86_64_sext_operand")
1261 (DI "x86_64_sext_operand")])
1262
1263 ;; General sign/zero extend operand predicate for integer modes.
1264 (define_mode_attr general_szext_operand
1265 [(QI "general_operand")
1266 (HI "general_operand")
1267 (SI "x86_64_szext_general_operand")
1268 (DI "x86_64_szext_general_operand")
1269 (TI "x86_64_hilo_general_operand")])
1270
1271 (define_mode_attr nonmemory_szext_operand
1272 [(QI "nonmemory_operand")
1273 (HI "nonmemory_operand")
1274 (SI "x86_64_szext_nonmemory_operand")
1275 (DI "x86_64_szext_nonmemory_operand")])
1276
1277 ;; Immediate operand predicate for integer modes.
1278 (define_mode_attr immediate_operand
1279 [(QI "immediate_operand")
1280 (HI "immediate_operand")
1281 (SI "x86_64_immediate_operand")
1282 (DI "x86_64_immediate_operand")])
1283
1284 ;; Nonmemory operand predicate for integer modes.
1285 (define_mode_attr nonmemory_operand
1286 [(QI "nonmemory_operand")
1287 (HI "nonmemory_operand")
1288 (SI "x86_64_nonmemory_operand")
1289 (DI "x86_64_nonmemory_operand")])
1290
1291 ;; Operand predicate for shifts.
1292 (define_mode_attr shift_operand
1293 [(QI "nonimmediate_operand")
1294 (HI "nonimmediate_operand")
1295 (SI "nonimmediate_operand")
1296 (DI "shiftdi_operand")
1297 (TI "register_operand")])
1298
1299 ;; Operand predicate for shift argument.
1300 (define_mode_attr shift_immediate_operand
1301 [(QI "const_1_to_31_operand")
1302 (HI "const_1_to_31_operand")
1303 (SI "const_1_to_31_operand")
1304 (DI "const_1_to_63_operand")])
1305
1306 ;; Input operand predicate for arithmetic left shifts.
1307 (define_mode_attr ashl_input_operand
1308 [(QI "nonimmediate_operand")
1309 (HI "nonimmediate_operand")
1310 (SI "nonimmediate_operand")
1311 (DI "ashldi_input_operand")
1312 (TI "reg_or_pm1_operand")])
1313
1314 ;; SSE and x87 SFmode and DFmode floating point modes
1315 (define_mode_iterator MODEF [SF DF])
1316
1317 ;; SSE floating point modes
1318 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1319
1320 ;; All x87 floating point modes
1321 (define_mode_iterator X87MODEF [SF DF XF])
1322
1323 ;; All x87 floating point modes plus HFmode
1324 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1325
1326 ;; All SSE floating point modes
1327 (define_mode_iterator SSEMODEF [HF SF DF TF])
1328 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1329
1330 ;; SSE instruction suffix for various modes
1331 (define_mode_attr ssemodesuffix
1332 [(HF "sh") (SF "ss") (DF "sd")
1333 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1334 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1335 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1336 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1337 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1338 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1339
1340 ;; SSE vector suffix for floating point modes
1341 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1342
1343 ;; SSE vector mode corresponding to a scalar mode
1344 (define_mode_attr ssevecmode
1345 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1346 (define_mode_attr ssevecmodelower
1347 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1348
1349 ;; AVX512F vector mode corresponding to a scalar mode
1350 (define_mode_attr avx512fvecmode
1351 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1352
1353 ;; Instruction suffix for REX 64bit operators.
1354 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1355 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1356
1357 ;; This mode iterator allows :P to be used for patterns that operate on
1358 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1359 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1360
1361 ;; This mode iterator allows :W to be used for patterns that operate on
1362 ;; word_mode sized quantities.
1363 (define_mode_iterator W
1364 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1365
1366 ;; This mode iterator allows :PTR to be used for patterns that operate on
1367 ;; ptr_mode sized quantities.
1368 (define_mode_iterator PTR
1369 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1370 \f
1371 ;; Scheduling descriptions
1372
1373 (include "pentium.md")
1374 (include "ppro.md")
1375 (include "k6.md")
1376 (include "athlon.md")
1377 (include "bdver1.md")
1378 (include "bdver3.md")
1379 (include "btver2.md")
1380 (include "znver.md")
1381 (include "znver4.md")
1382 (include "geode.md")
1383 (include "atom.md")
1384 (include "slm.md")
1385 (include "glm.md")
1386 (include "core2.md")
1387 (include "haswell.md")
1388 (include "lujiazui.md")
1389 (include "yongfeng.md")
1390
1391 \f
1392 ;; Operand and operator predicates and constraints
1393
1394 (include "predicates.md")
1395 (include "constraints.md")
1396
1397 \f
1398 ;; Compare and branch/compare and store instructions.
1399
1400 (define_expand "cbranch<mode>4"
1401 [(set (reg:CC FLAGS_REG)
1402 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1403 (match_operand:SWIM1248x 2 "<general_operand>")))
1404 (set (pc) (if_then_else
1405 (match_operator 0 "ordered_comparison_operator"
1406 [(reg:CC FLAGS_REG) (const_int 0)])
1407 (label_ref (match_operand 3))
1408 (pc)))]
1409 ""
1410 {
1411 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1412 operands[1] = force_reg (<MODE>mode, operands[1]);
1413 ix86_expand_branch (GET_CODE (operands[0]),
1414 operands[1], operands[2], operands[3]);
1415 DONE;
1416 })
1417
1418 (define_expand "cbranchti4"
1419 [(set (reg:CC FLAGS_REG)
1420 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1421 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1422 (set (pc) (if_then_else
1423 (match_operator 0 "ix86_timode_comparison_operator"
1424 [(reg:CC FLAGS_REG) (const_int 0)])
1425 (label_ref (match_operand 3))
1426 (pc)))]
1427 "TARGET_64BIT || TARGET_SSE4_1"
1428 {
1429 ix86_expand_branch (GET_CODE (operands[0]),
1430 operands[1], operands[2], operands[3]);
1431 DONE;
1432 })
1433
1434 (define_expand "cbranchoi4"
1435 [(set (reg:CC FLAGS_REG)
1436 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1437 (match_operand:OI 2 "nonimmediate_operand")))
1438 (set (pc) (if_then_else
1439 (match_operator 0 "bt_comparison_operator"
1440 [(reg:CC FLAGS_REG) (const_int 0)])
1441 (label_ref (match_operand 3))
1442 (pc)))]
1443 "TARGET_AVX"
1444 {
1445 ix86_expand_branch (GET_CODE (operands[0]),
1446 operands[1], operands[2], operands[3]);
1447 DONE;
1448 })
1449
1450 (define_expand "cbranchxi4"
1451 [(set (reg:CC FLAGS_REG)
1452 (compare:CC (match_operand:XI 1 "nonimmediate_operand")
1453 (match_operand:XI 2 "nonimmediate_operand")))
1454 (set (pc) (if_then_else
1455 (match_operator 0 "bt_comparison_operator"
1456 [(reg:CC FLAGS_REG) (const_int 0)])
1457 (label_ref (match_operand 3))
1458 (pc)))]
1459 "TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256"
1460 {
1461 ix86_expand_branch (GET_CODE (operands[0]),
1462 operands[1], operands[2], operands[3]);
1463 DONE;
1464 })
1465
1466 (define_expand "cstore<mode>4"
1467 [(set (reg:CC FLAGS_REG)
1468 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1469 (match_operand:SDWIM 3 "<general_operand>")))
1470 (set (match_operand:QI 0 "register_operand")
1471 (match_operator 1 "ordered_comparison_operator"
1472 [(reg:CC FLAGS_REG) (const_int 0)]))]
1473 ""
1474 {
1475 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1476 {
1477 if (GET_CODE (operands[1]) != EQ
1478 && GET_CODE (operands[1]) != NE)
1479 FAIL;
1480 }
1481 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1482 operands[2] = force_reg (<MODE>mode, operands[2]);
1483 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1484 operands[2], operands[3]);
1485 DONE;
1486 })
1487
1488 (define_expand "@cmp<mode>_1"
1489 [(set (reg:CC FLAGS_REG)
1490 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1491 (match_operand:SWI48 1 "<general_operand>")))])
1492
1493 (define_mode_iterator SWI1248_AVX512BWDQ_64
1494 [(QI "TARGET_AVX512DQ") HI
1495 (SI "TARGET_AVX512BW")
1496 (DI "TARGET_AVX512BW && TARGET_EVEX512 && TARGET_64BIT")])
1497
1498 (define_insn "*cmp<mode>_ccz_1"
1499 [(set (reg FLAGS_REG)
1500 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1501 "nonimmediate_operand" "<r>,?m<r>,$k")
1502 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1503 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1504 "@
1505 test{<imodesuffix>}\t%0, %0
1506 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1507 kortest<mskmodesuffix>\t%0, %0"
1508 [(set_attr "type" "test,icmp,msklog")
1509 (set_attr "length_immediate" "0,1,*")
1510 (set_attr "prefix" "*,*,vex")
1511 (set_attr "mode" "<MODE>")])
1512
1513 (define_insn "*cmp<mode>_ccno_1"
1514 [(set (reg FLAGS_REG)
1515 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1516 (match_operand:SWI 1 "const0_operand")))]
1517 "ix86_match_ccmode (insn, CCNOmode)"
1518 "@
1519 test{<imodesuffix>}\t%0, %0
1520 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1521 [(set_attr "type" "test,icmp")
1522 (set_attr "length_immediate" "0,1")
1523 (set_attr "mode" "<MODE>")])
1524
1525 (define_insn "*cmp<mode>_1"
1526 [(set (reg FLAGS_REG)
1527 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1528 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1529 "ix86_match_ccmode (insn, CCmode)"
1530 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1531 [(set_attr "type" "icmp")
1532 (set_attr "mode" "<MODE>")])
1533
1534 (define_insn "*cmp<mode>_minus_1"
1535 [(set (reg FLAGS_REG)
1536 (compare
1537 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1538 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1539 (const_int 0)))]
1540 "ix86_match_ccmode (insn, CCGOCmode)"
1541 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1542 [(set_attr "type" "icmp")
1543 (set_attr "mode" "<MODE>")])
1544
1545 (define_insn "*cmpqi_ext<mode>_1"
1546 [(set (reg FLAGS_REG)
1547 (compare
1548 (match_operand:QI 0 "nonimmediate_operand" "QBn")
1549 (subreg:QI
1550 (match_operator:SWI248 2 "extract_operator"
1551 [(match_operand 1 "int248_register_operand" "Q")
1552 (const_int 8)
1553 (const_int 8)]) 0)))]
1554 "ix86_match_ccmode (insn, CCmode)"
1555 "cmp{b}\t{%h1, %0|%0, %h1}"
1556 [(set_attr "addr" "gpr8")
1557 (set_attr "type" "icmp")
1558 (set_attr "mode" "QI")])
1559
1560 (define_insn "*cmpqi_ext<mode>_2"
1561 [(set (reg FLAGS_REG)
1562 (compare
1563 (subreg:QI
1564 (match_operator:SWI248 2 "extract_operator"
1565 [(match_operand 0 "int248_register_operand" "Q")
1566 (const_int 8)
1567 (const_int 8)]) 0)
1568 (match_operand:QI 1 "const0_operand")))]
1569 "ix86_match_ccmode (insn, CCNOmode)"
1570 "test{b}\t%h0, %h0"
1571 [(set_attr "type" "test")
1572 (set_attr "length_immediate" "0")
1573 (set_attr "mode" "QI")])
1574
1575 (define_expand "cmpqi_ext_3"
1576 [(set (reg:CC FLAGS_REG)
1577 (compare:CC
1578 (subreg:QI
1579 (zero_extract:HI
1580 (match_operand:HI 0 "register_operand")
1581 (const_int 8)
1582 (const_int 8)) 0)
1583 (match_operand:QI 1 "const_int_operand")))])
1584
1585 (define_insn "*cmpqi_ext<mode>_3"
1586 [(set (reg FLAGS_REG)
1587 (compare
1588 (subreg:QI
1589 (match_operator:SWI248 2 "extract_operator"
1590 [(match_operand 0 "int248_register_operand" "Q")
1591 (const_int 8)
1592 (const_int 8)]) 0)
1593 (match_operand:QI 1 "general_operand" "QnBn")))]
1594 "ix86_match_ccmode (insn, CCmode)"
1595 "cmp{b}\t{%1, %h0|%h0, %1}"
1596 [(set_attr "addr" "gpr8")
1597 (set_attr "type" "icmp")
1598 (set_attr "mode" "QI")])
1599
1600 (define_insn "*cmpqi_ext<mode>_4"
1601 [(set (reg FLAGS_REG)
1602 (compare
1603 (subreg:QI
1604 (match_operator:SWI248 2 "extract_operator"
1605 [(match_operand 0 "int248_register_operand" "Q")
1606 (const_int 8)
1607 (const_int 8)]) 0)
1608 (subreg:QI
1609 (match_operator:SWI248 3 "extract_operator"
1610 [(match_operand 1 "int248_register_operand" "Q")
1611 (const_int 8)
1612 (const_int 8)]) 0)))]
1613 "ix86_match_ccmode (insn, CCmode)"
1614 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1615 [(set_attr "type" "icmp")
1616 (set_attr "mode" "QI")])
1617
1618 (define_insn_and_split "*cmp<dwi>_doubleword"
1619 [(set (reg:CCZ FLAGS_REG)
1620 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1621 (match_operand:<DWI> 1 "general_operand")))]
1622 "ix86_pre_reload_split ()"
1623 "#"
1624 "&& 1"
1625 [(parallel [(set (reg:CCZ FLAGS_REG)
1626 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1627 (const_int 0)))
1628 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1629 {
1630 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1631 /* Placing the SUBREG pieces in pseudos helps reload. */
1632 for (int i = 0; i < 4; i++)
1633 if (SUBREG_P (operands[i]))
1634 operands[i] = force_reg (<MODE>mode, operands[i]);
1635
1636 operands[4] = gen_reg_rtx (<MODE>mode);
1637
1638 /* Special case comparisons against -1. */
1639 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1640 {
1641 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1642 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1643 DONE;
1644 }
1645
1646 if (operands[1] == const0_rtx)
1647 emit_move_insn (operands[4], operands[0]);
1648 else if (operands[0] == const0_rtx)
1649 emit_move_insn (operands[4], operands[1]);
1650 else if (operands[1] == constm1_rtx)
1651 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1652 else if (operands[0] == constm1_rtx)
1653 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1654 else
1655 {
1656 if (CONST_SCALAR_INT_P (operands[1])
1657 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1658 operands[1] = force_reg (<MODE>mode, operands[1]);
1659 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1660 }
1661
1662 if (operands[3] == const0_rtx)
1663 operands[5] = operands[2];
1664 else if (operands[2] == const0_rtx)
1665 operands[5] = operands[3];
1666 else
1667 {
1668 operands[5] = gen_reg_rtx (<MODE>mode);
1669 if (operands[3] == constm1_rtx)
1670 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1671 else if (operands[2] == constm1_rtx)
1672 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1673 else
1674 {
1675 if (CONST_SCALAR_INT_P (operands[3])
1676 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1677 operands[3] = force_reg (<MODE>mode, operands[3]);
1678 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1679 }
1680 }
1681 })
1682
1683 ;; These implement float point compares.
1684 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1685 ;; which would allow mix and match FP modes on the compares. Which is what
1686 ;; the old patterns did, but with many more of them.
1687
1688 (define_expand "cbranchxf4"
1689 [(set (reg:CC FLAGS_REG)
1690 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1691 (match_operand:XF 2 "nonmemory_operand")))
1692 (set (pc) (if_then_else
1693 (match_operator 0 "ix86_fp_comparison_operator"
1694 [(reg:CC FLAGS_REG)
1695 (const_int 0)])
1696 (label_ref (match_operand 3))
1697 (pc)))]
1698 "TARGET_80387"
1699 {
1700 ix86_expand_branch (GET_CODE (operands[0]),
1701 operands[1], operands[2], operands[3]);
1702 DONE;
1703 })
1704
1705 (define_expand "cstorexf4"
1706 [(set (reg:CC FLAGS_REG)
1707 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1708 (match_operand:XF 3 "nonmemory_operand")))
1709 (set (match_operand:QI 0 "register_operand")
1710 (match_operator 1 "ix86_fp_comparison_operator"
1711 [(reg:CC FLAGS_REG)
1712 (const_int 0)]))]
1713 "TARGET_80387"
1714 {
1715 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1716 operands[2], operands[3]);
1717 DONE;
1718 })
1719
1720 (define_expand "cbranchhf4"
1721 [(set (reg:CC FLAGS_REG)
1722 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1723 (match_operand:HF 2 "cmp_fp_expander_operand")))
1724 (set (pc) (if_then_else
1725 (match_operator 0 "ix86_fp_comparison_operator"
1726 [(reg:CC FLAGS_REG)
1727 (const_int 0)])
1728 (label_ref (match_operand 3))
1729 (pc)))]
1730 "TARGET_AVX512FP16"
1731 {
1732 ix86_expand_branch (GET_CODE (operands[0]),
1733 operands[1], operands[2], operands[3]);
1734 DONE;
1735 })
1736
1737 (define_expand "cbranch<mode>4"
1738 [(set (reg:CC FLAGS_REG)
1739 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1740 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1741 (set (pc) (if_then_else
1742 (match_operator 0 "ix86_fp_comparison_operator"
1743 [(reg:CC FLAGS_REG)
1744 (const_int 0)])
1745 (label_ref (match_operand 3))
1746 (pc)))]
1747 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1748 {
1749 ix86_expand_branch (GET_CODE (operands[0]),
1750 operands[1], operands[2], operands[3]);
1751 DONE;
1752 })
1753
1754 (define_expand "cbranchbf4"
1755 [(set (reg:CC FLAGS_REG)
1756 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1757 (match_operand:BF 2 "cmp_fp_expander_operand")))
1758 (set (pc) (if_then_else
1759 (match_operator 0 "comparison_operator"
1760 [(reg:CC FLAGS_REG)
1761 (const_int 0)])
1762 (label_ref (match_operand 3))
1763 (pc)))]
1764 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1765 {
1766 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1767 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1768 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1769 SFmode, NULL_RTX, NULL,
1770 as_a <rtx_code_label *> (operands[3]),
1771 /* Unfortunately this isn't propagated. */
1772 profile_probability::even ());
1773 DONE;
1774 })
1775
1776 (define_expand "cstorehf4"
1777 [(set (reg:CC FLAGS_REG)
1778 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1779 (match_operand:HF 3 "cmp_fp_expander_operand")))
1780 (set (match_operand:QI 0 "register_operand")
1781 (match_operator 1 "ix86_fp_comparison_operator"
1782 [(reg:CC FLAGS_REG)
1783 (const_int 0)]))]
1784 "TARGET_AVX512FP16"
1785 {
1786 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1787 operands[2], operands[3]);
1788 DONE;
1789 })
1790
1791 (define_expand "cstorebf4"
1792 [(set (reg:CC FLAGS_REG)
1793 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1794 (match_operand:BF 3 "cmp_fp_expander_operand")))
1795 (set (match_operand:QI 0 "register_operand")
1796 (match_operator 1 "comparison_operator"
1797 [(reg:CC FLAGS_REG)
1798 (const_int 0)]))]
1799 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1800 {
1801 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1802 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1803 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1804 op1, op2, SFmode, 0, 1);
1805 if (!rtx_equal_p (res, operands[0]))
1806 emit_move_insn (operands[0], res);
1807 DONE;
1808 })
1809
1810 (define_expand "cstore<mode>4"
1811 [(set (reg:CC FLAGS_REG)
1812 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1813 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1814 (set (match_operand:QI 0 "register_operand")
1815 (match_operator 1 "ix86_fp_comparison_operator"
1816 [(reg:CC FLAGS_REG)
1817 (const_int 0)]))]
1818 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1819 {
1820 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1821 operands[2], operands[3]);
1822 DONE;
1823 })
1824
1825 (define_expand "cbranchcc4"
1826 [(set (pc) (if_then_else
1827 (match_operator 0 "comparison_operator"
1828 [(match_operand 1 "flags_reg_operand")
1829 (match_operand 2 "const0_operand")])
1830 (label_ref (match_operand 3))
1831 (pc)))]
1832 ""
1833 {
1834 ix86_expand_branch (GET_CODE (operands[0]),
1835 operands[1], operands[2], operands[3]);
1836 DONE;
1837 })
1838
1839 (define_expand "cstorecc4"
1840 [(set (match_operand:QI 0 "register_operand")
1841 (match_operator 1 "comparison_operator"
1842 [(match_operand 2 "flags_reg_operand")
1843 (match_operand 3 "const0_operand")]))]
1844 ""
1845 {
1846 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1847 operands[2], operands[3]);
1848 DONE;
1849 })
1850
1851 ;; FP compares, step 1:
1852 ;; Set the FP condition codes and move fpsr to ax.
1853
1854 ;; We may not use "#" to split and emit these
1855 ;; due to reg-stack pops killing fpsr.
1856
1857 (define_insn "*cmpxf_i387"
1858 [(set (match_operand:HI 0 "register_operand" "=a")
1859 (unspec:HI
1860 [(compare:CCFP
1861 (match_operand:XF 1 "register_operand" "f")
1862 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1863 UNSPEC_FNSTSW))]
1864 "TARGET_80387"
1865 "* return output_fp_compare (insn, operands, false, false);"
1866 [(set_attr "type" "multi")
1867 (set_attr "unit" "i387")
1868 (set_attr "mode" "XF")])
1869
1870 (define_insn "*cmp<mode>_i387"
1871 [(set (match_operand:HI 0 "register_operand" "=a")
1872 (unspec:HI
1873 [(compare:CCFP
1874 (match_operand:MODEF 1 "register_operand" "f")
1875 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1876 UNSPEC_FNSTSW))]
1877 "TARGET_80387"
1878 "* return output_fp_compare (insn, operands, false, false);"
1879 [(set_attr "type" "multi")
1880 (set_attr "unit" "i387")
1881 (set_attr "mode" "<MODE>")])
1882
1883 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1884 [(set (match_operand:HI 0 "register_operand" "=a")
1885 (unspec:HI
1886 [(compare:CCFP
1887 (match_operand:X87MODEF 1 "register_operand" "f")
1888 (float:X87MODEF
1889 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1890 UNSPEC_FNSTSW))]
1891 "TARGET_80387
1892 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1893 || optimize_function_for_size_p (cfun))"
1894 "* return output_fp_compare (insn, operands, false, false);"
1895 [(set_attr "type" "multi")
1896 (set_attr "unit" "i387")
1897 (set_attr "fp_int_src" "true")
1898 (set_attr "mode" "<SWI24:MODE>")])
1899
1900 (define_insn "*cmpu<mode>_i387"
1901 [(set (match_operand:HI 0 "register_operand" "=a")
1902 (unspec:HI
1903 [(unspec:CCFP
1904 [(compare:CCFP
1905 (match_operand:X87MODEF 1 "register_operand" "f")
1906 (match_operand:X87MODEF 2 "register_operand" "f"))]
1907 UNSPEC_NOTRAP)]
1908 UNSPEC_FNSTSW))]
1909 "TARGET_80387"
1910 "* return output_fp_compare (insn, operands, false, true);"
1911 [(set_attr "type" "multi")
1912 (set_attr "unit" "i387")
1913 (set_attr "mode" "<MODE>")])
1914
1915 ;; FP compares, step 2:
1916 ;; Get ax into flags, general case.
1917
1918 (define_insn "x86_sahf_1"
1919 [(set (reg:CC FLAGS_REG)
1920 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1921 UNSPEC_SAHF))]
1922 "TARGET_SAHF"
1923 {
1924 #ifndef HAVE_AS_IX86_SAHF
1925 if (TARGET_64BIT)
1926 return ASM_BYTE "0x9e";
1927 else
1928 #endif
1929 return "sahf";
1930 }
1931 [(set_attr "length" "1")
1932 (set_attr "athlon_decode" "vector")
1933 (set_attr "amdfam10_decode" "direct")
1934 (set_attr "bdver1_decode" "direct")
1935 (set_attr "mode" "SI")])
1936
1937 ;; Pentium Pro can do both steps in one go.
1938 ;; (these instructions set flags directly)
1939
1940 (define_subst_attr "unord" "unord_subst" "" "u")
1941 (define_subst_attr "unordered" "unord_subst" "false" "true")
1942
1943 (define_subst "unord_subst"
1944 [(set (match_operand:CCFP 0)
1945 (match_operand:CCFP 1))]
1946 ""
1947 [(set (match_dup 0)
1948 (unspec:CCFP
1949 [(match_dup 1)]
1950 UNSPEC_NOTRAP))])
1951
1952 (define_insn "*cmpi<unord>xf_i387"
1953 [(set (reg:CCFP FLAGS_REG)
1954 (compare:CCFP
1955 (match_operand:XF 0 "register_operand" "f")
1956 (match_operand:XF 1 "register_operand" "f")))]
1957 "TARGET_80387 && TARGET_CMOVE"
1958 "* return output_fp_compare (insn, operands, true, <unordered>);"
1959 [(set_attr "type" "fcmp")
1960 (set_attr "mode" "XF")
1961 (set_attr "athlon_decode" "vector")
1962 (set_attr "amdfam10_decode" "direct")
1963 (set_attr "bdver1_decode" "double")
1964 (set_attr "znver1_decode" "double")])
1965
1966 (define_insn "*cmpi<unord><MODEF:mode>"
1967 [(set (reg:CCFP FLAGS_REG)
1968 (compare:CCFP
1969 (match_operand:MODEF 0 "register_operand" "f,v")
1970 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1971 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1972 || (TARGET_80387 && TARGET_CMOVE)"
1973 "@
1974 * return output_fp_compare (insn, operands, true, <unordered>);
1975 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1976 [(set_attr "type" "fcmp,ssecomi")
1977 (set_attr "prefix" "orig,maybe_vex")
1978 (set_attr "mode" "<MODEF:MODE>")
1979 (set_attr "prefix_rep" "*,0")
1980 (set (attr "prefix_data16")
1981 (cond [(eq_attr "alternative" "0")
1982 (const_string "*")
1983 (eq_attr "mode" "DF")
1984 (const_string "1")
1985 ]
1986 (const_string "0")))
1987 (set_attr "athlon_decode" "vector")
1988 (set_attr "amdfam10_decode" "direct")
1989 (set_attr "bdver1_decode" "double")
1990 (set_attr "znver1_decode" "double")
1991 (set (attr "enabled")
1992 (if_then_else
1993 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1994 (if_then_else
1995 (eq_attr "alternative" "0")
1996 (symbol_ref "TARGET_MIX_SSE_I387")
1997 (symbol_ref "true"))
1998 (if_then_else
1999 (eq_attr "alternative" "0")
2000 (symbol_ref "true")
2001 (symbol_ref "false"))))])
2002
2003 (define_insn "*cmpi<unord>hf"
2004 [(set (reg:CCFP FLAGS_REG)
2005 (compare:CCFP
2006 (match_operand:HF 0 "register_operand" "v")
2007 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2008 "TARGET_AVX512FP16"
2009 "v<unord>comish\t{%1, %0|%0, %1}"
2010 [(set_attr "type" "ssecomi")
2011 (set_attr "prefix" "evex")
2012 (set_attr "mode" "HF")])
2013
2014 ;; Set carry flag.
2015 (define_insn "x86_stc"
2016 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2017 ""
2018 "stc"
2019 [(set_attr "length" "1")
2020 (set_attr "length_immediate" "0")
2021 (set_attr "modrm" "0")])
2022
2023 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2024 (define_peephole2
2025 [(match_scratch:QI 0 "r")
2026 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2027 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2028 [(set (match_dup 0) (const_int 1))
2029 (parallel
2030 [(set (reg:CCC FLAGS_REG)
2031 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2032 (match_dup 0)))
2033 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2034
2035 ;; Complement carry flag.
2036 (define_insn "*x86_cmc"
2037 [(set (reg:CCC FLAGS_REG)
2038 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2039 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2040 ""
2041 "cmc"
2042 [(set_attr "length" "1")
2043 (set_attr "length_immediate" "0")
2044 (set_attr "use_carry" "1")
2045 (set_attr "modrm" "0")])
2046
2047 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2048 (define_peephole2
2049 [(match_scratch:QI 0 "r")
2050 (set (reg:CCC FLAGS_REG)
2051 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2052 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2053 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2054 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2055 (parallel
2056 [(set (reg:CCC FLAGS_REG)
2057 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2058 (match_dup 0)))
2059 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2060 \f
2061 ;; Push/pop instructions.
2062
2063 (define_insn_and_split "*pushv1ti2"
2064 [(set (match_operand:V1TI 0 "push_operand" "=<")
2065 (match_operand:V1TI 1 "register_operand" "v"))]
2066 "TARGET_64BIT && TARGET_STV"
2067 "#"
2068 "&& reload_completed"
2069 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2070 (set (match_dup 0) (match_dup 1))]
2071 {
2072 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2073 /* Preserve memory attributes. */
2074 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2075 }
2076 [(set_attr "type" "multi")
2077 (set_attr "mode" "TI")])
2078
2079 (define_insn "*push<mode>2"
2080 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2081 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2082 ""
2083 "#"
2084 [(set_attr "type" "multi")
2085 (set_attr "mode" "<MODE>")])
2086
2087 (define_split
2088 [(set (match_operand:DWI 0 "push_operand")
2089 (match_operand:DWI 1 "general_gr_operand"))]
2090 "reload_completed"
2091 [(const_int 0)]
2092 "ix86_split_long_move (operands); DONE;")
2093
2094 (define_insn "*pushdi2_rex64"
2095 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2096 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2097 "TARGET_64BIT"
2098 "@
2099 push{q}\t%1
2100 #
2101 #"
2102 [(set_attr "type" "push,multi,multi")
2103 (set_attr "mode" "DI")])
2104
2105 ;; Convert impossible pushes of immediate to existing instructions.
2106 ;; First try to get scratch register and go through it. In case this
2107 ;; fails, push sign extended lower part first and then overwrite
2108 ;; upper part by 32bit move.
2109
2110 (define_peephole2
2111 [(match_scratch:DI 2 "r")
2112 (set (match_operand:DI 0 "push_operand")
2113 (match_operand:DI 1 "immediate_operand"))]
2114 "TARGET_64BIT
2115 && !symbolic_operand (operands[1], DImode)
2116 && !x86_64_immediate_operand (operands[1], DImode)"
2117 [(set (match_dup 2) (match_dup 1))
2118 (set (match_dup 0) (match_dup 2))])
2119
2120 (define_split
2121 [(set (match_operand:DI 0 "push_operand")
2122 (match_operand:DI 1 "immediate_operand"))]
2123 "TARGET_64BIT && epilogue_completed
2124 && !symbolic_operand (operands[1], DImode)
2125 && !x86_64_immediate_operand (operands[1], DImode)"
2126 [(set (match_dup 0) (match_dup 1))
2127 (set (match_dup 2) (match_dup 3))]
2128 {
2129 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2130
2131 operands[1] = gen_lowpart (DImode, operands[2]);
2132 operands[2] = gen_rtx_MEM (SImode,
2133 plus_constant (Pmode, stack_pointer_rtx, 4));
2134 })
2135
2136 ;; For TARGET_64BIT we always round up to 8 bytes.
2137 (define_insn "*pushsi2_rex64"
2138 [(set (match_operand:SI 0 "push_operand" "=X,X")
2139 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2140 "TARGET_64BIT"
2141 "@
2142 push{q}\t%q1
2143 #"
2144 [(set_attr "type" "push,multi")
2145 (set_attr "mode" "DI")])
2146
2147 (define_insn "*pushsi2"
2148 [(set (match_operand:SI 0 "push_operand" "=<,<")
2149 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2150 "!TARGET_64BIT"
2151 "@
2152 push{l}\t%1
2153 #"
2154 [(set_attr "type" "push,multi")
2155 (set_attr "mode" "SI")])
2156
2157 (define_split
2158 [(set (match_operand:SWI48DWI 0 "push_operand")
2159 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2160 "TARGET_SSE && reload_completed"
2161 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2162 (set (match_dup 0) (match_dup 1))]
2163 {
2164 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2165 /* Preserve memory attributes. */
2166 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2167 })
2168
2169 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2170 ;; "push a byte/word". But actually we use push{l,q}, which has
2171 ;; the effect of rounding the amount pushed up to a word.
2172
2173 (define_insn "*push<mode>2"
2174 [(set (match_operand:SWI12 0 "push_operand" "=X")
2175 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2176 ""
2177 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2178 [(set_attr "type" "push")
2179 (set (attr "mode")
2180 (if_then_else (match_test "TARGET_64BIT")
2181 (const_string "DI")
2182 (const_string "SI")))])
2183
2184 (define_insn "*push<mode>2_prologue"
2185 [(set (match_operand:W 0 "push_operand" "=<")
2186 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2187 (clobber (mem:BLK (scratch)))]
2188 ""
2189 "push{<imodesuffix>}\t%1"
2190 [(set_attr "type" "push")
2191 (set_attr "mode" "<MODE>")])
2192
2193 (define_insn "*pop<mode>1"
2194 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2195 (match_operand:W 1 "pop_operand" ">"))]
2196 ""
2197 "pop{<imodesuffix>}\t%0"
2198 [(set_attr "type" "pop")
2199 (set_attr "mode" "<MODE>")])
2200
2201 (define_insn "*pop<mode>1_epilogue"
2202 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2203 (match_operand:W 1 "pop_operand" ">"))
2204 (clobber (mem:BLK (scratch)))]
2205 ""
2206 "pop{<imodesuffix>}\t%0"
2207 [(set_attr "type" "pop")
2208 (set_attr "mode" "<MODE>")])
2209
2210 (define_insn "@pushfl<mode>2"
2211 [(set (match_operand:W 0 "push_operand" "=<")
2212 (unspec:W [(match_operand:CC 1 "flags_reg_operand")]
2213 UNSPEC_PUSHFL))]
2214 ""
2215 "pushf{<imodesuffix>}"
2216 [(set_attr "type" "push")
2217 (set_attr "mode" "<MODE>")])
2218
2219 (define_insn "@popfl<mode>1"
2220 [(set (match_operand:CC 0 "flags_reg_operand")
2221 (unspec:CC [(match_operand:W 1 "pop_operand" ">")]
2222 UNSPEC_POPFL))]
2223 ""
2224 "popf{<imodesuffix>}"
2225 [(set_attr "type" "pop")
2226 (set_attr "mode" "<MODE>")])
2227
2228 \f
2229 ;; Reload patterns to support multi-word load/store
2230 ;; with non-offsetable address.
2231 (define_expand "reload_noff_store"
2232 [(parallel [(match_operand 0 "memory_operand" "=m")
2233 (match_operand 1 "register_operand" "r")
2234 (match_operand:DI 2 "register_operand" "=&r")])]
2235 "TARGET_64BIT"
2236 {
2237 rtx mem = operands[0];
2238 rtx addr = XEXP (mem, 0);
2239
2240 emit_move_insn (operands[2], addr);
2241 mem = replace_equiv_address_nv (mem, operands[2]);
2242
2243 emit_insn (gen_rtx_SET (mem, operands[1]));
2244 DONE;
2245 })
2246
2247 (define_expand "reload_noff_load"
2248 [(parallel [(match_operand 0 "register_operand" "=r")
2249 (match_operand 1 "memory_operand" "m")
2250 (match_operand:DI 2 "register_operand" "=r")])]
2251 "TARGET_64BIT"
2252 {
2253 rtx mem = operands[1];
2254 rtx addr = XEXP (mem, 0);
2255
2256 emit_move_insn (operands[2], addr);
2257 mem = replace_equiv_address_nv (mem, operands[2]);
2258
2259 emit_insn (gen_rtx_SET (operands[0], mem));
2260 DONE;
2261 })
2262
2263 ;; Move instructions.
2264
2265 (define_expand "movxi"
2266 [(set (match_operand:XI 0 "nonimmediate_operand")
2267 (match_operand:XI 1 "general_operand"))]
2268 "TARGET_AVX512F && TARGET_EVEX512"
2269 "ix86_expand_vector_move (XImode, operands); DONE;")
2270
2271 (define_expand "movoi"
2272 [(set (match_operand:OI 0 "nonimmediate_operand")
2273 (match_operand:OI 1 "general_operand"))]
2274 "TARGET_AVX"
2275 "ix86_expand_vector_move (OImode, operands); DONE;")
2276
2277 (define_expand "movti"
2278 [(set (match_operand:TI 0 "nonimmediate_operand")
2279 (match_operand:TI 1 "general_operand"))]
2280 "TARGET_64BIT || TARGET_SSE"
2281 {
2282 if (TARGET_64BIT)
2283 ix86_expand_move (TImode, operands);
2284 else
2285 ix86_expand_vector_move (TImode, operands);
2286 DONE;
2287 })
2288
2289 ;; This expands to what emit_move_complex would generate if we didn't
2290 ;; have a movti pattern. Having this avoids problems with reload on
2291 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2292 ;; to have around all the time.
2293 (define_expand "movcdi"
2294 [(set (match_operand:CDI 0 "nonimmediate_operand")
2295 (match_operand:CDI 1 "general_operand"))]
2296 ""
2297 {
2298 if (push_operand (operands[0], CDImode))
2299 emit_move_complex_push (CDImode, operands[0], operands[1]);
2300 else
2301 emit_move_complex_parts (operands[0], operands[1]);
2302 DONE;
2303 })
2304
2305 (define_expand "mov<mode>"
2306 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2307 (match_operand:SWI1248x 1 "general_operand"))]
2308 ""
2309 "ix86_expand_move (<MODE>mode, operands); DONE;")
2310
2311 (define_insn "*mov<mode>_xor"
2312 [(set (match_operand:SWI48 0 "register_operand" "=r")
2313 (match_operand:SWI48 1 "const0_operand"))
2314 (clobber (reg:CC FLAGS_REG))]
2315 "reload_completed"
2316 "xor{l}\t%k0, %k0"
2317 [(set_attr "type" "alu1")
2318 (set_attr "mode" "SI")
2319 (set_attr "length_immediate" "0")])
2320
2321 (define_insn "*mov<mode>_and"
2322 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2323 (match_operand:SWI248 1 "const0_operand"))
2324 (clobber (reg:CC FLAGS_REG))]
2325 "reload_completed"
2326 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2327 [(set_attr "type" "alu1")
2328 (set_attr "mode" "<MODE>")
2329 (set_attr "length_immediate" "1")])
2330
2331 (define_insn "*mov<mode>_or"
2332 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2333 (match_operand:SWI248 1 "constm1_operand"))
2334 (clobber (reg:CC FLAGS_REG))]
2335 "reload_completed"
2336 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2337 [(set_attr "type" "alu1")
2338 (set_attr "mode" "<MODE>")
2339 (set_attr "length_immediate" "1")])
2340
2341 (define_insn "*movxi_internal_avx512f"
2342 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2343 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2344 "TARGET_AVX512F && TARGET_EVEX512
2345 && (register_operand (operands[0], XImode)
2346 || register_operand (operands[1], XImode))"
2347 {
2348 switch (get_attr_type (insn))
2349 {
2350 case TYPE_SSELOG1:
2351 return standard_sse_constant_opcode (insn, operands);
2352
2353 case TYPE_SSEMOV:
2354 return ix86_output_ssemov (insn, operands);
2355
2356 default:
2357 gcc_unreachable ();
2358 }
2359 }
2360 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2361 (set_attr "prefix" "evex")
2362 (set_attr "mode" "XI")])
2363
2364 (define_insn "*movoi_internal_avx"
2365 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2366 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2367 "TARGET_AVX
2368 && (register_operand (operands[0], OImode)
2369 || register_operand (operands[1], OImode))"
2370 {
2371 switch (get_attr_type (insn))
2372 {
2373 case TYPE_SSELOG1:
2374 return standard_sse_constant_opcode (insn, operands);
2375
2376 case TYPE_SSEMOV:
2377 return ix86_output_ssemov (insn, operands);
2378
2379 default:
2380 gcc_unreachable ();
2381 }
2382 }
2383 [(set_attr "isa" "*,avx2,*,*")
2384 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2385 (set_attr "prefix" "vex")
2386 (set_attr "mode" "OI")])
2387
2388 (define_insn "*movti_internal"
2389 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?jc,?Yd")
2390 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,jc"))]
2391 "(TARGET_64BIT
2392 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2393 || (TARGET_SSE
2394 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2395 && (register_operand (operands[0], TImode)
2396 || register_operand (operands[1], TImode)))"
2397 {
2398 switch (get_attr_type (insn))
2399 {
2400 case TYPE_MULTI:
2401 return "#";
2402
2403 case TYPE_SSELOG1:
2404 return standard_sse_constant_opcode (insn, operands);
2405
2406 case TYPE_SSEMOV:
2407 return ix86_output_ssemov (insn, operands);
2408
2409 default:
2410 gcc_unreachable ();
2411 }
2412 }
2413 [(set (attr "isa")
2414 (cond [(eq_attr "alternative" "0,1,6,7")
2415 (const_string "x64")
2416 (eq_attr "alternative" "3")
2417 (const_string "sse2")
2418 ]
2419 (const_string "*")))
2420 (set (attr "type")
2421 (cond [(eq_attr "alternative" "0,1,6,7")
2422 (const_string "multi")
2423 (eq_attr "alternative" "2,3")
2424 (const_string "sselog1")
2425 ]
2426 (const_string "ssemov")))
2427 (set (attr "prefix")
2428 (if_then_else (eq_attr "type" "sselog1,ssemov")
2429 (const_string "maybe_vex")
2430 (const_string "orig")))
2431 (set (attr "mode")
2432 (cond [(eq_attr "alternative" "0,1")
2433 (const_string "DI")
2434 (match_test "TARGET_AVX")
2435 (const_string "TI")
2436 (ior (not (match_test "TARGET_SSE2"))
2437 (match_test "optimize_function_for_size_p (cfun)"))
2438 (const_string "V4SF")
2439 (and (eq_attr "alternative" "5")
2440 (match_test "TARGET_SSE_TYPELESS_STORES"))
2441 (const_string "V4SF")
2442 ]
2443 (const_string "TI")))
2444 (set (attr "preferred_for_speed")
2445 (cond [(eq_attr "alternative" "6")
2446 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2447 (eq_attr "alternative" "7")
2448 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2449 ]
2450 (symbol_ref "true")))])
2451
2452 (define_split
2453 [(set (match_operand:TI 0 "sse_reg_operand")
2454 (match_operand:TI 1 "general_reg_operand"))]
2455 "TARGET_64BIT && TARGET_SSE4_1
2456 && reload_completed"
2457 [(set (match_dup 2)
2458 (vec_merge:V2DI
2459 (vec_duplicate:V2DI (match_dup 3))
2460 (match_dup 2)
2461 (const_int 2)))]
2462 {
2463 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2464 operands[3] = gen_highpart (DImode, operands[1]);
2465
2466 emit_move_insn (gen_lowpart (DImode, operands[0]),
2467 gen_lowpart (DImode, operands[1]));
2468 })
2469
2470 (define_insn "*movdi_internal"
2471 [(set (match_operand:DI 0 "nonimmediate_operand"
2472 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,m,?jc,?*Yd,?r,?v,?*y,?*x,*k,*k ,*r,*m,*k")
2473 (match_operand:DI 1 "general_operand"
2474 "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,v,*Yd,jc ,?v,r ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2475 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2476 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2477 {
2478 switch (get_attr_type (insn))
2479 {
2480 case TYPE_MSKMOV:
2481 return "kmovq\t{%1, %0|%0, %1}";
2482
2483 case TYPE_MSKLOG:
2484 if (operands[1] == const0_rtx)
2485 return "kxorq\t%0, %0, %0";
2486 else if (operands[1] == constm1_rtx)
2487 return "kxnorq\t%0, %0, %0";
2488 gcc_unreachable ();
2489
2490 case TYPE_MULTI:
2491 return "#";
2492
2493 case TYPE_MMX:
2494 return "pxor\t%0, %0";
2495
2496 case TYPE_MMXMOV:
2497 /* Handle broken assemblers that require movd instead of movq. */
2498 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2499 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2500 return "movd\t{%1, %0|%0, %1}";
2501 return "movq\t{%1, %0|%0, %1}";
2502
2503 case TYPE_SSELOG1:
2504 return standard_sse_constant_opcode (insn, operands);
2505
2506 case TYPE_SSEMOV:
2507 return ix86_output_ssemov (insn, operands);
2508
2509 case TYPE_SSECVT:
2510 if (SSE_REG_P (operands[0]))
2511 return "movq2dq\t{%1, %0|%0, %1}";
2512 else
2513 return "movdq2q\t{%1, %0|%0, %1}";
2514
2515 case TYPE_LEA:
2516 return "lea{q}\t{%E1, %0|%0, %E1}";
2517
2518 case TYPE_IMOV:
2519 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2520 if (get_attr_mode (insn) == MODE_SI)
2521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2522 else if (which_alternative == 4)
2523 return "movabs{q}\t{%1, %0|%0, %1}";
2524 else if (ix86_use_lea_for_mov (insn, operands))
2525 return "lea{q}\t{%E1, %0|%0, %E1}";
2526 else
2527 return "mov{q}\t{%1, %0|%0, %1}";
2528
2529 default:
2530 gcc_unreachable ();
2531 }
2532 }
2533 [(set (attr "isa")
2534 (cond [(eq_attr "alternative" "0,1,17,18")
2535 (const_string "nox64")
2536 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2537 (const_string "x64")
2538 (eq_attr "alternative" "19,20")
2539 (const_string "x64_sse2")
2540 (eq_attr "alternative" "21,22")
2541 (const_string "sse2")
2542 ]
2543 (const_string "*")))
2544 (set (attr "type")
2545 (cond [(eq_attr "alternative" "0,1,17,18")
2546 (const_string "multi")
2547 (eq_attr "alternative" "6")
2548 (const_string "mmx")
2549 (eq_attr "alternative" "7,8,9,10,11")
2550 (const_string "mmxmov")
2551 (eq_attr "alternative" "12")
2552 (const_string "sselog1")
2553 (eq_attr "alternative" "13,14,15,16,19,20")
2554 (const_string "ssemov")
2555 (eq_attr "alternative" "21,22")
2556 (const_string "ssecvt")
2557 (eq_attr "alternative" "23,24,25,26")
2558 (const_string "mskmov")
2559 (eq_attr "alternative" "27")
2560 (const_string "msklog")
2561 (and (match_operand 0 "register_operand")
2562 (match_operand 1 "pic_32bit_operand"))
2563 (const_string "lea")
2564 ]
2565 (const_string "imov")))
2566 (set (attr "modrm")
2567 (if_then_else
2568 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2569 (const_string "0")
2570 (const_string "*")))
2571 (set (attr "length_immediate")
2572 (if_then_else
2573 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2574 (const_string "8")
2575 (const_string "*")))
2576 (set (attr "prefix_rex")
2577 (if_then_else
2578 (eq_attr "alternative" "10,11,19,20")
2579 (const_string "1")
2580 (const_string "*")))
2581 (set (attr "prefix")
2582 (if_then_else (eq_attr "type" "sselog1,ssemov")
2583 (const_string "maybe_vex")
2584 (const_string "orig")))
2585 (set (attr "prefix_data16")
2586 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2587 (const_string "1")
2588 (const_string "*")))
2589 (set (attr "mode")
2590 (cond [(eq_attr "alternative" "2")
2591 (const_string "SI")
2592 (eq_attr "alternative" "12")
2593 (cond [(match_test "TARGET_AVX")
2594 (const_string "TI")
2595 (ior (not (match_test "TARGET_SSE2"))
2596 (match_test "optimize_function_for_size_p (cfun)"))
2597 (const_string "V4SF")
2598 ]
2599 (const_string "TI"))
2600 (eq_attr "alternative" "13")
2601 (cond [(match_test "TARGET_AVX512VL")
2602 (const_string "TI")
2603 (match_test "TARGET_AVX512F")
2604 (const_string "DF")
2605 (match_test "TARGET_AVX")
2606 (const_string "TI")
2607 (ior (not (match_test "TARGET_SSE2"))
2608 (match_test "optimize_function_for_size_p (cfun)"))
2609 (const_string "V4SF")
2610 ]
2611 (const_string "TI"))
2612
2613 (and (eq_attr "alternative" "14,15,16")
2614 (not (match_test "TARGET_SSE2")))
2615 (const_string "V2SF")
2616 ]
2617 (const_string "DI")))
2618 (set (attr "preferred_for_speed")
2619 (cond [(eq_attr "alternative" "10,17,19")
2620 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2621 (eq_attr "alternative" "11,18,20")
2622 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2623 ]
2624 (symbol_ref "true")))
2625 (set (attr "enabled")
2626 (cond [(eq_attr "alternative" "15")
2627 (if_then_else
2628 (match_test "TARGET_STV && TARGET_SSE2")
2629 (symbol_ref "false")
2630 (const_string "*"))
2631 (eq_attr "alternative" "16")
2632 (if_then_else
2633 (match_test "TARGET_STV && TARGET_SSE2")
2634 (symbol_ref "true")
2635 (symbol_ref "false"))
2636 ]
2637 (const_string "*")))])
2638
2639 (define_split
2640 [(set (match_operand:<DWI> 0 "general_reg_operand")
2641 (match_operand:<DWI> 1 "sse_reg_operand"))]
2642 "TARGET_SSE4_1
2643 && reload_completed"
2644 [(set (match_dup 2)
2645 (vec_select:DWIH
2646 (match_dup 3)
2647 (parallel [(const_int 1)])))]
2648 {
2649 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2650 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2651
2652 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2653 gen_lowpart (<MODE>mode, operands[1]));
2654 })
2655
2656 (define_split
2657 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2658 (match_operand:DWI 1 "general_gr_operand"))]
2659 "reload_completed"
2660 [(const_int 0)]
2661 "ix86_split_long_move (operands); DONE;")
2662
2663 (define_split
2664 [(set (match_operand:DI 0 "sse_reg_operand")
2665 (match_operand:DI 1 "general_reg_operand"))]
2666 "!TARGET_64BIT && TARGET_SSE4_1
2667 && reload_completed"
2668 [(set (match_dup 2)
2669 (vec_merge:V4SI
2670 (vec_duplicate:V4SI (match_dup 3))
2671 (match_dup 2)
2672 (const_int 2)))]
2673 {
2674 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2675 operands[3] = gen_highpart (SImode, operands[1]);
2676
2677 emit_move_insn (gen_lowpart (SImode, operands[0]),
2678 gen_lowpart (SImode, operands[1]));
2679 })
2680
2681 ;; movabsq $0x0012345678000000, %rax is longer
2682 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2683 (define_peephole2
2684 [(set (match_operand:DI 0 "register_operand")
2685 (match_operand:DI 1 "const_int_operand"))]
2686 "TARGET_64BIT
2687 && optimize_insn_for_size_p ()
2688 && LEGACY_INT_REG_P (operands[0])
2689 && !x86_64_immediate_operand (operands[1], DImode)
2690 && !x86_64_zext_immediate_operand (operands[1], DImode)
2691 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2692 & ~(HOST_WIDE_INT) 0xffffffff)
2693 && peep2_regno_dead_p (0, FLAGS_REG)"
2694 [(set (match_dup 0) (match_dup 1))
2695 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2696 (clobber (reg:CC FLAGS_REG))])]
2697 {
2698 int shift = ctz_hwi (UINTVAL (operands[1]));
2699 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2700 operands[2] = gen_int_mode (shift, QImode);
2701 })
2702
2703 (define_insn "*movsi_internal"
2704 [(set (match_operand:SI 0 "nonimmediate_operand"
2705 "=r,m ,*y,*y,?*y,?m,?r,?*y,?Yv,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2706 (match_operand:SI 1 "general_operand"
2707 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2708 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2709 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2710 {
2711 switch (get_attr_type (insn))
2712 {
2713 case TYPE_SSELOG1:
2714 return standard_sse_constant_opcode (insn, operands);
2715
2716 case TYPE_MSKMOV:
2717 return "kmovd\t{%1, %0|%0, %1}";
2718
2719 case TYPE_MSKLOG:
2720 if (operands[1] == const0_rtx)
2721 return "kxord\t%0, %0, %0";
2722 else if (operands[1] == constm1_rtx)
2723 return "kxnord\t%0, %0, %0";
2724 gcc_unreachable ();
2725
2726 case TYPE_SSEMOV:
2727 return ix86_output_ssemov (insn, operands);
2728
2729 case TYPE_MMX:
2730 return "pxor\t%0, %0";
2731
2732 case TYPE_MMXMOV:
2733 switch (get_attr_mode (insn))
2734 {
2735 case MODE_DI:
2736 return "movq\t{%1, %0|%0, %1}";
2737 case MODE_SI:
2738 return "movd\t{%1, %0|%0, %1}";
2739
2740 default:
2741 gcc_unreachable ();
2742 }
2743
2744 case TYPE_LEA:
2745 return "lea{l}\t{%E1, %0|%0, %E1}";
2746
2747 case TYPE_IMOV:
2748 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2749 if (ix86_use_lea_for_mov (insn, operands))
2750 return "lea{l}\t{%E1, %0|%0, %E1}";
2751 else
2752 return "mov{l}\t{%1, %0|%0, %1}";
2753
2754 default:
2755 gcc_unreachable ();
2756 }
2757 }
2758 [(set (attr "isa")
2759 (cond [(eq_attr "alternative" "12,13")
2760 (const_string "sse2")
2761 ]
2762 (const_string "*")))
2763 (set (attr "type")
2764 (cond [(eq_attr "alternative" "2")
2765 (const_string "mmx")
2766 (eq_attr "alternative" "3,4,5,6,7")
2767 (const_string "mmxmov")
2768 (eq_attr "alternative" "8")
2769 (const_string "sselog1")
2770 (eq_attr "alternative" "9,10,11,12,13")
2771 (const_string "ssemov")
2772 (eq_attr "alternative" "14,15,16")
2773 (const_string "mskmov")
2774 (eq_attr "alternative" "17")
2775 (const_string "msklog")
2776 (and (match_operand 0 "register_operand")
2777 (match_operand 1 "pic_32bit_operand"))
2778 (const_string "lea")
2779 ]
2780 (const_string "imov")))
2781 (set (attr "prefix")
2782 (if_then_else (eq_attr "type" "sselog1,ssemov")
2783 (const_string "maybe_vex")
2784 (const_string "orig")))
2785 (set (attr "prefix_data16")
2786 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2787 (const_string "1")
2788 (const_string "*")))
2789 (set (attr "mode")
2790 (cond [(eq_attr "alternative" "2,3")
2791 (const_string "DI")
2792 (eq_attr "alternative" "8")
2793 (cond [(match_test "TARGET_AVX")
2794 (const_string "TI")
2795 (ior (not (match_test "TARGET_SSE2"))
2796 (match_test "optimize_function_for_size_p (cfun)"))
2797 (const_string "V4SF")
2798 ]
2799 (const_string "TI"))
2800 (eq_attr "alternative" "9")
2801 (cond [(match_test "TARGET_AVX512VL")
2802 (const_string "TI")
2803 (match_test "TARGET_AVX512F")
2804 (const_string "SF")
2805 (match_test "TARGET_AVX")
2806 (const_string "TI")
2807 (ior (not (match_test "TARGET_SSE2"))
2808 (match_test "optimize_function_for_size_p (cfun)"))
2809 (const_string "V4SF")
2810 ]
2811 (const_string "TI"))
2812
2813 (and (eq_attr "alternative" "10,11")
2814 (not (match_test "TARGET_SSE2")))
2815 (const_string "SF")
2816 ]
2817 (const_string "SI")))
2818 (set (attr "preferred_for_speed")
2819 (cond [(eq_attr "alternative" "6,12")
2820 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2821 (eq_attr "alternative" "7,13")
2822 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2823 ]
2824 (symbol_ref "true")))])
2825
2826 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2827 (define_peephole2
2828 [(set (match_operand:SWI248 0 "general_reg_operand")
2829 (match_operand:SWI248 1 "const_int_operand"))]
2830 "optimize_insn_for_size_p () && optimize_size > 1
2831 && operands[1] != const0_rtx
2832 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2833 && !ix86_red_zone_used
2834 && REGNO (operands[0]) != SP_REG"
2835 [(set (match_dup 2) (match_dup 1))
2836 (set (match_dup 0) (match_dup 3))]
2837 {
2838 if (GET_MODE (operands[0]) != word_mode)
2839 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2840
2841 operands[2] = gen_rtx_MEM (word_mode,
2842 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2843 operands[3] = gen_rtx_MEM (word_mode,
2844 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2845 })
2846
2847 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2848 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2849 (define_peephole2
2850 [(set (match_operand:SWI248 0 "memory_operand")
2851 (match_operand:SWI248 1 "const_int_operand"))]
2852 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2853 && optimize_insn_for_size_p () && optimize_size > 1
2854 && peep2_regno_dead_p (0, FLAGS_REG)"
2855 [(parallel [(set (match_dup 0) (match_dup 1))
2856 (clobber (reg:CC FLAGS_REG))])])
2857
2858 (define_insn "*movhi_internal"
2859 [(set (match_operand:HI 0 "nonimmediate_operand"
2860 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*Yv,*v,*v,jm,m")
2861 (match_operand:HI 1 "general_operand"
2862 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*x,*v"))]
2863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2865 {
2866 switch (get_attr_type (insn))
2867 {
2868 case TYPE_IMOVX:
2869 /* movzwl is faster than movw on p2 due to partial word stalls,
2870 though not as fast as an aligned movl. */
2871 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2872
2873 case TYPE_MSKMOV:
2874 switch (which_alternative)
2875 {
2876 case 4:
2877 return "kmovw\t{%k1, %0|%0, %k1}";
2878 case 6:
2879 return "kmovw\t{%1, %k0|%k0, %1}";
2880 case 5:
2881 case 7:
2882 return "kmovw\t{%1, %0|%0, %1}";
2883 default:
2884 gcc_unreachable ();
2885 }
2886
2887 case TYPE_SSEMOV:
2888 return ix86_output_ssemov (insn, operands);
2889
2890 case TYPE_SSELOG1:
2891 if (satisfies_constraint_C (operands[1]))
2892 return standard_sse_constant_opcode (insn, operands);
2893
2894 if (SSE_REG_P (operands[0]))
2895 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2896 else
2897 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2898
2899 case TYPE_MSKLOG:
2900 if (operands[1] == const0_rtx)
2901 return "kxorw\t%0, %0, %0";
2902 else if (operands[1] == constm1_rtx)
2903 return "kxnorw\t%0, %0, %0";
2904 gcc_unreachable ();
2905
2906 default:
2907 if (get_attr_mode (insn) == MODE_SI)
2908 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2909 else
2910 return "mov{w}\t{%1, %0|%0, %1}";
2911 }
2912 }
2913 [(set (attr "isa")
2914 (cond [(eq_attr "alternative" "9,10,11,12,13")
2915 (const_string "sse2")
2916 (eq_attr "alternative" "14")
2917 (const_string "sse4_noavx")
2918 (eq_attr "alternative" "15")
2919 (const_string "avx")
2920 ]
2921 (const_string "*")))
2922 (set (attr "addr")
2923 (if_then_else (eq_attr "alternative" "14")
2924 (const_string "gpr16")
2925 (const_string "*")))
2926 (set (attr "type")
2927 (cond [(eq_attr "alternative" "4,5,6,7")
2928 (const_string "mskmov")
2929 (eq_attr "alternative" "8")
2930 (const_string "msklog")
2931 (eq_attr "alternative" "13,14,15")
2932 (if_then_else (match_test "TARGET_AVX512FP16")
2933 (const_string "ssemov")
2934 (const_string "sselog1"))
2935 (eq_attr "alternative" "11")
2936 (const_string "sselog1")
2937 (eq_attr "alternative" "9,10,12")
2938 (const_string "ssemov")
2939 (match_test "optimize_function_for_size_p (cfun)")
2940 (const_string "imov")
2941 (and (eq_attr "alternative" "0")
2942 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2943 (not (match_test "TARGET_HIMODE_MATH"))))
2944 (const_string "imov")
2945 (and (eq_attr "alternative" "1,2")
2946 (match_operand:HI 1 "aligned_operand"))
2947 (const_string "imov")
2948 (and (match_test "TARGET_MOVX")
2949 (eq_attr "alternative" "0,2"))
2950 (const_string "imovx")
2951 ]
2952 (const_string "imov")))
2953 (set (attr "prefix")
2954 (cond [(eq_attr "alternative" "4,5,6,7,8")
2955 (const_string "vex")
2956 (eq_attr "alternative" "9,10,11,12,13,14,15")
2957 (const_string "maybe_evex")
2958 ]
2959 (const_string "orig")))
2960 (set (attr "mode")
2961 (cond [(eq_attr "alternative" "9,10")
2962 (if_then_else (match_test "TARGET_AVX512FP16")
2963 (const_string "HI")
2964 (const_string "SI"))
2965 (eq_attr "alternative" "13,14,15")
2966 (if_then_else (match_test "TARGET_AVX512FP16")
2967 (const_string "HI")
2968 (const_string "TI"))
2969 (eq_attr "alternative" "11")
2970 (cond [(match_test "TARGET_AVX")
2971 (const_string "TI")
2972 (ior (not (match_test "TARGET_SSE2"))
2973 (match_test "optimize_function_for_size_p (cfun)"))
2974 (const_string "V4SF")
2975 ]
2976 (const_string "TI"))
2977 (eq_attr "alternative" "12")
2978 (cond [(match_test "TARGET_AVX512VL")
2979 (const_string "TI")
2980 (match_test "TARGET_AVX512FP16")
2981 (const_string "HF")
2982 (match_test "TARGET_AVX512F")
2983 (const_string "SF")
2984 (match_test "TARGET_AVX")
2985 (const_string "TI")
2986 (ior (not (match_test "TARGET_SSE2"))
2987 (match_test "optimize_function_for_size_p (cfun)"))
2988 (const_string "V4SF")
2989 ]
2990 (const_string "TI"))
2991 (eq_attr "type" "imovx")
2992 (const_string "SI")
2993 (and (eq_attr "alternative" "1,2")
2994 (match_operand:HI 1 "aligned_operand"))
2995 (const_string "SI")
2996 (and (eq_attr "alternative" "0")
2997 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2998 (not (match_test "TARGET_HIMODE_MATH"))))
2999 (const_string "SI")
3000 ]
3001 (const_string "HI")))
3002 (set (attr "preferred_for_speed")
3003 (cond [(eq_attr "alternative" "9")
3004 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3005 (eq_attr "alternative" "10")
3006 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3007 ]
3008 (symbol_ref "true")))])
3009
3010 ;; Situation is quite tricky about when to choose full sized (SImode) move
3011 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
3012 ;; partial register dependency machines (such as AMD Athlon), where QImode
3013 ;; moves issue extra dependency and for partial register stalls machines
3014 ;; that don't use QImode patterns (and QImode move cause stall on the next
3015 ;; instruction).
3016 ;;
3017 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
3018 ;; register stall machines with, where we use QImode instructions, since
3019 ;; partial register stall can be caused there. Then we use movzx.
3020
3021 (define_insn "*movqi_internal"
3022 [(set (match_operand:QI 0 "nonimmediate_operand"
3023 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
3024 (match_operand:QI 1 "general_operand"
3025 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3026 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3027 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3028
3029 {
3030 char buf[128];
3031 const char *ops;
3032 const char *suffix;
3033
3034 switch (get_attr_type (insn))
3035 {
3036 case TYPE_IMOVX:
3037 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3038 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3039
3040 case TYPE_MSKMOV:
3041 switch (which_alternative)
3042 {
3043 case 9:
3044 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3045 break;
3046 case 11:
3047 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3048 break;
3049 case 12:
3050 case 13:
3051 gcc_assert (TARGET_AVX512DQ);
3052 /* FALLTHRU */
3053 case 10:
3054 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3055 break;
3056 default:
3057 gcc_unreachable ();
3058 }
3059
3060 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3061
3062 snprintf (buf, sizeof (buf), ops, suffix);
3063 output_asm_insn (buf, operands);
3064 return "";
3065
3066 case TYPE_MSKLOG:
3067 if (operands[1] == const0_rtx)
3068 {
3069 if (get_attr_mode (insn) == MODE_HI)
3070 return "kxorw\t%0, %0, %0";
3071 else
3072 return "kxorb\t%0, %0, %0";
3073 }
3074 else if (operands[1] == constm1_rtx)
3075 {
3076 gcc_assert (TARGET_AVX512DQ);
3077 return "kxnorb\t%0, %0, %0";
3078 }
3079 gcc_unreachable ();
3080
3081 default:
3082 if (get_attr_mode (insn) == MODE_SI)
3083 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3084 else
3085 return "mov{b}\t{%1, %0|%0, %1}";
3086 }
3087 }
3088 [(set (attr "isa")
3089 (cond [(eq_attr "alternative" "1,2")
3090 (const_string "x64")
3091 (eq_attr "alternative" "12,13,15")
3092 (const_string "avx512dq")
3093 ]
3094 (const_string "*")))
3095 (set (attr "type")
3096 (cond [(eq_attr "alternative" "9,10,11,12,13")
3097 (const_string "mskmov")
3098 (eq_attr "alternative" "14,15")
3099 (const_string "msklog")
3100 (and (eq_attr "alternative" "7")
3101 (not (match_operand:QI 1 "aligned_operand")))
3102 (const_string "imovx")
3103 (match_test "optimize_function_for_size_p (cfun)")
3104 (const_string "imov")
3105 (and (eq_attr "alternative" "5")
3106 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3107 (not (match_test "TARGET_QIMODE_MATH"))))
3108 (const_string "imov")
3109 (eq_attr "alternative" "5,7")
3110 (const_string "imovx")
3111 (and (match_test "TARGET_MOVX")
3112 (eq_attr "alternative" "4"))
3113 (const_string "imovx")
3114 ]
3115 (const_string "imov")))
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3118 (const_string "vex")
3119 (const_string "orig")))
3120 (set (attr "mode")
3121 (cond [(eq_attr "alternative" "5,6,7")
3122 (const_string "SI")
3123 (eq_attr "alternative" "8")
3124 (const_string "QI")
3125 (and (eq_attr "alternative" "9,10,11,14")
3126 (not (match_test "TARGET_AVX512DQ")))
3127 (const_string "HI")
3128 (eq_attr "type" "imovx")
3129 (const_string "SI")
3130 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3131 ;; ones.
3132 (and (eq_attr "type" "imov")
3133 (and (eq_attr "alternative" "3")
3134 (match_test "optimize_function_for_size_p (cfun)")))
3135 (const_string "QI")
3136 ;; For -Os, movl where one or both operands are NON_Q_REGS
3137 ;; and both are LEGACY_REGS is shorter than movb.
3138 ;; Otherwise movb and movl sizes are the same, so decide purely
3139 ;; based on speed factors.
3140 (and (eq_attr "type" "imov")
3141 (and (eq_attr "alternative" "1")
3142 (match_test "optimize_function_for_size_p (cfun)")))
3143 (const_string "SI")
3144 (and (eq_attr "type" "imov")
3145 (and (eq_attr "alternative" "0,1,2,3")
3146 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3147 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3148 (const_string "SI")
3149 ;; Avoid partial register stalls when not using QImode arithmetic
3150 (and (eq_attr "type" "imov")
3151 (and (eq_attr "alternative" "0,1,2,3")
3152 (and (match_test "TARGET_PARTIAL_REG_STALL")
3153 (not (match_test "TARGET_QIMODE_MATH")))))
3154 (const_string "SI")
3155 ]
3156 (const_string "QI")))])
3157
3158 /* Reload dislikes loading 0/-1 directly into mask registers.
3159 Try to tidy things up here. */
3160 (define_peephole2
3161 [(set (match_operand:SWI 0 "general_reg_operand")
3162 (match_operand:SWI 1 "immediate_operand"))
3163 (set (match_operand:SWI 2 "mask_reg_operand")
3164 (match_dup 0))]
3165 "peep2_reg_dead_p (2, operands[0])
3166 && (const0_operand (operands[1], <MODE>mode)
3167 || (constm1_operand (operands[1], <MODE>mode)
3168 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3169 [(set (match_dup 2) (match_dup 1))])
3170
3171 ;; Stores and loads of ax to arbitrary constant address.
3172 ;; We fake an second form of instruction to force reload to load address
3173 ;; into register when rax is not available
3174 (define_insn "*movabs<mode>_1"
3175 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3176 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3177 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3178 {
3179 /* Recover the full memory rtx. */
3180 operands[0] = SET_DEST (PATTERN (insn));
3181 switch (which_alternative)
3182 {
3183 case 0:
3184 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3185 case 1:
3186 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3187 default:
3188 gcc_unreachable ();
3189 }
3190 }
3191 [(set_attr "type" "imov")
3192 (set_attr "modrm" "0,*")
3193 (set_attr "length_address" "8,0")
3194 (set_attr "length_immediate" "0,*")
3195 (set_attr "memory" "store")
3196 (set_attr "mode" "<MODE>")])
3197
3198 (define_insn "*movabs<mode>_2"
3199 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3200 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3201 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3202 {
3203 /* Recover the full memory rtx. */
3204 operands[1] = SET_SRC (PATTERN (insn));
3205 switch (which_alternative)
3206 {
3207 case 0:
3208 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3209 case 1:
3210 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3211 default:
3212 gcc_unreachable ();
3213 }
3214 }
3215 [(set_attr "type" "imov")
3216 (set_attr "modrm" "0,*")
3217 (set_attr "length_address" "8,0")
3218 (set_attr "length_immediate" "0")
3219 (set_attr "memory" "load")
3220 (set_attr "mode" "<MODE>")])
3221
3222 (define_insn "swap<mode>"
3223 [(set (match_operand:SWI48 0 "register_operand" "+r")
3224 (match_operand:SWI48 1 "register_operand" "+r"))
3225 (set (match_dup 1)
3226 (match_dup 0))]
3227 ""
3228 "xchg{<imodesuffix>}\t%1, %0"
3229 [(set_attr "type" "imov")
3230 (set_attr "mode" "<MODE>")
3231 (set_attr "pent_pair" "np")
3232 (set_attr "athlon_decode" "vector")
3233 (set_attr "amdfam10_decode" "double")
3234 (set_attr "bdver1_decode" "double")])
3235
3236 (define_insn "*swap<mode>"
3237 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3238 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3239 (set (match_dup 1)
3240 (match_dup 0))]
3241 ""
3242 "@
3243 xchg{<imodesuffix>}\t%1, %0
3244 xchg{l}\t%k1, %k0"
3245 [(set_attr "type" "imov")
3246 (set_attr "mode" "<MODE>,SI")
3247 (set (attr "preferred_for_size")
3248 (cond [(eq_attr "alternative" "0")
3249 (symbol_ref "false")]
3250 (symbol_ref "true")))
3251 ;; Potential partial reg stall on alternative 1.
3252 (set (attr "preferred_for_speed")
3253 (cond [(eq_attr "alternative" "1")
3254 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3255 (symbol_ref "true")))
3256 (set_attr "pent_pair" "np")
3257 (set_attr "athlon_decode" "vector")
3258 (set_attr "amdfam10_decode" "double")
3259 (set_attr "bdver1_decode" "double")])
3260
3261 (define_peephole2
3262 [(set (match_operand:SWI 0 "general_reg_operand")
3263 (match_operand:SWI 1 "general_reg_operand"))
3264 (set (match_dup 1)
3265 (match_operand:SWI 2 "general_reg_operand"))
3266 (set (match_dup 2) (match_dup 0))]
3267 "peep2_reg_dead_p (3, operands[0])
3268 && optimize_insn_for_size_p ()"
3269 [(parallel [(set (match_dup 1) (match_dup 2))
3270 (set (match_dup 2) (match_dup 1))])])
3271
3272 ;; Convert xchg with a REG_UNUSED note to a mov (variant #1).
3273 (define_peephole2
3274 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3275 (match_operand:SWI 1 "general_reg_operand"))
3276 (set (match_dup 1) (match_dup 0))])]
3277 "((REGNO (operands[0]) != AX_REG
3278 && REGNO (operands[1]) != AX_REG)
3279 || optimize_size < 2
3280 || !optimize_insn_for_size_p ())
3281 && peep2_reg_dead_p (1, operands[0])"
3282 [(set (match_dup 1) (match_dup 0))])
3283
3284 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3285 (define_peephole2
3286 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3287 (match_operand:SWI 1 "general_reg_operand"))
3288 (set (match_dup 1) (match_dup 0))])]
3289 "((REGNO (operands[0]) != AX_REG
3290 && REGNO (operands[1]) != AX_REG)
3291 || optimize_size < 2
3292 || !optimize_insn_for_size_p ())
3293 && peep2_reg_dead_p (1, operands[1])"
3294 [(set (match_dup 0) (match_dup 1))])
3295
3296 ;; Convert moves to/from AX_REG into xchg with -Oz.
3297 (define_peephole2
3298 [(set (match_operand:SWI48 0 "general_reg_operand")
3299 (match_operand:SWI48 1 "general_reg_operand"))]
3300 "optimize_size > 1
3301 && ((REGNO (operands[0]) == AX_REG)
3302 != (REGNO (operands[1]) == AX_REG))
3303 && optimize_insn_for_size_p ()
3304 && peep2_reg_dead_p (1, operands[1])"
3305 [(parallel [(set (match_dup 0) (match_dup 1))
3306 (set (match_dup 1) (match_dup 0))])])
3307
3308 (define_expand "movstrict<mode>"
3309 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3310 (match_operand:SWI12 1 "general_operand"))]
3311 ""
3312 {
3313 gcc_assert (SUBREG_P (operands[0]));
3314 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3315 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3316 FAIL;
3317 })
3318
3319 (define_insn "*movstrict<mode>_1"
3320 [(set (strict_low_part
3321 (match_operand:SWI12 0 "register_operand" "+<r>"))
3322 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3323 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3324 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3325 [(set_attr "type" "imov")
3326 (set_attr "mode" "<MODE>")])
3327
3328 (define_insn "*movstrict<mode>_xor"
3329 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3330 (match_operand:SWI12 1 "const0_operand"))
3331 (clobber (reg:CC FLAGS_REG))]
3332 "reload_completed"
3333 "xor{<imodesuffix>}\t%0, %0"
3334 [(set_attr "type" "alu1")
3335 (set_attr "mode" "<MODE>")
3336 (set_attr "length_immediate" "0")])
3337
3338 (define_insn "*movstrictqi_ext<mode>_1"
3339 [(set (strict_low_part
3340 (match_operand:QI 0 "register_operand" "+Q"))
3341 (subreg:QI
3342 (match_operator:SWI248 2 "extract_operator"
3343 [(match_operand 1 "int248_register_operand" "Q")
3344 (const_int 8)
3345 (const_int 8)]) 0))]
3346 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3347 "mov{b}\t{%h1, %0|%0, %h1}"
3348 [(set_attr "type" "imov")
3349 (set_attr "mode" "QI")])
3350
3351 (define_expand "extv<mode>"
3352 [(set (match_operand:SWI24 0 "register_operand")
3353 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3354 (match_operand:QI 2 "const_int_operand")
3355 (match_operand:QI 3 "const_int_operand")))]
3356 ""
3357 {
3358 /* Handle extractions from %ah et al. */
3359 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3360 FAIL;
3361
3362 unsigned int regno = reg_or_subregno (operands[1]);
3363
3364 /* Be careful to expand only with registers having upper parts. */
3365 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3366 operands[1] = copy_to_reg (operands[1]);
3367 })
3368
3369 (define_insn "*extv<mode>"
3370 [(set (match_operand:SWI24 0 "register_operand" "=R")
3371 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3372 (const_int 8)
3373 (const_int 8)))]
3374 ""
3375 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3376 [(set_attr "type" "imovx")
3377 (set_attr "mode" "SI")])
3378
3379 ;; Split sign-extension of single least significant bit as and x,$1;neg x
3380 (define_insn_and_split "*extv<mode>_1_0"
3381 [(set (match_operand:SWI48 0 "register_operand" "=r")
3382 (sign_extract:SWI48 (match_operand:SWI48 1 "register_operand" "0")
3383 (const_int 1)
3384 (const_int 0)))
3385 (clobber (reg:CC FLAGS_REG))]
3386 ""
3387 "#"
3388 ""
3389 [(parallel [(set (match_dup 0) (and:SWI48 (match_dup 1) (const_int 1)))
3390 (clobber (reg:CC FLAGS_REG))])
3391 (parallel [(set (match_dup 0) (neg:SWI48 (match_dup 0)))
3392 (clobber (reg:CC FLAGS_REG))])])
3393
3394 (define_expand "extzv<mode>"
3395 [(set (match_operand:SWI248 0 "register_operand")
3396 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3397 (match_operand:QI 2 "const_int_operand")
3398 (match_operand:QI 3 "const_int_operand")))]
3399 ""
3400 {
3401 if (ix86_expand_pextr (operands))
3402 DONE;
3403
3404 /* Handle extractions from %ah et al. */
3405 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3406 FAIL;
3407
3408 unsigned int regno = reg_or_subregno (operands[1]);
3409
3410 /* Be careful to expand only with registers having upper parts. */
3411 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3412 operands[1] = copy_to_reg (operands[1]);
3413 })
3414
3415 (define_insn "*extzv<mode>"
3416 [(set (match_operand:SWI248 0 "register_operand" "=R")
3417 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3418 (const_int 8)
3419 (const_int 8)))]
3420 ""
3421 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "SI")])
3424
3425 (define_insn "*extzvqi"
3426 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn,?R")
3427 (subreg:QI
3428 (match_operator:SWI248 2 "extract_operator"
3429 [(match_operand 1 "int248_register_operand" "Q,Q")
3430 (const_int 8)
3431 (const_int 8)]) 0))]
3432 ""
3433 {
3434 switch (get_attr_type (insn))
3435 {
3436 case TYPE_IMOVX:
3437 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3438 default:
3439 return "mov{b}\t{%h1, %0|%0, %h1}";
3440 }
3441 }
3442 [(set_attr "addr" "gpr8,*")
3443 (set (attr "type")
3444 (if_then_else (and (match_operand:QI 0 "register_operand")
3445 (ior (not (match_operand:QI 0 "QIreg_operand"))
3446 (match_test "TARGET_MOVX")))
3447 (const_string "imovx")
3448 (const_string "imov")))
3449 (set (attr "mode")
3450 (if_then_else (eq_attr "type" "imovx")
3451 (const_string "SI")
3452 (const_string "QI")))])
3453
3454 (define_expand "insv<mode>"
3455 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3456 (match_operand:QI 1 "const_int_operand")
3457 (match_operand:QI 2 "const_int_operand"))
3458 (match_operand:SWI248 3 "register_operand"))]
3459 ""
3460 {
3461 rtx dst;
3462
3463 if (ix86_expand_pinsr (operands))
3464 DONE;
3465
3466 /* Handle insertions to %ah et al. */
3467 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3468 FAIL;
3469
3470 unsigned int regno = reg_or_subregno (operands[0]);
3471
3472 /* Be careful to expand only with registers having upper parts. */
3473 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3474 dst = copy_to_reg (operands[0]);
3475 else
3476 dst = operands[0];
3477
3478 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3479
3480 /* Fix up the destination if needed. */
3481 if (dst != operands[0])
3482 emit_move_insn (operands[0], dst);
3483
3484 DONE;
3485 })
3486
3487 (define_insn "@insv<mode>_1"
3488 [(set (zero_extract:SWI248
3489 (match_operand 0 "int248_register_operand" "+Q")
3490 (const_int 8)
3491 (const_int 8))
3492 (match_operand:SWI248 1 "general_operand" "QnBn"))]
3493 ""
3494 {
3495 if (CONST_INT_P (operands[1]))
3496 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3497 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3498 }
3499 [(set_attr "addr" "gpr8")
3500 (set_attr "type" "imov")
3501 (set_attr "mode" "QI")])
3502
3503 (define_insn "*insvqi_1"
3504 [(set (zero_extract:SWI248
3505 (match_operand 0 "int248_register_operand" "+Q")
3506 (const_int 8)
3507 (const_int 8))
3508 (subreg:SWI248
3509 (match_operand:QI 1 "general_operand" "QnBn") 0))]
3510 ""
3511 "mov{b}\t{%1, %h0|%h0, %1}"
3512 [(set_attr "addr" "gpr8")
3513 (set_attr "type" "imov")
3514 (set_attr "mode" "QI")])
3515
3516 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3517 (define_peephole2
3518 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3519 (const_int 0))
3520 (clobber (reg:CC FLAGS_REG))])
3521 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3522 (const_int 8)
3523 (const_int 8))
3524 (const_int 0))]
3525 "REGNO (operands[0]) == REGNO (operands[1])"
3526 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3527 (const_int 0))
3528 (clobber (reg:CC FLAGS_REG))])])
3529
3530 ;; Combine movl followed by movb.
3531 (define_peephole2
3532 [(set (match_operand:SWI48 0 "general_reg_operand")
3533 (match_operand:SWI48 1 "const_int_operand"))
3534 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3535 (const_int 8)
3536 (const_int 8))
3537 (match_operand:SWI248 3 "const_int_operand"))]
3538 "REGNO (operands[0]) == REGNO (operands[2])"
3539 [(set (match_operand:SWI48 0 "general_reg_operand")
3540 (match_dup 4))]
3541 {
3542 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3543 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3544 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3545 })
3546
3547 (define_insn "*insvqi_2"
3548 [(set (zero_extract:SWI248
3549 (match_operand 0 "int248_register_operand" "+Q")
3550 (const_int 8)
3551 (const_int 8))
3552 (match_operator:SWI248 2 "extract_operator"
3553 [(match_operand 1 "int248_register_operand" "Q")
3554 (const_int 8)
3555 (const_int 8)]))]
3556 ""
3557 "mov{b}\t{%h1, %h0|%h0, %h1}"
3558 [(set_attr "type" "imov")
3559 (set_attr "mode" "QI")])
3560
3561 (define_insn "*insvqi_3"
3562 [(set (zero_extract:SWI248
3563 (match_operand 0 "int248_register_operand" "+Q")
3564 (const_int 8)
3565 (const_int 8))
3566 (any_shiftrt:SWI248
3567 (match_operand:SWI248 1 "register_operand" "Q")
3568 (const_int 8)))]
3569 ""
3570 "mov{b}\t{%h1, %h0|%h0, %h1}"
3571 [(set_attr "type" "imov")
3572 (set_attr "mode" "QI")])
3573
3574 (define_code_iterator any_or_plus [plus ior xor])
3575
3576 (define_insn_and_split "*insvti_highpart_1"
3577 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3578 (any_or_plus:TI
3579 (and:TI
3580 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3581 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3582 (ashift:TI
3583 (zero_extend:TI
3584 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3585 (const_int 64))))]
3586 "TARGET_64BIT
3587 && CONST_WIDE_INT_P (operands[3])
3588 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3589 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3590 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3591 "#"
3592 "&& reload_completed"
3593 [(const_int 0)]
3594 {
3595 operands[4] = gen_lowpart (DImode, operands[1]);
3596 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3597 DONE;
3598 })
3599
3600 (define_insn_and_split "*insvti_lowpart_1"
3601 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3602 (any_or_plus:TI
3603 (and:TI
3604 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3605 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3606 (zero_extend:TI
3607 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3608 "TARGET_64BIT
3609 && CONST_WIDE_INT_P (operands[3])
3610 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3611 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3612 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3613 "#"
3614 "&& reload_completed"
3615 [(const_int 0)]
3616 {
3617 operands[4] = gen_highpart (DImode, operands[1]);
3618 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3619 DONE;
3620 })
3621
3622 (define_insn_and_split "*insvdi_lowpart_1"
3623 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3624 (any_or_plus:DI
3625 (and:DI
3626 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3627 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3628 (zero_extend:DI
3629 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3630 "!TARGET_64BIT
3631 && CONST_INT_P (operands[3])
3632 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3633 "#"
3634 "&& reload_completed"
3635 [(const_int 0)]
3636 {
3637 operands[4] = gen_highpart (SImode, operands[1]);
3638 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3639 DONE;
3640 })
3641 \f
3642 ;; Floating point push instructions.
3643
3644 (define_insn "*pushtf"
3645 [(set (match_operand:TF 0 "push_operand" "=<,<")
3646 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3647 "TARGET_64BIT || TARGET_SSE"
3648 {
3649 /* This insn should be already split before reg-stack. */
3650 return "#";
3651 }
3652 [(set_attr "isa" "*,x64")
3653 (set_attr "type" "multi")
3654 (set_attr "unit" "sse,*")
3655 (set_attr "mode" "TF,DI")])
3656
3657 ;; %%% Kill this when call knows how to work this out.
3658 (define_split
3659 [(set (match_operand:TF 0 "push_operand")
3660 (match_operand:TF 1 "sse_reg_operand"))]
3661 "TARGET_SSE && reload_completed"
3662 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3663 (set (match_dup 0) (match_dup 1))]
3664 {
3665 /* Preserve memory attributes. */
3666 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3667 })
3668
3669 (define_insn "*pushxf"
3670 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3671 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3672 ""
3673 {
3674 /* This insn should be already split before reg-stack. */
3675 return "#";
3676 }
3677 [(set_attr "isa" "*,*,*,nox64,x64")
3678 (set_attr "type" "multi")
3679 (set_attr "unit" "i387,*,*,*,*")
3680 (set (attr "mode")
3681 (cond [(eq_attr "alternative" "1,2,3,4")
3682 (if_then_else (match_test "TARGET_64BIT")
3683 (const_string "DI")
3684 (const_string "SI"))
3685 ]
3686 (const_string "XF")))
3687 (set (attr "preferred_for_size")
3688 (cond [(eq_attr "alternative" "1")
3689 (symbol_ref "false")]
3690 (symbol_ref "true")))])
3691
3692 ;; %%% Kill this when call knows how to work this out.
3693 (define_split
3694 [(set (match_operand:XF 0 "push_operand")
3695 (match_operand:XF 1 "fp_register_operand"))]
3696 "reload_completed"
3697 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3698 (set (match_dup 0) (match_dup 1))]
3699 {
3700 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3701 /* Preserve memory attributes. */
3702 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3703 })
3704
3705 (define_insn "*pushdf"
3706 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3707 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3708 ""
3709 {
3710 /* This insn should be already split before reg-stack. */
3711 return "#";
3712 }
3713 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3714 (set_attr "type" "multi")
3715 (set_attr "unit" "i387,*,*,*,*,sse")
3716 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3717 (set (attr "preferred_for_size")
3718 (cond [(eq_attr "alternative" "1")
3719 (symbol_ref "false")]
3720 (symbol_ref "true")))
3721 (set (attr "preferred_for_speed")
3722 (cond [(eq_attr "alternative" "1")
3723 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3724 (symbol_ref "true")))])
3725
3726 ;; %%% Kill this when call knows how to work this out.
3727 (define_split
3728 [(set (match_operand:DF 0 "push_operand")
3729 (match_operand:DF 1 "any_fp_register_operand"))]
3730 "reload_completed"
3731 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3732 (set (match_dup 0) (match_dup 1))]
3733 {
3734 /* Preserve memory attributes. */
3735 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3736 })
3737
3738 (define_mode_iterator HFBF [HF BF])
3739
3740 (define_insn "*push<mode>_rex64"
3741 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3742 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3743 "TARGET_64BIT"
3744 {
3745 /* Anything else should be already split before reg-stack. */
3746 gcc_assert (which_alternative == 0);
3747 return "push{q}\t%q1";
3748 }
3749 [(set_attr "isa" "*,sse4")
3750 (set_attr "type" "push,multi")
3751 (set_attr "mode" "DI,TI")])
3752
3753 (define_insn "*push<mode>"
3754 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3755 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3756 "!TARGET_64BIT"
3757 {
3758 /* Anything else should be already split before reg-stack. */
3759 gcc_assert (which_alternative == 0);
3760 return "push{l}\t%k1";
3761 }
3762 [(set_attr "isa" "*,sse4")
3763 (set_attr "type" "push,multi")
3764 (set_attr "mode" "SI,TI")])
3765
3766 (define_insn "push2_di"
3767 [(set (match_operand:TI 0 "push_operand" "=<")
3768 (unspec:TI [(match_operand:DI 1 "register_operand" "r")
3769 (match_operand:DI 2 "register_operand" "r")]
3770 UNSPEC_APXPUSH2))]
3771 "TARGET_APX_PUSH2POP2"
3772 "push2\t%1, %2"
3773 [(set_attr "mode" "TI")
3774 (set_attr "type" "multi")
3775 (set_attr "prefix" "evex")])
3776
3777 (define_insn "pop2_di"
3778 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3779 (unspec:DI [(match_operand:TI 1 "pop_operand" ">")]
3780 UNSPEC_APXPOP2_LOW))
3781 (set (match_operand:DI 2 "register_operand" "=r")
3782 (unspec:DI [(const_int 0)] UNSPEC_APXPOP2_HIGH))])]
3783 "TARGET_APX_PUSH2POP2"
3784 "pop2\t%0, %2"
3785 [(set_attr "mode" "TI")
3786 (set_attr "prefix" "evex")])
3787
3788 (define_insn "*pushsf_rex64"
3789 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3790 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3791 "TARGET_64BIT"
3792 {
3793 /* Anything else should be already split before reg-stack. */
3794 if (which_alternative != 1)
3795 return "#";
3796 return "push{q}\t%q1";
3797 }
3798 [(set_attr "type" "multi,push,multi")
3799 (set_attr "unit" "i387,*,*")
3800 (set_attr "mode" "SF,DI,SF")])
3801
3802 (define_insn "*pushsf"
3803 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3804 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3805 "!TARGET_64BIT"
3806 {
3807 /* Anything else should be already split before reg-stack. */
3808 if (which_alternative != 1)
3809 return "#";
3810 return "push{l}\t%1";
3811 }
3812 [(set_attr "type" "multi,push,multi")
3813 (set_attr "unit" "i387,*,*")
3814 (set_attr "mode" "SF,SI,SF")])
3815
3816 (define_mode_iterator MODESH [SF HF BF])
3817 ;; %%% Kill this when call knows how to work this out.
3818 (define_split
3819 [(set (match_operand:MODESH 0 "push_operand")
3820 (match_operand:MODESH 1 "any_fp_register_operand"))]
3821 "reload_completed"
3822 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3823 (set (match_dup 0) (match_dup 1))]
3824 {
3825 rtx op = XEXP (operands[0], 0);
3826 if (GET_CODE (op) == PRE_DEC)
3827 {
3828 gcc_assert (!TARGET_64BIT);
3829 op = GEN_INT (-4);
3830 }
3831 else
3832 {
3833 op = XEXP (XEXP (op, 1), 1);
3834 gcc_assert (CONST_INT_P (op));
3835 }
3836 operands[2] = op;
3837 /* Preserve memory attributes. */
3838 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3839 })
3840
3841 (define_split
3842 [(set (match_operand:SF 0 "push_operand")
3843 (match_operand:SF 1 "memory_operand"))]
3844 "reload_completed
3845 && find_constant_src (insn)"
3846 [(set (match_dup 0) (match_dup 2))]
3847 "operands[2] = find_constant_src (curr_insn);")
3848
3849 (define_split
3850 [(set (match_operand 0 "push_operand")
3851 (match_operand 1 "general_gr_operand"))]
3852 "reload_completed
3853 && (GET_MODE (operands[0]) == TFmode
3854 || GET_MODE (operands[0]) == XFmode
3855 || GET_MODE (operands[0]) == DFmode)"
3856 [(const_int 0)]
3857 "ix86_split_long_move (operands); DONE;")
3858 \f
3859 ;; Floating point move instructions.
3860
3861 (define_expand "movtf"
3862 [(set (match_operand:TF 0 "nonimmediate_operand")
3863 (match_operand:TF 1 "nonimmediate_operand"))]
3864 "TARGET_64BIT || TARGET_SSE"
3865 "ix86_expand_move (TFmode, operands); DONE;")
3866
3867 (define_expand "mov<mode>"
3868 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3869 (match_operand:X87MODEFH 1 "general_operand"))]
3870 ""
3871 "ix86_expand_move (<MODE>mode, operands); DONE;")
3872
3873 (define_insn "*movtf_internal"
3874 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3875 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3876 "(TARGET_64BIT || TARGET_SSE)
3877 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3878 && (lra_in_progress || reload_completed
3879 || !CONST_DOUBLE_P (operands[1])
3880 || (standard_sse_constant_p (operands[1], TFmode) == 1
3881 && !memory_operand (operands[0], TFmode))
3882 || (!TARGET_MEMORY_MISMATCH_STALL
3883 && memory_operand (operands[0], TFmode)))"
3884 {
3885 switch (get_attr_type (insn))
3886 {
3887 case TYPE_SSELOG1:
3888 return standard_sse_constant_opcode (insn, operands);
3889
3890 case TYPE_SSEMOV:
3891 return ix86_output_ssemov (insn, operands);
3892
3893 case TYPE_MULTI:
3894 return "#";
3895
3896 default:
3897 gcc_unreachable ();
3898 }
3899 }
3900 [(set_attr "isa" "*,*,*,x64,x64")
3901 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3902 (set (attr "prefix")
3903 (if_then_else (eq_attr "type" "sselog1,ssemov")
3904 (const_string "maybe_vex")
3905 (const_string "orig")))
3906 (set (attr "mode")
3907 (cond [(eq_attr "alternative" "3,4")
3908 (const_string "DI")
3909 (match_test "TARGET_AVX")
3910 (const_string "TI")
3911 (ior (not (match_test "TARGET_SSE2"))
3912 (match_test "optimize_function_for_size_p (cfun)"))
3913 (const_string "V4SF")
3914 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3915 (const_string "V4SF")
3916 (and (eq_attr "alternative" "2")
3917 (match_test "TARGET_SSE_TYPELESS_STORES"))
3918 (const_string "V4SF")
3919 ]
3920 (const_string "TI")))])
3921
3922 (define_split
3923 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3924 (match_operand:TF 1 "general_gr_operand"))]
3925 "reload_completed"
3926 [(const_int 0)]
3927 "ix86_split_long_move (operands); DONE;")
3928
3929 ;; Possible store forwarding (partial memory) stall
3930 ;; in alternatives 4, 6, 7 and 8.
3931 (define_insn "*movxf_internal"
3932 [(set (match_operand:XF 0 "nonimmediate_operand"
3933 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3934 (match_operand:XF 1 "general_operand"
3935 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3936 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3937 && (lra_in_progress || reload_completed
3938 || !CONST_DOUBLE_P (operands[1])
3939 || ((optimize_function_for_size_p (cfun)
3940 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3941 && standard_80387_constant_p (operands[1]) > 0
3942 && !memory_operand (operands[0], XFmode))
3943 || (!TARGET_MEMORY_MISMATCH_STALL
3944 && memory_operand (operands[0], XFmode))
3945 || !TARGET_HARD_XF_REGS)"
3946 {
3947 switch (get_attr_type (insn))
3948 {
3949 case TYPE_FMOV:
3950 if (which_alternative == 2)
3951 return standard_80387_constant_opcode (operands[1]);
3952 return output_387_reg_move (insn, operands);
3953
3954 case TYPE_MULTI:
3955 return "#";
3956
3957 default:
3958 gcc_unreachable ();
3959 }
3960 }
3961 [(set (attr "isa")
3962 (cond [(eq_attr "alternative" "7,10")
3963 (const_string "nox64")
3964 (eq_attr "alternative" "8,11")
3965 (const_string "x64")
3966 ]
3967 (const_string "*")))
3968 (set (attr "type")
3969 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3970 (const_string "multi")
3971 ]
3972 (const_string "fmov")))
3973 (set (attr "mode")
3974 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3975 (if_then_else (match_test "TARGET_64BIT")
3976 (const_string "DI")
3977 (const_string "SI"))
3978 ]
3979 (const_string "XF")))
3980 (set (attr "preferred_for_size")
3981 (cond [(eq_attr "alternative" "3,4")
3982 (symbol_ref "false")]
3983 (symbol_ref "true")))
3984 (set (attr "enabled")
3985 (cond [(eq_attr "alternative" "9,10,11")
3986 (if_then_else
3987 (match_test "TARGET_HARD_XF_REGS")
3988 (symbol_ref "false")
3989 (const_string "*"))
3990 (not (match_test "TARGET_HARD_XF_REGS"))
3991 (symbol_ref "false")
3992 ]
3993 (const_string "*")))])
3994
3995 (define_split
3996 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3997 (match_operand:XF 1 "general_gr_operand"))]
3998 "reload_completed"
3999 [(const_int 0)]
4000 "ix86_split_long_move (operands); DONE;")
4001
4002 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
4003 (define_insn "*movdf_internal"
4004 [(set (match_operand:DF 0 "nonimmediate_operand"
4005 "=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")
4006 (match_operand:DF 1 "general_operand"
4007 "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"))]
4008 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4009 && (lra_in_progress || reload_completed
4010 || !CONST_DOUBLE_P (operands[1])
4011 || ((optimize_function_for_size_p (cfun)
4012 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4013 && IS_STACK_MODE (DFmode)
4014 && standard_80387_constant_p (operands[1]) > 0
4015 && !memory_operand (operands[0], DFmode))
4016 || (TARGET_SSE2 && TARGET_SSE_MATH
4017 && standard_sse_constant_p (operands[1], DFmode) == 1
4018 && !memory_operand (operands[0], DFmode))
4019 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
4020 && memory_operand (operands[0], DFmode))
4021 || !TARGET_HARD_DF_REGS)"
4022 {
4023 switch (get_attr_type (insn))
4024 {
4025 case TYPE_FMOV:
4026 if (which_alternative == 2)
4027 return standard_80387_constant_opcode (operands[1]);
4028 return output_387_reg_move (insn, operands);
4029
4030 case TYPE_MULTI:
4031 return "#";
4032
4033 case TYPE_IMOV:
4034 if (get_attr_mode (insn) == MODE_SI)
4035 return "mov{l}\t{%1, %k0|%k0, %1}";
4036 else if (which_alternative == 11)
4037 return "movabs{q}\t{%1, %0|%0, %1}";
4038 else
4039 return "mov{q}\t{%1, %0|%0, %1}";
4040
4041 case TYPE_SSELOG1:
4042 return standard_sse_constant_opcode (insn, operands);
4043
4044 case TYPE_SSEMOV:
4045 return ix86_output_ssemov (insn, operands);
4046
4047 default:
4048 gcc_unreachable ();
4049 }
4050 }
4051 [(set (attr "isa")
4052 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4053 (const_string "nox64")
4054 (eq_attr "alternative" "8,9,10,11,24,25")
4055 (const_string "x64")
4056 (eq_attr "alternative" "12,13,14,15")
4057 (const_string "sse2")
4058 (eq_attr "alternative" "20,21")
4059 (const_string "x64_sse2")
4060 ]
4061 (const_string "*")))
4062 (set (attr "type")
4063 (cond [(eq_attr "alternative" "0,1,2")
4064 (const_string "fmov")
4065 (eq_attr "alternative" "3,4,5,6,7,22,23")
4066 (const_string "multi")
4067 (eq_attr "alternative" "8,9,10,11,24,25")
4068 (const_string "imov")
4069 (eq_attr "alternative" "12,16")
4070 (const_string "sselog1")
4071 ]
4072 (const_string "ssemov")))
4073 (set (attr "modrm")
4074 (if_then_else (eq_attr "alternative" "11")
4075 (const_string "0")
4076 (const_string "*")))
4077 (set (attr "length_immediate")
4078 (if_then_else (eq_attr "alternative" "11")
4079 (const_string "8")
4080 (const_string "*")))
4081 (set (attr "prefix")
4082 (if_then_else (eq_attr "type" "sselog1,ssemov")
4083 (const_string "maybe_vex")
4084 (const_string "orig")))
4085 (set (attr "prefix_data16")
4086 (if_then_else
4087 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4088 (eq_attr "mode" "V1DF"))
4089 (const_string "1")
4090 (const_string "*")))
4091 (set (attr "mode")
4092 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4093 (const_string "SI")
4094 (eq_attr "alternative" "8,9,11,20,21,24,25")
4095 (const_string "DI")
4096
4097 /* xorps is one byte shorter for non-AVX targets. */
4098 (eq_attr "alternative" "12,16")
4099 (cond [(match_test "TARGET_AVX")
4100 (const_string "V2DF")
4101 (ior (not (match_test "TARGET_SSE2"))
4102 (match_test "optimize_function_for_size_p (cfun)"))
4103 (const_string "V4SF")
4104 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4105 (const_string "TI")
4106 ]
4107 (const_string "V2DF"))
4108
4109 /* For architectures resolving dependencies on
4110 whole SSE registers use movapd to break dependency
4111 chains, otherwise use short move to avoid extra work. */
4112
4113 /* movaps is one byte shorter for non-AVX targets. */
4114 (eq_attr "alternative" "13,17")
4115 (cond [(match_test "TARGET_AVX512VL")
4116 (const_string "V2DF")
4117 (match_test "TARGET_AVX512F")
4118 (const_string "DF")
4119 (match_test "TARGET_AVX")
4120 (const_string "V2DF")
4121 (ior (not (match_test "TARGET_SSE2"))
4122 (match_test "optimize_function_for_size_p (cfun)"))
4123 (const_string "V4SF")
4124 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4125 (const_string "V4SF")
4126 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4127 (const_string "V2DF")
4128 ]
4129 (const_string "DF"))
4130
4131 /* For architectures resolving dependencies on register
4132 parts we may avoid extra work to zero out upper part
4133 of register. */
4134 (eq_attr "alternative" "14,18")
4135 (cond [(not (match_test "TARGET_SSE2"))
4136 (const_string "V2SF")
4137 (match_test "TARGET_AVX")
4138 (const_string "DF")
4139 (match_test "TARGET_SSE_SPLIT_REGS")
4140 (const_string "V1DF")
4141 ]
4142 (const_string "DF"))
4143
4144 (and (eq_attr "alternative" "15,19")
4145 (not (match_test "TARGET_SSE2")))
4146 (const_string "V2SF")
4147 ]
4148 (const_string "DF")))
4149 (set (attr "preferred_for_size")
4150 (cond [(eq_attr "alternative" "3,4")
4151 (symbol_ref "false")]
4152 (symbol_ref "true")))
4153 (set (attr "preferred_for_speed")
4154 (cond [(eq_attr "alternative" "3,4")
4155 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4156 (eq_attr "alternative" "20")
4157 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4158 (eq_attr "alternative" "21")
4159 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4160 ]
4161 (symbol_ref "true")))
4162 (set (attr "enabled")
4163 (cond [(eq_attr "alternative" "22,23,24,25")
4164 (if_then_else
4165 (match_test "TARGET_HARD_DF_REGS")
4166 (symbol_ref "false")
4167 (const_string "*"))
4168 (not (match_test "TARGET_HARD_DF_REGS"))
4169 (symbol_ref "false")
4170 ]
4171 (const_string "*")))])
4172
4173 (define_split
4174 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4175 (match_operand:DF 1 "general_gr_operand"))]
4176 "!TARGET_64BIT && reload_completed"
4177 [(const_int 0)]
4178 "ix86_split_long_move (operands); DONE;")
4179
4180 (define_insn "*movsf_internal"
4181 [(set (match_operand:SF 0 "nonimmediate_operand"
4182 "=Yf*f,m ,Yf*f,?r ,?m,Yv,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4183 (match_operand:SF 1 "general_operand"
4184 "Yf*fm,Yf*f,G ,rmF,rF,C ,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4185 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4186 && (lra_in_progress || reload_completed
4187 || !CONST_DOUBLE_P (operands[1])
4188 || ((optimize_function_for_size_p (cfun)
4189 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4190 && IS_STACK_MODE (SFmode)
4191 && standard_80387_constant_p (operands[1]) > 0)
4192 || (TARGET_SSE && TARGET_SSE_MATH
4193 && standard_sse_constant_p (operands[1], SFmode) == 1)
4194 || memory_operand (operands[0], SFmode)
4195 || !TARGET_HARD_SF_REGS)"
4196 {
4197 switch (get_attr_type (insn))
4198 {
4199 case TYPE_FMOV:
4200 if (which_alternative == 2)
4201 return standard_80387_constant_opcode (operands[1]);
4202 return output_387_reg_move (insn, operands);
4203
4204 case TYPE_IMOV:
4205 return "mov{l}\t{%1, %0|%0, %1}";
4206
4207 case TYPE_SSELOG1:
4208 return standard_sse_constant_opcode (insn, operands);
4209
4210 case TYPE_SSEMOV:
4211 return ix86_output_ssemov (insn, operands);
4212
4213 case TYPE_MMXMOV:
4214 switch (get_attr_mode (insn))
4215 {
4216 case MODE_DI:
4217 return "movq\t{%1, %0|%0, %1}";
4218 case MODE_SI:
4219 return "movd\t{%1, %0|%0, %1}";
4220
4221 default:
4222 gcc_unreachable ();
4223 }
4224
4225 default:
4226 gcc_unreachable ();
4227 }
4228 }
4229 [(set (attr "isa")
4230 (cond [(eq_attr "alternative" "9,10")
4231 (const_string "sse2")
4232 ]
4233 (const_string "*")))
4234 (set (attr "type")
4235 (cond [(eq_attr "alternative" "0,1,2")
4236 (const_string "fmov")
4237 (eq_attr "alternative" "3,4,16,17")
4238 (const_string "imov")
4239 (eq_attr "alternative" "5")
4240 (const_string "sselog1")
4241 (eq_attr "alternative" "11,12,13,14,15")
4242 (const_string "mmxmov")
4243 ]
4244 (const_string "ssemov")))
4245 (set (attr "prefix")
4246 (if_then_else (eq_attr "type" "sselog1,ssemov")
4247 (const_string "maybe_vex")
4248 (const_string "orig")))
4249 (set (attr "prefix_data16")
4250 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4251 (const_string "1")
4252 (const_string "*")))
4253 (set (attr "mode")
4254 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4255 (const_string "SI")
4256 (eq_attr "alternative" "11")
4257 (const_string "DI")
4258 (eq_attr "alternative" "5")
4259 (cond [(and (match_test "TARGET_AVX512F && TARGET_EVEX512")
4260 (not (match_test "TARGET_PREFER_AVX256")))
4261 (const_string "V16SF")
4262 (match_test "TARGET_AVX")
4263 (const_string "V4SF")
4264 (ior (not (match_test "TARGET_SSE2"))
4265 (match_test "optimize_function_for_size_p (cfun)"))
4266 (const_string "V4SF")
4267 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4268 (const_string "TI")
4269 ]
4270 (const_string "V4SF"))
4271
4272 /* For architectures resolving dependencies on
4273 whole SSE registers use APS move to break dependency
4274 chains, otherwise use short move to avoid extra work.
4275
4276 Do the same for architectures resolving dependencies on
4277 the parts. While in DF mode it is better to always handle
4278 just register parts, the SF mode is different due to lack
4279 of instructions to load just part of the register. It is
4280 better to maintain the whole registers in single format
4281 to avoid problems on using packed logical operations. */
4282 (eq_attr "alternative" "6")
4283 (cond [(match_test "TARGET_AVX512VL")
4284 (const_string "V4SF")
4285 (match_test "TARGET_AVX512F")
4286 (const_string "SF")
4287 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4288 (match_test "TARGET_SSE_SPLIT_REGS"))
4289 (const_string "V4SF")
4290 ]
4291 (const_string "SF"))
4292 ]
4293 (const_string "SF")))
4294 (set (attr "preferred_for_speed")
4295 (cond [(eq_attr "alternative" "9,14")
4296 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4297 (eq_attr "alternative" "10,15")
4298 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4299 ]
4300 (symbol_ref "true")))
4301 (set (attr "enabled")
4302 (cond [(eq_attr "alternative" "16,17")
4303 (if_then_else
4304 (match_test "TARGET_HARD_SF_REGS")
4305 (symbol_ref "false")
4306 (const_string "*"))
4307 (not (match_test "TARGET_HARD_SF_REGS"))
4308 (symbol_ref "false")
4309 ]
4310 (const_string "*")))])
4311
4312 (define_mode_attr hfbfconstf
4313 [(HF "F") (BF "")])
4314
4315 (define_insn "*mov<mode>_internal"
4316 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4317 "=?r,?r,?r,?m ,Yv,v,?r,jm,m,?v,v")
4318 (match_operand:HFBF 1 "general_operand"
4319 "r ,F ,m ,r<hfbfconstf>,C ,v, v,v ,v,r ,m"))]
4320 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4321 && (lra_in_progress
4322 || reload_completed
4323 || !CONST_DOUBLE_P (operands[1])
4324 || (TARGET_SSE2
4325 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4326 || memory_operand (operands[0], <MODE>mode))"
4327 {
4328 switch (get_attr_type (insn))
4329 {
4330 case TYPE_IMOVX:
4331 /* movzwl is faster than movw on p2 due to partial word stalls,
4332 though not as fast as an aligned movl. */
4333 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4334
4335 case TYPE_SSEMOV:
4336 return ix86_output_ssemov (insn, operands);
4337
4338 case TYPE_SSELOG1:
4339 if (satisfies_constraint_C (operands[1]))
4340 return standard_sse_constant_opcode (insn, operands);
4341
4342 if (SSE_REG_P (operands[0]))
4343 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4344 else
4345 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4346
4347 default:
4348 if (get_attr_mode (insn) == MODE_SI)
4349 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4350 else
4351 return "mov{w}\t{%1, %0|%0, %1}";
4352 }
4353 }
4354 [(set (attr "isa")
4355 (cond [(eq_attr "alternative" "4,5,6,9,10")
4356 (const_string "sse2")
4357 (eq_attr "alternative" "7")
4358 (const_string "sse4_noavx")
4359 (eq_attr "alternative" "8")
4360 (const_string "avx")
4361 ]
4362 (const_string "*")))
4363 (set (attr "addr")
4364 (if_then_else (eq_attr "alternative" "7")
4365 (const_string "gpr16")
4366 (const_string "*")))
4367 (set (attr "type")
4368 (cond [(eq_attr "alternative" "4")
4369 (const_string "sselog1")
4370 (eq_attr "alternative" "5,6,9")
4371 (const_string "ssemov")
4372 (eq_attr "alternative" "7,8,10")
4373 (if_then_else
4374 (match_test ("TARGET_AVX512FP16"))
4375 (const_string "ssemov")
4376 (const_string "sselog1"))
4377 (match_test "optimize_function_for_size_p (cfun)")
4378 (const_string "imov")
4379 (and (eq_attr "alternative" "0")
4380 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4381 (not (match_test "TARGET_HIMODE_MATH"))))
4382 (const_string "imov")
4383 (and (eq_attr "alternative" "1,2")
4384 (match_operand:HI 1 "aligned_operand"))
4385 (const_string "imov")
4386 (and (match_test "TARGET_MOVX")
4387 (eq_attr "alternative" "0,2"))
4388 (const_string "imovx")
4389 ]
4390 (const_string "imov")))
4391 (set (attr "prefix")
4392 (cond [(eq_attr "alternative" "4,5,6,7,8,9,10")
4393 (const_string "maybe_vex")
4394 ]
4395 (const_string "orig")))
4396 (set (attr "mode")
4397 (cond [(eq_attr "alternative" "4")
4398 (const_string "V4SF")
4399 (eq_attr "alternative" "6,9")
4400 (if_then_else
4401 (match_test "TARGET_AVX512FP16")
4402 (const_string "HI")
4403 (const_string "SI"))
4404 (eq_attr "alternative" "7,8,10")
4405 (if_then_else
4406 (match_test "TARGET_AVX512FP16")
4407 (const_string "HI")
4408 (const_string "TI"))
4409 (eq_attr "alternative" "5")
4410 (cond [(match_test "TARGET_AVX512VL")
4411 (const_string "V4SF")
4412 (match_test "TARGET_AVX512FP16")
4413 (const_string "HF")
4414 (match_test "TARGET_AVX512F")
4415 (const_string "SF")
4416 (match_test "TARGET_AVX")
4417 (const_string "V4SF")
4418 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4419 (match_test "TARGET_SSE_SPLIT_REGS"))
4420 (const_string "V4SF")
4421 ]
4422 (const_string "SF"))
4423 (eq_attr "type" "imovx")
4424 (const_string "SI")
4425 (and (eq_attr "alternative" "1,2")
4426 (match_operand:HI 1 "aligned_operand"))
4427 (const_string "SI")
4428 (and (eq_attr "alternative" "0")
4429 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4430 (not (match_test "TARGET_HIMODE_MATH"))))
4431 (const_string "SI")
4432 ]
4433 (const_string "HI")))
4434 (set (attr "enabled")
4435 (cond [(and (match_test "<MODE>mode == BFmode")
4436 (eq_attr "alternative" "1"))
4437 (symbol_ref "false")
4438 ]
4439 (const_string "*")))])
4440
4441 (define_split
4442 [(set (match_operand 0 "any_fp_register_operand")
4443 (match_operand 1 "memory_operand"))]
4444 "reload_completed
4445 && (GET_MODE (operands[0]) == TFmode
4446 || GET_MODE (operands[0]) == XFmode
4447 || GET_MODE (operands[0]) == DFmode
4448 || GET_MODE (operands[0]) == SFmode)
4449 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4450 [(set (match_dup 0) (match_dup 2))]
4451 "operands[2] = find_constant_src (curr_insn);")
4452
4453 (define_split
4454 [(set (match_operand 0 "any_fp_register_operand")
4455 (float_extend (match_operand 1 "memory_operand")))]
4456 "reload_completed
4457 && (GET_MODE (operands[0]) == TFmode
4458 || GET_MODE (operands[0]) == XFmode
4459 || GET_MODE (operands[0]) == DFmode)
4460 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4461 [(set (match_dup 0) (match_dup 2))]
4462 "operands[2] = find_constant_src (curr_insn);")
4463
4464 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4465 (define_split
4466 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4467 (match_operand:X87MODEF 1 "immediate_operand"))]
4468 "reload_completed
4469 && (standard_80387_constant_p (operands[1]) == 8
4470 || standard_80387_constant_p (operands[1]) == 9)"
4471 [(set (match_dup 0)(match_dup 1))
4472 (set (match_dup 0)
4473 (neg:X87MODEF (match_dup 0)))]
4474 {
4475 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4476 operands[1] = CONST0_RTX (<MODE>mode);
4477 else
4478 operands[1] = CONST1_RTX (<MODE>mode);
4479 })
4480
4481 (define_insn "*swapxf"
4482 [(set (match_operand:XF 0 "register_operand" "+f")
4483 (match_operand:XF 1 "register_operand" "+f"))
4484 (set (match_dup 1)
4485 (match_dup 0))]
4486 "TARGET_80387"
4487 {
4488 if (STACK_TOP_P (operands[0]))
4489 return "fxch\t%1";
4490 else
4491 return "fxch\t%0";
4492 }
4493 [(set_attr "type" "fxch")
4494 (set_attr "mode" "XF")])
4495 \f
4496
4497 ;; Zero extension instructions
4498
4499 (define_insn_and_split "zero_extendditi2"
4500 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4501 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4502 "TARGET_64BIT"
4503 "#"
4504 "&& reload_completed"
4505 [(set (match_dup 3) (match_dup 1))
4506 (set (match_dup 4) (const_int 0))]
4507 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4508
4509 (define_expand "zero_extendsidi2"
4510 [(set (match_operand:DI 0 "nonimmediate_operand")
4511 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4512
4513 (define_insn "*zero_extendsidi2"
4514 [(set (match_operand:DI 0 "nonimmediate_operand"
4515 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4516 (zero_extend:DI
4517 (match_operand:SI 1 "x86_64_zext_operand"
4518 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4519 ""
4520 {
4521 switch (get_attr_type (insn))
4522 {
4523 case TYPE_IMOVX:
4524 if (ix86_use_lea_for_mov (insn, operands))
4525 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4526 else
4527 return "mov{l}\t{%1, %k0|%k0, %1}";
4528
4529 case TYPE_MULTI:
4530 return "#";
4531
4532 case TYPE_MMXMOV:
4533 return "movd\t{%1, %0|%0, %1}";
4534
4535 case TYPE_SSEMOV:
4536 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4537 {
4538 if (EXT_REX_SSE_REG_P (operands[0])
4539 || EXT_REX_SSE_REG_P (operands[1]))
4540 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4541 else
4542 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4543 }
4544
4545 if (GENERAL_REG_P (operands[0]))
4546 return "%vmovd\t{%1, %k0|%k0, %1}";
4547
4548 return "%vmovd\t{%1, %0|%0, %1}";
4549
4550 case TYPE_MSKMOV:
4551 return "kmovd\t{%1, %k0|%k0, %1}";
4552
4553 default:
4554 gcc_unreachable ();
4555 }
4556 }
4557 [(set (attr "isa")
4558 (cond [(eq_attr "alternative" "0,1,2")
4559 (const_string "nox64")
4560 (eq_attr "alternative" "3")
4561 (const_string "x64")
4562 (eq_attr "alternative" "7,8,9")
4563 (const_string "sse2")
4564 (eq_attr "alternative" "10")
4565 (const_string "sse4")
4566 (eq_attr "alternative" "11")
4567 (const_string "avx512f")
4568 (eq_attr "alternative" "12")
4569 (const_string "x64_avx512bw")
4570 (eq_attr "alternative" "13")
4571 (const_string "avx512bw_512")
4572 ]
4573 (const_string "*")))
4574 (set (attr "mmx_isa")
4575 (if_then_else (eq_attr "alternative" "5,6")
4576 (const_string "native")
4577 (const_string "*")))
4578 (set (attr "type")
4579 (cond [(eq_attr "alternative" "0,1,2,4")
4580 (const_string "multi")
4581 (eq_attr "alternative" "5,6")
4582 (const_string "mmxmov")
4583 (eq_attr "alternative" "7")
4584 (if_then_else (match_test "TARGET_64BIT")
4585 (const_string "ssemov")
4586 (const_string "multi"))
4587 (eq_attr "alternative" "8,9,10,11")
4588 (const_string "ssemov")
4589 (eq_attr "alternative" "12,13")
4590 (const_string "mskmov")
4591 ]
4592 (const_string "imovx")))
4593 (set (attr "prefix_extra")
4594 (if_then_else (eq_attr "alternative" "10,11")
4595 (const_string "1")
4596 (const_string "*")))
4597 (set (attr "prefix")
4598 (if_then_else (eq_attr "type" "ssemov")
4599 (const_string "maybe_vex")
4600 (const_string "orig")))
4601 (set (attr "prefix_0f")
4602 (if_then_else (eq_attr "type" "imovx")
4603 (const_string "0")
4604 (const_string "*")))
4605 (set (attr "mode")
4606 (cond [(eq_attr "alternative" "5,6")
4607 (const_string "DI")
4608 (and (eq_attr "alternative" "7")
4609 (match_test "TARGET_64BIT"))
4610 (const_string "TI")
4611 (eq_attr "alternative" "8,10,11")
4612 (const_string "TI")
4613 ]
4614 (const_string "SI")))
4615 (set (attr "preferred_for_speed")
4616 (cond [(eq_attr "alternative" "7")
4617 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4618 (eq_attr "alternative" "5,8")
4619 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4620 ]
4621 (symbol_ref "true")))])
4622
4623 (define_split
4624 [(set (match_operand:DI 0 "memory_operand")
4625 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4626 "reload_completed"
4627 [(set (match_dup 4) (const_int 0))]
4628 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4629
4630 (define_split
4631 [(set (match_operand:DI 0 "general_reg_operand")
4632 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4633 "!TARGET_64BIT && reload_completed
4634 && REGNO (operands[0]) == REGNO (operands[1])"
4635 [(set (match_dup 4) (const_int 0))]
4636 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4637
4638 (define_split
4639 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4640 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4641 "!TARGET_64BIT && reload_completed
4642 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4643 [(set (match_dup 3) (match_dup 1))
4644 (set (match_dup 4) (const_int 0))]
4645 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4646
4647 (define_mode_attr kmov_isa
4648 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw_512")])
4649
4650 (define_insn "zero_extend<mode>di2"
4651 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4652 (zero_extend:DI
4653 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4654 "TARGET_64BIT"
4655 "@
4656 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4657 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4658 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4659 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4660 (set_attr "type" "imovx,mskmov,mskmov")
4661 (set_attr "mode" "SI,<MODE>,<MODE>")])
4662
4663 (define_expand "zero_extend<mode>si2"
4664 [(set (match_operand:SI 0 "register_operand")
4665 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4666 ""
4667 {
4668 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4669 {
4670 operands[1] = force_reg (<MODE>mode, operands[1]);
4671 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4672 DONE;
4673 }
4674 })
4675
4676 (define_insn_and_split "zero_extend<mode>si2_and"
4677 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4678 (zero_extend:SI
4679 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4680 (clobber (reg:CC FLAGS_REG))]
4681 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4682 "#"
4683 "&& reload_completed"
4684 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4685 (clobber (reg:CC FLAGS_REG))])]
4686 {
4687 if (!REG_P (operands[1])
4688 || REGNO (operands[0]) != REGNO (operands[1]))
4689 {
4690 ix86_expand_clear (operands[0]);
4691
4692 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4693 emit_insn (gen_rtx_SET
4694 (gen_rtx_STRICT_LOW_PART
4695 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4696 operands[1]));
4697 DONE;
4698 }
4699
4700 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4701 }
4702 [(set_attr "type" "alu1")
4703 (set_attr "mode" "SI")])
4704
4705 (define_insn "*zero_extend<mode>si2"
4706 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4707 (zero_extend:SI
4708 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4709 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4710 "@
4711 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4712 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4713 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4714 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4715 (set_attr "type" "imovx,mskmov,mskmov")
4716 (set_attr "mode" "SI,<MODE>,<MODE>")])
4717
4718 (define_expand "zero_extendqihi2"
4719 [(set (match_operand:HI 0 "register_operand")
4720 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4721 ""
4722 {
4723 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4724 {
4725 operands[1] = force_reg (QImode, operands[1]);
4726 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4727 DONE;
4728 }
4729 })
4730
4731 (define_insn_and_split "zero_extendqihi2_and"
4732 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4733 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4734 (clobber (reg:CC FLAGS_REG))]
4735 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4736 "#"
4737 "&& reload_completed"
4738 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4739 (clobber (reg:CC FLAGS_REG))])]
4740 {
4741 if (!REG_P (operands[1])
4742 || REGNO (operands[0]) != REGNO (operands[1]))
4743 {
4744 ix86_expand_clear (operands[0]);
4745
4746 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4747 emit_insn (gen_rtx_SET
4748 (gen_rtx_STRICT_LOW_PART
4749 (VOIDmode, gen_lowpart (QImode, operands[0])),
4750 operands[1]));
4751 DONE;
4752 }
4753
4754 operands[0] = gen_lowpart (SImode, operands[0]);
4755 }
4756 [(set_attr "type" "alu1")
4757 (set_attr "mode" "SI")])
4758
4759 ; zero extend to SImode to avoid partial register stalls
4760 (define_insn "*zero_extendqihi2"
4761 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4762 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4763 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4764 "@
4765 movz{bl|x}\t{%1, %k0|%k0, %1}
4766 kmovb\t{%1, %k0|%k0, %1}
4767 kmovb\t{%1, %0|%0, %1}"
4768 [(set_attr "isa" "*,avx512dq,avx512dq")
4769 (set_attr "type" "imovx,mskmov,mskmov")
4770 (set_attr "mode" "SI,QI,QI")])
4771
4772 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4773 (define_peephole2
4774 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4775 (const_int 0))
4776 (clobber (reg:CC FLAGS_REG))])
4777 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4778 (match_operand:SWI12 2 "nonimmediate_operand"))]
4779 "REGNO (operands[0]) == REGNO (operands[1])
4780 && (<SWI48:MODE>mode != SImode
4781 || !TARGET_ZERO_EXTEND_WITH_AND
4782 || !optimize_function_for_speed_p (cfun))"
4783 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4784
4785 ;; Likewise, but preserving FLAGS_REG.
4786 (define_peephole2
4787 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4788 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4789 (match_operand:SWI12 2 "nonimmediate_operand"))]
4790 "REGNO (operands[0]) == REGNO (operands[1])
4791 && (<SWI48:MODE>mode != SImode
4792 || !TARGET_ZERO_EXTEND_WITH_AND
4793 || !optimize_function_for_speed_p (cfun))"
4794 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4795 \f
4796 ;; Sign extension instructions
4797
4798 (define_expand "extendsidi2"
4799 [(set (match_operand:DI 0 "register_operand")
4800 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4801 ""
4802 {
4803 if (!TARGET_64BIT)
4804 {
4805 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4806 DONE;
4807 }
4808 })
4809
4810 (define_insn "*extendsidi2_rex64"
4811 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4812 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4813 "TARGET_64BIT"
4814 "@
4815 {cltq|cdqe}
4816 movs{lq|x}\t{%1, %0|%0, %1}"
4817 [(set_attr "type" "imovx")
4818 (set_attr "mode" "DI")
4819 (set_attr "prefix_0f" "0")
4820 (set_attr "modrm" "0,1")])
4821
4822 (define_insn "extendsidi2_1"
4823 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4824 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4825 (clobber (reg:CC FLAGS_REG))
4826 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4827 "!TARGET_64BIT"
4828 "#")
4829
4830 (define_insn "extendditi2"
4831 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4832 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4833 (clobber (reg:CC FLAGS_REG))
4834 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4835 "TARGET_64BIT"
4836 "#")
4837
4838 ;; Split the memory case. If the source register doesn't die, it will stay
4839 ;; this way, if it does die, following peephole2s take care of it.
4840 (define_split
4841 [(set (match_operand:<DWI> 0 "memory_operand")
4842 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4843 (clobber (reg:CC FLAGS_REG))
4844 (clobber (match_operand:DWIH 2 "register_operand"))]
4845 "reload_completed"
4846 [(const_int 0)]
4847 {
4848 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4849
4850 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4851
4852 emit_move_insn (operands[3], operands[1]);
4853
4854 /* Generate a cltd if possible and doing so it profitable. */
4855 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4856 && REGNO (operands[1]) == AX_REG
4857 && REGNO (operands[2]) == DX_REG)
4858 {
4859 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4860 }
4861 else
4862 {
4863 emit_move_insn (operands[2], operands[1]);
4864 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4865 }
4866 emit_move_insn (operands[4], operands[2]);
4867 DONE;
4868 })
4869
4870 ;; Peepholes for the case where the source register does die, after
4871 ;; being split with the above splitter.
4872 (define_peephole2
4873 [(set (match_operand:DWIH 0 "memory_operand")
4874 (match_operand:DWIH 1 "general_reg_operand"))
4875 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4876 (parallel [(set (match_dup 2)
4877 (ashiftrt:DWIH (match_dup 2)
4878 (match_operand 4 "const_int_operand")))
4879 (clobber (reg:CC FLAGS_REG))])
4880 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4881 "REGNO (operands[1]) != REGNO (operands[2])
4882 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4883 && peep2_reg_dead_p (2, operands[1])
4884 && peep2_reg_dead_p (4, operands[2])
4885 && !reg_mentioned_p (operands[2], operands[3])"
4886 [(set (match_dup 0) (match_dup 1))
4887 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4888 (clobber (reg:CC FLAGS_REG))])
4889 (set (match_dup 3) (match_dup 1))])
4890
4891 (define_peephole2
4892 [(set (match_operand:DWIH 0 "memory_operand")
4893 (match_operand:DWIH 1 "general_reg_operand"))
4894 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4895 (ashiftrt:DWIH (match_dup 1)
4896 (match_operand 4 "const_int_operand")))
4897 (clobber (reg:CC FLAGS_REG))])
4898 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4899 "/* cltd is shorter than sarl $31, %eax */
4900 !optimize_function_for_size_p (cfun)
4901 && REGNO (operands[1]) == AX_REG
4902 && REGNO (operands[2]) == DX_REG
4903 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4904 && peep2_reg_dead_p (2, operands[1])
4905 && peep2_reg_dead_p (3, operands[2])
4906 && !reg_mentioned_p (operands[2], operands[3])"
4907 [(set (match_dup 0) (match_dup 1))
4908 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4909 (clobber (reg:CC FLAGS_REG))])
4910 (set (match_dup 3) (match_dup 1))])
4911
4912 ;; Extend to register case. Optimize case where source and destination
4913 ;; registers match and cases where we can use cltd.
4914 (define_split
4915 [(set (match_operand:<DWI> 0 "register_operand")
4916 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4917 (clobber (reg:CC FLAGS_REG))
4918 (clobber (match_scratch:DWIH 2))]
4919 "reload_completed"
4920 [(const_int 0)]
4921 {
4922 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4923
4924 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4925
4926 if (REGNO (operands[3]) != REGNO (operands[1]))
4927 emit_move_insn (operands[3], operands[1]);
4928
4929 rtx src = operands[1];
4930 if (REGNO (operands[3]) == AX_REG)
4931 src = operands[3];
4932
4933 /* Generate a cltd if possible and doing so it profitable. */
4934 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4935 && REGNO (src) == AX_REG
4936 && REGNO (operands[4]) == DX_REG)
4937 {
4938 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4939 DONE;
4940 }
4941
4942 if (REGNO (operands[4]) != REGNO (operands[1]))
4943 emit_move_insn (operands[4], operands[1]);
4944
4945 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4946 DONE;
4947 })
4948
4949 (define_insn "extend<mode>di2"
4950 [(set (match_operand:DI 0 "register_operand" "=r")
4951 (sign_extend:DI
4952 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4953 "TARGET_64BIT"
4954 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4955 [(set_attr "type" "imovx")
4956 (set_attr "mode" "DI")])
4957
4958 (define_insn "extendhisi2"
4959 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4960 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4961 ""
4962 {
4963 switch (get_attr_prefix_0f (insn))
4964 {
4965 case 0:
4966 return "{cwtl|cwde}";
4967 default:
4968 return "movs{wl|x}\t{%1, %0|%0, %1}";
4969 }
4970 }
4971 [(set_attr "type" "imovx")
4972 (set_attr "mode" "SI")
4973 (set (attr "prefix_0f")
4974 ;; movsx is short decodable while cwtl is vector decoded.
4975 (if_then_else (and (eq_attr "cpu" "!k6")
4976 (eq_attr "alternative" "0"))
4977 (const_string "0")
4978 (const_string "1")))
4979 (set (attr "znver1_decode")
4980 (if_then_else (eq_attr "prefix_0f" "0")
4981 (const_string "double")
4982 (const_string "direct")))
4983 (set (attr "modrm")
4984 (if_then_else (eq_attr "prefix_0f" "0")
4985 (const_string "0")
4986 (const_string "1")))])
4987
4988 (define_insn "*extendhisi2_zext"
4989 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4990 (zero_extend:DI
4991 (sign_extend:SI
4992 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4993 "TARGET_64BIT"
4994 {
4995 switch (get_attr_prefix_0f (insn))
4996 {
4997 case 0:
4998 return "{cwtl|cwde}";
4999 default:
5000 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
5001 }
5002 }
5003 [(set_attr "type" "imovx")
5004 (set_attr "mode" "SI")
5005 (set (attr "prefix_0f")
5006 ;; movsx is short decodable while cwtl is vector decoded.
5007 (if_then_else (and (eq_attr "cpu" "!k6")
5008 (eq_attr "alternative" "0"))
5009 (const_string "0")
5010 (const_string "1")))
5011 (set (attr "modrm")
5012 (if_then_else (eq_attr "prefix_0f" "0")
5013 (const_string "0")
5014 (const_string "1")))])
5015
5016 (define_insn "extendqisi2"
5017 [(set (match_operand:SI 0 "register_operand" "=r")
5018 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
5019 ""
5020 "movs{bl|x}\t{%1, %0|%0, %1}"
5021 [(set_attr "type" "imovx")
5022 (set_attr "mode" "SI")])
5023
5024 (define_insn "*extendqisi2_zext"
5025 [(set (match_operand:DI 0 "register_operand" "=r")
5026 (zero_extend:DI
5027 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
5028 "TARGET_64BIT"
5029 "movs{bl|x}\t{%1, %k0|%k0, %1}"
5030 [(set_attr "type" "imovx")
5031 (set_attr "mode" "SI")])
5032
5033 (define_insn "extendqihi2"
5034 [(set (match_operand:HI 0 "register_operand" "=*a,r")
5035 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
5036 ""
5037 {
5038 switch (get_attr_prefix_0f (insn))
5039 {
5040 case 0:
5041 return "{cbtw|cbw}";
5042 default:
5043 return "movs{bw|x}\t{%1, %0|%0, %1}";
5044 }
5045 }
5046 [(set_attr "type" "imovx")
5047 (set_attr "mode" "HI")
5048 (set (attr "prefix_0f")
5049 ;; movsx is short decodable while cwtl is vector decoded.
5050 (if_then_else (and (eq_attr "cpu" "!k6")
5051 (eq_attr "alternative" "0"))
5052 (const_string "0")
5053 (const_string "1")))
5054 (set (attr "modrm")
5055 (if_then_else (eq_attr "prefix_0f" "0")
5056 (const_string "0")
5057 (const_string "1")))])
5058
5059 (define_insn "*extendqi<SWI24:mode>_ext_1"
5060 [(set (match_operand:SWI24 0 "register_operand" "=R")
5061 (sign_extend:SWI24
5062 (subreg:QI
5063 (match_operator:SWI248 2 "extract_operator"
5064 [(match_operand 1 "int248_register_operand" "Q")
5065 (const_int 8)
5066 (const_int 8)]) 0)))]
5067 ""
5068 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5069 [(set_attr "type" "imovx")
5070 (set_attr "mode" "<SWI24:MODE>")])
5071 \f
5072 ;; Conversions between float and double.
5073
5074 ;; These are all no-ops in the model used for the 80387.
5075 ;; So just emit moves.
5076
5077 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5078 (define_split
5079 [(set (match_operand:DF 0 "push_operand")
5080 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5081 "reload_completed"
5082 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5083 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5084
5085 (define_split
5086 [(set (match_operand:XF 0 "push_operand")
5087 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5088 "reload_completed"
5089 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5090 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5091 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5092
5093 (define_expand "extendsfdf2"
5094 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5095 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5096 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5097 {
5098 /* ??? Needed for compress_float_constant since all fp constants
5099 are TARGET_LEGITIMATE_CONSTANT_P. */
5100 if (CONST_DOUBLE_P (operands[1]))
5101 {
5102 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5103 && standard_80387_constant_p (operands[1]) > 0)
5104 {
5105 operands[1] = simplify_const_unary_operation
5106 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5107 emit_move_insn_1 (operands[0], operands[1]);
5108 DONE;
5109 }
5110 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5111 }
5112 })
5113
5114 (define_insn "*extendsfdf2"
5115 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5116 (float_extend:DF
5117 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5118 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5119 {
5120 switch (which_alternative)
5121 {
5122 case 0:
5123 case 1:
5124 return output_387_reg_move (insn, operands);
5125
5126 case 2:
5127 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5128 case 3:
5129 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5130
5131 default:
5132 gcc_unreachable ();
5133 }
5134 }
5135 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5136 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5137 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5138 (set_attr "mode" "SF,XF,DF,DF")
5139 (set (attr "enabled")
5140 (if_then_else
5141 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5142 (if_then_else
5143 (eq_attr "alternative" "0,1")
5144 (symbol_ref "TARGET_MIX_SSE_I387")
5145 (symbol_ref "true"))
5146 (if_then_else
5147 (eq_attr "alternative" "0,1")
5148 (symbol_ref "true")
5149 (symbol_ref "false"))))])
5150
5151 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5152 cvtss2sd:
5153 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5154 cvtps2pd xmm2,xmm1
5155 We do the conversion post reload to avoid producing of 128bit spills
5156 that might lead to ICE on 32bit target. The sequence unlikely combine
5157 anyway. */
5158 (define_split
5159 [(set (match_operand:DF 0 "sse_reg_operand")
5160 (float_extend:DF
5161 (match_operand:SF 1 "nonimmediate_operand")))]
5162 "TARGET_USE_VECTOR_FP_CONVERTS
5163 && optimize_insn_for_speed_p ()
5164 && reload_completed
5165 && (!EXT_REX_SSE_REG_P (operands[0])
5166 || TARGET_AVX512VL || TARGET_EVEX512)"
5167 [(set (match_dup 2)
5168 (float_extend:V2DF
5169 (vec_select:V2SF
5170 (match_dup 3)
5171 (parallel [(const_int 0) (const_int 1)]))))]
5172 {
5173 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5174 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5175 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5176 Try to avoid move when unpacking can be done in source. */
5177 if (REG_P (operands[1]))
5178 {
5179 /* If it is unsafe to overwrite upper half of source, we need
5180 to move to destination and unpack there. */
5181 if (REGNO (operands[0]) != REGNO (operands[1])
5182 || (EXT_REX_SSE_REG_P (operands[1])
5183 && !TARGET_AVX512VL))
5184 {
5185 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5186 emit_move_insn (tmp, operands[1]);
5187 }
5188 else
5189 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5190 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5191 =v, v, then vbroadcastss will be only needed for AVX512F without
5192 AVX512VL. */
5193 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5194 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5195 operands[3]));
5196 else
5197 {
5198 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5199 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5200 }
5201 }
5202 else
5203 emit_insn (gen_vec_setv4sf_0 (operands[3],
5204 CONST0_RTX (V4SFmode), operands[1]));
5205 })
5206
5207 ;; It's more profitable to split and then extend in the same register.
5208 (define_peephole2
5209 [(set (match_operand:DF 0 "sse_reg_operand")
5210 (float_extend:DF
5211 (match_operand:SF 1 "memory_operand")))]
5212 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5213 && optimize_insn_for_speed_p ()"
5214 [(set (match_dup 2) (match_dup 1))
5215 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5216 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5217
5218 ;; Break partial SSE register dependency stall. This splitter should split
5219 ;; late in the pass sequence (after register rename pass), so allocated
5220 ;; registers won't change anymore
5221
5222 (define_split
5223 [(set (match_operand:DF 0 "sse_reg_operand")
5224 (float_extend:DF
5225 (match_operand:SF 1 "nonimmediate_operand")))]
5226 "!TARGET_AVX
5227 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5228 && epilogue_completed
5229 && optimize_function_for_speed_p (cfun)
5230 && (!REG_P (operands[1])
5231 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5232 && (!EXT_REX_SSE_REG_P (operands[0])
5233 || TARGET_AVX512VL)"
5234 [(set (match_dup 0)
5235 (vec_merge:V2DF
5236 (vec_duplicate:V2DF
5237 (float_extend:DF
5238 (match_dup 1)))
5239 (match_dup 0)
5240 (const_int 1)))]
5241 {
5242 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5243 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5244 })
5245
5246 (define_expand "extendhfsf2"
5247 [(set (match_operand:SF 0 "register_operand")
5248 (float_extend:SF
5249 (match_operand:HF 1 "nonimmediate_operand")))]
5250 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5251 {
5252 if (!TARGET_AVX512FP16)
5253 {
5254 rtx res = gen_reg_rtx (V4SFmode);
5255 rtx tmp = gen_reg_rtx (V8HFmode);
5256 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5257
5258 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5259 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5260 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5261 DONE;
5262 }
5263 })
5264
5265 (define_expand "extendhfdf2"
5266 [(set (match_operand:DF 0 "register_operand")
5267 (float_extend:DF
5268 (match_operand:HF 1 "nonimmediate_operand")))]
5269 "TARGET_AVX512FP16")
5270
5271 (define_insn "*extendhf<mode>2"
5272 [(set (match_operand:MODEF 0 "register_operand" "=v")
5273 (float_extend:MODEF
5274 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5275 "TARGET_AVX512FP16"
5276 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5277 [(set_attr "type" "ssecvt")
5278 (set_attr "prefix" "evex")
5279 (set_attr "mode" "<MODE>")])
5280
5281 (define_expand "extendbfsf2"
5282 [(set (match_operand:SF 0 "register_operand")
5283 (unspec:SF
5284 [(match_operand:BF 1 "register_operand")]
5285 UNSPEC_CVTBFSF))]
5286 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5287
5288 ;; Don't use float_extend since psrlld doesn't raise
5289 ;; exceptions and turn a sNaN into a qNaN.
5290 (define_insn "extendbfsf2_1"
5291 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5292 (unspec:SF
5293 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5294 UNSPEC_CVTBFSF))]
5295 "TARGET_SSE2"
5296 "@
5297 pslld\t{$16, %0|%0, 16}
5298 vpslld\t{$16, %1, %0|%0, %1, 16}
5299 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5300 [(set_attr "isa" "noavx,avx,*")
5301 (set_attr "type" "sseishft1")
5302 (set_attr "length_immediate" "1")
5303 (set_attr "prefix_data16" "1,*,*")
5304 (set_attr "prefix" "orig,maybe_evex,evex")
5305 (set_attr "mode" "TI,TI,XI")
5306 (set_attr "memory" "none")
5307 (set (attr "enabled")
5308 (if_then_else (eq_attr "alternative" "2")
5309 (symbol_ref "TARGET_AVX512F && TARGET_EVEX512
5310 && !TARGET_AVX512VL && !TARGET_PREFER_AVX256")
5311 (const_string "*")))])
5312
5313 (define_expand "extend<mode>xf2"
5314 [(set (match_operand:XF 0 "nonimmediate_operand")
5315 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5316 "TARGET_80387"
5317 {
5318 /* ??? Needed for compress_float_constant since all fp constants
5319 are TARGET_LEGITIMATE_CONSTANT_P. */
5320 if (CONST_DOUBLE_P (operands[1]))
5321 {
5322 if (standard_80387_constant_p (operands[1]) > 0)
5323 {
5324 operands[1] = simplify_const_unary_operation
5325 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5326 emit_move_insn_1 (operands[0], operands[1]);
5327 DONE;
5328 }
5329 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5330 }
5331 })
5332
5333 (define_insn "*extend<mode>xf2_i387"
5334 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5335 (float_extend:XF
5336 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5337 "TARGET_80387"
5338 "* return output_387_reg_move (insn, operands);"
5339 [(set_attr "type" "fmov")
5340 (set_attr "mode" "<MODE>,XF")])
5341
5342 ;; %%% This seems like bad news.
5343 ;; This cannot output into an f-reg because there is no way to be sure
5344 ;; of truncating in that case. Otherwise this is just like a simple move
5345 ;; insn. So we pretend we can output to a reg in order to get better
5346 ;; register preferencing, but we really use a stack slot.
5347
5348 ;; Conversion from DFmode to SFmode.
5349
5350 (define_insn "truncdfsf2"
5351 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5352 (float_truncate:SF
5353 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5354 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5355 {
5356 switch (which_alternative)
5357 {
5358 case 0:
5359 case 1:
5360 return output_387_reg_move (insn, operands);
5361
5362 case 2:
5363 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5364 case 3:
5365 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5366
5367 default:
5368 gcc_unreachable ();
5369 }
5370 }
5371 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5372 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5373 (set_attr "mode" "SF")
5374 (set (attr "enabled")
5375 (if_then_else
5376 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5377 (cond [(eq_attr "alternative" "0")
5378 (symbol_ref "TARGET_MIX_SSE_I387")
5379 (eq_attr "alternative" "1")
5380 (symbol_ref "TARGET_MIX_SSE_I387
5381 && flag_unsafe_math_optimizations")
5382 ]
5383 (symbol_ref "true"))
5384 (cond [(eq_attr "alternative" "0")
5385 (symbol_ref "true")
5386 (eq_attr "alternative" "1")
5387 (symbol_ref "flag_unsafe_math_optimizations")
5388 ]
5389 (symbol_ref "false"))))])
5390
5391 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5392 cvtsd2ss:
5393 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5394 cvtpd2ps xmm2,xmm1
5395 We do the conversion post reload to avoid producing of 128bit spills
5396 that might lead to ICE on 32bit target. The sequence unlikely combine
5397 anyway. */
5398 (define_split
5399 [(set (match_operand:SF 0 "sse_reg_operand")
5400 (float_truncate:SF
5401 (match_operand:DF 1 "nonimmediate_operand")))]
5402 "TARGET_USE_VECTOR_FP_CONVERTS
5403 && optimize_insn_for_speed_p ()
5404 && reload_completed
5405 && (!EXT_REX_SSE_REG_P (operands[0])
5406 || TARGET_AVX512VL)"
5407 [(set (match_dup 2)
5408 (vec_concat:V4SF
5409 (float_truncate:V2SF
5410 (match_dup 4))
5411 (match_dup 3)))]
5412 {
5413 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5414 operands[3] = CONST0_RTX (V2SFmode);
5415 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5416 /* Use movsd for loading from memory, unpcklpd for registers.
5417 Try to avoid move when unpacking can be done in source, or SSE3
5418 movddup is available. */
5419 if (REG_P (operands[1]))
5420 {
5421 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5422 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5423 {
5424 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5425 emit_move_insn (tmp, operands[1]);
5426 operands[1] = tmp;
5427 }
5428 else if (!TARGET_SSE3)
5429 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5430 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5431 }
5432 else
5433 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5434 CONST0_RTX (DFmode)));
5435 })
5436
5437 ;; It's more profitable to split and then truncate in the same register.
5438 (define_peephole2
5439 [(set (match_operand:SF 0 "sse_reg_operand")
5440 (float_truncate:SF
5441 (match_operand:DF 1 "memory_operand")))]
5442 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5443 && optimize_insn_for_speed_p ()"
5444 [(set (match_dup 2) (match_dup 1))
5445 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5446 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5447
5448 ;; Break partial SSE register dependency stall. This splitter should split
5449 ;; late in the pass sequence (after register rename pass), so allocated
5450 ;; registers won't change anymore
5451
5452 (define_split
5453 [(set (match_operand:SF 0 "sse_reg_operand")
5454 (float_truncate:SF
5455 (match_operand:DF 1 "nonimmediate_operand")))]
5456 "!TARGET_AVX
5457 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5458 && epilogue_completed
5459 && optimize_function_for_speed_p (cfun)
5460 && (!REG_P (operands[1])
5461 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5462 && (!EXT_REX_SSE_REG_P (operands[0])
5463 || TARGET_AVX512VL)"
5464 [(set (match_dup 0)
5465 (vec_merge:V4SF
5466 (vec_duplicate:V4SF
5467 (float_truncate:SF
5468 (match_dup 1)))
5469 (match_dup 0)
5470 (const_int 1)))]
5471 {
5472 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5473 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5474 })
5475
5476 ;; Conversion from XFmode to {SF,DF}mode
5477
5478 (define_insn "truncxf<mode>2"
5479 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5480 (float_truncate:MODEF
5481 (match_operand:XF 1 "register_operand" "f,f")))]
5482 "TARGET_80387"
5483 "* return output_387_reg_move (insn, operands);"
5484 [(set_attr "type" "fmov")
5485 (set_attr "mode" "<MODE>")
5486 (set (attr "enabled")
5487 (cond [(eq_attr "alternative" "1")
5488 (symbol_ref "flag_unsafe_math_optimizations")
5489 ]
5490 (symbol_ref "true")))])
5491
5492 ;; Conversion from {SF,DF}mode to HFmode.
5493
5494 (define_expand "truncsfhf2"
5495 [(set (match_operand:HF 0 "register_operand")
5496 (float_truncate:HF
5497 (match_operand:SF 1 "nonimmediate_operand")))]
5498 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5499 {
5500 if (!TARGET_AVX512FP16)
5501 {
5502 rtx res = gen_reg_rtx (V8HFmode);
5503 rtx tmp = gen_reg_rtx (V4SFmode);
5504 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5505
5506 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5507 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5508 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5509 DONE;
5510 }
5511 })
5512
5513 (define_expand "truncdfhf2"
5514 [(set (match_operand:HF 0 "register_operand")
5515 (float_truncate:HF
5516 (match_operand:DF 1 "nonimmediate_operand")))]
5517 "TARGET_AVX512FP16")
5518
5519 (define_insn "*trunc<mode>hf2"
5520 [(set (match_operand:HF 0 "register_operand" "=v")
5521 (float_truncate:HF
5522 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5523 "TARGET_AVX512FP16"
5524 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5525 [(set_attr "type" "ssecvt")
5526 (set_attr "prefix" "evex")
5527 (set_attr "mode" "HF")])
5528
5529 (define_insn "truncsfbf2"
5530 [(set (match_operand:BF 0 "register_operand" "=x, v")
5531 (float_truncate:BF
5532 (match_operand:SF 1 "register_operand" "x,v")))]
5533 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5534 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5535 "@
5536 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5537 vcvtneps2bf16\t{%1, %0|%0, %1}"
5538 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5539 (set_attr "prefix" "vex,evex")])
5540
5541 ;; Signed conversion to DImode.
5542
5543 (define_expand "fix_truncxfdi2"
5544 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5545 (fix:DI (match_operand:XF 1 "register_operand")))
5546 (clobber (reg:CC FLAGS_REG))])]
5547 "TARGET_80387"
5548 {
5549 if (TARGET_FISTTP)
5550 {
5551 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5552 DONE;
5553 }
5554 })
5555
5556 (define_expand "fix_trunc<mode>di2"
5557 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5558 (fix:DI (match_operand:MODEF 1 "register_operand")))
5559 (clobber (reg:CC FLAGS_REG))])]
5560 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5561 {
5562 if (TARGET_FISTTP
5563 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5564 {
5565 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5566 DONE;
5567 }
5568 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5569 {
5570 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5571 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5572 if (out != operands[0])
5573 emit_move_insn (operands[0], out);
5574 DONE;
5575 }
5576 })
5577
5578 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5579 [(set (match_operand:SWI48 0 "register_operand" "=r")
5580 (any_fix:SWI48
5581 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5582 "TARGET_AVX512FP16"
5583 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5584 [(set_attr "type" "sseicvt")
5585 (set_attr "prefix" "evex")
5586 (set_attr "mode" "<MODE>")])
5587
5588 ;; Signed conversion to SImode.
5589
5590 (define_expand "fix_truncxfsi2"
5591 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5592 (fix:SI (match_operand:XF 1 "register_operand")))
5593 (clobber (reg:CC FLAGS_REG))])]
5594 "TARGET_80387"
5595 {
5596 if (TARGET_FISTTP)
5597 {
5598 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5599 DONE;
5600 }
5601 })
5602
5603 (define_expand "fix_trunc<mode>si2"
5604 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5605 (fix:SI (match_operand:MODEF 1 "register_operand")))
5606 (clobber (reg:CC FLAGS_REG))])]
5607 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5608 {
5609 if (TARGET_FISTTP
5610 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5611 {
5612 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5613 DONE;
5614 }
5615 if (SSE_FLOAT_MODE_P (<MODE>mode))
5616 {
5617 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5618 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5619 if (out != operands[0])
5620 emit_move_insn (operands[0], out);
5621 DONE;
5622 }
5623 })
5624
5625 ;; Signed conversion to HImode.
5626
5627 (define_expand "fix_trunc<mode>hi2"
5628 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5629 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5630 (clobber (reg:CC FLAGS_REG))])]
5631 "TARGET_80387
5632 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5633 {
5634 if (TARGET_FISTTP)
5635 {
5636 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5637 DONE;
5638 }
5639 })
5640
5641 ;; Unsigned conversion to DImode
5642
5643 (define_insn "fixuns_trunc<mode>di2"
5644 [(set (match_operand:DI 0 "register_operand" "=r")
5645 (unsigned_fix:DI
5646 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5647 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5648 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5649 [(set_attr "type" "sseicvt")
5650 (set_attr "prefix" "evex")
5651 (set_attr "mode" "DI")])
5652
5653 ;; Unsigned conversion to SImode.
5654
5655 (define_expand "fixuns_trunc<mode>si2"
5656 [(parallel
5657 [(set (match_operand:SI 0 "register_operand")
5658 (unsigned_fix:SI
5659 (match_operand:MODEF 1 "nonimmediate_operand")))
5660 (use (match_dup 2))
5661 (clobber (scratch:<ssevecmode>))
5662 (clobber (scratch:<ssevecmode>))])]
5663 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5664 {
5665 machine_mode mode = <MODE>mode;
5666 machine_mode vecmode = <ssevecmode>mode;
5667 REAL_VALUE_TYPE TWO31r;
5668 rtx two31;
5669
5670 if (TARGET_AVX512F)
5671 {
5672 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5673 DONE;
5674 }
5675
5676 if (optimize_insn_for_size_p ())
5677 FAIL;
5678
5679 real_ldexp (&TWO31r, &dconst1, 31);
5680 two31 = const_double_from_real_value (TWO31r, mode);
5681 two31 = ix86_build_const_vector (vecmode, true, two31);
5682 operands[2] = force_reg (vecmode, two31);
5683 })
5684
5685 (define_insn "fixuns_trunc<mode>si2_avx512f"
5686 [(set (match_operand:SI 0 "register_operand" "=r")
5687 (unsigned_fix:SI
5688 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5689 "TARGET_AVX512F && TARGET_SSE_MATH"
5690 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5691 [(set_attr "type" "sseicvt")
5692 (set_attr "prefix" "evex")
5693 (set_attr "mode" "SI")])
5694
5695 (define_insn "*fixuns_trunchfsi2zext"
5696 [(set (match_operand:DI 0 "register_operand" "=r")
5697 (zero_extend:DI
5698 (unsigned_fix:SI
5699 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5700 "TARGET_64BIT && TARGET_AVX512FP16"
5701 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5702 [(set_attr "type" "sseicvt")
5703 (set_attr "prefix" "evex")
5704 (set_attr "mode" "SI")])
5705
5706 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5707 [(set (match_operand:DI 0 "register_operand" "=r")
5708 (zero_extend:DI
5709 (unsigned_fix:SI
5710 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5711 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5712 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5713 [(set_attr "type" "sseicvt")
5714 (set_attr "prefix" "evex")
5715 (set_attr "mode" "SI")])
5716
5717 (define_insn_and_split "*fixuns_trunc<mode>_1"
5718 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5719 (unsigned_fix:SI
5720 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5721 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5722 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5723 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5724 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5725 && optimize_function_for_speed_p (cfun)"
5726 "#"
5727 "&& reload_completed"
5728 [(const_int 0)]
5729 {
5730 ix86_split_convert_uns_si_sse (operands);
5731 DONE;
5732 })
5733
5734 ;; Unsigned conversion to HImode.
5735 ;; Without these patterns, we'll try the unsigned SI conversion which
5736 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5737
5738 (define_expand "fixuns_trunchfhi2"
5739 [(set (match_dup 2)
5740 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5741 (set (match_operand:HI 0 "nonimmediate_operand")
5742 (subreg:HI (match_dup 2) 0))]
5743 "TARGET_AVX512FP16"
5744 "operands[2] = gen_reg_rtx (SImode);")
5745
5746 (define_expand "fixuns_trunc<mode>hi2"
5747 [(set (match_dup 2)
5748 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5749 (set (match_operand:HI 0 "nonimmediate_operand")
5750 (subreg:HI (match_dup 2) 0))]
5751 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5752 "operands[2] = gen_reg_rtx (SImode);")
5753
5754 ;; When SSE is available, it is always faster to use it!
5755 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5756 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5757 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5758 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5759 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5760 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5761 [(set_attr "type" "sseicvt")
5762 (set_attr "prefix" "maybe_vex")
5763 (set (attr "prefix_rex")
5764 (if_then_else
5765 (match_test "<SWI48:MODE>mode == DImode")
5766 (const_string "1")
5767 (const_string "*")))
5768 (set_attr "mode" "<MODEF:MODE>")
5769 (set_attr "athlon_decode" "double,vector")
5770 (set_attr "amdfam10_decode" "double,double")
5771 (set_attr "bdver1_decode" "double,double")])
5772
5773 ;; Avoid vector decoded forms of the instruction.
5774 (define_peephole2
5775 [(match_scratch:MODEF 2 "x")
5776 (set (match_operand:SWI48 0 "register_operand")
5777 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5778 "TARGET_AVOID_VECTOR_DECODE
5779 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5780 && optimize_insn_for_speed_p ()"
5781 [(set (match_dup 2) (match_dup 1))
5782 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5783
5784 (define_insn "fix_trunc<mode>_i387_fisttp"
5785 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5786 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5787 (clobber (match_scratch:XF 2 "=&f"))]
5788 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5789 && TARGET_FISTTP
5790 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5791 && (TARGET_64BIT || <MODE>mode != DImode))
5792 && TARGET_SSE_MATH)"
5793 "* return output_fix_trunc (insn, operands, true);"
5794 [(set_attr "type" "fisttp")
5795 (set_attr "mode" "<MODE>")])
5796
5797 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5798 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5799 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5800 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5801 ;; function in i386.cc.
5802 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5803 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5804 (fix:SWI248x (match_operand 1 "register_operand")))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5807 && !TARGET_FISTTP
5808 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5809 && (TARGET_64BIT || <MODE>mode != DImode))
5810 && ix86_pre_reload_split ()"
5811 "#"
5812 "&& 1"
5813 [(const_int 0)]
5814 {
5815 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5816
5817 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5818 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5819
5820 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5821 operands[2], operands[3]));
5822 DONE;
5823 }
5824 [(set_attr "type" "fistp")
5825 (set_attr "i387_cw" "trunc")
5826 (set_attr "mode" "<MODE>")])
5827
5828 (define_insn "fix_truncdi_i387"
5829 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5830 (fix:DI (match_operand 1 "register_operand" "f")))
5831 (use (match_operand:HI 2 "memory_operand" "m"))
5832 (use (match_operand:HI 3 "memory_operand" "m"))
5833 (clobber (match_scratch:XF 4 "=&f"))]
5834 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5835 && !TARGET_FISTTP
5836 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5837 "* return output_fix_trunc (insn, operands, false);"
5838 [(set_attr "type" "fistp")
5839 (set_attr "i387_cw" "trunc")
5840 (set_attr "mode" "DI")])
5841
5842 (define_insn "fix_trunc<mode>_i387"
5843 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5844 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5845 (use (match_operand:HI 2 "memory_operand" "m"))
5846 (use (match_operand:HI 3 "memory_operand" "m"))]
5847 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5848 && !TARGET_FISTTP
5849 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5850 "* return output_fix_trunc (insn, operands, false);"
5851 [(set_attr "type" "fistp")
5852 (set_attr "i387_cw" "trunc")
5853 (set_attr "mode" "<MODE>")])
5854
5855 (define_insn "x86_fnstcw_1"
5856 [(set (match_operand:HI 0 "memory_operand" "=m")
5857 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5858 "TARGET_80387"
5859 "fnstcw\t%0"
5860 [(set (attr "length")
5861 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5862 (set_attr "mode" "HI")
5863 (set_attr "unit" "i387")
5864 (set_attr "bdver1_decode" "vector")])
5865 \f
5866 ;; Conversion between fixed point and floating point.
5867
5868 ;; Even though we only accept memory inputs, the backend _really_
5869 ;; wants to be able to do this between registers. Thankfully, LRA
5870 ;; will fix this up for us during register allocation.
5871
5872 (define_insn "floathi<mode>2"
5873 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5874 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5875 "TARGET_80387
5876 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5877 || TARGET_MIX_SSE_I387)"
5878 "fild%Z1\t%1"
5879 [(set_attr "type" "fmov")
5880 (set_attr "mode" "<MODE>")
5881 (set_attr "znver1_decode" "double")
5882 (set_attr "fp_int_src" "true")])
5883
5884 (define_insn "float<SWI48x:mode>xf2"
5885 [(set (match_operand:XF 0 "register_operand" "=f")
5886 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5887 "TARGET_80387"
5888 "fild%Z1\t%1"
5889 [(set_attr "type" "fmov")
5890 (set_attr "mode" "XF")
5891 (set_attr "znver1_decode" "double")
5892 (set_attr "fp_int_src" "true")])
5893
5894 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5895 [(set (match_operand:MODEF 0 "register_operand")
5896 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5897 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5898 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5899 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5900
5901 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5902 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5903 (float:MODEF
5904 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5905 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5906 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5907 "@
5908 fild%Z1\t%1
5909 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5910 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5911 [(set_attr "type" "fmov,sseicvt,sseicvt")
5912 (set_attr "avx_partial_xmm_update" "false,true,true")
5913 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5914 (set_attr "mode" "<MODEF:MODE>")
5915 (set (attr "prefix_rex")
5916 (if_then_else
5917 (and (eq_attr "prefix" "maybe_vex")
5918 (match_test "<SWI48:MODE>mode == DImode"))
5919 (const_string "1")
5920 (const_string "*")))
5921 (set_attr "unit" "i387,*,*")
5922 (set_attr "athlon_decode" "*,double,direct")
5923 (set_attr "amdfam10_decode" "*,vector,double")
5924 (set_attr "bdver1_decode" "*,double,direct")
5925 (set_attr "znver1_decode" "double,*,*")
5926 (set_attr "fp_int_src" "true")
5927 (set (attr "enabled")
5928 (if_then_else
5929 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5930 (if_then_else
5931 (eq_attr "alternative" "0")
5932 (symbol_ref "TARGET_MIX_SSE_I387
5933 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5934 <SWI48:MODE>mode)")
5935 (symbol_ref "true"))
5936 (if_then_else
5937 (eq_attr "alternative" "0")
5938 (symbol_ref "true")
5939 (symbol_ref "false"))))
5940 (set (attr "preferred_for_speed")
5941 (cond [(eq_attr "alternative" "1")
5942 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5943 (symbol_ref "true")))])
5944
5945 (define_insn "float<floatunssuffix><mode>hf2"
5946 [(set (match_operand:HF 0 "register_operand" "=v")
5947 (any_float:HF
5948 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5949 "TARGET_AVX512FP16"
5950 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5951 [(set_attr "type" "sseicvt")
5952 (set_attr "prefix" "evex")
5953 (set_attr "mode" "HF")])
5954
5955 (define_insn "*floatdi<MODEF:mode>2_i387"
5956 [(set (match_operand:MODEF 0 "register_operand" "=f")
5957 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5958 "!TARGET_64BIT
5959 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5960 "fild%Z1\t%1"
5961 [(set_attr "type" "fmov")
5962 (set_attr "mode" "<MODEF:MODE>")
5963 (set_attr "znver1_decode" "double")
5964 (set_attr "fp_int_src" "true")])
5965
5966 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5967 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5968 ;; alternative in sse2_loadld.
5969 (define_split
5970 [(set (match_operand:MODEF 0 "sse_reg_operand")
5971 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5972 "TARGET_SSE2
5973 && TARGET_USE_VECTOR_CONVERTS
5974 && optimize_function_for_speed_p (cfun)
5975 && reload_completed
5976 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5977 && (!EXT_REX_SSE_REG_P (operands[0])
5978 || TARGET_AVX512VL)"
5979 [(const_int 0)]
5980 {
5981 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5982 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5983
5984 emit_insn (gen_sse2_loadld (operands[4],
5985 CONST0_RTX (V4SImode), operands[1]));
5986
5987 if (<ssevecmode>mode == V4SFmode)
5988 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5989 else
5990 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5991 DONE;
5992 })
5993
5994 ;; Avoid store forwarding (partial memory) stall penalty
5995 ;; by passing DImode value through XMM registers. */
5996
5997 (define_split
5998 [(set (match_operand:X87MODEF 0 "register_operand")
5999 (float:X87MODEF
6000 (match_operand:DI 1 "register_operand")))]
6001 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6002 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6003 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
6004 && can_create_pseudo_p ()"
6005 [(const_int 0)]
6006 {
6007 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
6008 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
6009 DONE;
6010 })
6011
6012 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
6013 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
6014 (float:X87MODEF
6015 (match_operand:DI 1 "register_operand" "r,r")))
6016 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
6017 (clobber (match_scratch:V4SI 3 "=x,x"))
6018 (clobber (match_scratch:V4SI 4 "=X,x"))]
6019 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
6020 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6021 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
6022 "#"
6023 "&& reload_completed"
6024 [(set (match_dup 2) (match_dup 3))
6025 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
6026 {
6027 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
6028 Assemble the 64-bit DImode value in an xmm register. */
6029 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
6030 gen_lowpart (SImode, operands[1])));
6031 if (TARGET_SSE4_1)
6032 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
6033 gen_highpart (SImode, operands[1]),
6034 GEN_INT (2)));
6035 else
6036 {
6037 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
6038 gen_highpart (SImode, operands[1])));
6039 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
6040 operands[4]));
6041 }
6042 operands[3] = gen_lowpart (DImode, operands[3]);
6043 }
6044 [(set_attr "isa" "sse4,*")
6045 (set_attr "type" "multi")
6046 (set_attr "mode" "<X87MODEF:MODE>")
6047 (set_attr "unit" "i387")
6048 (set_attr "fp_int_src" "true")])
6049
6050 ;; Break partial SSE register dependency stall. This splitter should split
6051 ;; late in the pass sequence (after register rename pass), so allocated
6052 ;; registers won't change anymore
6053
6054 (define_split
6055 [(set (match_operand:MODEF 0 "sse_reg_operand")
6056 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6057 "!TARGET_AVX
6058 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6059 && epilogue_completed
6060 && optimize_function_for_speed_p (cfun)
6061 && (!EXT_REX_SSE_REG_P (operands[0])
6062 || TARGET_AVX512VL)"
6063 [(set (match_dup 0)
6064 (vec_merge:<MODEF:ssevecmode>
6065 (vec_duplicate:<MODEF:ssevecmode>
6066 (float:MODEF
6067 (match_dup 1)))
6068 (match_dup 0)
6069 (const_int 1)))]
6070 {
6071 const machine_mode vmode = <MODEF:ssevecmode>mode;
6072
6073 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6074 emit_move_insn (operands[0], CONST0_RTX (vmode));
6075 })
6076
6077 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6078 [(set (match_operand:MODEF 0 "register_operand")
6079 (unsigned_float:MODEF
6080 (match_operand:SWI12 1 "nonimmediate_operand")))]
6081 "!TARGET_64BIT
6082 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6083 {
6084 operands[1] = convert_to_mode (SImode, operands[1], 1);
6085 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6086 DONE;
6087 })
6088
6089 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6090 [(set (match_operand:MODEF 0 "register_operand" "=v")
6091 (unsigned_float:MODEF
6092 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6093 "TARGET_AVX512F && TARGET_SSE_MATH"
6094 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6095 [(set_attr "type" "sseicvt")
6096 (set_attr "avx_partial_xmm_update" "true")
6097 (set_attr "prefix" "evex")
6098 (set_attr "mode" "<MODEF:MODE>")])
6099
6100 ;; Avoid store forwarding (partial memory) stall penalty by extending
6101 ;; SImode value to DImode through XMM register instead of pushing two
6102 ;; SImode values to stack. Also note that fild loads from memory only.
6103
6104 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6105 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6106 (unsigned_float:X87MODEF
6107 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6108 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6109 (clobber (match_scratch:DI 3 "=x"))]
6110 "!TARGET_64BIT
6111 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6112 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6113 "#"
6114 "&& reload_completed"
6115 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6116 (set (match_dup 2) (match_dup 3))
6117 (set (match_dup 0)
6118 (float:X87MODEF (match_dup 2)))]
6119 ""
6120 [(set_attr "type" "multi")
6121 (set_attr "mode" "<MODE>")])
6122
6123 (define_expand "floatunssi<mode>2"
6124 [(set (match_operand:X87MODEF 0 "register_operand")
6125 (unsigned_float:X87MODEF
6126 (match_operand:SI 1 "nonimmediate_operand")))]
6127 "(!TARGET_64BIT
6128 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6129 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6130 || ((!TARGET_64BIT || TARGET_AVX512F)
6131 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6132 {
6133 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6134 {
6135 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6136 (operands[0], operands[1],
6137 assign_386_stack_local (DImode, SLOT_TEMP)));
6138 DONE;
6139 }
6140 if (!TARGET_AVX512F)
6141 {
6142 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6143 DONE;
6144 }
6145 })
6146
6147 (define_expand "floatunsdisf2"
6148 [(set (match_operand:SF 0 "register_operand")
6149 (unsigned_float:SF
6150 (match_operand:DI 1 "nonimmediate_operand")))]
6151 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6152 {
6153 if (!TARGET_AVX512F)
6154 {
6155 x86_emit_floatuns (operands);
6156 DONE;
6157 }
6158 })
6159
6160 (define_expand "floatunsdidf2"
6161 [(set (match_operand:DF 0 "register_operand")
6162 (unsigned_float:DF
6163 (match_operand:DI 1 "nonimmediate_operand")))]
6164 "((TARGET_64BIT && TARGET_AVX512F)
6165 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6166 && TARGET_SSE2 && TARGET_SSE_MATH"
6167 {
6168 if (!TARGET_64BIT)
6169 {
6170 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6171 DONE;
6172 }
6173 if (!TARGET_AVX512F)
6174 {
6175 x86_emit_floatuns (operands);
6176 DONE;
6177 }
6178 })
6179 \f
6180 ;; Load effective address instructions
6181
6182 (define_insn "*lea<mode>"
6183 [(set (match_operand:SWI48 0 "register_operand" "=r")
6184 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6185 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6186 {
6187 if (SImode_address_operand (operands[1], VOIDmode))
6188 {
6189 gcc_assert (TARGET_64BIT);
6190 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6191 }
6192 else
6193 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6194 }
6195 [(set_attr "type" "lea")
6196 (set (attr "mode")
6197 (if_then_else
6198 (match_operand 1 "SImode_address_operand")
6199 (const_string "SI")
6200 (const_string "<MODE>")))])
6201
6202 (define_peephole2
6203 [(set (match_operand:SWI48 0 "register_operand")
6204 (match_operand:SWI48 1 "address_no_seg_operand"))]
6205 "ix86_hardreg_mov_ok (operands[0], operands[1])
6206 && peep2_regno_dead_p (0, FLAGS_REG)
6207 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6208 [(const_int 0)]
6209 {
6210 machine_mode mode = <MODE>mode;
6211
6212 /* Emit all operations in SImode for zero-extended addresses. */
6213 if (SImode_address_operand (operands[1], VOIDmode))
6214 mode = SImode;
6215
6216 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6217
6218 /* Zero-extend return register to DImode for zero-extended addresses. */
6219 if (mode != <MODE>mode)
6220 emit_insn (gen_zero_extendsidi2 (operands[0],
6221 gen_lowpart (mode, operands[0])));
6222
6223 DONE;
6224 })
6225
6226 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6227 ;; peephole2 optimized back into a lea. Split that into the shift during
6228 ;; the following split pass.
6229 (define_split
6230 [(set (match_operand:SWI48 0 "general_reg_operand")
6231 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6232 (clobber (reg:CC FLAGS_REG))]
6233 "reload_completed"
6234 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6235 (clobber (reg:CC FLAGS_REG))])]
6236 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6237 \f
6238 ;; Add instructions
6239
6240 (define_expand "add<mode>3"
6241 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6242 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6243 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6244 ""
6245 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6246
6247 (define_insn_and_split "*add<dwi>3_doubleword"
6248 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6249 (plus:<DWI>
6250 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6251 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6252 (clobber (reg:CC FLAGS_REG))]
6253 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6254 "#"
6255 "&& reload_completed"
6256 [(parallel [(set (reg:CCC FLAGS_REG)
6257 (compare:CCC
6258 (plus:DWIH (match_dup 1) (match_dup 2))
6259 (match_dup 1)))
6260 (set (match_dup 0)
6261 (plus:DWIH (match_dup 1) (match_dup 2)))])
6262 (parallel [(set (match_dup 3)
6263 (plus:DWIH
6264 (plus:DWIH
6265 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6266 (match_dup 4))
6267 (match_dup 5)))
6268 (clobber (reg:CC FLAGS_REG))])]
6269 {
6270 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6271 if (operands[2] == const0_rtx)
6272 {
6273 if (operands[5] != const0_rtx)
6274 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6275 else if (!rtx_equal_p (operands[3], operands[4]))
6276 emit_move_insn (operands[3], operands[4]);
6277 else
6278 emit_note (NOTE_INSN_DELETED);
6279 DONE;
6280 }
6281 })
6282
6283 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6284 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6285 (plus:<DWI>
6286 (zero_extend:<DWI>
6287 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6288 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6289 (clobber (reg:CC FLAGS_REG))]
6290 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6291 "#"
6292 "&& reload_completed"
6293 [(parallel [(set (reg:CCC FLAGS_REG)
6294 (compare:CCC
6295 (plus:DWIH (match_dup 1) (match_dup 2))
6296 (match_dup 1)))
6297 (set (match_dup 0)
6298 (plus:DWIH (match_dup 1) (match_dup 2)))])
6299 (parallel [(set (match_dup 3)
6300 (plus:DWIH
6301 (plus:DWIH
6302 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6303 (match_dup 4))
6304 (const_int 0)))
6305 (clobber (reg:CC FLAGS_REG))])]
6306 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6307
6308 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6309 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6310 (plus:<DWI>
6311 (any_or_plus:<DWI>
6312 (ashift:<DWI>
6313 (zero_extend:<DWI>
6314 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6315 (match_operand:QI 3 "const_int_operand"))
6316 (zero_extend:<DWI>
6317 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6318 (match_operand:<DWI> 1 "register_operand" "0")))
6319 (clobber (reg:CC FLAGS_REG))]
6320 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6321 "#"
6322 "&& reload_completed"
6323 [(parallel [(set (reg:CCC FLAGS_REG)
6324 (compare:CCC
6325 (plus:DWIH (match_dup 1) (match_dup 4))
6326 (match_dup 1)))
6327 (set (match_dup 0)
6328 (plus:DWIH (match_dup 1) (match_dup 4)))])
6329 (parallel [(set (match_dup 5)
6330 (plus:DWIH
6331 (plus:DWIH
6332 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6333 (match_dup 6))
6334 (match_dup 2)))
6335 (clobber (reg:CC FLAGS_REG))])]
6336 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6337
6338 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6339 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6340 (plus:<DWI>
6341 (any_or_plus:<DWI>
6342 (ashift:<DWI>
6343 (zero_extend:<DWI>
6344 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6345 (match_operand:QI 3 "const_int_operand"))
6346 (zero_extend:<DWI>
6347 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6348 (zero_extend:<DWI>
6349 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6350 (clobber (reg:CC FLAGS_REG))]
6351 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6352 "#"
6353 "&& reload_completed"
6354 [(set (match_dup 0) (match_dup 4))
6355 (set (match_dup 5) (match_dup 2))
6356 (parallel [(set (reg:CCC FLAGS_REG)
6357 (compare:CCC
6358 (plus:DWIH (match_dup 0) (match_dup 1))
6359 (match_dup 0)))
6360 (set (match_dup 0)
6361 (plus:DWIH (match_dup 0) (match_dup 1)))])
6362 (parallel [(set (match_dup 5)
6363 (plus:DWIH
6364 (plus:DWIH
6365 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6366 (match_dup 5))
6367 (const_int 0)))
6368 (clobber (reg:CC FLAGS_REG))])]
6369 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6370
6371 (define_insn "*add<mode>_1"
6372 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6373 (plus:SWI48
6374 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6375 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6376 (clobber (reg:CC FLAGS_REG))]
6377 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6378 {
6379 switch (get_attr_type (insn))
6380 {
6381 case TYPE_LEA:
6382 return "#";
6383
6384 case TYPE_INCDEC:
6385 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6386 if (operands[2] == const1_rtx)
6387 return "inc{<imodesuffix>}\t%0";
6388 else
6389 {
6390 gcc_assert (operands[2] == constm1_rtx);
6391 return "dec{<imodesuffix>}\t%0";
6392 }
6393
6394 default:
6395 /* For most processors, ADD is faster than LEA. This alternative
6396 was added to use ADD as much as possible. */
6397 if (which_alternative == 2)
6398 std::swap (operands[1], operands[2]);
6399
6400 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6401 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6402 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6403
6404 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6405 }
6406 }
6407 [(set (attr "type")
6408 (cond [(eq_attr "alternative" "3")
6409 (const_string "lea")
6410 (match_operand:SWI48 2 "incdec_operand")
6411 (const_string "incdec")
6412 ]
6413 (const_string "alu")))
6414 (set (attr "length_immediate")
6415 (if_then_else
6416 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6417 (const_string "1")
6418 (const_string "*")))
6419 (set_attr "mode" "<MODE>")])
6420
6421 ;; It may seem that nonimmediate operand is proper one for operand 1.
6422 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6423 ;; we take care in ix86_binary_operator_ok to not allow two memory
6424 ;; operands so proper swapping will be done in reload. This allow
6425 ;; patterns constructed from addsi_1 to match.
6426
6427 (define_insn "addsi_1_zext"
6428 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6429 (zero_extend:DI
6430 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6431 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6432 (clobber (reg:CC FLAGS_REG))]
6433 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6434 {
6435 switch (get_attr_type (insn))
6436 {
6437 case TYPE_LEA:
6438 return "#";
6439
6440 case TYPE_INCDEC:
6441 if (operands[2] == const1_rtx)
6442 return "inc{l}\t%k0";
6443 else
6444 {
6445 gcc_assert (operands[2] == constm1_rtx);
6446 return "dec{l}\t%k0";
6447 }
6448
6449 default:
6450 /* For most processors, ADD is faster than LEA. This alternative
6451 was added to use ADD as much as possible. */
6452 if (which_alternative == 1)
6453 std::swap (operands[1], operands[2]);
6454
6455 if (x86_maybe_negate_const_int (&operands[2], SImode))
6456 return "sub{l}\t{%2, %k0|%k0, %2}";
6457
6458 return "add{l}\t{%2, %k0|%k0, %2}";
6459 }
6460 }
6461 [(set (attr "type")
6462 (cond [(eq_attr "alternative" "2")
6463 (const_string "lea")
6464 (match_operand:SI 2 "incdec_operand")
6465 (const_string "incdec")
6466 ]
6467 (const_string "alu")))
6468 (set (attr "length_immediate")
6469 (if_then_else
6470 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6471 (const_string "1")
6472 (const_string "*")))
6473 (set_attr "mode" "SI")])
6474
6475 (define_insn "*addhi_1"
6476 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6477 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6478 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6479 (clobber (reg:CC FLAGS_REG))]
6480 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6481 {
6482 switch (get_attr_type (insn))
6483 {
6484 case TYPE_LEA:
6485 return "#";
6486
6487 case TYPE_INCDEC:
6488 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6489 if (operands[2] == const1_rtx)
6490 return "inc{w}\t%0";
6491 else
6492 {
6493 gcc_assert (operands[2] == constm1_rtx);
6494 return "dec{w}\t%0";
6495 }
6496
6497 default:
6498 /* For most processors, ADD is faster than LEA. This alternative
6499 was added to use ADD as much as possible. */
6500 if (which_alternative == 2)
6501 std::swap (operands[1], operands[2]);
6502
6503 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6504 if (x86_maybe_negate_const_int (&operands[2], HImode))
6505 return "sub{w}\t{%2, %0|%0, %2}";
6506
6507 return "add{w}\t{%2, %0|%0, %2}";
6508 }
6509 }
6510 [(set (attr "type")
6511 (cond [(eq_attr "alternative" "3")
6512 (const_string "lea")
6513 (match_operand:HI 2 "incdec_operand")
6514 (const_string "incdec")
6515 ]
6516 (const_string "alu")))
6517 (set (attr "length_immediate")
6518 (if_then_else
6519 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6520 (const_string "1")
6521 (const_string "*")))
6522 (set_attr "mode" "HI,HI,HI,SI")])
6523
6524 (define_insn "*addqi_1"
6525 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6526 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6527 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6528 (clobber (reg:CC FLAGS_REG))]
6529 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6530 {
6531 bool widen = (get_attr_mode (insn) != MODE_QI);
6532
6533 switch (get_attr_type (insn))
6534 {
6535 case TYPE_LEA:
6536 return "#";
6537
6538 case TYPE_INCDEC:
6539 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6540 if (operands[2] == const1_rtx)
6541 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6542 else
6543 {
6544 gcc_assert (operands[2] == constm1_rtx);
6545 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6546 }
6547
6548 default:
6549 /* For most processors, ADD is faster than LEA. These alternatives
6550 were added to use ADD as much as possible. */
6551 if (which_alternative == 2 || which_alternative == 4)
6552 std::swap (operands[1], operands[2]);
6553
6554 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6555 if (x86_maybe_negate_const_int (&operands[2], QImode))
6556 {
6557 if (widen)
6558 return "sub{l}\t{%2, %k0|%k0, %2}";
6559 else
6560 return "sub{b}\t{%2, %0|%0, %2}";
6561 }
6562 if (widen)
6563 return "add{l}\t{%k2, %k0|%k0, %k2}";
6564 else
6565 return "add{b}\t{%2, %0|%0, %2}";
6566 }
6567 }
6568 [(set (attr "type")
6569 (cond [(eq_attr "alternative" "5")
6570 (const_string "lea")
6571 (match_operand:QI 2 "incdec_operand")
6572 (const_string "incdec")
6573 ]
6574 (const_string "alu")))
6575 (set (attr "length_immediate")
6576 (if_then_else
6577 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6578 (const_string "1")
6579 (const_string "*")))
6580 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6581 ;; Potential partial reg stall on alternatives 3 and 4.
6582 (set (attr "preferred_for_speed")
6583 (cond [(eq_attr "alternative" "3,4")
6584 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6585 (symbol_ref "true")))])
6586
6587 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6588 (define_insn_and_split "*add<mode>_1_slp"
6589 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6590 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6591 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6592 (clobber (reg:CC FLAGS_REG))]
6593 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6594 {
6595 if (which_alternative)
6596 return "#";
6597
6598 switch (get_attr_type (insn))
6599 {
6600 case TYPE_INCDEC:
6601 if (operands[2] == const1_rtx)
6602 return "inc{<imodesuffix>}\t%0";
6603 else
6604 {
6605 gcc_assert (operands[2] == constm1_rtx);
6606 return "dec{<imodesuffix>}\t%0";
6607 }
6608
6609 default:
6610 if (x86_maybe_negate_const_int (&operands[2], QImode))
6611 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6612
6613 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6614 }
6615 }
6616 "&& reload_completed
6617 && !(rtx_equal_p (operands[0], operands[1])
6618 || rtx_equal_p (operands[0], operands[2]))"
6619 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6620 (parallel
6621 [(set (strict_low_part (match_dup 0))
6622 (plus:SWI12 (match_dup 0) (match_dup 2)))
6623 (clobber (reg:CC FLAGS_REG))])]
6624 ""
6625 [(set (attr "type")
6626 (if_then_else (match_operand:QI 2 "incdec_operand")
6627 (const_string "incdec")
6628 (const_string "alu")))
6629 (set_attr "mode" "<MODE>")])
6630
6631 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6632 (define_insn_and_split "*addqi_ext<mode>_1_slp"
6633 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
6634 (plus:QI
6635 (subreg:QI
6636 (match_operator:SWI248 3 "extract_operator"
6637 [(match_operand 2 "int248_register_operand" "Q,Q")
6638 (const_int 8)
6639 (const_int 8)]) 0)
6640 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
6641 (clobber (reg:CC FLAGS_REG))]
6642 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6643 "@
6644 add{b}\t{%h2, %0|%0, %h2}
6645 #"
6646 "&& reload_completed
6647 && !rtx_equal_p (operands[0], operands[1])"
6648 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6649 (parallel
6650 [(set (strict_low_part (match_dup 0))
6651 (plus:QI
6652 (subreg:QI
6653 (match_op_dup 3
6654 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
6655 (match_dup 0)))
6656 (clobber (reg:CC FLAGS_REG))])]
6657 ""
6658 [(set_attr "type" "alu")
6659 (set_attr "mode" "QI")])
6660
6661 (define_insn_and_split "*addqi_ext<mode>_2_slp"
6662 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
6663 (plus:QI
6664 (subreg:QI
6665 (match_operator:SWI248 3 "extract_operator"
6666 [(match_operand 1 "int248_register_operand" "Q")
6667 (const_int 8)
6668 (const_int 8)]) 0)
6669 (subreg:QI
6670 (match_operator:SWI248 4 "extract_operator"
6671 [(match_operand 2 "int248_register_operand" "Q")
6672 (const_int 8)
6673 (const_int 8)]) 0)))
6674 (clobber (reg:CC FLAGS_REG))]
6675 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6676 "#"
6677 "&& reload_completed"
6678 [(set (strict_low_part (match_dup 0))
6679 (subreg:QI
6680 (match_op_dup 4
6681 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
6682 (parallel
6683 [(set (strict_low_part (match_dup 0))
6684 (plus:QI
6685 (subreg:QI
6686 (match_op_dup 3
6687 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
6688 (match_dup 0)))
6689 (clobber (reg:CC FLAGS_REG))])]
6690 ""
6691 [(set_attr "type" "alu")
6692 (set_attr "mode" "QI")])
6693
6694 ;; Split non destructive adds if we cannot use lea.
6695 (define_split
6696 [(set (match_operand:SWI48 0 "register_operand")
6697 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6698 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6699 (clobber (reg:CC FLAGS_REG))]
6700 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6701 [(set (match_dup 0) (match_dup 1))
6702 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6703 (clobber (reg:CC FLAGS_REG))])])
6704
6705 ;; Split non destructive adds if we cannot use lea.
6706 (define_split
6707 [(set (match_operand:DI 0 "register_operand")
6708 (zero_extend:DI
6709 (plus:SI (match_operand:SI 1 "register_operand")
6710 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6711 (clobber (reg:CC FLAGS_REG))]
6712 "TARGET_64BIT
6713 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6714 [(set (match_dup 3) (match_dup 1))
6715 (parallel [(set (match_dup 0)
6716 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6717 (clobber (reg:CC FLAGS_REG))])]
6718 "operands[3] = gen_lowpart (SImode, operands[0]);")
6719
6720 ;; Convert add to the lea pattern to avoid flags dependency.
6721 (define_split
6722 [(set (match_operand:SWI 0 "register_operand")
6723 (plus:SWI (match_operand:SWI 1 "register_operand")
6724 (match_operand:SWI 2 "<nonmemory_operand>")))
6725 (clobber (reg:CC FLAGS_REG))]
6726 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6727 [(set (match_dup 0)
6728 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6729 {
6730 if (<MODE>mode != <LEAMODE>mode)
6731 {
6732 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6733 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6734 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6735 }
6736 })
6737
6738 ;; Convert add to the lea pattern to avoid flags dependency.
6739 (define_split
6740 [(set (match_operand:DI 0 "register_operand")
6741 (zero_extend:DI
6742 (plus:SI (match_operand:SI 1 "register_operand")
6743 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6744 (clobber (reg:CC FLAGS_REG))]
6745 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6746 [(set (match_dup 0)
6747 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6748
6749 (define_insn "*add<mode>_2"
6750 [(set (reg FLAGS_REG)
6751 (compare
6752 (plus:SWI
6753 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6754 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6755 (const_int 0)))
6756 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6757 (plus:SWI (match_dup 1) (match_dup 2)))]
6758 "ix86_match_ccmode (insn, CCGOCmode)
6759 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6760 {
6761 switch (get_attr_type (insn))
6762 {
6763 case TYPE_INCDEC:
6764 if (operands[2] == const1_rtx)
6765 return "inc{<imodesuffix>}\t%0";
6766 else
6767 {
6768 gcc_assert (operands[2] == constm1_rtx);
6769 return "dec{<imodesuffix>}\t%0";
6770 }
6771
6772 default:
6773 if (which_alternative == 2)
6774 std::swap (operands[1], operands[2]);
6775
6776 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6777 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6778 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6779
6780 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6781 }
6782 }
6783 [(set (attr "type")
6784 (if_then_else (match_operand:SWI 2 "incdec_operand")
6785 (const_string "incdec")
6786 (const_string "alu")))
6787 (set (attr "length_immediate")
6788 (if_then_else
6789 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6790 (const_string "1")
6791 (const_string "*")))
6792 (set_attr "mode" "<MODE>")])
6793
6794 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6795 (define_insn "*addsi_2_zext"
6796 [(set (reg FLAGS_REG)
6797 (compare
6798 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6799 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6800 (const_int 0)))
6801 (set (match_operand:DI 0 "register_operand" "=r,r")
6802 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6803 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6804 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6805 {
6806 switch (get_attr_type (insn))
6807 {
6808 case TYPE_INCDEC:
6809 if (operands[2] == const1_rtx)
6810 return "inc{l}\t%k0";
6811 else
6812 {
6813 gcc_assert (operands[2] == constm1_rtx);
6814 return "dec{l}\t%k0";
6815 }
6816
6817 default:
6818 if (which_alternative == 1)
6819 std::swap (operands[1], operands[2]);
6820
6821 if (x86_maybe_negate_const_int (&operands[2], SImode))
6822 return "sub{l}\t{%2, %k0|%k0, %2}";
6823
6824 return "add{l}\t{%2, %k0|%k0, %2}";
6825 }
6826 }
6827 [(set (attr "type")
6828 (if_then_else (match_operand:SI 2 "incdec_operand")
6829 (const_string "incdec")
6830 (const_string "alu")))
6831 (set (attr "length_immediate")
6832 (if_then_else
6833 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6834 (const_string "1")
6835 (const_string "*")))
6836 (set_attr "mode" "SI")])
6837
6838 (define_insn "*add<mode>_3"
6839 [(set (reg FLAGS_REG)
6840 (compare
6841 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6842 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6843 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6844 "ix86_match_ccmode (insn, CCZmode)
6845 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6846 {
6847 switch (get_attr_type (insn))
6848 {
6849 case TYPE_INCDEC:
6850 if (operands[2] == const1_rtx)
6851 return "inc{<imodesuffix>}\t%0";
6852 else
6853 {
6854 gcc_assert (operands[2] == constm1_rtx);
6855 return "dec{<imodesuffix>}\t%0";
6856 }
6857
6858 default:
6859 if (which_alternative == 1)
6860 std::swap (operands[1], operands[2]);
6861
6862 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6863 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6864 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6865
6866 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6867 }
6868 }
6869 [(set (attr "type")
6870 (if_then_else (match_operand:SWI 2 "incdec_operand")
6871 (const_string "incdec")
6872 (const_string "alu")))
6873 (set (attr "length_immediate")
6874 (if_then_else
6875 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6876 (const_string "1")
6877 (const_string "*")))
6878 (set_attr "mode" "<MODE>")])
6879
6880 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6881 (define_insn "*addsi_3_zext"
6882 [(set (reg FLAGS_REG)
6883 (compare
6884 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6885 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6886 (set (match_operand:DI 0 "register_operand" "=r,r")
6887 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6888 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6889 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6890 {
6891 switch (get_attr_type (insn))
6892 {
6893 case TYPE_INCDEC:
6894 if (operands[2] == const1_rtx)
6895 return "inc{l}\t%k0";
6896 else
6897 {
6898 gcc_assert (operands[2] == constm1_rtx);
6899 return "dec{l}\t%k0";
6900 }
6901
6902 default:
6903 if (which_alternative == 1)
6904 std::swap (operands[1], operands[2]);
6905
6906 if (x86_maybe_negate_const_int (&operands[2], SImode))
6907 return "sub{l}\t{%2, %k0|%k0, %2}";
6908
6909 return "add{l}\t{%2, %k0|%k0, %2}";
6910 }
6911 }
6912 [(set (attr "type")
6913 (if_then_else (match_operand:SI 2 "incdec_operand")
6914 (const_string "incdec")
6915 (const_string "alu")))
6916 (set (attr "length_immediate")
6917 (if_then_else
6918 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6919 (const_string "1")
6920 (const_string "*")))
6921 (set_attr "mode" "SI")])
6922
6923 ; For comparisons against 1, -1 and 128, we may generate better code
6924 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6925 ; is matched then. We can't accept general immediate, because for
6926 ; case of overflows, the result is messed up.
6927 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6928 ; only for comparisons not depending on it.
6929
6930 (define_insn "*adddi_4"
6931 [(set (reg FLAGS_REG)
6932 (compare
6933 (match_operand:DI 1 "nonimmediate_operand" "0")
6934 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6935 (clobber (match_scratch:DI 0 "=r"))]
6936 "TARGET_64BIT
6937 && ix86_match_ccmode (insn, CCGCmode)"
6938 {
6939 switch (get_attr_type (insn))
6940 {
6941 case TYPE_INCDEC:
6942 if (operands[2] == constm1_rtx)
6943 return "inc{q}\t%0";
6944 else
6945 {
6946 gcc_assert (operands[2] == const1_rtx);
6947 return "dec{q}\t%0";
6948 }
6949
6950 default:
6951 if (x86_maybe_negate_const_int (&operands[2], DImode))
6952 return "add{q}\t{%2, %0|%0, %2}";
6953
6954 return "sub{q}\t{%2, %0|%0, %2}";
6955 }
6956 }
6957 [(set (attr "type")
6958 (if_then_else (match_operand:DI 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" "DI")])
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 "*add<mode>_4"
6976 [(set (reg FLAGS_REG)
6977 (compare
6978 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6979 (match_operand:SWI124 2 "const_int_operand")))
6980 (clobber (match_scratch:SWI124 0 "=<r>"))]
6981 "ix86_match_ccmode (insn, CCGCmode)"
6982 {
6983 switch (get_attr_type (insn))
6984 {
6985 case TYPE_INCDEC:
6986 if (operands[2] == constm1_rtx)
6987 return "inc{<imodesuffix>}\t%0";
6988 else
6989 {
6990 gcc_assert (operands[2] == const1_rtx);
6991 return "dec{<imodesuffix>}\t%0";
6992 }
6993
6994 default:
6995 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6996 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6997
6998 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6999 }
7000 }
7001 [(set (attr "type")
7002 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
7003 (const_string "incdec")
7004 (const_string "alu")))
7005 (set (attr "length_immediate")
7006 (if_then_else
7007 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7008 (const_string "1")
7009 (const_string "*")))
7010 (set_attr "mode" "<MODE>")])
7011
7012 (define_insn "*add<mode>_5"
7013 [(set (reg FLAGS_REG)
7014 (compare
7015 (plus:SWI
7016 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
7017 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
7018 (const_int 0)))
7019 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
7020 "ix86_match_ccmode (insn, CCGOCmode)
7021 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7022 {
7023 switch (get_attr_type (insn))
7024 {
7025 case TYPE_INCDEC:
7026 if (operands[2] == const1_rtx)
7027 return "inc{<imodesuffix>}\t%0";
7028 else
7029 {
7030 gcc_assert (operands[2] == constm1_rtx);
7031 return "dec{<imodesuffix>}\t%0";
7032 }
7033
7034 default:
7035 if (which_alternative == 1)
7036 std::swap (operands[1], operands[2]);
7037
7038 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7039 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
7040 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7041
7042 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7043 }
7044 }
7045 [(set (attr "type")
7046 (if_then_else (match_operand:SWI 2 "incdec_operand")
7047 (const_string "incdec")
7048 (const_string "alu")))
7049 (set (attr "length_immediate")
7050 (if_then_else
7051 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
7052 (const_string "1")
7053 (const_string "*")))
7054 (set_attr "mode" "<MODE>")])
7055
7056 (define_insn "*addqi_ext<mode>_0"
7057 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7058 (plus:QI
7059 (subreg:QI
7060 (match_operator:SWI248 3 "extract_operator"
7061 [(match_operand 2 "int248_register_operand" "Q")
7062 (const_int 8)
7063 (const_int 8)]) 0)
7064 (match_operand:QI 1 "nonimmediate_operand" "0")))
7065 (clobber (reg:CC FLAGS_REG))]
7066 ""
7067 "add{b}\t{%h2, %0|%0, %h2}"
7068 [(set_attr "addr" "gpr8")
7069 (set_attr "type" "alu")
7070 (set_attr "mode" "QI")])
7071
7072 (define_expand "addqi_ext_1"
7073 [(parallel
7074 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
7075 (const_int 8)
7076 (const_int 8))
7077 (subreg:HI
7078 (plus:QI
7079 (subreg:QI
7080 (zero_extract:HI (match_operand:HI 1 "register_operand")
7081 (const_int 8)
7082 (const_int 8)) 0)
7083 (match_operand:QI 2 "const_int_operand")) 0))
7084 (clobber (reg:CC FLAGS_REG))])])
7085
7086 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7087 (define_insn_and_split "*addqi_ext<mode>_1"
7088 [(set (zero_extract:SWI248
7089 (match_operand 0 "int248_register_operand" "+Q,&Q")
7090 (const_int 8)
7091 (const_int 8))
7092 (subreg:SWI248
7093 (plus:QI
7094 (subreg:QI
7095 (match_operator:SWI248 3 "extract_operator"
7096 [(match_operand 1 "int248_register_operand" "0,!Q")
7097 (const_int 8)
7098 (const_int 8)]) 0)
7099 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7100 (clobber (reg:CC FLAGS_REG))]
7101 ""
7102 {
7103 if (which_alternative)
7104 return "#";
7105
7106 switch (get_attr_type (insn))
7107 {
7108 case TYPE_INCDEC:
7109 if (operands[2] == const1_rtx)
7110 return "inc{b}\t%h0";
7111 else
7112 {
7113 gcc_assert (operands[2] == constm1_rtx);
7114 return "dec{b}\t%h0";
7115 }
7116
7117 default:
7118 return "add{b}\t{%2, %h0|%h0, %2}";
7119 }
7120 }
7121 "reload_completed
7122 && !rtx_equal_p (operands[0], operands[1])"
7123 [(set (zero_extract:SWI248
7124 (match_dup 0) (const_int 8) (const_int 8))
7125 (zero_extract:SWI248
7126 (match_dup 1) (const_int 8) (const_int 8)))
7127 (parallel
7128 [(set (zero_extract:SWI248
7129 (match_dup 0) (const_int 8) (const_int 8))
7130 (subreg:SWI248
7131 (plus:QI
7132 (subreg:QI
7133 (match_op_dup 3
7134 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7135 (match_dup 2)) 0))
7136 (clobber (reg:CC FLAGS_REG))])]
7137 ""
7138 [(set_attr "addr" "gpr8")
7139 (set (attr "type")
7140 (if_then_else (match_operand:QI 2 "incdec_operand")
7141 (const_string "incdec")
7142 (const_string "alu")))
7143 (set_attr "mode" "QI")])
7144
7145 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7146 (define_insn_and_split "*<insn>qi_ext<mode>_2"
7147 [(set (zero_extract:SWI248
7148 (match_operand 0 "int248_register_operand" "+Q,&Q")
7149 (const_int 8)
7150 (const_int 8))
7151 (subreg:SWI248
7152 (plusminus:QI
7153 (subreg:QI
7154 (match_operator:SWI248 3 "extract_operator"
7155 [(match_operand 1 "int248_register_operand" "<comm>0,!Q")
7156 (const_int 8)
7157 (const_int 8)]) 0)
7158 (subreg:QI
7159 (match_operator:SWI248 4 "extract_operator"
7160 [(match_operand 2 "int248_register_operand" "Q,Q")
7161 (const_int 8)
7162 (const_int 8)]) 0)) 0))
7163 (clobber (reg:CC FLAGS_REG))]
7164 ""
7165 "@
7166 <insn>{b}\t{%h2, %h0|%h0, %h2}
7167 #"
7168 "reload_completed
7169 && !(rtx_equal_p (operands[0], operands[1])
7170 || (<CODE> == PLUS && rtx_equal_p (operands[0], operands[2])))"
7171 [(set (zero_extract:SWI248
7172 (match_dup 0) (const_int 8) (const_int 8))
7173 (zero_extract:SWI248
7174 (match_dup 1) (const_int 8) (const_int 8)))
7175 (parallel
7176 [(set (zero_extract:SWI248
7177 (match_dup 0) (const_int 8) (const_int 8))
7178 (subreg:SWI248
7179 (plusminus:QI
7180 (subreg:QI
7181 (match_op_dup 3
7182 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7183 (subreg:QI
7184 (match_op_dup 4
7185 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
7186 (clobber (reg:CC FLAGS_REG))])]
7187 ""
7188 [(set_attr "type" "alu")
7189 (set_attr "mode" "QI")])
7190
7191 ;; Like DWI, but use POImode instead of OImode.
7192 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7193
7194 ;; Add with jump on overflow.
7195 (define_expand "addv<mode>4"
7196 [(parallel [(set (reg:CCO FLAGS_REG)
7197 (eq:CCO
7198 (plus:<DPWI>
7199 (sign_extend:<DPWI>
7200 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7201 (match_dup 4))
7202 (sign_extend:<DPWI>
7203 (plus:SWIDWI (match_dup 1)
7204 (match_operand:SWIDWI 2
7205 "<general_hilo_operand>")))))
7206 (set (match_operand:SWIDWI 0 "register_operand")
7207 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7208 (set (pc) (if_then_else
7209 (eq (reg:CCO FLAGS_REG) (const_int 0))
7210 (label_ref (match_operand 3))
7211 (pc)))]
7212 ""
7213 {
7214 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7215 if (CONST_SCALAR_INT_P (operands[2]))
7216 operands[4] = operands[2];
7217 else
7218 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7219 })
7220
7221 (define_insn "*addv<mode>4"
7222 [(set (reg:CCO FLAGS_REG)
7223 (eq:CCO (plus:<DWI>
7224 (sign_extend:<DWI>
7225 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7226 (sign_extend:<DWI>
7227 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7228 (sign_extend:<DWI>
7229 (plus:SWI (match_dup 1) (match_dup 2)))))
7230 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7231 (plus:SWI (match_dup 1) (match_dup 2)))]
7232 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7233 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7234 [(set_attr "type" "alu")
7235 (set_attr "mode" "<MODE>")])
7236
7237 (define_insn "addv<mode>4_1"
7238 [(set (reg:CCO FLAGS_REG)
7239 (eq:CCO (plus:<DWI>
7240 (sign_extend:<DWI>
7241 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7242 (match_operand:<DWI> 3 "const_int_operand"))
7243 (sign_extend:<DWI>
7244 (plus:SWI
7245 (match_dup 1)
7246 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7247 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7248 (plus:SWI (match_dup 1) (match_dup 2)))]
7249 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7250 && CONST_INT_P (operands[2])
7251 && INTVAL (operands[2]) == INTVAL (operands[3])"
7252 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7253 [(set_attr "type" "alu")
7254 (set_attr "mode" "<MODE>")
7255 (set (attr "length_immediate")
7256 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7257 (const_string "1")
7258 (match_test "<MODE_SIZE> == 8")
7259 (const_string "4")]
7260 (const_string "<MODE_SIZE>")))])
7261
7262 ;; Quad word integer modes as mode attribute.
7263 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7264
7265 (define_insn_and_split "*addv<dwi>4_doubleword"
7266 [(set (reg:CCO FLAGS_REG)
7267 (eq:CCO
7268 (plus:<QPWI>
7269 (sign_extend:<QPWI>
7270 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7271 (sign_extend:<QPWI>
7272 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7273 (sign_extend:<QPWI>
7274 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7275 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7276 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7277 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7278 "#"
7279 "&& reload_completed"
7280 [(parallel [(set (reg:CCC FLAGS_REG)
7281 (compare:CCC
7282 (plus:DWIH (match_dup 1) (match_dup 2))
7283 (match_dup 1)))
7284 (set (match_dup 0)
7285 (plus:DWIH (match_dup 1) (match_dup 2)))])
7286 (parallel [(set (reg:CCO FLAGS_REG)
7287 (eq:CCO
7288 (plus:<DWI>
7289 (plus:<DWI>
7290 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7291 (sign_extend:<DWI> (match_dup 4)))
7292 (sign_extend:<DWI> (match_dup 5)))
7293 (sign_extend:<DWI>
7294 (plus:DWIH
7295 (plus:DWIH
7296 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7297 (match_dup 4))
7298 (match_dup 5)))))
7299 (set (match_dup 3)
7300 (plus:DWIH
7301 (plus:DWIH
7302 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7303 (match_dup 4))
7304 (match_dup 5)))])]
7305 {
7306 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7307 })
7308
7309 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7310 [(set (reg:CCO FLAGS_REG)
7311 (eq:CCO
7312 (plus:<QPWI>
7313 (sign_extend:<QPWI>
7314 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7315 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7316 (sign_extend:<QPWI>
7317 (plus:<DWI>
7318 (match_dup 1)
7319 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7320 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7321 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7322 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7323 && CONST_SCALAR_INT_P (operands[2])
7324 && rtx_equal_p (operands[2], operands[3])"
7325 "#"
7326 "&& reload_completed"
7327 [(parallel [(set (reg:CCC FLAGS_REG)
7328 (compare:CCC
7329 (plus:DWIH (match_dup 1) (match_dup 2))
7330 (match_dup 1)))
7331 (set (match_dup 0)
7332 (plus:DWIH (match_dup 1) (match_dup 2)))])
7333 (parallel [(set (reg:CCO FLAGS_REG)
7334 (eq:CCO
7335 (plus:<DWI>
7336 (plus:<DWI>
7337 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7338 (sign_extend:<DWI> (match_dup 4)))
7339 (match_dup 5))
7340 (sign_extend:<DWI>
7341 (plus:DWIH
7342 (plus:DWIH
7343 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7344 (match_dup 4))
7345 (match_dup 5)))))
7346 (set (match_dup 3)
7347 (plus:DWIH
7348 (plus:DWIH
7349 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7350 (match_dup 4))
7351 (match_dup 5)))])]
7352 {
7353 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7354 if (operands[2] == const0_rtx)
7355 {
7356 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7357 operands[5]));
7358 DONE;
7359 }
7360 })
7361
7362 (define_insn "*addv<mode>4_overflow_1"
7363 [(set (reg:CCO FLAGS_REG)
7364 (eq:CCO
7365 (plus:<DWI>
7366 (plus:<DWI>
7367 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7368 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7369 (sign_extend:<DWI>
7370 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7371 (sign_extend:<DWI>
7372 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7373 (sign_extend:<DWI>
7374 (plus:SWI
7375 (plus:SWI
7376 (match_operator:SWI 5 "ix86_carry_flag_operator"
7377 [(match_dup 3) (const_int 0)])
7378 (match_dup 1))
7379 (match_dup 2)))))
7380 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7381 (plus:SWI
7382 (plus:SWI
7383 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7384 (match_dup 1))
7385 (match_dup 2)))]
7386 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7387 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7388 [(set_attr "type" "alu")
7389 (set_attr "mode" "<MODE>")])
7390
7391 (define_insn "*addv<mode>4_overflow_2"
7392 [(set (reg:CCO FLAGS_REG)
7393 (eq:CCO
7394 (plus:<DWI>
7395 (plus:<DWI>
7396 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7397 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7398 (sign_extend:<DWI>
7399 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7400 (match_operand:<DWI> 6 "const_int_operand" "n"))
7401 (sign_extend:<DWI>
7402 (plus:SWI
7403 (plus:SWI
7404 (match_operator:SWI 5 "ix86_carry_flag_operator"
7405 [(match_dup 3) (const_int 0)])
7406 (match_dup 1))
7407 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7408 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7409 (plus:SWI
7410 (plus:SWI
7411 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7412 (match_dup 1))
7413 (match_dup 2)))]
7414 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7415 && CONST_INT_P (operands[2])
7416 && INTVAL (operands[2]) == INTVAL (operands[6])"
7417 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7418 [(set_attr "type" "alu")
7419 (set_attr "mode" "<MODE>")
7420 (set (attr "length_immediate")
7421 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7422 (const_string "1")
7423 (const_string "4")))])
7424
7425 (define_expand "uaddv<mode>4"
7426 [(parallel [(set (reg:CCC FLAGS_REG)
7427 (compare:CCC
7428 (plus:SWIDWI
7429 (match_operand:SWIDWI 1 "nonimmediate_operand")
7430 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7431 (match_dup 1)))
7432 (set (match_operand:SWIDWI 0 "register_operand")
7433 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7434 (set (pc) (if_then_else
7435 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7436 (label_ref (match_operand 3))
7437 (pc)))]
7438 ""
7439 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7440
7441 ;; The lea patterns for modes less than 32 bits need to be matched by
7442 ;; several insns converted to real lea by splitters.
7443
7444 (define_insn_and_split "*lea<mode>_general_1"
7445 [(set (match_operand:SWI12 0 "register_operand" "=r")
7446 (plus:SWI12
7447 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7448 (match_operand:SWI12 2 "register_operand" "r"))
7449 (match_operand:SWI12 3 "immediate_operand" "i")))]
7450 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7451 "#"
7452 "&& reload_completed"
7453 [(set (match_dup 0)
7454 (plus:SI
7455 (plus:SI (match_dup 1) (match_dup 2))
7456 (match_dup 3)))]
7457 {
7458 operands[0] = gen_lowpart (SImode, operands[0]);
7459 operands[1] = gen_lowpart (SImode, operands[1]);
7460 operands[2] = gen_lowpart (SImode, operands[2]);
7461 operands[3] = gen_lowpart (SImode, operands[3]);
7462 }
7463 [(set_attr "type" "lea")
7464 (set_attr "mode" "SI")])
7465
7466 (define_insn_and_split "*lea<mode>_general_2"
7467 [(set (match_operand:SWI12 0 "register_operand" "=r")
7468 (plus:SWI12
7469 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7470 (match_operand 2 "const248_operand" "n"))
7471 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7472 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7473 "#"
7474 "&& reload_completed"
7475 [(set (match_dup 0)
7476 (plus:SI
7477 (mult:SI (match_dup 1) (match_dup 2))
7478 (match_dup 3)))]
7479 {
7480 operands[0] = gen_lowpart (SImode, operands[0]);
7481 operands[1] = gen_lowpart (SImode, operands[1]);
7482 operands[3] = gen_lowpart (SImode, operands[3]);
7483 }
7484 [(set_attr "type" "lea")
7485 (set_attr "mode" "SI")])
7486
7487 (define_insn_and_split "*lea<mode>_general_2b"
7488 [(set (match_operand:SWI12 0 "register_operand" "=r")
7489 (plus:SWI12
7490 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7491 (match_operand 2 "const123_operand" "n"))
7492 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7493 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7494 "#"
7495 "&& reload_completed"
7496 [(set (match_dup 0)
7497 (plus:SI
7498 (ashift:SI (match_dup 1) (match_dup 2))
7499 (match_dup 3)))]
7500 {
7501 operands[0] = gen_lowpart (SImode, operands[0]);
7502 operands[1] = gen_lowpart (SImode, operands[1]);
7503 operands[3] = gen_lowpart (SImode, operands[3]);
7504 }
7505 [(set_attr "type" "lea")
7506 (set_attr "mode" "SI")])
7507
7508 (define_insn_and_split "*lea<mode>_general_3"
7509 [(set (match_operand:SWI12 0 "register_operand" "=r")
7510 (plus:SWI12
7511 (plus:SWI12
7512 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7513 (match_operand 2 "const248_operand" "n"))
7514 (match_operand:SWI12 3 "register_operand" "r"))
7515 (match_operand:SWI12 4 "immediate_operand" "i")))]
7516 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7517 "#"
7518 "&& reload_completed"
7519 [(set (match_dup 0)
7520 (plus:SI
7521 (plus:SI
7522 (mult:SI (match_dup 1) (match_dup 2))
7523 (match_dup 3))
7524 (match_dup 4)))]
7525 {
7526 operands[0] = gen_lowpart (SImode, operands[0]);
7527 operands[1] = gen_lowpart (SImode, operands[1]);
7528 operands[3] = gen_lowpart (SImode, operands[3]);
7529 operands[4] = gen_lowpart (SImode, operands[4]);
7530 }
7531 [(set_attr "type" "lea")
7532 (set_attr "mode" "SI")])
7533
7534 (define_insn_and_split "*lea<mode>_general_3b"
7535 [(set (match_operand:SWI12 0 "register_operand" "=r")
7536 (plus:SWI12
7537 (plus:SWI12
7538 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7539 (match_operand 2 "const123_operand" "n"))
7540 (match_operand:SWI12 3 "register_operand" "r"))
7541 (match_operand:SWI12 4 "immediate_operand" "i")))]
7542 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7543 "#"
7544 "&& reload_completed"
7545 [(set (match_dup 0)
7546 (plus:SI
7547 (plus:SI
7548 (ashift:SI (match_dup 1) (match_dup 2))
7549 (match_dup 3))
7550 (match_dup 4)))]
7551 {
7552 operands[0] = gen_lowpart (SImode, operands[0]);
7553 operands[1] = gen_lowpart (SImode, operands[1]);
7554 operands[3] = gen_lowpart (SImode, operands[3]);
7555 operands[4] = gen_lowpart (SImode, operands[4]);
7556 }
7557 [(set_attr "type" "lea")
7558 (set_attr "mode" "SI")])
7559
7560 (define_insn_and_split "*lea<mode>_general_4"
7561 [(set (match_operand:SWI12 0 "register_operand" "=r")
7562 (any_or:SWI12
7563 (ashift:SWI12
7564 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7565 (match_operand 2 "const_0_to_3_operand"))
7566 (match_operand 3 "const_int_operand")))]
7567 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7568 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7569 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7570 "#"
7571 "&& reload_completed"
7572 [(set (match_dup 0)
7573 (plus:SI
7574 (mult:SI (match_dup 1) (match_dup 2))
7575 (match_dup 3)))]
7576 {
7577 operands[0] = gen_lowpart (SImode, operands[0]);
7578 operands[1] = gen_lowpart (SImode, operands[1]);
7579 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7580 }
7581 [(set_attr "type" "lea")
7582 (set_attr "mode" "SI")])
7583
7584 (define_insn_and_split "*lea<mode>_general_4"
7585 [(set (match_operand:SWI48 0 "register_operand" "=r")
7586 (any_or:SWI48
7587 (ashift:SWI48
7588 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7589 (match_operand 2 "const_0_to_3_operand"))
7590 (match_operand 3 "const_int_operand")))]
7591 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7592 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7593 "#"
7594 "&& reload_completed"
7595 [(set (match_dup 0)
7596 (plus:SWI48
7597 (mult:SWI48 (match_dup 1) (match_dup 2))
7598 (match_dup 3)))]
7599 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7600 [(set_attr "type" "lea")
7601 (set_attr "mode" "<MODE>")])
7602 \f
7603 ;; Subtract instructions
7604
7605 (define_expand "sub<mode>3"
7606 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7607 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7608 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7609 ""
7610 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7611
7612 (define_insn_and_split "*sub<dwi>3_doubleword"
7613 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7614 (minus:<DWI>
7615 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7616 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7617 (clobber (reg:CC FLAGS_REG))]
7618 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7619 "#"
7620 "&& reload_completed"
7621 [(parallel [(set (reg:CC FLAGS_REG)
7622 (compare:CC (match_dup 1) (match_dup 2)))
7623 (set (match_dup 0)
7624 (minus:DWIH (match_dup 1) (match_dup 2)))])
7625 (parallel [(set (match_dup 3)
7626 (minus:DWIH
7627 (minus:DWIH
7628 (match_dup 4)
7629 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7630 (match_dup 5)))
7631 (clobber (reg:CC FLAGS_REG))])]
7632 {
7633 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7634 if (operands[2] == const0_rtx)
7635 {
7636 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7637 DONE;
7638 }
7639 })
7640
7641 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7642 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7643 (minus:<DWI>
7644 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7645 (zero_extend:<DWI>
7646 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7647 (clobber (reg:CC FLAGS_REG))]
7648 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7649 "#"
7650 "&& reload_completed"
7651 [(parallel [(set (reg:CC FLAGS_REG)
7652 (compare:CC (match_dup 1) (match_dup 2)))
7653 (set (match_dup 0)
7654 (minus:DWIH (match_dup 1) (match_dup 2)))])
7655 (parallel [(set (match_dup 3)
7656 (minus:DWIH
7657 (minus:DWIH
7658 (match_dup 4)
7659 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7660 (const_int 0)))
7661 (clobber (reg:CC FLAGS_REG))])]
7662 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7663
7664 (define_insn "*sub<mode>_1"
7665 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7666 (minus:SWI
7667 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7668 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7669 (clobber (reg:CC FLAGS_REG))]
7670 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7671 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7672 [(set_attr "type" "alu")
7673 (set_attr "mode" "<MODE>")])
7674
7675 (define_insn "*subsi_1_zext"
7676 [(set (match_operand:DI 0 "register_operand" "=r")
7677 (zero_extend:DI
7678 (minus:SI (match_operand:SI 1 "register_operand" "0")
7679 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7680 (clobber (reg:CC FLAGS_REG))]
7681 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682 "sub{l}\t{%2, %k0|%k0, %2}"
7683 [(set_attr "type" "alu")
7684 (set_attr "mode" "SI")])
7685
7686 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7687 (define_insn_and_split "*sub<mode>_1_slp"
7688 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7689 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7690 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7691 (clobber (reg:CC FLAGS_REG))]
7692 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7693 "@
7694 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7695 #"
7696 "&& reload_completed
7697 && !(rtx_equal_p (operands[0], operands[1]))"
7698 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7699 (parallel
7700 [(set (strict_low_part (match_dup 0))
7701 (minus:SWI12 (match_dup 0) (match_dup 2)))
7702 (clobber (reg:CC FLAGS_REG))])]
7703 ""
7704 [(set_attr "type" "alu")
7705 (set_attr "mode" "<MODE>")])
7706
7707 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7708 (define_insn_and_split "*subqi_ext<mode>_1_slp"
7709 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
7710 (minus:QI
7711 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")
7712 (subreg:QI
7713 (match_operator:SWI248 3 "extract_operator"
7714 [(match_operand 2 "int248_register_operand" "Q,Q")
7715 (const_int 8)
7716 (const_int 8)]) 0)))
7717 (clobber (reg:CC FLAGS_REG))]
7718 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7719 "@
7720 sub{b}\t{%h2, %0|%0, %h2}
7721 #"
7722 "&& reload_completed
7723 && !rtx_equal_p (operands[0], operands[1])"
7724 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7725 (parallel
7726 [(set (strict_low_part (match_dup 0))
7727 (minus:QI
7728 (match_dup 0)
7729 (subreg:QI
7730 (match_op_dup 3
7731 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7732 (clobber (reg:CC FLAGS_REG))])]
7733 ""
7734 [(set_attr "type" "alu")
7735 (set_attr "mode" "QI")])
7736
7737 (define_insn_and_split "*subqi_ext<mode>_2_slp"
7738 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
7739 (minus:QI
7740 (subreg:QI
7741 (match_operator:SWI248 3 "extract_operator"
7742 [(match_operand 1 "int248_register_operand" "Q")
7743 (const_int 8)
7744 (const_int 8)]) 0)
7745 (subreg:QI
7746 (match_operator:SWI248 4 "extract_operator"
7747 [(match_operand 2 "int248_register_operand" "Q")
7748 (const_int 8)
7749 (const_int 8)]) 0)))
7750 (clobber (reg:CC FLAGS_REG))]
7751 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7752 "#"
7753 "&& reload_completed"
7754 [(set (strict_low_part (match_dup 0))
7755 (subreg:QI
7756 (match_op_dup 3
7757 [(match_dup 1) (const_int 8) (const_int 8)]) 0))
7758 (parallel
7759 [(set (strict_low_part (match_dup 0))
7760 (minus:QI
7761 (match_dup 0)
7762 (subreg:QI
7763 (match_op_dup 4
7764 [(match_dup 2) (const_int 8) (const_int 8)]) 0)))
7765 (clobber (reg:CC FLAGS_REG))])]
7766 ""
7767 [(set_attr "type" "alu")
7768 (set_attr "mode" "QI")])
7769
7770 (define_insn "*sub<mode>_2"
7771 [(set (reg FLAGS_REG)
7772 (compare
7773 (minus:SWI
7774 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7775 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7776 (const_int 0)))
7777 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7778 (minus:SWI (match_dup 1) (match_dup 2)))]
7779 "ix86_match_ccmode (insn, CCGOCmode)
7780 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7781 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7782 [(set_attr "type" "alu")
7783 (set_attr "mode" "<MODE>")])
7784
7785 (define_insn "*subsi_2_zext"
7786 [(set (reg FLAGS_REG)
7787 (compare
7788 (minus:SI (match_operand:SI 1 "register_operand" "0")
7789 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7790 (const_int 0)))
7791 (set (match_operand:DI 0 "register_operand" "=r")
7792 (zero_extend:DI
7793 (minus:SI (match_dup 1)
7794 (match_dup 2))))]
7795 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7796 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7797 "sub{l}\t{%2, %k0|%k0, %2}"
7798 [(set_attr "type" "alu")
7799 (set_attr "mode" "SI")])
7800
7801 (define_insn "*subqi_ext<mode>_0"
7802 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
7803 (minus:QI
7804 (match_operand:QI 1 "nonimmediate_operand" "0")
7805 (subreg:QI
7806 (match_operator:SWI248 3 "extract_operator"
7807 [(match_operand 2 "int248_register_operand" "Q")
7808 (const_int 8)
7809 (const_int 8)]) 0)))
7810 (clobber (reg:CC FLAGS_REG))]
7811 ""
7812 "sub{b}\t{%h2, %0|%0, %h2}"
7813 [(set_attr "addr" "gpr8")
7814 (set_attr "type" "alu")
7815 (set_attr "mode" "QI")])
7816
7817 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7818 (define_insn_and_split "*subqi_ext<mode>_1"
7819 [(set (zero_extract:SWI248
7820 (match_operand 0 "int248_register_operand" "+Q,&Q")
7821 (const_int 8)
7822 (const_int 8))
7823 (subreg:SWI248
7824 (minus:QI
7825 (subreg:QI
7826 (match_operator:SWI248 3 "extract_operator"
7827 [(match_operand 1 "int248_register_operand" "0,!Q")
7828 (const_int 8)
7829 (const_int 8)]) 0)
7830 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
7831 (clobber (reg:CC FLAGS_REG))]
7832 ""
7833 "@
7834 sub{b}\t{%2, %h0|%h0, %2}
7835 #"
7836 "reload_completed
7837 && !(rtx_equal_p (operands[0], operands[1]))"
7838 [(set (zero_extract:SWI248
7839 (match_dup 0) (const_int 8) (const_int 8))
7840 (zero_extract:SWI248
7841 (match_dup 1) (const_int 8) (const_int 8)))
7842 (parallel
7843 [(set (zero_extract:SWI248
7844 (match_dup 0) (const_int 8) (const_int 8))
7845 (subreg:SWI248
7846 (minus:QI
7847 (subreg:QI
7848 (match_op_dup 3
7849 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
7850 (match_dup 2)) 0))
7851 (clobber (reg:CC FLAGS_REG))])]
7852 ""
7853 [(set_attr "addr" "gpr8")
7854 (set_attr "type" "alu")
7855 (set_attr "mode" "QI")])
7856
7857 ;; Subtract with jump on overflow.
7858 (define_expand "subv<mode>4"
7859 [(parallel [(set (reg:CCO FLAGS_REG)
7860 (eq:CCO
7861 (minus:<DPWI>
7862 (sign_extend:<DPWI>
7863 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7864 (match_dup 4))
7865 (sign_extend:<DPWI>
7866 (minus:SWIDWI (match_dup 1)
7867 (match_operand:SWIDWI 2
7868 "<general_hilo_operand>")))))
7869 (set (match_operand:SWIDWI 0 "register_operand")
7870 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7871 (set (pc) (if_then_else
7872 (eq (reg:CCO FLAGS_REG) (const_int 0))
7873 (label_ref (match_operand 3))
7874 (pc)))]
7875 ""
7876 {
7877 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7878 if (CONST_SCALAR_INT_P (operands[2]))
7879 operands[4] = operands[2];
7880 else
7881 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7882 })
7883
7884 (define_insn "*subv<mode>4"
7885 [(set (reg:CCO FLAGS_REG)
7886 (eq:CCO (minus:<DWI>
7887 (sign_extend:<DWI>
7888 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7889 (sign_extend:<DWI>
7890 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7891 (sign_extend:<DWI>
7892 (minus:SWI (match_dup 1) (match_dup 2)))))
7893 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7894 (minus:SWI (match_dup 1) (match_dup 2)))]
7895 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7896 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7897 [(set_attr "type" "alu")
7898 (set_attr "mode" "<MODE>")])
7899
7900 (define_insn "subv<mode>4_1"
7901 [(set (reg:CCO FLAGS_REG)
7902 (eq:CCO (minus:<DWI>
7903 (sign_extend:<DWI>
7904 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7905 (match_operand:<DWI> 3 "const_int_operand"))
7906 (sign_extend:<DWI>
7907 (minus:SWI
7908 (match_dup 1)
7909 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7910 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7911 (minus:SWI (match_dup 1) (match_dup 2)))]
7912 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7913 && CONST_INT_P (operands[2])
7914 && INTVAL (operands[2]) == INTVAL (operands[3])"
7915 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7916 [(set_attr "type" "alu")
7917 (set_attr "mode" "<MODE>")
7918 (set (attr "length_immediate")
7919 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7920 (const_string "1")
7921 (match_test "<MODE_SIZE> == 8")
7922 (const_string "4")]
7923 (const_string "<MODE_SIZE>")))])
7924
7925 (define_insn_and_split "*subv<dwi>4_doubleword"
7926 [(set (reg:CCO FLAGS_REG)
7927 (eq:CCO
7928 (minus:<QPWI>
7929 (sign_extend:<QPWI>
7930 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7931 (sign_extend:<QPWI>
7932 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7933 (sign_extend:<QPWI>
7934 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7935 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7936 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7937 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7938 "#"
7939 "&& reload_completed"
7940 [(parallel [(set (reg:CC FLAGS_REG)
7941 (compare:CC (match_dup 1) (match_dup 2)))
7942 (set (match_dup 0)
7943 (minus:DWIH (match_dup 1) (match_dup 2)))])
7944 (parallel [(set (reg:CCO FLAGS_REG)
7945 (eq:CCO
7946 (minus:<DWI>
7947 (minus:<DWI>
7948 (sign_extend:<DWI> (match_dup 4))
7949 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7950 (sign_extend:<DWI> (match_dup 5)))
7951 (sign_extend:<DWI>
7952 (minus:DWIH
7953 (minus:DWIH
7954 (match_dup 4)
7955 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7956 (match_dup 5)))))
7957 (set (match_dup 3)
7958 (minus:DWIH
7959 (minus:DWIH
7960 (match_dup 4)
7961 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7962 (match_dup 5)))])]
7963 {
7964 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7965 })
7966
7967 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7968 [(set (reg:CCO FLAGS_REG)
7969 (eq:CCO
7970 (minus:<QPWI>
7971 (sign_extend:<QPWI>
7972 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7973 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7974 (sign_extend:<QPWI>
7975 (minus:<DWI>
7976 (match_dup 1)
7977 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7978 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7979 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7980 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7981 && CONST_SCALAR_INT_P (operands[2])
7982 && rtx_equal_p (operands[2], operands[3])"
7983 "#"
7984 "&& reload_completed"
7985 [(parallel [(set (reg:CC FLAGS_REG)
7986 (compare:CC (match_dup 1) (match_dup 2)))
7987 (set (match_dup 0)
7988 (minus:DWIH (match_dup 1) (match_dup 2)))])
7989 (parallel [(set (reg:CCO FLAGS_REG)
7990 (eq:CCO
7991 (minus:<DWI>
7992 (minus:<DWI>
7993 (sign_extend:<DWI> (match_dup 4))
7994 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7995 (match_dup 5))
7996 (sign_extend:<DWI>
7997 (minus:DWIH
7998 (minus:DWIH
7999 (match_dup 4)
8000 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8001 (match_dup 5)))))
8002 (set (match_dup 3)
8003 (minus:DWIH
8004 (minus:DWIH
8005 (match_dup 4)
8006 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
8007 (match_dup 5)))])]
8008 {
8009 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8010 if (operands[2] == const0_rtx)
8011 {
8012 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
8013 operands[5]));
8014 DONE;
8015 }
8016 })
8017
8018 (define_insn "*subv<mode>4_overflow_1"
8019 [(set (reg:CCO FLAGS_REG)
8020 (eq:CCO
8021 (minus:<DWI>
8022 (minus:<DWI>
8023 (sign_extend:<DWI>
8024 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8025 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8026 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8027 (sign_extend:<DWI>
8028 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
8029 (sign_extend:<DWI>
8030 (minus:SWI
8031 (minus:SWI
8032 (match_dup 1)
8033 (match_operator:SWI 5 "ix86_carry_flag_operator"
8034 [(match_dup 3) (const_int 0)]))
8035 (match_dup 2)))))
8036 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
8037 (minus:SWI
8038 (minus:SWI
8039 (match_dup 1)
8040 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8041 (match_dup 2)))]
8042 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8043 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8044 [(set_attr "type" "alu")
8045 (set_attr "mode" "<MODE>")])
8046
8047 (define_insn "*subv<mode>4_overflow_2"
8048 [(set (reg:CCO FLAGS_REG)
8049 (eq:CCO
8050 (minus:<DWI>
8051 (minus:<DWI>
8052 (sign_extend:<DWI>
8053 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
8054 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8055 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8056 (match_operand:<DWI> 6 "const_int_operand" "n"))
8057 (sign_extend:<DWI>
8058 (minus:SWI
8059 (minus:SWI
8060 (match_dup 1)
8061 (match_operator:SWI 5 "ix86_carry_flag_operator"
8062 [(match_dup 3) (const_int 0)]))
8063 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
8064 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
8065 (minus:SWI
8066 (minus:SWI
8067 (match_dup 1)
8068 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
8069 (match_dup 2)))]
8070 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
8071 && CONST_INT_P (operands[2])
8072 && INTVAL (operands[2]) == INTVAL (operands[6])"
8073 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8074 [(set_attr "type" "alu")
8075 (set_attr "mode" "<MODE>")
8076 (set (attr "length_immediate")
8077 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8078 (const_string "1")
8079 (const_string "4")))])
8080
8081 (define_expand "usubv<mode>4"
8082 [(parallel [(set (reg:CC FLAGS_REG)
8083 (compare:CC
8084 (match_operand:SWI 1 "nonimmediate_operand")
8085 (match_operand:SWI 2 "<general_operand>")))
8086 (set (match_operand:SWI 0 "register_operand")
8087 (minus:SWI (match_dup 1) (match_dup 2)))])
8088 (set (pc) (if_then_else
8089 (ltu (reg:CC FLAGS_REG) (const_int 0))
8090 (label_ref (match_operand 3))
8091 (pc)))]
8092 ""
8093 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
8094
8095 (define_insn "*sub<mode>_3"
8096 [(set (reg FLAGS_REG)
8097 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8098 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8099 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8100 (minus:SWI (match_dup 1) (match_dup 2)))]
8101 "ix86_match_ccmode (insn, CCmode)
8102 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8103 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
8104 [(set_attr "type" "alu")
8105 (set_attr "mode" "<MODE>")])
8106
8107 (define_peephole2
8108 [(parallel
8109 [(set (reg:CC FLAGS_REG)
8110 (compare:CC (match_operand:SWI 0 "general_reg_operand")
8111 (match_operand:SWI 1 "general_gr_operand")))
8112 (set (match_dup 0)
8113 (minus:SWI (match_dup 0) (match_dup 1)))])]
8114 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
8115 [(set (reg:CC FLAGS_REG)
8116 (compare:CC (match_dup 0) (match_dup 1)))])
8117
8118 (define_peephole2
8119 [(set (match_operand:SWI 0 "general_reg_operand")
8120 (match_operand:SWI 1 "memory_operand"))
8121 (parallel [(set (reg:CC FLAGS_REG)
8122 (compare:CC (match_dup 0)
8123 (match_operand:SWI 2 "memory_operand")))
8124 (set (match_dup 0)
8125 (minus:SWI (match_dup 0) (match_dup 2)))])
8126 (set (match_dup 1) (match_dup 0))]
8127 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8128 && peep2_reg_dead_p (3, operands[0])
8129 && !reg_overlap_mentioned_p (operands[0], operands[1])
8130 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8131 [(set (match_dup 0) (match_dup 2))
8132 (parallel [(set (reg:CC FLAGS_REG)
8133 (compare:CC (match_dup 1) (match_dup 0)))
8134 (set (match_dup 1)
8135 (minus:SWI (match_dup 1) (match_dup 0)))])])
8136
8137 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
8138 ;; subl $1, %eax; jnc .Lxx;
8139 (define_peephole2
8140 [(parallel
8141 [(set (match_operand:SWI 0 "general_reg_operand")
8142 (plus:SWI (match_dup 0) (const_int -1)))
8143 (clobber (reg FLAGS_REG))])
8144 (set (reg:CCZ FLAGS_REG)
8145 (compare:CCZ (match_dup 0) (const_int -1)))
8146 (set (pc)
8147 (if_then_else (match_operator 1 "bt_comparison_operator"
8148 [(reg:CCZ FLAGS_REG) (const_int 0)])
8149 (match_operand 2)
8150 (pc)))]
8151 "peep2_regno_dead_p (3, FLAGS_REG)"
8152 [(parallel
8153 [(set (reg:CC FLAGS_REG)
8154 (compare:CC (match_dup 0) (const_int 1)))
8155 (set (match_dup 0)
8156 (minus:SWI (match_dup 0) (const_int 1)))])
8157 (set (pc)
8158 (if_then_else (match_dup 3)
8159 (match_dup 2)
8160 (pc)))]
8161 {
8162 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
8163 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8164 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8165 })
8166
8167 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
8168 (define_insn_and_split "*dec_cmov<mode>"
8169 [(set (match_operand:SWI248 0 "register_operand" "=r")
8170 (if_then_else:SWI248
8171 (match_operator 1 "bt_comparison_operator"
8172 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
8173 (plus:SWI248 (match_dup 2) (const_int -1))
8174 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
8175 (clobber (reg:CC FLAGS_REG))]
8176 "TARGET_CMOVE"
8177 "#"
8178 "&& reload_completed"
8179 [(parallel [(set (reg:CC FLAGS_REG)
8180 (compare:CC (match_dup 2) (const_int 1)))
8181 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
8182 (set (match_dup 0)
8183 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
8184 {
8185 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
8186 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
8187 ? GEU : LTU, VOIDmode, cc, const0_rtx);
8188 })
8189
8190 (define_insn "*subsi_3_zext"
8191 [(set (reg FLAGS_REG)
8192 (compare (match_operand:SI 1 "register_operand" "0")
8193 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
8194 (set (match_operand:DI 0 "register_operand" "=r")
8195 (zero_extend:DI
8196 (minus:SI (match_dup 1)
8197 (match_dup 2))))]
8198 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8199 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8200 "sub{l}\t{%2, %1|%1, %2}"
8201 [(set_attr "type" "alu")
8202 (set_attr "mode" "SI")])
8203 \f
8204 ;; Add with carry and subtract with borrow
8205
8206 (define_insn "@add<mode>3_carry"
8207 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8208 (plus:SWI
8209 (plus:SWI
8210 (match_operator:SWI 4 "ix86_carry_flag_operator"
8211 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8212 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
8213 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8214 (clobber (reg:CC FLAGS_REG))]
8215 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8216 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8217 [(set_attr "type" "alu")
8218 (set_attr "use_carry" "1")
8219 (set_attr "pent_pair" "pu")
8220 (set_attr "mode" "<MODE>")])
8221
8222 (define_peephole2
8223 [(set (match_operand:SWI 0 "general_reg_operand")
8224 (match_operand:SWI 1 "memory_operand"))
8225 (parallel [(set (match_dup 0)
8226 (plus:SWI
8227 (plus:SWI
8228 (match_operator:SWI 4 "ix86_carry_flag_operator"
8229 [(match_operand 3 "flags_reg_operand")
8230 (const_int 0)])
8231 (match_dup 0))
8232 (match_operand:SWI 2 "memory_operand")))
8233 (clobber (reg:CC FLAGS_REG))])
8234 (set (match_dup 1) (match_dup 0))]
8235 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8236 && peep2_reg_dead_p (3, operands[0])
8237 && !reg_overlap_mentioned_p (operands[0], operands[1])
8238 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8239 [(set (match_dup 0) (match_dup 2))
8240 (parallel [(set (match_dup 1)
8241 (plus:SWI (plus:SWI (match_op_dup 4
8242 [(match_dup 3) (const_int 0)])
8243 (match_dup 1))
8244 (match_dup 0)))
8245 (clobber (reg:CC FLAGS_REG))])])
8246
8247 (define_peephole2
8248 [(set (match_operand:SWI 0 "general_reg_operand")
8249 (match_operand:SWI 1 "memory_operand"))
8250 (parallel [(set (match_dup 0)
8251 (plus:SWI
8252 (plus:SWI
8253 (match_operator:SWI 4 "ix86_carry_flag_operator"
8254 [(match_operand 3 "flags_reg_operand")
8255 (const_int 0)])
8256 (match_dup 0))
8257 (match_operand:SWI 2 "memory_operand")))
8258 (clobber (reg:CC FLAGS_REG))])
8259 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8260 (set (match_dup 1) (match_dup 5))]
8261 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8262 && peep2_reg_dead_p (3, operands[0])
8263 && peep2_reg_dead_p (4, operands[5])
8264 && !reg_overlap_mentioned_p (operands[0], operands[1])
8265 && !reg_overlap_mentioned_p (operands[0], operands[2])
8266 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8267 [(set (match_dup 0) (match_dup 2))
8268 (parallel [(set (match_dup 1)
8269 (plus:SWI (plus:SWI (match_op_dup 4
8270 [(match_dup 3) (const_int 0)])
8271 (match_dup 1))
8272 (match_dup 0)))
8273 (clobber (reg:CC FLAGS_REG))])])
8274
8275 (define_insn "*add<mode>3_carry_0"
8276 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8277 (plus:SWI
8278 (match_operator:SWI 2 "ix86_carry_flag_operator"
8279 [(reg FLAGS_REG) (const_int 0)])
8280 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8281 (clobber (reg:CC FLAGS_REG))]
8282 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8283 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8284 [(set_attr "type" "alu")
8285 (set_attr "use_carry" "1")
8286 (set_attr "pent_pair" "pu")
8287 (set_attr "mode" "<MODE>")])
8288
8289 (define_insn "*add<mode>3_carry_0r"
8290 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8291 (plus:SWI
8292 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8293 [(reg FLAGS_REG) (const_int 0)])
8294 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8297 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8298 [(set_attr "type" "alu")
8299 (set_attr "use_carry" "1")
8300 (set_attr "pent_pair" "pu")
8301 (set_attr "mode" "<MODE>")])
8302
8303 (define_insn "*addsi3_carry_zext"
8304 [(set (match_operand:DI 0 "register_operand" "=r")
8305 (zero_extend:DI
8306 (plus:SI
8307 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8308 [(reg FLAGS_REG) (const_int 0)])
8309 (match_operand:SI 1 "register_operand" "%0"))
8310 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8311 (clobber (reg:CC FLAGS_REG))]
8312 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8313 "adc{l}\t{%2, %k0|%k0, %2}"
8314 [(set_attr "type" "alu")
8315 (set_attr "use_carry" "1")
8316 (set_attr "pent_pair" "pu")
8317 (set_attr "mode" "SI")])
8318
8319 (define_insn "*addsi3_carry_zext_0"
8320 [(set (match_operand:DI 0 "register_operand" "=r")
8321 (zero_extend:DI
8322 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8323 [(reg FLAGS_REG) (const_int 0)])
8324 (match_operand:SI 1 "register_operand" "0"))))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "TARGET_64BIT"
8327 "adc{l}\t{$0, %k0|%k0, 0}"
8328 [(set_attr "type" "alu")
8329 (set_attr "use_carry" "1")
8330 (set_attr "pent_pair" "pu")
8331 (set_attr "mode" "SI")])
8332
8333 (define_insn "*addsi3_carry_zext_0r"
8334 [(set (match_operand:DI 0 "register_operand" "=r")
8335 (zero_extend:DI
8336 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8337 [(reg FLAGS_REG) (const_int 0)])
8338 (match_operand:SI 1 "register_operand" "0"))))
8339 (clobber (reg:CC FLAGS_REG))]
8340 "TARGET_64BIT"
8341 "sbb{l}\t{$-1, %k0|%k0, -1}"
8342 [(set_attr "type" "alu")
8343 (set_attr "use_carry" "1")
8344 (set_attr "pent_pair" "pu")
8345 (set_attr "mode" "SI")])
8346
8347 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8348
8349 (define_insn "addcarry<mode>"
8350 [(set (reg:CCC FLAGS_REG)
8351 (compare:CCC
8352 (zero_extend:<DWI>
8353 (plus:SWI48
8354 (plus:SWI48
8355 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8356 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8357 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8358 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8359 (plus:<DWI>
8360 (zero_extend:<DWI> (match_dup 2))
8361 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8362 [(match_dup 3) (const_int 0)]))))
8363 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8364 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8365 [(match_dup 3) (const_int 0)])
8366 (match_dup 1))
8367 (match_dup 2)))]
8368 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8369 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8370 [(set_attr "type" "alu")
8371 (set_attr "use_carry" "1")
8372 (set_attr "pent_pair" "pu")
8373 (set_attr "mode" "<MODE>")])
8374
8375 (define_peephole2
8376 [(parallel [(set (reg:CCC FLAGS_REG)
8377 (compare:CCC
8378 (zero_extend:<DWI>
8379 (plus:SWI48
8380 (plus:SWI48
8381 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8382 [(match_operand 2 "flags_reg_operand")
8383 (const_int 0)])
8384 (match_operand:SWI48 0 "general_reg_operand"))
8385 (match_operand:SWI48 1 "memory_operand")))
8386 (plus:<DWI>
8387 (zero_extend:<DWI> (match_dup 1))
8388 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8389 [(match_dup 2) (const_int 0)]))))
8390 (set (match_dup 0)
8391 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8392 [(match_dup 2) (const_int 0)])
8393 (match_dup 0))
8394 (match_dup 1)))])
8395 (set (match_dup 1) (match_dup 0))]
8396 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8397 && peep2_reg_dead_p (2, operands[0])
8398 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8399 [(parallel [(set (reg:CCC FLAGS_REG)
8400 (compare:CCC
8401 (zero_extend:<DWI>
8402 (plus:SWI48
8403 (plus:SWI48
8404 (match_op_dup 4
8405 [(match_dup 2) (const_int 0)])
8406 (match_dup 1))
8407 (match_dup 0)))
8408 (plus:<DWI>
8409 (zero_extend:<DWI> (match_dup 0))
8410 (match_op_dup 3
8411 [(match_dup 2) (const_int 0)]))))
8412 (set (match_dup 1)
8413 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8414 [(match_dup 2) (const_int 0)])
8415 (match_dup 1))
8416 (match_dup 0)))])])
8417
8418 (define_peephole2
8419 [(set (match_operand:SWI48 0 "general_reg_operand")
8420 (match_operand:SWI48 1 "memory_operand"))
8421 (parallel [(set (reg:CCC FLAGS_REG)
8422 (compare:CCC
8423 (zero_extend:<DWI>
8424 (plus:SWI48
8425 (plus:SWI48
8426 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8427 [(match_operand 3 "flags_reg_operand")
8428 (const_int 0)])
8429 (match_dup 0))
8430 (match_operand:SWI48 2 "memory_operand")))
8431 (plus:<DWI>
8432 (zero_extend:<DWI> (match_dup 2))
8433 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8434 [(match_dup 3) (const_int 0)]))))
8435 (set (match_dup 0)
8436 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8437 [(match_dup 3) (const_int 0)])
8438 (match_dup 0))
8439 (match_dup 2)))])
8440 (set (match_dup 1) (match_dup 0))]
8441 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8442 && peep2_reg_dead_p (3, operands[0])
8443 && !reg_overlap_mentioned_p (operands[0], operands[1])
8444 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8445 [(set (match_dup 0) (match_dup 2))
8446 (parallel [(set (reg:CCC FLAGS_REG)
8447 (compare:CCC
8448 (zero_extend:<DWI>
8449 (plus:SWI48
8450 (plus:SWI48
8451 (match_op_dup 5
8452 [(match_dup 3) (const_int 0)])
8453 (match_dup 1))
8454 (match_dup 0)))
8455 (plus:<DWI>
8456 (zero_extend:<DWI> (match_dup 0))
8457 (match_op_dup 4
8458 [(match_dup 3) (const_int 0)]))))
8459 (set (match_dup 1)
8460 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8461 [(match_dup 3) (const_int 0)])
8462 (match_dup 1))
8463 (match_dup 0)))])])
8464
8465 (define_peephole2
8466 [(parallel [(set (reg:CCC FLAGS_REG)
8467 (compare:CCC
8468 (zero_extend:<DWI>
8469 (plus:SWI48
8470 (plus:SWI48
8471 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8472 [(match_operand 2 "flags_reg_operand")
8473 (const_int 0)])
8474 (match_operand:SWI48 0 "general_reg_operand"))
8475 (match_operand:SWI48 1 "memory_operand")))
8476 (plus:<DWI>
8477 (zero_extend:<DWI> (match_dup 1))
8478 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8479 [(match_dup 2) (const_int 0)]))))
8480 (set (match_dup 0)
8481 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8482 [(match_dup 2) (const_int 0)])
8483 (match_dup 0))
8484 (match_dup 1)))])
8485 (set (match_operand:QI 5 "general_reg_operand")
8486 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8487 (set (match_operand:SWI48 6 "general_reg_operand")
8488 (zero_extend:SWI48 (match_dup 5)))
8489 (set (match_dup 1) (match_dup 0))]
8490 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8491 && peep2_reg_dead_p (4, operands[0])
8492 && !reg_overlap_mentioned_p (operands[0], operands[1])
8493 && !reg_overlap_mentioned_p (operands[0], operands[5])
8494 && !reg_overlap_mentioned_p (operands[5], operands[1])
8495 && !reg_overlap_mentioned_p (operands[0], operands[6])
8496 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8497 [(parallel [(set (reg:CCC FLAGS_REG)
8498 (compare:CCC
8499 (zero_extend:<DWI>
8500 (plus:SWI48
8501 (plus:SWI48
8502 (match_op_dup 4
8503 [(match_dup 2) (const_int 0)])
8504 (match_dup 1))
8505 (match_dup 0)))
8506 (plus:<DWI>
8507 (zero_extend:<DWI> (match_dup 0))
8508 (match_op_dup 3
8509 [(match_dup 2) (const_int 0)]))))
8510 (set (match_dup 1)
8511 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8512 [(match_dup 2) (const_int 0)])
8513 (match_dup 1))
8514 (match_dup 0)))])
8515 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8516 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8517
8518 (define_expand "addcarry<mode>_0"
8519 [(parallel
8520 [(set (reg:CCC FLAGS_REG)
8521 (compare:CCC
8522 (plus:SWI48
8523 (match_operand:SWI48 1 "nonimmediate_operand")
8524 (match_operand:SWI48 2 "x86_64_general_operand"))
8525 (match_dup 1)))
8526 (set (match_operand:SWI48 0 "nonimmediate_operand")
8527 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8528 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8529
8530 (define_insn "*addcarry<mode>_1"
8531 [(set (reg:CCC FLAGS_REG)
8532 (compare:CCC
8533 (zero_extend:<DWI>
8534 (plus:SWI48
8535 (plus:SWI48
8536 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8537 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8538 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8539 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8540 (plus:<DWI>
8541 (match_operand:<DWI> 6 "const_scalar_int_operand")
8542 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8543 [(match_dup 3) (const_int 0)]))))
8544 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8545 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8546 [(match_dup 3) (const_int 0)])
8547 (match_dup 1))
8548 (match_dup 2)))]
8549 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8550 && CONST_INT_P (operands[2])
8551 /* Check that operands[6] is operands[2] zero extended from
8552 <MODE>mode to <DWI>mode. */
8553 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8554 ? (CONST_INT_P (operands[6])
8555 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8556 & GET_MODE_MASK (<MODE>mode)))
8557 : (CONST_WIDE_INT_P (operands[6])
8558 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8559 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8560 == UINTVAL (operands[2]))
8561 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8562 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8563 [(set_attr "type" "alu")
8564 (set_attr "use_carry" "1")
8565 (set_attr "pent_pair" "pu")
8566 (set_attr "mode" "<MODE>")
8567 (set (attr "length_immediate")
8568 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8569 (const_string "1")
8570 (const_string "4")))])
8571
8572 (define_insn "@sub<mode>3_carry"
8573 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8574 (minus:SWI
8575 (minus:SWI
8576 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8577 (match_operator:SWI 4 "ix86_carry_flag_operator"
8578 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8579 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8582 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8583 [(set_attr "type" "alu")
8584 (set_attr "use_carry" "1")
8585 (set_attr "pent_pair" "pu")
8586 (set_attr "mode" "<MODE>")])
8587
8588 (define_peephole2
8589 [(set (match_operand:SWI 0 "general_reg_operand")
8590 (match_operand:SWI 1 "memory_operand"))
8591 (parallel [(set (match_dup 0)
8592 (minus:SWI
8593 (minus:SWI
8594 (match_dup 0)
8595 (match_operator:SWI 4 "ix86_carry_flag_operator"
8596 [(match_operand 3 "flags_reg_operand")
8597 (const_int 0)]))
8598 (match_operand:SWI 2 "memory_operand")))
8599 (clobber (reg:CC FLAGS_REG))])
8600 (set (match_dup 1) (match_dup 0))]
8601 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8602 && peep2_reg_dead_p (3, operands[0])
8603 && !reg_overlap_mentioned_p (operands[0], operands[1])
8604 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8605 [(set (match_dup 0) (match_dup 2))
8606 (parallel [(set (match_dup 1)
8607 (minus:SWI (minus:SWI (match_dup 1)
8608 (match_op_dup 4
8609 [(match_dup 3) (const_int 0)]))
8610 (match_dup 0)))
8611 (clobber (reg:CC FLAGS_REG))])])
8612
8613 (define_peephole2
8614 [(set (match_operand:SWI 0 "general_reg_operand")
8615 (match_operand:SWI 1 "memory_operand"))
8616 (parallel [(set (match_dup 0)
8617 (minus:SWI
8618 (minus:SWI
8619 (match_dup 0)
8620 (match_operator:SWI 4 "ix86_carry_flag_operator"
8621 [(match_operand 3 "flags_reg_operand")
8622 (const_int 0)]))
8623 (match_operand:SWI 2 "memory_operand")))
8624 (clobber (reg:CC FLAGS_REG))])
8625 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8626 (set (match_dup 1) (match_dup 5))]
8627 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8628 && peep2_reg_dead_p (3, operands[0])
8629 && peep2_reg_dead_p (4, operands[5])
8630 && !reg_overlap_mentioned_p (operands[0], operands[1])
8631 && !reg_overlap_mentioned_p (operands[0], operands[2])
8632 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8633 [(set (match_dup 0) (match_dup 2))
8634 (parallel [(set (match_dup 1)
8635 (minus:SWI (minus:SWI (match_dup 1)
8636 (match_op_dup 4
8637 [(match_dup 3) (const_int 0)]))
8638 (match_dup 0)))
8639 (clobber (reg:CC FLAGS_REG))])])
8640
8641 (define_insn "*sub<mode>3_carry_0"
8642 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8643 (minus:SWI
8644 (match_operand:SWI 1 "nonimmediate_operand" "0")
8645 (match_operator:SWI 2 "ix86_carry_flag_operator"
8646 [(reg FLAGS_REG) (const_int 0)])))
8647 (clobber (reg:CC FLAGS_REG))]
8648 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8649 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8650 [(set_attr "type" "alu")
8651 (set_attr "use_carry" "1")
8652 (set_attr "pent_pair" "pu")
8653 (set_attr "mode" "<MODE>")])
8654
8655 (define_insn "*sub<mode>3_carry_0r"
8656 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8657 (minus:SWI
8658 (match_operand:SWI 1 "nonimmediate_operand" "0")
8659 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8660 [(reg FLAGS_REG) (const_int 0)])))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8663 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8664 [(set_attr "type" "alu")
8665 (set_attr "use_carry" "1")
8666 (set_attr "pent_pair" "pu")
8667 (set_attr "mode" "<MODE>")])
8668
8669 (define_insn "*subsi3_carry_zext"
8670 [(set (match_operand:DI 0 "register_operand" "=r")
8671 (zero_extend:DI
8672 (minus:SI
8673 (minus:SI
8674 (match_operand:SI 1 "register_operand" "0")
8675 (match_operator:SI 3 "ix86_carry_flag_operator"
8676 [(reg FLAGS_REG) (const_int 0)]))
8677 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8678 (clobber (reg:CC FLAGS_REG))]
8679 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8680 "sbb{l}\t{%2, %k0|%k0, %2}"
8681 [(set_attr "type" "alu")
8682 (set_attr "use_carry" "1")
8683 (set_attr "pent_pair" "pu")
8684 (set_attr "mode" "SI")])
8685
8686 (define_insn "*subsi3_carry_zext_0"
8687 [(set (match_operand:DI 0 "register_operand" "=r")
8688 (zero_extend:DI
8689 (minus:SI
8690 (match_operand:SI 1 "register_operand" "0")
8691 (match_operator:SI 2 "ix86_carry_flag_operator"
8692 [(reg FLAGS_REG) (const_int 0)]))))
8693 (clobber (reg:CC FLAGS_REG))]
8694 "TARGET_64BIT"
8695 "sbb{l}\t{$0, %k0|%k0, 0}"
8696 [(set_attr "type" "alu")
8697 (set_attr "use_carry" "1")
8698 (set_attr "pent_pair" "pu")
8699 (set_attr "mode" "SI")])
8700
8701 (define_insn "*subsi3_carry_zext_0r"
8702 [(set (match_operand:DI 0 "register_operand" "=r")
8703 (zero_extend:DI
8704 (minus:SI
8705 (match_operand:SI 1 "register_operand" "0")
8706 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8707 [(reg FLAGS_REG) (const_int 0)]))))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "TARGET_64BIT"
8710 "adc{l}\t{$-1, %k0|%k0, -1}"
8711 [(set_attr "type" "alu")
8712 (set_attr "use_carry" "1")
8713 (set_attr "pent_pair" "pu")
8714 (set_attr "mode" "SI")])
8715
8716 (define_insn "@sub<mode>3_carry_ccc"
8717 [(set (reg:CCC FLAGS_REG)
8718 (compare:CCC
8719 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8720 (plus:<DWI>
8721 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8722 (zero_extend:<DWI>
8723 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8724 (clobber (match_scratch:DWIH 0 "=r"))]
8725 ""
8726 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8727 [(set_attr "type" "alu")
8728 (set_attr "mode" "<MODE>")])
8729
8730 (define_insn "*sub<mode>3_carry_ccc_1"
8731 [(set (reg:CCC FLAGS_REG)
8732 (compare:CCC
8733 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8734 (plus:<DWI>
8735 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8736 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8737 (clobber (match_scratch:DWIH 0 "=r"))]
8738 ""
8739 {
8740 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8741 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8742 }
8743 [(set_attr "type" "alu")
8744 (set_attr "mode" "<MODE>")])
8745
8746 ;; The sign flag is set from the
8747 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8748 ;; result, the overflow flag likewise, but the overflow flag is also
8749 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8750 (define_insn "@sub<mode>3_carry_ccgz"
8751 [(set (reg:CCGZ FLAGS_REG)
8752 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8753 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8754 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8755 UNSPEC_SBB))
8756 (clobber (match_scratch:DWIH 0 "=r"))]
8757 ""
8758 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8759 [(set_attr "type" "alu")
8760 (set_attr "mode" "<MODE>")])
8761
8762 (define_insn "subborrow<mode>"
8763 [(set (reg:CCC FLAGS_REG)
8764 (compare:CCC
8765 (zero_extend:<DWI>
8766 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8767 (plus:<DWI>
8768 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8769 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8770 (zero_extend:<DWI>
8771 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8772 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8773 (minus:SWI48 (minus:SWI48
8774 (match_dup 1)
8775 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8776 [(match_dup 3) (const_int 0)]))
8777 (match_dup 2)))]
8778 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8779 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "use_carry" "1")
8782 (set_attr "pent_pair" "pu")
8783 (set_attr "mode" "<MODE>")])
8784
8785 (define_peephole2
8786 [(set (match_operand:SWI48 0 "general_reg_operand")
8787 (match_operand:SWI48 1 "memory_operand"))
8788 (parallel [(set (reg:CCC FLAGS_REG)
8789 (compare:CCC
8790 (zero_extend:<DWI> (match_dup 0))
8791 (plus:<DWI>
8792 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8793 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8794 (zero_extend:<DWI>
8795 (match_operand:SWI48 2 "memory_operand")))))
8796 (set (match_dup 0)
8797 (minus:SWI48
8798 (minus:SWI48
8799 (match_dup 0)
8800 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8801 [(match_dup 3) (const_int 0)]))
8802 (match_dup 2)))])
8803 (set (match_dup 1) (match_dup 0))]
8804 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8805 && peep2_reg_dead_p (3, operands[0])
8806 && !reg_overlap_mentioned_p (operands[0], operands[1])
8807 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8808 [(set (match_dup 0) (match_dup 2))
8809 (parallel [(set (reg:CCC FLAGS_REG)
8810 (compare:CCC
8811 (zero_extend:<DWI> (match_dup 1))
8812 (plus:<DWI> (match_op_dup 4
8813 [(match_dup 3) (const_int 0)])
8814 (zero_extend:<DWI> (match_dup 0)))))
8815 (set (match_dup 1)
8816 (minus:SWI48 (minus:SWI48 (match_dup 1)
8817 (match_op_dup 5
8818 [(match_dup 3) (const_int 0)]))
8819 (match_dup 0)))])])
8820
8821 (define_peephole2
8822 [(set (match_operand:SWI48 6 "general_reg_operand")
8823 (match_operand:SWI48 7 "memory_operand"))
8824 (set (match_operand:SWI48 8 "general_reg_operand")
8825 (match_operand:SWI48 9 "memory_operand"))
8826 (parallel [(set (reg:CCC FLAGS_REG)
8827 (compare:CCC
8828 (zero_extend:<DWI>
8829 (match_operand:SWI48 0 "general_reg_operand"))
8830 (plus:<DWI>
8831 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8832 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8833 (zero_extend:<DWI>
8834 (match_operand:SWI48 2 "general_reg_operand")))))
8835 (set (match_dup 0)
8836 (minus:SWI48
8837 (minus:SWI48
8838 (match_dup 0)
8839 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8840 [(match_dup 3) (const_int 0)]))
8841 (match_dup 2)))])
8842 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8843 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8844 && peep2_reg_dead_p (4, operands[0])
8845 && peep2_reg_dead_p (3, operands[2])
8846 && !reg_overlap_mentioned_p (operands[0], operands[1])
8847 && !reg_overlap_mentioned_p (operands[2], operands[1])
8848 && !reg_overlap_mentioned_p (operands[6], operands[9])
8849 && (rtx_equal_p (operands[6], operands[0])
8850 ? (rtx_equal_p (operands[7], operands[1])
8851 && rtx_equal_p (operands[8], operands[2]))
8852 : (rtx_equal_p (operands[8], operands[0])
8853 && rtx_equal_p (operands[9], operands[1])
8854 && rtx_equal_p (operands[6], operands[2])))"
8855 [(set (match_dup 0) (match_dup 9))
8856 (parallel [(set (reg:CCC FLAGS_REG)
8857 (compare:CCC
8858 (zero_extend:<DWI> (match_dup 1))
8859 (plus:<DWI> (match_op_dup 4
8860 [(match_dup 3) (const_int 0)])
8861 (zero_extend:<DWI> (match_dup 0)))))
8862 (set (match_dup 1)
8863 (minus:SWI48 (minus:SWI48 (match_dup 1)
8864 (match_op_dup 5
8865 [(match_dup 3) (const_int 0)]))
8866 (match_dup 0)))])]
8867 {
8868 if (!rtx_equal_p (operands[6], operands[0]))
8869 operands[9] = operands[7];
8870 })
8871
8872 (define_peephole2
8873 [(set (match_operand:SWI48 6 "general_reg_operand")
8874 (match_operand:SWI48 7 "memory_operand"))
8875 (set (match_operand:SWI48 8 "general_reg_operand")
8876 (match_operand:SWI48 9 "memory_operand"))
8877 (parallel [(set (reg:CCC FLAGS_REG)
8878 (compare:CCC
8879 (zero_extend:<DWI>
8880 (match_operand:SWI48 0 "general_reg_operand"))
8881 (plus:<DWI>
8882 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8883 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8884 (zero_extend:<DWI>
8885 (match_operand:SWI48 2 "general_reg_operand")))))
8886 (set (match_dup 0)
8887 (minus:SWI48
8888 (minus:SWI48
8889 (match_dup 0)
8890 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8891 [(match_dup 3) (const_int 0)]))
8892 (match_dup 2)))])
8893 (set (match_operand:QI 10 "general_reg_operand")
8894 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8895 (set (match_operand:SWI48 11 "general_reg_operand")
8896 (zero_extend:SWI48 (match_dup 10)))
8897 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8898 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8899 && peep2_reg_dead_p (6, operands[0])
8900 && peep2_reg_dead_p (3, operands[2])
8901 && !reg_overlap_mentioned_p (operands[0], operands[1])
8902 && !reg_overlap_mentioned_p (operands[2], operands[1])
8903 && !reg_overlap_mentioned_p (operands[6], operands[9])
8904 && !reg_overlap_mentioned_p (operands[0], operands[10])
8905 && !reg_overlap_mentioned_p (operands[10], operands[1])
8906 && !reg_overlap_mentioned_p (operands[0], operands[11])
8907 && !reg_overlap_mentioned_p (operands[11], operands[1])
8908 && (rtx_equal_p (operands[6], operands[0])
8909 ? (rtx_equal_p (operands[7], operands[1])
8910 && rtx_equal_p (operands[8], operands[2]))
8911 : (rtx_equal_p (operands[8], operands[0])
8912 && rtx_equal_p (operands[9], operands[1])
8913 && rtx_equal_p (operands[6], operands[2])))"
8914 [(set (match_dup 0) (match_dup 9))
8915 (parallel [(set (reg:CCC FLAGS_REG)
8916 (compare:CCC
8917 (zero_extend:<DWI> (match_dup 1))
8918 (plus:<DWI> (match_op_dup 4
8919 [(match_dup 3) (const_int 0)])
8920 (zero_extend:<DWI> (match_dup 0)))))
8921 (set (match_dup 1)
8922 (minus:SWI48 (minus:SWI48 (match_dup 1)
8923 (match_op_dup 5
8924 [(match_dup 3) (const_int 0)]))
8925 (match_dup 0)))])
8926 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8927 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8928 {
8929 if (!rtx_equal_p (operands[6], operands[0]))
8930 operands[9] = operands[7];
8931 })
8932
8933 (define_expand "subborrow<mode>_0"
8934 [(parallel
8935 [(set (reg:CC FLAGS_REG)
8936 (compare:CC
8937 (match_operand:SWI48 1 "nonimmediate_operand")
8938 (match_operand:SWI48 2 "<general_operand>")))
8939 (set (match_operand:SWI48 0 "register_operand")
8940 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8941 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8942
8943 (define_expand "uaddc<mode>5"
8944 [(match_operand:SWI48 0 "register_operand")
8945 (match_operand:SWI48 1 "register_operand")
8946 (match_operand:SWI48 2 "register_operand")
8947 (match_operand:SWI48 3 "register_operand")
8948 (match_operand:SWI48 4 "nonmemory_operand")]
8949 ""
8950 {
8951 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8952 if (operands[4] == const0_rtx)
8953 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8954 else
8955 {
8956 ix86_expand_carry (operands[4]);
8957 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8958 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8959 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8960 cf, pat, pat2));
8961 }
8962 rtx cc = gen_reg_rtx (QImode);
8963 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8964 emit_insn (gen_rtx_SET (cc, pat));
8965 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8966 DONE;
8967 })
8968
8969 (define_expand "usubc<mode>5"
8970 [(match_operand:SWI48 0 "register_operand")
8971 (match_operand:SWI48 1 "register_operand")
8972 (match_operand:SWI48 2 "register_operand")
8973 (match_operand:SWI48 3 "register_operand")
8974 (match_operand:SWI48 4 "nonmemory_operand")]
8975 ""
8976 {
8977 rtx cf, pat, pat2;
8978 if (operands[4] == const0_rtx)
8979 {
8980 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8981 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8982 operands[3]));
8983 }
8984 else
8985 {
8986 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8987 ix86_expand_carry (operands[4]);
8988 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8989 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8990 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8991 cf, pat, pat2));
8992 }
8993 rtx cc = gen_reg_rtx (QImode);
8994 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8995 emit_insn (gen_rtx_SET (cc, pat));
8996 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8997 DONE;
8998 })
8999
9000 (define_mode_iterator CC_CCC [CC CCC])
9001
9002 ;; Pre-reload splitter to optimize
9003 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
9004 ;; operand and no intervening flags modifications into nothing.
9005 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
9006 [(set (reg:CCC FLAGS_REG)
9007 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
9008 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
9009 "ix86_pre_reload_split ()"
9010 "#"
9011 "&& 1"
9012 [(const_int 0)]
9013 "emit_note (NOTE_INSN_DELETED); DONE;")
9014
9015 ;; Set the carry flag from the carry flag.
9016 (define_insn_and_split "*setccc"
9017 [(set (reg:CCC FLAGS_REG)
9018 (reg:CCC FLAGS_REG))]
9019 "ix86_pre_reload_split ()"
9020 "#"
9021 "&& 1"
9022 [(const_int 0)]
9023 "emit_note (NOTE_INSN_DELETED); DONE;")
9024
9025 ;; Set the carry flag from the carry flag.
9026 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
9027 [(set (reg:CCC FLAGS_REG)
9028 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
9029 "ix86_pre_reload_split ()"
9030 "#"
9031 "&& 1"
9032 [(const_int 0)]
9033 "emit_note (NOTE_INSN_DELETED); DONE;")
9034
9035 ;; Set the carry flag from the carry flag.
9036 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
9037 [(set (reg:CCC FLAGS_REG)
9038 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
9039 (const_int 0)] UNSPEC_CC_NE))]
9040 "ix86_pre_reload_split ()"
9041 "#"
9042 "&& 1"
9043 [(const_int 0)]
9044 "emit_note (NOTE_INSN_DELETED); DONE;")
9045 \f
9046 ;; Overflow setting add instructions
9047
9048 (define_expand "addqi3_cconly_overflow"
9049 [(parallel
9050 [(set (reg:CCC FLAGS_REG)
9051 (compare:CCC
9052 (plus:QI
9053 (match_operand:QI 0 "nonimmediate_operand")
9054 (match_operand:QI 1 "general_operand"))
9055 (match_dup 0)))
9056 (clobber (scratch:QI))])]
9057 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
9058
9059 (define_insn "*add<mode>3_cconly_overflow_1"
9060 [(set (reg:CCC FLAGS_REG)
9061 (compare:CCC
9062 (plus:SWI
9063 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9064 (match_operand:SWI 2 "<general_operand>" "<g>"))
9065 (match_dup 1)))
9066 (clobber (match_scratch:SWI 0 "=<r>"))]
9067 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9068 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "mode" "<MODE>")])
9071
9072 (define_insn "@add<mode>3_cc_overflow_1"
9073 [(set (reg:CCC FLAGS_REG)
9074 (compare:CCC
9075 (plus:SWI
9076 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9077 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9078 (match_dup 1)))
9079 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9080 (plus:SWI (match_dup 1) (match_dup 2)))]
9081 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9082 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9083 [(set_attr "type" "alu")
9084 (set_attr "mode" "<MODE>")])
9085
9086 (define_peephole2
9087 [(parallel [(set (reg:CCC FLAGS_REG)
9088 (compare:CCC
9089 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
9090 (match_operand:SWI 1 "memory_operand"))
9091 (match_dup 0)))
9092 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
9093 (set (match_dup 1) (match_dup 0))]
9094 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9095 && peep2_reg_dead_p (2, operands[0])
9096 && !reg_overlap_mentioned_p (operands[0], operands[1])"
9097 [(parallel [(set (reg:CCC FLAGS_REG)
9098 (compare:CCC
9099 (plus:SWI (match_dup 1) (match_dup 0))
9100 (match_dup 1)))
9101 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9102
9103 (define_peephole2
9104 [(set (match_operand:SWI 0 "general_reg_operand")
9105 (match_operand:SWI 1 "memory_operand"))
9106 (parallel [(set (reg:CCC FLAGS_REG)
9107 (compare:CCC
9108 (plus:SWI (match_dup 0)
9109 (match_operand:SWI 2 "memory_operand"))
9110 (match_dup 0)))
9111 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
9112 (set (match_dup 1) (match_dup 0))]
9113 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
9114 && peep2_reg_dead_p (3, operands[0])
9115 && !reg_overlap_mentioned_p (operands[0], operands[1])
9116 && !reg_overlap_mentioned_p (operands[0], operands[2])"
9117 [(set (match_dup 0) (match_dup 2))
9118 (parallel [(set (reg:CCC FLAGS_REG)
9119 (compare:CCC
9120 (plus:SWI (match_dup 1) (match_dup 0))
9121 (match_dup 1)))
9122 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
9123
9124 (define_insn "*addsi3_zext_cc_overflow_1"
9125 [(set (reg:CCC FLAGS_REG)
9126 (compare:CCC
9127 (plus:SI
9128 (match_operand:SI 1 "nonimmediate_operand" "%0")
9129 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9130 (match_dup 1)))
9131 (set (match_operand:DI 0 "register_operand" "=r")
9132 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9133 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9134 "add{l}\t{%2, %k0|%k0, %2}"
9135 [(set_attr "type" "alu")
9136 (set_attr "mode" "SI")])
9137
9138 (define_insn "*add<mode>3_cconly_overflow_2"
9139 [(set (reg:CCC FLAGS_REG)
9140 (compare:CCC
9141 (plus:SWI
9142 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9143 (match_operand:SWI 2 "<general_operand>" "<g>"))
9144 (match_dup 2)))
9145 (clobber (match_scratch:SWI 0 "=<r>"))]
9146 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9147 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9148 [(set_attr "type" "alu")
9149 (set_attr "mode" "<MODE>")])
9150
9151 (define_insn "*add<mode>3_cc_overflow_2"
9152 [(set (reg:CCC FLAGS_REG)
9153 (compare:CCC
9154 (plus:SWI
9155 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9156 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
9157 (match_dup 2)))
9158 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9159 (plus:SWI (match_dup 1) (match_dup 2)))]
9160 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
9161 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
9162 [(set_attr "type" "alu")
9163 (set_attr "mode" "<MODE>")])
9164
9165 (define_insn "*addsi3_zext_cc_overflow_2"
9166 [(set (reg:CCC FLAGS_REG)
9167 (compare:CCC
9168 (plus:SI
9169 (match_operand:SI 1 "nonimmediate_operand" "%0")
9170 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
9171 (match_dup 2)))
9172 (set (match_operand:DI 0 "register_operand" "=r")
9173 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9174 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
9175 "add{l}\t{%2, %k0|%k0, %2}"
9176 [(set_attr "type" "alu")
9177 (set_attr "mode" "SI")])
9178
9179 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
9180 [(set (reg:CCC FLAGS_REG)
9181 (compare:CCC
9182 (plus:<DWI>
9183 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
9184 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
9185 (match_dup 1)))
9186 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
9187 (plus:<DWI> (match_dup 1) (match_dup 2)))]
9188 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
9189 "#"
9190 "&& reload_completed"
9191 [(parallel [(set (reg:CCC FLAGS_REG)
9192 (compare:CCC
9193 (plus:DWIH (match_dup 1) (match_dup 2))
9194 (match_dup 1)))
9195 (set (match_dup 0)
9196 (plus:DWIH (match_dup 1) (match_dup 2)))])
9197 (parallel [(set (reg:CCC FLAGS_REG)
9198 (compare:CCC
9199 (zero_extend:<DWI>
9200 (plus:DWIH
9201 (plus:DWIH
9202 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9203 (match_dup 4))
9204 (match_dup 5)))
9205 (plus:<DWI>
9206 (match_dup 6)
9207 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
9208 (set (match_dup 3)
9209 (plus:DWIH
9210 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9211 (match_dup 4))
9212 (match_dup 5)))])]
9213 {
9214 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
9215 if (operands[2] == const0_rtx)
9216 {
9217 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
9218 DONE;
9219 }
9220 if (CONST_INT_P (operands[5]))
9221 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
9222 operands[5], <MODE>mode);
9223 else
9224 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
9225 })
9226
9227 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9228 ;; test, where the latter is preferrable if we have some carry consuming
9229 ;; instruction.
9230 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9231 ;; + (1 - CF).
9232 (define_insn_and_split "*add<mode>3_eq"
9233 [(set (match_operand:SWI 0 "nonimmediate_operand")
9234 (plus:SWI
9235 (plus:SWI
9236 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9237 (match_operand:SWI 1 "nonimmediate_operand"))
9238 (match_operand:SWI 2 "<general_operand>")))
9239 (clobber (reg:CC FLAGS_REG))]
9240 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9241 && ix86_pre_reload_split ()"
9242 "#"
9243 "&& 1"
9244 [(set (reg:CC FLAGS_REG)
9245 (compare:CC (match_dup 3) (const_int 1)))
9246 (parallel [(set (match_dup 0)
9247 (plus:SWI
9248 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9249 (match_dup 1))
9250 (match_dup 2)))
9251 (clobber (reg:CC FLAGS_REG))])])
9252
9253 (define_insn_and_split "*add<mode>3_ne"
9254 [(set (match_operand:SWI 0 "nonimmediate_operand")
9255 (plus:SWI
9256 (plus:SWI
9257 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9258 (match_operand:SWI 1 "nonimmediate_operand"))
9259 (match_operand:SWI 2 "<immediate_operand>")))
9260 (clobber (reg:CC FLAGS_REG))]
9261 "CONST_INT_P (operands[2])
9262 && (<MODE>mode != DImode
9263 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9264 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9265 && ix86_pre_reload_split ()"
9266 "#"
9267 "&& 1"
9268 [(set (reg:CC FLAGS_REG)
9269 (compare:CC (match_dup 3) (const_int 1)))
9270 (parallel [(set (match_dup 0)
9271 (minus:SWI
9272 (minus:SWI (match_dup 1)
9273 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9274 (match_dup 2)))
9275 (clobber (reg:CC FLAGS_REG))])]
9276 {
9277 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9278 <MODE>mode == DImode ? SImode : <MODE>mode);
9279 })
9280
9281 (define_insn_and_split "*add<mode>3_eq_0"
9282 [(set (match_operand:SWI 0 "nonimmediate_operand")
9283 (plus:SWI
9284 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9285 (match_operand:SWI 1 "<general_operand>")))
9286 (clobber (reg:CC FLAGS_REG))]
9287 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9288 && ix86_pre_reload_split ()"
9289 "#"
9290 "&& 1"
9291 [(set (reg:CC FLAGS_REG)
9292 (compare:CC (match_dup 2) (const_int 1)))
9293 (parallel [(set (match_dup 0)
9294 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9295 (match_dup 1)))
9296 (clobber (reg:CC FLAGS_REG))])]
9297 {
9298 if (!nonimmediate_operand (operands[1], <MODE>mode))
9299 operands[1] = force_reg (<MODE>mode, operands[1]);
9300 })
9301
9302 (define_insn_and_split "*add<mode>3_ne_0"
9303 [(set (match_operand:SWI 0 "nonimmediate_operand")
9304 (plus:SWI
9305 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9306 (match_operand:SWI 1 "<general_operand>")))
9307 (clobber (reg:CC FLAGS_REG))]
9308 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9309 && ix86_pre_reload_split ()"
9310 "#"
9311 "&& 1"
9312 [(set (reg:CC FLAGS_REG)
9313 (compare:CC (match_dup 2) (const_int 1)))
9314 (parallel [(set (match_dup 0)
9315 (minus:SWI (minus:SWI
9316 (match_dup 1)
9317 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9318 (const_int -1)))
9319 (clobber (reg:CC FLAGS_REG))])]
9320 {
9321 if (!nonimmediate_operand (operands[1], <MODE>mode))
9322 operands[1] = force_reg (<MODE>mode, operands[1]);
9323 })
9324
9325 (define_insn_and_split "*sub<mode>3_eq"
9326 [(set (match_operand:SWI 0 "nonimmediate_operand")
9327 (minus:SWI
9328 (minus:SWI
9329 (match_operand:SWI 1 "nonimmediate_operand")
9330 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9331 (const_int 0)))
9332 (match_operand:SWI 2 "<general_operand>")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9335 && ix86_pre_reload_split ()"
9336 "#"
9337 "&& 1"
9338 [(set (reg:CC FLAGS_REG)
9339 (compare:CC (match_dup 3) (const_int 1)))
9340 (parallel [(set (match_dup 0)
9341 (minus:SWI
9342 (minus:SWI (match_dup 1)
9343 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9344 (match_dup 2)))
9345 (clobber (reg:CC FLAGS_REG))])])
9346
9347 (define_insn_and_split "*sub<mode>3_ne"
9348 [(set (match_operand:SWI 0 "nonimmediate_operand")
9349 (plus:SWI
9350 (minus:SWI
9351 (match_operand:SWI 1 "nonimmediate_operand")
9352 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9353 (const_int 0)))
9354 (match_operand:SWI 2 "<immediate_operand>")))
9355 (clobber (reg:CC FLAGS_REG))]
9356 "CONST_INT_P (operands[2])
9357 && (<MODE>mode != DImode
9358 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9359 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9360 && ix86_pre_reload_split ()"
9361 "#"
9362 "&& 1"
9363 [(set (reg:CC FLAGS_REG)
9364 (compare:CC (match_dup 3) (const_int 1)))
9365 (parallel [(set (match_dup 0)
9366 (plus:SWI
9367 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9368 (match_dup 1))
9369 (match_dup 2)))
9370 (clobber (reg:CC FLAGS_REG))])]
9371 {
9372 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9373 <MODE>mode == DImode ? SImode : <MODE>mode);
9374 })
9375
9376 (define_insn_and_split "*sub<mode>3_eq_1"
9377 [(set (match_operand:SWI 0 "nonimmediate_operand")
9378 (plus:SWI
9379 (minus:SWI
9380 (match_operand:SWI 1 "nonimmediate_operand")
9381 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9382 (const_int 0)))
9383 (match_operand:SWI 2 "<immediate_operand>")))
9384 (clobber (reg:CC FLAGS_REG))]
9385 "CONST_INT_P (operands[2])
9386 && (<MODE>mode != DImode
9387 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9388 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9389 && ix86_pre_reload_split ()"
9390 "#"
9391 "&& 1"
9392 [(set (reg:CC FLAGS_REG)
9393 (compare:CC (match_dup 3) (const_int 1)))
9394 (parallel [(set (match_dup 0)
9395 (minus:SWI
9396 (minus:SWI (match_dup 1)
9397 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9398 (match_dup 2)))
9399 (clobber (reg:CC FLAGS_REG))])]
9400 {
9401 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9402 <MODE>mode == DImode ? SImode : <MODE>mode);
9403 })
9404
9405 (define_insn_and_split "*sub<mode>3_eq_0"
9406 [(set (match_operand:SWI 0 "nonimmediate_operand")
9407 (minus:SWI
9408 (match_operand:SWI 1 "<general_operand>")
9409 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9412 && ix86_pre_reload_split ()"
9413 "#"
9414 "&& 1"
9415 [(set (reg:CC FLAGS_REG)
9416 (compare:CC (match_dup 2) (const_int 1)))
9417 (parallel [(set (match_dup 0)
9418 (minus:SWI (match_dup 1)
9419 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9420 (clobber (reg:CC FLAGS_REG))])]
9421 {
9422 if (!nonimmediate_operand (operands[1], <MODE>mode))
9423 operands[1] = force_reg (<MODE>mode, operands[1]);
9424 })
9425
9426 (define_insn_and_split "*sub<mode>3_ne_0"
9427 [(set (match_operand:SWI 0 "nonimmediate_operand")
9428 (minus:SWI
9429 (match_operand:SWI 1 "<general_operand>")
9430 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9431 (clobber (reg:CC FLAGS_REG))]
9432 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9433 && ix86_pre_reload_split ()"
9434 "#"
9435 "&& 1"
9436 [(set (reg:CC FLAGS_REG)
9437 (compare:CC (match_dup 2) (const_int 1)))
9438 (parallel [(set (match_dup 0)
9439 (plus:SWI (plus:SWI
9440 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9441 (match_dup 1))
9442 (const_int -1)))
9443 (clobber (reg:CC FLAGS_REG))])]
9444 {
9445 if (!nonimmediate_operand (operands[1], <MODE>mode))
9446 operands[1] = force_reg (<MODE>mode, operands[1]);
9447 })
9448
9449 ;; The patterns that match these are at the end of this file.
9450
9451 (define_expand "<insn>xf3"
9452 [(set (match_operand:XF 0 "register_operand")
9453 (plusminus:XF
9454 (match_operand:XF 1 "register_operand")
9455 (match_operand:XF 2 "register_operand")))]
9456 "TARGET_80387")
9457
9458 (define_expand "<insn>hf3"
9459 [(set (match_operand:HF 0 "register_operand")
9460 (plusminus:HF
9461 (match_operand:HF 1 "register_operand")
9462 (match_operand:HF 2 "nonimmediate_operand")))]
9463 "TARGET_AVX512FP16")
9464
9465 (define_expand "<insn><mode>3"
9466 [(set (match_operand:MODEF 0 "register_operand")
9467 (plusminus:MODEF
9468 (match_operand:MODEF 1 "register_operand")
9469 (match_operand:MODEF 2 "nonimmediate_operand")))]
9470 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9471 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9472 \f
9473 ;; Multiply instructions
9474
9475 (define_expand "mul<mode>3"
9476 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9477 (mult:SWIM248
9478 (match_operand:SWIM248 1 "register_operand")
9479 (match_operand:SWIM248 2 "<general_operand>")))
9480 (clobber (reg:CC FLAGS_REG))])])
9481
9482 (define_expand "mulqi3"
9483 [(parallel [(set (match_operand:QI 0 "register_operand")
9484 (mult:QI
9485 (match_operand:QI 1 "register_operand")
9486 (match_operand:QI 2 "nonimmediate_operand")))
9487 (clobber (reg:CC FLAGS_REG))])]
9488 "TARGET_QIMODE_MATH")
9489
9490 ;; On AMDFAM10
9491 ;; IMUL reg32/64, reg32/64, imm8 Direct
9492 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9493 ;; IMUL reg32/64, reg32/64, imm32 Direct
9494 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9495 ;; IMUL reg32/64, reg32/64 Direct
9496 ;; IMUL reg32/64, mem32/64 Direct
9497 ;;
9498 ;; On BDVER1, all above IMULs use DirectPath
9499 ;;
9500 ;; On AMDFAM10
9501 ;; IMUL reg16, reg16, imm8 VectorPath
9502 ;; IMUL reg16, mem16, imm8 VectorPath
9503 ;; IMUL reg16, reg16, imm16 VectorPath
9504 ;; IMUL reg16, mem16, imm16 VectorPath
9505 ;; IMUL reg16, reg16 Direct
9506 ;; IMUL reg16, mem16 Direct
9507 ;;
9508 ;; On BDVER1, all HI MULs use DoublePath
9509
9510 (define_insn "*mul<mode>3_1"
9511 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9512 (mult:SWIM248
9513 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9514 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9515 (clobber (reg:CC FLAGS_REG))]
9516 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9517 "@
9518 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9519 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9520 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9521 [(set_attr "type" "imul")
9522 (set_attr "prefix_0f" "0,0,1")
9523 (set (attr "athlon_decode")
9524 (cond [(eq_attr "cpu" "athlon")
9525 (const_string "vector")
9526 (eq_attr "alternative" "1")
9527 (const_string "vector")
9528 (and (eq_attr "alternative" "2")
9529 (ior (match_test "<MODE>mode == HImode")
9530 (match_operand 1 "memory_operand")))
9531 (const_string "vector")]
9532 (const_string "direct")))
9533 (set (attr "amdfam10_decode")
9534 (cond [(and (eq_attr "alternative" "0,1")
9535 (ior (match_test "<MODE>mode == HImode")
9536 (match_operand 1 "memory_operand")))
9537 (const_string "vector")]
9538 (const_string "direct")))
9539 (set (attr "bdver1_decode")
9540 (if_then_else
9541 (match_test "<MODE>mode == HImode")
9542 (const_string "double")
9543 (const_string "direct")))
9544 (set_attr "mode" "<MODE>")])
9545
9546 (define_insn "*mulsi3_1_zext"
9547 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9548 (zero_extend:DI
9549 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9550 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9551 (clobber (reg:CC FLAGS_REG))]
9552 "TARGET_64BIT
9553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9554 "@
9555 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9556 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9557 imul{l}\t{%2, %k0|%k0, %2}"
9558 [(set_attr "type" "imul")
9559 (set_attr "prefix_0f" "0,0,1")
9560 (set (attr "athlon_decode")
9561 (cond [(eq_attr "cpu" "athlon")
9562 (const_string "vector")
9563 (eq_attr "alternative" "1")
9564 (const_string "vector")
9565 (and (eq_attr "alternative" "2")
9566 (match_operand 1 "memory_operand"))
9567 (const_string "vector")]
9568 (const_string "direct")))
9569 (set (attr "amdfam10_decode")
9570 (cond [(and (eq_attr "alternative" "0,1")
9571 (match_operand 1 "memory_operand"))
9572 (const_string "vector")]
9573 (const_string "direct")))
9574 (set_attr "bdver1_decode" "direct")
9575 (set_attr "mode" "SI")])
9576
9577 ;;On AMDFAM10 and BDVER1
9578 ;; MUL reg8 Direct
9579 ;; MUL mem8 Direct
9580
9581 (define_insn "*mulqi3_1"
9582 [(set (match_operand:QI 0 "register_operand" "=a")
9583 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9584 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9585 (clobber (reg:CC FLAGS_REG))]
9586 "TARGET_QIMODE_MATH
9587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9588 "mul{b}\t%2"
9589 [(set_attr "type" "imul")
9590 (set_attr "length_immediate" "0")
9591 (set (attr "athlon_decode")
9592 (if_then_else (eq_attr "cpu" "athlon")
9593 (const_string "vector")
9594 (const_string "direct")))
9595 (set_attr "amdfam10_decode" "direct")
9596 (set_attr "bdver1_decode" "direct")
9597 (set_attr "mode" "QI")])
9598
9599 ;; Multiply with jump on overflow.
9600 (define_expand "mulv<mode>4"
9601 [(parallel [(set (reg:CCO FLAGS_REG)
9602 (eq:CCO (mult:<DWI>
9603 (sign_extend:<DWI>
9604 (match_operand:SWI248 1 "register_operand"))
9605 (match_dup 4))
9606 (sign_extend:<DWI>
9607 (mult:SWI248 (match_dup 1)
9608 (match_operand:SWI248 2
9609 "<general_operand>")))))
9610 (set (match_operand:SWI248 0 "register_operand")
9611 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9612 (set (pc) (if_then_else
9613 (eq (reg:CCO FLAGS_REG) (const_int 0))
9614 (label_ref (match_operand 3))
9615 (pc)))]
9616 ""
9617 {
9618 if (CONST_INT_P (operands[2]))
9619 operands[4] = operands[2];
9620 else
9621 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9622 })
9623
9624 (define_insn "*mulv<mode>4"
9625 [(set (reg:CCO FLAGS_REG)
9626 (eq:CCO (mult:<DWI>
9627 (sign_extend:<DWI>
9628 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9629 (sign_extend:<DWI>
9630 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9631 (sign_extend:<DWI>
9632 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9633 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9634 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9636 "@
9637 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9638 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9639 [(set_attr "type" "imul")
9640 (set_attr "prefix_0f" "0,1")
9641 (set (attr "athlon_decode")
9642 (cond [(eq_attr "cpu" "athlon")
9643 (const_string "vector")
9644 (eq_attr "alternative" "0")
9645 (const_string "vector")
9646 (and (eq_attr "alternative" "1")
9647 (match_operand 1 "memory_operand"))
9648 (const_string "vector")]
9649 (const_string "direct")))
9650 (set (attr "amdfam10_decode")
9651 (cond [(and (eq_attr "alternative" "1")
9652 (match_operand 1 "memory_operand"))
9653 (const_string "vector")]
9654 (const_string "direct")))
9655 (set_attr "bdver1_decode" "direct")
9656 (set_attr "mode" "<MODE>")])
9657
9658 (define_insn "*mulvhi4"
9659 [(set (reg:CCO FLAGS_REG)
9660 (eq:CCO (mult:SI
9661 (sign_extend:SI
9662 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9663 (sign_extend:SI
9664 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9665 (sign_extend:SI
9666 (mult:HI (match_dup 1) (match_dup 2)))))
9667 (set (match_operand:HI 0 "register_operand" "=r")
9668 (mult:HI (match_dup 1) (match_dup 2)))]
9669 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9670 "imul{w}\t{%2, %0|%0, %2}"
9671 [(set_attr "type" "imul")
9672 (set_attr "prefix_0f" "1")
9673 (set_attr "athlon_decode" "vector")
9674 (set_attr "amdfam10_decode" "direct")
9675 (set_attr "bdver1_decode" "double")
9676 (set_attr "mode" "HI")])
9677
9678 (define_insn "*mulv<mode>4_1"
9679 [(set (reg:CCO FLAGS_REG)
9680 (eq:CCO (mult:<DWI>
9681 (sign_extend:<DWI>
9682 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9683 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9684 (sign_extend:<DWI>
9685 (mult:SWI248 (match_dup 1)
9686 (match_operand:SWI248 2
9687 "<immediate_operand>" "K,<i>")))))
9688 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9689 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9690 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9691 && CONST_INT_P (operands[2])
9692 && INTVAL (operands[2]) == INTVAL (operands[3])"
9693 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9694 [(set_attr "type" "imul")
9695 (set (attr "prefix_0f")
9696 (if_then_else
9697 (match_test "<MODE>mode == HImode")
9698 (const_string "0")
9699 (const_string "*")))
9700 (set (attr "athlon_decode")
9701 (cond [(eq_attr "cpu" "athlon")
9702 (const_string "vector")
9703 (eq_attr "alternative" "1")
9704 (const_string "vector")]
9705 (const_string "direct")))
9706 (set (attr "amdfam10_decode")
9707 (cond [(ior (match_test "<MODE>mode == HImode")
9708 (match_operand 1 "memory_operand"))
9709 (const_string "vector")]
9710 (const_string "direct")))
9711 (set (attr "bdver1_decode")
9712 (if_then_else
9713 (match_test "<MODE>mode == HImode")
9714 (const_string "double")
9715 (const_string "direct")))
9716 (set_attr "mode" "<MODE>")
9717 (set (attr "length_immediate")
9718 (cond [(eq_attr "alternative" "0")
9719 (const_string "1")
9720 (match_test "<MODE_SIZE> == 8")
9721 (const_string "4")]
9722 (const_string "<MODE_SIZE>")))])
9723
9724 (define_expand "umulv<mode>4"
9725 [(parallel [(set (reg:CCO FLAGS_REG)
9726 (eq:CCO (mult:<DWI>
9727 (zero_extend:<DWI>
9728 (match_operand:SWI248 1
9729 "nonimmediate_operand"))
9730 (zero_extend:<DWI>
9731 (match_operand:SWI248 2
9732 "nonimmediate_operand")))
9733 (zero_extend:<DWI>
9734 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9735 (set (match_operand:SWI248 0 "register_operand")
9736 (mult:SWI248 (match_dup 1) (match_dup 2)))
9737 (clobber (scratch:SWI248))])
9738 (set (pc) (if_then_else
9739 (eq (reg:CCO FLAGS_REG) (const_int 0))
9740 (label_ref (match_operand 3))
9741 (pc)))]
9742 ""
9743 {
9744 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9745 operands[1] = force_reg (<MODE>mode, operands[1]);
9746 })
9747
9748 (define_insn "*umulv<mode>4"
9749 [(set (reg:CCO FLAGS_REG)
9750 (eq:CCO (mult:<DWI>
9751 (zero_extend:<DWI>
9752 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9753 (zero_extend:<DWI>
9754 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9755 (zero_extend:<DWI>
9756 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9757 (set (match_operand:SWI248 0 "register_operand" "=a")
9758 (mult:SWI248 (match_dup 1) (match_dup 2)))
9759 (clobber (match_scratch:SWI248 3 "=d"))]
9760 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9761 "mul{<imodesuffix>}\t%2"
9762 [(set_attr "type" "imul")
9763 (set_attr "length_immediate" "0")
9764 (set (attr "athlon_decode")
9765 (if_then_else (eq_attr "cpu" "athlon")
9766 (const_string "vector")
9767 (const_string "double")))
9768 (set_attr "amdfam10_decode" "double")
9769 (set_attr "bdver1_decode" "direct")
9770 (set_attr "mode" "<MODE>")])
9771
9772 (define_expand "<u>mulvqi4"
9773 [(parallel [(set (reg:CCO FLAGS_REG)
9774 (eq:CCO (mult:HI
9775 (any_extend:HI
9776 (match_operand:QI 1 "nonimmediate_operand"))
9777 (any_extend:HI
9778 (match_operand:QI 2 "nonimmediate_operand")))
9779 (any_extend:HI
9780 (mult:QI (match_dup 1) (match_dup 2)))))
9781 (set (match_operand:QI 0 "register_operand")
9782 (mult:QI (match_dup 1) (match_dup 2)))])
9783 (set (pc) (if_then_else
9784 (eq (reg:CCO FLAGS_REG) (const_int 0))
9785 (label_ref (match_operand 3))
9786 (pc)))]
9787 "TARGET_QIMODE_MATH"
9788 {
9789 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9790 operands[1] = force_reg (QImode, operands[1]);
9791 })
9792
9793 (define_insn "*<u>mulvqi4"
9794 [(set (reg:CCO FLAGS_REG)
9795 (eq:CCO (mult:HI
9796 (any_extend:HI
9797 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9798 (any_extend:HI
9799 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9800 (any_extend:HI
9801 (mult:QI (match_dup 1) (match_dup 2)))))
9802 (set (match_operand:QI 0 "register_operand" "=a")
9803 (mult:QI (match_dup 1) (match_dup 2)))]
9804 "TARGET_QIMODE_MATH
9805 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9806 "<sgnprefix>mul{b}\t%2"
9807 [(set_attr "type" "imul")
9808 (set_attr "length_immediate" "0")
9809 (set (attr "athlon_decode")
9810 (if_then_else (eq_attr "cpu" "athlon")
9811 (const_string "vector")
9812 (const_string "direct")))
9813 (set_attr "amdfam10_decode" "direct")
9814 (set_attr "bdver1_decode" "direct")
9815 (set_attr "mode" "QI")])
9816
9817 (define_expand "<u>mul<mode><dwi>3"
9818 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9819 (mult:<DWI>
9820 (any_extend:<DWI>
9821 (match_operand:DWIH 1 "register_operand"))
9822 (any_extend:<DWI>
9823 (match_operand:DWIH 2 "nonimmediate_operand"))))
9824 (clobber (reg:CC FLAGS_REG))])])
9825
9826 (define_expand "<u>mulqihi3"
9827 [(parallel [(set (match_operand:HI 0 "register_operand")
9828 (mult:HI
9829 (any_extend:HI
9830 (match_operand:QI 1 "register_operand"))
9831 (any_extend:HI
9832 (match_operand:QI 2 "nonimmediate_operand"))))
9833 (clobber (reg:CC FLAGS_REG))])]
9834 "TARGET_QIMODE_MATH")
9835
9836 (define_insn "*bmi2_umul<mode><dwi>3_1"
9837 [(set (match_operand:DWIH 0 "register_operand" "=r")
9838 (mult:DWIH
9839 (match_operand:DWIH 2 "register_operand" "%d")
9840 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9841 (set (match_operand:DWIH 1 "register_operand" "=r")
9842 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))]
9843 "TARGET_BMI2"
9844 "mulx\t{%3, %0, %1|%1, %0, %3}"
9845 [(set_attr "type" "imulx")
9846 (set_attr "prefix" "vex")
9847 (set_attr "mode" "<MODE>")])
9848
9849 ;; Tweak *bmi2_umul<mode><dwi>3_1 to eliminate following mov.
9850 (define_peephole2
9851 [(parallel [(set (match_operand:DWIH 0 "general_reg_operand")
9852 (mult:DWIH (match_operand:DWIH 2 "register_operand")
9853 (match_operand:DWIH 3 "nonimmediate_operand")))
9854 (set (match_operand:DWIH 1 "general_reg_operand")
9855 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])
9856 (set (match_operand:DWIH 4 "general_reg_operand")
9857 (match_operand:DWIH 5 "general_reg_operand"))]
9858 "TARGET_BMI2
9859 && ((REGNO (operands[5]) == REGNO (operands[0])
9860 && REGNO (operands[1]) != REGNO (operands[4]))
9861 || (REGNO (operands[5]) == REGNO (operands[1])
9862 && REGNO (operands[0]) != REGNO (operands[4])))
9863 && peep2_reg_dead_p (2, operands[5])"
9864 [(parallel [(set (match_dup 0) (mult:DWIH (match_dup 2) (match_dup 3)))
9865 (set (match_dup 1)
9866 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])]
9867 {
9868 if (REGNO (operands[5]) == REGNO (operands[0]))
9869 operands[0] = operands[4];
9870 else
9871 operands[1] = operands[4];
9872 })
9873
9874 (define_insn "*umul<mode><dwi>3_1"
9875 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9876 (mult:<DWI>
9877 (zero_extend:<DWI>
9878 (match_operand:DWIH 1 "register_operand" "%d,a"))
9879 (zero_extend:<DWI>
9880 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9881 (clobber (reg:CC FLAGS_REG))]
9882 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9883 "@
9884 #
9885 mul{<imodesuffix>}\t%2"
9886 [(set_attr "isa" "bmi2,*")
9887 (set_attr "type" "imulx,imul")
9888 (set_attr "length_immediate" "*,0")
9889 (set (attr "athlon_decode")
9890 (cond [(eq_attr "alternative" "1")
9891 (if_then_else (eq_attr "cpu" "athlon")
9892 (const_string "vector")
9893 (const_string "double"))]
9894 (const_string "*")))
9895 (set_attr "amdfam10_decode" "*,double")
9896 (set_attr "bdver1_decode" "*,direct")
9897 (set_attr "prefix" "vex,orig")
9898 (set_attr "mode" "<MODE>")])
9899
9900 ;; Convert mul to the mulx pattern to avoid flags dependency.
9901 (define_split
9902 [(set (match_operand:<DWI> 0 "register_operand")
9903 (mult:<DWI>
9904 (zero_extend:<DWI>
9905 (match_operand:DWIH 1 "register_operand"))
9906 (zero_extend:<DWI>
9907 (match_operand:DWIH 2 "nonimmediate_operand"))))
9908 (clobber (reg:CC FLAGS_REG))]
9909 "TARGET_BMI2 && reload_completed
9910 && REGNO (operands[1]) == DX_REG"
9911 [(parallel [(set (match_dup 3)
9912 (mult:DWIH (match_dup 1) (match_dup 2)))
9913 (set (match_dup 4)
9914 (umul_highpart:DWIH (match_dup 1) (match_dup 2)))])]
9915 {
9916 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9917
9918 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9919 })
9920
9921 (define_insn "*mul<mode><dwi>3_1"
9922 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9923 (mult:<DWI>
9924 (sign_extend:<DWI>
9925 (match_operand:DWIH 1 "register_operand" "%a"))
9926 (sign_extend:<DWI>
9927 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9928 (clobber (reg:CC FLAGS_REG))]
9929 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9930 "imul{<imodesuffix>}\t%2"
9931 [(set_attr "type" "imul")
9932 (set_attr "length_immediate" "0")
9933 (set (attr "athlon_decode")
9934 (if_then_else (eq_attr "cpu" "athlon")
9935 (const_string "vector")
9936 (const_string "double")))
9937 (set_attr "amdfam10_decode" "double")
9938 (set_attr "bdver1_decode" "direct")
9939 (set_attr "mode" "<MODE>")])
9940
9941 (define_insn "*<u>mulqihi3_1"
9942 [(set (match_operand:HI 0 "register_operand" "=a")
9943 (mult:HI
9944 (any_extend:HI
9945 (match_operand:QI 1 "register_operand" "%0"))
9946 (any_extend:HI
9947 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9948 (clobber (reg:CC FLAGS_REG))]
9949 "TARGET_QIMODE_MATH
9950 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9951 "<sgnprefix>mul{b}\t%2"
9952 [(set_attr "type" "imul")
9953 (set_attr "length_immediate" "0")
9954 (set (attr "athlon_decode")
9955 (if_then_else (eq_attr "cpu" "athlon")
9956 (const_string "vector")
9957 (const_string "direct")))
9958 (set_attr "amdfam10_decode" "direct")
9959 (set_attr "bdver1_decode" "direct")
9960 (set_attr "mode" "QI")])
9961
9962 ;; Widening multiplication peephole2s to tweak register allocation.
9963 ;; mov imm,%rdx; mov %rdi,%rax; mulq %rdx -> mov imm,%rax; mulq %rdi
9964 (define_peephole2
9965 [(set (match_operand:DWIH 0 "general_reg_operand")
9966 (match_operand:DWIH 1 "immediate_operand"))
9967 (set (match_operand:DWIH 2 "general_reg_operand")
9968 (match_operand:DWIH 3 "general_reg_operand"))
9969 (parallel [(set (match_operand:<DWI> 4 "general_reg_operand")
9970 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9971 (zero_extend:<DWI> (match_dup 0))))
9972 (clobber (reg:CC FLAGS_REG))])]
9973 "REGNO (operands[3]) != AX_REG
9974 && REGNO (operands[0]) != REGNO (operands[2])
9975 && REGNO (operands[0]) != REGNO (operands[3])
9976 && (REGNO (operands[0]) == REGNO (operands[4])
9977 || REGNO (operands[0]) == DX_REG
9978 || peep2_reg_dead_p (3, operands[0]))"
9979 [(set (match_dup 2) (match_dup 1))
9980 (parallel [(set (match_dup 4)
9981 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9982 (zero_extend:<DWI> (match_dup 3))))
9983 (clobber (reg:CC FLAGS_REG))])])
9984
9985 ;; mov imm,%rax; mov %rdi,%rdx; mulx %rax -> mov imm,%rdx; mulx %rdi
9986 (define_peephole2
9987 [(set (match_operand:DWIH 0 "general_reg_operand")
9988 (match_operand:DWIH 1 "immediate_operand"))
9989 (set (match_operand:DWIH 2 "general_reg_operand")
9990 (match_operand:DWIH 3 "general_reg_operand"))
9991 (parallel [(set (match_operand:DWIH 4 "general_reg_operand")
9992 (mult:DWIH (match_dup 2) (match_dup 0)))
9993 (set (match_operand:DWIH 5 "general_reg_operand")
9994 (umul_highpart:DWIH (match_dup 2) (match_dup 0)))])]
9995 "REGNO (operands[3]) != DX_REG
9996 && REGNO (operands[0]) != REGNO (operands[2])
9997 && REGNO (operands[0]) != REGNO (operands[3])
9998 && (REGNO (operands[0]) == REGNO (operands[4])
9999 || REGNO (operands[0]) == REGNO (operands[5])
10000 || peep2_reg_dead_p (3, operands[0]))
10001 && (REGNO (operands[2]) == REGNO (operands[4])
10002 || REGNO (operands[2]) == REGNO (operands[5])
10003 || peep2_reg_dead_p (3, operands[2]))"
10004 [(set (match_dup 2) (match_dup 1))
10005 (parallel [(set (match_dup 4)
10006 (mult:DWIH (match_dup 2) (match_dup 3)))
10007 (set (match_dup 5)
10008 (umul_highpart:DWIH (match_dup 2) (match_dup 3)))])])
10009
10010 ;; Highpart multiplication patterns
10011 (define_insn "<s>mul<mode>3_highpart"
10012 [(set (match_operand:DWIH 0 "register_operand" "=d")
10013 (any_mul_highpart:DWIH
10014 (match_operand:DWIH 1 "register_operand" "%a")
10015 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
10016 (clobber (match_scratch:DWIH 3 "=1"))
10017 (clobber (reg:CC FLAGS_REG))]
10018 ""
10019 "<sgnprefix>mul{<imodesuffix>}\t%2"
10020 [(set_attr "type" "imul")
10021 (set_attr "length_immediate" "0")
10022 (set (attr "athlon_decode")
10023 (if_then_else (eq_attr "cpu" "athlon")
10024 (const_string "vector")
10025 (const_string "double")))
10026 (set_attr "amdfam10_decode" "double")
10027 (set_attr "bdver1_decode" "direct")
10028 (set_attr "mode" "<MODE>")])
10029
10030 (define_insn "*<s>mulsi3_highpart_zext"
10031 [(set (match_operand:DI 0 "register_operand" "=d")
10032 (zero_extend:DI
10033 (any_mul_highpart:SI
10034 (match_operand:SI 1 "register_operand" "%a")
10035 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
10036 (clobber (match_scratch:SI 3 "=1"))
10037 (clobber (reg:CC FLAGS_REG))]
10038 "TARGET_64BIT"
10039 "<sgnprefix>mul{l}\t%2"
10040 [(set_attr "type" "imul")
10041 (set_attr "length_immediate" "0")
10042 (set (attr "athlon_decode")
10043 (if_then_else (eq_attr "cpu" "athlon")
10044 (const_string "vector")
10045 (const_string "double")))
10046 (set_attr "amdfam10_decode" "double")
10047 (set_attr "bdver1_decode" "direct")
10048 (set_attr "mode" "SI")])
10049
10050 (define_insn "*<s>muldi3_highpart_1"
10051 [(set (match_operand:DI 0 "register_operand" "=d")
10052 (truncate:DI
10053 (lshiftrt:TI
10054 (mult:TI
10055 (any_extend:TI
10056 (match_operand:DI 1 "nonimmediate_operand" "%a"))
10057 (any_extend:TI
10058 (match_operand:DI 2 "nonimmediate_operand" "rm")))
10059 (const_int 64))))
10060 (clobber (match_scratch:DI 3 "=1"))
10061 (clobber (reg:CC FLAGS_REG))]
10062 "TARGET_64BIT
10063 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10064 "<sgnprefix>mul{q}\t%2"
10065 [(set_attr "type" "imul")
10066 (set_attr "length_immediate" "0")
10067 (set (attr "athlon_decode")
10068 (if_then_else (eq_attr "cpu" "athlon")
10069 (const_string "vector")
10070 (const_string "double")))
10071 (set_attr "amdfam10_decode" "double")
10072 (set_attr "bdver1_decode" "direct")
10073 (set_attr "mode" "DI")])
10074
10075 (define_insn "*<s>mulsi3_highpart_zext"
10076 [(set (match_operand:DI 0 "register_operand" "=d")
10077 (zero_extend:DI (truncate:SI
10078 (lshiftrt:DI
10079 (mult:DI (any_extend:DI
10080 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10081 (any_extend:DI
10082 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10083 (const_int 32)))))
10084 (clobber (match_scratch:SI 3 "=1"))
10085 (clobber (reg:CC FLAGS_REG))]
10086 "TARGET_64BIT
10087 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10088 "<sgnprefix>mul{l}\t%2"
10089 [(set_attr "type" "imul")
10090 (set_attr "length_immediate" "0")
10091 (set (attr "athlon_decode")
10092 (if_then_else (eq_attr "cpu" "athlon")
10093 (const_string "vector")
10094 (const_string "double")))
10095 (set_attr "amdfam10_decode" "double")
10096 (set_attr "bdver1_decode" "direct")
10097 (set_attr "mode" "SI")])
10098
10099 (define_insn "*<s>mulsi3_highpart_1"
10100 [(set (match_operand:SI 0 "register_operand" "=d")
10101 (truncate:SI
10102 (lshiftrt:DI
10103 (mult:DI
10104 (any_extend:DI
10105 (match_operand:SI 1 "nonimmediate_operand" "%a"))
10106 (any_extend:DI
10107 (match_operand:SI 2 "nonimmediate_operand" "rm")))
10108 (const_int 32))))
10109 (clobber (match_scratch:SI 3 "=1"))
10110 (clobber (reg:CC FLAGS_REG))]
10111 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
10112 "<sgnprefix>mul{l}\t%2"
10113 [(set_attr "type" "imul")
10114 (set_attr "length_immediate" "0")
10115 (set (attr "athlon_decode")
10116 (if_then_else (eq_attr "cpu" "athlon")
10117 (const_string "vector")
10118 (const_string "double")))
10119 (set_attr "amdfam10_decode" "double")
10120 (set_attr "bdver1_decode" "direct")
10121 (set_attr "mode" "SI")])
10122
10123 ;; Highpart multiplication peephole2s to tweak register allocation.
10124 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
10125 (define_peephole2
10126 [(set (match_operand:SWI48 0 "general_reg_operand")
10127 (match_operand:SWI48 1 "immediate_operand"))
10128 (set (match_operand:SWI48 2 "general_reg_operand")
10129 (match_operand:SWI48 3 "general_reg_operand"))
10130 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
10131 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
10132 (clobber (match_dup 2))
10133 (clobber (reg:CC FLAGS_REG))])]
10134 "REGNO (operands[3]) != AX_REG
10135 && REGNO (operands[0]) != REGNO (operands[2])
10136 && REGNO (operands[0]) != REGNO (operands[3])
10137 && (REGNO (operands[0]) == REGNO (operands[4])
10138 || peep2_reg_dead_p (3, operands[0]))"
10139 [(set (match_dup 2) (match_dup 1))
10140 (parallel [(set (match_dup 4)
10141 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
10142 (clobber (match_dup 2))
10143 (clobber (reg:CC FLAGS_REG))])])
10144
10145 (define_peephole2
10146 [(set (match_operand:SI 0 "general_reg_operand")
10147 (match_operand:SI 1 "immediate_operand"))
10148 (set (match_operand:SI 2 "general_reg_operand")
10149 (match_operand:SI 3 "general_reg_operand"))
10150 (parallel [(set (match_operand:DI 4 "general_reg_operand")
10151 (zero_extend:DI
10152 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
10153 (clobber (match_dup 2))
10154 (clobber (reg:CC FLAGS_REG))])]
10155 "TARGET_64BIT
10156 && REGNO (operands[3]) != AX_REG
10157 && REGNO (operands[0]) != REGNO (operands[2])
10158 && REGNO (operands[2]) != REGNO (operands[3])
10159 && REGNO (operands[0]) != REGNO (operands[3])
10160 && (REGNO (operands[0]) == REGNO (operands[4])
10161 || peep2_reg_dead_p (3, operands[0]))"
10162 [(set (match_dup 2) (match_dup 1))
10163 (parallel [(set (match_dup 4)
10164 (zero_extend:DI
10165 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
10166 (clobber (match_dup 2))
10167 (clobber (reg:CC FLAGS_REG))])])
10168
10169 ;; The patterns that match these are at the end of this file.
10170
10171 (define_expand "mulxf3"
10172 [(set (match_operand:XF 0 "register_operand")
10173 (mult:XF (match_operand:XF 1 "register_operand")
10174 (match_operand:XF 2 "register_operand")))]
10175 "TARGET_80387")
10176
10177 (define_expand "mulhf3"
10178 [(set (match_operand:HF 0 "register_operand")
10179 (mult:HF (match_operand:HF 1 "register_operand")
10180 (match_operand:HF 2 "nonimmediate_operand")))]
10181 "TARGET_AVX512FP16")
10182
10183 (define_expand "mul<mode>3"
10184 [(set (match_operand:MODEF 0 "register_operand")
10185 (mult:MODEF (match_operand:MODEF 1 "register_operand")
10186 (match_operand:MODEF 2 "nonimmediate_operand")))]
10187 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10188 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
10189 \f
10190 ;; Divide instructions
10191
10192 ;; The patterns that match these are at the end of this file.
10193
10194 (define_expand "divxf3"
10195 [(set (match_operand:XF 0 "register_operand")
10196 (div:XF (match_operand:XF 1 "register_operand")
10197 (match_operand:XF 2 "register_operand")))]
10198 "TARGET_80387")
10199
10200 /* There is no more precision loss than Newton-Rhapson approximation
10201 when using HFmode rcp/rsqrt, so do the transformation directly under
10202 TARGET_RECIP_DIV and fast-math. */
10203 (define_expand "divhf3"
10204 [(set (match_operand:HF 0 "register_operand")
10205 (div:HF (match_operand:HF 1 "register_operand")
10206 (match_operand:HF 2 "nonimmediate_operand")))]
10207 "TARGET_AVX512FP16"
10208 {
10209 if (TARGET_RECIP_DIV
10210 && optimize_insn_for_speed_p ()
10211 && flag_finite_math_only && !flag_trapping_math
10212 && flag_unsafe_math_optimizations)
10213 {
10214 rtx op = gen_reg_rtx (HFmode);
10215 operands[2] = force_reg (HFmode, operands[2]);
10216 emit_insn (gen_rcphf2 (op, operands[2]));
10217 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
10218 DONE;
10219 }
10220 })
10221
10222 (define_expand "div<mode>3"
10223 [(set (match_operand:MODEF 0 "register_operand")
10224 (div:MODEF (match_operand:MODEF 1 "register_operand")
10225 (match_operand:MODEF 2 "nonimmediate_operand")))]
10226 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
10227 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10228 {
10229 if (<MODE>mode == SFmode
10230 && TARGET_SSE && TARGET_SSE_MATH
10231 && TARGET_RECIP_DIV
10232 && optimize_insn_for_speed_p ()
10233 && flag_finite_math_only && !flag_trapping_math
10234 && flag_unsafe_math_optimizations)
10235 {
10236 ix86_emit_swdivsf (operands[0], operands[1],
10237 operands[2], SFmode);
10238 DONE;
10239 }
10240 })
10241 \f
10242 ;; Divmod instructions.
10243
10244 (define_code_iterator any_div [div udiv])
10245 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
10246
10247 (define_expand "<u>divmod<mode>4"
10248 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
10249 (any_div:SWIM248
10250 (match_operand:SWIM248 1 "register_operand")
10251 (match_operand:SWIM248 2 "nonimmediate_operand")))
10252 (set (match_operand:SWIM248 3 "register_operand")
10253 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
10254 (clobber (reg:CC FLAGS_REG))])])
10255
10256 ;; Split with 8bit unsigned divide:
10257 ;; if (dividend an divisor are in [0-255])
10258 ;; use 8bit unsigned integer divide
10259 ;; else
10260 ;; use original integer divide
10261 (define_split
10262 [(set (match_operand:SWI48 0 "register_operand")
10263 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
10264 (match_operand:SWI48 3 "nonimmediate_operand")))
10265 (set (match_operand:SWI48 1 "register_operand")
10266 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
10267 (clobber (reg:CC FLAGS_REG))]
10268 "TARGET_USE_8BIT_IDIV
10269 && TARGET_QIMODE_MATH
10270 && can_create_pseudo_p ()
10271 && !optimize_insn_for_size_p ()"
10272 [(const_int 0)]
10273 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
10274
10275 (define_split
10276 [(set (match_operand:DI 0 "register_operand")
10277 (zero_extend:DI
10278 (any_div:SI (match_operand:SI 2 "register_operand")
10279 (match_operand:SI 3 "nonimmediate_operand"))))
10280 (set (match_operand:SI 1 "register_operand")
10281 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10282 (clobber (reg:CC FLAGS_REG))]
10283 "TARGET_64BIT
10284 && TARGET_USE_8BIT_IDIV
10285 && TARGET_QIMODE_MATH
10286 && can_create_pseudo_p ()
10287 && !optimize_insn_for_size_p ()"
10288 [(const_int 0)]
10289 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10290
10291 (define_split
10292 [(set (match_operand:DI 1 "register_operand")
10293 (zero_extend:DI
10294 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10295 (match_operand:SI 3 "nonimmediate_operand"))))
10296 (set (match_operand:SI 0 "register_operand")
10297 (any_div:SI (match_dup 2) (match_dup 3)))
10298 (clobber (reg:CC FLAGS_REG))]
10299 "TARGET_64BIT
10300 && TARGET_USE_8BIT_IDIV
10301 && TARGET_QIMODE_MATH
10302 && can_create_pseudo_p ()
10303 && !optimize_insn_for_size_p ()"
10304 [(const_int 0)]
10305 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10306
10307 (define_insn_and_split "divmod<mode>4_1"
10308 [(set (match_operand:SWI48 0 "register_operand" "=a")
10309 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10310 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10311 (set (match_operand:SWI48 1 "register_operand" "=&d")
10312 (mod:SWI48 (match_dup 2) (match_dup 3)))
10313 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10314 (clobber (reg:CC FLAGS_REG))]
10315 ""
10316 "#"
10317 "reload_completed"
10318 [(parallel [(set (match_dup 1)
10319 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10320 (clobber (reg:CC FLAGS_REG))])
10321 (parallel [(set (match_dup 0)
10322 (div:SWI48 (match_dup 2) (match_dup 3)))
10323 (set (match_dup 1)
10324 (mod:SWI48 (match_dup 2) (match_dup 3)))
10325 (use (match_dup 1))
10326 (clobber (reg:CC FLAGS_REG))])]
10327 {
10328 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10329
10330 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10331 operands[4] = operands[2];
10332 else
10333 {
10334 /* Avoid use of cltd in favor of a mov+shift. */
10335 emit_move_insn (operands[1], operands[2]);
10336 operands[4] = operands[1];
10337 }
10338 }
10339 [(set_attr "type" "multi")
10340 (set_attr "mode" "<MODE>")])
10341
10342 (define_insn_and_split "udivmod<mode>4_1"
10343 [(set (match_operand:SWI48 0 "register_operand" "=a")
10344 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10345 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10346 (set (match_operand:SWI48 1 "register_operand" "=&d")
10347 (umod:SWI48 (match_dup 2) (match_dup 3)))
10348 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10349 (clobber (reg:CC FLAGS_REG))]
10350 ""
10351 "#"
10352 "reload_completed"
10353 [(set (match_dup 1) (const_int 0))
10354 (parallel [(set (match_dup 0)
10355 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10356 (set (match_dup 1)
10357 (umod:SWI48 (match_dup 2) (match_dup 3)))
10358 (use (match_dup 1))
10359 (clobber (reg:CC FLAGS_REG))])]
10360 ""
10361 [(set_attr "type" "multi")
10362 (set_attr "mode" "<MODE>")])
10363
10364 (define_insn_and_split "divmodsi4_zext_1"
10365 [(set (match_operand:DI 0 "register_operand" "=a")
10366 (zero_extend:DI
10367 (div:SI (match_operand:SI 2 "register_operand" "0")
10368 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10369 (set (match_operand:SI 1 "register_operand" "=&d")
10370 (mod:SI (match_dup 2) (match_dup 3)))
10371 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10372 (clobber (reg:CC FLAGS_REG))]
10373 "TARGET_64BIT"
10374 "#"
10375 "&& reload_completed"
10376 [(parallel [(set (match_dup 1)
10377 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10378 (clobber (reg:CC FLAGS_REG))])
10379 (parallel [(set (match_dup 0)
10380 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10381 (set (match_dup 1)
10382 (mod:SI (match_dup 2) (match_dup 3)))
10383 (use (match_dup 1))
10384 (clobber (reg:CC FLAGS_REG))])]
10385 {
10386 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10387
10388 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10389 operands[4] = operands[2];
10390 else
10391 {
10392 /* Avoid use of cltd in favor of a mov+shift. */
10393 emit_move_insn (operands[1], operands[2]);
10394 operands[4] = operands[1];
10395 }
10396 }
10397 [(set_attr "type" "multi")
10398 (set_attr "mode" "SI")])
10399
10400 (define_insn_and_split "udivmodsi4_zext_1"
10401 [(set (match_operand:DI 0 "register_operand" "=a")
10402 (zero_extend:DI
10403 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10404 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10405 (set (match_operand:SI 1 "register_operand" "=&d")
10406 (umod:SI (match_dup 2) (match_dup 3)))
10407 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10408 (clobber (reg:CC FLAGS_REG))]
10409 "TARGET_64BIT"
10410 "#"
10411 "&& reload_completed"
10412 [(set (match_dup 1) (const_int 0))
10413 (parallel [(set (match_dup 0)
10414 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10415 (set (match_dup 1)
10416 (umod:SI (match_dup 2) (match_dup 3)))
10417 (use (match_dup 1))
10418 (clobber (reg:CC FLAGS_REG))])]
10419 ""
10420 [(set_attr "type" "multi")
10421 (set_attr "mode" "SI")])
10422
10423 (define_insn_and_split "divmodsi4_zext_2"
10424 [(set (match_operand:DI 1 "register_operand" "=&d")
10425 (zero_extend:DI
10426 (mod:SI (match_operand:SI 2 "register_operand" "0")
10427 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10428 (set (match_operand:SI 0 "register_operand" "=a")
10429 (div:SI (match_dup 2) (match_dup 3)))
10430 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10431 (clobber (reg:CC FLAGS_REG))]
10432 "TARGET_64BIT"
10433 "#"
10434 "&& reload_completed"
10435 [(parallel [(set (match_dup 6)
10436 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10437 (clobber (reg:CC FLAGS_REG))])
10438 (parallel [(set (match_dup 1)
10439 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10440 (set (match_dup 0)
10441 (div:SI (match_dup 2) (match_dup 3)))
10442 (use (match_dup 6))
10443 (clobber (reg:CC FLAGS_REG))])]
10444 {
10445 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10446 operands[6] = gen_lowpart (SImode, operands[1]);
10447
10448 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10449 operands[4] = operands[2];
10450 else
10451 {
10452 /* Avoid use of cltd in favor of a mov+shift. */
10453 emit_move_insn (operands[6], operands[2]);
10454 operands[4] = operands[6];
10455 }
10456 }
10457 [(set_attr "type" "multi")
10458 (set_attr "mode" "SI")])
10459
10460 (define_insn_and_split "udivmodsi4_zext_2"
10461 [(set (match_operand:DI 1 "register_operand" "=&d")
10462 (zero_extend:DI
10463 (umod:SI (match_operand:SI 2 "register_operand" "0")
10464 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10465 (set (match_operand:SI 0 "register_operand" "=a")
10466 (udiv:SI (match_dup 2) (match_dup 3)))
10467 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10468 (clobber (reg:CC FLAGS_REG))]
10469 "TARGET_64BIT"
10470 "#"
10471 "&& reload_completed"
10472 [(set (match_dup 4) (const_int 0))
10473 (parallel [(set (match_dup 1)
10474 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10475 (set (match_dup 0)
10476 (udiv:SI (match_dup 2) (match_dup 3)))
10477 (use (match_dup 4))
10478 (clobber (reg:CC FLAGS_REG))])]
10479 "operands[4] = gen_lowpart (SImode, operands[1]);"
10480 [(set_attr "type" "multi")
10481 (set_attr "mode" "SI")])
10482
10483 (define_insn_and_split "*divmod<mode>4"
10484 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10485 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10486 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10487 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10488 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10489 (clobber (reg:CC FLAGS_REG))]
10490 ""
10491 "#"
10492 "reload_completed"
10493 [(parallel [(set (match_dup 1)
10494 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10495 (clobber (reg:CC FLAGS_REG))])
10496 (parallel [(set (match_dup 0)
10497 (div:SWIM248 (match_dup 2) (match_dup 3)))
10498 (set (match_dup 1)
10499 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10500 (use (match_dup 1))
10501 (clobber (reg:CC FLAGS_REG))])]
10502 {
10503 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10504
10505 if (<MODE>mode != HImode
10506 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10507 operands[4] = operands[2];
10508 else
10509 {
10510 /* Avoid use of cltd in favor of a mov+shift. */
10511 emit_move_insn (operands[1], operands[2]);
10512 operands[4] = operands[1];
10513 }
10514 }
10515 [(set_attr "type" "multi")
10516 (set_attr "mode" "<MODE>")])
10517
10518 (define_insn_and_split "*udivmod<mode>4"
10519 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10520 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10521 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10522 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10523 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10524 (clobber (reg:CC FLAGS_REG))]
10525 ""
10526 "#"
10527 "reload_completed"
10528 [(set (match_dup 1) (const_int 0))
10529 (parallel [(set (match_dup 0)
10530 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10531 (set (match_dup 1)
10532 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10533 (use (match_dup 1))
10534 (clobber (reg:CC FLAGS_REG))])]
10535 ""
10536 [(set_attr "type" "multi")
10537 (set_attr "mode" "<MODE>")])
10538
10539 ;; Optimize division or modulo by constant power of 2, if the constant
10540 ;; materializes only after expansion.
10541 (define_insn_and_split "*udivmod<mode>4_pow2"
10542 [(set (match_operand:SWI48 0 "register_operand" "=r")
10543 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10544 (match_operand:SWI48 3 "const_int_operand")))
10545 (set (match_operand:SWI48 1 "register_operand" "=r")
10546 (umod:SWI48 (match_dup 2) (match_dup 3)))
10547 (clobber (reg:CC FLAGS_REG))]
10548 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10549 "#"
10550 "&& reload_completed"
10551 [(set (match_dup 1) (match_dup 2))
10552 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10553 (clobber (reg:CC FLAGS_REG))])
10554 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10555 (clobber (reg:CC FLAGS_REG))])]
10556 {
10557 int v = exact_log2 (UINTVAL (operands[3]));
10558 operands[4] = GEN_INT (v);
10559 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10560 }
10561 [(set_attr "type" "multi")
10562 (set_attr "mode" "<MODE>")])
10563
10564 (define_insn_and_split "*divmodsi4_zext_1"
10565 [(set (match_operand:DI 0 "register_operand" "=a")
10566 (zero_extend:DI
10567 (div:SI (match_operand:SI 2 "register_operand" "0")
10568 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10569 (set (match_operand:SI 1 "register_operand" "=&d")
10570 (mod:SI (match_dup 2) (match_dup 3)))
10571 (clobber (reg:CC FLAGS_REG))]
10572 "TARGET_64BIT"
10573 "#"
10574 "&& reload_completed"
10575 [(parallel [(set (match_dup 1)
10576 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10577 (clobber (reg:CC FLAGS_REG))])
10578 (parallel [(set (match_dup 0)
10579 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10580 (set (match_dup 1)
10581 (mod:SI (match_dup 2) (match_dup 3)))
10582 (use (match_dup 1))
10583 (clobber (reg:CC FLAGS_REG))])]
10584 {
10585 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10586
10587 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10588 operands[4] = operands[2];
10589 else
10590 {
10591 /* Avoid use of cltd in favor of a mov+shift. */
10592 emit_move_insn (operands[1], operands[2]);
10593 operands[4] = operands[1];
10594 }
10595 }
10596 [(set_attr "type" "multi")
10597 (set_attr "mode" "SI")])
10598
10599 (define_insn_and_split "*udivmodsi4_zext_1"
10600 [(set (match_operand:DI 0 "register_operand" "=a")
10601 (zero_extend:DI
10602 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10603 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10604 (set (match_operand:SI 1 "register_operand" "=&d")
10605 (umod:SI (match_dup 2) (match_dup 3)))
10606 (clobber (reg:CC FLAGS_REG))]
10607 "TARGET_64BIT"
10608 "#"
10609 "&& reload_completed"
10610 [(set (match_dup 1) (const_int 0))
10611 (parallel [(set (match_dup 0)
10612 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10613 (set (match_dup 1)
10614 (umod:SI (match_dup 2) (match_dup 3)))
10615 (use (match_dup 1))
10616 (clobber (reg:CC FLAGS_REG))])]
10617 ""
10618 [(set_attr "type" "multi")
10619 (set_attr "mode" "SI")])
10620
10621 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10622 [(set (match_operand:DI 0 "register_operand" "=r")
10623 (zero_extend:DI
10624 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10625 (match_operand:SI 3 "const_int_operand"))))
10626 (set (match_operand:SI 1 "register_operand" "=r")
10627 (umod:SI (match_dup 2) (match_dup 3)))
10628 (clobber (reg:CC FLAGS_REG))]
10629 "TARGET_64BIT
10630 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10631 "#"
10632 "&& reload_completed"
10633 [(set (match_dup 1) (match_dup 2))
10634 (parallel [(set (match_dup 0)
10635 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10636 (clobber (reg:CC FLAGS_REG))])
10637 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10638 (clobber (reg:CC FLAGS_REG))])]
10639 {
10640 int v = exact_log2 (UINTVAL (operands[3]));
10641 operands[4] = GEN_INT (v);
10642 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10643 }
10644 [(set_attr "type" "multi")
10645 (set_attr "mode" "SI")])
10646
10647 (define_insn_and_split "*divmodsi4_zext_2"
10648 [(set (match_operand:DI 1 "register_operand" "=&d")
10649 (zero_extend:DI
10650 (mod:SI (match_operand:SI 2 "register_operand" "0")
10651 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10652 (set (match_operand:SI 0 "register_operand" "=a")
10653 (div:SI (match_dup 2) (match_dup 3)))
10654 (clobber (reg:CC FLAGS_REG))]
10655 "TARGET_64BIT"
10656 "#"
10657 "&& reload_completed"
10658 [(parallel [(set (match_dup 6)
10659 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10660 (clobber (reg:CC FLAGS_REG))])
10661 (parallel [(set (match_dup 1)
10662 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10663 (set (match_dup 0)
10664 (div:SI (match_dup 2) (match_dup 3)))
10665 (use (match_dup 6))
10666 (clobber (reg:CC FLAGS_REG))])]
10667 {
10668 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10669 operands[6] = gen_lowpart (SImode, operands[1]);
10670
10671 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10672 operands[4] = operands[2];
10673 else
10674 {
10675 /* Avoid use of cltd in favor of a mov+shift. */
10676 emit_move_insn (operands[6], operands[2]);
10677 operands[4] = operands[6];
10678 }
10679 }
10680 [(set_attr "type" "multi")
10681 (set_attr "mode" "SI")])
10682
10683 (define_insn_and_split "*udivmodsi4_zext_2"
10684 [(set (match_operand:DI 1 "register_operand" "=&d")
10685 (zero_extend:DI
10686 (umod:SI (match_operand:SI 2 "register_operand" "0")
10687 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10688 (set (match_operand:SI 0 "register_operand" "=a")
10689 (udiv:SI (match_dup 2) (match_dup 3)))
10690 (clobber (reg:CC FLAGS_REG))]
10691 "TARGET_64BIT"
10692 "#"
10693 "&& reload_completed"
10694 [(set (match_dup 4) (const_int 0))
10695 (parallel [(set (match_dup 1)
10696 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10697 (set (match_dup 0)
10698 (udiv:SI (match_dup 2) (match_dup 3)))
10699 (use (match_dup 4))
10700 (clobber (reg:CC FLAGS_REG))])]
10701 "operands[4] = gen_lowpart (SImode, operands[1]);"
10702 [(set_attr "type" "multi")
10703 (set_attr "mode" "SI")])
10704
10705 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10706 [(set (match_operand:DI 1 "register_operand" "=r")
10707 (zero_extend:DI
10708 (umod:SI (match_operand:SI 2 "register_operand" "0")
10709 (match_operand:SI 3 "const_int_operand"))))
10710 (set (match_operand:SI 0 "register_operand" "=r")
10711 (udiv:SI (match_dup 2) (match_dup 3)))
10712 (clobber (reg:CC FLAGS_REG))]
10713 "TARGET_64BIT
10714 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10715 "#"
10716 "&& reload_completed"
10717 [(set (match_dup 1) (match_dup 2))
10718 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10719 (clobber (reg:CC FLAGS_REG))])
10720 (parallel [(set (match_dup 1)
10721 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10722 (clobber (reg:CC FLAGS_REG))])]
10723 {
10724 int v = exact_log2 (UINTVAL (operands[3]));
10725 operands[4] = GEN_INT (v);
10726 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10727 }
10728 [(set_attr "type" "multi")
10729 (set_attr "mode" "SI")])
10730
10731 (define_insn "*<u>divmod<mode>4_noext"
10732 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10733 (any_div:SWIM248
10734 (match_operand:SWIM248 2 "register_operand" "0")
10735 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10736 (set (match_operand:SWIM248 1 "register_operand" "=d")
10737 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10738 (use (match_operand:SWIM248 4 "register_operand" "1"))
10739 (clobber (reg:CC FLAGS_REG))]
10740 ""
10741 "<sgnprefix>div{<imodesuffix>}\t%3"
10742 [(set_attr "type" "idiv")
10743 (set_attr "mode" "<MODE>")])
10744
10745 (define_insn "*<u>divmodsi4_noext_zext_1"
10746 [(set (match_operand:DI 0 "register_operand" "=a")
10747 (zero_extend:DI
10748 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10749 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10750 (set (match_operand:SI 1 "register_operand" "=d")
10751 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10752 (use (match_operand:SI 4 "register_operand" "1"))
10753 (clobber (reg:CC FLAGS_REG))]
10754 "TARGET_64BIT"
10755 "<sgnprefix>div{l}\t%3"
10756 [(set_attr "type" "idiv")
10757 (set_attr "mode" "SI")])
10758
10759 (define_insn "*<u>divmodsi4_noext_zext_2"
10760 [(set (match_operand:DI 1 "register_operand" "=d")
10761 (zero_extend:DI
10762 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10763 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10764 (set (match_operand:SI 0 "register_operand" "=a")
10765 (any_div:SI (match_dup 2) (match_dup 3)))
10766 (use (match_operand:SI 4 "register_operand" "1"))
10767 (clobber (reg:CC FLAGS_REG))]
10768 "TARGET_64BIT"
10769 "<sgnprefix>div{l}\t%3"
10770 [(set_attr "type" "idiv")
10771 (set_attr "mode" "SI")])
10772
10773 ;; Avoid sign-extension (using cdq) for constant numerators.
10774 (define_insn_and_split "*divmodsi4_const"
10775 [(set (match_operand:SI 0 "register_operand" "=&a")
10776 (div:SI (match_operand:SI 2 "const_int_operand")
10777 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10778 (set (match_operand:SI 1 "register_operand" "=&d")
10779 (mod:SI (match_dup 2) (match_dup 3)))
10780 (clobber (reg:CC FLAGS_REG))]
10781 "!optimize_function_for_size_p (cfun)"
10782 "#"
10783 "&& reload_completed"
10784 [(set (match_dup 0) (match_dup 2))
10785 (set (match_dup 1) (match_dup 4))
10786 (parallel [(set (match_dup 0)
10787 (div:SI (match_dup 0) (match_dup 3)))
10788 (set (match_dup 1)
10789 (mod:SI (match_dup 0) (match_dup 3)))
10790 (use (match_dup 1))
10791 (clobber (reg:CC FLAGS_REG))])]
10792 {
10793 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10794 }
10795 [(set_attr "type" "multi")
10796 (set_attr "mode" "SI")])
10797
10798 (define_expand "divmodqi4"
10799 [(parallel [(set (match_operand:QI 0 "register_operand")
10800 (div:QI
10801 (match_operand:QI 1 "register_operand")
10802 (match_operand:QI 2 "nonimmediate_operand")))
10803 (set (match_operand:QI 3 "register_operand")
10804 (mod:QI (match_dup 1) (match_dup 2)))
10805 (clobber (reg:CC FLAGS_REG))])]
10806 "TARGET_QIMODE_MATH"
10807 {
10808 rtx div, mod;
10809 rtx tmp0, tmp1;
10810
10811 tmp0 = gen_reg_rtx (HImode);
10812 tmp1 = gen_reg_rtx (HImode);
10813
10814 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10815 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10816 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10817
10818 /* Extract remainder from AH. */
10819 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10820 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10821 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10822
10823 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10824 set_unique_reg_note (insn, REG_EQUAL, mod);
10825
10826 /* Extract quotient from AL. */
10827 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10828
10829 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10830 set_unique_reg_note (insn, REG_EQUAL, div);
10831
10832 DONE;
10833 })
10834
10835 (define_expand "udivmodqi4"
10836 [(parallel [(set (match_operand:QI 0 "register_operand")
10837 (udiv:QI
10838 (match_operand:QI 1 "register_operand")
10839 (match_operand:QI 2 "nonimmediate_operand")))
10840 (set (match_operand:QI 3 "register_operand")
10841 (umod:QI (match_dup 1) (match_dup 2)))
10842 (clobber (reg:CC FLAGS_REG))])]
10843 "TARGET_QIMODE_MATH"
10844 {
10845 rtx div, mod;
10846 rtx tmp0, tmp1;
10847
10848 tmp0 = gen_reg_rtx (HImode);
10849 tmp1 = gen_reg_rtx (HImode);
10850
10851 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10852 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10853 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10854
10855 /* Extract remainder from AH. */
10856 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10857 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10858 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10859
10860 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10861 set_unique_reg_note (insn, REG_EQUAL, mod);
10862
10863 /* Extract quotient from AL. */
10864 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10865
10866 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10867 set_unique_reg_note (insn, REG_EQUAL, div);
10868
10869 DONE;
10870 })
10871
10872 ;; Divide AX by r/m8, with result stored in
10873 ;; AL <- Quotient
10874 ;; AH <- Remainder
10875 ;; Change div/mod to HImode and extend the second argument to HImode
10876 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10877 ;; combine may fail.
10878 (define_insn "<u>divmodhiqi3"
10879 [(set (match_operand:HI 0 "register_operand" "=a")
10880 (ior:HI
10881 (ashift:HI
10882 (zero_extend:HI
10883 (truncate:QI
10884 (mod:HI (match_operand:HI 1 "register_operand" "0")
10885 (any_extend:HI
10886 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10887 (const_int 8))
10888 (zero_extend:HI
10889 (truncate:QI
10890 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10891 (clobber (reg:CC FLAGS_REG))]
10892 "TARGET_QIMODE_MATH"
10893 "<sgnprefix>div{b}\t%2"
10894 [(set_attr "type" "idiv")
10895 (set_attr "mode" "QI")])
10896
10897 ;; We cannot use div/idiv for double division, because it causes
10898 ;; "division by zero" on the overflow and that's not what we expect
10899 ;; from truncate. Because true (non truncating) double division is
10900 ;; never generated, we can't create this insn anyway.
10901 ;
10902 ;(define_insn ""
10903 ; [(set (match_operand:SI 0 "register_operand" "=a")
10904 ; (truncate:SI
10905 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10906 ; (zero_extend:DI
10907 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10908 ; (set (match_operand:SI 3 "register_operand" "=d")
10909 ; (truncate:SI
10910 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10911 ; (clobber (reg:CC FLAGS_REG))]
10912 ; ""
10913 ; "div{l}\t{%2, %0|%0, %2}"
10914 ; [(set_attr "type" "idiv")])
10915 \f
10916 ;;- Logical AND instructions
10917
10918 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10919 ;; Note that this excludes ah.
10920
10921 (define_expand "@test<mode>_ccno_1"
10922 [(set (reg:CCNO FLAGS_REG)
10923 (compare:CCNO
10924 (and:SWI48
10925 (match_operand:SWI48 0 "nonimmediate_operand")
10926 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10927 (const_int 0)))])
10928
10929 (define_expand "testqi_ccz_1"
10930 [(set (reg:CCZ FLAGS_REG)
10931 (compare:CCZ
10932 (and:QI
10933 (match_operand:QI 0 "nonimmediate_operand")
10934 (match_operand:QI 1 "nonmemory_operand"))
10935 (const_int 0)))])
10936
10937 (define_insn "*testdi_1"
10938 [(set (reg FLAGS_REG)
10939 (compare
10940 (and:DI
10941 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10942 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10943 (const_int 0)))]
10944 "TARGET_64BIT
10945 && ix86_match_ccmode
10946 (insn,
10947 /* If we are going to emit testl instead of testq, and the operands[1]
10948 constant might have the SImode sign bit set, make sure the sign
10949 flag isn't tested, because the instruction will set the sign flag
10950 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10951 conservatively assume it might have bit 31 set. */
10952 (satisfies_constraint_Z (operands[1])
10953 && (!CONST_INT_P (operands[1])
10954 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10955 ? CCZmode : CCNOmode)"
10956 "@
10957 test{l}\t{%k1, %k0|%k0, %k1}
10958 test{q}\t{%1, %0|%0, %1}"
10959 [(set_attr "type" "test")
10960 (set_attr "mode" "SI,DI")])
10961
10962 (define_insn "*testqi_1_maybe_si"
10963 [(set (reg FLAGS_REG)
10964 (compare
10965 (and:QI
10966 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10967 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10968 (const_int 0)))]
10969 "ix86_match_ccmode (insn,
10970 CONST_INT_P (operands[1])
10971 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10972 {
10973 if (get_attr_mode (insn) == MODE_SI)
10974 {
10975 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10976 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10977 return "test{l}\t{%1, %k0|%k0, %1}";
10978 }
10979 return "test{b}\t{%1, %0|%0, %1}";
10980 }
10981 [(set_attr "type" "test")
10982 (set (attr "mode")
10983 (cond [(eq_attr "alternative" "2")
10984 (const_string "SI")
10985 (and (match_test "optimize_insn_for_size_p ()")
10986 (and (match_operand 0 "ext_QIreg_operand")
10987 (match_operand 1 "const_0_to_127_operand")))
10988 (const_string "SI")
10989 ]
10990 (const_string "QI")))
10991 (set_attr "pent_pair" "uv,np,np")])
10992
10993 (define_insn "*test<mode>_1"
10994 [(set (reg FLAGS_REG)
10995 (compare
10996 (and:SWI124
10997 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10998 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10999 (const_int 0)))]
11000 "ix86_match_ccmode (insn, CCNOmode)"
11001 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
11002 [(set_attr "type" "test")
11003 (set_attr "mode" "<MODE>")
11004 (set_attr "pent_pair" "uv,uv,np")])
11005
11006 (define_expand "testqi_ext_1_ccno"
11007 [(set (reg:CCNO FLAGS_REG)
11008 (compare:CCNO
11009 (and:QI
11010 (subreg:QI
11011 (zero_extract:HI
11012 (match_operand:HI 0 "register_operand")
11013 (const_int 8)
11014 (const_int 8)) 0)
11015 (match_operand:QI 1 "const_int_operand"))
11016 (const_int 0)))])
11017
11018 (define_insn "*testqi_ext<mode>_1"
11019 [(set (reg FLAGS_REG)
11020 (compare
11021 (and:QI
11022 (subreg:QI
11023 (match_operator:SWI248 2 "extract_operator"
11024 [(match_operand 0 "int248_register_operand" "Q")
11025 (const_int 8)
11026 (const_int 8)]) 0)
11027 (match_operand:QI 1 "general_operand" "QnBn"))
11028 (const_int 0)))]
11029 "ix86_match_ccmode (insn, CCNOmode)"
11030 "test{b}\t{%1, %h0|%h0, %1}"
11031 [(set_attr "addr" "gpr8")
11032 (set_attr "type" "test")
11033 (set_attr "mode" "QI")])
11034
11035 (define_insn "*testqi_ext<mode>_2"
11036 [(set (reg FLAGS_REG)
11037 (compare
11038 (and:QI
11039 (subreg:QI
11040 (match_operator:SWI248 2 "extract_operator"
11041 [(match_operand 0 "int248_register_operand" "Q")
11042 (const_int 8)
11043 (const_int 8)]) 0)
11044 (subreg:QI
11045 (match_operator:SWI248 3 "extract_operator"
11046 [(match_operand 1 "int248_register_operand" "Q")
11047 (const_int 8)
11048 (const_int 8)]) 0))
11049 (const_int 0)))]
11050 "ix86_match_ccmode (insn, CCNOmode)"
11051 "test{b}\t{%h1, %h0|%h0, %h1}"
11052 [(set_attr "type" "test")
11053 (set_attr "mode" "QI")])
11054
11055 ;; Provide a *testti instruction that STV can implement using ptest.
11056 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
11057 (define_insn_and_split "*testti_doubleword"
11058 [(set (reg:CCZ FLAGS_REG)
11059 (compare:CCZ
11060 (and:TI (match_operand:TI 0 "register_operand")
11061 (match_operand:TI 1 "general_operand"))
11062 (const_int 0)))]
11063 "TARGET_64BIT
11064 && ix86_pre_reload_split ()"
11065 "#"
11066 "&& 1"
11067 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
11068 (clobber (reg:CC FLAGS_REG))])
11069 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11070 {
11071 operands[2] = gen_reg_rtx (TImode);
11072 if (!x86_64_hilo_general_operand (operands[1], TImode))
11073 operands[1] = force_reg (TImode, operands[1]);
11074 })
11075
11076 ;; Combine likes to form bit extractions for some tests. Humor it.
11077 (define_insn_and_split "*testqi_ext_3"
11078 [(set (match_operand 0 "flags_reg_operand")
11079 (match_operator 1 "compare_operator"
11080 [(zero_extract:SWI248
11081 (match_operand 2 "int_nonimmediate_operand" "rm")
11082 (match_operand:QI 3 "const_int_operand")
11083 (match_operand:QI 4 "const_int_operand"))
11084 (const_int 0)]))]
11085 "/* Ensure that resulting mask is zero or sign extended operand. */
11086 INTVAL (operands[4]) >= 0
11087 && ((INTVAL (operands[3]) > 0
11088 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
11089 || (<MODE>mode == DImode
11090 && INTVAL (operands[3]) > 32
11091 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
11092 && ix86_match_ccmode (insn,
11093 /* If zero_extract mode precision is the same
11094 as len, the SF of the zero_extract
11095 comparison will be the most significant
11096 extracted bit, but this could be matched
11097 after splitting only for pos 0 len all bits
11098 trivial extractions. Require CCZmode. */
11099 (GET_MODE_PRECISION (<MODE>mode)
11100 == INTVAL (operands[3]))
11101 /* Otherwise, require CCZmode if we'd use a mask
11102 with the most significant bit set and can't
11103 widen it to wider mode. *testdi_1 also
11104 requires CCZmode if the mask has bit
11105 31 set and all bits above it clear. */
11106 || (INTVAL (operands[3]) + INTVAL (operands[4])
11107 >= 32)
11108 /* We can't widen also if val is not a REG. */
11109 || (INTVAL (operands[3]) + INTVAL (operands[4])
11110 == GET_MODE_PRECISION (GET_MODE (operands[2]))
11111 && !register_operand (operands[2],
11112 GET_MODE (operands[2])))
11113 /* And we shouldn't widen if
11114 TARGET_PARTIAL_REG_STALL. */
11115 || (TARGET_PARTIAL_REG_STALL
11116 && (INTVAL (operands[3]) + INTVAL (operands[4])
11117 >= (paradoxical_subreg_p (operands[2])
11118 && (GET_MODE_CLASS
11119 (GET_MODE (SUBREG_REG (operands[2])))
11120 == MODE_INT)
11121 ? GET_MODE_PRECISION
11122 (GET_MODE (SUBREG_REG (operands[2])))
11123 : GET_MODE_PRECISION
11124 (GET_MODE (operands[2])))))
11125 ? CCZmode : CCNOmode)"
11126 "#"
11127 "&& 1"
11128 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11129 {
11130 rtx val = operands[2];
11131 HOST_WIDE_INT len = INTVAL (operands[3]);
11132 HOST_WIDE_INT pos = INTVAL (operands[4]);
11133 machine_mode mode = GET_MODE (val);
11134
11135 if (SUBREG_P (val))
11136 {
11137 machine_mode submode = GET_MODE (SUBREG_REG (val));
11138
11139 /* Narrow paradoxical subregs to prevent partial register stalls. */
11140 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
11141 && GET_MODE_CLASS (submode) == MODE_INT
11142 && (GET_MODE (operands[0]) == CCZmode
11143 || pos + len < GET_MODE_PRECISION (submode)
11144 || REG_P (SUBREG_REG (val))))
11145 {
11146 val = SUBREG_REG (val);
11147 mode = submode;
11148 }
11149 }
11150
11151 /* Small HImode tests can be converted to QImode. */
11152 if (pos + len <= 8
11153 && register_operand (val, HImode))
11154 {
11155 rtx nval = gen_lowpart (QImode, val);
11156 if (!MEM_P (nval)
11157 || GET_MODE (operands[0]) == CCZmode
11158 || pos + len < 8)
11159 {
11160 val = nval;
11161 mode = QImode;
11162 }
11163 }
11164
11165 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
11166
11167 /* If the mask is going to have the sign bit set in the mode
11168 we want to do the comparison in and user isn't interested just
11169 in the zero flag, then we must widen the target mode. */
11170 if (pos + len == GET_MODE_PRECISION (mode)
11171 && GET_MODE (operands[0]) != CCZmode)
11172 {
11173 gcc_assert (pos + len < 32 && !MEM_P (val));
11174 mode = SImode;
11175 val = gen_lowpart (mode, val);
11176 }
11177
11178 wide_int mask
11179 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
11180
11181 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
11182 })
11183
11184 ;; Split and;cmp (as optimized by combine) into not;test
11185 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
11186 (define_insn_and_split "*test<mode>_not"
11187 [(set (reg:CCZ FLAGS_REG)
11188 (compare:CCZ
11189 (and:SWI
11190 (not:SWI (match_operand:SWI 0 "register_operand"))
11191 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
11192 (const_int 0)))]
11193 "ix86_pre_reload_split ()
11194 && (!TARGET_BMI || !REG_P (operands[1]))"
11195 "#"
11196 "&& 1"
11197 [(set (match_dup 2) (not:SWI (match_dup 0)))
11198 (set (reg:CCZ FLAGS_REG)
11199 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
11200 (const_int 0)))]
11201 "operands[2] = gen_reg_rtx (<MODE>mode);")
11202
11203 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
11204 (define_insn_and_split "*test<mode>_not_doubleword"
11205 [(set (reg:CCZ FLAGS_REG)
11206 (compare:CCZ
11207 (and:DWI
11208 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
11209 (match_operand:DWI 1 "nonimmediate_operand"))
11210 (const_int 0)))]
11211 "ix86_pre_reload_split ()"
11212 "#"
11213 "&& 1"
11214 [(parallel
11215 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
11216 (clobber (reg:CC FLAGS_REG))])
11217 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
11218 {
11219 operands[0] = force_reg (<MODE>mode, operands[0]);
11220 operands[2] = gen_reg_rtx (<MODE>mode);
11221 })
11222
11223 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
11224 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
11225 ;; this is relatively important trick.
11226 ;; Do the conversion only post-reload to avoid limiting of the register class
11227 ;; to QI regs.
11228 (define_split
11229 [(set (match_operand 0 "flags_reg_operand")
11230 (match_operator 1 "compare_operator"
11231 [(and (match_operand 2 "QIreg_operand")
11232 (match_operand 3 "const_int_operand"))
11233 (const_int 0)]))]
11234 "reload_completed
11235 && GET_MODE (operands[2]) != QImode
11236 && ((ix86_match_ccmode (insn, CCZmode)
11237 && !(INTVAL (operands[3]) & ~(255 << 8)))
11238 || (ix86_match_ccmode (insn, CCNOmode)
11239 && !(INTVAL (operands[3]) & ~(127 << 8))))"
11240 [(set (match_dup 0)
11241 (match_op_dup 1
11242 [(and:QI
11243 (subreg:QI
11244 (zero_extract:HI (match_dup 2)
11245 (const_int 8)
11246 (const_int 8)) 0)
11247 (match_dup 3))
11248 (const_int 0)]))]
11249 {
11250 operands[2] = gen_lowpart (HImode, operands[2]);
11251 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
11252 })
11253
11254 (define_split
11255 [(set (match_operand 0 "flags_reg_operand")
11256 (match_operator 1 "compare_operator"
11257 [(and (match_operand 2 "nonimmediate_operand")
11258 (match_operand 3 "const_int_operand"))
11259 (const_int 0)]))]
11260 "reload_completed
11261 && GET_MODE (operands[2]) != QImode
11262 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
11263 && ((ix86_match_ccmode (insn, CCZmode)
11264 && !(INTVAL (operands[3]) & ~255))
11265 || (ix86_match_ccmode (insn, CCNOmode)
11266 && !(INTVAL (operands[3]) & ~127)))"
11267 [(set (match_dup 0)
11268 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
11269 (const_int 0)]))]
11270 {
11271 operands[2] = gen_lowpart (QImode, operands[2]);
11272 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
11273 })
11274
11275 ;; Narrow test instructions with immediate operands that test
11276 ;; memory locations for zero. E.g. testl $0x00aa0000, mem can be
11277 ;; converted to testb $0xaa, mem+2. Reject volatile locations and
11278 ;; targets where reading (possibly unaligned) part of memory
11279 ;; location after a large write to the same address causes
11280 ;; store-to-load forwarding stall.
11281 (define_peephole2
11282 [(set (reg:CCZ FLAGS_REG)
11283 (compare:CCZ
11284 (and:SWI248 (match_operand:SWI248 0 "memory_operand")
11285 (match_operand 1 "const_int_operand"))
11286 (const_int 0)))]
11287 "!TARGET_PARTIAL_MEMORY_READ_STALL && !MEM_VOLATILE_P (operands[0])"
11288 [(set (reg:CCZ FLAGS_REG)
11289 (compare:CCZ (match_dup 2) (const_int 0)))]
11290 {
11291 unsigned HOST_WIDE_INT ival = UINTVAL (operands[1]);
11292 int first_nonzero_byte, bitsize;
11293 rtx new_addr, new_const;
11294 machine_mode new_mode;
11295
11296 if (ival == 0)
11297 FAIL;
11298
11299 /* Clear bits outside mode width. */
11300 ival &= GET_MODE_MASK (<MODE>mode);
11301
11302 first_nonzero_byte = ctz_hwi (ival) / BITS_PER_UNIT;
11303
11304 ival >>= first_nonzero_byte * BITS_PER_UNIT;
11305
11306 bitsize = sizeof (ival) * BITS_PER_UNIT - clz_hwi (ival);
11307
11308 if (bitsize <= GET_MODE_BITSIZE (QImode))
11309 new_mode = QImode;
11310 else if (bitsize <= GET_MODE_BITSIZE (HImode))
11311 new_mode = HImode;
11312 else if (bitsize <= GET_MODE_BITSIZE (SImode))
11313 new_mode = SImode;
11314 else
11315 new_mode = DImode;
11316
11317 if (GET_MODE_SIZE (new_mode) >= GET_MODE_SIZE (<MODE>mode))
11318 FAIL;
11319
11320 new_addr = adjust_address (operands[0], new_mode, first_nonzero_byte);
11321 new_const = gen_int_mode (ival, new_mode);
11322
11323 operands[2] = gen_rtx_AND (new_mode, new_addr, new_const);
11324 })
11325
11326 ;; %%% This used to optimize known byte-wide and operations to memory,
11327 ;; and sometimes to QImode registers. If this is considered useful,
11328 ;; it should be done with splitters.
11329
11330 (define_expand "and<mode>3"
11331 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11332 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11333 (match_operand:SDWIM 2 "<general_szext_operand>")))]
11334 ""
11335 {
11336 machine_mode mode = <MODE>mode;
11337
11338 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11339 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11340 operands[2] = force_reg (<MODE>mode, operands[2]);
11341
11342 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11343 && const_int_operand (operands[2], <MODE>mode)
11344 && register_operand (operands[0], <MODE>mode)
11345 && !(TARGET_ZERO_EXTEND_WITH_AND
11346 && optimize_function_for_speed_p (cfun)))
11347 {
11348 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11349
11350 if (ival == GET_MODE_MASK (SImode))
11351 mode = SImode;
11352 else if (ival == GET_MODE_MASK (HImode))
11353 mode = HImode;
11354 else if (ival == GET_MODE_MASK (QImode))
11355 mode = QImode;
11356 }
11357
11358 if (mode != <MODE>mode)
11359 emit_insn (gen_extend_insn
11360 (operands[0], gen_lowpart (mode, operands[1]),
11361 <MODE>mode, mode, 1));
11362 else
11363 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11364
11365 DONE;
11366 })
11367
11368 (define_insn_and_split "*and<dwi>3_doubleword"
11369 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11370 (and:<DWI>
11371 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11372 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11373 (clobber (reg:CC FLAGS_REG))]
11374 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11375 "#"
11376 "&& reload_completed"
11377 [(const_int:DWIH 0)]
11378 {
11379 bool emit_insn_deleted_note_p = false;
11380
11381 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11382
11383 if (operands[2] == const0_rtx)
11384 emit_move_insn (operands[0], const0_rtx);
11385 else if (operands[2] == constm1_rtx)
11386 emit_insn_deleted_note_p = true;
11387 else
11388 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11389
11390 if (operands[5] == const0_rtx)
11391 emit_move_insn (operands[3], const0_rtx);
11392 else if (operands[5] == constm1_rtx)
11393 {
11394 if (emit_insn_deleted_note_p)
11395 emit_note (NOTE_INSN_DELETED);
11396 }
11397 else
11398 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11399
11400 DONE;
11401 })
11402
11403 (define_insn "*anddi_1"
11404 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11405 (and:DI
11406 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11407 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11408 (clobber (reg:CC FLAGS_REG))]
11409 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11410 "@
11411 and{l}\t{%k2, %k0|%k0, %k2}
11412 and{q}\t{%2, %0|%0, %2}
11413 and{q}\t{%2, %0|%0, %2}
11414 #
11415 #"
11416 [(set_attr "isa" "x64,x64,x64,x64,avx512bw_512")
11417 (set_attr "type" "alu,alu,alu,imovx,msklog")
11418 (set_attr "length_immediate" "*,*,*,0,*")
11419 (set (attr "prefix_rex")
11420 (if_then_else
11421 (and (eq_attr "type" "imovx")
11422 (and (match_test "INTVAL (operands[2]) == 0xff")
11423 (match_operand 1 "ext_QIreg_operand")))
11424 (const_string "1")
11425 (const_string "*")))
11426 (set_attr "mode" "SI,DI,DI,SI,DI")])
11427
11428 (define_insn_and_split "*anddi_1_btr"
11429 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11430 (and:DI
11431 (match_operand:DI 1 "nonimmediate_operand" "%0")
11432 (match_operand:DI 2 "const_int_operand" "n")))
11433 (clobber (reg:CC FLAGS_REG))]
11434 "TARGET_64BIT && TARGET_USE_BT
11435 && ix86_binary_operator_ok (AND, DImode, operands)
11436 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11437 "#"
11438 "&& reload_completed"
11439 [(parallel [(set (zero_extract:DI (match_dup 0)
11440 (const_int 1)
11441 (match_dup 3))
11442 (const_int 0))
11443 (clobber (reg:CC FLAGS_REG))])]
11444 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11445 [(set_attr "type" "alu1")
11446 (set_attr "prefix_0f" "1")
11447 (set_attr "znver1_decode" "double")
11448 (set_attr "mode" "DI")])
11449
11450 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11451 (define_split
11452 [(set (match_operand:DI 0 "register_operand")
11453 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11454 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11455 (clobber (reg:CC FLAGS_REG))]
11456 "TARGET_64BIT"
11457 [(parallel [(set (match_dup 0)
11458 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11459 (clobber (reg:CC FLAGS_REG))])]
11460 {
11461 if (GET_CODE (operands[2]) == SYMBOL_REF
11462 || GET_CODE (operands[2]) == LABEL_REF)
11463 {
11464 operands[2] = shallow_copy_rtx (operands[2]);
11465 PUT_MODE (operands[2], SImode);
11466 }
11467 else if (GET_CODE (operands[2]) == CONST)
11468 {
11469 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11470 operands[2] = copy_rtx (operands[2]);
11471 PUT_MODE (operands[2], SImode);
11472 PUT_MODE (XEXP (operands[2], 0), SImode);
11473 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11474 }
11475 else
11476 operands[2] = gen_lowpart (SImode, operands[2]);
11477 })
11478
11479 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11480 (define_insn "*andsi_1_zext"
11481 [(set (match_operand:DI 0 "register_operand" "=r")
11482 (zero_extend:DI
11483 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11484 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11485 (clobber (reg:CC FLAGS_REG))]
11486 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11487 "and{l}\t{%2, %k0|%k0, %2}"
11488 [(set_attr "type" "alu")
11489 (set_attr "mode" "SI")])
11490
11491 (define_insn "*and<mode>_1"
11492 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11493 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11494 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11495 (clobber (reg:CC FLAGS_REG))]
11496 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11497 "@
11498 and{<imodesuffix>}\t{%2, %0|%0, %2}
11499 and{<imodesuffix>}\t{%2, %0|%0, %2}
11500 #
11501 #"
11502 [(set (attr "isa")
11503 (cond [(eq_attr "alternative" "3")
11504 (if_then_else (eq_attr "mode" "SI")
11505 (const_string "avx512bw")
11506 (const_string "avx512f"))
11507 ]
11508 (const_string "*")))
11509 (set_attr "type" "alu,alu,imovx,msklog")
11510 (set_attr "length_immediate" "*,*,0,*")
11511 (set (attr "prefix_rex")
11512 (if_then_else
11513 (and (eq_attr "type" "imovx")
11514 (and (match_test "INTVAL (operands[2]) == 0xff")
11515 (match_operand 1 "ext_QIreg_operand")))
11516 (const_string "1")
11517 (const_string "*")))
11518 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11519
11520 (define_insn "*andqi_1"
11521 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11522 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11523 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11524 (clobber (reg:CC FLAGS_REG))]
11525 "ix86_binary_operator_ok (AND, QImode, operands)"
11526 "@
11527 and{b}\t{%2, %0|%0, %2}
11528 and{b}\t{%2, %0|%0, %2}
11529 and{l}\t{%k2, %k0|%k0, %k2}
11530 #"
11531 [(set_attr "type" "alu,alu,alu,msklog")
11532 (set (attr "mode")
11533 (cond [(eq_attr "alternative" "2")
11534 (const_string "SI")
11535 (and (eq_attr "alternative" "3")
11536 (match_test "!TARGET_AVX512DQ"))
11537 (const_string "HI")
11538 ]
11539 (const_string "QI")))
11540 ;; Potential partial reg stall on alternative 2.
11541 (set (attr "preferred_for_speed")
11542 (cond [(eq_attr "alternative" "2")
11543 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11544 (symbol_ref "true")))])
11545
11546 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11547 (define_insn_and_split "*<code><mode>_1_slp"
11548 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11549 (any_logic:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11550 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11551 (clobber (reg:CC FLAGS_REG))]
11552 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11553 "@
11554 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11555 #"
11556 "&& reload_completed
11557 && !(rtx_equal_p (operands[0], operands[1])
11558 || rtx_equal_p (operands[0], operands[2]))"
11559 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11560 (parallel
11561 [(set (strict_low_part (match_dup 0))
11562 (any_logic:SWI12 (match_dup 0) (match_dup 2)))
11563 (clobber (reg:CC FLAGS_REG))])]
11564 ""
11565 [(set_attr "type" "alu")
11566 (set_attr "mode" "<MODE>")])
11567
11568 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11569 (define_insn_and_split "*<code>qi_ext<mode>_1_slp"
11570 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+Q,&Q"))
11571 (any_logic:QI
11572 (subreg:QI
11573 (match_operator:SWI248 3 "extract_operator"
11574 [(match_operand 2 "int248_register_operand" "Q,Q")
11575 (const_int 8)
11576 (const_int 8)]) 0)
11577 (match_operand:QI 1 "nonimmediate_operand" "0,!qm")))
11578 (clobber (reg:CC FLAGS_REG))]
11579 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11580 "@
11581 <logic>{b}\t{%h2, %0|%0, %h2}
11582 #"
11583 "&& reload_completed
11584 && !rtx_equal_p (operands[0], operands[1])"
11585 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11586 (parallel
11587 [(set (strict_low_part (match_dup 0))
11588 (any_logic:QI
11589 (subreg:QI
11590 (match_op_dup 3
11591 [(match_dup 2) (const_int 8) (const_int 8)]) 0)
11592 (match_dup 0)))
11593 (clobber (reg:CC FLAGS_REG))])]
11594 ""
11595 [(set_attr "type" "alu")
11596 (set_attr "mode" "QI")])
11597
11598 (define_insn_and_split "*<code>qi_ext<mode>_2_slp"
11599 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+&Q"))
11600 (any_logic:QI
11601 (subreg:QI
11602 (match_operator:SWI248 3 "extract_operator"
11603 [(match_operand 1 "int248_register_operand" "Q")
11604 (const_int 8)
11605 (const_int 8)]) 0)
11606 (subreg:QI
11607 (match_operator:SWI248 4 "extract_operator"
11608 [(match_operand 2 "int248_register_operand" "Q")
11609 (const_int 8)
11610 (const_int 8)]) 0)))
11611 (clobber (reg:CC FLAGS_REG))]
11612 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11613 "#"
11614 "&& reload_completed"
11615 [(set (strict_low_part (match_dup 0))
11616 (subreg:QI
11617 (match_op_dup 4
11618 [(match_dup 2) (const_int 8) (const_int 8)]) 0))
11619 (parallel
11620 [(set (strict_low_part (match_dup 0))
11621 (any_logic:QI
11622 (subreg:QI
11623 (match_op_dup 3
11624 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11625 (match_dup 0)))
11626 (clobber (reg:CC FLAGS_REG))])]
11627 ""
11628 [(set_attr "type" "alu")
11629 (set_attr "mode" "QI")])
11630
11631 (define_split
11632 [(set (match_operand:SWI248 0 "register_operand")
11633 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11634 (match_operand:SWI248 2 "const_int_operand")))
11635 (clobber (reg:CC FLAGS_REG))]
11636 "reload_completed
11637 && (!REG_P (operands[1])
11638 || REGNO (operands[0]) != REGNO (operands[1]))"
11639 [(const_int 0)]
11640 {
11641 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11642 machine_mode mode;
11643
11644 if (ival == GET_MODE_MASK (SImode))
11645 mode = SImode;
11646 else if (ival == GET_MODE_MASK (HImode))
11647 mode = HImode;
11648 else if (ival == GET_MODE_MASK (QImode))
11649 mode = QImode;
11650 else
11651 gcc_unreachable ();
11652
11653 /* Zero extend to SImode to avoid partial register stalls. */
11654 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11655 operands[0] = gen_lowpart (SImode, operands[0]);
11656
11657 emit_insn (gen_extend_insn
11658 (operands[0], gen_lowpart (mode, operands[1]),
11659 GET_MODE (operands[0]), mode, 1));
11660 DONE;
11661 })
11662
11663 (define_split
11664 [(set (match_operand:SWI48 0 "register_operand")
11665 (and:SWI48 (match_dup 0)
11666 (const_int -65536)))
11667 (clobber (reg:CC FLAGS_REG))]
11668 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11669 || optimize_function_for_size_p (cfun)"
11670 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11671 "operands[1] = gen_lowpart (HImode, operands[0]);")
11672
11673 (define_split
11674 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11675 (and:SWI248 (match_dup 0)
11676 (const_int -256)))
11677 (clobber (reg:CC FLAGS_REG))]
11678 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11679 && reload_completed"
11680 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11681 "operands[1] = gen_lowpart (QImode, operands[0]);")
11682
11683 (define_split
11684 [(set (match_operand:SWI248 0 "QIreg_operand")
11685 (and:SWI248 (match_dup 0)
11686 (const_int -65281)))
11687 (clobber (reg:CC FLAGS_REG))]
11688 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11689 && reload_completed"
11690 [(parallel
11691 [(set (zero_extract:HI (match_dup 0)
11692 (const_int 8)
11693 (const_int 8))
11694 (subreg:HI
11695 (xor:QI
11696 (subreg:QI
11697 (zero_extract:HI (match_dup 0)
11698 (const_int 8)
11699 (const_int 8)) 0)
11700 (subreg:QI
11701 (zero_extract:HI (match_dup 0)
11702 (const_int 8)
11703 (const_int 8)) 0)) 0))
11704 (clobber (reg:CC FLAGS_REG))])]
11705 "operands[0] = gen_lowpart (HImode, operands[0]);")
11706
11707 (define_insn "*anddi_2"
11708 [(set (reg FLAGS_REG)
11709 (compare
11710 (and:DI
11711 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11712 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11713 (const_int 0)))
11714 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11715 (and:DI (match_dup 1) (match_dup 2)))]
11716 "TARGET_64BIT
11717 && ix86_match_ccmode
11718 (insn,
11719 /* If we are going to emit andl instead of andq, and the operands[2]
11720 constant might have the SImode sign bit set, make sure the sign
11721 flag isn't tested, because the instruction will set the sign flag
11722 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11723 conservatively assume it might have bit 31 set. */
11724 (satisfies_constraint_Z (operands[2])
11725 && (!CONST_INT_P (operands[2])
11726 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11727 ? CCZmode : CCNOmode)
11728 && ix86_binary_operator_ok (AND, DImode, operands)"
11729 "@
11730 and{l}\t{%k2, %k0|%k0, %k2}
11731 and{q}\t{%2, %0|%0, %2}
11732 and{q}\t{%2, %0|%0, %2}"
11733 [(set_attr "type" "alu")
11734 (set_attr "mode" "SI,DI,DI")])
11735
11736 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11737 (define_insn "*andsi_2_zext"
11738 [(set (reg FLAGS_REG)
11739 (compare (and:SI
11740 (match_operand:SI 1 "nonimmediate_operand" "%0")
11741 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11742 (const_int 0)))
11743 (set (match_operand:DI 0 "register_operand" "=r")
11744 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11745 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11746 && ix86_binary_operator_ok (AND, SImode, operands)"
11747 "and{l}\t{%2, %k0|%k0, %2}"
11748 [(set_attr "type" "alu")
11749 (set_attr "mode" "SI")])
11750
11751 (define_insn "*andqi_2_maybe_si"
11752 [(set (reg FLAGS_REG)
11753 (compare (and:QI
11754 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11755 (match_operand:QI 2 "general_operand" "qn,m,n"))
11756 (const_int 0)))
11757 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11758 (and:QI (match_dup 1) (match_dup 2)))]
11759 "ix86_binary_operator_ok (AND, QImode, operands)
11760 && ix86_match_ccmode (insn,
11761 CONST_INT_P (operands[2])
11762 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11763 {
11764 if (get_attr_mode (insn) == MODE_SI)
11765 {
11766 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11767 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11768 return "and{l}\t{%2, %k0|%k0, %2}";
11769 }
11770 return "and{b}\t{%2, %0|%0, %2}";
11771 }
11772 [(set_attr "type" "alu")
11773 (set (attr "mode")
11774 (cond [(eq_attr "alternative" "2")
11775 (const_string "SI")
11776 (and (match_test "optimize_insn_for_size_p ()")
11777 (and (match_operand 0 "ext_QIreg_operand")
11778 (match_operand 2 "const_0_to_127_operand")))
11779 (const_string "SI")
11780 ]
11781 (const_string "QI")))
11782 ;; Potential partial reg stall on alternative 2.
11783 (set (attr "preferred_for_speed")
11784 (cond [(eq_attr "alternative" "2")
11785 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11786 (symbol_ref "true")))])
11787
11788 (define_insn "*and<mode>_2"
11789 [(set (reg FLAGS_REG)
11790 (compare (and:SWI124
11791 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11792 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11793 (const_int 0)))
11794 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11795 (and:SWI124 (match_dup 1) (match_dup 2)))]
11796 "ix86_match_ccmode (insn, CCNOmode)
11797 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11798 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11799 [(set_attr "type" "alu")
11800 (set_attr "mode" "<MODE>")])
11801
11802 (define_insn "*<code>qi_ext<mode>_0"
11803 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBn")
11804 (any_logic:QI
11805 (subreg:QI
11806 (match_operator:SWI248 3 "extract_operator"
11807 [(match_operand 2 "int248_register_operand" "Q")
11808 (const_int 8)
11809 (const_int 8)]) 0)
11810 (match_operand:QI 1 "nonimmediate_operand" "0")))
11811 (clobber (reg:CC FLAGS_REG))]
11812 ""
11813 "<logic>{b}\t{%h2, %0|%0, %h2}"
11814 [(set_attr "addr" "gpr8")
11815 (set_attr "type" "alu")
11816 (set_attr "mode" "QI")])
11817
11818 (define_expand "andqi_ext_1"
11819 [(parallel
11820 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11821 (const_int 8)
11822 (const_int 8))
11823 (subreg:HI
11824 (and:QI
11825 (subreg:QI
11826 (zero_extract:HI (match_operand:HI 1 "register_operand")
11827 (const_int 8)
11828 (const_int 8)) 0)
11829 (match_operand:QI 2 "const_int_operand")) 0))
11830 (clobber (reg:CC FLAGS_REG))])])
11831
11832 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11833 (define_insn_and_split "*<code>qi_ext<mode>_1"
11834 [(set (zero_extract:SWI248
11835 (match_operand 0 "int248_register_operand" "+Q,&Q")
11836 (const_int 8)
11837 (const_int 8))
11838 (subreg:SWI248
11839 (any_logic:QI
11840 (subreg:QI
11841 (match_operator:SWI248 3 "extract_operator"
11842 [(match_operand 1 "int248_register_operand" "0,!Q")
11843 (const_int 8)
11844 (const_int 8)]) 0)
11845 (match_operand:QI 2 "general_operand" "QnBn,QnBn")) 0))
11846 (clobber (reg:CC FLAGS_REG))]
11847 ""
11848 "@
11849 <logic>{b}\t{%2, %h0|%h0, %2}
11850 #"
11851 "reload_completed
11852 && !(rtx_equal_p (operands[0], operands[1]))"
11853 [(set (zero_extract:SWI248
11854 (match_dup 0) (const_int 8) (const_int 8))
11855 (zero_extract:SWI248
11856 (match_dup 1) (const_int 8) (const_int 8)))
11857 (parallel
11858 [(set (zero_extract:SWI248
11859 (match_dup 0) (const_int 8) (const_int 8))
11860 (subreg:SWI248
11861 (any_logic:QI
11862 (subreg:QI
11863 (match_op_dup 3
11864 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11865 (match_dup 2)) 0))
11866 (clobber (reg:CC FLAGS_REG))])]
11867 ""
11868 [(set_attr "addr" "gpr8")
11869 (set_attr "type" "alu")
11870 (set_attr "mode" "QI")])
11871
11872 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11873 (define_insn_and_split "*<code>qi_ext<mode>_1_cc"
11874 [(set (match_operand 4 "flags_reg_operand")
11875 (match_operator 5 "compare_operator"
11876 [(any_logic:QI
11877 (subreg:QI
11878 (match_operator:SWI248 3 "extract_operator"
11879 [(match_operand 1 "int248_register_operand" "0,!Q")
11880 (const_int 8)
11881 (const_int 8)]) 0)
11882 (match_operand:QI 2 "general_operand" "QnBn,QnBn"))
11883 (const_int 0)]))
11884 (set (zero_extract:SWI248
11885 (match_operand 0 "int248_register_operand" "+Q,&Q")
11886 (const_int 8)
11887 (const_int 8))
11888 (subreg:SWI248
11889 (any_logic:QI
11890 (subreg:QI
11891 (match_op_dup 3
11892 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11893 (match_dup 2)) 0))]
11894 "ix86_match_ccmode (insn, CCNOmode)"
11895 "@
11896 <logic>{b}\t{%2, %h0|%h0, %2}
11897 #"
11898 "&& reload_completed
11899 && !(rtx_equal_p (operands[0], operands[1]))"
11900 [(set (zero_extract:SWI248
11901 (match_dup 0) (const_int 8) (const_int 8))
11902 (zero_extract:SWI248
11903 (match_dup 1) (const_int 8) (const_int 8)))
11904 (parallel
11905 [(set (match_dup 4)
11906 (match_op_dup 5
11907 [(any_logic:QI
11908 (subreg:QI
11909 (match_op_dup 3
11910 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11911 (match_dup 2))
11912 (const_int 0)]))
11913 (set (zero_extract:SWI248
11914 (match_dup 0) (const_int 8) (const_int 8))
11915 (subreg:SWI248
11916 (any_logic:QI
11917 (subreg:QI
11918 (match_op_dup 3
11919 [(match_dup 1) (const_int 8) (const_int 8)]) 0)
11920 (match_dup 2)) 0))])]
11921 ""
11922 [(set_attr "addr" "gpr8")
11923 (set_attr "type" "alu")
11924 (set_attr "mode" "QI")])
11925
11926 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11927 (define_insn_and_split "*<code>qi_ext<mode>_2"
11928 [(set (zero_extract:SWI248
11929 (match_operand 0 "int248_register_operand" "+Q,&Q")
11930 (const_int 8)
11931 (const_int 8))
11932 (subreg:SWI248
11933 (any_logic:QI
11934 (subreg:QI
11935 (match_operator:SWI248 3 "extract_operator"
11936 [(match_operand 1 "int248_register_operand" "%0,!Q")
11937 (const_int 8)
11938 (const_int 8)]) 0)
11939 (subreg:QI
11940 (match_operator:SWI248 4 "extract_operator"
11941 [(match_operand 2 "int248_register_operand" "Q,Q")
11942 (const_int 8)
11943 (const_int 8)]) 0)) 0))
11944 (clobber (reg:CC FLAGS_REG))]
11945 ""
11946 "@
11947 <logic>{b}\t{%h2, %h0|%h0, %h2}
11948 #"
11949 "reload_completed
11950 && !(rtx_equal_p (operands[0], operands[1])
11951 || rtx_equal_p (operands[0], operands[2]))"
11952 [(set (zero_extract:SWI248
11953 (match_dup 0) (const_int 8) (const_int 8))
11954 (zero_extract:SWI248
11955 (match_dup 1) (const_int 8) (const_int 8)))
11956 (parallel
11957 [(set (zero_extract:SWI248
11958 (match_dup 0) (const_int 8) (const_int 8))
11959 (subreg:SWI248
11960 (any_logic:QI
11961 (subreg:QI
11962 (match_op_dup 3
11963 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
11964 (subreg:QI
11965 (match_op_dup 4
11966 [(match_dup 2) (const_int 8) (const_int 8)]) 0)) 0))
11967 (clobber (reg:CC FLAGS_REG))])]
11968 ""
11969 [(set_attr "type" "alu")
11970 (set_attr "mode" "QI")])
11971
11972 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11973 (define_insn_and_split "*<code>qi_ext<mode>_3"
11974 [(set (zero_extract:SWI248
11975 (match_operand 0 "int248_register_operand" "+Q,&Q")
11976 (const_int 8)
11977 (const_int 8))
11978 (match_operator:SWI248 3 "extract_operator"
11979 [(any_logic
11980 (match_operand 1 "int248_register_operand" "%0,!Q")
11981 (match_operand 2 "int248_register_operand" "Q,Q"))
11982 (const_int 8)
11983 (const_int 8)]))
11984 (clobber (reg:CC FLAGS_REG))]
11985 "GET_MODE (operands[1]) == GET_MODE (operands[2])"
11986 "@
11987 <logic>{b}\t{%h2, %h0|%h0, %h2}
11988 #"
11989 "&& reload_completed
11990 && !(rtx_equal_p (operands[0], operands[1])
11991 || rtx_equal_p (operands[0], operands[2]))"
11992 [(set (zero_extract:SWI248
11993 (match_dup 0) (const_int 8) (const_int 8))
11994 (zero_extract:SWI248
11995 (match_dup 1) (const_int 8) (const_int 8)))
11996 (parallel
11997 [(set (zero_extract:SWI248
11998 (match_dup 0) (const_int 8) (const_int 8))
11999 (match_op_dup 3
12000 [(any_logic (match_dup 4) (match_dup 2))
12001 (const_int 8) (const_int 8)]))
12002 (clobber (reg:CC FLAGS_REG))])]
12003 "operands[4] = gen_lowpart (GET_MODE (operands[1]), operands[0]);"
12004 [(set_attr "type" "alu")
12005 (set_attr "mode" "QI")])
12006
12007 ;; Convert wide AND instructions with immediate operand to shorter QImode
12008 ;; equivalents when possible.
12009 ;; Don't do the splitting with memory operands, since it introduces risk
12010 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12011 ;; for size, but that can (should?) be handled by generic code instead.
12012 (define_split
12013 [(set (match_operand:SWI248 0 "QIreg_operand")
12014 (and:SWI248 (match_operand:SWI248 1 "register_operand")
12015 (match_operand:SWI248 2 "const_int_operand")))
12016 (clobber (reg:CC FLAGS_REG))]
12017 "reload_completed
12018 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12019 && !(~INTVAL (operands[2]) & ~(255 << 8))"
12020 [(parallel
12021 [(set (zero_extract:HI (match_dup 0)
12022 (const_int 8)
12023 (const_int 8))
12024 (subreg:HI
12025 (and:QI
12026 (subreg:QI
12027 (zero_extract:HI (match_dup 1)
12028 (const_int 8)
12029 (const_int 8)) 0)
12030 (match_dup 2)) 0))
12031 (clobber (reg:CC FLAGS_REG))])]
12032 {
12033 operands[0] = gen_lowpart (HImode, operands[0]);
12034 operands[1] = gen_lowpart (HImode, operands[1]);
12035 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12036 })
12037
12038 ;; Since AND can be encoded with sign extended immediate, this is only
12039 ;; profitable when 7th bit is not set.
12040 (define_split
12041 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12042 (and:SWI248 (match_operand:SWI248 1 "general_operand")
12043 (match_operand:SWI248 2 "const_int_operand")))
12044 (clobber (reg:CC FLAGS_REG))]
12045 "reload_completed
12046 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12047 && !(~INTVAL (operands[2]) & ~255)
12048 && !(INTVAL (operands[2]) & 128)"
12049 [(parallel [(set (strict_low_part (match_dup 0))
12050 (and:QI (match_dup 1)
12051 (match_dup 2)))
12052 (clobber (reg:CC FLAGS_REG))])]
12053 {
12054 operands[0] = gen_lowpart (QImode, operands[0]);
12055 operands[1] = gen_lowpart (QImode, operands[1]);
12056 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12057 })
12058
12059 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
12060 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
12061 (and:<DWI>
12062 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
12063 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
12064 (clobber (reg:CC FLAGS_REG))]
12065 "TARGET_BMI"
12066 "#"
12067 "&& reload_completed"
12068 [(parallel [(set (match_dup 0)
12069 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
12070 (clobber (reg:CC FLAGS_REG))])
12071 (parallel [(set (match_dup 3)
12072 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
12073 (clobber (reg:CC FLAGS_REG))])]
12074 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
12075
12076 (define_insn_and_split "*andn<mode>3_doubleword"
12077 [(set (match_operand:DWI 0 "register_operand")
12078 (and:DWI
12079 (not:DWI (match_operand:DWI 1 "register_operand"))
12080 (match_operand:DWI 2 "nonimmediate_operand")))
12081 (clobber (reg:CC FLAGS_REG))]
12082 "!TARGET_BMI
12083 && ix86_pre_reload_split ()"
12084 "#"
12085 "&& 1"
12086 [(set (match_dup 3) (not:DWI (match_dup 1)))
12087 (parallel [(set (match_dup 0)
12088 (and:DWI (match_dup 3) (match_dup 2)))
12089 (clobber (reg:CC FLAGS_REG))])]
12090 "operands[3] = gen_reg_rtx (<MODE>mode);")
12091
12092 (define_insn "*andn<mode>_1"
12093 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
12094 (and:SWI48
12095 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
12096 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
12097 (clobber (reg:CC FLAGS_REG))]
12098 "TARGET_BMI
12099 || (TARGET_AVX512BW && (<MODE>mode == SImode || TARGET_EVEX512))"
12100 "@
12101 andn\t{%2, %1, %0|%0, %1, %2}
12102 andn\t{%2, %1, %0|%0, %1, %2}
12103 #"
12104 [(set_attr "isa" "bmi,bmi,<kmov_isa>")
12105 (set_attr "type" "bitmanip,bitmanip,msklog")
12106 (set_attr "btver2_decode" "direct, double,*")
12107 (set_attr "mode" "<MODE>")])
12108
12109 (define_insn "*andn<mode>_1"
12110 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
12111 (and:SWI12
12112 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
12113 (match_operand:SWI12 2 "register_operand" "r,k")))
12114 (clobber (reg:CC FLAGS_REG))]
12115 "TARGET_BMI || TARGET_AVX512BW"
12116 "@
12117 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
12118 #"
12119 [(set_attr "isa" "bmi,avx512f")
12120 (set_attr "type" "bitmanip,msklog")
12121 (set_attr "btver2_decode" "direct,*")
12122 (set (attr "mode")
12123 (cond [(eq_attr "alternative" "0")
12124 (const_string "SI")
12125 (and (eq_attr "alternative" "1")
12126 (match_test "!TARGET_AVX512DQ"))
12127 (const_string "HI")
12128 ]
12129 (const_string "<MODE>")))])
12130
12131 (define_insn "*andn_<mode>_ccno"
12132 [(set (reg FLAGS_REG)
12133 (compare
12134 (and:SWI48
12135 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12136 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12137 (const_int 0)))
12138 (clobber (match_scratch:SWI48 0 "=r,r"))]
12139 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12140 "andn\t{%2, %1, %0|%0, %1, %2}"
12141 [(set_attr "type" "bitmanip")
12142 (set_attr "btver2_decode" "direct, double")
12143 (set_attr "mode" "<MODE>")])
12144
12145 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
12146 (define_split
12147 [(set (match_operand:SI 0 "register_operand")
12148 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
12149 (match_operand:SI 2 "nonimmediate_operand")))
12150 (clobber (reg:CC FLAGS_REG))]
12151 "reload_completed
12152 && optimize_insn_for_size_p () && optimize_size > 1
12153 && REGNO (operands[0]) == REGNO (operands[1])
12154 && LEGACY_INT_REG_P (operands[0])
12155 && !REX_INT_REG_P (operands[2])
12156 && !reg_overlap_mentioned_p (operands[0], operands[2])"
12157 [(set (match_dup 0) (not:SI (match_dup 1)))
12158 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
12159 (clobber (reg:CC FLAGS_REG))])])
12160
12161 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
12162 (define_split
12163 [(set (match_operand 0 "flags_reg_operand")
12164 (match_operator 1 "compare_operator"
12165 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
12166 (match_operand:SI 3 "nonimmediate_operand"))
12167 (const_int 0)]))
12168 (clobber (match_dup 2))]
12169 "reload_completed
12170 && optimize_insn_for_size_p () && optimize_size > 1
12171 && LEGACY_INT_REG_P (operands[2])
12172 && !REX_INT_REG_P (operands[3])
12173 && !reg_overlap_mentioned_p (operands[2], operands[3])"
12174 [(set (match_dup 2) (not:SI (match_dup 2)))
12175 (set (match_dup 0) (match_op_dup 1
12176 [(and:SI (match_dup 3) (match_dup 2))
12177 (const_int 0)]))])
12178
12179 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
12180 (define_split
12181 [(set (match_operand:SWI48 0 "register_operand")
12182 (xor:SWI48
12183 (xor:SWI48
12184 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12185 (match_operand:SWI48 2 "nonimmediate_operand"))
12186 (match_dup 1))
12187 (match_operand:SWI48 3 "nonimmediate_operand")))
12188 (clobber (reg:CC FLAGS_REG))]
12189 "TARGET_BMI"
12190 [(parallel
12191 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12192 (clobber (reg:CC FLAGS_REG))])
12193 (parallel
12194 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12195 (clobber (reg:CC FLAGS_REG))])]
12196 "operands[4] = gen_reg_rtx (<MODE>mode);")
12197
12198 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
12199 (define_split
12200 [(set (match_operand:SWI48 0 "register_operand")
12201 (xor:SWI48
12202 (xor:SWI48
12203 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12204 (match_operand:SWI48 2 "register_operand"))
12205 (match_dup 2))
12206 (match_operand:SWI48 3 "nonimmediate_operand")))
12207 (clobber (reg:CC FLAGS_REG))]
12208 "TARGET_BMI"
12209 [(parallel
12210 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12211 (clobber (reg:CC FLAGS_REG))])
12212 (parallel
12213 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12214 (clobber (reg:CC FLAGS_REG))])]
12215 "operands[4] = gen_reg_rtx (<MODE>mode);")
12216
12217 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
12218 (define_split
12219 [(set (match_operand:SWI48 0 "register_operand")
12220 (xor:SWI48
12221 (xor:SWI48
12222 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12223 (match_operand:SWI48 2 "nonimmediate_operand"))
12224 (match_operand:SWI48 3 "nonimmediate_operand"))
12225 (match_dup 1)))
12226 (clobber (reg:CC FLAGS_REG))]
12227 "TARGET_BMI"
12228 [(parallel
12229 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
12230 (clobber (reg:CC FLAGS_REG))])
12231 (parallel
12232 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12233 (clobber (reg:CC FLAGS_REG))])]
12234 "operands[4] = gen_reg_rtx (<MODE>mode);")
12235
12236 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
12237 (define_split
12238 [(set (match_operand:SWI48 0 "register_operand")
12239 (xor:SWI48
12240 (xor:SWI48
12241 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
12242 (match_operand:SWI48 2 "register_operand"))
12243 (match_operand:SWI48 3 "nonimmediate_operand"))
12244 (match_dup 2)))
12245 (clobber (reg:CC FLAGS_REG))]
12246 "TARGET_BMI"
12247 [(parallel
12248 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
12249 (clobber (reg:CC FLAGS_REG))])
12250 (parallel
12251 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
12252 (clobber (reg:CC FLAGS_REG))])]
12253 "operands[4] = gen_reg_rtx (<MODE>mode);")
12254 \f
12255 ;; Logical inclusive and exclusive OR instructions
12256
12257 ;; %%% This used to optimize known byte-wide and operations to memory.
12258 ;; If this is considered useful, it should be done with splitters.
12259
12260 (define_expand "<code><mode>3"
12261 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12262 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
12263 (match_operand:SDWIM 2 "<general_operand>")))]
12264 ""
12265 {
12266 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
12267 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
12268 operands[2] = force_reg (<MODE>mode, operands[2]);
12269
12270 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
12271 DONE;
12272 })
12273
12274 (define_insn_and_split "*<code><dwi>3_doubleword"
12275 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12276 (any_or:<DWI>
12277 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
12278 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
12279 (clobber (reg:CC FLAGS_REG))]
12280 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
12281 "#"
12282 "&& reload_completed"
12283 [(const_int:DWIH 0)]
12284 {
12285 /* This insn may disappear completely when operands[2] == const0_rtx
12286 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
12287 bool emit_insn_deleted_note_p = false;
12288
12289 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12290
12291 if (operands[2] == const0_rtx)
12292 emit_insn_deleted_note_p = true;
12293 else if (operands[2] == constm1_rtx)
12294 {
12295 if (<CODE> == IOR)
12296 emit_move_insn (operands[0], constm1_rtx);
12297 else
12298 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
12299 }
12300 else
12301 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
12302
12303 if (operands[5] == const0_rtx)
12304 {
12305 if (emit_insn_deleted_note_p)
12306 emit_note (NOTE_INSN_DELETED);
12307 }
12308 else if (operands[5] == constm1_rtx)
12309 {
12310 if (<CODE> == IOR)
12311 emit_move_insn (operands[3], constm1_rtx);
12312 else
12313 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
12314 }
12315 else
12316 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
12317
12318 DONE;
12319 })
12320
12321 (define_insn "*<code><mode>_1"
12322 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12323 (any_or:SWI248
12324 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12325 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
12326 (clobber (reg:CC FLAGS_REG))]
12327 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12328 "@
12329 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12330 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12331 #"
12332 [(set_attr "isa" "*,*,<kmov_isa>")
12333 (set_attr "type" "alu, alu, msklog")
12334 (set_attr "mode" "<MODE>")])
12335
12336 (define_insn_and_split "*notxor<mode>_1"
12337 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
12338 (not:SWI248
12339 (xor:SWI248
12340 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
12341 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
12342 (clobber (reg:CC FLAGS_REG))]
12343 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
12344 "#"
12345 "&& reload_completed"
12346 [(parallel
12347 [(set (match_dup 0)
12348 (xor:SWI248 (match_dup 1) (match_dup 2)))
12349 (clobber (reg:CC FLAGS_REG))])
12350 (set (match_dup 0)
12351 (not:SWI248 (match_dup 0)))]
12352 {
12353 if (MASK_REG_P (operands[0]))
12354 {
12355 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
12356 DONE;
12357 }
12358 }
12359 [(set_attr "isa" "*,*,<kmov_isa>")
12360 (set_attr "type" "alu, alu, msklog")
12361 (set_attr "mode" "<MODE>")])
12362
12363 (define_insn_and_split "*iordi_1_bts"
12364 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12365 (ior:DI
12366 (match_operand:DI 1 "nonimmediate_operand" "%0")
12367 (match_operand:DI 2 "const_int_operand" "n")))
12368 (clobber (reg:CC FLAGS_REG))]
12369 "TARGET_64BIT && TARGET_USE_BT
12370 && ix86_binary_operator_ok (IOR, DImode, operands)
12371 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12372 "#"
12373 "&& reload_completed"
12374 [(parallel [(set (zero_extract:DI (match_dup 0)
12375 (const_int 1)
12376 (match_dup 3))
12377 (const_int 1))
12378 (clobber (reg:CC FLAGS_REG))])]
12379 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12380 [(set_attr "type" "alu1")
12381 (set_attr "prefix_0f" "1")
12382 (set_attr "znver1_decode" "double")
12383 (set_attr "mode" "DI")])
12384
12385 (define_insn_and_split "*xordi_1_btc"
12386 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12387 (xor:DI
12388 (match_operand:DI 1 "nonimmediate_operand" "%0")
12389 (match_operand:DI 2 "const_int_operand" "n")))
12390 (clobber (reg:CC FLAGS_REG))]
12391 "TARGET_64BIT && TARGET_USE_BT
12392 && ix86_binary_operator_ok (XOR, DImode, operands)
12393 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
12394 "#"
12395 "&& reload_completed"
12396 [(parallel [(set (zero_extract:DI (match_dup 0)
12397 (const_int 1)
12398 (match_dup 3))
12399 (not:DI (zero_extract:DI (match_dup 0)
12400 (const_int 1)
12401 (match_dup 3))))
12402 (clobber (reg:CC FLAGS_REG))])]
12403 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
12404 [(set_attr "type" "alu1")
12405 (set_attr "prefix_0f" "1")
12406 (set_attr "znver1_decode" "double")
12407 (set_attr "mode" "DI")])
12408
12409 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
12410 (define_insn_and_split "*xor2andn"
12411 [(set (match_operand:SWI248 0 "register_operand")
12412 (xor:SWI248
12413 (and:SWI248
12414 (xor:SWI248
12415 (match_operand:SWI248 1 "nonimmediate_operand")
12416 (match_operand:SWI248 2 "nonimmediate_operand"))
12417 (match_operand:SWI248 3 "nonimmediate_operand"))
12418 (match_dup 1)))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "TARGET_BMI && ix86_pre_reload_split ()"
12421 "#"
12422 "&& 1"
12423 [(parallel [(set (match_dup 4)
12424 (and:SWI248
12425 (not:SWI248
12426 (match_dup 3))
12427 (match_dup 1)))
12428 (clobber (reg:CC FLAGS_REG))])
12429 (parallel [(set (match_dup 5)
12430 (and:SWI248
12431 (match_dup 3)
12432 (match_dup 2)))
12433 (clobber (reg:CC FLAGS_REG))])
12434 (parallel [(set (match_dup 0)
12435 (ior:SWI248
12436 (match_dup 4)
12437 (match_dup 5)))
12438 (clobber (reg:CC FLAGS_REG))])]
12439 {
12440 operands[1] = force_reg (<MODE>mode, operands[1]);
12441 operands[3] = force_reg (<MODE>mode, operands[3]);
12442 operands[4] = gen_reg_rtx (<MODE>mode);
12443 operands[5] = gen_reg_rtx (<MODE>mode);
12444 })
12445
12446 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12447 (define_insn "*<code>si_1_zext"
12448 [(set (match_operand:DI 0 "register_operand" "=r")
12449 (zero_extend:DI
12450 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12451 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
12452 (clobber (reg:CC FLAGS_REG))]
12453 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12454 "<logic>{l}\t{%2, %k0|%k0, %2}"
12455 [(set_attr "type" "alu")
12456 (set_attr "mode" "SI")])
12457
12458 (define_insn "*<code>si_1_zext_imm"
12459 [(set (match_operand:DI 0 "register_operand" "=r")
12460 (any_or:DI
12461 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
12462 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
12463 (clobber (reg:CC FLAGS_REG))]
12464 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12465 "<logic>{l}\t{%2, %k0|%k0, %2}"
12466 [(set_attr "type" "alu")
12467 (set_attr "mode" "SI")])
12468
12469 (define_insn "*<code>qi_1"
12470 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12471 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12472 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
12473 (clobber (reg:CC FLAGS_REG))]
12474 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
12475 "@
12476 <logic>{b}\t{%2, %0|%0, %2}
12477 <logic>{b}\t{%2, %0|%0, %2}
12478 <logic>{l}\t{%k2, %k0|%k0, %k2}
12479 #"
12480 [(set_attr "isa" "*,*,*,avx512f")
12481 (set_attr "type" "alu,alu,alu,msklog")
12482 (set (attr "mode")
12483 (cond [(eq_attr "alternative" "2")
12484 (const_string "SI")
12485 (and (eq_attr "alternative" "3")
12486 (match_test "!TARGET_AVX512DQ"))
12487 (const_string "HI")
12488 ]
12489 (const_string "QI")))
12490 ;; Potential partial reg stall on alternative 2.
12491 (set (attr "preferred_for_speed")
12492 (cond [(eq_attr "alternative" "2")
12493 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12494 (symbol_ref "true")))])
12495
12496 (define_insn_and_split "*notxorqi_1"
12497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12498 (not:QI
12499 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12500 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12501 (clobber (reg:CC FLAGS_REG))]
12502 "ix86_binary_operator_ok (XOR, QImode, operands)"
12503 "#"
12504 "&& reload_completed"
12505 [(parallel
12506 [(set (match_dup 0)
12507 (xor:QI (match_dup 1) (match_dup 2)))
12508 (clobber (reg:CC FLAGS_REG))])
12509 (set (match_dup 0)
12510 (not:QI (match_dup 0)))]
12511 {
12512 if (mask_reg_operand (operands[0], QImode))
12513 {
12514 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12515 DONE;
12516 }
12517 }
12518 [(set_attr "isa" "*,*,*,avx512f")
12519 (set_attr "type" "alu,alu,alu,msklog")
12520 (set (attr "mode")
12521 (cond [(eq_attr "alternative" "2")
12522 (const_string "SI")
12523 (and (eq_attr "alternative" "3")
12524 (match_test "!TARGET_AVX512DQ"))
12525 (const_string "HI")
12526 ]
12527 (const_string "QI")))
12528 ;; Potential partial reg stall on alternative 2.
12529 (set (attr "preferred_for_speed")
12530 (cond [(eq_attr "alternative" "2")
12531 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12532 (symbol_ref "true")))])
12533
12534 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12535 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12536 ;; This eliminates sign extension after logic operation.
12537
12538 (define_split
12539 [(set (match_operand:SWI248 0 "register_operand")
12540 (sign_extend:SWI248
12541 (any_logic:QI (match_operand:QI 1 "memory_operand")
12542 (match_operand:QI 2 "const_int_operand"))))]
12543 ""
12544 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12545 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12546 "operands[3] = gen_reg_rtx (<MODE>mode);")
12547
12548 (define_split
12549 [(set (match_operand:SWI48 0 "register_operand")
12550 (sign_extend:SWI48
12551 (any_logic:HI (match_operand:HI 1 "memory_operand")
12552 (match_operand:HI 2 "const_int_operand"))))]
12553 ""
12554 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12555 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12556 "operands[3] = gen_reg_rtx (<MODE>mode);")
12557
12558 (define_split
12559 [(set (match_operand:DI 0 "register_operand")
12560 (sign_extend:DI
12561 (any_logic:SI (match_operand:SI 1 "memory_operand")
12562 (match_operand:SI 2 "const_int_operand"))))]
12563 "TARGET_64BIT"
12564 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12565 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12566 "operands[3] = gen_reg_rtx (DImode);")
12567
12568 (define_insn "*<code><mode>_2"
12569 [(set (reg FLAGS_REG)
12570 (compare (any_or:SWI
12571 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12572 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12573 (const_int 0)))
12574 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12575 (any_or:SWI (match_dup 1) (match_dup 2)))]
12576 "ix86_match_ccmode (insn, CCNOmode)
12577 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12578 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12579 [(set_attr "type" "alu")
12580 (set_attr "mode" "<MODE>")])
12581
12582 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12583 ;; ??? Special case for immediate operand is missing - it is tricky.
12584 (define_insn "*<code>si_2_zext"
12585 [(set (reg FLAGS_REG)
12586 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12587 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12588 (const_int 0)))
12589 (set (match_operand:DI 0 "register_operand" "=r")
12590 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12591 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12592 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12593 "<logic>{l}\t{%2, %k0|%k0, %2}"
12594 [(set_attr "type" "alu")
12595 (set_attr "mode" "SI")])
12596
12597 (define_insn "*<code>si_2_zext_imm"
12598 [(set (reg FLAGS_REG)
12599 (compare (any_or:SI
12600 (match_operand:SI 1 "nonimmediate_operand" "%0")
12601 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12602 (const_int 0)))
12603 (set (match_operand:DI 0 "register_operand" "=r")
12604 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12605 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12606 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12607 "<logic>{l}\t{%2, %k0|%k0, %2}"
12608 [(set_attr "type" "alu")
12609 (set_attr "mode" "SI")])
12610
12611 (define_insn "*<code><mode>_3"
12612 [(set (reg FLAGS_REG)
12613 (compare (any_or:SWI
12614 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12615 (match_operand:SWI 2 "<general_operand>" "<g>"))
12616 (const_int 0)))
12617 (clobber (match_scratch:SWI 0 "=<r>"))]
12618 "ix86_match_ccmode (insn, CCNOmode)
12619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12620 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12621 [(set_attr "type" "alu")
12622 (set_attr "mode" "<MODE>")])
12623
12624 ;; Convert wide OR instructions with immediate operand to shorter QImode
12625 ;; equivalents when possible.
12626 ;; Don't do the splitting with memory operands, since it introduces risk
12627 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12628 ;; for size, but that can (should?) be handled by generic code instead.
12629 (define_split
12630 [(set (match_operand:SWI248 0 "QIreg_operand")
12631 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12632 (match_operand:SWI248 2 "const_int_operand")))
12633 (clobber (reg:CC FLAGS_REG))]
12634 "reload_completed
12635 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12636 && !(INTVAL (operands[2]) & ~(255 << 8))"
12637 [(parallel
12638 [(set (zero_extract:HI (match_dup 0)
12639 (const_int 8)
12640 (const_int 8))
12641 (subreg:HI
12642 (any_or:QI
12643 (subreg:QI
12644 (zero_extract:HI (match_dup 1)
12645 (const_int 8)
12646 (const_int 8)) 0)
12647 (match_dup 2)) 0))
12648 (clobber (reg:CC FLAGS_REG))])]
12649 {
12650 /* Handle the case where INTVAL (operands[2]) == 0. */
12651 if (operands[2] == const0_rtx)
12652 {
12653 if (!rtx_equal_p (operands[0], operands[1]))
12654 emit_move_insn (operands[0], operands[1]);
12655 else
12656 emit_note (NOTE_INSN_DELETED);
12657 DONE;
12658 }
12659 operands[0] = gen_lowpart (HImode, operands[0]);
12660 operands[1] = gen_lowpart (HImode, operands[1]);
12661 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12662 })
12663
12664 ;; Since OR can be encoded with sign extended immediate, this is only
12665 ;; profitable when 7th bit is set.
12666 (define_split
12667 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12668 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12669 (match_operand:SWI248 2 "const_int_operand")))
12670 (clobber (reg:CC FLAGS_REG))]
12671 "reload_completed
12672 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12673 && !(INTVAL (operands[2]) & ~255)
12674 && (INTVAL (operands[2]) & 128)"
12675 [(parallel [(set (strict_low_part (match_dup 0))
12676 (any_or:QI (match_dup 1)
12677 (match_dup 2)))
12678 (clobber (reg:CC FLAGS_REG))])]
12679 {
12680 operands[0] = gen_lowpart (QImode, operands[0]);
12681 operands[1] = gen_lowpart (QImode, operands[1]);
12682 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12683 })
12684
12685 (define_expand "xorqi_ext_1_cc"
12686 [(parallel
12687 [(set (reg:CCNO FLAGS_REG)
12688 (compare:CCNO
12689 (xor:QI
12690 (subreg:QI
12691 (zero_extract:HI (match_operand:HI 1 "register_operand")
12692 (const_int 8)
12693 (const_int 8)) 0)
12694 (match_operand:QI 2 "const_int_operand"))
12695 (const_int 0)))
12696 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12697 (const_int 8)
12698 (const_int 8))
12699 (subreg:HI
12700 (xor:QI
12701 (subreg:QI
12702 (zero_extract:HI (match_dup 1)
12703 (const_int 8)
12704 (const_int 8)) 0)
12705 (match_dup 2)) 0))])])
12706
12707 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12708 (define_peephole2
12709 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12710 (const_int 0))
12711 (clobber (reg:CC FLAGS_REG))])
12712 (parallel [(set (match_dup 0)
12713 (any_or_plus:SWI (match_dup 0)
12714 (match_operand:SWI 1 "<general_operand>")))
12715 (clobber (reg:CC FLAGS_REG))])]
12716 "!reg_mentioned_p (operands[0], operands[1])"
12717 [(set (match_dup 0) (match_dup 1))])
12718
12719 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12720 (define_peephole2
12721 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12722 (const_int 0))
12723 (clobber (reg:CC FLAGS_REG))])
12724 (parallel [(set (match_dup 0)
12725 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12726 (clobber (reg:CC FLAGS_REG))])]
12727 ""
12728 [(parallel [(set (match_dup 0) (const_int 0))
12729 (clobber (reg:CC FLAGS_REG))])])
12730
12731 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12732 (define_insn_and_split "*concat<mode><dwi>3_1"
12733 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12734 (any_or_plus:<DWI>
12735 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12736 (match_operand:QI 2 "const_int_operand"))
12737 (zero_extend:<DWI>
12738 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12739 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12740 "#"
12741 "&& reload_completed"
12742 [(const_int 0)]
12743 {
12744 split_double_concat (<DWI>mode, operands[0], operands[3],
12745 gen_lowpart (<MODE>mode, operands[1]));
12746 DONE;
12747 })
12748
12749 (define_insn_and_split "*concat<mode><dwi>3_2"
12750 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12751 (any_or_plus:<DWI>
12752 (zero_extend:<DWI>
12753 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12754 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12755 (match_operand:QI 3 "const_int_operand"))))]
12756 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12757 "#"
12758 "&& reload_completed"
12759 [(const_int 0)]
12760 {
12761 split_double_concat (<DWI>mode, operands[0], operands[1],
12762 gen_lowpart (<MODE>mode, operands[2]));
12763 DONE;
12764 })
12765
12766 (define_insn_and_split "*concat<mode><dwi>3_3"
12767 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12768 (any_or_plus:<DWI>
12769 (ashift:<DWI>
12770 (zero_extend:<DWI>
12771 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m,x"))
12772 (match_operand:QI 2 "const_int_operand"))
12773 (zero_extend:<DWI>
12774 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12775 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12776 "#"
12777 "&& reload_completed"
12778 [(const_int 0)]
12779 {
12780 if (SSE_REG_P (operands[0]))
12781 {
12782 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12783 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12784 }
12785 else
12786 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12787 DONE;
12788 }
12789 [(set_attr "isa" "*,*,*,x64,x64")])
12790
12791 (define_insn_and_split "*concat<mode><dwi>3_4"
12792 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12793 (any_or_plus:<DWI>
12794 (zero_extend:<DWI>
12795 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12796 (ashift:<DWI>
12797 (zero_extend:<DWI>
12798 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12799 (match_operand:QI 3 "const_int_operand"))))]
12800 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12801 "#"
12802 "&& reload_completed"
12803 [(const_int 0)]
12804 {
12805 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12806 DONE;
12807 }
12808 [(set_attr "isa" "*,*,*,x64")])
12809
12810 (define_insn_and_split "*concat<half><mode>3_5"
12811 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12812 (any_or_plus:DWI
12813 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12814 (match_operand:QI 2 "const_int_operand"))
12815 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12816 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12817 && (<MODE>mode == DImode
12818 ? CONST_INT_P (operands[3])
12819 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12820 : CONST_INT_P (operands[3])
12821 ? INTVAL (operands[3]) >= 0
12822 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12823 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12824 && !(CONST_INT_P (operands[3])
12825 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12826 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12827 0)),
12828 VOIDmode))"
12829 "#"
12830 "&& reload_completed"
12831 [(const_int 0)]
12832 {
12833 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12834 split_double_concat (<MODE>mode, operands[0], op3,
12835 gen_lowpart (<HALF>mode, operands[1]));
12836 DONE;
12837 }
12838 [(set_attr "isa" "*,nox64,x64")])
12839
12840 (define_insn_and_split "*concat<mode><dwi>3_6"
12841 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12842 (any_or_plus:<DWI>
12843 (ashift:<DWI>
12844 (zero_extend:<DWI>
12845 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12846 (match_operand:QI 2 "const_int_operand"))
12847 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12848 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12849 && (<DWI>mode == DImode
12850 ? CONST_INT_P (operands[3])
12851 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12852 : CONST_INT_P (operands[3])
12853 ? INTVAL (operands[3]) >= 0
12854 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12855 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12856 && !(CONST_INT_P (operands[3])
12857 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12858 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12859 0)),
12860 VOIDmode))"
12861 "#"
12862 "&& reload_completed"
12863 [(const_int 0)]
12864 {
12865 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12866 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12867 DONE;
12868 }
12869 [(set_attr "isa" "*,nox64,x64,*")])
12870
12871 (define_insn_and_split "*concat<mode><dwi>3_7"
12872 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12873 (any_or_plus:<DWI>
12874 (zero_extend:<DWI>
12875 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12876 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12877 "<DWI>mode == DImode
12878 ? CONST_INT_P (operands[2])
12879 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12880 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12881 : CONST_WIDE_INT_P (operands[2])
12882 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12883 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12884 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12885 1)),
12886 VOIDmode)"
12887 "#"
12888 "&& reload_completed"
12889 [(const_int 0)]
12890 {
12891 rtx op2;
12892 if (<DWI>mode == DImode)
12893 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12894 else
12895 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12896 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12897 DONE;
12898 }
12899 [(set_attr "isa" "*,nox64,x64,*")])
12900 \f
12901 ;; Negation instructions
12902
12903 (define_expand "neg<mode>2"
12904 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12905 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12906 ""
12907 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12908
12909 (define_insn_and_split "*neg<dwi>2_doubleword"
12910 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12911 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12914 "#"
12915 "&& reload_completed"
12916 [(parallel
12917 [(set (reg:CCC FLAGS_REG)
12918 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12919 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12920 (parallel
12921 [(set (match_dup 2)
12922 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12923 (match_dup 3))
12924 (const_int 0)))
12925 (clobber (reg:CC FLAGS_REG))])
12926 (parallel
12927 [(set (match_dup 2)
12928 (neg:DWIH (match_dup 2)))
12929 (clobber (reg:CC FLAGS_REG))])]
12930 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12931
12932 ;; Convert:
12933 ;; mov %esi, %edx
12934 ;; negl %eax
12935 ;; adcl $0, %edx
12936 ;; negl %edx
12937 ;; to:
12938 ;; xorl %edx, %edx
12939 ;; negl %eax
12940 ;; sbbl %esi, %edx
12941
12942 (define_peephole2
12943 [(set (match_operand:SWI48 0 "general_reg_operand")
12944 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12945 (parallel
12946 [(set (reg:CCC FLAGS_REG)
12947 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12948 (const_int 0)] UNSPEC_CC_NE))
12949 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12950 (parallel
12951 [(set (match_dup 0)
12952 (plus:SWI48 (plus:SWI48
12953 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12954 (match_dup 0))
12955 (const_int 0)))
12956 (clobber (reg:CC FLAGS_REG))])
12957 (parallel
12958 [(set (match_dup 0)
12959 (neg:SWI48 (match_dup 0)))
12960 (clobber (reg:CC FLAGS_REG))])]
12961 "REGNO (operands[0]) != REGNO (operands[2])
12962 && !reg_mentioned_p (operands[0], operands[1])
12963 && !reg_mentioned_p (operands[2], operands[1])"
12964 [(parallel
12965 [(set (reg:CCC FLAGS_REG)
12966 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12967 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12968 (parallel
12969 [(set (match_dup 0)
12970 (minus:SWI48 (minus:SWI48
12971 (match_dup 0)
12972 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12973 (match_dup 1)))
12974 (clobber (reg:CC FLAGS_REG))])]
12975 "ix86_expand_clear (operands[0]);")
12976
12977 ;; Convert:
12978 ;; xorl %edx, %edx
12979 ;; negl %eax
12980 ;; adcl $0, %edx
12981 ;; negl %edx
12982 ;; to:
12983 ;; negl %eax
12984 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12985
12986 (define_peephole2
12987 [(parallel
12988 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12989 (clobber (reg:CC FLAGS_REG))])
12990 (parallel
12991 [(set (reg:CCC FLAGS_REG)
12992 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12993 (const_int 0)] UNSPEC_CC_NE))
12994 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12995 (parallel
12996 [(set (match_dup 0)
12997 (plus:SWI48 (plus:SWI48
12998 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12999 (match_dup 0))
13000 (const_int 0)))
13001 (clobber (reg:CC FLAGS_REG))])
13002 (parallel
13003 [(set (match_dup 0)
13004 (neg:SWI48 (match_dup 0)))
13005 (clobber (reg:CC FLAGS_REG))])]
13006 "REGNO (operands[0]) != REGNO (operands[1])"
13007 [(parallel
13008 [(set (reg:CCC FLAGS_REG)
13009 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13010 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
13011 (parallel
13012 [(set (match_dup 0)
13013 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
13014 (const_int -1)
13015 (const_int 0)))
13016 (clobber (reg:CC FLAGS_REG))])])
13017
13018 (define_insn "*neg<mode>_1"
13019 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13020 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
13021 (clobber (reg:CC FLAGS_REG))]
13022 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
13023 "neg{<imodesuffix>}\t%0"
13024 [(set_attr "type" "negnot")
13025 (set_attr "mode" "<MODE>")])
13026
13027 (define_insn "*negsi_1_zext"
13028 [(set (match_operand:DI 0 "register_operand" "=r")
13029 (zero_extend:DI
13030 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
13031 (clobber (reg:CC FLAGS_REG))]
13032 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
13033 "neg{l}\t%k0"
13034 [(set_attr "type" "negnot")
13035 (set_attr "mode" "SI")])
13036
13037 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13038 (define_insn_and_split "*neg<mode>_1_slp"
13039 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13040 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13043 "@
13044 neg{<imodesuffix>}\t%0
13045 #"
13046 "&& reload_completed
13047 && !(rtx_equal_p (operands[0], operands[1]))"
13048 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13049 (parallel
13050 [(set (strict_low_part (match_dup 0))
13051 (neg:SWI12 (match_dup 0)))
13052 (clobber (reg:CC FLAGS_REG))])]
13053 ""
13054 [(set_attr "type" "negnot")
13055 (set_attr "mode" "<MODE>")])
13056
13057 (define_insn "*neg<mode>_2"
13058 [(set (reg FLAGS_REG)
13059 (compare
13060 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13061 (const_int 0)))
13062 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13063 (neg:SWI (match_dup 1)))]
13064 "ix86_match_ccmode (insn, CCGOCmode)
13065 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
13066 "neg{<imodesuffix>}\t%0"
13067 [(set_attr "type" "negnot")
13068 (set_attr "mode" "<MODE>")])
13069
13070 (define_insn "*negsi_2_zext"
13071 [(set (reg FLAGS_REG)
13072 (compare
13073 (neg:SI (match_operand:SI 1 "register_operand" "0"))
13074 (const_int 0)))
13075 (set (match_operand:DI 0 "register_operand" "=r")
13076 (zero_extend:DI
13077 (neg:SI (match_dup 1))))]
13078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
13079 && ix86_unary_operator_ok (NEG, SImode, operands)"
13080 "neg{l}\t%k0"
13081 [(set_attr "type" "negnot")
13082 (set_attr "mode" "SI")])
13083
13084 (define_insn "*neg<mode>_ccc_1"
13085 [(set (reg:CCC FLAGS_REG)
13086 (unspec:CCC
13087 [(match_operand:SWI 1 "nonimmediate_operand" "0")
13088 (const_int 0)] UNSPEC_CC_NE))
13089 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13090 (neg:SWI (match_dup 1)))]
13091 ""
13092 "neg{<imodesuffix>}\t%0"
13093 [(set_attr "type" "negnot")
13094 (set_attr "mode" "<MODE>")])
13095
13096 (define_insn "*neg<mode>_ccc_2"
13097 [(set (reg:CCC FLAGS_REG)
13098 (unspec:CCC
13099 [(match_operand:SWI 1 "nonimmediate_operand" "0")
13100 (const_int 0)] UNSPEC_CC_NE))
13101 (clobber (match_scratch:SWI 0 "=<r>"))]
13102 ""
13103 "neg{<imodesuffix>}\t%0"
13104 [(set_attr "type" "negnot")
13105 (set_attr "mode" "<MODE>")])
13106
13107 (define_expand "x86_neg<mode>_ccc"
13108 [(parallel
13109 [(set (reg:CCC FLAGS_REG)
13110 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
13111 (const_int 0)] UNSPEC_CC_NE))
13112 (set (match_operand:SWI48 0 "register_operand")
13113 (neg:SWI48 (match_dup 1)))])])
13114
13115 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13116 (define_insn_and_split "*negqi_ext<mode>_1"
13117 [(set (zero_extract:SWI248
13118 (match_operand 0 "int248_register_operand" "+Q,&Q")
13119 (const_int 8)
13120 (const_int 8))
13121 (subreg:SWI248
13122 (neg:QI
13123 (subreg:QI
13124 (match_operator:SWI248 2 "extract_operator"
13125 [(match_operand 1 "int248_register_operand" "0,!Q")
13126 (const_int 8)
13127 (const_int 8)]) 0)) 0))
13128 (clobber (reg:CC FLAGS_REG))]
13129 ""
13130 "@
13131 neg{b}\t%h0
13132 #"
13133 "reload_completed
13134 && !(rtx_equal_p (operands[0], operands[1]))"
13135 [(set (zero_extract:SWI248
13136 (match_dup 0) (const_int 8) (const_int 8))
13137 (zero_extract:SWI248
13138 (match_dup 1) (const_int 8) (const_int 8)))
13139 (parallel
13140 [(set (zero_extract:SWI248
13141 (match_dup 0) (const_int 8) (const_int 8))
13142 (subreg:SWI248
13143 (neg:QI
13144 (subreg:QI
13145 (match_op_dup 2
13146 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))
13147 (clobber (reg:CC FLAGS_REG))])]
13148 ""
13149 [(set_attr "type" "negnot")
13150 (set_attr "mode" "QI")])
13151
13152 ;; Negate with jump on overflow.
13153 (define_expand "negv<mode>3"
13154 [(parallel [(set (reg:CCO FLAGS_REG)
13155 (unspec:CCO
13156 [(match_operand:SWI 1 "register_operand")
13157 (match_dup 3)] UNSPEC_CC_NE))
13158 (set (match_operand:SWI 0 "register_operand")
13159 (neg:SWI (match_dup 1)))])
13160 (set (pc) (if_then_else
13161 (eq (reg:CCO FLAGS_REG) (const_int 0))
13162 (label_ref (match_operand 2))
13163 (pc)))]
13164 ""
13165 {
13166 operands[3]
13167 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
13168 <MODE>mode);
13169 })
13170
13171 (define_insn "*negv<mode>3"
13172 [(set (reg:CCO FLAGS_REG)
13173 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
13174 (match_operand:SWI 2 "const_int_operand")]
13175 UNSPEC_CC_NE))
13176 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13177 (neg:SWI (match_dup 1)))]
13178 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
13179 && mode_signbit_p (<MODE>mode, operands[2])"
13180 "neg{<imodesuffix>}\t%0"
13181 [(set_attr "type" "negnot")
13182 (set_attr "mode" "<MODE>")])
13183
13184 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
13185 (define_peephole2
13186 [(set (match_operand:SWI 0 "general_reg_operand")
13187 (match_operand:SWI 1 "general_reg_operand"))
13188 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
13189 (clobber (reg:CC FLAGS_REG))])
13190 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
13191 ""
13192 [(set (match_dup 0) (match_dup 1))
13193 (parallel [(set (reg:CCZ FLAGS_REG)
13194 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
13195 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
13196
13197 ;; Special expand pattern to handle integer mode abs
13198
13199 (define_expand "abs<mode>2"
13200 [(parallel
13201 [(set (match_operand:SDWIM 0 "register_operand")
13202 (abs:SDWIM
13203 (match_operand:SDWIM 1 "general_operand")))
13204 (clobber (reg:CC FLAGS_REG))])]
13205 "TARGET_CMOVE
13206 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
13207 {
13208 if (TARGET_EXPAND_ABS)
13209 {
13210 machine_mode mode = <MODE>mode;
13211 operands[1] = force_reg (mode, operands[1]);
13212
13213 /* Generate rtx abs using:
13214 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
13215
13216 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
13217 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
13218 shift_amount, NULL_RTX,
13219 0, OPTAB_DIRECT);
13220 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
13221 operands[0], 0, OPTAB_DIRECT);
13222 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
13223 operands[0], 0, OPTAB_DIRECT);
13224 if (!rtx_equal_p (minus_dst, operands[0]))
13225 emit_move_insn (operands[0], minus_dst);
13226 DONE;
13227 }
13228 })
13229
13230 (define_insn_and_split "*abs<dwi>2_doubleword"
13231 [(set (match_operand:<DWI> 0 "register_operand")
13232 (abs:<DWI>
13233 (match_operand:<DWI> 1 "general_operand")))
13234 (clobber (reg:CC FLAGS_REG))]
13235 "TARGET_CMOVE
13236 && ix86_pre_reload_split ()"
13237 "#"
13238 "&& 1"
13239 [(parallel
13240 [(set (reg:CCC FLAGS_REG)
13241 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13242 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13243 (parallel
13244 [(set (match_dup 5)
13245 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13246 (match_dup 4))
13247 (const_int 0)))
13248 (clobber (reg:CC FLAGS_REG))])
13249 (parallel
13250 [(set (reg:CCGOC FLAGS_REG)
13251 (compare:CCGOC
13252 (neg:DWIH (match_dup 5))
13253 (const_int 0)))
13254 (set (match_dup 5)
13255 (neg:DWIH (match_dup 5)))])
13256 (set (match_dup 0)
13257 (if_then_else:DWIH
13258 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13259 (match_dup 2)
13260 (match_dup 1)))
13261 (set (match_dup 3)
13262 (if_then_else:DWIH
13263 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13264 (match_dup 5)
13265 (match_dup 4)))]
13266 {
13267 operands[1] = force_reg (<DWI>mode, operands[1]);
13268 operands[2] = gen_reg_rtx (<DWI>mode);
13269
13270 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13271 })
13272
13273 (define_insn_and_split "*nabs<dwi>2_doubleword"
13274 [(set (match_operand:<DWI> 0 "register_operand")
13275 (neg:<DWI>
13276 (abs:<DWI>
13277 (match_operand:<DWI> 1 "general_operand"))))
13278 (clobber (reg:CC FLAGS_REG))]
13279 "TARGET_CMOVE
13280 && ix86_pre_reload_split ()"
13281 "#"
13282 "&& 1"
13283 [(parallel
13284 [(set (reg:CCC FLAGS_REG)
13285 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
13286 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
13287 (parallel
13288 [(set (match_dup 5)
13289 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
13290 (match_dup 4))
13291 (const_int 0)))
13292 (clobber (reg:CC FLAGS_REG))])
13293 (parallel
13294 [(set (reg:CCGOC FLAGS_REG)
13295 (compare:CCGOC
13296 (neg:DWIH (match_dup 5))
13297 (const_int 0)))
13298 (set (match_dup 5)
13299 (neg:DWIH (match_dup 5)))])
13300 (set (match_dup 0)
13301 (if_then_else:DWIH
13302 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13303 (match_dup 2)
13304 (match_dup 1)))
13305 (set (match_dup 3)
13306 (if_then_else:DWIH
13307 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13308 (match_dup 5)
13309 (match_dup 4)))]
13310 {
13311 operands[1] = force_reg (<DWI>mode, operands[1]);
13312 operands[2] = gen_reg_rtx (<DWI>mode);
13313
13314 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
13315 })
13316
13317 (define_insn_and_split "*abs<mode>2_1"
13318 [(set (match_operand:SWI 0 "register_operand")
13319 (abs:SWI
13320 (match_operand:SWI 1 "general_operand")))
13321 (clobber (reg:CC FLAGS_REG))]
13322 "TARGET_CMOVE
13323 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13324 && ix86_pre_reload_split ()"
13325 "#"
13326 "&& 1"
13327 [(parallel
13328 [(set (reg:CCGOC FLAGS_REG)
13329 (compare:CCGOC
13330 (neg:SWI (match_dup 1))
13331 (const_int 0)))
13332 (set (match_dup 2)
13333 (neg:SWI (match_dup 1)))])
13334 (set (match_dup 0)
13335 (if_then_else:SWI
13336 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
13337 (match_dup 2)
13338 (match_dup 1)))]
13339 {
13340 operands[1] = force_reg (<MODE>mode, operands[1]);
13341 operands[2] = gen_reg_rtx (<MODE>mode);
13342 })
13343
13344 (define_insn_and_split "*nabs<mode>2_1"
13345 [(set (match_operand:SWI 0 "register_operand")
13346 (neg:SWI
13347 (abs:SWI
13348 (match_operand:SWI 1 "general_operand"))))
13349 (clobber (reg:CC FLAGS_REG))]
13350 "TARGET_CMOVE
13351 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
13352 && ix86_pre_reload_split ()"
13353 "#"
13354 "&& 1"
13355 [(parallel
13356 [(set (reg:CCGOC FLAGS_REG)
13357 (compare:CCGOC
13358 (neg:SWI (match_dup 1))
13359 (const_int 0)))
13360 (set (match_dup 2)
13361 (neg:SWI (match_dup 1)))])
13362 (set (match_dup 0)
13363 (if_then_else:SWI
13364 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13365 (match_dup 2)
13366 (match_dup 1)))]
13367 {
13368 operands[1] = force_reg (<MODE>mode, operands[1]);
13369 operands[2] = gen_reg_rtx (<MODE>mode);
13370 })
13371
13372 (define_expand "<code>tf2"
13373 [(set (match_operand:TF 0 "register_operand")
13374 (absneg:TF (match_operand:TF 1 "register_operand")))]
13375 "TARGET_SSE"
13376 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13377
13378 (define_insn_and_split "*<code>tf2_1"
13379 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13380 (absneg:TF
13381 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13382 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13383 "TARGET_SSE"
13384 "#"
13385 "&& reload_completed"
13386 [(set (match_dup 0)
13387 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13388 {
13389 if (TARGET_AVX)
13390 {
13391 if (MEM_P (operands[1]))
13392 std::swap (operands[1], operands[2]);
13393 }
13394 else
13395 {
13396 if (operands_match_p (operands[0], operands[2]))
13397 std::swap (operands[1], operands[2]);
13398 }
13399 }
13400 [(set_attr "isa" "noavx,noavx,avx,avx")])
13401
13402 (define_insn_and_split "*nabstf2_1"
13403 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13404 (neg:TF
13405 (abs:TF
13406 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13407 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13408 "TARGET_SSE"
13409 "#"
13410 "&& reload_completed"
13411 [(set (match_dup 0)
13412 (ior:TF (match_dup 1) (match_dup 2)))]
13413 {
13414 if (TARGET_AVX)
13415 {
13416 if (MEM_P (operands[1]))
13417 std::swap (operands[1], operands[2]);
13418 }
13419 else
13420 {
13421 if (operands_match_p (operands[0], operands[2]))
13422 std::swap (operands[1], operands[2]);
13423 }
13424 }
13425 [(set_attr "isa" "noavx,noavx,avx,avx")])
13426
13427 (define_expand "<code>hf2"
13428 [(set (match_operand:HF 0 "register_operand")
13429 (absneg:HF (match_operand:HF 1 "register_operand")))]
13430 "TARGET_AVX512FP16"
13431 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13432
13433 (define_expand "<code><mode>2"
13434 [(set (match_operand:X87MODEF 0 "register_operand")
13435 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13436 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13437 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13438
13439 ;; Changing of sign for FP values is doable using integer unit too.
13440 (define_insn "*<code><mode>2_i387_1"
13441 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13442 (absneg:X87MODEF
13443 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13444 (clobber (reg:CC FLAGS_REG))]
13445 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13446 "#")
13447
13448 (define_split
13449 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13450 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13451 (clobber (reg:CC FLAGS_REG))]
13452 "TARGET_80387 && reload_completed"
13453 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13454
13455 (define_split
13456 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13457 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13458 (clobber (reg:CC FLAGS_REG))]
13459 "TARGET_80387 && reload_completed"
13460 [(const_int 0)]
13461 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13462
13463 (define_insn_and_split "*<code>hf2_1"
13464 [(set (match_operand:HF 0 "register_operand" "=Yv")
13465 (absneg:HF
13466 (match_operand:HF 1 "register_operand" "Yv")))
13467 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13468 (clobber (reg:CC FLAGS_REG))]
13469 "TARGET_AVX512FP16"
13470 "#"
13471 "&& reload_completed"
13472 [(set (match_dup 0)
13473 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13474 {
13475 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13476 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13477 })
13478
13479 (define_insn "*<code><mode>2_1"
13480 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13481 (absneg:MODEF
13482 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13483 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13484 (clobber (reg:CC FLAGS_REG))]
13485 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13486 "#"
13487 [(set_attr "isa" "noavx,noavx,avx,*,*")
13488 (set (attr "enabled")
13489 (if_then_else
13490 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13491 (if_then_else
13492 (eq_attr "alternative" "3,4")
13493 (symbol_ref "TARGET_MIX_SSE_I387")
13494 (const_string "*"))
13495 (if_then_else
13496 (eq_attr "alternative" "3,4")
13497 (symbol_ref "true")
13498 (symbol_ref "false"))))])
13499
13500 (define_split
13501 [(set (match_operand:MODEF 0 "sse_reg_operand")
13502 (absneg:MODEF
13503 (match_operand:MODEF 1 "sse_reg_operand")))
13504 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13505 (clobber (reg:CC FLAGS_REG))]
13506 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13507 && reload_completed"
13508 [(set (match_dup 0)
13509 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13510 {
13511 machine_mode mode = <MODE>mode;
13512 machine_mode vmode = <ssevecmodef>mode;
13513
13514 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13515 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13516
13517 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13518 std::swap (operands[1], operands[2]);
13519 })
13520
13521 (define_split
13522 [(set (match_operand:MODEF 0 "fp_register_operand")
13523 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13524 (use (match_operand 2))
13525 (clobber (reg:CC FLAGS_REG))]
13526 "TARGET_80387 && reload_completed"
13527 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13528
13529 (define_split
13530 [(set (match_operand:MODEF 0 "general_reg_operand")
13531 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13532 (use (match_operand 2))
13533 (clobber (reg:CC FLAGS_REG))]
13534 "TARGET_80387 && reload_completed"
13535 [(const_int 0)]
13536 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13537
13538 (define_insn_and_split "*nabs<mode>2_1"
13539 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13540 (neg:MODEF
13541 (abs:MODEF
13542 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13543 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13544 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13545 "#"
13546 "&& reload_completed"
13547 [(set (match_dup 0)
13548 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13549 {
13550 machine_mode mode = <MODE>mode;
13551 machine_mode vmode = <ssevecmodef>mode;
13552
13553 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13554 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13555
13556 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13557 std::swap (operands[1], operands[2]);
13558 }
13559 [(set_attr "isa" "noavx,noavx,avx")])
13560
13561 ;; Conditionalize these after reload. If they match before reload, we
13562 ;; lose the clobber and ability to use integer instructions.
13563
13564 (define_insn "*<code><mode>2_i387"
13565 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13566 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13567 "TARGET_80387 && reload_completed"
13568 "<absneg_mnemonic>"
13569 [(set_attr "type" "fsgn")
13570 (set_attr "mode" "<MODE>")])
13571
13572 ;; Copysign instructions
13573
13574 (define_expand "copysign<mode>3"
13575 [(match_operand:SSEMODEF 0 "register_operand")
13576 (match_operand:SSEMODEF 1 "nonmemory_operand")
13577 (match_operand:SSEMODEF 2 "register_operand")]
13578 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13579 || (TARGET_SSE && (<MODE>mode == TFmode))
13580 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13581 "ix86_expand_copysign (operands); DONE;")
13582
13583 (define_expand "xorsign<mode>3"
13584 [(match_operand:MODEFH 0 "register_operand")
13585 (match_operand:MODEFH 1 "register_operand")
13586 (match_operand:MODEFH 2 "register_operand")]
13587 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13588 || <MODE>mode == HFmode"
13589 {
13590 if (rtx_equal_p (operands[1], operands[2]))
13591 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13592 else
13593 ix86_expand_xorsign (operands);
13594 DONE;
13595 })
13596 \f
13597 ;; One complement instructions
13598
13599 (define_expand "one_cmpl<mode>2"
13600 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13601 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13602 ""
13603 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13604
13605 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13606 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13607 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13608 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13609 "#"
13610 "&& reload_completed"
13611 [(set (match_dup 0)
13612 (not:DWIH (match_dup 1)))
13613 (set (match_dup 2)
13614 (not:DWIH (match_dup 3)))]
13615 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13616
13617 (define_insn "*one_cmpl<mode>2_1"
13618 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13619 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13620 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13621 "@
13622 not{<imodesuffix>}\t%0
13623 #"
13624 [(set_attr "isa" "*,<kmov_isa>")
13625 (set_attr "type" "negnot,msklog")
13626 (set_attr "mode" "<MODE>")])
13627
13628 (define_insn "*one_cmplsi2_1_zext"
13629 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13630 (zero_extend:DI
13631 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13632 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13633 "@
13634 not{l}\t%k0
13635 #"
13636 [(set_attr "isa" "x64,avx512bw_512")
13637 (set_attr "type" "negnot,msklog")
13638 (set_attr "mode" "SI,SI")])
13639
13640 (define_insn "*one_cmplqi2_1"
13641 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13642 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13643 "ix86_unary_operator_ok (NOT, QImode, operands)"
13644 "@
13645 not{b}\t%0
13646 not{l}\t%k0
13647 #"
13648 [(set_attr "isa" "*,*,avx512f")
13649 (set_attr "type" "negnot,negnot,msklog")
13650 (set (attr "mode")
13651 (cond [(eq_attr "alternative" "1")
13652 (const_string "SI")
13653 (and (eq_attr "alternative" "2")
13654 (match_test "!TARGET_AVX512DQ"))
13655 (const_string "HI")
13656 ]
13657 (const_string "QI")))
13658 ;; Potential partial reg stall on alternative 1.
13659 (set (attr "preferred_for_speed")
13660 (cond [(eq_attr "alternative" "1")
13661 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13662 (symbol_ref "true")))])
13663
13664 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13665 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13666 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13667 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13668 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13669 "@
13670 not{<imodesuffix>}\t%0
13671 #"
13672 "&& reload_completed
13673 && !(rtx_equal_p (operands[0], operands[1]))"
13674 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13675 (set (strict_low_part (match_dup 0))
13676 (not:SWI12 (match_dup 0)))]
13677 ""
13678 [(set_attr "type" "negnot")
13679 (set_attr "mode" "<MODE>")])
13680
13681 (define_insn "*one_cmpl<mode>2_2"
13682 [(set (reg FLAGS_REG)
13683 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13684 (const_int 0)))
13685 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13686 (not:SWI (match_dup 1)))]
13687 "ix86_match_ccmode (insn, CCNOmode)
13688 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13689 "#"
13690 [(set_attr "type" "alu1")
13691 (set_attr "mode" "<MODE>")])
13692
13693 (define_split
13694 [(set (match_operand 0 "flags_reg_operand")
13695 (match_operator 2 "compare_operator"
13696 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13697 (const_int 0)]))
13698 (set (match_operand:SWI 1 "nonimmediate_operand")
13699 (not:SWI (match_dup 3)))]
13700 "ix86_match_ccmode (insn, CCNOmode)"
13701 [(parallel [(set (match_dup 0)
13702 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13703 (const_int 0)]))
13704 (set (match_dup 1)
13705 (xor:SWI (match_dup 3) (const_int -1)))])])
13706
13707 (define_insn "*one_cmplsi2_2_zext"
13708 [(set (reg FLAGS_REG)
13709 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13710 (const_int 0)))
13711 (set (match_operand:DI 0 "register_operand" "=r")
13712 (zero_extend:DI (not:SI (match_dup 1))))]
13713 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13714 && ix86_unary_operator_ok (NOT, SImode, operands)"
13715 "#"
13716 [(set_attr "type" "alu1")
13717 (set_attr "mode" "SI")])
13718
13719 (define_split
13720 [(set (match_operand 0 "flags_reg_operand")
13721 (match_operator 2 "compare_operator"
13722 [(not:SI (match_operand:SI 3 "register_operand"))
13723 (const_int 0)]))
13724 (set (match_operand:DI 1 "register_operand")
13725 (zero_extend:DI (not:SI (match_dup 3))))]
13726 "ix86_match_ccmode (insn, CCNOmode)"
13727 [(parallel [(set (match_dup 0)
13728 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13729 (const_int 0)]))
13730 (set (match_dup 1)
13731 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13732
13733 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13734 (define_insn_and_split "*one_cmplqi_ext<mode>_1"
13735 [(set (zero_extract:SWI248
13736 (match_operand 0 "int248_register_operand" "+Q,&Q")
13737 (const_int 8)
13738 (const_int 8))
13739 (subreg:SWI248
13740 (not:QI
13741 (subreg:QI
13742 (match_operator:SWI248 2 "extract_operator"
13743 [(match_operand 1 "int248_register_operand" "0,!Q")
13744 (const_int 8)
13745 (const_int 8)]) 0)) 0))]
13746 ""
13747 "@
13748 not{b}\t%h0
13749 #"
13750 "reload_completed
13751 && !(rtx_equal_p (operands[0], operands[1]))"
13752 [(set (zero_extract:SWI248
13753 (match_dup 0) (const_int 8) (const_int 8))
13754 (zero_extract:SWI248
13755 (match_dup 1) (const_int 8) (const_int 8)))
13756 (set (zero_extract:SWI248
13757 (match_dup 0) (const_int 8) (const_int 8))
13758 (subreg:SWI248
13759 (not:QI
13760 (subreg:QI
13761 (match_op_dup 2
13762 [(match_dup 0) (const_int 8) (const_int 8)]) 0)) 0))]
13763 ""
13764 [(set_attr "type" "negnot")
13765 (set_attr "mode" "QI")])
13766 \f
13767 ;; Shift instructions
13768
13769 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13770 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13771 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13772 ;; from the assembler input.
13773 ;;
13774 ;; This instruction shifts the target reg/mem as usual, but instead of
13775 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13776 ;; is a left shift double, bits are taken from the high order bits of
13777 ;; reg, else if the insn is a shift right double, bits are taken from the
13778 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13779 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13780 ;;
13781 ;; Since sh[lr]d does not change the `reg' operand, that is done
13782 ;; separately, making all shifts emit pairs of shift double and normal
13783 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13784 ;; support a 63 bit shift, each shift where the count is in a reg expands
13785 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13786 ;;
13787 ;; If the shift count is a constant, we need never emit more than one
13788 ;; shift pair, instead using moves and sign extension for counts greater
13789 ;; than 31.
13790
13791 (define_expand "ashl<mode>3"
13792 [(set (match_operand:SDWIM 0 "<shift_operand>")
13793 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13794 (match_operand:QI 2 "nonmemory_operand")))]
13795 ""
13796 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13797
13798 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13799 [(set (match_operand:<DWI> 0 "register_operand")
13800 (ashift:<DWI>
13801 (match_operand:<DWI> 1 "register_operand")
13802 (subreg:QI
13803 (and
13804 (match_operand 2 "int248_register_operand" "c")
13805 (match_operand 3 "const_int_operand")) 0)))
13806 (clobber (reg:CC FLAGS_REG))]
13807 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13808 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13809 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13810 && ix86_pre_reload_split ()"
13811 "#"
13812 "&& 1"
13813 [(parallel
13814 [(set (match_dup 6)
13815 (ior:DWIH (ashift:DWIH (match_dup 6)
13816 (and:QI (match_dup 2) (match_dup 8)))
13817 (subreg:DWIH
13818 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13819 (minus:QI (match_dup 9)
13820 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13821 (clobber (reg:CC FLAGS_REG))])
13822 (parallel
13823 [(set (match_dup 4)
13824 (ashift:DWIH (match_dup 5) (match_dup 2)))
13825 (clobber (reg:CC FLAGS_REG))])]
13826 {
13827 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13828 {
13829 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13830 operands[2] = gen_lowpart (QImode, operands[2]);
13831 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13832 operands[2]));
13833 DONE;
13834 }
13835
13836 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13837
13838 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13839 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13840
13841 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13842 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13843 {
13844 rtx xops[3];
13845 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13846 xops[1] = operands[2];
13847 xops[2] = GEN_INT (INTVAL (operands[3])
13848 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13849 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13850 operands[2] = xops[0];
13851 }
13852
13853 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13854 operands[2] = gen_lowpart (QImode, operands[2]);
13855
13856 if (!rtx_equal_p (operands[6], operands[7]))
13857 emit_move_insn (operands[6], operands[7]);
13858 })
13859
13860 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13861 [(set (match_operand:<DWI> 0 "register_operand")
13862 (ashift:<DWI>
13863 (match_operand:<DWI> 1 "register_operand")
13864 (and:QI
13865 (match_operand:QI 2 "register_operand" "c")
13866 (match_operand:QI 3 "const_int_operand"))))
13867 (clobber (reg:CC FLAGS_REG))]
13868 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13869 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13870 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13871 && ix86_pre_reload_split ()"
13872 "#"
13873 "&& 1"
13874 [(parallel
13875 [(set (match_dup 6)
13876 (ior:DWIH (ashift:DWIH (match_dup 6)
13877 (and:QI (match_dup 2) (match_dup 8)))
13878 (subreg:DWIH
13879 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13880 (minus:QI (match_dup 9)
13881 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13882 (clobber (reg:CC FLAGS_REG))])
13883 (parallel
13884 [(set (match_dup 4)
13885 (ashift:DWIH (match_dup 5) (match_dup 2)))
13886 (clobber (reg:CC FLAGS_REG))])]
13887 {
13888 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13889 {
13890 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13891 operands[2]));
13892 DONE;
13893 }
13894
13895 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13896
13897 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13898 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13899
13900 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13901 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13902 {
13903 rtx tem = gen_reg_rtx (QImode);
13904 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13905 operands[2] = tem;
13906 }
13907
13908 if (!rtx_equal_p (operands[6], operands[7]))
13909 emit_move_insn (operands[6], operands[7]);
13910 })
13911
13912 (define_insn "ashl<mode>3_doubleword"
13913 [(set (match_operand:DWI 0 "register_operand" "=&r")
13914 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13915 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13916 (clobber (reg:CC FLAGS_REG))]
13917 ""
13918 "#"
13919 [(set_attr "type" "multi")])
13920
13921 (define_split
13922 [(set (match_operand:DWI 0 "register_operand")
13923 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13924 (match_operand:QI 2 "nonmemory_operand")))
13925 (clobber (reg:CC FLAGS_REG))]
13926 "epilogue_completed"
13927 [(const_int 0)]
13928 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13929
13930 ;; By default we don't ask for a scratch register, because when DWImode
13931 ;; values are manipulated, registers are already at a premium. But if
13932 ;; we have one handy, we won't turn it away.
13933
13934 (define_peephole2
13935 [(match_scratch:DWIH 3 "r")
13936 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13937 (ashift:<DWI>
13938 (match_operand:<DWI> 1 "nonmemory_operand")
13939 (match_operand:QI 2 "nonmemory_operand")))
13940 (clobber (reg:CC FLAGS_REG))])
13941 (match_dup 3)]
13942 "TARGET_CMOVE"
13943 [(const_int 0)]
13944 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13945
13946 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13947 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13948 (ashift:<DWI>
13949 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13950 (match_operand:QI 2 "const_int_operand")))
13951 (clobber (reg:CC FLAGS_REG))]
13952 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13953 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13954 "#"
13955 "&& reload_completed"
13956 [(const_int 0)]
13957 {
13958 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13959 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13960 if (!rtx_equal_p (operands[3], operands[1]))
13961 emit_move_insn (operands[3], operands[1]);
13962 if (bits > 0)
13963 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13964 ix86_expand_clear (operands[0]);
13965 DONE;
13966 })
13967
13968 (define_insn "x86_64_shld"
13969 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13970 (ior:DI (ashift:DI (match_dup 0)
13971 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13972 (const_int 63)))
13973 (subreg:DI
13974 (lshiftrt:TI
13975 (zero_extend:TI
13976 (match_operand:DI 1 "register_operand" "r"))
13977 (minus:QI (const_int 64)
13978 (and:QI (match_dup 2) (const_int 63)))) 0)))
13979 (clobber (reg:CC FLAGS_REG))]
13980 "TARGET_64BIT"
13981 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13982 [(set_attr "type" "ishift")
13983 (set_attr "prefix_0f" "1")
13984 (set_attr "mode" "DI")
13985 (set_attr "athlon_decode" "vector")
13986 (set_attr "amdfam10_decode" "vector")
13987 (set_attr "bdver1_decode" "vector")])
13988
13989 (define_insn "x86_64_shld_1"
13990 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13991 (ior:DI (ashift:DI (match_dup 0)
13992 (match_operand:QI 2 "const_0_to_63_operand"))
13993 (subreg:DI
13994 (lshiftrt:TI
13995 (zero_extend:TI
13996 (match_operand:DI 1 "register_operand" "r"))
13997 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13998 (clobber (reg:CC FLAGS_REG))]
13999 "TARGET_64BIT
14000 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14001 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
14002 [(set_attr "type" "ishift")
14003 (set_attr "prefix_0f" "1")
14004 (set_attr "mode" "DI")
14005 (set_attr "length_immediate" "1")
14006 (set_attr "athlon_decode" "vector")
14007 (set_attr "amdfam10_decode" "vector")
14008 (set_attr "bdver1_decode" "vector")])
14009
14010 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
14011 [(set (match_operand:DI 0 "nonimmediate_operand")
14012 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
14013 (match_operand:QI 2 "const_0_to_63_operand"))
14014 (lshiftrt:DI
14015 (match_operand:DI 1 "nonimmediate_operand")
14016 (match_operand:QI 3 "const_0_to_63_operand"))))
14017 (clobber (reg:CC FLAGS_REG))]
14018 "TARGET_64BIT
14019 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14020 && ix86_pre_reload_split ()"
14021 "#"
14022 "&& 1"
14023 [(const_int 0)]
14024 {
14025 if (rtx_equal_p (operands[4], operands[0]))
14026 {
14027 operands[1] = force_reg (DImode, operands[1]);
14028 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14029 }
14030 else if (rtx_equal_p (operands[1], operands[0]))
14031 {
14032 operands[4] = force_reg (DImode, operands[4]);
14033 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14034 }
14035 else
14036 {
14037 operands[1] = force_reg (DImode, operands[1]);
14038 rtx tmp = gen_reg_rtx (DImode);
14039 emit_move_insn (tmp, operands[4]);
14040 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
14041 emit_move_insn (operands[0], tmp);
14042 }
14043 DONE;
14044 })
14045
14046 (define_insn_and_split "*x86_64_shld_2"
14047 [(set (match_operand:DI 0 "nonimmediate_operand")
14048 (ior:DI (ashift:DI (match_dup 0)
14049 (match_operand:QI 2 "nonmemory_operand"))
14050 (lshiftrt:DI (match_operand:DI 1 "register_operand")
14051 (minus:QI (const_int 64) (match_dup 2)))))
14052 (clobber (reg:CC FLAGS_REG))]
14053 "TARGET_64BIT && ix86_pre_reload_split ()"
14054 "#"
14055 "&& 1"
14056 [(parallel [(set (match_dup 0)
14057 (ior:DI (ashift:DI (match_dup 0)
14058 (and:QI (match_dup 2) (const_int 63)))
14059 (subreg:DI
14060 (lshiftrt:TI
14061 (zero_extend:TI (match_dup 1))
14062 (minus:QI (const_int 64)
14063 (and:QI (match_dup 2)
14064 (const_int 63)))) 0)))
14065 (clobber (reg:CC FLAGS_REG))])])
14066
14067 (define_insn "x86_shld"
14068 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14069 (ior:SI (ashift:SI (match_dup 0)
14070 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14071 (const_int 31)))
14072 (subreg:SI
14073 (lshiftrt:DI
14074 (zero_extend:DI
14075 (match_operand:SI 1 "register_operand" "r"))
14076 (minus:QI (const_int 32)
14077 (and:QI (match_dup 2) (const_int 31)))) 0)))
14078 (clobber (reg:CC FLAGS_REG))]
14079 ""
14080 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
14081 [(set_attr "type" "ishift")
14082 (set_attr "prefix_0f" "1")
14083 (set_attr "mode" "SI")
14084 (set_attr "pent_pair" "np")
14085 (set_attr "athlon_decode" "vector")
14086 (set_attr "amdfam10_decode" "vector")
14087 (set_attr "bdver1_decode" "vector")])
14088
14089 (define_insn "x86_shld_1"
14090 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14091 (ior:SI (ashift:SI (match_dup 0)
14092 (match_operand:QI 2 "const_0_to_31_operand"))
14093 (subreg:SI
14094 (lshiftrt:DI
14095 (zero_extend:DI
14096 (match_operand:SI 1 "register_operand" "r"))
14097 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14098 (clobber (reg:CC FLAGS_REG))]
14099 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14100 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
14101 [(set_attr "type" "ishift")
14102 (set_attr "prefix_0f" "1")
14103 (set_attr "length_immediate" "1")
14104 (set_attr "mode" "SI")
14105 (set_attr "pent_pair" "np")
14106 (set_attr "athlon_decode" "vector")
14107 (set_attr "amdfam10_decode" "vector")
14108 (set_attr "bdver1_decode" "vector")])
14109
14110 (define_insn_and_split "*x86_shld_shrd_1_nozext"
14111 [(set (match_operand:SI 0 "nonimmediate_operand")
14112 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
14113 (match_operand:QI 2 "const_0_to_31_operand"))
14114 (lshiftrt:SI
14115 (match_operand:SI 1 "nonimmediate_operand")
14116 (match_operand:QI 3 "const_0_to_31_operand"))))
14117 (clobber (reg:CC FLAGS_REG))]
14118 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14119 && ix86_pre_reload_split ()"
14120 "#"
14121 "&& 1"
14122 [(const_int 0)]
14123 {
14124 if (rtx_equal_p (operands[4], operands[0]))
14125 {
14126 operands[1] = force_reg (SImode, operands[1]);
14127 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
14128 }
14129 else if (rtx_equal_p (operands[1], operands[0]))
14130 {
14131 operands[4] = force_reg (SImode, operands[4]);
14132 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
14133 }
14134 else
14135 {
14136 operands[1] = force_reg (SImode, operands[1]);
14137 rtx tmp = gen_reg_rtx (SImode);
14138 emit_move_insn (tmp, operands[4]);
14139 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
14140 emit_move_insn (operands[0], tmp);
14141 }
14142 DONE;
14143 })
14144
14145 (define_insn_and_split "*x86_shld_2"
14146 [(set (match_operand:SI 0 "nonimmediate_operand")
14147 (ior:SI (ashift:SI (match_dup 0)
14148 (match_operand:QI 2 "nonmemory_operand"))
14149 (lshiftrt:SI (match_operand:SI 1 "register_operand")
14150 (minus:QI (const_int 32) (match_dup 2)))))
14151 (clobber (reg:CC FLAGS_REG))]
14152 "TARGET_64BIT && ix86_pre_reload_split ()"
14153 "#"
14154 "&& 1"
14155 [(parallel [(set (match_dup 0)
14156 (ior:SI (ashift:SI (match_dup 0)
14157 (and:QI (match_dup 2) (const_int 31)))
14158 (subreg:SI
14159 (lshiftrt:DI
14160 (zero_extend:DI (match_dup 1))
14161 (minus:QI (const_int 32)
14162 (and:QI (match_dup 2)
14163 (const_int 31)))) 0)))
14164 (clobber (reg:CC FLAGS_REG))])])
14165
14166 (define_expand "@x86_shift<mode>_adj_1"
14167 [(set (reg:CCZ FLAGS_REG)
14168 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
14169 (match_dup 4))
14170 (const_int 0)))
14171 (set (match_operand:SWI48 0 "register_operand")
14172 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14173 (match_operand:SWI48 1 "register_operand")
14174 (match_dup 0)))
14175 (set (match_dup 1)
14176 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
14177 (match_operand:SWI48 3 "register_operand")
14178 (match_dup 1)))]
14179 "TARGET_CMOVE"
14180 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
14181
14182 (define_expand "@x86_shift<mode>_adj_2"
14183 [(use (match_operand:SWI48 0 "register_operand"))
14184 (use (match_operand:SWI48 1 "register_operand"))
14185 (use (match_operand:QI 2 "register_operand"))]
14186 ""
14187 {
14188 rtx_code_label *label = gen_label_rtx ();
14189 rtx tmp;
14190
14191 emit_insn (gen_testqi_ccz_1 (operands[2],
14192 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14193
14194 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14195 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14196 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14197 gen_rtx_LABEL_REF (VOIDmode, label),
14198 pc_rtx);
14199 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14200 JUMP_LABEL (tmp) = label;
14201
14202 emit_move_insn (operands[0], operands[1]);
14203 ix86_expand_clear (operands[1]);
14204
14205 emit_label (label);
14206 LABEL_NUSES (label) = 1;
14207
14208 DONE;
14209 })
14210
14211 ;; Avoid useless masking of count operand.
14212 (define_insn_and_split "*ashl<mode>3_mask"
14213 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14214 (ashift:SWI48
14215 (match_operand:SWI48 1 "nonimmediate_operand")
14216 (subreg:QI
14217 (and
14218 (match_operand 2 "int248_register_operand" "c,r")
14219 (match_operand 3 "const_int_operand")) 0)))
14220 (clobber (reg:CC FLAGS_REG))]
14221 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14222 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14223 == GET_MODE_BITSIZE (<MODE>mode)-1
14224 && ix86_pre_reload_split ()"
14225 "#"
14226 "&& 1"
14227 [(parallel
14228 [(set (match_dup 0)
14229 (ashift:SWI48 (match_dup 1)
14230 (match_dup 2)))
14231 (clobber (reg:CC FLAGS_REG))])]
14232 {
14233 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14234 operands[2] = gen_lowpart (QImode, operands[2]);
14235 }
14236 [(set_attr "isa" "*,bmi2")])
14237
14238 (define_insn_and_split "*ashl<mode>3_mask_1"
14239 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14240 (ashift:SWI48
14241 (match_operand:SWI48 1 "nonimmediate_operand")
14242 (and:QI
14243 (match_operand:QI 2 "register_operand" "c,r")
14244 (match_operand:QI 3 "const_int_operand"))))
14245 (clobber (reg:CC FLAGS_REG))]
14246 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
14247 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14248 == GET_MODE_BITSIZE (<MODE>mode)-1
14249 && ix86_pre_reload_split ()"
14250 "#"
14251 "&& 1"
14252 [(parallel
14253 [(set (match_dup 0)
14254 (ashift:SWI48 (match_dup 1)
14255 (match_dup 2)))
14256 (clobber (reg:CC FLAGS_REG))])]
14257 ""
14258 [(set_attr "isa" "*,bmi2")])
14259
14260 (define_insn "*bmi2_ashl<mode>3_1"
14261 [(set (match_operand:SWI48 0 "register_operand" "=r")
14262 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14263 (match_operand:SWI48 2 "register_operand" "r")))]
14264 "TARGET_BMI2"
14265 "shlx\t{%2, %1, %0|%0, %1, %2}"
14266 [(set_attr "type" "ishiftx")
14267 (set_attr "mode" "<MODE>")])
14268
14269 (define_insn "*ashl<mode>3_1"
14270 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
14271 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
14272 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
14273 (clobber (reg:CC FLAGS_REG))]
14274 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14275 {
14276 switch (get_attr_type (insn))
14277 {
14278 case TYPE_LEA:
14279 case TYPE_ISHIFTX:
14280 case TYPE_MSKLOG:
14281 return "#";
14282
14283 case TYPE_ALU:
14284 gcc_assert (operands[2] == const1_rtx);
14285 gcc_assert (rtx_equal_p (operands[0], operands[1]));
14286 return "add{<imodesuffix>}\t%0, %0";
14287
14288 default:
14289 if (operands[2] == const1_rtx
14290 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14291 return "sal{<imodesuffix>}\t%0";
14292 else
14293 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14294 }
14295 }
14296 [(set_attr "isa" "*,*,bmi2,<kmov_isa>")
14297 (set (attr "type")
14298 (cond [(eq_attr "alternative" "1")
14299 (const_string "lea")
14300 (eq_attr "alternative" "2")
14301 (const_string "ishiftx")
14302 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14303 (match_operand 0 "register_operand"))
14304 (match_operand 2 "const1_operand"))
14305 (const_string "alu")
14306 (eq_attr "alternative" "3")
14307 (const_string "msklog")
14308 ]
14309 (const_string "ishift")))
14310 (set (attr "length_immediate")
14311 (if_then_else
14312 (ior (eq_attr "type" "alu")
14313 (and (eq_attr "type" "ishift")
14314 (and (match_operand 2 "const1_operand")
14315 (ior (match_test "TARGET_SHIFT1")
14316 (match_test "optimize_function_for_size_p (cfun)")))))
14317 (const_string "0")
14318 (const_string "*")))
14319 (set_attr "mode" "<MODE>")])
14320
14321 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14322 (define_split
14323 [(set (match_operand:SWI48 0 "register_operand")
14324 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14325 (match_operand:QI 2 "register_operand")))
14326 (clobber (reg:CC FLAGS_REG))]
14327 "TARGET_BMI2 && reload_completed"
14328 [(set (match_dup 0)
14329 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
14330 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14331
14332 (define_insn "*bmi2_ashlsi3_1_zext"
14333 [(set (match_operand:DI 0 "register_operand" "=r")
14334 (zero_extend:DI
14335 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14336 (match_operand:SI 2 "register_operand" "r"))))]
14337 "TARGET_64BIT && TARGET_BMI2"
14338 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
14339 [(set_attr "type" "ishiftx")
14340 (set_attr "mode" "SI")])
14341
14342 (define_insn "*ashlsi3_1_zext"
14343 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
14344 (zero_extend:DI
14345 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
14346 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
14347 (clobber (reg:CC FLAGS_REG))]
14348 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14349 {
14350 switch (get_attr_type (insn))
14351 {
14352 case TYPE_LEA:
14353 case TYPE_ISHIFTX:
14354 return "#";
14355
14356 case TYPE_ALU:
14357 gcc_assert (operands[2] == const1_rtx);
14358 return "add{l}\t%k0, %k0";
14359
14360 default:
14361 if (operands[2] == const1_rtx
14362 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14363 return "sal{l}\t%k0";
14364 else
14365 return "sal{l}\t{%2, %k0|%k0, %2}";
14366 }
14367 }
14368 [(set_attr "isa" "*,*,bmi2")
14369 (set (attr "type")
14370 (cond [(eq_attr "alternative" "1")
14371 (const_string "lea")
14372 (eq_attr "alternative" "2")
14373 (const_string "ishiftx")
14374 (and (match_test "TARGET_DOUBLE_WITH_ADD")
14375 (match_operand 2 "const1_operand"))
14376 (const_string "alu")
14377 ]
14378 (const_string "ishift")))
14379 (set (attr "length_immediate")
14380 (if_then_else
14381 (ior (eq_attr "type" "alu")
14382 (and (eq_attr "type" "ishift")
14383 (and (match_operand 2 "const1_operand")
14384 (ior (match_test "TARGET_SHIFT1")
14385 (match_test "optimize_function_for_size_p (cfun)")))))
14386 (const_string "0")
14387 (const_string "*")))
14388 (set_attr "mode" "SI")])
14389
14390 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14391 (define_split
14392 [(set (match_operand:DI 0 "register_operand")
14393 (zero_extend:DI
14394 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14395 (match_operand:QI 2 "register_operand"))))
14396 (clobber (reg:CC FLAGS_REG))]
14397 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14398 [(set (match_dup 0)
14399 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14400 "operands[2] = gen_lowpart (SImode, operands[2]);")
14401
14402 (define_insn "*ashlhi3_1"
14403 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14404 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14405 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14406 (clobber (reg:CC FLAGS_REG))]
14407 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14408 {
14409 switch (get_attr_type (insn))
14410 {
14411 case TYPE_LEA:
14412 case TYPE_MSKLOG:
14413 return "#";
14414
14415 case TYPE_ALU:
14416 gcc_assert (operands[2] == const1_rtx);
14417 return "add{w}\t%0, %0";
14418
14419 default:
14420 if (operands[2] == const1_rtx
14421 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14422 return "sal{w}\t%0";
14423 else
14424 return "sal{w}\t{%2, %0|%0, %2}";
14425 }
14426 }
14427 [(set_attr "isa" "*,*,avx512f")
14428 (set (attr "type")
14429 (cond [(eq_attr "alternative" "1")
14430 (const_string "lea")
14431 (eq_attr "alternative" "2")
14432 (const_string "msklog")
14433 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14434 (match_operand 0 "register_operand"))
14435 (match_operand 2 "const1_operand"))
14436 (const_string "alu")
14437 ]
14438 (const_string "ishift")))
14439 (set (attr "length_immediate")
14440 (if_then_else
14441 (ior (eq_attr "type" "alu")
14442 (and (eq_attr "type" "ishift")
14443 (and (match_operand 2 "const1_operand")
14444 (ior (match_test "TARGET_SHIFT1")
14445 (match_test "optimize_function_for_size_p (cfun)")))))
14446 (const_string "0")
14447 (const_string "*")))
14448 (set_attr "mode" "HI,SI,HI")])
14449
14450 (define_insn "*ashlqi3_1"
14451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14452 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14453 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14454 (clobber (reg:CC FLAGS_REG))]
14455 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14456 {
14457 switch (get_attr_type (insn))
14458 {
14459 case TYPE_LEA:
14460 case TYPE_MSKLOG:
14461 return "#";
14462
14463 case TYPE_ALU:
14464 gcc_assert (operands[2] == const1_rtx);
14465 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14466 return "add{l}\t%k0, %k0";
14467 else
14468 return "add{b}\t%0, %0";
14469
14470 default:
14471 if (operands[2] == const1_rtx
14472 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14473 {
14474 if (get_attr_mode (insn) == MODE_SI)
14475 return "sal{l}\t%k0";
14476 else
14477 return "sal{b}\t%0";
14478 }
14479 else
14480 {
14481 if (get_attr_mode (insn) == MODE_SI)
14482 return "sal{l}\t{%2, %k0|%k0, %2}";
14483 else
14484 return "sal{b}\t{%2, %0|%0, %2}";
14485 }
14486 }
14487 }
14488 [(set_attr "isa" "*,*,*,avx512dq")
14489 (set (attr "type")
14490 (cond [(eq_attr "alternative" "2")
14491 (const_string "lea")
14492 (eq_attr "alternative" "3")
14493 (const_string "msklog")
14494 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14495 (match_operand 0 "register_operand"))
14496 (match_operand 2 "const1_operand"))
14497 (const_string "alu")
14498 ]
14499 (const_string "ishift")))
14500 (set (attr "length_immediate")
14501 (if_then_else
14502 (ior (eq_attr "type" "alu")
14503 (and (eq_attr "type" "ishift")
14504 (and (match_operand 2 "const1_operand")
14505 (ior (match_test "TARGET_SHIFT1")
14506 (match_test "optimize_function_for_size_p (cfun)")))))
14507 (const_string "0")
14508 (const_string "*")))
14509 (set_attr "mode" "QI,SI,SI,QI")
14510 ;; Potential partial reg stall on alternative 1.
14511 (set (attr "preferred_for_speed")
14512 (cond [(eq_attr "alternative" "1")
14513 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14514 (symbol_ref "true")))])
14515
14516 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14517 (define_insn_and_split "*ashl<mode>3_1_slp"
14518 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14519 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14520 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14521 (clobber (reg:CC FLAGS_REG))]
14522 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14523 {
14524 if (which_alternative)
14525 return "#";
14526
14527 switch (get_attr_type (insn))
14528 {
14529 case TYPE_ALU:
14530 gcc_assert (operands[2] == const1_rtx);
14531 return "add{<imodesuffix>}\t%0, %0";
14532
14533 default:
14534 if (operands[2] == const1_rtx
14535 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14536 return "sal{<imodesuffix>}\t%0";
14537 else
14538 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14539 }
14540 }
14541 "&& reload_completed
14542 && !(rtx_equal_p (operands[0], operands[1]))"
14543 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14544 (parallel
14545 [(set (strict_low_part (match_dup 0))
14546 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14547 (clobber (reg:CC FLAGS_REG))])]
14548 ""
14549 [(set (attr "type")
14550 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14551 (match_operand 2 "const1_operand"))
14552 (const_string "alu")
14553 ]
14554 (const_string "ishift")))
14555 (set (attr "length_immediate")
14556 (if_then_else
14557 (ior (eq_attr "type" "alu")
14558 (and (eq_attr "type" "ishift")
14559 (and (match_operand 2 "const1_operand")
14560 (ior (match_test "TARGET_SHIFT1")
14561 (match_test "optimize_function_for_size_p (cfun)")))))
14562 (const_string "0")
14563 (const_string "*")))
14564 (set_attr "mode" "<MODE>")])
14565
14566 ;; Convert ashift to the lea pattern to avoid flags dependency.
14567 (define_split
14568 [(set (match_operand:SWI 0 "general_reg_operand")
14569 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14570 (match_operand 2 "const_0_to_3_operand")))
14571 (clobber (reg:CC FLAGS_REG))]
14572 "reload_completed
14573 && REGNO (operands[0]) != REGNO (operands[1])"
14574 [(set (match_dup 0)
14575 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14576 {
14577 if (<MODE>mode != <LEAMODE>mode)
14578 {
14579 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14580 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14581 }
14582 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14583 })
14584
14585 ;; Convert ashift to the lea pattern to avoid flags dependency.
14586 (define_split
14587 [(set (match_operand:DI 0 "general_reg_operand")
14588 (zero_extend:DI
14589 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14590 (match_operand 2 "const_0_to_3_operand"))))
14591 (clobber (reg:CC FLAGS_REG))]
14592 "TARGET_64BIT && reload_completed
14593 && REGNO (operands[0]) != REGNO (operands[1])"
14594 [(set (match_dup 0)
14595 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14596 {
14597 operands[1] = gen_lowpart (SImode, operands[1]);
14598 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14599 })
14600
14601 ;; This pattern can't accept a variable shift count, since shifts by
14602 ;; zero don't affect the flags. We assume that shifts by constant
14603 ;; zero are optimized away.
14604 (define_insn "*ashl<mode>3_cmp"
14605 [(set (reg FLAGS_REG)
14606 (compare
14607 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14608 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14609 (const_int 0)))
14610 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14611 (ashift:SWI (match_dup 1) (match_dup 2)))]
14612 "(optimize_function_for_size_p (cfun)
14613 || !TARGET_PARTIAL_FLAG_REG_STALL
14614 || (operands[2] == const1_rtx
14615 && (TARGET_SHIFT1
14616 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14617 && ix86_match_ccmode (insn, CCGOCmode)
14618 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14619 {
14620 switch (get_attr_type (insn))
14621 {
14622 case TYPE_ALU:
14623 gcc_assert (operands[2] == const1_rtx);
14624 return "add{<imodesuffix>}\t%0, %0";
14625
14626 default:
14627 if (operands[2] == const1_rtx
14628 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14629 return "sal{<imodesuffix>}\t%0";
14630 else
14631 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14632 }
14633 }
14634 [(set (attr "type")
14635 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14636 (match_operand 0 "register_operand"))
14637 (match_operand 2 "const1_operand"))
14638 (const_string "alu")
14639 ]
14640 (const_string "ishift")))
14641 (set (attr "length_immediate")
14642 (if_then_else
14643 (ior (eq_attr "type" "alu")
14644 (and (eq_attr "type" "ishift")
14645 (and (match_operand 2 "const1_operand")
14646 (ior (match_test "TARGET_SHIFT1")
14647 (match_test "optimize_function_for_size_p (cfun)")))))
14648 (const_string "0")
14649 (const_string "*")))
14650 (set_attr "mode" "<MODE>")])
14651
14652 (define_insn "*ashlsi3_cmp_zext"
14653 [(set (reg FLAGS_REG)
14654 (compare
14655 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14656 (match_operand:QI 2 "const_1_to_31_operand"))
14657 (const_int 0)))
14658 (set (match_operand:DI 0 "register_operand" "=r")
14659 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14660 "TARGET_64BIT
14661 && (optimize_function_for_size_p (cfun)
14662 || !TARGET_PARTIAL_FLAG_REG_STALL
14663 || (operands[2] == const1_rtx
14664 && (TARGET_SHIFT1
14665 || TARGET_DOUBLE_WITH_ADD)))
14666 && ix86_match_ccmode (insn, CCGOCmode)
14667 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14668 {
14669 switch (get_attr_type (insn))
14670 {
14671 case TYPE_ALU:
14672 gcc_assert (operands[2] == const1_rtx);
14673 return "add{l}\t%k0, %k0";
14674
14675 default:
14676 if (operands[2] == const1_rtx
14677 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14678 return "sal{l}\t%k0";
14679 else
14680 return "sal{l}\t{%2, %k0|%k0, %2}";
14681 }
14682 }
14683 [(set (attr "type")
14684 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14685 (match_operand 2 "const1_operand"))
14686 (const_string "alu")
14687 ]
14688 (const_string "ishift")))
14689 (set (attr "length_immediate")
14690 (if_then_else
14691 (ior (eq_attr "type" "alu")
14692 (and (eq_attr "type" "ishift")
14693 (and (match_operand 2 "const1_operand")
14694 (ior (match_test "TARGET_SHIFT1")
14695 (match_test "optimize_function_for_size_p (cfun)")))))
14696 (const_string "0")
14697 (const_string "*")))
14698 (set_attr "mode" "SI")])
14699
14700 (define_insn "*ashl<mode>3_cconly"
14701 [(set (reg FLAGS_REG)
14702 (compare
14703 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14704 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14705 (const_int 0)))
14706 (clobber (match_scratch:SWI 0 "=<r>"))]
14707 "(optimize_function_for_size_p (cfun)
14708 || !TARGET_PARTIAL_FLAG_REG_STALL
14709 || (operands[2] == const1_rtx
14710 && (TARGET_SHIFT1
14711 || TARGET_DOUBLE_WITH_ADD)))
14712 && ix86_match_ccmode (insn, CCGOCmode)"
14713 {
14714 switch (get_attr_type (insn))
14715 {
14716 case TYPE_ALU:
14717 gcc_assert (operands[2] == const1_rtx);
14718 return "add{<imodesuffix>}\t%0, %0";
14719
14720 default:
14721 if (operands[2] == const1_rtx
14722 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14723 return "sal{<imodesuffix>}\t%0";
14724 else
14725 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14726 }
14727 }
14728 [(set (attr "type")
14729 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14730 (match_operand 0 "register_operand"))
14731 (match_operand 2 "const1_operand"))
14732 (const_string "alu")
14733 ]
14734 (const_string "ishift")))
14735 (set (attr "length_immediate")
14736 (if_then_else
14737 (ior (eq_attr "type" "alu")
14738 (and (eq_attr "type" "ishift")
14739 (and (match_operand 2 "const1_operand")
14740 (ior (match_test "TARGET_SHIFT1")
14741 (match_test "optimize_function_for_size_p (cfun)")))))
14742 (const_string "0")
14743 (const_string "*")))
14744 (set_attr "mode" "<MODE>")])
14745
14746 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14747 (define_insn_and_split "*ashlqi_ext<mode>_1"
14748 [(set (zero_extract:SWI248
14749 (match_operand 0 "int248_register_operand" "+Q,&Q")
14750 (const_int 8)
14751 (const_int 8))
14752 (subreg:SWI248
14753 (ashift:QI
14754 (subreg:QI
14755 (match_operator:SWI248 3 "extract_operator"
14756 [(match_operand 1 "int248_register_operand" "0,!Q")
14757 (const_int 8)
14758 (const_int 8)]) 0)
14759 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
14760 (clobber (reg:CC FLAGS_REG))]
14761 ""
14762 {
14763 if (which_alternative)
14764 return "#";
14765
14766 switch (get_attr_type (insn))
14767 {
14768 case TYPE_ALU:
14769 gcc_assert (operands[2] == const1_rtx);
14770 return "add{b}\t%h0, %h0";
14771
14772 default:
14773 if (operands[2] == const1_rtx
14774 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14775 return "sal{b}\t%h0";
14776 else
14777 return "sal{b}\t{%2, %h0|%h0, %2}";
14778 }
14779 }
14780 "reload_completed
14781 && !(rtx_equal_p (operands[0], operands[1]))"
14782 [(set (zero_extract:SWI248
14783 (match_dup 0) (const_int 8) (const_int 8))
14784 (match_dup 1))
14785 (parallel
14786 [(set (zero_extract:SWI248
14787 (match_dup 0) (const_int 8) (const_int 8))
14788 (subreg:SWI248
14789 (ashift:QI
14790 (subreg:QI
14791 (match_op_dup 3
14792 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
14793 (match_dup 2)) 0))
14794 (clobber (reg:CC FLAGS_REG))])]
14795 ""
14796 [(set (attr "type")
14797 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14798 (match_operand 2 "const1_operand"))
14799 (const_string "alu")
14800 ]
14801 (const_string "ishift")))
14802 (set (attr "length_immediate")
14803 (if_then_else
14804 (ior (eq_attr "type" "alu")
14805 (and (eq_attr "type" "ishift")
14806 (and (match_operand 2 "const1_operand")
14807 (ior (match_test "TARGET_SHIFT1")
14808 (match_test "optimize_function_for_size_p (cfun)")))))
14809 (const_string "0")
14810 (const_string "*")))
14811 (set_attr "mode" "QI")])
14812
14813 ;; See comment above `ashl<mode>3' about how this works.
14814
14815 (define_expand "<insn><mode>3"
14816 [(set (match_operand:SDWIM 0 "<shift_operand>")
14817 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14818 (match_operand:QI 2 "nonmemory_operand")))]
14819 ""
14820 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14821
14822 ;; Avoid useless masking of count operand.
14823 (define_insn_and_split "*<insn><mode>3_mask"
14824 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14825 (any_shiftrt:SWI48
14826 (match_operand:SWI48 1 "nonimmediate_operand")
14827 (subreg:QI
14828 (and
14829 (match_operand 2 "int248_register_operand" "c,r")
14830 (match_operand 3 "const_int_operand")) 0)))
14831 (clobber (reg:CC FLAGS_REG))]
14832 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14833 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14834 == GET_MODE_BITSIZE (<MODE>mode)-1
14835 && ix86_pre_reload_split ()"
14836 "#"
14837 "&& 1"
14838 [(parallel
14839 [(set (match_dup 0)
14840 (any_shiftrt:SWI48 (match_dup 1)
14841 (match_dup 2)))
14842 (clobber (reg:CC FLAGS_REG))])]
14843 {
14844 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14845 operands[2] = gen_lowpart (QImode, operands[2]);
14846 }
14847 [(set_attr "isa" "*,bmi2")])
14848
14849 (define_insn_and_split "*<insn><mode>3_mask_1"
14850 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14851 (any_shiftrt:SWI48
14852 (match_operand:SWI48 1 "nonimmediate_operand")
14853 (and:QI
14854 (match_operand:QI 2 "register_operand" "c,r")
14855 (match_operand:QI 3 "const_int_operand"))))
14856 (clobber (reg:CC FLAGS_REG))]
14857 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14858 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14859 == GET_MODE_BITSIZE (<MODE>mode)-1
14860 && ix86_pre_reload_split ()"
14861 "#"
14862 "&& 1"
14863 [(parallel
14864 [(set (match_dup 0)
14865 (any_shiftrt:SWI48 (match_dup 1)
14866 (match_dup 2)))
14867 (clobber (reg:CC FLAGS_REG))])]
14868 ""
14869 [(set_attr "isa" "*,bmi2")])
14870
14871 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14872 [(set (match_operand:<DWI> 0 "register_operand")
14873 (any_shiftrt:<DWI>
14874 (match_operand:<DWI> 1 "register_operand")
14875 (subreg:QI
14876 (and
14877 (match_operand 2 "int248_register_operand" "c")
14878 (match_operand 3 "const_int_operand")) 0)))
14879 (clobber (reg:CC FLAGS_REG))]
14880 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14881 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14882 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14883 && ix86_pre_reload_split ()"
14884 "#"
14885 "&& 1"
14886 [(parallel
14887 [(set (match_dup 4)
14888 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14889 (and:QI (match_dup 2) (match_dup 8)))
14890 (subreg:DWIH
14891 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14892 (minus:QI (match_dup 9)
14893 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14894 (clobber (reg:CC FLAGS_REG))])
14895 (parallel
14896 [(set (match_dup 6)
14897 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14898 (clobber (reg:CC FLAGS_REG))])]
14899 {
14900 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14901 {
14902 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14903 operands[2] = gen_lowpart (QImode, operands[2]);
14904 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14905 operands[2]));
14906 DONE;
14907 }
14908
14909 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14910
14911 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14912 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14913
14914 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14915 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14916 {
14917 rtx xops[3];
14918 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14919 xops[1] = operands[2];
14920 xops[2] = GEN_INT (INTVAL (operands[3])
14921 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14922 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14923 operands[2] = xops[0];
14924 }
14925
14926 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14927 operands[2] = gen_lowpart (QImode, operands[2]);
14928
14929 if (!rtx_equal_p (operands[4], operands[5]))
14930 emit_move_insn (operands[4], operands[5]);
14931 })
14932
14933 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14934 [(set (match_operand:<DWI> 0 "register_operand")
14935 (any_shiftrt:<DWI>
14936 (match_operand:<DWI> 1 "register_operand")
14937 (and:QI
14938 (match_operand:QI 2 "register_operand" "c")
14939 (match_operand:QI 3 "const_int_operand"))))
14940 (clobber (reg:CC FLAGS_REG))]
14941 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14942 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14943 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14944 && ix86_pre_reload_split ()"
14945 "#"
14946 "&& 1"
14947 [(parallel
14948 [(set (match_dup 4)
14949 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14950 (and:QI (match_dup 2) (match_dup 8)))
14951 (subreg:DWIH
14952 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14953 (minus:QI (match_dup 9)
14954 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14955 (clobber (reg:CC FLAGS_REG))])
14956 (parallel
14957 [(set (match_dup 6)
14958 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14959 (clobber (reg:CC FLAGS_REG))])]
14960 {
14961 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14962 {
14963 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14964 operands[2]));
14965 DONE;
14966 }
14967
14968 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14969
14970 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14971 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14972
14973 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14974 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14975 {
14976 rtx tem = gen_reg_rtx (QImode);
14977 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14978 operands[2] = tem;
14979 }
14980
14981 if (!rtx_equal_p (operands[4], operands[5]))
14982 emit_move_insn (operands[4], operands[5]);
14983 })
14984
14985 (define_insn_and_split "<insn><mode>3_doubleword"
14986 [(set (match_operand:DWI 0 "register_operand" "=&r")
14987 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14988 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14989 (clobber (reg:CC FLAGS_REG))]
14990 ""
14991 "#"
14992 "epilogue_completed"
14993 [(const_int 0)]
14994 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14995 [(set_attr "type" "multi")])
14996
14997 ;; By default we don't ask for a scratch register, because when DWImode
14998 ;; values are manipulated, registers are already at a premium. But if
14999 ;; we have one handy, we won't turn it away.
15000
15001 (define_peephole2
15002 [(match_scratch:DWIH 3 "r")
15003 (parallel [(set (match_operand:<DWI> 0 "register_operand")
15004 (any_shiftrt:<DWI>
15005 (match_operand:<DWI> 1 "register_operand")
15006 (match_operand:QI 2 "nonmemory_operand")))
15007 (clobber (reg:CC FLAGS_REG))])
15008 (match_dup 3)]
15009 "TARGET_CMOVE"
15010 [(const_int 0)]
15011 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
15012
15013 ;; Split truncations of double word right shifts into x86_shrd_1.
15014 (define_insn_and_split "<insn><dwi>3_doubleword_lowpart"
15015 [(set (match_operand:DWIH 0 "register_operand" "=&r")
15016 (subreg:DWIH
15017 (any_shiftrt:<DWI> (match_operand:<DWI> 1 "register_operand" "r")
15018 (match_operand:QI 2 "const_int_operand")) 0))
15019 (clobber (reg:CC FLAGS_REG))]
15020 "UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15021 "#"
15022 "&& reload_completed"
15023 [(parallel
15024 [(set (match_dup 0)
15025 (ior:DWIH (lshiftrt:DWIH (match_dup 0) (match_dup 2))
15026 (subreg:DWIH
15027 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15028 (match_dup 4)) 0)))
15029 (clobber (reg:CC FLAGS_REG))])]
15030 {
15031 split_double_mode (<DWI>mode, &operands[1], 1, &operands[1], &operands[3]);
15032 operands[4] = GEN_INT ((<MODE_SIZE> * BITS_PER_UNIT) - INTVAL (operands[2]));
15033 if (!rtx_equal_p (operands[0], operands[1]))
15034 emit_move_insn (operands[0], operands[1]);
15035 })
15036
15037 (define_insn "x86_64_shrd"
15038 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15039 (ior:DI (lshiftrt:DI (match_dup 0)
15040 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
15041 (const_int 63)))
15042 (subreg:DI
15043 (ashift:TI
15044 (zero_extend:TI
15045 (match_operand:DI 1 "register_operand" "r"))
15046 (minus:QI (const_int 64)
15047 (and:QI (match_dup 2) (const_int 63)))) 0)))
15048 (clobber (reg:CC FLAGS_REG))]
15049 "TARGET_64BIT"
15050 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
15051 [(set_attr "type" "ishift")
15052 (set_attr "prefix_0f" "1")
15053 (set_attr "mode" "DI")
15054 (set_attr "athlon_decode" "vector")
15055 (set_attr "amdfam10_decode" "vector")
15056 (set_attr "bdver1_decode" "vector")])
15057
15058 (define_insn "x86_64_shrd_1"
15059 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
15060 (ior:DI (lshiftrt:DI (match_dup 0)
15061 (match_operand:QI 2 "const_0_to_63_operand"))
15062 (subreg:DI
15063 (ashift:TI
15064 (zero_extend:TI
15065 (match_operand:DI 1 "register_operand" "r"))
15066 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
15067 (clobber (reg:CC FLAGS_REG))]
15068 "TARGET_64BIT
15069 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
15070 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
15071 [(set_attr "type" "ishift")
15072 (set_attr "prefix_0f" "1")
15073 (set_attr "length_immediate" "1")
15074 (set_attr "mode" "DI")
15075 (set_attr "athlon_decode" "vector")
15076 (set_attr "amdfam10_decode" "vector")
15077 (set_attr "bdver1_decode" "vector")])
15078
15079 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
15080 [(set (match_operand:DI 0 "nonimmediate_operand")
15081 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
15082 (match_operand:QI 2 "const_0_to_63_operand"))
15083 (ashift:DI
15084 (match_operand:DI 1 "nonimmediate_operand")
15085 (match_operand:QI 3 "const_0_to_63_operand"))))
15086 (clobber (reg:CC FLAGS_REG))]
15087 "TARGET_64BIT
15088 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
15089 && ix86_pre_reload_split ()"
15090 "#"
15091 "&& 1"
15092 [(const_int 0)]
15093 {
15094 if (rtx_equal_p (operands[4], operands[0]))
15095 {
15096 operands[1] = force_reg (DImode, operands[1]);
15097 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
15098 }
15099 else if (rtx_equal_p (operands[1], operands[0]))
15100 {
15101 operands[4] = force_reg (DImode, operands[4]);
15102 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15103 }
15104 else
15105 {
15106 operands[1] = force_reg (DImode, operands[1]);
15107 rtx tmp = gen_reg_rtx (DImode);
15108 emit_move_insn (tmp, operands[4]);
15109 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15110 emit_move_insn (operands[0], tmp);
15111 }
15112 DONE;
15113 })
15114
15115 (define_insn_and_split "*x86_64_shrd_2"
15116 [(set (match_operand:DI 0 "nonimmediate_operand")
15117 (ior:DI (lshiftrt:DI (match_dup 0)
15118 (match_operand:QI 2 "nonmemory_operand"))
15119 (ashift:DI (match_operand:DI 1 "register_operand")
15120 (minus:QI (const_int 64) (match_dup 2)))))
15121 (clobber (reg:CC FLAGS_REG))]
15122 "TARGET_64BIT && ix86_pre_reload_split ()"
15123 "#"
15124 "&& 1"
15125 [(parallel [(set (match_dup 0)
15126 (ior:DI (lshiftrt:DI (match_dup 0)
15127 (and:QI (match_dup 2) (const_int 63)))
15128 (subreg:DI
15129 (ashift:TI
15130 (zero_extend:TI (match_dup 1))
15131 (minus:QI (const_int 64)
15132 (and:QI (match_dup 2)
15133 (const_int 63)))) 0)))
15134 (clobber (reg:CC FLAGS_REG))])])
15135
15136 (define_insn "x86_shrd"
15137 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15138 (ior:SI (lshiftrt:SI (match_dup 0)
15139 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
15140 (const_int 31)))
15141 (subreg:SI
15142 (ashift:DI
15143 (zero_extend:DI
15144 (match_operand:SI 1 "register_operand" "r"))
15145 (minus:QI (const_int 32)
15146 (and:QI (match_dup 2) (const_int 31)))) 0)))
15147 (clobber (reg:CC FLAGS_REG))]
15148 ""
15149 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
15150 [(set_attr "type" "ishift")
15151 (set_attr "prefix_0f" "1")
15152 (set_attr "mode" "SI")
15153 (set_attr "pent_pair" "np")
15154 (set_attr "athlon_decode" "vector")
15155 (set_attr "amdfam10_decode" "vector")
15156 (set_attr "bdver1_decode" "vector")])
15157
15158 (define_insn "x86_shrd_1"
15159 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
15160 (ior:SI (lshiftrt:SI (match_dup 0)
15161 (match_operand:QI 2 "const_0_to_31_operand"))
15162 (subreg:SI
15163 (ashift:DI
15164 (zero_extend:DI
15165 (match_operand:SI 1 "register_operand" "r"))
15166 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
15167 (clobber (reg:CC FLAGS_REG))]
15168 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
15169 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
15170 [(set_attr "type" "ishift")
15171 (set_attr "prefix_0f" "1")
15172 (set_attr "length_immediate" "1")
15173 (set_attr "mode" "SI")
15174 (set_attr "pent_pair" "np")
15175 (set_attr "athlon_decode" "vector")
15176 (set_attr "amdfam10_decode" "vector")
15177 (set_attr "bdver1_decode" "vector")])
15178
15179 (define_insn_and_split "*x86_shrd_shld_1_nozext"
15180 [(set (match_operand:SI 0 "nonimmediate_operand")
15181 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
15182 (match_operand:QI 2 "const_0_to_31_operand"))
15183 (ashift:SI
15184 (match_operand:SI 1 "nonimmediate_operand")
15185 (match_operand:QI 3 "const_0_to_31_operand"))))
15186 (clobber (reg:CC FLAGS_REG))]
15187 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
15188 && ix86_pre_reload_split ()"
15189 "#"
15190 "&& 1"
15191 [(const_int 0)]
15192 {
15193 if (rtx_equal_p (operands[4], operands[0]))
15194 {
15195 operands[1] = force_reg (SImode, operands[1]);
15196 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
15197 }
15198 else if (rtx_equal_p (operands[1], operands[0]))
15199 {
15200 operands[4] = force_reg (SImode, operands[4]);
15201 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
15202 }
15203 else
15204 {
15205 operands[1] = force_reg (SImode, operands[1]);
15206 rtx tmp = gen_reg_rtx (SImode);
15207 emit_move_insn (tmp, operands[4]);
15208 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
15209 emit_move_insn (operands[0], tmp);
15210 }
15211 DONE;
15212 })
15213
15214 (define_insn_and_split "*x86_shrd_2"
15215 [(set (match_operand:SI 0 "nonimmediate_operand")
15216 (ior:SI (lshiftrt:SI (match_dup 0)
15217 (match_operand:QI 2 "nonmemory_operand"))
15218 (ashift:SI (match_operand:SI 1 "register_operand")
15219 (minus:QI (const_int 32) (match_dup 2)))))
15220 (clobber (reg:CC FLAGS_REG))]
15221 "TARGET_64BIT && ix86_pre_reload_split ()"
15222 "#"
15223 "&& 1"
15224 [(parallel [(set (match_dup 0)
15225 (ior:SI (lshiftrt:SI (match_dup 0)
15226 (and:QI (match_dup 2) (const_int 31)))
15227 (subreg:SI
15228 (ashift:DI
15229 (zero_extend:DI (match_dup 1))
15230 (minus:QI (const_int 32)
15231 (and:QI (match_dup 2)
15232 (const_int 31)))) 0)))
15233 (clobber (reg:CC FLAGS_REG))])])
15234
15235 ;; Base name for insn mnemonic.
15236 (define_mode_attr cvt_mnemonic
15237 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
15238
15239 (define_insn "ashr<mode>3_cvt"
15240 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
15241 (ashiftrt:SWI48
15242 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
15243 (match_operand:QI 2 "const_int_operand")))
15244 (clobber (reg:CC FLAGS_REG))]
15245 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
15246 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15247 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15248 "@
15249 <cvt_mnemonic>
15250 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
15251 [(set_attr "type" "imovx,ishift")
15252 (set_attr "prefix_0f" "0,*")
15253 (set_attr "length_immediate" "0,*")
15254 (set_attr "modrm" "0,1")
15255 (set_attr "mode" "<MODE>")])
15256
15257 (define_insn "*ashrsi3_cvt_zext"
15258 [(set (match_operand:DI 0 "register_operand" "=*d,r")
15259 (zero_extend:DI
15260 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
15261 (match_operand:QI 2 "const_int_operand"))))
15262 (clobber (reg:CC FLAGS_REG))]
15263 "TARGET_64BIT && INTVAL (operands[2]) == 31
15264 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
15265 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
15266 "@
15267 {cltd|cdq}
15268 sar{l}\t{%2, %k0|%k0, %2}"
15269 [(set_attr "type" "imovx,ishift")
15270 (set_attr "prefix_0f" "0,*")
15271 (set_attr "length_immediate" "0,*")
15272 (set_attr "modrm" "0,1")
15273 (set_attr "mode" "SI")])
15274
15275 (define_expand "@x86_shift<mode>_adj_3"
15276 [(use (match_operand:SWI48 0 "register_operand"))
15277 (use (match_operand:SWI48 1 "register_operand"))
15278 (use (match_operand:QI 2 "register_operand"))]
15279 ""
15280 {
15281 rtx_code_label *label = gen_label_rtx ();
15282 rtx tmp;
15283
15284 emit_insn (gen_testqi_ccz_1 (operands[2],
15285 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
15286
15287 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
15288 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
15289 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
15290 gen_rtx_LABEL_REF (VOIDmode, label),
15291 pc_rtx);
15292 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
15293 JUMP_LABEL (tmp) = label;
15294
15295 emit_move_insn (operands[0], operands[1]);
15296 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
15297 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
15298 emit_label (label);
15299 LABEL_NUSES (label) = 1;
15300
15301 DONE;
15302 })
15303
15304 (define_insn "*bmi2_<insn><mode>3_1"
15305 [(set (match_operand:SWI48 0 "register_operand" "=r")
15306 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15307 (match_operand:SWI48 2 "register_operand" "r")))]
15308 "TARGET_BMI2"
15309 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
15310 [(set_attr "type" "ishiftx")
15311 (set_attr "mode" "<MODE>")])
15312
15313 (define_insn "*ashr<mode>3_1"
15314 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15315 (ashiftrt:SWI48
15316 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15317 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
15318 (clobber (reg:CC FLAGS_REG))]
15319 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15320 {
15321 switch (get_attr_type (insn))
15322 {
15323 case TYPE_ISHIFTX:
15324 return "#";
15325
15326 default:
15327 if (operands[2] == const1_rtx
15328 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15329 return "sar{<imodesuffix>}\t%0";
15330 else
15331 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15332 }
15333 }
15334 [(set_attr "isa" "*,bmi2")
15335 (set_attr "type" "ishift,ishiftx")
15336 (set (attr "length_immediate")
15337 (if_then_else
15338 (and (match_operand 2 "const1_operand")
15339 (ior (match_test "TARGET_SHIFT1")
15340 (match_test "optimize_function_for_size_p (cfun)")))
15341 (const_string "0")
15342 (const_string "*")))
15343 (set_attr "mode" "<MODE>")])
15344
15345 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
15346 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
15347 (define_insn_and_split "*highpartdisi2"
15348 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
15349 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
15350 (const_int 32)))
15351 (clobber (reg:CC FLAGS_REG))]
15352 "TARGET_64BIT"
15353 "#"
15354 "&& reload_completed"
15355 [(parallel
15356 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
15357 (clobber (reg:CC FLAGS_REG))])]
15358 {
15359 if (SSE_REG_P (operands[0]))
15360 {
15361 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
15362 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
15363 const1_rtx, const1_rtx,
15364 GEN_INT (5), GEN_INT (5)));
15365 DONE;
15366 }
15367 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
15368 })
15369
15370 (define_insn "*lshr<mode>3_1"
15371 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
15372 (lshiftrt:SWI48
15373 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
15374 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
15375 (clobber (reg:CC FLAGS_REG))]
15376 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
15377 {
15378 switch (get_attr_type (insn))
15379 {
15380 case TYPE_ISHIFTX:
15381 case TYPE_MSKLOG:
15382 return "#";
15383
15384 default:
15385 if (operands[2] == const1_rtx
15386 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15387 return "shr{<imodesuffix>}\t%0";
15388 else
15389 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
15390 }
15391 }
15392 [(set_attr "isa" "*,bmi2,<kmov_isa>")
15393 (set_attr "type" "ishift,ishiftx,msklog")
15394 (set (attr "length_immediate")
15395 (if_then_else
15396 (and (and (match_operand 2 "const1_operand")
15397 (eq_attr "alternative" "0"))
15398 (ior (match_test "TARGET_SHIFT1")
15399 (match_test "optimize_function_for_size_p (cfun)")))
15400 (const_string "0")
15401 (const_string "*")))
15402 (set_attr "mode" "<MODE>")])
15403
15404 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15405 (define_split
15406 [(set (match_operand:SWI48 0 "register_operand")
15407 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15408 (match_operand:QI 2 "register_operand")))
15409 (clobber (reg:CC FLAGS_REG))]
15410 "TARGET_BMI2 && reload_completed"
15411 [(set (match_dup 0)
15412 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
15413 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
15414
15415 (define_insn "*bmi2_<insn>si3_1_zext"
15416 [(set (match_operand:DI 0 "register_operand" "=r")
15417 (zero_extend:DI
15418 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15419 (match_operand:SI 2 "register_operand" "r"))))]
15420 "TARGET_64BIT && TARGET_BMI2"
15421 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
15422 [(set_attr "type" "ishiftx")
15423 (set_attr "mode" "SI")])
15424
15425 (define_insn "*<insn>si3_1_zext"
15426 [(set (match_operand:DI 0 "register_operand" "=r,r")
15427 (zero_extend:DI
15428 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15429 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15430 (clobber (reg:CC FLAGS_REG))]
15431 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15432 {
15433 switch (get_attr_type (insn))
15434 {
15435 case TYPE_ISHIFTX:
15436 return "#";
15437
15438 default:
15439 if (operands[2] == const1_rtx
15440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15441 return "<shift>{l}\t%k0";
15442 else
15443 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15444 }
15445 }
15446 [(set_attr "isa" "*,bmi2")
15447 (set_attr "type" "ishift,ishiftx")
15448 (set (attr "length_immediate")
15449 (if_then_else
15450 (and (match_operand 2 "const1_operand")
15451 (ior (match_test "TARGET_SHIFT1")
15452 (match_test "optimize_function_for_size_p (cfun)")))
15453 (const_string "0")
15454 (const_string "*")))
15455 (set_attr "mode" "SI")])
15456
15457 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15458 (define_split
15459 [(set (match_operand:DI 0 "register_operand")
15460 (zero_extend:DI
15461 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15462 (match_operand:QI 2 "register_operand"))))
15463 (clobber (reg:CC FLAGS_REG))]
15464 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15465 [(set (match_dup 0)
15466 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15467 "operands[2] = gen_lowpart (SImode, operands[2]);")
15468
15469 (define_insn "*ashr<mode>3_1"
15470 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15471 (ashiftrt:SWI12
15472 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15473 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15474 (clobber (reg:CC FLAGS_REG))]
15475 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15476 {
15477 if (operands[2] == const1_rtx
15478 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15479 return "sar{<imodesuffix>}\t%0";
15480 else
15481 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15482 }
15483 [(set_attr "type" "ishift")
15484 (set (attr "length_immediate")
15485 (if_then_else
15486 (and (match_operand 2 "const1_operand")
15487 (ior (match_test "TARGET_SHIFT1")
15488 (match_test "optimize_function_for_size_p (cfun)")))
15489 (const_string "0")
15490 (const_string "*")))
15491 (set_attr "mode" "<MODE>")])
15492
15493 (define_insn "*lshrqi3_1"
15494 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15495 (lshiftrt:QI
15496 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15497 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15498 (clobber (reg:CC FLAGS_REG))]
15499 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15500 {
15501 switch (get_attr_type (insn))
15502 {
15503 case TYPE_ISHIFT:
15504 if (operands[2] == const1_rtx
15505 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15506 return "shr{b}\t%0";
15507 else
15508 return "shr{b}\t{%2, %0|%0, %2}";
15509 case TYPE_MSKLOG:
15510 return "#";
15511 default:
15512 gcc_unreachable ();
15513 }
15514 }
15515 [(set_attr "isa" "*,avx512dq")
15516 (set_attr "type" "ishift,msklog")
15517 (set (attr "length_immediate")
15518 (if_then_else
15519 (and (and (match_operand 2 "const1_operand")
15520 (eq_attr "alternative" "0"))
15521 (ior (match_test "TARGET_SHIFT1")
15522 (match_test "optimize_function_for_size_p (cfun)")))
15523 (const_string "0")
15524 (const_string "*")))
15525 (set_attr "mode" "QI")])
15526
15527 (define_insn "*lshrhi3_1"
15528 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15529 (lshiftrt:HI
15530 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15531 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15532 (clobber (reg:CC FLAGS_REG))]
15533 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15534 {
15535 switch (get_attr_type (insn))
15536 {
15537 case TYPE_ISHIFT:
15538 if (operands[2] == const1_rtx
15539 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15540 return "shr{w}\t%0";
15541 else
15542 return "shr{w}\t{%2, %0|%0, %2}";
15543 case TYPE_MSKLOG:
15544 return "#";
15545 default:
15546 gcc_unreachable ();
15547 }
15548 }
15549 [(set_attr "isa" "*, avx512f")
15550 (set_attr "type" "ishift,msklog")
15551 (set (attr "length_immediate")
15552 (if_then_else
15553 (and (and (match_operand 2 "const1_operand")
15554 (eq_attr "alternative" "0"))
15555 (ior (match_test "TARGET_SHIFT1")
15556 (match_test "optimize_function_for_size_p (cfun)")))
15557 (const_string "0")
15558 (const_string "*")))
15559 (set_attr "mode" "HI")])
15560
15561 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15562 (define_insn_and_split "*<insn><mode>3_1_slp"
15563 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15564 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15565 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15566 (clobber (reg:CC FLAGS_REG))]
15567 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15568 {
15569 if (which_alternative)
15570 return "#";
15571
15572 if (operands[2] == const1_rtx
15573 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15574 return "<shift>{<imodesuffix>}\t%0";
15575 else
15576 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15577 }
15578 "&& reload_completed
15579 && !(rtx_equal_p (operands[0], operands[1]))"
15580 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15581 (parallel
15582 [(set (strict_low_part (match_dup 0))
15583 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15584 (clobber (reg:CC FLAGS_REG))])]
15585 ""
15586 [(set_attr "type" "ishift")
15587 (set (attr "length_immediate")
15588 (if_then_else
15589 (and (match_operand 2 "const1_operand")
15590 (ior (match_test "TARGET_SHIFT1")
15591 (match_test "optimize_function_for_size_p (cfun)")))
15592 (const_string "0")
15593 (const_string "*")))
15594 (set_attr "mode" "<MODE>")])
15595
15596 ;; This pattern can't accept a variable shift count, since shifts by
15597 ;; zero don't affect the flags. We assume that shifts by constant
15598 ;; zero are optimized away.
15599 (define_insn "*<insn><mode>3_cmp"
15600 [(set (reg FLAGS_REG)
15601 (compare
15602 (any_shiftrt:SWI
15603 (match_operand:SWI 1 "nonimmediate_operand" "0")
15604 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15605 (const_int 0)))
15606 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15607 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15608 "(optimize_function_for_size_p (cfun)
15609 || !TARGET_PARTIAL_FLAG_REG_STALL
15610 || (operands[2] == const1_rtx
15611 && TARGET_SHIFT1))
15612 && ix86_match_ccmode (insn, CCGOCmode)
15613 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15614 {
15615 if (operands[2] == const1_rtx
15616 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15617 return "<shift>{<imodesuffix>}\t%0";
15618 else
15619 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15620 }
15621 [(set_attr "type" "ishift")
15622 (set (attr "length_immediate")
15623 (if_then_else
15624 (and (match_operand 2 "const1_operand")
15625 (ior (match_test "TARGET_SHIFT1")
15626 (match_test "optimize_function_for_size_p (cfun)")))
15627 (const_string "0")
15628 (const_string "*")))
15629 (set_attr "mode" "<MODE>")])
15630
15631 (define_insn "*<insn>si3_cmp_zext"
15632 [(set (reg FLAGS_REG)
15633 (compare
15634 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15635 (match_operand:QI 2 "const_1_to_31_operand"))
15636 (const_int 0)))
15637 (set (match_operand:DI 0 "register_operand" "=r")
15638 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15639 "TARGET_64BIT
15640 && (optimize_function_for_size_p (cfun)
15641 || !TARGET_PARTIAL_FLAG_REG_STALL
15642 || (operands[2] == const1_rtx
15643 && TARGET_SHIFT1))
15644 && ix86_match_ccmode (insn, CCGOCmode)
15645 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15646 {
15647 if (operands[2] == const1_rtx
15648 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15649 return "<shift>{l}\t%k0";
15650 else
15651 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15652 }
15653 [(set_attr "type" "ishift")
15654 (set (attr "length_immediate")
15655 (if_then_else
15656 (and (match_operand 2 "const1_operand")
15657 (ior (match_test "TARGET_SHIFT1")
15658 (match_test "optimize_function_for_size_p (cfun)")))
15659 (const_string "0")
15660 (const_string "*")))
15661 (set_attr "mode" "SI")])
15662
15663 (define_insn "*<insn><mode>3_cconly"
15664 [(set (reg FLAGS_REG)
15665 (compare
15666 (any_shiftrt:SWI
15667 (match_operand:SWI 1 "register_operand" "0")
15668 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15669 (const_int 0)))
15670 (clobber (match_scratch:SWI 0 "=<r>"))]
15671 "(optimize_function_for_size_p (cfun)
15672 || !TARGET_PARTIAL_FLAG_REG_STALL
15673 || (operands[2] == const1_rtx
15674 && TARGET_SHIFT1))
15675 && ix86_match_ccmode (insn, CCGOCmode)"
15676 {
15677 if (operands[2] == const1_rtx
15678 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15679 return "<shift>{<imodesuffix>}\t%0";
15680 else
15681 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15682 }
15683 [(set_attr "type" "ishift")
15684 (set (attr "length_immediate")
15685 (if_then_else
15686 (and (match_operand 2 "const1_operand")
15687 (ior (match_test "TARGET_SHIFT1")
15688 (match_test "optimize_function_for_size_p (cfun)")))
15689 (const_string "0")
15690 (const_string "*")))
15691 (set_attr "mode" "<MODE>")])
15692
15693 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15694 (define_insn_and_split "*<insn>qi_ext<mode>_1"
15695 [(set (zero_extract:SWI248
15696 (match_operand 0 "int248_register_operand" "+Q,&Q")
15697 (const_int 8)
15698 (const_int 8))
15699 (subreg:SWI248
15700 (any_shiftrt:QI
15701 (subreg:QI
15702 (match_operator:SWI248 3 "extract_operator"
15703 [(match_operand 1 "int248_register_operand" "0,!Q")
15704 (const_int 8)
15705 (const_int 8)]) 0)
15706 (match_operand:QI 2 "nonmemory_operand" "cI,cI")) 0))
15707 (clobber (reg:CC FLAGS_REG))]
15708 ""
15709 {
15710 if (which_alternative)
15711 return "#";
15712
15713 if (operands[2] == const1_rtx
15714 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15715 return "<shift>{b}\t%h0";
15716 else
15717 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15718 }
15719 "reload_completed
15720 && !(rtx_equal_p (operands[0], operands[1]))"
15721 [(set (zero_extract:SWI248
15722 (match_dup 0) (const_int 8) (const_int 8))
15723 (match_dup 1))
15724 (parallel
15725 [(set (zero_extract:SWI248
15726 (match_dup 0) (const_int 8) (const_int 8))
15727 (subreg:SWI248
15728 (any_shiftrt:QI
15729 (subreg:QI
15730 (match_op_dup 3
15731 [(match_dup 0) (const_int 8) (const_int 8)]) 0)
15732 (match_dup 2)) 0))
15733 (clobber (reg:CC FLAGS_REG))])]
15734 ""
15735 [(set_attr "type" "ishift")
15736 (set (attr "length_immediate")
15737 (if_then_else
15738 (and (match_operand 2 "const1_operand")
15739 (ior (match_test "TARGET_SHIFT1")
15740 (match_test "optimize_function_for_size_p (cfun)")))
15741 (const_string "0")
15742 (const_string "*")))
15743 (set_attr "mode" "QI")])
15744
15745 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15746 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15747 (ashiftrt:<DWI>
15748 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15749 (match_operand:QI 2 "const_int_operand"))
15750 (match_operand:QI 3 "const_int_operand")))
15751 (clobber (reg:CC FLAGS_REG))]
15752 "INTVAL (operands[2]) == INTVAL (operands[3])
15753 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15754 "#"
15755 "&& reload_completed"
15756 [(parallel [(set (match_dup 4)
15757 (ashift:DWIH (match_dup 4) (match_dup 2)))
15758 (clobber (reg:CC FLAGS_REG))])
15759 (parallel [(set (match_dup 4)
15760 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15761 (clobber (reg:CC FLAGS_REG))])]
15762 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15763
15764 (define_insn_and_split "*extendv2di2_highpart_stv"
15765 [(set (match_operand:V2DI 0 "register_operand" "=v")
15766 (ashiftrt:V2DI
15767 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15768 (match_operand:QI 2 "const_int_operand"))
15769 (match_operand:QI 3 "const_int_operand")))]
15770 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15771 && INTVAL (operands[2]) == INTVAL (operands[3])
15772 && UINTVAL (operands[2]) < 32"
15773 "#"
15774 "&& reload_completed"
15775 [(set (match_dup 0)
15776 (ashift:V2DI (match_dup 1) (match_dup 2)))
15777 (set (match_dup 0)
15778 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15779 \f
15780 ;; Rotate instructions
15781
15782 (define_expand "<insn>ti3"
15783 [(set (match_operand:TI 0 "register_operand")
15784 (any_rotate:TI (match_operand:TI 1 "register_operand")
15785 (match_operand:QI 2 "nonmemory_operand")))]
15786 "TARGET_64BIT"
15787 {
15788 if (const_1_to_63_operand (operands[2], VOIDmode))
15789 emit_insn (gen_ix86_<insn>ti3_doubleword
15790 (operands[0], operands[1], operands[2]));
15791 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15792 {
15793 operands[1] = force_reg (TImode, operands[1]);
15794 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15795 }
15796 else
15797 {
15798 rtx amount = force_reg (QImode, operands[2]);
15799 rtx src_lo = gen_lowpart (DImode, operands[1]);
15800 rtx src_hi = gen_highpart (DImode, operands[1]);
15801 rtx tmp_lo = gen_reg_rtx (DImode);
15802 rtx tmp_hi = gen_reg_rtx (DImode);
15803 emit_move_insn (tmp_lo, src_lo);
15804 emit_move_insn (tmp_hi, src_hi);
15805 rtx (*shiftd) (rtx, rtx, rtx)
15806 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15807 emit_insn (shiftd (tmp_lo, src_hi, amount));
15808 emit_insn (shiftd (tmp_hi, src_lo, amount));
15809 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15810 rtx dst_hi = gen_highpart (DImode, operands[0]);
15811 emit_move_insn (dst_lo, tmp_lo);
15812 emit_move_insn (dst_hi, tmp_hi);
15813 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15814 }
15815 DONE;
15816 })
15817
15818 (define_expand "<insn>di3"
15819 [(set (match_operand:DI 0 "shiftdi_operand")
15820 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15821 (match_operand:QI 2 "nonmemory_operand")))]
15822 ""
15823 {
15824 if (TARGET_64BIT)
15825 ix86_expand_binary_operator (<CODE>, DImode, operands);
15826 else if (const_1_to_31_operand (operands[2], VOIDmode))
15827 emit_insn (gen_ix86_<insn>di3_doubleword
15828 (operands[0], operands[1], operands[2]));
15829 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15830 {
15831 operands[1] = force_reg (DImode, operands[1]);
15832 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15833 }
15834 else
15835 FAIL;
15836
15837 DONE;
15838 })
15839
15840 (define_expand "<insn><mode>3"
15841 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15842 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15843 (match_operand:QI 2 "nonmemory_operand")))]
15844 ""
15845 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15846
15847 ;; Avoid useless masking of count operand.
15848 (define_insn_and_split "*<insn><mode>3_mask"
15849 [(set (match_operand:SWI 0 "nonimmediate_operand")
15850 (any_rotate:SWI
15851 (match_operand:SWI 1 "nonimmediate_operand")
15852 (subreg:QI
15853 (and
15854 (match_operand 2 "int248_register_operand" "c")
15855 (match_operand 3 "const_int_operand")) 0)))
15856 (clobber (reg:CC FLAGS_REG))]
15857 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15858 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15859 == GET_MODE_BITSIZE (<MODE>mode)-1
15860 && ix86_pre_reload_split ()"
15861 "#"
15862 "&& 1"
15863 [(parallel
15864 [(set (match_dup 0)
15865 (any_rotate:SWI (match_dup 1)
15866 (match_dup 2)))
15867 (clobber (reg:CC FLAGS_REG))])]
15868 {
15869 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15870 operands[2] = gen_lowpart (QImode, operands[2]);
15871 })
15872
15873 (define_split
15874 [(set (match_operand:SWI 0 "register_operand")
15875 (any_rotate:SWI
15876 (match_operand:SWI 1 "const_int_operand")
15877 (subreg:QI
15878 (and
15879 (match_operand 2 "int248_register_operand")
15880 (match_operand 3 "const_int_operand")) 0)))]
15881 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15882 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15883 [(set (match_dup 4) (match_dup 1))
15884 (set (match_dup 0)
15885 (any_rotate:SWI (match_dup 4)
15886 (subreg:QI (match_dup 2) 0)))]
15887 "operands[4] = gen_reg_rtx (<MODE>mode);")
15888
15889 (define_insn_and_split "*<insn><mode>3_mask_1"
15890 [(set (match_operand:SWI 0 "nonimmediate_operand")
15891 (any_rotate:SWI
15892 (match_operand:SWI 1 "nonimmediate_operand")
15893 (and:QI
15894 (match_operand:QI 2 "register_operand" "c")
15895 (match_operand:QI 3 "const_int_operand"))))
15896 (clobber (reg:CC FLAGS_REG))]
15897 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15898 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15899 == GET_MODE_BITSIZE (<MODE>mode)-1
15900 && ix86_pre_reload_split ()"
15901 "#"
15902 "&& 1"
15903 [(parallel
15904 [(set (match_dup 0)
15905 (any_rotate:SWI (match_dup 1)
15906 (match_dup 2)))
15907 (clobber (reg:CC FLAGS_REG))])])
15908
15909 (define_split
15910 [(set (match_operand:SWI 0 "register_operand")
15911 (any_rotate:SWI
15912 (match_operand:SWI 1 "const_int_operand")
15913 (and:QI
15914 (match_operand:QI 2 "register_operand")
15915 (match_operand:QI 3 "const_int_operand"))))]
15916 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15917 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15918 [(set (match_dup 4) (match_dup 1))
15919 (set (match_dup 0)
15920 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15921 "operands[4] = gen_reg_rtx (<MODE>mode);")
15922
15923 ;; Implement rotation using two double-precision
15924 ;; shift instructions and a scratch register.
15925
15926 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15927 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15928 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15929 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15930 (clobber (reg:CC FLAGS_REG))
15931 (clobber (match_scratch:DWIH 3 "=&r"))]
15932 ""
15933 "#"
15934 "reload_completed"
15935 [(set (match_dup 3) (match_dup 4))
15936 (parallel
15937 [(set (match_dup 4)
15938 (ior:DWIH (ashift:DWIH (match_dup 4)
15939 (and:QI (match_dup 2) (match_dup 6)))
15940 (subreg:DWIH
15941 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15942 (minus:QI (match_dup 7)
15943 (and:QI (match_dup 2)
15944 (match_dup 6)))) 0)))
15945 (clobber (reg:CC FLAGS_REG))])
15946 (parallel
15947 [(set (match_dup 5)
15948 (ior:DWIH (ashift:DWIH (match_dup 5)
15949 (and:QI (match_dup 2) (match_dup 6)))
15950 (subreg:DWIH
15951 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15952 (minus:QI (match_dup 7)
15953 (and:QI (match_dup 2)
15954 (match_dup 6)))) 0)))
15955 (clobber (reg:CC FLAGS_REG))])]
15956 {
15957 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15958 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15959
15960 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15961 })
15962
15963 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15964 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15965 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15966 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15967 (clobber (reg:CC FLAGS_REG))
15968 (clobber (match_scratch:DWIH 3 "=&r"))]
15969 ""
15970 "#"
15971 "reload_completed"
15972 [(set (match_dup 3) (match_dup 4))
15973 (parallel
15974 [(set (match_dup 4)
15975 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15976 (and:QI (match_dup 2) (match_dup 6)))
15977 (subreg:DWIH
15978 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15979 (minus:QI (match_dup 7)
15980 (and:QI (match_dup 2)
15981 (match_dup 6)))) 0)))
15982 (clobber (reg:CC FLAGS_REG))])
15983 (parallel
15984 [(set (match_dup 5)
15985 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15986 (and:QI (match_dup 2) (match_dup 6)))
15987 (subreg:DWIH
15988 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15989 (minus:QI (match_dup 7)
15990 (and:QI (match_dup 2)
15991 (match_dup 6)))) 0)))
15992 (clobber (reg:CC FLAGS_REG))])]
15993 {
15994 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15995 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15996
15997 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15998 })
15999
16000 (define_insn_and_split "<insn>32di2_doubleword"
16001 [(set (match_operand:DI 0 "register_operand" "=r,r")
16002 (any_rotate:DI (match_operand:DI 1 "register_operand" "0,r")
16003 (const_int 32)))]
16004 "!TARGET_64BIT"
16005 "#"
16006 "&& reload_completed"
16007 [(set (match_dup 0) (match_dup 3))
16008 (set (match_dup 2) (match_dup 1))]
16009 {
16010 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
16011 if (rtx_equal_p (operands[0], operands[1]))
16012 {
16013 emit_insn (gen_swapsi (operands[0], operands[2]));
16014 DONE;
16015 }
16016 })
16017
16018 (define_insn_and_split "<insn>64ti2_doubleword"
16019 [(set (match_operand:TI 0 "register_operand" "=r,r")
16020 (any_rotate:TI (match_operand:TI 1 "register_operand" "0,r")
16021 (const_int 64)))]
16022 "TARGET_64BIT"
16023 "#"
16024 "&& reload_completed"
16025 [(set (match_dup 0) (match_dup 3))
16026 (set (match_dup 2) (match_dup 1))]
16027 {
16028 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
16029 if (rtx_equal_p (operands[0], operands[1]))
16030 {
16031 emit_insn (gen_swapdi (operands[0], operands[2]));
16032 DONE;
16033 }
16034 })
16035
16036 (define_mode_attr rorx_immediate_operand
16037 [(SI "const_0_to_31_operand")
16038 (DI "const_0_to_63_operand")])
16039
16040 (define_insn "*bmi2_rorx<mode>3_1"
16041 [(set (match_operand:SWI48 0 "register_operand" "=r")
16042 (rotatert:SWI48
16043 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
16044 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
16045 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
16046 "rorx\t{%2, %1, %0|%0, %1, %2}"
16047 [(set_attr "type" "rotatex")
16048 (set_attr "mode" "<MODE>")])
16049
16050 (define_insn "*<insn><mode>3_1"
16051 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
16052 (any_rotate:SWI48
16053 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
16054 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
16055 (clobber (reg:CC FLAGS_REG))]
16056 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
16057 {
16058 switch (get_attr_type (insn))
16059 {
16060 case TYPE_ROTATEX:
16061 return "#";
16062
16063 default:
16064 if (operands[2] == const1_rtx
16065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16066 return "<rotate>{<imodesuffix>}\t%0";
16067 else
16068 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16069 }
16070 }
16071 [(set_attr "isa" "*,bmi2")
16072 (set_attr "type" "rotate,rotatex")
16073 (set (attr "preferred_for_size")
16074 (cond [(eq_attr "alternative" "0")
16075 (symbol_ref "true")]
16076 (symbol_ref "false")))
16077 (set (attr "length_immediate")
16078 (if_then_else
16079 (and (eq_attr "type" "rotate")
16080 (and (match_operand 2 "const1_operand")
16081 (ior (match_test "TARGET_SHIFT1")
16082 (match_test "optimize_function_for_size_p (cfun)"))))
16083 (const_string "0")
16084 (const_string "*")))
16085 (set_attr "mode" "<MODE>")])
16086
16087 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
16088 (define_split
16089 [(set (match_operand:SWI48 0 "register_operand")
16090 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16091 (match_operand:QI 2 "const_int_operand")))
16092 (clobber (reg:CC FLAGS_REG))]
16093 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
16094 [(set (match_dup 0)
16095 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
16096 {
16097 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
16098
16099 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
16100 })
16101
16102 (define_split
16103 [(set (match_operand:SWI48 0 "register_operand")
16104 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16105 (match_operand:QI 2 "const_int_operand")))
16106 (clobber (reg:CC FLAGS_REG))]
16107 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
16108 [(set (match_dup 0)
16109 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
16110
16111 (define_insn "*bmi2_rorxsi3_1_zext"
16112 [(set (match_operand:DI 0 "register_operand" "=r")
16113 (zero_extend:DI
16114 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
16115 (match_operand:QI 2 "const_0_to_31_operand"))))]
16116 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
16117 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
16118 [(set_attr "type" "rotatex")
16119 (set_attr "mode" "SI")])
16120
16121 (define_insn "*<insn>si3_1_zext"
16122 [(set (match_operand:DI 0 "register_operand" "=r,r")
16123 (zero_extend:DI
16124 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
16125 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
16126 (clobber (reg:CC FLAGS_REG))]
16127 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
16128 {
16129 switch (get_attr_type (insn))
16130 {
16131 case TYPE_ROTATEX:
16132 return "#";
16133
16134 default:
16135 if (operands[2] == const1_rtx
16136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16137 return "<rotate>{l}\t%k0";
16138 else
16139 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
16140 }
16141 }
16142 [(set_attr "isa" "*,bmi2")
16143 (set_attr "type" "rotate,rotatex")
16144 (set (attr "preferred_for_size")
16145 (cond [(eq_attr "alternative" "0")
16146 (symbol_ref "true")]
16147 (symbol_ref "false")))
16148 (set (attr "length_immediate")
16149 (if_then_else
16150 (and (eq_attr "type" "rotate")
16151 (and (match_operand 2 "const1_operand")
16152 (ior (match_test "TARGET_SHIFT1")
16153 (match_test "optimize_function_for_size_p (cfun)"))))
16154 (const_string "0")
16155 (const_string "*")))
16156 (set_attr "mode" "SI")])
16157
16158 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
16159 (define_split
16160 [(set (match_operand:DI 0 "register_operand")
16161 (zero_extend:DI
16162 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
16163 (match_operand:QI 2 "const_int_operand"))))
16164 (clobber (reg:CC FLAGS_REG))]
16165 "TARGET_64BIT && TARGET_BMI2 && reload_completed
16166 && !optimize_function_for_size_p (cfun)"
16167 [(set (match_dup 0)
16168 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
16169 {
16170 int bitsize = GET_MODE_BITSIZE (SImode);
16171
16172 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
16173 })
16174
16175 (define_split
16176 [(set (match_operand:DI 0 "register_operand")
16177 (zero_extend:DI
16178 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
16179 (match_operand:QI 2 "const_int_operand"))))
16180 (clobber (reg:CC FLAGS_REG))]
16181 "TARGET_64BIT && TARGET_BMI2 && reload_completed
16182 && !optimize_function_for_size_p (cfun)"
16183 [(set (match_dup 0)
16184 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
16185
16186 (define_insn "*<insn><mode>3_1"
16187 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
16188 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
16189 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
16190 (clobber (reg:CC FLAGS_REG))]
16191 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
16192 {
16193 if (operands[2] == const1_rtx
16194 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16195 return "<rotate>{<imodesuffix>}\t%0";
16196 else
16197 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16198 }
16199 [(set_attr "type" "rotate")
16200 (set (attr "length_immediate")
16201 (if_then_else
16202 (and (match_operand 2 "const1_operand")
16203 (ior (match_test "TARGET_SHIFT1")
16204 (match_test "optimize_function_for_size_p (cfun)")))
16205 (const_string "0")
16206 (const_string "*")))
16207 (set_attr "mode" "<MODE>")])
16208
16209 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
16210 (define_insn_and_split "*<insn><mode>3_1_slp"
16211 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
16212 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
16213 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
16214 (clobber (reg:CC FLAGS_REG))]
16215 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
16216 {
16217 if (which_alternative)
16218 return "#";
16219
16220 if (operands[2] == const1_rtx
16221 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
16222 return "<rotate>{<imodesuffix>}\t%0";
16223 else
16224 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
16225 }
16226 "&& reload_completed
16227 && !(rtx_equal_p (operands[0], operands[1]))"
16228 [(set (strict_low_part (match_dup 0)) (match_dup 1))
16229 (parallel
16230 [(set (strict_low_part (match_dup 0))
16231 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
16232 (clobber (reg:CC FLAGS_REG))])]
16233 ""
16234 [(set_attr "type" "rotate")
16235 (set (attr "length_immediate")
16236 (if_then_else
16237 (and (match_operand 2 "const1_operand")
16238 (ior (match_test "TARGET_SHIFT1")
16239 (match_test "optimize_function_for_size_p (cfun)")))
16240 (const_string "0")
16241 (const_string "*")))
16242 (set_attr "mode" "<MODE>")])
16243
16244 (define_split
16245 [(set (match_operand:HI 0 "QIreg_operand")
16246 (any_rotate:HI (match_dup 0) (const_int 8)))
16247 (clobber (reg:CC FLAGS_REG))]
16248 "reload_completed
16249 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
16250 [(parallel [(set (strict_low_part (match_dup 0))
16251 (bswap:HI (match_dup 0)))
16252 (clobber (reg:CC FLAGS_REG))])])
16253
16254 ;; Rotations through carry flag
16255 (define_insn "rcrsi2"
16256 [(set (match_operand:SI 0 "register_operand" "=r")
16257 (plus:SI
16258 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
16259 (const_int 1))
16260 (ashift:SI (ltu:SI (reg:CCC FLAGS_REG) (const_int 0))
16261 (const_int 31))))
16262 (clobber (reg:CC FLAGS_REG))]
16263 ""
16264 "rcr{l}\t%0"
16265 [(set_attr "type" "ishift1")
16266 (set_attr "memory" "none")
16267 (set_attr "length_immediate" "0")
16268 (set_attr "mode" "SI")])
16269
16270 (define_insn "rcrdi2"
16271 [(set (match_operand:DI 0 "register_operand" "=r")
16272 (plus:DI
16273 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
16274 (const_int 1))
16275 (ashift:DI (ltu:DI (reg:CCC FLAGS_REG) (const_int 0))
16276 (const_int 63))))
16277 (clobber (reg:CC FLAGS_REG))]
16278 "TARGET_64BIT"
16279 "rcr{q}\t%0"
16280 [(set_attr "type" "ishift1")
16281 (set_attr "length_immediate" "0")
16282 (set_attr "mode" "DI")])
16283
16284 ;; Versions of sar and shr that set the carry flag.
16285 (define_insn "<insn><mode>3_carry"
16286 [(set (reg:CCC FLAGS_REG)
16287 (unspec:CCC [(and:SWI48 (match_operand:SWI48 1 "register_operand" "0")
16288 (const_int 1))
16289 (const_int 0)] UNSPEC_CC_NE))
16290 (set (match_operand:SWI48 0 "register_operand" "=r")
16291 (any_shiftrt:SWI48 (match_dup 1) (const_int 1)))]
16292 ""
16293 {
16294 if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
16295 return "<shift>{<imodesuffix>}\t%0";
16296 return "<shift>{<imodesuffix>}\t{1, %0|%0, 1}";
16297 }
16298 [(set_attr "type" "ishift1")
16299 (set (attr "length_immediate")
16300 (if_then_else
16301 (ior (match_test "TARGET_SHIFT1")
16302 (match_test "optimize_function_for_size_p (cfun)"))
16303 (const_string "0")
16304 (const_string "*")))
16305 (set_attr "mode" "<MODE>")])
16306 \f
16307 ;; Bit set / bit test instructions
16308
16309 ;; %%% bts, btr, btc
16310
16311 ;; These instructions are *slow* when applied to memory.
16312
16313 (define_code_attr btsc [(ior "bts") (xor "btc")])
16314
16315 (define_insn "*<btsc><mode>"
16316 [(set (match_operand:SWI48 0 "register_operand" "=r")
16317 (any_or:SWI48
16318 (ashift:SWI48 (const_int 1)
16319 (match_operand:QI 2 "register_operand" "r"))
16320 (match_operand:SWI48 1 "register_operand" "0")))
16321 (clobber (reg:CC FLAGS_REG))]
16322 "TARGET_USE_BT"
16323 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16324 [(set_attr "type" "alu1")
16325 (set_attr "prefix_0f" "1")
16326 (set_attr "znver1_decode" "double")
16327 (set_attr "mode" "<MODE>")])
16328
16329 ;; Avoid useless masking of count operand.
16330 (define_insn_and_split "*<btsc><mode>_mask"
16331 [(set (match_operand:SWI48 0 "register_operand")
16332 (any_or:SWI48
16333 (ashift:SWI48
16334 (const_int 1)
16335 (subreg:QI
16336 (and
16337 (match_operand 1 "int248_register_operand")
16338 (match_operand 2 "const_int_operand")) 0))
16339 (match_operand:SWI48 3 "register_operand")))
16340 (clobber (reg:CC FLAGS_REG))]
16341 "TARGET_USE_BT
16342 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16343 == GET_MODE_BITSIZE (<MODE>mode)-1
16344 && ix86_pre_reload_split ()"
16345 "#"
16346 "&& 1"
16347 [(parallel
16348 [(set (match_dup 0)
16349 (any_or:SWI48
16350 (ashift:SWI48 (const_int 1)
16351 (match_dup 1))
16352 (match_dup 3)))
16353 (clobber (reg:CC FLAGS_REG))])]
16354 {
16355 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16356 operands[1] = gen_lowpart (QImode, operands[1]);
16357 })
16358
16359 (define_insn_and_split "*<btsc><mode>_mask_1"
16360 [(set (match_operand:SWI48 0 "register_operand")
16361 (any_or:SWI48
16362 (ashift:SWI48
16363 (const_int 1)
16364 (and:QI
16365 (match_operand:QI 1 "register_operand")
16366 (match_operand:QI 2 "const_int_operand")))
16367 (match_operand:SWI48 3 "register_operand")))
16368 (clobber (reg:CC FLAGS_REG))]
16369 "TARGET_USE_BT
16370 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16371 == GET_MODE_BITSIZE (<MODE>mode)-1
16372 && ix86_pre_reload_split ()"
16373 "#"
16374 "&& 1"
16375 [(parallel
16376 [(set (match_dup 0)
16377 (any_or:SWI48
16378 (ashift:SWI48 (const_int 1)
16379 (match_dup 1))
16380 (match_dup 3)))
16381 (clobber (reg:CC FLAGS_REG))])])
16382
16383 (define_insn "*btr<mode>"
16384 [(set (match_operand:SWI48 0 "register_operand" "=r")
16385 (and:SWI48
16386 (rotate:SWI48 (const_int -2)
16387 (match_operand:QI 2 "register_operand" "r"))
16388 (match_operand:SWI48 1 "register_operand" "0")))
16389 (clobber (reg:CC FLAGS_REG))]
16390 "TARGET_USE_BT"
16391 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
16392 [(set_attr "type" "alu1")
16393 (set_attr "prefix_0f" "1")
16394 (set_attr "znver1_decode" "double")
16395 (set_attr "mode" "<MODE>")])
16396
16397 ;; Avoid useless masking of count operand.
16398 (define_insn_and_split "*btr<mode>_mask"
16399 [(set (match_operand:SWI48 0 "register_operand")
16400 (and:SWI48
16401 (rotate:SWI48
16402 (const_int -2)
16403 (subreg:QI
16404 (and
16405 (match_operand 1 "int248_register_operand")
16406 (match_operand 2 "const_int_operand")) 0))
16407 (match_operand:SWI48 3 "register_operand")))
16408 (clobber (reg:CC FLAGS_REG))]
16409 "TARGET_USE_BT
16410 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16411 == GET_MODE_BITSIZE (<MODE>mode)-1
16412 && ix86_pre_reload_split ()"
16413 "#"
16414 "&& 1"
16415 [(parallel
16416 [(set (match_dup 0)
16417 (and:SWI48
16418 (rotate:SWI48 (const_int -2)
16419 (match_dup 1))
16420 (match_dup 3)))
16421 (clobber (reg:CC FLAGS_REG))])]
16422 {
16423 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
16424 operands[1] = gen_lowpart (QImode, operands[1]);
16425 })
16426
16427 (define_insn_and_split "*btr<mode>_mask_1"
16428 [(set (match_operand:SWI48 0 "register_operand")
16429 (and:SWI48
16430 (rotate:SWI48
16431 (const_int -2)
16432 (and:QI
16433 (match_operand:QI 1 "register_operand")
16434 (match_operand:QI 2 "const_int_operand")))
16435 (match_operand:SWI48 3 "register_operand")))
16436 (clobber (reg:CC FLAGS_REG))]
16437 "TARGET_USE_BT
16438 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16439 == GET_MODE_BITSIZE (<MODE>mode)-1
16440 && ix86_pre_reload_split ()"
16441 "#"
16442 "&& 1"
16443 [(parallel
16444 [(set (match_dup 0)
16445 (and:SWI48
16446 (rotate:SWI48 (const_int -2)
16447 (match_dup 1))
16448 (match_dup 3)))
16449 (clobber (reg:CC FLAGS_REG))])])
16450
16451 (define_insn_and_split "*btr<mode>_1"
16452 [(set (match_operand:SWI12 0 "register_operand")
16453 (and:SWI12
16454 (subreg:SWI12
16455 (rotate:SI (const_int -2)
16456 (match_operand:QI 2 "register_operand")) 0)
16457 (match_operand:SWI12 1 "nonimmediate_operand")))
16458 (clobber (reg:CC FLAGS_REG))]
16459 "TARGET_USE_BT && ix86_pre_reload_split ()"
16460 "#"
16461 "&& 1"
16462 [(parallel
16463 [(set (match_dup 0)
16464 (and:SI (rotate:SI (const_int -2) (match_dup 2))
16465 (match_dup 1)))
16466 (clobber (reg:CC FLAGS_REG))])]
16467 {
16468 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16469 operands[1] = force_reg (<MODE>mode, operands[1]);
16470 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
16471 })
16472
16473 (define_insn_and_split "*btr<mode>_2"
16474 [(set (zero_extract:HI
16475 (match_operand:SWI12 0 "nonimmediate_operand")
16476 (const_int 1)
16477 (match_operand:QI 1 "register_operand"))
16478 (const_int 0))
16479 (clobber (reg:CC FLAGS_REG))]
16480 "TARGET_USE_BT && ix86_pre_reload_split ()"
16481 "#"
16482 "&& MEM_P (operands[0])"
16483 [(set (match_dup 2) (match_dup 0))
16484 (parallel
16485 [(set (match_dup 3)
16486 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16487 (match_dup 4)))
16488 (clobber (reg:CC FLAGS_REG))])
16489 (set (match_dup 0) (match_dup 5))]
16490 {
16491 operands[2] = gen_reg_rtx (<MODE>mode);
16492 operands[5] = gen_reg_rtx (<MODE>mode);
16493 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
16494 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
16495 })
16496
16497 (define_split
16498 [(set (zero_extract:HI
16499 (match_operand:SWI12 0 "register_operand")
16500 (const_int 1)
16501 (match_operand:QI 1 "register_operand"))
16502 (const_int 0))
16503 (clobber (reg:CC FLAGS_REG))]
16504 "TARGET_USE_BT && ix86_pre_reload_split ()"
16505 [(parallel
16506 [(set (match_dup 0)
16507 (and:SI (rotate:SI (const_int -2) (match_dup 1))
16508 (match_dup 2)))
16509 (clobber (reg:CC FLAGS_REG))])]
16510 {
16511 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16512 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16513 })
16514
16515 ;; These instructions are never faster than the corresponding
16516 ;; and/ior/xor operations when using immediate operand, so with
16517 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16518 ;; relevant immediates within the instruction itself, so operating
16519 ;; on bits in the high 32-bits of a register becomes easier.
16520 ;;
16521 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16522 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16523 ;; negdf respectively, so they can never be disabled entirely.
16524
16525 (define_insn "*btsq_imm"
16526 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16527 (const_int 1)
16528 (match_operand:QI 1 "const_0_to_63_operand"))
16529 (const_int 1))
16530 (clobber (reg:CC FLAGS_REG))]
16531 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16532 "bts{q}\t{%1, %0|%0, %1}"
16533 [(set_attr "type" "alu1")
16534 (set_attr "prefix_0f" "1")
16535 (set_attr "znver1_decode" "double")
16536 (set_attr "mode" "DI")])
16537
16538 (define_insn "*btrq_imm"
16539 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16540 (const_int 1)
16541 (match_operand:QI 1 "const_0_to_63_operand"))
16542 (const_int 0))
16543 (clobber (reg:CC FLAGS_REG))]
16544 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16545 "btr{q}\t{%1, %0|%0, %1}"
16546 [(set_attr "type" "alu1")
16547 (set_attr "prefix_0f" "1")
16548 (set_attr "znver1_decode" "double")
16549 (set_attr "mode" "DI")])
16550
16551 (define_insn "*btcq_imm"
16552 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16553 (const_int 1)
16554 (match_operand:QI 1 "const_0_to_63_operand"))
16555 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16556 (clobber (reg:CC FLAGS_REG))]
16557 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16558 "btc{q}\t{%1, %0|%0, %1}"
16559 [(set_attr "type" "alu1")
16560 (set_attr "prefix_0f" "1")
16561 (set_attr "znver1_decode" "double")
16562 (set_attr "mode" "DI")])
16563
16564 ;; Allow Nocona to avoid these instructions if a register is available.
16565
16566 (define_peephole2
16567 [(match_scratch:DI 2 "r")
16568 (parallel [(set (zero_extract:DI
16569 (match_operand:DI 0 "nonimmediate_operand")
16570 (const_int 1)
16571 (match_operand:QI 1 "const_0_to_63_operand"))
16572 (const_int 1))
16573 (clobber (reg:CC FLAGS_REG))])]
16574 "TARGET_64BIT && !TARGET_USE_BT"
16575 [(parallel [(set (match_dup 0)
16576 (ior:DI (match_dup 0) (match_dup 3)))
16577 (clobber (reg:CC FLAGS_REG))])]
16578 {
16579 int i = INTVAL (operands[1]);
16580
16581 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16582
16583 if (!x86_64_immediate_operand (operands[3], DImode))
16584 {
16585 emit_move_insn (operands[2], operands[3]);
16586 operands[3] = operands[2];
16587 }
16588 })
16589
16590 (define_peephole2
16591 [(match_scratch:DI 2 "r")
16592 (parallel [(set (zero_extract:DI
16593 (match_operand:DI 0 "nonimmediate_operand")
16594 (const_int 1)
16595 (match_operand:QI 1 "const_0_to_63_operand"))
16596 (const_int 0))
16597 (clobber (reg:CC FLAGS_REG))])]
16598 "TARGET_64BIT && !TARGET_USE_BT"
16599 [(parallel [(set (match_dup 0)
16600 (and:DI (match_dup 0) (match_dup 3)))
16601 (clobber (reg:CC FLAGS_REG))])]
16602 {
16603 int i = INTVAL (operands[1]);
16604
16605 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16606
16607 if (!x86_64_immediate_operand (operands[3], DImode))
16608 {
16609 emit_move_insn (operands[2], operands[3]);
16610 operands[3] = operands[2];
16611 }
16612 })
16613
16614 (define_peephole2
16615 [(match_scratch:DI 2 "r")
16616 (parallel [(set (zero_extract:DI
16617 (match_operand:DI 0 "nonimmediate_operand")
16618 (const_int 1)
16619 (match_operand:QI 1 "const_0_to_63_operand"))
16620 (not:DI (zero_extract:DI
16621 (match_dup 0) (const_int 1) (match_dup 1))))
16622 (clobber (reg:CC FLAGS_REG))])]
16623 "TARGET_64BIT && !TARGET_USE_BT"
16624 [(parallel [(set (match_dup 0)
16625 (xor:DI (match_dup 0) (match_dup 3)))
16626 (clobber (reg:CC FLAGS_REG))])]
16627 {
16628 int i = INTVAL (operands[1]);
16629
16630 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16631
16632 if (!x86_64_immediate_operand (operands[3], DImode))
16633 {
16634 emit_move_insn (operands[2], operands[3]);
16635 operands[3] = operands[2];
16636 }
16637 })
16638
16639 ;; %%% bt
16640
16641 (define_insn "*bt<mode>"
16642 [(set (reg:CCC FLAGS_REG)
16643 (compare:CCC
16644 (zero_extract:SWI48
16645 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16646 (const_int 1)
16647 (match_operand:QI 1 "nonmemory_operand" "q<S>,<S>"))
16648 (const_int 0)))]
16649 ""
16650 {
16651 switch (get_attr_mode (insn))
16652 {
16653 case MODE_SI:
16654 return "bt{l}\t{%k1, %k0|%k0, %k1}";
16655
16656 case MODE_DI:
16657 return "bt{q}\t{%q1, %0|%0, %q1}";
16658
16659 default:
16660 gcc_unreachable ();
16661 }
16662 }
16663 [(set_attr "type" "alu1")
16664 (set_attr "prefix_0f" "1")
16665 (set (attr "mode")
16666 (if_then_else
16667 (and (match_test "CONST_INT_P (operands[1])")
16668 (match_test "INTVAL (operands[1]) < 32"))
16669 (const_string "SI")
16670 (const_string "<MODE>")))])
16671
16672 (define_insn_and_split "*bt<SWI48:mode>_mask"
16673 [(set (reg:CCC FLAGS_REG)
16674 (compare:CCC
16675 (zero_extract:SWI48
16676 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16677 (const_int 1)
16678 (subreg:QI
16679 (and:SWI248
16680 (match_operand:SWI248 1 "register_operand")
16681 (match_operand 2 "const_int_operand")) 0))
16682 (const_int 0)))]
16683 "TARGET_USE_BT
16684 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16685 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16686 && ix86_pre_reload_split ()"
16687 "#"
16688 "&& 1"
16689 [(set (reg:CCC FLAGS_REG)
16690 (compare:CCC
16691 (zero_extract:SWI48 (match_dup 0) (const_int 1) (match_dup 1))
16692 (const_int 0)))]
16693 "operands[1] = gen_lowpart (QImode, operands[1]);")
16694
16695 (define_insn_and_split "*jcc_bt<mode>"
16696 [(set (pc)
16697 (if_then_else (match_operator 0 "bt_comparison_operator"
16698 [(zero_extract:SWI48
16699 (match_operand:SWI48 1 "nonimmediate_operand")
16700 (const_int 1)
16701 (match_operand:QI 2 "nonmemory_operand"))
16702 (const_int 0)])
16703 (label_ref (match_operand 3))
16704 (pc)))
16705 (clobber (reg:CC FLAGS_REG))]
16706 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16707 && (CONST_INT_P (operands[2])
16708 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16709 && INTVAL (operands[2])
16710 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16711 : !memory_operand (operands[1], <MODE>mode))
16712 && ix86_pre_reload_split ()"
16713 "#"
16714 "&& 1"
16715 [(set (reg:CCC FLAGS_REG)
16716 (compare:CCC
16717 (zero_extract:SWI48
16718 (match_dup 1)
16719 (const_int 1)
16720 (match_dup 2))
16721 (const_int 0)))
16722 (set (pc)
16723 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16724 (label_ref (match_dup 3))
16725 (pc)))]
16726 {
16727 operands[0] = shallow_copy_rtx (operands[0]);
16728 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16729 })
16730
16731 ;; Avoid useless masking of bit offset operand.
16732 (define_insn_and_split "*jcc_bt<mode>_mask"
16733 [(set (pc)
16734 (if_then_else (match_operator 0 "bt_comparison_operator"
16735 [(zero_extract:SWI48
16736 (match_operand:SWI48 1 "register_operand")
16737 (const_int 1)
16738 (and:QI
16739 (match_operand:QI 2 "register_operand")
16740 (match_operand 3 "const_int_operand")))])
16741 (label_ref (match_operand 4))
16742 (pc)))
16743 (clobber (reg:CC FLAGS_REG))]
16744 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16745 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16746 == GET_MODE_BITSIZE (<MODE>mode)-1
16747 && ix86_pre_reload_split ()"
16748 "#"
16749 "&& 1"
16750 [(set (reg:CCC FLAGS_REG)
16751 (compare:CCC
16752 (zero_extract:SWI48
16753 (match_dup 1)
16754 (const_int 1)
16755 (match_dup 2))
16756 (const_int 0)))
16757 (set (pc)
16758 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16759 (label_ref (match_dup 4))
16760 (pc)))]
16761 {
16762 operands[0] = shallow_copy_rtx (operands[0]);
16763 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16764 })
16765
16766 ;; Avoid useless masking of bit offset operand.
16767 (define_insn_and_split "*jcc_bt<SWI48:mode>_mask_1"
16768 [(set (pc)
16769 (if_then_else (match_operator 0 "bt_comparison_operator"
16770 [(zero_extract:SWI48
16771 (match_operand:SWI48 1 "register_operand")
16772 (const_int 1)
16773 (subreg:QI
16774 (and:SWI248
16775 (match_operand:SWI248 2 "register_operand")
16776 (match_operand 3 "const_int_operand")) 0))])
16777 (label_ref (match_operand 4))
16778 (pc)))
16779 (clobber (reg:CC FLAGS_REG))]
16780 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16781 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
16782 == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
16783 && ix86_pre_reload_split ()"
16784 "#"
16785 "&& 1"
16786 [(set (reg:CCC FLAGS_REG)
16787 (compare:CCC
16788 (zero_extract:SWI48
16789 (match_dup 1)
16790 (const_int 1)
16791 (match_dup 2))
16792 (const_int 0)))
16793 (set (pc)
16794 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16795 (label_ref (match_dup 4))
16796 (pc)))]
16797 {
16798 operands[0] = shallow_copy_rtx (operands[0]);
16799 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16800 operands[2] = gen_lowpart (QImode, operands[2]);
16801 })
16802
16803 ;; Help combine recognize bt followed by cmov
16804 (define_split
16805 [(set (match_operand:SWI248 0 "register_operand")
16806 (if_then_else:SWI248
16807 (match_operator 5 "bt_comparison_operator"
16808 [(zero_extract:SWI48
16809 (match_operand:SWI48 1 "register_operand")
16810 (const_int 1)
16811 (match_operand:QI 2 "register_operand"))
16812 (const_int 0)])
16813 (match_operand:SWI248 3 "nonimmediate_operand")
16814 (match_operand:SWI248 4 "nonimmediate_operand")))]
16815 "TARGET_USE_BT && TARGET_CMOVE
16816 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16817 && ix86_pre_reload_split ()"
16818 [(set (reg:CCC FLAGS_REG)
16819 (compare:CCC
16820 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16821 (const_int 0)))
16822 (set (match_dup 0)
16823 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16824 (match_dup 3)
16825 (match_dup 4)))]
16826 {
16827 if (GET_CODE (operands[5]) == EQ)
16828 std::swap (operands[3], operands[4]);
16829 })
16830
16831 ;; Help combine recognize bt followed by setc
16832 (define_insn_and_split "*bt<mode>_setcqi"
16833 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16834 (zero_extract:SWI48
16835 (match_operand:SWI48 1 "register_operand")
16836 (const_int 1)
16837 (match_operand:QI 2 "register_operand")))
16838 (clobber (reg:CC FLAGS_REG))]
16839 "TARGET_USE_BT && ix86_pre_reload_split ()"
16840 "#"
16841 "&& 1"
16842 [(set (reg:CCC FLAGS_REG)
16843 (compare:CCC
16844 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16845 (const_int 0)))
16846 (set (match_dup 0)
16847 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16848
16849 ;; Help combine recognize bt followed by setnc
16850 (define_insn_and_split "*bt<mode>_setncqi"
16851 [(set (match_operand:QI 0 "register_operand")
16852 (and:QI
16853 (not:QI
16854 (subreg:QI
16855 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16856 (match_operand:QI 2 "register_operand")) 0))
16857 (const_int 1)))
16858 (clobber (reg:CC FLAGS_REG))]
16859 "TARGET_USE_BT && ix86_pre_reload_split ()"
16860 "#"
16861 "&& 1"
16862 [(set (reg:CCC FLAGS_REG)
16863 (compare:CCC
16864 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16865 (const_int 0)))
16866 (set (match_dup 0)
16867 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16868
16869 (define_insn_and_split "*bt<mode>_setnc<mode>"
16870 [(set (match_operand:SWI48 0 "register_operand")
16871 (and:SWI48
16872 (not:SWI48
16873 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16874 (match_operand:QI 2 "register_operand")))
16875 (const_int 1)))
16876 (clobber (reg:CC FLAGS_REG))]
16877 "TARGET_USE_BT && ix86_pre_reload_split ()"
16878 "#"
16879 "&& 1"
16880 [(set (reg:CCC FLAGS_REG)
16881 (compare:CCC
16882 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16883 (const_int 0)))
16884 (set (match_dup 3)
16885 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16886 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16887 "operands[3] = gen_reg_rtx (QImode);")
16888
16889 ;; Help combine recognize bt followed by setnc (PR target/110588)
16890 (define_insn_and_split "*bt<mode>_setncqi_2"
16891 [(set (match_operand:QI 0 "register_operand")
16892 (eq:QI
16893 (zero_extract:SWI48
16894 (match_operand:SWI48 1 "register_operand")
16895 (const_int 1)
16896 (match_operand:QI 2 "register_operand"))
16897 (const_int 0)))
16898 (clobber (reg:CC FLAGS_REG))]
16899 "TARGET_USE_BT && ix86_pre_reload_split ()"
16900 "#"
16901 "&& 1"
16902 [(set (reg:CCC FLAGS_REG)
16903 (compare:CCC
16904 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16905 (const_int 0)))
16906 (set (match_dup 0)
16907 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
16908
16909 ;; Help combine recognize bt followed by setc
16910 (define_insn_and_split "*bt<mode>_setc<mode>_mask"
16911 [(set (match_operand:SWI48 0 "register_operand")
16912 (zero_extract:SWI48
16913 (match_operand:SWI48 1 "register_operand")
16914 (const_int 1)
16915 (subreg:QI
16916 (and:SWI48
16917 (match_operand:SWI48 2 "register_operand")
16918 (match_operand 3 "const_int_operand")) 0)))
16919 (clobber (reg:CC FLAGS_REG))]
16920 "TARGET_USE_BT
16921 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16922 == GET_MODE_BITSIZE (<MODE>mode)-1
16923 && ix86_pre_reload_split ()"
16924 "#"
16925 "&& 1"
16926 [(set (reg:CCC FLAGS_REG)
16927 (compare:CCC
16928 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16929 (const_int 0)))
16930 (set (match_dup 3)
16931 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))
16932 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16933 {
16934 operands[2] = gen_lowpart (QImode, operands[2]);
16935 operands[3] = gen_reg_rtx (QImode);
16936 })
16937 \f
16938 ;; Store-flag instructions.
16939
16940 (define_split
16941 [(set (match_operand:QI 0 "nonimmediate_operand")
16942 (match_operator:QI 1 "add_comparison_operator"
16943 [(not:SWI (match_operand:SWI 2 "register_operand"))
16944 (match_operand:SWI 3 "nonimmediate_operand")]))]
16945 ""
16946 [(set (reg:CCC FLAGS_REG)
16947 (compare:CCC
16948 (plus:SWI (match_dup 2) (match_dup 3))
16949 (match_dup 2)))
16950 (set (match_dup 0)
16951 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16952
16953 (define_split
16954 [(set (match_operand:QI 0 "nonimmediate_operand")
16955 (match_operator:QI 1 "shr_comparison_operator"
16956 [(match_operand:DI 2 "register_operand")
16957 (match_operand 3 "const_int_operand")]))]
16958 "TARGET_64BIT
16959 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16960 [(set (reg:CCZ FLAGS_REG)
16961 (compare:CCZ
16962 (lshiftrt:DI (match_dup 2) (match_dup 4))
16963 (const_int 0)))
16964 (set (match_dup 0)
16965 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16966 {
16967 enum rtx_code new_code;
16968
16969 operands[1] = shallow_copy_rtx (operands[1]);
16970 switch (GET_CODE (operands[1]))
16971 {
16972 case GTU: new_code = NE; break;
16973 case LEU: new_code = EQ; break;
16974 default: gcc_unreachable ();
16975 }
16976 PUT_CODE (operands[1], new_code);
16977
16978 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16979 })
16980
16981 ;; For all sCOND expanders, also expand the compare or test insn that
16982 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16983
16984 (define_insn_and_split "*setcc_di_1"
16985 [(set (match_operand:DI 0 "register_operand" "=q")
16986 (match_operator:DI 1 "ix86_comparison_operator"
16987 [(reg FLAGS_REG) (const_int 0)]))]
16988 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16989 "#"
16990 "&& reload_completed"
16991 [(set (match_dup 2) (match_dup 1))
16992 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16993 {
16994 operands[1] = shallow_copy_rtx (operands[1]);
16995 PUT_MODE (operands[1], QImode);
16996 operands[2] = gen_lowpart (QImode, operands[0]);
16997 })
16998
16999 (define_insn_and_split "*setcc_<mode>_1_and"
17000 [(set (match_operand:SWI24 0 "register_operand" "=q")
17001 (match_operator:SWI24 1 "ix86_comparison_operator"
17002 [(reg FLAGS_REG) (const_int 0)]))
17003 (clobber (reg:CC FLAGS_REG))]
17004 "!TARGET_PARTIAL_REG_STALL
17005 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
17006 "#"
17007 "&& reload_completed"
17008 [(set (match_dup 2) (match_dup 1))
17009 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
17010 (clobber (reg:CC FLAGS_REG))])]
17011 {
17012 operands[1] = shallow_copy_rtx (operands[1]);
17013 PUT_MODE (operands[1], QImode);
17014 operands[2] = gen_lowpart (QImode, operands[0]);
17015 })
17016
17017 (define_insn_and_split "*setcc_<mode>_1_movzbl"
17018 [(set (match_operand:SWI24 0 "register_operand" "=q")
17019 (match_operator:SWI24 1 "ix86_comparison_operator"
17020 [(reg FLAGS_REG) (const_int 0)]))]
17021 "!TARGET_PARTIAL_REG_STALL
17022 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
17023 "#"
17024 "&& reload_completed"
17025 [(set (match_dup 2) (match_dup 1))
17026 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
17027 {
17028 operands[1] = shallow_copy_rtx (operands[1]);
17029 PUT_MODE (operands[1], QImode);
17030 operands[2] = gen_lowpart (QImode, operands[0]);
17031 })
17032
17033 (define_insn "*setcc_qi"
17034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17035 (match_operator:QI 1 "ix86_comparison_operator"
17036 [(reg FLAGS_REG) (const_int 0)]))]
17037 ""
17038 "set%C1\t%0"
17039 [(set_attr "type" "setcc")
17040 (set_attr "mode" "QI")])
17041
17042 (define_insn "*setcc_qi_slp"
17043 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
17044 (match_operator:QI 1 "ix86_comparison_operator"
17045 [(reg FLAGS_REG) (const_int 0)]))]
17046 ""
17047 "set%C1\t%0"
17048 [(set_attr "type" "setcc")
17049 (set_attr "mode" "QI")])
17050
17051 ;; In general it is not safe to assume too much about CCmode registers,
17052 ;; so simplify-rtx stops when it sees a second one. Under certain
17053 ;; conditions this is safe on x86, so help combine not create
17054 ;;
17055 ;; seta %al
17056 ;; testb %al, %al
17057 ;; sete %al
17058
17059 (define_split
17060 [(set (match_operand:QI 0 "nonimmediate_operand")
17061 (ne:QI (match_operator 1 "ix86_comparison_operator"
17062 [(reg FLAGS_REG) (const_int 0)])
17063 (const_int 0)))]
17064 ""
17065 [(set (match_dup 0) (match_dup 1))]
17066 {
17067 operands[1] = shallow_copy_rtx (operands[1]);
17068 PUT_MODE (operands[1], QImode);
17069 })
17070
17071 (define_split
17072 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
17073 (ne:QI (match_operator 1 "ix86_comparison_operator"
17074 [(reg FLAGS_REG) (const_int 0)])
17075 (const_int 0)))]
17076 ""
17077 [(set (match_dup 0) (match_dup 1))]
17078 {
17079 operands[1] = shallow_copy_rtx (operands[1]);
17080 PUT_MODE (operands[1], QImode);
17081 })
17082
17083 (define_split
17084 [(set (match_operand:QI 0 "nonimmediate_operand")
17085 (eq:QI (match_operator 1 "ix86_comparison_operator"
17086 [(reg FLAGS_REG) (const_int 0)])
17087 (const_int 0)))]
17088 ""
17089 [(set (match_dup 0) (match_dup 1))]
17090 {
17091 operands[1] = shallow_copy_rtx (operands[1]);
17092 PUT_MODE (operands[1], QImode);
17093 PUT_CODE (operands[1],
17094 ix86_reverse_condition (GET_CODE (operands[1]),
17095 GET_MODE (XEXP (operands[1], 0))));
17096
17097 /* Make sure that (a) the CCmode we have for the flags is strong
17098 enough for the reversed compare or (b) we have a valid FP compare. */
17099 if (! ix86_comparison_operator (operands[1], VOIDmode))
17100 FAIL;
17101 })
17102
17103 (define_split
17104 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
17105 (eq:QI (match_operator 1 "ix86_comparison_operator"
17106 [(reg FLAGS_REG) (const_int 0)])
17107 (const_int 0)))]
17108 ""
17109 [(set (match_dup 0) (match_dup 1))]
17110 {
17111 operands[1] = shallow_copy_rtx (operands[1]);
17112 PUT_MODE (operands[1], QImode);
17113 PUT_CODE (operands[1],
17114 ix86_reverse_condition (GET_CODE (operands[1]),
17115 GET_MODE (XEXP (operands[1], 0))));
17116
17117 /* Make sure that (a) the CCmode we have for the flags is strong
17118 enough for the reversed compare or (b) we have a valid FP compare. */
17119 if (! ix86_comparison_operator (operands[1], VOIDmode))
17120 FAIL;
17121 })
17122
17123 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
17124 ;; subsequent logical operations are used to imitate conditional moves.
17125 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
17126 ;; it directly.
17127
17128 (define_insn "setcc_<mode>_sse"
17129 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17130 (match_operator:MODEF 3 "sse_comparison_operator"
17131 [(match_operand:MODEF 1 "register_operand" "0,x")
17132 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xjm")]))]
17133 "SSE_FLOAT_MODE_P (<MODE>mode)"
17134 "@
17135 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
17136 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17137 [(set_attr "isa" "noavx,avx")
17138 (set_attr "addr" "*,gpr16")
17139 (set_attr "type" "ssecmp")
17140 (set_attr "length_immediate" "1")
17141 (set_attr "prefix" "orig,vex")
17142 (set_attr "mode" "<MODE>")])
17143
17144 (define_insn "setcc_hf_mask"
17145 [(set (match_operand:QI 0 "register_operand" "=k")
17146 (unspec:QI
17147 [(match_operand:HF 1 "register_operand" "v")
17148 (match_operand:HF 2 "nonimmediate_operand" "vm")
17149 (match_operand:SI 3 "const_0_to_31_operand")]
17150 UNSPEC_PCMP))]
17151 "TARGET_AVX512FP16"
17152 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
17153 [(set_attr "type" "ssecmp")
17154 (set_attr "prefix" "evex")
17155 (set_attr "mode" "HF")])
17156
17157 \f
17158 ;; Basic conditional jump instructions.
17159
17160 (define_split
17161 [(set (pc)
17162 (if_then_else
17163 (match_operator 1 "add_comparison_operator"
17164 [(not:SWI (match_operand:SWI 2 "register_operand"))
17165 (match_operand:SWI 3 "nonimmediate_operand")])
17166 (label_ref (match_operand 0))
17167 (pc)))]
17168 ""
17169 [(set (reg:CCC FLAGS_REG)
17170 (compare:CCC
17171 (plus:SWI (match_dup 2) (match_dup 3))
17172 (match_dup 2)))
17173 (set (pc)
17174 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
17175 (label_ref (match_operand 0))
17176 (pc)))])
17177
17178 (define_split
17179 [(set (pc)
17180 (if_then_else
17181 (match_operator 1 "shr_comparison_operator"
17182 [(match_operand:DI 2 "register_operand")
17183 (match_operand 3 "const_int_operand")])
17184 (label_ref (match_operand 0))
17185 (pc)))]
17186 "TARGET_64BIT
17187 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
17188 [(set (reg:CCZ FLAGS_REG)
17189 (compare:CCZ
17190 (lshiftrt:DI (match_dup 2) (match_dup 4))
17191 (const_int 0)))
17192 (set (pc)
17193 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
17194 (label_ref (match_operand 0))
17195 (pc)))]
17196 {
17197 enum rtx_code new_code;
17198
17199 operands[1] = shallow_copy_rtx (operands[1]);
17200 switch (GET_CODE (operands[1]))
17201 {
17202 case GTU: new_code = NE; break;
17203 case LEU: new_code = EQ; break;
17204 default: gcc_unreachable ();
17205 }
17206 PUT_CODE (operands[1], new_code);
17207
17208 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
17209 })
17210
17211 ;; We ignore the overflow flag for signed branch instructions.
17212
17213 (define_insn "*jcc"
17214 [(set (pc)
17215 (if_then_else (match_operator 1 "ix86_comparison_operator"
17216 [(reg FLAGS_REG) (const_int 0)])
17217 (label_ref (match_operand 0))
17218 (pc)))]
17219 ""
17220 "%!%+j%C1\t%l0"
17221 [(set_attr "type" "ibr")
17222 (set_attr "modrm" "0")
17223 (set (attr "length")
17224 (if_then_else
17225 (and (ge (minus (match_dup 0) (pc))
17226 (const_int -126))
17227 (lt (minus (match_dup 0) (pc))
17228 (const_int 128)))
17229 (const_int 2)
17230 (const_int 6)))])
17231
17232 ;; In general it is not safe to assume too much about CCmode registers,
17233 ;; so simplify-rtx stops when it sees a second one. Under certain
17234 ;; conditions this is safe on x86, so help combine not create
17235 ;;
17236 ;; seta %al
17237 ;; testb %al, %al
17238 ;; je Lfoo
17239
17240 (define_split
17241 [(set (pc)
17242 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
17243 [(reg FLAGS_REG) (const_int 0)])
17244 (const_int 0))
17245 (label_ref (match_operand 1))
17246 (pc)))]
17247 ""
17248 [(set (pc)
17249 (if_then_else (match_dup 0)
17250 (label_ref (match_dup 1))
17251 (pc)))]
17252 {
17253 operands[0] = shallow_copy_rtx (operands[0]);
17254 PUT_MODE (operands[0], VOIDmode);
17255 })
17256
17257 (define_split
17258 [(set (pc)
17259 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
17260 [(reg FLAGS_REG) (const_int 0)])
17261 (const_int 0))
17262 (label_ref (match_operand 1))
17263 (pc)))]
17264 ""
17265 [(set (pc)
17266 (if_then_else (match_dup 0)
17267 (label_ref (match_dup 1))
17268 (pc)))]
17269 {
17270 operands[0] = shallow_copy_rtx (operands[0]);
17271 PUT_MODE (operands[0], VOIDmode);
17272 PUT_CODE (operands[0],
17273 ix86_reverse_condition (GET_CODE (operands[0]),
17274 GET_MODE (XEXP (operands[0], 0))));
17275
17276 /* Make sure that (a) the CCmode we have for the flags is strong
17277 enough for the reversed compare or (b) we have a valid FP compare. */
17278 if (! ix86_comparison_operator (operands[0], VOIDmode))
17279 FAIL;
17280 })
17281 \f
17282 ;; Unconditional and other jump instructions
17283
17284 (define_insn "jump"
17285 [(set (pc)
17286 (label_ref (match_operand 0)))]
17287 ""
17288 "%!jmp\t%l0"
17289 [(set_attr "type" "ibr")
17290 (set_attr "modrm" "0")
17291 (set (attr "length")
17292 (if_then_else
17293 (and (ge (minus (match_dup 0) (pc))
17294 (const_int -126))
17295 (lt (minus (match_dup 0) (pc))
17296 (const_int 128)))
17297 (const_int 2)
17298 (const_int 5)))])
17299
17300 (define_expand "indirect_jump"
17301 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
17302 ""
17303 {
17304 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17305 operands[0] = convert_memory_address (word_mode, operands[0]);
17306 cfun->machine->has_local_indirect_jump = true;
17307 })
17308
17309 (define_insn "*indirect_jump"
17310 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
17311 ""
17312 "* return ix86_output_indirect_jmp (operands[0]);"
17313 [(set (attr "type")
17314 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17315 != indirect_branch_keep)")
17316 (const_string "multi")
17317 (const_string "ibr")))
17318 (set_attr "length_immediate" "0")])
17319
17320 (define_expand "tablejump"
17321 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
17322 (use (label_ref (match_operand 1)))])]
17323 ""
17324 {
17325 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
17326 relative. Convert the relative address to an absolute address. */
17327 if (flag_pic)
17328 {
17329 rtx op0, op1;
17330 enum rtx_code code;
17331
17332 /* We can't use @GOTOFF for text labels on VxWorks;
17333 see gotoff_operand. */
17334 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
17335 {
17336 code = PLUS;
17337 op0 = operands[0];
17338 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
17339 }
17340 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
17341 {
17342 code = PLUS;
17343 op0 = operands[0];
17344 op1 = pic_offset_table_rtx;
17345 }
17346 else
17347 {
17348 code = MINUS;
17349 op0 = pic_offset_table_rtx;
17350 op1 = operands[0];
17351 }
17352
17353 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
17354 OPTAB_DIRECT);
17355 }
17356
17357 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
17358 operands[0] = convert_memory_address (word_mode, operands[0]);
17359 cfun->machine->has_local_indirect_jump = true;
17360 })
17361
17362 (define_insn "*tablejump_1"
17363 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
17364 (use (label_ref (match_operand 1)))]
17365 ""
17366 "* return ix86_output_indirect_jmp (operands[0]);"
17367 [(set (attr "type")
17368 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17369 != indirect_branch_keep)")
17370 (const_string "multi")
17371 (const_string "ibr")))
17372 (set_attr "length_immediate" "0")])
17373 \f
17374 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
17375
17376 (define_peephole2
17377 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17378 (set (match_operand:QI 1 "register_operand")
17379 (match_operator:QI 2 "ix86_comparison_operator"
17380 [(reg FLAGS_REG) (const_int 0)]))
17381 (set (match_operand 3 "any_QIreg_operand")
17382 (zero_extend (match_dup 1)))]
17383 "(peep2_reg_dead_p (3, operands[1])
17384 || operands_match_p (operands[1], operands[3]))
17385 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17386 && peep2_regno_dead_p (0, FLAGS_REG)"
17387 [(set (match_dup 4) (match_dup 0))
17388 (set (strict_low_part (match_dup 5))
17389 (match_dup 2))]
17390 {
17391 operands[5] = gen_lowpart (QImode, operands[3]);
17392 ix86_expand_clear (operands[3]);
17393 })
17394
17395 (define_peephole2
17396 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17397 (match_operand 4)])
17398 (set (match_operand:QI 1 "register_operand")
17399 (match_operator:QI 2 "ix86_comparison_operator"
17400 [(reg FLAGS_REG) (const_int 0)]))
17401 (set (match_operand 3 "any_QIreg_operand")
17402 (zero_extend (match_dup 1)))]
17403 "(peep2_reg_dead_p (3, operands[1])
17404 || operands_match_p (operands[1], operands[3]))
17405 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17406 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17407 && ! reg_set_p (operands[3], operands[4])
17408 && peep2_regno_dead_p (0, FLAGS_REG)"
17409 [(parallel [(set (match_dup 5) (match_dup 0))
17410 (match_dup 4)])
17411 (set (strict_low_part (match_dup 6))
17412 (match_dup 2))]
17413 {
17414 operands[6] = gen_lowpart (QImode, operands[3]);
17415 ix86_expand_clear (operands[3]);
17416 })
17417
17418 (define_peephole2
17419 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17420 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17421 (match_operand 5)])
17422 (set (match_operand:QI 2 "register_operand")
17423 (match_operator:QI 3 "ix86_comparison_operator"
17424 [(reg FLAGS_REG) (const_int 0)]))
17425 (set (match_operand 4 "any_QIreg_operand")
17426 (zero_extend (match_dup 2)))]
17427 "(peep2_reg_dead_p (4, operands[2])
17428 || operands_match_p (operands[2], operands[4]))
17429 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17430 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17431 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17432 && ! reg_set_p (operands[4], operands[5])
17433 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17434 && peep2_regno_dead_p (0, FLAGS_REG)"
17435 [(set (match_dup 6) (match_dup 0))
17436 (parallel [(set (match_dup 7) (match_dup 1))
17437 (match_dup 5)])
17438 (set (strict_low_part (match_dup 8))
17439 (match_dup 3))]
17440 {
17441 operands[8] = gen_lowpart (QImode, operands[4]);
17442 ix86_expand_clear (operands[4]);
17443 })
17444
17445 ;; Similar, but match zero extend with andsi3.
17446
17447 (define_peephole2
17448 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
17449 (set (match_operand:QI 1 "register_operand")
17450 (match_operator:QI 2 "ix86_comparison_operator"
17451 [(reg FLAGS_REG) (const_int 0)]))
17452 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
17453 (and:SI (match_dup 3) (const_int 255)))
17454 (clobber (reg:CC FLAGS_REG))])]
17455 "REGNO (operands[1]) == REGNO (operands[3])
17456 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17457 && peep2_regno_dead_p (0, FLAGS_REG)"
17458 [(set (match_dup 4) (match_dup 0))
17459 (set (strict_low_part (match_dup 5))
17460 (match_dup 2))]
17461 {
17462 operands[5] = gen_lowpart (QImode, operands[3]);
17463 ix86_expand_clear (operands[3]);
17464 })
17465
17466 (define_peephole2
17467 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
17468 (match_operand 4)])
17469 (set (match_operand:QI 1 "register_operand")
17470 (match_operator:QI 2 "ix86_comparison_operator"
17471 [(reg FLAGS_REG) (const_int 0)]))
17472 (parallel [(set (match_operand 3 "any_QIreg_operand")
17473 (zero_extend (match_dup 1)))
17474 (clobber (reg:CC FLAGS_REG))])]
17475 "(peep2_reg_dead_p (3, operands[1])
17476 || operands_match_p (operands[1], operands[3]))
17477 && ! reg_overlap_mentioned_p (operands[3], operands[0])
17478 && ! reg_overlap_mentioned_p (operands[3], operands[4])
17479 && ! reg_set_p (operands[3], operands[4])
17480 && peep2_regno_dead_p (0, FLAGS_REG)"
17481 [(parallel [(set (match_dup 5) (match_dup 0))
17482 (match_dup 4)])
17483 (set (strict_low_part (match_dup 6))
17484 (match_dup 2))]
17485 {
17486 operands[6] = gen_lowpart (QImode, operands[3]);
17487 ix86_expand_clear (operands[3]);
17488 })
17489
17490 (define_peephole2
17491 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
17492 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
17493 (match_operand 5)])
17494 (set (match_operand:QI 2 "register_operand")
17495 (match_operator:QI 3 "ix86_comparison_operator"
17496 [(reg FLAGS_REG) (const_int 0)]))
17497 (parallel [(set (match_operand 4 "any_QIreg_operand")
17498 (zero_extend (match_dup 2)))
17499 (clobber (reg:CC FLAGS_REG))])]
17500 "(peep2_reg_dead_p (4, operands[2])
17501 || operands_match_p (operands[2], operands[4]))
17502 && ! reg_overlap_mentioned_p (operands[4], operands[0])
17503 && ! reg_overlap_mentioned_p (operands[4], operands[1])
17504 && ! reg_overlap_mentioned_p (operands[4], operands[5])
17505 && ! reg_set_p (operands[4], operands[5])
17506 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
17507 && peep2_regno_dead_p (0, FLAGS_REG)"
17508 [(set (match_dup 6) (match_dup 0))
17509 (parallel [(set (match_dup 7) (match_dup 1))
17510 (match_dup 5)])
17511 (set (strict_low_part (match_dup 8))
17512 (match_dup 3))]
17513 {
17514 operands[8] = gen_lowpart (QImode, operands[4]);
17515 ix86_expand_clear (operands[4]);
17516 })
17517 \f
17518 ;; Call instructions.
17519
17520 ;; The predicates normally associated with named expanders are not properly
17521 ;; checked for calls. This is a bug in the generic code, but it isn't that
17522 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17523
17524 ;; P6 processors will jump to the address after the decrement when %esp
17525 ;; is used as a call operand, so they will execute return address as a code.
17526 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17527
17528 ;; Register constraint for call instruction.
17529 (define_mode_attr c [(SI "l") (DI "r")])
17530
17531 ;; Call subroutine returning no value.
17532
17533 (define_expand "call"
17534 [(call (match_operand:QI 0)
17535 (match_operand 1))
17536 (use (match_operand 2))]
17537 ""
17538 {
17539 ix86_expand_call (NULL, operands[0], operands[1],
17540 operands[2], NULL, false);
17541 DONE;
17542 })
17543
17544 (define_expand "sibcall"
17545 [(call (match_operand:QI 0)
17546 (match_operand 1))
17547 (use (match_operand 2))]
17548 ""
17549 {
17550 ix86_expand_call (NULL, operands[0], operands[1],
17551 operands[2], NULL, true);
17552 DONE;
17553 })
17554
17555 (define_insn "*call"
17556 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17557 (match_operand 1))]
17558 "!SIBLING_CALL_P (insn)"
17559 "* return ix86_output_call_insn (insn, operands[0]);"
17560 [(set_attr "type" "call")])
17561
17562 ;; This covers both call and sibcall since only GOT slot is allowed.
17563 (define_insn "*call_got_x32"
17564 [(call (mem:QI (zero_extend:DI
17565 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17566 (match_operand 1))]
17567 "TARGET_X32"
17568 {
17569 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17570 return ix86_output_call_insn (insn, fnaddr);
17571 }
17572 [(set_attr "type" "call")])
17573
17574 ;; Since sibcall never returns, we can only use call-clobbered register
17575 ;; as GOT base.
17576 (define_insn "*sibcall_GOT_32"
17577 [(call (mem:QI
17578 (mem:SI (plus:SI
17579 (match_operand:SI 0 "register_no_elim_operand" "U")
17580 (match_operand:SI 1 "GOT32_symbol_operand"))))
17581 (match_operand 2))]
17582 "!TARGET_MACHO
17583 && !TARGET_64BIT
17584 && !TARGET_INDIRECT_BRANCH_REGISTER
17585 && SIBLING_CALL_P (insn)"
17586 {
17587 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17588 fnaddr = gen_const_mem (SImode, fnaddr);
17589 return ix86_output_call_insn (insn, fnaddr);
17590 }
17591 [(set_attr "type" "call")])
17592
17593 (define_insn "*sibcall"
17594 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17595 (match_operand 1))]
17596 "SIBLING_CALL_P (insn)"
17597 "* return ix86_output_call_insn (insn, operands[0]);"
17598 [(set_attr "type" "call")])
17599
17600 (define_insn "*sibcall_memory"
17601 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17602 (match_operand 1))
17603 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17604 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17605 "* return ix86_output_call_insn (insn, operands[0]);"
17606 [(set_attr "type" "call")])
17607
17608 (define_peephole2
17609 [(set (match_operand:W 0 "register_operand")
17610 (match_operand:W 1 "memory_operand"))
17611 (call (mem:QI (match_dup 0))
17612 (match_operand 3))]
17613 "!TARGET_X32
17614 && !TARGET_INDIRECT_BRANCH_REGISTER
17615 && SIBLING_CALL_P (peep2_next_insn (1))
17616 && !reg_mentioned_p (operands[0],
17617 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17618 [(parallel [(call (mem:QI (match_dup 1))
17619 (match_dup 3))
17620 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17621
17622 (define_peephole2
17623 [(set (match_operand:W 0 "register_operand")
17624 (match_operand:W 1 "memory_operand"))
17625 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17626 (call (mem:QI (match_dup 0))
17627 (match_operand 3))]
17628 "!TARGET_X32
17629 && !TARGET_INDIRECT_BRANCH_REGISTER
17630 && SIBLING_CALL_P (peep2_next_insn (2))
17631 && !reg_mentioned_p (operands[0],
17632 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17633 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17634 (parallel [(call (mem:QI (match_dup 1))
17635 (match_dup 3))
17636 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17637
17638 (define_expand "call_pop"
17639 [(parallel [(call (match_operand:QI 0)
17640 (match_operand:SI 1))
17641 (set (reg:SI SP_REG)
17642 (plus:SI (reg:SI SP_REG)
17643 (match_operand:SI 3)))])]
17644 "!TARGET_64BIT"
17645 {
17646 ix86_expand_call (NULL, operands[0], operands[1],
17647 operands[2], operands[3], false);
17648 DONE;
17649 })
17650
17651 (define_insn "*call_pop"
17652 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17653 (match_operand 1))
17654 (set (reg:SI SP_REG)
17655 (plus:SI (reg:SI SP_REG)
17656 (match_operand:SI 2 "immediate_operand" "i")))]
17657 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17658 "* return ix86_output_call_insn (insn, operands[0]);"
17659 [(set_attr "type" "call")])
17660
17661 (define_insn "*sibcall_pop"
17662 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17663 (match_operand 1))
17664 (set (reg:SI SP_REG)
17665 (plus:SI (reg:SI SP_REG)
17666 (match_operand:SI 2 "immediate_operand" "i")))]
17667 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17668 "* return ix86_output_call_insn (insn, operands[0]);"
17669 [(set_attr "type" "call")])
17670
17671 (define_insn "*sibcall_pop_memory"
17672 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17673 (match_operand 1))
17674 (set (reg:SI SP_REG)
17675 (plus:SI (reg:SI SP_REG)
17676 (match_operand:SI 2 "immediate_operand" "i")))
17677 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17678 "!TARGET_64BIT"
17679 "* return ix86_output_call_insn (insn, operands[0]);"
17680 [(set_attr "type" "call")])
17681
17682 (define_peephole2
17683 [(set (match_operand:SI 0 "register_operand")
17684 (match_operand:SI 1 "memory_operand"))
17685 (parallel [(call (mem:QI (match_dup 0))
17686 (match_operand 3))
17687 (set (reg:SI SP_REG)
17688 (plus:SI (reg:SI SP_REG)
17689 (match_operand:SI 4 "immediate_operand")))])]
17690 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17691 && !reg_mentioned_p (operands[0],
17692 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17693 [(parallel [(call (mem:QI (match_dup 1))
17694 (match_dup 3))
17695 (set (reg:SI SP_REG)
17696 (plus:SI (reg:SI SP_REG)
17697 (match_dup 4)))
17698 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17699
17700 (define_peephole2
17701 [(set (match_operand:SI 0 "register_operand")
17702 (match_operand:SI 1 "memory_operand"))
17703 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17704 (parallel [(call (mem:QI (match_dup 0))
17705 (match_operand 3))
17706 (set (reg:SI SP_REG)
17707 (plus:SI (reg:SI SP_REG)
17708 (match_operand:SI 4 "immediate_operand")))])]
17709 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17710 && !reg_mentioned_p (operands[0],
17711 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17712 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17713 (parallel [(call (mem:QI (match_dup 1))
17714 (match_dup 3))
17715 (set (reg:SI SP_REG)
17716 (plus:SI (reg:SI SP_REG)
17717 (match_dup 4)))
17718 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17719
17720 ;; Combining simple memory jump instruction
17721
17722 (define_peephole2
17723 [(set (match_operand:W 0 "register_operand")
17724 (match_operand:W 1 "memory_operand"))
17725 (set (pc) (match_dup 0))]
17726 "!TARGET_X32
17727 && !TARGET_INDIRECT_BRANCH_REGISTER
17728 && peep2_reg_dead_p (2, operands[0])"
17729 [(set (pc) (match_dup 1))])
17730
17731 ;; Call subroutine, returning value in operand 0
17732
17733 (define_expand "call_value"
17734 [(set (match_operand 0)
17735 (call (match_operand:QI 1)
17736 (match_operand 2)))
17737 (use (match_operand 3))]
17738 ""
17739 {
17740 ix86_expand_call (operands[0], operands[1], operands[2],
17741 operands[3], NULL, false);
17742 DONE;
17743 })
17744
17745 (define_expand "sibcall_value"
17746 [(set (match_operand 0)
17747 (call (match_operand:QI 1)
17748 (match_operand 2)))
17749 (use (match_operand 3))]
17750 ""
17751 {
17752 ix86_expand_call (operands[0], operands[1], operands[2],
17753 operands[3], NULL, true);
17754 DONE;
17755 })
17756
17757 (define_insn "*call_value"
17758 [(set (match_operand 0)
17759 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17760 (match_operand 2)))]
17761 "!SIBLING_CALL_P (insn)"
17762 "* return ix86_output_call_insn (insn, operands[1]);"
17763 [(set_attr "type" "callv")])
17764
17765 ;; This covers both call and sibcall since only GOT slot is allowed.
17766 (define_insn "*call_value_got_x32"
17767 [(set (match_operand 0)
17768 (call (mem:QI
17769 (zero_extend:DI
17770 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17771 (match_operand 2)))]
17772 "TARGET_X32"
17773 {
17774 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17775 return ix86_output_call_insn (insn, fnaddr);
17776 }
17777 [(set_attr "type" "callv")])
17778
17779 ;; Since sibcall never returns, we can only use call-clobbered register
17780 ;; as GOT base.
17781 (define_insn "*sibcall_value_GOT_32"
17782 [(set (match_operand 0)
17783 (call (mem:QI
17784 (mem:SI (plus:SI
17785 (match_operand:SI 1 "register_no_elim_operand" "U")
17786 (match_operand:SI 2 "GOT32_symbol_operand"))))
17787 (match_operand 3)))]
17788 "!TARGET_MACHO
17789 && !TARGET_64BIT
17790 && !TARGET_INDIRECT_BRANCH_REGISTER
17791 && SIBLING_CALL_P (insn)"
17792 {
17793 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17794 fnaddr = gen_const_mem (SImode, fnaddr);
17795 return ix86_output_call_insn (insn, fnaddr);
17796 }
17797 [(set_attr "type" "callv")])
17798
17799 (define_insn "*sibcall_value"
17800 [(set (match_operand 0)
17801 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17802 (match_operand 2)))]
17803 "SIBLING_CALL_P (insn)"
17804 "* return ix86_output_call_insn (insn, operands[1]);"
17805 [(set_attr "type" "callv")])
17806
17807 (define_insn "*sibcall_value_memory"
17808 [(set (match_operand 0)
17809 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17810 (match_operand 2)))
17811 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17812 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17813 "* return ix86_output_call_insn (insn, operands[1]);"
17814 [(set_attr "type" "callv")])
17815
17816 (define_peephole2
17817 [(set (match_operand:W 0 "register_operand")
17818 (match_operand:W 1 "memory_operand"))
17819 (set (match_operand 2)
17820 (call (mem:QI (match_dup 0))
17821 (match_operand 3)))]
17822 "!TARGET_X32
17823 && !TARGET_INDIRECT_BRANCH_REGISTER
17824 && SIBLING_CALL_P (peep2_next_insn (1))
17825 && !reg_mentioned_p (operands[0],
17826 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17827 [(parallel [(set (match_dup 2)
17828 (call (mem:QI (match_dup 1))
17829 (match_dup 3)))
17830 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17831
17832 (define_peephole2
17833 [(set (match_operand:W 0 "register_operand")
17834 (match_operand:W 1 "memory_operand"))
17835 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17836 (set (match_operand 2)
17837 (call (mem:QI (match_dup 0))
17838 (match_operand 3)))]
17839 "!TARGET_X32
17840 && !TARGET_INDIRECT_BRANCH_REGISTER
17841 && SIBLING_CALL_P (peep2_next_insn (2))
17842 && !reg_mentioned_p (operands[0],
17843 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17844 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17845 (parallel [(set (match_dup 2)
17846 (call (mem:QI (match_dup 1))
17847 (match_dup 3)))
17848 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17849
17850 (define_expand "call_value_pop"
17851 [(parallel [(set (match_operand 0)
17852 (call (match_operand:QI 1)
17853 (match_operand:SI 2)))
17854 (set (reg:SI SP_REG)
17855 (plus:SI (reg:SI SP_REG)
17856 (match_operand:SI 4)))])]
17857 "!TARGET_64BIT"
17858 {
17859 ix86_expand_call (operands[0], operands[1], operands[2],
17860 operands[3], operands[4], false);
17861 DONE;
17862 })
17863
17864 (define_insn "*call_value_pop"
17865 [(set (match_operand 0)
17866 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17867 (match_operand 2)))
17868 (set (reg:SI SP_REG)
17869 (plus:SI (reg:SI SP_REG)
17870 (match_operand:SI 3 "immediate_operand" "i")))]
17871 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17872 "* return ix86_output_call_insn (insn, operands[1]);"
17873 [(set_attr "type" "callv")])
17874
17875 (define_insn "*sibcall_value_pop"
17876 [(set (match_operand 0)
17877 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17878 (match_operand 2)))
17879 (set (reg:SI SP_REG)
17880 (plus:SI (reg:SI SP_REG)
17881 (match_operand:SI 3 "immediate_operand" "i")))]
17882 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17883 "* return ix86_output_call_insn (insn, operands[1]);"
17884 [(set_attr "type" "callv")])
17885
17886 (define_insn "*sibcall_value_pop_memory"
17887 [(set (match_operand 0)
17888 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17889 (match_operand 2)))
17890 (set (reg:SI SP_REG)
17891 (plus:SI (reg:SI SP_REG)
17892 (match_operand:SI 3 "immediate_operand" "i")))
17893 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17894 "!TARGET_64BIT"
17895 "* return ix86_output_call_insn (insn, operands[1]);"
17896 [(set_attr "type" "callv")])
17897
17898 (define_peephole2
17899 [(set (match_operand:SI 0 "register_operand")
17900 (match_operand:SI 1 "memory_operand"))
17901 (parallel [(set (match_operand 2)
17902 (call (mem:QI (match_dup 0))
17903 (match_operand 3)))
17904 (set (reg:SI SP_REG)
17905 (plus:SI (reg:SI SP_REG)
17906 (match_operand:SI 4 "immediate_operand")))])]
17907 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17908 && !reg_mentioned_p (operands[0],
17909 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17910 [(parallel [(set (match_dup 2)
17911 (call (mem:QI (match_dup 1))
17912 (match_dup 3)))
17913 (set (reg:SI SP_REG)
17914 (plus:SI (reg:SI SP_REG)
17915 (match_dup 4)))
17916 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17917
17918 (define_peephole2
17919 [(set (match_operand:SI 0 "register_operand")
17920 (match_operand:SI 1 "memory_operand"))
17921 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17922 (parallel [(set (match_operand 2)
17923 (call (mem:QI (match_dup 0))
17924 (match_operand 3)))
17925 (set (reg:SI SP_REG)
17926 (plus:SI (reg:SI SP_REG)
17927 (match_operand:SI 4 "immediate_operand")))])]
17928 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17929 && !reg_mentioned_p (operands[0],
17930 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17931 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17932 (parallel [(set (match_dup 2)
17933 (call (mem:QI (match_dup 1))
17934 (match_dup 3)))
17935 (set (reg:SI SP_REG)
17936 (plus:SI (reg:SI SP_REG)
17937 (match_dup 4)))
17938 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17939
17940 ;; Call subroutine returning any type.
17941
17942 (define_expand "untyped_call"
17943 [(parallel [(call (match_operand 0)
17944 (const_int 0))
17945 (match_operand 1)
17946 (match_operand 2)])]
17947 ""
17948 {
17949 int i;
17950
17951 /* In order to give reg-stack an easier job in validating two
17952 coprocessor registers as containing a possible return value,
17953 simply pretend the untyped call returns a complex long double
17954 value.
17955
17956 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17957 and should have the default ABI. */
17958
17959 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17960 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17961 operands[0], const0_rtx,
17962 GEN_INT ((TARGET_64BIT
17963 ? (ix86_abi == SYSV_ABI
17964 ? X86_64_SSE_REGPARM_MAX
17965 : X86_64_MS_SSE_REGPARM_MAX)
17966 : X86_32_SSE_REGPARM_MAX)
17967 - 1),
17968 NULL, false);
17969
17970 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17971 {
17972 rtx set = XVECEXP (operands[2], 0, i);
17973 emit_move_insn (SET_DEST (set), SET_SRC (set));
17974 }
17975
17976 /* The optimizer does not know that the call sets the function value
17977 registers we stored in the result block. We avoid problems by
17978 claiming that all hard registers are used and clobbered at this
17979 point. */
17980 emit_insn (gen_blockage ());
17981
17982 DONE;
17983 })
17984 \f
17985 ;; Prologue and epilogue instructions
17986
17987 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17988 ;; all of memory. This blocks insns from being moved across this point.
17989
17990 (define_insn "blockage"
17991 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17992 ""
17993 ""
17994 [(set_attr "length" "0")])
17995
17996 ;; Do not schedule instructions accessing memory across this point.
17997
17998 (define_expand "memory_blockage"
17999 [(set (match_dup 0)
18000 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
18001 ""
18002 {
18003 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18004 MEM_VOLATILE_P (operands[0]) = 1;
18005 })
18006
18007 (define_insn "*memory_blockage"
18008 [(set (match_operand:BLK 0)
18009 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
18010 ""
18011 ""
18012 [(set_attr "length" "0")])
18013
18014 ;; As USE insns aren't meaningful after reload, this is used instead
18015 ;; to prevent deleting instructions setting registers for PIC code
18016 (define_insn "prologue_use"
18017 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
18018 ""
18019 ""
18020 [(set_attr "length" "0")])
18021
18022 ;; Insn emitted into the body of a function to return from a function.
18023 ;; This is only done if the function's epilogue is known to be simple.
18024 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
18025
18026 (define_expand "return"
18027 [(simple_return)]
18028 "ix86_can_use_return_insn_p ()"
18029 {
18030 if (crtl->args.pops_args)
18031 {
18032 rtx popc = GEN_INT (crtl->args.pops_args);
18033 emit_jump_insn (gen_simple_return_pop_internal (popc));
18034 DONE;
18035 }
18036 })
18037
18038 ;; We need to disable this for TARGET_SEH, as otherwise
18039 ;; shrink-wrapped prologue gets enabled too. This might exceed
18040 ;; the maximum size of prologue in unwind information.
18041 ;; Also disallow shrink-wrapping if using stack slot to pass the
18042 ;; static chain pointer - the first instruction has to be pushl %esi
18043 ;; and it can't be moved around, as we use alternate entry points
18044 ;; in that case.
18045 ;; Also disallow for ms_hook_prologue functions which have frame
18046 ;; pointer set up in function label which is correctly handled in
18047 ;; ix86_expand_{prologue|epligoue}() only.
18048
18049 (define_expand "simple_return"
18050 [(simple_return)]
18051 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
18052 {
18053 if (crtl->args.pops_args)
18054 {
18055 rtx popc = GEN_INT (crtl->args.pops_args);
18056 emit_jump_insn (gen_simple_return_pop_internal (popc));
18057 DONE;
18058 }
18059 })
18060
18061 (define_insn "simple_return_internal"
18062 [(simple_return)]
18063 "reload_completed"
18064 "* return ix86_output_function_return (false);"
18065 [(set_attr "length" "1")
18066 (set_attr "atom_unit" "jeu")
18067 (set_attr "length_immediate" "0")
18068 (set_attr "modrm" "0")])
18069
18070 (define_insn "interrupt_return"
18071 [(simple_return)
18072 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
18073 "reload_completed"
18074 {
18075 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
18076 })
18077
18078 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
18079 ;; instruction Athlon and K8 have.
18080
18081 (define_insn "simple_return_internal_long"
18082 [(simple_return)
18083 (unspec [(const_int 0)] UNSPEC_REP)]
18084 "reload_completed"
18085 "* return ix86_output_function_return (true);"
18086 [(set_attr "length" "2")
18087 (set_attr "atom_unit" "jeu")
18088 (set_attr "length_immediate" "0")
18089 (set_attr "prefix_rep" "1")
18090 (set_attr "modrm" "0")])
18091
18092 (define_insn_and_split "simple_return_pop_internal"
18093 [(simple_return)
18094 (use (match_operand:SI 0 "const_int_operand"))]
18095 "reload_completed"
18096 "ret\t%0"
18097 "&& cfun->machine->function_return_type != indirect_branch_keep"
18098 [(const_int 0)]
18099 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
18100 [(set_attr "length" "3")
18101 (set_attr "atom_unit" "jeu")
18102 (set_attr "length_immediate" "2")
18103 (set_attr "modrm" "0")])
18104
18105 (define_expand "simple_return_indirect_internal"
18106 [(parallel
18107 [(simple_return)
18108 (use (match_operand 0 "register_operand"))])])
18109
18110 (define_insn "*simple_return_indirect_internal<mode>"
18111 [(simple_return)
18112 (use (match_operand:W 0 "register_operand" "r"))]
18113 "reload_completed"
18114 "* return ix86_output_indirect_function_return (operands[0]);"
18115 [(set (attr "type")
18116 (if_then_else (match_test "(cfun->machine->indirect_branch_type
18117 != indirect_branch_keep)")
18118 (const_string "multi")
18119 (const_string "ibr")))
18120 (set_attr "length_immediate" "0")])
18121
18122 (define_insn "nop"
18123 [(const_int 0)]
18124 ""
18125 "nop"
18126 [(set_attr "length" "1")
18127 (set_attr "length_immediate" "0")
18128 (set_attr "modrm" "0")])
18129
18130 ;; Generate nops. Operand 0 is the number of nops, up to 8.
18131 (define_insn "nops"
18132 [(unspec_volatile [(match_operand 0 "const_int_operand")]
18133 UNSPECV_NOPS)]
18134 "reload_completed"
18135 {
18136 int num = INTVAL (operands[0]);
18137
18138 gcc_assert (IN_RANGE (num, 1, 8));
18139
18140 while (num--)
18141 fputs ("\tnop\n", asm_out_file);
18142
18143 return "";
18144 }
18145 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
18146 (set_attr "length_immediate" "0")
18147 (set_attr "modrm" "0")])
18148
18149 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
18150 ;; branch prediction penalty for the third jump in a 16-byte
18151 ;; block on K8.
18152
18153 (define_insn "pad"
18154 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
18155 ""
18156 {
18157 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
18158 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
18159 #else
18160 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
18161 The align insn is used to avoid 3 jump instructions in the row to improve
18162 branch prediction and the benefits hardly outweigh the cost of extra 8
18163 nops on the average inserted by full alignment pseudo operation. */
18164 #endif
18165 return "";
18166 }
18167 [(set_attr "length" "16")])
18168
18169 (define_expand "prologue"
18170 [(const_int 0)]
18171 ""
18172 "ix86_expand_prologue (); DONE;")
18173
18174 (define_expand "set_got"
18175 [(parallel
18176 [(set (match_operand:SI 0 "register_operand")
18177 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
18178 (clobber (reg:CC FLAGS_REG))])]
18179 "!TARGET_64BIT"
18180 {
18181 if (flag_pic && !TARGET_VXWORKS_RTP)
18182 ix86_pc_thunk_call_expanded = true;
18183 })
18184
18185 (define_insn "*set_got"
18186 [(set (match_operand:SI 0 "register_operand" "=r")
18187 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
18188 (clobber (reg:CC FLAGS_REG))]
18189 "!TARGET_64BIT"
18190 "* return output_set_got (operands[0], NULL_RTX);"
18191 [(set_attr "type" "multi")
18192 (set_attr "length" "12")])
18193
18194 (define_expand "set_got_labelled"
18195 [(parallel
18196 [(set (match_operand:SI 0 "register_operand")
18197 (unspec:SI [(label_ref (match_operand 1))]
18198 UNSPEC_SET_GOT))
18199 (clobber (reg:CC FLAGS_REG))])]
18200 "!TARGET_64BIT"
18201 {
18202 if (flag_pic && !TARGET_VXWORKS_RTP)
18203 ix86_pc_thunk_call_expanded = true;
18204 })
18205
18206 (define_insn "*set_got_labelled"
18207 [(set (match_operand:SI 0 "register_operand" "=r")
18208 (unspec:SI [(label_ref (match_operand 1))]
18209 UNSPEC_SET_GOT))
18210 (clobber (reg:CC FLAGS_REG))]
18211 "!TARGET_64BIT"
18212 "* return output_set_got (operands[0], operands[1]);"
18213 [(set_attr "type" "multi")
18214 (set_attr "length" "12")])
18215
18216 (define_insn "set_got_rex64"
18217 [(set (match_operand:DI 0 "register_operand" "=r")
18218 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
18219 "TARGET_64BIT"
18220 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
18221 [(set_attr "type" "lea")
18222 (set_attr "length_address" "4")
18223 (set_attr "mode" "DI")])
18224
18225 (define_insn "set_rip_rex64"
18226 [(set (match_operand:DI 0 "register_operand" "=r")
18227 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
18228 "TARGET_64BIT"
18229 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
18230 [(set_attr "type" "lea")
18231 (set_attr "length_address" "4")
18232 (set_attr "mode" "DI")])
18233
18234 (define_insn "set_got_offset_rex64"
18235 [(set (match_operand:DI 0 "register_operand" "=r")
18236 (unspec:DI
18237 [(label_ref (match_operand 1))]
18238 UNSPEC_SET_GOT_OFFSET))]
18239 "TARGET_LP64"
18240 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
18241 [(set_attr "type" "imov")
18242 (set_attr "length_immediate" "0")
18243 (set_attr "length_address" "8")
18244 (set_attr "mode" "DI")])
18245
18246 (define_expand "epilogue"
18247 [(const_int 0)]
18248 ""
18249 "ix86_expand_epilogue (1); DONE;")
18250
18251 (define_expand "sibcall_epilogue"
18252 [(const_int 0)]
18253 ""
18254 "ix86_expand_epilogue (0); DONE;")
18255
18256 (define_expand "eh_return"
18257 [(use (match_operand 0 "register_operand"))]
18258 ""
18259 {
18260 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
18261
18262 /* Tricky bit: we write the address of the handler to which we will
18263 be returning into someone else's stack frame, one word below the
18264 stack address we wish to restore. */
18265 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
18266 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
18267 /* Return address is always in word_mode. */
18268 tmp = gen_rtx_MEM (word_mode, tmp);
18269 if (GET_MODE (ra) != word_mode)
18270 ra = convert_to_mode (word_mode, ra, 1);
18271 emit_move_insn (tmp, ra);
18272
18273 emit_jump_insn (gen_eh_return_internal ());
18274 emit_barrier ();
18275 DONE;
18276 })
18277
18278 (define_insn_and_split "eh_return_internal"
18279 [(eh_return)]
18280 ""
18281 "#"
18282 "epilogue_completed"
18283 [(const_int 0)]
18284 "ix86_expand_epilogue (2); DONE;")
18285
18286 (define_expand "@leave_<mode>"
18287 [(parallel
18288 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
18289 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
18290 (clobber (mem:BLK (scratch)))])]
18291 ""
18292 "operands[0] = GEN_INT (<MODE_SIZE>);")
18293
18294 (define_insn "*leave"
18295 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
18296 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
18297 (clobber (mem:BLK (scratch)))]
18298 "!TARGET_64BIT"
18299 "leave"
18300 [(set_attr "type" "leave")])
18301
18302 (define_insn "*leave_rex64"
18303 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
18304 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
18305 (clobber (mem:BLK (scratch)))]
18306 "TARGET_64BIT"
18307 "leave"
18308 [(set_attr "type" "leave")])
18309 \f
18310 ;; Handle -fsplit-stack.
18311
18312 (define_expand "split_stack_prologue"
18313 [(const_int 0)]
18314 ""
18315 {
18316 ix86_expand_split_stack_prologue ();
18317 DONE;
18318 })
18319
18320 ;; In order to support the call/return predictor, we use a return
18321 ;; instruction which the middle-end doesn't see.
18322 (define_insn "split_stack_return"
18323 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
18324 UNSPECV_SPLIT_STACK_RETURN)]
18325 ""
18326 {
18327 if (operands[0] == const0_rtx)
18328 return "ret";
18329 else
18330 return "ret\t%0";
18331 }
18332 [(set_attr "atom_unit" "jeu")
18333 (set_attr "modrm" "0")
18334 (set (attr "length")
18335 (if_then_else (match_operand:SI 0 "const0_operand")
18336 (const_int 1)
18337 (const_int 3)))
18338 (set (attr "length_immediate")
18339 (if_then_else (match_operand:SI 0 "const0_operand")
18340 (const_int 0)
18341 (const_int 2)))])
18342
18343 ;; If there are operand 0 bytes available on the stack, jump to
18344 ;; operand 1.
18345
18346 (define_expand "split_stack_space_check"
18347 [(set (pc) (if_then_else
18348 (ltu (minus (reg SP_REG)
18349 (match_operand 0 "register_operand"))
18350 (match_dup 2))
18351 (label_ref (match_operand 1))
18352 (pc)))]
18353 ""
18354 {
18355 rtx reg = gen_reg_rtx (Pmode);
18356
18357 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
18358
18359 operands[2] = ix86_split_stack_guard ();
18360 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
18361
18362 DONE;
18363 })
18364 \f
18365 ;; Bit manipulation instructions.
18366
18367 (define_expand "ffs<mode>2"
18368 [(set (match_dup 2) (const_int -1))
18369 (parallel [(set (match_dup 3) (match_dup 4))
18370 (set (match_operand:SWI48 0 "register_operand")
18371 (ctz:SWI48
18372 (match_operand:SWI48 1 "nonimmediate_operand")))])
18373 (set (match_dup 0) (if_then_else:SWI48
18374 (eq (match_dup 3) (const_int 0))
18375 (match_dup 2)
18376 (match_dup 0)))
18377 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
18378 (clobber (reg:CC FLAGS_REG))])]
18379 ""
18380 {
18381 machine_mode flags_mode;
18382
18383 if (<MODE>mode == SImode && !TARGET_CMOVE)
18384 {
18385 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
18386 DONE;
18387 }
18388
18389 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18390
18391 operands[2] = gen_reg_rtx (<MODE>mode);
18392 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
18393 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18394 })
18395
18396 (define_insn_and_split "ffssi2_no_cmove"
18397 [(set (match_operand:SI 0 "register_operand" "=r")
18398 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
18399 (clobber (match_scratch:SI 2 "=&q"))
18400 (clobber (reg:CC FLAGS_REG))]
18401 "!TARGET_CMOVE"
18402 "#"
18403 "&& reload_completed"
18404 [(parallel [(set (match_dup 4) (match_dup 5))
18405 (set (match_dup 0) (ctz:SI (match_dup 1)))])
18406 (set (strict_low_part (match_dup 3))
18407 (eq:QI (match_dup 4) (const_int 0)))
18408 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
18409 (clobber (reg:CC FLAGS_REG))])
18410 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
18411 (clobber (reg:CC FLAGS_REG))])
18412 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
18413 (clobber (reg:CC FLAGS_REG))])]
18414 {
18415 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
18416
18417 operands[3] = gen_lowpart (QImode, operands[2]);
18418 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
18419 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
18420
18421 ix86_expand_clear (operands[2]);
18422 })
18423
18424 (define_insn_and_split "*tzcnt<mode>_1"
18425 [(set (reg:CCC FLAGS_REG)
18426 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18427 (const_int 0)))
18428 (set (match_operand:SWI48 0 "register_operand" "=r")
18429 (ctz:SWI48 (match_dup 1)))]
18430 "TARGET_BMI"
18431 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18432 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18433 && optimize_function_for_speed_p (cfun)
18434 && !reg_mentioned_p (operands[0], operands[1])"
18435 [(parallel
18436 [(set (reg:CCC FLAGS_REG)
18437 (compare:CCC (match_dup 1) (const_int 0)))
18438 (set (match_dup 0)
18439 (ctz:SWI48 (match_dup 1)))
18440 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
18441 "ix86_expand_clear (operands[0]);"
18442 [(set_attr "type" "alu1")
18443 (set_attr "prefix_0f" "1")
18444 (set_attr "prefix_rep" "1")
18445 (set_attr "btver2_decode" "double")
18446 (set_attr "mode" "<MODE>")])
18447
18448 ; False dependency happens when destination is only updated by tzcnt,
18449 ; lzcnt or popcnt. There is no false dependency when destination is
18450 ; also used in source.
18451 (define_insn "*tzcnt<mode>_1_falsedep"
18452 [(set (reg:CCC FLAGS_REG)
18453 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18454 (const_int 0)))
18455 (set (match_operand:SWI48 0 "register_operand" "=r")
18456 (ctz:SWI48 (match_dup 1)))
18457 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18458 UNSPEC_INSN_FALSE_DEP)]
18459 "TARGET_BMI"
18460 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18461 [(set_attr "type" "alu1")
18462 (set_attr "prefix_0f" "1")
18463 (set_attr "prefix_rep" "1")
18464 (set_attr "btver2_decode" "double")
18465 (set_attr "mode" "<MODE>")])
18466
18467 (define_insn "*bsf<mode>_1"
18468 [(set (reg:CCZ FLAGS_REG)
18469 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18470 (const_int 0)))
18471 (set (match_operand:SWI48 0 "register_operand" "=r")
18472 (ctz:SWI48 (match_dup 1)))]
18473 ""
18474 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
18475 [(set_attr "type" "alu1")
18476 (set_attr "prefix_0f" "1")
18477 (set_attr "btver2_decode" "double")
18478 (set_attr "znver1_decode" "vector")
18479 (set_attr "mode" "<MODE>")])
18480
18481 (define_insn_and_split "ctz<mode>2"
18482 [(set (match_operand:SWI48 0 "register_operand" "=r")
18483 (ctz:SWI48
18484 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18485 (clobber (reg:CC FLAGS_REG))]
18486 ""
18487 {
18488 if (TARGET_BMI)
18489 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18490 else if (optimize_function_for_size_p (cfun))
18491 ;
18492 else if (TARGET_CPU_P (GENERIC))
18493 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18494 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18495
18496 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18497 }
18498 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18499 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18500 && optimize_function_for_speed_p (cfun)
18501 && !reg_mentioned_p (operands[0], operands[1])"
18502 [(parallel
18503 [(set (match_dup 0)
18504 (ctz:SWI48 (match_dup 1)))
18505 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18506 (clobber (reg:CC FLAGS_REG))])]
18507 "ix86_expand_clear (operands[0]);"
18508 [(set_attr "type" "alu1")
18509 (set_attr "prefix_0f" "1")
18510 (set (attr "prefix_rep")
18511 (if_then_else
18512 (ior (match_test "TARGET_BMI")
18513 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18514 (match_test "TARGET_CPU_P (GENERIC)")))
18515 (const_string "1")
18516 (const_string "0")))
18517 (set_attr "mode" "<MODE>")])
18518
18519 ; False dependency happens when destination is only updated by tzcnt,
18520 ; lzcnt or popcnt. There is no false dependency when destination is
18521 ; also used in source.
18522 (define_insn "*ctz<mode>2_falsedep"
18523 [(set (match_operand:SWI48 0 "register_operand" "=r")
18524 (ctz:SWI48
18525 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18526 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18527 UNSPEC_INSN_FALSE_DEP)
18528 (clobber (reg:CC FLAGS_REG))]
18529 ""
18530 {
18531 if (TARGET_BMI)
18532 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18533 else if (TARGET_CPU_P (GENERIC))
18534 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18535 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18536 else
18537 gcc_unreachable ();
18538 }
18539 [(set_attr "type" "alu1")
18540 (set_attr "prefix_0f" "1")
18541 (set_attr "prefix_rep" "1")
18542 (set_attr "mode" "<MODE>")])
18543
18544 (define_insn_and_split "*ctzsi2_zext"
18545 [(set (match_operand:DI 0 "register_operand" "=r")
18546 (and:DI
18547 (subreg:DI
18548 (ctz:SI
18549 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18550 (const_int 63)))
18551 (clobber (reg:CC FLAGS_REG))]
18552 "TARGET_BMI && TARGET_64BIT"
18553 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18554 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18555 && optimize_function_for_speed_p (cfun)
18556 && !reg_mentioned_p (operands[0], operands[1])"
18557 [(parallel
18558 [(set (match_dup 0)
18559 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18560 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18561 (clobber (reg:CC FLAGS_REG))])]
18562 "ix86_expand_clear (operands[0]);"
18563 [(set_attr "type" "alu1")
18564 (set_attr "prefix_0f" "1")
18565 (set_attr "prefix_rep" "1")
18566 (set_attr "mode" "SI")])
18567
18568 ; False dependency happens when destination is only updated by tzcnt,
18569 ; lzcnt or popcnt. There is no false dependency when destination is
18570 ; also used in source.
18571 (define_insn "*ctzsi2_zext_falsedep"
18572 [(set (match_operand:DI 0 "register_operand" "=r")
18573 (and:DI
18574 (subreg:DI
18575 (ctz:SI
18576 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18577 (const_int 63)))
18578 (unspec [(match_operand:DI 2 "register_operand" "0")]
18579 UNSPEC_INSN_FALSE_DEP)
18580 (clobber (reg:CC FLAGS_REG))]
18581 "TARGET_BMI && TARGET_64BIT"
18582 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18583 [(set_attr "type" "alu1")
18584 (set_attr "prefix_0f" "1")
18585 (set_attr "prefix_rep" "1")
18586 (set_attr "mode" "SI")])
18587
18588 (define_insn_and_split "*ctzsidi2_<s>ext"
18589 [(set (match_operand:DI 0 "register_operand" "=r")
18590 (any_extend:DI
18591 (ctz:SI
18592 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18593 (clobber (reg:CC FLAGS_REG))]
18594 "TARGET_64BIT"
18595 {
18596 if (TARGET_BMI)
18597 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18598 else if (TARGET_CPU_P (GENERIC)
18599 && !optimize_function_for_size_p (cfun))
18600 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18601 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18602 return "bsf{l}\t{%1, %k0|%k0, %1}";
18603 }
18604 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18605 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18606 && optimize_function_for_speed_p (cfun)
18607 && !reg_mentioned_p (operands[0], operands[1])"
18608 [(parallel
18609 [(set (match_dup 0)
18610 (any_extend:DI (ctz:SI (match_dup 1))))
18611 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18612 (clobber (reg:CC FLAGS_REG))])]
18613 "ix86_expand_clear (operands[0]);"
18614 [(set_attr "type" "alu1")
18615 (set_attr "prefix_0f" "1")
18616 (set (attr "prefix_rep")
18617 (if_then_else
18618 (ior (match_test "TARGET_BMI")
18619 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18620 (match_test "TARGET_CPU_P (GENERIC)")))
18621 (const_string "1")
18622 (const_string "0")))
18623 (set_attr "mode" "SI")])
18624
18625 (define_insn "*ctzsidi2_<s>ext_falsedep"
18626 [(set (match_operand:DI 0 "register_operand" "=r")
18627 (any_extend:DI
18628 (ctz:SI
18629 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18630 (unspec [(match_operand:DI 2 "register_operand" "0")]
18631 UNSPEC_INSN_FALSE_DEP)
18632 (clobber (reg:CC FLAGS_REG))]
18633 "TARGET_64BIT"
18634 {
18635 if (TARGET_BMI)
18636 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18637 else if (TARGET_CPU_P (GENERIC))
18638 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18639 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18640 else
18641 gcc_unreachable ();
18642 }
18643 [(set_attr "type" "alu1")
18644 (set_attr "prefix_0f" "1")
18645 (set_attr "prefix_rep" "1")
18646 (set_attr "mode" "SI")])
18647
18648 (define_insn "bsr_rex64"
18649 [(set (reg:CCZ FLAGS_REG)
18650 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18651 (const_int 0)))
18652 (set (match_operand:DI 0 "register_operand" "=r")
18653 (minus:DI (const_int 63)
18654 (clz:DI (match_dup 1))))]
18655 "TARGET_64BIT"
18656 "bsr{q}\t{%1, %0|%0, %1}"
18657 [(set_attr "type" "alu1")
18658 (set_attr "prefix_0f" "1")
18659 (set_attr "znver1_decode" "vector")
18660 (set_attr "mode" "DI")])
18661
18662 (define_insn "bsr_rex64_1"
18663 [(set (match_operand:DI 0 "register_operand" "=r")
18664 (minus:DI (const_int 63)
18665 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18666 (clobber (reg:CC FLAGS_REG))]
18667 "!TARGET_LZCNT && TARGET_64BIT"
18668 "bsr{q}\t{%1, %0|%0, %1}"
18669 [(set_attr "type" "alu1")
18670 (set_attr "prefix_0f" "1")
18671 (set_attr "znver1_decode" "vector")
18672 (set_attr "mode" "DI")])
18673
18674 (define_insn "bsr_rex64_1_zext"
18675 [(set (match_operand:DI 0 "register_operand" "=r")
18676 (zero_extend:DI
18677 (minus:SI (const_int 63)
18678 (subreg:SI
18679 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18680 0))))
18681 (clobber (reg:CC FLAGS_REG))]
18682 "!TARGET_LZCNT && TARGET_64BIT"
18683 "bsr{q}\t{%1, %0|%0, %1}"
18684 [(set_attr "type" "alu1")
18685 (set_attr "prefix_0f" "1")
18686 (set_attr "znver1_decode" "vector")
18687 (set_attr "mode" "DI")])
18688
18689 (define_insn "bsr"
18690 [(set (reg:CCZ FLAGS_REG)
18691 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18692 (const_int 0)))
18693 (set (match_operand:SI 0 "register_operand" "=r")
18694 (minus:SI (const_int 31)
18695 (clz:SI (match_dup 1))))]
18696 ""
18697 "bsr{l}\t{%1, %0|%0, %1}"
18698 [(set_attr "type" "alu1")
18699 (set_attr "prefix_0f" "1")
18700 (set_attr "znver1_decode" "vector")
18701 (set_attr "mode" "SI")])
18702
18703 (define_insn "bsr_1"
18704 [(set (match_operand:SI 0 "register_operand" "=r")
18705 (minus:SI (const_int 31)
18706 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18707 (clobber (reg:CC FLAGS_REG))]
18708 "!TARGET_LZCNT"
18709 "bsr{l}\t{%1, %0|%0, %1}"
18710 [(set_attr "type" "alu1")
18711 (set_attr "prefix_0f" "1")
18712 (set_attr "znver1_decode" "vector")
18713 (set_attr "mode" "SI")])
18714
18715 (define_insn "bsr_zext_1"
18716 [(set (match_operand:DI 0 "register_operand" "=r")
18717 (zero_extend:DI
18718 (minus:SI
18719 (const_int 31)
18720 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18721 (clobber (reg:CC FLAGS_REG))]
18722 "!TARGET_LZCNT && TARGET_64BIT"
18723 "bsr{l}\t{%1, %k0|%k0, %1}"
18724 [(set_attr "type" "alu1")
18725 (set_attr "prefix_0f" "1")
18726 (set_attr "znver1_decode" "vector")
18727 (set_attr "mode" "SI")])
18728
18729 ; As bsr is undefined behavior on zero and for other input
18730 ; values it is in range 0 to 63, we can optimize away sign-extends.
18731 (define_insn_and_split "*bsr_rex64_2"
18732 [(set (match_operand:DI 0 "register_operand")
18733 (xor:DI
18734 (sign_extend:DI
18735 (minus:SI
18736 (const_int 63)
18737 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18738 0)))
18739 (const_int 63)))
18740 (clobber (reg:CC FLAGS_REG))]
18741 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18742 "#"
18743 "&& 1"
18744 [(parallel [(set (reg:CCZ FLAGS_REG)
18745 (compare:CCZ (match_dup 1) (const_int 0)))
18746 (set (match_dup 2)
18747 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18748 (parallel [(set (match_dup 0)
18749 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18750 (clobber (reg:CC FLAGS_REG))])]
18751 {
18752 operands[2] = gen_reg_rtx (DImode);
18753 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18754 })
18755
18756 (define_insn_and_split "*bsr_2"
18757 [(set (match_operand:DI 0 "register_operand")
18758 (sign_extend:DI
18759 (xor:SI
18760 (minus:SI
18761 (const_int 31)
18762 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18763 (const_int 31))))
18764 (clobber (reg:CC FLAGS_REG))]
18765 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18766 "#"
18767 "&& 1"
18768 [(parallel [(set (reg:CCZ FLAGS_REG)
18769 (compare:CCZ (match_dup 1) (const_int 0)))
18770 (set (match_dup 2)
18771 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18772 (parallel [(set (match_dup 0)
18773 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18774 (clobber (reg:CC FLAGS_REG))])]
18775 "operands[2] = gen_reg_rtx (SImode);")
18776
18777 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18778 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18779 ; in [0, 63] or [0, 31] range.
18780 (define_split
18781 [(set (match_operand:SI 0 "register_operand")
18782 (minus:SI
18783 (match_operand:SI 2 "const_int_operand")
18784 (xor:SI
18785 (minus:SI (const_int 63)
18786 (subreg:SI
18787 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18788 0))
18789 (const_int 63))))]
18790 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18791 [(set (match_dup 3)
18792 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18793 (set (match_dup 0)
18794 (plus:SI (match_dup 5) (match_dup 4)))]
18795 {
18796 operands[3] = gen_reg_rtx (DImode);
18797 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18798 if (INTVAL (operands[2]) == 63)
18799 {
18800 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18801 emit_move_insn (operands[0], operands[5]);
18802 DONE;
18803 }
18804 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18805 })
18806
18807 (define_split
18808 [(set (match_operand:SI 0 "register_operand")
18809 (minus:SI
18810 (match_operand:SI 2 "const_int_operand")
18811 (xor:SI
18812 (minus:SI (const_int 31)
18813 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18814 (const_int 31))))]
18815 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18816 [(set (match_dup 3)
18817 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18818 (set (match_dup 0)
18819 (plus:SI (match_dup 3) (match_dup 4)))]
18820 {
18821 if (INTVAL (operands[2]) == 31)
18822 {
18823 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18824 DONE;
18825 }
18826 operands[3] = gen_reg_rtx (SImode);
18827 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18828 })
18829
18830 (define_split
18831 [(set (match_operand:DI 0 "register_operand")
18832 (minus:DI
18833 (match_operand:DI 2 "const_int_operand")
18834 (xor:DI
18835 (sign_extend:DI
18836 (minus:SI (const_int 63)
18837 (subreg:SI
18838 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18839 0)))
18840 (const_int 63))))]
18841 "!TARGET_LZCNT
18842 && TARGET_64BIT
18843 && ix86_pre_reload_split ()
18844 && ((unsigned HOST_WIDE_INT)
18845 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18846 == UINTVAL (operands[2]) - 63)"
18847 [(set (match_dup 3)
18848 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18849 (set (match_dup 0)
18850 (plus:DI (match_dup 3) (match_dup 4)))]
18851 {
18852 if (INTVAL (operands[2]) == 63)
18853 {
18854 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18855 DONE;
18856 }
18857 operands[3] = gen_reg_rtx (DImode);
18858 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18859 })
18860
18861 (define_split
18862 [(set (match_operand:DI 0 "register_operand")
18863 (minus:DI
18864 (match_operand:DI 2 "const_int_operand")
18865 (sign_extend:DI
18866 (xor:SI
18867 (minus:SI (const_int 31)
18868 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18869 (const_int 31)))))]
18870 "!TARGET_LZCNT
18871 && TARGET_64BIT
18872 && ix86_pre_reload_split ()
18873 && ((unsigned HOST_WIDE_INT)
18874 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18875 == UINTVAL (operands[2]) - 31)"
18876 [(set (match_dup 3)
18877 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18878 (set (match_dup 0)
18879 (plus:DI (match_dup 3) (match_dup 4)))]
18880 {
18881 if (INTVAL (operands[2]) == 31)
18882 {
18883 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18884 DONE;
18885 }
18886 operands[3] = gen_reg_rtx (DImode);
18887 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18888 })
18889
18890 (define_expand "clz<mode>2"
18891 [(parallel
18892 [(set (reg:CCZ FLAGS_REG)
18893 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18894 (const_int 0)))
18895 (set (match_dup 3) (minus:SWI48
18896 (match_dup 2)
18897 (clz:SWI48 (match_dup 1))))])
18898 (parallel
18899 [(set (match_operand:SWI48 0 "register_operand")
18900 (xor:SWI48 (match_dup 3) (match_dup 2)))
18901 (clobber (reg:CC FLAGS_REG))])]
18902 ""
18903 {
18904 if (TARGET_LZCNT)
18905 {
18906 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18907 DONE;
18908 }
18909 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18910 operands[3] = gen_reg_rtx (<MODE>mode);
18911 })
18912
18913 (define_insn_and_split "clz<mode>2_lzcnt"
18914 [(set (match_operand:SWI48 0 "register_operand" "=r")
18915 (clz:SWI48
18916 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18917 (clobber (reg:CC FLAGS_REG))]
18918 "TARGET_LZCNT"
18919 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18920 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18921 && optimize_function_for_speed_p (cfun)
18922 && !reg_mentioned_p (operands[0], operands[1])"
18923 [(parallel
18924 [(set (match_dup 0)
18925 (clz:SWI48 (match_dup 1)))
18926 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18927 (clobber (reg:CC FLAGS_REG))])]
18928 "ix86_expand_clear (operands[0]);"
18929 [(set_attr "prefix_rep" "1")
18930 (set_attr "type" "bitmanip")
18931 (set_attr "mode" "<MODE>")])
18932
18933 ; False dependency happens when destination is only updated by tzcnt,
18934 ; lzcnt or popcnt. There is no false dependency when destination is
18935 ; also used in source.
18936 (define_insn "*clz<mode>2_lzcnt_falsedep"
18937 [(set (match_operand:SWI48 0 "register_operand" "=r")
18938 (clz:SWI48
18939 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18940 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18941 UNSPEC_INSN_FALSE_DEP)
18942 (clobber (reg:CC FLAGS_REG))]
18943 "TARGET_LZCNT"
18944 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18945 [(set_attr "prefix_rep" "1")
18946 (set_attr "type" "bitmanip")
18947 (set_attr "mode" "<MODE>")])
18948
18949 (define_insn_and_split "*clzsi2_lzcnt_zext"
18950 [(set (match_operand:DI 0 "register_operand" "=r")
18951 (and:DI
18952 (subreg:DI
18953 (clz:SI
18954 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18955 (const_int 63)))
18956 (clobber (reg:CC FLAGS_REG))]
18957 "TARGET_LZCNT && TARGET_64BIT"
18958 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18959 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18960 && optimize_function_for_speed_p (cfun)
18961 && !reg_mentioned_p (operands[0], operands[1])"
18962 [(parallel
18963 [(set (match_dup 0)
18964 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18965 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18966 (clobber (reg:CC FLAGS_REG))])]
18967 "ix86_expand_clear (operands[0]);"
18968 [(set_attr "prefix_rep" "1")
18969 (set_attr "type" "bitmanip")
18970 (set_attr "mode" "SI")])
18971
18972 ; False dependency happens when destination is only updated by tzcnt,
18973 ; lzcnt or popcnt. There is no false dependency when destination is
18974 ; also used in source.
18975 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18976 [(set (match_operand:DI 0 "register_operand" "=r")
18977 (and:DI
18978 (subreg:DI
18979 (clz:SI
18980 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18981 (const_int 63)))
18982 (unspec [(match_operand:DI 2 "register_operand" "0")]
18983 UNSPEC_INSN_FALSE_DEP)
18984 (clobber (reg:CC FLAGS_REG))]
18985 "TARGET_LZCNT"
18986 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18987 [(set_attr "prefix_rep" "1")
18988 (set_attr "type" "bitmanip")
18989 (set_attr "mode" "SI")])
18990
18991 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18992 [(set (match_operand:DI 0 "register_operand" "=r")
18993 (zero_extend:DI
18994 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18995 (clobber (reg:CC FLAGS_REG))]
18996 "TARGET_LZCNT && TARGET_64BIT"
18997 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18998 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18999 && optimize_function_for_speed_p (cfun)
19000 && !reg_mentioned_p (operands[0], operands[1])"
19001 [(parallel
19002 [(set (match_dup 0)
19003 (zero_extend:DI (clz:SI (match_dup 1))))
19004 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19005 (clobber (reg:CC FLAGS_REG))])]
19006 "ix86_expand_clear (operands[0]);"
19007 [(set_attr "prefix_rep" "1")
19008 (set_attr "type" "bitmanip")
19009 (set_attr "mode" "SI")])
19010
19011 ; False dependency happens when destination is only updated by tzcnt,
19012 ; lzcnt or popcnt. There is no false dependency when destination is
19013 ; also used in source.
19014 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
19015 [(set (match_operand:DI 0 "register_operand" "=r")
19016 (zero_extend:DI
19017 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
19018 (unspec [(match_operand:DI 2 "register_operand" "0")]
19019 UNSPEC_INSN_FALSE_DEP)
19020 (clobber (reg:CC FLAGS_REG))]
19021 "TARGET_LZCNT"
19022 "lzcnt{l}\t{%1, %k0|%k0, %1}"
19023 [(set_attr "prefix_rep" "1")
19024 (set_attr "type" "bitmanip")
19025 (set_attr "mode" "SI")])
19026
19027 (define_int_iterator LT_ZCNT
19028 [(UNSPEC_TZCNT "TARGET_BMI")
19029 (UNSPEC_LZCNT "TARGET_LZCNT")])
19030
19031 (define_int_attr lt_zcnt
19032 [(UNSPEC_TZCNT "tzcnt")
19033 (UNSPEC_LZCNT "lzcnt")])
19034
19035 (define_int_attr lt_zcnt_type
19036 [(UNSPEC_TZCNT "alu1")
19037 (UNSPEC_LZCNT "bitmanip")])
19038
19039 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
19040 ;; provides operand size as output when source operand is zero.
19041
19042 (define_insn_and_split "<lt_zcnt>_<mode>"
19043 [(set (match_operand:SWI48 0 "register_operand" "=r")
19044 (unspec:SWI48
19045 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
19046 (clobber (reg:CC FLAGS_REG))]
19047 ""
19048 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
19049 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19050 && optimize_function_for_speed_p (cfun)
19051 && !reg_mentioned_p (operands[0], operands[1])"
19052 [(parallel
19053 [(set (match_dup 0)
19054 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
19055 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19056 (clobber (reg:CC FLAGS_REG))])]
19057 "ix86_expand_clear (operands[0]);"
19058 [(set_attr "type" "<lt_zcnt_type>")
19059 (set_attr "prefix_0f" "1")
19060 (set_attr "prefix_rep" "1")
19061 (set_attr "mode" "<MODE>")])
19062
19063 ; False dependency happens when destination is only updated by tzcnt,
19064 ; lzcnt or popcnt. There is no false dependency when destination is
19065 ; also used in source.
19066 (define_insn "*<lt_zcnt>_<mode>_falsedep"
19067 [(set (match_operand:SWI48 0 "register_operand" "=r")
19068 (unspec:SWI48
19069 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
19070 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19071 UNSPEC_INSN_FALSE_DEP)
19072 (clobber (reg:CC FLAGS_REG))]
19073 ""
19074 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
19075 [(set_attr "type" "<lt_zcnt_type>")
19076 (set_attr "prefix_0f" "1")
19077 (set_attr "prefix_rep" "1")
19078 (set_attr "mode" "<MODE>")])
19079
19080 (define_insn "<lt_zcnt>_hi"
19081 [(set (match_operand:HI 0 "register_operand" "=r")
19082 (unspec:HI
19083 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
19084 (clobber (reg:CC FLAGS_REG))]
19085 ""
19086 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
19087 [(set_attr "type" "<lt_zcnt_type>")
19088 (set_attr "prefix_0f" "1")
19089 (set_attr "prefix_rep" "1")
19090 (set_attr "mode" "HI")])
19091
19092 ;; BMI instructions.
19093
19094 (define_insn "bmi_bextr_<mode>"
19095 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
19096 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
19097 (match_operand:SWI48 2 "register_operand" "r,r")]
19098 UNSPEC_BEXTR))
19099 (clobber (reg:CC FLAGS_REG))]
19100 "TARGET_BMI"
19101 "bextr\t{%2, %1, %0|%0, %1, %2}"
19102 [(set_attr "type" "bitmanip")
19103 (set_attr "btver2_decode" "direct, double")
19104 (set_attr "mode" "<MODE>")])
19105
19106 (define_insn "*bmi_bextr_<mode>_ccz"
19107 [(set (reg:CCZ FLAGS_REG)
19108 (compare:CCZ
19109 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
19110 (match_operand:SWI48 2 "register_operand" "r,r")]
19111 UNSPEC_BEXTR)
19112 (const_int 0)))
19113 (clobber (match_scratch:SWI48 0 "=r,r"))]
19114 "TARGET_BMI"
19115 "bextr\t{%2, %1, %0|%0, %1, %2}"
19116 [(set_attr "type" "bitmanip")
19117 (set_attr "btver2_decode" "direct, double")
19118 (set_attr "mode" "<MODE>")])
19119
19120 (define_insn "*bmi_blsi_<mode>"
19121 [(set (match_operand:SWI48 0 "register_operand" "=r")
19122 (and:SWI48
19123 (neg:SWI48
19124 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19125 (match_dup 1)))
19126 (clobber (reg:CC FLAGS_REG))]
19127 "TARGET_BMI"
19128 "blsi\t{%1, %0|%0, %1}"
19129 [(set_attr "type" "bitmanip")
19130 (set_attr "btver2_decode" "double")
19131 (set_attr "mode" "<MODE>")])
19132
19133 (define_insn "*bmi_blsi_<mode>_cmp"
19134 [(set (reg FLAGS_REG)
19135 (compare
19136 (and:SWI48
19137 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19138 (match_dup 1))
19139 (const_int 0)))
19140 (set (match_operand:SWI48 0 "register_operand" "=r")
19141 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
19142 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
19143 "blsi\t{%1, %0|%0, %1}"
19144 [(set_attr "type" "bitmanip")
19145 (set_attr "btver2_decode" "double")
19146 (set_attr "mode" "<MODE>")])
19147
19148 (define_insn "*bmi_blsi_<mode>_ccno"
19149 [(set (reg FLAGS_REG)
19150 (compare
19151 (and:SWI48
19152 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
19153 (match_dup 1))
19154 (const_int 0)))
19155 (clobber (match_scratch:SWI48 0 "=r"))]
19156 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
19157 "blsi\t{%1, %0|%0, %1}"
19158 [(set_attr "type" "bitmanip")
19159 (set_attr "btver2_decode" "double")
19160 (set_attr "mode" "<MODE>")])
19161
19162 (define_insn "*bmi_blsmsk_<mode>"
19163 [(set (match_operand:SWI48 0 "register_operand" "=r")
19164 (xor:SWI48
19165 (plus:SWI48
19166 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19167 (const_int -1))
19168 (match_dup 1)))
19169 (clobber (reg:CC FLAGS_REG))]
19170 "TARGET_BMI"
19171 "blsmsk\t{%1, %0|%0, %1}"
19172 [(set_attr "type" "bitmanip")
19173 (set_attr "btver2_decode" "double")
19174 (set_attr "mode" "<MODE>")])
19175
19176 (define_insn "*bmi_blsr_<mode>"
19177 [(set (match_operand:SWI48 0 "register_operand" "=r")
19178 (and:SWI48
19179 (plus:SWI48
19180 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19181 (const_int -1))
19182 (match_dup 1)))
19183 (clobber (reg:CC FLAGS_REG))]
19184 "TARGET_BMI"
19185 "blsr\t{%1, %0|%0, %1}"
19186 [(set_attr "type" "bitmanip")
19187 (set_attr "btver2_decode" "double")
19188 (set_attr "mode" "<MODE>")])
19189
19190 (define_insn "*bmi_blsr_<mode>_cmp"
19191 [(set (reg:CCZ FLAGS_REG)
19192 (compare:CCZ
19193 (and:SWI48
19194 (plus:SWI48
19195 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19196 (const_int -1))
19197 (match_dup 1))
19198 (const_int 0)))
19199 (set (match_operand:SWI48 0 "register_operand" "=r")
19200 (and:SWI48
19201 (plus:SWI48
19202 (match_dup 1)
19203 (const_int -1))
19204 (match_dup 1)))]
19205 "TARGET_BMI"
19206 "blsr\t{%1, %0|%0, %1}"
19207 [(set_attr "type" "bitmanip")
19208 (set_attr "btver2_decode" "double")
19209 (set_attr "mode" "<MODE>")])
19210
19211 (define_insn "*bmi_blsr_<mode>_ccz"
19212 [(set (reg:CCZ FLAGS_REG)
19213 (compare:CCZ
19214 (and:SWI48
19215 (plus:SWI48
19216 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19217 (const_int -1))
19218 (match_dup 1))
19219 (const_int 0)))
19220 (clobber (match_scratch:SWI48 0 "=r"))]
19221 "TARGET_BMI"
19222 "blsr\t{%1, %0|%0, %1}"
19223 [(set_attr "type" "bitmanip")
19224 (set_attr "btver2_decode" "double")
19225 (set_attr "mode" "<MODE>")])
19226
19227 ;; BMI2 instructions.
19228 (define_expand "bmi2_bzhi_<mode>3"
19229 [(parallel
19230 [(set (match_operand:SWI48 0 "register_operand")
19231 (if_then_else:SWI48
19232 (ne:QI (match_operand:QI 2 "register_operand")
19233 (const_int 0))
19234 (zero_extract:SWI48
19235 (match_operand:SWI48 1 "nonimmediate_operand")
19236 (umin:QI (match_dup 2) (match_dup 3))
19237 (const_int 0))
19238 (const_int 0)))
19239 (clobber (reg:CC FLAGS_REG))])]
19240 "TARGET_BMI2"
19241 {
19242 operands[2] = gen_lowpart (QImode, operands[2]);
19243 operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
19244 })
19245
19246 (define_insn "*bmi2_bzhi_<mode>3"
19247 [(set (match_operand:SWI48 0 "register_operand" "=r")
19248 (if_then_else:SWI48
19249 (ne:QI (match_operand:QI 2 "register_operand" "q")
19250 (const_int 0))
19251 (zero_extract:SWI48
19252 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19253 (umin:QI (match_dup 2)
19254 (match_operand:QI 3 "const_int_operand"))
19255 (const_int 0))
19256 (const_int 0)))
19257 (clobber (reg:CC FLAGS_REG))]
19258 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19259 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19260 [(set_attr "type" "bitmanip")
19261 (set_attr "prefix" "vex")
19262 (set_attr "mode" "<MODE>")])
19263
19264 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
19265 [(set (reg:CCZ FLAGS_REG)
19266 (compare:CCZ
19267 (if_then_else:SWI48
19268 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
19269 (zero_extract:SWI48
19270 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19271 (umin:QI (match_dup 2)
19272 (match_operand:QI 3 "const_int_operand"))
19273 (const_int 0))
19274 (const_int 0))
19275 (const_int 0)))
19276 (clobber (match_scratch:SWI48 0 "=r"))]
19277 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
19278 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19279 [(set_attr "type" "bitmanip")
19280 (set_attr "prefix" "vex")
19281 (set_attr "mode" "<MODE>")])
19282
19283 (define_insn "*bmi2_bzhi_<mode>3_2"
19284 [(set (match_operand:SWI48 0 "register_operand" "=r")
19285 (and:SWI48
19286 (plus:SWI48
19287 (ashift:SWI48 (const_int 1)
19288 (match_operand:QI 2 "register_operand" "r"))
19289 (const_int -1))
19290 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19291 (clobber (reg:CC FLAGS_REG))]
19292 "TARGET_BMI2"
19293 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19294 [(set_attr "type" "bitmanip")
19295 (set_attr "prefix" "vex")
19296 (set_attr "mode" "<MODE>")])
19297
19298 (define_insn "*bmi2_bzhi_<mode>3_3"
19299 [(set (match_operand:SWI48 0 "register_operand" "=r")
19300 (and:SWI48
19301 (not:SWI48
19302 (ashift:SWI48 (const_int -1)
19303 (match_operand:QI 2 "register_operand" "r")))
19304 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19305 (clobber (reg:CC FLAGS_REG))]
19306 "TARGET_BMI2"
19307 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
19308 [(set_attr "type" "bitmanip")
19309 (set_attr "prefix" "vex")
19310 (set_attr "mode" "<MODE>")])
19311
19312 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
19313 [(set (match_operand:DI 0 "register_operand" "=r")
19314 (zero_extend:DI
19315 (and:SI
19316 (plus:SI
19317 (ashift:SI (const_int 1)
19318 (match_operand:QI 2 "register_operand" "r"))
19319 (const_int -1))
19320 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19321 (clobber (reg:CC FLAGS_REG))]
19322 "TARGET_64BIT && TARGET_BMI2"
19323 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19324 [(set_attr "type" "bitmanip")
19325 (set_attr "prefix" "vex")
19326 (set_attr "mode" "DI")])
19327
19328 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
19329 [(set (match_operand:DI 0 "register_operand" "=r")
19330 (and:DI
19331 (zero_extend:DI
19332 (plus:SI
19333 (ashift:SI (const_int 1)
19334 (match_operand:QI 2 "register_operand" "r"))
19335 (const_int -1)))
19336 (match_operand:DI 1 "nonimmediate_operand" "rm")))
19337 (clobber (reg:CC FLAGS_REG))]
19338 "TARGET_64BIT && TARGET_BMI2"
19339 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
19340 [(set_attr "type" "bitmanip")
19341 (set_attr "prefix" "vex")
19342 (set_attr "mode" "DI")])
19343
19344 (define_insn "bmi2_pdep_<mode>3"
19345 [(set (match_operand:SWI48 0 "register_operand" "=r")
19346 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19347 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19348 UNSPEC_PDEP))]
19349 "TARGET_BMI2"
19350 "pdep\t{%2, %1, %0|%0, %1, %2}"
19351 [(set_attr "type" "bitmanip")
19352 (set_attr "prefix" "vex")
19353 (set_attr "mode" "<MODE>")])
19354
19355 (define_insn "bmi2_pext_<mode>3"
19356 [(set (match_operand:SWI48 0 "register_operand" "=r")
19357 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
19358 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
19359 UNSPEC_PEXT))]
19360 "TARGET_BMI2"
19361 "pext\t{%2, %1, %0|%0, %1, %2}"
19362 [(set_attr "type" "bitmanip")
19363 (set_attr "prefix" "vex")
19364 (set_attr "mode" "<MODE>")])
19365
19366 ;; TBM instructions.
19367 (define_insn "@tbm_bextri_<mode>"
19368 [(set (match_operand:SWI48 0 "register_operand" "=r")
19369 (zero_extract:SWI48
19370 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19371 (match_operand:QI 2 "const_0_to_255_operand")
19372 (match_operand:QI 3 "const_0_to_255_operand")))
19373 (clobber (reg:CC FLAGS_REG))]
19374 "TARGET_TBM"
19375 {
19376 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
19377 return "bextr\t{%2, %1, %0|%0, %1, %2}";
19378 }
19379 [(set_attr "type" "bitmanip")
19380 (set_attr "mode" "<MODE>")])
19381
19382 (define_insn "*tbm_blcfill_<mode>"
19383 [(set (match_operand:SWI48 0 "register_operand" "=r")
19384 (and:SWI48
19385 (plus:SWI48
19386 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19387 (const_int 1))
19388 (match_dup 1)))
19389 (clobber (reg:CC FLAGS_REG))]
19390 "TARGET_TBM"
19391 "blcfill\t{%1, %0|%0, %1}"
19392 [(set_attr "type" "bitmanip")
19393 (set_attr "mode" "<MODE>")])
19394
19395 (define_insn "*tbm_blci_<mode>"
19396 [(set (match_operand:SWI48 0 "register_operand" "=r")
19397 (ior:SWI48
19398 (not:SWI48
19399 (plus:SWI48
19400 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19401 (const_int 1)))
19402 (match_dup 1)))
19403 (clobber (reg:CC FLAGS_REG))]
19404 "TARGET_TBM"
19405 "blci\t{%1, %0|%0, %1}"
19406 [(set_attr "type" "bitmanip")
19407 (set_attr "mode" "<MODE>")])
19408
19409 (define_insn "*tbm_blcic_<mode>"
19410 [(set (match_operand:SWI48 0 "register_operand" "=r")
19411 (and:SWI48
19412 (plus:SWI48
19413 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19414 (const_int 1))
19415 (not:SWI48
19416 (match_dup 1))))
19417 (clobber (reg:CC FLAGS_REG))]
19418 "TARGET_TBM"
19419 "blcic\t{%1, %0|%0, %1}"
19420 [(set_attr "type" "bitmanip")
19421 (set_attr "mode" "<MODE>")])
19422
19423 (define_insn "*tbm_blcmsk_<mode>"
19424 [(set (match_operand:SWI48 0 "register_operand" "=r")
19425 (xor:SWI48
19426 (plus:SWI48
19427 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19428 (const_int 1))
19429 (match_dup 1)))
19430 (clobber (reg:CC FLAGS_REG))]
19431 "TARGET_TBM"
19432 "blcmsk\t{%1, %0|%0, %1}"
19433 [(set_attr "type" "bitmanip")
19434 (set_attr "mode" "<MODE>")])
19435
19436 (define_insn "*tbm_blcs_<mode>"
19437 [(set (match_operand:SWI48 0 "register_operand" "=r")
19438 (ior:SWI48
19439 (plus:SWI48
19440 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19441 (const_int 1))
19442 (match_dup 1)))
19443 (clobber (reg:CC FLAGS_REG))]
19444 "TARGET_TBM"
19445 "blcs\t{%1, %0|%0, %1}"
19446 [(set_attr "type" "bitmanip")
19447 (set_attr "mode" "<MODE>")])
19448
19449 (define_insn "*tbm_blsfill_<mode>"
19450 [(set (match_operand:SWI48 0 "register_operand" "=r")
19451 (ior:SWI48
19452 (plus:SWI48
19453 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19454 (const_int -1))
19455 (match_dup 1)))
19456 (clobber (reg:CC FLAGS_REG))]
19457 "TARGET_TBM"
19458 "blsfill\t{%1, %0|%0, %1}"
19459 [(set_attr "type" "bitmanip")
19460 (set_attr "mode" "<MODE>")])
19461
19462 (define_insn "*tbm_blsic_<mode>"
19463 [(set (match_operand:SWI48 0 "register_operand" "=r")
19464 (ior:SWI48
19465 (plus:SWI48
19466 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19467 (const_int -1))
19468 (not:SWI48
19469 (match_dup 1))))
19470 (clobber (reg:CC FLAGS_REG))]
19471 "TARGET_TBM"
19472 "blsic\t{%1, %0|%0, %1}"
19473 [(set_attr "type" "bitmanip")
19474 (set_attr "mode" "<MODE>")])
19475
19476 (define_insn "*tbm_t1mskc_<mode>"
19477 [(set (match_operand:SWI48 0 "register_operand" "=r")
19478 (ior:SWI48
19479 (plus:SWI48
19480 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19481 (const_int 1))
19482 (not:SWI48
19483 (match_dup 1))))
19484 (clobber (reg:CC FLAGS_REG))]
19485 "TARGET_TBM"
19486 "t1mskc\t{%1, %0|%0, %1}"
19487 [(set_attr "type" "bitmanip")
19488 (set_attr "mode" "<MODE>")])
19489
19490 (define_insn "*tbm_tzmsk_<mode>"
19491 [(set (match_operand:SWI48 0 "register_operand" "=r")
19492 (and:SWI48
19493 (plus:SWI48
19494 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
19495 (const_int -1))
19496 (not:SWI48
19497 (match_dup 1))))
19498 (clobber (reg:CC FLAGS_REG))]
19499 "TARGET_TBM"
19500 "tzmsk\t{%1, %0|%0, %1}"
19501 [(set_attr "type" "bitmanip")
19502 (set_attr "mode" "<MODE>")])
19503
19504 (define_insn_and_split "popcount<mode>2"
19505 [(set (match_operand:SWI48 0 "register_operand" "=r")
19506 (popcount:SWI48
19507 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19508 (clobber (reg:CC FLAGS_REG))]
19509 "TARGET_POPCNT"
19510 {
19511 #if TARGET_MACHO
19512 return "popcnt\t{%1, %0|%0, %1}";
19513 #else
19514 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19515 #endif
19516 }
19517 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19518 && optimize_function_for_speed_p (cfun)
19519 && !reg_mentioned_p (operands[0], operands[1])"
19520 [(parallel
19521 [(set (match_dup 0)
19522 (popcount:SWI48 (match_dup 1)))
19523 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19524 (clobber (reg:CC FLAGS_REG))])]
19525 "ix86_expand_clear (operands[0]);"
19526 [(set_attr "prefix_rep" "1")
19527 (set_attr "type" "bitmanip")
19528 (set_attr "mode" "<MODE>")])
19529
19530 ; False dependency happens when destination is only updated by tzcnt,
19531 ; lzcnt or popcnt. There is no false dependency when destination is
19532 ; also used in source.
19533 (define_insn "*popcount<mode>2_falsedep"
19534 [(set (match_operand:SWI48 0 "register_operand" "=r")
19535 (popcount:SWI48
19536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19537 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19538 UNSPEC_INSN_FALSE_DEP)
19539 (clobber (reg:CC FLAGS_REG))]
19540 "TARGET_POPCNT"
19541 {
19542 #if TARGET_MACHO
19543 return "popcnt\t{%1, %0|%0, %1}";
19544 #else
19545 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19546 #endif
19547 }
19548 [(set_attr "prefix_rep" "1")
19549 (set_attr "type" "bitmanip")
19550 (set_attr "mode" "<MODE>")])
19551
19552 (define_insn_and_split "*popcountsi2_zext"
19553 [(set (match_operand:DI 0 "register_operand" "=r")
19554 (and:DI
19555 (subreg:DI
19556 (popcount:SI
19557 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19558 (const_int 63)))
19559 (clobber (reg:CC FLAGS_REG))]
19560 "TARGET_POPCNT && TARGET_64BIT"
19561 {
19562 #if TARGET_MACHO
19563 return "popcnt\t{%1, %k0|%k0, %1}";
19564 #else
19565 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19566 #endif
19567 }
19568 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19569 && optimize_function_for_speed_p (cfun)
19570 && !reg_mentioned_p (operands[0], operands[1])"
19571 [(parallel
19572 [(set (match_dup 0)
19573 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19574 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19575 (clobber (reg:CC FLAGS_REG))])]
19576 "ix86_expand_clear (operands[0]);"
19577 [(set_attr "prefix_rep" "1")
19578 (set_attr "type" "bitmanip")
19579 (set_attr "mode" "SI")])
19580
19581 ; False dependency happens when destination is only updated by tzcnt,
19582 ; lzcnt or popcnt. There is no false dependency when destination is
19583 ; also used in source.
19584 (define_insn "*popcountsi2_zext_falsedep"
19585 [(set (match_operand:DI 0 "register_operand" "=r")
19586 (and:DI
19587 (subreg:DI
19588 (popcount:SI
19589 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19590 (const_int 63)))
19591 (unspec [(match_operand:DI 2 "register_operand" "0")]
19592 UNSPEC_INSN_FALSE_DEP)
19593 (clobber (reg:CC FLAGS_REG))]
19594 "TARGET_POPCNT && TARGET_64BIT"
19595 {
19596 #if TARGET_MACHO
19597 return "popcnt\t{%1, %k0|%k0, %1}";
19598 #else
19599 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19600 #endif
19601 }
19602 [(set_attr "prefix_rep" "1")
19603 (set_attr "type" "bitmanip")
19604 (set_attr "mode" "SI")])
19605
19606 (define_insn_and_split "*popcountsi2_zext_2"
19607 [(set (match_operand:DI 0 "register_operand" "=r")
19608 (zero_extend:DI
19609 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19610 (clobber (reg:CC FLAGS_REG))]
19611 "TARGET_POPCNT && TARGET_64BIT"
19612 {
19613 #if TARGET_MACHO
19614 return "popcnt\t{%1, %k0|%k0, %1}";
19615 #else
19616 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19617 #endif
19618 }
19619 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19620 && optimize_function_for_speed_p (cfun)
19621 && !reg_mentioned_p (operands[0], operands[1])"
19622 [(parallel
19623 [(set (match_dup 0)
19624 (zero_extend:DI (popcount:SI (match_dup 1))))
19625 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19626 (clobber (reg:CC FLAGS_REG))])]
19627 "ix86_expand_clear (operands[0]);"
19628 [(set_attr "prefix_rep" "1")
19629 (set_attr "type" "bitmanip")
19630 (set_attr "mode" "SI")])
19631
19632 ; False dependency happens when destination is only updated by tzcnt,
19633 ; lzcnt or popcnt. There is no false dependency when destination is
19634 ; also used in source.
19635 (define_insn "*popcountsi2_zext_2_falsedep"
19636 [(set (match_operand:DI 0 "register_operand" "=r")
19637 (zero_extend:DI
19638 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19639 (unspec [(match_operand:DI 2 "register_operand" "0")]
19640 UNSPEC_INSN_FALSE_DEP)
19641 (clobber (reg:CC FLAGS_REG))]
19642 "TARGET_POPCNT && TARGET_64BIT"
19643 {
19644 #if TARGET_MACHO
19645 return "popcnt\t{%1, %k0|%k0, %1}";
19646 #else
19647 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19648 #endif
19649 }
19650 [(set_attr "prefix_rep" "1")
19651 (set_attr "type" "bitmanip")
19652 (set_attr "mode" "SI")])
19653
19654 (define_insn_and_split "*popcounthi2_1"
19655 [(set (match_operand:SI 0 "register_operand")
19656 (popcount:SI
19657 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19658 (clobber (reg:CC FLAGS_REG))]
19659 "TARGET_POPCNT
19660 && ix86_pre_reload_split ()"
19661 "#"
19662 "&& 1"
19663 [(const_int 0)]
19664 {
19665 rtx tmp = gen_reg_rtx (HImode);
19666
19667 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19668 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19669 DONE;
19670 })
19671
19672 (define_insn_and_split "*popcounthi2_2"
19673 [(set (match_operand:SI 0 "register_operand")
19674 (zero_extend:SI
19675 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19676 (clobber (reg:CC FLAGS_REG))]
19677 "TARGET_POPCNT
19678 && ix86_pre_reload_split ()"
19679 "#"
19680 "&& 1"
19681 [(const_int 0)]
19682 {
19683 rtx tmp = gen_reg_rtx (HImode);
19684
19685 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19686 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19687 DONE;
19688 })
19689
19690 (define_insn "popcounthi2"
19691 [(set (match_operand:HI 0 "register_operand" "=r")
19692 (popcount:HI
19693 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19694 (clobber (reg:CC FLAGS_REG))]
19695 "TARGET_POPCNT"
19696 {
19697 #if TARGET_MACHO
19698 return "popcnt\t{%1, %0|%0, %1}";
19699 #else
19700 return "popcnt{w}\t{%1, %0|%0, %1}";
19701 #endif
19702 }
19703 [(set_attr "prefix_rep" "1")
19704 (set_attr "type" "bitmanip")
19705 (set_attr "mode" "HI")])
19706
19707 (define_expand "bswapdi2"
19708 [(set (match_operand:DI 0 "register_operand")
19709 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19710 "TARGET_64BIT"
19711 {
19712 if (!TARGET_MOVBE)
19713 operands[1] = force_reg (DImode, operands[1]);
19714 })
19715
19716 (define_expand "bswapsi2"
19717 [(set (match_operand:SI 0 "register_operand")
19718 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19719 ""
19720 {
19721 if (TARGET_MOVBE)
19722 ;
19723 else if (TARGET_BSWAP)
19724 operands[1] = force_reg (SImode, operands[1]);
19725 else
19726 {
19727 rtx x = operands[0];
19728
19729 emit_move_insn (x, operands[1]);
19730 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19731 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19732 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19733 DONE;
19734 }
19735 })
19736
19737 (define_insn "*bswap<mode>2_movbe"
19738 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19739 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19740 "TARGET_MOVBE
19741 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19742 "@
19743 bswap\t%0
19744 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19745 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19746 [(set_attr "type" "bitmanip,imov,imov")
19747 (set_attr "modrm" "0,1,1")
19748 (set_attr "prefix_0f" "*,1,1")
19749 (set_attr "prefix_extra" "*,1,1")
19750 (set_attr "mode" "<MODE>")])
19751
19752 (define_insn "*bswap<mode>2"
19753 [(set (match_operand:SWI48 0 "register_operand" "=r")
19754 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19755 "TARGET_BSWAP"
19756 "bswap\t%0"
19757 [(set_attr "type" "bitmanip")
19758 (set_attr "modrm" "0")
19759 (set_attr "mode" "<MODE>")])
19760
19761 (define_expand "bswaphi2"
19762 [(set (match_operand:HI 0 "register_operand")
19763 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19764 "TARGET_MOVBE")
19765
19766 (define_insn "*bswaphi2_movbe"
19767 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19768 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19769 "TARGET_MOVBE
19770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19771 "@
19772 xchg{b}\t{%h0, %b0|%b0, %h0}
19773 movbe{w}\t{%1, %0|%0, %1}
19774 movbe{w}\t{%1, %0|%0, %1}"
19775 [(set_attr "type" "imov")
19776 (set_attr "modrm" "*,1,1")
19777 (set_attr "prefix_0f" "*,1,1")
19778 (set_attr "prefix_extra" "*,1,1")
19779 (set_attr "pent_pair" "np,*,*")
19780 (set_attr "athlon_decode" "vector,*,*")
19781 (set_attr "amdfam10_decode" "double,*,*")
19782 (set_attr "bdver1_decode" "double,*,*")
19783 (set_attr "mode" "QI,HI,HI")])
19784
19785 (define_peephole2
19786 [(set (match_operand:HI 0 "general_reg_operand")
19787 (bswap:HI (match_dup 0)))]
19788 "TARGET_MOVBE
19789 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19790 && peep2_regno_dead_p (0, FLAGS_REG)"
19791 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19792 (clobber (reg:CC FLAGS_REG))])])
19793
19794 (define_insn "bswaphi_lowpart"
19795 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19796 (bswap:HI (match_dup 0)))
19797 (clobber (reg:CC FLAGS_REG))]
19798 ""
19799 "@
19800 xchg{b}\t{%h0, %b0|%b0, %h0}
19801 rol{w}\t{$8, %0|%0, 8}"
19802 [(set (attr "preferred_for_size")
19803 (cond [(eq_attr "alternative" "0")
19804 (symbol_ref "true")]
19805 (symbol_ref "false")))
19806 (set (attr "preferred_for_speed")
19807 (cond [(eq_attr "alternative" "0")
19808 (symbol_ref "TARGET_USE_XCHGB")]
19809 (symbol_ref "!TARGET_USE_XCHGB")))
19810 (set_attr "length" "2,4")
19811 (set_attr "mode" "QI,HI")])
19812
19813 (define_expand "paritydi2"
19814 [(set (match_operand:DI 0 "register_operand")
19815 (parity:DI (match_operand:DI 1 "register_operand")))]
19816 "! TARGET_POPCNT"
19817 {
19818 rtx scratch = gen_reg_rtx (QImode);
19819 rtx hipart1 = gen_reg_rtx (SImode);
19820 rtx lopart1 = gen_reg_rtx (SImode);
19821 rtx xor1 = gen_reg_rtx (SImode);
19822 rtx shift2 = gen_reg_rtx (SImode);
19823 rtx hipart2 = gen_reg_rtx (HImode);
19824 rtx lopart2 = gen_reg_rtx (HImode);
19825 rtx xor2 = gen_reg_rtx (HImode);
19826
19827 if (TARGET_64BIT)
19828 {
19829 rtx shift1 = gen_reg_rtx (DImode);
19830 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19831 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19832 }
19833 else
19834 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19835
19836 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19837 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19838
19839 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19840 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19841 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19842 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19843
19844 emit_insn (gen_parityhi2_cmp (xor2));
19845
19846 ix86_expand_setcc (scratch, ORDERED,
19847 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19848
19849 if (TARGET_64BIT)
19850 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19851 else
19852 {
19853 rtx tmp = gen_reg_rtx (SImode);
19854
19855 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19856 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19857 }
19858 DONE;
19859 })
19860
19861 (define_expand "paritysi2"
19862 [(set (match_operand:SI 0 "register_operand")
19863 (parity:SI (match_operand:SI 1 "register_operand")))]
19864 "! TARGET_POPCNT"
19865 {
19866 rtx scratch = gen_reg_rtx (QImode);
19867 rtx shift = gen_reg_rtx (SImode);
19868 rtx hipart = gen_reg_rtx (HImode);
19869 rtx lopart = gen_reg_rtx (HImode);
19870 rtx tmp = gen_reg_rtx (HImode);
19871
19872 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19873 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19874 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19875 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19876
19877 emit_insn (gen_parityhi2_cmp (tmp));
19878
19879 ix86_expand_setcc (scratch, ORDERED,
19880 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19881
19882 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19883 DONE;
19884 })
19885
19886 (define_expand "parityhi2"
19887 [(set (match_operand:HI 0 "register_operand")
19888 (parity:HI (match_operand:HI 1 "register_operand")))]
19889 "! TARGET_POPCNT"
19890 {
19891 rtx scratch = gen_reg_rtx (QImode);
19892
19893 emit_insn (gen_parityhi2_cmp (operands[1]));
19894
19895 ix86_expand_setcc (scratch, ORDERED,
19896 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19897
19898 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19899 DONE;
19900 })
19901
19902 (define_expand "parityqi2"
19903 [(set (match_operand:QI 0 "register_operand")
19904 (parity:QI (match_operand:QI 1 "register_operand")))]
19905 "! TARGET_POPCNT"
19906 {
19907 emit_insn (gen_parityqi2_cmp (operands[1]));
19908
19909 ix86_expand_setcc (operands[0], ORDERED,
19910 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19911 DONE;
19912 })
19913
19914 (define_insn "parityhi2_cmp"
19915 [(set (reg:CC FLAGS_REG)
19916 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19917 UNSPEC_PARITY))
19918 (clobber (match_dup 0))]
19919 ""
19920 "xor{b}\t{%h0, %b0|%b0, %h0}"
19921 [(set_attr "length" "2")
19922 (set_attr "mode" "QI")])
19923
19924 (define_insn "parityqi2_cmp"
19925 [(set (reg:CC FLAGS_REG)
19926 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19927 UNSPEC_PARITY))]
19928 ""
19929 "test{b}\t%0, %0"
19930 [(set_attr "mode" "QI")])
19931
19932 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19933 (define_peephole2
19934 [(set (match_operand:HI 0 "register_operand")
19935 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19936 (parallel [(set (reg:CC FLAGS_REG)
19937 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19938 (clobber (match_dup 0))])]
19939 ""
19940 [(set (reg:CC FLAGS_REG)
19941 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19942
19943 ;; Eliminate QImode popcount&1 using parity flag
19944 (define_peephole2
19945 [(set (match_operand:SI 0 "register_operand")
19946 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19947 (parallel [(set (match_operand:SI 2 "register_operand")
19948 (popcount:SI (match_dup 0)))
19949 (clobber (reg:CC FLAGS_REG))])
19950 (set (reg:CCZ FLAGS_REG)
19951 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19952 (const_int 1))
19953 (const_int 0)))
19954 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19955 [(reg:CCZ FLAGS_REG)
19956 (const_int 0)])
19957 (label_ref (match_operand 5))
19958 (pc)))]
19959 "REGNO (operands[2]) == REGNO (operands[3])
19960 && peep2_reg_dead_p (3, operands[0])
19961 && peep2_reg_dead_p (3, operands[2])
19962 && peep2_regno_dead_p (4, FLAGS_REG)"
19963 [(set (reg:CC FLAGS_REG)
19964 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19965 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19966 (const_int 0)])
19967 (label_ref (match_dup 5))
19968 (pc)))]
19969 {
19970 operands[4] = shallow_copy_rtx (operands[4]);
19971 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19972 })
19973
19974 ;; Eliminate HImode popcount&1 using parity flag
19975 (define_peephole2
19976 [(match_scratch:HI 0 "Q")
19977 (parallel [(set (match_operand:HI 1 "register_operand")
19978 (popcount:HI
19979 (match_operand:HI 2 "nonimmediate_operand")))
19980 (clobber (reg:CC FLAGS_REG))])
19981 (set (match_operand 3 "register_operand")
19982 (zero_extend (match_dup 1)))
19983 (set (reg:CCZ FLAGS_REG)
19984 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19985 (const_int 1))
19986 (const_int 0)))
19987 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19988 [(reg:CCZ FLAGS_REG)
19989 (const_int 0)])
19990 (label_ref (match_operand 6))
19991 (pc)))]
19992 "REGNO (operands[3]) == REGNO (operands[4])
19993 && peep2_reg_dead_p (3, operands[1])
19994 && peep2_reg_dead_p (3, operands[3])
19995 && peep2_regno_dead_p (4, FLAGS_REG)"
19996 [(set (match_dup 0) (match_dup 2))
19997 (parallel [(set (reg:CC FLAGS_REG)
19998 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19999 (clobber (match_dup 0))])
20000 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
20001 (const_int 0)])
20002 (label_ref (match_dup 6))
20003 (pc)))]
20004 {
20005 operands[5] = shallow_copy_rtx (operands[5]);
20006 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
20007 })
20008
20009 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
20010 (define_peephole2
20011 [(match_scratch:HI 0 "Q")
20012 (parallel [(set (match_operand:HI 1 "register_operand")
20013 (popcount:HI
20014 (match_operand:HI 2 "nonimmediate_operand")))
20015 (clobber (reg:CC FLAGS_REG))])
20016 (set (reg:CCZ FLAGS_REG)
20017 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
20018 (const_int 1))
20019 (const_int 0)))
20020 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
20021 [(reg:CCZ FLAGS_REG)
20022 (const_int 0)])
20023 (label_ref (match_operand 5))
20024 (pc)))]
20025 "REGNO (operands[1]) == REGNO (operands[3])
20026 && peep2_reg_dead_p (2, operands[1])
20027 && peep2_reg_dead_p (2, operands[3])
20028 && peep2_regno_dead_p (3, FLAGS_REG)"
20029 [(set (match_dup 0) (match_dup 2))
20030 (parallel [(set (reg:CC FLAGS_REG)
20031 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
20032 (clobber (match_dup 0))])
20033 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
20034 (const_int 0)])
20035 (label_ref (match_dup 5))
20036 (pc)))]
20037 {
20038 operands[4] = shallow_copy_rtx (operands[4]);
20039 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
20040 })
20041
20042 \f
20043 ;; Thread-local storage patterns for ELF.
20044 ;;
20045 ;; Note that these code sequences must appear exactly as shown
20046 ;; in order to allow linker relaxation.
20047
20048 (define_insn "*tls_global_dynamic_32_gnu"
20049 [(set (match_operand:SI 0 "register_operand" "=a")
20050 (unspec:SI
20051 [(match_operand:SI 1 "register_operand" "Yb")
20052 (match_operand 2 "tls_symbolic_operand")
20053 (match_operand 3 "constant_call_address_operand" "Bz")
20054 (reg:SI SP_REG)]
20055 UNSPEC_TLS_GD))
20056 (clobber (match_scratch:SI 4 "=d"))
20057 (clobber (match_scratch:SI 5 "=c"))
20058 (clobber (reg:CC FLAGS_REG))]
20059 "!TARGET_64BIT && TARGET_GNU_TLS"
20060 {
20061 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20062 output_asm_insn
20063 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
20064 else
20065 output_asm_insn
20066 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
20067 if (TARGET_SUN_TLS)
20068 #ifdef HAVE_AS_IX86_TLSGDPLT
20069 return "call\t%a2@tlsgdplt";
20070 #else
20071 return "call\t%p3@plt";
20072 #endif
20073 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20074 return "call\t%P3";
20075 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
20076 }
20077 [(set_attr "type" "multi")
20078 (set_attr "length" "12")])
20079
20080 (define_expand "tls_global_dynamic_32"
20081 [(parallel
20082 [(set (match_operand:SI 0 "register_operand")
20083 (unspec:SI [(match_operand:SI 2 "register_operand")
20084 (match_operand 1 "tls_symbolic_operand")
20085 (match_operand 3 "constant_call_address_operand")
20086 (reg:SI SP_REG)]
20087 UNSPEC_TLS_GD))
20088 (clobber (scratch:SI))
20089 (clobber (scratch:SI))
20090 (clobber (reg:CC FLAGS_REG))])]
20091 ""
20092 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20093
20094 (define_insn "*tls_global_dynamic_64_<mode>"
20095 [(set (match_operand:P 0 "register_operand" "=a")
20096 (call:P
20097 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
20098 (match_operand 3)))
20099 (unspec:P [(match_operand 1 "tls_symbolic_operand")
20100 (reg:P SP_REG)]
20101 UNSPEC_TLS_GD)]
20102 "TARGET_64BIT"
20103 {
20104 if (!TARGET_X32)
20105 /* The .loc directive has effect for 'the immediately following assembly
20106 instruction'. So for a sequence:
20107 .loc f l
20108 .byte x
20109 insn1
20110 the 'immediately following assembly instruction' is insn1.
20111 We want to emit an insn prefix here, but if we use .byte (as shown in
20112 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
20113 inside the insn sequence, rather than to the start. After relaxation
20114 of the sequence by the linker, the .loc might point inside an insn.
20115 Use data16 prefix instead, which doesn't have this problem. */
20116 fputs ("\tdata16", asm_out_file);
20117 output_asm_insn
20118 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
20119 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20120 fputs (ASM_SHORT "0x6666\n", asm_out_file);
20121 else
20122 fputs (ASM_BYTE "0x66\n", asm_out_file);
20123 fputs ("\trex64\n", asm_out_file);
20124 if (TARGET_SUN_TLS)
20125 return "call\t%p2@plt";
20126 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20127 return "call\t%P2";
20128 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
20129 }
20130 [(set_attr "type" "multi")
20131 (set (attr "length")
20132 (symbol_ref "TARGET_X32 ? 15 : 16"))])
20133
20134 (define_insn "*tls_global_dynamic_64_largepic"
20135 [(set (match_operand:DI 0 "register_operand" "=a")
20136 (call:DI
20137 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
20138 (match_operand:DI 3 "immediate_operand" "i")))
20139 (match_operand 4)))
20140 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
20141 (reg:DI SP_REG)]
20142 UNSPEC_TLS_GD)]
20143 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20144 && GET_CODE (operands[3]) == CONST
20145 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
20146 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
20147 {
20148 output_asm_insn
20149 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
20150 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
20151 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
20152 return "call\t{*%%rax|rax}";
20153 }
20154 [(set_attr "type" "multi")
20155 (set_attr "length" "22")])
20156
20157 (define_expand "@tls_global_dynamic_64_<mode>"
20158 [(parallel
20159 [(set (match_operand:P 0 "register_operand")
20160 (call:P
20161 (mem:QI (match_operand 2))
20162 (const_int 0)))
20163 (unspec:P [(match_operand 1 "tls_symbolic_operand")
20164 (reg:P SP_REG)]
20165 UNSPEC_TLS_GD)])]
20166 "TARGET_64BIT"
20167 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20168
20169 (define_insn "*tls_local_dynamic_base_32_gnu"
20170 [(set (match_operand:SI 0 "register_operand" "=a")
20171 (unspec:SI
20172 [(match_operand:SI 1 "register_operand" "Yb")
20173 (match_operand 2 "constant_call_address_operand" "Bz")
20174 (reg:SI SP_REG)]
20175 UNSPEC_TLS_LD_BASE))
20176 (clobber (match_scratch:SI 3 "=d"))
20177 (clobber (match_scratch:SI 4 "=c"))
20178 (clobber (reg:CC FLAGS_REG))]
20179 "!TARGET_64BIT && TARGET_GNU_TLS"
20180 {
20181 output_asm_insn
20182 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
20183 if (TARGET_SUN_TLS)
20184 {
20185 if (HAVE_AS_IX86_TLSLDMPLT)
20186 return "call\t%&@tlsldmplt";
20187 else
20188 return "call\t%p2@plt";
20189 }
20190 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20191 return "call\t%P2";
20192 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
20193 }
20194 [(set_attr "type" "multi")
20195 (set_attr "length" "11")])
20196
20197 (define_expand "tls_local_dynamic_base_32"
20198 [(parallel
20199 [(set (match_operand:SI 0 "register_operand")
20200 (unspec:SI
20201 [(match_operand:SI 1 "register_operand")
20202 (match_operand 2 "constant_call_address_operand")
20203 (reg:SI SP_REG)]
20204 UNSPEC_TLS_LD_BASE))
20205 (clobber (scratch:SI))
20206 (clobber (scratch:SI))
20207 (clobber (reg:CC FLAGS_REG))])]
20208 ""
20209 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20210
20211 (define_insn "*tls_local_dynamic_base_64_<mode>"
20212 [(set (match_operand:P 0 "register_operand" "=a")
20213 (call:P
20214 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
20215 (match_operand 2)))
20216 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
20217 "TARGET_64BIT"
20218 {
20219 output_asm_insn
20220 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20221 if (TARGET_SUN_TLS)
20222 return "call\t%p1@plt";
20223 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
20224 return "call\t%P1";
20225 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
20226 }
20227 [(set_attr "type" "multi")
20228 (set_attr "length" "12")])
20229
20230 (define_insn "*tls_local_dynamic_base_64_largepic"
20231 [(set (match_operand:DI 0 "register_operand" "=a")
20232 (call:DI
20233 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
20234 (match_operand:DI 2 "immediate_operand" "i")))
20235 (match_operand 3)))
20236 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
20237 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
20238 && GET_CODE (operands[2]) == CONST
20239 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
20240 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
20241 {
20242 output_asm_insn
20243 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
20244 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
20245 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
20246 return "call\t{*%%rax|rax}";
20247 }
20248 [(set_attr "type" "multi")
20249 (set_attr "length" "22")])
20250
20251 (define_expand "@tls_local_dynamic_base_64_<mode>"
20252 [(parallel
20253 [(set (match_operand:P 0 "register_operand")
20254 (call:P
20255 (mem:QI (match_operand 1))
20256 (const_int 0)))
20257 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
20258 "TARGET_64BIT"
20259 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
20260
20261 ;; Local dynamic of a single variable is a lose. Show combine how
20262 ;; to convert that back to global dynamic.
20263
20264 (define_insn_and_split "*tls_local_dynamic_32_once"
20265 [(set (match_operand:SI 0 "register_operand" "=a")
20266 (plus:SI
20267 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
20268 (match_operand 2 "constant_call_address_operand" "Bz")
20269 (reg:SI SP_REG)]
20270 UNSPEC_TLS_LD_BASE)
20271 (const:SI (unspec:SI
20272 [(match_operand 3 "tls_symbolic_operand")]
20273 UNSPEC_DTPOFF))))
20274 (clobber (match_scratch:SI 4 "=d"))
20275 (clobber (match_scratch:SI 5 "=c"))
20276 (clobber (reg:CC FLAGS_REG))]
20277 ""
20278 "#"
20279 ""
20280 [(parallel
20281 [(set (match_dup 0)
20282 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
20283 (reg:SI SP_REG)]
20284 UNSPEC_TLS_GD))
20285 (clobber (match_dup 4))
20286 (clobber (match_dup 5))
20287 (clobber (reg:CC FLAGS_REG))])])
20288
20289 ;; Load and add the thread base pointer from %<tp_seg>:0.
20290 (define_expand "get_thread_pointer<mode>"
20291 [(set (match_operand:PTR 0 "register_operand")
20292 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20293 ""
20294 {
20295 /* targetm is not visible in the scope of the condition. */
20296 if (!targetm.have_tls)
20297 error ("%<__builtin_thread_pointer%> is not supported on this target");
20298 })
20299
20300 (define_insn_and_split "*load_tp_<mode>"
20301 [(set (match_operand:PTR 0 "register_operand" "=r")
20302 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
20303 ""
20304 "#"
20305 ""
20306 [(set (match_dup 0)
20307 (match_dup 1))]
20308 {
20309 addr_space_t as = DEFAULT_TLS_SEG_REG;
20310
20311 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
20312 set_mem_addr_space (operands[1], as);
20313 })
20314
20315 (define_insn_and_split "*load_tp_x32_zext"
20316 [(set (match_operand:DI 0 "register_operand" "=r")
20317 (zero_extend:DI
20318 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
20319 "TARGET_X32"
20320 "#"
20321 "&& 1"
20322 [(set (match_dup 0)
20323 (zero_extend:DI (match_dup 1)))]
20324 {
20325 addr_space_t as = DEFAULT_TLS_SEG_REG;
20326
20327 operands[1] = gen_const_mem (SImode, const0_rtx);
20328 set_mem_addr_space (operands[1], as);
20329 })
20330
20331 (define_insn_and_split "*add_tp_<mode>"
20332 [(set (match_operand:PTR 0 "register_operand" "=r")
20333 (plus:PTR
20334 (unspec:PTR [(const_int 0)] UNSPEC_TP)
20335 (match_operand:PTR 1 "register_operand" "0")))
20336 (clobber (reg:CC FLAGS_REG))]
20337 ""
20338 "#"
20339 ""
20340 [(parallel
20341 [(set (match_dup 0)
20342 (plus:PTR (match_dup 1) (match_dup 2)))
20343 (clobber (reg:CC FLAGS_REG))])]
20344 {
20345 addr_space_t as = DEFAULT_TLS_SEG_REG;
20346
20347 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
20348 set_mem_addr_space (operands[2], as);
20349 })
20350
20351 (define_insn_and_split "*add_tp_x32_zext"
20352 [(set (match_operand:DI 0 "register_operand" "=r")
20353 (zero_extend:DI
20354 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
20355 (match_operand:SI 1 "register_operand" "0"))))
20356 (clobber (reg:CC FLAGS_REG))]
20357 "TARGET_X32"
20358 "#"
20359 "&& 1"
20360 [(parallel
20361 [(set (match_dup 0)
20362 (zero_extend:DI
20363 (plus:SI (match_dup 1) (match_dup 2))))
20364 (clobber (reg:CC FLAGS_REG))])]
20365 {
20366 addr_space_t as = DEFAULT_TLS_SEG_REG;
20367
20368 operands[2] = gen_const_mem (SImode, const0_rtx);
20369 set_mem_addr_space (operands[2], as);
20370 })
20371
20372 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
20373 ;; %rax as destination of the initial executable code sequence.
20374 (define_insn "tls_initial_exec_64_sun"
20375 [(set (match_operand:DI 0 "register_operand" "=a")
20376 (unspec:DI
20377 [(match_operand 1 "tls_symbolic_operand")]
20378 UNSPEC_TLS_IE_SUN))
20379 (clobber (reg:CC FLAGS_REG))]
20380 "TARGET_64BIT && TARGET_SUN_TLS"
20381 {
20382 output_asm_insn
20383 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
20384 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
20385 }
20386 [(set_attr "type" "multi")])
20387
20388 ;; GNU2 TLS patterns can be split.
20389
20390 (define_expand "tls_dynamic_gnu2_32"
20391 [(set (match_dup 3)
20392 (plus:SI (match_operand:SI 2 "register_operand")
20393 (const:SI
20394 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
20395 UNSPEC_TLSDESC))))
20396 (parallel
20397 [(set (match_operand:SI 0 "register_operand")
20398 (unspec:SI [(match_dup 1) (match_dup 3)
20399 (match_dup 2) (reg:SI SP_REG)]
20400 UNSPEC_TLSDESC))
20401 (clobber (reg:CC FLAGS_REG))])]
20402 "!TARGET_64BIT && TARGET_GNU2_TLS"
20403 {
20404 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20405 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20406 })
20407
20408 (define_insn "*tls_dynamic_gnu2_lea_32"
20409 [(set (match_operand:SI 0 "register_operand" "=r")
20410 (plus:SI (match_operand:SI 1 "register_operand" "b")
20411 (const:SI
20412 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
20413 UNSPEC_TLSDESC))))]
20414 "!TARGET_64BIT && TARGET_GNU2_TLS"
20415 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
20416 [(set_attr "type" "lea")
20417 (set_attr "mode" "SI")
20418 (set_attr "length" "6")
20419 (set_attr "length_address" "4")])
20420
20421 (define_insn "*tls_dynamic_gnu2_call_32"
20422 [(set (match_operand:SI 0 "register_operand" "=a")
20423 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
20424 (match_operand:SI 2 "register_operand" "0")
20425 ;; we have to make sure %ebx still points to the GOT
20426 (match_operand:SI 3 "register_operand" "b")
20427 (reg:SI SP_REG)]
20428 UNSPEC_TLSDESC))
20429 (clobber (reg:CC FLAGS_REG))]
20430 "!TARGET_64BIT && TARGET_GNU2_TLS"
20431 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
20432 [(set_attr "type" "call")
20433 (set_attr "length" "2")
20434 (set_attr "length_address" "0")])
20435
20436 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
20437 [(set (match_operand:SI 0 "register_operand" "=&a")
20438 (plus:SI
20439 (unspec:SI [(match_operand 3 "tls_modbase_operand")
20440 (match_operand:SI 4)
20441 (match_operand:SI 2 "register_operand" "b")
20442 (reg:SI SP_REG)]
20443 UNSPEC_TLSDESC)
20444 (const:SI (unspec:SI
20445 [(match_operand 1 "tls_symbolic_operand")]
20446 UNSPEC_DTPOFF))))
20447 (clobber (reg:CC FLAGS_REG))]
20448 "!TARGET_64BIT && TARGET_GNU2_TLS"
20449 "#"
20450 "&& 1"
20451 [(set (match_dup 0) (match_dup 5))]
20452 {
20453 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
20454 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
20455 })
20456
20457 (define_expand "@tls_dynamic_gnu2_64_<mode>"
20458 [(set (match_dup 2)
20459 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20460 UNSPEC_TLSDESC))
20461 (parallel
20462 [(set (match_operand:PTR 0 "register_operand")
20463 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
20464 UNSPEC_TLSDESC))
20465 (clobber (reg:CC FLAGS_REG))])]
20466 "TARGET_64BIT && TARGET_GNU2_TLS"
20467 {
20468 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20469 ix86_tls_descriptor_calls_expanded_in_cfun = true;
20470 })
20471
20472 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
20473 [(set (match_operand:PTR 0 "register_operand" "=r")
20474 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
20475 UNSPEC_TLSDESC))]
20476 "TARGET_64BIT && TARGET_GNU2_TLS"
20477 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
20478 [(set_attr "type" "lea")
20479 (set_attr "mode" "<MODE>")
20480 (set_attr "length" "7")
20481 (set_attr "length_address" "4")])
20482
20483 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
20484 [(set (match_operand:PTR 0 "register_operand" "=a")
20485 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
20486 (match_operand:PTR 2 "register_operand" "0")
20487 (reg:PTR SP_REG)]
20488 UNSPEC_TLSDESC))
20489 (clobber (reg:CC FLAGS_REG))]
20490 "TARGET_64BIT && TARGET_GNU2_TLS"
20491 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
20492 [(set_attr "type" "call")
20493 (set_attr "length" "2")
20494 (set_attr "length_address" "0")])
20495
20496 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
20497 [(set (match_operand:PTR 0 "register_operand" "=&a")
20498 (plus:PTR
20499 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
20500 (match_operand:PTR 3)
20501 (reg:PTR SP_REG)]
20502 UNSPEC_TLSDESC)
20503 (const:PTR (unspec:PTR
20504 [(match_operand 1 "tls_symbolic_operand")]
20505 UNSPEC_DTPOFF))))
20506 (clobber (reg:CC FLAGS_REG))]
20507 "TARGET_64BIT && TARGET_GNU2_TLS"
20508 "#"
20509 "&& 1"
20510 [(set (match_dup 0) (match_dup 4))]
20511 {
20512 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20513 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20514 })
20515
20516 (define_split
20517 [(match_operand 0 "tls_address_pattern")]
20518 "TARGET_TLS_DIRECT_SEG_REFS"
20519 [(match_dup 0)]
20520 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20521
20522 \f
20523 ;; These patterns match the binary 387 instructions for addM3, subM3,
20524 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20525 ;; SFmode. The first is the normal insn, the second the same insn but
20526 ;; with one operand a conversion, and the third the same insn but with
20527 ;; the other operand a conversion. The conversion may be SFmode or
20528 ;; SImode if the target mode DFmode, but only SImode if the target mode
20529 ;; is SFmode.
20530
20531 ;; Gcc is slightly more smart about handling normal two address instructions
20532 ;; so use special patterns for add and mull.
20533
20534 (define_insn "*fop_xf_comm_i387"
20535 [(set (match_operand:XF 0 "register_operand" "=f")
20536 (match_operator:XF 3 "binary_fp_operator"
20537 [(match_operand:XF 1 "register_operand" "%0")
20538 (match_operand:XF 2 "register_operand" "f")]))]
20539 "TARGET_80387
20540 && COMMUTATIVE_ARITH_P (operands[3])"
20541 "* return output_387_binary_op (insn, operands);"
20542 [(set (attr "type")
20543 (if_then_else (match_operand:XF 3 "mult_operator")
20544 (const_string "fmul")
20545 (const_string "fop")))
20546 (set_attr "mode" "XF")])
20547
20548 (define_insn "*fop_<mode>_comm"
20549 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20550 (match_operator:MODEF 3 "binary_fp_operator"
20551 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20552 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20553 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20554 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20555 && COMMUTATIVE_ARITH_P (operands[3])
20556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20557 "* return output_387_binary_op (insn, operands);"
20558 [(set (attr "type")
20559 (if_then_else (eq_attr "alternative" "1,2")
20560 (if_then_else (match_operand:MODEF 3 "mult_operator")
20561 (const_string "ssemul")
20562 (const_string "sseadd"))
20563 (if_then_else (match_operand:MODEF 3 "mult_operator")
20564 (const_string "fmul")
20565 (const_string "fop"))))
20566 (set_attr "isa" "*,noavx,avx")
20567 (set_attr "prefix" "orig,orig,vex")
20568 (set_attr "mode" "<MODE>")
20569 (set (attr "enabled")
20570 (if_then_else
20571 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20572 (if_then_else
20573 (eq_attr "alternative" "0")
20574 (symbol_ref "TARGET_MIX_SSE_I387
20575 && X87_ENABLE_ARITH (<MODE>mode)")
20576 (const_string "*"))
20577 (if_then_else
20578 (eq_attr "alternative" "0")
20579 (symbol_ref "true")
20580 (symbol_ref "false"))))])
20581
20582 (define_insn "*<insn>hf"
20583 [(set (match_operand:HF 0 "register_operand" "=v")
20584 (plusminusmultdiv:HF
20585 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20586 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20587 "TARGET_AVX512FP16
20588 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20589 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20590 [(set_attr "prefix" "evex")
20591 (set_attr "mode" "HF")])
20592
20593 (define_insn "*rcpsf2_sse"
20594 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20595 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20596 UNSPEC_RCP))]
20597 "TARGET_SSE && TARGET_SSE_MATH"
20598 "@
20599 %vrcpss\t{%d1, %0|%0, %d1}
20600 %vrcpss\t{%d1, %0|%0, %d1}
20601 rcpss\t{%1, %d0|%d0, %1}
20602 vrcpss\t{%1, %d0|%d0, %1}"
20603 [(set_attr "isa" "*,*,noavx,avx")
20604 (set_attr "addr" "*,*,*,gpr16")
20605 (set_attr "type" "sse")
20606 (set_attr "atom_sse_attr" "rcp")
20607 (set_attr "btver2_sse_attr" "rcp")
20608 (set_attr "prefix" "maybe_vex")
20609 (set_attr "mode" "SF")
20610 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20611 (set (attr "preferred_for_speed")
20612 (cond [(match_test "TARGET_AVX")
20613 (symbol_ref "true")
20614 (eq_attr "alternative" "1,2,3")
20615 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20616 ]
20617 (symbol_ref "true")))])
20618
20619 (define_insn "rcphf2"
20620 [(set (match_operand:HF 0 "register_operand" "=v,v")
20621 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20622 UNSPEC_RCP))]
20623 "TARGET_AVX512FP16"
20624 "@
20625 vrcpsh\t{%d1, %0|%0, %d1}
20626 vrcpsh\t{%1, %d0|%d0, %1}"
20627 [(set_attr "type" "sse")
20628 (set_attr "prefix" "evex")
20629 (set_attr "mode" "HF")
20630 (set_attr "avx_partial_xmm_update" "false,true")])
20631
20632 (define_insn "*fop_xf_1_i387"
20633 [(set (match_operand:XF 0 "register_operand" "=f,f")
20634 (match_operator:XF 3 "binary_fp_operator"
20635 [(match_operand:XF 1 "register_operand" "0,f")
20636 (match_operand:XF 2 "register_operand" "f,0")]))]
20637 "TARGET_80387
20638 && !COMMUTATIVE_ARITH_P (operands[3])"
20639 "* return output_387_binary_op (insn, operands);"
20640 [(set (attr "type")
20641 (if_then_else (match_operand:XF 3 "div_operator")
20642 (const_string "fdiv")
20643 (const_string "fop")))
20644 (set_attr "mode" "XF")])
20645
20646 (define_insn "*fop_<mode>_1"
20647 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20648 (match_operator:MODEF 3 "binary_fp_operator"
20649 [(match_operand:MODEF 1
20650 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20651 (match_operand:MODEF 2
20652 "nonimmediate_operand" "fm,0,xm,vm")]))]
20653 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20654 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20655 && !COMMUTATIVE_ARITH_P (operands[3])
20656 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20657 "* return output_387_binary_op (insn, operands);"
20658 [(set (attr "type")
20659 (if_then_else (eq_attr "alternative" "2,3")
20660 (if_then_else (match_operand:MODEF 3 "div_operator")
20661 (const_string "ssediv")
20662 (const_string "sseadd"))
20663 (if_then_else (match_operand:MODEF 3 "div_operator")
20664 (const_string "fdiv")
20665 (const_string "fop"))))
20666 (set_attr "isa" "*,*,noavx,avx")
20667 (set_attr "prefix" "orig,orig,orig,vex")
20668 (set_attr "mode" "<MODE>")
20669 (set (attr "enabled")
20670 (if_then_else
20671 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20672 (if_then_else
20673 (eq_attr "alternative" "0,1")
20674 (symbol_ref "TARGET_MIX_SSE_I387
20675 && X87_ENABLE_ARITH (<MODE>mode)")
20676 (const_string "*"))
20677 (if_then_else
20678 (eq_attr "alternative" "0,1")
20679 (symbol_ref "true")
20680 (symbol_ref "false"))))])
20681
20682 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20683 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20684 (match_operator:X87MODEF 3 "binary_fp_operator"
20685 [(float:X87MODEF
20686 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20687 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20688 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20689 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20690 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20691 || optimize_function_for_size_p (cfun))"
20692 "* return output_387_binary_op (insn, operands);"
20693 [(set (attr "type")
20694 (cond [(match_operand:X87MODEF 3 "mult_operator")
20695 (const_string "fmul")
20696 (match_operand:X87MODEF 3 "div_operator")
20697 (const_string "fdiv")
20698 ]
20699 (const_string "fop")))
20700 (set_attr "fp_int_src" "true")
20701 (set_attr "mode" "<SWI24:MODE>")])
20702
20703 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20704 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20705 (match_operator:X87MODEF 3 "binary_fp_operator"
20706 [(match_operand:X87MODEF 1 "register_operand" "0")
20707 (float:X87MODEF
20708 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20709 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20710 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20711 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20712 || optimize_function_for_size_p (cfun))"
20713 "* return output_387_binary_op (insn, operands);"
20714 [(set (attr "type")
20715 (cond [(match_operand:X87MODEF 3 "mult_operator")
20716 (const_string "fmul")
20717 (match_operand:X87MODEF 3 "div_operator")
20718 (const_string "fdiv")
20719 ]
20720 (const_string "fop")))
20721 (set_attr "fp_int_src" "true")
20722 (set_attr "mode" "<SWI24:MODE>")])
20723
20724 (define_insn "*fop_xf_4_i387"
20725 [(set (match_operand:XF 0 "register_operand" "=f,f")
20726 (match_operator:XF 3 "binary_fp_operator"
20727 [(float_extend:XF
20728 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20729 (match_operand:XF 2 "register_operand" "0,f")]))]
20730 "TARGET_80387"
20731 "* return output_387_binary_op (insn, operands);"
20732 [(set (attr "type")
20733 (cond [(match_operand:XF 3 "mult_operator")
20734 (const_string "fmul")
20735 (match_operand:XF 3 "div_operator")
20736 (const_string "fdiv")
20737 ]
20738 (const_string "fop")))
20739 (set_attr "mode" "<MODE>")])
20740
20741 (define_insn "*fop_df_4_i387"
20742 [(set (match_operand:DF 0 "register_operand" "=f,f")
20743 (match_operator:DF 3 "binary_fp_operator"
20744 [(float_extend:DF
20745 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20746 (match_operand:DF 2 "register_operand" "0,f")]))]
20747 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20748 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20749 "* return output_387_binary_op (insn, operands);"
20750 [(set (attr "type")
20751 (cond [(match_operand:DF 3 "mult_operator")
20752 (const_string "fmul")
20753 (match_operand:DF 3 "div_operator")
20754 (const_string "fdiv")
20755 ]
20756 (const_string "fop")))
20757 (set_attr "mode" "SF")])
20758
20759 (define_insn "*fop_xf_5_i387"
20760 [(set (match_operand:XF 0 "register_operand" "=f,f")
20761 (match_operator:XF 3 "binary_fp_operator"
20762 [(match_operand:XF 1 "register_operand" "0,f")
20763 (float_extend:XF
20764 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20765 "TARGET_80387"
20766 "* return output_387_binary_op (insn, operands);"
20767 [(set (attr "type")
20768 (cond [(match_operand:XF 3 "mult_operator")
20769 (const_string "fmul")
20770 (match_operand:XF 3 "div_operator")
20771 (const_string "fdiv")
20772 ]
20773 (const_string "fop")))
20774 (set_attr "mode" "<MODE>")])
20775
20776 (define_insn "*fop_df_5_i387"
20777 [(set (match_operand:DF 0 "register_operand" "=f,f")
20778 (match_operator:DF 3 "binary_fp_operator"
20779 [(match_operand:DF 1 "register_operand" "0,f")
20780 (float_extend:DF
20781 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20782 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20783 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20784 "* return output_387_binary_op (insn, operands);"
20785 [(set (attr "type")
20786 (cond [(match_operand:DF 3 "mult_operator")
20787 (const_string "fmul")
20788 (match_operand:DF 3 "div_operator")
20789 (const_string "fdiv")
20790 ]
20791 (const_string "fop")))
20792 (set_attr "mode" "SF")])
20793
20794 (define_insn "*fop_xf_6_i387"
20795 [(set (match_operand:XF 0 "register_operand" "=f,f")
20796 (match_operator:XF 3 "binary_fp_operator"
20797 [(float_extend:XF
20798 (match_operand:MODEF 1 "register_operand" "0,f"))
20799 (float_extend:XF
20800 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20801 "TARGET_80387"
20802 "* return output_387_binary_op (insn, operands);"
20803 [(set (attr "type")
20804 (cond [(match_operand:XF 3 "mult_operator")
20805 (const_string "fmul")
20806 (match_operand:XF 3 "div_operator")
20807 (const_string "fdiv")
20808 ]
20809 (const_string "fop")))
20810 (set_attr "mode" "<MODE>")])
20811
20812 (define_insn "*fop_df_6_i387"
20813 [(set (match_operand:DF 0 "register_operand" "=f,f")
20814 (match_operator:DF 3 "binary_fp_operator"
20815 [(float_extend:DF
20816 (match_operand:SF 1 "register_operand" "0,f"))
20817 (float_extend:DF
20818 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20819 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20820 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20821 "* return output_387_binary_op (insn, operands);"
20822 [(set (attr "type")
20823 (cond [(match_operand:DF 3 "mult_operator")
20824 (const_string "fmul")
20825 (match_operand:DF 3 "div_operator")
20826 (const_string "fdiv")
20827 ]
20828 (const_string "fop")))
20829 (set_attr "mode" "SF")])
20830 \f
20831 ;; FPU special functions.
20832
20833 ;; This pattern implements a no-op XFmode truncation for
20834 ;; all fancy i386 XFmode math functions.
20835
20836 (define_insn "truncxf<mode>2_i387_noop_unspec"
20837 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20838 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20839 UNSPEC_TRUNC_NOOP))]
20840 "TARGET_USE_FANCY_MATH_387"
20841 "* return output_387_reg_move (insn, operands);"
20842 [(set_attr "type" "fmov")
20843 (set_attr "mode" "<MODE>")])
20844
20845 (define_insn "sqrtxf2"
20846 [(set (match_operand:XF 0 "register_operand" "=f")
20847 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20848 "TARGET_USE_FANCY_MATH_387"
20849 "fsqrt"
20850 [(set_attr "type" "fpspc")
20851 (set_attr "mode" "XF")
20852 (set_attr "athlon_decode" "direct")
20853 (set_attr "amdfam10_decode" "direct")
20854 (set_attr "bdver1_decode" "direct")])
20855
20856 (define_insn "*rsqrtsf2_sse"
20857 [(set (match_operand:SF 0 "register_operand" "=x,x,x,x")
20858 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m,ja")]
20859 UNSPEC_RSQRT))]
20860 "TARGET_SSE && TARGET_SSE_MATH"
20861 "@
20862 %vrsqrtss\t{%d1, %0|%0, %d1}
20863 %vrsqrtss\t{%d1, %0|%0, %d1}
20864 rsqrtss\t{%1, %d0|%d0, %1}
20865 vrsqrtss\t{%1, %d0|%d0, %1}"
20866 [(set_attr "isa" "*,*,noavx,avx")
20867 (set_attr "addr" "*,*,*,gpr16")
20868 (set_attr "type" "sse")
20869 (set_attr "atom_sse_attr" "rcp")
20870 (set_attr "btver2_sse_attr" "rcp")
20871 (set_attr "prefix" "maybe_vex")
20872 (set_attr "mode" "SF")
20873 (set_attr "avx_partial_xmm_update" "false,false,true,true")
20874 (set (attr "preferred_for_speed")
20875 (cond [(match_test "TARGET_AVX")
20876 (symbol_ref "true")
20877 (eq_attr "alternative" "1,2,3")
20878 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20879 ]
20880 (symbol_ref "true")))])
20881
20882 (define_expand "rsqrtsf2"
20883 [(set (match_operand:SF 0 "register_operand")
20884 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20885 UNSPEC_RSQRT))]
20886 "TARGET_SSE && TARGET_SSE_MATH"
20887 {
20888 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20889 DONE;
20890 })
20891
20892 (define_insn "rsqrthf2"
20893 [(set (match_operand:HF 0 "register_operand" "=v,v")
20894 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20895 UNSPEC_RSQRT))]
20896 "TARGET_AVX512FP16"
20897 "@
20898 vrsqrtsh\t{%d1, %0|%0, %d1}
20899 vrsqrtsh\t{%1, %d0|%d0, %1}"
20900 [(set_attr "type" "sse")
20901 (set_attr "prefix" "evex")
20902 (set_attr "avx_partial_xmm_update" "false,true")
20903 (set_attr "mode" "HF")])
20904
20905 (define_insn "sqrthf2"
20906 [(set (match_operand:HF 0 "register_operand" "=v,v")
20907 (sqrt:HF
20908 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20909 "TARGET_AVX512FP16"
20910 "@
20911 vsqrtsh\t{%d1, %0|%0, %d1}
20912 vsqrtsh\t{%1, %d0|%d0, %1}"
20913 [(set_attr "type" "sse")
20914 (set_attr "prefix" "evex")
20915 (set_attr "avx_partial_xmm_update" "false,true")
20916 (set_attr "mode" "HF")])
20917
20918 (define_insn "*sqrt<mode>2_sse"
20919 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20920 (sqrt:MODEF
20921 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20922 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20923 "@
20924 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20925 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20926 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20927 [(set_attr "type" "sse")
20928 (set_attr "atom_sse_attr" "sqrt")
20929 (set_attr "btver2_sse_attr" "sqrt")
20930 (set_attr "prefix" "maybe_vex")
20931 (set_attr "avx_partial_xmm_update" "false,false,true")
20932 (set_attr "mode" "<MODE>")
20933 (set (attr "preferred_for_speed")
20934 (cond [(match_test "TARGET_AVX")
20935 (symbol_ref "true")
20936 (eq_attr "alternative" "1,2")
20937 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20938 ]
20939 (symbol_ref "true")))])
20940
20941 (define_expand "sqrt<mode>2"
20942 [(set (match_operand:MODEF 0 "register_operand")
20943 (sqrt:MODEF
20944 (match_operand:MODEF 1 "nonimmediate_operand")))]
20945 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20946 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20947 {
20948 if (<MODE>mode == SFmode
20949 && TARGET_SSE && TARGET_SSE_MATH
20950 && TARGET_RECIP_SQRT
20951 && !optimize_function_for_size_p (cfun)
20952 && flag_finite_math_only && !flag_trapping_math
20953 && flag_unsafe_math_optimizations)
20954 {
20955 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20956 DONE;
20957 }
20958
20959 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20960 {
20961 rtx op0 = gen_reg_rtx (XFmode);
20962 rtx op1 = gen_reg_rtx (XFmode);
20963
20964 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20965 emit_insn (gen_sqrtxf2 (op0, op1));
20966 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20967 DONE;
20968 }
20969 })
20970
20971 (define_expand "hypot<mode>3"
20972 [(use (match_operand:MODEF 0 "register_operand"))
20973 (use (match_operand:MODEF 1 "general_operand"))
20974 (use (match_operand:MODEF 2 "general_operand"))]
20975 "TARGET_USE_FANCY_MATH_387
20976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20977 || TARGET_MIX_SSE_I387)
20978 && flag_finite_math_only
20979 && flag_unsafe_math_optimizations"
20980 {
20981 rtx op0 = gen_reg_rtx (XFmode);
20982 rtx op1 = gen_reg_rtx (XFmode);
20983 rtx op2 = gen_reg_rtx (XFmode);
20984
20985 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20986 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20987
20988 emit_insn (gen_mulxf3 (op1, op1, op1));
20989 emit_insn (gen_mulxf3 (op2, op2, op2));
20990 emit_insn (gen_addxf3 (op0, op2, op1));
20991 emit_insn (gen_sqrtxf2 (op0, op0));
20992
20993 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20994 DONE;
20995 })
20996
20997 (define_insn "x86_fnstsw_1"
20998 [(set (match_operand:HI 0 "register_operand" "=a")
20999 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
21000 "TARGET_80387"
21001 "fnstsw\t%0"
21002 [(set_attr "length" "2")
21003 (set_attr "mode" "SI")
21004 (set_attr "unit" "i387")])
21005
21006 (define_insn "fpremxf4_i387"
21007 [(set (match_operand:XF 0 "register_operand" "=f")
21008 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21009 (match_operand:XF 3 "register_operand" "1")]
21010 UNSPEC_FPREM_F))
21011 (set (match_operand:XF 1 "register_operand" "=f")
21012 (unspec:XF [(match_dup 2) (match_dup 3)]
21013 UNSPEC_FPREM_U))
21014 (set (reg:CCFP FPSR_REG)
21015 (unspec:CCFP [(match_dup 2) (match_dup 3)]
21016 UNSPEC_C2_FLAG))]
21017 "TARGET_USE_FANCY_MATH_387"
21018 "fprem"
21019 [(set_attr "type" "fpspc")
21020 (set_attr "znver1_decode" "vector")
21021 (set_attr "mode" "XF")])
21022
21023 (define_expand "fmodxf3"
21024 [(use (match_operand:XF 0 "register_operand"))
21025 (use (match_operand:XF 1 "general_operand"))
21026 (use (match_operand:XF 2 "general_operand"))]
21027 "TARGET_USE_FANCY_MATH_387"
21028 {
21029 rtx_code_label *label = gen_label_rtx ();
21030
21031 rtx op1 = gen_reg_rtx (XFmode);
21032 rtx op2 = gen_reg_rtx (XFmode);
21033
21034 emit_move_insn (op2, operands[2]);
21035 emit_move_insn (op1, operands[1]);
21036
21037 emit_label (label);
21038 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
21039 ix86_emit_fp_unordered_jump (label);
21040 LABEL_NUSES (label) = 1;
21041
21042 emit_move_insn (operands[0], op1);
21043 DONE;
21044 })
21045
21046 (define_expand "fmod<mode>3"
21047 [(use (match_operand:MODEF 0 "register_operand"))
21048 (use (match_operand:MODEF 1 "general_operand"))
21049 (use (match_operand:MODEF 2 "general_operand"))]
21050 "TARGET_USE_FANCY_MATH_387"
21051 {
21052 rtx (*gen_truncxf) (rtx, rtx);
21053
21054 rtx_code_label *label = gen_label_rtx ();
21055
21056 rtx op1 = gen_reg_rtx (XFmode);
21057 rtx op2 = gen_reg_rtx (XFmode);
21058
21059 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21060 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21061
21062 emit_label (label);
21063 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
21064 ix86_emit_fp_unordered_jump (label);
21065 LABEL_NUSES (label) = 1;
21066
21067 /* Truncate the result properly for strict SSE math. */
21068 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21069 && !TARGET_MIX_SSE_I387)
21070 gen_truncxf = gen_truncxf<mode>2;
21071 else
21072 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
21073
21074 emit_insn (gen_truncxf (operands[0], op1));
21075 DONE;
21076 })
21077
21078 (define_insn "fprem1xf4_i387"
21079 [(set (match_operand:XF 0 "register_operand" "=f")
21080 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21081 (match_operand:XF 3 "register_operand" "1")]
21082 UNSPEC_FPREM1_F))
21083 (set (match_operand:XF 1 "register_operand" "=f")
21084 (unspec:XF [(match_dup 2) (match_dup 3)]
21085 UNSPEC_FPREM1_U))
21086 (set (reg:CCFP FPSR_REG)
21087 (unspec:CCFP [(match_dup 2) (match_dup 3)]
21088 UNSPEC_C2_FLAG))]
21089 "TARGET_USE_FANCY_MATH_387"
21090 "fprem1"
21091 [(set_attr "type" "fpspc")
21092 (set_attr "znver1_decode" "vector")
21093 (set_attr "mode" "XF")])
21094
21095 (define_expand "remainderxf3"
21096 [(use (match_operand:XF 0 "register_operand"))
21097 (use (match_operand:XF 1 "general_operand"))
21098 (use (match_operand:XF 2 "general_operand"))]
21099 "TARGET_USE_FANCY_MATH_387"
21100 {
21101 rtx_code_label *label = gen_label_rtx ();
21102
21103 rtx op1 = gen_reg_rtx (XFmode);
21104 rtx op2 = gen_reg_rtx (XFmode);
21105
21106 emit_move_insn (op2, operands[2]);
21107 emit_move_insn (op1, operands[1]);
21108
21109 emit_label (label);
21110 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
21111 ix86_emit_fp_unordered_jump (label);
21112 LABEL_NUSES (label) = 1;
21113
21114 emit_move_insn (operands[0], op1);
21115 DONE;
21116 })
21117
21118 (define_expand "remainder<mode>3"
21119 [(use (match_operand:MODEF 0 "register_operand"))
21120 (use (match_operand:MODEF 1 "general_operand"))
21121 (use (match_operand:MODEF 2 "general_operand"))]
21122 "TARGET_USE_FANCY_MATH_387"
21123 {
21124 rtx (*gen_truncxf) (rtx, rtx);
21125
21126 rtx_code_label *label = gen_label_rtx ();
21127
21128 rtx op1 = gen_reg_rtx (XFmode);
21129 rtx op2 = gen_reg_rtx (XFmode);
21130
21131 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21132 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21133
21134 emit_label (label);
21135
21136 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
21137 ix86_emit_fp_unordered_jump (label);
21138 LABEL_NUSES (label) = 1;
21139
21140 /* Truncate the result properly for strict SSE math. */
21141 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21142 && !TARGET_MIX_SSE_I387)
21143 gen_truncxf = gen_truncxf<mode>2;
21144 else
21145 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
21146
21147 emit_insn (gen_truncxf (operands[0], op1));
21148 DONE;
21149 })
21150
21151 (define_int_iterator SINCOS
21152 [UNSPEC_SIN
21153 UNSPEC_COS])
21154
21155 (define_int_attr sincos
21156 [(UNSPEC_SIN "sin")
21157 (UNSPEC_COS "cos")])
21158
21159 (define_insn "<sincos>xf2"
21160 [(set (match_operand:XF 0 "register_operand" "=f")
21161 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21162 SINCOS))]
21163 "TARGET_USE_FANCY_MATH_387
21164 && flag_unsafe_math_optimizations"
21165 "f<sincos>"
21166 [(set_attr "type" "fpspc")
21167 (set_attr "znver1_decode" "vector")
21168 (set_attr "mode" "XF")])
21169
21170 (define_expand "<sincos><mode>2"
21171 [(set (match_operand:MODEF 0 "register_operand")
21172 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
21173 SINCOS))]
21174 "TARGET_USE_FANCY_MATH_387
21175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21176 || TARGET_MIX_SSE_I387)
21177 && flag_unsafe_math_optimizations"
21178 {
21179 rtx op0 = gen_reg_rtx (XFmode);
21180 rtx op1 = gen_reg_rtx (XFmode);
21181
21182 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21183 emit_insn (gen_<sincos>xf2 (op0, op1));
21184 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21185 DONE;
21186 })
21187
21188 (define_insn "sincosxf3"
21189 [(set (match_operand:XF 0 "register_operand" "=f")
21190 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21191 UNSPEC_SINCOS_COS))
21192 (set (match_operand:XF 1 "register_operand" "=f")
21193 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
21194 "TARGET_USE_FANCY_MATH_387
21195 && flag_unsafe_math_optimizations"
21196 "fsincos"
21197 [(set_attr "type" "fpspc")
21198 (set_attr "znver1_decode" "vector")
21199 (set_attr "mode" "XF")])
21200
21201 (define_expand "sincos<mode>3"
21202 [(use (match_operand:MODEF 0 "register_operand"))
21203 (use (match_operand:MODEF 1 "register_operand"))
21204 (use (match_operand:MODEF 2 "general_operand"))]
21205 "TARGET_USE_FANCY_MATH_387
21206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21207 || TARGET_MIX_SSE_I387)
21208 && flag_unsafe_math_optimizations"
21209 {
21210 rtx op0 = gen_reg_rtx (XFmode);
21211 rtx op1 = gen_reg_rtx (XFmode);
21212 rtx op2 = gen_reg_rtx (XFmode);
21213
21214 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21215 emit_insn (gen_sincosxf3 (op0, op1, op2));
21216 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21217 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
21218 DONE;
21219 })
21220
21221 (define_insn "fptanxf4_i387"
21222 [(set (match_operand:SF 0 "register_operand" "=f")
21223 (match_operand:SF 3 "const1_operand"))
21224 (set (match_operand:XF 1 "register_operand" "=f")
21225 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21226 UNSPEC_TAN))]
21227 "TARGET_USE_FANCY_MATH_387
21228 && flag_unsafe_math_optimizations"
21229 "fptan"
21230 [(set_attr "type" "fpspc")
21231 (set_attr "znver1_decode" "vector")
21232 (set_attr "mode" "XF")])
21233
21234 (define_expand "tanxf2"
21235 [(use (match_operand:XF 0 "register_operand"))
21236 (use (match_operand:XF 1 "register_operand"))]
21237 "TARGET_USE_FANCY_MATH_387
21238 && flag_unsafe_math_optimizations"
21239 {
21240 rtx one = gen_reg_rtx (SFmode);
21241 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
21242 CONST1_RTX (SFmode)));
21243 DONE;
21244 })
21245
21246 (define_expand "tan<mode>2"
21247 [(use (match_operand:MODEF 0 "register_operand"))
21248 (use (match_operand:MODEF 1 "general_operand"))]
21249 "TARGET_USE_FANCY_MATH_387
21250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21251 || TARGET_MIX_SSE_I387)
21252 && flag_unsafe_math_optimizations"
21253 {
21254 rtx op0 = gen_reg_rtx (XFmode);
21255 rtx op1 = gen_reg_rtx (XFmode);
21256
21257 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21258 emit_insn (gen_tanxf2 (op0, op1));
21259 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21260 DONE;
21261 })
21262
21263 (define_insn "atan2xf3"
21264 [(set (match_operand:XF 0 "register_operand" "=f")
21265 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21266 (match_operand:XF 1 "register_operand" "f")]
21267 UNSPEC_FPATAN))
21268 (clobber (match_scratch:XF 3 "=1"))]
21269 "TARGET_USE_FANCY_MATH_387
21270 && flag_unsafe_math_optimizations"
21271 "fpatan"
21272 [(set_attr "type" "fpspc")
21273 (set_attr "znver1_decode" "vector")
21274 (set_attr "mode" "XF")])
21275
21276 (define_expand "atan2<mode>3"
21277 [(use (match_operand:MODEF 0 "register_operand"))
21278 (use (match_operand:MODEF 1 "general_operand"))
21279 (use (match_operand:MODEF 2 "general_operand"))]
21280 "TARGET_USE_FANCY_MATH_387
21281 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21282 || TARGET_MIX_SSE_I387)
21283 && flag_unsafe_math_optimizations"
21284 {
21285 rtx op0 = gen_reg_rtx (XFmode);
21286 rtx op1 = gen_reg_rtx (XFmode);
21287 rtx op2 = gen_reg_rtx (XFmode);
21288
21289 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21290 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21291
21292 emit_insn (gen_atan2xf3 (op0, op1, op2));
21293 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21294 DONE;
21295 })
21296
21297 (define_expand "atanxf2"
21298 [(parallel [(set (match_operand:XF 0 "register_operand")
21299 (unspec:XF [(match_dup 2)
21300 (match_operand:XF 1 "register_operand")]
21301 UNSPEC_FPATAN))
21302 (clobber (scratch:XF))])]
21303 "TARGET_USE_FANCY_MATH_387
21304 && flag_unsafe_math_optimizations"
21305 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21306
21307 (define_expand "atan<mode>2"
21308 [(use (match_operand:MODEF 0 "register_operand"))
21309 (use (match_operand:MODEF 1 "general_operand"))]
21310 "TARGET_USE_FANCY_MATH_387
21311 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21312 || TARGET_MIX_SSE_I387)
21313 && flag_unsafe_math_optimizations"
21314 {
21315 rtx op0 = gen_reg_rtx (XFmode);
21316 rtx op1 = gen_reg_rtx (XFmode);
21317
21318 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21319 emit_insn (gen_atanxf2 (op0, op1));
21320 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21321 DONE;
21322 })
21323
21324 (define_expand "asinxf2"
21325 [(set (match_dup 2)
21326 (mult:XF (match_operand:XF 1 "register_operand")
21327 (match_dup 1)))
21328 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21329 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21330 (parallel [(set (match_operand:XF 0 "register_operand")
21331 (unspec:XF [(match_dup 5) (match_dup 1)]
21332 UNSPEC_FPATAN))
21333 (clobber (scratch:XF))])]
21334 "TARGET_USE_FANCY_MATH_387
21335 && flag_unsafe_math_optimizations"
21336 {
21337 int i;
21338
21339 for (i = 2; i < 6; i++)
21340 operands[i] = gen_reg_rtx (XFmode);
21341
21342 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21343 })
21344
21345 (define_expand "asin<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_asinxf2 (op0, op1));
21358 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21359 DONE;
21360 })
21361
21362 (define_expand "acosxf2"
21363 [(set (match_dup 2)
21364 (mult:XF (match_operand:XF 1 "register_operand")
21365 (match_dup 1)))
21366 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
21367 (set (match_dup 5) (sqrt:XF (match_dup 4)))
21368 (parallel [(set (match_operand:XF 0 "register_operand")
21369 (unspec:XF [(match_dup 1) (match_dup 5)]
21370 UNSPEC_FPATAN))
21371 (clobber (scratch:XF))])]
21372 "TARGET_USE_FANCY_MATH_387
21373 && flag_unsafe_math_optimizations"
21374 {
21375 int i;
21376
21377 for (i = 2; i < 6; i++)
21378 operands[i] = gen_reg_rtx (XFmode);
21379
21380 emit_move_insn (operands[3], CONST1_RTX (XFmode));
21381 })
21382
21383 (define_expand "acos<mode>2"
21384 [(use (match_operand:MODEF 0 "register_operand"))
21385 (use (match_operand:MODEF 1 "general_operand"))]
21386 "TARGET_USE_FANCY_MATH_387
21387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21388 || TARGET_MIX_SSE_I387)
21389 && flag_unsafe_math_optimizations"
21390 {
21391 rtx op0 = gen_reg_rtx (XFmode);
21392 rtx op1 = gen_reg_rtx (XFmode);
21393
21394 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21395 emit_insn (gen_acosxf2 (op0, op1));
21396 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21397 DONE;
21398 })
21399
21400 (define_expand "sinhxf2"
21401 [(use (match_operand:XF 0 "register_operand"))
21402 (use (match_operand:XF 1 "register_operand"))]
21403 "TARGET_USE_FANCY_MATH_387
21404 && flag_finite_math_only
21405 && flag_unsafe_math_optimizations"
21406 {
21407 ix86_emit_i387_sinh (operands[0], operands[1]);
21408 DONE;
21409 })
21410
21411 (define_expand "sinh<mode>2"
21412 [(use (match_operand:MODEF 0 "register_operand"))
21413 (use (match_operand:MODEF 1 "general_operand"))]
21414 "TARGET_USE_FANCY_MATH_387
21415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21416 || TARGET_MIX_SSE_I387)
21417 && flag_finite_math_only
21418 && flag_unsafe_math_optimizations"
21419 {
21420 rtx op0 = gen_reg_rtx (XFmode);
21421 rtx op1 = gen_reg_rtx (XFmode);
21422
21423 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21424 emit_insn (gen_sinhxf2 (op0, op1));
21425 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21426 DONE;
21427 })
21428
21429 (define_expand "coshxf2"
21430 [(use (match_operand:XF 0 "register_operand"))
21431 (use (match_operand:XF 1 "register_operand"))]
21432 "TARGET_USE_FANCY_MATH_387
21433 && flag_unsafe_math_optimizations"
21434 {
21435 ix86_emit_i387_cosh (operands[0], operands[1]);
21436 DONE;
21437 })
21438
21439 (define_expand "cosh<mode>2"
21440 [(use (match_operand:MODEF 0 "register_operand"))
21441 (use (match_operand:MODEF 1 "general_operand"))]
21442 "TARGET_USE_FANCY_MATH_387
21443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21444 || TARGET_MIX_SSE_I387)
21445 && flag_unsafe_math_optimizations"
21446 {
21447 rtx op0 = gen_reg_rtx (XFmode);
21448 rtx op1 = gen_reg_rtx (XFmode);
21449
21450 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21451 emit_insn (gen_coshxf2 (op0, op1));
21452 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21453 DONE;
21454 })
21455
21456 (define_expand "tanhxf2"
21457 [(use (match_operand:XF 0 "register_operand"))
21458 (use (match_operand:XF 1 "register_operand"))]
21459 "TARGET_USE_FANCY_MATH_387
21460 && flag_unsafe_math_optimizations"
21461 {
21462 ix86_emit_i387_tanh (operands[0], operands[1]);
21463 DONE;
21464 })
21465
21466 (define_expand "tanh<mode>2"
21467 [(use (match_operand:MODEF 0 "register_operand"))
21468 (use (match_operand:MODEF 1 "general_operand"))]
21469 "TARGET_USE_FANCY_MATH_387
21470 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21471 || TARGET_MIX_SSE_I387)
21472 && flag_unsafe_math_optimizations"
21473 {
21474 rtx op0 = gen_reg_rtx (XFmode);
21475 rtx op1 = gen_reg_rtx (XFmode);
21476
21477 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21478 emit_insn (gen_tanhxf2 (op0, op1));
21479 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21480 DONE;
21481 })
21482
21483 (define_expand "asinhxf2"
21484 [(use (match_operand:XF 0 "register_operand"))
21485 (use (match_operand:XF 1 "register_operand"))]
21486 "TARGET_USE_FANCY_MATH_387
21487 && flag_finite_math_only
21488 && flag_unsafe_math_optimizations"
21489 {
21490 ix86_emit_i387_asinh (operands[0], operands[1]);
21491 DONE;
21492 })
21493
21494 (define_expand "asinh<mode>2"
21495 [(use (match_operand:MODEF 0 "register_operand"))
21496 (use (match_operand:MODEF 1 "general_operand"))]
21497 "TARGET_USE_FANCY_MATH_387
21498 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21499 || TARGET_MIX_SSE_I387)
21500 && flag_finite_math_only
21501 && flag_unsafe_math_optimizations"
21502 {
21503 rtx op0 = gen_reg_rtx (XFmode);
21504 rtx op1 = gen_reg_rtx (XFmode);
21505
21506 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21507 emit_insn (gen_asinhxf2 (op0, op1));
21508 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21509 DONE;
21510 })
21511
21512 (define_expand "acoshxf2"
21513 [(use (match_operand:XF 0 "register_operand"))
21514 (use (match_operand:XF 1 "register_operand"))]
21515 "TARGET_USE_FANCY_MATH_387
21516 && flag_unsafe_math_optimizations"
21517 {
21518 ix86_emit_i387_acosh (operands[0], operands[1]);
21519 DONE;
21520 })
21521
21522 (define_expand "acosh<mode>2"
21523 [(use (match_operand:MODEF 0 "register_operand"))
21524 (use (match_operand:MODEF 1 "general_operand"))]
21525 "TARGET_USE_FANCY_MATH_387
21526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21527 || TARGET_MIX_SSE_I387)
21528 && flag_unsafe_math_optimizations"
21529 {
21530 rtx op0 = gen_reg_rtx (XFmode);
21531 rtx op1 = gen_reg_rtx (XFmode);
21532
21533 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21534 emit_insn (gen_acoshxf2 (op0, op1));
21535 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21536 DONE;
21537 })
21538
21539 (define_expand "atanhxf2"
21540 [(use (match_operand:XF 0 "register_operand"))
21541 (use (match_operand:XF 1 "register_operand"))]
21542 "TARGET_USE_FANCY_MATH_387
21543 && flag_unsafe_math_optimizations"
21544 {
21545 ix86_emit_i387_atanh (operands[0], operands[1]);
21546 DONE;
21547 })
21548
21549 (define_expand "atanh<mode>2"
21550 [(use (match_operand:MODEF 0 "register_operand"))
21551 (use (match_operand:MODEF 1 "general_operand"))]
21552 "TARGET_USE_FANCY_MATH_387
21553 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21554 || TARGET_MIX_SSE_I387)
21555 && flag_unsafe_math_optimizations"
21556 {
21557 rtx op0 = gen_reg_rtx (XFmode);
21558 rtx op1 = gen_reg_rtx (XFmode);
21559
21560 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21561 emit_insn (gen_atanhxf2 (op0, op1));
21562 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21563 DONE;
21564 })
21565
21566 (define_insn "fyl2xxf3_i387"
21567 [(set (match_operand:XF 0 "register_operand" "=f")
21568 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21569 (match_operand:XF 2 "register_operand" "f")]
21570 UNSPEC_FYL2X))
21571 (clobber (match_scratch:XF 3 "=2"))]
21572 "TARGET_USE_FANCY_MATH_387
21573 && flag_unsafe_math_optimizations"
21574 "fyl2x"
21575 [(set_attr "type" "fpspc")
21576 (set_attr "znver1_decode" "vector")
21577 (set_attr "mode" "XF")])
21578
21579 (define_expand "logxf2"
21580 [(parallel [(set (match_operand:XF 0 "register_operand")
21581 (unspec:XF [(match_operand:XF 1 "register_operand")
21582 (match_dup 2)] UNSPEC_FYL2X))
21583 (clobber (scratch:XF))])]
21584 "TARGET_USE_FANCY_MATH_387
21585 && flag_unsafe_math_optimizations"
21586 {
21587 operands[2]
21588 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21589 })
21590
21591 (define_expand "log<mode>2"
21592 [(use (match_operand:MODEF 0 "register_operand"))
21593 (use (match_operand:MODEF 1 "general_operand"))]
21594 "TARGET_USE_FANCY_MATH_387
21595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21596 || TARGET_MIX_SSE_I387)
21597 && flag_unsafe_math_optimizations"
21598 {
21599 rtx op0 = gen_reg_rtx (XFmode);
21600 rtx op1 = gen_reg_rtx (XFmode);
21601
21602 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21603 emit_insn (gen_logxf2 (op0, op1));
21604 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21605 DONE;
21606 })
21607
21608 (define_expand "log10xf2"
21609 [(parallel [(set (match_operand:XF 0 "register_operand")
21610 (unspec:XF [(match_operand:XF 1 "register_operand")
21611 (match_dup 2)] UNSPEC_FYL2X))
21612 (clobber (scratch:XF))])]
21613 "TARGET_USE_FANCY_MATH_387
21614 && flag_unsafe_math_optimizations"
21615 {
21616 operands[2]
21617 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21618 })
21619
21620 (define_expand "log10<mode>2"
21621 [(use (match_operand:MODEF 0 "register_operand"))
21622 (use (match_operand:MODEF 1 "general_operand"))]
21623 "TARGET_USE_FANCY_MATH_387
21624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21625 || TARGET_MIX_SSE_I387)
21626 && flag_unsafe_math_optimizations"
21627 {
21628 rtx op0 = gen_reg_rtx (XFmode);
21629 rtx op1 = gen_reg_rtx (XFmode);
21630
21631 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21632 emit_insn (gen_log10xf2 (op0, op1));
21633 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21634 DONE;
21635 })
21636
21637 (define_expand "log2xf2"
21638 [(parallel [(set (match_operand:XF 0 "register_operand")
21639 (unspec:XF [(match_operand:XF 1 "register_operand")
21640 (match_dup 2)] UNSPEC_FYL2X))
21641 (clobber (scratch:XF))])]
21642 "TARGET_USE_FANCY_MATH_387
21643 && flag_unsafe_math_optimizations"
21644 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21645
21646 (define_expand "log2<mode>2"
21647 [(use (match_operand:MODEF 0 "register_operand"))
21648 (use (match_operand:MODEF 1 "general_operand"))]
21649 "TARGET_USE_FANCY_MATH_387
21650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21651 || TARGET_MIX_SSE_I387)
21652 && flag_unsafe_math_optimizations"
21653 {
21654 rtx op0 = gen_reg_rtx (XFmode);
21655 rtx op1 = gen_reg_rtx (XFmode);
21656
21657 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21658 emit_insn (gen_log2xf2 (op0, op1));
21659 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21660 DONE;
21661 })
21662
21663 (define_insn "fyl2xp1xf3_i387"
21664 [(set (match_operand:XF 0 "register_operand" "=f")
21665 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21666 (match_operand:XF 2 "register_operand" "f")]
21667 UNSPEC_FYL2XP1))
21668 (clobber (match_scratch:XF 3 "=2"))]
21669 "TARGET_USE_FANCY_MATH_387
21670 && flag_unsafe_math_optimizations"
21671 "fyl2xp1"
21672 [(set_attr "type" "fpspc")
21673 (set_attr "znver1_decode" "vector")
21674 (set_attr "mode" "XF")])
21675
21676 (define_expand "log1pxf2"
21677 [(use (match_operand:XF 0 "register_operand"))
21678 (use (match_operand:XF 1 "register_operand"))]
21679 "TARGET_USE_FANCY_MATH_387
21680 && flag_unsafe_math_optimizations"
21681 {
21682 ix86_emit_i387_log1p (operands[0], operands[1]);
21683 DONE;
21684 })
21685
21686 (define_expand "log1p<mode>2"
21687 [(use (match_operand:MODEF 0 "register_operand"))
21688 (use (match_operand:MODEF 1 "general_operand"))]
21689 "TARGET_USE_FANCY_MATH_387
21690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21691 || TARGET_MIX_SSE_I387)
21692 && flag_unsafe_math_optimizations"
21693 {
21694 rtx op0 = gen_reg_rtx (XFmode);
21695 rtx op1 = gen_reg_rtx (XFmode);
21696
21697 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21698 emit_insn (gen_log1pxf2 (op0, op1));
21699 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21700 DONE;
21701 })
21702
21703 (define_insn "fxtractxf3_i387"
21704 [(set (match_operand:XF 0 "register_operand" "=f")
21705 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21706 UNSPEC_XTRACT_FRACT))
21707 (set (match_operand:XF 1 "register_operand" "=f")
21708 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21709 "TARGET_USE_FANCY_MATH_387
21710 && flag_unsafe_math_optimizations"
21711 "fxtract"
21712 [(set_attr "type" "fpspc")
21713 (set_attr "znver1_decode" "vector")
21714 (set_attr "mode" "XF")])
21715
21716 (define_expand "logbxf2"
21717 [(parallel [(set (match_dup 2)
21718 (unspec:XF [(match_operand:XF 1 "register_operand")]
21719 UNSPEC_XTRACT_FRACT))
21720 (set (match_operand:XF 0 "register_operand")
21721 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21722 "TARGET_USE_FANCY_MATH_387
21723 && flag_unsafe_math_optimizations"
21724 "operands[2] = gen_reg_rtx (XFmode);")
21725
21726 (define_expand "logb<mode>2"
21727 [(use (match_operand:MODEF 0 "register_operand"))
21728 (use (match_operand:MODEF 1 "general_operand"))]
21729 "TARGET_USE_FANCY_MATH_387
21730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21731 || TARGET_MIX_SSE_I387)
21732 && flag_unsafe_math_optimizations"
21733 {
21734 rtx op0 = gen_reg_rtx (XFmode);
21735 rtx op1 = gen_reg_rtx (XFmode);
21736
21737 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21738 emit_insn (gen_logbxf2 (op0, op1));
21739 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21740 DONE;
21741 })
21742
21743 (define_expand "ilogbxf2"
21744 [(use (match_operand:SI 0 "register_operand"))
21745 (use (match_operand:XF 1 "register_operand"))]
21746 "TARGET_USE_FANCY_MATH_387
21747 && flag_unsafe_math_optimizations"
21748 {
21749 rtx op0, op1;
21750
21751 if (optimize_insn_for_size_p ())
21752 FAIL;
21753
21754 op0 = gen_reg_rtx (XFmode);
21755 op1 = gen_reg_rtx (XFmode);
21756
21757 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21758 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21759 DONE;
21760 })
21761
21762 (define_expand "ilogb<mode>2"
21763 [(use (match_operand:SI 0 "register_operand"))
21764 (use (match_operand:MODEF 1 "general_operand"))]
21765 "TARGET_USE_FANCY_MATH_387
21766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21767 || TARGET_MIX_SSE_I387)
21768 && flag_unsafe_math_optimizations"
21769 {
21770 rtx op0, op1, op2;
21771
21772 if (optimize_insn_for_size_p ())
21773 FAIL;
21774
21775 op0 = gen_reg_rtx (XFmode);
21776 op1 = gen_reg_rtx (XFmode);
21777 op2 = gen_reg_rtx (XFmode);
21778
21779 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21780 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21781 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21782 DONE;
21783 })
21784
21785 (define_insn "*f2xm1xf2_i387"
21786 [(set (match_operand:XF 0 "register_operand" "=f")
21787 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21788 UNSPEC_F2XM1))]
21789 "TARGET_USE_FANCY_MATH_387
21790 && flag_unsafe_math_optimizations"
21791 "f2xm1"
21792 [(set_attr "type" "fpspc")
21793 (set_attr "znver1_decode" "vector")
21794 (set_attr "mode" "XF")])
21795
21796 (define_insn "fscalexf4_i387"
21797 [(set (match_operand:XF 0 "register_operand" "=f")
21798 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21799 (match_operand:XF 3 "register_operand" "1")]
21800 UNSPEC_FSCALE_FRACT))
21801 (set (match_operand:XF 1 "register_operand" "=f")
21802 (unspec:XF [(match_dup 2) (match_dup 3)]
21803 UNSPEC_FSCALE_EXP))]
21804 "TARGET_USE_FANCY_MATH_387
21805 && flag_unsafe_math_optimizations"
21806 "fscale"
21807 [(set_attr "type" "fpspc")
21808 (set_attr "znver1_decode" "vector")
21809 (set_attr "mode" "XF")])
21810
21811 (define_expand "expNcorexf3"
21812 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21813 (match_operand:XF 2 "register_operand")))
21814 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21815 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21816 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21817 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21818 (parallel [(set (match_operand:XF 0 "register_operand")
21819 (unspec:XF [(match_dup 8) (match_dup 4)]
21820 UNSPEC_FSCALE_FRACT))
21821 (set (match_dup 9)
21822 (unspec:XF [(match_dup 8) (match_dup 4)]
21823 UNSPEC_FSCALE_EXP))])]
21824 "TARGET_USE_FANCY_MATH_387
21825 && flag_unsafe_math_optimizations"
21826 {
21827 int i;
21828
21829 for (i = 3; i < 10; i++)
21830 operands[i] = gen_reg_rtx (XFmode);
21831
21832 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21833 })
21834
21835 (define_expand "expxf2"
21836 [(use (match_operand:XF 0 "register_operand"))
21837 (use (match_operand:XF 1 "register_operand"))]
21838 "TARGET_USE_FANCY_MATH_387
21839 && flag_unsafe_math_optimizations"
21840 {
21841 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21842
21843 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21844 DONE;
21845 })
21846
21847 (define_expand "exp<mode>2"
21848 [(use (match_operand:MODEF 0 "register_operand"))
21849 (use (match_operand:MODEF 1 "general_operand"))]
21850 "TARGET_USE_FANCY_MATH_387
21851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21852 || TARGET_MIX_SSE_I387)
21853 && flag_unsafe_math_optimizations"
21854 {
21855 rtx op0 = gen_reg_rtx (XFmode);
21856 rtx op1 = gen_reg_rtx (XFmode);
21857
21858 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21859 emit_insn (gen_expxf2 (op0, op1));
21860 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21861 DONE;
21862 })
21863
21864 (define_expand "exp10xf2"
21865 [(use (match_operand:XF 0 "register_operand"))
21866 (use (match_operand:XF 1 "register_operand"))]
21867 "TARGET_USE_FANCY_MATH_387
21868 && flag_unsafe_math_optimizations"
21869 {
21870 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21871
21872 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21873 DONE;
21874 })
21875
21876 (define_expand "exp10<mode>2"
21877 [(use (match_operand:MODEF 0 "register_operand"))
21878 (use (match_operand:MODEF 1 "general_operand"))]
21879 "TARGET_USE_FANCY_MATH_387
21880 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21881 || TARGET_MIX_SSE_I387)
21882 && flag_unsafe_math_optimizations"
21883 {
21884 rtx op0 = gen_reg_rtx (XFmode);
21885 rtx op1 = gen_reg_rtx (XFmode);
21886
21887 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21888 emit_insn (gen_exp10xf2 (op0, op1));
21889 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21890 DONE;
21891 })
21892
21893 (define_expand "exp2xf2"
21894 [(use (match_operand:XF 0 "register_operand"))
21895 (use (match_operand:XF 1 "register_operand"))]
21896 "TARGET_USE_FANCY_MATH_387
21897 && flag_unsafe_math_optimizations"
21898 {
21899 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21900
21901 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21902 DONE;
21903 })
21904
21905 (define_expand "exp2<mode>2"
21906 [(use (match_operand:MODEF 0 "register_operand"))
21907 (use (match_operand:MODEF 1 "general_operand"))]
21908 "TARGET_USE_FANCY_MATH_387
21909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21910 || TARGET_MIX_SSE_I387)
21911 && flag_unsafe_math_optimizations"
21912 {
21913 rtx op0 = gen_reg_rtx (XFmode);
21914 rtx op1 = gen_reg_rtx (XFmode);
21915
21916 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21917 emit_insn (gen_exp2xf2 (op0, op1));
21918 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21919 DONE;
21920 })
21921
21922 (define_expand "expm1xf2"
21923 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21924 (match_dup 2)))
21925 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21926 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21927 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21928 (parallel [(set (match_dup 7)
21929 (unspec:XF [(match_dup 6) (match_dup 4)]
21930 UNSPEC_FSCALE_FRACT))
21931 (set (match_dup 8)
21932 (unspec:XF [(match_dup 6) (match_dup 4)]
21933 UNSPEC_FSCALE_EXP))])
21934 (parallel [(set (match_dup 10)
21935 (unspec:XF [(match_dup 9) (match_dup 8)]
21936 UNSPEC_FSCALE_FRACT))
21937 (set (match_dup 11)
21938 (unspec:XF [(match_dup 9) (match_dup 8)]
21939 UNSPEC_FSCALE_EXP))])
21940 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21941 (set (match_operand:XF 0 "register_operand")
21942 (plus:XF (match_dup 12) (match_dup 7)))]
21943 "TARGET_USE_FANCY_MATH_387
21944 && flag_unsafe_math_optimizations"
21945 {
21946 int i;
21947
21948 for (i = 2; i < 13; i++)
21949 operands[i] = gen_reg_rtx (XFmode);
21950
21951 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21952 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21953 })
21954
21955 (define_expand "expm1<mode>2"
21956 [(use (match_operand:MODEF 0 "register_operand"))
21957 (use (match_operand:MODEF 1 "general_operand"))]
21958 "TARGET_USE_FANCY_MATH_387
21959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21960 || TARGET_MIX_SSE_I387)
21961 && flag_unsafe_math_optimizations"
21962 {
21963 rtx op0 = gen_reg_rtx (XFmode);
21964 rtx op1 = gen_reg_rtx (XFmode);
21965
21966 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21967 emit_insn (gen_expm1xf2 (op0, op1));
21968 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21969 DONE;
21970 })
21971
21972 (define_insn "avx512f_scalef<mode>2"
21973 [(set (match_operand:MODEF 0 "register_operand" "=v")
21974 (unspec:MODEF
21975 [(match_operand:MODEF 1 "register_operand" "v")
21976 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21977 UNSPEC_SCALEF))]
21978 "TARGET_AVX512F"
21979 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21980 [(set_attr "prefix" "evex")
21981 (set_attr "mode" "<MODE>")])
21982
21983 (define_expand "ldexpxf3"
21984 [(match_operand:XF 0 "register_operand")
21985 (match_operand:XF 1 "register_operand")
21986 (match_operand:SI 2 "register_operand")]
21987 "TARGET_USE_FANCY_MATH_387
21988 && flag_unsafe_math_optimizations"
21989 {
21990 rtx tmp1 = gen_reg_rtx (XFmode);
21991 rtx tmp2 = gen_reg_rtx (XFmode);
21992
21993 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21994 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21995 operands[1], tmp1));
21996 DONE;
21997 })
21998
21999 (define_expand "ldexp<mode>3"
22000 [(use (match_operand:MODEF 0 "register_operand"))
22001 (use (match_operand:MODEF 1 "general_operand"))
22002 (use (match_operand:SI 2 "register_operand"))]
22003 "((TARGET_USE_FANCY_MATH_387
22004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22005 || TARGET_MIX_SSE_I387))
22006 || (TARGET_AVX512F && TARGET_SSE_MATH))
22007 && flag_unsafe_math_optimizations"
22008 {
22009 /* Prefer avx512f version. */
22010 if (TARGET_AVX512F && TARGET_SSE_MATH)
22011 {
22012 rtx op2 = gen_reg_rtx (<MODE>mode);
22013 operands[1] = force_reg (<MODE>mode, operands[1]);
22014
22015 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
22016 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
22017 }
22018 else
22019 {
22020 rtx op0 = gen_reg_rtx (XFmode);
22021 rtx op1 = gen_reg_rtx (XFmode);
22022
22023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22024 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
22025 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22026 }
22027 DONE;
22028 })
22029
22030 (define_expand "scalbxf3"
22031 [(parallel [(set (match_operand:XF 0 " register_operand")
22032 (unspec:XF [(match_operand:XF 1 "register_operand")
22033 (match_operand:XF 2 "register_operand")]
22034 UNSPEC_FSCALE_FRACT))
22035 (set (match_dup 3)
22036 (unspec:XF [(match_dup 1) (match_dup 2)]
22037 UNSPEC_FSCALE_EXP))])]
22038 "TARGET_USE_FANCY_MATH_387
22039 && flag_unsafe_math_optimizations"
22040 "operands[3] = gen_reg_rtx (XFmode);")
22041
22042 (define_expand "scalb<mode>3"
22043 [(use (match_operand:MODEF 0 "register_operand"))
22044 (use (match_operand:MODEF 1 "general_operand"))
22045 (use (match_operand:MODEF 2 "general_operand"))]
22046 "TARGET_USE_FANCY_MATH_387
22047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22048 || TARGET_MIX_SSE_I387)
22049 && flag_unsafe_math_optimizations"
22050 {
22051 rtx op0 = gen_reg_rtx (XFmode);
22052 rtx op1 = gen_reg_rtx (XFmode);
22053 rtx op2 = gen_reg_rtx (XFmode);
22054
22055 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22056 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
22057 emit_insn (gen_scalbxf3 (op0, op1, op2));
22058 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22059 DONE;
22060 })
22061
22062 (define_expand "significandxf2"
22063 [(parallel [(set (match_operand:XF 0 "register_operand")
22064 (unspec:XF [(match_operand:XF 1 "register_operand")]
22065 UNSPEC_XTRACT_FRACT))
22066 (set (match_dup 2)
22067 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
22068 "TARGET_USE_FANCY_MATH_387
22069 && flag_unsafe_math_optimizations"
22070 "operands[2] = gen_reg_rtx (XFmode);")
22071
22072 (define_expand "significand<mode>2"
22073 [(use (match_operand:MODEF 0 "register_operand"))
22074 (use (match_operand:MODEF 1 "general_operand"))]
22075 "TARGET_USE_FANCY_MATH_387
22076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22077 || TARGET_MIX_SSE_I387)
22078 && flag_unsafe_math_optimizations"
22079 {
22080 rtx op0 = gen_reg_rtx (XFmode);
22081 rtx op1 = gen_reg_rtx (XFmode);
22082
22083 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22084 emit_insn (gen_significandxf2 (op0, op1));
22085 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
22086 DONE;
22087 })
22088 \f
22089
22090 (define_insn "sse4_1_round<mode>2"
22091 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
22092 (unspec:MODEFH
22093 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,jm,v,m")
22094 (match_operand:SI 2 "const_0_to_15_operand")]
22095 UNSPEC_ROUND))]
22096 "TARGET_SSE4_1"
22097 "@
22098 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
22099 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
22100 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
22101 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
22102 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
22103 [(set_attr "type" "ssecvt")
22104 (set_attr "prefix_extra" "1,1,1,*,*")
22105 (set_attr "length_immediate" "1")
22106 (set_attr "addr" "*,*,gpr16,*,*")
22107 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
22108 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
22109 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
22110 (set_attr "mode" "<MODE>")
22111 (set (attr "preferred_for_speed")
22112 (cond [(match_test "TARGET_AVX")
22113 (symbol_ref "true")
22114 (eq_attr "alternative" "1,2")
22115 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
22116 ]
22117 (symbol_ref "true")))])
22118
22119 (define_insn "rintxf2"
22120 [(set (match_operand:XF 0 "register_operand" "=f")
22121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22122 UNSPEC_FRNDINT))]
22123 "TARGET_USE_FANCY_MATH_387"
22124 "frndint"
22125 [(set_attr "type" "fpspc")
22126 (set_attr "znver1_decode" "vector")
22127 (set_attr "mode" "XF")])
22128
22129 (define_expand "rinthf2"
22130 [(match_operand:HF 0 "register_operand")
22131 (match_operand:HF 1 "nonimmediate_operand")]
22132 "TARGET_AVX512FP16"
22133 {
22134 emit_insn (gen_sse4_1_roundhf2 (operands[0],
22135 operands[1],
22136 GEN_INT (ROUND_MXCSR)));
22137 DONE;
22138 })
22139
22140 (define_expand "rint<mode>2"
22141 [(use (match_operand:MODEF 0 "register_operand"))
22142 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
22143 "TARGET_USE_FANCY_MATH_387
22144 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
22145 {
22146 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22147 {
22148 if (TARGET_SSE4_1)
22149 emit_insn (gen_sse4_1_round<mode>2
22150 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
22151 else
22152 ix86_expand_rint (operands[0], operands[1]);
22153 }
22154 else
22155 {
22156 rtx op0 = gen_reg_rtx (XFmode);
22157 rtx op1 = gen_reg_rtx (XFmode);
22158
22159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22160 emit_insn (gen_rintxf2 (op0, op1));
22161 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22162 }
22163 DONE;
22164 })
22165
22166 (define_expand "nearbyintxf2"
22167 [(set (match_operand:XF 0 "register_operand")
22168 (unspec:XF [(match_operand:XF 1 "register_operand")]
22169 UNSPEC_FRNDINT))]
22170 "TARGET_USE_FANCY_MATH_387
22171 && !flag_trapping_math")
22172
22173 (define_expand "nearbyinthf2"
22174 [(match_operand:HF 0 "register_operand")
22175 (match_operand:HF 1 "nonimmediate_operand")]
22176 "TARGET_AVX512FP16"
22177 {
22178 emit_insn (gen_sse4_1_roundhf2 (operands[0],
22179 operands[1],
22180 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
22181 DONE;
22182 })
22183
22184 (define_expand "nearbyint<mode>2"
22185 [(use (match_operand:MODEF 0 "register_operand"))
22186 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
22187 "(TARGET_USE_FANCY_MATH_387
22188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22189 || TARGET_MIX_SSE_I387)
22190 && !flag_trapping_math)
22191 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
22192 {
22193 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
22194 emit_insn (gen_sse4_1_round<mode>2
22195 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
22196 | ROUND_NO_EXC)));
22197 else
22198 {
22199 rtx op0 = gen_reg_rtx (XFmode);
22200 rtx op1 = gen_reg_rtx (XFmode);
22201
22202 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22203 emit_insn (gen_nearbyintxf2 (op0, op1));
22204 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22205 }
22206 DONE;
22207 })
22208
22209 (define_expand "roundhf2"
22210 [(match_operand:HF 0 "register_operand")
22211 (match_operand:HF 1 "register_operand")]
22212 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22213 {
22214 ix86_expand_round_sse4 (operands[0], operands[1]);
22215 DONE;
22216 })
22217
22218 (define_expand "round<mode>2"
22219 [(match_operand:X87MODEF 0 "register_operand")
22220 (match_operand:X87MODEF 1 "nonimmediate_operand")]
22221 "(TARGET_USE_FANCY_MATH_387
22222 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22223 || TARGET_MIX_SSE_I387)
22224 && flag_unsafe_math_optimizations
22225 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22226 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22227 && !flag_trapping_math && !flag_rounding_math)"
22228 {
22229 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22230 && !flag_trapping_math && !flag_rounding_math)
22231 {
22232 if (TARGET_SSE4_1)
22233 {
22234 operands[1] = force_reg (<MODE>mode, operands[1]);
22235 ix86_expand_round_sse4 (operands[0], operands[1]);
22236 }
22237 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22238 ix86_expand_round (operands[0], operands[1]);
22239 else
22240 ix86_expand_rounddf_32 (operands[0], operands[1]);
22241 }
22242 else
22243 {
22244 operands[1] = force_reg (<MODE>mode, operands[1]);
22245 ix86_emit_i387_round (operands[0], operands[1]);
22246 }
22247 DONE;
22248 })
22249
22250 (define_insn "lrintxfdi2"
22251 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22252 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22253 UNSPEC_FIST))
22254 (clobber (match_scratch:XF 2 "=&f"))]
22255 "TARGET_USE_FANCY_MATH_387"
22256 "* return output_fix_trunc (insn, operands, false);"
22257 [(set_attr "type" "fpspc")
22258 (set_attr "mode" "DI")])
22259
22260 (define_insn "lrintxf<mode>2"
22261 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22262 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22263 UNSPEC_FIST))]
22264 "TARGET_USE_FANCY_MATH_387"
22265 "* return output_fix_trunc (insn, operands, false);"
22266 [(set_attr "type" "fpspc")
22267 (set_attr "mode" "<MODE>")])
22268
22269 (define_expand "lroundhf<mode>2"
22270 [(set (match_operand:SWI248 0 "register_operand")
22271 (unspec:SWI248 [(match_operand:HF 1 "nonimmediate_operand")]
22272 UNSPEC_FIX_NOTRUNC))]
22273 "TARGET_AVX512FP16 && !flag_trapping_math && !flag_rounding_math"
22274 {
22275 ix86_expand_lround (operands[0], operands[1]);
22276 DONE;
22277 })
22278
22279 (define_expand "lrinthf<mode>2"
22280 [(set (match_operand:SWI48 0 "register_operand")
22281 (unspec:SWI48 [(match_operand:HF 1 "nonimmediate_operand")]
22282 UNSPEC_FIX_NOTRUNC))]
22283 "TARGET_AVX512FP16")
22284
22285 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
22286 [(set (match_operand:SWI48 0 "register_operand")
22287 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
22288 UNSPEC_FIX_NOTRUNC))]
22289 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
22290
22291 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
22292 [(match_operand:SWI248x 0 "nonimmediate_operand")
22293 (match_operand:X87MODEF 1 "register_operand")]
22294 "(TARGET_USE_FANCY_MATH_387
22295 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
22296 || TARGET_MIX_SSE_I387)
22297 && flag_unsafe_math_optimizations)
22298 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22299 && <SWI248x:MODE>mode != HImode
22300 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22301 && !flag_trapping_math && !flag_rounding_math)"
22302 {
22303 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
22304 && <SWI248x:MODE>mode != HImode
22305 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
22306 && !flag_trapping_math && !flag_rounding_math)
22307 ix86_expand_lround (operands[0], operands[1]);
22308 else
22309 ix86_emit_i387_round (operands[0], operands[1]);
22310 DONE;
22311 })
22312
22313 (define_int_iterator FRNDINT_ROUNDING
22314 [UNSPEC_FRNDINT_ROUNDEVEN
22315 UNSPEC_FRNDINT_FLOOR
22316 UNSPEC_FRNDINT_CEIL
22317 UNSPEC_FRNDINT_TRUNC])
22318
22319 (define_int_iterator FIST_ROUNDING
22320 [UNSPEC_FIST_FLOOR
22321 UNSPEC_FIST_CEIL])
22322
22323 ;; Base name for define_insn
22324 (define_int_attr rounding_insn
22325 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22326 (UNSPEC_FRNDINT_FLOOR "floor")
22327 (UNSPEC_FRNDINT_CEIL "ceil")
22328 (UNSPEC_FRNDINT_TRUNC "btrunc")
22329 (UNSPEC_FIST_FLOOR "floor")
22330 (UNSPEC_FIST_CEIL "ceil")])
22331
22332 (define_int_attr rounding
22333 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
22334 (UNSPEC_FRNDINT_FLOOR "floor")
22335 (UNSPEC_FRNDINT_CEIL "ceil")
22336 (UNSPEC_FRNDINT_TRUNC "trunc")
22337 (UNSPEC_FIST_FLOOR "floor")
22338 (UNSPEC_FIST_CEIL "ceil")])
22339
22340 (define_int_attr ROUNDING
22341 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
22342 (UNSPEC_FRNDINT_FLOOR "FLOOR")
22343 (UNSPEC_FRNDINT_CEIL "CEIL")
22344 (UNSPEC_FRNDINT_TRUNC "TRUNC")
22345 (UNSPEC_FIST_FLOOR "FLOOR")
22346 (UNSPEC_FIST_CEIL "CEIL")])
22347
22348 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22349 (define_insn_and_split "frndintxf2_<rounding>"
22350 [(set (match_operand:XF 0 "register_operand")
22351 (unspec:XF [(match_operand:XF 1 "register_operand")]
22352 FRNDINT_ROUNDING))
22353 (clobber (reg:CC FLAGS_REG))]
22354 "TARGET_USE_FANCY_MATH_387
22355 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
22356 && ix86_pre_reload_split ()"
22357 "#"
22358 "&& 1"
22359 [(const_int 0)]
22360 {
22361 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22362
22363 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22364 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22365
22366 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
22367 operands[2], operands[3]));
22368 DONE;
22369 }
22370 [(set_attr "type" "frndint")
22371 (set_attr "i387_cw" "<rounding>")
22372 (set_attr "mode" "XF")])
22373
22374 (define_insn "frndintxf2_<rounding>_i387"
22375 [(set (match_operand:XF 0 "register_operand" "=f")
22376 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
22377 FRNDINT_ROUNDING))
22378 (use (match_operand:HI 2 "memory_operand" "m"))
22379 (use (match_operand:HI 3 "memory_operand" "m"))]
22380 "TARGET_USE_FANCY_MATH_387
22381 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
22382 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
22383 [(set_attr "type" "frndint")
22384 (set_attr "i387_cw" "<rounding>")
22385 (set_attr "mode" "XF")])
22386
22387 (define_expand "<rounding_insn>xf2"
22388 [(parallel [(set (match_operand:XF 0 "register_operand")
22389 (unspec:XF [(match_operand:XF 1 "register_operand")]
22390 FRNDINT_ROUNDING))
22391 (clobber (reg:CC FLAGS_REG))])]
22392 "TARGET_USE_FANCY_MATH_387
22393 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
22394
22395 (define_expand "<rounding_insn>hf2"
22396 [(parallel [(set (match_operand:HF 0 "register_operand")
22397 (unspec:HF [(match_operand:HF 1 "register_operand")]
22398 FRNDINT_ROUNDING))
22399 (clobber (reg:CC FLAGS_REG))])]
22400 "TARGET_AVX512FP16"
22401 {
22402 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
22403 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22404 DONE;
22405 })
22406
22407 (define_expand "<rounding_insn><mode>2"
22408 [(parallel [(set (match_operand:MODEF 0 "register_operand")
22409 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
22410 FRNDINT_ROUNDING))
22411 (clobber (reg:CC FLAGS_REG))])]
22412 "(TARGET_USE_FANCY_MATH_387
22413 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
22414 || TARGET_MIX_SSE_I387)
22415 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
22416 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22417 && (TARGET_SSE4_1
22418 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22419 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
22420 {
22421 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
22422 && (TARGET_SSE4_1
22423 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
22424 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
22425 {
22426 if (TARGET_SSE4_1)
22427 emit_insn (gen_sse4_1_round<mode>2
22428 (operands[0], operands[1],
22429 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22430 else if (TARGET_64BIT || (<MODE>mode != DFmode))
22431 {
22432 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22433 ix86_expand_floorceil (operands[0], operands[1], true);
22434 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22435 ix86_expand_floorceil (operands[0], operands[1], false);
22436 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22437 ix86_expand_trunc (operands[0], operands[1]);
22438 else
22439 gcc_unreachable ();
22440 }
22441 else
22442 {
22443 if (ROUND_<ROUNDING> == ROUND_FLOOR)
22444 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
22445 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22446 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
22447 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
22448 ix86_expand_truncdf_32 (operands[0], operands[1]);
22449 else
22450 gcc_unreachable ();
22451 }
22452 }
22453 else
22454 {
22455 rtx op0 = gen_reg_rtx (XFmode);
22456 rtx op1 = gen_reg_rtx (XFmode);
22457
22458 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
22459 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
22460 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
22461 }
22462 DONE;
22463 })
22464
22465 ;; Rounding mode control word calculation could clobber FLAGS_REG.
22466 (define_insn_and_split "*fist<mode>2_<rounding>_1"
22467 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22468 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22469 FIST_ROUNDING))
22470 (clobber (reg:CC FLAGS_REG))]
22471 "TARGET_USE_FANCY_MATH_387
22472 && flag_unsafe_math_optimizations
22473 && ix86_pre_reload_split ()"
22474 "#"
22475 "&& 1"
22476 [(const_int 0)]
22477 {
22478 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
22479
22480 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
22481 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
22482
22483 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
22484 operands[2], operands[3]));
22485 DONE;
22486 }
22487 [(set_attr "type" "fistp")
22488 (set_attr "i387_cw" "<rounding>")
22489 (set_attr "mode" "<MODE>")])
22490
22491 (define_insn "fistdi2_<rounding>"
22492 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
22493 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
22494 FIST_ROUNDING))
22495 (use (match_operand:HI 2 "memory_operand" "m"))
22496 (use (match_operand:HI 3 "memory_operand" "m"))
22497 (clobber (match_scratch:XF 4 "=&f"))]
22498 "TARGET_USE_FANCY_MATH_387
22499 && flag_unsafe_math_optimizations"
22500 "* return output_fix_trunc (insn, operands, false);"
22501 [(set_attr "type" "fistp")
22502 (set_attr "i387_cw" "<rounding>")
22503 (set_attr "mode" "DI")])
22504
22505 (define_insn "fist<mode>2_<rounding>"
22506 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
22507 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
22508 FIST_ROUNDING))
22509 (use (match_operand:HI 2 "memory_operand" "m"))
22510 (use (match_operand:HI 3 "memory_operand" "m"))]
22511 "TARGET_USE_FANCY_MATH_387
22512 && flag_unsafe_math_optimizations"
22513 "* return output_fix_trunc (insn, operands, false);"
22514 [(set_attr "type" "fistp")
22515 (set_attr "i387_cw" "<rounding>")
22516 (set_attr "mode" "<MODE>")])
22517
22518 (define_expand "l<rounding_insn>xf<mode>2"
22519 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
22520 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
22521 FIST_ROUNDING))
22522 (clobber (reg:CC FLAGS_REG))])]
22523 "TARGET_USE_FANCY_MATH_387
22524 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
22525 && flag_unsafe_math_optimizations")
22526
22527 (define_expand "l<rounding_insn>hf<mode>2"
22528 [(set (match_operand:SWI48 0 "nonimmediate_operand")
22529 (unspec:SWI48 [(match_operand:HF 1 "register_operand")]
22530 FIST_ROUNDING))]
22531 "TARGET_AVX512FP16"
22532 {
22533 rtx tmp = gen_reg_rtx (HFmode);
22534 emit_insn (gen_sse4_1_roundhf2 (tmp, operands[1],
22535 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
22536 emit_insn (gen_fix_trunchf<mode>2 (operands[0], tmp));
22537 DONE;
22538 })
22539
22540 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
22541 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
22542 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
22543 FIST_ROUNDING))
22544 (clobber (reg:CC FLAGS_REG))])]
22545 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
22546 && (TARGET_SSE4_1 || !flag_trapping_math)"
22547 {
22548 if (TARGET_SSE4_1)
22549 {
22550 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22551
22552 emit_insn (gen_sse4_1_round<MODEF:mode>2
22553 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22554 | ROUND_NO_EXC)));
22555 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22556 (operands[0], tmp));
22557 }
22558 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22559 ix86_expand_lfloorceil (operands[0], operands[1], true);
22560 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22561 ix86_expand_lfloorceil (operands[0], operands[1], false);
22562 else
22563 gcc_unreachable ();
22564
22565 DONE;
22566 })
22567
22568 (define_insn "fxam<mode>2_i387"
22569 [(set (match_operand:HI 0 "register_operand" "=a")
22570 (unspec:HI
22571 [(match_operand:X87MODEF 1 "register_operand" "f")]
22572 UNSPEC_FXAM))]
22573 "TARGET_USE_FANCY_MATH_387"
22574 "fxam\n\tfnstsw\t%0"
22575 [(set_attr "type" "multi")
22576 (set_attr "length" "4")
22577 (set_attr "unit" "i387")
22578 (set_attr "mode" "<MODE>")])
22579
22580 (define_expand "signbittf2"
22581 [(use (match_operand:SI 0 "register_operand"))
22582 (use (match_operand:TF 1 "register_operand"))]
22583 "TARGET_SSE"
22584 {
22585 if (TARGET_SSE4_1)
22586 {
22587 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22588 rtx scratch = gen_reg_rtx (QImode);
22589
22590 emit_insn (gen_ptesttf2 (operands[1], mask));
22591 ix86_expand_setcc (scratch, NE,
22592 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22593
22594 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22595 }
22596 else
22597 {
22598 emit_insn (gen_sse_movmskps (operands[0],
22599 gen_lowpart (V4SFmode, operands[1])));
22600 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22601 }
22602 DONE;
22603 })
22604
22605 (define_expand "signbitxf2"
22606 [(use (match_operand:SI 0 "register_operand"))
22607 (use (match_operand:XF 1 "register_operand"))]
22608 "TARGET_USE_FANCY_MATH_387"
22609 {
22610 rtx scratch = gen_reg_rtx (HImode);
22611
22612 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22613 emit_insn (gen_andsi3 (operands[0],
22614 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22615 DONE;
22616 })
22617
22618 (define_insn "movmsk_df"
22619 [(set (match_operand:SI 0 "register_operand" "=r,jr")
22620 (unspec:SI
22621 [(match_operand:DF 1 "register_operand" "x,x")]
22622 UNSPEC_MOVMSK))]
22623 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22624 "%vmovmskpd\t{%1, %0|%0, %1}"
22625 [(set_attr "isa" "noavx,avx")
22626 (set_attr "type" "ssemov")
22627 (set_attr "prefix" "maybe_evex")
22628 (set_attr "mode" "DF")])
22629
22630 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22631 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22632 (define_expand "signbitdf2"
22633 [(use (match_operand:SI 0 "register_operand"))
22634 (use (match_operand:DF 1 "register_operand"))]
22635 "TARGET_USE_FANCY_MATH_387
22636 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22637 {
22638 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22639 {
22640 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22641 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22642 }
22643 else
22644 {
22645 rtx scratch = gen_reg_rtx (HImode);
22646
22647 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22648 emit_insn (gen_andsi3 (operands[0],
22649 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22650 }
22651 DONE;
22652 })
22653
22654 (define_expand "signbitsf2"
22655 [(use (match_operand:SI 0 "register_operand"))
22656 (use (match_operand:SF 1 "register_operand"))]
22657 "TARGET_USE_FANCY_MATH_387
22658 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22659 {
22660 rtx scratch = gen_reg_rtx (HImode);
22661
22662 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22663 emit_insn (gen_andsi3 (operands[0],
22664 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22665 DONE;
22666 })
22667 \f
22668 ;; Block operation instructions
22669
22670 (define_insn "cld"
22671 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22672 ""
22673 "cld"
22674 [(set_attr "length" "1")
22675 (set_attr "length_immediate" "0")
22676 (set_attr "modrm" "0")])
22677
22678 (define_expand "cpymem<mode>"
22679 [(use (match_operand:BLK 0 "memory_operand"))
22680 (use (match_operand:BLK 1 "memory_operand"))
22681 (use (match_operand:SWI48 2 "nonmemory_operand"))
22682 (use (match_operand:SWI48 3 "const_int_operand"))
22683 (use (match_operand:SI 4 "const_int_operand"))
22684 (use (match_operand:SI 5 "const_int_operand"))
22685 (use (match_operand:SI 6 ""))
22686 (use (match_operand:SI 7 ""))
22687 (use (match_operand:SI 8 ""))]
22688 ""
22689 {
22690 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22691 operands[2], NULL, operands[3],
22692 operands[4], operands[5],
22693 operands[6], operands[7],
22694 operands[8], false))
22695 DONE;
22696 else
22697 FAIL;
22698 })
22699
22700 ;; Most CPUs don't like single string operations
22701 ;; Handle this case here to simplify previous expander.
22702
22703 (define_expand "strmov"
22704 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22705 (set (match_operand 1 "memory_operand") (match_dup 4))
22706 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22707 (clobber (reg:CC FLAGS_REG))])
22708 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22709 (clobber (reg:CC FLAGS_REG))])]
22710 ""
22711 {
22712 /* Can't use this for non-default address spaces. */
22713 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22714 FAIL;
22715
22716 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22717
22718 /* If .md ever supports :P for Pmode, these can be directly
22719 in the pattern above. */
22720 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22721 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22722
22723 /* Can't use this if the user has appropriated esi or edi. */
22724 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22725 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22726 {
22727 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22728 operands[2], operands[3],
22729 operands[5], operands[6]));
22730 DONE;
22731 }
22732
22733 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22734 })
22735
22736 (define_expand "strmov_singleop"
22737 [(parallel [(set (match_operand 1 "memory_operand")
22738 (match_operand 3 "memory_operand"))
22739 (set (match_operand 0 "register_operand")
22740 (match_operand 4))
22741 (set (match_operand 2 "register_operand")
22742 (match_operand 5))])]
22743 ""
22744 {
22745 if (TARGET_CLD)
22746 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22747 })
22748
22749 (define_insn "*strmovdi_rex_1"
22750 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22751 (mem:DI (match_operand:P 3 "register_operand" "1")))
22752 (set (match_operand:P 0 "register_operand" "=D")
22753 (plus:P (match_dup 2)
22754 (const_int 8)))
22755 (set (match_operand:P 1 "register_operand" "=S")
22756 (plus:P (match_dup 3)
22757 (const_int 8)))]
22758 "TARGET_64BIT
22759 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22760 && ix86_check_no_addr_space (insn)"
22761 "%^movsq"
22762 [(set_attr "type" "str")
22763 (set_attr "memory" "both")
22764 (set_attr "mode" "DI")])
22765
22766 (define_insn "*strmovsi_1"
22767 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22768 (mem:SI (match_operand:P 3 "register_operand" "1")))
22769 (set (match_operand:P 0 "register_operand" "=D")
22770 (plus:P (match_dup 2)
22771 (const_int 4)))
22772 (set (match_operand:P 1 "register_operand" "=S")
22773 (plus:P (match_dup 3)
22774 (const_int 4)))]
22775 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22776 && ix86_check_no_addr_space (insn)"
22777 "%^movs{l|d}"
22778 [(set_attr "type" "str")
22779 (set_attr "memory" "both")
22780 (set_attr "mode" "SI")])
22781
22782 (define_insn "*strmovhi_1"
22783 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22784 (mem:HI (match_operand:P 3 "register_operand" "1")))
22785 (set (match_operand:P 0 "register_operand" "=D")
22786 (plus:P (match_dup 2)
22787 (const_int 2)))
22788 (set (match_operand:P 1 "register_operand" "=S")
22789 (plus:P (match_dup 3)
22790 (const_int 2)))]
22791 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22792 && ix86_check_no_addr_space (insn)"
22793 "%^movsw"
22794 [(set_attr "type" "str")
22795 (set_attr "memory" "both")
22796 (set_attr "mode" "HI")])
22797
22798 (define_insn "*strmovqi_1"
22799 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22800 (mem:QI (match_operand:P 3 "register_operand" "1")))
22801 (set (match_operand:P 0 "register_operand" "=D")
22802 (plus:P (match_dup 2)
22803 (const_int 1)))
22804 (set (match_operand:P 1 "register_operand" "=S")
22805 (plus:P (match_dup 3)
22806 (const_int 1)))]
22807 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22808 && ix86_check_no_addr_space (insn)"
22809 "%^movsb"
22810 [(set_attr "type" "str")
22811 (set_attr "memory" "both")
22812 (set (attr "prefix_rex")
22813 (if_then_else
22814 (match_test "<P:MODE>mode == DImode")
22815 (const_string "0")
22816 (const_string "*")))
22817 (set_attr "mode" "QI")])
22818
22819 (define_expand "rep_mov"
22820 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22821 (set (match_operand 0 "register_operand")
22822 (match_operand 5))
22823 (set (match_operand 2 "register_operand")
22824 (match_operand 6))
22825 (set (match_operand 1 "memory_operand")
22826 (match_operand 3 "memory_operand"))
22827 (use (match_dup 4))])]
22828 ""
22829 {
22830 if (TARGET_CLD)
22831 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22832 })
22833
22834 (define_insn "*rep_movdi_rex64"
22835 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22836 (set (match_operand:P 0 "register_operand" "=D")
22837 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22838 (const_int 3))
22839 (match_operand:P 3 "register_operand" "0")))
22840 (set (match_operand:P 1 "register_operand" "=S")
22841 (plus:P (ashift:P (match_dup 5) (const_int 3))
22842 (match_operand:P 4 "register_operand" "1")))
22843 (set (mem:BLK (match_dup 3))
22844 (mem:BLK (match_dup 4)))
22845 (use (match_dup 5))]
22846 "TARGET_64BIT
22847 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22848 && ix86_check_no_addr_space (insn)"
22849 "%^rep{%;} movsq"
22850 [(set_attr "type" "str")
22851 (set_attr "prefix_rep" "1")
22852 (set_attr "memory" "both")
22853 (set_attr "mode" "DI")])
22854
22855 (define_insn "*rep_movsi"
22856 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22857 (set (match_operand:P 0 "register_operand" "=D")
22858 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22859 (const_int 2))
22860 (match_operand:P 3 "register_operand" "0")))
22861 (set (match_operand:P 1 "register_operand" "=S")
22862 (plus:P (ashift:P (match_dup 5) (const_int 2))
22863 (match_operand:P 4 "register_operand" "1")))
22864 (set (mem:BLK (match_dup 3))
22865 (mem:BLK (match_dup 4)))
22866 (use (match_dup 5))]
22867 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22868 && ix86_check_no_addr_space (insn)"
22869 "%^rep{%;} movs{l|d}"
22870 [(set_attr "type" "str")
22871 (set_attr "prefix_rep" "1")
22872 (set_attr "memory" "both")
22873 (set_attr "mode" "SI")])
22874
22875 (define_insn "*rep_movqi"
22876 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22877 (set (match_operand:P 0 "register_operand" "=D")
22878 (plus:P (match_operand:P 3 "register_operand" "0")
22879 (match_operand:P 5 "register_operand" "2")))
22880 (set (match_operand:P 1 "register_operand" "=S")
22881 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22882 (set (mem:BLK (match_dup 3))
22883 (mem:BLK (match_dup 4)))
22884 (use (match_dup 5))]
22885 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22886 && ix86_check_no_addr_space (insn)"
22887 "%^rep{%;} movsb"
22888 [(set_attr "type" "str")
22889 (set_attr "prefix_rep" "1")
22890 (set_attr "memory" "both")
22891 (set_attr "mode" "QI")])
22892
22893 (define_expand "setmem<mode>"
22894 [(use (match_operand:BLK 0 "memory_operand"))
22895 (use (match_operand:SWI48 1 "nonmemory_operand"))
22896 (use (match_operand:QI 2 "nonmemory_operand"))
22897 (use (match_operand 3 "const_int_operand"))
22898 (use (match_operand:SI 4 "const_int_operand"))
22899 (use (match_operand:SI 5 "const_int_operand"))
22900 (use (match_operand:SI 6 ""))
22901 (use (match_operand:SI 7 ""))
22902 (use (match_operand:SI 8 ""))]
22903 ""
22904 {
22905 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22906 operands[1], operands[2],
22907 operands[3], operands[4],
22908 operands[5], operands[6],
22909 operands[7], operands[8], true))
22910 DONE;
22911 else
22912 FAIL;
22913 })
22914
22915 ;; Most CPUs don't like single string operations
22916 ;; Handle this case here to simplify previous expander.
22917
22918 (define_expand "strset"
22919 [(set (match_operand 1 "memory_operand")
22920 (match_operand 2 "register_operand"))
22921 (parallel [(set (match_operand 0 "register_operand")
22922 (match_dup 3))
22923 (clobber (reg:CC FLAGS_REG))])]
22924 ""
22925 {
22926 /* Can't use this for non-default address spaces. */
22927 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22928 FAIL;
22929
22930 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22931 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22932
22933 /* If .md ever supports :P for Pmode, this can be directly
22934 in the pattern above. */
22935 operands[3] = plus_constant (Pmode, operands[0],
22936 GET_MODE_SIZE (GET_MODE (operands[2])));
22937
22938 /* Can't use this if the user has appropriated eax or edi. */
22939 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22940 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22941 {
22942 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22943 operands[3]));
22944 DONE;
22945 }
22946 })
22947
22948 (define_expand "strset_singleop"
22949 [(parallel [(set (match_operand 1 "memory_operand")
22950 (match_operand 2 "register_operand"))
22951 (set (match_operand 0 "register_operand")
22952 (match_operand 3))
22953 (unspec [(const_int 0)] UNSPEC_STOS)])]
22954 ""
22955 {
22956 if (TARGET_CLD)
22957 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22958 })
22959
22960 (define_insn "*strsetdi_rex_1"
22961 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22962 (match_operand:DI 2 "register_operand" "a"))
22963 (set (match_operand:P 0 "register_operand" "=D")
22964 (plus:P (match_dup 1)
22965 (const_int 8)))
22966 (unspec [(const_int 0)] UNSPEC_STOS)]
22967 "TARGET_64BIT
22968 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22969 && ix86_check_no_addr_space (insn)"
22970 "%^stosq"
22971 [(set_attr "type" "str")
22972 (set_attr "memory" "store")
22973 (set_attr "mode" "DI")])
22974
22975 (define_insn "*strsetsi_1"
22976 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22977 (match_operand:SI 2 "register_operand" "a"))
22978 (set (match_operand:P 0 "register_operand" "=D")
22979 (plus:P (match_dup 1)
22980 (const_int 4)))
22981 (unspec [(const_int 0)] UNSPEC_STOS)]
22982 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22983 && ix86_check_no_addr_space (insn)"
22984 "%^stos{l|d}"
22985 [(set_attr "type" "str")
22986 (set_attr "memory" "store")
22987 (set_attr "mode" "SI")])
22988
22989 (define_insn "*strsethi_1"
22990 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22991 (match_operand:HI 2 "register_operand" "a"))
22992 (set (match_operand:P 0 "register_operand" "=D")
22993 (plus:P (match_dup 1)
22994 (const_int 2)))
22995 (unspec [(const_int 0)] UNSPEC_STOS)]
22996 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22997 && ix86_check_no_addr_space (insn)"
22998 "%^stosw"
22999 [(set_attr "type" "str")
23000 (set_attr "memory" "store")
23001 (set_attr "mode" "HI")])
23002
23003 (define_insn "*strsetqi_1"
23004 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
23005 (match_operand:QI 2 "register_operand" "a"))
23006 (set (match_operand:P 0 "register_operand" "=D")
23007 (plus:P (match_dup 1)
23008 (const_int 1)))
23009 (unspec [(const_int 0)] UNSPEC_STOS)]
23010 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
23011 && ix86_check_no_addr_space (insn)"
23012 "%^stosb"
23013 [(set_attr "type" "str")
23014 (set_attr "memory" "store")
23015 (set (attr "prefix_rex")
23016 (if_then_else
23017 (match_test "<P:MODE>mode == DImode")
23018 (const_string "0")
23019 (const_string "*")))
23020 (set_attr "mode" "QI")])
23021
23022 (define_expand "rep_stos"
23023 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
23024 (set (match_operand 0 "register_operand")
23025 (match_operand 4))
23026 (set (match_operand 2 "memory_operand") (const_int 0))
23027 (use (match_operand 3 "register_operand"))
23028 (use (match_dup 1))])]
23029 ""
23030 {
23031 if (TARGET_CLD)
23032 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23033 })
23034
23035 (define_insn "*rep_stosdi_rex64"
23036 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
23037 (set (match_operand:P 0 "register_operand" "=D")
23038 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
23039 (const_int 3))
23040 (match_operand:P 3 "register_operand" "0")))
23041 (set (mem:BLK (match_dup 3))
23042 (const_int 0))
23043 (use (match_operand:DI 2 "register_operand" "a"))
23044 (use (match_dup 4))]
23045 "TARGET_64BIT
23046 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23047 && ix86_check_no_addr_space (insn)"
23048 "%^rep{%;} stosq"
23049 [(set_attr "type" "str")
23050 (set_attr "prefix_rep" "1")
23051 (set_attr "memory" "store")
23052 (set_attr "mode" "DI")])
23053
23054 (define_insn "*rep_stossi"
23055 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
23056 (set (match_operand:P 0 "register_operand" "=D")
23057 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
23058 (const_int 2))
23059 (match_operand:P 3 "register_operand" "0")))
23060 (set (mem:BLK (match_dup 3))
23061 (const_int 0))
23062 (use (match_operand:SI 2 "register_operand" "a"))
23063 (use (match_dup 4))]
23064 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23065 && ix86_check_no_addr_space (insn)"
23066 "%^rep{%;} stos{l|d}"
23067 [(set_attr "type" "str")
23068 (set_attr "prefix_rep" "1")
23069 (set_attr "memory" "store")
23070 (set_attr "mode" "SI")])
23071
23072 (define_insn "*rep_stosqi"
23073 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
23074 (set (match_operand:P 0 "register_operand" "=D")
23075 (plus:P (match_operand:P 3 "register_operand" "0")
23076 (match_operand:P 4 "register_operand" "1")))
23077 (set (mem:BLK (match_dup 3))
23078 (const_int 0))
23079 (use (match_operand:QI 2 "register_operand" "a"))
23080 (use (match_dup 4))]
23081 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23082 && ix86_check_no_addr_space (insn)"
23083 "%^rep{%;} stosb"
23084 [(set_attr "type" "str")
23085 (set_attr "prefix_rep" "1")
23086 (set_attr "memory" "store")
23087 (set (attr "prefix_rex")
23088 (if_then_else
23089 (match_test "<P:MODE>mode == DImode")
23090 (const_string "0")
23091 (const_string "*")))
23092 (set_attr "mode" "QI")])
23093
23094 (define_expand "cmpmemsi"
23095 [(set (match_operand:SI 0 "register_operand" "")
23096 (compare:SI (match_operand:BLK 1 "memory_operand" "")
23097 (match_operand:BLK 2 "memory_operand" "") ) )
23098 (use (match_operand 3 "general_operand"))
23099 (use (match_operand 4 "immediate_operand"))]
23100 ""
23101 {
23102 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
23103 operands[2], operands[3],
23104 operands[4], false))
23105 DONE;
23106 else
23107 FAIL;
23108 })
23109
23110 (define_expand "cmpstrnsi"
23111 [(set (match_operand:SI 0 "register_operand")
23112 (compare:SI (match_operand:BLK 1 "general_operand")
23113 (match_operand:BLK 2 "general_operand")))
23114 (use (match_operand 3 "general_operand"))
23115 (use (match_operand 4 "immediate_operand"))]
23116 ""
23117 {
23118 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
23119 operands[2], operands[3],
23120 operands[4], true))
23121 DONE;
23122 else
23123 FAIL;
23124 })
23125
23126 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
23127
23128 (define_expand "cmpintqi"
23129 [(set (match_dup 1)
23130 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23131 (set (match_dup 2)
23132 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23133 (parallel [(set (match_operand:QI 0 "register_operand")
23134 (minus:QI (match_dup 1)
23135 (match_dup 2)))
23136 (clobber (reg:CC FLAGS_REG))])]
23137 ""
23138 {
23139 operands[1] = gen_reg_rtx (QImode);
23140 operands[2] = gen_reg_rtx (QImode);
23141 })
23142
23143 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
23144 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
23145
23146 (define_expand "cmpstrnqi_nz_1"
23147 [(parallel [(set (reg:CC FLAGS_REG)
23148 (compare:CC (match_operand 4 "memory_operand")
23149 (match_operand 5 "memory_operand")))
23150 (use (match_operand 2 "register_operand"))
23151 (use (match_operand:SI 3 "immediate_operand"))
23152 (clobber (match_operand 0 "register_operand"))
23153 (clobber (match_operand 1 "register_operand"))
23154 (clobber (match_dup 2))])]
23155 ""
23156 {
23157 if (TARGET_CLD)
23158 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23159 })
23160
23161 (define_insn "*cmpstrnqi_nz_1"
23162 [(set (reg:CC FLAGS_REG)
23163 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23164 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
23165 (use (match_operand:P 6 "register_operand" "2"))
23166 (use (match_operand:SI 3 "immediate_operand" "i"))
23167 (clobber (match_operand:P 0 "register_operand" "=S"))
23168 (clobber (match_operand:P 1 "register_operand" "=D"))
23169 (clobber (match_operand:P 2 "register_operand" "=c"))]
23170 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23171 && ix86_check_no_addr_space (insn)"
23172 "%^repz{%;} cmpsb"
23173 [(set_attr "type" "str")
23174 (set_attr "mode" "QI")
23175 (set (attr "prefix_rex")
23176 (if_then_else
23177 (match_test "<P:MODE>mode == DImode")
23178 (const_string "0")
23179 (const_string "*")))
23180 (set_attr "prefix_rep" "1")])
23181
23182 ;; The same, but the count is not known to not be zero.
23183
23184 (define_expand "cmpstrnqi_1"
23185 [(parallel [(set (reg:CC FLAGS_REG)
23186 (if_then_else:CC (ne (match_operand 2 "register_operand")
23187 (const_int 0))
23188 (compare:CC (match_operand 4 "memory_operand")
23189 (match_operand 5 "memory_operand"))
23190 (const_int 0)))
23191 (use (match_operand:SI 3 "immediate_operand"))
23192 (use (reg:CC FLAGS_REG))
23193 (clobber (match_operand 0 "register_operand"))
23194 (clobber (match_operand 1 "register_operand"))
23195 (clobber (match_dup 2))])]
23196 ""
23197 {
23198 if (TARGET_CLD)
23199 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23200 })
23201
23202 (define_insn "*cmpstrnqi_1"
23203 [(set (reg:CC FLAGS_REG)
23204 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
23205 (const_int 0))
23206 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
23207 (mem:BLK (match_operand:P 5 "register_operand" "1")))
23208 (const_int 0)))
23209 (use (match_operand:SI 3 "immediate_operand" "i"))
23210 (use (reg:CC FLAGS_REG))
23211 (clobber (match_operand:P 0 "register_operand" "=S"))
23212 (clobber (match_operand:P 1 "register_operand" "=D"))
23213 (clobber (match_operand:P 2 "register_operand" "=c"))]
23214 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
23215 && ix86_check_no_addr_space (insn)"
23216 "%^repz{%;} cmpsb"
23217 [(set_attr "type" "str")
23218 (set_attr "mode" "QI")
23219 (set (attr "prefix_rex")
23220 (if_then_else
23221 (match_test "<P:MODE>mode == DImode")
23222 (const_string "0")
23223 (const_string "*")))
23224 (set_attr "prefix_rep" "1")])
23225
23226 (define_expand "strlen<mode>"
23227 [(set (match_operand:P 0 "register_operand")
23228 (unspec:P [(match_operand:BLK 1 "general_operand")
23229 (match_operand:QI 2 "immediate_operand")
23230 (match_operand 3 "immediate_operand")]
23231 UNSPEC_SCAS))]
23232 ""
23233 {
23234 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
23235 DONE;
23236 else
23237 FAIL;
23238 })
23239
23240 (define_expand "strlenqi_1"
23241 [(parallel [(set (match_operand 0 "register_operand")
23242 (match_operand 2))
23243 (clobber (match_operand 1 "register_operand"))
23244 (clobber (reg:CC FLAGS_REG))])]
23245 ""
23246 {
23247 if (TARGET_CLD)
23248 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
23249 })
23250
23251 (define_insn "*strlenqi_1"
23252 [(set (match_operand:P 0 "register_operand" "=&c")
23253 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
23254 (match_operand:QI 2 "register_operand" "a")
23255 (match_operand:P 3 "immediate_operand" "i")
23256 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
23257 (clobber (match_operand:P 1 "register_operand" "=D"))
23258 (clobber (reg:CC FLAGS_REG))]
23259 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
23260 && ix86_check_no_addr_space (insn)"
23261 "%^repnz{%;} scasb"
23262 [(set_attr "type" "str")
23263 (set_attr "mode" "QI")
23264 (set (attr "prefix_rex")
23265 (if_then_else
23266 (match_test "<P:MODE>mode == DImode")
23267 (const_string "0")
23268 (const_string "*")))
23269 (set_attr "prefix_rep" "1")])
23270
23271 ;; Peephole optimizations to clean up after cmpstrn*. This should be
23272 ;; handled in combine, but it is not currently up to the task.
23273 ;; When used for their truth value, the cmpstrn* expanders generate
23274 ;; code like this:
23275 ;;
23276 ;; repz cmpsb
23277 ;; seta %al
23278 ;; setb %dl
23279 ;; cmpb %al, %dl
23280 ;; jcc label
23281 ;;
23282 ;; The intermediate three instructions are unnecessary.
23283
23284 ;; This one handles cmpstrn*_nz_1...
23285 (define_peephole2
23286 [(parallel[
23287 (set (reg:CC FLAGS_REG)
23288 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23289 (mem:BLK (match_operand 5 "register_operand"))))
23290 (use (match_operand 6 "register_operand"))
23291 (use (match_operand:SI 3 "immediate_operand"))
23292 (clobber (match_operand 0 "register_operand"))
23293 (clobber (match_operand 1 "register_operand"))
23294 (clobber (match_operand 2 "register_operand"))])
23295 (set (match_operand:QI 7 "register_operand")
23296 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23297 (set (match_operand:QI 8 "register_operand")
23298 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23299 (set (reg FLAGS_REG)
23300 (compare (match_dup 7) (match_dup 8)))
23301 ]
23302 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23303 [(parallel[
23304 (set (reg:CC FLAGS_REG)
23305 (compare:CC (mem:BLK (match_dup 4))
23306 (mem:BLK (match_dup 5))))
23307 (use (match_dup 6))
23308 (use (match_dup 3))
23309 (clobber (match_dup 0))
23310 (clobber (match_dup 1))
23311 (clobber (match_dup 2))])])
23312
23313 ;; ...and this one handles cmpstrn*_1.
23314 (define_peephole2
23315 [(parallel[
23316 (set (reg:CC FLAGS_REG)
23317 (if_then_else:CC (ne (match_operand 6 "register_operand")
23318 (const_int 0))
23319 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
23320 (mem:BLK (match_operand 5 "register_operand")))
23321 (const_int 0)))
23322 (use (match_operand:SI 3 "immediate_operand"))
23323 (use (reg:CC FLAGS_REG))
23324 (clobber (match_operand 0 "register_operand"))
23325 (clobber (match_operand 1 "register_operand"))
23326 (clobber (match_operand 2 "register_operand"))])
23327 (set (match_operand:QI 7 "register_operand")
23328 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
23329 (set (match_operand:QI 8 "register_operand")
23330 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
23331 (set (reg FLAGS_REG)
23332 (compare (match_dup 7) (match_dup 8)))
23333 ]
23334 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
23335 [(parallel[
23336 (set (reg:CC FLAGS_REG)
23337 (if_then_else:CC (ne (match_dup 6)
23338 (const_int 0))
23339 (compare:CC (mem:BLK (match_dup 4))
23340 (mem:BLK (match_dup 5)))
23341 (const_int 0)))
23342 (use (match_dup 3))
23343 (use (reg:CC FLAGS_REG))
23344 (clobber (match_dup 0))
23345 (clobber (match_dup 1))
23346 (clobber (match_dup 2))])])
23347 \f
23348 ;; Conditional move instructions.
23349
23350 (define_expand "mov<mode>cc"
23351 [(set (match_operand:SWIM 0 "register_operand")
23352 (if_then_else:SWIM (match_operand 1 "comparison_operator")
23353 (match_operand:SWIM 2 "<general_operand>")
23354 (match_operand:SWIM 3 "<general_operand>")))]
23355 ""
23356 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
23357
23358 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
23359 ;; the register first winds up with `sbbl $0,reg', which is also weird.
23360 ;; So just document what we're doing explicitly.
23361
23362 (define_expand "x86_mov<mode>cc_0_m1"
23363 [(parallel
23364 [(set (match_operand:SWI48 0 "register_operand")
23365 (if_then_else:SWI48
23366 (match_operator:SWI48 2 "ix86_carry_flag_operator"
23367 [(match_operand 1 "flags_reg_operand")
23368 (const_int 0)])
23369 (const_int -1)
23370 (const_int 0)))
23371 (clobber (reg:CC FLAGS_REG))])])
23372
23373 (define_insn "*x86_mov<mode>cc_0_m1"
23374 [(set (match_operand:SWI48 0 "register_operand" "=r")
23375 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23376 [(reg FLAGS_REG) (const_int 0)])
23377 (const_int -1)
23378 (const_int 0)))
23379 (clobber (reg:CC FLAGS_REG))]
23380 ""
23381 "sbb{<imodesuffix>}\t%0, %0"
23382 [(set_attr "type" "alu1")
23383 (set_attr "use_carry" "1")
23384 (set_attr "pent_pair" "pu")
23385 (set_attr "mode" "<MODE>")
23386 (set_attr "length_immediate" "0")])
23387
23388 (define_insn "*x86_mov<mode>cc_0_m1_se"
23389 [(set (match_operand:SWI48 0 "register_operand" "=r")
23390 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
23391 [(reg FLAGS_REG) (const_int 0)])
23392 (const_int 1)
23393 (const_int 0)))
23394 (clobber (reg:CC FLAGS_REG))]
23395 ""
23396 "sbb{<imodesuffix>}\t%0, %0"
23397 [(set_attr "type" "alu1")
23398 (set_attr "use_carry" "1")
23399 (set_attr "pent_pair" "pu")
23400 (set_attr "mode" "<MODE>")
23401 (set_attr "length_immediate" "0")])
23402
23403 (define_insn "*x86_mov<mode>cc_0_m1_neg"
23404 [(set (match_operand:SWI 0 "register_operand" "=<r>")
23405 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
23406 [(reg FLAGS_REG) (const_int 0)])))
23407 (clobber (reg:CC FLAGS_REG))]
23408 ""
23409 "sbb{<imodesuffix>}\t%0, %0"
23410 [(set_attr "type" "alu1")
23411 (set_attr "use_carry" "1")
23412 (set_attr "pent_pair" "pu")
23413 (set_attr "mode" "<MODE>")
23414 (set_attr "length_immediate" "0")])
23415
23416 (define_expand "x86_mov<mode>cc_0_m1_neg"
23417 [(parallel
23418 [(set (match_operand:SWI48 0 "register_operand")
23419 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
23420 (clobber (reg:CC FLAGS_REG))])])
23421
23422 (define_split
23423 [(set (match_operand:SWI48 0 "register_operand")
23424 (neg:SWI48
23425 (leu:SWI48
23426 (match_operand 1 "int_nonimmediate_operand")
23427 (match_operand 2 "const_int_operand"))))]
23428 "x86_64_immediate_operand (operands[2], VOIDmode)
23429 && INTVAL (operands[2]) != -1
23430 && INTVAL (operands[2]) != 2147483647"
23431 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
23432 (set (match_dup 0)
23433 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
23434 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
23435
23436 (define_split
23437 [(set (match_operand:SWI 0 "register_operand")
23438 (neg:SWI
23439 (eq:SWI
23440 (match_operand 1 "int_nonimmediate_operand")
23441 (const_int 0))))]
23442 ""
23443 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
23444 (set (match_dup 0)
23445 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
23446
23447 (define_split
23448 [(set (match_operand:SWI 0 "register_operand")
23449 (neg:SWI
23450 (ne:SWI
23451 (match_operand 1 "int_nonimmediate_operand")
23452 (const_int 0))))]
23453 ""
23454 [(set (reg:CCC FLAGS_REG)
23455 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
23456 (set (match_dup 0)
23457 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
23458
23459 (define_insn "*mov<mode>cc_noc"
23460 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
23461 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23462 [(reg FLAGS_REG) (const_int 0)])
23463 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
23464 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
23465 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23466 "@
23467 cmov%O2%C1\t{%2, %0|%0, %2}
23468 cmov%O2%c1\t{%3, %0|%0, %3}"
23469 [(set_attr "type" "icmov")
23470 (set_attr "mode" "<MODE>")])
23471
23472 (define_insn "*movsicc_noc_zext"
23473 [(set (match_operand:DI 0 "register_operand" "=r,r")
23474 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23475 [(reg FLAGS_REG) (const_int 0)])
23476 (zero_extend:DI
23477 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
23478 (zero_extend:DI
23479 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23480 "TARGET_64BIT
23481 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23482 "@
23483 cmov%O2%C1\t{%2, %k0|%k0, %2}
23484 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23485 [(set_attr "type" "icmov")
23486 (set_attr "mode" "SI")])
23487
23488 (define_insn "*movsicc_noc_zext_1"
23489 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
23490 (zero_extend:DI
23491 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
23492 [(reg FLAGS_REG) (const_int 0)])
23493 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
23494 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
23495 "TARGET_64BIT
23496 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23497 "@
23498 cmov%O2%C1\t{%2, %k0|%k0, %2}
23499 cmov%O2%c1\t{%3, %k0|%k0, %3}"
23500 [(set_attr "type" "icmov")
23501 (set_attr "mode" "SI")])
23502
23503
23504 ;; Don't do conditional moves with memory inputs. This splitter helps
23505 ;; register starved x86_32 by forcing inputs into registers before reload.
23506 (define_split
23507 [(set (match_operand:SWI248 0 "register_operand")
23508 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23509 [(reg FLAGS_REG) (const_int 0)])
23510 (match_operand:SWI248 2 "nonimmediate_operand")
23511 (match_operand:SWI248 3 "nonimmediate_operand")))]
23512 "!TARGET_64BIT && TARGET_CMOVE
23513 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23514 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23515 && can_create_pseudo_p ()
23516 && optimize_insn_for_speed_p ()"
23517 [(set (match_dup 0)
23518 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23519 {
23520 operands[2] = force_reg (<MODE>mode, operands[2]);
23521 operands[3] = force_reg (<MODE>mode, operands[3]);
23522 })
23523
23524 (define_insn "*movqicc_noc"
23525 [(set (match_operand:QI 0 "register_operand" "=r,r")
23526 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
23527 [(reg FLAGS_REG) (const_int 0)])
23528 (match_operand:QI 2 "register_operand" "r,0")
23529 (match_operand:QI 3 "register_operand" "0,r")))]
23530 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
23531 "#"
23532 [(set_attr "type" "icmov")
23533 (set_attr "mode" "QI")])
23534
23535 (define_split
23536 [(set (match_operand:SWI12 0 "register_operand")
23537 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
23538 [(reg FLAGS_REG) (const_int 0)])
23539 (match_operand:SWI12 2 "register_operand")
23540 (match_operand:SWI12 3 "register_operand")))]
23541 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
23542 && reload_completed"
23543 [(set (match_dup 0)
23544 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
23545 {
23546 operands[0] = gen_lowpart (SImode, operands[0]);
23547 operands[2] = gen_lowpart (SImode, operands[2]);
23548 operands[3] = gen_lowpart (SImode, operands[3]);
23549 })
23550
23551 ;; Don't do conditional moves with memory inputs
23552 (define_peephole2
23553 [(match_scratch:SWI248 4 "r")
23554 (set (match_operand:SWI248 0 "register_operand")
23555 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23556 [(reg FLAGS_REG) (const_int 0)])
23557 (match_operand:SWI248 2 "nonimmediate_operand")
23558 (match_operand:SWI248 3 "nonimmediate_operand")))]
23559 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23560 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23561 && optimize_insn_for_speed_p ()"
23562 [(set (match_dup 4) (match_dup 5))
23563 (set (match_dup 0)
23564 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23565 {
23566 if (MEM_P (operands[2]))
23567 {
23568 operands[5] = operands[2];
23569 operands[2] = operands[4];
23570 }
23571 else if (MEM_P (operands[3]))
23572 {
23573 operands[5] = operands[3];
23574 operands[3] = operands[4];
23575 }
23576 else
23577 gcc_unreachable ();
23578 })
23579
23580 (define_peephole2
23581 [(match_scratch:SI 4 "r")
23582 (set (match_operand:DI 0 "register_operand")
23583 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23584 [(reg FLAGS_REG) (const_int 0)])
23585 (zero_extend:DI
23586 (match_operand:SI 2 "nonimmediate_operand"))
23587 (zero_extend:DI
23588 (match_operand:SI 3 "nonimmediate_operand"))))]
23589 "TARGET_64BIT
23590 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23591 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23592 && optimize_insn_for_speed_p ()"
23593 [(set (match_dup 4) (match_dup 5))
23594 (set (match_dup 0)
23595 (if_then_else:DI (match_dup 1)
23596 (zero_extend:DI (match_dup 2))
23597 (zero_extend:DI (match_dup 3))))]
23598 {
23599 if (MEM_P (operands[2]))
23600 {
23601 operands[5] = operands[2];
23602 operands[2] = operands[4];
23603 }
23604 else if (MEM_P (operands[3]))
23605 {
23606 operands[5] = operands[3];
23607 operands[3] = operands[4];
23608 }
23609 else
23610 gcc_unreachable ();
23611 })
23612
23613 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23614 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23615 (define_peephole2
23616 [(set (match_operand:SWI248 0 "general_reg_operand")
23617 (match_operand:SWI248 1 "general_reg_operand"))
23618 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23619 (set (match_dup 0) (match_operand:SWI248 6))])
23620 (set (match_operand:SWI248 2 "general_reg_operand")
23621 (match_operand:SWI248 3 "general_gr_operand"))
23622 (set (match_dup 0)
23623 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23624 [(reg FLAGS_REG) (const_int 0)])
23625 (match_dup 0)
23626 (match_dup 2)))]
23627 "TARGET_CMOVE
23628 && REGNO (operands[2]) != REGNO (operands[0])
23629 && REGNO (operands[2]) != REGNO (operands[1])
23630 && peep2_reg_dead_p (1, operands[1])
23631 && peep2_reg_dead_p (4, operands[2])
23632 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23633 [(parallel [(set (match_dup 7) (match_dup 8))
23634 (set (match_dup 1) (match_dup 9))])
23635 (set (match_dup 0) (match_dup 3))
23636 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23637 (match_dup 1)
23638 (match_dup 0)))]
23639 {
23640 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23641 operands[8]
23642 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23643 operands[9]
23644 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23645 })
23646
23647 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23648 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23649 (define_peephole2
23650 [(set (match_operand:SWI248 2 "general_reg_operand")
23651 (match_operand:SWI248 3 "general_gr_operand"))
23652 (set (match_operand:SWI248 0 "general_reg_operand")
23653 (match_operand:SWI248 1 "general_reg_operand"))
23654 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23655 (set (match_dup 0) (match_operand:SWI248 6))])
23656 (set (match_dup 0)
23657 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23658 [(reg FLAGS_REG) (const_int 0)])
23659 (match_dup 0)
23660 (match_dup 2)))]
23661 "TARGET_CMOVE
23662 && REGNO (operands[2]) != REGNO (operands[0])
23663 && REGNO (operands[2]) != REGNO (operands[1])
23664 && peep2_reg_dead_p (2, operands[1])
23665 && peep2_reg_dead_p (4, operands[2])
23666 && !reg_overlap_mentioned_p (operands[0], operands[3])
23667 && !reg_mentioned_p (operands[2], operands[6])"
23668 [(parallel [(set (match_dup 7) (match_dup 8))
23669 (set (match_dup 1) (match_dup 9))])
23670 (set (match_dup 0) (match_dup 3))
23671 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23672 (match_dup 1)
23673 (match_dup 0)))]
23674 {
23675 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23676 operands[8]
23677 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23678 operands[9]
23679 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23680 })
23681
23682 (define_insn "movhf_mask"
23683 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23684 (unspec:HF
23685 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23686 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23687 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23688 UNSPEC_MOVCC_MASK))]
23689 "TARGET_AVX512FP16"
23690 "@
23691 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23692 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23693 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23694 [(set_attr "type" "ssemov")
23695 (set_attr "prefix" "evex")
23696 (set_attr "mode" "HF")])
23697
23698 (define_expand "movhfcc"
23699 [(set (match_operand:HF 0 "register_operand")
23700 (if_then_else:HF
23701 (match_operand 1 "comparison_operator")
23702 (match_operand:HF 2 "register_operand")
23703 (match_operand:HF 3 "register_operand")))]
23704 "TARGET_AVX512FP16"
23705 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23706
23707 (define_expand "mov<mode>cc"
23708 [(set (match_operand:X87MODEF 0 "register_operand")
23709 (if_then_else:X87MODEF
23710 (match_operand 1 "comparison_operator")
23711 (match_operand:X87MODEF 2 "register_operand")
23712 (match_operand:X87MODEF 3 "register_operand")))]
23713 "(TARGET_80387 && TARGET_CMOVE)
23714 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23715 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23716
23717 (define_insn "*movxfcc_1"
23718 [(set (match_operand:XF 0 "register_operand" "=f,f")
23719 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23720 [(reg FLAGS_REG) (const_int 0)])
23721 (match_operand:XF 2 "register_operand" "f,0")
23722 (match_operand:XF 3 "register_operand" "0,f")))]
23723 "TARGET_80387 && TARGET_CMOVE"
23724 "@
23725 fcmov%F1\t{%2, %0|%0, %2}
23726 fcmov%f1\t{%3, %0|%0, %3}"
23727 [(set_attr "type" "fcmov")
23728 (set_attr "mode" "XF")])
23729
23730 (define_insn "*movdfcc_1"
23731 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23732 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23733 [(reg FLAGS_REG) (const_int 0)])
23734 (match_operand:DF 2 "nonimmediate_operand"
23735 "f ,0,rm,0 ,rm,0")
23736 (match_operand:DF 3 "nonimmediate_operand"
23737 "0 ,f,0 ,rm,0, rm")))]
23738 "TARGET_80387 && TARGET_CMOVE
23739 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23740 "@
23741 fcmov%F1\t{%2, %0|%0, %2}
23742 fcmov%f1\t{%3, %0|%0, %3}
23743 #
23744 #
23745 cmov%O2%C1\t{%2, %0|%0, %2}
23746 cmov%O2%c1\t{%3, %0|%0, %3}"
23747 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23748 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23749 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23750
23751 (define_split
23752 [(set (match_operand:DF 0 "general_reg_operand")
23753 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23754 [(reg FLAGS_REG) (const_int 0)])
23755 (match_operand:DF 2 "nonimmediate_operand")
23756 (match_operand:DF 3 "nonimmediate_operand")))]
23757 "!TARGET_64BIT && reload_completed"
23758 [(set (match_dup 2)
23759 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23760 (set (match_dup 3)
23761 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23762 {
23763 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23764 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23765 })
23766
23767 (define_insn "*movsfcc_1_387"
23768 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23769 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23770 [(reg FLAGS_REG) (const_int 0)])
23771 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23772 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23773 "TARGET_80387 && TARGET_CMOVE
23774 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23775 "@
23776 fcmov%F1\t{%2, %0|%0, %2}
23777 fcmov%f1\t{%3, %0|%0, %3}
23778 cmov%O2%C1\t{%2, %0|%0, %2}
23779 cmov%O2%c1\t{%3, %0|%0, %3}"
23780 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23781 (set_attr "mode" "SF,SF,SI,SI")])
23782
23783 ;; Don't do conditional moves with memory inputs. This splitter helps
23784 ;; register starved x86_32 by forcing inputs into registers before reload.
23785 (define_split
23786 [(set (match_operand:MODEF 0 "register_operand")
23787 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23788 [(reg FLAGS_REG) (const_int 0)])
23789 (match_operand:MODEF 2 "nonimmediate_operand")
23790 (match_operand:MODEF 3 "nonimmediate_operand")))]
23791 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23792 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23793 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23794 && can_create_pseudo_p ()
23795 && optimize_insn_for_speed_p ()"
23796 [(set (match_dup 0)
23797 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23798 {
23799 operands[2] = force_reg (<MODE>mode, operands[2]);
23800 operands[3] = force_reg (<MODE>mode, operands[3]);
23801 })
23802
23803 ;; Don't do conditional moves with memory inputs
23804 (define_peephole2
23805 [(match_scratch:MODEF 4 "r")
23806 (set (match_operand:MODEF 0 "general_reg_operand")
23807 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23808 [(reg FLAGS_REG) (const_int 0)])
23809 (match_operand:MODEF 2 "nonimmediate_operand")
23810 (match_operand:MODEF 3 "nonimmediate_operand")))]
23811 "(<MODE>mode != DFmode || TARGET_64BIT)
23812 && TARGET_80387 && TARGET_CMOVE
23813 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23814 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23815 && optimize_insn_for_speed_p ()"
23816 [(set (match_dup 4) (match_dup 5))
23817 (set (match_dup 0)
23818 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23819 {
23820 if (MEM_P (operands[2]))
23821 {
23822 operands[5] = operands[2];
23823 operands[2] = operands[4];
23824 }
23825 else if (MEM_P (operands[3]))
23826 {
23827 operands[5] = operands[3];
23828 operands[3] = operands[4];
23829 }
23830 else
23831 gcc_unreachable ();
23832 })
23833
23834 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23835 ;; the scalar versions to have only XMM registers as operands.
23836
23837 ;; XOP conditional move
23838 (define_insn "*xop_pcmov_<mode>"
23839 [(set (match_operand:MODEF 0 "register_operand" "=x")
23840 (if_then_else:MODEF
23841 (match_operand:MODEF 1 "register_operand" "x")
23842 (match_operand:MODEF 2 "register_operand" "x")
23843 (match_operand:MODEF 3 "register_operand" "x")))]
23844 "TARGET_XOP"
23845 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23846 [(set_attr "type" "sse4arg")
23847 (set_attr "mode" "TI")])
23848
23849 ;; These versions of the min/max patterns are intentionally ignorant of
23850 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23851 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23852 ;; are undefined in this condition, we're certain this is correct.
23853
23854 (define_insn "<code><mode>3"
23855 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23856 (smaxmin:MODEF
23857 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23858 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23859 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23860 "@
23861 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23862 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23863 [(set_attr "isa" "noavx,avx")
23864 (set_attr "prefix" "orig,vex")
23865 (set_attr "type" "sseadd")
23866 (set_attr "mode" "<MODE>")])
23867
23868 (define_insn "<code>hf3"
23869 [(set (match_operand:HF 0 "register_operand" "=v")
23870 (smaxmin:HF
23871 (match_operand:HF 1 "nonimmediate_operand" "%v")
23872 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23873 "TARGET_AVX512FP16"
23874 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23875 [(set_attr "prefix" "evex")
23876 (set_attr "type" "sseadd")
23877 (set_attr "mode" "HF")])
23878
23879 ;; These versions of the min/max patterns implement exactly the operations
23880 ;; min = (op1 < op2 ? op1 : op2)
23881 ;; max = (!(op1 < op2) ? op1 : op2)
23882 ;; Their operands are not commutative, and thus they may be used in the
23883 ;; presence of -0.0 and NaN.
23884
23885 (define_insn "*ieee_s<ieee_maxmin>hf3"
23886 [(set (match_operand:HF 0 "register_operand" "=v")
23887 (unspec:HF
23888 [(match_operand:HF 1 "register_operand" "v")
23889 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23890 IEEE_MAXMIN))]
23891 "TARGET_AVX512FP16"
23892 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23893 [(set_attr "prefix" "evex")
23894 (set_attr "type" "sseadd")
23895 (set_attr "mode" "HF")])
23896
23897 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23898 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23899 (unspec:MODEF
23900 [(match_operand:MODEF 1 "register_operand" "0,v")
23901 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23902 IEEE_MAXMIN))]
23903 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23904 "@
23905 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23906 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23907 [(set_attr "isa" "noavx,avx")
23908 (set_attr "prefix" "orig,maybe_evex")
23909 (set_attr "type" "sseadd")
23910 (set_attr "mode" "<MODE>")])
23911
23912 ;; Operands order in min/max instruction matters for signed zero and NANs.
23913 (define_insn_and_split "*ieee_max<mode>3_1"
23914 [(set (match_operand:MODEF 0 "register_operand")
23915 (unspec:MODEF
23916 [(match_operand:MODEF 1 "register_operand")
23917 (match_operand:MODEF 2 "register_operand")
23918 (lt:MODEF
23919 (match_operand:MODEF 3 "register_operand")
23920 (match_operand:MODEF 4 "register_operand"))]
23921 UNSPEC_BLENDV))]
23922 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23923 && (rtx_equal_p (operands[1], operands[3])
23924 && rtx_equal_p (operands[2], operands[4]))
23925 && ix86_pre_reload_split ()"
23926 "#"
23927 "&& 1"
23928 [(set (match_dup 0)
23929 (unspec:MODEF
23930 [(match_dup 2)
23931 (match_dup 1)]
23932 UNSPEC_IEEE_MAX))])
23933
23934 (define_insn_and_split "*ieee_min<mode>3_1"
23935 [(set (match_operand:MODEF 0 "register_operand")
23936 (unspec:MODEF
23937 [(match_operand:MODEF 1 "register_operand")
23938 (match_operand:MODEF 2 "register_operand")
23939 (lt:MODEF
23940 (match_operand:MODEF 3 "register_operand")
23941 (match_operand:MODEF 4 "register_operand"))]
23942 UNSPEC_BLENDV))]
23943 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23944 && (rtx_equal_p (operands[1], operands[4])
23945 && rtx_equal_p (operands[2], operands[3]))
23946 && ix86_pre_reload_split ()"
23947 "#"
23948 "&& 1"
23949 [(set (match_dup 0)
23950 (unspec:MODEF
23951 [(match_dup 2)
23952 (match_dup 1)]
23953 UNSPEC_IEEE_MIN))])
23954
23955 ;; Make two stack loads independent:
23956 ;; fld aa fld aa
23957 ;; fld %st(0) -> fld bb
23958 ;; fmul bb fmul %st(1), %st
23959 ;;
23960 ;; Actually we only match the last two instructions for simplicity.
23961
23962 (define_peephole2
23963 [(set (match_operand 0 "fp_register_operand")
23964 (match_operand 1 "fp_register_operand"))
23965 (set (match_dup 0)
23966 (match_operator 2 "binary_fp_operator"
23967 [(match_dup 0)
23968 (match_operand 3 "memory_operand")]))]
23969 "REGNO (operands[0]) != REGNO (operands[1])"
23970 [(set (match_dup 0) (match_dup 3))
23971 (set (match_dup 0)
23972 (match_op_dup 2
23973 [(match_dup 5) (match_dup 4)]))]
23974 {
23975 operands[4] = operands[0];
23976 operands[5] = operands[1];
23977
23978 /* The % modifier is not operational anymore in peephole2's, so we have to
23979 swap the operands manually in the case of addition and multiplication. */
23980 if (COMMUTATIVE_ARITH_P (operands[2]))
23981 std::swap (operands[4], operands[5]);
23982 })
23983
23984 (define_peephole2
23985 [(set (match_operand 0 "fp_register_operand")
23986 (match_operand 1 "fp_register_operand"))
23987 (set (match_dup 0)
23988 (match_operator 2 "binary_fp_operator"
23989 [(match_operand 3 "memory_operand")
23990 (match_dup 0)]))]
23991 "REGNO (operands[0]) != REGNO (operands[1])"
23992 [(set (match_dup 0) (match_dup 3))
23993 (set (match_dup 0)
23994 (match_op_dup 2
23995 [(match_dup 4) (match_dup 5)]))]
23996 {
23997 operands[4] = operands[0];
23998 operands[5] = operands[1];
23999
24000 /* The % modifier is not operational anymore in peephole2's, so we have to
24001 swap the operands manually in the case of addition and multiplication. */
24002 if (COMMUTATIVE_ARITH_P (operands[2]))
24003 std::swap (operands[4], operands[5]);
24004 })
24005
24006 ;; Conditional addition patterns
24007 (define_expand "add<mode>cc"
24008 [(match_operand:SWI 0 "register_operand")
24009 (match_operand 1 "ordered_comparison_operator")
24010 (match_operand:SWI 2 "register_operand")
24011 (match_operand:SWI 3 "const_int_operand")]
24012 ""
24013 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
24014
24015 ;; min/max patterns
24016
24017 (define_code_attr maxmin_rel
24018 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
24019
24020 (define_expand "<code><mode>3"
24021 [(parallel
24022 [(set (match_operand:SDWIM 0 "register_operand")
24023 (maxmin:SDWIM
24024 (match_operand:SDWIM 1 "register_operand")
24025 (match_operand:SDWIM 2 "general_operand")))
24026 (clobber (reg:CC FLAGS_REG))])]
24027 "TARGET_CMOVE
24028 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
24029
24030 (define_insn_and_split "*<code><dwi>3_doubleword"
24031 [(set (match_operand:<DWI> 0 "register_operand")
24032 (maxmin:<DWI>
24033 (match_operand:<DWI> 1 "register_operand")
24034 (match_operand:<DWI> 2 "general_operand")))
24035 (clobber (reg:CC FLAGS_REG))]
24036 "TARGET_CMOVE
24037 && ix86_pre_reload_split ()"
24038 "#"
24039 "&& 1"
24040 [(set (match_dup 0)
24041 (if_then_else:DWIH (match_dup 6)
24042 (match_dup 1)
24043 (match_dup 2)))
24044 (set (match_dup 3)
24045 (if_then_else:DWIH (match_dup 6)
24046 (match_dup 4)
24047 (match_dup 5)))]
24048 {
24049 operands[2] = force_reg (<DWI>mode, operands[2]);
24050
24051 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
24052
24053 rtx cmplo[2] = { operands[1], operands[2] };
24054 rtx cmphi[2] = { operands[4], operands[5] };
24055
24056 enum rtx_code code = <maxmin_rel>;
24057
24058 switch (code)
24059 {
24060 case LE: case LEU:
24061 std::swap (cmplo[0], cmplo[1]);
24062 std::swap (cmphi[0], cmphi[1]);
24063 code = swap_condition (code);
24064 /* FALLTHRU */
24065
24066 case GE: case GEU:
24067 {
24068 bool uns = (code == GEU);
24069 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
24070 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
24071
24072 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
24073
24074 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
24075 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
24076
24077 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
24078 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
24079
24080 break;
24081 }
24082
24083 default:
24084 gcc_unreachable ();
24085 }
24086 })
24087
24088 (define_insn_and_split "*<code><mode>3_1"
24089 [(set (match_operand:SWI 0 "register_operand")
24090 (maxmin:SWI
24091 (match_operand:SWI 1 "register_operand")
24092 (match_operand:SWI 2 "general_operand")))
24093 (clobber (reg:CC FLAGS_REG))]
24094 "TARGET_CMOVE
24095 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
24096 && ix86_pre_reload_split ()"
24097 "#"
24098 "&& 1"
24099 [(set (match_dup 0)
24100 (if_then_else:SWI (match_dup 3)
24101 (match_dup 1)
24102 (match_dup 2)))]
24103 {
24104 machine_mode mode = <MODE>mode;
24105 rtx cmp_op = operands[2];
24106
24107 operands[2] = force_reg (mode, cmp_op);
24108
24109 enum rtx_code code = <maxmin_rel>;
24110
24111 if (cmp_op == const1_rtx)
24112 {
24113 /* Convert smax (x, 1) into (x > 0 ? x : 1).
24114 Convert umax (x, 1) into (x != 0 ? x : 1).
24115 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
24116 cmp_op = const0_rtx;
24117 if (code == GE)
24118 code = GT;
24119 else if (code == GEU)
24120 code = NE;
24121 }
24122 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
24123 else if (cmp_op == constm1_rtx && code == LE)
24124 {
24125 cmp_op = const0_rtx;
24126 code = LT;
24127 }
24128 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
24129 else if (cmp_op == constm1_rtx && code == GE)
24130 cmp_op = const0_rtx;
24131 else if (cmp_op != const0_rtx)
24132 cmp_op = operands[2];
24133
24134 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
24135 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
24136
24137 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
24138 emit_insn (gen_rtx_SET (flags, tmp));
24139
24140 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
24141 })
24142
24143 ;; Avoid clearing a register between a flags setting comparison and its use,
24144 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
24145 (define_peephole2
24146 [(set (reg FLAGS_REG) (match_operand 0))
24147 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
24148 "peep2_regno_dead_p (0, FLAGS_REG)
24149 && !reg_overlap_mentioned_p (operands[1], operands[0])"
24150 [(set (match_dup 2) (match_dup 0))]
24151 {
24152 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
24153 ix86_expand_clear (operands[1]);
24154 })
24155
24156 ;; When optimizing for size, zeroing memory should use a register.
24157 (define_peephole2
24158 [(match_scratch:SWI48 0 "r")
24159 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24160 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24161 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24162 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24163 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24164 [(const_int 0)]
24165 {
24166 ix86_expand_clear (operands[0]);
24167 emit_move_insn (operands[1], operands[0]);
24168 emit_move_insn (operands[2], operands[0]);
24169 emit_move_insn (operands[3], operands[0]);
24170 ix86_last_zero_store_uid
24171 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24172 DONE;
24173 })
24174
24175 (define_peephole2
24176 [(match_scratch:SWI48 0 "r")
24177 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24178 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24179 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24180 [(const_int 0)]
24181 {
24182 ix86_expand_clear (operands[0]);
24183 emit_move_insn (operands[1], operands[0]);
24184 ix86_last_zero_store_uid
24185 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24186 DONE;
24187 })
24188
24189 (define_peephole2
24190 [(match_scratch:SWI48 0 "r")
24191 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24192 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
24193 [(const_int 0)]
24194 {
24195 ix86_expand_clear (operands[0]);
24196 ix86_last_zero_store_uid
24197 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24198 DONE;
24199 })
24200
24201 (define_peephole2
24202 [(set (match_operand:SWI48 5 "memory_operand")
24203 (match_operand:SWI48 0 "general_reg_operand"))
24204 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24205 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
24206 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
24207 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
24208 "optimize_insn_for_size_p ()
24209 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24210 [(const_int 0)]
24211 {
24212 emit_move_insn (operands[5], operands[0]);
24213 emit_move_insn (operands[1], operands[0]);
24214 emit_move_insn (operands[2], operands[0]);
24215 emit_move_insn (operands[3], operands[0]);
24216 ix86_last_zero_store_uid
24217 = INSN_UID (emit_move_insn (operands[4], operands[0]));
24218 DONE;
24219 })
24220
24221 (define_peephole2
24222 [(set (match_operand:SWI48 3 "memory_operand")
24223 (match_operand:SWI48 0 "general_reg_operand"))
24224 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
24225 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
24226 "optimize_insn_for_size_p ()
24227 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24228 [(const_int 0)]
24229 {
24230 emit_move_insn (operands[3], operands[0]);
24231 emit_move_insn (operands[1], operands[0]);
24232 ix86_last_zero_store_uid
24233 = INSN_UID (emit_move_insn (operands[2], operands[0]));
24234 DONE;
24235 })
24236
24237 (define_peephole2
24238 [(set (match_operand:SWI48 2 "memory_operand")
24239 (match_operand:SWI48 0 "general_reg_operand"))
24240 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
24241 "optimize_insn_for_size_p ()
24242 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
24243 [(const_int 0)]
24244 {
24245 emit_move_insn (operands[2], operands[0]);
24246 ix86_last_zero_store_uid
24247 = INSN_UID (emit_move_insn (operands[1], operands[0]));
24248 DONE;
24249 })
24250
24251 ;; Reload dislikes loading constants directly into class_likely_spilled
24252 ;; hard registers. Try to tidy things up here.
24253 (define_peephole2
24254 [(set (match_operand:SWI 0 "general_reg_operand")
24255 (match_operand:SWI 1 "x86_64_general_operand"))
24256 (set (match_operand:SWI 2 "general_reg_operand")
24257 (match_dup 0))]
24258 "peep2_reg_dead_p (2, operands[0])"
24259 [(set (match_dup 2) (match_dup 1))])
24260 \f
24261 ;; Misc patterns (?)
24262
24263 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
24264 ;; Otherwise there will be nothing to keep
24265 ;;
24266 ;; [(set (reg ebp) (reg esp))]
24267 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
24268 ;; (clobber (eflags)]
24269 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
24270 ;;
24271 ;; in proper program order.
24272
24273 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
24274 [(set (match_operand:P 0 "register_operand" "=r,r")
24275 (plus:P (match_operand:P 1 "register_operand" "0,r")
24276 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
24277 (clobber (reg:CC FLAGS_REG))
24278 (clobber (mem:BLK (scratch)))]
24279 ""
24280 {
24281 switch (get_attr_type (insn))
24282 {
24283 case TYPE_IMOV:
24284 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
24285
24286 case TYPE_ALU:
24287 gcc_assert (rtx_equal_p (operands[0], operands[1]));
24288 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
24289 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
24290
24291 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
24292
24293 default:
24294 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
24295 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
24296 }
24297 }
24298 [(set (attr "type")
24299 (cond [(and (eq_attr "alternative" "0")
24300 (not (match_test "TARGET_OPT_AGU")))
24301 (const_string "alu")
24302 (match_operand:<MODE> 2 "const0_operand")
24303 (const_string "imov")
24304 ]
24305 (const_string "lea")))
24306 (set (attr "length_immediate")
24307 (cond [(eq_attr "type" "imov")
24308 (const_string "0")
24309 (and (eq_attr "type" "alu")
24310 (match_operand 2 "const128_operand"))
24311 (const_string "1")
24312 ]
24313 (const_string "*")))
24314 (set_attr "mode" "<MODE>")])
24315
24316 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
24317 [(set (match_operand:P 0 "register_operand" "=r")
24318 (minus:P (match_operand:P 1 "register_operand" "0")
24319 (match_operand:P 2 "register_operand" "r")))
24320 (clobber (reg:CC FLAGS_REG))
24321 (clobber (mem:BLK (scratch)))]
24322 ""
24323 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
24324 [(set_attr "type" "alu")
24325 (set_attr "mode" "<MODE>")])
24326
24327 (define_insn "@allocate_stack_worker_probe_<mode>"
24328 [(set (match_operand:P 0 "register_operand" "=a")
24329 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24330 UNSPECV_STACK_PROBE))
24331 (clobber (reg:CC FLAGS_REG))]
24332 "ix86_target_stack_probe ()"
24333 "call\t___chkstk_ms"
24334 [(set_attr "type" "multi")
24335 (set_attr "length" "5")])
24336
24337 (define_expand "allocate_stack"
24338 [(match_operand 0 "register_operand")
24339 (match_operand 1 "general_operand")]
24340 "ix86_target_stack_probe ()"
24341 {
24342 rtx x;
24343
24344 #ifndef CHECK_STACK_LIMIT
24345 #define CHECK_STACK_LIMIT 0
24346 #endif
24347
24348 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
24349 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
24350 x = operands[1];
24351 else
24352 {
24353 x = copy_to_mode_reg (Pmode, operands[1]);
24354
24355 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
24356 }
24357
24358 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
24359 stack_pointer_rtx, 0, OPTAB_DIRECT);
24360
24361 if (x != stack_pointer_rtx)
24362 emit_move_insn (stack_pointer_rtx, x);
24363
24364 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
24365 DONE;
24366 })
24367
24368 (define_expand "probe_stack"
24369 [(match_operand 0 "memory_operand")]
24370 ""
24371 {
24372 emit_insn (gen_probe_stack_1
24373 (word_mode, operands[0], const0_rtx));
24374 DONE;
24375 })
24376
24377 ;; Use OR for stack probes, this is shorter.
24378 (define_insn "@probe_stack_1_<mode>"
24379 [(set (match_operand:W 0 "memory_operand" "=m")
24380 (unspec:W [(match_operand:W 1 "const0_operand")]
24381 UNSPEC_PROBE_STACK))
24382 (clobber (reg:CC FLAGS_REG))]
24383 ""
24384 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
24385 [(set_attr "type" "alu1")
24386 (set_attr "mode" "<MODE>")
24387 (set_attr "length_immediate" "1")])
24388
24389 (define_insn "@adjust_stack_and_probe_<mode>"
24390 [(set (match_operand:P 0 "register_operand" "=r")
24391 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
24392 UNSPECV_PROBE_STACK_RANGE))
24393 (set (reg:P SP_REG)
24394 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
24395 (clobber (reg:CC FLAGS_REG))
24396 (clobber (mem:BLK (scratch)))]
24397 ""
24398 "* return output_adjust_stack_and_probe (operands[0]);"
24399 [(set_attr "type" "multi")])
24400
24401 (define_insn "@probe_stack_range_<mode>"
24402 [(set (match_operand:P 0 "register_operand" "=r")
24403 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
24404 (match_operand:P 2 "const_int_operand")]
24405 UNSPECV_PROBE_STACK_RANGE))
24406 (clobber (reg:CC FLAGS_REG))]
24407 ""
24408 "* return output_probe_stack_range (operands[0], operands[2]);"
24409 [(set_attr "type" "multi")])
24410
24411 (define_expand "builtin_setjmp_receiver"
24412 [(label_ref (match_operand 0))]
24413 "!TARGET_64BIT && flag_pic"
24414 {
24415 #if TARGET_MACHO
24416 if (TARGET_MACHO)
24417 {
24418 rtx xops[3];
24419 rtx_code_label *label_rtx = gen_label_rtx ();
24420 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
24421 xops[0] = xops[1] = pic_offset_table_rtx;
24422 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
24423 ix86_expand_binary_operator (MINUS, SImode, xops);
24424 }
24425 else
24426 #endif
24427 emit_insn (gen_set_got (pic_offset_table_rtx));
24428 DONE;
24429 })
24430
24431 (define_expand "save_stack_nonlocal"
24432 [(set (match_operand 0 "memory_operand")
24433 (match_operand 1 "register_operand"))]
24434 ""
24435 {
24436 rtx stack_slot;
24437
24438 if (flag_cf_protection & CF_RETURN)
24439 {
24440 /* Copy shadow stack pointer to the first slot
24441 and stack pointer to the second slot. */
24442 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
24443 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
24444
24445 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24446 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24447 emit_move_insn (ssp_slot, reg_ssp);
24448 }
24449 else
24450 stack_slot = adjust_address (operands[0], Pmode, 0);
24451 emit_move_insn (stack_slot, operands[1]);
24452 DONE;
24453 })
24454
24455 (define_expand "restore_stack_nonlocal"
24456 [(set (match_operand 0 "register_operand" "")
24457 (match_operand 1 "memory_operand" ""))]
24458 ""
24459 {
24460 rtx stack_slot;
24461
24462 if (flag_cf_protection & CF_RETURN)
24463 {
24464 /* Restore shadow stack pointer from the first slot
24465 and stack pointer from the second slot. */
24466 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
24467 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
24468
24469 /* Get the current shadow stack pointer. The code below will check if
24470 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
24471 is a NOP. */
24472 rtx reg_ssp = force_reg (word_mode, const0_rtx);
24473 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
24474
24475 /* Compare through subtraction the saved and the current ssp
24476 to decide if ssp has to be adjusted. */
24477 reg_ssp = expand_simple_binop (word_mode, MINUS,
24478 reg_ssp, ssp_slot,
24479 reg_ssp, 1, OPTAB_DIRECT);
24480
24481 /* Compare and jump over adjustment code. */
24482 rtx noadj_label = gen_label_rtx ();
24483 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
24484 word_mode, 1, noadj_label);
24485
24486 /* Compute the number of frames to adjust. */
24487 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
24488 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
24489 NULL_RTX, 1);
24490
24491 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
24492 GEN_INT (exact_log2 (UNITS_PER_WORD)),
24493 reg_adj, 1, OPTAB_DIRECT);
24494
24495 /* Check if number of frames <= 255 so no loop is needed. */
24496 rtx inc_label = gen_label_rtx ();
24497 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
24498 ptr_mode, 1, inc_label);
24499
24500 /* Adjust the ssp in a loop. */
24501 rtx loop_label = gen_label_rtx ();
24502 emit_label (loop_label);
24503 LABEL_NUSES (loop_label) = 1;
24504
24505 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
24506 emit_insn (gen_incssp (word_mode, reg_255));
24507
24508 reg_adj = expand_simple_binop (ptr_mode, MINUS,
24509 reg_adj, GEN_INT (255),
24510 reg_adj, 1, OPTAB_DIRECT);
24511
24512 /* Compare and jump to the loop label. */
24513 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
24514 ptr_mode, 1, loop_label);
24515
24516 emit_label (inc_label);
24517 LABEL_NUSES (inc_label) = 1;
24518
24519 emit_insn (gen_incssp (word_mode, reg_ssp));
24520
24521 emit_label (noadj_label);
24522 LABEL_NUSES (noadj_label) = 1;
24523 }
24524 else
24525 stack_slot = adjust_address (operands[1], Pmode, 0);
24526 emit_move_insn (operands[0], stack_slot);
24527 DONE;
24528 })
24529
24530 (define_expand "stack_protect_set"
24531 [(match_operand 0 "memory_operand")
24532 (match_operand 1 "memory_operand")]
24533 ""
24534 {
24535 rtx scratch = gen_reg_rtx (word_mode);
24536
24537 emit_insn (gen_stack_protect_set_1
24538 (ptr_mode, word_mode, operands[0], operands[1], scratch));
24539 DONE;
24540 })
24541
24542 (define_insn "@stack_protect_set_1_<PTR:mode>_<W:mode>"
24543 [(set (match_operand:PTR 0 "memory_operand" "=m")
24544 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
24545 UNSPEC_SP_SET))
24546 (set (match_operand:W 2 "register_operand" "=&r") (const_int 0))
24547 (clobber (reg:CC FLAGS_REG))]
24548 ""
24549 {
24550 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%1, %<PTR:k>2|%<PTR:k>2, %1}",
24551 operands);
24552 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>2, %0|%0, %<PTR:k>2}",
24553 operands);
24554 if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24555 return "xor{l}\t%k2, %k2";
24556 else
24557 return "mov{l}\t{$0, %k2|%k2, 0}";
24558 }
24559 [(set_attr "type" "multi")])
24560
24561 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
24562 ;; immediately followed by *mov{s,d}i_internal, where we can avoid
24563 ;; the xor{l} above. We don't split this, so that scheduling or
24564 ;; anything else doesn't separate the *stack_protect_set* pattern from
24565 ;; the set of the register that overwrites the register with a new value.
24566
24567 (define_peephole2
24568 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24569 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24570 UNSPEC_SP_SET))
24571 (set (match_operand 2 "general_reg_operand") (const_int 0))
24572 (clobber (reg:CC FLAGS_REG))])
24573 (set (match_operand 3 "general_reg_operand")
24574 (match_operand 4 "const0_operand"))]
24575 "GET_MODE (operands[2]) == word_mode
24576 && GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD
24577 && peep2_reg_dead_p (0, operands[3])
24578 && peep2_reg_dead_p (1, operands[2])"
24579 [(parallel [(set (match_dup 0)
24580 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24581 (set (match_dup 3) (const_int 0))
24582 (clobber (reg:CC FLAGS_REG))])]
24583 "operands[3] = gen_lowpart (word_mode, operands[3]);")
24584
24585 (define_insn "*stack_protect_set_2_<mode>_si"
24586 [(set (match_operand:PTR 0 "memory_operand" "=m")
24587 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24588 UNSPEC_SP_SET))
24589 (set (match_operand:SI 1 "register_operand" "=&r")
24590 (match_operand:SI 2 "general_operand" "g"))]
24591 "reload_completed"
24592 {
24593 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24594 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24595 if (pic_32bit_operand (operands[2], SImode)
24596 || ix86_use_lea_for_mov (insn, operands + 1))
24597 return "lea{l}\t{%E2, %1|%1, %E2}";
24598 else
24599 return "mov{l}\t{%2, %1|%1, %2}";
24600 }
24601 [(set_attr "type" "multi")
24602 (set_attr "length" "24")])
24603
24604 (define_insn "*stack_protect_set_2_<mode>_di"
24605 [(set (match_operand:PTR 0 "memory_operand" "=m,m,m")
24606 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m,m,m")]
24607 UNSPEC_SP_SET))
24608 (set (match_operand:DI 1 "register_operand" "=&r,&r,&r")
24609 (match_operand:DI 2 "general_operand" "Z,rem,i"))]
24610 "TARGET_64BIT && reload_completed"
24611 {
24612 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24613 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24614 if (pic_32bit_operand (operands[2], DImode))
24615 return "lea{q}\t{%E2, %1|%1, %E2}";
24616 else if (which_alternative == 0)
24617 return "mov{l}\t{%k2, %k1|%k1, %k2}";
24618 else if (which_alternative == 2)
24619 return "movabs{q}\t{%2, %1|%1, %2}";
24620 else if (ix86_use_lea_for_mov (insn, operands + 1))
24621 return "lea{q}\t{%E2, %1|%1, %E2}";
24622 else
24623 return "mov{q}\t{%2, %1|%1, %2}";
24624 }
24625 [(set_attr "type" "multi")
24626 (set_attr "length" "24")])
24627
24628 (define_peephole2
24629 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24630 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24631 UNSPEC_SP_SET))
24632 (set (match_operand 2 "general_reg_operand") (const_int 0))
24633 (clobber (reg:CC FLAGS_REG))])
24634 (set (match_operand:SWI48 3 "general_reg_operand")
24635 (match_operand:SWI48 4 "general_gr_operand"))]
24636 "GET_MODE (operands[2]) == word_mode
24637 && peep2_reg_dead_p (0, operands[3])
24638 && peep2_reg_dead_p (1, operands[2])"
24639 [(parallel [(set (match_dup 0)
24640 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24641 (set (match_dup 3) (match_dup 4))])])
24642
24643 (define_peephole2
24644 [(set (match_operand:SWI48 3 "general_reg_operand")
24645 (match_operand:SWI48 4 "general_gr_operand"))
24646 (parallel [(set (match_operand:PTR 0 "memory_operand")
24647 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24648 UNSPEC_SP_SET))
24649 (set (match_operand 2 "general_reg_operand") (const_int 0))
24650 (clobber (reg:CC FLAGS_REG))])]
24651 "GET_MODE (operands[2]) == word_mode
24652 && peep2_reg_dead_p (0, operands[3])
24653 && peep2_reg_dead_p (2, operands[2])
24654 && !reg_mentioned_p (operands[3], operands[0])
24655 && !reg_mentioned_p (operands[3], operands[1])"
24656 [(parallel [(set (match_dup 0)
24657 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24658 (set (match_dup 3) (match_dup 4))])])
24659
24660 (define_insn "*stack_protect_set_3_<PTR:mode>_<SWI48:mode>"
24661 [(set (match_operand:PTR 0 "memory_operand" "=m")
24662 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24663 UNSPEC_SP_SET))
24664 (set (match_operand:SWI48 1 "register_operand" "=&r")
24665 (match_operand:SWI48 2 "address_no_seg_operand" "Ts"))]
24666 ""
24667 {
24668 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%3, %<PTR:k>1|%<PTR:k>1, %3}",
24669 operands);
24670 output_asm_insn ("mov{<PTR:imodesuffix>}\t{%<PTR:k>1, %0|%0, %<PTR:k>1}",
24671 operands);
24672 if (SImode_address_operand (operands[2], VOIDmode))
24673 {
24674 gcc_assert (TARGET_64BIT);
24675 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24676 }
24677 else
24678 return "lea{<SWI48:imodesuffix>}\t{%E2, %1|%1, %E2}";
24679 }
24680 [(set_attr "type" "multi")
24681 (set_attr "length" "24")])
24682
24683 (define_peephole2
24684 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24685 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24686 UNSPEC_SP_SET))
24687 (set (match_operand 2 "general_reg_operand") (const_int 0))
24688 (clobber (reg:CC FLAGS_REG))])
24689 (set (match_operand:SWI48 3 "general_reg_operand")
24690 (match_operand:SWI48 4 "address_no_seg_operand"))]
24691 "GET_MODE (operands[2]) == word_mode
24692 && peep2_reg_dead_p (0, operands[3])
24693 && peep2_reg_dead_p (1, operands[2])"
24694 [(parallel [(set (match_dup 0)
24695 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24696 (set (match_dup 3) (match_dup 4))])])
24697
24698 (define_insn "*stack_protect_set_4z_<mode>_di"
24699 [(set (match_operand:PTR 0 "memory_operand" "=m")
24700 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24701 UNSPEC_SP_SET))
24702 (set (match_operand:DI 1 "register_operand" "=&r")
24703 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24704 "TARGET_64BIT && reload_completed"
24705 {
24706 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24707 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24708 if (ix86_use_lea_for_mov (insn, operands + 1))
24709 return "lea{l}\t{%E2, %k1|%k1, %E2}";
24710 else
24711 return "mov{l}\t{%2, %k1|%k1, %2}";
24712 }
24713 [(set_attr "type" "multi")
24714 (set_attr "length" "24")])
24715
24716 (define_insn "*stack_protect_set_4s_<mode>_di"
24717 [(set (match_operand:PTR 0 "memory_operand" "=m")
24718 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
24719 UNSPEC_SP_SET))
24720 (set (match_operand:DI 1 "register_operand" "=&r")
24721 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))]
24722 "TARGET_64BIT && reload_completed"
24723 {
24724 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
24725 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
24726 return "movs{lq|x}\t{%2, %1|%1, %2}";
24727 }
24728 [(set_attr "type" "multi")
24729 (set_attr "length" "24")])
24730
24731 (define_peephole2
24732 [(parallel [(set (match_operand:PTR 0 "memory_operand")
24733 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
24734 UNSPEC_SP_SET))
24735 (set (match_operand 2 "general_reg_operand") (const_int 0))
24736 (clobber (reg:CC FLAGS_REG))])
24737 (set (match_operand:DI 3 "general_reg_operand")
24738 (any_extend:DI
24739 (match_operand:SI 4 "nonimmediate_gr_operand")))]
24740 "TARGET_64BIT
24741 && GET_MODE (operands[2]) == word_mode
24742 && peep2_reg_dead_p (0, operands[3])
24743 && peep2_reg_dead_p (1, operands[2])"
24744 [(parallel [(set (match_dup 0)
24745 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
24746 (set (match_dup 3)
24747 (any_extend:DI (match_dup 4)))])])
24748
24749 (define_expand "stack_protect_test"
24750 [(match_operand 0 "memory_operand")
24751 (match_operand 1 "memory_operand")
24752 (match_operand 2)]
24753 ""
24754 {
24755 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
24756
24757 emit_insn (gen_stack_protect_test_1
24758 (ptr_mode, flags, operands[0], operands[1]));
24759
24760 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
24761 flags, const0_rtx, operands[2]));
24762 DONE;
24763 })
24764
24765 (define_insn "@stack_protect_test_1_<mode>"
24766 [(set (match_operand:CCZ 0 "flags_reg_operand")
24767 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
24768 (match_operand:PTR 2 "memory_operand" "m")]
24769 UNSPEC_SP_TEST))
24770 (clobber (match_scratch:PTR 3 "=&r"))]
24771 ""
24772 {
24773 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
24774 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
24775 }
24776 [(set_attr "type" "multi")])
24777
24778 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
24779 ;; Do not split instructions with mask registers.
24780 (define_split
24781 [(set (match_operand 0 "general_reg_operand")
24782 (match_operator 3 "promotable_binary_operator"
24783 [(match_operand 1 "general_reg_operand")
24784 (match_operand 2 "aligned_operand")]))
24785 (clobber (reg:CC FLAGS_REG))]
24786 "! TARGET_PARTIAL_REG_STALL && reload_completed
24787 && ((GET_MODE (operands[0]) == HImode
24788 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
24789 /* ??? next two lines just !satisfies_constraint_K (...) */
24790 || !CONST_INT_P (operands[2])
24791 || satisfies_constraint_K (operands[2])))
24792 || (GET_MODE (operands[0]) == QImode
24793 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
24794 [(parallel [(set (match_dup 0)
24795 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24796 (clobber (reg:CC FLAGS_REG))])]
24797 {
24798 operands[0] = gen_lowpart (SImode, operands[0]);
24799 operands[1] = gen_lowpart (SImode, operands[1]);
24800 if (GET_CODE (operands[3]) != ASHIFT)
24801 operands[2] = gen_lowpart (SImode, operands[2]);
24802 operands[3] = shallow_copy_rtx (operands[3]);
24803 PUT_MODE (operands[3], SImode);
24804 })
24805
24806 ; Promote the QImode tests, as i386 has encoding of the AND
24807 ; instruction with 32-bit sign-extended immediate and thus the
24808 ; instruction size is unchanged, except in the %eax case for
24809 ; which it is increased by one byte, hence the ! optimize_size.
24810 (define_split
24811 [(set (match_operand 0 "flags_reg_operand")
24812 (match_operator 2 "compare_operator"
24813 [(and (match_operand 3 "aligned_operand")
24814 (match_operand 4 "const_int_operand"))
24815 (const_int 0)]))
24816 (set (match_operand 1 "register_operand")
24817 (and (match_dup 3) (match_dup 4)))]
24818 "! TARGET_PARTIAL_REG_STALL && reload_completed
24819 && optimize_insn_for_speed_p ()
24820 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24821 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24822 /* Ensure that the operand will remain sign-extended immediate. */
24823 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24824 [(parallel [(set (match_dup 0)
24825 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24826 (const_int 0)]))
24827 (set (match_dup 1)
24828 (and:SI (match_dup 3) (match_dup 4)))])]
24829 {
24830 operands[4]
24831 = gen_int_mode (INTVAL (operands[4])
24832 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24833 operands[1] = gen_lowpart (SImode, operands[1]);
24834 operands[3] = gen_lowpart (SImode, operands[3]);
24835 })
24836
24837 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24838 ; the TEST instruction with 32-bit sign-extended immediate and thus
24839 ; the instruction size would at least double, which is not what we
24840 ; want even with ! optimize_size.
24841 (define_split
24842 [(set (match_operand 0 "flags_reg_operand")
24843 (match_operator 1 "compare_operator"
24844 [(and (match_operand:HI 2 "aligned_operand")
24845 (match_operand:HI 3 "const_int_operand"))
24846 (const_int 0)]))]
24847 "! TARGET_PARTIAL_REG_STALL && reload_completed
24848 && ! TARGET_FAST_PREFIX
24849 && optimize_insn_for_speed_p ()
24850 /* Ensure that the operand will remain sign-extended immediate. */
24851 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24852 [(set (match_dup 0)
24853 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24854 (const_int 0)]))]
24855 {
24856 operands[3]
24857 = gen_int_mode (INTVAL (operands[3])
24858 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24859 operands[2] = gen_lowpart (SImode, operands[2]);
24860 })
24861
24862 (define_split
24863 [(set (match_operand 0 "register_operand")
24864 (neg (match_operand 1 "register_operand")))
24865 (clobber (reg:CC FLAGS_REG))]
24866 "! TARGET_PARTIAL_REG_STALL && reload_completed
24867 && (GET_MODE (operands[0]) == HImode
24868 || (GET_MODE (operands[0]) == QImode
24869 && (TARGET_PROMOTE_QImode
24870 || optimize_insn_for_size_p ())))"
24871 [(parallel [(set (match_dup 0)
24872 (neg:SI (match_dup 1)))
24873 (clobber (reg:CC FLAGS_REG))])]
24874 {
24875 operands[0] = gen_lowpart (SImode, operands[0]);
24876 operands[1] = gen_lowpart (SImode, operands[1]);
24877 })
24878
24879 ;; Do not split instructions with mask regs.
24880 (define_split
24881 [(set (match_operand 0 "general_reg_operand")
24882 (not (match_operand 1 "general_reg_operand")))]
24883 "! TARGET_PARTIAL_REG_STALL && reload_completed
24884 && (GET_MODE (operands[0]) == HImode
24885 || (GET_MODE (operands[0]) == QImode
24886 && (TARGET_PROMOTE_QImode
24887 || optimize_insn_for_size_p ())))"
24888 [(set (match_dup 0)
24889 (not:SI (match_dup 1)))]
24890 {
24891 operands[0] = gen_lowpart (SImode, operands[0]);
24892 operands[1] = gen_lowpart (SImode, operands[1]);
24893 })
24894 \f
24895 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24896 ;; transform a complex memory operation into two memory to register operations.
24897
24898 ;; Don't push memory operands
24899 (define_peephole2
24900 [(set (match_operand:SWI 0 "push_operand")
24901 (match_operand:SWI 1 "memory_operand"))
24902 (match_scratch:SWI 2 "<r>")]
24903 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24904 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24905 [(set (match_dup 2) (match_dup 1))
24906 (set (match_dup 0) (match_dup 2))])
24907
24908 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24909 ;; SImode pushes.
24910 (define_peephole2
24911 [(set (match_operand:SF 0 "push_operand")
24912 (match_operand:SF 1 "memory_operand"))
24913 (match_scratch:SF 2 "r")]
24914 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24915 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24916 [(set (match_dup 2) (match_dup 1))
24917 (set (match_dup 0) (match_dup 2))])
24918
24919 ;; Don't move an immediate directly to memory when the instruction
24920 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24921 (define_peephole2
24922 [(match_scratch:SWI124 1 "<r>")
24923 (set (match_operand:SWI124 0 "memory_operand")
24924 (const_int 0))]
24925 "optimize_insn_for_speed_p ()
24926 && ((<MODE>mode == HImode
24927 && TARGET_LCP_STALL)
24928 || (!TARGET_USE_MOV0
24929 && TARGET_SPLIT_LONG_MOVES
24930 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24931 && peep2_regno_dead_p (0, FLAGS_REG)"
24932 [(parallel [(set (match_dup 2) (const_int 0))
24933 (clobber (reg:CC FLAGS_REG))])
24934 (set (match_dup 0) (match_dup 1))]
24935 "operands[2] = gen_lowpart (SImode, operands[1]);")
24936
24937 (define_peephole2
24938 [(match_scratch:SWI124 2 "<r>")
24939 (set (match_operand:SWI124 0 "memory_operand")
24940 (match_operand:SWI124 1 "immediate_operand"))]
24941 "optimize_insn_for_speed_p ()
24942 && ((<MODE>mode == HImode
24943 && TARGET_LCP_STALL)
24944 || (TARGET_SPLIT_LONG_MOVES
24945 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24946 [(set (match_dup 2) (match_dup 1))
24947 (set (match_dup 0) (match_dup 2))])
24948
24949 ;; Don't compare memory with zero, load and use a test instead.
24950 (define_peephole2
24951 [(set (match_operand 0 "flags_reg_operand")
24952 (match_operator 1 "compare_operator"
24953 [(match_operand:SI 2 "memory_operand")
24954 (const_int 0)]))
24955 (match_scratch:SI 3 "r")]
24956 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24957 [(set (match_dup 3) (match_dup 2))
24958 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24959
24960 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24961 ;; Don't split NOTs with a displacement operand, because resulting XOR
24962 ;; will not be pairable anyway.
24963 ;;
24964 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24965 ;; represented using a modRM byte. The XOR replacement is long decoded,
24966 ;; so this split helps here as well.
24967 ;;
24968 ;; Note: Can't do this as a regular split because we can't get proper
24969 ;; lifetime information then.
24970
24971 (define_peephole2
24972 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24973 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24974 "optimize_insn_for_speed_p ()
24975 && ((TARGET_NOT_UNPAIRABLE
24976 && (!MEM_P (operands[0])
24977 || !memory_displacement_operand (operands[0], <MODE>mode)))
24978 || (TARGET_NOT_VECTORMODE
24979 && long_memory_operand (operands[0], <MODE>mode)))
24980 && peep2_regno_dead_p (0, FLAGS_REG)"
24981 [(parallel [(set (match_dup 0)
24982 (xor:SWI124 (match_dup 1) (const_int -1)))
24983 (clobber (reg:CC FLAGS_REG))])])
24984
24985 ;; Non pairable "test imm, reg" instructions can be translated to
24986 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24987 ;; byte opcode instead of two, have a short form for byte operands),
24988 ;; so do it for other CPUs as well. Given that the value was dead,
24989 ;; this should not create any new dependencies. Pass on the sub-word
24990 ;; versions if we're concerned about partial register stalls.
24991
24992 (define_peephole2
24993 [(set (match_operand 0 "flags_reg_operand")
24994 (match_operator 1 "compare_operator"
24995 [(and:SI (match_operand:SI 2 "register_operand")
24996 (match_operand:SI 3 "immediate_operand"))
24997 (const_int 0)]))]
24998 "ix86_match_ccmode (insn, CCNOmode)
24999 && (REGNO (operands[2]) != AX_REG
25000 || satisfies_constraint_K (operands[3]))
25001 && peep2_reg_dead_p (1, operands[2])"
25002 [(parallel
25003 [(set (match_dup 0)
25004 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
25005 (const_int 0)]))
25006 (set (match_dup 2)
25007 (and:SI (match_dup 2) (match_dup 3)))])])
25008
25009 ;; We don't need to handle HImode case, because it will be promoted to SImode
25010 ;; on ! TARGET_PARTIAL_REG_STALL
25011
25012 (define_peephole2
25013 [(set (match_operand 0 "flags_reg_operand")
25014 (match_operator 1 "compare_operator"
25015 [(and:QI (match_operand:QI 2 "register_operand")
25016 (match_operand:QI 3 "immediate_operand"))
25017 (const_int 0)]))]
25018 "! TARGET_PARTIAL_REG_STALL
25019 && ix86_match_ccmode (insn, CCNOmode)
25020 && REGNO (operands[2]) != AX_REG
25021 && peep2_reg_dead_p (1, operands[2])"
25022 [(parallel
25023 [(set (match_dup 0)
25024 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
25025 (const_int 0)]))
25026 (set (match_dup 2)
25027 (and:QI (match_dup 2) (match_dup 3)))])])
25028
25029 (define_peephole2
25030 [(set (match_operand 0 "flags_reg_operand")
25031 (match_operator 1 "compare_operator"
25032 [(and:QI
25033 (subreg:QI
25034 (match_operator:SWI248 4 "extract_operator"
25035 [(match_operand 2 "int248_register_operand")
25036 (const_int 8)
25037 (const_int 8)]) 0)
25038 (match_operand 3 "const_int_operand"))
25039 (const_int 0)]))]
25040 "! TARGET_PARTIAL_REG_STALL
25041 && ix86_match_ccmode (insn, CCNOmode)
25042 && REGNO (operands[2]) != AX_REG
25043 && peep2_reg_dead_p (1, operands[2])"
25044 [(parallel
25045 [(set (match_dup 0)
25046 (match_op_dup 1
25047 [(and:QI
25048 (subreg:QI
25049 (match_op_dup 4 [(match_dup 2)
25050 (const_int 8)
25051 (const_int 8)]) 0)
25052 (match_dup 3))
25053 (const_int 0)]))
25054 (set (zero_extract:SWI248 (match_dup 2)
25055 (const_int 8)
25056 (const_int 8))
25057 (subreg:SWI248
25058 (and:QI
25059 (subreg:QI
25060 (match_op_dup 4 [(match_dup 2)
25061 (const_int 8)
25062 (const_int 8)]) 0)
25063 (match_dup 3)) 0))])])
25064
25065 ;; Don't do logical operations with memory inputs.
25066 (define_peephole2
25067 [(match_scratch:SWI 2 "<r>")
25068 (parallel [(set (match_operand:SWI 0 "register_operand")
25069 (match_operator:SWI 3 "arith_or_logical_operator"
25070 [(match_dup 0)
25071 (match_operand:SWI 1 "memory_operand")]))
25072 (clobber (reg:CC FLAGS_REG))])]
25073 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
25074 [(set (match_dup 2) (match_dup 1))
25075 (parallel [(set (match_dup 0)
25076 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
25077 (clobber (reg:CC FLAGS_REG))])])
25078
25079 (define_peephole2
25080 [(match_scratch:SWI 2 "<r>")
25081 (parallel [(set (match_operand:SWI 0 "register_operand")
25082 (match_operator:SWI 3 "arith_or_logical_operator"
25083 [(match_operand:SWI 1 "memory_operand")
25084 (match_dup 0)]))
25085 (clobber (reg:CC FLAGS_REG))])]
25086 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
25087 [(set (match_dup 2) (match_dup 1))
25088 (parallel [(set (match_dup 0)
25089 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
25090 (clobber (reg:CC FLAGS_REG))])])
25091
25092 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
25093 ;; the memory address refers to the destination of the load!
25094
25095 (define_peephole2
25096 [(set (match_operand:SWI 0 "general_reg_operand")
25097 (match_operand:SWI 1 "general_reg_operand"))
25098 (parallel [(set (match_dup 0)
25099 (match_operator:SWI 3 "commutative_operator"
25100 [(match_dup 0)
25101 (match_operand:SWI 2 "memory_operand")]))
25102 (clobber (reg:CC FLAGS_REG))])]
25103 "REGNO (operands[0]) != REGNO (operands[1])
25104 && (<MODE>mode != QImode
25105 || any_QIreg_operand (operands[1], QImode))"
25106 [(set (match_dup 0) (match_dup 4))
25107 (parallel [(set (match_dup 0)
25108 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
25109 (clobber (reg:CC FLAGS_REG))])]
25110 {
25111 operands[4]
25112 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
25113 })
25114
25115 (define_peephole2
25116 [(set (match_operand 0 "mmx_reg_operand")
25117 (match_operand 1 "mmx_reg_operand"))
25118 (set (match_dup 0)
25119 (match_operator 3 "commutative_operator"
25120 [(match_dup 0)
25121 (match_operand 2 "memory_operand")]))]
25122 "REGNO (operands[0]) != REGNO (operands[1])"
25123 [(set (match_dup 0) (match_dup 2))
25124 (set (match_dup 0)
25125 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
25126
25127 (define_peephole2
25128 [(set (match_operand 0 "sse_reg_operand")
25129 (match_operand 1 "sse_reg_operand"))
25130 (set (match_dup 0)
25131 (match_operator 3 "commutative_operator"
25132 [(match_dup 0)
25133 (match_operand 2 "memory_operand")]))]
25134 "REGNO (operands[0]) != REGNO (operands[1])
25135 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
25136 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
25137 instructions require AVX512BW and AVX512VL, but with the original
25138 instructions it might require just AVX512VL.
25139 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
25140 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
25141 || TARGET_AVX512BW
25142 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
25143 || logic_operator (operands[3], VOIDmode))"
25144 [(set (match_dup 0) (match_dup 2))
25145 (set (match_dup 0)
25146 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
25147
25148 ; Don't do logical operations with memory outputs
25149 ;
25150 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
25151 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
25152 ; the same decoder scheduling characteristics as the original.
25153
25154 (define_peephole2
25155 [(match_scratch:SWI 2 "<r>")
25156 (parallel [(set (match_operand:SWI 0 "memory_operand")
25157 (match_operator:SWI 3 "arith_or_logical_operator"
25158 [(match_dup 0)
25159 (match_operand:SWI 1 "<nonmemory_operand>")]))
25160 (clobber (reg:CC FLAGS_REG))])]
25161 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
25162 [(set (match_dup 2) (match_dup 0))
25163 (parallel [(set (match_dup 2)
25164 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
25165 (clobber (reg:CC FLAGS_REG))])
25166 (set (match_dup 0) (match_dup 2))])
25167
25168 (define_peephole2
25169 [(match_scratch:SWI 2 "<r>")
25170 (parallel [(set (match_operand:SWI 0 "memory_operand")
25171 (match_operator:SWI 3 "arith_or_logical_operator"
25172 [(match_operand:SWI 1 "<nonmemory_operand>")
25173 (match_dup 0)]))
25174 (clobber (reg:CC FLAGS_REG))])]
25175 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
25176 [(set (match_dup 2) (match_dup 0))
25177 (parallel [(set (match_dup 2)
25178 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
25179 (clobber (reg:CC FLAGS_REG))])
25180 (set (match_dup 0) (match_dup 2))])
25181
25182 ;; Attempt to use arith or logical operations with memory outputs with
25183 ;; setting of flags.
25184 (define_peephole2
25185 [(set (match_operand:SWI 0 "register_operand")
25186 (match_operand:SWI 1 "memory_operand"))
25187 (parallel [(set (match_dup 0)
25188 (match_operator:SWI 3 "plusminuslogic_operator"
25189 [(match_dup 0)
25190 (match_operand:SWI 2 "<nonmemory_operand>")]))
25191 (clobber (reg:CC FLAGS_REG))])
25192 (set (match_dup 1) (match_dup 0))
25193 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25194 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25195 && peep2_reg_dead_p (4, operands[0])
25196 && !reg_overlap_mentioned_p (operands[0], operands[1])
25197 && !reg_overlap_mentioned_p (operands[0], operands[2])
25198 && (<MODE>mode != QImode
25199 || immediate_operand (operands[2], QImode)
25200 || any_QIreg_operand (operands[2], QImode))
25201 && ix86_match_ccmode (peep2_next_insn (3),
25202 (GET_CODE (operands[3]) == PLUS
25203 || GET_CODE (operands[3]) == MINUS)
25204 ? CCGOCmode : CCNOmode)"
25205 [(parallel [(set (match_dup 4) (match_dup 6))
25206 (set (match_dup 1) (match_dup 5))])]
25207 {
25208 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
25209 operands[5]
25210 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25211 copy_rtx (operands[1]),
25212 operands[2]);
25213 operands[6]
25214 = gen_rtx_COMPARE (GET_MODE (operands[4]),
25215 copy_rtx (operands[5]),
25216 const0_rtx);
25217 })
25218
25219 ;; Likewise for cmpelim optimized pattern.
25220 (define_peephole2
25221 [(set (match_operand:SWI 0 "register_operand")
25222 (match_operand:SWI 1 "memory_operand"))
25223 (parallel [(set (reg FLAGS_REG)
25224 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25225 [(match_dup 0)
25226 (match_operand:SWI 2 "<nonmemory_operand>")])
25227 (const_int 0)))
25228 (set (match_dup 0) (match_dup 3))])
25229 (set (match_dup 1) (match_dup 0))]
25230 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25231 && peep2_reg_dead_p (3, operands[0])
25232 && !reg_overlap_mentioned_p (operands[0], operands[1])
25233 && !reg_overlap_mentioned_p (operands[0], operands[2])
25234 && ix86_match_ccmode (peep2_next_insn (1),
25235 (GET_CODE (operands[3]) == PLUS
25236 || GET_CODE (operands[3]) == MINUS)
25237 ? CCGOCmode : CCNOmode)"
25238 [(parallel [(set (match_dup 4) (match_dup 6))
25239 (set (match_dup 1) (match_dup 5))])]
25240 {
25241 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25242 operands[5]
25243 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25244 copy_rtx (operands[1]), operands[2]);
25245 operands[6]
25246 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
25247 const0_rtx);
25248 })
25249
25250 ;; Likewise for instances where we have a lea pattern.
25251 (define_peephole2
25252 [(set (match_operand:SWI 0 "register_operand")
25253 (match_operand:SWI 1 "memory_operand"))
25254 (set (match_operand:<LEAMODE> 3 "register_operand")
25255 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
25256 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
25257 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
25258 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25259 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25260 && REGNO (operands[4]) == REGNO (operands[0])
25261 && REGNO (operands[5]) == REGNO (operands[3])
25262 && peep2_reg_dead_p (4, operands[3])
25263 && ((REGNO (operands[0]) == REGNO (operands[3]))
25264 || peep2_reg_dead_p (2, operands[0]))
25265 && !reg_overlap_mentioned_p (operands[0], operands[1])
25266 && !reg_overlap_mentioned_p (operands[3], operands[1])
25267 && !reg_overlap_mentioned_p (operands[0], operands[2])
25268 && (<MODE>mode != QImode
25269 || immediate_operand (operands[2], QImode)
25270 || any_QIreg_operand (operands[2], QImode))
25271 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
25272 [(parallel [(set (match_dup 6) (match_dup 8))
25273 (set (match_dup 1) (match_dup 7))])]
25274 {
25275 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
25276 operands[7]
25277 = gen_rtx_PLUS (<MODE>mode,
25278 copy_rtx (operands[1]),
25279 gen_lowpart (<MODE>mode, operands[2]));
25280 operands[8]
25281 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25282 copy_rtx (operands[7]),
25283 const0_rtx);
25284 })
25285
25286 (define_peephole2
25287 [(parallel [(set (match_operand:SWI 0 "register_operand")
25288 (match_operator:SWI 2 "plusminuslogic_operator"
25289 [(match_dup 0)
25290 (match_operand:SWI 1 "memory_operand")]))
25291 (clobber (reg:CC FLAGS_REG))])
25292 (set (match_dup 1) (match_dup 0))
25293 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25294 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25295 && COMMUTATIVE_ARITH_P (operands[2])
25296 && peep2_reg_dead_p (3, operands[0])
25297 && !reg_overlap_mentioned_p (operands[0], operands[1])
25298 && ix86_match_ccmode (peep2_next_insn (2),
25299 GET_CODE (operands[2]) == PLUS
25300 ? CCGOCmode : CCNOmode)"
25301 [(parallel [(set (match_dup 3) (match_dup 5))
25302 (set (match_dup 1) (match_dup 4))])]
25303 {
25304 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
25305 operands[4]
25306 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25307 copy_rtx (operands[1]),
25308 operands[0]);
25309 operands[5]
25310 = gen_rtx_COMPARE (GET_MODE (operands[3]),
25311 copy_rtx (operands[4]),
25312 const0_rtx);
25313 })
25314
25315 ;; Likewise for cmpelim optimized pattern.
25316 (define_peephole2
25317 [(parallel [(set (reg FLAGS_REG)
25318 (compare (match_operator:SWI 2 "plusminuslogic_operator"
25319 [(match_operand:SWI 0 "register_operand")
25320 (match_operand:SWI 1 "memory_operand")])
25321 (const_int 0)))
25322 (set (match_dup 0) (match_dup 2))])
25323 (set (match_dup 1) (match_dup 0))]
25324 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25325 && COMMUTATIVE_ARITH_P (operands[2])
25326 && peep2_reg_dead_p (2, operands[0])
25327 && !reg_overlap_mentioned_p (operands[0], operands[1])
25328 && ix86_match_ccmode (peep2_next_insn (0),
25329 GET_CODE (operands[2]) == PLUS
25330 ? CCGOCmode : CCNOmode)"
25331 [(parallel [(set (match_dup 3) (match_dup 5))
25332 (set (match_dup 1) (match_dup 4))])]
25333 {
25334 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
25335 operands[4]
25336 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
25337 copy_rtx (operands[1]), operands[0]);
25338 operands[5]
25339 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
25340 const0_rtx);
25341 })
25342
25343 (define_peephole2
25344 [(set (match_operand:SWI12 0 "register_operand")
25345 (match_operand:SWI12 1 "memory_operand"))
25346 (parallel [(set (match_operand:SI 4 "register_operand")
25347 (match_operator:SI 3 "plusminuslogic_operator"
25348 [(match_dup 4)
25349 (match_operand:SI 2 "nonmemory_operand")]))
25350 (clobber (reg:CC FLAGS_REG))])
25351 (set (match_dup 1) (match_dup 0))
25352 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
25353 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25354 && REGNO (operands[0]) == REGNO (operands[4])
25355 && peep2_reg_dead_p (4, operands[0])
25356 && (<MODE>mode != QImode
25357 || immediate_operand (operands[2], SImode)
25358 || any_QIreg_operand (operands[2], SImode))
25359 && !reg_overlap_mentioned_p (operands[0], operands[1])
25360 && !reg_overlap_mentioned_p (operands[0], operands[2])
25361 && ix86_match_ccmode (peep2_next_insn (3),
25362 (GET_CODE (operands[3]) == PLUS
25363 || GET_CODE (operands[3]) == MINUS)
25364 ? CCGOCmode : CCNOmode)"
25365 [(parallel [(set (match_dup 5) (match_dup 7))
25366 (set (match_dup 1) (match_dup 6))])]
25367 {
25368 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
25369 operands[6]
25370 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25371 copy_rtx (operands[1]),
25372 gen_lowpart (<MODE>mode, operands[2]));
25373 operands[7]
25374 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25375 copy_rtx (operands[6]),
25376 const0_rtx);
25377 })
25378
25379 ;; peephole2 comes before regcprop, so deal also with a case that
25380 ;; would be cleaned up by regcprop.
25381 (define_peephole2
25382 [(set (match_operand:SWI 0 "register_operand")
25383 (match_operand:SWI 1 "memory_operand"))
25384 (parallel [(set (match_dup 0)
25385 (match_operator:SWI 3 "plusminuslogic_operator"
25386 [(match_dup 0)
25387 (match_operand:SWI 2 "<nonmemory_operand>")]))
25388 (clobber (reg:CC FLAGS_REG))])
25389 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25390 (set (match_dup 1) (match_dup 4))
25391 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
25392 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25393 && peep2_reg_dead_p (3, operands[0])
25394 && peep2_reg_dead_p (5, operands[4])
25395 && !reg_overlap_mentioned_p (operands[0], operands[1])
25396 && !reg_overlap_mentioned_p (operands[0], operands[2])
25397 && !reg_overlap_mentioned_p (operands[4], operands[1])
25398 && (<MODE>mode != QImode
25399 || immediate_operand (operands[2], QImode)
25400 || any_QIreg_operand (operands[2], QImode))
25401 && ix86_match_ccmode (peep2_next_insn (4),
25402 (GET_CODE (operands[3]) == PLUS
25403 || GET_CODE (operands[3]) == MINUS)
25404 ? CCGOCmode : CCNOmode)"
25405 [(parallel [(set (match_dup 5) (match_dup 7))
25406 (set (match_dup 1) (match_dup 6))])]
25407 {
25408 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
25409 operands[6]
25410 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25411 copy_rtx (operands[1]),
25412 operands[2]);
25413 operands[7]
25414 = gen_rtx_COMPARE (GET_MODE (operands[5]),
25415 copy_rtx (operands[6]),
25416 const0_rtx);
25417 })
25418
25419 (define_peephole2
25420 [(set (match_operand:SWI12 0 "register_operand")
25421 (match_operand:SWI12 1 "memory_operand"))
25422 (parallel [(set (match_operand:SI 4 "register_operand")
25423 (match_operator:SI 3 "plusminuslogic_operator"
25424 [(match_dup 4)
25425 (match_operand:SI 2 "nonmemory_operand")]))
25426 (clobber (reg:CC FLAGS_REG))])
25427 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
25428 (set (match_dup 1) (match_dup 5))
25429 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
25430 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25431 && REGNO (operands[0]) == REGNO (operands[4])
25432 && peep2_reg_dead_p (3, operands[0])
25433 && peep2_reg_dead_p (5, operands[5])
25434 && (<MODE>mode != QImode
25435 || immediate_operand (operands[2], SImode)
25436 || any_QIreg_operand (operands[2], SImode))
25437 && !reg_overlap_mentioned_p (operands[0], operands[1])
25438 && !reg_overlap_mentioned_p (operands[0], operands[2])
25439 && !reg_overlap_mentioned_p (operands[5], operands[1])
25440 && ix86_match_ccmode (peep2_next_insn (4),
25441 (GET_CODE (operands[3]) == PLUS
25442 || GET_CODE (operands[3]) == MINUS)
25443 ? CCGOCmode : CCNOmode)"
25444 [(parallel [(set (match_dup 6) (match_dup 8))
25445 (set (match_dup 1) (match_dup 7))])]
25446 {
25447 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
25448 operands[7]
25449 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
25450 copy_rtx (operands[1]),
25451 gen_lowpart (<MODE>mode, operands[2]));
25452 operands[8]
25453 = gen_rtx_COMPARE (GET_MODE (operands[6]),
25454 copy_rtx (operands[7]),
25455 const0_rtx);
25456 })
25457
25458 ;; Likewise for cmpelim optimized pattern.
25459 (define_peephole2
25460 [(set (match_operand:SWI 0 "register_operand")
25461 (match_operand:SWI 1 "memory_operand"))
25462 (parallel [(set (reg FLAGS_REG)
25463 (compare (match_operator:SWI 3 "plusminuslogic_operator"
25464 [(match_dup 0)
25465 (match_operand:SWI 2 "<nonmemory_operand>")])
25466 (const_int 0)))
25467 (set (match_dup 0) (match_dup 3))])
25468 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
25469 (set (match_dup 1) (match_dup 4))]
25470 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25471 && peep2_reg_dead_p (3, operands[0])
25472 && peep2_reg_dead_p (4, operands[4])
25473 && !reg_overlap_mentioned_p (operands[0], operands[1])
25474 && !reg_overlap_mentioned_p (operands[0], operands[2])
25475 && !reg_overlap_mentioned_p (operands[4], operands[1])
25476 && ix86_match_ccmode (peep2_next_insn (1),
25477 (GET_CODE (operands[3]) == PLUS
25478 || GET_CODE (operands[3]) == MINUS)
25479 ? CCGOCmode : CCNOmode)"
25480 [(parallel [(set (match_dup 5) (match_dup 7))
25481 (set (match_dup 1) (match_dup 6))])]
25482 {
25483 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
25484 operands[6]
25485 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
25486 copy_rtx (operands[1]), operands[2]);
25487 operands[7]
25488 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
25489 const0_rtx);
25490 })
25491
25492 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
25493 ;; into x = z; x ^= y; x != z
25494 (define_peephole2
25495 [(set (match_operand:SWI 0 "register_operand")
25496 (match_operand:SWI 1 "memory_operand"))
25497 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
25498 (parallel [(set (match_operand:SWI 4 "register_operand")
25499 (xor:SWI (match_dup 4)
25500 (match_operand:SWI 2 "<nonmemory_operand>")))
25501 (clobber (reg:CC FLAGS_REG))])
25502 (set (match_dup 1) (match_dup 4))
25503 (set (reg:CCZ FLAGS_REG)
25504 (compare:CCZ (match_operand:SWI 5 "register_operand")
25505 (match_operand:SWI 6 "<nonmemory_operand>")))]
25506 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25507 && (REGNO (operands[4]) == REGNO (operands[0])
25508 || REGNO (operands[4]) == REGNO (operands[3]))
25509 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25510 ? 3 : 0], operands[5])
25511 ? rtx_equal_p (operands[2], operands[6])
25512 : rtx_equal_p (operands[2], operands[5])
25513 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
25514 ? 3 : 0], operands[6]))
25515 && peep2_reg_dead_p (4, operands[4])
25516 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
25517 ? 3 : 0])
25518 && !reg_overlap_mentioned_p (operands[0], operands[1])
25519 && !reg_overlap_mentioned_p (operands[0], operands[2])
25520 && !reg_overlap_mentioned_p (operands[3], operands[0])
25521 && !reg_overlap_mentioned_p (operands[3], operands[1])
25522 && !reg_overlap_mentioned_p (operands[3], operands[2])
25523 && (<MODE>mode != QImode
25524 || immediate_operand (operands[2], QImode)
25525 || any_QIreg_operand (operands[2], QImode))"
25526 [(parallel [(set (match_dup 7) (match_dup 9))
25527 (set (match_dup 1) (match_dup 8))])]
25528 {
25529 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
25530 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25531 operands[2]);
25532 operands[9]
25533 = gen_rtx_COMPARE (GET_MODE (operands[7]),
25534 copy_rtx (operands[8]),
25535 const0_rtx);
25536 })
25537
25538 (define_peephole2
25539 [(set (match_operand:SWI12 0 "register_operand")
25540 (match_operand:SWI12 1 "memory_operand"))
25541 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
25542 (parallel [(set (match_operand:SI 4 "register_operand")
25543 (xor:SI (match_dup 4)
25544 (match_operand:SI 2 "<nonmemory_operand>")))
25545 (clobber (reg:CC FLAGS_REG))])
25546 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
25547 (set (reg:CCZ FLAGS_REG)
25548 (compare:CCZ (match_operand:SWI12 6 "register_operand")
25549 (match_operand:SWI12 7 "<nonmemory_operand>")))]
25550 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
25551 && (REGNO (operands[5]) == REGNO (operands[0])
25552 || REGNO (operands[5]) == REGNO (operands[3]))
25553 && REGNO (operands[5]) == REGNO (operands[4])
25554 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25555 ? 3 : 0], operands[6])
25556 ? (REG_P (operands[2])
25557 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
25558 : rtx_equal_p (operands[2], operands[7]))
25559 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
25560 ? 3 : 0], operands[7])
25561 && REG_P (operands[2])
25562 && REGNO (operands[2]) == REGNO (operands[6])))
25563 && peep2_reg_dead_p (4, operands[5])
25564 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
25565 ? 3 : 0])
25566 && !reg_overlap_mentioned_p (operands[0], operands[1])
25567 && !reg_overlap_mentioned_p (operands[0], operands[2])
25568 && !reg_overlap_mentioned_p (operands[3], operands[0])
25569 && !reg_overlap_mentioned_p (operands[3], operands[1])
25570 && !reg_overlap_mentioned_p (operands[3], operands[2])
25571 && (<MODE>mode != QImode
25572 || immediate_operand (operands[2], SImode)
25573 || any_QIreg_operand (operands[2], SImode))"
25574 [(parallel [(set (match_dup 8) (match_dup 10))
25575 (set (match_dup 1) (match_dup 9))])]
25576 {
25577 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
25578 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
25579 gen_lowpart (<MODE>mode, operands[2]));
25580 operands[10]
25581 = gen_rtx_COMPARE (GET_MODE (operands[8]),
25582 copy_rtx (operands[9]),
25583 const0_rtx);
25584 })
25585
25586 ;; Attempt to optimize away memory stores of values the memory already
25587 ;; has. See PR79593.
25588 (define_peephole2
25589 [(set (match_operand 0 "register_operand")
25590 (match_operand 1 "memory_operand"))
25591 (set (match_operand 2 "memory_operand") (match_dup 0))]
25592 "!MEM_VOLATILE_P (operands[1])
25593 && !MEM_VOLATILE_P (operands[2])
25594 && rtx_equal_p (operands[1], operands[2])
25595 && !reg_overlap_mentioned_p (operands[0], operands[2])"
25596 [(set (match_dup 0) (match_dup 1))])
25597
25598 ;; Attempt to always use XOR for zeroing registers (including FP modes).
25599 (define_peephole2
25600 [(set (match_operand 0 "general_reg_operand")
25601 (match_operand 1 "const0_operand"))]
25602 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
25603 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25604 && peep2_regno_dead_p (0, FLAGS_REG)"
25605 [(parallel [(set (match_dup 0) (const_int 0))
25606 (clobber (reg:CC FLAGS_REG))])]
25607 "operands[0] = gen_lowpart (word_mode, operands[0]);")
25608
25609 (define_peephole2
25610 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
25611 (const_int 0))]
25612 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
25613 && peep2_regno_dead_p (0, FLAGS_REG)"
25614 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
25615 (clobber (reg:CC FLAGS_REG))])])
25616
25617 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
25618 (define_peephole2
25619 [(set (match_operand:SWI248 0 "general_reg_operand")
25620 (const_int -1))]
25621 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
25622 && peep2_regno_dead_p (0, FLAGS_REG)"
25623 [(parallel [(set (match_dup 0) (const_int -1))
25624 (clobber (reg:CC FLAGS_REG))])]
25625 {
25626 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
25627 operands[0] = gen_lowpart (SImode, operands[0]);
25628 })
25629
25630 ;; Attempt to convert simple lea to add/shift.
25631 ;; These can be created by move expanders.
25632 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
25633 ;; relevant lea instructions were already split.
25634
25635 (define_peephole2
25636 [(set (match_operand:SWI48 0 "register_operand")
25637 (plus:SWI48 (match_dup 0)
25638 (match_operand:SWI48 1 "<nonmemory_operand>")))]
25639 "!TARGET_OPT_AGU
25640 && peep2_regno_dead_p (0, FLAGS_REG)"
25641 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25642 (clobber (reg:CC FLAGS_REG))])])
25643
25644 (define_peephole2
25645 [(set (match_operand:SWI48 0 "register_operand")
25646 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
25647 (match_dup 0)))]
25648 "!TARGET_OPT_AGU
25649 && peep2_regno_dead_p (0, FLAGS_REG)"
25650 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
25651 (clobber (reg:CC FLAGS_REG))])])
25652
25653 (define_peephole2
25654 [(set (match_operand:DI 0 "register_operand")
25655 (zero_extend:DI
25656 (plus:SI (match_operand:SI 1 "register_operand")
25657 (match_operand:SI 2 "nonmemory_operand"))))]
25658 "TARGET_64BIT && !TARGET_OPT_AGU
25659 && REGNO (operands[0]) == REGNO (operands[1])
25660 && peep2_regno_dead_p (0, FLAGS_REG)"
25661 [(parallel [(set (match_dup 0)
25662 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
25663 (clobber (reg:CC FLAGS_REG))])])
25664
25665 (define_peephole2
25666 [(set (match_operand:DI 0 "register_operand")
25667 (zero_extend:DI
25668 (plus:SI (match_operand:SI 1 "nonmemory_operand")
25669 (match_operand:SI 2 "register_operand"))))]
25670 "TARGET_64BIT && !TARGET_OPT_AGU
25671 && REGNO (operands[0]) == REGNO (operands[2])
25672 && peep2_regno_dead_p (0, FLAGS_REG)"
25673 [(parallel [(set (match_dup 0)
25674 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
25675 (clobber (reg:CC FLAGS_REG))])])
25676
25677 (define_peephole2
25678 [(set (match_operand:SWI48 0 "register_operand")
25679 (mult:SWI48 (match_dup 0)
25680 (match_operand:SWI48 1 "const_int_operand")))]
25681 "pow2p_hwi (INTVAL (operands[1]))
25682 && peep2_regno_dead_p (0, FLAGS_REG)"
25683 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
25684 (clobber (reg:CC FLAGS_REG))])]
25685 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
25686
25687 (define_peephole2
25688 [(set (match_operand:DI 0 "register_operand")
25689 (zero_extend:DI
25690 (mult:SI (match_operand:SI 1 "register_operand")
25691 (match_operand:SI 2 "const_int_operand"))))]
25692 "TARGET_64BIT
25693 && pow2p_hwi (INTVAL (operands[2]))
25694 && REGNO (operands[0]) == REGNO (operands[1])
25695 && peep2_regno_dead_p (0, FLAGS_REG)"
25696 [(parallel [(set (match_dup 0)
25697 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
25698 (clobber (reg:CC FLAGS_REG))])]
25699 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
25700
25701 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
25702 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
25703 ;; On many CPUs it is also faster, since special hardware to avoid esp
25704 ;; dependencies is present.
25705
25706 ;; While some of these conversions may be done using splitters, we use
25707 ;; peepholes in order to allow combine_stack_adjustments pass to see
25708 ;; nonobfuscated RTL.
25709
25710 ;; Convert prologue esp subtractions to push.
25711 ;; We need register to push. In order to keep verify_flow_info happy we have
25712 ;; two choices
25713 ;; - use scratch and clobber it in order to avoid dependencies
25714 ;; - use already live register
25715 ;; We can't use the second way right now, since there is no reliable way how to
25716 ;; verify that given register is live. First choice will also most likely in
25717 ;; fewer dependencies. On the place of esp adjustments it is very likely that
25718 ;; call clobbered registers are dead. We may want to use base pointer as an
25719 ;; alternative when no register is available later.
25720
25721 (define_peephole2
25722 [(match_scratch:W 1 "r")
25723 (parallel [(set (reg:P SP_REG)
25724 (plus:P (reg:P SP_REG)
25725 (match_operand:P 0 "const_int_operand")))
25726 (clobber (reg:CC FLAGS_REG))
25727 (clobber (mem:BLK (scratch)))])]
25728 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25729 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25730 && !ix86_red_zone_used"
25731 [(clobber (match_dup 1))
25732 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25733 (clobber (mem:BLK (scratch)))])])
25734
25735 (define_peephole2
25736 [(match_scratch:W 1 "r")
25737 (parallel [(set (reg:P SP_REG)
25738 (plus:P (reg:P SP_REG)
25739 (match_operand:P 0 "const_int_operand")))
25740 (clobber (reg:CC FLAGS_REG))
25741 (clobber (mem:BLK (scratch)))])]
25742 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25743 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25744 && !ix86_red_zone_used"
25745 [(clobber (match_dup 1))
25746 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25747 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25748 (clobber (mem:BLK (scratch)))])])
25749
25750 ;; Convert esp subtractions to push.
25751 (define_peephole2
25752 [(match_scratch:W 1 "r")
25753 (parallel [(set (reg:P SP_REG)
25754 (plus:P (reg:P SP_REG)
25755 (match_operand:P 0 "const_int_operand")))
25756 (clobber (reg:CC FLAGS_REG))])]
25757 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
25758 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
25759 && !ix86_red_zone_used"
25760 [(clobber (match_dup 1))
25761 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25762
25763 (define_peephole2
25764 [(match_scratch:W 1 "r")
25765 (parallel [(set (reg:P SP_REG)
25766 (plus:P (reg:P SP_REG)
25767 (match_operand:P 0 "const_int_operand")))
25768 (clobber (reg:CC FLAGS_REG))])]
25769 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
25770 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
25771 && !ix86_red_zone_used"
25772 [(clobber (match_dup 1))
25773 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
25774 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
25775
25776 ;; Convert epilogue deallocator to pop.
25777 (define_peephole2
25778 [(match_scratch:W 1 "r")
25779 (parallel [(set (reg:P SP_REG)
25780 (plus:P (reg:P SP_REG)
25781 (match_operand:P 0 "const_int_operand")))
25782 (clobber (reg:CC FLAGS_REG))
25783 (clobber (mem:BLK (scratch)))])]
25784 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
25785 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25786 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25787 (clobber (mem:BLK (scratch)))])])
25788
25789 ;; Two pops case is tricky, since pop causes dependency
25790 ;; on destination register. We use two registers if available.
25791 (define_peephole2
25792 [(match_scratch:W 1 "r")
25793 (match_scratch:W 2 "r")
25794 (parallel [(set (reg:P SP_REG)
25795 (plus:P (reg:P SP_REG)
25796 (match_operand:P 0 "const_int_operand")))
25797 (clobber (reg:CC FLAGS_REG))
25798 (clobber (mem:BLK (scratch)))])]
25799 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25800 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25801 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25802 (clobber (mem:BLK (scratch)))])
25803 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25804
25805 (define_peephole2
25806 [(match_scratch:W 1 "r")
25807 (parallel [(set (reg:P SP_REG)
25808 (plus:P (reg:P SP_REG)
25809 (match_operand:P 0 "const_int_operand")))
25810 (clobber (reg:CC FLAGS_REG))
25811 (clobber (mem:BLK (scratch)))])]
25812 "optimize_insn_for_size_p ()
25813 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25814 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25815 (clobber (mem:BLK (scratch)))])
25816 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25817
25818 ;; Convert esp additions to pop.
25819 (define_peephole2
25820 [(match_scratch:W 1 "r")
25821 (parallel [(set (reg:P SP_REG)
25822 (plus:P (reg:P SP_REG)
25823 (match_operand:P 0 "const_int_operand")))
25824 (clobber (reg:CC FLAGS_REG))])]
25825 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25826 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25827
25828 ;; Two pops case is tricky, since pop causes dependency
25829 ;; on destination register. We use two registers if available.
25830 (define_peephole2
25831 [(match_scratch:W 1 "r")
25832 (match_scratch:W 2 "r")
25833 (parallel [(set (reg:P SP_REG)
25834 (plus:P (reg:P SP_REG)
25835 (match_operand:P 0 "const_int_operand")))
25836 (clobber (reg:CC FLAGS_REG))])]
25837 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25838 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25839 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25840
25841 (define_peephole2
25842 [(match_scratch:W 1 "r")
25843 (parallel [(set (reg:P SP_REG)
25844 (plus:P (reg:P SP_REG)
25845 (match_operand:P 0 "const_int_operand")))
25846 (clobber (reg:CC FLAGS_REG))])]
25847 "optimize_insn_for_size_p ()
25848 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25849 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25850 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25851 \f
25852 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25853 ;; required and register dies. Similarly for 128 to -128.
25854 (define_peephole2
25855 [(set (match_operand 0 "flags_reg_operand")
25856 (match_operator 1 "compare_operator"
25857 [(match_operand 2 "register_operand")
25858 (match_operand 3 "const_int_operand")]))]
25859 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25860 && incdec_operand (operands[3], GET_MODE (operands[3])))
25861 || (!TARGET_FUSE_CMP_AND_BRANCH
25862 && INTVAL (operands[3]) == 128))
25863 && ix86_match_ccmode (insn, CCGCmode)
25864 && peep2_reg_dead_p (1, operands[2])"
25865 [(parallel [(set (match_dup 0)
25866 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25867 (clobber (match_dup 2))])])
25868 \f
25869 ;; Convert imul by three, five and nine into lea
25870 (define_peephole2
25871 [(parallel
25872 [(set (match_operand:SWI48 0 "register_operand")
25873 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25874 (match_operand:SWI48 2 "const359_operand")))
25875 (clobber (reg:CC FLAGS_REG))])]
25876 "!TARGET_PARTIAL_REG_STALL
25877 || <MODE>mode == SImode
25878 || optimize_function_for_size_p (cfun)"
25879 [(set (match_dup 0)
25880 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25881 (match_dup 1)))]
25882 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25883
25884 (define_peephole2
25885 [(parallel
25886 [(set (match_operand:SWI48 0 "register_operand")
25887 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25888 (match_operand:SWI48 2 "const359_operand")))
25889 (clobber (reg:CC FLAGS_REG))])]
25890 "optimize_insn_for_speed_p ()
25891 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25892 [(set (match_dup 0) (match_dup 1))
25893 (set (match_dup 0)
25894 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25895 (match_dup 0)))]
25896 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25897
25898 ;; imul $32bit_imm, mem, reg is vector decoded, while
25899 ;; imul $32bit_imm, reg, reg is direct decoded.
25900 (define_peephole2
25901 [(match_scratch:SWI48 3 "r")
25902 (parallel [(set (match_operand:SWI48 0 "register_operand")
25903 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25904 (match_operand:SWI48 2 "immediate_operand")))
25905 (clobber (reg:CC FLAGS_REG))])]
25906 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25907 && !satisfies_constraint_K (operands[2])"
25908 [(set (match_dup 3) (match_dup 1))
25909 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25910 (clobber (reg:CC FLAGS_REG))])])
25911
25912 (define_peephole2
25913 [(match_scratch:SI 3 "r")
25914 (parallel [(set (match_operand:DI 0 "register_operand")
25915 (zero_extend:DI
25916 (mult:SI (match_operand:SI 1 "memory_operand")
25917 (match_operand:SI 2 "immediate_operand"))))
25918 (clobber (reg:CC FLAGS_REG))])]
25919 "TARGET_64BIT
25920 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25921 && !satisfies_constraint_K (operands[2])"
25922 [(set (match_dup 3) (match_dup 1))
25923 (parallel [(set (match_dup 0)
25924 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25925 (clobber (reg:CC FLAGS_REG))])])
25926
25927 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25928 ;; Convert it into imul reg, reg
25929 ;; It would be better to force assembler to encode instruction using long
25930 ;; immediate, but there is apparently no way to do so.
25931 (define_peephole2
25932 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25933 (mult:SWI248
25934 (match_operand:SWI248 1 "nonimmediate_operand")
25935 (match_operand:SWI248 2 "const_int_operand")))
25936 (clobber (reg:CC FLAGS_REG))])
25937 (match_scratch:SWI248 3 "r")]
25938 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25939 && satisfies_constraint_K (operands[2])"
25940 [(set (match_dup 3) (match_dup 2))
25941 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25942 (clobber (reg:CC FLAGS_REG))])]
25943 {
25944 if (!rtx_equal_p (operands[0], operands[1]))
25945 emit_move_insn (operands[0], operands[1]);
25946 })
25947
25948 ;; After splitting up read-modify operations, array accesses with memory
25949 ;; operands might end up in form:
25950 ;; sall $2, %eax
25951 ;; movl 4(%esp), %edx
25952 ;; addl %edx, %eax
25953 ;; instead of pre-splitting:
25954 ;; sall $2, %eax
25955 ;; addl 4(%esp), %eax
25956 ;; Turn it into:
25957 ;; movl 4(%esp), %edx
25958 ;; leal (%edx,%eax,4), %eax
25959
25960 (define_peephole2
25961 [(match_scratch:W 5 "r")
25962 (parallel [(set (match_operand 0 "register_operand")
25963 (ashift (match_operand 1 "register_operand")
25964 (match_operand 2 "const_int_operand")))
25965 (clobber (reg:CC FLAGS_REG))])
25966 (parallel [(set (match_operand 3 "register_operand")
25967 (plus (match_dup 0)
25968 (match_operand 4 "x86_64_general_operand")))
25969 (clobber (reg:CC FLAGS_REG))])]
25970 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25971 /* Validate MODE for lea. */
25972 && ((!TARGET_PARTIAL_REG_STALL
25973 && (GET_MODE (operands[0]) == QImode
25974 || GET_MODE (operands[0]) == HImode))
25975 || GET_MODE (operands[0]) == SImode
25976 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25977 && (rtx_equal_p (operands[0], operands[3])
25978 || peep2_reg_dead_p (2, operands[0]))
25979 /* We reorder load and the shift. */
25980 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25981 [(set (match_dup 5) (match_dup 4))
25982 (set (match_dup 0) (match_dup 1))]
25983 {
25984 machine_mode op1mode = GET_MODE (operands[1]);
25985 machine_mode mode = op1mode == DImode ? DImode : SImode;
25986 int scale = 1 << INTVAL (operands[2]);
25987 rtx index = gen_lowpart (word_mode, operands[1]);
25988 rtx base = gen_lowpart (word_mode, operands[5]);
25989 rtx dest = gen_lowpart (mode, operands[3]);
25990
25991 operands[1] = gen_rtx_PLUS (word_mode, base,
25992 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25993 if (mode != word_mode)
25994 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25995
25996 operands[5] = base;
25997 if (op1mode != word_mode)
25998 operands[5] = gen_lowpart (op1mode, operands[5]);
25999
26000 operands[0] = dest;
26001 })
26002 \f
26003 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
26004 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
26005 ;; caught for use by garbage collectors and the like. Using an insn that
26006 ;; maps to SIGILL makes it more likely the program will rightfully die.
26007 ;; Keeping with tradition, "6" is in honor of #UD.
26008 (define_insn "trap"
26009 [(trap_if (const_int 1) (const_int 6))]
26010 ""
26011 {
26012 #ifdef HAVE_AS_IX86_UD2
26013 return "ud2";
26014 #else
26015 return ASM_SHORT "0x0b0f";
26016 #endif
26017 }
26018 [(set_attr "length" "2")])
26019
26020 (define_insn "ud2"
26021 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
26022 ""
26023 {
26024 #ifdef HAVE_AS_IX86_UD2
26025 return "ud2";
26026 #else
26027 return ASM_SHORT "0x0b0f";
26028 #endif
26029 }
26030 [(set_attr "length" "2")])
26031
26032 (define_expand "prefetch"
26033 [(prefetch (match_operand 0 "address_operand")
26034 (match_operand:SI 1 "const_int_operand")
26035 (match_operand:SI 2 "const_int_operand"))]
26036 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
26037 {
26038 bool write = operands[1] != const0_rtx;
26039 int locality = INTVAL (operands[2]);
26040
26041 gcc_assert (IN_RANGE (locality, 0, 3));
26042
26043 /* Use 3dNOW prefetch in case we are asking for write prefetch not
26044 supported by SSE counterpart (non-SSE2 athlon machines) or the
26045 SSE prefetch is not available (K6 machines). Otherwise use SSE
26046 prefetch as it allows specifying of locality. */
26047
26048 if (write)
26049 {
26050 if (TARGET_PREFETCHWT1)
26051 operands[2] = GEN_INT (MAX (locality, 2));
26052 else if (TARGET_PRFCHW)
26053 operands[2] = GEN_INT (3);
26054 else if (TARGET_3DNOW && !TARGET_SSE2)
26055 operands[2] = GEN_INT (3);
26056 else if (TARGET_PREFETCH_SSE)
26057 operands[1] = const0_rtx;
26058 else
26059 {
26060 gcc_assert (TARGET_3DNOW);
26061 operands[2] = GEN_INT (3);
26062 }
26063 }
26064 else
26065 {
26066 if (TARGET_PREFETCH_SSE)
26067 ;
26068 else
26069 {
26070 gcc_assert (TARGET_3DNOW);
26071 operands[2] = GEN_INT (3);
26072 }
26073 }
26074 })
26075
26076 (define_insn "*prefetch_sse"
26077 [(prefetch (match_operand 0 "address_operand" "p")
26078 (const_int 0)
26079 (match_operand:SI 1 "const_int_operand"))]
26080 "TARGET_PREFETCH_SSE"
26081 {
26082 static const char * const patterns[4] = {
26083 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
26084 };
26085
26086 int locality = INTVAL (operands[1]);
26087 gcc_assert (IN_RANGE (locality, 0, 3));
26088
26089 return patterns[locality];
26090 }
26091 [(set_attr "type" "sse")
26092 (set_attr "atom_sse_attr" "prefetch")
26093 (set (attr "length_address")
26094 (symbol_ref "memory_address_length (operands[0], false)"))
26095 (set_attr "memory" "none")])
26096
26097 (define_insn "*prefetch_3dnow"
26098 [(prefetch (match_operand 0 "address_operand" "p")
26099 (match_operand:SI 1 "const_int_operand")
26100 (const_int 3))]
26101 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
26102 {
26103 if (operands[1] == const0_rtx)
26104 return "prefetch\t%a0";
26105 else
26106 return "prefetchw\t%a0";
26107 }
26108 [(set_attr "type" "mmx")
26109 (set (attr "length_address")
26110 (symbol_ref "memory_address_length (operands[0], false)"))
26111 (set_attr "memory" "none")])
26112
26113 (define_insn "*prefetch_prefetchwt1"
26114 [(prefetch (match_operand 0 "address_operand" "p")
26115 (const_int 1)
26116 (const_int 2))]
26117 "TARGET_PREFETCHWT1"
26118 "prefetchwt1\t%a0";
26119 [(set_attr "type" "sse")
26120 (set (attr "length_address")
26121 (symbol_ref "memory_address_length (operands[0], false)"))
26122 (set_attr "memory" "none")])
26123
26124 (define_insn "prefetchi"
26125 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
26126 (match_operand:SI 1 "const_int_operand")]
26127 UNSPECV_PREFETCHI)]
26128 "TARGET_PREFETCHI && TARGET_64BIT"
26129 {
26130 static const char * const patterns[2] = {
26131 "prefetchit1\t%0", "prefetchit0\t%0"
26132 };
26133
26134 int locality = INTVAL (operands[1]);
26135 gcc_assert (IN_RANGE (locality, 2, 3));
26136
26137 return patterns[locality - 2];
26138 }
26139 [(set_attr "type" "sse")
26140 (set (attr "length_address")
26141 (symbol_ref "memory_address_length (operands[0], false)"))
26142 (set_attr "memory" "none")])
26143
26144 (define_insn "sse4_2_crc32<mode>"
26145 [(set (match_operand:SI 0 "register_operand" "=r")
26146 (unspec:SI
26147 [(match_operand:SI 1 "register_operand" "0")
26148 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
26149 UNSPEC_CRC32))]
26150 "TARGET_CRC32"
26151 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
26152 [(set_attr "type" "sselog1")
26153 (set_attr "prefix_rep" "1")
26154 (set_attr "prefix_extra" "1")
26155 (set (attr "prefix_data16")
26156 (if_then_else (match_operand:HI 2)
26157 (const_string "1")
26158 (const_string "*")))
26159 (set (attr "prefix_rex")
26160 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
26161 (const_string "1")
26162 (const_string "*")))
26163 (set_attr "mode" "SI")])
26164
26165 (define_insn "sse4_2_crc32di"
26166 [(set (match_operand:DI 0 "register_operand" "=r")
26167 (zero_extend:DI
26168 (unspec:SI
26169 [(match_operand:SI 1 "register_operand" "0")
26170 (match_operand:DI 2 "nonimmediate_operand" "rm")]
26171 UNSPEC_CRC32)))]
26172 "TARGET_64BIT && TARGET_CRC32"
26173 "crc32{q}\t{%2, %0|%0, %2}"
26174 [(set_attr "type" "sselog1")
26175 (set_attr "prefix_rep" "1")
26176 (set_attr "prefix_extra" "1")
26177 (set_attr "mode" "DI")])
26178
26179 (define_insn "rdpmc"
26180 [(set (match_operand:DI 0 "register_operand" "=A")
26181 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26182 UNSPECV_RDPMC))]
26183 "!TARGET_64BIT"
26184 "rdpmc"
26185 [(set_attr "type" "other")
26186 (set_attr "length" "2")])
26187
26188 (define_insn "rdpmc_rex64"
26189 [(set (match_operand:DI 0 "register_operand" "=a")
26190 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26191 UNSPECV_RDPMC))
26192 (set (match_operand:DI 1 "register_operand" "=d")
26193 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
26194 "TARGET_64BIT"
26195 "rdpmc"
26196 [(set_attr "type" "other")
26197 (set_attr "length" "2")])
26198
26199 (define_insn "rdtsc"
26200 [(set (match_operand:DI 0 "register_operand" "=A")
26201 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26202 "!TARGET_64BIT"
26203 "rdtsc"
26204 [(set_attr "type" "other")
26205 (set_attr "length" "2")])
26206
26207 (define_insn "rdtsc_rex64"
26208 [(set (match_operand:DI 0 "register_operand" "=a")
26209 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
26210 (set (match_operand:DI 1 "register_operand" "=d")
26211 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
26212 "TARGET_64BIT"
26213 "rdtsc"
26214 [(set_attr "type" "other")
26215 (set_attr "length" "2")])
26216
26217 (define_insn "rdtscp"
26218 [(set (match_operand:DI 0 "register_operand" "=A")
26219 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26220 (set (match_operand:SI 1 "register_operand" "=c")
26221 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26222 "!TARGET_64BIT"
26223 "rdtscp"
26224 [(set_attr "type" "other")
26225 (set_attr "length" "3")])
26226
26227 (define_insn "rdtscp_rex64"
26228 [(set (match_operand:DI 0 "register_operand" "=a")
26229 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26230 (set (match_operand:DI 1 "register_operand" "=d")
26231 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
26232 (set (match_operand:SI 2 "register_operand" "=c")
26233 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
26234 "TARGET_64BIT"
26235 "rdtscp"
26236 [(set_attr "type" "other")
26237 (set_attr "length" "3")])
26238
26239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26240 ;;
26241 ;; FXSR, XSAVE and XSAVEOPT instructions
26242 ;;
26243 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26244
26245 (define_insn "fxsave"
26246 [(set (match_operand:BLK 0 "memory_operand" "=m")
26247 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
26248 "TARGET_FXSR"
26249 "fxsave\t%0"
26250 [(set_attr "type" "other")
26251 (set_attr "memory" "store")
26252 (set (attr "length")
26253 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26254
26255 (define_insn "fxsave64"
26256 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26257 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
26258 "TARGET_64BIT && TARGET_FXSR"
26259 "fxsave64\t%0"
26260 [(set_attr "type" "other")
26261 (set_attr "addr" "gpr16")
26262 (set_attr "memory" "store")
26263 (set (attr "length")
26264 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26265
26266 (define_insn "fxrstor"
26267 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26268 UNSPECV_FXRSTOR)]
26269 "TARGET_FXSR"
26270 "fxrstor\t%0"
26271 [(set_attr "type" "other")
26272 (set_attr "memory" "load")
26273 (set (attr "length")
26274 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26275
26276 (define_insn "fxrstor64"
26277 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "jm")]
26278 UNSPECV_FXRSTOR64)]
26279 "TARGET_64BIT && TARGET_FXSR"
26280 "fxrstor64\t%0"
26281 [(set_attr "type" "other")
26282 (set_attr "addr" "gpr16")
26283 (set_attr "memory" "load")
26284 (set (attr "length")
26285 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26286
26287 (define_int_iterator ANY_XSAVE
26288 [UNSPECV_XSAVE
26289 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
26290 (UNSPECV_XSAVEC "TARGET_XSAVEC")
26291 (UNSPECV_XSAVES "TARGET_XSAVES")])
26292
26293 (define_int_iterator ANY_XSAVE64
26294 [UNSPECV_XSAVE64
26295 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
26296 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
26297 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
26298
26299 (define_int_attr xsave
26300 [(UNSPECV_XSAVE "xsave")
26301 (UNSPECV_XSAVE64 "xsave64")
26302 (UNSPECV_XSAVEOPT "xsaveopt")
26303 (UNSPECV_XSAVEOPT64 "xsaveopt64")
26304 (UNSPECV_XSAVEC "xsavec")
26305 (UNSPECV_XSAVEC64 "xsavec64")
26306 (UNSPECV_XSAVES "xsaves")
26307 (UNSPECV_XSAVES64 "xsaves64")])
26308
26309 (define_int_iterator ANY_XRSTOR
26310 [UNSPECV_XRSTOR
26311 (UNSPECV_XRSTORS "TARGET_XSAVES")])
26312
26313 (define_int_iterator ANY_XRSTOR64
26314 [UNSPECV_XRSTOR64
26315 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
26316
26317 (define_int_attr xrstor
26318 [(UNSPECV_XRSTOR "xrstor")
26319 (UNSPECV_XRSTOR64 "xrstor")
26320 (UNSPECV_XRSTORS "xrstors")
26321 (UNSPECV_XRSTORS64 "xrstors")])
26322
26323 (define_insn "<xsave>"
26324 [(set (match_operand:BLK 0 "memory_operand" "=m")
26325 (unspec_volatile:BLK
26326 [(match_operand:DI 1 "register_operand" "A")]
26327 ANY_XSAVE))]
26328 "!TARGET_64BIT && TARGET_XSAVE"
26329 "<xsave>\t%0"
26330 [(set_attr "type" "other")
26331 (set_attr "memory" "store")
26332 (set (attr "length")
26333 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26334
26335 (define_insn "<xsave>_rex64"
26336 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26337 (unspec_volatile:BLK
26338 [(match_operand:SI 1 "register_operand" "a")
26339 (match_operand:SI 2 "register_operand" "d")]
26340 ANY_XSAVE))]
26341 "TARGET_64BIT && TARGET_XSAVE"
26342 "<xsave>\t%0"
26343 [(set_attr "type" "other")
26344 (set_attr "memory" "store")
26345 (set_attr "addr" "gpr16")
26346 (set (attr "length")
26347 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26348
26349 (define_insn "<xsave>"
26350 [(set (match_operand:BLK 0 "memory_operand" "=jm")
26351 (unspec_volatile:BLK
26352 [(match_operand:SI 1 "register_operand" "a")
26353 (match_operand:SI 2 "register_operand" "d")]
26354 ANY_XSAVE64))]
26355 "TARGET_64BIT && TARGET_XSAVE"
26356 "<xsave>\t%0"
26357 [(set_attr "type" "other")
26358 (set_attr "memory" "store")
26359 (set_attr "addr" "gpr16")
26360 (set (attr "length")
26361 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26362
26363 (define_insn "<xrstor>"
26364 [(unspec_volatile:BLK
26365 [(match_operand:BLK 0 "memory_operand" "m")
26366 (match_operand:DI 1 "register_operand" "A")]
26367 ANY_XRSTOR)]
26368 "!TARGET_64BIT && TARGET_XSAVE"
26369 "<xrstor>\t%0"
26370 [(set_attr "type" "other")
26371 (set_attr "memory" "load")
26372 (set (attr "length")
26373 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26374
26375 (define_insn "<xrstor>_rex64"
26376 [(unspec_volatile:BLK
26377 [(match_operand:BLK 0 "memory_operand" "jm")
26378 (match_operand:SI 1 "register_operand" "a")
26379 (match_operand:SI 2 "register_operand" "d")]
26380 ANY_XRSTOR)]
26381 "TARGET_64BIT && TARGET_XSAVE"
26382 "<xrstor>\t%0"
26383 [(set_attr "type" "other")
26384 (set_attr "memory" "load")
26385 (set_attr "addr" "gpr16")
26386 (set (attr "length")
26387 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
26388
26389 (define_insn "<xrstor>64"
26390 [(unspec_volatile:BLK
26391 [(match_operand:BLK 0 "memory_operand" "jm")
26392 (match_operand:SI 1 "register_operand" "a")
26393 (match_operand:SI 2 "register_operand" "d")]
26394 ANY_XRSTOR64)]
26395 "TARGET_64BIT && TARGET_XSAVE"
26396 "<xrstor>64\t%0"
26397 [(set_attr "type" "other")
26398 (set_attr "memory" "load")
26399 (set_attr "addr" "gpr16")
26400 (set (attr "length")
26401 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
26402
26403 (define_insn "xsetbv"
26404 [(unspec_volatile:SI
26405 [(match_operand:SI 0 "register_operand" "c")
26406 (match_operand:DI 1 "register_operand" "A")]
26407 UNSPECV_XSETBV)]
26408 "!TARGET_64BIT && TARGET_XSAVE"
26409 "xsetbv"
26410 [(set_attr "type" "other")])
26411
26412 (define_insn "xsetbv_rex64"
26413 [(unspec_volatile:SI
26414 [(match_operand:SI 0 "register_operand" "c")
26415 (match_operand:SI 1 "register_operand" "a")
26416 (match_operand:SI 2 "register_operand" "d")]
26417 UNSPECV_XSETBV)]
26418 "TARGET_64BIT && TARGET_XSAVE"
26419 "xsetbv"
26420 [(set_attr "type" "other")])
26421
26422 (define_insn "xgetbv"
26423 [(set (match_operand:DI 0 "register_operand" "=A")
26424 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
26425 UNSPECV_XGETBV))]
26426 "!TARGET_64BIT && TARGET_XSAVE"
26427 "xgetbv"
26428 [(set_attr "type" "other")])
26429
26430 (define_insn "xgetbv_rex64"
26431 [(set (match_operand:DI 0 "register_operand" "=a")
26432 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
26433 UNSPECV_XGETBV))
26434 (set (match_operand:DI 1 "register_operand" "=d")
26435 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
26436 "TARGET_64BIT && TARGET_XSAVE"
26437 "xgetbv"
26438 [(set_attr "type" "other")])
26439
26440 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26441 ;;
26442 ;; Floating-point instructions for atomic compound assignments
26443 ;;
26444 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26445
26446 ; Clobber all floating-point registers on environment save and restore
26447 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
26448 (define_insn "fnstenv"
26449 [(set (match_operand:BLK 0 "memory_operand" "=m")
26450 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
26451 (clobber (reg:XF ST0_REG))
26452 (clobber (reg:XF ST1_REG))
26453 (clobber (reg:XF ST2_REG))
26454 (clobber (reg:XF ST3_REG))
26455 (clobber (reg:XF ST4_REG))
26456 (clobber (reg:XF ST5_REG))
26457 (clobber (reg:XF ST6_REG))
26458 (clobber (reg:XF ST7_REG))]
26459 "TARGET_80387"
26460 "fnstenv\t%0"
26461 [(set_attr "type" "other")
26462 (set_attr "memory" "store")
26463 (set (attr "length")
26464 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26465
26466 (define_insn "fldenv"
26467 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
26468 UNSPECV_FLDENV)
26469 (clobber (reg:XF ST0_REG))
26470 (clobber (reg:XF ST1_REG))
26471 (clobber (reg:XF ST2_REG))
26472 (clobber (reg:XF ST3_REG))
26473 (clobber (reg:XF ST4_REG))
26474 (clobber (reg:XF ST5_REG))
26475 (clobber (reg:XF ST6_REG))
26476 (clobber (reg:XF ST7_REG))]
26477 "TARGET_80387"
26478 "fldenv\t%0"
26479 [(set_attr "type" "other")
26480 (set_attr "memory" "load")
26481 (set (attr "length")
26482 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26483
26484 (define_insn "fnstsw"
26485 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
26486 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
26487 "TARGET_80387"
26488 "fnstsw\t%0"
26489 [(set_attr "type" "other,other")
26490 (set_attr "memory" "none,store")
26491 (set (attr "length")
26492 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
26493
26494 (define_insn "fnclex"
26495 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
26496 "TARGET_80387"
26497 "fnclex"
26498 [(set_attr "type" "other")
26499 (set_attr "memory" "none")
26500 (set_attr "length" "2")])
26501
26502 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26503 ;;
26504 ;; LWP instructions
26505 ;;
26506 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26507
26508 (define_insn "@lwp_llwpcb<mode>"
26509 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26510 UNSPECV_LLWP_INTRINSIC)]
26511 "TARGET_LWP"
26512 "llwpcb\t%0"
26513 [(set_attr "type" "lwp")
26514 (set_attr "mode" "<MODE>")
26515 (set_attr "length" "5")])
26516
26517 (define_insn "@lwp_slwpcb<mode>"
26518 [(set (match_operand:P 0 "register_operand" "=r")
26519 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
26520 "TARGET_LWP"
26521 "slwpcb\t%0"
26522 [(set_attr "type" "lwp")
26523 (set_attr "mode" "<MODE>")
26524 (set_attr "length" "5")])
26525
26526 (define_insn "@lwp_lwpval<mode>"
26527 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26528 (match_operand:SI 1 "nonimmediate_operand" "rm")
26529 (match_operand:SI 2 "const_int_operand")]
26530 UNSPECV_LWPVAL_INTRINSIC)]
26531 "TARGET_LWP"
26532 "lwpval\t{%2, %1, %0|%0, %1, %2}"
26533 [(set_attr "type" "lwp")
26534 (set_attr "mode" "<MODE>")
26535 (set (attr "length")
26536 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26537
26538 (define_insn "@lwp_lwpins<mode>"
26539 [(set (reg:CCC FLAGS_REG)
26540 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
26541 (match_operand:SI 1 "nonimmediate_operand" "rm")
26542 (match_operand:SI 2 "const_int_operand")]
26543 UNSPECV_LWPINS_INTRINSIC))]
26544 "TARGET_LWP"
26545 "lwpins\t{%2, %1, %0|%0, %1, %2}"
26546 [(set_attr "type" "lwp")
26547 (set_attr "mode" "<MODE>")
26548 (set (attr "length")
26549 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
26550
26551 (define_int_iterator RDFSGSBASE
26552 [UNSPECV_RDFSBASE
26553 UNSPECV_RDGSBASE])
26554
26555 (define_int_iterator WRFSGSBASE
26556 [UNSPECV_WRFSBASE
26557 UNSPECV_WRGSBASE])
26558
26559 (define_int_attr fsgs
26560 [(UNSPECV_RDFSBASE "fs")
26561 (UNSPECV_RDGSBASE "gs")
26562 (UNSPECV_WRFSBASE "fs")
26563 (UNSPECV_WRGSBASE "gs")])
26564
26565 (define_insn "rd<fsgs>base<mode>"
26566 [(set (match_operand:SWI48 0 "register_operand" "=r")
26567 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
26568 "TARGET_64BIT && TARGET_FSGSBASE"
26569 "rd<fsgs>base\t%0"
26570 [(set_attr "type" "other")
26571 (set_attr "prefix_0f" "1")
26572 (set_attr "prefix_rep" "1")])
26573
26574 (define_insn "wr<fsgs>base<mode>"
26575 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26576 WRFSGSBASE)]
26577 "TARGET_64BIT && TARGET_FSGSBASE"
26578 "wr<fsgs>base\t%0"
26579 [(set_attr "type" "other")
26580 (set_attr "prefix_0f" "1")
26581 (set_attr "prefix_rep" "1")])
26582
26583 (define_insn "ptwrite<mode>"
26584 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
26585 UNSPECV_PTWRITE)]
26586 "TARGET_PTWRITE"
26587 "ptwrite\t%0"
26588 [(set_attr "type" "other")
26589 (set_attr "prefix_0f" "1")
26590 (set_attr "prefix_rep" "1")])
26591
26592 (define_insn "@rdrand<mode>"
26593 [(set (match_operand:SWI248 0 "register_operand" "=r")
26594 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
26595 (set (reg:CCC FLAGS_REG)
26596 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
26597 "TARGET_RDRND"
26598 "rdrand\t%0"
26599 [(set_attr "type" "other")
26600 (set_attr "prefix_0f" "1")])
26601
26602 (define_insn "@rdseed<mode>"
26603 [(set (match_operand:SWI248 0 "register_operand" "=r")
26604 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
26605 (set (reg:CCC FLAGS_REG)
26606 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
26607 "TARGET_RDSEED"
26608 "rdseed\t%0"
26609 [(set_attr "type" "other")
26610 (set_attr "prefix_0f" "1")])
26611
26612 (define_expand "pause"
26613 [(set (match_dup 0)
26614 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26615 ""
26616 {
26617 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
26618 MEM_VOLATILE_P (operands[0]) = 1;
26619 })
26620
26621 ;; Use "rep; nop", instead of "pause", to support older assemblers.
26622 ;; They have the same encoding.
26623 (define_insn "*pause"
26624 [(set (match_operand:BLK 0)
26625 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
26626 ""
26627 "rep%; nop"
26628 [(set_attr "length" "2")
26629 (set_attr "memory" "unknown")])
26630
26631 ;; CET instructions
26632 (define_insn "@rdssp<mode>"
26633 [(set (match_operand:SWI48 0 "register_operand" "=r")
26634 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
26635 UNSPECV_NOP_RDSSP))]
26636 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26637 "rdssp<mskmodesuffix>\t%0"
26638 [(set_attr "length" "6")
26639 (set_attr "type" "other")])
26640
26641 (define_insn "@incssp<mode>"
26642 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
26643 UNSPECV_INCSSP)]
26644 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
26645 "incssp<mskmodesuffix>\t%0"
26646 [(set_attr "length" "4")
26647 (set_attr "type" "other")])
26648
26649 (define_insn "saveprevssp"
26650 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
26651 "TARGET_SHSTK"
26652 "saveprevssp"
26653 [(set_attr "length" "5")
26654 (set_attr "type" "other")])
26655
26656 (define_insn "rstorssp"
26657 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26658 UNSPECV_RSTORSSP)]
26659 "TARGET_SHSTK"
26660 "rstorssp\t%0"
26661 [(set_attr "length" "5")
26662 (set_attr "type" "other")])
26663
26664 (define_insn "@wrss<mode>"
26665 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26666 (match_operand:SWI48 1 "memory_operand" "m")]
26667 UNSPECV_WRSS)]
26668 "TARGET_SHSTK"
26669 "wrss<mskmodesuffix>\t%0, %1"
26670 [(set_attr "length" "3")
26671 (set_attr "type" "other")])
26672
26673 (define_insn "@wruss<mode>"
26674 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26675 (match_operand:SWI48 1 "memory_operand" "m")]
26676 UNSPECV_WRUSS)]
26677 "TARGET_SHSTK"
26678 "wruss<mskmodesuffix>\t%0, %1"
26679 [(set_attr "length" "4")
26680 (set_attr "type" "other")])
26681
26682 (define_insn "setssbsy"
26683 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26684 "TARGET_SHSTK"
26685 "setssbsy"
26686 [(set_attr "length" "4")
26687 (set_attr "type" "other")])
26688
26689 (define_insn "clrssbsy"
26690 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26691 UNSPECV_CLRSSBSY)]
26692 "TARGET_SHSTK"
26693 "clrssbsy\t%0"
26694 [(set_attr "length" "4")
26695 (set_attr "type" "other")])
26696
26697 (define_insn "nop_endbr"
26698 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26699 "(flag_cf_protection & CF_BRANCH)"
26700 {
26701 return TARGET_64BIT ? "endbr64" : "endbr32";
26702 }
26703 [(set_attr "length" "4")
26704 (set_attr "length_immediate" "0")
26705 (set_attr "modrm" "0")])
26706
26707 ;; For RTM support
26708 (define_expand "xbegin"
26709 [(set (match_operand:SI 0 "register_operand")
26710 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26711 "TARGET_RTM"
26712 {
26713 rtx_code_label *label = gen_label_rtx ();
26714
26715 /* xbegin is emitted as jump_insn, so reload won't be able
26716 to reload its operand. Force the value into AX hard register. */
26717 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26718 emit_move_insn (ax_reg, constm1_rtx);
26719
26720 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26721
26722 emit_label (label);
26723 LABEL_NUSES (label) = 1;
26724
26725 emit_move_insn (operands[0], ax_reg);
26726
26727 DONE;
26728 })
26729
26730 (define_insn "xbegin_1"
26731 [(set (pc)
26732 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26733 (const_int 0))
26734 (label_ref (match_operand 1))
26735 (pc)))
26736 (set (match_operand:SI 0 "register_operand" "+a")
26737 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26738 "TARGET_RTM"
26739 "xbegin\t%l1"
26740 [(set_attr "type" "other")
26741 (set_attr "length" "6")])
26742
26743 (define_insn "xend"
26744 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26745 "TARGET_RTM"
26746 "xend"
26747 [(set_attr "type" "other")
26748 (set_attr "length" "3")])
26749
26750 (define_insn "xabort"
26751 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26752 UNSPECV_XABORT)]
26753 "TARGET_RTM"
26754 "xabort\t%0"
26755 [(set_attr "type" "other")
26756 (set_attr "length" "3")])
26757
26758 (define_expand "xtest"
26759 [(set (match_operand:QI 0 "register_operand")
26760 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26761 "TARGET_RTM"
26762 {
26763 emit_insn (gen_xtest_1 ());
26764
26765 ix86_expand_setcc (operands[0], NE,
26766 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26767 DONE;
26768 })
26769
26770 (define_insn "xtest_1"
26771 [(set (reg:CCZ FLAGS_REG)
26772 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26773 "TARGET_RTM"
26774 "xtest"
26775 [(set_attr "type" "other")
26776 (set_attr "length" "3")])
26777
26778 (define_insn "clwb"
26779 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26780 UNSPECV_CLWB)]
26781 "TARGET_CLWB"
26782 "clwb\t%a0"
26783 [(set_attr "type" "sse")
26784 (set_attr "atom_sse_attr" "fence")
26785 (set_attr "memory" "unknown")])
26786
26787 (define_insn "clflushopt"
26788 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26789 UNSPECV_CLFLUSHOPT)]
26790 "TARGET_CLFLUSHOPT"
26791 "clflushopt\t%a0"
26792 [(set_attr "type" "sse")
26793 (set_attr "atom_sse_attr" "fence")
26794 (set_attr "memory" "unknown")])
26795
26796 ;; MONITORX and MWAITX
26797 (define_insn "mwaitx"
26798 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26799 (match_operand:SI 1 "register_operand" "a")
26800 (match_operand:SI 2 "register_operand" "b")]
26801 UNSPECV_MWAITX)]
26802 "TARGET_MWAITX"
26803 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26804 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26805 ;; we only need to set up 32bit registers.
26806 "mwaitx"
26807 [(set_attr "length" "3")])
26808
26809 (define_insn "@monitorx_<mode>"
26810 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26811 (match_operand:SI 1 "register_operand" "c")
26812 (match_operand:SI 2 "register_operand" "d")]
26813 UNSPECV_MONITORX)]
26814 "TARGET_MWAITX"
26815 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26816 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26817 ;; zero extended to 64bit, we only need to set up 32bit registers.
26818 "%^monitorx"
26819 [(set (attr "length")
26820 (symbol_ref ("(Pmode != word_mode) + 3")))])
26821
26822 ;; CLZERO
26823 (define_insn "@clzero_<mode>"
26824 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26825 UNSPECV_CLZERO)]
26826 "TARGET_CLZERO"
26827 "clzero"
26828 [(set_attr "length" "3")
26829 (set_attr "memory" "unknown")])
26830
26831 ;; RDPKRU and WRPKRU
26832
26833 (define_expand "rdpkru"
26834 [(parallel
26835 [(set (match_operand:SI 0 "register_operand")
26836 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26837 (set (match_dup 2) (const_int 0))])]
26838 "TARGET_PKU"
26839 {
26840 operands[1] = force_reg (SImode, const0_rtx);
26841 operands[2] = gen_reg_rtx (SImode);
26842 })
26843
26844 (define_insn "*rdpkru"
26845 [(set (match_operand:SI 0 "register_operand" "=a")
26846 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26847 UNSPECV_PKU))
26848 (set (match_operand:SI 1 "register_operand" "=d")
26849 (const_int 0))]
26850 "TARGET_PKU"
26851 "rdpkru"
26852 [(set_attr "type" "other")])
26853
26854 (define_expand "wrpkru"
26855 [(unspec_volatile:SI
26856 [(match_operand:SI 0 "register_operand")
26857 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26858 "TARGET_PKU"
26859 {
26860 operands[1] = force_reg (SImode, const0_rtx);
26861 operands[2] = force_reg (SImode, const0_rtx);
26862 })
26863
26864 (define_insn "*wrpkru"
26865 [(unspec_volatile:SI
26866 [(match_operand:SI 0 "register_operand" "a")
26867 (match_operand:SI 1 "register_operand" "d")
26868 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26869 "TARGET_PKU"
26870 "wrpkru"
26871 [(set_attr "type" "other")])
26872
26873 (define_insn "rdpid"
26874 [(set (match_operand:SI 0 "register_operand" "=r")
26875 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26876 "!TARGET_64BIT && TARGET_RDPID"
26877 "rdpid\t%0"
26878 [(set_attr "type" "other")])
26879
26880 (define_insn "rdpid_rex64"
26881 [(set (match_operand:DI 0 "register_operand" "=r")
26882 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26883 "TARGET_64BIT && TARGET_RDPID"
26884 "rdpid\t%0"
26885 [(set_attr "type" "other")])
26886
26887 ;; Intirinsics for > i486
26888
26889 (define_insn "wbinvd"
26890 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26891 ""
26892 "wbinvd"
26893 [(set_attr "type" "other")])
26894
26895 (define_insn "wbnoinvd"
26896 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26897 "TARGET_WBNOINVD"
26898 "wbnoinvd"
26899 [(set_attr "type" "other")])
26900
26901 ;; MOVDIRI and MOVDIR64B
26902
26903 (define_insn "movdiri<mode>"
26904 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26905 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26906 UNSPEC_MOVDIRI))]
26907 "TARGET_MOVDIRI"
26908 "movdiri\t{%1, %0|%0, %1}"
26909 [(set_attr "type" "other")])
26910
26911 (define_insn "@movdir64b_<mode>"
26912 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26913 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26914 UNSPEC_MOVDIR64B))]
26915 "TARGET_MOVDIR64B"
26916 "movdir64b\t{%1, %0|%0, %1}"
26917 [(set_attr "type" "other")])
26918
26919 ;; TSXLDTRK
26920 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26921 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26922 (UNSPECV_XRESLDTRK "xresldtrk")])
26923 (define_insn "<tsxldtrk>"
26924 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26925 "TARGET_TSXLDTRK"
26926 "<tsxldtrk>"
26927 [(set_attr "type" "other")
26928 (set_attr "length" "4")])
26929
26930 ;; ENQCMD and ENQCMDS
26931
26932 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26933 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26934
26935 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26936 [(set (reg:CCZ FLAGS_REG)
26937 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26938 (match_operand:XI 1 "memory_operand" "m")]
26939 ENQCMD))]
26940 "TARGET_ENQCMD"
26941 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26942 [(set_attr "type" "other")])
26943
26944 ;; UINTR
26945 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26946 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26947
26948 (define_insn "<uintr>"
26949 [(unspec_volatile [(const_int 0)] UINTR)]
26950 "TARGET_UINTR && TARGET_64BIT"
26951 "<uintr>"
26952 [(set_attr "type" "other")
26953 (set_attr "length" "4")])
26954
26955 (define_insn "testui"
26956 [(set (reg:CCC FLAGS_REG)
26957 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26958 "TARGET_UINTR && TARGET_64BIT"
26959 "testui"
26960 [(set_attr "type" "other")
26961 (set_attr "length" "4")])
26962
26963 (define_insn "senduipi"
26964 [(unspec_volatile
26965 [(match_operand:DI 0 "register_operand" "r")]
26966 UNSPECV_SENDUIPI)]
26967 "TARGET_UINTR && TARGET_64BIT"
26968 "senduipi\t%0"
26969 [(set_attr "type" "other")
26970 (set_attr "length" "4")])
26971
26972 ;; WAITPKG
26973
26974 (define_insn "umwait"
26975 [(set (reg:CCC FLAGS_REG)
26976 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26977 (match_operand:DI 1 "register_operand" "A")]
26978 UNSPECV_UMWAIT))]
26979 "!TARGET_64BIT && TARGET_WAITPKG"
26980 "umwait\t%0"
26981 [(set_attr "length" "3")])
26982
26983 (define_insn "umwait_rex64"
26984 [(set (reg:CCC FLAGS_REG)
26985 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26986 (match_operand:SI 1 "register_operand" "a")
26987 (match_operand:SI 2 "register_operand" "d")]
26988 UNSPECV_UMWAIT))]
26989 "TARGET_64BIT && TARGET_WAITPKG"
26990 "umwait\t%0"
26991 [(set_attr "length" "3")])
26992
26993 (define_insn "@umonitor_<mode>"
26994 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26995 UNSPECV_UMONITOR)]
26996 "TARGET_WAITPKG"
26997 "umonitor\t%0"
26998 [(set (attr "length")
26999 (symbol_ref ("(Pmode != word_mode) + 3")))])
27000
27001 (define_insn "tpause"
27002 [(set (reg:CCC FLAGS_REG)
27003 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
27004 (match_operand:DI 1 "register_operand" "A")]
27005 UNSPECV_TPAUSE))]
27006 "!TARGET_64BIT && TARGET_WAITPKG"
27007 "tpause\t%0"
27008 [(set_attr "length" "3")])
27009
27010 (define_insn "tpause_rex64"
27011 [(set (reg:CCC FLAGS_REG)
27012 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
27013 (match_operand:SI 1 "register_operand" "a")
27014 (match_operand:SI 2 "register_operand" "d")]
27015 UNSPECV_TPAUSE))]
27016 "TARGET_64BIT && TARGET_WAITPKG"
27017 "tpause\t%0"
27018 [(set_attr "length" "3")])
27019
27020 (define_insn "cldemote"
27021 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
27022 UNSPECV_CLDEMOTE)]
27023 "TARGET_CLDEMOTE"
27024 "cldemote\t%a0"
27025 [(set_attr "type" "other")
27026 (set_attr "memory" "unknown")])
27027
27028 (define_insn "speculation_barrier"
27029 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
27030 ""
27031 "lfence"
27032 [(set_attr "type" "other")
27033 (set_attr "length" "3")])
27034
27035 (define_insn "serialize"
27036 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
27037 "TARGET_SERIALIZE"
27038 "serialize"
27039 [(set_attr "type" "other")
27040 (set_attr "length" "3")])
27041
27042 (define_insn "patchable_area"
27043 [(unspec_volatile [(match_operand 0 "const_int_operand")
27044 (match_operand 1 "const_int_operand")]
27045 UNSPECV_PATCHABLE_AREA)]
27046 ""
27047 {
27048 ix86_output_patchable_area (INTVAL (operands[0]),
27049 INTVAL (operands[1]) != 0);
27050 return "";
27051 }
27052 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
27053 (set_attr "length_immediate" "0")
27054 (set_attr "modrm" "0")])
27055
27056 (define_insn "hreset"
27057 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
27058 UNSPECV_HRESET)]
27059 "TARGET_HRESET"
27060 "hreset\t{$0|0}"
27061 [(set_attr "type" "other")
27062 (set_attr "length" "4")])
27063
27064 ;; Spaceship optimization
27065 (define_expand "spaceship<mode>3"
27066 [(match_operand:SI 0 "register_operand")
27067 (match_operand:MODEF 1 "cmp_fp_expander_operand")
27068 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
27069 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
27070 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
27071 {
27072 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
27073 DONE;
27074 })
27075
27076 (define_expand "spaceshipxf3"
27077 [(match_operand:SI 0 "register_operand")
27078 (match_operand:XF 1 "nonmemory_operand")
27079 (match_operand:XF 2 "nonmemory_operand")]
27080 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
27081 {
27082 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
27083 DONE;
27084 })
27085
27086 ;; Defined because the generic expand_builtin_issignaling for XFmode
27087 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
27088 ;; signaling.
27089 (define_expand "issignalingxf2"
27090 [(match_operand:SI 0 "register_operand")
27091 (match_operand:XF 1 "general_operand")]
27092 ""
27093 {
27094 rtx temp = operands[1];
27095 if (!MEM_P (temp))
27096 {
27097 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
27098 emit_move_insn (mem, temp);
27099 temp = mem;
27100 }
27101 rtx ex = adjust_address (temp, HImode, 8);
27102 rtx hi = adjust_address (temp, SImode, 4);
27103 rtx lo = adjust_address (temp, SImode, 0);
27104 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
27105 rtx mask = GEN_INT (0x7fff);
27106 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
27107 /* Expand to:
27108 ((ex & mask) && (int) hi >= 0)
27109 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
27110 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
27111 lo = expand_binop (SImode, ior_optab, lo, nlo,
27112 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27113 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
27114 temp = expand_binop (SImode, xor_optab, hi, bit,
27115 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27116 temp = expand_binop (SImode, ior_optab, temp, lo,
27117 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27118 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
27119 SImode, 1, 1);
27120 ex = expand_binop (HImode, and_optab, ex, mask,
27121 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27122 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
27123 ex, const0_rtx, SImode, 1, 1);
27124 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
27125 ex, mask, HImode, 1, 1);
27126 temp = expand_binop (SImode, and_optab, temp, ex,
27127 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27128 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
27129 hi, const0_rtx, SImode, 0, 1);
27130 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
27131 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27132 temp = expand_binop (SImode, ior_optab, temp, temp2,
27133 NULL_RTX, 1, OPTAB_LIB_WIDEN);
27134 emit_move_insn (operands[0], temp);
27135 DONE;
27136 })
27137
27138 (define_insn "urdmsr"
27139 [(set (match_operand:DI 0 "register_operand" "=r")
27140 (unspec_volatile:DI
27141 [(match_operand:DI 1 "x86_64_szext_nonmemory_operand" "reZ")]
27142 UNSPECV_URDMSR))]
27143 "TARGET_USER_MSR && TARGET_64BIT"
27144 "urdmsr\t{%1, %0|%0, %1}"
27145 [(set_attr "prefix" "vex")
27146 (set_attr "type" "other")])
27147
27148 (define_insn "uwrmsr"
27149 [(unspec_volatile
27150 [(match_operand:DI 0 "x86_64_szext_nonmemory_operand" "reZ")
27151 (match_operand:DI 1 "register_operand" "r")]
27152 UNSPECV_UWRMSR)]
27153 "TARGET_USER_MSR && TARGET_64BIT"
27154 "uwrmsr\t{%1, %0|%0, %1}"
27155 [(set_attr "prefix" "vex")
27156 (set_attr "type" "other")])
27157
27158 (include "mmx.md")
27159 (include "sse.md")
27160 (include "sync.md")